diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index d02ca370f4..0000000000 --- a/.eslintignore +++ /dev/null @@ -1,11 +0,0 @@ -!.eslintrc.js -**/node_modules/** -**/VendorLib/** -**/flow-typed/** -**/gen-nodejs/** -**/build/** - -# TODO(dabramov): these have lint errors - fix them -**/__tests__/** -**/__atom_tests__/** -**/__mocks__/** diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 7bfa4acb2b..0000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,576 +0,0 @@ -/** - * 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. - * - * @noflow - */ -'use strict'; - -/* eslint - comma-dangle: [1, always-multiline], - prefer-object-spread/prefer-object-spread: 0, - nuclide-internal/no-commonjs: 0, - */ -/* eslint-disable max-len */ - -module.exports = { - root: true, - - parser: 'babel-eslint', - - parserOptions: { - ecmaVersion: 7, - sourceType: 'module', - ecmaFeatures: { - globalReturn: true, - jsx: true, - experimentalObjectRestSpread: true, - }, - }, - - // https://github.com/sindresorhus/globals/blob/master/globals.json - env: { - atomtest: true, - es6: true, - jasmine: true, - jest: true, - node: true, - }, - - extends: ['plugin:jsx-a11y/recommended'], - - globals: { - atom: false, - document: false, - window: false, - }, - - rules: { - // Possible Errors (http://eslint.org/docs/rules/#possible-errors) - 'no-await-in-loop': 1, - 'no-cond-assign': 1, - 'no-console': 1, - 'no-constant-condition': [1, {checkLoops: false}], - 'no-control-regex': 1, - 'no-debugger': 1, - 'no-dupe-args': 1, - 'no-dupe-keys': 1, - 'no-duplicate-case': 1, - 'no-empty-character-class': 1, - 'no-empty': [1, {allowEmptyCatch: true}], - 'no-ex-assign': 1, - 'no-extra-boolean-cast': 0, // Flow actually requires us to cast to avoid sketchy null checks. - 'no-extra-parens': 0, - 'no-extra-semi': 1, - 'no-func-assign': 1, - 'no-inner-declarations': 1, - 'no-invalid-regexp': 1, - 'no-irregular-whitespace': 1, - 'no-obj-calls': 1, - 'no-prototype-builtins': 0, - 'no-regex-spaces': 1, - 'no-sparse-arrays': 1, - 'no-template-curly-in-string': 0, - 'no-unexpected-multiline': 1, - 'no-unreachable': 1, - 'no-unsafe-finally': 1, - 'no-unsafe-negation': 1, - 'use-isnan': 1, - 'valid-jsdoc': 0, - 'valid-typeof': 1, - - // Best Practices (http://eslint.org/docs/rules/#best-practices) - 'accessor-pairs': 1, - 'array-callback-return': 0, - 'block-scoped-var': 0, - 'class-methods-use-this': 0, - complexity: 0, - 'consistent-return': 0, - curly: 1, - 'default-case': 0, - 'dot-location': [1, 'property'], - 'dot-notation': 1, - eqeqeq: [1, 'always', {null: 'never'}], - 'getter-return': 2, - 'guard-for-in': 0, - 'no-alert': 0, - 'no-caller': 1, - 'no-case-declarations': 0, - 'no-div-regex': 1, - 'no-else-return': 0, - 'no-empty-function': 0, - 'no-empty-pattern': 1, - 'no-eq-null': 0, - 'no-eval': 1, - 'no-extend-native': 1, - 'no-extra-bind': 1, - 'no-extra-label': 1, - 'no-fallthrough': 1, - 'no-floating-decimal': 1, - 'no-global-assign': 1, - 'no-implicit-coercion': 1, - 'no-implicit-globals': 0, - 'no-implied-eval': 1, - 'no-invalid-this': 0, - 'no-iterator': 1, - 'no-labels': 1, - 'no-lone-blocks': 1, - 'no-loop-func': 0, - 'no-magic-numbers': 0, - 'no-multi-spaces': 1, - 'no-multi-str': 0, - 'no-new-func': 1, - 'no-new-wrappers': 1, - 'no-new': 1, - 'no-octal-escape': 1, - 'no-octal': 1, - 'no-param-reassign': 1, - 'no-proto': 1, - 'no-redeclare': [1, {builtinGlobals: true}], - 'no-restricted-properties': 0, - 'no-return-assign': 1, - 'no-return-await': 1, - 'no-script-url': 1, - 'no-self-assign': 1, - 'no-self-compare': 1, - 'no-sequences': 1, - 'no-throw-literal': 1, - 'no-unmodified-loop-condition': 0, - 'no-unused-expressions': 0, - 'no-unused-labels': 1, - 'no-useless-call': 1, - 'no-useless-concat': 1, - 'no-useless-escape': 1, - 'no-useless-return': 0, - 'no-void': 1, - 'no-warning-comments': 0, - 'no-with': 1, - 'prefer-promise-reject-errors': 1, - radix: 1, - 'require-await': 0, - // 'require-await': 1, - 'vars-on-top': 0, - 'wrap-iife': [1, 'inside'], - yoda: 1, - - // Strict Mode (http://eslint.org/docs/rules/#strict-mode) - strict: 0, - - // Variables (http://eslint.org/docs/rules/#variables) - 'init-declarations': 0, - 'no-catch-shadow': 1, - 'no-delete-var': 1, - 'no-label-var': 1, - 'no-restricted-globals': 0, - 'no-shadow-restricted-names': 1, - 'no-shadow': 1, - 'no-undef-init': 0, - 'no-undef': 1, - 'no-undefined': 0, - 'no-unused-vars': [1, {args: 'none', ignoreRestSiblings: true}], - 'no-use-before-define': 0, - - // Node.js and CommonJS (http://eslint.org/docs/rules/#nodejs-and-commonjs) - 'callback-return': 0, - 'global-require': 0, - 'handle-callback-err': 1, - 'no-mixed-requires': 1, - 'no-new-require': 1, - 'no-path-concat': 1, - 'no-process-env': 0, - 'no-process-exit': 0, - 'no-restricted-modules': 0, - 'no-sync': 0, - - // Stylistic Issues (http://eslint.org/docs/rules/#stylistic-issues) - 'array-bracket-spacing': 1, - 'block-spacing': 1, - 'brace-style': [1, '1tbs', {allowSingleLine: true}], - camelcase: 0, - 'capitalized-comments': 0, - 'comma-dangle': 0, - 'comma-spacing': 1, - 'comma-style': 1, - 'computed-property-spacing': 1, - 'consistent-this': 0, - 'eol-last': 1, - 'func-call-spacing': 1, - 'func-name-matching': 0, - 'func-names': 0, - 'func-style': 0, - 'id-blacklist': 0, - 'id-length': 0, - 'id-match': 0, - // 'indent': [1, 2, {SwitchCase: 1}], - 'jsx-quotes': [1, 'prefer-double'], - 'key-spacing': [1, {beforeColon: false, afterColon: true}], - 'keyword-spacing': 1, - 'line-comment-position': 0, - 'linebreak-style': 1, - 'lines-between-class-members': 0, - 'lines-around-comment': 0, - 'lines-around-directive': 0, - 'max-depth': 0, - // 'max-len': [1, 100, {tabWidth: 2, ignoreUrls: true}], - 'max-lines': 0, - 'max-nested-callbacks': 0, - 'max-params': 0, - 'max-statements-per-line': 0, - 'max-statements': 0, - 'multiline-ternary': 0, - 'new-cap': 0, - 'new-parens': 1, - 'newline-after-var': 0, - 'newline-before-return': 0, - 'newline-per-chained-call': 0, - 'no-array-constructor': 1, - 'no-bitwise': 1, - 'no-continue': 0, - 'no-inline-comments': 0, - 'no-lonely-if': 0, - 'no-mixed-operators': 0, - 'no-mixed-spaces-and-tabs': 1, - 'no-multi-assign': 0, - 'no-multiple-empty-lines': [1, {max: 2, maxBOF: 0, maxEOF: 1}], - 'no-negated-condition': 0, - 'no-nested-ternary': 0, - 'no-new-object': 1, - 'no-plusplus': 0, - 'no-restricted-syntax': 0, - 'no-tabs': 1, - 'no-ternary': 0, - 'no-trailing-spaces': 1, - 'no-underscore-dangle': 0, - 'no-unneeded-ternary': 0, - 'no-whitespace-before-property': 1, - 'object-curly-newline': 0, - // 'object-curly-spacing': 1, - 'object-property-newline': 0, - 'one-var-declaration-per-line': 0, - 'one-var': [1, 'never'], - 'operator-assignment': 1, - 'operator-linebreak': 0, - 'padded-blocks': [ - 1, - {blocks: 'never', classes: 'never', switches: 'never'}, - ], - // 'quote-props': [1, 'as-needed'], - quotes: [1, 'single', 'avoid-escape'], - 'require-jsdoc': 0, - // 'semi-spacing': 1, - semi: 1, - 'sort-keys': 0, - 'sort-vars': 0, - 'space-before-blocks': 1, - 'space-before-function-paren': [ - 1, - {anonymous: 'never', named: 'never', asyncArrow: 'always'}, - ], - 'space-in-parens': [1, 'never'], - 'space-infix-ops': 1, - 'space-unary-ops': 1, - 'spaced-comment': [ - 1, - 'always', - {line: {exceptions: ['-']}, block: {balanced: true}}, - ], - 'template-tag-spacing': 1, - 'unicode-bom': [1, 'never'], - 'wrap-regex': 0, - - // ECMAScript 6 (http://eslint.org/docs/rules/#ecmascript-6) - 'arrow-body-style': 0, - 'arrow-parens': [1, 'as-needed'], - 'arrow-spacing': 1, - 'constructor-super': 1, - // 'generator-star-spacing': 1, - 'no-class-assign': 1, - 'no-confusing-arrow': 0, - 'no-const-assign': 1, - 'no-dupe-class-members': 1, - 'no-duplicate-imports': 0, - 'no-new-symbol': 1, - 'no-restricted-imports': 0, - 'no-this-before-super': 1, - 'no-useless-computed-key': 1, - 'no-useless-constructor': 0, - 'no-useless-rename': 1, - 'no-var': 1, - 'object-shorthand': 1, - 'prefer-arrow-callback': [1, {allowNamedFunctions: true}], - 'prefer-const': 1, - 'prefer-destructuring': 0, - 'prefer-numeric-literals': 0, - 'prefer-rest-params': 0, - 'prefer-spread': 1, - 'prefer-template': 0, - 'require-yield': 0, - 'rest-spread-spacing': 1, - 'sort-imports': 0, - 'symbol-description': 1, - 'template-curly-spacing': 1, - 'yield-star-spacing': 1, - - // dependencies (https://github.com/zertosh/eslint-plugin-dependencies) - 'dependencies/case-sensitive': 1, - 'dependencies/no-cycles': [0, {skip: ['/spec/', '/sample-[^/]+/']}], - 'dependencies/no-unresolved': 0, - 'dependencies/require-json-ext': 1, - - // flowtype (https://github.com/gajus/eslint-plugin-flowtype) - 'flowtype/boolean-style': 1, - 'flowtype/define-flow-type': 1, - 'flowtype/delimiter-dangle': [1, 'always-multiline'], - // 'flowtype/generic-spacing': 1, - 'flowtype/no-dupe-keys': 0, - 'flowtype/no-primitive-constructor-types': 1, - 'flowtype/no-weak-types': 0, - 'flowtype/object-type-delimiter': 0, - 'flowtype/require-parameter-type': 0, - 'flowtype/require-return-type': 0, - 'flowtype/require-valid-file-annotation': 0, - 'flowtype/require-variable-type': 0, - 'flowtype/semi': 1, - 'flowtype/sort-keys': 0, - 'flowtype/space-after-type-colon': [1, 'always', {allowLineBreak: true}], - 'flowtype/space-before-generic-bracket': 1, - 'flowtype/space-before-type-colon': 1, - 'flowtype/type-id-match': 0, - 'flowtype/union-intersection-spacing': 1, - 'flowtype/use-flow-type': 1, - 'flowtype/valid-syntax': 0, - - // Jasmine (https://github.com/tlvince/eslint-plugin-jasmine) - 'jasmine/missing-expect': 0, - 'jasmine/named-spy': 0, - 'jasmine/no-assign-spyon': 0, - 'jasmine/no-disabled-tests': 1, - 'jasmine/no-expect-in-setup-teardown': 0, - 'jasmine/no-focused-tests': 0, - 'jasmine/no-global-setup': 0, - 'jasmine/no-spec-dupes': [1, 'branch'], - 'jasmine/no-suite-callback-args': 0, - 'jasmine/no-suite-dupes': [1, 'branch'], - 'jasmine/no-unsafe-spy': 0, - 'jasmine/valid-expect': 0, - - // nuclide-internal (https://github.com/facebook/nuclide/tree/master/modules/eslint-plugin-nuclide-internal) - 'nuclide-internal/api-spelling': 1, - 'nuclide-internal/atom-apis': 1, - 'nuclide-internal/consistent-import-name': 1, - 'nuclide-internal/disallowed-modules': 1, - 'nuclide-internal/dom-apis': 1, - 'nuclide-internal/flow-fb-oss': 1, - 'nuclide-internal/import-type-style': 1, - 'nuclide-internal/jsx-simple-callback-refs': 1, - 'nuclide-internal/license-header': 1, - 'nuclide-internal/modules-dependencies': 1, - 'nuclide-internal/no-cross-atom-imports': [1, {whitelist: ['nuclide-ui']}], - 'nuclide-internal/no-unnecessary-disposable-wrapping': 1, - 'nuclide-internal/no-unresolved': 1, - 'nuclide-internal/prefer-nuclide-uri': 1, - 'nuclide-internal/react-virtualized-import': 1, - 'nuclide-internal/require-universal-disposable': 1, - 'nuclide-internal/use-nuclide-ui-components': 1, - 'nuclide-internal/no-commonjs': 1, - - // prefer-object-spread (https://github.com/bryanrsmith/eslint-plugin-prefer-object-spread) - 'prefer-object-spread/prefer-object-spread': 1, - - // prettier (https://github.com/prettier/eslint-plugin-prettier) - 'prettier/prettier': [1, 'fb', '@format'], - - // React (https://github.com/yannickcr/eslint-plugin-react) - 'react/display-name': 0, - 'react/forbid-component-props:': 0, - 'react/forbid-prop-types': 1, - 'react/no-array-index-key': 0, - 'react/no-children-prop': 0, - 'react/no-danger': 0, - 'react/no-danger-with-children': 0, - 'react/no-deprecated': 1, - 'react/no-did-mount-set-state': 0, - 'react/no-did-update-set-state': 0, - 'react/no-direct-mutation-state': 1, - 'react/no-find-dom-node': 0, - 'react/no-is-mounted': 0, - 'react/no-multi-comp': 0, - 'react/no-render-return-value': 0, - 'react/no-set-state': 0, - - // String refs don't work correctly if multiple versions of React are at play. - 'react/no-string-refs': 1, - - 'react/no-unescaped-entities': 0, - 'react/no-unknown-property': 1, - 'react/no-unused-prop-types': 1, - 'react/no-unused-state': 1, - 'react/prefer-es6-class': 0, - 'react/prefer-stateless-function': 0, - // 'react/prefer-stateless-function': 1, - // 'react/prop-types': 1, - 'react/react-in-jsx-scope': 1, - 'react/require-default-props': 0, - 'react/require-optimization': 0, - 'react/require-render-return': 0, - 'react/self-closing-comp': 1, - 'react/sort-comp': 0, - 'react/sort-prop-types': 0, - 'react/style-prop-object': 0, - 'react/jsx-boolean-value': 0, - 'react/jsx-closing-bracket-location': [ - 1, - {selfClosing: 'tag-aligned', nonEmpty: 'after-props'}, - ], - // 'react/jsx-curly-spacing': [1, 'never'], - 'react/jsx-equals-spacing': 0, - 'react/jsx-filename-extension': 0, - 'react/jsx-first-prop-new-line': 0, - 'react/jsx-handler-names': 0, - 'react/jsx-indent': 0, - 'react/jsx-indent-props': 0, - 'react/jsx-key': 1, - 'react/jsx-max-props-per-line': 0, - 'react/jsx-no-bind': 0, - // 'react/jsx-no-bind': 1, - 'react/jsx-no-comment-textnodes': 1, - 'react/jsx-no-duplicate-props': 1, - 'react/jsx-no-literals': 0, - 'react/jsx-no-target-blank': 0, - 'react/jsx-no-undef': 1, - 'react/jsx-pascal-case': 0, - 'react/jsx-sort-props': 0, - 'react/jsx-tag-spacing': 1, - 'react/jsx-uses-react': 1, - 'react/jsx-uses-vars': 1, - 'react/jxs-wrap-multilines': 0, - - // JSX Accessibility checks - // some currently disabled to adopt incrementally, annotated 'incremental' - 'jsx-a11y/accessible-emoji': 0, - 'jsx-a11y/alt-text': 0, // incremental: error - 'jsx-a11y/anchor-has-content': 0, - 'jsx-a11y/anchor-is-valid': 0, // incremental: error - 'jsx-a11y/aria-activedescendant-has-tabindex': 0, - 'jsx-a11y/aria-props': 1, - 'jsx-a11y/aria-proptypes': 0, - 'jsx-a11y/aria-role': 0, - 'jsx-a11y/aria-unsupported-elements': 0, - 'jsx-a11y/click-events-have-key-events': 0, - 'jsx-a11y/heading-has-content': 0, - 'jsx-a11y/href-no-hash': 0, - 'jsx-a11y/html-has-lang': 0, - 'jsx-a11y/iframe-has-title': 0, - 'jsx-a11y/img-has-alt': 0, - 'jsx-a11y/img-redundant-alt': 0, - 'jsx-a11y/interactive-supports-focus': [ - 1, - { - tabbable: [ - 'button', - 'checkbox', - 'link', - 'searchbox', - 'spinbutton', - 'switch', - 'textbox', - ], - }, - ], - 'jsx-a11y/label-has-for': 0, - 'jsx-a11y/lang': 0, - 'jsx-a11y/mouse-events-have-key-events': 0, - 'jsx-a11y/no-access-key': 0, - 'jsx-a11y/no-autofocus': 0, - 'jsx-a11y/no-distracting-elements': 0, - 'jsx-a11y/no-interactive-element-to-noninteractive-role': [ - 1, - { - tr: ['none', 'presentation'], - }, - ], - 'jsx-a11y/no-noninteractive-element-interactions': [ - 0, // incremental: warning - { - handlers: ['onClick'], - }, - ], - 'jsx-a11y/no-noninteractive-element-to-interactive-role': [ - 1, - { - ul: [ - 'listbox', - 'menu', - 'menubar', - 'radiogroup', - 'tablist', - 'tree', - 'treegrid', - ], - ol: [ - 'listbox', - 'menu', - 'menubar', - 'radiogroup', - 'tablist', - 'tree', - 'treegrid', - ], - li: ['menuitem', 'option', 'row', 'tab', 'treeitem'], - table: ['grid'], - td: ['gridcell'], - }, - ], - 'jsx-a11y/no-noninteractive-tabindex': 0, // incremental: error - 'jsx-a11y/no-onchange': 0, - 'jsx-a11y/no-redundant-roles': 0, - 'jsx-a11y/no-static-element-interactions': [ - 0, // incremental: warning - { - handlers: ['onClick'], - }, - ], - 'jsx-a11y/role-has-required-aria-props': 0, - 'jsx-a11y/role-supports-aria-props': 0, - 'jsx-a11y/scope': 0, - 'jsx-a11y/tabindex-no-positive': 0, - - 'unicorn/catch-error-name': 0, - 'unicorn/explicit-length-check': 0, - 'unicorn/filename-case': 0, - 'unicorn/no-abusive-eslint-disable': 0, - 'unicorn/no-process-exit': 0, - 'unicorn/throw-new-error': 2, - 'unicorn/number-literal-case': 0, - 'unicorn/escape-case': 0, - 'unicorn/no-array-instanceof': 0, - 'unicorn/no-new-buffer': 0, - 'unicorn/no-hex-escape': 0, - 'unicorn/custom-error-definition': 0, - 'unicorn/prefer-starts-ends-with': 0, - 'unicorn/prefer-type-error': 0, - 'unicorn/no-fn-reference-in-iterator': 0, - 'unicorn/import-index': 0, - 'unicorn/new-for-builtins': 0, - 'unicorn/regex-shorthand': 0, - 'unicorn/prefer-spread': 0, - 'unicorn/error-message': 0, - 'unicorn/no-unsafe-regex': 0, - 'unicorn/prefer-add-event-listener': 0, - }, - - plugins: [ - 'dependencies', - 'flowtype', - 'jasmine', - 'jsx-a11y', - 'prefer-object-spread', - 'prettier', - 'react', - 'nuclide-internal', - 'unicorn', - ], -}; diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 7da1f9608e..0000000000 --- a/.flake8 +++ /dev/null @@ -1,2 +0,0 @@ -[flake8] -max-line-length = 100 diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index 5def53f983..0000000000 --- a/.flowconfig +++ /dev/null @@ -1,54 +0,0 @@ -[include] - -[ignore] -; ignore module source to prefer declaration -/node_modules/classnames/.* -/node_modules/lru-cache/.* -/node_modules/prop-types/.* -/node_modules/react/.* -/node_modules/rxjs/.* -/node_modules/semver/.* -/node_modules/jest-validate/.* -; TODO(T28589014): re-enable flow typing of graphql module -/node_modules/graphql/.* -/node_modules/graphql-language-service/.* -/node_modules/graphql-language-service-utils/.* -/node_modules/graphql-language-service-types/.* -; annotated with `@flow` but have errors -/node_modules/\(.*/\)*fbjs/lib/.* -/modules/nuclide-node-transpiler/spec/fixtures/.* -; large dirs that are not imported -/docs/.* - -[libs] -flow-libs/ - -[options] -emoji=true -experimental.const_params=true -module.use_strict=true -module.system.node.resolve_dirname=node_modules - -suppress_comment=.*\\$FlowFixMe.* -suppress_comment=.*\\$FlowIssue.* -suppress_comment=.*\\$FlowIgnore.* -; uncommenting the next line will silence flow errors about missing 'fb' modules -; suppress_comment=.*\\$FlowFB.* - -[lints] -untyped-type-import=error - -sketchy-null=error -sketchy-null-bool=off - -[strict] -deprecated-type -nonstrict-import -sketchy-null -unclear-type -unsafe-getters-setters -untyped-import -untyped-type-import - -[version] -0.73.0 diff --git a/.gitignore b/.gitignore index c91e4842f8..b578e79b96 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,39 @@ npm-debug.log* /docs/Gemfile.lock /modules/jest-atom-runner/build + + +######################################################## +### !!!AUTO GENERATED by "prepare_apm_release.js"!!! ### +######################################################## + +# "apm" doesn't honor ".npmignore" files. As a workaround, we merge the +# ".npmignore" content into ".gitignore": +/.eslintignore +/.eslintrc.js +/.flake8 +/.flowconfig +/CONTRIBUTING.md +/ISSUE_TEMPLATE.md +/circle.yml +/docs +/flow-libs +/flow-typed +/pkg/dev-* +/pkg/sample-* +/resources/benchmarker +/resources/nuclicons +/scripts +DEVELOPMENT +spec + +# Ignore "BUCK" files, but not "buck/" directories. +# Note: These rules get inlined into ".gitignore" for apm publishing, git will +# ignore "buck/" directories without this exclusion on case-insensitive Macs. +BUCK +!buck/ + +/pkg/fb-java-rpc/**/*.java +/pkg/fb-java-rpc/.idea +/pkg/fb-java-rpc/*.iml + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 3a90661442..0000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,63 +0,0 @@ -# Contributing to Nuclide -We want to make contributing to this project as easy and transparent as -possible. The -[Nuclide license](https://github.com/facebook/nuclide/blob/master/LICENSE) has -certain limitations around distribution. However, this does not affect your -ability to fork the project and make contributions. - -## Code of Conduct - -Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](https://code.facebook.com/pages/876921332402685/open-source-code-of-conduct) so that you can understand what actions will and will not be tolerated. - -## Our Development Process -Nuclide is currently developed in Facebook's internal repositories and then -exported out to GitHub by a Facebook team member. We invite you to submit pull -requests directly to GitHub and, after review, these can be merged into the -project. - -## Getting Started - -Follow this guide to start developing on Nuclide: -https://nuclide.io/docs/advanced-topics/building-from-source/ - -## atom-ide-ui - -atom-ide-ui should be developed in its own repository - see the [CONTRIBUTING.md]( -https://github.com/facebook-atom/atom-ide-ui/blob/master/CONTRIBUTING.md) -guide in https://github.com/facebook-atom/atom-ide-ui. - -## Pull Requests - -1. Fork the repo and create your branch from `master` for core changes, or -`gh-pages` for docs and website changes. -2. If you've added code that should be tested, [add tests](https://github.com/facebook/nuclide/wiki/Tips-for-Testing#writing-tests). -3. If you've changed APIs, update the documentation. -4. Ensure the test suite passes by [running `scripts/test`, or run the affected tests individually](https://github.com/facebook/nuclide/wiki/Tips-for-Testing#running-tests). -5. Make sure your JavaScript code lints by using Flow. -6. If you haven't already, complete the Contributor License Agreement ("CLA"). - -## Contributor License Agreement ("CLA") -In order to accept your pull request, we need you to submit a CLA. You only need -to do this once to work on Nuclide and on Facebook's open source projects. - -Complete your CLA here: - -## Issues -We use GitHub issues to track public bugs. Please ensure your description is -clear and has sufficient instructions to be able to reproduce the issue. - -Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe -disclosure of security bugs. In those cases, please go through the process -outlined on that page and do not file a public issue. - -## Coding Style -* Spaces for indentation rather than tabs - 2 for JavaScript, 4 for Python -* 100 character line length -* See the [project wiki](https://github.com/facebook/nuclide/wiki) for coding -practices and development tips. - -## License -By contributing to Nuclide, you agree that your contributions will be licensed -under the license outlined in the LICENSE file in the same directory as this -file. Due to certain limitations on distribution, this should not be considered -an [open source license](https://opensource.org/licenses/alphabetical). diff --git a/DEVELOPMENT b/DEVELOPMENT deleted file mode 100644 index 0c2e324251..0000000000 --- a/DEVELOPMENT +++ /dev/null @@ -1,3 +0,0 @@ -The existence of this file is used to denote that Nuclide is running from source. - -This file is *not* in `.npmignore` because the transpile script should delete it instead. diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md deleted file mode 100644 index 0d1fbb5532..0000000000 --- a/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,17 +0,0 @@ -### Issue and Steps to Reproduce -Describe your issue and tell us how to reproduce it (include screenshots and/or any console messages). - -### Expected Behavior -Tell us what should happen. - -### Actual Behavior -Tell us what happens instead. - -### Versions -* Atom: -* Nuclide: -* Client OS: -* Server OS (optional): - -### Additional Details -* Installed packages (`apm ls --installed`): diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 7513370f3a..0000000000 --- a/circle.yml +++ /dev/null @@ -1,51 +0,0 @@ -machine: - environment: - PATH: "${PATH}:${HOME}/${CIRCLE_PROJECT_REPONAME}/node_modules/.bin" - # The prettier ESLint plugin is problematic in Node v7. - ESLINT_NODE_VERSION: "9.11.1" - node: - version: 7.9.0 - -dependencies: - override: - - yarn - cache_directories: - - ~/.cache/yarn - -test: - override: - # Do not run tests for releases. - - | - # eslint - if [[ "$CIRCLE_BRANCH" != "release-v"* && -z "$CIRCLE_TAG" ]]; then - nvm install "$ESLINT_NODE_VERSION" - node -v - ./node_modules/.bin/eslint --max-warnings=0 . - # Restore default node version. - nvm use 7.9.0 - fi - - | - # flow - if [[ "$CIRCLE_BRANCH" != "release-v"* && -z "$CIRCLE_TAG" ]]; then - sed -i.tmp -e 's/^; \(suppress_comment=.*FlowFB.*\)$/\1/' .flowconfig - ./node_modules/.bin/flow check --show-all-errors - fi - -deployment: - release: - branch: /^release-v[0-9]+\.[0-9]+\.[0-9]+$/ - owner: facebook - commands: - - ./scripts/oss-publish.sh - modules: - tag: /modules-v.*/ - owner: facebook - commands: - - bash -x ./scripts/modules-publish.sh - -experimental: - notify: - branches: - only: - - master - - /^release-v[0-9]+\.[0-9]+\.[0-9]+$/ diff --git a/docs/CNAME b/docs/CNAME deleted file mode 100644 index 825146408a..0000000000 --- a/docs/CNAME +++ /dev/null @@ -1 +0,0 @@ -nuclide.io diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md deleted file mode 100644 index ac8e316a7c..0000000000 --- a/docs/CONTRIBUTING.md +++ /dev/null @@ -1,115 +0,0 @@ -This provides guidance on how to contribute various content to `nuclide.io`. - -## Getting started - -You should only have to do these one time. - -- Rename this file to `CONTRIBUTING.md`. -- Rename `EXAMPLE-README-FOR-RUNNING-DOCS.md` to `README.md` (replacing the existing `README.md` that came with the template). -- Rename `EXAMPLE-LICENSE` to `LICENSE`. -- Checkout the [template information](./TEMPLATE-INFORMATION.md). -- Review `./_config.yml`. -- Make sure you update `title`, `description`, `tagline` and `gacode` (Google Analytics) in `./_config.yml`. - -## Basic Structure - -Most content is written in markdown. You name the file `something.md`, then have a header that looks like this: - -``` ---- -pageid: getting-started -title: Getting started with ProjectName -layout: docs -permalink: /docs/getting-started.html ---- -``` - -Customize these values for each document, blog post, etc. - -> The filename of the `.md` file doesn't actually matter; what is important is the `pageid` being unique and the `permalink` correct and unique too). - -## Landing page - -Modify `index.md` with your new or updated content. - -If you want a `GridBlock` as part of your content, you can do so directly with HTML: - -``` -
-
-
-

Your Features

- -
-
- -
-
-

More information

-

- Stuff here -

-
-
-
-``` - -or with a combination of changing `./_data/features.yml` and adding some Liquid to `index.md`, such as: - -``` -{% include content/gridblocks.html data_source=site.data.features imagealign="bottom"%} -``` - -## Blog - -To modify a blog post, edit the appropriate markdown file in `./_posts/`. - -Adding a new blog post is a four-step process. - -> Some posts have a `permalink` and `comments` in the blog post YAML header. You will not need these for new blog posts. These are an artifact of migrating the blog from Wordpress to gh-pages. - -1. Create your blog post in `./_posts/` in markdown (file extension `.md` or `.markdown`). See current posts in that folder or `./doc-type-examples/2016-04-07-blog-post-example.md` for an example of the YAML format. **If the `./_posts` directory does not exist, create it**. - - You can add a `` tag in the middle of your post such that you show only the excerpt above that tag in the main `/blog` index on your page. -1. If you have not authored a blog post before, modify the `./_data/authors.yml` file with the `author` id you used in your blog post, along with your full name and Facebook ID to get your profile picture. -1. [Run the site locally](./README.md) to test your changes. It will be at `http://127.0.0.1/blog/your-new-blog-post-title.html` -1. Push your changes to GitHub. - -## Docs - -To modify docs, edit the appropriate markdown file in `./_docs/`. - -To add docs to the site.... - -1. Add your markdown file to the `./_docs/` folder. See `./doc-type-examples/docs-hello-world.md` for an example of the YAML header format. **If the `./_docs/` directory does not exist, create it**. - - You can use folders in the `./_docs/` directory to organize your content if you want. -1. Update `_data/nav_docs.yml` to add your new document to the navigation bar. Use the `pageid` you put in your doc markdown in as the `id` in the `_data/nav_docs.yml` file. -1. [Run the site locally](./README.md) to test your changes. It will be at `http://127.0.0.1/docs/your-new-doc-permalink.html` -1. Push your changes to GitHub. - -## Header Bar - -To modify the header bar, change `./_data/nav.yml`. - -## Top Level Page - -To modify a top-level page, edit the appropriate markdown file in `./top-level/` - -If you want a top-level page (e.g., http://your-site.com/top-level.html) -- not in `/blog/` or `/docs/`.... - -1. Create a markdown file in the root `./top-level/`. See `./doc-type-examples/top-level-example.md` for more information. -1. If you want a visible link to that file, update `_data/nav.yml` to add a link to your new top-level document in the header bar. - - > This is not necessary if you just want to have a page that is linked to from another page, but not exposed as direct link to the user. - -1. [Run the site locally](./README.md) to test your changes. It will be at `http://127.0.0.1/your-top-level-page-permalink.html` -1. Push your changes to GitHub. - -## Other Changes - -- CSS: `./css/main.css` or `./_sass/*.scss`. -- Images: `./static/images/[docs | posts]/....` -- Main Blog post HTML: `./_includes/post.html` -- Main Docs HTML: `./_includes/doc.html` diff --git a/docs/Gemfile b/docs/Gemfile deleted file mode 100644 index aed0323a1b..0000000000 --- a/docs/Gemfile +++ /dev/null @@ -1,3 +0,0 @@ -source 'https://rubygems.org' - -gem 'github-pages', '~> 104', group: :jekyll_plugins diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index ceea4852e0..0000000000 --- a/docs/README.md +++ /dev/null @@ -1,84 +0,0 @@ -## User Documentation for nuclide.io - -This directory will contain the user and feature documentation for Nuclide. The documentation will be hosted on GitHub pages. - -### Contributing - -See [CONTRIBUTING.md](./CONTRIBUTING.md) for details on how to add or modify content. - -### Run the Site Locally - -The requirements for running a GitHub pages site locally is described in [GitHub help](https://help.github.com/articles/setting-up-your-github-pages-site-locally-with-jekyll/#requirements). The steps below summarize these steps. - -> If you have run the site before, you can start with step 1 and then move on to step 5. - -1. Ensure that you are in the same directory where this `README.md` and the `Gemfile` file exists (e.g., it could be in `nuclide/docs` on `master`, in the root of a `gh-pages` branch, etc). The below RubyGems commands, etc. must be run from there. - -1. Make sure you have Ruby and [RubyGems](https://rubygems.org/) installed. - - > Ruby >= 2.2 is required for the gems. On the latest versions of Mac OS X, Ruby 2.0 is the - > default. Use [Homebrew](http://brew.sh) and the `brew install ruby` command (or your - > preferred upgrade mechanism) to install a newer version of Ruby for your Mac OS X system. - -1. Make sure you have [Bundler](http://bundler.io/) installed. - - ``` - # may require sudo - gem install bundler - ``` - -1. Install the project's dependencies - - ``` - # run this in the directory containing the "Gemfile" file. - bundle install - ``` - - > If you get an error when installing `nokogiri`, you may be running into the problem described - > in [this nokogiri issue](https://github.com/sparklemotion/nokogiri/issues/1483). You can - > either `brew uninstall xz` (and then `brew install xz` after the bundle is installed) or - > `xcode-select --install` (although this may not work if you have already installed command - > line tools). - -1. Run Jekyll's server. - - - On first runs or for structural changes to the documentation (e.g., new sidebar menu item), do a full build. - - ``` - # run this in the directory containing the "Gemfile" file - bundle exec jekyll serve - ``` - - - For content changes only, you can use `--incremental` for faster builds. - - ``` - bundle exec jekyll serve --incremental - ``` - - > We use `bundle exec` instead of running straight `jekyll` because `bundle exec` will always use the version of Jekyll from our `Gemfile`. Just running `jekyll` will use the system version and may not necessarily be compatible. - - - To run using an actual IP address, you can use `--host=0.0.0.0` - - ``` - # run this in the directory containing the "Gemfile" file - bundle exec jekyll serve --host=0.0.0.0 - ``` - - This will allow you to use the IP address associated with your machine in the URL. That way you could share it with other people. - - e.g., on a Mac, you can your IP address with something like `ifconfig | grep "inet " | grep -v 127.0.0.1`. - -1. Either of commands in the previous step will serve up the site on your local device at http://127.0.0.1:4000/ or http://localhost:4000. - -### Updating the Bundle - -The site depends on Github Pages and the installed bundle is based on the `github-pages` gem. -Occasionally that gem might get updated with new or changed functionality. If that is the case, -you can run: - -``` -# run this in the directory containing the "Gemfile" file -bundle update -``` - -to get the latest packages for the installation. diff --git a/docs/TEMPLATE-INFORMATION.md b/docs/TEMPLATE-INFORMATION.md deleted file mode 100644 index 9175bc0c29..0000000000 --- a/docs/TEMPLATE-INFORMATION.md +++ /dev/null @@ -1,17 +0,0 @@ -## Template Details - -First, go through `_config.yml` and adjust the available settings to your project's standard. When you make changes here, you'll have to kill the `jekyll serve` instance and restart it to see those changes, but that's only the case with the config file. - -Next, update some image assets - you'll want to update `favicon.png`, `logo.svg`, and `og_image.png` (used for Like button stories and Shares on Facbeook) in the `static` folder with your own logos. - -Next, if you're going to have docs on your site, keep the `_docs` and `docs` folders, if not, you can safely remove them (or you can safely leave them and not include them in your navigation - Jekyll renders all of this before a client views the site anyway, so there's no performance hit from just leaving it there for a future expansion). - -Same thing with a blog section, either keep or delete the `_posts` and `blog` folders. - -You can customize your homepage in three parts - the first in the homepage header, which is mostly automatically derived from the elements you insert into your config file. However, you can also specify a series of 'promotional' elements in `_data/promo.yml`. You can read that file for more information. - -The second place for your homepage is in `index.md` which contains the bulk of the main content below the header. This is all markdown if you want, but you can use HTML and Jekyll's template tags (called Liquid) in there too. Checkout this folder's index.md for an example of one common template tag that we use on our sites called gridblocks. - -The third and last place is in the `_data/powered_by.yml` and `_data/powered_by_highlight.yml` files. Both these files combine to create a section on the homepage that is intended to show a list of companies or apps that are using your project. The `powered_by_highlight` file is a list of curated companies/apps that you want to show as a highlight at the top of this section, including their logos in whatever format you want. The `powered_by` file is a more open list that is just text links to the companies/apps and can be updated via Pull Request by the community. If you don't want these sections on your homepage, just empty out both files and leave them blank. - -The last thing you'll want to do is setup your top level navigation bar. You can do this by editing `nav.yml` and keeping the existing title/href/category structure used there. Although the nav is responsive and fairly flexible design-wise, no more than 5 or 6 nav items is recommended. diff --git a/docs/_config.yml b/docs/_config.yml deleted file mode 100644 index 0386252b1c..0000000000 --- a/docs/_config.yml +++ /dev/null @@ -1,99 +0,0 @@ -# Site settings -permalink: /blog/:year/:month/:day/:title/ -title: Nuclide -tagline: A unified developer experience for software development -fbappid: "" -gacode: "UA-44373548-2" -description: > - Nuclide is built as a single package on top of Atom to provide hackability and the support of an active community. - - It provides a first-class development environment for React Native, Hack and Flow projects. -logo: /static/og_image.png - -# baseurl determines the subpath of your site. For example if you're using an -# organisation.github.io/reponame/ basic site URL, then baseurl would be set -# as "/reponame". If you have a top-level domain URL, you can set it to "" or -# leave blank as it is now set to "" by default as discussed in: -# http://jekyllrb.com/news/2016/10/06/jekyll-3-3-is-here/ - -# the base hostname & protocol for your site -# If baseurl is set, then the absolute url for your site would be url/baseurl -# This was also be set to the right thing automatically for local development -# https://github.com/blog/2277-what-s-new-in-github-pages-with-jekyll-3-3 -# http://jekyllrb.com/news/2016/10/06/jekyll-3-3-is-here/ -url: "https://nuclide.io" - -# Note: There are new filters in Jekyll 3.3 to help with absolute and relative urls -# absolute_url -# relative_url -# So you will see these used throughout the Jekyll code in this template. -# no more need for | prepend: site.url | prepend: site.baseurl -# http://jekyllrb.com/news/2016/10/06/jekyll-3-3-is-here/ -# https://github.com/blog/2277-what-s-new-in-github-pages-with-jekyll-3-3 - -# The GitHub repo for your project -ghrepo: "facebook/nuclide" - -# Build settings -# Github pages now only supports Kramdown and Rouge -# https://github.com/blog/2100-github-pages-now-faster-and-simpler-with-jekyll-3-0 -# So no need to be explicit with respect to our markdown and highlighter settings since they -# cannot change. -# kramdown also automatically generates header ID's too. But we remove any auto id suffix -# in a post processing step (js/jekyll-link-anchors.js) to make the links more readable. - -# For local development and testing, explicitly set kramdown settings that GitHub does -# https://help.github.com/articles/using-jekyll-with-pages/#defaults-you-can-change -kramdown: - input: GFM - hard_wrap: false - -# Blog posts are built into to Jekyll by default, with the `_posts` directory. -# Here you can specify other types of documentation. The names here are `docs` -# and `top-level`. This means their content will be in `_docs` and `_top-level`. -# The permalink format is also given. -# http://ben.balter.com/2015/02/20/jekyll-collections/ -collections: - docs: - output: true - permalink: /docs/:name/ - top-level: - output: true - permalink: /:name/ - -sass: - style: :compressed - -color: - # Provides colour for background of top header of homepage - primary: "#2F0F56" - # Provides colour for background of elsewhere on site - secondary: "#e4e4e4" - # A color that will work for buttons laid on top of primary colour - light: "#9B4DCA" - # Color that will work for text on top of light color - lighttext: "#fff" - # Color of text in the top header of homepage, must be legible on top of primary color - headertext: "#fff" - # Color of text on top of the secondary color background - bodytext: "#151515" - # Background of fixed nav header - headertext color is used for mini logo text - nav: "#4A148C" - # Text of links in the nav - navtext: "#c79aff" - # Color of link underlines in the main body, and hover background color for links - link: "#6223b0" - -# RSS Feed -gems: - - jekyll-feed - - jekyll-seo-tag - - jekyll-sitemap - -# Set default open graph image for all pages -defaults: - - - scope: - path: "" - values: - image: /static/og_image.png diff --git a/docs/_data/authors.yml b/docs/_data/authors.yml deleted file mode 100644 index 80182f2fc5..0000000000 --- a/docs/_data/authors.yml +++ /dev/null @@ -1,12 +0,0 @@ -zertosh: - full_name: Andres Suarez - fbid: 18700343 -matthewwithanm: - full_name: Matthew Dapena-Tretter - fbid: 100002839212206 -a20012251: - full_name: Walter Erquinigo - fbid: 750002794 -hansonw: - full_name: Hanson Wang - fbid: 505887506 diff --git a/docs/_data/features.yml b/docs/_data/features.yml deleted file mode 100644 index 81d5f2a52f..0000000000 --- a/docs/_data/features.yml +++ /dev/null @@ -1,47 +0,0 @@ -- title: Built-in Debugging - text: | - Building upon Chrome Developer Tools, Nuclide has first class debugging support for React - Native, Hack (shown here), Flow and other platforms. \\ - [**Read More**](/docs/features/debugger) - image: images/docs/promo-debugger.png - -- title: Remote Development - text: | - Connect to your remote servers, and get full access to the file tree within Nuclide. \\ - [**Get Started**](/docs/features/remote/) - image: images/docs/promo-remote-development.png - -- title: Developing JavaScript - text: | - Improve the quality of your JavaScript with built in support for [Flow](http://flowtype.org), - including autocomplete, jump-to-definition, and inline errors. \\ - [**Read More**](/docs/languages/flow/) - image: images/docs/promo-flow.png - -- title: Developing Hack - text: | - Nuclide is the first IDE with support for Hack, including autocomplete, jump-to-definition, - inline errors, and an omni-search bar for your project. \\ - [**Read More**](/docs/languages/hack/) - image: images/docs/promo-hack.png - -- title: Task Runner - text: | - Nuclide's Task Runner is a tool for building, running, testing, and debugging your Buck, Hack, and Swift projects. \\ - [**Read More**](/docs/features/task-runner/) - image: images/docs/promo-task-runner.png - -- title: Working Sets - text: | - Is your project big, but only a small subset applies to your work? Working Sets can reduce - noise. \\ - [**Read More**](/docs/features/working-sets/) - image: images/docs/promo-working-sets.png - -- title: Mercurial Support - text: | - Local changes to files in a Mercurial repo will be reflected in Atom's file tree and UI, as - Atom does natively for Git repos. \\ - [**Read More**](/docs/features/hg/) - image: images/docs/promo-mercurial.png - center: true diff --git a/docs/_data/nav.yml b/docs/_data/nav.yml deleted file mode 100644 index 4fc9bd2cd1..0000000000 --- a/docs/_data/nav.yml +++ /dev/null @@ -1,18 +0,0 @@ -- title: Docs - href: /docs/ - category: docs - -- title: Blog - href: /blog/ - category: blog - -- title: Support - href: /support/ - category: support - -- title: GitHub - href: https://github.com/facebook/nuclide - category: external - -# Use external for external links not associated with the paths of the current site. -# If a category is external, site urls, for example, are not prepended to the href, etc. diff --git a/docs/_data/nav_docs.yml b/docs/_data/nav_docs.yml deleted file mode 100644 index da077fbad5..0000000000 --- a/docs/_data/nav_docs.yml +++ /dev/null @@ -1,49 +0,0 @@ -- title: Quick Start - items: - - id: quick-start-getting-started - - id: editor-basics -- title: About - items: - - id: editor-setup - - id: editor-keyboard-shortcuts - - id: editor-uninstall - - id: help-faq - - id: help-troubleshooting -- title: Feature Guides - items: - - id: feature-remote - - id: feature-debugger - - id: feature-task-runner - - id: feature-quick-open - - id: feature-working-sets - - id: feature-outline-view - - id: feature-context-view - - id: feature-health - - id: feature-terminal -- title: Plugins - items: - - id: feature-hg - - id: feature-toolbar - - id: feature-buck - - id: feature-format-js -- title: Languages - items: - - id: language-hack - - id: language-flow - - id: language-objective-c - - id: language-cpp - - id: language-python - - id: language-swift - - id: language-graphql - - id: language-other -- title: Platforms - items: - - id: platform-ios - - id: platform-android - - id: platform-react-native - - id: platform-web -- title: Advanced Topics - items: - - id: advanced-building-from-source - - id: advanced-custom-keybindings - - id: advanced-linter-package-compatibility diff --git a/docs/_data/promo.yml b/docs/_data/promo.yml deleted file mode 100644 index 011321542f..0000000000 --- a/docs/_data/promo.yml +++ /dev/null @@ -1,12 +0,0 @@ -- type: button - href: docs/quick-start/getting-started/ - text: Getting Started -- type: button - href: docs/platforms/react-native/ - text: React Native -- type: button - href: docs/platforms/ios/ - text: iOS -- type: button - href: docs/platforms/web/ - text: Web diff --git a/docs/_docs/advanced-topics/building-from-source.md b/docs/_docs/advanced-topics/building-from-source.md deleted file mode 100644 index 26c925d758..0000000000 --- a/docs/_docs/advanced-topics/building-from-source.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -pageid: advanced-building-from-source -title: Building Nuclide From Source -layout: docs -permalink: /docs/advanced-topics/building-from-source/ ---- - -It is generally recommended to [install the released package of Nuclide](/docs/setup), but for -those willing to live on the bleeding edge, you can install Nuclide from source. - -* TOC -{:toc} - -## Mac - -### Prerequisites - -You must have the [general prerequisites](/docs/editor/setup#mac__prerequisites) installed. In -addition, you must have - -
    -
  • Xcode (for Command Line Tools)
  • -
  • -
  • Atom Shell Commands (open Atom and go to `Atom | Install Shell Commands`) installed as well.
  • -
  • The Yarn package manager (run npm install -g yarn)
  • -
- -> Xcode can be installed from the App Store. Installation can take a *long, long* time. So be patient. - -> To install Node, the easiest way is to -> [download the latest released Node package](https://nodejs.org) and go through the installer. - -You can verify all the appropriate dependencies. All the following should be in your `$PATH` environment variable (usually `usr/bin` or `usr/local/bin`). - -```bash -$ git --version -$ node --version -$ yarn --version -$ apm --version -``` - -### Building - -Run the following commands to build Nuclide from source. - -```bash -# Clone the source -$ git clone https://github.com/facebook/nuclide.git -$ cd nuclide -# Install dependencies -$ yarn --pure-lockfile -# Link the 'nuclide' package to Atom's package directory -# You could also use apm link --dev ... see Development Mode below. -$ apm link -``` - -Verify the installation: - -1. Open Atom. -2. Go to `Atom | Preferences`. -3. Click on **Packages**. -4. Verify `nuclide` is one of the packages. - -## Linux - -### Prerequisites - -You must have the [general prerequisites](/docs/editor/setup#linux__prerequisites) installed. - -

- -To install Node, see [Node.js's download page](https://nodejs.org/en/download/) for steps that work best for your setup. - -You'll also need the [Yarn](https://yarnpkg.com) package manager (run `npm install -g yarn`). - -You can verify all the appropriate dependencies. All the following should be in your `$PATH` environment variable (usually `usr/bin` or `usr/local/bin`). - -```bash -$ git --version -$ node --version -$ yarn --version -$ apm --version -``` - -### Building - -Run the following commands to build Nuclide from source. - -```bash -# Clone the source -$ git clone https://github.com/facebook/nuclide.git -$ cd nuclide -# Install dependencies -$ yarn --pure-lockfile -# Link the 'nuclide' package to Atom's package directory -# You could also use apm link --dev ... see Development Mode below. -$ apm link -``` - -Verify the installation: - -1. Open Atom. -2. Go to `File | Preferences`. -3. Click on **Packages**. -4. Verify `nuclide` is one of the packages. - -## Windows - -Building Nuclide from source is not currently supported on Windows. - -> It is possible to build Nuclide from source on Windows, but this is done with no guarantee of -> success. The feature set will also be [limited](/docs/editor/setup/#windows). - -## Development Mode - -If you have another version of Nuclide installed (e.g., the official `apm` package), but you also want to run Nuclide from source, you can `apm link --dev` then run Nuclide via `atom --dev`. This will allow something similar to a production and development installation of Nuclide. - -When you open Atom in development mode, either with the `atom --dev` from the command line or with -the `View | Developer | Open in Dev Mode...` command from within the Atom menus, your linked version -of Nuclide will load in place of any other version of Nuclide you might have installed. diff --git a/docs/_docs/advanced-topics/custom-keybindings.md b/docs/_docs/advanced-topics/custom-keybindings.md deleted file mode 100644 index 1f37c257b1..0000000000 --- a/docs/_docs/advanced-topics/custom-keybindings.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -pageid: advanced-custom-keybindings -title: Custom Keybindings -layout: docs -permalink: /docs/advanced-topics/custom-keybindings/ ---- - -Nuclide has a bunch of [built-in bindings](/docs/editor/keyboard-shortcuts) to help you be -productive from the keyboard. However, you may want to add your own keybindings for Nuclide -commands as well. This is fairly easily done with some CSON editing. - -* TOC -{:toc} - -## Keymap CSON - -To create your own keybinding, you will need to edit your `~/.atom/keymap.cson` file. If you aren't -familiar with CSON, it is the [CoffeeScript equivalent of JSON](https://github.com/bevry/cson). - -Here is an example `~/.atom/keymap.cson` file: - -```coffeescript -'.editor:not(.mini)': - 'cmd-d': 'editor:delete-line' - 'cmd-home': 'core:move-to-top' - 'cmd-end': 'core:move-to-bottom' - 'cmd-l': 'go-to-line:toggle' -``` - -Because CSON is a superset of JSON this could also be written as: - -```coffeescript -{ - '.editor:not(.mini)': { - 'cmd-d': 'editor:delete-line', - 'cmd-home': 'core:move-to-top', - 'cmd-end': 'core:move-to-bottom', - 'cmd-l': 'go-to-line:toggle' - } -} -``` - -It may not be obvious, but each key in the top-level map is a CSS selector. Values are pairs of -commands and keybindings that are applicable in an element that matches the CSS selector. The -selector `.editor:not(.mini)` matches an editor in Nuclide that is not used as a single-line input -text box. Therefore, when you want to add a keyboard shortcut for an editor, add it to the -`.editor:not(.mini)` map. - -### Platform Specific Bindings - -You can make your bindings platform specific with `.platform-xxxxx` as part of your CSS selector. -For example the Nuclide `nuclide-quick-open` CSON looks like this: - -``` -{ - ".platform-darwin atom-workspace": { - "cmd-t": "nuclide-quick-open:find-anything-via-omni-search" - }, - ".platform-win32 atom-workspace, .platform-linux atom-workspace": { - "ctrl-t": "nuclide-quick-open:find-anything-via-omni-search" - } -} -``` - -where `.platform-darwin` represents macOS, `.platform-win32` represents Windows, and `.platform-linux` represents Linux. diff --git a/docs/_docs/advanced-topics/linter-package-compatibility.md b/docs/_docs/advanced-topics/linter-package-compatibility.md deleted file mode 100644 index d2bed3549b..0000000000 --- a/docs/_docs/advanced-topics/linter-package-compatibility.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -pageid: advanced-linter-package-compatibility -title: Linter Package Compatibility -layout: docs -permalink: /docs/advanced-topics/linter-package-compatibility/ ---- - -Nuclide Diagnostics displays diagnostic messages about your code from arbitrary providers. These can be lint warnings, compiler errors, etc. - -Any package that works with the [`linter`](https://atom.io/packages/linter) package should also work with Nuclide Diagnostics. - -We discourage the use of both Nuclide Diagnostics and `linter` together, since you will see duplicate UI for reporting diagnostics. To that end, if you wish to use Nuclide Diagnostics, we recommend disabling the `linter` package. If you wish to continue using the `linter`, we recommend disabling all `nuclide-diagnostics-*` Nuclide features. Please note that doing so will disable some Nuclide capabilities such as Flow and Hack error reporting. diff --git a/docs/_docs/editor/basics.md b/docs/_docs/editor/basics.md deleted file mode 100644 index 8c9dac2134..0000000000 --- a/docs/_docs/editor/basics.md +++ /dev/null @@ -1,245 +0,0 @@ ---- -pageid: editor-basics -title: Basics -layout: docs -permalink: /docs/editor/basics/ ---- - -Nuclide is a code editor built on the backbone of [GitHub's Atom text editor](https://atom.io). -Like other code editors and IDEs, there is a familiar look and feel to Nuclide. On the left side is your project tree, which includes associated files and folders. On the right side is -the main editor that contains the code and text for files in your project. And at the bottom is a -status bar providing quick-look information such as errors, the path of the current file relative -to your project root, the type of file that is open, and other context-aware data. - -![](/static/images/docs/editor-basics-intro.png) - -* TOC -{:toc} - -## Opening - -Assuming you have it [installed](/docs/editor/setup/), Nuclide is opened by opening Atom via mouse -(Dock, Applications folder, etc.) or from the command-line in a terminal window by running: - -```bash -$ atom -``` - -> To enable opening Atom from the command-line, you will need to install shell commands from the -> either the `Atom` menu or the Atom [Command Palette](/docs/editor/basics/#command-palette). In the -> Command Palette, search for "Window: Install Shell Commands". - -To open a specific directory into the [Project Explorer](/docs/editor/basics/#project-explorer), you can add a path argument to the `atom` command. - -```bash -$ atom /path/to/your/project/ -``` - -By default, when you open Nuclide, the Home page appears. - -![](/static/images/docs/editor-basics-homepage.png) - -The Nuclide Home page gives you quick access to common Nuclide tools and features, as well as -information regarding how to provide feedback. - -## Project Explorer - -The Project Explorer is on the left side of Nuclide and contains two tabs: **File Tree** and **Source Control**. This is where you can open projects, navigate through your project to open files in the [Editing Area](#editing-area), create new files and folders, view source control information, etc. - -### Adding Projects - -The first time you open Nuclide, there will be no projects or files open. Instead you will see two options in the Project Explorer's File Tree tab: 1) **Add Project Folder**, which opens a local project, and 2) **Add Remote Project Folder**, which opens a project on a [remote machine](/docs/features/remote/). - -![](/static/images/docs/editor-basics-adding-projects.png) - -When you choose a project to open, you are choosing the root directory of that project. Upon -opening, the project's file tree appears with the root folder at the top. - - - -To remove a project from the Project Explorer, *right-click* on the root folder, and choose **Remove Project Folder**. - -### Multiple Projects - -You can have more than one project open at a time. To open a second project, *right-click* anywhere in the Project Explorer's File Tree area, and choose **Add Project Folder** or **Add Remote Project Folder**. - -> You can have both local and remote projects open at the same time. - -With multiple projects open, default searching for files and in files will span both projects. -However, features such as debugging and error checking will still occur by project. - -> For the `Find | Find In Project` task, you can add project-level granularity by specifying the -> root of the desired project as a filter for the search. - -### Open Files - -The Project Explorer's **Open Files** list displays which files are currently open, allows for quick closure of open files (click on the `x` icon of a file), and indicates which files have unsaved changes (a blue dot in front of the file name). - - - -### Changed Files - -If your project is under source control, the Project Explorer will highlight the files that have changed in your project since your last commit. - -![](/static/images/docs/editor-basics-explorer-changed-files.png) - -#### Uncommitted Changes - -Files that have had changes made to them will also appear in the **Uncommitted Changes** list at the top of the Project Explorer. - - - -#### Source Control - -Under the Project Explorer's **Source Control** tab, you can see if uncommitted changes exist or not. If you are working with a Mercurial repository, the branches are listed as well. - -### Context-Aware Menu - -A context-aware menu appears when you *right-click* in the explorer. This menu provides -options such as adding new projects, searching within the project, etc. - -![](/static/images/docs/editor-basics-explorer-context-aware.png) - -## Editing Area - -The Editing Area is the main area for working with your code and text files. Each file is represented by a -tab. You can split this area into various panes for easier modification of multiple files. -The Editing Area is also where you will find specialized tabs for the Nuclide Home page, -the settings page, etc. - -### File Navigation - -Navigating between files and within files is the same as in -[Atom](https://atom.io/docs/v1.5.0/using-atom-moving-in-atom). - -You can quickly switch between open files by using `Ctrl-Tab` to cycle right or `Ctrl-Shift-Tab` to -cycle left. - -Within files you can go straight to a line number by pressing `Ctrl-G`. If your project uses -a supported language, you can also jump to symbols with `Cmd-R` (`Ctrl-R` on Linux). - -![](/static/images/docs/editor-basics-editing-area-symbols.png) - -### Search - -Most of the searching actions are the same as -[Atom](https://atom.io/docs/v1.5.0/using-atom-find-and-replace). For example, you can search within -a file (i.e., `Cmd-F`) or throughout your entire project(s) (i.e., `Cmd-Shift-F`). - -In addition to the basic Atom searching, Nuclide adds an additional powerful search functionality -that allows you to search in various contexts. OmniSearch (`Cmd-T` on Mac and `Ctrl-T` on Linux) -provides a way to search, all at once, across your project, within your files, code symbols, etc. - -![](/static/images/docs/editor-basics-editing-omnisearch.png) - -### Context-Aware Menu - -A context-aware menu appears when you *right-click* in the Editing Area. This menu provides options such as adding and closing panes, setting and removing breakpoints, showing line-by-line blame (if that information is available), etc. - -![](/static/images/docs/editor-basics-editing-context-aware.png) - -## Status Bar - -The Nuclide status bar builds upon the -[Atom status bar package](https://github.com/atom/status-bar), adding powerful new -features, including code diagnostics and remote connection status. - -![](/static/images/docs/editor-basics-status-bar-intro.png) - -### Code Diagnostics - -If you are using a supported language that provides linting and/or type checking capabilities -(e.g., [Hack](/docs/languages/hack/) or [Flow](/docs/languages/flow/)), then code diagnostics is built directly into Nuclide for that language. - -![](/static/images/docs/editor-basics-status-bar-diagnostics.png) - -### Remote Connection Status - -If you are connected to a project on a remote machine, clicking the Remote Connection icon on -the status bar will provide information about the current status of that connection. Generally, if -all is well, the connection to the server is "healthy". - -![](/static/images/docs/editor-basics-status-bar-connection.png) - -> If you check the connection against a local project, you will get information regarding whether -> the current active file exists on the local filesystem. - -### File Encoding - -The default file encoding for Atom is `UTF-8`. Clicking on this in the status bar allows you to -change the encoding of the current file. - -### Language Selection - -Atom automatically determines the language of the current file. Normally, this is correct. However, you can change -the language, and Atom will change its syntax highlighting appropriately. - -### Branch - -Assuming your project is under source control, the status bar also shows the current branch on -which you are working. - -## Gutter - -Atom has a [gutter](https://atom.io/docs/latest/getting-started-atom-basics#basic-terminology) that -shows you information such as current line number, source control status and function/method -folding. Nuclide has added further features to the gutter, including setting breakpoints for the -debugger and showing diagnostics for supported languages. - -![](/static/images/docs/editor-basics-gutter-intro.png) - -### Code Diagnostics - -If you hover over the code diagnostics errors, an inline window appears showing the problem. - -![](/static/images/docs/editor-basics-gutter-code-diagnostics.png) - -## Preferences Pane - -Nuclide has its own set of customizable preferences and settings. - -You get to these preferences by opening the Atom Settings view via the `Cmd-,` keyboard shortcut -(`Ctrl-,` on Linux) or through the `Packages | Settings View | Open` menu option. - -A new tab opens in the [Editing Area](/docs/editor/basics/#editing-area) titled **Settings**. Select **Packages** from the list at the left of the Settings tab, and scroll down until you see `nuclide` under either **Community Packages** or **Development Packages**. - -![](/static/images/docs/editor-basics-nuclide-package.png) - -> If you linked the [Nuclide source code](https://github.com/facebook/nuclide) to Atom's development -> packages and opened Atom in development mode via the `--dev` flag, you will see the `nuclide` -> package under **Development Packages**. - -Click on **Settings** to see all of the Nuclide preferences and settings. - -![](/static/images/docs/editor-basics-nuclide-preferences.png) - -## Command Palette - -Atom is highly flexible in how you perform actions. Nuclide adds actions as well. There is a -variety of menu options, and many menu commands are equally accessible from the keyboard as well. - -The Command Palette shows you every available command available in Atom and Nuclide. - -`Cmd-Shift-P` toggles the Command Palette. - -![](/static/images/docs/editor-basics-command-palette-intro.png) - -You can narrow down the options that match your search by typing in the text box at the top of the Command Palette. - -![](/static/images/docs/editor-basics-command-palette-search.png) - -## Distraction-Free Mode - -Distraction-Free Mode enables you to eliminate any surrounding panes allowing the [Editing Area](/docs/editor/basics/#editing-area) to take over the entirety of the window without having to toggle panes off individually. - -To use Distraction-Free Mode in your project, click on the **Toggle Distraction-Free Mode** button in the [Nuclide toolbar](/docs/features/toolbar/#buttons). - -Before activating Distraction-Free Mode: - -![](/static/images/docs/editor-basics-distraction.png) - -After activating Distraction-Free Mode: - -![](/static/images/docs/editor-basics-distraction-free.png) - ->If you wish, you can activate other panes after entering Distraction-Free Mode by toggling them on with their [toolbar buttons](/docs/features/toolbar/#buttons) or the [Command Palette](#command-palette). diff --git a/docs/_docs/editor/keyboard-shortcuts.md b/docs/_docs/editor/keyboard-shortcuts.md deleted file mode 100644 index f4e145a261..0000000000 --- a/docs/_docs/editor/keyboard-shortcuts.md +++ /dev/null @@ -1,196 +0,0 @@ ---- -pageid: editor-keyboard-shortcuts -title: Keyboard Shortcuts -layout: docs -permalink: /docs/editor/keyboard-shortcuts/ ---- - -You can perform many tasks in Nuclide from the keyboard. Below are the various keyboard shortcuts -available for the sets of functionality that Nuclide has to offer. - -> Atom has many more keyboard shortcuts available above and beyond what Nuclide offers. To -> get a complete list of the keybindings, you can go to -> `Packages | Settings View | Show Keybindngs`. - -> You can create your own [custom keybindings](/docs/advanced-topics/custom-keybindings) beyond -> those Nuclide provides. - -
- -* TOC -{:toc} - - -## Symbols - -Here is a legend of symbols that are associated with the keys shown in the keybindings. - -| Key | Symbol | -| ----|--------| -| `Alt` or `Option` on macOS | `⌥` | -| `Cmd` on macOS | `⌘` | -| `Ctrl` | `^` | -| `Shift` | `⇧` | -| `Left` | `←` | -| `Up` | `↑` | -| `Right` | `→` | -| `Down` | `↓` | -| `Backspace` | `⌫` | - -If you see a comma (`,`) in a key sequence that means *then*, as in "press this sequence, then press that -sequence". - -## Common Bindings - -These are also described in their respective sections below, but this provides a quick access table -for the most common shortcuts provided by Nuclide. - -| Key (macOS) | Key (Linux) | Description | -|-----------|-------------|-------------| -| `Cmd-T` | `Ctrl-T` | Use [OmniSearch](/docs/features/quick-open/#omnisearch) to open files, etc. | -| `Cmd-\` | `Ctrl-\` | Toggle the [Project Explorer](/docs/editor/basics/#project-explorer). | -| `Ctrl-0` | `Ctrl-0` | Toggle between the [Editing Area](/docs/editor/basics/#editing-area) and the [Project Explorer](/docs/editor/basics/#project-explorer)'s File Tree. | -| `Cmd-K,` | `Ctrl-K,` | Split the current file to the pane represented by ``, where `` is the down, up, left or right arrow. | -| `Option-Shift-D` | `Alt-Shift-D` | Open the [Code Diagnostics](/docs/editor/basics/#status-bar__code-diagnostics) window. | - -## Development - -These shortcuts provide quick access to development features such as [Code Diagnostics](/docs/editor/basics/#status-bar__code-diagnostics) (e.g, linting), etc. - -| Key (macOS) | Key (Linux) | Command | Description | -|-----------|-------------|---------|-------------| -| `Option-O`| `Alt-O` | `outline-view:toggle` | Toggles the [Outline View](/docs/features/outline-view/) for a supported file so you can easily navigate to class and function definitions. | -| `Cmd-I` | `Ctrl-I` | `nuclide-context-view:toggle` | Toggles the [Context View](/docs/features/context-view/). | - -### Hack/Flow/JavaScript - -| Key (macOS) | Key (Linux) | Command | Description | -|-----------|-------------|---------|-------------| -| `Option-Shift-Cmd-F` | `Alt-Shift-Ctrl-F` | `find-references:activate` | In projects such as Hack or Flow, this will allow you to find all the references to a selected, highlighted entity in your project. | -| `Option-Cmd-Y` | `Alt-Cmd-Y` | `nuclide-hack-symbol-provider:toggle-provider` | Allows you to search for Hack function, classes and constants within you Hack project. -| `Cmd-Shift-I` | `Ctrl-Shift-I` | `nuclide-format-js:format` | Automatically tries to insert missing `require` statements to your [Flow](/docs/languages/flow/) or [JavaScript](/docs/languages/other/#javascript) project. - - -### Code Diagnostics - -| Key (macOS) | Key (Linux) | Command | Description | -|-----------|-------------|---------|-------------| -| `Option-Shift-D` | `Alt-Shift-D` | `diagnostics:toggle-table` | Display the window showing you messages about your code. Possible messages include lint, compiler errors, etc. | -| `Option-Shift-A` | `Alt-Shift-A` | `diagnostics:fix-all-in-current-file` | Nuclide can fix certain types of problems for you automatically, including various lint problems. This will allow all those to be fixed in the current file. | -| `Option-Ctrl-<` | `Alt-Ctrl-<` | `diagnostics:go-to-first-diagnostic` | Go to the first diagnostic. | -| `Option-Ctrl->` | `Alt-Ctrl->` | `diagnostics:go-to-last-diagnostic` | Go to the last diagnostic. | -| `Option-<` | `Alt-<` | `diagnostics:go-to-previous-diagnostic` | Go to the previous diagnostic. | -| `Option-Ctrl->` | `Alt->` | `diagnostics:go-to-next-diagnostic` | Go to the next diagnostic. | - -## Project Explorer's File Tree - -The [Project Explorer](/docs/editor/basics/#project-explorer)'s File Tree tab in the left side pane is a tree of all of your project files. - -| Key (macOS) | Key (Linux) | Command | Description | Alternative | -|-----------|-------------|---------|-------------|-------------| -| `Right` | `Right` | `expand-directory` | Expand the current directory. | `Ctrl-]` | -| `Left` | `Left` | `collapse-directory` | Collapse the current directory. | `Ctrl-[` | -| `Option-Right` | `Alt-Right` | `recursive-expand-directory` | Expand all the directories from the current to the final directory child. | `Ctrl-Alt-]` | -| `Option-Left` | `Alt-Left` | `recursive-collapse-directory` | Collapse all the directories to the top parent. | `Ctrl-Alt-[` -| `Ctrl-{` | `Ctrl-{` | `recursive-collapse-all` | Collapse the entire [Project Explorer](/docs/editor/basics/#project-explorer)'s File Tree to the root. | | -| `Delete` | `Delete` | `remove` | Remove a file or directory from the tree. You will be prompted first to avoid accidental mistakes. | | -| `Cmd-\` | `Ctrl-\` | `toggle` | Toggles whether the [Project Explorer](/docs/editor/basics/#project-explorer)'s File Tree is shown. | `Cmd-K`, `Cmd-B` | -| `Home` | `Home` | `move-to-top` | Move the selection to the very top of the [Project Explorer](/docs/editor/basics/#project-explorer)'s File Tree. | | -| `End` | `End` | `move-to-bottom` | Move the selection to the very bottom of the [Project Explorer](/docs/editor/basics/#project-explorer)'s File Tree. | | -| `Enter` | `Enter` | `open-selected-entry` | Opens the selected entry in the [Project Explorer](/docs/editor/basics/#project-explorer)'s File Tree. If a directory is selected, then the directory is expanded. If a file is selected, then the file is opened in the main [Editing Area](/docs/editor/basics/#editing-area). | | -| `Cmd-K-Down` | `Ctrl-K-Down` | `open-selected-entry-down` | If a file is selected, it opens the file in the bottom pane. | | -| `Cmd-K-Right` | `Ctrl-K-Right` | `open-selected-entry-right` | If a file is selected, it opens the file in the right pane. | | -| `Cmd-K-Up` | `Ctrl-K-Up` | `open-selected-entry-up` | If a file is selected, it opens the file in the top pane. | | -| `Cmd-K-Left` | `Ctrl-K-Left` | `open-selected-entry-left` | If a file is selected, it opens the file in the left pane. | | -| `Cmd-|` | `Ctrl-|` | `reveal-active-file` | Shows the file that is currently active in the main workspace in the [Project Explorer](/docs/editor/basics/#project-explorer)'s File Tree. | `Cmd-Shift-\` (macOS) or `Ctrl-Shift-\` (Linux) -| `Ctrl-O` | `Ctrl-O` | `toggle-focus` | Toggles the focus of the current active file. | | - -## Files - -Whether switching between or searching for or within files, there are some keyboard shortcuts to -help accomplish file tasks a bit faster. - -| Key (macOS) | Key (Linux) | Command | Description | Alternative | -|-----------|-------------|---------|-------------|-------------| -| `Cmd-T` | `Ctrl-T` | `nuclide-quick-open:find-anything-via-omni-search` | Use this for a global search of anything within your project, including all files, currently open files, etc. | `Cmd-P` (macOS) or `Ctrl-P` (Linux) | -| `Option-Cmd-O` | `Alt-Ctrl-O` | `nuclide-open-filenames-provider:toggle-provider` | This lets you switch between files that are currently open in the editor. Useful for quickly accessing files if you have a bunch of files open. | -| `Option-Cmd-R` | `Alt-Ctrl-r` | `nuclide-recent-files-provider:toggle-provider` | This will show you files that you have recently opened and used in previous sessions of Nuclide. | -| `Option-Cmd-T`| `Alt-Ctrl-T` | `nuclide-fuzzy-filename-provider:toggle-provider` | This allows you to search for files based on patterns. | -| `Option-Cmd-N`| `Alt-Ctrl-N` | `nuclide-related-files:jump-to-next-related-file` | Find files related to the current file. A file is related if they have the same basename, but a different extension, for example. | - -## Task Runner - -Nuclide has support for running some common tasks on a variety of projects, like building a Buck project or debugging a React-Native one. For these tasks there is a set of useful keybord shortcuts you can use. - -| Key (macOS) | Key (Linux) | Command | Description | -|-------------|-------------|---------|-------------| -| `Cmd-B B` | `Alt-B B` | `nuclide-task-runner:build` | Executes the Build task for the currently selected Task Runner or the default one| -| `Cmd-B D` | `Alt-B D` | `nuclide-task-runner:debug` | Executes the Debug task for the currently selected Task Runner or the default one| -| `Cmd-B R` | `Alt-B R` | `nuclide-task-runner:run` | Executes the Run task for the currently selected Task Runner or the default one| -| `Cmd-B T` | `Alt-B T` | `nuclide-task-runner:test` | Executes the Test task for the currently selected Task Runner or the default one| -| `Cmd-B P` | `Alt-B P` | `nuclide-task-runner:run-selected-task` | Executes the currently selected Task| - -## Debugger - -The [Nuclide Debugger](/docs/features/debugger/) attaches to a running process. [Breakpoints](/docs/features/debugger/#basics__breakpoints) are managed in the [gutter](/docs/editor/basics/#gutter) to the left of your code and line numbers. - -| Key (macOS) | Key (Linux) | Command | Description | -|-----------|-------------|---------|-------------| -| `Option-Cmd-I` | `Alt-Ctrl-I` | `window:toggle-dev-tools` | Toggle the developer tools UI. | -| `Shift-Cmd-A` | `Shift-Ctrl-A` | `debugger:show-attach-dialog` | Shows the process attachment UI where you will choose the process on which you would like to debug (e.g., a Node process, etc.) | -| `Cmd-F8` | `Ctrl-F8` | `debugger:show-launch-dialog` | Shows the process launch UI where you will choose the process on which you would like to debug (e.g., a Node process, etc.) | -| `Cmd-Alt-J` | `Ctrl-Shift-J` | `nuclide-output:toggle` | Toggle the [Console](/docs/features/debugger/#basics__evaluation) pane. | -| `F8` | `F8` | `debugger:continue-debugging` | After stopping at a breakpoint, and possibly stepping through code, this will enable debugging to continue to the next breakpoint or end of the process. | -| `Shift-F8` | `Shift-F8` | `debugger:run-to-location` | After breaking at a certain position or breakpoint, it will continue to cursor location. | -| `F9` | `F9` | `debugger:toggle-breakpoint` | If a breakpoint is set, this will unset that breakpoint and vice-versa. | -| `F10` | `F10` | `debugger:step-over` | Step over a piece of code. For example, if you are stopped at a method call, this will execute that method without stepping through it line-by-line. | -| `F11` | `F11` | `debugger:step-into` | Step into a piece of code. For example, if you are stopped at a method call, this will go into the first line of that method. | -| `Shift-F11` | `Shift-F11` | `debugger:step-out` | If you have stepped into a piece of code, this will step out to the point on which you entered that piece of code. For example, if you stepped into a method, this will step out back to the method call itself. | -| `Shift-F5` | `Shift-F5` | `debugger:stop-debugging` | Detach debugger. | -| `Cmd-Shift-F8` | `Ctrl-Shift-F8` | `debugger:restart-debugging` | Restart the current debugging session with the same configuration settings. | - -## Editor Panes - -These are keyboard shortcuts with respect to moving currently active files in the editor around the -main panes. - -| Key (macOS) | Key (Linux) | Command | Description | -|-----------|-------------|---------|-------------| -| `Cmd-K-Down` | `Ctrl-K-Down` | `nuclide-move-pane:move-tab-to-new-pane-down` | Moves the currently active file in the editor to a bottom pane. | -| `Cmd-K-Right` | `Ctrl-K-Right` | `nuclide-move-pane:move-tab-to-new-pane-right` | Moves the currently active file in the editor to a right pane. | -| `Cmd-K-Up` | `Ctrl-K-Up` | `nuclide-move-pane:move-tab-to-new-pane-up` | Moves the currently active file in the editor to a top pane. | -| `Cmd-K-Left` | `Ctrl-K-Left` | `nuclide-move-pane:move-tab-to-new-pane-left` | Moves the currently active file in the editor to a left pane. | - -## Navigation - -These are keyboard shortcuts with respect to navigation within files, etc. - -| Key (macOS) | Key (Linux) | Command | Description | -|-----------|-------------|---------|-------------| -| `Ctrl-,` | `Ctrl-<` | `nuclide-navigation-stack:navigate-backwards` | Moves the cursor to a previous position from the current position. | -| `Ctrl-.` | `Ctrl->` | `nuclide-navigation-stack:navigate-forwards` | Moves the cursor to the next position from the current, but former, position. | - -## Miscellaneous - -These are other key-based shortcuts that are included with Nuclide, including [Hyperclick](#hyperclick), clipboard -and Nuclide health actions. - -| Key (macOS) | Key (Linux) | Command | Description | -|-----------|-------------|---------|-------------| -| `Option-Cmd-Enter` | `Alt-Ctrl-Enter` | `hyperclick:confirm-cursor` | When using [Hyperclick](#hyperclick), this will confirm the Hyperclick action you want to take. | -| `Ctrl-Option-Shift-H` | `Ctrl-Alt-Shift-H` | `nuclide-health:toggle` | Toggle the Nuclide Health tab, which show details about the Nuclide process itself (how much CPU, memory is being used, etc.). | -| `Ctrl-Option-Shift-X` | `Ctrl-Alt-Shift-X` | `nuclide-clipboard-path:copy-project-relative-path` | Copy the relative path of the current file to the clipboard. | -| `Ctrl-Shift-X` | `Ctrl-Shift-X` | `nuclide-clipboard-path:copy-absolute-path` | Copy the absolute path of the current file to the clipboard. | -| `Ctrl-Option-X` | `Ctrl-Alt-X` | `nuclide-clipboard-path:copy-repository-relative-path` | Copy the relative path of the current file starting at the root of the Mercurial repository. | - -### Hyperclick - -Hyperclick Trigger keys are configurable. - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. - -The Hyperclick Trigger key settings are right at the top and set to the defaults. You can change them by clicking on the selection bar and choosing from the provided list. - -![](/static/images/docs/editor-keyboard-shortcuts-hyperclick.png) diff --git a/docs/_docs/editor/setup.md b/docs/_docs/editor/setup.md deleted file mode 100644 index 3ee789bd1e..0000000000 --- a/docs/_docs/editor/setup.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -pageid: editor-setup -title: Setup -layout: docs -permalink: /docs/editor/setup/ ---- - -There are two supported platforms for Nuclide, [Linux](#linux) and [macOS](#macos). - -> Nuclide can be installed on [Windows](#windows), but it is -> [not fully supported](https://github.com/facebook/nuclide/issues/321). - -These instructions are for installing the released package of Nuclide. For advanced users, you can -[build from source](/docs/advanced-topics/building-from-source), but this is not officially -supported and stability is not guaranteed. - -* TOC -{:toc} - -## Quick Install - -

- -Assuming you have met all the prerequisites for your platform, the easiest way to install Nuclide is within Atom itself: - -1. Open Atom. -2. Choose `Atom | Preferences` (`Edit | Preferences` on Linux and `File | Settings` on Windows) to bring up the **Settings** tab. -3. In the **Settings** tab, select **Install** from the list at the left. -4. In the search box, type "Nuclide" and press the `Enter` key. -5. Click the **Install** button for the `nuclide` package. - -> Installing Nuclide within the Atom Packages UI is the recommended method, however you can install Nuclide from the command-line, if you wish, using: -> -```bash -$ apm install nuclide -``` -> - -Otherwise, see your installation platform below for detailed installation instructions, including -prerequisites. - -## macOS - -### Prerequisites - -

- -You can follow the [instructions on the Atom website](http://flight-manual.atom.io/getting-started/sections/installing-atom/#platform-mac). Essentially, -if you go to [Atom.io](https://atom.io/), there will be direct link to download Atom. - -### Installation - -Install Nuclide through the Atom Packages UI: - -1. Open Atom. -2. Choose `Atom | Preferences` to bring up the **Settings** tab. -3. In the **Settings** tab, select **Install** from the list at the left. -4. In the search box, type "Nuclide" and press the `Enter` key. -5. Click the **Install** button for the `nuclide` package. - -![](/static/images/docs/editor-setup-atom-install-nuclide.png) - -> Installing Nuclide within the Atom Packages UI is the recommended method, however you can install Nuclide from the command-line, if you wish, using: -> -```bash -$ apm install nuclide -``` -> - -## Linux - -### Prerequisites - -

- ->Git is required to install Atom on Linux. - -There are [instructions on the Atom website](http://flight-manual.atom.io/getting-started/sections/installing-atom/#platform-linux) for installing Atom on Linux, but it doesn't mention the Git requirement. - -Instead, follow the command-line process below which shows you the installation of all the -necessary prerequisites, including Git. - -This is an installation on Ubuntu. If you are using an RPM-based distro, you should replace the -`apt-get` commands with the appropriate `rpm` or `yum` commands. Depending on your permissions, you -may need to prefix these commands with `sudo`. - -```bash -$ sudo apt-get update -# optional -$ sudo apt-get upgrade -$ sudo apt-get install git -$ sudo add-apt-repository ppa:webupd8team/atom -$ sudo apt-get update -$ sudo apt-get install atom -# Run atom from the command-line if you want -$ atom -``` - -### Installation - -Install Nuclide through the Atom Packages UI: - -1. Open Atom. -2. Choose `Edit | Preferences` to bring up the **Settings** tab. -3. In the **Settings** tab, select **Install** from the list at the left. -4. In the search box, type "Nuclide" and press the `Enter` key. -5. Click the **Install** button for the `nuclide` package. - -> Installing Nuclide within the Atom Packages UI is the recommended method, however you can install Nuclide from the command-line, if you wish, using: -> -```bash -$ apm install nuclide -``` -> - -## Windows - -### Prerequisites - -Atom can be installed on Windows. - -

- -You can follow the [instructions on the Atom website](http://flight-manual.atom.io/getting-started/sections/installing-atom/#platform-windows). Essentially, -if you go to [Atom.io](https://atom.io/), there will be direct link to download Atom. - ->Some features of Nuclide may work on Windows, but the full Nuclide experience is [not yet supported](https://github.com/facebook/nuclide/issues/321). -> ->[Remote development](/docs/features/remote) functionality (seeing the directory tree, editing remote files, etc.) is generally successful on Windows. If you have [Hack](/docs/languages/hack) or [Flow](/docs/languages/flow) on a remote server, it is possible that you could get some of those language integrations to work as well. -> ->However, local projects may run into issues. - -### Installation - -Install Nuclide through the Atom Packages UI: - -1. Open Atom. -2. Choose `File | Settings` to bring up the **Settings** tab. -3. In the **Settings** tab, select **Install** from the list at the left. -4. In the search box, type "Nuclide" and press the `Enter` key. -5. Click the **Install** button for the `nuclide` package. - -![](/static/images/docs/editor-setup-atom-install-windows.png) - -## Post Installation - -After installation, running Atom will automatically load Nuclide. - -### Recommended Packages - -By default, Nuclide does not install all of the recommended Atom packages that enhance the Nuclide -experience. This was done purposely in order to ensure that users have to opt-in to some features -rather than obtrusively modify their work environment. - -Recommended packages include: - -- [`tool-bar`](https://atom.io/packages/tool-bar) to enable the [Nuclide toolbar](/docs/features/toolbar/). -- [`sort-lines`](https://atom.io/packages/sort-lines) to enable sorting lines of text. -- [`language-ocaml`](https://atom.io/packages/language-ocaml) to enable [OCaml](/docs/languages/other/#ocaml) language syntax highlighting. -- [`language-babel`](https://atom.io/packages/language-babel) to enable language grammar for [JS, Flow and React JS](/docs/languages/flow/), etc. -- ...and [others](https://github.com/facebook/nuclide/blob/master/package.json) under `package-deps`. - -
-In order to install all of the recommended packages: - -1. Go to `Packages | Settings View | Manage Packages`. -2. Search for the `nuclide` package, and click on the package's **Settings** button. -3. Select the **Install Recommended Packages on Startup** checkbox. - -![](/static/images/docs/editor-setup-recommended-packages.png) - -### Installing Nuclide Server - -If you want to use Nuclide for remote development, you'll also need to set up the `npm nuclide` -package. Instructions can be found in the [Remote Development docs](/docs/features/remote/). - -### Other Installations - -To benefit from all of Nuclide's features, we recommend you also install the following: - -* [Watchman](https://facebook.github.io/watchman/) - version 3.2 or above. It must be in `/usr/local/bin/` or in your `$PATH` environment variable. - ->Without Watchman, Nuclide will lose some functionality of its [Mercurial](/docs/features/hg), [Remote Development](/docs/features/remote), and [Quick Open](/docs/quick-start/getting-started/#quick-open) features. - -
- -* [Flow](/docs/languages/flow/) -* [Hack](/docs/languages/hack/) -* [Mercurial](/docs/features/hg/) diff --git a/docs/_docs/editor/uninstall.md b/docs/_docs/editor/uninstall.md deleted file mode 100644 index 32c99b2086..0000000000 --- a/docs/_docs/editor/uninstall.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -pageid: editor-uninstall -title: Uninstalling -layout: docs -permalink: /docs/editor/uninstall/ ---- - -To uninstall Nuclide, you run the Atom package manager uninstall command at the command-line: - -```bash -$ apm uninstall nuclide -``` - -> If you have a version of Nuclide prior to 0.0.35, you will need to follow a -> [different process](/docs/help/troubleshooting#uninstalling-older-versions-of-nuclide) to -> uninstall Nuclide. - -## Re-activate Disabled Core Packages - -Nuclide replaces Atom's `tree-view` package in order to support remote file systems. When -uninstalling Nuclide, you need to re-activate the `tree-view` package yourself. The following are -two ways to do that: - -* Re-activate the `tree-view` package through Atom's Settings page. - - 1. Go to `Atom | Preferences` and select **Packages** from the list at the left. - 2. Scroll down to find the `tree-view` package listed under **Core Packages**, or type "tree-view" into the search box. - 3. Click the **Enable** button. - - ![](/static/images/docs/editor-uninstall-reenable-atom-tree-view.png) - -* Edit your Atom `config.cson` file. - - 1. Open `~/.atom/config.cson`. - 2. Remove "tree-view" from the array of `disabledPackages` and save the file. - - ```coffeescript - "*": - core: - disabledPackages: [ - "tree-view" # REMOVE THIS LINE - ] - ``` diff --git a/docs/_docs/features/buck.md b/docs/_docs/features/buck.md deleted file mode 100644 index f976cf9380..0000000000 --- a/docs/_docs/features/buck.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -pageid: feature-buck -title: Buck -layout: docs -permalink: /docs/features/buck/ ---- - -Nuclide supports many common workflows with the [Buck](https://buckbuild.com/) -build system. See the [Buck website](https://buckbuild.com/setup/getting_started.html) -for instructions on how to install Buck and create a Buck project. - -* TOC -{:toc} - -## Getting Started - -First, open a Buck project (any project with a `.buckconfig` file) as a project -in Nuclide. - -> [Enabling Buck's httpserver interface](https://buckbuild.com/concept/buckconfig.html#httpserver) -> is recommended for better Buck output in Nuclide. - -If you have multiple projects open, or if your Buck project is a subdirectory -of one of your project roots, you'll need to mark the Buck project root as the -*Current Working Root*. You can do this by right-clicking on the root folder -in the file tree and selecting **Set to Current Working Root**. - -There are a few ways to trigger Buck commands from Nuclide: - -### Via the Task Runner - -Buck tasks live in the [Task Runner toolbar](/docs/features/task-runner). - -Click the **Toggle Task Runner Toolbar** button (i.e., the play icon) from the [Nuclide toolbar](/docs/features/toolbar). Alternatively, - go to `Nuclide | Task Runner | Toggle Toolbar Visibility`. - -Choose any of the Buck tasks from the Task Runner toolbar's drop-down menu. - - - -### Via the Nuclide menu - -The top-level Nuclide menu contains a **Buck** submenu. - - - -### Via Atom's Command Palette - -Open the [Command Palette](/docs/editor/basics/#command-palette) (`Cmd-Shift-P` or `Ctrl-Shift-P` on Linux/Windows) -and type "buck" in the text box: - - - -> You can use these commands to add keybindings in Atom's keymap: -> -> ``` -> 'atom-workspace': -> # note: commands are case-sensitive -> 'cmd-b': 'nuclide-task-runner:toggle-buck-toolbar' -> 'f5': 'nuclide-task-runner:buck-build' -> 'f6': 'nuclide-task-runner:buck-test' -> 'shift-cmd-k': 'nuclide-buck:open-nearest-build-file' -> ... -> ``` - -## Workflows - -Nuclide supports Buck workflows matching the corresponding Buck command-line tasks via the [Task Runner toolbar](/docs/features/task-runner). See the [Task Runner Buck guide](/docs/features/task-runner/#buck) for more information on the following Buck workflows: - -- [Build](/docs/features/task-runner/#buck__build) -- [Run](/docs/features/task-runner/#buck__run) -- [Test](/docs/features/task-runner/#buck__test) -- [Debug](/docs/features/task-runner/#buck__debug) diff --git a/docs/_docs/features/context-view.md b/docs/_docs/features/context-view.md deleted file mode 100644 index 51eb5dbb4d..0000000000 --- a/docs/_docs/features/context-view.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -pageid: feature-context-view -title: Context View -layout: docs -permalink: /docs/features/context-view/ ---- - -Nuclide provides a Context View to easily navigate between symbol's and their definitions in your code. - - - -
- -* TOC -{:toc} - -## Toggling - -To toggle the Context View panel, you can: - -1. Press `Cmd-I` (`Ctrl-I` on Linux). -2. Go to the `Nuclide | Context View | Toggle` menu. -3. Click on the **Toggle Context View** [button](/docs/features/toolbar/#buttons) on the [Nuclide toolbar](/docs/features/toolbar). - -## Definition Preview - -When you click on a symbol in the [Editing Area](/docs/editor/basics/#editing-area), the symbol's definition will be highlighted in the Context View panel. - -![](/static/images/docs/feature-context-view-highlight.png) - -Clicking on the **Open in main editor** button at the bottom of the Context View panel moves the cursor to that definition be it in the current file or a different one. - -> Context View currently supports [Hack](/docs/languages/hack), [Python](/docs/languages/python), [Objective-C](/docs/languages/objective-c/), [C++](/docs/languages/cpp), and [GraphQL](/docs/languages/graphql) files. diff --git a/docs/_docs/features/debugger.md b/docs/_docs/features/debugger.md deleted file mode 100644 index 393baef76d..0000000000 --- a/docs/_docs/features/debugger.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -pageid: feature-debugger -title: Debugger -layout: docs -permalink: /docs/features/debugger/ ---- - -One of the key features of Nuclide is its multiple-language debugging support provided with a debugger interface inspired by the familiar [Chrome DevTools](https://developer.chrome.com/devtools). The Nuclide Debugger provides many capabilities allowing you to have a productive debug loop, including inspection, watches, setting breakpoints, step in/over/out, etc. - -* TOC -{:toc} - -## Instantiation - -Attach to a running debug target via `Cmd-Shift-A` (`Ctrl-Shift-A` on Linux and Windows). You can also -toggle the Debugger through the [Command Palette](/docs/editor/basics/#command-palette) and the -[Nuclide toolbar](/docs/features/toolbar/#buttons)'s **Toggle Debugger** icon. You can also launch a new target with the debugger -attached via `Cmd-F8` (`Ctrl-F8` on Linux and Windows). - -You can also bring up the Debugger panel by choosing `Debugger -> Show` from the Nuclide menu. - -## Basics - -Nuclide supports debugging for multiple [languages](#language-specific-debugging) and -[platforms](#platform-specific-debugging). However, there are some basic debugging concepts that apply across all languages. - -### Debuggable Target - -Specific details are provided for each [language](#language-specific-debugging) or -[platform](#platform-specific-debugging), but in general, to begin debugging code in Nuclide, you -need to either launch a debug process from within Nuclide (e.g., iOS from the Buck toolbar) or -attach to a currently running process for debugging. - -After attaching to the process by clicking **Attach**, you should see the Debugger Controls to the right of the [Editing Area](/docs/editor/basics/#editing-area). - -![](/static/images/docs/feature-debugger-target-attach.png) - -### Breakpoints - -To set a breakpoint in Nuclide, you use the [gutter](/docs/editor/basics#gutter). Click to the left -of each line number in the file(s) in which you want Nuclide to break the running program. Then -as the program is running, if a line on which a breakpoint is set is hit, the program halts, and you -are able to perform debugging tasks such as [step](#basics__stepping) and -[evaluation](#basics__evaluation) from that point. - -> There is currently only one type of breakpoint called a *source breakpoint*. This is a breakpoint -> on one line of code. We are looking into ways to support functional, conditional, and other types -> of breakpoints. - -### Debugger - -The Debugger Controls are the information control center for the Nuclide Debugger. - -In addition to the specialized areas described below, it also provides mouse-clickable execution, -[stepping](#basics__stepping), and breakpoint options. - -***Call Stack*** - -The **Call Stack** area shows you where you came from to get to your current point in the code. The -top function is where you currently are, the function below the top is the one that called the -current function, and so on. Clicking on any function in the call stack will change the scope -information so that it is relevant to that function. - -***Breakpoints*** - -The **Breakpoints** area shows you all the places in your project where you have breakpoints set. If -any are highlighted, that means that you have now hit that breakpoint while running the code. Clicking on a breakpoint in this list will move your cursor to its line of code in the Editing Area. You can deactivate/reactive breakpoints by clicking the checkmark next to each one. Right-clicking in the area will give you the option to quickly remove, enable, or disable all breakpoints at once. - - - -***Unresolved Breakpoints*** - -These are breakpoints that cannot be resolved by the debugger. The most likely cause of an -unresolved breakpoint is putting a breakpoint on code that is not part of the project on which the -debugger process is attached. For some languages, this can also indicate that the program was built without debug symbols (check - your compiler flags!), or that the symbols are missing or do not match the binary being debugged. - -***Scopes*** - -The **Scopes** pane shows you information about variables based upon the current point in the running of the code. Which scopes are visible -depends on the language being debugged. - -***Watch Expressions*** - -The **Watch Expressions** area is for you to keep track of the values of global and local variables. To add a new value to track, enter it in the `add new watch expression` text box. To remove a watched variable, click the `x` icon of the variable you wish to delete. - -***Detaching*** - -You can detach the debugger from the current process by clicking "X" to close the debugger controls pane, or by clicking the "stop" button. -This will stop the entire debugging session for that process, but will not kill the target. - -### Stepping - -It is essential for any debugger to have a mechanism to step into, over, and out of code. The -Nuclide Debugger provides stepping functionality with shortcuts within the Debugger itself and -via the [keyboard](/docs/editor/keyboard-shortcuts/#debugger). - -![](/static/images/docs/feature-debugger-stepping-controls.png) - -### Evaluation - -The Nuclide Debugger supports -[REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) via the **Console** tab. - -When you hit a breakpoint during your debugging session, you can use the Console to write -expressions, call functions, etc. using the current state of the program at the breakpoint. - -> For Hack and PHP debugging, hitting a breakpoint is not necessary to use the REPL support of -> the Nuclide Debugger. If you do not hit a breakpoint, then REPL is run in the global context as -> opposed to the current stack frame if a breakpoint is hit. - -> For LLDB-based debugging, REPL runs LLDB debugger commands as opposed to evaluating code in the -> Debugger. - -*Example* - -Here we have a breakpoint before printing out the sum of the two global variables `num1` and `num2`. -This shows printing out the values of the global and local variables, writing simple expressions, -calling a function in another module (`math.add()`), and inspecting objects. - -![](/static/images/docs/feature-debugger-evaluation-ex.png) - -## Language Specific Debugging - -While the [general process](#basics) for debugging in Nuclide is similar, there are platform and -language specific debugging workflows that require discussion and illustration. - -- [Hack and PHP](/docs/languages/hack/#debugging) -- [C++](/docs/languages/cpp/#debugging) -- [Objective-C](/docs/languages/objective-c/#debugging) - - -## Platform Specific Debugging - -- [iOS](/docs/platforms/ios/#debugging) -- [Android](/docs/platforms/android/#debugging) -- [React Native](/docs/platforms/react-native/#debugging) - -Buck projects can be more easily debugged via the [Task Runner](/docs/features/task-runner/#buck). diff --git a/docs/_docs/features/format-js.md b/docs/_docs/features/format-js.md deleted file mode 100644 index bc688c56bd..0000000000 --- a/docs/_docs/features/format-js.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -pageid: feature-format-js -title: Format JS -layout: docs -permalink: /docs/features/format-js/ ---- - ->[Format-js](https://atom.io/packages/nuclide-format-js) is now available as a separate Atom package for use with Nuclide. However, it is currently experimental. For example, this currently does not handle using relative paths for the automatic requires. - -Format-js is a package with a goal of getting rid of worrying about every little formatting detail you might run across while writing -[Flow](/docs/languages/flow) or [JavaScript](/docs/languages/other/#javascript) code. For more information about the Format-js package visit the [Format-js Atom package page](https://atom.io/packages/nuclide-format-js). - -To install the Format-js package: - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide-format-js`. -3. Click **Install**. - -Currently, Format-js is focused on automatically adding, removing, and formatting, your `require` statements. - -## Auto-Require - -Adding `require` statements automatically allows you to focus on writing code without -worrying about that overhead. For example, if you try to use a variable that has not been declared -elsewhere, we will try to add it as a `require`. - -> This assumes the `require` added is a valid module. Of course, it might not be. -> However, something like the [Flow typechecker](/docs/languages/flow) should tell you when you are -> using `require` on an entity that is not a module. - -Take the following code example: - -![](/static/images/docs/feature-format-js-before.png) - -If you press `Cmd-Shift-I` (`Ctrl-Shift-I` on Linux), your code will be analyzed for types that -you are using in your code that may need to be `require`d. The possible `require`s for your code are then added. - -![](/static/images/docs/feature-format-js-after.png) - -You can then check if these are correct and modify accordingly. For example, maybe instead of -`const`, you want `var`. - -## Settings - -There are customizable settings for the Format-js package. - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide-format-js`. -3. Click on the **Settings** button for the Format-js package. - -![](/static/images/docs/feature-format-js-settings.png) - -You can also enable or disable keybindings in the Format-js settings. - -![](/static/images/docs/feature-format-js-keybindings.png) diff --git a/docs/_docs/features/health.md b/docs/_docs/features/health.md deleted file mode 100644 index ce69d986fb..0000000000 --- a/docs/_docs/features/health.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -pageid: feature-health -title: Health Statistics -layout: docs -permalink: /docs/features/health-statistics/ ---- - -Nuclide uses computing resources. We try to keep the resource usage as low as possible. One of the -features of Nuclide is a health monitor that allows you to track CPU, memory, heap usage and other -statistics. - -![](/static/images/docs/feature-health-overview.png) - -* TOC -{:toc} - -## Toggling - -To open the **Health** tab in the main [Editing Area](/docs/editor/basics/#editing-area), you have four primary -options: - -- The `Ctrl-Option-Shift-H` (macOS) or `Ctrl-Alt-Shift-H` (Linux) keyboard shortcuts -- The [Nuclide toolbar](/docs/features/toolbar) -- The [Command Palette](/docs/editor/basics/#command-palette) - -## Statistics - -The following statistics are shown in the Nuclide health monitor. If you have multiple Nuclide -sessions open, the statistics are per session and not a combination of all sessions. - -- **CPU**: How much CPU Nuclide is using. -- **Memory**: How much memory Nuclide is using. -- **Heap**: How much of the memory heap given to Node by V8 is being used by Nuclide. -- **Key Latency**: How much time between a key press and the event to occur within Nuclide. -- **Handles**: The number of active handles that still exist in Nuclide. -- **Event Loop**: How many pending requests that Nuclide has. - -The last two statistics are reported by the underlying Atom renderer process and indicate how many -processes, handles, and outstanding activities are currently being managed by Node. - -Also shown are the processes that have been spawned by Nuclide since it has been running, including -process ID (PID), bytes received, sent and the number of errors from the process. - -These statistics are provided by Node's [`process`](https://nodejs.org/api/process.html) APIs. diff --git a/docs/_docs/features/hg.md b/docs/_docs/features/hg.md deleted file mode 100644 index 5b24bb77b1..0000000000 --- a/docs/_docs/features/hg.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -pageid: feature-hg -title: Mercurial Support -layout: docs -permalink: /docs/features/hg/ ---- - -Atom provides [Git support](https://atom.io/docs/v1.5.3/using-atom-version-control-in-atom) in its -core packages. Given Facebook's heavy use of Mercurial, Nuclide extends Atom's source control -integration with support for [Mercurial](https://www.mercurial-scm.org/). - -> Nuclide's support for Mercurial is much more full-featured that its support for Git. Nuclide -> has not yet tried to extend the default support for Git provided by Atom. - -
- -* TOC -{:toc} - -## Blame - -Nuclide provides the capability to show you line-by-line -[blame (or annotate)](https://selenic.com/hg/help/annotate) for the current file within your -Mercurial repository. - -*Right-click* in the editor and select `Source Control | Toggle Blame` in the context-aware menu. - -![](/static/images/docs/feature-hg-blame-access.png) - -The [gutter](/docs/editor/basics/#gutter) displays the last commit hash on which there was a change for -the line and the user who made the change. - -![](/static/images/docs/feature-hg-blame-gutter.png) - -## File Tree Highlighting - -To the left of the [Editing Area](/docs/editor/basics/#editing-area) is Nuclide's [Project Explorer](/docs/editor/basics/#project-explorer). The Project Explorer's **File Tree** tab shows you all of the files that are in your project. In a Mercurial project, the File Tree will also show you what files have changed since your last commit. - -If a file is highlighted orange, it indicates a change in that file since your last commit. If a -folder in your project is highlighted orange, that means that files in that folder have changed -since your last commit. Green files or folders are new. Grey files or folders are ignored or -untracked. - -![](/static/images/docs/feature-hg-file-tree-highlight.png) - -## Line Modification Notifications - -This is a built-in Atom feature that displays in the [gutter](/docs/editor/basics/#gutter) showing any lines -that have been modified since the last commit. - ->This feature is not enabled by default. - -To enable this setting: - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-hg-repository`, and select the **Enables `git-diff` and `status-bar` diff stats to display added, changed, or removed lines in the editor gutter and status bar** checkbox. - -![](/static/images/docs/feature-hg-line-mod-gutter-setting.png) - -Then, if a line has been modified, you will see an orange vertical line in the gutter, and if a new line of -content has been added, you will see a green vertical line. - -![](/static/images/docs/feature-hg-line-modifications.png) - -## Added and Removed Lines - -This is a built-in Atom feature that displays in the [status bar](/docs/editor/basics/#status-bar) showing the number of lines that have been added and/or removed since the last commit. - -The **+** value is the number of lines that have been added. The **-** value is the number of lines -that have been removed. - -If you change a line (not added or removed), that counts as both an add and a removal, so you -might see something like "+1, -1" for a one line modification. - -![](/static/images/docs/feature-hg-number-of-line-changes.png) - -## Bookmark - -The [status bar](/docs/editor/basics/#status-bars) also shows the current Mercurial bookmark on -which you are currently working. - -![](/static/images/docs/feature-hg-bookmark.png) diff --git a/docs/_docs/features/outline-view.md b/docs/_docs/features/outline-view.md deleted file mode 100644 index df163f0354..0000000000 --- a/docs/_docs/features/outline-view.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -pageid: feature-outline-view -title: Outline -layout: docs -permalink: /docs/features/outline-view/ ---- - -Nuclide provides a code outline to allow for quick navigation of a code file. This can be -particularly useful for lengthy files with many classes, functions, methods, etc. - - - -* TOC -{:toc} - -## Toggling - -To toggle the **Outline** panel, you can: - -- Press `Option-O` (`Alt-O` on Linux). -- Go to the `View` menu, and select `Toggle Outline`. -- Click on the **Outline** [button](/docs/features/toolbar/#buttons) within the Nuclide [toolbar](http://nuclide.io/docs/features/toolbar/). -- Use the **Try It** button associated with the **Outline** [Quick Launch](/docs/quick-start/getting-started/#quick-launch-menu) menu in the Nuclide Home tab. - -## Navigation - -Clicking on any entity in Outline will bring you to the line in Nuclide that represents the -beginning of the definition for that entity. For example, clicking on -`function withDestinationPath` in the outline view will bring you to line 44 in the file that -defines that function. - -![](/static/images/docs/feature-outline-view-click.png) - -> Outline currently supports Hack, PHP, Flow, JavaScript, Python, C++, JSON, and GraphQL files. If you -> have Outline opened for a file that is not supported, you will see a message similar to -> *"Outline does not currently support..."* - -## Requirements - -In order for the Outline to work correctly, the following are required for specific languages: - -- **Hack**: The [Hack typechecker](/docs/languages/hack/#installing-hack), `hh_client`. -- **Flow**: The [Flow typechecker](/docs/languages/flow/#installing-flow), `flow`. -- **Python**: A working installation of [Python](https://www.python.org/), `python`. -- **C++**: One of the [compilers necessary for C++ Nuclide support](/docs/languages/cpp/#supported-compilers). diff --git a/docs/_docs/features/quick-open.md b/docs/_docs/features/quick-open.md deleted file mode 100644 index 65fee2b424..0000000000 --- a/docs/_docs/features/quick-open.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -pageid: feature-quick-open -title: Quick Open -layout: docs -permalink: /docs/features/quick-open/ ---- - -Nuclide goes beyond just normal file opening capabilities. Quick Open provides multiple -mechanisms to find a file, from recently opened files to a global OmniSearch that lets you search -for anything a file might contain. - -* TOC -{:toc} - -## Toggling - -There are three ways to toggle the **Quick Open** window. - -- The `Cmd-T` (macOS) or `Ctrl-T` (Linux) keyboard shortcuts -- [Command palette](/docs/editor/basics/#command-palette) searching for -`Nuclide Quick Open: Find Anything Via Omni Search` -- [Quick Launch Menu](/docs/quick-start/getting-started/#quick-launch-menu) - -![](/static/images/docs/feature-quick-open-toggle-window.png) - -> The `Hack Symbols` pane will only show if you have [Hack](/docs/languages/hack) files in your -> project. - -## OmniSearch - -*Keyboard Shortcuts*: `Cmd-T` or `Cmd-P` (`Ctrl-T` or `Ctrl-P` on Linux) - -When launching the **Quick Open** window, you will be taken to the **OmniSearch** tab. All of the -features of the other tabs are coalesced and condensed into your search results in this tab. - -![](/static/images/docs/feature-quick-open-omnisearch.png) - -## Filenames - -*Keyboard Shortcut*: `Option-Cmd-T` (`Alt-Ctrl-T` Linux) - -If you just want to search by filename (including within the path to the file) only, you can click -on the **Filenames** tab in the **Quick Open** window. - -![](/static/images/docs/feature-quick-open-filenames.png) - -## Open Files - -*Keyboard Shortcut*: `Option-Cmd-O` (`Alt-Ctrl-O` Linux) - -If you have a lot of files open in your [editor](/docs/editor/basics), you can use the **Open Files** tab of Quick Open to quickly scan a list of your currently open files. - -![](/static/images/docs/feature-quick-open-open-files.png) - -## Recent Files - -*Keyboard Shortcut*: `Option-Cmd-R` (`Alt-Ctrl-R` Linux) - -If you have recently closed a file and would like to quickly open it back up, you can use the -**Recent Files** tab of Quick Open. This tab also displays when you last opened the file(s). - -![](/static/images/docs/feature-quick-open-toggle-recent-files.png) - -## Hack Symbols - -*Keyboard Shortcut*: `Option-Cmd-Y` (`Alt-Ctrl-Y` Linux) - -If your project contains [Hack](/docs/languages/hack) code, you will get Hack language-specific -search options. Here you can search based on function (`@function-name`), class (`#class-name`), or -constant (`%constant-name`) symbols in your project. - -To access this feature, click on the **Hack Symbols** tab in the **Quick Open** window. - -![](/static/images/docs/feature-quick-open-toggle-hack-symbols.png) - -## Code Search - -*Keyboard Shortcut*: `Option-Cmd-K` (`Alt-Ctrl-K` Linux) - -The Code Search tab will help you find a piece of code within all the source files in your projects. -Internally it uses either [ripgrep](https://github.com/BurntSushi/ripgrep) (rg), -[silversearcher](https://github.com/ggreer/the_silver_searcher) (ag) or -[ack](https://beyondgrep.com/). - -By default, Nuclide will use any available tool in your PATH. -However, you can specify a default one in the *nuclide-code-search* tab in the Nuclide package -settings. We recommend ripgrep and ag because they are blazing fast. Sadly, only ripgrep works -properly on Windows. - -![](/static/images/blog/2017-08-31/quick-open.png) diff --git a/docs/_docs/features/remote.md b/docs/_docs/features/remote.md deleted file mode 100644 index 910f53214a..0000000000 --- a/docs/_docs/features/remote.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -pageid: feature-remote -title: Remote Development -layout: docs -permalink: /docs/features/remote/ ---- - -In addition to local development, Nuclide supports remote development. Using one of -three authentication methods (Password, an SSH agent, or a private key), you can connect to a -project on a remote machine. This project is then added to your Project Explorer's [File Tree](/docs/editor/basics/#project-explorer) as a remote project where development occurs just it would with a local project. - -* TOC -{:toc} - -## Nuclide Server - -Nuclide has two main components, the client and the optional server. The client is -[set up via an Atom `apm` package](/docs/editor/setup/) on your local machine. The -[server](#nuclide-server__setup) is set up via a Node `npm` package on any machine where you have -remote projects to which Nuclide will connect. - -### Prerequisites - -The remote machine must meet certain prerequisites before the -[remote Nuclide server](#nuclide-server__setup) can be installed. - -- [Python](https://www.python.org/) 2.7 or later. In many cases, this will already be installed by -default on your OS distribution. -
-- `node` and `npm` must be in your `$PATH` environment variable. -- [Watchman](https://facebook.github.io/watchman). The Nuclide server -requires Watchman to detect file and directory changes. Follow the Watchman -[build or install instructions](http://facebook.github.io/watchman/docs/install.html#build-install) -for your server's platform. -- SSH Daemon - The Nuclide client connects to the server via SSH, so ensure that the server exposes -an SSH daemon that you can connect to from your client machine and that you know the required credentials. You will need to have an existing private key that can be used to connect to the server. -- Port 9090-9093 exposed. *Note:* you can specify another port in the **Remote Server Command** box in -the [Connection Dialog box](#remote-connection__connection-dialog-box). - -### Setup - -The Nuclide server is installed through an [`npm` package](https://www.npmjs.com/package/nuclide) in -the Node Package Manager. - -```bash -npm install -g nuclide -``` - -> The `-g` switch to ensures Nuclide is installed as a Node global package. - -> While both the client and server packages are named `nuclide`, the `apm` package is the client -> and the `npm` package is the server. - -You do not need to explicitly start the server since the Nuclide client will attempt to do so when -it first connects through one of three authentication methods. - -## Remote Connection - -There are two ways to connect to a project on your remote server. - -If you do not have any projects currently open in Nuclide, you can click on the -**Add Remote Project Folder** button in the Project Explorer's [File Tree](/docs/editor/basics/#project-explorer). - -![](/static/images/docs/feature-remote-add-remote-project-file-tree.png) - -If you have a project already open, you can use `Nuclide | Remote Projects | Connect Remote Project...`, the `Ctrl-Shift-Cmd-C` keyboard shortcut (Mac only), or *right-click* in the Project Explorer's [File Tree](/docs/editor/basics/#project-explorer) and select **Add Remote Project Folder**. - - - -You can also go to the Nuclide Home page, and click the **Try it** button for **Remote Connection** in the [Quick Launch Menu](/docs/editor/getting-started/#quick-launch-menu). - -### Connection Dialog Box - -All the required information to connect to the remote Nuclide server is entered in the Connection -Dialog box. - -![](/static/images/docs/feature-remote-connect-dialog-box.png) - -> All of the values shown above are examples and will vary based on your own username, filesystem, -and SSH and Nuclide configuration. - -The options are as follows: - -- **Username** - the username that you use to connect to your server. -- **Server** - the address of your server. This can be a domain name based or IP address. -- **Initial Directory** - the path on your remote server that contains the project you want to open. -- **SSH Port** - the port used to connect to your server (default is 22). -- **Use ssh-agent-based authentication** - causes the server to try and talk to the ssh agent. -- **Password** - your server password, if you wish to use password authentication. -- **Private Key** - the local path to your private SSH key for this server (*Note:* If your key is -password protected you have to add it to the ssh-agent and use the ssh-agent-based authentication -option). -- **Remote Server Command** - if you have correctly [installed](#nuclide-server__setup) the -[Nuclide server](#nuclide-server), this will be `nuclide-start-server`. If not, you need to -supply the full path to the location of the script. You can either let the script pick an open port -for you from a list of predefined ports, or start the server on a specific port using the -`--port` flag. For example, in this box, you could type `nuclide-start-server --port 9099` (or -similar). - -> Only one of the three authentication options can be chosen and used. - -After supplying these options, click **Connect**. - -### Profiles - -In order to reduce the tediousness of having to specify the same connection information over and -over for machines you connect to frequently, you can use profiles. - -![](/static/images/docs/feature-remote-profiles.png) - -To create a profile, click the **+** button under the **Profiles** list on the left side of the [Connection Dialog box](#remote-connection__connection-dialog-box). - -![](/static/images/docs/feature-remote-add-profile.png) - -Any pre-filled information will be based on your *(default)* profile. Enter all of your connection -information for the new profile (similar to that in the -[Connection Dialog box](#remote-connection__connection-dialog-box)), then click **Save**. - -> `(DEFAULT)` in the **Remote Server Command** box is the default command for the Nuclide server, which -> is `nuclide-start-server`. - -## Development - -Once you have established a [remote connection](#remote-connection) and the Nuclide server is -initiated, the root folder of the project will be added to the Project Explorer's [File Tree](/docs/editor/basics/#project-explorer), underneath any other local (or other -remote) projects you currently have open. - -![](/static/images/docs/feature-remote-file-tree.png) - -Nuclide has now established a connection between your local client and the remote server, and -development can take place as normal. - -> Changes made to a remote file in Nuclide is reflected on the remote machine; changes made in the -> project on the remote server is reflected in your remote project file tree within Nuclide. diff --git a/docs/_docs/features/task-runner.md b/docs/_docs/features/task-runner.md deleted file mode 100644 index b03f732e0c..0000000000 --- a/docs/_docs/features/task-runner.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -pageid: feature-task-runner -title: Task Runner -layout: docs -permalink: /docs/features/task-runner/ ---- - -Nuclide provides the Task Runner toolbar for building, running, testing, and debugging projects. - - -* TOC -{:toc} - -## Buck - -Nuclide supports the [Build](#build), [Run](#run), [Test](#test), and [Debug](#debug) workflows for [Buck](/docs/features/buck), matching the corresponding Buck command-line tasks. - ->Your project must contain a `.buckconfig` file for the Buck tasks to be available in the Task Runner. - -Click the **Toggle Task Runner Toolbar** button on the [Nuclide toolbar](/docs/features/toolbar/#buttons) to display options for building, running, testing, and debugging your Buck project. - -### Build - -The Build task invokes [`buck build`](https://buckbuild.com/command/build.html), -displaying build output in the [Console](/docs/features/debugger/#basics__evaluation) below the [Editing Area](/docs/editor/basics/#editing-area). - -In the Task Runner toolbar's text box, type in the name of the build target exactly -as you would specify on the command-line, i.e., `//path/to/dir:target_name#flavor`. - ->The usual leading `//` is optional. - -![](/static/images/docs/feature-task-runner-buck-build.png) - -Clicking on the **Settings** button (i.e., the gear icon) opens a dialog where you can provide extra flags to Buck. - - - -Upon clicking the **Build** button (i.e., the crossed tools icon), build progress displays via a blue progress bar below the toolbar and also periodically via messages in the [Console](/docs/features/debugger/#basics__evaluation). - -Click the **Stop** button (i.e., the square icon) at any time to cancel an ongoing build. - -![](/static/images/docs/feature-task-runer-buck-build-console.png) - -C++ compilation errors will appear in both the [Console](/docs/features/debugger/#basics__evaluation) and the [Diagnostics Table](/docs/editor/basics/#code-diagnostics). Buck diagnostics are cleared upon triggering a new build. - -![](/static/images/docs/feature-task-runner-buck-build-diagnostics.png) - -### Run - -The Run task is only enabled for iOS and Android application targets ([`apple_bundle`](https://buckbuild.com/rule/android_binary.html), [`android_binary`](https://buckbuild.com/rule/android_binary.html), and [`apk_genrule`](https://buckbuild.com/rule/apk_genrule.html) rules). It invokes [`buck install --run`](https://buckbuild.com/command/install.html) and builds, installs, then runs the app. Build output will be reported as documented in the [Build workflow](#build) section above. - -![](/static/images/docs/feature-task-runner-buck-run.png) - -The iOS simulator type can be explicitly selected via the drop-down menu to the right of the toolbar's **Settings** button (i.e., the gear icon). - -### Test - -![](/static/images/docs/feature-task-runner-buck-test.png) - -The Test task invokes [`buck test`](https://buckbuild.com/command/test.html), building and running valid test targets (e.g., `cxx_test`). -Build output will be reported as documented in the [Build workflow](#build) section above. - -### Debug - -![](/static/images/docs/feature-task-runner-buck-debug.png) - -The Debug task is only enabled for the following target types: - -- iOS applications (`apple_bundle`) -- C++ unit tests (`cxx_test`) -- C++ binaries (`cxx_binary`) - -The [LLDB debugger](/docs/languages/cpp/#debugging) is invoked after a successful build in all three cases, but with slight variations. - -*iOS Applications* - -For iOS applications, the Debug task invokes [`buck install --run --wait-for-debugger`](https://buckbuild.com/command/install.html), then attaches LLDB to the simulator process once the app starts. - -As with the Run task, the iOS simulator type can be selected from the drop-down menu to the right of the toolbar's **Settings** button (i.e., the gear icon). - -*C++ unit tests* - -For C++ unit tests, LLDB is launched against the unit test binary with the `args` and `env` parameters [specified by the `cxx_test` target](https://buckbuild.com/rule/cxx_test.html) after a successful `buck build`. - -*C++ binaries* - -For C++ binaries, LLDB is launched directly against the output binary after a successful `buck build`. Extra launch arguments can be specified using the **Settings** button (i.e., the gear icon). - -## Swift - -The Task Runner toolbar can build [Swift](/docs/languages/swift) packages and run their tests. - ->Your project must contain a `Package.swift` file for the Swift tasks to be available in the Task Runner. - -Click the **Toggle Task Runner Toolbar** button on the [Nuclide toolbar](/docs/features/toolbar/#buttons) to display options for building or testing a Swift package. - -### Building a Swift package - - - -Enter the path to a Swift package's root directory, then click the **Build** button (i.e., the crossed tools icon) to build the package. (This path is not needed if your project's working root contains a Swift package.) Build output is displayed in the [Console](/docs/features/debugger/#basics__evaluation) below the [Editing Area](/docs/editor/basics/#editing-area). - -![](/static/images/docs/feature-task-runner-swift-build-output.png) - -You can customize build settings, such as whether to build the package in a *Debug* or *Release* configuration, by clicking the **Settings** button (i.e., the gear icon) to the right of the toolbar's text box. - -![](/static/images/docs/feature-task-runner-swift-build-settings.png) - -### Running a Swift package's tests - - - -Enter the path to a Swift package's root directory, then click the **Test** button (i.e., the checkmark icon) to run the package's tests. (This path is not needed if your project's working root contains a Swift package.) Test output is displayed in the [Console](/docs/features/debugger/#basics__evaluation) below the [Editing Area](/docs/editor/basics/#editing-area). - -![](/static/images/docs/feature-task-runner-swift-test-output.png) - -Clicking the **Settings** button (i.e., the gear icon) to the right of the toolbar's text box displays additional settings for running your Swift package's tests. - -## HHVM Debug Toolbar - -Nuclide provides an HHVM toolbar in the Task Runner for debugging [Hack](/docs/languages/hack) projects. You can launch the toolbar by clicking the **Toggle Task Runner Toolbar** button in the [Nuclide toolbar](/docs/features/toolbar/#buttons). - -![](/static/images/docs/feature-task-runner-hack-toolbar.png) - -> You must have a Hack or PHP file open to successfully launch the toolbar. - -You can choose either **Attach to WebServer** or **Launch Script** from the drop-down menu. If you select **Attach to WebServer**, the text box will fill automatically with the server to which you are connected. If you select **Launch Script**, the text box will fill automatically with the path of the open file. - - - -Set [breakpoints](/docs/features/debugger/#basics__breakpoints) in your code. - -Click the **Debug** button (i.e., the bug icon) to open the Debugger; it will stop at the first breakpoint. - -You can then follow the [basic Debugger information](/docs/features/debugger/#basics) and use the additional features of the [Console](/docs/languages/hack/#debugging__console), [Evaluation](/docs/languages/hack/#debugging__evaluation), [Filtering](/docs/languages/hack/#debugging__filtering) and [other HHVM-specific debugging settings]( /docs/languages/hack/#debugging__other-settings) to debug your code. - -![](/static/images/docs/feature-task-runner-hhvm-debug.png) - -In both the script and server launching/attaching scenarios, the line at which you've set a -breakpoint will highlight in blue when the breakpoint is hit. When this happens, execution of your -code is paused and you can use the Debugger Controls to step, evaluate expressions, inspect the current -call stack, etc. diff --git a/docs/_docs/features/terminal.md b/docs/_docs/features/terminal.md deleted file mode 100644 index 51edc64c48..0000000000 --- a/docs/_docs/features/terminal.md +++ /dev/null @@ -1,171 +0,0 @@ ---- -pageid: feature-terminal -title: Integrated Terminal -layout: docs -permalink: /docs/features/terminal/ ---- - -Nuclide includes support for a terminal via the excellent [xterm.js](https://github.com/xtermjs/xterm.js). It uses Nuclide's remote connection to give command-line access to project directories. Here are some notes regarding common customization issues. - -* TOC -{:toc} - -# Getting Started - -To open a new terminal window, right-click on a folder or file in the file tree and choose 'New Terminal Here'. - -You can also open a terminal by running the command `atom-ide-terminal:new-terminal` from the command-palette or via a key-binding. For example, here is a keymap.cson (menu command Atom/Keymaps) you can use to bind `ctrl-t` to create a new terminal: - -``` -'atom-text-editor': - 'ctrl-t': 'atom-ide-terminal:new-terminal' -``` -By default, this command is bound to `ctrl-shift-t` on macOS and `alt-shift-t` on Windows and Linux. - -# Copy/Paste - -Copy and Paste work in terminal from the menu commands Edit/Copy and Edit/Paste. On OS X, these commands are bound by default to Cmd-C and Cmd-V respectively, similar to editor windows in Nuclide. On Windows, these commands are bound to right-click with and without selection like Quick-Edit mode in cmd.exe. - -Some programs (e.g. emacs, tmux, vim) running in a terminal enable mouse support. This requests that the terminal forward mouse events to the program, and by default this prevents the local terminal from selecting text for copy. On a mac it is possible to temporarily override this by holding `option`/`alt` while selecting the text you want to copy. - -# Key Repeat on OS X - -OS X introduced a keyboard feature similar to iOS that affects Atom, where holding down a key offers diacritical options rather than repeating the ASCII character. If you prefer to have keys repeat in Atom/Nuclide, run the following command: - -``` -defaults write com.github.atom ApplePressAndHoldEnabled -bool false -``` - -(from [this gist](https://gist.github.com/rastasheep/bfc8266eeb58b899054c)) - -# Custom Shell - -By default, Nuclide terminal starts a new shell by running `/bin/bash --login -i`. You can customize this behavior by adding a file `$HOME/.nuclide-terminal.json` **on the machine where the shell process runs**. Here is an example you can use on OSX to start the version of bash from MacPorts: - -``` -{ - "command": [ - "/opt/local/bin/bash", - "--login", - ] -} -``` - -# Detecting Nuclide Terminal - -Nuclide terminal binds an environment variable `$TERM_PROGRAM` to the value 'nuclide'. This allows you to add special-cases to your `~/.bash_profile`, `~/.bashrc`, or similar startup script: - -``` -if [[ "$TERM_PROGRAM" == "nuclide" ]]; then - # Run Nuclide-terminal-specific initialization -else - # Run initialization for terminals other than in Nuclide -fi -``` - -For instance, if you want to use Nuclide as your editor if you've opened a terminal from within nuclide - -``` -if [[ "$TERM_PROGRAM" == "nuclide" ]]; then - export EDITOR='atom --wait' -else - export EDITOR=emacs # your favorite editor here -fi -``` - -# Scrollback - -Go to Atom > Preferences > Packages > Nuclide, expand `atom-ide-terminal`, and there is a setting there. Note that xterm.js does an eager memory allocation proportional to the size of the number here, so there is no 'unlimited' value. - -# Preserved Commands - -When you are using a terminal window, you might want a key binding to go to Atom/Nuclide rather than to the terminal. The commands bound to these keys are called 'Preserved Commands'. To add a preserved command, go to Atom > Preferences > Packages > Nuclide, expand `atom-ide-terminal`, and add the command to the list under 'Preserved Commands'. - -If you do not already know the name of the command, you can use 'key-binding-resolver:toggle' (cmd-. on mac) in a context where the command works, like another editor window, and type the key you want. The pane at the bottom of the screen will show you what you pressed and the command(s) for that key binding. - -# Setting the Title - -You can set the title of a nuclide terminal tab with an escape sequence. In `bash`, you can do the following: - -``` -echo -ne "\033]0;The Title\007" -``` - -This will set the terminal tab's title to "The Title". - -Similarly, if you wanted to have the terminal tab to always display the current directory name, in `bash` you could do something like: - -``` -PS1='\e]0;\W\a\$ ' -``` - -Tabs in Atom also have a 'path' property. E.g. you can right click a tab and `Copy Full Path`. Normally the path of a terminal tab is the original directory where the terminal was opened (e.g. right-click a file/directory and `New Terminal Here`). If you use a prompt hack like the one above and want the 'path' property to match the tile, you can set a property in `~/.nuclide-terminal.json` to make this happen: - -``` -{ - "useTitleAsPath": true -} -``` - -# Clearing the Screen - -Some terminal emulators bind `cmd-k` to clear the screen. Unfortunately, this key combination is used already for splitting windows in Atom. To avoid conflicting keybindings, we don't automatically bind this, but in your Atom > Keymap..., you can bind the command `atom-ide-terminal:clear` to get this functionality. - -Note that just binding `atom-ide-terminal:clear` to `cmd-k` will result in conflicting bindings, which manifests as needing to hit `cmd-k` twice to get it to work. To fix this, you need to unbind all commands that use `cmd-k` as a prefix. Here are the settings to put in Atom > Keymap... to get this working: - -``` -'.terminal-pane': - 'cmd-k alt-cmd-w': 'unset!' - 'cmd-k cmd-b': 'unset!' - 'cmd-k cmd-down': 'unset!' - 'cmd-k cmd-left': 'unset!' - 'cmd-k cmd-n': 'unset!' - 'cmd-k cmd-p': 'unset!' - 'cmd-k cmd-right': 'unset!' - 'cmd-k cmd-up': 'unset!' - 'cmd-k cmd-w': 'unset!' - 'cmd-k down': 'unset!' - 'cmd-k left': 'unset!' - 'cmd-k right': 'unset!' - 'cmd-k up': 'unset!' - 'cmd-k': 'atom-ide-terminal:clear' -``` - -# Binding Meta Keys - -Many terminal programs interpret `ESC`+//key// to mean `Meta`+//key//. Nuclide terminal supports a command `atom-ide-terminal:add-escape-prefix` for this scenario. When you bind a key combination to this command, the terminal sends `ESC` followed by the key with modifiers removed. - -Here is an example keymap.cson (Under the menu: Atom > Keymap...) that enables the `Command` key as `Meta` for several combinations: - -``` -'.terminal-pane': - 'cmd-b b': 'unset!' - 'cmd-b t': 'unset!' - 'cmd-b r': 'unset!' - 'cmd-b d': 'unset!' - 'cmd-b s': 'unset!' - - 'cmd-a': 'atom-ide-terminal:add-escape-prefix' - 'cmd-b': 'atom-ide-terminal:add-escape-prefix' - 'cmd-c': 'atom-ide-terminal:add-escape-prefix' - 'cmd-d': 'atom-ide-terminal:add-escape-prefix' - 'cmd-e': 'atom-ide-terminal:add-escape-prefix' - 'cmd-f': 'atom-ide-terminal:add-escape-prefix' - 'cmd-g': 'atom-ide-terminal:add-escape-prefix' - 'cmd-m': 'atom-ide-terminal:add-escape-prefix' - 'cmd-p': 'atom-ide-terminal:add-escape-prefix' - 'cmd-q': 'atom-ide-terminal:add-escape-prefix' - 'cmd-r': 'atom-ide-terminal:add-escape-prefix' - 'cmd-v': 'atom-ide-terminal:add-escape-prefix' - 'cmd-w': 'atom-ide-terminal:add-escape-prefix' - 'cmd-x': 'atom-ide-terminal:add-escape-prefix' - 'cmd-y': 'atom-ide-terminal:add-escape-prefix' - 'cmd-z': 'atom-ide-terminal:add-escape-prefix' - 'cmd-.': 'atom-ide-terminal:add-escape-prefix' - 'cmd-/': 'atom-ide-terminal:add-escape-prefix' - 'cmd-\\': 'atom-ide-terminal:add-escape-prefix' -``` - -Note that `cmd-b` is a prefix for several commands, all of which must be unbound to make `cmd-b` work as a standalone key binding. - -You can achieve a similar effect for the `Option` key by using `alt` instead of `cmd` in these key bindings. diff --git a/docs/_docs/features/toolbar.md b/docs/_docs/features/toolbar.md deleted file mode 100644 index d9b31a235d..0000000000 --- a/docs/_docs/features/toolbar.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -pageid: feature-toolbar -title: Toolbar -layout: docs -permalink: /docs/features/toolbar/ ---- - -Nuclide customizes the [tool-bar community Atom package](https://atom.io/packages/tool-bar) for its -specific use. The Nuclide Toolbar provides quick launch access to many common features including -the [Debugger](), Diagnostics, etc. - -By default, the Nuclide Toolbar is not installed. - -> Internally to Facebook the Toolbar is installed, by default. However, at this point, we did not -> want to presume to install other community packages without the user opting in. - -
- -* TOC -{:toc} - -## Installing - -The Nuclide Toolbar can be installed as part of installing the -[recommended packages](/docs/editor/setup/#post-installation__recommended-packages) through the -Nuclide package settings or it can be installed separately through the normal Atom package -installation process. - -### Singular package - -If you would prefer not to have all of the recommended Nuclide packages installed, you can install -the Toolbar separately. - -1. Go to `Packages | Settings View | Install Packages/Themes`. -2. In the `Search packages` text box, type "tool-bar".

-![](/static/images/docs/feature-toolbar-find-package.png) - -3. Click the **Install** button for the `tool-bar` package. - -The Toolbar will be added to your Nuclide environment (normally either at the top or along the left side of your Atom window). - -### Toggling - -You can toggle the Nuclide Toolbar either through `Packages | Tool Bar | Toggle` or by pressing `Cmd-Option-T` -(`Ctrl-Alt-T` on Linux). - -## Buttons - -The Nuclide Toolbar has buttons that, when clicked, take you to a specific feature of Nuclide. - -| ![](/static/images/docs/feature-toolbar-button-diagnostics.png) | Toggle [Diagnostics](/docs/editor/basics/#status-bar__code-diagnostics) Table | -| ![](/static/images/docs/feature-toolbar-button-outline-view.png) | Toggle [Outline View](/docs/features/outline-view/) | -| | Toggle [Context View](/docs/features/context-view) | -| | Toggle [Task Runner Toolbar](/docs/features/task-runner) | -| | Toggle [Debugger](/docs/features/debugger/) | -| ![](/static/images/docs/feature-toolbar-button-test-runner.png) | Toggle Test Runner | -| | Toggle [Console](/docs/features/debugger/#basics__evaluation) | -| | Toggle [Distraction-Free Mode](/docs/editor/basics/#distraction-free-mode) | -| ![](/static/images/docs/feature-toolbar-button-nuclide-settings.png) | Open [Nuclide Settings](/docs/editor/basics/#preferences-pane) | -| ![](/static/images/docs/feature-toolbar-button-nuclide-health.png) | Toggle [Nuclide health stats](/docs/features/health-statistics/) | - - -## Uninstalling - -You can uninstall the Nuclide Toolbar by following the normal Atom package uninstall mechanism. - -1. Go to `Packages | Settings View | Update Packages/Themes`. -2. Click the **Uninstall** button under the `tool-bar` package. - -> If you [uninstall Nuclide](/docs/editor/uninstall/), the `tool-bar` package is *not* uninstalled. diff --git a/docs/_docs/features/working-sets.md b/docs/_docs/features/working-sets.md deleted file mode 100644 index 3df01c5e2f..0000000000 --- a/docs/_docs/features/working-sets.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -pageid: feature-working-sets -title: Working Sets -layout: docs -permalink: /docs/features/working-sets/ ---- - -It can be common to have a -[large project](/docs/editor/basics/#project-explorer__adding-projects) with a root folder -that has a bunch of children folders and files underneath it. However, your work in that project may only exist in one or a few of the files within the project. The rest of the files are just noise in the [File Tree](/docs/editor/basics/#project-explorer). - -Working Sets allow you to select a subset of folders or files in your project that you -are interested in, hiding all of the other folders and files to display a sparser File Tree. - -* TOC -{:toc} - -## Defining Working Sets - -To define a Working Set, go to the upper right corner of the [Project Explorer](/docs/editor/basics/#project-explorer). As -you move your mouse there, you will see a **+** button appear. - -![](/static/images/docs/feature-working-set-begin.png) - -Clicking on the **+** button toggles the File Tree to allow for selecting folders and files to add to the Working Set you are currently creating. - -After selecting all the folders and files that you want, enter a name for the Working Set in the text box next to the checkmark. - -![](/static/images/docs/feature-working-set-add.png) - -> Click on the **-** button to cancel the creation of the Working Set. - -Once you create the Working Set you will see the File Tree reduced to only those files and folders -that you selected. - -![](/static/images/docs/feature-working-set-created.png) - -You can create as many Working Sets as you like. Just click on the **+** button again. Every time you -create a new Working Set, you will see the entirety of the project tree again for choosing files -and folders. - -> Files and folders can overlap in Working Sets. This might be useful when -> [toggling Working Sets](#toggling-working-sets). - -## Toggling Working Sets - -By default, all Working Sets are active as you create them. This means all of the files and folders -for every Working Set is shown combined in the File Tree. - -Here is an example of three Working Sets shown. - -![](/static/images/docs/feature-working-set-all-working-sets.png) - -However, you can toggle which Working Sets are active. - -![](/static/images/docs/feature-working-set-select-active.png) - -> You can also press `Ctrl-S` or go to `Nuclide | Working Sets | Select Active` to choose your -> active Working Sets. - -To deactivate a Working Set, click on its name. You will see the check mark -disappear, and the folders and files of that Working Set will be removed from the File Tree. - -![](/static/images/docs/feature-working-set-deactivate.png) - -> Pressing `Ctrl-Shift-S` or going to `Nuclide | Working Sets | Toggle Last Selected` will allow -> you to toggle between the full project tree and the currently active Working Set(s). - -## Editing Working Sets - -You can also edit and delete Working Sets. - -![](/static/images/docs/feature-working-set-edit.png) - -By clicking on the trash can, the Working Set is deleted, and if active, the files and folders of -that Working Set will be removed from the File Tree. - -> If a folder or file is part of another active Working Set, then it will remain in the File Tree. - -By clicking on the pencil, you can add or remove folders and files from that Working Set. You can rename the Working Set as well. - -## Opening Non-Working Set Files - -You can open files that do not belong to a Working Set. If, for example, you use -[Quick Open](/docs/features/quick-open) to open a file that is not part of a Working Set, then that file and its parent folders -will be shown *grayed out* in the File Tree. - -![](/static/images/docs/feature-working-set-not-working-set-file.png) - -> If you close the non-Working Set file, it will be removed from the File Tree. diff --git a/docs/_docs/help/faq.md b/docs/_docs/help/faq.md deleted file mode 100644 index 0e325910b4..0000000000 --- a/docs/_docs/help/faq.md +++ /dev/null @@ -1,227 +0,0 @@ ---- -pageid: help-faq -title: FAQ -layout: docs -permalink: /docs/help/faq/ ---- - -Here is an ever-growing list of frequently asked questions around Nuclide. - -* TOC -{:toc} - -## How do I open Nuclide? - -After ensuring you have Nuclide [set up](/docs/editor/setup/), see the [Opening](/docs/editor/basics/#opening) section in Nuclide [Basics](/docs/editor/basics/) for instructions. - -## What version of Nuclide is installed? - -You can determine the installed version of Nuclide with the [Atom Package Manager](https://github.com/atom/apm) (APM) from the command-line. - -```bash -$ apm list --no-dev --installed -``` - -The output will contain installed Atom packages and their versions. - -```bash -/Users/foobar/.atom/packages (1) -└── nuclide@X.Y.Z -``` - -Your installed version is the number following either the `nuclide` package or the first package -starting with `nuclide-`. In the example above, the installed version is `X.Y.Z`. - -

- -## How do I migrate from a pre-unified package version of Nuclide? - -If you previously installed Nuclide via the `nuclide-installer` package or by installing `nuclide-` -packages individually, you should uninstall them first. - -The new `nuclide` package will automatically disable any deprecated `nuclide-*` packages and warn -you on start up that you should uninstall them to ensure everything works as expected. - -Features you may have been familiar with as separate packages before, such as Hyperclick, -Diagnostics, and File Tree, are now listed as features in Nuclide's Settings page and are togglable -as if they were Atom packages. If you want to use only one or a few of the features of Nuclide, you -can disable the rest of Nuclide without incurring any load time for the disabled features' code. All -features are enabled by default. - - - -### Migrating settings from previous packages - -If you changed settings in any of Nuclide's previous packages, the settings will be automatically -migrated to their new location in the `nuclide.` namespace when you first launch Atom after -installing the `nuclide` package. The settings will be configurable like before but under the -Atom Settings rather than under the package's name. - -## How do I return Nuclide to a known state? - -To reset Atom and Nuclide to factory settings, removing all your packages and settings, do the following: - -1. Quit Atom. -2. Reinstall Atom.app. -3. Reset Atom's settings (optional, but recommended). - - > This will delay any custom settings and packages. - - On your machine, run: - - rm -rf ~/.atom - -4. Reset Atom's cache (optional, but recommended). - On your machine, run: - - rm -rf ~/Library/Application\ Support/Atom - -5. Kill the Nuclide Server (if you have one). - If you are running the Nuclide Server on a remote machine, SSH into it and run: - - pkill -f nuclide - -6. Reinstall Nuclide. - -## How can I make Nuclide like my favorite editor? - -Because Nuclide is a package on top of Atom, it is infinitely configurable with a massive collection of open source packages. If you want Atom to behave more like your favorite editor, try one of these: - -* Vim - * [vim-mode-plus](https://atom.io/packages/vim-mode-plus) - * [ex-mode](https://atom.io/packages/ex-mode) -* Emacs - * [emacs-plus](https://atom.io/packages/emacs-plus) - -## Can I write a script to automate basic Atom/Nuclide functionality? - -Atom provides a customizable `init.coffee` script that has full access to the Atom APIs and is executed at startup. For more information, see [Hacking Atom - The Init File](http://flight-manual.atom.io/hacking-atom/sections/the-init-file/). - -You can access the `init.coffee` script by going to `Atom | Init Script...`. - -It's easy to create your own commands with keybindings (you can also configure keybindings in a separate file, see [Keymaps In-Depth](http://flight-manual.atom.io/behind-atom/sections/keymaps-in-depth/)). - ->You have to reload Atom to test your changes. - -## Can the Nuclide Server use ports other than 9090-9093? - -With Nuclide's default server configuration you may run into port number conflicts on your remote server. To specify a specific port for the server to use, you can provide the `--port` option along with the remote server command. - -## Can I print from Nuclide? - -Unfortunately, this is not currently available as an option in Atom and doesn't appear to be something they will be adding. For more information, see [https://discuss.atom.io/t/printing-support/760/45](https://discuss.atom.io/t/printing-support/760/45). - -## How can I make the File Tree always automatically scroll to the current active file? - -1. Open the **Settings** tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-file-tree`. -5. Select the **Reveal File on Switch** checkbox. - - - -## How can I jump to the last cursor position in a file? - -Assume you performed an action that caused the cursor to jump to a new position. How do you go back? - -Use the Nuclide Navigation Stack commands: - -- Forward navigation: `Ctrl-,` (`Ctrl-<` on Linux and Windows) -- Backward navigation: `Ctrl-.` (`Ctrl->` on Linux and Windows) - -## Is there a way to search only files in the Working Set? - -Unfortunately, no. The external search tools Nuclide uses are not aware of the Working Sets. Nuclide also provides the external search tools with the upper limit on result set size preventing purely client-side filtering. - -## How do I disable Most Recently Used tab switching? - -Atom 1.7.0 introduced Most Recently Used (MRU) tab switching. To revert to the old behavior: - -1. Go to `Atom | Keymap...`. This will open the `keympa.cson` file. -2. Add - - 'body': - 'ctrl-tab': 'pane:show-next-item' - 'ctrl-tab ^ctrl': 'unset!' - 'ctrl-shift-tab': 'pane:show-previous-item' - 'ctrl-shift-tab ^ctrl': 'unset!' - -## Can Nuclide save the tabs I have open for each branch/bookmark? - -Yes, Nuclide's Bookshelf feature can save the tabs you have open for each branch/bookmark. When you switch between bookmarks, it will prompt you about restoring the files you had open. - -To control Bookshelf behavior: - -1. Open the **Settings** tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-bookshelf`. -5. Select **Always Restore**, **Always Ignore**, or **Prompt to Restore**. - - - -## Tabs become too small to read the file names when I have many tabs open. - ->This is an issue in Atom. - -One work-around is to make the tabs display in multiple rows. - -1. Go to `Atom | Stylesheet...`. This will open the `styles.less` file. -2. Add - - // Make tabs multi-row - .tab-bar { - height: auto; - flex-wrap: wrap; - .tab, - .tab.active { - flex: 1 0 auto; - height: 30px; - line-height: 27px; - } - .tab .title, - tab.active .title { - padding-right: 5px; - position: relative; - top: 1px; - } - .tab .close-icon, - .tab.active .close-icon { - line-height: 29px; - } - } - -## How do I report bugs, request features, or ask general questions about how to use Nuclide? - -If you've encountered a *bug*, please see the [GitHub Issues page](https://github.com/facebook/nuclide/issues) to see if anyone else has encountered the same problem and to report it as an issue if it is new. - -If you have a *feature request* or *general question*, the [Nuclide Community](https://www.facebook.com/groups/nuclide/) Facebook group is a good place to post. - -## Why is Nuclide a single Atom package? - -The Atom ecosystem is centered around modular packages that can be installed and updated -independently, and Nuclide took that same approach from the start. We wrote scripts to let our code -live in a single repository but be released as many Atom packages. Nuclide releases were actually -simultaneous releases of 40+ Atom packages. While this fit well with the Atom model, it meant we -also had to distribute a "installer" package that oversaw the installation of top-level Atom -packages. - -In practice, the installer process was computationally expensive, difficult to -troubleshoot, and took roughly 40 minutes partially due to large amounts of network traffic. When -all Nuclide packages were installed, they filled over 3GB of disk space. Nuclide packages are -heavily interdependent, and because they were installed as top-level Atom packages they each had -their own 'node_modules' directory with largely duplicate dependencies. - -By unifying Nuclide into a single Atom package, we aimed to improve installation, updates, and -maintenance. The single 'nuclide' package does not require a special installer, only `apm install` -like other Atom packages. This simplifies installation for everyone and makes Nuclide updates fast. -Once installed, the 'nuclide' package takes under 110MB of disk space, a 95%+ reduction in disk use, -and subsequently, network use during installation. The dramatic drop in disk use was possible -because Nuclide's features now share a single 'node_modules' directory and use relative paths to -require one another, eliminating the duplicate dependencies present when Nuclide was 40+ top-level -Atom packages. - -We hope that simplifying the installation -process will make [Nuclide's source](https://github.com/facebook/nuclide) more familiar to other -Atom developers and make it easier for anyone to contribute. diff --git a/docs/_docs/help/troubleshooting.md b/docs/_docs/help/troubleshooting.md deleted file mode 100644 index ac90a38fb9..0000000000 --- a/docs/_docs/help/troubleshooting.md +++ /dev/null @@ -1,262 +0,0 @@ ---- -pageid: help-troubleshooting -title: Troubleshooting -layout: docs -permalink: /docs/help/troubleshooting/ ---- - -If you are having problems with Nuclide itself, check out some of these troubleshooting tips. More -are being added as we come across common issues found by users. If you have an issue that is not -listed here, please [file a GitHub issue](https://github.com/facebook/nuclide/issues), and -depending on how widespread the problem may be, we will add it here as well. - -* TOC -{:toc} - -## Help! I think Nuclide is broken. - -It is probably best to [return Nuclide to a known state](/docs/help/faq/#how-do-i-return-nuclide-to-a-known-state). This can solve a variety of bizarre problems. - -## Command-Line Issues - -If `atom` or `apm` don't work from the command line, try removing the `/usr/local/bin/atom` and `/usr/local/bin/npm` symlinks and restarting Atom. Or, select **Install Shell Commands** from the `Atom` menu. - -## Settings Issues - -### Keyboard Shorts aren't working - -* Is the keyboard shortcut registered? - 1. Open the **Settings** tab either by pressing `Cmd-,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. - 2. Select **Keybindings** from the list at the left to see what keybindings you have active. - -* Check your system keyboard shortcuts. - There may be another application that is intercepting the shortcut before it reaches Atom. - -## Nuclide Server Issues - -### Installation - -If you are having issues installing the [Nuclide Server](/docs/features/remote#nuclide-server), -check out the following tips: - -*Node Version* - -

- -Use the command-line to verify your Node version by running: - -```bash -node --version -``` - -*Permissions* - -If you get `EACCESS` errors when you run the `npm install` command, you likely do not have your NPM properly -configured for installing global packages without root permissions. To fix this problem, install in -a directory your user owns like this: - -```bash -npm config set prefix '~/.npm_packages' -``` - -and add - -```bash -PATH=$PATH:$HOME/.npm_packages/bin; export PATH -``` - -to the end of your `.profile`. Now you should be able to run: - -```bash -npm install -g nuclide -``` - -without errors. - -If you previously ran `npm install` as root, you may need to correct the permissions on your `.npm` -directory by running: - -```bash -sudo chown -R userid:userid .npm -``` - -where `userid` is your userid. If you still get errors you may need to clear your NPM cache with: - -```bash -npm cache clear -``` - -### Files Not Syncing - -Sometimes you'll have a setup that used to work, but starts to fail. Here some things you can try to make it work again: - -* If you have a version mismatch between your client and remote server Nuclide installations, you'll want to run `npm update -g nuclide` on the server and make sure you have the same version on the client as well. -* Other tools that watch files may cause problems as well. Try stopping that process and stopping the file watcher as well via `watchman shutdown-server`. Then try to reconnect to the server again from Atom. -* Use `killall node` on the server side, then try reconnecting. - -## Source Control Issues - -### Source Control features aren't working - -If any Source Control features such as File Tree highlighting are working in Nuclide, there are a few things to check. - -1. Is the directory you opened in Atom part of a source control repository? -2. If you are working on a remote directory, only [Mercurial](/docs/features/hg/) is supported. Git will not work. -3. As of Atom 1.14, symlinks to directories essentially don't work, even if it's a Mercurial repository. Use a direct link to the directory to access all the source control features. - -### Why is the output of `hg status` wrong? - -Files not showing up as expected in `hg status` are generally caused by one of a few things: - -1. The file is ignored. - - You can run `hg status -i` to list ignored files. - - hg status -i | grep - -2. Watchman Issues - - Sometimes Watchman, the filesystem monitoring tool, isn't telling Mercurial that a file has been added, removed, or changed. You can check if it's a Watchman issue by running a status command without the Watchman extension: - - hg status --config extensions.fsmonitor=\! - - If the file shows up when you do that, it's a Watchman issue. In that case, run: - - watchman-diag > out.txt - - Sometimes on Macs, the output file might contain: - - There are 139 items on the filesystem not reported by watchman: - ... - - If you see this and if any components of the listed file names either are or were at some point a symlink, then you have fallen afoul of an Apple bug where fsevents won't report changes associated with a dangling symlink. You might be able to recover with: - - watchman watch-del-all - hg --config fsmonitor.mode=off rebase -s '(::bookmark() and draft()) - master::' -d master - watchman watch-project . - -3. Dirstate Corruption - - This happens most often because someone pressed `Ctrl-C` during a Mercurial command that was writing to the dirstate file (an index of all the files in the working directory). This corruption can be subtle and you might not notice any issues with it for a while, until you notice files not showing up that really should. - - In this case, try running: - - hg debugrebuilddirstate --minimal - - Then, run `hg status` again. - -4. Unknown Bugs - - Mercurial is under heavy development and there may be bugs we don't know about yet that cause issues like this. If you've verified that the above things don't work to fix the issue, let us know by filing a [GitHub issue](https://github.com/facebook/nuclide/issues). - -## Environment Issues - -### Uninstalling Older Versions of Nuclide - -[Nuclide v0.0.35](https://github.com/facebook/nuclide/releases/tag/v0.0.35) and earlier were released -as many separate Atom packages. If you have any packages starting with `nuclide-`, you likely have -some part of <=v0.0.35 still installed. - -Run the uninstall command below, which contains the full list of Nuclide's packages when they were -last released on 25 November 2015. This is safe to run even if you only have a subset of the -packages installed; `apm` will ignore any packages that are not present. - -```bash -$ apm uninstall \ -hyperclick \ -nuclide-arcanist \ -nuclide-blame \ -nuclide-blame-provider-hg \ -nuclide-blame-ui \ -nuclide-buck-files \ -nuclide-busy-signal \ -nuclide-clang-atom \ -nuclide-clipboard-path \ -nuclide-code-format \ -nuclide-code-highlight \ -nuclide-debugger-atom \ -nuclide-debugger-hhvm \ -nuclide-debugger-lldb \ -nuclide-diagnostics-store \ -nuclide-diagnostics-ui \ -nuclide-file-tree \ -nuclide-file-watcher \ -nuclide-find-references \ -nuclide-flow \ -nuclide-format-js \ -nuclide-fuzzy-filename-provider \ -nuclide-hack \ -nuclide-hack-symbol-provider \ -nuclide-health \ -nuclide-hg-repository \ -nuclide-home \ -nuclide-installer \ -nuclide-language-hack \ -nuclide-move-pane \ -nuclide-objc \ -nuclide-ocaml \ -nuclide-open-filenames-provider \ -nuclide-quick-open \ -nuclide-react-native-inspector \ -nuclide-recent-files-provider \ -nuclide-recent-files-service \ -nuclide-remote-projects \ -nuclide-test-runner \ -nuclide-toolbar \ -nuclide-type-hint \ -nuclide-url-hyperclick -``` - -## Flow Issues - -### Features Not Working - -If the Flow features are not working in Nuclide: - -- Make sure `flow` is in your [`$PATH`](#flow-issues__flow-and-path) environment variable. -- Ensure that you have `/* @flow */` at the top of your `.js` file. -- Ensure you have an empty `.flowconfig` file in the root of of your project directory. - -### `flow` and `$PATH` - -If you installed `flow` in a place not in your `$PATH` environment variable (e.g., unzipped it in your home directory), then you either have to update your `$PATH` environment variable or explicitly specify it. - -1. Open the **Settings** tab either by pressing `Cmd-,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-flow`. -5. Set the location of your `flow` installation in the **Path to Flow Executable** text box. - - - -### Module Not Found - -If you are [running Nuclide from source](/docs/advanced-topics/building-from-source/), you may -occasionally run into a `Cannot find module` error. - -![](/static/images/help/troubleshooting-module-not-found.png) - -As Nuclide is continuously updated, new modules may be added as dependencies. When you rebase to -the latest code and run Nuclide, the new module will not have been installed, so it will not be -found. - -Running `npm update` will get you the latest modules so that you should be able to open Nuclide -successfully again. - -## Buck Issues - -### Nuclide says Diagnostics are disabled, but Buck builds my C++ project - -Stand-alone header files are not fully supported yet because Buck doesn't report flags for them. - ->The majority of features may still work even without complete flags. You can provide more default flags in the Settings, if necessary. - -
- -1. Open the **Settings** tab either by pressing `Cmd-,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-clang`. -5. Add default flags as necessary. - - diff --git a/docs/_docs/languages/cpp.md b/docs/_docs/languages/cpp.md deleted file mode 100644 index ac2f7ce3b3..0000000000 --- a/docs/_docs/languages/cpp.md +++ /dev/null @@ -1,219 +0,0 @@ ---- -pageid: language-cpp -title: C++ -layout: docs -permalink: /docs/languages/cpp/ ---- - -Nuclide provides support for C++ developers. - -
- -* TOC -{:toc} - -## Supported Compilers - -In order to get the full features for a C++ project beyond basic syntax highlighting -and a generic autocomplete, you must have the following prerequisites installed: - -1. A compatible build system. You must have one of the following: - * [Buck](http://buckbuild.com) - With no additional setup required! - * [CMake](https://cmake.org/) - You will also have to generate a compilation database with the - [`CMAKE_EXPORT_COMPILE_COMMANDS`](http://clang.llvm.org/docs/JSONCompilationDatabase.html) - option via command-line and place it/symlink it in your project root. - Note that Nuclide does *not* provide any additional CMake integration at the moment. - * You can also manually create a compliant [`compile_commands.json`](http://clang.llvm.org/docs/JSONCompilationDatabase.html) in your project root. -2. [Clang](http://clang.llvm.org/) version 3.6 or higher (we recommend 3.8+) - -### Installing CMake and Clang - -*CMake* - -You can install CMake using one of the [pre-compiled binaries](https://cmake.org/install/) for -Linux and macOS. - -*Clang* - -Clang is generally provided by default on all major Linux distributions. You can use your packaging -system to install it (e.g., `sudo apt-get install clang libclang`). - -Note that **version 3.6 or higher is required**. We recommend 3.8 or above for best results. - -> You can [build Clang from source](http://clang.llvm.org/get_started.html) on Linux as well. - -On macOS, install Clang by installing [Xcode](https://developer.apple.com/xcode/). - -*Verify Install* - -You can verify that Clang is installed by typing `clang++ --version` on the command line. - -> A similar install process occurs for GNU `g++`. It is provided with Xcode, and you can install -> it via a Linux package (e.g., `sudo apt-get install g++`). - -*Building* - -Once Clang is installed, you need to build your C++ project with the `cmake` command, passing in the -`CMAKE_EXPORT_COMPILE_COMMANDS` flag. This will create a `compile_commands.json` file which lives -in the root of your project and provides the necessary information for the -[Nuclide C++ features support](#features). - -> If you use [Buck](#supported-compilers__installing-buck), you will not need to build with this -> flag. - -You may also provide additional project-wide compilation flags and include paths (such as `-isystem` -includes), as well as compilation flags to ignore, in a `.nuclide_clang_config.json` -file at the root of your project. These flags will specifically be used for the -[Nuclide C++ features](#features) that require libclang, rather than in the build process itself, -and they will be appended to the end of the compilation line. This file should look as follows: -> `{ 'extra_compiler_flags': [..], 'ignored_compiler_flags': [..] }` - -### Installing Buck - -Buck is [available](https://buckbuild.com/setup/install.html) via Homebrew on macOS, or you can -build from source on Linux. - -*Building* - -Your C++ project must be set up for a Buck build by creating [rules and targets](https://buckbuild.com/about/overview.html). - -## Features - -C++'s Nuclide integration provides you with productivity features such as: - -- [Code Diagnostics](#features__code-diagnostics) -- [Autocomplete](#features__autocomplete) -- [Jump To Declaration](#features__jump-to-declaration) -- [Jump Between Header and Implementation](#features__jump-between-header-and-implementation) -- [Type Hinting](#features__type-hinting) -- [Code Formatting](#features__code-formatting) - -> Remember that these features are only fully-enabled when used with a -> [supported compiler](#supported-compilers). - -### Code Diagnostics - -If you write code that doesn't compile correctly, Nuclide will warn you through its -[Code Diagnostics](/docs/editor/basics/#code-diagnostics) pane, as well with inline -[gutter](/docs/editor/basics/#gutter) tooltips (represented by a sideways red triangle). - -![](/static/images/docs/language-cpp-code-diagnostics.png) - -For [gutter diagnostics](/docs/editor/basics/#gutter), you will sometimes see a **Fix** button. For -some common errors (e.g., a missing semicolon), clicking the **Fix** button will fix the -problem for you. - -In this example, clicking the **Fix** button will insert a semicolon for you. - -![](/static/images/docs/language-cpp-code-diagnostics-gutter-fix.png) - -### Autocomplete - -Nuclide uses metadata from your Clang or Buck build to understand the objects within your project. -This allows for a detailed Autocomplete feature, providing you hints on what is available for a -given object. - -![](/static/images/docs/language-cpp-autocomplete.png) - -### Jump to Declaration - -You can click on a function call for your project and be taken directly to the declaration for that -function. - -Using `Cmd-` or `Cmd-Option-Enter` (`Ctrl-` or `Ctrl-Alt-Enter` on -Linux), the function call will be underlined. - -![](/static/images/docs/language-cpp-jump-to-declaration-link.png) - -Then, you will be taken to the declaration for that function. - -![](/static/images/docs/language-cpp-jump-to-declaration-result.png) - -### Jump Between Header and Implementation - -Using `Cmd-Option-N` (`Ctrl-Alt-N` on Linux), you can jump between the header (`.h`) and -implementation files (`.cpp`). - -### Type Hinting - -If you hover over a variable, Nuclide will show you a datatip with its type. - -![](/static/images/docs/language-cpp-type-hint.png) - -You can pin type hints to the main [Editing Area](/docs/editor/basics/#editing-area) so they -are always shown. - -Click on the pin icon of the type hint to pin the hint and the `x` icon to remove the pinned hint. Pinned type hints can be moved around and placed anywhere in the editing window. - -![](/static/images/docs/language-cpp-type-hint-pinned.png) - -> Hovering over a pinned type hint will highlight the variable associated with it. This is useful -> if you have two pinned type hints for variables on the same line. - -### Code Formatting - -Nuclide will format code based on a set of default Clang standards. - -1. Place your cursor on a function or line of code you wish to format. -2. Press `Cmd-Shift-C` (`Ctrl-Shift-C` on Linux), or use the context-aware menu and choose -**Format Code** to take a piece of code that looks like this... - -![](/static/images/docs/language-cpp-code-formatting-before.png) - -...and format it like this: - -![](/static/images/docs/language-cpp-code-formatting-after.png) - -## Debugging - -Nuclide supports [LLDB](http://lldb.llvm.org/) as the backend for its native C++ debugging. - -> At a minimum, you must have a C++ compiler (e.g., `g++` or `clang++`) and the LLVM Debugger -> (`lldb`) installed to use this feature. For example, on macOS, if you install -> [Xcode](https://developer.apple.com/xcode/) with its command-line tools, these will be installed -> for you. - -> Your C++ code must be compiled with debug symbols. For `g++` or `clang++`, this is accomplished -> by using `-g`. e.g., `clang++ hello.cpp -g -o hello.cpp`. If you are using `cmake` or some other -> build management system, ensure that you are compiling in debug mode with symbols. - -There are three ways to invoke the LLDB debugger: - -- [Attaching to a running process](#attaching-to-a-running-process) -- [Launching a process](#launching-a-process) -- [Debugging a Buck target](#debugging-a-buck-target) - -### Attaching to a running process - -Nuclide can attach to a running C++ process (after -[adding a C++ project](/docs/quick-start/getting-started/#adding-a-project) to Nuclide). Once you -compile your code, run it. - -NOTE: C++ debugging in Nuclide is not currently supported on Windows. - -1. Open the Debugger Selection window by pressing `Cmd-Shift-A` (`Ctrl-Shift-A` on Linux) or by clicking on the **Toggle Debugger** button in the [Nuclide toolbar](/docs/features/toolbar/#buttons). -2. Choose the **Native** tab. -3. Find your process in the list, and click the **Attach** button. - - - -After you attach to the process, the Nuclide Debugger appears to the right of the [Editing Area](/docs/editor/basics/#editing-area). -You can then debug your code normally, [following the Debugger guide](/docs/features/debugger/#basics). - -### Launching a process - -Launching a process is similar to the Attach flow. - -1. Open the Debugger Launch dialog by pressing `Cmd-F8` (`Ctrl-F8` on Linux) or by clicking on the **Toggle Debugger** button in the [Nuclide toolbar](/docs/features/toolbar/#buttons). -2. Choose the **Native** tab. -3. Fill out the fields, and click the **Launch** button. - - - -### Debugging a Buck target - -See the [Buck guide](/docs/features/task-runner/#buck__debug) for instructions on how to debug C++ Buck targets. - -### LLDB Commands - -You can run LLDB commands directly in the Nuclide Debugger [Console](/docs/features/debugger#basics__evaluation). diff --git a/docs/_docs/languages/flow.md b/docs/_docs/languages/flow.md deleted file mode 100644 index 5ff8f7344a..0000000000 --- a/docs/_docs/languages/flow.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -pageid: language-flow -title: Flow -layout: docs -permalink: /docs/languages/flow/ ---- - -Nuclide has deep, built-in support for [Flow-enabled](http://flowtype.org) JavaScript. - ->Flow recently became supported on Windows. See the [Windows is Supported!](https://flowtype.org/blog/2016/08/01/Windows-Support.html) Flow blog post for more information. - -
- -* TOC -{:toc} - -## Installing Flow - -In order to fully use the integration of Flow, you must have Flow installed on your system: - -1. [Install Flow](http://flowtype.org/docs/getting-started.html#installing-flow). -2. If you are new to Flow, [five simple examples](http://flowtype.org/docs/five-simple-examples.html) can get you started writing Flow programs. The -key items of note are: - * The `flow` path is in your `$PATH` environment variable. If it is not in your `$PATH` environment variable for any reason, you can specify the - path to the `flow` binary in `Settings | Packages | Nuclide | Settings | nuclide-flow: Path to Flow Executable`. - * You have an empty `.flowconfig` file in the root of your project. - * You have `/* @flow */` at the top of your JavaScript (`.js`) file. - -## Features - -Flow's integration into Nuclide provides you with productivity features such as: - -* [Code Diagnostics](#features__code-diagnostics) (e.g., inline Flow errors) -* [Autocomplete](#features__autocomplete) -* [Jump to Definition](#features__jump-to-definition) -* [Inline (mouseover) type hinting](#features__type-hinting) -* [Inline type coverage](#features__type-coverage) - -> These features will not work properly unless you are working with Flow-enabled JavaScript since -> they require a `.flowconfig` file in your project root and the ability to run the Flow -> typechecker (e.g., `flow`) from the project root. - -### Code Diagnostics - -If you write code that doesn't pass the Flow typechecker, Nuclide will provide you error details in -both its [Code Diagnostics](/docs/editor/basics/#status-bar__code-diagnostics) pane and inline -within the [Editing Area](/docs/editor/basics/#editing-area). - -![](/static/images/docs/language-flow-code-diagnostics.png) - -Hover over the sideways red triangle in the [gutter](/docs/editor/basics/#gutter) to see the Flow -error inline. - -![](/static/images/docs/language-flow-code-diagnostics-gutter.png) - -### Autocomplete -​​ -Given that Nuclide has access to all of the type information within your project along with the -built-in types provided by Flow, autocomplete just works. - -![](/static/images/docs/language-flow-autocomplete.png) - -By default suggestions from Flow will be shown first in the list of autocomplete results. -However if you don't want this behavior (e.g. you want snippets to be on top), -you can configure priority in Nuclide's preferences. - -### Jump To Definition - -Nuclide provides a jump to definition/symbol feature for Flow programs. - -For example, if you want to go to the definition of `arr_length()`, hover over -`arr_length()`and either press `Cmd-` (`Ctrl-` on Linux) or -`Cmd-Option-Enter` (`Ctrl-Alt-Enter` on Linux). - -![](/static/images/docs/language-flow-jump-to-definition-link.png) - -![](/static/images/docs/language-flow-jump-to-definition-result.png) - -### Type Hinting - -If you hover over a variable in your Flow file, you can get the type of the variable directly -inline. - -![](/static/images/docs/language-flow-typehint.png) - -In fact, you can even pin that type hint so that it always displays. Just click on the pin icon -when hovering over a variable to pin it. - -​​![](/static/images/docs/language-flow-pinned-typehint.png) - -The highlighted variables show that their type variables have been pinned. If you hover over the -type hint, its associated variable will have motion in its highlight. - -Click the `x` icon of a pinned type hint to remove it. - -> Pinned type hints can be moved anywhere within the editor. - -### Type Coverage - -Nuclide can show you how much of your Flow file is covered by the type system with Type Coverage. - -![](/static/images/docs/language-flow-type-coverage.png) - -If the percentage is less than 100%, you can toggle the Type Coverage inline display to show you where the issues are. - -From the [Command Palette](/docs/editor/basics/#command-palette), choose `Nuclide Type Coverage: Toggle Inline Display`. You can also either press `Ctrl-Option-Shift-V` (`Ctrl-Alt-Shift-V` on Linux) or simply click on the percentage displayed in the [Status Bar](/docs/editor/basics/#status-bar). - -Hover over any sideways triangles that appear in the gutter to see the type check issue inline, or open the [Diagnostics Table](/docs/editor/basics/#status-bar__code-diagnostics) to see them all listed together. Clicking on any issue in the Diagnostics Table will highlight the associated line. - -![](/static/images/docs/language-flow-type-coverage-inline.png) diff --git a/docs/_docs/languages/graphql.md b/docs/_docs/languages/graphql.md deleted file mode 100644 index 1d547ffb4a..0000000000 --- a/docs/_docs/languages/graphql.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -pageid: language-graphql -title: GraphQL -layout: docs -permalink: /docs/languages/graphql/ ---- - -Nuclide has built-in support for [GraphQL](http://graphql.org/) using the [GraphQL Language Service](https://github.com/graphql/graphql-language-service). - -* TOC -{:toc} - -## Installing GraphQL - -Several [server libraries](http://graphql.org/code/) are provided for GraphQL implementation in a wide range of languages. - -The GraphQL Language Service needs to know some information about your GraphQL development environment to provide its full feature set. A GraphQL configuration file (`.graphqlrc`) contains this information. The `.graphqlrc` file can define multiple configurations for each GraphQL environment, should you have more than one. - -Make sure the `.graphqlrc` file is configured and saved in your project's top-level directory. For more information on how to configure your `.graphqlrc` file, refer to the [GraphQL Language Service documentation](https://github.com/graphql/graphql-language-service#graphql-configuration-file-graphqlrc). - -Opening a `.graphql` file in Nuclide will trigger the GraphQL support. - -## Features - -GraphQL's integration into Nuclide provides you with productivity features such as: - -- [Autocomplete](#features__autocomplete) -- [Go to Definition](#features__go-to-definition) -- [Outline View](#features__outline-view) -- [Context View](#features__context-view) -- [Code Diagnostics](#features__code-diagnostics) - -### Autocomplete - -Nuclide has access to the schema type information in your project when the GraphQL configuration file (`.graphqlrc`) is defined, so autocomplete just works. - -![](/static/images/docs/language-graphql-autocomplete.png) - -### Go to Definition - -Nuclide provides a **Go to Definition** feature for fragments in `.graphql` files. - -For example, if you want to go to the definition of `pilotFragment`, hover over `...pilotFragment` and either press `Cmd-` or `Cmd-Option-Enter`. You can also *right-click* on the fragment, and select **Go to Declaration** from the pop-up menu. - -![](/static/images/docs/language-graphql-gotodefinition.png) - -The cursor will jump to the definition even if it's in another file. - -![](/static/images/docs/language-graphql-definitionjump.png) - -### Outline View - -Nuclide's [Outline View](/docs/features/outline-view) allows you to see an outline of a `.graphql` file's queries, fragments, fields, etc. at-a-glance so you can navigate quickly. - -![](/static/images/docs/language-graphql-outline-view.png) - -### Context View - -Nuclide's [Context View](/docs/features/context-view) allows you to quickly see and navigate between fragments and their definitions. - -![](/static/images/docs/language-graphql-context-view.png) - -### Code Diagnostics - -Nuclide has code diagnostics that will show lint and validation errors in your `.graphql` file. You can see the errors in two places, inline within the [Editing Area](/docs/editor/basics/#editing-area) and in the [Code Diagnostics](/docs/editor/basics/#status-bar__code-diagnostics) pane below. - -![](/static/images/docs/language-graphql-diagnostics-pane.png) - -Hover over the sideways red triangle in the [gutter](/docs/editor/basics/#gutter) to see the error inline. - - diff --git a/docs/_docs/languages/hack.md b/docs/_docs/languages/hack.md deleted file mode 100644 index 97d2bb7c43..0000000000 --- a/docs/_docs/languages/hack.md +++ /dev/null @@ -1,207 +0,0 @@ ---- -pageid: language-hack -title: Hack -layout: docs -permalink: /docs/languages/hack/ ---- - -Nuclide has been built from the start to provide a great IDE experience for -[Hack](http://hacklang.org) development. Hack is a programming language for -[HHVM](http://hhvm.com). - -> Currently, HHVM is [not supported on Windows](https://docs.hhvm.com/hhvm/installation/windows), so -> this integration has limited viability on that platform. However, -> [work is being done](https://github.com/facebook/hhvm/issues/5460) to port HHVM to Windows. - -
- -* TOC -{:toc} - -## Installing Hack - -In order to fully use the integration of Hack, you must have both Hack and HHVM installed on your -system: - -1. [Install HHVM](https://docs.hhvm.com/hhvm/installation/introduction). By default, Hack is -installed with HHVM. -2. If you are new to Hack, HHVM's [Getting Started](https://docs.hhvm.com/hack/getting-started/getting-started) provides [steps for writing your first Hack program](https://docs.hhvm.com/hack/getting-started/getting-started#your-first-hack-program). The -key items of note are: - * The typechecker `hh_client` is in your `$PATH` environment variable (the default install of - HHVM, should place it there). - * You have an `.hhconfig` file at the root of your project. - * You have ` If you are planning on developing with Hack [remotely](/docs/features/remote), ensure HHVM and -> Hack are installed on the *remote* machine. - -## Features - -Hack's integration into Nuclide provides you with productivity features such as: - -* [Code Diagnostics](#features__code-diagnostics) -* [Autocomplete](#features__autocomplete) -* [Jump to Definition](#features__jump-to-definition) -* [Inline (mouseover) type hinting](#features__type-hinting) -* [Code formatting](#features__code-formatting) -* [OmniSearch](/docs/features/quick-open), with a special [Hack symbol](/docs/features/quick-open#hack-symbols) search pane. - -### Code Diagnostics - -If your code doesn't correctly [typecheck](https://docs.hhvm.com/hack/typechecker/introduction), Nuclide has code diagnostics that will show you the error. You can see the error in two places, inline within the -[Editing Area](/docs/editor/basics/#editing-area) and in the -[Code Diagnostics](/docs/editor/basics/#status-bar__code-diagnostics) pane below. - -![](/static/images/docs/language-hack-code-diagnostics.png) - -Hover over the sideways red triangle in the [gutter](/docs/editor/basics/#gutter) to see the Hack -error inline. - -![](/static/images/docs/language-hack-code-diagnostics-gutter.png) - -### Autocomplete - -Given that Nuclide has access to all of the type information within your project and the built-in -types provided by Hack, autocomplete just works. - -![](/static/images/docs/language-hack-autocomplete.png) - -### Jump to Definition - -Nuclide provides a jump to definition/symbol feature for Hack programs. - -> In order for this to work, you must have an `.hhconfig` file in the root of your project and a -> running `hh_server` monitoring the root as well. - -For example, if you want to go to the definition of `getPages()`, hover over `getPages()` -and either press `Cmd-` or `Cmd-Option-Enter` (`Ctrl-Alt-Enter` on Linux). - -![](/static/images/docs/language-hack-jump-to-definition-link.png) - -![](/static/images/docs/language-hack-jump-to-definition-result.png) - -### Type Hinting - -If you hover over a variable in your Hack file, you can get the type of the variable directly -inline. - -![](/static/images/docs/language-hack-typehint.png) - -In fact, you can even pin that type hint so that it always displays. Just click on the pin icon -when hovering over a variable to pin it. - -![](/static/images/docs/language-hack-pinned-typehint.png) - -The highlighted variables show that their type variables have been pinned. If you hover over the -type hint, its associated variable will have motion in its highlight. - -Click the `x` icon of a pinned type hint to remove it. - -> Pinned type hints can be moved anywhere within the editor. - -### Type Coverage - -Nuclide can show you how much of your Hack file is covered by the type system with Type Coverage. - -![](/static/images/docs/language-hack-type-coverage.png) - -If the percentage is less than 100%, you can toggle the Type Coverage inline display to show you where the issues are. - -From the [Command Palette](/docs/editor/basics/#command-palette), choose `Nuclide Type Coverage: Toggle Inline Display`. You can also either press `Ctrl-Option-Shift-V` (`Ctrl-Alt-Shift-V` on Linux) or simply click on the percentage displayed in the [Status Bar](/docs/editor/basics/#status-bar). - -Hover over any sideways triangles that appear in the gutter to see the type check issue inline, or open the [Diagnostics Table](/docs/editor/basics/#status-bar__code-diagnostics) to see them all listed together. Clicking on any issue in the Diagnostics Table will highlight the associated line. - -![](/static/images/docs/language-hack-type-coverage-inline.png) - -### Code Formatting - -Nuclide can take your Hack code and format it according to a built-in set of coding standards -(e.g, two-space indents, bracket location, etc.). - -For example, here is a bit of code that looks relatively haphazard from a formatting perspective. - -![](/static/images/docs/language-hack-badly-formatted.png) - -Place your cursor inside the function and press `Cmd-Shift-C` (`Ctrl-Shift-C` on Linux) to apply the coding standards to the function. - -![](/static/images/docs/language-hack-well-formatted.png) - -## Debugging - -Nuclide supports debugging PHP and Hack applications running on [HHVM](https://docs.hhvm.com/hhvm/installation/introduction). **HHVM version 3.25.0 or greater is required,** as older versions do not support the Visual Studio Code Debug Adapter Protocol, which is the debugging protocol Nuclide now uses. - -> Note: debugging PHP servers other than HHVM is no longer supported in Nuclide. In previous versions, Nuclide supported debugging via the XDebug protocol, but this is also no longer supported. Debugging older HHVM versions (< 3.25.0) with Nuclide is not possible. - -### Configuring HHVM for debugging - -To enable debugging Hack/PHP applications **in webserver mode**, you'll need to add -the following to your server's config.ini: - -``` -hhvm.debugger.vs_debug_enable=1 -``` - -By default, HHVM will listen for incoming debugger connections on port 8999. You can specify a different port by adding an additional line to your config.ini: -``` -hhvm.debugger.vs_debug_listen_port= -``` - -More information about configuring HHVM can be found here: [HHVM Configuration](https://docs.hhvm.com/hhvm/configuration/introduction) - -If you want to debug a Hack/PHP script running in **script mode**, you simply add a couple extra command line parameters when invoking HHVM: - -``` -hhvm --mode vsdebug --vsDebugPort -``` - -The above command will startup HHVM with the debugger listening on the specified port, and will wait forever for the debugger to connect before starting the script. You can add an additional optional parameter, `--vsDebugNoWait true` to cause HHVM to begin execution of the script immediately, while still allowing the debugger to connect and break in later. This mode is especially useful for long-running scripts that you may want to break into to debug things like infinite loops, hangs, etc. - - -In order for Nuclide to be able to connect to your HHVM instance, you'll need to either have Nuclide server on the same host as HHVM and use a remote project, or forward the HHVM debugger port to your local machine via SSH tunneling or some other means. - -We *strongly* advise against exposing the HHVM debugger port to the internet on production machines, for obvious security reasons. - - -### Configuring Nuclide to debug HHVM - -There are two configuration options in Nuclide settings that you'll want to configure for HHVM if you want to launch scripts in debug mode. You don't need to configure these if you only want to attach to a webserver. - -![](/static/images/docs/debugger-hhvm-settings.png) - -The first is the full path to your HHVM runtime binary, and the second is any arguments Nuclide should pass when starting HHVM, such as the path to your config.ini. These arguments will be passed verbatim on the command line when invoking HHVM. - -Additionally, you may specify an optional attach port to use when attaching to webserver mode, if you've configured your server to listen on a port other than 8999. - - -### Debugging: HHVM Toolbar - -The [Task Runner toolbar](/docs/features/task-runner) is one way to debug Hack or PHP projects. To open the Task Runner toolbar, click on the **Toggle Task Runner Toolbar** button in the [Nuclide toolbar](/docs/features/toolbar/#buttons) or search for `Nuclide Task Runner: Toggle HHVM Toolbar` in the [Command Palette](/docs/editor/basics/#command-palette). - -See the [Task Runner HHVM guide](/docs/features/task-runner/#hhvm-debug-toolbar) for instructions on debugging Hack or PHP projects. - -### Debugging: Launch / Attach Dialogs - -The HHVM debugger can also be started via our advanced configuration dialogs. You'll find these under the Nuclide menu (Nuclide -> Debugger -> [Launch | Attach] Debugger), and select the "Hack / PHP" tab, which will be offered if your current working root is a remote project that supports HHVM. - -When launching, Nuclide will prompt for the path to your Hack/PHP script, and any arguments you'd like Nuclide to pass to it. - -When attaching, Nuclide will offer to connect to your webserver instance, or attach to an already-running script that was started with the `--mode vsdebug --vsDebugPort ` HHVM arguments. - -### Console - -When debugging a *script*, all output from HHVM's stdout and stderr is redirected to the Nuclide console. When debugging a *webserver*, stdout is redirected, but stderr is not due to the output traffic being too high. - -The console also provides a REPL that allows you to execute Hack/PHP code (see below). - -### Console Evaluation - -Basic [evaluation](/docs/features/debugger/#basics__evaluation) in the REPL works out of the box for built in Hack/PHP routines. - -Nuclide now executes console input **as Hack by default**, instead of PHP. For many commands, there is no difference, but the behavior between Hack and PHP differs in some contexts, so this is important to know. You can explicitly have the debugger run your code as Hack or PHP by beginning your input with ` Linux does not have Xcode. However, there are ways to compile Objective-C programs on Linux using -> `gobjc`, [`gnustep`](http://www.gnustep.org/), etc. - -However, to get the full [feature list](#buck-enabled-features) for Objective-C support, you must -compile your Objective-C program with [Buck](http://buckbuild.com). - -## Default Features - -Objective-C's integration into Nuclide provides you with productivity features out-of-the-box such -as: - -* [Automatic Square Bracket Completion](#default-features__automatic-square-bracket-completion) -* [Automatic Colon Indenting](#default-features__automatic-colon-indenting) - -### Automatic Square Bracket Completion - -If you forget to put a starting bracket at the front of your target or selector, one will be inserted -for you automatically if you add the ending bracket. This will work for any number of bracket -levels deep. - -For example, if you add an ending bracket here... - -![](/static/images/docs/language-objc-before-bracket-insert.png) - -... then the beginning bracket is inserted for you automatically. - -![](/static/images/docs/language-objc-after-bracket-insert.png) - -To enable this setting: - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-objc`, and select the **Enable Automatic Square Bracket Completion** checkbox. - -![](/static/images/docs/language-objc-auto-bracket-completion-setting.png) - -### Automatic Colon Indenting - -Nuclide will automatically indent the colons (`:`) associated with new method arguments to be -aligned with the arguments of that method. - -If you start a `:` at the beginning of the next line after the method declaration... - -![](/static/images/docs/language-objc-before-colon-indent.png) - -... it will be aligned automatically. - -![](/static/images/docs/language-objc-after-colon-indent.png) - -## Buck-enabled Features - -The following features require that your Objective-C project is compiled with [Buck](http://buckbuild.com). - -> You can also generate a `compile_commands.json` file with the -> [`json-compilation-databse` reporter](https://github.com/facebook/xctool#included-reporters) -> of [`xctool`](https://github.com/facebook/xctool) to get these features. - -
- -* [Code Diagnostics](#buck-enabled-features__code-diagnostics) -* [Inline Type Hints](#buck-enabled-features__type-hints) -* [Autocomplete](#buck-enabled-features__autocomplete) -* [Jump to Definition](#buck-enabled-features__jump-to-definition) - -> The [Buck toolbar](/docs/features/buck) allows you to build and run your Buck-enabled programs. - -### Code Diagnostics - -If you write code that will cause `clang` errors or warnings, Nuclide's Code Diagnostics will show -you the error. You can see the error in two places: inline within the -[Editing Area](/docs/editor/basics/#editing-area), and in the [Code Diagnostics](/docs/editor/basics/#status-bar__code-diagnostics) pane below. - -![](/static/images/docs/language-objc-code-diagnostics.png) - -Hover over the sideways red triangle in the [gutter](/docs/editor/basics/#gutter) to see the `clang` error inline. - -![](/static/images/docs/language-objc-lint-gutter.png) - -### Type Hints - -Hovering over an Objective-C object will provide you the type of that object inline. - -![](/static/images/docs/language-objc-typehint.png) - -In fact, you can even pin that type hint so that it always displays. Just click on the pin icon when hovering over a variable to pin it. - -![](/static/images/docs/language-objc-pinned-typehint.png) - -Click the `x` icon of a pinned type hint to remove it. - -> Pinned type hints can be moved anywhere within the editor. - -### Autocomplete - -Buck enhances the understanding of the types of objects in your project so that autocomplete can be -enabled. - -![](/static/images/docs/language-objc-autocomplete.png) - -> Without Buck, you will still get the default autocomplete feature, but without project and object -> specific information. - -### Jump To Definition - -Nuclide provides a jump to definition/symbol feature for Objective-C programs. - -For example, if you want to go to the definition of `initWithHelloString:`, hover over -`initWithHelloString:` and either press `Cmd-` (`Ctrl-` on Linux) or -`Cmd-Option-Enter` (`Ctrl-Alt-Enter` on Linux). - -![](/static/images/docs/language-objc-jump-to-definition-link.png) - -![](/static/images/docs/language-objc-jump-to-definition-result.png) - -### Jump Between Header and Implementation - -Using `Cmd-Option-N` (`Ctrl-Alt-N` on Linux), you can jump between the header (i.e., `.h`) and -the implementation (i.e., `.cpp` or `.m`) files. - -## Debugging - -Nuclide has support for [iOS](/docs/platforms/ios) debugging and [Buck](http://buckbuild.com) -for native Objective-C applications (i.e., `.m` files). - -> Debugging Swift applications is currently not supported. - -See the [Buck guide](/docs/features/buck) for how to build, run and debug iOS apps. - -> Optimally, it would be nice to run the application directly from Xcode and attach to the -> simulator process associated with that Xcode project. However, due to `lldb` process conflict -> issues, this is currently not possible. - -### LLDB Commands - -Native iOS debugging uses [LLDB](http://lldb.llvm.org/) as its debugging backend. You can run LLDB -commands directly in the Nuclide Debugger's [Console](/docs/features/debugger#basics__evaluation). diff --git a/docs/_docs/languages/other.md b/docs/_docs/languages/other.md deleted file mode 100644 index 78dab89637..0000000000 --- a/docs/_docs/languages/other.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -pageid: language-other -title: PHP, JS, OCaml -layout: docs -permalink: /docs/languages/other/ ---- - -Nuclide provides support for other languages as well. Some of these are not as full-featured as -similar languages (e.g., Hack vs PHP); others are experimental. - -* TOC -{:toc} - -## PHP - -Nuclide's PHP support is similar to its support for [Hack](/docs/languages/hack), except you will -not get as full-featured diagnostics, type hinting, etc. since there is no -[typechecker](https://docs.hhvm.com/hack/typechecker/introduction) to assist Nuclide with your project's metadata. - -## JavaScript - -Nuclide's JavaScript support is similar to its support for [Flow](/docs/languages/flow), except -you will not get as full-featured diagnostics, type hinting, etc. since there is no -[typechecker](http://flowtype.org/) to assist Nuclide with your project's metadata. - -JavaScript is a primary language for [React Native](https://facebook.github.io/react-native/), and -Nuclide is a great IDE for [developing React Native applications](/docs/platforms/react-native). - -## OCaml - -This **experimental** feature provides rudimentary support for OCaml via -[ocamlmerlin](https://github.com/the-lambda-church/merlin). Merlin can be installed from source -or by installing the `merlin` OPAM package. - -OCaml's integration into Nuclide provides you with productivity features such as: - -* Autocomplete -* Jump to Definition - -It requires that `ocamlmerlin` be installed on your system and properly configured for your -project. `ocamlmerlin` should be in your `$PATH` environment variable. If it is not, you may specify the path to -`ocamlmerlin` in the settings for the 'nuclide' package. - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-ocaml`, and enter the custom path in the **Path to Merlin Executable** text box. diff --git a/docs/_docs/languages/python.md b/docs/_docs/languages/python.md deleted file mode 100644 index 73517a4f3d..0000000000 --- a/docs/_docs/languages/python.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -pageid: language-python -title: Python -layout: docs -permalink: /docs/languages/python/ ---- - -Nuclide has well-rounded support for Python 2 and 3. - -* TOC -{:toc} - -## Using Python Features with Buck Projects - -If your code uses Buck to manage Python dependencies, you will need to build -your project's `python_binary` target in order for autocomplete and -jump to definition to find results from dependencies. - -## Features - -Python's integration into Nuclide provides you with productivity features such as: - -- [Autocomplete](#features__autocomplete) -- [Jump To Definition](#features__jump-to-definition) -- [Code Formatting](#features__code-formatting) -- [Code Diagnostics](#features__code-diagnostics) -- [Outline View](#features__outline-view) - -### Autocomplete - -Nuclide integrates [Jedi](http://jedi.jedidjah.ch/) to provide fast, -detailed, and context-aware autocompletion. - -![](/static/images/docs/language-python-autocomplete.png) - -By default, Nuclide will provide tab-able snippets for function and method -arguments. To turn this behavior on or off: - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-python`, and select or deselect the **Autocomplete arguments** checkbox. - -### Jump to Definition - -Nuclide allows you to directly jump to definition for local or imported symbols -alike. - -For example, to go to the definition of `get_all_patches()`, you can -hover over `get_all_patches()`and either press `Cmd-` -(`Ctrl-` on Linux) or `Cmd-Option-Enter` (`Ctrl-Alt-Enter` on Linux). - -![](/static/images/docs/language-python-jump-to-definition-link.png) - -![](/static/images/docs/language-python-jump-to-definition-result.png) - -Jump to definition also works for [Buck](http://buckbuild.com) config files. -Since `BUCK` files are written in Python, you can use `Cmd-` -(`Ctrl- Nuclide's built-in Swift support is not endorsed by Apple. The Swift - logo is a registered trademark of Apple Inc. - -
- -* TOC -{:toc} - -## Configuring Nuclide for Swift Package Development - -Nuclide will attempt to find a Swift executable automatically: - -- On macOS, it will use the latest version of Swift installed at `/Library/Developer/Toolchains/swift-latest.xctoolchain`. -- On Linux, it will find a Swift executable based on your `$PATH`. - -You may use a specific version of Swift by setting the **Swift Toolchain Path** in the Nuclide settings: - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-swift`, and enter the Toolchain path in the **Swift Toolchain Path** text box. - -![](/static/images/docs/language-swift-toolchain-path-setting.png) - -Nuclide uses [SourceKitten](https://github.com/jpsim/SourceKitten) to provide features such as [Autocomplete]((#features__autocomplete)). - -On macOS, Nuclide expects to find a SourceKitten executable at `/usr/local/bin/sourcekitten`. Installing SourceKitten via [Homebrew](http://brew.sh/), by running `brew install sourcekitten` at the command line, places it in this location. - -> Unfortunately, SourceKitten is not yet available on Linux. As a result, - features such as [Autocomplete](#features__autocomplete) are only available on macOS. - -You may configure Nuclide to use a SourceKitten executable at a different location by setting the **Path to SourceKitten Executable** in the Nuclide -settings. - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-swift`, and enter the custom SourceKitten path in the **Path to SourceKitten Executable** text box. - -## Features - -Swift integration in Nuclide provides you with productivity features such as: - -- [Building and Testing Swift packages](#features__building-and-testing-swift-packages) -- [Autocomplete](#features__autocomplete) - -### Building and Testing Swift packages - -The [Task Runner toolbar](/docs/features/task-runner) is used to build and test Swift packages. To open the Task Runner toolbar, click on the **Toggle Task Runner Toolbar** button in the [Nuclide toolbar](/docs/features/toolbar/#buttons) or search for `Nuclide Task Runner: Toggle Swift Toolbar` in the [Command Palette](/docs/editor/basics/#command-palette). - -See the [Task Runner Swift guide](/docs/features/task-runner/#swift) for how to build and test Swift packages. - -### Autocomplete - -Once you have [built your Swift package](#features__building-a-swift-package) via the [Task Runner's](/docs/features/task-runner) [Swift toolbar](/docs/features/task-runner/#swift), Nuclide will be able to provide autocompletion suggestions for Swift source code. - -![](/static/images/docs/language-swift-autocompletion.png) diff --git a/docs/_docs/platforms/android.md b/docs/_docs/platforms/android.md deleted file mode 100644 index 3f4fb406bf..0000000000 --- a/docs/_docs/platforms/android.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -pageid: platform-android -title: Android -layout: docs -permalink: /docs/platforms/android/ ---- - -Nuclide's support for Android is currently much more basic and limited than that for -[iOS](/docs/platforms/ios). If you are a [React Native](/docs/platforms/react-native) developer for Android, there is more -full-featured support for the [Flow](/docs/languages/flow) or [JavaScript](/docs/languages/other/#javascript) side of your application. For debugging, there is -currently built-in support for [ADB logs](#emulator-logs). - -> This section discusses primarily native Android development since there is a whole separate -> section dedicated to [React Native](/docs/platforms/react-native). - -
- -* TOC -{:toc} - -## Features - -When you open an Android Java file (i.e., `.java`), you only get the basic syntax highlighting and -quick-completion capabilities given to you by Atom. - -## Running Applications - -Currently, the easiest way to build and run a native Android application is from an IDE such as -Android Studio. You can also use the command-line tools such as `adb`, `am`, etc. - -## Debugging - -Debugging Android applications is currently not supported except through the logs provided -by Nuclide's [Android Debug Bridge (ADB) Logcat support](#emulator-logs). - -## Emulator Logs - -When running your Android project in the Android emulator, you can open and view the emulator logs -directly within Nuclide. From the [Command Palette](/docs/editor/basics/#command-palette), search -for `Nuclide Adb Logcat: Start`. - -![](/static/images/docs/platform-android-toggle-simulator.png) - -![](/static/images/docs/platform-android-simulator-output.png) - -> Currently, the logs are very verbose as they do not delineate between actual underlying emulator -> information with the actual running application. diff --git a/docs/_docs/platforms/ios.md b/docs/_docs/platforms/ios.md deleted file mode 100644 index c28cd3084d..0000000000 --- a/docs/_docs/platforms/ios.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -pageid: platform-ios -title: iOS -layout: docs -permalink: /docs/platforms/ios/ ---- - -Nuclide supports both native iOS development in [Objective-C](/docs/languages/objective-c) and -cross-platform development in [React Native](/docs/platforms/react-native). - -> This section discusses primarily native iOS development since there is a whole separate section -> dedicated to [React Native](/docs/platforms/react-native). - -
- -* TOC -{:toc} - -## Features - -When you open an [Objective-C](/docs/languages/objective-c/) file (e.g., `.h`, `.m`, `.mm`), you -automatically get support for default [features](/docs/languages/objective-c/#default-features) such -as [Automatic Square Bracket Completion](/docs/languages/objective-c/#default-features__automatic-square-bracket-completion). - -However, if you compile your project with [Buck](http://buckbuild.com), you get richer -[features](/docs/languages/objective-c/#buck-enabled-features) such as -[Autocomplete](/docs/languages/objective-c/#buck-enabled-features__autocomplete) and -[Jump to Definition](/docs/languages/objective-c/#buck-enabled-features__jump-to-definition). - -![](/static/images/docs/platform-ios-native-autocomplete.png) - -## Running Applications - -Currently, the easiest way to build and run a native iOS application is from Xcode itself. -You can also use the command-line tools such as `xcodebuild`, etc. - -### Buck Integration - -Nuclide supports the [Buck](https://buckbuild.com/) build system. See the -[Buck guide](/docs/features/buck) for how to build, run, and debug iOS apps. - -## Debugging - -Debugging native [Objective-C](/docs/languages/objective-c/) iOS applications is -[supported using Buck](/docs/features/buck/#debug). - -## Simulator Logs - -When running your iOS project in the iOS simulator, you can open and view the simulator logs -directly within Nuclide. From the [Command Palette](/docs/editor/basics/#command-palette), search -for `Nuclide iOS Simulator Logs: Start`. - -![](/static/images/docs/platform-ios-toggle-simulator.png) - -![](/static/images/docs/platform-ios-simulator-output.png) - -> Currently, the logs are very verbose as they do not delineate between actual underlying simulator -> information with the actual running application. diff --git a/docs/_docs/platforms/react-native.md b/docs/_docs/platforms/react-native.md deleted file mode 100644 index eb76225c96..0000000000 --- a/docs/_docs/platforms/react-native.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -pageid: platform-react-native -title: React Native -layout: docs -permalink: /docs/platforms/react-native/ ---- - -Nuclide has built-in support for the [React Native](https://facebook.github.io/react-native/) -framework. React Native provides a set of components and extensions that allows you to easily write -native iOS and Android applications using the [Flow](/docs/languages/flow) and -[JavaScript](/docs/languages/other#javascript) programming languages and the -[React](http://facebook.github.io/react/) UI library. - -* TOC -{:toc} - -## Features - -If your React Native apps are primarily written in [Flow](/docs/languages/flow), you get all of its -[features](/docs/languages/flow/#features) within Nuclide, including -[Autocomplete](/docs/languages/flow/#autocomplete), -[Code Diagnostics](/docs/languages/flow/#features__code-diagnostics), etc. - -![](/static/images/docs/platform-react-native-feature-autocomplete.png) - -> [JavaScript](/docs/languages/other/#javascript) works well with Nuclide as well. - -> You can also write [native iOS (Objective-C)](/docs/platforms/ios) code with React Native, and get -> features such as [Automatic Square Bracket Completion](/docs/languages/objective-c/#default-features__automatic-square-bracket-completion) from Nuclide when doing so. Native Android code written in conjunction with React Native has [minimal support](/docs/platforms/android). - -## Running applications - -All React Native features are currently available from the [Command Palette](/docs/editor/basics/#command-palette). - -You run Metro from Nuclide and your application from the command line. - -### Metro - -From the [Command Palette](/docs/editor/basics/#command-palette), choose `Nuclide Metro: Start` to start Metro. The output in the `Console` panel indicates if Metro started or if it encountered any errors. - -![](/static/images/docs/platform-react-native-start-packager.png) - -The server runs on the default `port 8081`. You can stop and restart the server at anytime. - -### Command Line - -Ensure that you are in the root directory of the React Native project, then run the application from the command-line: - -```bash -$ react-native run-ios -$ react-native run-android -``` - -This should bring up the Simulator with your running application inside. - -## Support - -Nuclide has support for [React Native](https://facebook.github.io/react-native/) for [iOS](/docs/platforms/ios). - -From Nuclide, you can start a React Native development server, inspect React Native elements. - -> In order to use React Native within Nuclide, you must -> [install](https://facebook.github.io/react-native/docs/getting-started.html) it. - -### Loading a React Native Project - -You open a React Native project the -[usual way](/docs/quick-start/getting-started/#adding-a-project). Nuclide will automatically -establish that you have a React Native project by seeing the `node_modules/react-native` directory -from the root of your project. - -### Metro - -[Launch Metro from within Nuclide](#running-applications__metro). - -### Run the React Native Application - -[Start your React Native application from the command-line](#running-applications__command-line). - -### Element Inspector - -Nuclide provides an Element Inspector, where you can view and toggle properties of your application. - -From the [Command Palette](/docs/editor/basics/#command-palette), choose `Nuclide React Inspector: Show` to open the **React Inspector** tab in the -main [Editing Area](/docs/editor/basics/#editing-area). - -![](/static/images/docs/platform-react-native-element-inspector.png) - -To see the actual elements highlighted in the Nuclide Element Inspector also highlighted in the -Simulator, you must enable the Simulator Inspector as well. Press `Cmd-D` (`Ctrl-D` on Linux) within -the Simulator and choose **Show Inspector**. - -![](/static/images/docs/platform-react-native-show-inspector.png) - -## Simulator Logs - -Nuclide supports the [iOS Simulator logs](/docs/platforms/ios#simulator-logs) and -[Android Emulator logs](/docs/platforms/android#emulator-logs) directly within Nuclide. - -## Debugging - -Nuclide's new React Native debugger support is ported from -[vscode-react-native](https://github.com/Microsoft/vscode-react-native) at -version 0.5.7 ([fork source](https://github.com/pelmers/vscode-react-native/tree/nuclide)). -There are two ways to invoke the React Native debugger. Nuclide can either attach to -a running packager, or it can launch the debug target in a new packager for -debugging. Note that the debugger from Nuclide can only attach if the default -Chrome debugger is not already running. - -Both cases require a workspace path which should be set to the directory -containing the `package.json` file of the debug target. Launching the debugger -also requires specifying the platform to debug, either `ios` or `android` as -well as the target, either `simulator` or `device`. Note that debugging on an -iOS device requires some manual setup; see -[these instructions](https://github.com/Microsoft/vscode-react-native/blob/master/doc/debugging.md#debugging-on-ios-device). -In most cases the default port setting of 8081 will be correct. - -> Changing the port setting in the debugger may require external setup, see -> [the issue on GitHub](https://github.com/facebook/react-native/issues/9145) - -![](/static/images/docs/platform-react-native-debugger-ex.png) - -> A DeprecationWarning: 'root' is deprecated error may appear when the program -> first runs, which can be safely dismissed. diff --git a/docs/_docs/platforms/web.md b/docs/_docs/platforms/web.md deleted file mode 100644 index 353e4e5d2b..0000000000 --- a/docs/_docs/platforms/web.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -pageid: platform-web -title: Web Development -layout: docs -permalink: /docs/platforms/web/ ---- - -The development of modern websites makes use of both server-side and client-side web technologies. -Nuclide makes web developers more productive in this process. - -* TOC -{:toc} - -## Server-side Development - -[Hack](/docs/languages/hack) has first-class support in Nuclide. In conjunction with -[HHVM](http://docs.hhvm.com), Hack offers quick development and testing with the comfort of -[type safety](https://docs.hhvm.com/hack/typechecker/introduction). Nuclide enhances this by -utilizing Hack's information to deliver developer productivity features such as -[Autocomplete](/docs/languages/hack/#features__autocomplete) and -[inline error checking](/docs/languages/hack/#features__code-diagnostics). - -If you are a [PHP](http://php.net) developer, Nuclide has [support](/docs/languages/other/#php) for that as well. - -## Client-side Development - -[Flow](/docs/languages/flow) has first-class support in Nuclide. Flow gives you -[type safety](http://flowtype.org) as you develop, and Nuclide uses the information provided by -Flow to enhance developer productivity. This includes -[Jump to Definition](/docs/languages/flow/#jump-to-definition) and -[Type Hinting](/docs/languages/flow/#type-hinting). - -If you are a [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) developer, -Nuclide has [support](/docs/languages/other/#javascript) for that as well. - -## Scripting - -Nuclide supports many languages to help you write your scripts quicker and error-free. With -first-class support for [Hack](/docs/languages/hack) and [Flow](/docs/languages/flow), along -with support for [C++](/docs/languages/cpp), Nuclide make you more productive in your script -writing. diff --git a/docs/_docs/quick-start/getting-started.md b/docs/_docs/quick-start/getting-started.md deleted file mode 100644 index ccf8ef4cdb..0000000000 --- a/docs/_docs/quick-start/getting-started.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -pageid: quick-start-getting-started -title: Getting Started -layout: docs -permalink: /docs/quick-start/getting-started/ ---- - -This getting started guide walks you through the core features of Nuclide and aims to get you productive quickly. - -If you are new to Atom, you can find more information about its features in the [Atom Flight Manual](http://flight-manual.atom.io/). Then, to find out more about using Nuclide, see [Basics](/docs/editor/basics) or any of the other guides available in the Nuclide documentation. -
- -* TOC -{:toc} - -## Installation - -The [installation guides](/docs/editor/setup/) provide detailed information to install -Nuclide on your platform, but if you have already met the platform dependent prerequisites -([macOS](/docs/editor/setup/#macos__prerequisites) | [Linux](/docs/editor/setup/#linux__prerequisites)), -you can install Nuclide easily from within Atom itself. - -> Nuclide can be installed on [Windows](#windows), but it is [not fully supported](https://github.com/facebook/nuclide/issues/321). - -
- -1. Open Atom. -2. Choose `Atom | Preferences` (`Edit | Preferences` on Linux and `File | Settings` on Windows) to bring up the **Settings** tab. -3. In the **Settings** tab, select **Install** from the list at the left. -4. In the search box, type "Nuclide" and press the `Enter` key. -5. Click the **Install** button for the `nuclide` package. - -![](/static/images/docs/editor-setup-atom-install-nuclide.png) - -> Installing Nuclide within the Atom Packages UI is the recommended method, however you can install Nuclide from the command-line, if you wish, using: -> -```bash -$ apm install nuclide -``` -> - -
- -### Packages - -If you want features such as [Quick Open](#quick-open), [Remote Development](/docs/features/remote), and [Mercurial support](/docs/features/hg) to work correctly, you also need to install [Watchman](https://facebook.github.io/watchman/) and ensure it is in your `$PATH` environment variable. There are other [recommended package installations](/docs/editor/setup/#post-installation) as well. - -## Launch - -After installation, launch Nuclide by [opening Atom](/docs/editor/basics/#opening). Once Atom -is open, you should see the Nuclide Home page. - -![](/static/images/docs/quick-start-getting-started-home.png) - -- The left side-pane is the Nuclide [Project Explorer](/docs/editor/basics/#project-explorer). -- The main pane contains introductory information about Nuclide and the Quick Launch Menu. This is also where you will edit your files (just like in normal Atom). -- The bottom status bar shows you error and health statistics. - -## Adding a Project - -The first common step after launching Nuclide is to open a project you would like to work on. -This could be a [Hack](/docs/languages/hack/), [Flow](/docs/languages/flow/), or any other project that has a root directory. - -To add a project, click the **Add Project Folder** button in the left side-pane, use the `Cmd-Shift-O` keyboard shortcut (`Ctrl-Shift-O` on Linux), or choose -`File | Add Project Folder` from the Atom menu bar. - -![](/static/images/docs/quick-start-getting-started-add-project.png) - -After adding a project you will see the root of your project at the top of the [Project Explorer's](/docs/editor/basics/#project-explorer) File Tree with all -files and folders as a tree hierarchy underneath it. - -![](/static/images/docs/quick-start-getting-started-file-tree-view.png) - -## Quick Launch Menu - -On the Nuclide Home page you will find the Quick Launch Menu that gives quick access to many of -the popular features of Nuclide. Click the **Try It** button of any feature to use it. - -![](/static/images/docs/quick-start-getting-started-quick-launch-menu.png) - -## Quick Open - -The [Quick Open](/docs/features/quick-open) feature gives you access to Nuclide's file -search mechanism, including [OmniSearch](/docs/features/quick-open/#omnisearch), which quickly displays recently opened files, quick searches for files based on partial names, and depending on the project, can search within files for symbols, etc. Click **Try It** or use the `Cmd-T` keyboard shortcut (`Ctrl-T` on Linux) to access the feature. - -![](/static/images/docs/quick-start-getting-started-quick-open.png) - -You can also search by filenames in your project, filenames of currently open files, and see which files have been -recently opened. - -## Remote Connection - -Nuclide provides the ability to do [remote development](/docs/features/remote/) out of the box. This -allows you to have Nuclide installed on a local machine, your project on a remote machine, and have -your editing experience be seamless between the two. - -Nuclide provides a *server* that bridges your local client with the remote development machine. In -order for remote development to work correctly, you must meet the -[prerequisites](/docs/features/remote/#nuclide-server__prerequisites) on the remote machine before -installing the Nuclide server. - -Once the prerequisites are met, you can -[install the server](/docs/features/remote/#nuclide-server__setup) on the remote machine. - -In order to connect to your remote project, click on the **Try It** button next to -**Remote Connection** in the Quick Launch Menu. You can also select `Nuclide | Remote Projects | Connect to Remote Project...`, -use the `Ctrl-Shift-Cmd-C` keyboard shortcut, or click **Add Remote Project Folder** -in the [Project Explorer](/docs/editor/basics/#project-explorer) (however, please note that if you have other projects open that button will not be there). - -![](/static/images/docs/quick-start-getting-started-remote-connection-dialog.png) - -Enter all the necessary credentials, including the username for logging into the remote server, the -server's address, and the actual root directory of the remote project you want to open. Then, if you installed the Nuclide Server as instructed, the **Remote Server Command** is -`nuclide-start-server`. - -Any changes you make in the local Nuclide editor will be communicated back to the remote server and -properly synchronized. diff --git a/docs/_includes/blog_pagination.html b/docs/_includes/blog_pagination.html deleted file mode 100644 index e26da279bc..0000000000 --- a/docs/_includes/blog_pagination.html +++ /dev/null @@ -1,28 +0,0 @@ - -{% if paginator.total_pages > 1 %} -
- -
-{% endif %} diff --git a/docs/_includes/content/gridblocks.html b/docs/_includes/content/gridblocks.html deleted file mode 100644 index d58078dde2..0000000000 --- a/docs/_includes/content/gridblocks.html +++ /dev/null @@ -1,6 +0,0 @@ -
-{% for item in {{include.data_source}} %} - {% include content/items/gridblock.html item=item gridtype=include.grid_type %} - {% cycle '', '
' %} -{% endfor %} -
diff --git a/docs/_includes/content/items/gridblock.html b/docs/_includes/content/items/gridblock.html deleted file mode 100644 index d79b5f868f..0000000000 --- a/docs/_includes/content/items/gridblock.html +++ /dev/null @@ -1,7 +0,0 @@ -
- {% if item.image %} - {{ item.title }} - {% endif %} -

{{ item.title }}

- {{ item.text | markdownify }} -
diff --git a/docs/_includes/doc.html b/docs/_includes/doc.html deleted file mode 100644 index ec63dd5cb8..0000000000 --- a/docs/_includes/doc.html +++ /dev/null @@ -1,23 +0,0 @@ -
-
-

{% if include.truncate %}{{ page.title }}{% else %}{{ page.title }}{% endif %}

-
- -
- {% if include.truncate %} - {% if page.content contains '' %} - {{ page.content | split:'' | first }} - - {% else %} - {{ page.content }} - {% endif %} - {% else %} - {{ content }} - {% endif %} -
- {% include doc_paging.html %} -
diff --git a/docs/_includes/doc_paging.html b/docs/_includes/doc_paging.html deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/_includes/footer.html b/docs/_includes/footer.html deleted file mode 100644 index 3943a3d516..0000000000 --- a/docs/_includes/footer.html +++ /dev/null @@ -1,24 +0,0 @@ -
- -
- - - -{% comment %} -For Algolia search -{% endcomment %} - - - diff --git a/docs/_includes/head.html b/docs/_includes/head.html deleted file mode 100644 index 82ec24b92d..0000000000 --- a/docs/_includes/head.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - {% seo %} - - {% comment %} - For Algolia search - {% endcomment %} - - - {% comment %}Local "Gotham Rounded A" stylesheet{% endcomment %} - - - - - {% comment %} - The file below is the redirect destination of 'http://fb.me/react-with-addons-0.13.1.min.js'. Use - the final destination to eliminate a redirect for clients. - {% endcomment %} - - - {% comment %} - jQuery and ajax to automatically insert Atom and Node version dependencies into the documentation. - {% endcomment %} - - {% comment %} - For our RSS feed.xml - https://help.github.com/articles/atom-rss-feeds-for-github-pages/ - {% endcomment %} - {% feed_meta %} - diff --git a/docs/_includes/hero.html b/docs/_includes/hero.html deleted file mode 100644 index c7423f75ef..0000000000 --- a/docs/_includes/hero.html +++ /dev/null @@ -1,9 +0,0 @@ -
-
-
-

An image management library

- -
-
diff --git a/docs/_includes/homeContent.html b/docs/_includes/homeContent.html deleted file mode 100644 index 44fbd4dfb4..0000000000 --- a/docs/_includes/homeContent.html +++ /dev/null @@ -1,16 +0,0 @@ -
-
-
-

{{ site.tagline }}

-
-

{% if page.excerpt %}{{ page.excerpt | strip_html }}{% else %}{{ site.description }}{% endif %}

-
-
- Get Started or read more about using Nuclide for React Native, iOS, or Web development. -
-
- -
-
diff --git a/docs/_includes/nav.html b/docs/_includes/nav.html deleted file mode 100644 index dee708140b..0000000000 --- a/docs/_includes/nav.html +++ /dev/null @@ -1,108 +0,0 @@ -
-
- - -

{{ site.title }}

-
- - -
- - -
diff --git a/docs/_includes/nav_blog.html b/docs/_includes/nav_blog.html deleted file mode 100644 index ebbb173898..0000000000 --- a/docs/_includes/nav_blog.html +++ /dev/null @@ -1,85 +0,0 @@ - - - diff --git a/docs/_includes/nav_docs.html b/docs/_includes/nav_docs.html deleted file mode 100644 index 2fd641921f..0000000000 --- a/docs/_includes/nav_docs.html +++ /dev/null @@ -1,98 +0,0 @@ - - - diff --git a/docs/_includes/plugins/all_share.html b/docs/_includes/plugins/all_share.html deleted file mode 100644 index a62015b685..0000000000 --- a/docs/_includes/plugins/all_share.html +++ /dev/null @@ -1,3 +0,0 @@ -
- {% include plugins/like_button.html %} -
diff --git a/docs/_includes/plugins/button.html b/docs/_includes/plugins/button.html deleted file mode 100644 index 04c61c64cd..0000000000 --- a/docs/_includes/plugins/button.html +++ /dev/null @@ -1 +0,0 @@ -{{ include.button_text }} diff --git a/docs/_includes/plugins/group_join.html b/docs/_includes/plugins/group_join.html deleted file mode 100644 index b8fbbbc27c..0000000000 --- a/docs/_includes/plugins/group_join.html +++ /dev/null @@ -1 +0,0 @@ -{{ include.button_text }} diff --git a/docs/_includes/plugins/like_button.html b/docs/_includes/plugins/like_button.html deleted file mode 100644 index d403ec7d47..0000000000 --- a/docs/_includes/plugins/like_button.html +++ /dev/null @@ -1,18 +0,0 @@ -
- diff --git a/docs/_includes/plugins/post_social_plugins.html b/docs/_includes/plugins/post_social_plugins.html deleted file mode 100644 index cb4d6e2ece..0000000000 --- a/docs/_includes/plugins/post_social_plugins.html +++ /dev/null @@ -1,34 +0,0 @@ -
- -
-
- - - diff --git a/docs/_includes/plugins/slideshow.html b/docs/_includes/plugins/slideshow.html deleted file mode 100644 index 5d2a7d993f..0000000000 --- a/docs/_includes/plugins/slideshow.html +++ /dev/null @@ -1,87 +0,0 @@ -
- - diff --git a/docs/_includes/post.html b/docs/_includes/post.html deleted file mode 100644 index 26a37c58ef..0000000000 --- a/docs/_includes/post.html +++ /dev/null @@ -1,22 +0,0 @@ -
- {% assign author = site.data.authors[include.post.author] %} -
- {% if author.fbid %} -
- {{ author.fullname }} -
- {% endif %} - {% if author.full_name %} - - {% endif %} -

{% if include.truncate %}{{ include.post.title }}{% else %}{{ include.post.title }}{% endif %}

- -
- -
- {{ include.post.content | markdownify }} - {% unless include.truncate %} - {% include plugins/all_share.html %} - {% endunless %} -
-
diff --git a/docs/_includes/social_plugins.html b/docs/_includes/social_plugins.html deleted file mode 100644 index db4f1aecdd..0000000000 --- a/docs/_includes/social_plugins.html +++ /dev/null @@ -1,24 +0,0 @@ - -
- -
- - - diff --git a/docs/_includes/ui/button.html b/docs/_includes/ui/button.html deleted file mode 100644 index e663e85eff..0000000000 --- a/docs/_includes/ui/button.html +++ /dev/null @@ -1 +0,0 @@ -{{ include.button_text }} diff --git a/docs/_layouts/blog.html b/docs/_layouts/blog.html deleted file mode 100644 index 419180fddc..0000000000 --- a/docs/_layouts/blog.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -category: blog -layout: default ---- - -
-
-
- {% include nav_blog.html %} -
- {{ content }} -
-
-
-
diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html deleted file mode 100644 index ad2681b6b2..0000000000 --- a/docs/_layouts/default.html +++ /dev/null @@ -1,10 +0,0 @@ - - - {% include head.html %} - - {% include nav.html alwayson=true %} - {{ content }} - {% include footer.html %} - - - diff --git a/docs/_layouts/doc_page.html b/docs/_layouts/doc_page.html deleted file mode 100644 index f9fe5c8d5b..0000000000 --- a/docs/_layouts/doc_page.html +++ /dev/null @@ -1,10 +0,0 @@ ---- -layout: default ---- - -
-
- {% include nav_docs.html %} - {{ content }} -
-
diff --git a/docs/_layouts/docs.html b/docs/_layouts/docs.html deleted file mode 100644 index 1b9aa9e8e7..0000000000 --- a/docs/_layouts/docs.html +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: doc_page ---- - -{% include doc.html %} diff --git a/docs/_layouts/home.html b/docs/_layouts/home.html deleted file mode 100644 index e3595df98b..0000000000 --- a/docs/_layouts/home.html +++ /dev/null @@ -1,14 +0,0 @@ - - - {% include head.html %} - - {% include nav.html alwayson=true %} - {% include homeContent.html %} -
-
- {{ content }} -
-
- {% include footer.html %} - - diff --git a/docs/_layouts/page.html b/docs/_layouts/page.html deleted file mode 100644 index af1b08ff4d..0000000000 --- a/docs/_layouts/page.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: default ---- -
-
- {% include nav_blog.html %} - {{ content }} -
-
diff --git a/docs/_layouts/plain.html b/docs/_layouts/plain.html deleted file mode 100644 index 71fbd8306f..0000000000 --- a/docs/_layouts/plain.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: default ---- - -
-
- {{ content }} -
-
diff --git a/docs/_layouts/post.html b/docs/_layouts/post.html deleted file mode 100644 index d361eb981f..0000000000 --- a/docs/_layouts/post.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -collection: blog -layout: page ---- - -{% include post.html post=page %} diff --git a/docs/_layouts/redirect.html b/docs/_layouts/redirect.html deleted file mode 100644 index c24f817484..0000000000 --- a/docs/_layouts/redirect.html +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/docs/_layouts/top-level.html b/docs/_layouts/top-level.html deleted file mode 100644 index 71fbd8306f..0000000000 --- a/docs/_layouts/top-level.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: default ---- - -
-
- {{ content }} -
-
diff --git a/docs/_posts/2016-01-13-Nuclide-v0.111.0-The-Unified-Package.md b/docs/_posts/2016-01-13-Nuclide-v0.111.0-The-Unified-Package.md deleted file mode 100644 index 8534f4083b..0000000000 --- a/docs/_posts/2016-01-13-Nuclide-v0.111.0-The-Unified-Package.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -layout: post -title: "Nuclide v0.111.0: The Unified Package" -author: zertosh ---- - -This is a significant release for Nuclide that is mainly aimed at improving and simplifying Nuclide as an open source project. The most apparent and important change is moving Nuclide from many Atom -packages—44 of them to be exact—to just one: `nuclide`. We will discuss below why we are excited -about moving to a single package and how it improves Nuclide for everyone, but first we will cover -how to get going with the new release. - -## Installing Nuclide v0.111.0 - -Nuclide v0.111.0 is a single Atom package. To install it, you can either search for the -['nuclide' Atom package](https://atom.io/packages/nuclide) in *Atom > Packages > Install* or install -it from the command line with `apm`. While this release focuses on moving to a single package, it -does include fixes and improvements that you can find in the -[CHANGELOG.md](https://github.com/facebook/nuclide/blob/v0.111.0/CHANGELOG.md). - -```bash -$ apm install nuclide -``` - -#### Installing Nuclide Server v0.111.0 - -Nuclide's server has moved into the ['nuclide' NPM package](https://www.npmjs.com/package/nuclide). -The server is required only if you intend to edit remote files from within Atom+Nuclide, and it -should be installed on the host where the remote files live. We recommend installing the server as -a global module using NPM's `-g` flag so its binaries are available in '/usr/local/bin'. - -```bash -$ npm install -g nuclide -``` - -### New Version Scheme - -The last version of the Nuclide packages that were published was v0.0.35. Internally, however, the -server was last released as v0.108.0. This release adopts our internal version scheme so the -versions stay in sync with open source releases. - -### Migrating from Previous Versions - -If you previously installed Nuclide via the `nuclide-installer` package or by installing `nuclide-` -packages individually, you should uninstall them first. Follow the -[v0.0.35 uninstall instructions](/docs/editor/uninstall/#v0-0-35-and-prior) to ensure previous -versions of Nuclide are removed. - -The new 'nuclide' package will automatically disable any deprecated 'nuclide-*' packages and warn -you on start up that you should uninstall them to ensure everything works as expected. - -## Configuring Single-package Nuclide - -Because Nuclide is now a single Atom Package, its settings are unified under the 'nuclide' package -in *Atom > Packages > nuclide > Settings*. - -![](/static/images/blog/nuclide-atom-settings.png) - -Features you may have been familiar with as separate packages before, such as Hyperclick, -Diagnostics, and File Tree, are now listed as features in Nuclide's Settings page and are togglable -as if they were Atom packages. If you want to use only one or a few of the features of Nuclide, you -can disable the rest of Nuclide without incurring any load time for the disabled features' code. All -features are enabled by default. - -![](/static/images/blog/nuclide-feature-settings.png) - -### Migrating Settings from Previous Packages - -If you changed settings in any of Nuclide's previous packages, the settings will be automatically -migrated to their new location in the `nuclide.` namespace when you first launch Atom after -installing the 'nuclide' package. The settings will be configurable like before but under the -*Atom > Packages > nuclide > Settings* rather than under the package's name. - -## Why a Single Atom Package? - -The Atom ecosystem is centered around modular packages that can be installed and updated -independently, and Nuclide took that same approach from the start. We wrote scripts to let our code -live in a single repository but be released as many Atom packages. Nuclide releases were actually -simultaneous releases of 40+ Atom packages. While this fit well with the Atom model, it meant we -also had to distribute a "installer" package that oversaw the installation of top-level Atom -packages. - -In practice, the installer process was computationally expensive, difficult to -troubleshoot, and took roughly 40 minutes partially due to large amounts of network traffic. When -all Nuclide packages were installed, they filled over 3GB of disk space. Nuclide packages are -heavily interdependent, and because they were installed as top-level Atom packages they each had -their own 'node_modules' directory with largely duplicate dependencies. - -By unifying Nuclide into a single Atom package, we aimed to improve installation, updates, and -maintenance. The single 'nuclide' package does not require a special installer, only `apm install` -like other Atom packages. This simplifies installation for everyone and makes Nuclide updates fast. -Once installed, the 'nuclide' package takes under 110MB of disk space, a 95%+ reduction in disk use, -and subsequently, network use during installation. The dramatic drop in disk use was possible -because Nuclide's features now share a single 'node_modules' directory and use relative paths to -require one another, eliminating the duplicate dependencies present when Nuclide was 40+ top-level -Atom packages. - -## What's Next? - -We are excited to greatly improve the experience of Nuclide for users outside Facebook. This release -should solve many of the most common installation and upgrade issues that have been reported, and it -paves the way for more frequent and more stable releases. We hope that simplifying the installation -process will make [Nuclide's source](https://github.com/facebook/nuclide) more familiar to other -Atom developers and make it easier for anyone to contribute. - -If you run into issues with the upgrade process, or if you run into any issue at all, open a -[Nuclide GitHub issue](https://github.com/facebook/nuclide/issues) so we can help out. diff --git a/docs/_posts/2017-02-27-Command-Click-You-Have-One-Job.md b/docs/_posts/2017-02-27-Command-Click-You-Have-One-Job.md deleted file mode 100644 index 4929c3a1a3..0000000000 --- a/docs/_posts/2017-02-27-Command-Click-You-Have-One-Job.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -layout: post -title: "Command + Click: You Have One Job" -author: matthewwithanm ---- - -One of the cool things about Nuclide is that, even though it’s an IDE with a ton -of awesome IDE features, it still belongs to the TextMate/Sublime/Atom lineage -of modern text editors. Unfortunately, sometimes these two things come into -conflict. Such is the case with command click. - -See, in the Atom family of editors, command + click (control + click on Windows -and Linux) means multiple cursors. But if you’re coming from an IDE, you’re -probably used to using command + click to jump to a definition (“Hyperclick”). - -Since Nuclide is both of these things, we’ve always tried to do both: if you -clicked on something that we could get a definition for, we’d take you to it; -otherwise, we’d let Atom do its default behavior (add another cursor). This way -we only interfered with expected Atom behavior when we knew we were supposed to. -Perfect! Right? - -An internal poll - -It turns out that, in trying to accommodate everybody, we hadn’t made command + -click predictable to anybody. It’s true: when you command click on something, -you may want to go to its definition. Or you may want to add another cursor. But -nobody wants to sometimes go to its definition and sometimes add a cursor. Sorry -about that. - -So as of [v0.207][1] (rolled out last week!), command clicking will always jump -to definition. - -# Upgrade Path - -We know that these kind of breaking changes are disruptive, so the first time -you command + click, we’ll show you a one-time notification explaining the -situation: - - - -Don’t despair, multicursor fans! command + option + click still works! (In -Sublime too.) Or if you really insist on using command + click for multiple -cursors, you can change the Hyperclick trigger to something else in the Nuclide -package’s settings. - -[1]: https://github.com/facebook/nuclide/releases/tag/v0.207.0 diff --git a/docs/_posts/2017-08-31-Code-Search.md b/docs/_posts/2017-08-31-Code-Search.md deleted file mode 100644 index 734e03b21d..0000000000 --- a/docs/_posts/2017-08-31-Code-Search.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -layout: post -title: "Code Search" -author: a20012251 ---- - -One of the missing features in the [Quick Open](/docs/features/quick-open) pane is searching for -code in your current projects. Internally at Facebook, we have a plugin that provides this -functionality but we never offered a similar tool for the open source world. And we've just published this missing feature!! - -Now you can use Quick Open (*command + T* on Mac and *control + T* on Windows and Linux) and type any -code you want to look for. You can also explore the *Code Search* tab. - -Quick Open - -Code Search supports [ripgrep](https://github.com/BurntSushi/ripgrep) (rg), -[silversearcher](https://github.com/ggreer/the_silver_searcher) (ag) and -[ack](https://beyondgrep.com/). We recommend ripgrep and ag because they are blazing fast. Sadly, -only ripgrep works properly on Windows. You can configure which tool to use in the Nuclide package -settings under the *nuclide-code-search* tab. - -If you don't specifically select a tool, Nuclide will try to use any available one. On Windows, it -will only try rg. - -Settings diff --git a/docs/_posts/2017-09-12-Introducing-Atom-IDE-UI.md b/docs/_posts/2017-09-12-Introducing-Atom-IDE-UI.md deleted file mode 100644 index 80fb29d285..0000000000 --- a/docs/_posts/2017-09-12-Introducing-Atom-IDE-UI.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -layout: post -title: "Introducing Atom IDE UI" -author: hansonw ---- - -Since the beginning, Nuclide has strived to provide a feature-rich IDE -experience on top of Atom, with functionality like -[code diagnostics](https://nuclide.io/docs/languages/flow/#code-diagnostics), -[jump to definition](https://nuclide.io/docs/languages/flow/#jump-to-definition), -and much more. However, over time we've heard feedback that the -"one-size-fits-all" philosophy can be overwhelming for many Atom users. - -That's why we're proud to announce the new -[Atom IDE UI](https://atom.io/packages/atom-ide-ui) package, which is part of -our collaboration with GitHub in the broader -[Atom IDE](https://atom.io/ide) initative. Read -more about that on [the Atom blog](http://blog.atom.io/2017/09/12/announcing-atom-ide.html). - -![Screenshot](/static/images/blog/2017-09-12/atom-ide-ui.png) - -Atom IDE UI is fast and lightweight by design. It extracts only the subset of the -core UI features from Nuclide necessary to support Atom's -[atom-languageclient](https://github.com/atom/atom-languageclient) -library in displaying features supported by the [language server protocol]( -http://langserver.org/). Like Nuclide, it's a [unified package]( -https://nuclide.io/blog/2016/01/13/Nuclide-v0.111.0-The-Unified-Package/) which -contains the following features: - -- [Diagnostics](https://github.com/facebook-atom/atom-ide-ui/blob/master/docs/diagnostics.md) -- [Definitions](https://github.com/facebook-atom/atom-ide-ui/blob/master/docs/definitions.md) -- [Find References](https://github.com/facebook-atom/atom-ide-ui/blob/master/docs/find-references.md) -- [Outline View](https://github.com/facebook-atom/atom-ide-ui/blob/master/docs/outline-view.md) -- [Datatips](https://github.com/facebook-atom/atom-ide-ui/blob/master/docs/datatips.md) -- [Code Formatting](https://github.com/facebook-atom/atom-ide-ui/blob/master/docs/code-format.md) -- [Code Actions](https://github.com/facebook-atom/atom-ide-ui/blob/master/docs/code-actions.md) -- [Code Highlight](https://github.com/facebook-atom/atom-ide-ui/blob/master/docs/code-highlight.md) -- [Busy Signal](https://github.com/facebook-atom/atom-ide-ui/blob/master/docs/busy-signal.md) - -Atom IDE UI is designed to work out-of-the-box with packages using -[atom-languageclient](https://github.com/atom/atom-languageclient), such as -[ide-typescript](https://atom.io/packages/ide-typescript) and our own -[ide-flowtype](https://atom.io/packages/ide-flowtype). - -As always, these features can be also be used directly via Atom services. -Documentation for these APIs is available inside the -[atom-ide-ui repository](https://github.com/facebook-atom/atom-ide-ui/tree/master/docs). - -## Getting started - -Using Atom IDE UI is as simple as: - -1. Install the [`atom-ide-ui` Atom package](https://atom.io/packages/atom-ide-ui) -2. Install an "ide-" package for your favourite language: - * [TypeScript](https://www.typescriptlang.org/): [`ide-typescript`](https://atom.io/packages/ide-typescript) - * [Flow](https://flow.org): [`ide-flowtype`](https://atom.io/packages/ide-flowtype) - * Java: [`ide-java`](https://atom.io/packages/ide-java) - * C#: [`ide-csharp`](https://atom.io/packages/ide-csharp) - * [Full list at the atom-languageclient wiki](https://github.com/atom/atom-languageclient/wiki/List-of-Atom-packages-using-Atom-LanguageClient) - -Note that if you're already a Nuclide user, all of Atom IDE UI's features will -still be bundled inside of Nuclide, so there's no need to install another -package. - -## Roadmap - -The list of features in Atom IDE UI doesn't yet encompass all the features -available in the language service protocol, and over time we'll be working to -fill in the gaps. In particular, we're looking to add: - -- [code lenses](https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#textDocument_codeLens) -- [rename support](https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#textDocument_rename) -- [function signature help](https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#textDocument_signatureHelp) - -Our hope is that other Nuclide features will eventually also become part of the -Atom IDE effort, including key components like the [Nuclide debugger]( -https://nuclide.io/docs/features/debugger/). Note that we're still committed to -supporting the open-source Nuclide package for the foreseeable future. - -Contributions and bug reports are welcome over at -[facebook-atom/atom-ide-ui](https://github.com/facebook-atom/atom-ide-ui)! - -The Atom IDE UI code is released under the BSD-3-Clause license. diff --git a/docs/_sass/_base.scss b/docs/_sass/_base.scss deleted file mode 100644 index 51eea88ff6..0000000000 --- a/docs/_sass/_base.scss +++ /dev/null @@ -1,974 +0,0 @@ -body { - background: $footer-bg; - color: $text; - font: 300 #{$base-font-size}/#{$base-line-height} $base-font-family; - text-align: center; - text-rendering: optimizeLegibility; -} - -img { - max-width: 100%; -} - -article { - p { - img { - max-width: 100%; - display:block; - margin-left: auto; - margin-right: auto; - } - } -} - -a { - border-bottom: 1px dotted $primary-bg; - color: $text; - text-decoration: none; - -webkit-transition: background 0.3s, color 0.3s; - transition: background 0.3s, color 0.3s; -} - -blockquote { - padding: 15px 30px 15px 15px; - margin: 20px 0 0 10px; - background-color: rgba(204, 122, 111, 0.1); - border-left: 10px solid rgba(191, 87, 73, 0.2); -} - -#fb_oss a { - border: 0; -} - -h1, h2, h3, h4 { - font-family: $header-font-family; -} - -.headerBarContainer { - background: $primary-bg; - color: $header-text; - height: $header-height; - opacity: 0.0; - padding: $header-ptop 0 $header-pbot; - position: relative; - -webkit-transition: opacity 0.2s ease-in-out; - transition: opacity 0.2s ease-in-out; - width: 100%; - z-index: 9999; - - &.visible { - opacity: 1.0; - } - - a { - border: 0; - color: $header-text; - } - - header { - height: $header-height; - margin: 0 auto; - max-width: $content-width; - padding: 0 20px; - position: relative; - text-align: left; - - img { - height: 30px; - margin-right: 10px; - } - - h2 { - display: inline; - font-family: $header-font-family; - font-size: 16px; - letter-spacing: -0.02em; - line-height: 18px; - position: relative; - top: -9px; - } - } - - .navigationWrapper { - display: inline-block; - font-family: $header-font-family; - - &.navigationFull { - display: none; - } - - &.navigationSlider { - position:absolute; - right: 12px; - z-index:99; - - .navSlideout { - cursor: pointer; - font-size: 24px; - padding-top: 5px; - -webkit-transition: -webkit-transform 0.3s; - transition: transform 0.3s; - } - - .slidingNav { - background: #222; - box-sizing: border-box; - height: 100vh; - opacity: 0; - overflow: hidden; - padding: 0; - position: absolute; - right: -12px; - top: $header-height + $header-pbot; - -webkit-transition: opacity 0.5s, width 0.5s; - transition: opacity 0.5s, width 0.5s; - width: 0; - - &.slidingNavActive { - opacity: 1; - width: 75vw; - } - - ul { - list-style: none; - padding-left: 0; - - li { - padding: 0; - a { - border-bottom: 1px solid #111; - display:block; - padding: 4vw 12px; - -webkit-transition: background-color 0.3s; - transition: background-color 0.3s; - - &:focus, - &:hover { - background: $primary-bg; - } - } - } - } - } - } - } -} - -.homeContainer { - background: $primary-bg; - color: $header-text; - - a { - color: $header-text; - } - - .homeWrapper { - padding-bottom: 2em; - padding-top: 2em; - text-align: left; - - .wrapper { - margin: 0px auto; - max-width: $content-width; - padding: 0 20px; - } - - .projectLogo { - pointer-events: none; - img { - height: 100px; - margin-bottom: 0px; - pointer-events: auto; - } - } - - h1#project_title { - font-family: $header-font-family; - font-size: 300%; - letter-spacing: -0.08em; - line-height: 1em; - margin-bottom: 80px; - } - - h2#project_tagline { - font-family: $header-font-family; - font-size: 200%; - letter-spacing: -0.04em; - line-height: 1em; - } - } -} - -.wrapper { - margin: 0px auto; - max-width: $content-width; - padding: 0 20px; -} - -.footerContainer { - background: $footer-bg; - - .footerWrapper { - padding-top: 4vh; - padding-bottom: 4vh; - } -} - - -.projectLogo { - display: none; - - img { - height: 100px; - margin-bottom: 0px; - } -} - -section#intro { - margin: 40px 0; -} - -.fbossFontLight { - font-family: $base-font-family; - font-weight: 300; - font-style: normal; -} - -.fb-like { - display: block; - margin-bottom: 50px; - width: 100%; -} - -a.blockButton { - background: $primary-bg; - border-radius: 4px; - border: 2px solid transparent; - clear: both; - color: $header-text; - display: inline-block; - font-family: $header-font-family; - font-size: 120%; - padding: 10px 20px; - position: relative; - -webkit-transition: background-color 0.2s, color 0.2s, border 0.2s; - transition: background-color 0.2s, color 0.2s, border 0.2s; - - .mainContainer .mainWrapper &:hover, - .mainContainer .mainWrapper &:focus { - background: $secondary-bg; - border: 2px solid $primary-bg; - color: $primary-bg; - } - - .homeContainer &{ - background: $light-color; - color: $light-text-color; - - &:hover, - &:focus { - background: $primary-bg; - border: 2px solid $light-color; - color: $light-text-color; - } - } -} - -.promoSection { - font-size: 125%; - line-height: 1.6em; - margin: 0; - position: relative; - z-index: 99; - - a { - border-bottom: 3px solid $light-color; - color: lighten($light-color, 20%); - } -} - -.center { - display: block; - text-align: center; -} - -.mainContainer { - background: $secondary-bg; - overflow: auto; - padding: 0 4vw; - - .mainWrapper { - padding-bottom: 4vh; - padding-top: 4vh; - text-align: left; - - .blogWrapper .blogPostWrapper { - .post { - margin-bottom: 50px; - } - } - - .blockButton { - margin: 4vh 0; - - &.marginsmall { - margin: 1vh 0; - } - } - - .allShareBlock { - margin: -12px; - padding: 1vh 0; - - .pluginBlock { - margin: 12px; - padding: 0; - } - } - - a { - &:hover, - &:focus { - background: $primary-bg; - color: $header-text; - } - } - - em { - font-style: italic; - } - - strong, b { - font-weight: bold; - } - - h1 { - font-size: 300%; - line-height: 1em; - padding: 1.4em 0 1em; - text-align: center; - } - - h2 { - font-size: 250%; - line-height: 1em; - padding: 1.4em 0 1em; - text-align: left; - } - - h3 { - font-size: 150%; - line-height: 1em; - padding: 1em 0 0.8em; - } - - p { - padding: 0.8em 0; - } - - ol { - list-style: decimal; - } - - ul { - list-style: disc; - } - - ol, ul { - padding-left: 24px; - li { - padding-bottom: 4px; - padding-left: 6px; - } - } - - strong { - font-weight: bold; - } - - nav.toc { - position: relative; - section { - background: $primary-bg; - color: $header-text; - margin-bottom: 2vh; - padding: 12px 24px; - - .navGroup { - h3 { - display: none; - } - - &:not(.navGroupActive) { - display: none; - } - } - } - - .toggleNav { - position: relative; - } - - .navToggle { - background: $primary-bg; - color: $header-text; - font-size: 12px; - height: 24px; - position: absolute; - right: 0; - text-align: center; - top: 0; - width: 24px; - - i { - cursor: pointer; - } - } - - .toggleNavActive { - section { - .navGroup { - display: block; - - h3 { - display: block; - } - - ul li { - display: block; - } - } - - ul li { - display: block; - padding-bottom: 4px; - } - } - } - - h3 { - font-size: 125%; - padding-right: 24px; - padding-top: 0.4em; - } - - ul { - padding-left: 0; - padding-right: 24px; - - li { - list-style-type: none; - padding-bottom: 0; - padding-left: 0; - - &:not(.navListItemActive) { - display: none; - } - - a { - border-bottom: none; - border-left: 4px solid transparent; - color: $header-text; - display: inline-block; - margin-bottom: 0.6vh; - padding: 1vh 0 0.4vh 8px; - -webkit-transition: border-color 0.3s; - transition: border-color 0.3s; - - &:hover, - &:focus { - border-left: 4px solid $nav-text; - } - - &.navItemActive { - border-left: 4px solid $header-text; - } - } - } - } - } - - .post { - background: #fff; - padding: 6vw 6vw 8vh; - position: relative; - - a { - color: $link-color; - - &:hover, - &:focus { - color: #fff; - } - } - - h2 { - border-bottom: 4px solid $primary-bg; - font-size: 130%; - } - - h3 { - border-bottom: 1px solid $primary-bg; - font-size: 110%; - } - - .authorPhoto { - border-radius: 50%; - height: 50px; - left: 50%; - margin-left: -25px; - overflow: hidden; - position: absolute; - top: -25px; - width: 50px; - } - - .post-header { - padding: 0 0 1em; - text-align: center; - - h1 { - font-size: 150%; - line-height: 1em; - padding: 0.4em 0 0; - - a { - border: none; - } - } - - .post-authorName { - color: $primary-bg; - font-family: $header-font-family; - margin-top: -2vw; - text-align: center; - } - - .post-meta { - color: $primary-bg; - font-family: $header-font-family; - text-align: center; - } - } - - .postSocialPlugins { - padding-top: 1em; - } - - .docPagination { - background: $primary-bg; - bottom: 0px; - left: 0px; - position: absolute; - right: 0px; - - .pager { - display: inline-block; - width: 50%; - } - - .pagingNext { - float: right; - text-align: right; - } - - a { - border: none; - color: $header-text; - display: block; - padding: 4px 12px; - - &:hover { - background-color: $secondary-bg; - color: $text; - } - - .pagerLabel { - display: inline; - } - - .pagerTitle { - display: none; - } - } - } - } - - .posts { - .post { - margin-bottom: 6vh; - } - } - } -} - -.gridBlock { - margin: 20px 0; - padding: 2vh 0; - - .twoByGridBlock { - padding: 0; - - img { - margin-top: 6vh; - max-width: 100%; - } - - &.featureBlock h3 { - font-size: 150%; - margin: 20px 0; - padding-bottom: 0; - } - } - - .gridClear { - clear: both; - } - - .leftBlock { - padding: 40px 0; - text-align: left; - } -} - -#integrations_title { - font-size: 250%; - margin: 80px 0; -} - -.ytVideo { - height: 0; - overflow: hidden; - padding-bottom: 53.4%; /* 16:9 */ - padding-top: 25px; - position: relative; -} - -.ytVideo iframe, -.ytVideo object, -.ytVideo embed { - height: 100%; - left: 0; - position: absolute; - top: 0; - width: 100%; -} - -@media only screen and (min-width: 480px) { - h1#project_title { - font-size: 500%; - } - - h2#project_tagline { - font-size: 250%; - } - - .projectLogo { - img { - margin-bottom: 10px; - height: 200px; - } - } - - .headerBarContainer { - .navigationWrapper { - &.navigationSlider { - - .slidingNav { - right: -22px; - - &.slidingNavActive { - width: 50vw; - } - - ul { - li { - a { - padding: 1vw 12px; - } - } - } - } - } - } - } - - .gridBlock { - margin: -20px; - overflow: auto; - padding: 1vh 0; - - .twoByGridBlock { - box-sizing: border-box; - float: left; - padding: 20px; - text-align: center; - width: 50%; - } - - .centerInGrid { - margin-left: 25%; - } - - .leftBlock { - padding: 40px 20px; - } - } - - .mainContainer { - .mainWrapper { - nav.toc { - h3 { - padding-top: 0.4em; - } - - ul li a { - margin-bottom: 0; - padding-bottom: 0.2vh; - padding-top: 0; - display: block; - } - - .navToggle { - top: 12px; - } - } - - .post { - padding: 4vw 4vw 4em; - - h2 { - font-size: 180%; - } - - h3 { - font-size: 120%; - } - - .post-header { - padding: 1em 0; - } - - .docPagination { - a { - .pagerLabel { - display: none; - } - .pagerTitle { - display: inline; - } - } - } - } - } - } -} - -@media only screen and (min-width: 900px) { - .homeContainer { - .homeWrapper { - padding-bottom: 4em; - position: relative; - - #inner { - box-sizing: border-box; - max-width: 600px; - padding-right: 40px; - } - - .projectLogo { - align-items: center; - bottom: 0; - display: flex; - justify-content: flex-end; - left: 0; - padding: 2em 20px 4em; - position: absolute; - right: 20px; - top: 0; - - img { - height: 100%; - } - } - } - } - - .headerBarContainer { - .navigationWrapper { - nav { - padding: 0 1em; - position: relative; - top: -9px; - - ul { - margin: 0 -0.4em; - li { - display: inline-block; - - a { - padding: 14px 0.4em; - border: 0; - color: $nav-text; - display: inline-block; - - &:hover { - color: $header-text; - } - } - - &.navItemActive { - a { - color: $header-text; - } - } - } - } - } - - &.navigationFull { - display: inline-block; - } - - &.navigationSlider { - display: none; - } - } - } -} - -@media only screen and (min-width: 1024px) { - .mainContainer { - .mainWrapper { - .blogWrapper { - display: flex; - nav.toc { - width: 400px; - } - } - nav.toc { - box-sizing: border-box; - display: inline-block; - border-right: 12px solid $secondary-bg; - width: 285px; - vertical-align: top; - - .navToggle { - display: none; - } - - .toggleNav { - section { - .navGroup { - display: block; - - h3 { - display: block; - } - - ul li { - display: block; - } - } - - ul li { - display: block; - padding-bottom: 4px; - } - } - } - ul li a { - font-size: 14px; - padding-bottom: 0.1vh; - } - } - - .post { - box-sizing: border-box; - display: inline-block; - padding: 2vw 24px 4em; - width: 590px; - - .post-header { - h1 { - font-size: 250%; - } - } - } - - .posts { - display: inline-block; - width: 590px; - - .post { - margin-bottom: 4vh; - width: 100%; - } - } - } - } -} - -@media only screen and (min-width: 1040px) { - .mainContainer { - .mainWrapper { - nav.toc { - width: 300px; - } - } - } -} - -@media only screen and (min-width: 1200px) { - .homeContainer { - .homeWrapper { - #inner { - max-width: 750px; - } - } - } - - .headerBarContainer { - header { - max-width: 1100px; - } - } - - .wrapper { - max-width: 1100px; - } - - .mainContainer .mainWrapper { - .post, .posts { - width: 760px; - } - } -} - -@media only screen and (min-width: 1500px) { - .homeContainer { - .homeWrapper { - #inner { - max-width: 1100px; - padding-bottom: 40px; - padding-top: 40px; - } - } - } - - .headerBarContainer { - header { - max-width: 1400px; - } - } - - .wrapper { - max-width: 1400px; - } - - .mainContainer .mainWrapper { - .post, .posts { - width: 1035px; - } - } -} diff --git a/docs/_sass/_reset.scss b/docs/_sass/_reset.scss deleted file mode 100644 index 45bd74b6a4..0000000000 --- a/docs/_sass/_reset.scss +++ /dev/null @@ -1,43 +0,0 @@ -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} -/* HTML5 display-role reset for older browsers */ -article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { - display: block; -} -body { - line-height: 1; -} -ol, ul { - list-style: none; -} -blockquote, q { - quotes: none; -} -blockquote:before, blockquote:after, -q:before, q:after { - content: ''; - content: none; -} -table { - border-collapse: collapse; - border-spacing: 0; -} diff --git a/docs/_sass/_search.scss b/docs/_sass/_search.scss deleted file mode 100644 index 9cbeff3692..0000000000 --- a/docs/_sass/_search.scss +++ /dev/null @@ -1,116 +0,0 @@ -/** Algolia Doc Search **/ - -::-webkit-input-placeholder { /* Safari, Chrome */ - color: $nav-text; -} -:-moz-placeholder { /* Mozilla Firefox <= 18 */ - color: $nav-text; - opacity: 1; -} -::-moz-placeholder { /* Mozilla Firefox 19+ */ - color: $nav-text; - opacity: 1; -} -:-ms-input-placeholder { /* Internet Explorer */ - color: $nav-text; -} -:placeholder-shown { /* Standard (https://drafts.csswg.org/selectors-4/#placeholder) */ - color: $nav-text; -} - -[type="search"] { - -moz-appearance: textfield; - -webkit-appearance: textfield; - appearance: textfield; -} - -div.algolia-search-wrapper { - display: inline-block; - vertical-align: top; - margin-left: 15px; -} - -@media screen and (max-width: 960px) { - div.algolia-search-wrapper { - display: none; - } -} - -input#algolia-doc-search { - font-family: $header-font-family; - - background: transparent url('/static/search.png') no-repeat left center; - background-size: 16px 16px; - - padding-left: 20px; - margin-left: 10px; - font-size: 16px; - line-height: 20px; - background-color: $nav-bg; - border: none; - color: white; - outline: none; - width: 160px; - - transition: border-color .2s ease, width .2s ease; - -webkit-transition: border-color .2s ease, width .2s ease; - -moz-transition: border-color .2s ease, width .2s ease; - -o-transition: border-color .2s ease, width .2s ease; -} - -input#algolia-doc-search:focus { - border-color: #05A5D1; - width: 240px; -} - -@media screen and (max-width: 1085px) { - input#algolia-doc-search:focus { - width: 178px; - } -} - -.algolia-autocomplete { - vertical-align: top; - font-family: $header-font-family; -} - -/* Bottom border of each suggestion */ -.algolia-docsearch-suggestion { - border-bottom-color: #2F0A57; -} -/* Main category headers */ -.algolia-docsearch-suggestion--category-header { - background-color: #2F0A57; -} -/* Highlighted search terms */ -.algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight { - color: #C897FF; -} -.algolia-docsearch-suggestion--title .algolia-docsearch-suggestion--highlight, -.algolia-docsearch-suggestion--subcategory-column .algolia-docsearch-suggestion--highlight { - color: #4A078E; -} -.algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--highlight { - background-color: #C897FF; -} -/* Currently selected suggestion */ -.aa-cursor .algolia-docsearch-suggestion--content { - color: #151515; -} -.aa-cursor .algolia-docsearch-suggestion { - background: #F3E8FF; -} - -/* For bigger screens, when displaying results in two columns */ -@media (min-width: 768px) { - /* Bottom border of each suggestion */ - .algolia-docsearch-suggestion { - border-bottom-color: #2F0A57; - } - /* Left column, with secondary category header */ - .algolia-docsearch-suggestion--subcategory-column { - border-right-color: #2F0A57; - background-color: #E4E4E4; - color: #151515; - } -} diff --git a/docs/_sass/_slideshow.scss b/docs/_sass/_slideshow.scss deleted file mode 100644 index cd98a6cdba..0000000000 --- a/docs/_sass/_slideshow.scss +++ /dev/null @@ -1,48 +0,0 @@ -.slideshow { - position: relative; - - .slide { - display: none; - - img { - display: block; - margin: 0 auto; - } - - &.slideActive { - display: block; - } - - a { - border: none; - display: block; - } - } - - .pagination { - display: block; - margin: -10px; - padding: 1em 0; - text-align: center; - width: 100%; - - .pager { - background: transparent; - border: 2px solid rgba(255, 255, 255, 0.5); - border-radius: 50%; - cursor: pointer; - display: inline-block; - height: 12px; - margin: 10px; - transition: background-color 0.3s, border-color 0.3s; - width: 12px; - - &.pagerActive { - background: rgba(255, 255, 255, 0.5); - border-width: 4px; - height: 8px; - width: 8px; - } - } - } -} diff --git a/docs/_sass/_syntax-highlighting.scss b/docs/_sass/_syntax-highlighting.scss deleted file mode 100644 index b84b8bd638..0000000000 --- a/docs/_sass/_syntax-highlighting.scss +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Syntax highlighting styles - */ -.highlighter-rouge { - .c { color: #998; font-style: italic } // Comment - .err { color: #a61717; background-color: #e3d2d2 } // Error - .k { font-weight: bold } // Keyword - .o { font-weight: bold } // Operator - .cm { color: #998; font-style: italic } // Comment.Multiline - .cp { color: #999; font-weight: bold } // Comment.Preproc - .c1 { color: #998; font-style: italic } // Comment.Single - .cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special - .gd { color: #000; background-color: #fdd } // Generic.Deleted - .gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific - .ge { font-style: italic } // Generic.Emph - .gr { color: #a00 } // Generic.Error - .gh { color: #999 } // Generic.Heading - .gi { color: #000; background-color: #dfd } // Generic.Inserted - .gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific - .go { color: #888 } // Generic.Output - .gp { color: #555 } // Generic.Prompt - .gs { font-weight: bold } // Generic.Strong - .gu { color: #aaa } // Generic.Subheading - .gt { color: #a00 } // Generic.Traceback - .kc { font-weight: bold } // Keyword.Constant - .kd { font-weight: bold } // Keyword.Declaration - .kp { font-weight: bold } // Keyword.Pseudo - .kr { font-weight: bold } // Keyword.Reserved - .kt { color: #458; font-weight: bold } // Keyword.Type - .m { color: #099 } // Literal.Number - .s { color: #d14 } // Literal.String - .na { color: #008080 } // Name.Attribute - .nb { color: #0086B3 } // Name.Builtin - .nc { color: #458; font-weight: bold } // Name.Class - .no { color: #008080 } // Name.Constant - .ni { color: #800080 } // Name.Entity - .ne { color: #900; font-weight: bold } // Name.Exception - .nf { color: #900; font-weight: bold } // Name.Function - .nn { color: #555 } // Name.Namespace - .nt { color: #000080 } // Name.Tag - .nv { color: #008080 } // Name.Variable - .ow { font-weight: bold } // Operator.Word - .w { color: #bbb } // Text.Whitespace - .mf { color: #099 } // Literal.Number.Float - .mh { color: #099 } // Literal.Number.Hex - .mi { color: #099 } // Literal.Number.Integer - .mo { color: #099 } // Literal.Number.Oct - .sb { color: #d14 } // Literal.String.Backtick - .sc { color: #d14 } // Literal.String.Char - .sd { color: #d14 } // Literal.String.Doc - .s2 { color: #d14 } // Literal.String.Double - .se { color: #d14 } // Literal.String.Escape - .sh { color: #d14 } // Literal.String.Heredoc - .si { color: #d14 } // Literal.String.Interpol - .sx { color: #d14 } // Literal.String.Other - .sr { color: #009926 } // Literal.String.Regex - .s1 { color: #d14 } // Literal.String.Single - .ss { color: #990073 } // Literal.String.Symbol - .bp { color: #999 } // Name.Builtin.Pseudo - .vc { color: #008080 } // Name.Variable.Class - .vg { color: #008080 } // Name.Variable.Global - .vi { color: #008080 } // Name.Variable.Instance - .il { color: #099 } // Literal.Number.Integer.Long -} - -.highlighter-rouge pre code { - background: #f0f0f0; - color: #000; - display: block; - font-family: monospace; - font-size: 12px; - margin: 1em 0; - overflow-x: auto; - padding: 12px; - text-align: left; -} - -code { - color: $primary-bg; - font-family: monospace; -} diff --git a/docs/_sass/_tables.scss b/docs/_sass/_tables.scss deleted file mode 100644 index f5b97395f5..0000000000 --- a/docs/_sass/_tables.scss +++ /dev/null @@ -1,46 +0,0 @@ -table { - background: $lightergrey; - border: 1px solid $lightgrey; - border-collapse: collapse; - display:table; - - thead { - border-bottom: 1px solid $lightgrey; - display: table-header-group; - } - tbody { - display: table-row-group; - } - tr { - display: table-row; - &:nth-of-type(odd) { - background: $greyish; - } - - th, td { - border-right: 1px dotted $lightgrey; - display: table-cell; - font-size: 14px; - line-height: 1.3em; - padding: 10px; - text-align: left; - - &:last-of-type { - border-right: 0; - } - - code { - color: $green; - display: inline-block; - font-size: 12px; - } - } - - th { - color: #000000; - font-weight: bold; - font-family: $header-font-family; - text-transform: uppercase; - } - } -} diff --git a/docs/_top-level/support.md b/docs/_top-level/support.md deleted file mode 100644 index a481475d9e..0000000000 --- a/docs/_top-level/support.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -layout: top-level -id: support -category: support ---- - -## Need help? - -Do not hesitate to ask questions using the following channels, or to -[submit a pull request](https://github.com/facebook/nuclide/pulls)! - -### GitHub issues - -The [GitHub issues](https://github.com/facebook/nuclide/issues) page is a good place to ask -questions, find answers, and report issues. - -### Facebook Group - - - -### FAQ - -Check out a list of [commonly asked questions](/docs/help/faq) about Nuclide. - -### Troubleshooting - -Have installation or other issues, check out our -[troubleshooting section](/docs/help/troubleshooting). - -### Uninstalling Nuclide - -To remove Nuclide and its dependencies, follow the [uninstall instructions](/docs/editor/uninstall). diff --git a/docs/blog/all.html b/docs/blog/all.html deleted file mode 100644 index 884823f024..0000000000 --- a/docs/blog/all.html +++ /dev/null @@ -1,19 +0,0 @@ ---- -id: blog -title: All Posts … -layout: blog ---- - -
-
-

All Posts

-
-
    - {% for post in site.posts %} -
  • - {{ post.title }} - on {{ post.date | date: '%d %B %Y' }} -
  • - {% endfor %} -
-
diff --git a/docs/blog/index.md b/docs/blog/index.md deleted file mode 100644 index 84953e4f94..0000000000 --- a/docs/blog/index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -id: blog -title: Blog -layout: blog ---- - -{% assign posts = site.posts limit 10 %} -{% for post in posts %} - {% include post.html post=post truncate=true %} -{% endfor %} diff --git a/docs/css/main.scss b/docs/css/main.scss deleted file mode 100644 index 4867e89ba2..0000000000 --- a/docs/css/main.scss +++ /dev/null @@ -1,84 +0,0 @@ ---- -# Only the main Sass file needs front matter (the dashes are enough) ---- -@charset "utf-8"; - - - -// Our variables -$base-font-family: "Segoe UI", Helvetica, sans-serif; -$header-font-family: "Gotham Rounded A", "Gotham Rounded B", 'Helvetica Neue', Arial, sans-serif; -$base-font-size: 16px; -$small-font-size: $base-font-size * 0.875; -$base-line-height: 1.4em; - -$spacing-unit: 12px; - -$text: {{ site.color.bodytext }}; -$header-text: {{ site.color.headertext }}; -$primary-bg: {{ site.color.primary }}; -$secondary-bg: {{ site.color.secondary }}; -$light-color: {{ site.color.light }}; -$light-text-color: {{ site.color.lighttext }}; -$nav-bg: {{ site.color.primary }}; -$nav-text: {{ site.color.navtext }}; -$footer-bg: #1F242A; -$link-color: {{ site.color.link }}; - -$header-height: 34px; -$header-ptop: 10px; -$header-pbot: 8px; - -// Width of the content area -$content-width: 900px; - -// Table setting variables -$lightergrey: #F8F8F8; -$greyish: #E8E8E8; -$lightgrey: #B0B0B0; -$green: #2db04b; - -// Using media queries with like this: -// @include media-query($on-palm) { -// .wrapper { -// padding-right: $spacing-unit / 2; -// padding-left: $spacing-unit / 2; -// } -// } -@mixin media-query($device) { - @media screen and (max-width: $device) { - @content; - } -} - - - -// Import partials from `sass_dir` (defaults to `_sass`) -@import - "reset", - "base", - "search", - "slideshow", - "syntax-highlighting", - "tables" -; - -// Anchor links -// http://ben.balter.com/2014/03/13/pages-anchor-links/ -.header-link { - position: absolute; - margin-left: 0.2em; - opacity: 0; - - -webkit-transition: opacity 0.2s ease-in-out 0.1s; - -moz-transition: opacity 0.2s ease-in-out 0.1s; - -ms-transition: opacity 0.2s ease-in-out 0.1s; -} - -h2:hover .header-link, -h3:hover .header-link, -h4:hover .header-link, -h5:hover .header-link, -h6:hover .header-link { - opacity: 1; -} diff --git a/docs/doc-type-examples/2016-04-07-blog-post-example.md b/docs/doc-type-examples/2016-04-07-blog-post-example.md deleted file mode 100644 index ef954d63a7..0000000000 --- a/docs/doc-type-examples/2016-04-07-blog-post-example.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Blog Post Example -layout: post -author: exampleauthor -category: blog ---- - -Any local blog posts would go in the `_posts` directory. - -This is an example blog post introduction, try to keep it short and about a paragraph long, to encourage people to click through to read the entire post. - - - -Everything below the `` tag will only show on the actual blog post page, not on the `/blog/` index. - -Author is defined in `_data/authors.yml` - - -## No posts? - -If you have no blog for your site, you can remove the entire `_posts` folder. Otherwise add markdown files in here. See CONTRIBUTING.md for details. diff --git a/docs/doc-type-examples/docs-hello-world.md b/docs/doc-type-examples/docs-hello-world.md deleted file mode 100644 index c7094ba5af..0000000000 --- a/docs/doc-type-examples/docs-hello-world.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -docid: hello-world -title: Hello, World! -layout: docs -permalink: /docs/hello-world.html ---- - -Any local docs would go in the `_docs` directory. - -## No documentation? - -If you have no documentation for your site, you can remove the entire `_docs` folder. Otherwise add markdown files in here. See CONTRIBUTING.md for details. diff --git a/docs/doc-type-examples/top-level-example.md b/docs/doc-type-examples/top-level-example.md deleted file mode 100644 index 67b1fa7110..0000000000 --- a/docs/doc-type-examples/top-level-example.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -layout: top-level -title: Support Example -id: top-level-example -category: top-level ---- - -This is a static page disconnected from the blog or docs collections that can be added at a top-level (i.e., the same level as `index.md`). diff --git a/docs/docs/index.md b/docs/docs/index.md deleted file mode 100644 index d70536aafe..0000000000 --- a/docs/docs/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -id: docs -title: Docs -layout: redirect -destination: quick-start/getting-started/ ---- diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index f1711ad340..0000000000 --- a/docs/index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -layout: home -id: home ---- - -{% include content/gridblocks.html data_source=site.data.features grid_type="twoByGridBlock" %} - -
- This project is unrelated to the CSS framework project named Nuclide. -
diff --git a/docs/js/docsearch.js b/docs/js/docsearch.js deleted file mode 100644 index 47d29cbde4..0000000000 --- a/docs/js/docsearch.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * 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. - * - * @noflow - */ -'use strict'; - -/* eslint - comma-dangle: [1, always-multiline], - prefer-object-spread/prefer-object-spread: 0, - nuclide-internal/no-commonjs: 0, - */ - -/* eslint-disable no-var */ -/* eslint-disable no-undef */ - -// For Algolia search -(function() { - // Algolia - docsearch({ - apiKey: '421f79d033cee73a376aba52e4f572eb', - indexName: 'nuclide', - inputSelector: '#algolia-doc-search', - }); -})(); diff --git a/docs/js/get-required-versions.js b/docs/js/get-required-versions.js deleted file mode 100644 index 8b6c03af2a..0000000000 --- a/docs/js/get-required-versions.js +++ /dev/null @@ -1,64 +0,0 @@ -/** - * 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. - * - * @noflow - */ -'use strict'; - -/* eslint - comma-dangle: [1, always-multiline], - prefer-object-spread/prefer-object-spread: 0, - nuclide-internal/no-commonjs: 0, - */ -/* eslint-disable prefer-arrow-callback */ -/* eslint-disable no-var */ -/* eslint-disable no-undef */ - -(function() { - if (typeof fetch !== 'function') { - // Your browser is too old... - return; - } - - // Not supported on all browsers, but is on modern browsers that - // will be used by 99% of the people accessing the site. - var nodeEls = document.getElementsByClassName('node'); - var atomEls = document.getElementsByClassName('atom'); - var nuclideEls = document.getElementsByClassName('nuclide'); - - if (!(nodeEls.length > 0 || atomEls.length > 0 || nuclideEls.length > 0)) { - // Nothing to do in this page... - return; - } - - fetch( - 'https://raw.githubusercontent.com/facebook/nuclide/master/package.json', - {mode: 'cors'} - ).then(function(response) { - return response.json(); - }).then(function(data) { - // Get the first part that looks like a version... - var versionLikeRe = /\b\d+\.\d+\.\d+\b/; - - var nodeVersion = data.engines.node.match(versionLikeRe)[0]; - var atomVersion = data.engines.atom.match(versionLikeRe)[0]; - var nuclideVersion = data.version; - - for (var i = 0; i < nodeEls.length; i++) { - nodeEls.item(i).innerHTML = - 'A Node version that is greater or equal to ' + nodeVersion + ' is required.'; - } - for (var j = 0; j < atomEls.length; j++) { - atomEls.item(j).innerHTML = - 'Nuclide requires an Atom version that is greater or equal to ' + atomVersion + '.'; - } - for (var k = 0; k < nuclideEls.length; k++) { - nuclideEls.item(k).innerHTML = - 'The current version of Nuclide is ' + nuclideVersion + '.'; - } - }); -})(); diff --git a/docs/js/jekyll-link-anchors.js b/docs/js/jekyll-link-anchors.js deleted file mode 100644 index 0026725b09..0000000000 --- a/docs/js/jekyll-link-anchors.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * 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. - * - * @noflow - */ -'use strict'; - -/* eslint - comma-dangle: [1, always-multiline], - prefer-object-spread/prefer-object-spread: 0, - nuclide-internal/no-commonjs: 0, - */ - -/* eslint-disable no-var */ -/* eslint-disable prefer-arrow-callback */ - -// Taken and modified from https://gist.github.com/SimplGy/a229d25cdb19d7f21231 -(function() { - // Create intra-page links - // Requires that your headings already have an `id` attribute set (because that's what jekyll - // does). For every heading in your page, this adds a little anchor link `#` that you can click - // to get a permalink to the heading. Ignores `h1`, because you should only have one per page. - - // This also allows us to have uniquely named links even with headings of the same name. - // e.g., - // h2: Mac (#mac) - // h3: prerequisites (#mac__prerequisites) - // h2: Linux (#linux) - // h3: prerequisites (#linux__prerequisites) - - // We don't want anchors for any random h2 or h3; only ones with an - // id attribute which aren't in h2's and h3's in the sidebar ToC and - // header bar. - var possibleNodeNames = ['h2', 'h3', 'h4', 'h5']; // Really try to only have up to h3, please - var tags = document.querySelectorAll('h2[id], h3[id], h4[id], h5[id]'); - var headingNodes = Array.prototype.slice.call(tags); - - headingNodes.forEach(function(node) { - var nameIdx = possibleNodeNames.indexOf(node.localName); // h2 = 0, h3 = 1, etc. - var link; - var id; - var psib; - var suffix; - - // Remove automatic id suffix added by kramdown if heading with same name exists. - // e.g., - // h2: Mac - // h3: prerequisites (id = prerequisites) - // h2: Linux - // h3: prerequisites (id = prerequisites-1) - - // Only match at end of string since that is where auto suffix wil be added. - suffix = node.getAttribute('id').match(/-[0-9]+$/); - // If the -1, etc. suffix exists, make sure someone didn't purposely put the suffix there - // by checking against the actual text associated with the node - if (suffix != null && - node.getAttribute('id').substring(0, suffix.index) === node.textContent.toLowerCase()) { - node.setAttribute('id', node.textContent.toLowerCase()); - } - - link = document.createElement('a'); - link.className = 'header-link'; - link.textContent = '#'; - id = ''; - - // Avoid duplicate anchor links - // If we are at an h3, go through the previous element siblings of this node, and find its - // h2 parent and append it to the href text. - psib = node.previousElementSibling; - var idx; - while (psib) { - // Find the parent, if it exists. - idx = possibleNodeNames.indexOf(psib.localName); - if (idx !== -1 && idx === nameIdx - 1) { // if we are at h3, we want h2. That's why the - 1 - id += psib.getAttribute('id') + '__'; - break; - } - psib = psib.previousElementSibling; - } - link.id = id + node.getAttribute('id'); - link.href = '#' + link.id; - node.appendChild(link); - }); -})(); diff --git a/docs/static/favicon.png b/docs/static/favicon.png deleted file mode 100644 index 9e0eaf4a11..0000000000 Binary files a/docs/static/favicon.png and /dev/null differ diff --git a/docs/static/fonts/332720/11F30310EFD3175B0.css b/docs/static/fonts/332720/11F30310EFD3175B0.css deleted file mode 100644 index 06c864d7a7..0000000000 --- a/docs/static/fonts/332720/11F30310EFD3175B0.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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))); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/143BB439096CFDFC4.css b/docs/static/fonts/332720/143BB439096CFDFC4.css deleted file mode 100644 index 93e7cb801c..0000000000 --- a/docs/static/fonts/332720/143BB439096CFDFC4.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,MgA/Al0APwA9ACoCOgBdA1MAZQIzAD8BXQA/AToAPwI8AD8CSQA/AmgAFgNvABIBaAA/AmgAPwI1AD8DQgA/AjcAdgJAAD8CPABdAjcAYgIsAE4CHgBPAUEAPwI9AHgCXQA/AAAALAEAAD8BCgA/PwEAAQAAAAIAAAAEAAEAGgABAAEAAgAAAAAAGAAAAA4AAAABAAALHz8/P35/Pz9/fz8/Pz8/Pz8LHz8/P38/Pz8/Pz8/Pz8/Pz8LHj8/Pz8GfR8/Pz8/Cx8/Pz8/CD8/Pz8/PwY/CD8/Pz8/Px8/Pz9/fz8/Pwg/fT8/Pz9YRjQnAQEEABM/FT8/FBY/Dh8/Pz8/Pz8/Pz8/Pz8/Pz8/FT9YPwc/Yj8/bj8/P3V7Pz8Gbj8/Pz8/Pz8/eT8/Pz8/FWhzPwohFT8/CiAVPz8/CH54P30/Pz90Pz8/P3w/fD97PxU/PwU/CD8/Pz8/Pz8/Pz8/Px4/Pz8/Pz8/PxU/Fz8HfT8fPz8/Pz8/Pz8ePz8/Pz8/Pz8VPxs/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/Px8/Pz8/FXBoBj8/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwU/Pwg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8ePz8/Pz8/Pz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Bz8/FVt3Pwc/cj8/ej8IPz8/Pz8/Hj8/Pz8HPz8/Pz8/eR4/Pz8/Pz8/PwY/Pz8/FXw/ZT8IPz8/Pz8/P3I/ej93P3Z/f3o/BT8/CD8/Pz8/Pz8/Pz9pPz8/Pz8/Pz9jP1Y/YT9sbnlWdT95P24/HmBhYUhNP2o/CD8/Pz8/Pz9wP3c/P3N7fXg/ch9vP3U/Pz8/Pwg/Pz8/fD8VSj8iPwc/fj8/Px8/Pz8/CD8/Pz8/PwU/Pwg/Pz8/Pz8ePz8/Pwd3Pz8/PxUqPwg/P3Q/bD98P30/Pz8/eT9vP28/Pz8/Pz8VFz9iBj8IPz8/Pz8/Pz8/Pz8/Pz8/P3s/Pz8/Pz8/Pz8/Pz8/BT8/Bj8/Pwg/Pz8/Pz8/Pz8/Pz8/Pz9zPz8/Pz8/Pz8/Pz8/Pz8FPz8/PxU/Px56fz97ej9/Pwg/Pz8/Pz91P30/dD8VPz8tPwg/Pz8/Pz8/Pz8/Pz8/P3Q/Pz8FPz8/Pz9yPz8/Pz8/dz8/Pz8/P3o/Pz8/Pz8IPz8/Pz8/Hz8/Pz8/Pz8/FVk/Bz8/eT8IPz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwU/Pz8/FT97Bz9yPz95Pwg/Pz8/Pz8ePz8/Pz8/Pz8/Pz8/Bz8IPz8/Pz8/Bj8/Pz8VPwc/cj8/Pz8ffj8/Pwg/Pz8/Pz8FPz8GPz8/Pz8/cj8/Pz8/FTsrHz8/Pz8/Pz8/Pz8/Pz8/Pz8VPxI/Hz8/P3p5f359CD8/Pz8/PwU/PwY/Pz8Ifz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwY/CD8/Pz8/PxVRPyY/Bj8/Pz8VQT9VPwojFT8GP2I/P1g/Pwg/Pz8/Pz8GPz8/CD8/Pz8/PwY/Pz8IPz8/Pz8/Bj8/Pz8/FT85PwojBD8KIhU/PwojBD8KIhVBPwoiFT9QCiEVPz8KIBU/Pw4ePz8/Pz99P3gHcB54fX14eD99Pwc/FQI/Px8/Pz8/Bj8ePz8/fQV3P3sePz8/Pz8/Pz8VPz8hPz8OHj8/Pz8HPwg/Pz8/Pz8FPD8/Pz8fPz8/f38/P38GEz8efz8/Pwc/CD8/Pz8/PwU8Pz8/H38/Pz8/Pz8/BiE/Fj9aDgg/Pz8/fT8FXz87Pwg/Pz8/Pz9+Pz9/P30/fT8/Pz8FQz8oP0U/KD8IPz8/Pz9+Bj8IP30/Pz8/BUU/KD9FPyk/CD8/Pz8/fT99Pz8/Pz8/Pz8/PwVfPzs/CD8/Pz8/PwY/CD8/Pz98PwU1PyU/NT8mPwg/Pz8/Pz8GPxU/Pz8/Pw4ePz8/Pz8/P3wHQQg/Pz8/HhU/Mz8OPwc/Px58Pz99fT8/Pwc/Px4/P1AkJz8+IQc/Px58Pz99fT8/PxV9Pz8/Pw4IP3A/ZD8/Pz8/Pz9+Pz8/P34/Pz8/Pz8/Vj9TP04eRmVVUAc/CE8/dT93P3M/cj8wPwc/HzlQRigIP1Q/Tj9aPz8/Pz8/Pz8/Pz8/Pz8/Pz8/cT97Pz8/Hj8/Pz8HPwg/Pz9GP0I/OT81Pz8HPx8/Pz8/FT8/PyEOHn0/P319Pz8/BxA/CChfVTI/Qz98Pz8/Pz8/Pz8/Pz8APz84Pz8HUD8ePz8/Pz8/P3wVP18/Dh4NPyg0DD8HPx4PPyk/Cj8NPz8MPwc/Hw8/Lwo/FT8/His/Dj8CPyM/Bz8eIz8QPwM/LD8rPw4/Aj8jPwc/HyM/ED8DPyw/FX8/Pz8OHgM/Px0/Bz8eGj8uICEyJRY/Bz8fFz8zPz8VWj8/Px4/Pz8/Pz8/fAcuCD8/Pz8eDz8oET86Pwc/Hzo/JhE/Dz8IPyU/ST9hBz8/Hnw/P319Pz8/FVk/Pw4IPz8/Pz8/BT8/Pz8/Pz8IPz8/Pz8/fz9/fz9+Pz8/Pz8/BT8/fD8/P3k/CD8/Pz8/Pz9+Pz8/Pz8/Pz8/PwU/Pz8/Pz8/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwU/Pz8/Pz8/CD8/Pz8/Px4/Pz9+FT8LPw4ffX9/fQY/CD8/Pz8/PwU/P2w/Pz8efT8/fX0/Pz8HKD8fPz8/PwY/CD8/Pz8/PwU/P3U/Pz8ePz8/Pz8/P30VP08/Dh59f399fT9/PwckPx4/Pz8/P38/fRU/Az8/Dh59f399fT9/Pwc/P1Q/Px59f399fT9/PwckPx4/Pz8/P38/fQc/P1Q/Px4/Pz8/P38/fRU/MT8OHj9/P30HHD8ffX9/fQZYPx9+Pz8/Pz8/PwY+Pz8/ET8ffj8/Pz8/Pz8GET8/P0M/H34/Pz8/Pz8/Bl0/FhY/Dh8tLDUpPE8/Pz8/PwQ/P1Q9FT8/Vh8/P1k/Uj8/Pz8/Wz9VPz8/Pz9NP1M/Zz8/Pz8/CD9nP1I/Pz8/Pz8fP0M/ISM/IQ0/BD8IPzo/Xj90BVA/CHw/Pz8/fj97Pz8/PwVWPz8IPz8/Pz8/Hz8/alJFTUElP0s/ST9AP3o/ez9LP0E/cz90P0g/Pz8/Pwg/KXVEYUE/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8VNj8/Pw0/Dh4LPzE/Mwc/Hig8Pwg/Bz8/Pwc/Hz8/PAM/FT8/Pwg/aT9gPwg/Pz8/Pz99P38/P30/Pz8/Pz8/VT9WP08/IT8rPyhmPz8/Pz8CPx4hPy0/DD8HPx8VPyEnJj8IP0A/Tj9hP1U/aSA/Pwc/H3A/Mj8OPzc/FX8/Pw4eFT9GPjwHPx40TD8GPwY/Pz8HPx8/Pz4VPwQ/Px4oUTg1Bz8ePFI/Pz8/Pz8HPx8/PzgoBBs/Hic/OgU/CD8HPwg5P01IbjNvP1c/OD8HPx4BP0EHPw0/DT8HPwE/Bz8IPz8/Pz8zP0g/Pwc/Hwg/BT8nPxU/Pz8OHgU/OUEoBz8eK0M/Az8HPz8/Bz8fPz82BT8VPz8IP28/YT9RP0U/JT8/Bz8fZz88PwM/Qj8IP0E/Uj9TCD8/Pz8/Pz8/Pz8/Pz8/Pz8/P2I/dT8/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GAEWARQBEgEPAT8APwA/AD8APwB6AHcAdQBzAG8AZABYAE4ASQBFAEAAOQA2ADMAJAAhADgABQBAAHgAAAAYAgQAHAAAAAEAAwA0AgAAAAABABwAAAADAAAAAwAAAABlAHIAYQB3AHQAZgBvAHMALQB0AG4AbwBmAGIAZQB3AC8AbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcALwAvADoAcAB0AHQAaABtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQALgB3AHcAdwA5ADEAMgAwADQAMQAtADMAMgA0ADIALQAzADIANgAwADUAMQAwADIALQA0ADcANAA4ADgALQA3ADQAMgAxADcAMQAgAG0AbwBjAC4AeQBoAHAAYQByAGcAbwBwAHkAdAAuAHcAdwB3ACAAdABhACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAHQAYwBhAHQAbgBvAGMAIAByAG8AIAAsAGUAcgBhAHcAdABmAG8AcwAtAHQAbgBvAGYAYgBlAHcALwBtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQALgB3AHcAdwAvAC8AOgBwAHQAdABoACAAdABpAHMAaQB2ACAAZQBzAGEAZQBsAHAAIAAsAG4AbwBpAHQAYQBtAHIAbwBmAG4AaQAgAGUAcgBvAG0AIAByAG8ARgAgAC4AZQBzAG8AcAByAHUAcAAgAHkAbgBhACAAcgBvAGYAIABlAHIAYQB3AHQAZgBvAHMAIABzAGkAaAB0ACAAZQBzAHUAIAB0AG8AbgAgAHkAYQBtACAAdQBvAHkAIAAsAHMAdABzAGkAeABlACAAdABuAGUAbQBlAGUAcgBnAGEAIABoAGMAdQBzACAAbwBuACAAZgBJACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGQAbgBhACAAdQBvAHkAIABuAGUAZQB3AHQAZQBiACAAcwB0AHMAaQB4AGUAIAB0AGEAaAB0ACAAdABuAGUAbQBlAGUAcgBnAGEAIABlAGMAaQB2AHIAZQBTACAAZgBvACAAcwBtAHIAZQBUACAAZQBoAHQAIABvAHQAIAB0AGMAZQBqAGIAdQBzACAAcwBpACAAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAdAAgAGUAcwB1ACAAbwB0ACAAdABoAGcAaQByACAAcgB1AG8AWQAgAC4AbgBvAGkAdABhAGMAbwBsACAAeQBuAGEAIABtAG8AcgBmACAAdABpACAAdABzAG8AaAAgAHIAbwAgACwAcgBlAHQAdQBwAG0AbwBjACAAeQBuAGEAIABuAG8AcAB1ACAAdABpACAAbABsAGEAdABzAG4AaQAgAHIAbwAgACwAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAdAAgAGQAYQBvAGwAbgB3AG8AZAAgAHIAbwAgACwAZQB0AHUAYgBpAHIAdABzAGkAZAAgACwAeQBmAGkAZABvAG0AIAAsAHkAcABvAGMAIAB0AG8AbgAgAHkAYQBtACAAdQBvAFkAIAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIACAAZgBvACAAeQB0AHIAZQBwAG8AcgBwACAAZQBoAHQAIABzAGkAIABlAHIAYQB3AHQAZgBvAHMAIABzAGkAaABUAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgALgBzAG4AbwBpAHQAYwBpAGQAcwBpAHIAdQBqACAAbgBpAGEAdAByAGUAYwAgAG4AaQAgAGQAZQByAGUAdABzAGkAZwBlAHIAIABlAGIAIAB5AGEAbQAgAGgAYwBpAGgAdwAgACwALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGYAbwAgAGsAcgBhAG0AZQBkAGEAcgB0ACAAYQAgAHMAaQAgAGQAZQBkAG4AdQBvAFIAIABtAGEAaAB0AG8ARwB0AG4AbwBGADEAMAAyAC4AMQAgAG4AbwBpAHMAcgBlAFYAOQAxADIAMAA0ADEALQAzADIANAAyAC0AMwAyADYAMAA1ADEAMAAyAC0ANAA3ADQAOAA4AC0ANwA0ADIAMQA3ADEAcgBhAGwAdQBnAGUAUgBtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQAIAB8ACAAbwBDACYASAAgACkAQwAoACAAdABoAGcAaQByAHkAcABvAEMAbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcALwAvADoAcAB0AHQAaAAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIAA3ADAAMAAyACAALAA2ADAAMAAyACAAKQBDACgAIAB0AGgAZwBpAHIAeQBwAG8AQwBlcmF3dGZvcy10bm9mYmV3L21vYy55aHBhcmdvcHl0Lnd3dy8vOnB0dGhtb2MueWhwYXJnb3B5dC53d3c5MTIwNDEtMzI0Mi0zMjYwNTEwMi00NzQ4OC03NDIxNzEgbW9jLnlocGFyZ29weXQud3d3IHRhIC5vQyAmIHJlbGZlb0ggdGNhdG5vYyBybyAsZXJhd3Rmb3MtdG5vZmJldy9tb2MueWhwYXJnb3B5dC53d3cvLzpwdHRoIHRpc2l2IGVzYWVscCAsbm9pdGFtcm9mbmkgZXJvbSByb0YgLmVzb3BydXAgeW5hIHJvZiBlcmF3dGZvcyBzaWh0IGVzdSB0b24geWFtIHVveSAsc3RzaXhlIHRuZW1lZXJnYSBoY3VzIG9uIGZJIC5vQyAmIHJlbGZlb0ggZG5hIHVveSBuZWV3dGViIHN0c2l4ZSB0YWh0IHRuZW1lZXJnYSBlY2l2cmVTIGZvIHNtcmVUIGVodCBvdCB0Y2VqYnVzIHNpIGVyYXd0Zm9zIHNpaHQgZXN1IG90IHRoZ2lyIHJ1b1kgLm5vaXRhY29sIHluYSBtb3JmIHRpIHRzb2ggcm8gLHJldHVwbW9jIHluYSBub3B1IHRpIGxsYXRzbmkgcm8gLGVyYXd0Zm9zIHNpaHQgZGFvbG53b2Qgcm8gLGV0dWJpcnRzaWQgLHlmaWRvbSAseXBvYyB0b24geWFtIHVvWSAub0MgJiByZWxmZW9IIGZvIHl0cmVwb3JwIGVodCBzaSBlcmF3dGZvcyBzaWhULm9DICYgcmVsZmVvSC5zbm9pdGNpZHNpcnVqIG5pYXRyZWMgbmkgZGVyZXRzaWdlciBlYiB5YW0gaGNpaHcgLC5vQyAmIHJlbGZlb0ggZm8ga3JhbWVkYXJ0IGEgc2kgZGVkbnVvUiBtYWh0b0d0bm9GMTAyLjEgbm9pc3JlVjkxMjA0MS0zMjQyLTMyNjA1MTAyLTQ3NDg4LTc0MjE3MXJhbHVnZVJtb2MueWhwYXJnb3B5dCB8IG9DJkggKUMoIHRoZ2lyeXBvQ21vYy55aHBhcmdvcHl0Lnd3dy8vOnB0dGggLm9DICYgcmVsZmVvSCA3MDAyICw2MDAyIClDKCB0aGdpcnlwb0M/A0YAEgAJBAEAAwA/A0YAEQAJBAEAAwA/A0YAEAAJBAEAAwA/CVQADgAJBAEAAwBrBSIEDQAJBAEAAwA/CSQADAAJBAEAAwA/CSQACwAJBAEAAwBrBSIECgAJBAEAAwBRBRoACQAJBAEAAwBRBRoACAAJBAEAAwA/BD8ABwAJBAEAAwA/BAgABgAJBAEAAwBtBBoABQAJBAEAAwA/A0YABAAJBAEAAwArBEIAAwAJBAEAAwAdBA4AAgAJBAEAAwA/A0YAAQAJBAEAAwBXAz8AAAAJBAEAAwBAACMAEgAAAAAAAQBAACMAEQAAAAAAAQBAACMAEAAAAAAAAQAtAyoADgAAAAAAAQAKARECDQAAAAAAAQAbAxIADAAAAAAAAQAbAxIACwAAAAAAAQAKARECCgAAAAAAAQA/AA0ACQAAAAAAAQA/AA0ACAAAAAAAAQA/AGEABwAAAAAAAQA/AAQABgAAAAAAAQA/AA0ABQAAAAAAAQBAACMABAAAAAAAAQBqACEAAwAAAAAAAQBjAAcAAgAAAAAAAQBAACMAAQAAAAAAAQAAAEAAAAAAAAAAAQA/ASQAAAABACAAIAA/Aj8BAAAAAAsAAAA/AD8DPwA4PyADEj8kAAAAb0MmSAAAAAAAAAAASgAAUH8AAD8AAAAAAAAAAAAAAAA/ADIAPwEAAD8CPwI/AAAAPwI/AgQABQAsAU0CAgAAABsAAFAAABsAAAAAAAAAAAAAAAAAAAABAD8DAAAAAD8DAAAQPz8DAAABAAAAAAAAAAIACAAAACADPwM4PwAAHwIsPwAAAAAfAiw/AAAAAD8DCwA/PA9fPz8/LkEAAQAAAAEAIAAAAHgQAAAyAD8/dHNvcD8LAAA/AQAABDM1KGVtYW4GAAAAGAEAAABQGwBweGFtbAAAADAfAAA/Bj89eHRtaCQAAAA/AAAAAANhB2FlaGg2AAAAPwAAAD9HFgNkYWVoCAAAACgfAAALAAAAcHNhZzoDAAA8DQAAAj8/cGFtY2AAAAAgAQAASyU/VTIvU08gAAAACB8AAAQASABGRURHbw4AAD8QAABjPz9PIEZGQzAAAwA/AAsAT1RUTw==))); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:font/opentype;base64,T1RUTwALAIAAAwAwQ0ZGIE+2i2MAABCYAAAOb0dERUYASAAEAAAfCAAAACBPUy8yVcclSwAAASAAAABgY21hcO62ywIAAA08AAADOmdhc3AAAAALAAAfKAAAAAhoZWFkAxZHvAAAALwAAAA2aGhlYQdhAwAAAAD0AAAAJGhtdHg9xwbVAAAfMAAAAGxtYXhwABtQAAAAARgAAAAGbmFtZSg1MwQAAAGAAAALu3Bvc3T/uAAyAAAQeAAAACAAAQAAAAEAQS6s5cVfDzz1AAsD6AAAAADQLAIfAAAAANAsAh8AAP84A58DIAAAAAgAAgAAAAAAAAABAAADwP8QAAAD1AAAAAADnwABAAAAAAAAAAAAAAAAAAAAGwAAUAAAGwAAAAICTQEsAAUABAK8AooAAACMArwCigAAAd0AMgD6AAAAAAAAAAAAAAAAoAAAf1AAAEoAAAAAAAAAAEgmQ28AAAAk4BIDIP84AMgDwADwAAAACwAAAAAB/gK8ACAAIAABAAAAJAG2AAEAAAAAAAAAQAAAAAEAAAAAAAEAIwBAAAEAAAAAAAIABwBjAAEAAAAAAAMAIQBqAAEAAAAAAAQAIwBAAAEAAAAAAAUADQCLAAEAAAAAAAYABACYAAEAAAAAAAcAYQCcAAEAAAAAAAgADQD9AAEAAAAAAAkADQD9AAEAAAAAAAoCEQEKAAEAAAAAAAsAEgMbAAEAAAAAAAwAEgMbAAEAAAAAAA0CEQEKAAEAAAAAAA4AKgMtAAEAAAAAABAAIwBAAAEAAAAAABEAIwBAAAEAAAAAABIAIwBAAAMAAQQJAAAAgANXAAMAAQQJAAEARgPXAAMAAQQJAAIADgQdAAMAAQQJAAMAQgQrAAMAAQQJAAQARgPXAAMAAQQJAAUAGgRtAAMAAQQJAAYACASHAAMAAQQJAAcAwgSPAAMAAQQJAAgAGgVRAAMAAQQJAAkAGgVRAAMAAQQJAAoEIgVrAAMAAQQJAAsAJAmNAAMAAQQJAAwAJAmNAAMAAQQJAA0EIgVrAAMAAQQJAA4AVAmxAAMAAQQJABAARgPXAAMAAQQJABEARgPXAAMAAQQJABIARgPXQ29weXJpZ2h0IChDKSAyMDA2LCAyMDA3IEhvZWZsZXIgJiBDby4gaHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbUNvcHlyaWdodCAoQykgSCZDbyB8IHR5cG9ncmFwaHkuY29tUmVndWxhcjE3MTI0Ny04ODQ3NC0yMDE1MDYyMy0yNDIzLTE0MDIxOVZlcnNpb24gMS4yMDFGb250R290aGFtIFJvdW5kZWQgaXMgYSB0cmFkZW1hcmsgb2YgSG9lZmxlciAmIENvLiwgd2hpY2ggbWF5IGJlIHJlZ2lzdGVyZWQgaW4gY2VydGFpbiBqdXJpc2RpY3Rpb25zLkhvZWZsZXIgJiBDby5UaGlzIHNvZnR3YXJlIGlzIHRoZSBwcm9wZXJ0eSBvZiBIb2VmbGVyICYgQ28uIFlvdSBtYXkgbm90IGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgb3IgZG93bmxvYWQgdGhpcyBzb2Z0d2FyZSwgb3IgaW5zdGFsbCBpdCB1cG9uIGFueSBjb21wdXRlciwgb3IgaG9zdCBpdCBmcm9tIGFueSBsb2NhdGlvbi4gWW91ciByaWdodCB0byB1c2UgdGhpcyBzb2Z0d2FyZSBpcyBzdWJqZWN0IHRvIHRoZSBUZXJtcyBvZiBTZXJ2aWNlIGFncmVlbWVudCB0aGF0IGV4aXN0cyBiZXR3ZWVuIHlvdSBhbmQgSG9lZmxlciAmIENvLiBJZiBubyBzdWNoIGFncmVlbWVudCBleGlzdHMsIHlvdSBtYXkgbm90IHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSB2aXNpdCBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUsIG9yIGNvbnRhY3QgSG9lZmxlciAmIENvLiBhdCB3d3cudHlwb2dyYXBoeS5jb20gMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5d3d3LnR5cG9ncmFwaHkuY29taHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbS93ZWJmb250LXNvZnR3YXJlAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMAA2ACwAIAAyADAAMAA3ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgAEgAJgBDAG8AIAB8ACAAdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAFIAZQBnAHUAbABhAHIAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAVgBlAHIAcwBpAG8AbgAgADEALgAyADAAMQBGAG8AbgB0AEcAbwB0AGgAYQBtACAAUgBvAHUAbgBkAGUAZAAgAGkAcwAgAGEAIAB0AHIAYQBkAGUAbQBhAHIAawAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4ALAAgAHcAaABpAGMAaAAgAG0AYQB5ACAAYgBlACAAcgBlAGcAaQBzAHQAZQByAGUAZAAgAGkAbgAgAGMAZQByAHQAYQBpAG4AIABqAHUAcgBpAHMAZABpAGMAdABpAG8AbgBzAC4ASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgBUAGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAaQBzACAAdABoAGUAIABwAHIAbwBwAGUAcgB0AHkAIABvAGYAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAWQBvAHUAIABtAGEAeQAgAG4AbwB0ACAAYwBvAHAAeQAsACAAbQBvAGQAaQBmAHkALAAgAGQAaQBzAHQAcgBpAGIAdQB0AGUALAAgAG8AcgAgAGQAbwB3AG4AbABvAGEAZAAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUALAAgAG8AcgAgAGkAbgBzAHQAYQBsAGwAIABpAHQAIAB1AHAAbwBuACAAYQBuAHkAIABjAG8AbQBwAHUAdABlAHIALAAgAG8AcgAgAGgAbwBzAHQAIABpAHQAIABmAHIAbwBtACAAYQBuAHkAIABsAG8AYwBhAHQAaQBvAG4ALgAgAFkAbwB1AHIAIAByAGkAZwBoAHQAIAB0AG8AIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIABzAHUAYgBqAGUAYwB0ACAAdABvACAAdABoAGUAIABUAGUAcgBtAHMAIABvAGYAIABTAGUAcgB2AGkAYwBlACAAYQBnAHIA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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/16C102A36B2DBC6E6.css b/docs/static/fonts/332720/16C102A36B2DBC6E6.css deleted file mode 100644 index 96c8c1f725..0000000000 --- a/docs/static/fonts/332720/16C102A36B2DBC6E6.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,T1RUTwANAIAAAwBQQ0ZGILkPphQAABIUAAAk2kdERUYAkAAEAAA28AAAACBHUE9TuESiiwAANxAAABwCR1NVQunFLUgAAFMUAAAAgE9TLzJVxiUrAAABQAAAAGBjbWFw0U4uVAAADVwAAASYZ2FzcAAAAAsAAFOUAAAACGhlYWQDcke+AAAA3AAAADZoaGVhB74DqgAAARQAAAAkaG10eNbiGPsAAFOcAAABjG1heHAAY1AAAAABOAAAAAZuYW1lKDUzBAAAAaAAAAu7cG9zdP+4ADIAABH0AAAAIAABAAAAAQBBj0s7+V8PPPUACwPoAAAAANAsAh8AAAAA0CwCH//o/zgEEwMiAAAACAACAAAAAAAAAAEAAAPA/xAAAARO/+j/6AQTAAEAAAAAAAAAAAAAAAAAAABjAABQAABjAAAAAgIsASwABQAEArwCigAAAIwCvAKKAAAB3QAyAPoAAAAAAAAAAAAAAACgAAB/UAAASgAAAAAAAAAASCZDbwAAACPgEgMg/zgAyAPAAPAAAAALAAAAAAH+ArwAIAAgAAIAAAAkAbYAAQAAAAAAAABAAAAAAQAAAAAAAQAjAEAAAQAAAAAAAgAHAGMAAQAAAAAAAwAhAGoAAQAAAAAABAAjAEAAAQAAAAAABQANAIsAAQAAAAAABgAEAJgAAQAAAAAABwBhAJwAAQAAAAAACAANAP0AAQAAAAAACQANAP0AAQAAAAAACgIRAQoAAQAAAAAACwASAxsAAQAAAAAADAASAxsAAQAAAAAADQIRAQoAAQAAAAAADgAqAy0AAQAAAAAAEAAjAEAAAQAAAAAAEQAjAEAAAQAAAAAAEgAjAEAAAwABBAkAAACAA1cAAwABBAkAAQBGA9cAAwABBAkAAgAOBB0AAwABBAkAAwBCBCsAAwABBAkABABGA9cAAwABBAkABQAaBG0AAwABBAkABgAIBIcAAwABBAkABwDCBI8AAwABBAkACAAaBVEAAwABBAkACQAaBVEAAwABBAkACgQiBWsAAwABBAkACwAkCY0AAwABBAkADAAkCY0AAwABBAkADQQiBWsAAwABBAkADgBUCbEAAwABBAkAEABGA9cAAwABBAkAEQBGA9cAAwABBAkAEgBGA9dDb3B5cmlnaHQgKEMpIDIwMDYsIDIwMDcgSG9lZmxlciAmIENvLiBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tQ29weXJpZ2h0IChDKSBIJkNvIHwgdHlwb2dyYXBoeS5jb21SZWd1bGFyMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5VmVyc2lvbiAxLjIwMUZvbnRHb3RoYW0gUm91bmRlZCBpcyBhIHRyYWRlbWFyayBvZiBIb2VmbGVyICYgQ28uLCB3aGljaCBtYXkgYmUgcmVnaXN0ZXJlZCBpbiBjZXJ0YWluIGp1cmlzZGljdGlvbnMuSG9lZmxlciAmIENvLlRoaXMgc29mdHdhcmUgaXMgdGhlIHByb3BlcnR5IG9mIEhvZWZsZXIgJiBDby4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBvciBkb3dubG9hZCB0aGlzIHNvZnR3YXJlLCBvciBpbnN0YWxsIGl0IHVwb24gYW55IGNvbXB1dGVyLCBvciBob3N0IGl0IGZyb20gYW55IGxvY2F0aW9uLiBZb3VyIHJpZ2h0IHRvIHVzZSB0aGlzIHNvZnR3YXJlIGlzIHN1YmplY3QgdG8gdGhlIFRlcm1zIG9mIFNlcnZpY2UgYWdyZWVtZW50IHRoYXQgZXhpc3RzIGJldHdlZW4geW91IGFuZCBIb2VmbGVyICYgQ28uIElmIG5vIHN1Y2ggYWdyZWVtZW50IGV4aXN0cywgeW91IG1heSBub3QgdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpc2l0IGh0dHA6Ly93d3cudHlwb2dyYXBoeS5jb20vd2ViZm9udC1zb2Z0d2FyZSwgb3IgY29udGFjdCBIb2VmbGVyICYgQ28uIGF0IHd3dy50eXBvZ3JhcGh5LmNvbSAxNzEyNDctODg0NzQtMjAxNTA2MjMtMjQyMy0xNDAyMTl3d3cudHlwb2dyYXBoeS5jb21odHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUAQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgADIAMAAwADYALAAgADIAMAAwADcAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAASAAmAEMAbwAgAHwAIAB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AUgBlAGcAdQBsAGEAcgAxADcAMQAyADQANwAtADgAOAA0ADcANAAtADIAMAAxADUAMAA2ADIAMwAtADIANAAyADMALQAxADQAMAAyADEAOQBWAGUAcgBzAGkAbwBuACAAMQAuADIAMAAxAEYAbwBuAHQARwBvAHQAaABhAG0AIABSAG8AdQBuAGQAZQBkACAAaQBzACAAYQAgAHQAcgBhAGQAZQBtAGEAcgBrACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAsACAAdwBoAGkAYwBoACAAbQBhAHkAIABiAGUAIAByAGUAZwBpAHMAdABlAHIAZQBkACAAaQBuACAAYwBlAHIAdABhAGkAbgAgAGoAdQByAGkAcwBkAGkAYwB0AGkAbwBuAHMALgBIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuAFQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIAB0AGgAZQAgAHAAcgBvAHAAZQByAHQAeQAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABZAG8AdQAgAG0AYQB5ACAAbgBvAHQAIABjAG8AcAB5ACwAIABtAG8AZABpAGYAeQAsACAAZABpAHMAdAByAGkAYgB1AHQAZQAsACAAbwByACAAZABvAHcAbgBsAG8AYQBkACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAsACAAbwByACAAaQBuAHMAdABhAGwAbAAgAGkAdAAgAHUAcABvAG4AIABhAG4AeQAgAGMAbwBtAHAAdQB0AGUAcgAsACAAbwByACAAaABvAHMAdAAgAGkAdAAgAGYAcgBvAG0AIABhAG4AeQAgAGwAbwBjAGEAdABpAG8AbgAuACAAWQBvAHUAcgAgAHIAaQBnAGgAdAAgAHQAbwAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHMAdQBiAGoAZQBjAHQAIAB0AG8AIAB0AGgAZQAgAFQAZQByAG0AcwAgAG8AZgAgAFMAZQByAHYAaQBjAGUAIABhAGcAcgBlAGUAbQBlAG4AdAAgAHQAaABhAHQAIABlAHgAaQBzAHQAcwAgAGIAZQB0AHcAZQBlAG4AIAB5AG8AdQAgAGEAbgBkACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAEkAZgAgAG4AbwAgAHMAdQBjAGgAIABhAGcAcgBlAGUAbQBlAG4AdAAgAGUAeABpAHMAdABzACwAIAB5AG8AdQAgAG0AYQB5ACAAbgBvAHQAIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABmAG8AcgAgAGEAbgB5ACAAcAB1AHIAcABvAHMAZQAuACAARgBvAHIAIABtAG8AcgBlACAAaQBuAGYAbwByAG0AYQB0AGkAbwBuACwAIABwAGwAZQBhAHMAZQAgAHYAaQBzAGkAdAAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0ALwB3AGUAYgBmAG8AbgB0AC0AcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABjAG8AbgB0AGEAYwB0ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGEAdAAgAHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtACAAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAvAHcAZQBiAGYAbwBuAHQALQBzAG8AZgB0AHcAYQByAGUAAAAAAwAAAAMAAAAcAAEAAAAAA5IAAwABAAAAHAAEA3YAAACsAIAABgAsACAAIwAvADQANwA/AEQARwBNAF0AXwBjAHEAdAB2AHkAfQCjAKUAqwCuALAAtwC7AMUAxwDWAN0A5QDvAPYA+AD9AQcBDgEQARMBFQEXARkBGwEjAScBKwEtAS8BMQE3AUIBRAFGAUgBUQFUAVYBWAFaAV4BYAFlAWoBbAFuAXABcgF0AXkBewF9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/+cAAAAAAAAAAAAAAAD/8QAA/5z/9v+cAAAAAP/2AAD/8QAAAAAAAAAAAAAAAAAAAAAAFAAA//YAAAAAAAAAAAAAAAD/9gAA//H/8QAAAAAAAAAAAAAAAP/sAAD/7P/x//b/4gAAAAoAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAAAA//sAAAAAAAD/5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/OAAD/9v/2//H/4v/iAAD/2AAA//b/9gAAAAAAAAAAAAD/4gAAAAD/5wAA/87/7P/n/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAP/s/8T/zgAA/84AAAAAAAAAAP/YAAAAAP+c/+z/jf+cAAD/fgAAAAD/9v+wAAD/iAAAAAD/9gAAAAD/+wAA/9j/7P/7AAAAAAAAAAAAAAAAAAD/xAAA/9j/2P+mAAAAAAAA/+wAAAAA/8T/zgAA/8QAAAAAAAD/2AAA/+L/+//JAAD/2P/d/87/xP/YAAAAAAAAAAD/2P/s/+wAAAAA/9gAAP/YAAAAAAAAAAAAAAAAAAAAAAAA/+L/7AAAAAAAAAAAAAAAAP/YAAAAAAAAAAAAAP/7AAAAAAAAAAD/ugAAAAAAAAAAAAAAAP/7AAD/9v/x//YAAAAAAAAAAAAAAAD/+wAA/5wAAP+cAAAADwAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAA8AAAAFAAAACgAAAAoAAAAAAAAAAAAAAAAAAP/JAAAAAP/dAAD/vwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAP/2AAD/7P/xAAD/5wAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+wAAAAAACv/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/9v/xAAD/4v/n/+f/4v/2AAAAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAD/+wAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAA//sAAAAA//H/9v/x//H/+wAAAAD/pv/J/5L/8QAAAAAAAAAAAAAAAP/s/3n/ugAA/+wAAAAAAAD/ef/O/5z/g/+c/6b/zv+D/6b/uv/Y/9j/nAAAAAAAAAAAAAAAAAAA/40AAP+m/84AAP+c/5z/nP+c/5z/kgAAAAD/5wAA/+wAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAP/7AAAAAAAAAAD/nP/YAAD/5wAAAAAAAP/2AAD/7P/2/7oAAAAA//YAAAAAAAD/uv/s/4j/v/+I/9j/5/+//8T/2P/sAAD/2AAAAAAAAAAAAAAAAAAA/8QAAAAA/+wAAP/YAAD/3QAA/9j/yQAAAAD/pv/d/5f/7AAAAAD/9v/2//H/7P/2/7r/0wAA//YAAAAAAAD/v//x/5z/xP+c/93/4v/E/87/3f/x//H/3QAAAAAAAAAAAAAAAAAA/8QAAP+c/+cAAP/d/93/3f/Y/93/yQAAAAAAAP/OAAD/4gAA//YAAP/xAAD/7AAA//YAAAAA//YAAAAAAAD/0wAAAAD/2AAA/87/7P/Y/87/7P/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP/sAAD/2AAA/9gAAAAAAAD/kv/E/37/3QAAAAD/7P/s/+wAAP/2/5z/ugAA//YAAAAAAAD/kv/Y/37/l/9+/7D/2P+X/5z/tf/s/+z/tQAAAAAAAAAAAAAAAAAA/5wAAP+S/+IAAP+1/8T/yf+6/8T/sAAAAAAAAP/YAAD/9gAAAAAAAAAAAAAAAP/2AAD/8QAAAAAAAAAAAAD/5wAAAAD/7AAA/+L/9v/s/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+z/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/3QAAAAAAAAAAAAAAAAAA//sAAAAA/+z/7AAA/+wAAAAAAAAAAAAAAAD/9v+mAAAAAP/OAAD/ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/nAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/7AAAAAD/8QAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/uv/x/+wAAAAA//YAAP/2AAAAAAAAAAD/+wAAAAAAAAAA/+L/3QAA//YAAAAAAAAAAAAAAAAAAAAA/+f/7P/i/+f/8QAAAAAAAP/YAAAAAP+m//EAAP+cAAD/kgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAD/xAAA/8QAAAAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/8QAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/9gAA//b/9gAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/7AAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAD/7AAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/8QAAAAD/9gAAAAAAAP/2//YACgAAAAAAAAAA//H/8QAAAAoADwAAAAAAAAAAAAAAAAAA//v/+//2//sAAAAAAAAAAAAAAAAAAP/OAAD/7P/xAAD/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/YAAAAAP+c//H/iP+cAAD/fgAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/9gAAAAD/8f/2AAAAAAAAAA8AAP/OAAAAAAAAAAD/2AAAAAD/7AAA/+cAAAAA/6v/ugAA/9MAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/sP/2/+wAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAA/+L/2AAAAAAAAAAAAAAAAAAAAAAAAAAA/+f/5//i/+f/8QAAAAAAAP/YAAAAAP+c//H/iP+cAAD/fgAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/9gAAAAD/8f/2AAAAAAAAAAAAAP/OAAAAAAAAAAD/2AAAAAD/7AAA/+cAAAAA/6v/ugAA/8QAAP/sAAD/2AAAAAAAAP+mAAD/2P/d/87/sP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAD/2AAAAAD/9gAA//H/9v/i//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAeAAAAHgAeABT/9gAA/9P/9v/TAAAAAP/2//EAAAAAAAAAAAAAAB4AIwAAAB4AIwA3AAAAAP/TAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+6AAD/2P/d/+z/tQAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+wAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//H/9v/x//EAAAAAAAD/7AAAAAD/9v+mAAD/xP/O/87/nP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAA//YAAAAA/+L/7P/T/+L/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAAAA/+z/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAD/2AAAAAD/5wAAAAD/5wAA/+wAAP/n/+z/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/2/+z/7AAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/sP/x/+wAAAAA/+wAAP/sAAAAAAAAAAD/9gAAAAAAAAAA/+L/zgAA/+wAAAAAAAAAAAAAAAAAAAAA/+L/5//d/+L/7AAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAD/4gAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAAAAP/E//EAAP/OAAD/ugAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAD/3QAA/90AAAAAAAD/pgAA/7AAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/8QAAAAD/8QAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAP/dAAAAAAAA//YAAAAAAA8AAAAAAAAAAAAAAAD/9gAAAAD/nAAA/5wAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/0wAAAAD/2AAAAAAAAP/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAUAAD/4gAAAAD/5wAA/6b/5/+mAAAAAP/n//YAAAAAAAAAAAAAAAAAAAAAABQAIwAAAAAAAP+1AAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/tf/2//EAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAA/+z/3QAA//YAAAAA//YAAAAA//YAAAAA/+z/8f/n//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5wAAP+c/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/iP/YAAD/4gAAAAAAAAAAAAAAAP/s/78AAAAAAAAAAAAAAAD/sAAAAAD/ugAAAAD/5/+6AAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAA/6sAAAAA/+wAAP/OAAD/zgAA/87/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/8QAAAAD/8QAAAAAAAP/x//YAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAAAAAAAAAD/4gAA/6v/5/+r//EAAP/n/+L/8QAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/8QAA//H/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAD/zv/2/+z/5wAA/7r/7P+6//YAAP/s/+z/9gAAAAAAAAAAAAD/9gAAAAAAAAAA//EAAP/EAAAAAAAA//H/9v/2//b/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAD/3QAAAAD/4gAA/+IAAP/i/9P/8QAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAD/zv/2/+z/4gAA/6v/5/+r//EAAP/n/+L/8QAAAAAAAAAAAAD/9gAAAAAAAAAA/+wAAP+6AAAAAAAA//H/9v/2//b/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/0wAAAAD/8QAAAAD/8QAAAAAAAP/x//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEABQBbABgAAAAsAAAAGQAAACAAIwAiADMAAAAyAB8AHwAAAAAAAAAAAAEAAgADAAQABgAHAAgACQAKAAAACwAMAA0ADgAPABAAEQASABMAFAAVABYAHQAbAAAAAAAXABoAHgAhACQAJQAoAAAAAAApAAAAKAAoACsAGgAAADQANgA4ADkAHAAAAAAAAAAAAAAAAAAAACYAAAAAAAAAAAAnAC0AIwAjAC4ALwAgAC4ALwAgAAAAIgAmACcAAQAFAF0ADQAAAAAAIQAOAAAAFQAYABcAKQAAACgAFAAUAAAAAAAAACIAAQAAAAIAAAAAAAIAAwAAAAAAAAACAAAAAgAAAAQABQAGAAcACAAJAAoACwAAABAAEgAAAAwADwATABMAGQAaAA8AHQAeAA8ADwAfAB8AEwAfABYAKgAtAC8AMAAAAAAAEQAAAAAAAAAAAAAAGwAmAAAAAAAAABwAIwAYABgAJAAlABUAJAAlABUAAAAXABsAHAAAACYAAgAOAAUABQAAAAcABwABAAkACQACAAsADgADABAAEgAHABcAHwAKACEALgATADEANwAhADoAOgAoADwAPwApAEEARQAtAE0ATQAyAFIAWwAzAF0AXwA9AAEACAABAAAAAQABAAEAAAABAAAACgAwAD4AAkRGTFQADmxhdG4AGgAEAAAAAP//AAEAAAAEAAAAAP//AAEAAAABc3MwMQAIAAAAAQAAAAIABgAOAAYAAAABABAAAQAAAAEAKAABAAgAAQAOAAEAAQBiAAEABAABAGIAAQAAAAEAAAABAAEABv+fAAEAAQBiAAEAAf//AAoB9AAAASwAAAGaAEUCvAAtAzgANwK4ADEA5gBFAa4ARwGuADwBrgBMAmwAQADmADYBmABCAOYAUgH0//oCmAAvAksAQADwAFcA8AA7AmwAPAJsAE8CbABZAhYAJQMWADgC0gBoAuIASQMOAGgCkABoAxAASQIlACoCywBoAmsAaANkAGgDUgBJApwAaANSAEkC0wBoAoAAQQKIADIC+ABdAu4AOAROADwC0gBJAswANgKwAEcBrgBiAfQACQGuADcCWP/oAj4AMwKUAF0COwA6AkgAOgFqAC0ClAA8AmUAXQD5AF4A+f/7AjAAXQD5AGQDtwBdAmUAXQKAADoClABdApQAPAGQACoCRgA1AjoAQwJMADQB4AA3AR4AeQHgADUCRQA+AoQAQgKuADUDPgA1AYYAOgIDADcBoAAiAcIASgDmAFIBhgAvAgMAQwIWADQCEABCA4IAQgDmAE0A5gA7AOYANgGaAE0BmgA7AZoANgHWAG8CqABSATcANwE3AEMC0AA3ArIAFgK2ADI=); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:font/opentype;base64,T1RUTwALAIAAAwAwQ0ZGIE+2i2MAABCYAAAOb0dERUYASAAEAAAfCAAAACBPUy8yVcclSwAAASAAAABgY21hcO62ywIAAA08AAADOmdhc3AAAAALAAAfKAAAAAhoZWFkAxZHvAAAALwAAAA2aGhlYQdhAwAAAAD0AAAAJGhtdHg9xwbVAAAfMAAAAGxtYXhwABtQAAAAARgAAAAGbmFtZSg1MwQAAAGAAAALu3Bvc3T/uAAyAAAQeAAAACAAAQAAAAEAQS6s5cVfDzz1AAsD6AAAAADQLAIfAAAAANAsAh8AAP84A58DIAAAAAgAAgAAAAAAAAABAAADwP8QAAAD1AAAAAADnwABAAAAAAAAAAAAAAAAAAAAGwAAUAAAGwAAAAICTQEsAAUABAK8AooAAACMArwCigAAAd0AMgD6AAAAAAAAAAAAAAAAoAAAf1AAAEoAAAAAAAAAAEgmQ28AAAAk4BIDIP84AMgDwADwAAAACwAAAAAB/gK8ACAAIAABAAAAJAG2AAEAAAAAAAAAQAAAAAEAAAAAAAEAIwBAAAEAAAAAAAIABwBjAAEAAAAAAAMAIQBqAAEAAAAAAAQAIwBAAAEAAAAAAAUADQCLAAEAAAAAAAYABACYAAEAAAAAAAcAYQCcAAEAAAAAAAgADQD9AAEAAAAAAAkADQD9AAEAAAAAAAoCEQEKAAEAAAAAAAsAEgMbAAEAAAAAAAwAEgMbAAEAAAAAAA0CEQEKAAEAAAAAAA4AKgMtAAEAAAAAABAAIwBAAAEAAAAAABEAIwBAAAEAAAAAABIAIwBAAAMAAQQJAAAAgANXAAMAAQQJAAEARgPXAAMAAQQJAAIADgQdAAMAAQQJAAMAQgQrAAMAAQQJAAQARgPXAAMAAQQJAAUAGgRtAAMAAQQJAAYACASHAAMAAQQJAAcAwgSPAAMAAQQJAAgAGgVRAAMAAQQJAAkAGgVRAAMAAQQJAAoEIgVrAAMAAQQJAAsAJAmNAAMAAQQJAAwAJAmNAAMAAQQJAA0EIgVrAAMAAQQJAA4AVAmxAAMAAQQJABAARgPXAAMAAQQJABEARgPXAAMAAQQJABIARgPXQ29weXJpZ2h0IChDKSAyMDA2LCAyMDA3IEhvZWZsZXIgJiBDby4gaHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbUNvcHlyaWdodCAoQykgSCZDbyB8IHR5cG9ncmFwaHkuY29tUmVndWxhcjE3MTI0Ny04ODQ3NC0yMDE1MDYyMy0yNDIzLTE0MDIxOVZlcnNpb24gMS4yMDFGb250R290aGFtIFJvdW5kZWQgaXMgYSB0cmFkZW1hcmsgb2YgSG9lZmxlciAmIENvLiwgd2hpY2ggbWF5IGJlIHJlZ2lzdGVyZWQgaW4gY2VydGFpbiBqdXJpc2RpY3Rpb25zLkhvZWZsZXIgJiBDby5UaGlzIHNvZnR3YXJlIGlzIHRoZSBwcm9wZXJ0eSBvZiBIb2VmbGVyICYgQ28uIFlvdSBtYXkgbm90IGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgb3IgZG93bmxvYWQgdGhpcyBzb2Z0d2FyZSwgb3IgaW5zdGFsbCBpdCB1cG9uIGFueSBjb21wdXRlciwgb3IgaG9zdCBpdCBmcm9tIGFueSBsb2NhdGlvbi4gWW91ciByaWdodCB0byB1c2UgdGhpcyBzb2Z0d2FyZSBpcyBzdWJqZWN0IHRvIHRoZSBUZXJtcyBvZiBTZXJ2aWNlIGFncmVlbWVudCB0aGF0IGV4aXN0cyBiZXR3ZWVuIHlvdSBhbmQgSG9lZmxlciAmIENvLiBJZiBubyBzdWNoIGFncmVlbWVudCBleGlzdHMsIHlvdSBtYXkgbm90IHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSB2aXNpdCBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUsIG9yIGNvbnRhY3QgSG9lZmxlciAmIENvLiBhdCB3d3cudHlwb2dyYXBoeS5jb20gMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5d3d3LnR5cG9ncmFwaHkuY29taHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbS93ZWJmb250LXNvZnR3YXJlAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMAA2ACwAIAAyADAAMAA3ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgAEgAJgBDAG8AIAB8ACAAdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAFIAZQBnAHUAbABhAHIAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAVgBlAHIAcwBpAG8AbgAgADEALgAyADAAMQBGAG8AbgB0AEcAbwB0AGgAYQBtACAAUgBvAHUAbgBkAGUAZAAgAGkAcwAgAGEAIAB0AHIAYQBkAGUAbQBhAHIAawAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4ALAAgAHcAaABpAGMAaAAgAG0AYQB5ACAAYgBlACAAcgBlAGcAaQBzAHQAZQByAGUAZAAgAGkAbgAgAGMAZQByAHQAYQBpAG4AIABqAHUAcgBpAHMAZABpAGMAdABpAG8AbgBzAC4ASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgBUAGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAaQBzACAAdABoAGUAIABwAHIAbwBwAGUAcgB0AHkAIABvAGYAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAWQBvAHUAIABtAGEAeQAgAG4AbwB0ACAAYwBvAHAAeQAsACAAbQBvAGQAaQBmAHkALAAgAGQAaQBzAHQAcgBpAGIAdQB0AGUALAAgAG8AcgAgAGQAbwB3AG4AbABvAGEAZAAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUALAAgAG8AcgAgAGkAbgBzAHQAYQBsAGwAIABpAHQAIAB1AHAAbwBuACAAYQBuAHkAIABjAG8AbQBwAHUAdABlAHIALAAgAG8AcgAgAGgAbwBzAHQAIABpAHQAIABmAHIAbwBtACAAYQBuAHkAIABsAG8AYwBhAHQAaQBvAG4ALgAgAFkAbwB1AHIAIAByAGkAZwBoAHQAIAB0AG8AIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIABzAHUAYgBqAGUAYwB0ACAAdABvACAAdABoAGUAIABUAGUAcgBtAHMAIABvAGYAIABTAGUAcgB2AGkAYwBlACAAYQBnAHIA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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/21FF71D0D2122923F.css b/docs/static/fonts/332720/21FF71D0D2122923F.css deleted file mode 100644 index 1251976746..0000000000 --- a/docs/static/fonts/332720/21FF71D0D2122923F.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/truetype;base64,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LiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpc2l0IGh0dHA6Ly93d3cudHlwb2dyYXBoeS5jb20vd2ViZm9udC1zb2Z0d2FyZSwgb3IgY29udGFjdCBIb2VmbGVyICYgQ28uIGF0IHd3dy50eXBvZ3JhcGh5LmNvbSAxNzEyNDctODg0NzQtMjAxNTA2MjMtMjQyMy0xNDAyMTl3d3cudHlwb2dyYXBoeS5jb21odHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUAQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgADIAMAAwADYALAAgADIAMAAwADcAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAASAAmAEMAbwAgAHwAIAB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AUgBlAGcAdQBsAGEAcgAxADcAMQAyADQANwAtADgAOAA0ADcANAAtADIAMAAxADUAMAA2ADIAMwAtADIANAAyADMALQAxADQAMAAyADEAOQBWAGUAcgBzAGkAbwBuACAAMQAuADMAMAAxAEYAbwBuAHQARwBvAHQAaABhAG0AIABpAHMAIABhACAAdAByAGEAZABlAG0AYQByAGsAIABvAGYAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACwAIAB3AGgAaQBjAGgAIABtAGEAeQAgAGIAZQAgAHIAZQBnAGkAcwB0AGUAcgBlAGQAIABpAG4AIABjAGUAcgB0AGEAaQBuACAAagB1AHIAaQBzAGQAaQBjAHQAaQBvAG4AcwAuAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AVABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHQAaABlACAAcAByAG8AcABlAHIAdAB5ACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAFkAbwB1ACAAbQBhAHkAIABuAG8AdAAgAGMAbwBwAHkALAAgAG0AbwBkAGkAZgB5ACwAIABkAGkAcwB0AHIAaQBiAHUAdABlACwAIABvAHIAIABkAG8AdwBuAGwAbwBhAGQAIAB0AGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABpAG4AcwB0AGEAbABsACAAaQB0ACAAdQBwAG8AbgAgAGEAbgB5ACAAYwBvAG0AcAB1AHQAZQByACwAIABvAHIAIABoAG8AcwB0ACAAaQB0ACAAZgByAG8AbQAgAGEAbgB5ACAAbABvAGMAYQB0AGkAbwBuAC4AIABZAG8AdQByACAAcgBpAGcAaAB0ACAAdABvACAAdQBzAGUAIAB0AGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAaQBzACAAcwB1AGIAagBlAGMAdAAgAHQAbwAgAHQAaABlACAAVABlAHIAbQBzACAAbwBmACAAUwBlAHIAdgBpAGMAZQAgAGEAZwByAGUAZQBtAGUAbgB0ACAAdABoAGEAdAAgAGUAeABpAHMAdABzACAAYgBlAHQAdwBlAGUAbgAgAHkAbwB1ACAAYQBuAGQAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAASQBmACAAbgBvACAAcwB1AGMAaAAgAGEAZwByAGUAZQBtAGUAbgB0ACAAZQB4AGkAcwB0AHMALAAgAHkAbwB1ACAAbQBhAHkAIABuAG8AdAAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGYAbwByACAAYQBuAHkAIABwAHUAcgBwAG8AcwBlAC4AIABGAG8AcgAgAG0AbwByAGUAIABpAG4AZgBvAHIAbQBhAHQAaQBvAG4ALAAgAHAAbABlAGEAcwBlACAAdgBpAHMAaQB0ACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAvAHcAZQBiAGYAbwBuAHQALQBzAG8AZgB0AHcAYQByAGUALAAgAG8AcgAgAGMAbwBuAHQAYQBjAHQAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAYQB0ACAAdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AIAAxADcAMQAyADQANwAtADgAOAA0ADcANAAtADIAMAAxADUAMAA2ADIAMwAtADIANAAyADMALQAxADQAMAAyADEAOQB3AHcA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AAAAAAAAAAAAAAAAAAD/9gAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//b/9gAA//YAAAAAAAD/sP/sAAAAAAAAAAAAAAAAAAAAAP/2/+cAAAAAAAAAAAAAAAD/8QAA/5z/9v+cAAAAAP/2AAD/8QAAAAAAAAAAAAAAAAAAAAAAFAAA//YAAAAAAAAAAAAAAAD/9gAA//H/8QAAAAAAAAAAAAAAAP/sAAD/7P/x//b/4gAAAAoAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAAAA//sAAAAAAAD/5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/OAAD/9v/2//H/4v/iAAD/2AAA//b/9gAAAAAAAAAAAAD/4gAAAAD/5wAA/87/7P/n/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAP/s/8T/zgAA/84AAAAAAAAAAP/YAAAAAP+c/+z/jf+cAAD/fgAAAAD/9v+wAAD/iAAAAAD/9gAAAAD/+wAA/9j/7P/7AAAAAAAAAAAAAAAAAAD/xAAA/9j/2P+mAAAAAAAA/+wAAAAA/8T/zgAA/8QAAAAAAAD/2AAA/+L/+//JAAD/2P/d/87/xP/YAAAAAAAAAAD/2P/s/+wAAAAA/9gAAP/YAAAAAAAAAAAAAAAAAAAAAAAA/+L/7AAAAAAAAAAAAAAAAP/YAAAAAAAAAAAAAP/7AAAAAAAAAAD/ugAAAAAAAAAAAAAAAP/7AAD/9v/x//YAAAAAAAAAAAAAAAD/+wAA/5wAAP+cAAAADwAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAA8AAAAFAAAACgAAAAoAAAAAAAAAAAAAAAAAAP/JAAAAAP/dAAD/vwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAP/2AAD/7P/xAAD/5wAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+wAAAAAACv/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/9v/xAAD/4v/n/+f/4v/2AAAAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAD/+wAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAA//sAAAAA//H/9v/x//H/+wAAAAD/pv/J/5L/8QAAAAAAAAAAAAAAAP/s/3n/ugAA/+wAAAAAAAD/ef/O/5z/g/+c/6b/zv+D/6b/uv/Y/9j/nAAAAAAAAAAAAAAAAAAA/40AAP+m/84AAP+c/5z/nP+c/5z/kgAAAAD/5wAA/+wAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAP/7AAAAAAAAAAD/nP/YAAD/5wAAAAAAAP/2AAD/7P/2/7oAAAAA//YAAAAAAAD/uv/s/4j/v/+I/9j/5/+//8T/2P/sAAD/2AAAAAAAAAAAAAAAAAAA/8QAAAAA/+wAAP/YAAD/3QAA/9j/yQAAAAD/pv/d/5f/7AAAAAD/9v/2//H/7P/2/7r/0wAA//YAAAAAAAD/v//x/5z/xP+c/93/4v/E/87/3f/x//H/3QAAAAAAAAAAAAAAAAAA/8QAAP+c/+cAAP/d/93/3f/Y/93/yQAAAAAAAP/OAAD/4gAA//YAAP/xAAD/7AAA//YAAAAA//YAAAAAAAD/0wAAAAD/2AAA/87/7P/Y/87/7P/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP/sAAD/2AAA/9gAAAAAAAD/kv/E/37/3QAAAAD/7P/s/+wAAP/2/5z/ugAA//YAAAAAAAD/kv/Y/37/l/9+/7D/2P+X/5z/tf/s/+z/tQAAAAAAAAAAAAAAAAAA/5wAAP+S/+IAAP+1/8T/yf+6/8T/sAAAAAAAAP/YAAD/9gAAAAAAAAAAAAAAAP/2AAD/8QAAAAAAAAAAAAD/5wAAAAD/7AAA/+L/9v/s/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+z/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/3QAAAAAAAAAAAAAAAAAA//sAAAAA/+z/7AAA/+wAAAAAAAAAAAAAAAD/9v+mAAAAAP/OAAD/ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/nAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/7AAAAAD/8QAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/uv/x/+wAAAAA//YAAP/2AAAAAAAAAAD/+wAAAAAAAAAA/+L/3QAA//YAAAAAAAAAAAAAAAAAAAAA/+f/7P/i/+f/8QAAAAAAAP/YAAAAAP+m//EAAP+cAAD/kgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAD/xAAA/8QAAAAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/8QAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/9gAA//b/9gAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/7AAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAD/7AAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/8QAAAAD/9gAAAAAAAP/2//YACgAAAAAAAAAA//H/8QAAAAoADwAAAAAAAAAAAAAAAAAA//v/+//2//sAAAAAAAAAAAAAAAAAAP/OAAD/7P/xAAD/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/YAAAAAP+c//H/iP+cAAD/fgAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/9gAAAAD/8f/2AAAAAAAAAA8AAP/OAAAAAAAAAAD/2AAAAAD/7AAA/+cAAAAA/6v/ugAA/9MAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/sP/2/+wAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAA/+L/2AAAAAAAAAAAAAAAAAAAAAAAAAAA/+f/5//i/+f/8QAAAAAAAP/YAAAAAP+c//H/iP+cAAD/fgAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/9gAAAAD/8f/2AAAAAAAAAAAAAP/OAAAAAAAAAAD/2AAAAAD/7AAA/+cAAAAA/6v/ugAA/8QAAP/sAAD/2AAAAAAAAP+mAAD/2P/d/87/sP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAD/2AAAAAD/9gAA//H/9v/i//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAeAAAAHgAeABT/9gAA/9P/9v/TAAAAAP/2//EAAAAAAAAAAAAAAB4AIwAAAB4AIwA3AAAAAP/TAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+6AAD/2P/d/+z/tQAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+wAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//H/9v/x//EAAAAAAAD/7AAAAAD/9v+mAAD/xP/O/87/nP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAA//YAAAAA/+L/7P/T/+L/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAAAA/+z/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAD/2AAAAAD/5wAAAAD/5wAA/+wAAP/n/+z/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/2/+z/7AAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/sP/x/+wAAAAA/+wAAP/sAAAAAAAAAAD/9gAAAAAAAAAA/+L/zgAA/+wAAAAAAAAAAAAAAAAAAAAA/+L/5//d/+L/7AAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAD/4gAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAAAAP/E//EAAP/OAAD/ugAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAD/3QAA/90AAAAAAAD/pgAA/7AAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/8QAAAAD/8QAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAP/dAAAAAAAA//YAAAAAAA8AAAAAAAAAAAAAAAD/9gAAAAD/nAAA/5wAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/0wAAAAD/2AAAAAAAAP/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAUAAD/4gAAAAD/5wAA/6b/5/+mAAAAAP/n//YAAAAAAAAAAAAAAAAAAAAAABQAIwAAAAAAAP+1AAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/tf/2//EAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAA/+z/3QAA//YAAAAA//YAAAAA//YAAAAA/+z/8f/n//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5wAAP+c/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/iP/YAAD/4gAAAAAAAAAAAAAAAP/s/78AAAAAAAAAAAAAAAD/sAAAAAD/ugAAAAD/5/+6AAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAA/6sAAAAA/+wAAP/OAAD/zgAA/87/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/8QAAAAD/8QAAAAAAAP/x//YAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAAAAAAAAAD/4gAA/6v/5/+r//EAAP/n/+L/8QAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/8QAA//H/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAD/zv/2/+z/5wAA/7r/7P+6//YAAP/s/+z/9gAAAAAAAAAAAAD/9gAAAAAAAAAA//EAAP/EAAAAAAAA//H/9v/2//b/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAD/3QAAAAD/4gAA/+IAAP/i/9P/8QAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAD/zv/2/+z/4gAA/6v/5/+r//EAAP/n/+L/8QAAAAAAAAAAAAD/9gAAAAAAAAAA/+wAAP+6AAAAAAAA//H/9v/2//b/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/0wAAAAD/8QAAAAD/8QAAAAAAAP/x//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEACQBvABgAAAAsAAAAGQAAACAAIwAiADMAOwAAAAAAAAAAAAAAAAAyAAAAKgAfAB8AAAAAAAAAAAAAAAEAAgADAAQABQAGAAcAAAAAAAgACQAKAAAAAAALAAwADQAOAA8AEAARABIAEwAUABUAFgAdABsAAAAAABcAGgAeAAAAIQAkACUAKAAAAAAAKQAAACgAKAArABoAAAAwADEANAA1ADYANwA4ADkAOgAcAAAAAAAAAAAAAAAAAAAAAAAmAAAAAAAAAAAAJwAtACMAIwAuAC8AIAAuAC8AIAAAACIAJgAnAAEACQBxAA0AAAAAACEADgAAABUAGAAXACkAMgAgAAAAKwAAAAAAAAAoAAAAAAAUABQAAAAAAAAAIgAAAAEAAAACAAAAAAAAAAIAAAAAAAMAAAAAAAAAAAACAAAAAgAAAAQABQAGAAcACAAJAAoACwAAABAAEgAAAAwADwATABYAEwAZABoADwAdAB4ADwAPAB8AHwATAB8AFgAfACcAKgAsAC0ALgAvADAAMQAAAAAAEQAAAAAAAAAAAAAAAAAbACYAAAAAAAAAHAAjABgAGAAkACUAFQAkACUAFQAAABcAGwAcAAAAJgACABEACQAJAAAACwALAAEADQANAAIADwATAAMAGgAaAAgAHAAeAAkAJAAqAAwALQAvABMAMgA/ABYAQgBEACQARgBJACcATABMACsATgBRACwAUwBcADAAZQBlADoAagBzADsAdQB3AEUAAQAIAAEAAAABAAEAAwAAAAEAAAAKADAAPgACREZMVAAObGF0bgAaAAQAAAAA//8AAQAAAAQAAAAA//8AAQAAAAFzczAxAAgAAAABAAAAAgAGAA4ABgAAAAEAEAABAAAAAQAoAAEACAABAA4AAQABAHoAAQAEAAEAegABAAAAAQAAAAEAAQAG/4kAAQABAHo=); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/2C6F673F0C1CF0A97.css b/docs/static/fonts/332720/2C6F673F0C1CF0A97.css deleted file mode 100644 index 1eb5423b53..0000000000 --- a/docs/static/fonts/332720/2C6F673F0C1CF0A97.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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))); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/3919129618BB6AFD8.css b/docs/static/fonts/332720/3919129618BB6AFD8.css deleted file mode 100644 index ceb4caa3b8..0000000000 --- a/docs/static/fonts/332720/3919129618BB6AFD8.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,S0EpP18/Wj89PDM/GT8/PzA/H3p5Jz8/VD8/Wm8/Cx1kP2w/Pz8PP3cOCD9DIz8/XQJyCj9ZPwUzQz9IPz98NEtxIz8/LUQ/Pz8/TyE/Pz8zPz8yYj8/Pxo/aj9OH1g/PT8fJUscPyE/azw/Zz8hP04/LkV+Rz95T1R4EFM/M3k/YD9Waxw/P0w/P2A/ATckem0/P0NNCz8/Ex5LOj8PA1JiPzl1Dj8ZPT8/Pz4/Zj8VPz8MPzA/GiE/Pz8/Ez8BFj8/NGohPz8UFz0/Kz9APz9BP30/Pw0/Pz8lPxM/Pz8EAz8/OB0/P0UqG1o9Iz8/GHw/dXZbSxk/PwZLWgFQGmg/KTRkFHk/Pz86Pz9gEz9tTg8/Lj9ZPz8Cfj8lAD8/aC1OPxI/Pz9zVT9wFUA/Lj8jPxE/cz9PPw8rU2I/DhM/VT0/TD8/acg/NT48aD9GP0c/Pz91Py0/SXU/aT9gP1RVP0EfQT9fGHQ5XAM/Pz9UP0Q/Kj9CMDkkaD8/Py4/bD8/Pz8/Jj9FPz8/P2ceYj8/Pz9sPxY/P1BJUWw/Rj8/aT8/PykIMT9FPz8/LxVzbT9VPzI/Pz8BGmQ/RVk/XnR7A3VvLz8/fT8/P2o/SRc/P20JA2kNPz8/cT8hWlg/HWsVHA4QP0A/ZD0/AE0JPxMwMD47FT8/EDA/cj9VPz94AF5oP38APz9zPz8/P3M5MD9MZwk/Pz8/JCJHImg/P0Q/eT9IXDs/Dj8/Pz85P2s/P2M/Pz8aPwg/ei0lIT8/PyU/Pz9QP25UPz1MRT8/FklMLT9sez8/BT8/PwETPz8/Pz8/P3k/Xj8/PzI/e3QVPz9hVz8zGj8/Pyo1FgRvQHICOD97Pz8/Pxg6Pz9yQh0/Pz8HP3c/cz8/KSI/Pw8/P38/KQYmXj8/Pz8rP00/NRULP2QuP1E/Pz8QP2QXP1E/Pz8/BEc/Pxg/FD9HcD8iP1U/Wyc/CRVKPz8/OD8/DyU/BVQ/bls/Tj8tRSBqPz8/QD9ZJRIZPz8rPz8/KT8dMRtlRhU/SD8/Pz8BPz86Pz9yPzs/OXc/Pz8/FT9RTRA/PxYQPz81NDVDRD9jREg/Qz9ISFtRbQVIGD9eGj8/Hz8/Pz8/PD9NKjEXAh0bP0hLS257PxRRQkg/Py0/eAoAPz8BAAEAAABHDHk/ACw/Tj8DIzFAM0oFPz8qGRk/Dz8/OT8DQT9EAD8gPwc/Pz9AWD9wMhgbFxYzZkc/AD8/PzM/AWBiP2M/LEk/P2EJP3FyYGM/YDBiP2BgZGBjP3gAP0g/PxQnPz8/Pz9LfQY/Fz8/Tz8/cVcYGXQ7Pz8/P10yPwY/PzU/P3oLOmU/PzM/HFwYfUh2PyF7IxpiPwN5Pz8AO2AgPz8/PydyFwUZeD9mazdyal4/Kxo/Kz80Pyh3cT8/Nz8/Pz9LPwh6PwA/Am0TPz8/fj8+P2E/Pz9oEz8/GBoJPwIyAg8/Pw0CP3U1P3s/Pz8+Pz8/Sz8/RVBxPz8/Zx0/Eng/Q3o/DT8/UiMfPyc/AkI/Qjo+Pz8/QDp8Pz9wP000Pz8/dz9HPz96ST8/P3RGMT9xB2g/P2QdFD8/T3s/F2knPz8/Pz9YP38/Zz8hPztpBm8/bT8ZDCQ/Pz8/ej9cPz8PaGc/cT8EPydLP0RFP0I/Qh08JUV9P1E/Pz9PJwc/LT8/P0tiPz88Pz8jPz8sahssP08PFGM/OyE/P0I2P10/P3I/Pzs/Pz8/LHJiJj86PydWPz8/Pz8bKD8/eTs/Pz97Pz8eRQtpPz8/C2Y/dxk7Pz8oP2E/P1RaD1U/LT8/VR0/Pz91Pz8kfBRrST95Mz8/2no/P10/Sj8vej8/Pz8mZT8/Uj8/ETY/M1M/VTg/PzFRVT8/PzM/P2xEPz8/Pz8nPw9RP0k/PyNuPz8sPz8/P11cbj8sP2o/Ww0/BD9Ubj9/Pz8/Cj8/UT8/RT9ydmE/VT8bOT9cPyYjMBE/Znw/SD9FGz8/Pz8/XT8/Ez9ePz8/Pz9iaD8rPzY/FncjEU4/Pz9+Pz8WOD8/PzU/RmRfeWdyUj8/ej9RP1E+Pz85Pyo/SyI8PyJhP0U/Ln4/Zj8ZPz8/Pz8/Phk/DD8/ZXNdK30/Ty1qPz9WPz8lPz98UWpZDlA/P3JbTT9xP10/PzUTPz8RP1g/ND90Hj8cPz9GEz8/LT8/KT8FPzQyYT83MRc5RwU/Pz89D1A/S15cZz8/DD9aPD8iFT9WIT9HP1M/P3FhPz9xfT9OfT8aPxk6Pz9URD8RH2tTP2JxPz5ZN2U/RENfPz9kTT8RP1w/Lz9GP0U/dUQ/PzcUP10/Pz9Waj82Pz8vPz9dEFs/P3A/Pz80CT8/MjU/OWtYPz98Pwo/Pz8/P1M/ZD9kZjw/TjJqRj9dUDU/Pz8/Pz9aPzE/Q3cTCT8lP0EvKAo/PzVRPzU/P1c+SxNfOxg/Jj8/AT8/P0xhGT8/bz8/YiQ/WD8/P1g/Pz8/awY/P10/f0lrPzY/DUA9Pz9CMz9eAEc/PlR+Rz8/PypkP1Q/Pz8/P0Z4Wk17Pz8/Pz8RPyM/PxU/P1kDP2I/ajY/Pz8ZXj8/Rzs/Pz8NP2dXPx0/P0ZVbD8/Pz8/bwY/P3gaP18/Oz8/JWs/BVs/dz8/eUU/P1JcYj9ZcT86Pz8/C2w/flpfekI/X0o/P2TWP1lTZT8/b3Y/Pz9TClYUPzEnP2NtI2w/Gjc/PxY/Pz8/RB8/PyM/Px1yWE0/NEt8PxY/Xz88P0c/NwxrVFM1Pz8FP14/Pz8/Ez93ET8/Cj8/P0xqVj9nP2l/Vj8vPz9vP1hOfT9pOxcIPz8/Wz8/Pz8/Pxk/C2knPz8QXD8/QXE/C1w/JD98Pmk/PxY/Pz8aPxluPz8nYT8/blxOfj9kbj8/Zj8UPxk/P0JyGhNoFhJ7Pz9DRT8uPz9jej8/az8/P1k/Pz8WNH4/Wz8/PyM/Mk0JP1wJP2E/DUQ/Qj8/GXFWPz8/JD8/cD8XPz8/bQNwUV54KiE/Pz8meg8/P0E/GD8/Pz8/TVQ/RT8zPw8/P3Q/G0NvQzpFPz8/aT9GOmVAOlAuP00SPz8JP1YCdj9yPyA/Pzc/amU/GwAPPzE2Pz8/P2RQdj8/GD8DQko/PEc/UkE/FT8yPz8lPz8/ED8/PwA/Tgo/FT8Pcz9dABZXciE/XT8/Pz8FPxJKST9kP155Pz8/ZT8MPz8/AD8gP0YsPz9UPXgBaD88PwMLKz8Efj97ByE/Pz8rFl0/P0o/Iz8/Pz8/bR5jMD8/LD8/PwU/P2Q/Pz88F0wHPz91ODYaPz8/B1E/Px1OCT8/Pz8/P0xzPH14PyY/cD8eICYgDhk/P2Q/Pz9NKgc/Pz9LPz8LCSo/Hlk/P1k/P31oP04/C0Q/ZT8LPz9TPz8/AmhfPy0/Qz87RD8aDRUaJT9GP2lWLD8/PD9wPz9hPz8/DwkrP3U/Rz8rPz8/Px8/Pj9/Pz8/P2o/az9oP2s/az9qP2o/Pz8/Nj8/fT8/Rj8TPz8/P0g/Vjo/PT8xbz9JPz8/fz8/Olg/NGM/ez8QPzRrPz8/Pz9xP14/ej8/Pz9CTgI/ND8/Nz8/ND8/P0k3Pz8CPyNJZz9VV1dXVD8/UT8/WT8/P115PxY/Rlw/ET8jLmU/DmU/RVhzFz8PZT8fISJePz8RPws/Pz9CRSFiP0QkCFM/IC8/UUY4P3xFBD9RQggccD8hJj8/BD8TP2s/PydZPz8ZPxBFHGxLWT94AAAAPwByCQAYPwFmIAo/BGBiYBAGCWIDP2BgZGBjP3gAPz8QPwc/ulgPPz8GDT82HCBAPz91LxAaN20/Pz8QP0hzaD8/egA/JXRbPz8uPx0RMT8/Pwg/PyIQPyJbP2A/FD9ySxU/Pz9xXj9UehQ/UiAqCD9BPz8/Pz8/Pz8/UlY/Pz9rez8/djksVCE/dDU/Pz8VFT8/P0VhTVI/Yz9fPz8hSWltPz8/Fj8SSnFhPxcZPz8RFShqXRc/P0k/EXkuPz8/VT8/PwgYOGJJPz8/P2JCPz8/Kz8/JVU/VT8/Iz8/VT8jKz8/Pz98PwI/Pz8/P1JrPyw/Pz8/PzdHPz8kLz83Pz0/P2k/Hj8/eT9uPz9eP1Q/Dj9KTEs/WD8/NT8/Nk4/E2Q/dyg/Nj9iPz9bPxQ/d2FYP3l0ND8/Rj8xPzc/Pz9fKD9zP3w/P2g/P1ZmYDx8Pz8HYz8/Pz9QPzMcSFN/PR8/Pz8nZz88Pz8/P0ITPz8/Hz8/FHFsP0U/KwsxPz8/aFg/BXM/MD8/P0c/TT8/Pz8SED8/P1YrPyU1P00/az8/NT95RWY/cT1pb1E/Pz9OP1k/V30/dj9yPz8SPz8/Sz8/Pz8/eVU/VT9UP28/VD9UPz9RP08/P2toSxs/SHY/Pxw/P08jRT9/Py8/PyovPz9iP349Pz8iPz8/WWc/Py5aPz4/PS4/Pz8/cT9TZj8/P3Y/eD9xcD8/RwcYTT8/OS4/Pz8/ED8/Pxk/Pyk8DRI/dD9lP0A/Sj8/P3xbPz8kPwdOHVg/ND95cj8/Pz8/dj8uP1M/Pz9+BzonLj8UP0tLPz9WP3w/Pwc/dzY/P3E/GD8nPz8NP04/P0M/AUU/P2s/P0s/Dz82SHJdP04/UUppKj8/BmMrP0g/dj9IPz80az8/F2hQPw5IPy0/Pwo/fD8/FRo/PyI/ZW1iPz9eGV05dGU/DStMPz8/J1w/Pz8/GT8/Pz8/fD9pP0M/NDk/JnRFPz9OQXo/WDg/BDM/P0R7eC52QT8/b1I/Pz9zP1JRXSluP3o/Wj9vPz8/Pz8/Pz98Pz9IGkM/PxtbPz9HEj8cNj9xc2IBXD9UPxc/PxY1P0VRP2kSUm8/dT9ZBD8/RlU/Pz8zPz8od2E/USc/VEQ/Pz82Pz8/Uz8/KVgUPz8/Px0/TnE/VT8/J20/P1BRMD9yP3g/fD9Uaj8APyI/EmU/Pj8HPz8/Pz8rFQ0/Ij8/Pz9oQX1kPz80P38EPxRcPj8/FD8/P0o4Pz8/Fz95P2U/eipSVj8/RWw/ID8/EAU/Pz82P1c/Pzg5PyY/WnA/Sg4/WwgcKWElHw4/Pzk/Kl4/Pz99P0I/IWE/P1E/TT8OPD9GPz8/IzIpPz8/Uj8/Rj8/bmo/LT9RUj8/WzVHAz97Mj9ycm1Uej8/cTY/Pz96Pz4/XTo/BT82XHg/Pz8/Pz91Pz8/VwobPykpFj8/dnI/bDo/EDJdP1M/P2g/UVc/PwBRE2w/Pz8TPz8PPwo/Pw82P1B/P1Q/P0sceQQ/fC1PPz9mPyA/Iy4/Pz8/YT8/JRtSPypdUXo/EiZaWlA/Pz9TPj8/P1s/PxNdP2xeOkVCXD8fayElPxVvP2w/NXE/Ok0UST8/LT8/MD8kPz8SP1Y/VT8/PxxlGj8/dj8yP0c8Hj8/P0c/ej92PVknHD89P2FIPxAxfk0/KxZhP3QEPz8/Fj8/P1k/FgIHPyY/P1FoPz9vHT9TQi9oPz8JCW4/Pz93PR4/CBU/dD87ej8/P3khVwo/RXQ/Py0oKD9adT8/Xj8rWD8/KT8uP09WPT8wPz8hPz9eP2Q8C28/PyE/P2R6ez8/Pz8/ID8/P206Pz8/fj9aP10tdD8/P2o/PwE/PwQmPy0/PT8/P2E/Pz9rEnY+C0A/P3dNUT8/Ez9xXj4/PxM/c1ZrLT85Pxg/Pz8/P3M/Pz86PxQ7Gj8OZB9RPyhzP3c/Pz8MBj9zVD8Xcj8/Pz8/Kjo/GWY9PxZ6PD8/Pz8/Pz8/Yz9FPz8/P0wfP2o/VT8qdhY/cT9WPz9WP3U/P1c/P1s/Pz8/P2M/P2g2Pzg/FhpXPAg/I0o/Cyg/EAc/P2xKPz9JKT8/MT82PxQ/PxZyPz8/Pz8/KU8GP15aTT8/P0YYdD8/cz8/Pw1LWioWP1c/Fz8/Qz8/P2JOQ2J8fD8DFz8/EDY/Cz8oYGc/DX8/Bj8LPzVzPz8gP00lSUFkPzoNPzBvHnkBP2glPz9mLz8eTz8nPz9ieD8hPz9PZz88PAk/agZ1HUA/Pyw/PyN8Zh9pMwcqPyM/Pz86P18vPyk/Pz80HD8uPx0/Pwo/P0k/Q2A/Jj8TPz8/PzYePzg/Zz8/Fl4/F2k/Pz9DQT9vP3QcP0Y/X3M/PxdyBQ0/Pz9LP0orZT8VDT8DPz8/LVo/bVMhPD94PxN0NT8/DT9dPzsOPz80PT94PwocP2Q/WUM/Oz8/P14kTAA/eG8/Pz8/PzM/Pz8/Pz9fP2drxl4/YT98TWFXP346aj8oPz92Pz8/Pz9XWT8/P1s/RA5gUz8/e1k/NjI/Pj8oP1ATMz8/P14/Vj8/csY9P1w/XQhjFwV0PzQQYE1LP3ZKcAs/Uz9KPz8/Pz85Pz8/NGc/cj9ZSEA/Qj9OVnU/P2g/P00zPz99Pz8uPyM/fT8KFj9YLj8/Pz8nPz9jPzhZP2Q/P197Pz9nQTo/P0clM2BTYG1gMj8/P3JxTT9ESj8sSz8/OCV7PxdXCj9NOz9AUH8BPwQ/Pz9kLT8/Yz9ePz8/Lz89Pz9pPxQ/Tz9RZT9zPz8/Pz8iPyA/ShxHET8/FT97Cy9nPz8caz9xGz8/aT8o+T82eScoDmQpPz8/bXY/XT8fPz8HPz86Pz8/PzI/azJDZDRgHQVoTD9KPwdoZD9lPzk/P2E/Pz8/Pyg/Fz8/Pz88Pz8/zT8/Dj92Yj8/LiFYOT8/PywzVD8uP0NoP0o/c19OURo/WD85P5ojRgw/Ij9tP1gIOSx4dj9gaVg/PxM/Pz9nYD8/PxY/YT9hPz8DSxtwbBQ/P0U/Pw8XenI/P24/PzkKPz8/DD8/Pz8wPxAHST8/Py8/P346SD8/PT8/P2Q8Pz9YKFgiP0I/Kmd/Pz9MPyA/Pz9vPyM/Pz8SFT8DPz8/CH0/CT9gP3IZeQQ/SFg/Pz83aD8/FT8bbT8/FT8APzEfPz9jP0c/Pz8/PyEwPz8xaH4/P3JnZz8kQ2o/c05EP2xzfj8/WXADPwoGTVsePz8/eD8zPz8/Kj8XBmVLPxI/OD8fTz8/Pz8faj8fMhA/P34/Pz8RP0U/flQ/V0ECPT8rPwwvbzo/Pz8/Ej8/Pz8/GzscIW8kPzl0UUItFEU/Pj8/Pz9JP2coPz8/aT9neho/Py8/P3U/Pz8hQz8/Dz8/ZT93Pz8/O2kFP2tBDGg/VWk/P2UsPz8/P10/ZitLP2w/P3Y/P2Q/P1Y/UhM/Vj9bP2w/P3lTVT8/RTZFakUaPz8/PxQ5FT8/P3gbP30fNj8/bT9oaj8TSk8/dz8tPzRiPz91Pz8/P1c/a2kzCz8/P3RrPz8/Pz9CPz9VPz8ob0U/P2tTP3t5eD8/Nz8/Pz9ZKT9vPz9xBnE/OV4/Pz8jGFMhTD9ILT83P30/Pyg3Ag5aP2g/GgxoKj8/Pz8/P1A/Pz9aPz8/XA4/Rj8mP34/az8/RHI/Sj95FShaIj9jPz9/P1s/Dj8VPz9/Pz8MPyM/Qz9WPz8JPz8/dHozP3k/Py0/Nj8/BWMNPz8APzhJPz8oVGQ/fVs/Pz8/Pzc/JFU/Vj85IQpiSho/CWw/X1UgFAZYQz8/Dnw/Qj8/fhE/Kj8gPz9YIz8/P1AIWGNBDT8/Uz9RPz8SUz90Pz9KKGc/Pz9Qbj9ASyQyEGE/alIZBRMUPxRLPyQ/Rg8qP2A/P2M4HT9SPwlHCkhhXTw/Pz8/Pwx0PyU/P3B7RD8HPxtAPz8/AT8VPxQEJwU/ET8/Pz9ecGdGZgQ/HT9jGR8/Yj8/Pz8/OUg/Iz+yJj9YdGAZPz94Rj9SP0I/JT95Pz8/Pz9HP0RDPz8/Hj8/XgN3PzgWP2w/Vj8/CT9PP20/P0k/P1o/P1U/ST8/GT8/Pwc/BT8/OD8/Yj9HPz8OPx4eP3s/VwdMP2xmP0pcP0U/WmIMY2Q/H15KCz9dP10LfmY/BF5KP0Q/LS5zPz9IPz8/NGY/Yn5IPz8/dD8/Qz8/Tz8KOgI/P352Pz8/Pzo/WSE/Pz89XD82P0o/Pz8/RTI/Pz8/Kh4/cD8/PyM/OD8/P318Dz8/Pz8/AwoPPz8/fz9kIRI/FHU/Pz89Nx12PzpiPz8qWUI/Pz9UGj8vChpZXxsoPyM/bD8SP28/Pz8zP2Y/Pz9cPz8IPz8/EjA/P3E/P0g/Pz9RFxRUP0E/CT92Pz9BPwY/Pw0/E1s8JT9PPz8HXgYePwI/Jz8rPz8/Pz9oHj9WP2I/Pyo+Px1iPwU/NhE/Yj8ZP3R1P3ILPz9dP3Q/Yz8/ZzY5fD8ePz8MTwNHP1U/Pz8/Pz8/PwY/Zig/P2BJPDE4fh8/cz8/P28/Pyg/P14/Pz97P0o/Pz8qJT9nYRs2PwU/KWI/dSgLPxgoPz9TY2MZPz8/BT8/DjxZPz8/EwxtP2A/SD8/Yz9DP0c/Vz8/PwIaP0pMJCUyPz9gP380Pz8/Gj9aP04/Pz8/Pz8ePx4/Vzg/PyUOPzoPPxNTP3VVPz8/WVo/Pz8/P09HTD8WPz8/P34/P1o/PwkEOTk/Pxc/Pz8/WD95P0A/QSQ/PyUEPz8/f34lexRoFT8/Jz8ERD8/Pz8zO25ePwJHQD8/Pws/Pj9dYzQ/PwIGQj89Pz9IPz9xPz87aA0/P1Y/R20OP18/Pw8/P29uPwk/Pz8/NiBOGz0/P38/Pz8/RD9PPz8/fz8/Dz8/BjVjPz9mPzRcXi4/P150aT8/P1Y/P3RoJT8/REcKPz8cPz8/Kn4/Pz9DP2hGP0xHfFYtP1k/Px1RPz9/Pw8/Pz83C08JaR0pFko/Pz8rQmI/PyBdNj8UOHA/Pz9KaGY/P2ltPww/CT8/KB0/FQk/dExvXj8/Pz81Pz8/ekpEbT8/Pz8HPz89QhdoJj8/ThM/Pxo/NT8lPz8nXz8/Pz8KP2hvUT8/bT8/Gz8/PzsPTzM1Pz9HPxNVPz8/Pz8sWmM/P2FAFT8RPz8/Pz8/P2l2UD80Pz8/Pxg/Dmc/XB4/P0QFPz9pPykaFT90Gj9DDhZyP1k/G1A/PwhlUz8/LkkqOR1vPz9vODQ/BD98Pz8AWD8/Ej8/PypoPwQZPz8/aQg/Nz9vVmA/bT8/P2k/Bz8/PD8/Pz8/Ig9oGj8/P0ErZms/WyQ/Pw0/Pz4SP8M/fXE/Bj8/PxZ+Px8/Yj8SVGU/PixiLwI/Ij80Cj9acj97Pz9+UD0/P2A/PxY3UwxkNj8/WzQ/Pz48UD84dCE/az8/dz8DPz9rDgEKPz8/Pw4pPz8hP3B1PRY/BmUJPz9UPz8ZMmA/P10GPz8/WD8/VxZjPz8/Pxw/P2I/P25YPx9yDj8CPzZsPz9iP2dXPz8/Xz9WOGgBP00/KxlKPzNDZl4/Pz8xTXovPz9lPz9hKT8/Uj8/Pz8iMRgNcX0/PyA/Vj8/PwE/BggQMHViPyQ/W18/Cx4/MD81Sj8sNhxZPz0/Pz9HPz8/Vio+Pz8yE0w/A0M/P15xPz8qdD8/fT8/Lj8/Xz85Pxg/ET8/NT84BV4/DWcccnw/Gj8/Lj9FWj8rCzQxfD8/PxsALj8/Pz8/PyQ/P24/Mz8/PzszASBJCQRLBHN6Pz9WP1k/OGI/Dj9fPz8/Pz8/Pwk/Pz8UPz9+Pz8/GEc/Pw59Tz9Yb1MQW14kPz8/P2k/PzA/Pz8/PyIxPz8/Pz8/d2ZePz8/P0o/Pw9nOz8/bD8/P1E/Nz8iQzA/P2Q9Pz9hPz8tPz8/LFM1KXE/Pxk/Pz9gPx8/Pz8/P0k/PxQ/NT9JPwg/BT8jUj9TPzc/Uz8KPz9XPz8SPz8/cloPPz8mF04/ZD8/GD9HP2VhPz8/bWwgPT9EZj8/WFEuGD8aPz8/Gj9KPwQ/P0g/Pz9yPz8/P0JMSAQ/ez83ID8/P2ptVA9LPyw1Jz8/Gz8/P30/Pz8PI3E/AT9qPysDP1A6Pz9MPz9IPz88GHs/Pzw/Yz8eP3gwPz9WPz9PPz8/HQslZQZ9P0x0P2e3Pz8/Pz8/Pz8/PzRTP28/Bz9JPz9WWWt7Pz8+K0c/Pwg/J3M/HEU/dz8/ez92Pz8TPz8/ACk/Pz8/Qn4BP0EDWD9hP0k/Pz80DRYHOHk/Pz8/Pww/ej8hPz99P1gfPz8/Aj8/Sz9eVCQcQhk1Lio/Pz9dDz9YPz87bD8/SD9ePz8/PyI/WSQ/P1o/P2lFKj9OPT8wPzw/DT97QVdfP1dCDT8/Pz8/Pz98Pz8/dz9IPz8/J3I/fSM/Pz9BPz8UKj8/P2c/ID8/Pz8/Pz8GPz8/TD9QPz8/Pz82bT9oGkk/fh44P1ATUVsCPz8uPz8/Pz9NA2gaPwI/Pz8/Py1nHj8/XSw/YTQ6az8/OD8/Pz8ZIE1nTA8YPz9LHQE/Pxg/P2JJPz9jSDphPzc/MT8kPyg/Py9GHDw/Pw8vP0U/Pz8/ET8MP1hgwT8/MQYvPz85Pz8LP38/Pz8fNj8/JSNeLAYnDT9GP20/SD9mP1syaSE/dj9WPz9XDT80CT8KP2I/Tz8AexNLDgQ/PxV8Pz8/Px9tdQQ/SDE/ez9vQz9AVj9wPz9OPz8/Gj8eRz8ePz8/HnE/Fj8fP3YOMD8/Pz8/PxQEPz8nNj9bPzogYF0KOFdWP1Ihbz8/PwkENj8+Mz8/DlM/P3U6f0IePz9iKj9OP20/RD8/Pz8/fj8/XT8/Yz8/cAw/P24/PzM/Wj8/Bz8/RB9gUj9CPx1qPz88Pz8/PD8/P38/Pz/rP2Q/ETs/Vj86WGc/Vz9JbD8/EjZiPyk/P14/Pz8/PRY/P0NaESA/Cj9hPzQcYj8dRXcvCz9hPVU2Yj8/az8/PyMIblNQP0g0Qj8KEjk/bz8/Pz9mPz8/aj8/MT8/VT9HeENoPz8bPxwoUxhoUmt3Oz9ybE0LQT8eP08/Pz82GD9zPzchPyA/PyUfPz8/NT8ffT8/bB8/Rj8/YT8/YD8/Pz8/GG0/P1A8ZT8/ES0/Pz8nUT8TP3EdAlhqPz8/fj8/PzdZUhU2PykmPz8/LGk/Rh0/MT0MP2c/P2E/Gj8PPz4/Pz9nP34VPww/Pz9ePwVgPxghPw4jPzE/Pz8/GD8YPz81UjM/aXoDS0YXP1oLQUNZYz8/D2J8P0BpMA4/Pz8RWBZITAc/P1A/Pz9AP2A/Pz92UT8SPwxLP1U/Pz8zPz94Py8/PxU/Dz8/Pz4PPz8/Pz8XPz8/Pz8BeD8YPz9/Pz8/Xg4/P2E/Lz9BInMUPz84LQc/P0xYPyY/Lj8/LBQ/Pzk/Pz9LPz9SPz8GPzFjAnk/PxlhXj9+TDArPwk/Pz8/RAoNPz8/AwtOPz8/Pz8/Yz8/Xz8/Bj8ePz8/Pw5dASBMaD8/CzMmPxk/Pz8YGD8/Dz8FPz9yUj95P2o/OT8/Rz9dPz8GPz8/WD8/Yz8/Pz8/Pz8YPz8/Gz8/UVQ/Pz8iB2Q/Gz9hPz89bBc/Pz8/SlkyPxsAYSsEUD8OP2s/PwZDPz8/HT8/fD8/P3Urag4/Tz8+PyQ/Pz8/bj9NPz92P1ZVP1I1Pz9TP2c/P1w/P0k/PzZqXFg/WWN+P144Pw9OPz8/Tj9DPzw/Pz8cP31SP2Jzbj95P04/Q2hKex0/Pz8ceFA/Xz8/HD9hZT9OMT8MKUF7aD8ZPz9DPzM/Pz9DQm0IaAQ/Py4iPz8uP0w/IxgPP0Y/P22ZPzk/Wmw/P2YAPz81HXo/Pz98Pz8/P08/KwJKfD8/P2gxPz8/Pz8iIz9qFj96CG0XPxFsPz8kPz8hHj8jIhA/Py4UPz8/TDk/SHszPz9TBFA/Iz8/P0kaP056Ly4/Pz8/Fj8jEQA/dT8/bRkMOT8/ZxU3P3w/PwY/dT9HFT9ePz9nP34/FCs/Pzc/P2k/JTA/Pz9Eej8/cT9oPz9KP05ePz9zP04/PwQ/CT8/NT8qPGJNP0o/Bls/P397Py8/Pz9zElhXQj95Pz8nPz8/P2ENP30/Xzc/Gj9PNz8/XD9+PxU/Aj8LPz8/Pz8/fz8/P3AOLT84X1M/Pz8raG9UP1gBSz8IP3FtPz9/Pz8/Uz86TR8/PT9zTFs/Jj8oPz9sPy0/cT8/Pyg/Pz8WPz8zPzl9OiVUenQyPywRPz9YPz97RCJQMT9JPxE/JD9VOBAKQHc/CjoYPy1tIT8/Ez9ePz8/B1B5fz8aDj8/bz9xPz8/Gj8SJQI/Onk/ZE8/Pz8/Pz88P31nPz80Pz8/P0c/MT8/QBI/PyoYPz0/Pz8OCj8/P0w/dj8WDT97MR8OPz8VNT99TD8/P18/Pz8/ET8/A3Y/Xj8/LT9BYxglP2Q/Hmw/WT8/Pws/Pxs/PzI/P2cuPxI/Pwc/Pz97AW0/KD4/P3A/WQV0Pz8oPz8/LSM/P1wFQVZAVj8rTj8wP3E/Pz8APzs/Pz8HPzU/Kz9pXT8/Hl0/dmo1P1I/Pz8/cRQ/Pz8/VD9WbRUDBSs/GVc/P3U/ZDE/Pz8JPz8fP14/Zyg8P0M/ZD8/Nj9tPyU/MD8RPzE/Pz8/Pz8ZP3QkP199P050P3E/Pz8/bwoTKD8/WHRVPz9WPzc/P1IqPxg/Pws/FD9IPw85PwxQJz8/fD8EPz8/PwFfPz8/Pz9rRD9VPxFnIVl5PyMUZz4/ED9FPz8qP2s/Pz8/OCxAPz8KPz9iOHo/Pz4ICiU/P3U/L3oLP2k/PyA/Bw5AFhQ/PxQ/PzM/XD8/Bj91fT82P0BFPz9RJC0QQ1Y/P1s/Zxp2P04/PyY/bVM/RT8/Pz8/UD9wPz8NPz9dDAdsPxFLAz9zPz8/P0dZNykCPz8/P0o/P3QsPz94B1wRDA8/Pz8/Pw42NPE/Q2E/Pj9xPz8/GFhDP0MPA30/Pz9OP21LP3M/Kz8TP0I/P0VEPz8ZPyoeTz9wJX8JP08/Xn1IMz8AQ3k/ZWIEQxY5Xj8/X0RxcX16Pz9LYz9SPj9FSD8VP0sPHWA/Pz9rfHM/P1o/aWMRPwdUP00/LAtsSj8/ajkIPz8WPzUTAz8LPwoeXlg/SXw/P3YJWnMfDz8/P1I/ED8CPz9FED8/ST9SZ3J2P1o/ZAozZj8/SD8OSj8/P3U/Pz8ZPzZqBj9oOT8/Hz9lP3Y/Oz8rUjQcPz8/Pj8/OT8PPyY/P0Q/PyM/DS9OSz8EYT8/FiYaWCBpPz9TAQ1LPz8vGEBsUD8/Gz9Fbj8/Dj9ZPyc/Fz8/MT8dDj87Bz8XKD9qRj9lPz9nNz8sKQo/Pz8/CkE/bz9BP3I/Pzw/P15GPz8PTj1KPz8/Clg/Pz9oP0sqalpYSlk/P1E/I34sPz8/eSQ/Fz8/Pxo/Fz88CT9+HWJRXj8/Pz8/Pz9MPz8/Pz85Pz9oP2k/Pz9cBT9mBD8/QX8/PzQ/XD9DDj8TRz9IXT8mE2E/ZQg/cHU/Pw8/Uz9xP1ZnET89P24/UQtrPz5xUy4/Sz8/aXonPyNAPzc/P1M/Pz8MZmc/Py94P28/Pz8/OT84GUl1Pz8/P1xOPzg/P3c/c2QSPxM/Pz8/Tk0VCWk/P15lSXI/Pz9ueD8/CT8/aD9VChFfMwNVVT9HP18/Pz8lWz9OVTRmPz8/Rj8/Sz9zP3otEkQ/P2oWP2ApPz8SZUtzP1RcP1c/Pyw5Pz9gPycnPz8/OT8/OT97Pz9hPwg/bic/Pz9+Gj8/P0k/Fj8DRT8kP24/Dz9PPj8vMAlSKz8YP00dPz8/DT8/Gz8/P0EvCHA/Pz8/T1Z8c0M/Pz9dPyNuOj88P39JPz8/LGgalz8/IxkPP1c/RT8/Pz9sPz9WSzF4DBs/P1Y/Oj9jPz80Pz8/P2hYPz9tDT9+P0daYT8/Pz9cOEo/cTQ/P2ZXP3Y+Pz8+P0M/WT8/Dj8/Qz8/aD8/P04/Pz82L1g/T1M/Jj8/Sj9iP1w/dBN0Pz8/PzAePz8/Xj8iRQoSLlAbP38/Px5pPwY/LT8waEY/P1c/Pz8bP0I/aD8QP2U/CUk/Zz9ZP0w/Pz5zP1g/P3UGCD8Mblc5eUo/Pz8/fFs/GH1BVRtEPy05RT8/DxRvLkNyAT8gfTw/KwchP0BhEj88GT9TYz99GhsoPz8/Pz4/cVc/P3g/Riw/Pz8JPz8/PzVoDVs/Vj9VP1VrPyc/Pz8/ST8/Tz8/TD8/PyZWPwNJez8/P28/Sz9QPz98PzM9PxY/az9aP1s/P3k/fT4XP3Q/fH8/Pz9/P38/Pi9TPz9/LD9PKdM/bx0/Pz8/Pz8afD9PPCc/Pz01bz8/Pz9tPz9YP2g/exs/Pz88Lz8/Pz8bY0Y/Pz8/X2hPPz9jPz82PT8/DSU/Pzo4Pz8lPyU/Bj8/P2o0Gj8/dkA/Ckg/NXJrPz8/P1s/DT8XN34yPx8/Fx8/Pz9bPz8/XX0/Uj8LP7g/P+4/Uz8/Pz8OcVU/P1dnFxhaP1A/HCpUP1Q/Pz9XP1I/VUo/P1dKP1M/KnlUPxVSP1o/SSpVS1Q/P1RtUj9aP1RUPz8/UT9TP2Y/WwNUPwY/eg1UP1Y/FUE/QRMSP2c/Pz8lPz9vNz9cLz93Pz8/P34/Pz9zLT8/P20uPz8/byMyPz4/UT8/dD9dPz9QdTI/Pz8/PwpLeUE/P1Ftez8/Pz8/Cz9ZSz8/fHg/PwJoPz9RPz8bUg4+P3NrP00/fz8bEz9mPz8LJz9ZOD8/Kj8/Py8/P3khPz8/Pz9TP1U7Pz8sP3VdVT8zPz83fT8/Pz8/SBJ6fz94ax05ARUFPxEEURRBQFwqLD9lBD8WQEU/Pz4/TD8/azJIQCYgP2EgPz8/EgRAPwEAP1NkVT8IEh4/Xj8/Pz9FMz8EPz8UeAl6P3gAPwE/LAAAPxg/GVs/PwBmYGM/eAA1PytvP10dP3U/Gz85Z2Y/Pz8/Hg4/Rz91MThdQT8BPz8/fz8/Hig/HT8/Az94Cz8bVgoZPz8dZj8/Pz8/MDowPz8/Pz96Pz8mP04cP2o/AT8/dns/dXZ1Pz9rbWw/Pz8/Pz8/Pz8/Pz8/P2w/Vj9vNj9cPyorPystLGw/cD8/Ki8/PygvP08tP2o5Ez8/Xj8/Pz9jXj9XPz9TKxU/P1l0P15OLRY/EhM/P1kVFxc/Ej9nMT9nNj80TD8/YD8/Mz8/Pyp8Pz8EdHI/e0MoRT9SP0c/OD89Pz8vNGI/Pw8/Pz8aIUIhPxQ/QBdQP2E/Pz9sPz8/Nz8/dj9NP11EPz8/IT8YPwM/Hj8LQT8xP3E/PzQjRD1uPj8vdyshSkc/Pz8LcBcOcWcaYUwJPzFaPVAtKT9YPzo/Zj8/MT8/Rh0ZPz8/KT8NeQ0/Pz9PeRk/Hyc5DS18P3A/PxVhND8+Vj8/Pz9BNANHP1o/P3ZGPz9JBj9PP3gYCz88Yz88fT9QPz9zPzA/cEE/JSo/Pzk/P3A/FUIoUyI/EXw/OUMlPz9KND9GPz8/P0o/KXI/KD9fAT9vEj8/BD8/BmI/Jj8/Cj8uIj9OID8/PwJBPyw/eD8/Rnw/PxY/Bj8EOD8LP34/VUl6P3s/PxdnP0Y/Yms/Hj8/MTE/P08TES4mNT8PGj8/P3g/ej8KCjsgPzI/Pwg/Ags/A0A/OCMDQzRbYj8/Cj8/bD8/PxhBFExJPz94ACZqPz9vPz8/Pz9vHz8PPz9EPz8/Pz93Pz99DQk/Pz8/Pz0/Pz8/Pz97P0k/XD8/P2l1VDw/Pz9jPz9LPz8/Pz0/Pz8/P25Of3ljXT8/exA/Pz8/cz8ZPz9+Pz8/TyUGPz8/P3FAPzs/Pzc/Pz8/TxUubnk/HCsUCnkuRyU/bj9TSj9yPz8/EiM/Tj94Pz8/Ej8/Wz8/Pz8NP1c/Pz8oP1o/P24/O1VVcFo/ITtTVns/E1U/Pz8/Mj95KD8/PBNXPw8/Sj8/Ow8/Pz8/PyhqPww/P3k/PxA/Pz95Hj8jP2Y/aEk/TT9SdxlXKz8/Pz8/P2I/PyM/P3M/Pz8/NQtWP1BzPzE/Pz8BUT8/Tz8/P0M/P18/YjkMPz8/cj8/Pzo/CmRDPzM/dgYuP04/KT8/Rz9bPxpiBT9ZTxdaPz9zPxU/Jz8iPxFGewY/AD8EP0I/P3pYP2M/Pz8BPww/P0BWPys/Pz1ABR4GRzE/P10/BFw/AGhxPx0OPwE/PzM/DT8/aEo/Qj8/ZT8WPxc/P3BPP0s/Pz8/Zj85P38GPz8/ZEU/Pz8/GT84Pz8/F0p3Xxd9Pz8/PyNFCj90AHw7Pz8/P30/Iz8/egksPz80JQw/PyM/Pz8/Pz8/Az8/NRc/EiIhPz9nSD8jPz9vbj9HPz9SZT9EP08/bWNlL2E/P0gRPys/F1w/XkM/QwRoPz89P0s/ZVU/Vz8/Jxg/P18/ez9mUGA/TD9UPz9APyBvUD8sRkMqP0o2OQlQPy5lSz8/Fj8pPz8/XD8/FAw/Py1CPy1bPz8jfmdpPz9EPz8/GR0/Py4/CT9SP2lZPzZlPxw/KxIiZD9hWSVvARo/GWg/ND8/Pz9tVT8/ST8CNT9kPz9FPyY/RW0yP14mPz86UT8/Pz8/HD9KP1BBPz8/XT9RBT8lEUk0Pz8/WD8/TD8/P1E/P2JnKkU/JD9MW2NRaD8hc0o/IyNYUhA/PxUiPz8/FTI/Pz8/P2M/Pz8/PxIpPz8/PzBPPz8/cT9+Pz8/ez8/MHBwPz9BPz8EHBNIPz9OUxYreD8/dk8/F04/Px5kbHo/Pz8/TT8/Pz8/HFdiMj8/Vj8Pfj8/b14/Ej0eHitjPz8zP0g/cT8aPz8/P20/Lj8tVj8/Pz8nP2A/Pz8/P3w/PzUbPz8/Pz91Pz8/Pxo/Pz9vWi0/P1Y/Pz95X1pvP3o/W3dCP3p/Pz8/cT9+bz8GPz9J+D81Pw01ez8/Zj8/dzlqPz8/fHg/P3Y/fHpsbj9cPxo/Pz8/Pz8/NT8/P1s/Pz8tP1k/VT8/OjM/Nx4/Gj8/Cj8/fQY/Wz9fPj8NTj9oPREQOzc/P2dnH2kIPwI/P0xVPz8pPz8PP3onPx4/Pz8ePz8IPy5YPyI/RD9FcT8/Yz9zPwNRUz8/KD8/Sj9GBj9gUUx9Pzg/P3JZHRBGP29NVD94ACAQXz8ACT8/FBh7TH8/OSA/PwA+GAc/Ez8Lfz8/ED9KQD9qHj8/eDAwBz8wMBYEPz9iMGU/M0IHPz8/Pz8/tD8/Pz8/YmBjP3gAAHkAAFAAAD8GPz8AEj8oIj8ZP1gvPz8/Pz8/Xz8+YGBkYGM/eFoKPzMACiQJPz8/ICVmYRYLfz8/Pxg5Jh0FPwg/Cz83Ays/Pz8hPBlpPHBkYGBgZGBjP3gyAD8/IAAAABMAAAA/CAAAdHNvcAQzNSg/CwAAPwQAAD8BAABlbWFuAFB5AAYAAAAGAAAAPwEAAHB4YW0bHz8JPwEAAHMBAABAMwAAeHRtaD8DPwckAAAAIAAAAGQBAABhZWhoP0dyAzYAAAA0AAAAMAEAAGRhZWgLAAAACAAAAAgAAAA4MwAAcHNhZ05aP2g/AwAAVwIAAGQGAABwYW1jPyQ/VWAAAABPAAAAPwEAADIvU09eLT8/PwAAAFoAAAA/MgAAQlVTRz8/aD9aHQAAPwcAACwrAABTT1BHBAA/ACAAAAAdAAAADCsAAEZFREdxUj8sAAA7IgAAPwgAACBGRkMAAAAAAAAAAD8GAAAmAgAAPzQAAAAAAQA8XgAAAAANAD82AABPVFRPRkZPdw==)); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/47EF802870551C878.css b/docs/static/fonts/332720/47EF802870551C878.css deleted file mode 100644 index e012278e87..0000000000 --- a/docs/static/fonts/332720/47EF802870551C878.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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)); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/52BE923A462D3F7AA.css b/docs/static/fonts/332720/52BE923A462D3F7AA.css deleted file mode 100644 index 93e7cb801c..0000000000 --- a/docs/static/fonts/332720/52BE923A462D3F7AA.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,MgA/Al0APwA9ACoCOgBdA1MAZQIzAD8BXQA/AToAPwI8AD8CSQA/AmgAFgNvABIBaAA/AmgAPwI1AD8DQgA/AjcAdgJAAD8CPABdAjcAYgIsAE4CHgBPAUEAPwI9AHgCXQA/AAAALAEAAD8BCgA/PwEAAQAAAAIAAAAEAAEAGgABAAEAAgAAAAAAGAAAAA4AAAABAAALHz8/P35/Pz9/fz8/Pz8/Pz8LHz8/P38/Pz8/Pz8/Pz8/Pz8LHj8/Pz8GfR8/Pz8/Cx8/Pz8/CD8/Pz8/PwY/CD8/Pz8/Px8/Pz9/fz8/Pwg/fT8/Pz9YRjQnAQEEABM/FT8/FBY/Dh8/Pz8/Pz8/Pz8/Pz8/Pz8/FT9YPwc/Yj8/bj8/P3V7Pz8Gbj8/Pz8/Pz8/eT8/Pz8/FWhzPwohFT8/CiAVPz8/CH54P30/Pz90Pz8/P3w/fD97PxU/PwU/CD8/Pz8/Pz8/Pz8/Px4/Pz8/Pz8/PxU/Fz8HfT8fPz8/Pz8/Pz8ePz8/Pz8/Pz8VPxs/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/Px8/Pz8/FXBoBj8/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwU/Pwg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8ePz8/Pz8/Pz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Bz8/FVt3Pwc/cj8/ej8IPz8/Pz8/Hj8/Pz8HPz8/Pz8/eR4/Pz8/Pz8/PwY/Pz8/FXw/ZT8IPz8/Pz8/P3I/ej93P3Z/f3o/BT8/CD8/Pz8/Pz8/Pz9pPz8/Pz8/Pz9jP1Y/YT9sbnlWdT95P24/HmBhYUhNP2o/CD8/Pz8/Pz9wP3c/P3N7fXg/ch9vP3U/Pz8/Pwg/Pz8/fD8VSj8iPwc/fj8/Px8/Pz8/CD8/Pz8/PwU/Pwg/Pz8/Pz8ePz8/Pwd3Pz8/PxUqPwg/P3Q/bD98P30/Pz8/eT9vP28/Pz8/Pz8VFz9iBj8IPz8/Pz8/Pz8/Pz8/Pz8/P3s/Pz8/Pz8/Pz8/Pz8/BT8/Bj8/Pwg/Pz8/Pz8/Pz8/Pz8/Pz9zPz8/Pz8/Pz8/Pz8/Pz8FPz8/PxU/Px56fz97ej9/Pwg/Pz8/Pz91P30/dD8VPz8tPwg/Pz8/Pz8/Pz8/Pz8/P3Q/Pz8FPz8/Pz9yPz8/Pz8/dz8/Pz8/P3o/Pz8/Pz8IPz8/Pz8/Hz8/Pz8/Pz8/FVk/Bz8/eT8IPz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwU/Pz8/FT97Bz9yPz95Pwg/Pz8/Pz8ePz8/Pz8/Pz8/Pz8/Bz8IPz8/Pz8/Bj8/Pz8VPwc/cj8/Pz8ffj8/Pwg/Pz8/Pz8FPz8GPz8/Pz8/cj8/Pz8/FTsrHz8/Pz8/Pz8/Pz8/Pz8/Pz8VPxI/Hz8/P3p5f359CD8/Pz8/PwU/PwY/Pz8Ifz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwY/CD8/Pz8/PxVRPyY/Bj8/Pz8VQT9VPwojFT8GP2I/P1g/Pwg/Pz8/Pz8GPz8/CD8/Pz8/PwY/Pz8IPz8/Pz8/Bj8/Pz8/FT85PwojBD8KIhU/PwojBD8KIhVBPwoiFT9QCiEVPz8KIBU/Pw4ePz8/Pz99P3gHcB54fX14eD99Pwc/FQI/Px8/Pz8/Bj8ePz8/fQV3P3sePz8/Pz8/Pz8VPz8hPz8OHj8/Pz8HPwg/Pz8/Pz8FPD8/Pz8fPz8/f38/P38GEz8efz8/Pwc/CD8/Pz8/PwU8Pz8/H38/Pz8/Pz8/BiE/Fj9aDgg/Pz8/fT8FXz87Pwg/Pz8/Pz9+Pz9/P30/fT8/Pz8FQz8oP0U/KD8IPz8/Pz9+Bj8IP30/Pz8/BUU/KD9FPyk/CD8/Pz8/fT99Pz8/Pz8/Pz8/PwVfPzs/CD8/Pz8/PwY/CD8/Pz98PwU1PyU/NT8mPwg/Pz8/Pz8GPxU/Pz8/Pw4ePz8/Pz8/P3wHQQg/Pz8/HhU/Mz8OPwc/Px58Pz99fT8/Pwc/Px4/P1AkJz8+IQc/Px58Pz99fT8/PxV9Pz8/Pw4IP3A/ZD8/Pz8/Pz9+Pz8/P34/Pz8/Pz8/Vj9TP04eRmVVUAc/CE8/dT93P3M/cj8wPwc/HzlQRigIP1Q/Tj9aPz8/Pz8/Pz8/Pz8/Pz8/Pz8/cT97Pz8/Hj8/Pz8HPwg/Pz9GP0I/OT81Pz8HPx8/Pz8/FT8/PyEOHn0/P319Pz8/BxA/CChfVTI/Qz98Pz8/Pz8/Pz8/Pz8APz84Pz8HUD8ePz8/Pz8/P3wVP18/Dh4NPyg0DD8HPx4PPyk/Cj8NPz8MPwc/Hw8/Lwo/FT8/His/Dj8CPyM/Bz8eIz8QPwM/LD8rPw4/Aj8jPwc/HyM/ED8DPyw/FX8/Pz8OHgM/Px0/Bz8eGj8uICEyJRY/Bz8fFz8zPz8VWj8/Px4/Pz8/Pz8/fAcuCD8/Pz8eDz8oET86Pwc/Hzo/JhE/Dz8IPyU/ST9hBz8/Hnw/P319Pz8/FVk/Pw4IPz8/Pz8/BT8/Pz8/Pz8IPz8/Pz8/fz9/fz9+Pz8/Pz8/BT8/fD8/P3k/CD8/Pz8/Pz9+Pz8/Pz8/Pz8/PwU/Pz8/Pz8/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwU/Pz8/Pz8/CD8/Pz8/Px4/Pz9+FT8LPw4ffX9/fQY/CD8/Pz8/PwU/P2w/Pz8efT8/fX0/Pz8HKD8fPz8/PwY/CD8/Pz8/PwU/P3U/Pz8ePz8/Pz8/P30VP08/Dh59f399fT9/PwckPx4/Pz8/P38/fRU/Az8/Dh59f399fT9/Pwc/P1Q/Px59f399fT9/PwckPx4/Pz8/P38/fQc/P1Q/Px4/Pz8/P38/fRU/MT8OHj9/P30HHD8ffX9/fQZYPx9+Pz8/Pz8/PwY+Pz8/ET8ffj8/Pz8/Pz8GET8/P0M/H34/Pz8/Pz8/Bl0/FhY/Dh8tLDUpPE8/Pz8/PwQ/P1Q9FT8/Vh8/P1k/Uj8/Pz8/Wz9VPz8/Pz9NP1M/Zz8/Pz8/CD9nP1I/Pz8/Pz8fP0M/ISM/IQ0/BD8IPzo/Xj90BVA/CHw/Pz8/fj97Pz8/PwVWPz8IPz8/Pz8/Hz8/alJFTUElP0s/ST9AP3o/ez9LP0E/cz90P0g/Pz8/Pwg/KXVEYUE/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8VNj8/Pw0/Dh4LPzE/Mwc/Hig8Pwg/Bz8/Pwc/Hz8/PAM/FT8/Pwg/aT9gPwg/Pz8/Pz99P38/P30/Pz8/Pz8/VT9WP08/IT8rPyhmPz8/Pz8CPx4hPy0/DD8HPx8VPyEnJj8IP0A/Tj9hP1U/aSA/Pwc/H3A/Mj8OPzc/FX8/Pw4eFT9GPjwHPx40TD8GPwY/Pz8HPx8/Pz4VPwQ/Px4oUTg1Bz8ePFI/Pz8/Pz8HPx8/PzgoBBs/Hic/OgU/CD8HPwg5P01IbjNvP1c/OD8HPx4BP0EHPw0/DT8HPwE/Bz8IPz8/Pz8zP0g/Pwc/Hwg/BT8nPxU/Pz8OHgU/OUEoBz8eK0M/Az8HPz8/Bz8fPz82BT8VPz8IP28/YT9RP0U/JT8/Bz8fZz88PwM/Qj8IP0E/Uj9TCD8/Pz8/Pz8/Pz8/Pz8/Pz8/P2I/dT8/PyI/KT9qPz9HY01KPwY/HhM/Bj8RPwc/Hxg/Px4/FX8/Pw4IP14/VD8/Pz8/Pz9/P38/P30/Pz8/P8ZQP0c/RR4DP0A+Jgc/HyhIPwU/CD8/Pz8/Pz8/Pz8/Pz9+P3w/BT8/egh4Pz9/P30GPz8ffT8/Pz8/Pz8FPz8/Pz8IdV57Xj9KHhs/IhE/Bz8fFT8/IT8Vfz8/Pw4IPwE/Wz9HPz8/Pz8/P30/f38/fT8/Pz8/P1Q/SD8zHi1MPC8HPx8pVT8SPwY/Hj8/P34IPz8/Pz8/BT8/ej8/Hz8/P319Pz99BiI/Hn4/Pz8IPz8/Pz8/BT8/fD8IPxk/Bz8UPz8HPx8OPz8NPxV/Pz8/Dgg/Pz8/Pz8FeT8/PwgiCD9PZEE/CDA/UD8/Pz8/Pz8/Pz8/Pz8/Pz9+Pz8/Pz8/PzVQV0s/Cj8eCz8yAT8HPwg/Pz8EPw8/BVY/aj8/Cz8ffT8/Pz8/Pz8GSD8ePz8/fRU/P34OBT8GPwg/Pz8/Pz8/Pz8/fz9/Pz8/Pz8FXg4/CD8/Pz8/PwY/Hns/Pz8HKD8ePz8/Pz9/P30VP0c/Pz8OHiU/Kz8xNj8HPx43Pyw/JT8lPyo/Nz8HPx82Py0/LyU/FT8/HkY/Oz8DP1U/Bz8eVT89PwU/Rj9GPzs/Az9VPwc/H1U/PT8FP0Y/FX8/Pz8OCD8/P2s/FT8HPz8IPz8/Pz8VPz8GPwhGP2E/bhY/Bz8/CD8nUUo/PxU/P2c/Hn4/P35+Pz8/Bz8IP0M/Vz9VPz8/Pz8/Pz8/Pz8/Pz8/Pz8/ZD93Pz8/Bz8/CD8sP0s/Pz8/Pz8RPwc/Hj8/Pz8/Pz9+BzwIP2s/UT8/Pz8/Pz9+P39/P34/Pz8/Pz8/Uz9OPz0HPz8Iaio/VD8nPyY/PjM/Dj8HZRV2Pz8/Pw4eeH19eHg/fT8HPx4/Pz8/P30/eAdwFQI/Px99Pz99Bn8efT8/PwV3Pz8ePz8/Pz8/Pz8VVz8DPz8OPz8OBT8/Pxo/Rz8VT28FDD9APz8/PxUMP3g/BQw/QD8/Pz8VSD9cPwUaP0c/Pz8/FVk/Bj8/fD8/PwRcPyQKDUkJDgk/CEQIAAg/B00HPwY/BikGPwU/BT8FSgU/BBUEPwMZAz8CJQI/AX8BLAF7AEAAPQABAAIbAD8BYABbAFgAVgBUAFMAUABFADkALwAqACkAJgAhABoAGQAXABYAFAATABIAEQAFAAIAAQAAAQEAAHRub0Ztb2MueWhwYXJnb3B5dC53d3cvLzpwdHRoIC5vQyAmIHJlbGZlb0ggNzAwMiAsNjAwMiApQyggdGhnaXJ5cG9DZ3Vsc29jaExICAEBAwARWD8SCA4AAB0/DyM/BT8/Mz9cPz8DDFkEFj8DHT8CHT8BHD8AED8oAQEBAHRub0YFAQEBAAQEAAEAAAAAAAAAAAAAAAAAAAAAAAAAADIAPz8AAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PDw0NAA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZABMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhYWFhMTExMTAAAAAAAAAAAAAAAAAAAAAAAAEA0AAAAAAAAAABgAABcAFgAVFAAAEwAAAAAAAAAAAAASAAAAAAAAAAAAAAARAAAAAAAAAAAAEAAAAAAPDgAADQAAAAAMAAAAAAAACwoACQgABwYFBAAAAAAAAAAAAAAAAwAAAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAABgEAAA0AEgAWABYAFgAWABMAEwATABMAEwATAA8ADwAPAA8ADQANAA0ADQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAABqAGIAAABWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAggPz8/Pz8UPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/PwAAAz8AAAAAPz8AAHg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/PxI/Px4/Hj8eGQI/AX4BfAF6AXUBcwFxAW8BbQFrAWEBXwFbAVkBVwFVAVEBTwFNAUcBRQFDATABLgEsASoBJgEaARgBFgEUAREBDwE/AD8APwA/AD8AegB3AHUAcgBvAGQAWABOAEgARQBAADgANQAwACQAIAAAAD8/Ej8/Hj8ePx4ZAj8BfgF8AXoBdQFzAXEBbwFtAWsBYQFfAVsBWQFXAVUBUQFPAU0BRwFFAUMBMAEuASwBKgEmARoBGAEWARQBEgEPAT8APwA/AD8APwB6AHcAdQBzAG8AZABYAE4ASQBFAEAAOQA2ADMAJAAhADgABQBAAHgAAAAYAgQAHAAAAAEAAwA0AgAAAAABABwAAAADAAAAAwAAAABlAHIAYQB3AHQAZgBvAHMALQB0AG4AbwBmAGIAZQB3AC8AbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcALwAvADoAcAB0AHQAaABtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQALgB3AHcAdwA5ADEAMgAwADQAMQAtADMAMgA0ADIALQAzADIANgAwADUAMQAwADIALQA0ADcANAA4ADgALQA3ADQAMgAxADcAMQAgAG0AbwBjAC4AeQBoAHAAYQByAGcAbwBwAHkAdAAuAHcAdwB3ACAAdABhACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAHQAYwBhAHQAbgBvAGMAIAByAG8AIAAsAGUAcgBhAHcAdABmAG8AcwAtAHQAbgBvAGYAYgBlAHcALwBtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQALgB3AHcAdwAvAC8AOgBwAHQAdABoACAAdABpAHMAaQB2ACAAZQBzAGEAZQBsAHAAIAAsAG4AbwBpAHQAYQBtAHIAbwBmAG4AaQAgAGUAcgBvAG0AIAByAG8ARgAgAC4AZQBzAG8AcAByAHUAcAAgAHkAbgBhACAAcgBvAGYAIABlAHIAYQB3AHQAZgBvAHMAIABzAGkAaAB0ACAAZQBzAHUAIAB0AG8AbgAgAHkAYQBtACAAdQBvAHkAIAAsAHMAdABzAGkAeABlACAAdABuAGUAbQBlAGUAcgBnAGEAIABoAGMAdQBzACAAbwBuACAAZgBJACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGQAbgBhACAAdQBvAHkAIABuAGUAZQB3AHQAZQBiACAAcwB0AHMAaQB4AGUAIAB0AGEAaAB0ACAAdABuAGUAbQBlAGUAcgBnAGEAIABlAGMAaQB2AHIAZQBTACAAZgBvACAAcwBtAHIAZQBUACAAZQBoAHQAIABvAHQAIAB0AGMAZQBqAGIAdQBzACAAcwBpACAAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAdAAgAGUAcwB1ACAAbwB0ACAAdABoAGcAaQByACAAcgB1AG8AWQAgAC4AbgBvAGkAdABhAGMAbwBsACAAeQBuAGEAIABtAG8AcgBmACAAdABpACAAdABzAG8AaAAgAHIAbwAgACwAcgBlAHQAdQBwAG0AbwBjACAAeQBuAGEAIABuAG8AcAB1ACAAdABpACAAbABsAGEAdABzAG4AaQAgAHIAbwAgACwAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAdAAgAGQAYQBvAGwAbgB3AG8AZAAgAHIAbwAgACwAZQB0AHUAYgBpAHIAdABzAGkAZAAgACwAeQBmAGkAZABvAG0AIAAsAHkAcABvAGMAIAB0AG8AbgAgAHkAYQBtACAAdQBvAFkAIAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIACAAZgBvACAAeQB0AHIAZQBwAG8AcgBwACAAZQBoAHQAIABzAGkAIABlAHIAYQB3AHQAZgBvAHMAIABzAGkAaABUAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgALgBzAG4AbwBpAHQAYwBpAGQAcwBpAHIAdQBqACAAbgBpAGEAdAByAGUAYwAgAG4AaQAgAGQAZQByAGUAdABzAGkAZwBlAHIAIABlAGIAIAB5AGEAbQAgAGgAYwBpAGgAdwAgACwALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGYAbwAgAGsAcgBhAG0AZQBkAGEAcgB0ACAAYQAgAHMAaQAgAGQAZQBkAG4AdQBvAFIAIABtAGEAaAB0AG8ARwB0AG4AbwBGADEAMAAyAC4AMQAgAG4AbwBpAHMAcgBlAFYAOQAxADIAMAA0ADEALQAzADIANAAyAC0AMwAyADYAMAA1ADEAMAAyAC0ANAA3ADQAOAA4AC0ANwA0ADIAMQA3ADEAcgBhAGwAdQBnAGUAUgBtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQAIAB8ACAAbwBDACYASAAgACkAQwAoACAAdABoAGcAaQByAHkAcABvAEMAbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcALwAvADoAcAB0AHQAaAAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIAA3ADAAMAAyACAALAA2ADAAMAAyACAAKQBDACgAIAB0AGgAZwBpAHIAeQBwAG8AQwBlcmF3dGZvcy10bm9mYmV3L21vYy55aHBhcmdvcHl0Lnd3dy8vOnB0dGhtb2MueWhwYXJnb3B5dC53d3c5MTIwNDEtMzI0Mi0zMjYwNTEwMi00NzQ4OC03NDIxNzEgbW9jLnlocGFyZ29weXQud3d3IHRhIC5vQyAmIHJlbGZlb0ggdGNhdG5vYyBybyAsZXJhd3Rmb3MtdG5vZmJldy9tb2MueWhwYXJnb3B5dC53d3cvLzpwdHRoIHRpc2l2IGVzYWVscCAsbm9pdGFtcm9mbmkgZXJvbSByb0YgLmVzb3BydXAgeW5hIHJvZiBlcmF3dGZvcyBzaWh0IGVzdSB0b24geWFtIHVveSAsc3RzaXhlIHRuZW1lZXJnYSBoY3VzIG9uIGZJIC5vQyAmIHJlbGZlb0ggZG5hIHVveSBuZWV3dGViIHN0c2l4ZSB0YWh0IHRuZW1lZXJnYSBlY2l2cmVTIGZvIHNtcmVUIGVodCBvdCB0Y2VqYnVzIHNpIGVyYXd0Zm9zIHNpaHQgZXN1IG90IHRoZ2lyIHJ1b1kgLm5vaXRhY29sIHluYSBtb3JmIHRpIHRzb2ggcm8gLHJldHVwbW9jIHluYSBub3B1IHRpIGxsYXRzbmkgcm8gLGVyYXd0Zm9zIHNpaHQgZGFvbG53b2Qgcm8gLGV0dWJpcnRzaWQgLHlmaWRvbSAseXBvYyB0b24geWFtIHVvWSAub0MgJiByZWxmZW9IIGZvIHl0cmVwb3JwIGVodCBzaSBlcmF3dGZvcyBzaWhULm9DICYgcmVsZmVvSC5zbm9pdGNpZHNpcnVqIG5pYXRyZWMgbmkgZGVyZXRzaWdlciBlYiB5YW0gaGNpaHcgLC5vQyAmIHJlbGZlb0ggZm8ga3JhbWVkYXJ0IGEgc2kgZGVkbnVvUiBtYWh0b0d0bm9GMTAyLjEgbm9pc3JlVjkxMjA0MS0zMjQyLTMyNjA1MTAyLTQ3NDg4LTc0MjE3MXJhbHVnZVJtb2MueWhwYXJnb3B5dCB8IG9DJkggKUMoIHRoZ2lyeXBvQ21vYy55aHBhcmdvcHl0Lnd3dy8vOnB0dGggLm9DICYgcmVsZmVvSCA3MDAyICw2MDAyIClDKCB0aGdpcnlwb0M/A0YAEgAJBAEAAwA/A0YAEQAJBAEAAwA/A0YAEAAJBAEAAwA/CVQADgAJBAEAAwBrBSIEDQAJBAEAAwA/CSQADAAJBAEAAwA/CSQACwAJBAEAAwBrBSIECgAJBAEAAwBRBRoACQAJBAEAAwBRBRoACAAJBAEAAwA/BD8ABwAJBAEAAwA/BAgABgAJBAEAAwBtBBoABQAJBAEAAwA/A0YABAAJBAEAAwArBEIAAwAJBAEAAwAdBA4AAgAJBAEAAwA/A0YAAQAJBAEAAwBXAz8AAAAJBAEAAwBAACMAEgAAAAAAAQBAACMAEQAAAAAAAQBAACMAEAAAAAAAAQAtAyoADgAAAAAAAQAKARECDQAAAAAAAQAbAxIADAAAAAAAAQAbAxIACwAAAAAAAQAKARECCgAAAAAAAQA/AA0ACQAAAAAAAQA/AA0ACAAAAAAAAQA/AGEABwAAAAAAAQA/AAQABgAAAAAAAQA/AA0ABQAAAAAAAQBAACMABAAAAAAAAQBqACEAAwAAAAAAAQBjAAcAAgAAAAAAAQBAACMAAQAAAAAAAQAAAEAAAAAAAAAAAQA/ASQAAAABACAAIAA/Aj8BAAAAAAsAAAA/AD8DPwA4PyADEj8kAAAAb0MmSAAAAAAAAAAASgAAUH8AAD8AAAAAAAAAAAAAAAA/ADIAPwEAAD8CPwI/AAAAPwI/AgQABQAsAU0CAgAAABsAAFAAABsAAAAAAAAAAAAAAAAAAAABAD8DAAAAAD8DAAAQPz8DAAABAAAAAAAAAAIACAAAACADPwM4PwAAHwIsPwAAAAAfAiw/AAAAAD8DCwA/PA9fPz8/LkEAAQAAAAEAIAAAAHgQAAAyAD8/dHNvcD8LAAA/AQAABDM1KGVtYW4GAAAAGAEAAABQGwBweGFtbAAAADAfAAA/Bj89eHRtaCQAAAA/AAAAAANhB2FlaGg2AAAAPwAAAD9HFgNkYWVoCAAAACgfAAALAAAAcHNhZzoDAAA8DQAAAj8/cGFtY2AAAAAgAQAASyU/VTIvU08gAAAACB8AAAQASABGRURHbw4AAD8QAABjPz9PIEZGQzAAAwA/AAsAT1RUTw==))); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:font/opentype;base64,T1RUTwALAIAAAwAwQ0ZGIE+2i2MAABCYAAAOb0dERUYASAAEAAAfCAAAACBPUy8yVcclSwAAASAAAABgY21hcO62ywIAAA08AAADOmdhc3AAAAALAAAfKAAAAAhoZWFkAxZHvAAAALwAAAA2aGhlYQdhAwAAAAD0AAAAJGhtdHg9xwbVAAAfMAAAAGxtYXhwABtQAAAAARgAAAAGbmFtZSg1MwQAAAGAAAALu3Bvc3T/uAAyAAAQeAAAACAAAQAAAAEAQS6s5cVfDzz1AAsD6AAAAADQLAIfAAAAANAsAh8AAP84A58DIAAAAAgAAgAAAAAAAAABAAADwP8QAAAD1AAAAAADnwABAAAAAAAAAAAAAAAAAAAAGwAAUAAAGwAAAAICTQEsAAUABAK8AooAAACMArwCigAAAd0AMgD6AAAAAAAAAAAAAAAAoAAAf1AAAEoAAAAAAAAAAEgmQ28AAAAk4BIDIP84AMgDwADwAAAACwAAAAAB/gK8ACAAIAABAAAAJAG2AAEAAAAAAAAAQAAAAAEAAAAAAAEAIwBAAAEAAAAAAAIABwBjAAEAAAAAAAMAIQBqAAEAAAAAAAQAIwBAAAEAAAAAAAUADQCLAAEAAAAAAAYABACYAAEAAAAAAAcAYQCcAAEAAAAAAAgADQD9AAEAAAAAAAkADQD9AAEAAAAAAAoCEQEKAAEAAAAAAAsAEgMbAAEAAAAAAAwAEgMbAAEAAAAAAA0CEQEKAAEAAAAAAA4AKgMtAAEAAAAAABAAIwBAAAEAAAAAABEAIwBAAAEAAAAAABIAIwBAAAMAAQQJAAAAgANXAAMAAQQJAAEARgPXAAMAAQQJAAIADgQdAAMAAQQJAAMAQgQrAAMAAQQJAAQARgPXAAMAAQQJAAUAGgRtAAMAAQQJAAYACASHAAMAAQQJAAcAwgSPAAMAAQQJAAgAGgVRAAMAAQQJAAkAGgVRAAMAAQQJAAoEIgVrAAMAAQQJAAsAJAmNAAMAAQQJAAwAJAmNAAMAAQQJAA0EIgVrAAMAAQQJAA4AVAmxAAMAAQQJABAARgPXAAMAAQQJABEARgPXAAMAAQQJABIARgPXQ29weXJpZ2h0IChDKSAyMDA2LCAyMDA3IEhvZWZsZXIgJiBDby4gaHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbUNvcHlyaWdodCAoQykgSCZDbyB8IHR5cG9ncmFwaHkuY29tUmVndWxhcjE3MTI0Ny04ODQ3NC0yMDE1MDYyMy0yNDIzLTE0MDIxOVZlcnNpb24gMS4yMDFGb250R290aGFtIFJvdW5kZWQgaXMgYSB0cmFkZW1hcmsgb2YgSG9lZmxlciAmIENvLiwgd2hpY2ggbWF5IGJlIHJlZ2lzdGVyZWQgaW4gY2VydGFpbiBqdXJpc2RpY3Rpb25zLkhvZWZsZXIgJiBDby5UaGlzIHNvZnR3YXJlIGlzIHRoZSBwcm9wZXJ0eSBvZiBIb2VmbGVyICYgQ28uIFlvdSBtYXkgbm90IGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgb3IgZG93bmxvYWQgdGhpcyBzb2Z0d2FyZSwgb3IgaW5zdGFsbCBpdCB1cG9uIGFueSBjb21wdXRlciwgb3IgaG9zdCBpdCBmcm9tIGFueSBsb2NhdGlvbi4gWW91ciByaWdodCB0byB1c2UgdGhpcyBzb2Z0d2FyZSBpcyBzdWJqZWN0IHRvIHRoZSBUZXJtcyBvZiBTZXJ2aWNlIGFncmVlbWVudCB0aGF0IGV4aXN0cyBiZXR3ZWVuIHlvdSBhbmQgSG9lZmxlciAmIENvLiBJZiBubyBzdWNoIGFncmVlbWVudCBleGlzdHMsIHlvdSBtYXkgbm90IHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSB2aXNpdCBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUsIG9yIGNvbnRhY3QgSG9lZmxlciAmIENvLiBhdCB3d3cudHlwb2dyYXBoeS5jb20gMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5d3d3LnR5cG9ncmFwaHkuY29taHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbS93ZWJmb250LXNvZnR3YXJlAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMAA2ACwAIAAyADAAMAA3ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgAEgAJgBDAG8AIAB8ACAAdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAFIAZQBnAHUAbABhAHIAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAVgBlAHIAcwBpAG8AbgAgADEALgAyADAAMQBGAG8AbgB0AEcAbwB0AGgAYQBtACAAUgBvAHUAbgBkAGUAZAAgAGkAcwAgAGEAIAB0AHIAYQBkAGUAbQBhAHIAawAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4ALAAgAHcAaABpAGMAaAAgAG0AYQB5ACAAYgBlACAAcgBlAGcAaQBzAHQAZQByAGUAZAAgAGkAbgAgAGMAZQByAHQAYQBpAG4AIABqAHUAcgBpAHMAZABpAGMAdABpAG8AbgBzAC4ASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgBUAGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAaQBzACAAdABoAGUAIABwAHIAbwBwAGUAcgB0AHkAIABvAGYAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAWQBvAHUAIABtAGEAeQAgAG4AbwB0ACAAYwBvAHAAeQAsACAAbQBvAGQAaQBmAHkALAAgAGQAaQBzAHQAcgBpAGIAdQB0AGUALAAgAG8AcgAgAGQAbwB3AG4AbABvAGEAZAAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUALAAgAG8AcgAgAGkAbgBzAHQAYQBsAGwAIABpAHQAIAB1AHAAbwBuACAAYQBuAHkAIABjAG8AbQBwAHUAdABlAHIALAAgAG8AcgAgAGgAbwBzAHQAIABpAHQAIABmAHIAbwBtACAAYQBuAHkAIABsAG8AYwBhAHQAaQBvAG4ALgAgAFkAbwB1AHIAIAByAGkAZwBoAHQAIAB0AG8AIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIABzAHUAYgBqAGUAYwB0ACAAdABvACAAdABoAGUAIABUAGUAcgBtAHMAIABvAGYAIABTAGUAcgB2AGkAYwBlACAAYQBnAHIAZQBlAG0AZQBuAHQAIAB0AGgAYQB0ACAAZQB4AGkAcwB0AHMAIABiAGUAdAB3AGUAZQBuACAAeQBvAHUAIABhAG4AZAAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABJAGYAIABuAG8AIABzAHUAYwBoACAAYQBnAHIAZQBlAG0AZQBuAHQAIABlAHgAaQBzAHQAcwAsACAAeQBvAHUAIABtAGEAeQAgAG4AbwB0ACAAdQBzAGUAIAB0AGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAZgBvAHIAIABhAG4AeQAgAHAAdQByAHAAbwBzAGUALgAgAEYAbwByACAAbQBvAHIAZQAgAGkAbgBmAG8AcgBtAGEAdABpAG8AbgAsACAAcABsAGUAYQBzAGUAIAB2AGkAcwBpAHQAIABoAHQAdABwADoALwAvAHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAC8AdwBlAGIAZgBvAG4AdAAtAHMAbwBmAHQAdwBhAHIAZQAsACAAbwByACAAYwBvAG4AdABhAGMAdAAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABhAHQAIAB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAgADEANwAxADIANAA3AC0AOAA4ADQANwA0AC0AMgAwADEANQAwADYAMgAzAC0AMgA0ADIAMwAtADEANAAwADIAMQA5AHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0ALwB3AGUAYgBmAG8AbgB0AC0AcwBvAGYAdAB3AGEAcgBlAAAAAAMAAAADAAAAHAABAAAAAAI0AAMAAQAAABwABAIYAAAAeABAAAUAOAAhACQAMwA2ADkAQABFAEkATgBYAGQAbwBzAHUAdwB6AKEAzwDRAPYA/AEPARIBFAEWARgBGgEmASoBLAEuATABQwFFAUcBTQFPAVEBVQFXAVkBWwFfAWEBawFtAW8BcQFzAXUBegF8AX4B/wIZHoEegx6F4BL//wAAACAAJAAwADUAOABAAEUASABOAFgAZABvAHIAdQB3AHoAoQDIANEA8gD4AQ8BEQEUARYBGAEaASYBKgEsAS4BMAFDAUUBRwFNAU8BUQFVAVcBWQFbAV8BYQFrAW0BbwFxAXMBdQF6AXwBfgH/AhkegR6DHoXgEv///+H/3//U/9P/0v/M/8j/xv/C/7n/rv+k/6L/of+g/57/eAAA/z8AAAAA/wMAAP75/vf+9f7z/uj+5f7j/uH+3/7N/sv+yf7G/sT+wv6//r3+u/66/rb+tP6r/qn+p/6l/qP+ov6e/pz+mv4U/fzhluGU4ZIgCAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWAAAAYgBqAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0ADQANAA0ADwAPAA8ADwATABMAEwATABMAEwAWABYAFgAWABIADQAAAQYAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIAAAMAAAAAAAAAAAAAAAQFBgcACAkACgsAAAAAAAAMAAAAAA0AAA4PAAAAABAAAAAAAAAAAAARAAAAAAAAAAAAAAASAAAAAAAAAAAAABMAABQVABYAFwAAGAAAAAAAAAAADRAAAAAAAAAAAAAAAAAAAAAAAAATExMTExYWFhYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEwAZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQANDQ8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAA/7UAMgAAAAAAAAAAAAAAAAAAAAAAAAAAAQAEBAABAQEFRm9udAABAQEo+BAA+BwB+B0C+B0D+BYEWQwDi/tc+jP5tAX3Iw+THQAADggS91gRAAMBAQhITGhjb3NsdWdDb3B5cmlnaHQgKEMpIDIwMDYsIDIwMDcgSG9lZmxlciAmIENvLiBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tRm9udAAAAQEAAAEAAgAFABEAEgATABQAFgAXABkAGgAhACYAKQAqAC8AOQBFAFAAUwBUAFYAWABbAGABhwAbAgABAD0AQAB7ASwBfwG7AiUCngMZA5YEFQSSBUoFiwXGBeIGKQafBv4HTQeGCAAIRAjGCQ4JSQ0KJPtcBPiI+nz8iAbSWRX3+ov7R/waBftc/EgVi/mE90D8DAX3ePgMFYv9hPtA+AwFb08V90f8Gvv6iwUO+8MO+/P3A/dXFYOShJOTkpKTHpv4dwWZgJZ9Hn8GfYCAfR+J/QIVcAd4mX2enpmZnh6mB559mXh4fX14Hg6o9735dhVlB/sOiDM+iyaLJ8lU9ypqCPuxBz2TTqpTv4iOhY+Ci36Lf3+LfouCj4WShc5R0mvihAg8B36WgJiYlpaYHtkH9xGP5NaL9YvtS8T7LKsI96wHwIW7d7xkkoWQipGLmYuXlouZi5WGkYKSVbNXo0ORCLMHmICWfn6AgH4e92f8wRWLP0pRJ4kI96gH9xZurmGLRgj8BvfqFYvTy8XsjQj7pQf7FaprtYvPCA729/Z/FfdG9wX3PfdVH40H91X7A/c7+0b7RvsF+z37VR6JB/tV9wP7O/dGHo26FfslL/ct9zYfjQf3N+X3Kvcl9yXn+yz7Nx6JB/s2Mfsr+yUeDvug90ehFX2Xf5mZlpeZHvkoB5iCl3seiQaAi4GIgIcI+w5eBYCHg4WLf4t/lYGXi4+Lj4yQjQj3BrIFDn63oxV9loGZHvhIBpmWlpmZgJZ9H/wLi/dq91YF9w/3BL/Li+sIjQf3ATLe+wse+wqLS1dQNYiHioaLh4t+loGYi5SLkY+QksHWxLXgi9+L1VCLMAiLQWRP+wgiCPuR+3kFg4SHhYuCCA6S98t/FfcN9t33Dh+NB4v3FPsHyfsZkwj3fPedBZCRj5OLkgiYgZR+HvwiBn2AgH19loGZH/fui/t6+50FhYSIhYuFCH6WgZgepAb3EudVKR+JBy88TC0eM4tIsFTNh5CDkIKLfYt/f4t9i4SPhI6Hw0ffW/cBiwgOjffCfxX3IfLr9xUfjQf3ESLh+xseSotee151CJz3mvfaiwWZlpaZmYCWfR/77wZ9i3+CingIevu0BYp8j36VhJOGlIeXi5yLurLmiwj3BdpIKB+JByY+QPsDHkWLR65Qw4aQgo+Di32LgH+Lf4uCjoWTg8RU4F7kiwgO999/Ffce9u33GB+NB/cR+wbi+xMe+waLSk1jR4b3auf3Kfcii8iLvHW9YpCHkImRi5mLl5eLmYuUh5GEkQhTt1KkQYsI+0L7A/s8+2cfiQeL+yWqRcVRtWHLb9OLCI+6FfsFNtfvH40H4dvi9wf3A9pDKx6JByhBOfsFHg6m98+BFfcn9wXc9wgfjQeL3UjJM6jQp8m/i94IjQf3AfsH1fsN+w37B0H7AR6JB4s4yVfQbzNuSE2LOQiJB/sI9wU69yce+BsEKDjF4R+NB9rbxPHx21I8HokHNThRKB777AT7FT7Q2h+NB+LnyvcG9wbnTDQeiQc8Pkb7FR4O97l/Ffc39w73MvdwH40Hi/cgadpVwWG1TqhAiwj7Jich+xUfiQf7DPAt9yEe9wKLz8qz05P7Zij7K/shi0+LVqNVuYWQhI2Fi32LgH+LfYuCj4WShQjAYMtp3YsInPfTFfsDPNPtH40H7NLk9wf3CN48KB6JBzM/MfsLHg74DfiH+zYV8IvfptW3jo2Pj4uSi5KFkoSLiIuGiomKQWFEdSmLCPuF+z/3SPd093P3QfdL93v3evdA+0n7S/slQU1FUmqqxB+Ll46kka4IrfdWBY6bgZp7i36LgoKIfAiAUAV0t164OosI+wT7DSH7IyHbQ+wf2ou+tbS+nFK8Z9GLCODs0/c/92f7U/dN+4n7iftV+1v7g/uD91L7WfeUH1b3rhU9VL3g9wTl4ObXw088KTUsLR8OzvcWFvhdBpiWlpiYgJZ+H/xD9634EQaYlpaYmICWfh/8Efen+D4GmJaWmJiAln4f/FgGfX9/fR/9HAd9l3+ZHg73MfOhFX2Xf5mZl5eZHvfG+FT7xgd9l3+ZmZeXmR75JAeZf5d9fX9/fR77wvxU98IHmX+XfX1/f30eDvvd9wOhFX2Xf5mZl5eZHvkkB5l/l319f399Hg73T/OgFX2WgJmZlpaZHov47/h1/PYFk4GThJWLCI8Gl5SVlx/5KAeZgJZ9fYCAfR6L/OL8bPjrBYSUg5GAiwiDBn1/f30fDvcL1J8VfpWAmB6Wi5KSkpQI94P3y/eG+84FkYORhpWLmIuXl4uXi5KIkYWSCPuL99L3g/fFBY+QjpGLkYuYgZZ+i4CLhISEggj7efu8+3z3vwWFk4WQgYt+i39/i3+LhI+FkIQI94L7w/uO+9QFh4aIhYuFCA7E+Mv5WRWagJV9fYGBfB77yQdhy0nFJYsI+w/7ESb7Oh+JB/s69xEo9w8e8IvMxrfOCC4HfJaBmZmVlZoe+5L4WhX18TP7Fx+JB/sWJTIhIC7h9xoejQf3HeTc9wMeDrD3038V9yz3A/cQ9yMfjQf3I/sC9w77K/ss+wP7EPsjHokH+yP3AvsO9ysejbkV+wov7fcPH40H9wzi7vcN9wrnKfsPHokH+ww0KPsNHg77X+igFXyWgZmZlZaZHvdQB4v3OOzc9wCVm4yVl4uZi5qAl3yLQ4syVV8oCPcQB5qAlX19gYB9Hg4h95aBFe3ZxeYfjQeL5TWpOaJCoEagi8QIjQe+ubHRHryLvHu3cY6JkImRi5iLlpaLmIuWhJKFj1qnTp1UiwgoRlA5H4kHizDnct5z0nfLdYtPCIkHUFVlRh5Oi1OfVrGHjoWNhYt+i4CAi36Lg5CDj4i/ZNhw0IsIDpX4nPh9FZqAlX19gYF8HvumByE+PyckUND0HveuB5qAlX19gYF8Hvu3B/sO1jP3FR7oi8S6rccIQQd8loGZmZWWmR4O95b3lIQVjQaYi5STkJoI9yb4Nfcl/DUFkHyUg5iLCI0Gl4uVk5CZCPc7+F8FjZCNkYuRi5eAln2LfYuEgoiBCPsp/EX7KPhFBYeWhJN9iwiJBn6LhIOHgAj7KPxF+yj4QwWHl4OUfYt9i3+Ai36Lho2FjYYI9zv8XwWQfZWDl4sIDlrfFvghBpeVlZeXgZV/H/vyi/f4+DwFkZKOkYuTCIwHlYCVfx78EwZ/gYF/f5WBlx/35Iv7+Pw8BYWEiIWLgwiKB4GWgZceDvvz9yH4jRWThJKDg4SEgx57/HcFfZaAmR6XBpmWlpkfjfkCFaYHnn2ZeHh9fXgecAd4mX2enpmZnh4O5velnRUgCpKcFSEKULYVIgqaQRUiCoYEIwr35JAVIgqGBCMK/DnWFamSgZuPBpCLi4qMhAiSooQGioSLioaLCIedlwaSi42JjYAIk59YhJJihAbRgxUjCvhV+0EV/Ob5tPjmBvsm/VEVmouTlIyZCIMGioKGhIOLCIGFkpqbkZGTH5OLjoePfwiToYMGioUFh4+GjoSLCH1+f3l6loCdH/sS3BWFiZCTko2RkZCNhoODiYaGHys7FaKShqSZcoaEopKFvwaBiQWJjIeMiIsIgYKFfh+KhISScoUH54QVpZKDmwaNkI6PjYsIigeHjomOj46Oj5CIjoYehouHiIiDCJV5hJFyhQd7zRWRi4+TBY6Gj4iSiwiXj5eUl4WTgh+Fi4aIiYUIpnmEkQe7WRWHiIiHho+Hkh+Ui5CRj5UImKqQi4uSeouLhJCLg3eCn5GLi5Jyi4uEkIsFi4uXdI+BioaIiIeLjo6KkoSLCPst9/UVi3SafaJ1lpySm4ucCKJ/mnp7gH96HsL79hWSi4yPBY6JjoiSi5SLkJGLkoubc4WLk4uNjY2Oi4+LjoiOhwiSmIUGiYYFiY6HjYaLgouGhYuFi3ujkIuDi4mJiYiLhouIjoeRCIQGYvcXFZqLl46WlG+ub6l5nICAhn2LfItsoXSpiwiYKhWChISSdweDj4aTHpOLj4+NlAiGjQWKhomJiYsIiIqNjh+fmJJ+lgf3IvdKFZR8m4GdiwinoaKqqnWgbx9yi3h9e3OJpneWcIqRlY6Wi5gIrmqyTUhhYWAei26VeaB1VnlubIthi1a8Y8eLtYutmaeqrGmhgKmLtouur43FCISNBYF6f392i3eLepdyqJqfm5ialAj7Zft8FaGSh5oGkY6Pj4+NiIceeYeEoZKFngeTiJGCHoSLh4eIhAiVeoSRcoUH93dbFYSRB4qIiIeJiYePiI+GkJKOj46LkQiRhpGCgYSEhB6Lho2Ij4eEiYWGi4OLg5GFl4uRi5CNj4+Pho6KkIuTi46QjZIIhowFioeKiomLiYuJjYmOjo+Oj46RCJCSBmhwFYWHj5Efi4+Njo2NkIaPhpCFiImIiomLCPsbrxWVjo2OjYyKix6LioqJh46Jjh+GfQf3F48Vjo2Njo+NiIgei4eJiIiJh4+JjouOCPsF978Vm3uXfJh8nqyQo3SigoF9gHh+CMH72BUgCpKcFSEK+3NoFaiSg52heYOEqJKDtJOSbgaEk3t1m5OSboSTYoMH+FiRFYeIiIeHjoiPj46Oj4+IjocfDvkWFPjvFZMTAAQBASc0RliMmIWUfYsIgIKCf3+Tg5gflouQkY2TCIQGioaIiYaLCISIjpQfC5CNh4MffQaUjo6PHguGiI+Xlo6PkJCOh4B/iIeGHwuXlJSXl4KTf3+Cg39+lIOXHwsAAAEAAAAOAAAAGAAAAAAAAgABAAEAGgABAAQAAAACAAAAAQAB//8ACgH0AAABLAAAAPwAXQJ4AD0CxgBBAU8AHgJOACwCYgA3Al0APAKCAEACdgA3AoIAQgPUADUCngBoAvgAaAESAG8DFgBoAtIASQKUADwCgAA6AZAAXQHxADMCZQBTA10AOgIqAD0A/ABdArYAMg==); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/52C563F8BC21B4B43.css b/docs/static/fonts/332720/52C563F8BC21B4B43.css deleted file mode 100644 index 33716adc57..0000000000 --- a/docs/static/fonts/332720/52C563F8BC21B4B43.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face { font-family:"Gotham Rounded A"; src: url('http://nuclide.io/static/fonts/332720/78E7259F6E64A8FDC.eot'); src: url('http://nuclide.io/static/fonts/332720/78E7259F6E64A8FDC.eot?#hfj') format('embedded-opentype'); font-style:normal; font-weight:300; } @font-face { font-family:"Gotham Rounded 3r"; src: url('http://nuclide.io/static/fonts/332720/78E7259F6E64A8FDC.eot'); src: url('http://nuclide.io/static/fonts/332720/78E7259F6E64A8FDC.eot?#hfj') format('embedded-opentype'); font-style:normal; font-weight:300; } \ No newline at end of file diff --git a/docs/static/fonts/332720/537C133D913A8D41D.css b/docs/static/fonts/332720/537C133D913A8D41D.css deleted file mode 100644 index 28e5ff0939..0000000000 --- a/docs/static/fonts/332720/537C133D913A8D41D.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/truetype;base64,egABAAEAPz8GAAEAAQAAAAEAAAABAHoAAQAEAAEAegABAAEADgABAAgAAQAoAAEAAAABABAAAQAAAAYADgAGAAIAAAABAAAACAAxMHNzAQAAAAEAPz8AAAAABAAAAAEAPz8AAAAABAAaAG50YWwOAFRMRkQCAD4AMAAKAAAAAQAAAAMAAQABAAAAAQAIAAEARQB3AHUAOwBzAGoAOgBlAGUAMABcAFMALABRAE4AKwBMAEwAJwBJAEYAJABEAEIAFgA/ADIAEwAvAC0ADAAqACQACQAeABwACAAaABoAAwATAA8AAgANAA0AAQALAAsAAAAJAAkAEQACACYAAAAcABsAFwAAABUAJQAkABUAJQAkABgAGAAjABwAAAAAAAAAJgAbAAAAAAAAAAAAAAAAABEAAAAAADEAMAAvAC4ALQAsACoAJwAfABYAHwATAB8AHwAPAA8AHgAdAA8AGgAZABMAFgATAA8ADAAAABIAEAAAAAsACgAJAAgABwAGAAUABAAAAAIAAAACAAAAAAAAAAAAAwAAAAAAAgAAAAAAAAACAAAAAQAAACIAAAAAAAAAFAAUAAAAAAAoAAAAAAAAACsAAAAgADIAKQAXABgAFQAAAA4AIQAAAAAADQBxAAkAAQAnACYAIgAAACAALwAuACAALwAuACMAIwAtACcAAAAAAAAAAAAmAAAAAAAAAAAAAAAAAAAAAAAcADoAOQA4ADcANgA1ADQAMQAwAAAAGgArACgAKAAAACkAAAAAACgAJQAkACEAAAAeABoAFwAAAAAAGwAdABYAFQAUABMAEgARABAADwAOAA0ADAALAAAAAAAKAAkACAAAAAAABwAGAAUABAADAAIAAQAAAAAAAAAAAAAAHwAfACoAAAAyAAAAAAAAAAAAAAAAADsAMwAiACMAIAAAABkAAAAsAAAAGABvAAkAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/AAAAAAAAPz8AAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/Pz8/PwAAAAAAAD8/AAA/PwAAAAAAAAAAPz8AAAAAAAAAAAAAPz8/PwAAPz8/Pz8/AAA/Pz8/Pz8AAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/PwAAPz8AAD8/AAAAAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8/Pz8AAAAAAAA/PwAAPz8AAAAAAAAAAD8/AAAAAAAAAAAAAD8/PwAAPz8/Pz8/AAA/Pz8/Pz8AAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8AAD8/Pz8/PwAAPz8AAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/PwAAPz8AAD8/AAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAD8/AAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAA/PwAAPz8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8AAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/PwAAAAA/PwAAAAA/PwAAAAA/PwAAPz8/AAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/Pz8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAPz8AAAAAAAAjABQAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAD8/Pz8AAD8/AAAAAD8/AAAUAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAD8/AAAAAAAAAAAAAAAADwAAAAAAPz8AAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAAAAPz8AAD8/AAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAD8/AAA/PwAAPz8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAPz8/Pz8/AAAAAAAAAAAAAAAAAAAAAD8/AAA/Pz8AAAAAAAAAAD8/AAAAAAAAAAA/PwAAPz8AAAAAPz8/Pz8AAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/Pz8AAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8AAD8/AAA/PwAAAAA/PwAAAAA/PwAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8/Pz8AAD8/Pz8AAAAAPz8AAAAAAAA/Pz8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAA/PwAAAAA3ACMAHgAAACMAHgAAAAAAAAAAAAAAPz8/PwAAAAA/Pz8/PwAAPz8UAB4AHgAAAB4AAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/PwAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8/Pz8AAD8/AAAAAAAAPz8AAD8/AAA/PwAAPz8/PwAAAAA/PwAAPz8AAAAAPz8AAAAAAAAAAD8/AAAAAAAAAAAAAD8/AAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAH4/AAA/Pz8/PwAAAAA/PwAAAAAAAD8/Pz8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/AAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAA/Pz8/AAAAAD8/AAA/PwAAAAA/PwAAAAAAAAAAPz8AAA8AAAAAAAAAPz8AAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAfj8AAD8/Pz8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/PwAAPz8AAAAAAAAAAAAAAAAAAD8/Pz8/Pz8/AAAAAAAAAAAAAAAAAAAPAAoAAAA/Pz8AAAAAAAAAAAoAPz8/PwAAAAAAAD8/AAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/Pz8AAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAPz8AAD8/AAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAPz8/PwAAAAA/PwAAAAAAAD8/Pz8/PwAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/AAAAAAAAAAA/PwAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAA/Pz8/AAAAAAAAAAAAAAAAPz8AAD8/PwAAAAA/PwAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8/AAA/PwAAAAA/PwAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAA/Pz8/Pz8/Pz8AAD8/Pz8AAD8/AAAAAAAAAAAAAAAAAAA/Pz8/Pz8/Pz8/Pz9+Pz8/fj8/Pz8AAAAAAAA/PwAAPz8/Pz8/AAA/Pz8/AAAAAD8/fj8/Pz8AAAAAAAA/PwAAPz8AAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8/PwAAPz8AAAAAPz8AAAAAAAA/PwAAAAA/PwAAPz8AAD8/AAA/PwAAPz8AAD8/AAAAAAAAPz8/Pz8/PwAAPz8/PwAAPz8AAAAAAAAAAAAAAAAAAD8/Pz8/Pz8/Pz8/Pz8/PwAAAAAAAD8/AAA/Pz8/Pz8/Pz8/PwAAAAA/Pz8/Pz8/AAAAAD8/PwAAPz8AAD8/AAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAPz8AAD8/Pz8/Pz8/Pz8/Pz8/PwAAAAAAAD8/AAAAAD8/Pz8AAD8/AAAAAAAAPz8AAD8/Pz8AAAAAAAAAAD8/AAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAA/PwAAPz8AAAAAPz8/Pz8/Pz8/Pz8/AAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz95PwAAAAAAAD8/AAA/P3k/PwAAAAAAAAAAAAAAAD8/Pz8/Pz8AAAAAPz8/PwAAAAA/PwAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAD8/Pz8/AAA/Pz8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwoAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAA/Pz8AAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAKAAAACgAAAAUAAAAPAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAADwAAAD8/AAA/PwAAPz8AAAAAAAAAAAAAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAA/PwAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAD8/PwAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAA/Pz8/AAAAAAAAAAA/Pz8/Pz8AAD8/Pz8AAD8/AAAAAAAAPz8AAD8/PwAAAAA/PwAAAAAAAD8/Pz8AAD8/AAAAAAAAAAAAAAAAAAA/Pz8AAD8/AAAAAD8/AAAAAD8/AAA/Pz8/AAAAAH4/AAA/Pz8/Pz8AAAAAPz8AAAAAAAAAAD8/AAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/PwAAPz8AAAAAPz8AAAAAAAAAAAAAPz8/PwAAPz8AAD8/Pz8/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAACgAAAD8/Pz8AAD8/AAAAAAAAAAAAAAAAPz8/AAA/PwAAAAAAAAAAAAAAAD8/AAAUAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAPz8/Pz8/AAA/PwAAAAAAAAAAAAAAAD8/Pz8AAAAAAAAAAAAAAAAAAAAAPz8/PwAAAAAAAD8/AAA/Pz8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAA/Pz8AAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAPz8/PwAAAAAAAAAAPz8/Pz8/PwAAPz8/Pz8AAD8/AAAAAAAAPz8/Pz8/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/Pz8AAAAAAAAA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AHkAdAAuAHcAdwB3AC8ALwA6AHAAdAB0AGgAIAB0AGkAcwBpAHYAIABlAHMAYQBlAGwAcAAgACwAbgBvAGkAdABhAG0AcgBvAGYAbgBpACAAZQByAG8AbQAgAHIAbwBGACAALgBlAHMAbwBwAHIAdQBwACAAeQBuAGEAIAByAG8AZgAgAGUAcgBhAHcAdABmAG8AcwAgAHMAaQBoAHQAIABlAHMAdQAgAHQAbwBuACAAeQBhAG0AIAB1AG8AeQAgACwAcwB0AHMAaQB4AGUAIAB0AG4AZQBtAGUAZQByAGcAYQAgAGgAYwB1AHMAIABvAG4AIABmAEkAIAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIACAAZABuAGEAIAB1AG8AeQAgAG4AZQBlAHcAdABlAGIAIABzAHQAcwBpAHgAZQAgAHQAYQBoAHQAIAB0AG4AZQBtAGUAZQByAGcAYQAgAGUAYwBpAHYAcgBlAFMAIABmAG8AIABzAG0AcgBlAFQAIABlAGgAdAAgAG8AdAAgAHQAYwBlAGoAYgB1AHMAIABzAGkAIABlAHIAYQB3AHQAZgBvAHMAIABzAGkAaAB0ACAAZQBzAHUAIABvAHQAIAB0AGgAZwBpAHIAIAByAHUAbwBZACAALgBuAG8AaQB0AGEAYwBvAGwAIAB5AG4AYQAgAG0AbwByAGYAIAB0AGkAIAB0AHMAbwBoACAAcgBvACAALAByAGUAdAB1AHAAbQBvAGMAIAB5AG4AYQAgAG4AbwBwAHUAIAB0AGkAIABsAGwAYQB0AHMAbgBpACAAcgBvACAALABlAHIAYQB3AHQAZgBvAHMAIABzAGkAaAB0ACAAZABhAG8AbABuAHcAbwBkACAAcgBvACAALABlAHQAdQBiAGkAcgB0AHMAaQBkACAALAB5AGYAaQBkAG8AbQAgACwAeQBwAG8AYwAgAHQAbwBuACAAeQBhAG0AIAB1AG8AWQAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIABmAG8AIAB5AHQAcgBlAHAAbwByAHAAIABlAGgAdAAgAHMAaQAgAGUAcgBhAHcAdABmAG8AcwAgAHMAaQBoAFQALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAuAHMAbgBvAGkAdABjAGkAZABzAGkAcgB1AGoAIABuAGkAYQB0AHIAZQBjACAAbgBpACAAZABlAHIAZQB0AHMAaQBnAGUAcgAgAGUAYgAgAHkAYQBtACAAaABjAGkAaAB3ACAALAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIACAAZgBvACAAawByAGEAbQBlAGQAYQByAHQAIABhACAAcwBpACAAbQBhAGgAdABvAEcAdABuAG8ARgAxADAAMwAuADEAIABuAG8AaQBzAHIAZQBWADkAMQAyADAANAAxAC0AMwAyADQAMgAtADMAMgA2ADAANQAxADAAMgAtADQANwA0ADgAOAAtADcANAAyADEANwAxAHIAYQBsAHUAZwBlAFIAbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0ACAAfAAgAG8AQwAmAEgAIAApAEMAKAAgAHQAaABnAGkAcgB5AHAAbwBDAG0AbwBjAC4AeQBoAHAAYQByAGcAbwBwAHkAdAAuAHcAdwB3AC8ALwA6AHAAdAB0AGgAIAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIACAANwAwADAAMgAgACwANgAwADAAMgAgACkAQwAoACAAdABoAGcAaQByAHkAcABvAEMAZXJhd3Rmb3MtdG5vZmJldy9tb2MueWhwYXJnb3B5dC53d3cvLzpwdHRobW9jLnlocGFyZ29weXQud3d3OTEyMDQxLTMyNDItMzI2MDUxMDItNDc0ODgtNzQyMTcxIG1vYy55aHBhcmdvcHl0Lnd3dyB0YSAub0MgJiByZWxmZW9IIHRjYXRub2Mgcm8gLGVyYXd0Zm9zLXRub2ZiZXcvbW9jLnlocGFyZ29weXQud3d3Ly86cHR0aCB0aXNpdiBlc2FlbHAgLG5vaXRhbXJvZm5pIGVyb20gcm9GIC5lc29wcnVwIHluYSByb2YgZXJhd3Rmb3Mgc2lodCBlc3UgdG9uIHlhbSB1b3kgLHN0c2l4ZSB0bmVtZWVyZ2EgaGN1cyBvbiBmSSAub0MgJiByZWxmZW9IIGRuYSB1b3kgbmVld3RlYiBzdHNpeGUgdGFodCB0bmVtZWVyZ2EgZWNpdnJlUyBmbyBzbXJlVCBlaHQgb3QgdGNlamJ1cyBzaSBlcmF3dGZvcyBzaWh0IGVzdSBvdCB0aGdpciBydW9ZIC5ub2l0YWNvbCB5bmEgbW9yZiB0aSB0c29oIHJvICxy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)); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/695AC8DE58C109BF3.css b/docs/static/fonts/332720/695AC8DE58C109BF3.css deleted file mode 100644 index 206532f78a..0000000000 --- a/docs/static/fonts/332720/695AC8DE58C109BF3.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/740083249BEF005F6.css b/docs/static/fonts/332720/740083249BEF005F6.css deleted file mode 100644 index 4aeacc5add..0000000000 --- a/docs/static/fonts/332720/740083249BEF005F6.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,T1RUTwANAIAAAwBQQ0ZGIKWnUnEAABFoAAAs60dERUYApgAEAAA+VAAAACBHUE9T5Gif/gAAPnQAAB1aR1NVQunbLV4AAFvQAAAAgE9TLzJVxSTvAAABQAAAAGBjbWFwaLtaTgAADVwAAAPsZ2FzcAAAAAsAAFxQAAAACGhlYWQDcke8AAAA3AAAADZoaGVhB74DwAAAARQAAAAkaG10eAmBHxsAAFxYAAAB5G1heHAAeVAAAAABOAAAAAZuYW1lKDUzBAAAAaAAAAu7cG9zdP+4ADIAABFIAAAAIAABAAAAAQBByTlTkF8PPPUACwPoAAAAANAsAh4AAAAA0CwCHv/o/zgEEwMiAAAACAACAAAAAAAAAAEAAAPA/xAAAARO/+j/6AQTAAEAAAAAAAAAAAAAAAAAAAB5AABQAAB5AAAAAgHwASwABQAEArwCigAAAIwCvAKKAAAB3QAyAPoAAAAAAAAAAAAAAACgAAB/UAAASgAAAAAAAAAASCZDbwAAACLgEgMg/zgAyAPAAPAAAAALAAAAAAH+ArwAIAAgAAIAAAAkAbYAAQAAAAAAAABAAAAAAQAAAAAAAQAjAEAAAQAAAAAAAgAHAGMAAQAAAAAAAwAhAGoAAQAAAAAABAAjAEAAAQAAAAAABQANAIsAAQAAAAAABgAEAJgAAQAAAAAABwBhAJwAAQAAAAAACAANAP0AAQAAAAAACQANAP0AAQAAAAAACgIRAQoAAQAAAAAACwASAxsAAQAAAAAADAASAxsAAQAAAAAADQIRAQoAAQAAAAAADgAqAy0AAQAAAAAAEAAjAEAAAQAAAAAAEQAjAEAAAQAAAAAAEgAjAEAAAwABBAkAAACAA1cAAwABBAkAAQBGA9cAAwABBAkAAgAOBB0AAwABBAkAAwBCBCsAAwABBAkABABGA9cAAwABBAkABQAaBG0AAwABBAkABgAIBIcAAwABBAkABwDCBI8AAwABBAkACAAaBVEAAwABBAkACQAaBVEAAwABBAkACgQiBWsAAwABBAkACwAkCY0AAwABBAkADAAkCY0AAwABBAkADQQiBWsAAwABBAkADgBUCbEAAwABBAkAEABGA9cAAwABBAkAEQBGA9cAAwABBAkAEgBGA9dDb3B5cmlnaHQgKEMpIDIwMDYsIDIwMDcgSG9lZmxlciAmIENvLiBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tQ29weXJpZ2h0IChDKSBIJkNvIHwgdHlwb2dyYXBoeS5jb21SZWd1bGFyMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5VmVyc2lvbiAxLjIwMUZvbnRHb3RoYW0gUm91bmRlZCBpcyBhIHRyYWRlbWFyayBvZiBIb2VmbGVyICYgQ28uLCB3aGljaCBtYXkgYmUgcmVnaXN0ZXJlZCBpbiBjZXJ0YWluIGp1cmlzZGljdGlvbnMuSG9lZmxlciAmIENvLlRoaXMgc29mdHdhcmUgaXMgdGhlIHByb3BlcnR5IG9mIEhvZWZsZXIgJiBDby4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBvciBkb3dubG9hZCB0aGlzIHNvZnR3YXJlLCBvciBpbnN0YWxsIGl0IHVwb24gYW55IGNvbXB1dGVyLCBvciBob3N0IGl0IGZyb20gYW55IGxvY2F0aW9uLiBZb3VyIHJpZ2h0IHRvIHVzZSB0aGlzIHNvZnR3YXJlIGlzIHN1YmplY3QgdG8gdGhlIFRlcm1zIG9mIFNlcnZpY2UgYWdyZWVtZW50IHRoYXQgZXhpc3RzIGJldHdlZW4geW91IGFuZCBIb2VmbGVyICYgQ28uIElmIG5vIHN1Y2ggYWdyZWVtZW50IGV4aXN0cywgeW91IG1heSBub3QgdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpc2l0IGh0dHA6Ly93d3cudHlwb2dyYXBoeS5jb20vd2ViZm9udC1zb2Z0d2FyZSwgb3IgY29udGFjdCBIb2VmbGVyICYgQ28uIGF0IHd3dy50eXBvZ3JhcGh5LmNvbSAxNzEyNDctODg0NzQtMjAxNTA2MjMtMjQyMy0xNDAyMTl3d3cudHlwb2dyYXBoeS5jb21odHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUAQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgADIAMAAwADYALAAgADIAMAAwADcAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAASAAmAEMAbwAgAHwAIAB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AUgBlAGcAdQBsAGEAcgAxADcAMQAyADQANwAtADgAOAA0ADcANAAtADIAMAAxADUAMAA2ADIAMwAtADIANAAyADMALQAxADQAMAAyADEAOQBWAGUAcgBzAGkAbwBuACAAMQAuADIAMAAxAEYAbwBuAHQARwBvAHQAaABhAG0AIABSAG8AdQBuAGQAZQBkACAAaQBzACAAYQAgAHQAcgBhAGQAZQBtAGEAcgBrACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAsACAAdwBoAGkAYwBoACAAbQBhAHkAIABiAGUAIAByAGUAZwBpAHMAdABlAHIAZQBkACAAaQBuACAAYwBlAHIAdABhAGkAbgAgAGoAdQByAGkAcwBkAGkAYwB0AGkAbwBuAHMALgBIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuAFQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIAB0AGgAZQAgAHAAcgBvAHAAZQByAHQAeQAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABZAG8AdQAgAG0AYQB5ACAAbgBvAHQAIABjAG8AcAB5ACwAIABtAG8AZABpAGYAeQAsACAAZABpAHMAdAByAGkAYgB1AHQAZQAsACAAbwByACAAZABvAHcAbgBsAG8AYQBkACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAsACAAbwByACAAaQBuAHMAdABhAGwAbAAgAGkAdAAgAHUAcABvAG4AIABhAG4AeQAgAGMAbwBtAHAAdQB0AGUAcgAsACAAbwByACAAaABvAHMAdAAgAGkAdAAgAGYAcgBvAG0AIABhAG4AeQAgAGwAbwBjAGEAdABpAG8AbgAuACAAWQBvAHUAcgAgAHIAaQBnAGgAdAAgAHQAbwAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHMAdQBiAGoAZQBjAHQAIAB0AG8AIAB0AGgAZQAgAFQAZQByAG0AcwAgAG8AZgAgAFMAZQByAHYAaQBjAGUAIABhAGcAcgBlAGUAbQBlAG4AdAAgAHQAaABhAHQAIABlAHgAaQBzAHQAcwAgAGIAZQB0AHcAZQBlAG4AIAB5AG8AdQAgAGEAbgBkACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAEkAZgAgAG4AbwAgAHMAdQBjAGgAIABhAGcAcgBlAGUAbQBlAG4AdAAgAGUAeABpAHMAdABzACwAIAB5AG8AdQAgAG0AYQB5ACAAbgBvAHQAIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABmAG8AcgAgAGEAbgB5ACAAcAB1AHIAcABvAHMAZQAuACAARgBvAHIAIABtAG8AcgBlACAAaQBuAGYAbwByAG0AYQB0AGkAbwBuACwAIABwAGwAZQBhAHMAZQAgAHYAaQBzAGkAdAAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0ALwB3AGUAYgBmAG8AbgB0AC0AcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABjAG8AbgB0AGEAYwB0ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGEAdAAgAHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtACAAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAvAHcAZQBiAGYAbwBuAHQALQBzAG8AZgB0AHcAYQByAGUAAAAAAwAAAAMAAAAcAAEAAAAAAuYAAwABAAAAHAAEAsoAAABYAEAABQAYAF0AXwB9AKMApQCrAK4AsAC3ALsAxQDPANYA3QDlAO8A9gD9AQcBGwEjAScBMQE3AUgBUQFbAWUBfgH7Af8CGR6FHvMgFCAaIB4gIiAmIDogrCEi4BL//wAAACAAXwBhAKEApQCpAK4AsAC3ALoAvwDHANEA2ADgAOcA8QD4AP8BCgEeASYBKgE2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AAD/9gAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/9v/2AAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/2AAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9v/2//b/9gAAAAAAAP/TAAD/2P/2/8kAAP/T/93/yf+//9MAAAAAAAAAAP/Y/+z/7AAAAAD/2AAA/9gAAAAAAAAAAAAAAAAAAAAAAAD/4v/sAAAAAAAAAAAAAAAA/9gAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9v/2AAD/9gAAAAAAAP+w/+wAAAAAAAAAAAAAAAAAAAAA//b/5wAAAAAAAAAAAAAAAP/xAAD/nP/2/5wAAAAA//YAAP/xAAAAAAAAAAAAAAAAAAAAAAAUAAD/9gAAAAAAAAAAAAAAAP/2AAD/8f/xAAAAAAAAAAAAAAAA/+wAAP/s//H/9v/iAAAACgAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAD/+wAAAAD/+wAAAAAAAP/nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/84AAP/2//b/8f/i/+IAAP/YAAD/9v/2AAAAAAAAAAAAAP/iAAAAAP/nAAD/zv/s/+f/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/5wAA/+z/xP/OAAD/zgAAAAAAAAAA/9gAAAAA/5z/7P+N/5wAAP9+AAAAAP/2/7AAAP+IAAAAAP/2AAAAAP/7AAD/2P/s//sAAAAAAAAAAAAAAAAAAP/EAAD/2P/Y/6YAAAAAAAD/7AAAAAD/xP/OAAD/xAAAAAAAAP/YAAD/4v/7/8kAAP/Y/93/zv/E/9gAAAAAAAAAAP/Y/+z/7AAAAAD/2AAA/9gAAAAAAAAAAAAAAAAAAAAAAAD/4v/sAAAAAAAAAAAAAAAA/9gAAAAAAAAAAAAA//sAAAAAAAAAAP+6AAAAAAAAAAAAAAAA//sAAP/2//H/9gAAAAAAAAAAAAAAAP/7AAD/nAAA/5wAAAAPAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAADwAAAAUAAAAKAAAACgAAAAAAAAAAAAAAAAAA/8kAAAAA/90AAP+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+wAA//YAAP/s//EAAP/nAAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/7AAAAAAAK//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAP/2//EAAP/i/+f/5//i//YAAAAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAD/+wAAAAD/8f/2//H/8f/7AAAAAP+m/8n/kv/xAAAAAAAAAAAAAAAA/+z/ef+6AAD/7AAAAAAAAP95/87/nP+D/5z/pv/O/4P/pv+6/9j/2P+cAAAAAAAAAAAAAAAAAAD/jQAA/6b/zgAA/5z/nP+c/5z/nP+SAAAAAP/nAAD/7AAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAA//sAAAAAAAAAAP+c/9gAAP/nAAAAAAAA//YAAP/s//b/ugAAAAD/9gAAAAAAAP+6/+z/iP+//4j/2P/n/7//xP/Y/+wAAP/YAAAAAAAAAAAAAAAAAAD/xAAAAAD/7AAA/9gAAP/dAAD/2P/JAAAAAP+m/93/l//sAAAAAP/2//b/8f/s//b/uv/TAAD/9gAAAAAAAP+///H/nP/E/5z/3f/i/8T/zv/d//H/8f/dAAAAAAAAAAAAAAAAAAD/xAAA/5z/5wAA/93/3f/d/9j/3f/JAAAAAAAA/84AAP/iAAD/9gAA//EAAP/sAAD/9gAAAAD/9gAAAAAAAP/TAAAAAP/YAAD/zv/s/9j/zv/s//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7AAA/+wAAP/YAAD/2AAAAAAAAP+S/8T/fv/dAAAAAP/s/+z/7AAA//b/nP+6AAD/9gAAAAAAAP+S/9j/fv+X/37/sP/Y/5f/nP+1/+z/7P+1AAAAAAAAAAAAAAAAAAD/nAAA/5L/4gAA/7X/xP/J/7r/xP+wAAAAAAAA/9gAAP/2AAAAAAAAAAAAAAAA//YAAP/xAAAAAAAAAAAAAP/nAAAAAP/sAAD/4v/2/+z/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7P/xAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP+1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/dAAAAAAAAAAAAAAAAAAD/+wAAAAD/7P/sAAD/7AAAAAAAAAAAAAAAAP/2/6YAAAAA/84AAP+6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+cAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAP/sAAAAAP/xAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP+6//H/7AAAAAD/9gAA//YAAAAAAAAAAP/7AAAAAAAAAAD/4v/dAAD/9gAAAAAAAAAAAAAAAAAAAAD/5//s/+L/5//xAAAAAAAA/9gAAAAA/6b/8QAA/5wAAP+SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAP/EAAD/xAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAP/xAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAP/2AAD/9v/2AAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAP/sAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAP/sAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/YAAAAAP/xAAAAAP/2AAAAAAAA//b/9gAKAAAAAAAAAAD/8f/xAAAACgAPAAAAAAAAAAAAAAAAAAD/+//7//b/+wAAAAAAAAAAAAAAAAAA/84AAP/s//EAAP/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9gAAAAA/5z/8f+I/5wAAP9+AAAAAAAAAAAAAAAAAAAAAP/sAAAAAP/2AAAAAP/x//YAAAAAAAAADwAA/84AAAAAAAAAAP/YAAAAAP/sAAD/5wAAAAD/q/+6AAD/0wAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP+w//b/7AAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAD/4v/YAAAAAAAAAAAAAAAAAAAAAAAAAAD/5//n/+L/5//xAAAAAAAA/9gAAAAA/5z/8f+I/5wAAP9+AAAAAAAAAAAAAAAAAAAAAP/sAAAAAP/2AAAAAP/x//YAAAAAAAAAAAAA/84AAAAAAAAAAP/YAAAAAP/sAAD/5wAAAAD/q/+6AAD/xAAA/+wAAP/YAAAAAAAA/6YAAP/Y/93/zv+w/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAP/YAAAAAP/2AAD/8f/2/+L/8f/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAB4AAAAeAB4AFP/2AAD/0//2/9MAAAAA//b/8QAAAAAAAAAAAAAAHgAjAAAAHgAjADcAAAAA/9MAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/7oAAP/Y/93/7P+1AAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/7AAAAAAAA//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8f/2//H/8QAAAAAAAP/sAAAAAP/2/6YAAP/E/87/zv+c//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/9gAAAAD/4v/s/9P/4v/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP+1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAD/7P/xAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAP/YAAAAAP/nAAAAAP/nAAD/7AAA/+f/7P/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAA//b/7P/sAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP+w//H/7AAAAAD/7AAA/+wAAAAAAAAAAP/2AAAAAAAAAAD/4v/OAAD/7AAAAAAAAAAAAAAAAAAAAAD/4v/n/93/4v/sAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAP/iAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAA/8T/8QAA/84AAP+6AAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAP/dAAD/3QAAAAAAAP+mAAD/sAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAP/xAAAAAP/xAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAA/90AAAAAAAD/9gAAAAAADwAAAAAAAAAAAAAAAP/2AAAAAP+c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AAsAAgANABEAAwAYABgACAAaABwACQAiACgADAArAC0AEwAwAD0AFgBAAEIAJABEAEcAJwBKAEoAKwBMAE8ALABRAFoAMABjAGMAOgBoAHEAOwBzAHUARQABAAgAAQAAAAEAAQABAAAAAQAAAAoAMAA+AAJERkxUAA5sYXRuABoABAAAAAD//wABAAAABAAAAAD//wABAAAAAXNzMDEACAAAAAEAAAACAAYADgAGAAAAAQAQAAEAAAABACgAAQAIAAEADgABAAEAeAABAAQAAQB4AAEAAAABAAAAAQABAAb/iQABAAEAeAABAAH//wAKAfQAAAEsAAAA/ABdAZoARQK8AC0CeAA9AzgANwK4ADEA5gBFAa4ARwGuADwBrgBMAmwAQADmADYBmABCAOYAUgH0//oCxgBBAU8AHgJOACwCYgA3ApgALwJdADwCggBAAksAQAJ2ADcCggBCAPAAVwDwADsCbAA8AmwATwJsAFkCFgAlA9QANQMWADgC0gBoAuIASQMOAGgCngBoApAAaAMQAEkC+ABoARIAbwIlACoCywBoAmsAaANkAGgDFgBoA1IASQKcAGgDUgBJAtMAaAKAAEECiAAyAvgAXQLuADgETgA8AtIASQLMADYCsABHAa4AYgH0AAkBrgA3Alj/6AI+ADMClABdAjsAOgKUADwCSAA6AWoALQKUADwCZQBdAPkAXgD5//sCMABdAPkAZAO3AF0CZQBdAoAAOgKUAF0ClAA8AZAAXQHxADMBkAAqAmUAUwJGADUDXQA6AjoAQwJMADQCKgA9AeAANwEeAHkB4AA1APwAXQJFAD4ChABCAq4ANQM+ADUBhgA6AgMANwGgACIBwgBKAOYAUgGGAC8CAwBDAhYANAIQAEIDggBCAOYATQDmADsA5gA2AZoATQGaADsBmgA2AdYAbwKoAFIBNwA3ATcAQwLQADcCsgAWArYAMg==); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/78E7259F6E64A8FDC.eot b/docs/static/fonts/332720/78E7259F6E64A8FDC.eot deleted file mode 100644 index ba441e1d8c..0000000000 Binary files a/docs/static/fonts/332720/78E7259F6E64A8FDC.eot and /dev/null differ diff --git a/docs/static/fonts/332720/7A39E6B5C7FDD35E3.css b/docs/static/fonts/332720/7A39E6B5C7FDD35E3.css deleted file mode 100644 index e23ea0ab49..0000000000 --- a/docs/static/fonts/332720/7A39E6B5C7FDD35E3.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face { font-family:"Gotham Rounded A"; src: url('http://nuclide.io/static/fonts/332720/B3C56516C7577235B.eot'); src: url('http://nuclide.io/static/fonts/332720/B3C56516C7577235B.eot?#hfj') format('embedded-opentype'); font-style:normal; font-weight:300; } @font-face { font-family:"Gotham Rounded 3r"; src: url('http://nuclide.io/static/fonts/332720/B3C56516C7577235B.eot'); src: url('http://nuclide.io/static/fonts/332720/B3C56516C7577235B.eot?#hfj') format('embedded-opentype'); font-style:normal; font-weight:300; } \ No newline at end of file diff --git a/docs/static/fonts/332720/7C6BEE7159DD678EF.css b/docs/static/fonts/332720/7C6BEE7159DD678EF.css deleted file mode 100644 index f2de0ea247..0000000000 --- a/docs/static/fonts/332720/7C6BEE7159DD678EF.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/888DDF1B4B9C1A5D5.css b/docs/static/fonts/332720/888DDF1B4B9C1A5D5.css deleted file mode 100644 index 93e7cb801c..0000000000 --- a/docs/static/fonts/332720/888DDF1B4B9C1A5D5.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,MgA/Al0APwA9ACoCOgBdA1MAZQIzAD8BXQA/AToAPwI8AD8CSQA/AmgAFgNvABIBaAA/AmgAPwI1AD8DQgA/AjcAdgJAAD8CPABdAjcAYgIsAE4CHgBPAUEAPwI9AHgCXQA/AAAALAEAAD8BCgA/PwEAAQAAAAIAAAAEAAEAGgABAAEAAgAAAAAAGAAAAA4AAAABAAALHz8/P35/Pz9/fz8/Pz8/Pz8LHz8/P38/Pz8/Pz8/Pz8/Pz8LHj8/Pz8GfR8/Pz8/Cx8/Pz8/CD8/Pz8/PwY/CD8/Pz8/Px8/Pz9/fz8/Pwg/fT8/Pz9YRjQnAQEEABM/FT8/FBY/Dh8/Pz8/Pz8/Pz8/Pz8/Pz8/FT9YPwc/Yj8/bj8/P3V7Pz8Gbj8/Pz8/Pz8/eT8/Pz8/FWhzPwohFT8/CiAVPz8/CH54P30/Pz90Pz8/P3w/fD97PxU/PwU/CD8/Pz8/Pz8/Pz8/Px4/Pz8/Pz8/PxU/Fz8HfT8fPz8/Pz8/Pz8ePz8/Pz8/Pz8VPxs/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/Px8/Pz8/FXBoBj8/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwU/Pwg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8ePz8/Pz8/Pz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Bz8/FVt3Pwc/cj8/ej8IPz8/Pz8/Hj8/Pz8HPz8/Pz8/eR4/Pz8/Pz8/PwY/Pz8/FXw/ZT8IPz8/Pz8/P3I/ej93P3Z/f3o/BT8/CD8/Pz8/Pz8/Pz9pPz8/Pz8/Pz9jP1Y/YT9sbnlWdT95P24/HmBhYUhNP2o/CD8/Pz8/Pz9wP3c/P3N7fXg/ch9vP3U/Pz8/Pwg/Pz8/fD8VSj8iPwc/fj8/Px8/Pz8/CD8/Pz8/PwU/Pwg/Pz8/Pz8ePz8/Pwd3Pz8/PxUqPwg/P3Q/bD98P30/Pz8/eT9vP28/Pz8/Pz8VFz9iBj8IPz8/Pz8/Pz8/Pz8/Pz8/P3s/Pz8/Pz8/Pz8/Pz8/BT8/Bj8/Pwg/Pz8/Pz8/Pz8/Pz8/Pz9zPz8/Pz8/Pz8/Pz8/Pz8FPz8/PxU/Px56fz97ej9/Pwg/Pz8/Pz91P30/dD8VPz8tPwg/Pz8/Pz8/Pz8/Pz8/P3Q/Pz8FPz8/Pz9yPz8/Pz8/dz8/Pz8/P3o/Pz8/Pz8IPz8/Pz8/Hz8/Pz8/Pz8/FVk/Bz8/eT8IPz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwU/Pz8/FT97Bz9yPz95Pwg/Pz8/Pz8ePz8/Pz8/Pz8/Pz8/Bz8IPz8/Pz8/Bj8/Pz8VPwc/cj8/Pz8ffj8/Pwg/Pz8/Pz8FPz8GPz8/Pz8/cj8/Pz8/FTsrHz8/Pz8/Pz8/Pz8/Pz8/Pz8VPxI/Hz8/P3p5f359CD8/Pz8/PwU/PwY/Pz8Ifz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwY/CD8/Pz8/PxVRPyY/Bj8/Pz8VQT9VPwojFT8GP2I/P1g/Pwg/Pz8/Pz8GPz8/CD8/Pz8/PwY/Pz8IPz8/Pz8/Bj8/Pz8/FT85PwojBD8KIhU/PwojBD8KIhVBPwoiFT9QCiEVPz8KIBU/Pw4ePz8/Pz99P3gHcB54fX14eD99Pwc/FQI/Px8/Pz8/Bj8ePz8/fQV3P3sePz8/Pz8/Pz8VPz8hPz8OHj8/Pz8HPwg/Pz8/Pz8FPD8/Pz8fPz8/f38/P38GEz8efz8/Pwc/CD8/Pz8/PwU8Pz8/H38/Pz8/Pz8/BiE/Fj9aDgg/Pz8/fT8FXz87Pwg/Pz8/Pz9+Pz9/P30/fT8/Pz8FQz8oP0U/KD8IPz8/Pz9+Bj8IP30/Pz8/BUU/KD9FPyk/CD8/Pz8/fT99Pz8/Pz8/Pz8/PwVfPzs/CD8/Pz8/PwY/CD8/Pz98PwU1PyU/NT8mPwg/Pz8/Pz8GPxU/Pz8/Pw4ePz8/Pz8/P3wHQQg/Pz8/HhU/Mz8OPwc/Px58Pz99fT8/Pwc/Px4/P1AkJz8+IQc/Px58Pz99fT8/PxV9Pz8/Pw4IP3A/ZD8/Pz8/Pz9+Pz8/P34/Pz8/Pz8/Vj9TP04eRmVVUAc/CE8/dT93P3M/cj8wPwc/HzlQRigIP1Q/Tj9aPz8/Pz8/Pz8/Pz8/Pz8/Pz8/cT97Pz8/Hj8/Pz8HPwg/Pz9GP0I/OT81Pz8HPx8/Pz8/FT8/PyEOHn0/P319Pz8/BxA/CChfVTI/Qz98Pz8/Pz8/Pz8/Pz8APz84Pz8HUD8ePz8/Pz8/P3wVP18/Dh4NPyg0DD8HPx4PPyk/Cj8NPz8MPwc/Hw8/Lwo/FT8/His/Dj8CPyM/Bz8eIz8QPwM/LD8rPw4/Aj8jPwc/HyM/ED8DPyw/FX8/Pz8OHgM/Px0/Bz8eGj8uICEyJRY/Bz8fFz8zPz8VWj8/Px4/Pz8/Pz8/fAcuCD8/Pz8eDz8oET86Pwc/Hzo/JhE/Dz8IPyU/ST9hBz8/Hnw/P319Pz8/FVk/Pw4IPz8/Pz8/BT8/Pz8/Pz8IPz8/Pz8/fz9/fz9+Pz8/Pz8/BT8/fD8/P3k/CD8/Pz8/Pz9+Pz8/Pz8/Pz8/PwU/Pz8/Pz8/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwU/Pz8/Pz8/CD8/Pz8/Px4/Pz9+FT8LPw4ffX9/fQY/CD8/Pz8/PwU/P2w/Pz8efT8/fX0/Pz8HKD8fPz8/PwY/CD8/Pz8/PwU/P3U/Pz8ePz8/Pz8/P30VP08/Dh59f399fT9/PwckPx4/Pz8/P38/fRU/Az8/Dh59f399fT9/Pwc/P1Q/Px59f399fT9/PwckPx4/Pz8/P38/fQc/P1Q/Px4/Pz8/P38/fRU/MT8OHj9/P30HHD8ffX9/fQZYPx9+Pz8/Pz8/PwY+Pz8/ET8ffj8/Pz8/Pz8GET8/P0M/H34/Pz8/Pz8/Bl0/FhY/Dh8tLDUpPE8/Pz8/PwQ/P1Q9FT8/Vh8/P1k/Uj8/Pz8/Wz9VPz8/Pz9NP1M/Zz8/Pz8/CD9nP1I/Pz8/Pz8fP0M/ISM/IQ0/BD8IPzo/Xj90BVA/CHw/Pz8/fj97Pz8/PwVWPz8IPz8/Pz8/Hz8/alJFTUElP0s/ST9AP3o/ez9LP0E/cz90P0g/Pz8/Pwg/KXVEYUE/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8VNj8/Pw0/Dh4LPzE/Mwc/Hig8Pwg/Bz8/Pwc/Hz8/PAM/FT8/Pwg/aT9gPwg/Pz8/Pz99P38/P30/Pz8/Pz8/VT9WP08/IT8rPyhmPz8/Pz8CPx4hPy0/DD8HPx8VPyEnJj8IP0A/Tj9hP1U/aSA/Pwc/H3A/Mj8OPzc/FX8/Pw4eFT9GPjwHPx40TD8GPwY/Pz8HPx8/Pz4VPwQ/Px4oUTg1Bz8ePFI/Pz8/Pz8HPx8/PzgoBBs/Hic/OgU/CD8HPwg5P01IbjNvP1c/OD8HPx4BP0EHPw0/DT8HPwE/Bz8IPz8/Pz8zP0g/Pwc/Hwg/BT8nPxU/Pz8OHgU/OUEoBz8eK0M/Az8HPz8/Bz8fPz82BT8VPz8IP28/YT9RP0U/JT8/Bz8fZz88PwM/Qj8IP0E/Uj9TCD8/Pz8/Pz8/Pz8/Pz8/Pz8/P2I/dT8/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GAEWARQBEgEPAT8APwA/AD8APwB6AHcAdQBzAG8AZABYAE4ASQBFAEAAOQA2ADMAJAAhADgABQBAAHgAAAAYAgQAHAAAAAEAAwA0AgAAAAABABwAAAADAAAAAwAAAABlAHIAYQB3AHQAZgBvAHMALQB0AG4AbwBmAGIAZQB3AC8AbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcALwAvADoAcAB0AHQAaABtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQALgB3AHcAdwA5ADEAMgAwADQAMQAtADMAMgA0ADIALQAzADIANgAwADUAMQAwADIALQA0ADcANAA4ADgALQA3ADQAMgAxADcAMQAgAG0AbwBjAC4AeQBoAHAAYQByAGcAbwBwAHkAdAAuAHcAdwB3ACAAdABhACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAHQAYwBhAHQAbgBvAGMAIAByAG8AIAAsAGUAcgBhAHcAdABmAG8AcwAtAHQAbgBvAGYAYgBlAHcALwBtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQALgB3AHcAdwAvAC8AOgBwAHQAdABoACAAdABpAHMAaQB2ACAAZQBzAGEAZQBsAHAAIAAsAG4AbwBpAHQAYQBtAHIAbwBmAG4AaQAgAGUAcgBvAG0AIAByAG8ARgAgAC4AZQBzAG8AcAByAHUAcAAgAHkAbgBhACAAcgBvAGYAIABlAHIAYQB3AHQAZgBvAHMAIABzAGkAaAB0ACAAZQBzAHUAIAB0AG8AbgAgAHkAYQBtACAAdQBvAHkAIAAsAHMAdABzAGkAeABlACAAdABuAGUAbQBlAGUAcgBnAGEAIABoAGMAdQBzACAAbwBuACAAZgBJACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGQAbgBhACAAdQBvAHkAIABuAGUAZQB3AHQAZQBiACAAcwB0AHMAaQB4AGUAIAB0AGEAaAB0ACAAdABuAGUAbQBlAGUAcgBnAGEAIABlAGMAaQB2AHIAZQBTACAAZgBvACAAcwBtAHIAZQBUACAAZQBoAHQAIABvAHQAIAB0AGMAZQBqAGIAdQBzACAAcwBpACAAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAdAAgAGUAcwB1ACAAbwB0ACAAdABoAGcAaQByACAAcgB1AG8AWQAgAC4AbgBvAGkAdABhAGMAbwBsACAAeQBuAGEAIABtAG8AcgBmACAAdABpACAAdABzAG8AaAAgAHIAbwAgACwAcgBlAHQAdQBwAG0AbwBjACAAeQBuAGEAIABuAG8AcAB1ACAAdABpACAAbABsAGEAdABzAG4AaQAgAHIAbwAgACwAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAdAAgAGQAYQBvAGwAbgB3AG8AZAAgAHIAbwAgACwAZQB0AHUAYgBpAHIAdABzAGkAZAAgACwAeQBmAGkAZABvAG0AIAAsAHkAcABvAGMAIAB0AG8AbgAgAHkAYQBtACAAdQBvAFkAIAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIACAAZgBvACAAeQB0AHIAZQBwAG8AcgBwACAAZQBoAHQAIABzAGkAIABlAHIAYQB3AHQAZgBvAHMAIABzAGkAaABUAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgALgBzAG4AbwBpAHQAYwBpAGQAcwBpAHIAdQBqACAAbgBpAGEAdAByAGUAYwAgAG4AaQAgAGQAZQByAGUAdABzAGkAZwBlAHIAIABlAGIAIAB5AGEAbQAgAGgAYwBpAGgAdwAgACwALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGYAbwAgAGsAcgBhAG0AZQBkAGEAcgB0ACAAYQAgAHMAaQAgAGQAZQBkAG4AdQBvAFIAIABtAGEAaAB0AG8ARwB0AG4AbwBGADEAMAAyAC4AMQAgAG4AbwBpAHMAcgBlAFYAOQAxADIAMAA0ADEALQAzADIANAAyAC0AMwAyADYAMAA1ADEAMAAyAC0ANAA3ADQAOAA4AC0ANwA0ADIAMQA3ADEAcgBhAGwAdQBnAGUAUgBtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQAIAB8ACAAbwBDACYASAAgACkAQwAoACAAdABoAGcAaQByAHkAcABvAEMAbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcALwAvADoAcAB0AHQAaAAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIAA3ADAAMAAyACAALAA2ADAAMAAyACAAKQBDACgAIAB0AGgAZwBpAHIAeQBwAG8AQwBlcmF3dGZvcy10bm9mYmV3L21vYy55aHBhcmdvcHl0Lnd3dy8vOnB0dGhtb2MueWhwYXJnb3B5dC53d3c5MTIwNDEtMzI0Mi0zMjYwNTEwMi00NzQ4OC03NDIxNzEgbW9jLnlocGFyZ29weXQud3d3IHRhIC5vQyAmIHJlbGZlb0ggdGNhdG5vYyBybyAsZXJhd3Rmb3MtdG5vZmJldy9tb2MueWhwYXJnb3B5dC53d3cvLzpwdHRoIHRpc2l2IGVzYWVscCAsbm9pdGFtcm9mbmkgZXJvbSByb0YgLmVzb3BydXAgeW5hIHJvZiBlcmF3dGZvcyBzaWh0IGVzdSB0b24geWFtIHVveSAsc3RzaXhlIHRuZW1lZXJnYSBoY3VzIG9uIGZJIC5vQyAmIHJlbGZlb0ggZG5hIHVveSBuZWV3dGViIHN0c2l4ZSB0YWh0IHRuZW1lZXJnYSBlY2l2cmVTIGZvIHNtcmVUIGVodCBvdCB0Y2VqYnVzIHNpIGVyYXd0Zm9zIHNpaHQgZXN1IG90IHRoZ2lyIHJ1b1kgLm5vaXRhY29sIHluYSBtb3JmIHRpIHRzb2ggcm8gLHJldHVwbW9jIHluYSBub3B1IHRpIGxsYXRzbmkgcm8gLGVyYXd0Zm9zIHNpaHQgZGFvbG53b2Qgcm8gLGV0dWJpcnRzaWQgLHlmaWRvbSAseXBvYyB0b24geWFtIHVvWSAub0MgJiByZWxmZW9IIGZvIHl0cmVwb3JwIGVodCBzaSBlcmF3dGZvcyBzaWhULm9DICYgcmVsZmVvSC5zbm9pdGNpZHNpcnVqIG5pYXRyZWMgbmkgZGVyZXRzaWdlciBlYiB5YW0gaGNpaHcgLC5vQyAmIHJlbGZlb0ggZm8ga3JhbWVkYXJ0IGEgc2kgZGVkbnVvUiBtYWh0b0d0bm9GMTAyLjEgbm9pc3JlVjkxMjA0MS0zMjQyLTMyNjA1MTAyLTQ3NDg4LTc0MjE3MXJhbHVnZVJtb2MueWhwYXJnb3B5dCB8IG9DJkggKUMoIHRoZ2lyeXBvQ21vYy55aHBhcmdvcHl0Lnd3dy8vOnB0dGggLm9DICYgcmVsZmVvSCA3MDAyICw2MDAyIClDKCB0aGdpcnlwb0M/A0YAEgAJBAEAAwA/A0YAEQAJBAEAAwA/A0YAEAAJBAEAAwA/CVQADgAJBAEAAwBrBSIEDQAJBAEAAwA/CSQADAAJBAEAAwA/CSQACwAJBAEAAwBrBSIECgAJBAEAAwBRBRoACQAJBAEAAwBRBRoACAAJBAEAAwA/BD8ABwAJBAEAAwA/BAgABgAJBAEAAwBtBBoABQAJBAEAAwA/A0YABAAJBAEAAwArBEIAAwAJBAEAAwAdBA4AAgAJBAEAAwA/A0YAAQAJBAEAAwBXAz8AAAAJBAEAAwBAACMAEgAAAAAAAQBAACMAEQAAAAAAAQBAACMAEAAAAAAAAQAtAyoADgAAAAAAAQAKARECDQAAAAAAAQAbAxIADAAAAAAAAQAbAxIACwAAAAAAAQAKARECCgAAAAAAAQA/AA0ACQAAAAAAAQA/AA0ACAAAAAAAAQA/AGEABwAAAAAAAQA/AAQABgAAAAAAAQA/AA0ABQAAAAAAAQBAACMABAAAAAAAAQBqACEAAwAAAAAAAQBjAAcAAgAAAAAAAQBAACMAAQAAAAAAAQAAAEAAAAAAAAAAAQA/ASQAAAABACAAIAA/Aj8BAAAAAAsAAAA/AD8DPwA4PyADEj8kAAAAb0MmSAAAAAAAAAAASgAAUH8AAD8AAAAAAAAAAAAAAAA/ADIAPwEAAD8CPwI/AAAAPwI/AgQABQAsAU0CAgAAABsAAFAAABsAAAAAAAAAAAAAAAAAAAABAD8DAAAAAD8DAAAQPz8DAAABAAAAAAAAAAIACAAAACADPwM4PwAAHwIsPwAAAAAfAiw/AAAAAD8DCwA/PA9fPz8/LkEAAQAAAAEAIAAAAHgQAAAyAD8/dHNvcD8LAAA/AQAABDM1KGVtYW4GAAAAGAEAAABQGwBweGFtbAAAADAfAAA/Bj89eHRtaCQAAAA/AAAAAANhB2FlaGg2AAAAPwAAAD9HFgNkYWVoCAAAACgfAAALAAAAcHNhZzoDAAA8DQAAAj8/cGFtY2AAAAAgAQAASyU/VTIvU08gAAAACB8AAAQASABGRURHbw4AAD8QAABjPz9PIEZGQzAAAwA/AAsAT1RUTw==))); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:font/opentype;base64,T1RUTwALAIAAAwAwQ0ZGIE+2i2MAABCYAAAOb0dERUYASAAEAAAfCAAAACBPUy8yVcclSwAAASAAAABgY21hcO62ywIAAA08AAADOmdhc3AAAAALAAAfKAAAAAhoZWFkAxZHvAAAALwAAAA2aGhlYQdhAwAAAAD0AAAAJGhtdHg9xwbVAAAfMAAAAGxtYXhwABtQAAAAARgAAAAGbmFtZSg1MwQAAAGAAAALu3Bvc3T/uAAyAAAQeAAAACAAAQAAAAEAQS6s5cVfDzz1AAsD6AAAAADQLAIfAAAAANAsAh8AAP84A58DIAAAAAgAAgAAAAAAAAABAAADwP8QAAAD1AAAAAADnwABAAAAAAAAAAAAAAAAAAAAGwAAUAAAGwAAAAICTQEsAAUABAK8AooAAACMArwCigAAAd0AMgD6AAAAAAAAAAAAAAAAoAAAf1AAAEoAAAAAAAAAAEgmQ28AAAAk4BIDIP84AMgDwADwAAAACwAAAAAB/gK8ACAAIAABAAAAJAG2AAEAAAAAAAAAQAAAAAEAAAAAAAEAIwBAAAEAAAAAAAIABwBjAAEAAAAAAAMAIQBqAAEAAAAAAAQAIwBAAAEAAAAAAAUADQCLAAEAAAAAAAYABACYAAEAAAAAAAcAYQCcAAEAAAAAAAgADQD9AAEAAAAAAAkADQD9AAEAAAAAAAoCEQEKAAEAAAAAAAsAEgMbAAEAAAAAAAwAEgMbAAEAAAAAAA0CEQEKAAEAAAAAAA4AKgMtAAEAAAAAABAAIwBAAAEAAAAAABEAIwBAAAEAAAAAABIAIwBAAAMAAQQJAAAAgANXAAMAAQQJAAEARgPXAAMAAQQJAAIADgQdAAMAAQQJAAMAQgQrAAMAAQQJAAQARgPXAAMAAQQJAAUAGgRtAAMAAQQJAAYACASHAAMAAQQJAAcAwgSPAAMAAQQJAAgAGgVRAAMAAQQJAAkAGgVRAAMAAQQJAAoEIgVrAAMAAQQJAAsAJAmNAAMAAQQJAAwAJAmNAAMAAQQJAA0EIgVrAAMAAQQJAA4AVAmxAAMAAQQJABAARgPXAAMAAQQJABEARgPXAAMAAQQJABIARgPXQ29weXJpZ2h0IChDKSAyMDA2LCAyMDA3IEhvZWZsZXIgJiBDby4gaHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbUNvcHlyaWdodCAoQykgSCZDbyB8IHR5cG9ncmFwaHkuY29tUmVndWxhcjE3MTI0Ny04ODQ3NC0yMDE1MDYyMy0yNDIzLTE0MDIxOVZlcnNpb24gMS4yMDFGb250R290aGFtIFJvdW5kZWQgaXMgYSB0cmFkZW1hcmsgb2YgSG9lZmxlciAmIENvLiwgd2hpY2ggbWF5IGJlIHJlZ2lzdGVyZWQgaW4gY2VydGFpbiBqdXJpc2RpY3Rpb25zLkhvZWZsZXIgJiBDby5UaGlzIHNvZnR3YXJlIGlzIHRoZSBwcm9wZXJ0eSBvZiBIb2VmbGVyICYgQ28uIFlvdSBtYXkgbm90IGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgb3IgZG93bmxvYWQgdGhpcyBzb2Z0d2FyZSwgb3IgaW5zdGFsbCBpdCB1cG9uIGFueSBjb21wdXRlciwgb3IgaG9zdCBpdCBmcm9tIGFueSBsb2NhdGlvbi4gWW91ciByaWdodCB0byB1c2UgdGhpcyBzb2Z0d2FyZSBpcyBzdWJqZWN0IHRvIHRoZSBUZXJtcyBvZiBTZXJ2aWNlIGFncmVlbWVudCB0aGF0IGV4aXN0cyBiZXR3ZWVuIHlvdSBhbmQgSG9lZmxlciAmIENvLiBJZiBubyBzdWNoIGFncmVlbWVudCBleGlzdHMsIHlvdSBtYXkgbm90IHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSB2aXNpdCBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUsIG9yIGNvbnRhY3QgSG9lZmxlciAmIENvLiBhdCB3d3cudHlwb2dyYXBoeS5jb20gMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5d3d3LnR5cG9ncmFwaHkuY29taHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbS93ZWJmb250LXNvZnR3YXJlAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMAA2ACwAIAAyADAAMAA3ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgAEgAJgBDAG8AIAB8ACAAdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAFIAZQBnAHUAbABhAHIAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAVgBlAHIAcwBpAG8AbgAgADEALgAyADAAMQBGAG8AbgB0AEcAbwB0AGgAYQBtACAAUgBvAHUAbgBkAGUAZAAgAGkAcwAgAGEAIAB0AHIAYQBkAGUAbQBhAHIAawAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4ALAAgAHcAaABpAGMAaAAgAG0AYQB5ACAAYgBlACAAcgBlAGcAaQBzAHQAZQByAGUAZAAgAGkAbgAgAGMAZQByAHQAYQBpAG4AIABqAHUAcgBpAHMAZABpAGMAdABpAG8AbgBzAC4ASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgBUAGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAaQBzACAAdABoAGUAIABwAHIAbwBwAGUAcgB0AHkAIABvAGYAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAWQBvAHUAIABtAGEAeQAgAG4AbwB0ACAAYwBvAHAAeQAsACAAbQBvAGQAaQBmAHkALAAgAGQAaQBzAHQAcgBpAGIAdQB0AGUALAAgAG8AcgAgAGQAbwB3AG4AbABvAGEAZAAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUALAAgAG8AcgAgAGkAbgBzAHQAYQBsAGwAIABpAHQAIAB1AHAAbwBuACAAYQBuAHkAIABjAG8AbQBwAHUAdABlAHIALAAgAG8AcgAgAGgAbwBzAHQAIABpAHQAIABmAHIAbwBtACAAYQBuAHkAIABsAG8AYwBhAHQAaQBvAG4ALgAgAFkAbwB1AHIAIAByAGkAZwBoAHQAIAB0AG8AIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIABzAHUAYgBqAGUAYwB0ACAAdABvACAAdABoAGUAIABUAGUAcgBtAHMAIABvAGYAIABTAGUAcgB2AGkAYwBlACAAYQBnAHIA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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/8E2ED03EAA5ED8BE2.css b/docs/static/fonts/332720/8E2ED03EAA5ED8BE2.css deleted file mode 100644 index 4aeacc5add..0000000000 --- a/docs/static/fonts/332720/8E2ED03EAA5ED8BE2.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,T1RUTwANAIAAAwBQQ0ZGIKWnUnEAABFoAAAs60dERUYApgAEAAA+VAAAACBHUE9T5Gif/gAAPnQAAB1aR1NVQunbLV4AAFvQAAAAgE9TLzJVxSTvAAABQAAAAGBjbWFwaLtaTgAADVwAAAPsZ2FzcAAAAAsAAFxQAAAACGhlYWQDcke8AAAA3AAAADZoaGVhB74DwAAAARQAAAAkaG10eAmBHxsAAFxYAAAB5G1heHAAeVAAAAABOAAAAAZuYW1lKDUzBAAAAaAAAAu7cG9zdP+4ADIAABFIAAAAIAABAAAAAQBByTlTkF8PPPUACwPoAAAAANAsAh4AAAAA0CwCHv/o/zgEEwMiAAAACAACAAAAAAAAAAEAAAPA/xAAAARO/+j/6AQTAAEAAAAAAAAAAAAAAAAAAAB5AABQAAB5AAAAAgHwASwABQAEArwCigAAAIwCvAKKAAAB3QAyAPoAAAAAAAAAAAAAAACgAAB/UAAASgAAAAAAAAAASCZDbwAAACLgEgMg/zgAyAPAAPAAAAALAAAAAAH+ArwAIAAgAAIAAAAkAbYAAQAAAAAAAABAAAAAAQAAAAAAAQAjAEAAAQAAAAAAAgAHAGMAAQAAAAAAAwAhAGoAAQAAAAAABAAjAEAAAQAAAAAABQANAIsAAQAAAAAABgAEAJgAAQAAAAAABwBhAJwAAQAAAAAACAANAP0AAQAAAAAACQANAP0AAQAAAAAACgIRAQoAAQAAAAAACwASAxsAAQAAAAAADAASAxsAAQAAAAAADQIRAQoAAQAAAAAADgAqAy0AAQAAAAAAEAAjAEAAAQAAAAAAEQAjAEAAAQAAAAAAEgAjAEAAAwABBAkAAACAA1cAAwABBAkAAQBGA9cAAwABBAkAAgAOBB0AAwABBAkAAwBCBCsAAwABBAkABABGA9cAAwABBAkABQAaBG0AAwABBAkABgAIBIcAAwABBAkABwDCBI8AAwABBAkACAAaBVEAAwABBAkACQAaBVEAAwABBAkACgQiBWsAAwABBAkACwAkCY0AAwABBAkADAAkCY0AAwABBAkADQQiBWsAAwABBAkADgBUCbEAAwABBAkAEABGA9cAAwABBAkAEQBGA9cAAwABBAkAEgBGA9dDb3B5cmlnaHQgKEMpIDIwMDYsIDIwMDcgSG9lZmxlciAmIENvLiBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tQ29weXJpZ2h0IChDKSBIJkNvIHwgdHlwb2dyYXBoeS5jb21SZWd1bGFyMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5VmVyc2lvbiAxLjIwMUZvbnRHb3RoYW0gUm91bmRlZCBpcyBhIHRyYWRlbWFyayBvZiBIb2VmbGVyICYgQ28uLCB3aGljaCBtYXkgYmUgcmVnaXN0ZXJlZCBpbiBjZXJ0YWluIGp1cmlzZGljdGlvbnMuSG9lZmxlciAmIENvLlRoaXMgc29mdHdhcmUgaXMgdGhlIHByb3BlcnR5IG9mIEhvZWZsZXIgJiBDby4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBvciBkb3dubG9hZCB0aGlzIHNvZnR3YXJlLCBvciBpbnN0YWxsIGl0IHVwb24gYW55IGNvbXB1dGVyLCBvciBob3N0IGl0IGZyb20gYW55IGxvY2F0aW9uLiBZb3VyIHJpZ2h0IHRvIHVzZSB0aGlzIHNvZnR3YXJlIGlzIHN1YmplY3QgdG8gdGhlIFRlcm1zIG9mIFNlcnZpY2UgYWdyZWVtZW50IHRoYXQgZXhpc3RzIGJldHdlZW4geW91IGFuZCBIb2VmbGVyICYgQ28uIElmIG5vIHN1Y2ggYWdyZWVtZW50IGV4aXN0cywgeW91IG1heSBub3QgdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpc2l0IGh0dHA6Ly93d3cudHlwb2dyYXBoeS5jb20vd2ViZm9udC1zb2Z0d2FyZSwgb3IgY29udGFjdCBIb2VmbGVyICYgQ28uIGF0IHd3dy50eXBvZ3JhcGh5LmNvbSAxNzEyNDctODg0NzQtMjAxNTA2MjMtMjQyMy0xNDAyMTl3d3cudHlwb2dyYXBoeS5jb21odHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUAQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgADIAMAAwADYALAAgADIAMAAwADcAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAASAAmAEMAbwAgAHwAIAB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AUgBlAGcAdQBsAGEAcgAxADcAMQAyADQANwAtADgAOAA0ADcANAAtADIAMAAxADUAMAA2ADIAMwAtADIANAAyADMALQAxADQAMAAyADEAOQBWAGUAcgBzAGkAbwBuACAAMQAuADIAMAAxAEYAbwBuAHQARwBvAHQAaABhAG0AIABSAG8AdQBuAGQAZQBkACAAaQBzACAAYQAgAHQAcgBhAGQAZQBtAGEAcgBrACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAsACAAdwBoAGkAYwBoACAAbQBhAHkAIABiAGUAIAByAGUAZwBpAHMAdABlAHIAZQBkACAAaQBuACAAYwBlAHIAdABhAGkAbgAgAGoAdQByAGkAcwBkAGkAYwB0AGkAbwBuAHMALgBIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuAFQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIAB0AGgAZQAgAHAAcgBvAHAAZQByAHQAeQAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABZAG8AdQAgAG0AYQB5ACAAbgBvAHQAIABjAG8AcAB5ACwAIABtAG8AZABpAGYAeQAsACAAZABpAHMAdAByAGkAYgB1AHQAZQAsACAAbwByACAAZABvAHcAbgBsAG8AYQBkACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAsACAAbwByACAAaQBuAHMAdABhAGwAbAAgAGkAdAAgAHUAcABvAG4AIABhAG4AeQAgAGMAbwBtAHAAdQB0AGUAcgAsACAAbwByACAAaABvAHMAdAAgAGkAdAAgAGYAcgBvAG0AIABhAG4AeQAgAGwAbwBjAGEAdABpAG8AbgAuACAAWQBvAHUAcgAgAHIAaQBnAGgAdAAgAHQAbwAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHMAdQBiAGoAZQBjAHQAIAB0AG8AIAB0AGgAZQAgAFQAZQByAG0AcwAgAG8AZgAgAFMAZQByAHYAaQBjAGUAIABhAGcAcgBlAGUAbQBlAG4AdAAgAHQAaABhAHQAIABlAHgAaQBzAHQAcwAgAGIAZQB0AHcAZQBlAG4AIAB5AG8AdQAgAGEAbgBkACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAEkAZgAgAG4AbwAgAHMAdQBjAGgAIABhAGcAcgBlAGUAbQBlAG4AdAAgAGUAeABpAHMAdABzACwAIAB5AG8AdQAgAG0AYQB5ACAAbgBvAHQAIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABmAG8AcgAgAGEAbgB5ACAAcAB1AHIAcABvAHMAZQAuACAARgBvAHIAIABtAG8AcgBlACAAaQBuAGYAbwByAG0AYQB0AGkAbwBuACwAIABwAGwAZQBhAHMAZQAgAHYAaQBzAGkAdAAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0ALwB3AGUAYgBmAG8AbgB0AC0AcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABjAG8AbgB0AGEAYwB0ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGEAdAAgAHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtACAAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAvAHcAZQBiAGYAbwBuAHQALQBzAG8AZgB0AHcAYQByAGUAAAAAAwAAAAMAAAAcAAEAAAAAAuYAAwABAAAAHAAEAsoAAABYAEAABQAYAF0AXwB9AKMApQCrAK4AsAC3ALsAxQDPANYA3QDlAO8A9gD9AQcBGwEjAScBMQE3AUgBUQFbAWUBfgH7Af8CGR6FHvMgFCAaIB4gIiAmIDogrCEi4BL//wAAACAAXwBhAKEApQCpAK4AsAC3ALoAvwDHANEA2ADgAOcA8QD4AP8BCgEeASYBKgE2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AAD/9gAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/9v/2AAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/2AAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9v/2//b/9gAAAAAAAP/TAAD/2P/2/8kAAP/T/93/yf+//9MAAAAAAAAAAP/Y/+z/7AAAAAD/2AAA/9gAAAAAAAAAAAAAAAAAAAAAAAD/4v/sAAAAAAAAAAAAAAAA/9gAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9v/2AAD/9gAAAAAAAP+w/+wAAAAAAAAAAAAAAAAAAAAA//b/5wAAAAAAAAAAAAAAAP/xAAD/nP/2/5wAAAAA//YAAP/xAAAAAAAAAAAAAAAAAAAAAAAUAAD/9gAAAAAAAAAAAAAAAP/2AAD/8f/xAAAAAAAAAAAAAAAA/+wAAP/s//H/9v/iAAAACgAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAD/+wAAAAD/+wAAAAAAAP/nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/84AAP/2//b/8f/i/+IAAP/YAAD/9v/2AAAAAAAAAAAAAP/iAAAAAP/nAAD/zv/s/+f/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/5wAA/+z/xP/OAAD/zgAAAAAAAAAA/9gAAAAA/5z/7P+N/5wAAP9+AAAAAP/2/7AAAP+IAAAAAP/2AAAAAP/7AAD/2P/s//sAAAAAAAAAAAAAAAAAAP/EAAD/2P/Y/6YAAAAAAAD/7AAAAAD/xP/OAAD/xAAAAAAAAP/YAAD/4v/7/8kAAP/Y/93/zv/E/9gAAAAAAAAAAP/Y/+z/7AAAAAD/2AAA/9gAAAAAAAAAAAAAAAAAAAAAAAD/4v/sAAAAAAAAAAAAAAAA/9gAAAAAAAAAAAAA//sAAAAAAAAAAP+6AAAAAAAAAAAAAAAA//sAAP/2//H/9gAAAAAAAAAAAAAAAP/7AAD/nAAA/5wAAAAPAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAADwAAAAUAAAAKAAAACgAAAAAAAAAAAAAAAAAA/8kAAAAA/90AAP+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+wAA//YAAP/s//EAAP/nAAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/7AAAAAAAK//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAP/2//EAAP/i/+f/5//i//YAAAAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAD/+wAAAAD/8f/2//H/8f/7AAAAAP+m/8n/kv/xAAAAAAAAAAAAAAAA/+z/ef+6AAD/7AAAAAAAAP95/87/nP+D/5z/pv/O/4P/pv+6/9j/2P+cAAAAAAAAAAAAAAAAAAD/jQAA/6b/zgAA/5z/nP+c/5z/nP+SAAAAAP/nAAD/7AAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAA//sAAAAAAAAAAP+c/9gAAP/nAAAAAAAA//YAAP/s//b/ugAAAAD/9gAAAAAAAP+6/+z/iP+//4j/2P/n/7//xP/Y/+wAAP/YAAAAAAAAAAAAAAAAAAD/xAAAAAD/7AAA/9gAAP/dAAD/2P/JAAAAAP+m/93/l//sAAAAAP/2//b/8f/s//b/uv/TAAD/9gAAAAAAAP+///H/nP/E/5z/3f/i/8T/zv/d//H/8f/dAAAAAAAAAAAAAAAAAAD/xAAA/5z/5wAA/93/3f/d/9j/3f/JAAAAAAAA/84AAP/iAAD/9gAA//EAAP/sAAD/9gAAAAD/9gAAAAAAAP/TAAAAAP/YAAD/zv/s/9j/zv/s//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7AAA/+wAAP/YAAD/2AAAAAAAAP+S/8T/fv/dAAAAAP/s/+z/7AAA//b/nP+6AAD/9gAAAAAAAP+S/9j/fv+X/37/sP/Y/5f/nP+1/+z/7P+1AAAAAAAAAAAAAAAAAAD/nAAA/5L/4gAA/7X/xP/J/7r/xP+wAAAAAAAA/9gAAP/2AAAAAAAAAAAAAAAA//YAAP/xAAAAAAAAAAAAAP/nAAAAAP/sAAD/4v/2/+z/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7P/xAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP+1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/dAAAAAAAAAAAAAAAAAAD/+wAAAAD/7P/sAAD/7AAAAAAAAAAAAAAAAP/2/6YAAAAA/84AAP+6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+cAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAP/sAAAAAP/xAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP+6//H/7AAAAAD/9gAA//YAAAAAAAAAAP/7AAAAAAAAAAD/4v/dAAD/9gAAAAAAAAAAAAAAAAAAAAD/5//s/+L/5//xAAAAAAAA/9gAAAAA/6b/8QAA/5wAAP+SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAP/EAAD/xAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAP/xAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAP/2AAD/9v/2AAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAP/sAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAP/sAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/YAAAAAP/xAAAAAP/2AAAAAAAA//b/9gAKAAAAAAAAAAD/8f/xAAAACgAPAAAAAAAAAAAAAAAAAAD/+//7//b/+wAAAAAAAAAAAAAAAAAA/84AAP/s//EAAP/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9gAAAAA/5z/8f+I/5wAAP9+AAAAAAAAAAAAAAAAAAAAAP/sAAAAAP/2AAAAAP/x//YAAAAAAAAADwAA/84AAAAAAAAAAP/YAAAAAP/sAAD/5wAAAAD/q/+6AAD/0wAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP+w//b/7AAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAD/4v/YAAAAAAAAAAAAAAAAAAAAAAAAAAD/5//n/+L/5//xAAAAAAAA/9gAAAAA/5z/8f+I/5wAAP9+AAAAAAAAAAAAAAAAAAAAAP/sAAAAAP/2AAAAAP/x//YAAAAAAAAAAAAA/84AAAAAAAAAAP/YAAAAAP/sAAD/5wAAAAD/q/+6AAD/xAAA/+wAAP/YAAAAAAAA/6YAAP/Y/93/zv+w/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAP/YAAAAAP/2AAD/8f/2/+L/8f/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAB4AAAAeAB4AFP/2AAD/0//2/9MAAAAA//b/8QAAAAAAAAAAAAAAHgAjAAAAHgAjADcAAAAA/9MAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/7oAAP/Y/93/7P+1AAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/7AAAAAAAA//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8f/2//H/8QAAAAAAAP/sAAAAAP/2/6YAAP/E/87/zv+c//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/9gAAAAD/4v/s/9P/4v/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP+1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAD/7P/xAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAP/YAAAAAP/nAAAAAP/nAAD/7AAA/+f/7P/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAA//b/7P/sAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP+w//H/7AAAAAD/7AAA/+wAAAAAAAAAAP/2AAAAAAAAAAD/4v/OAAD/7AAAAAAAAAAAAAAAAAAAAAD/4v/n/93/4v/sAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAP/iAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAA/8T/8QAA/84AAP+6AAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAP/dAAD/3QAAAAAAAP+mAAD/sAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAP/xAAAAAP/xAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAA/90AAAAAAAD/9gAAAAAADwAAAAAAAAAAAAAAAP/2AAAAAP+c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AAsAAgANABEAAwAYABgACAAaABwACQAiACgADAArAC0AEwAwAD0AFgBAAEIAJABEAEcAJwBKAEoAKwBMAE8ALABRAFoAMABjAGMAOgBoAHEAOwBzAHUARQABAAgAAQAAAAEAAQABAAAAAQAAAAoAMAA+AAJERkxUAA5sYXRuABoABAAAAAD//wABAAAABAAAAAD//wABAAAAAXNzMDEACAAAAAEAAAACAAYADgAGAAAAAQAQAAEAAAABACgAAQAIAAEADgABAAEAeAABAAQAAQB4AAEAAAABAAAAAQABAAb/iQABAAEAeAABAAH//wAKAfQAAAEsAAAA/ABdAZoARQK8AC0CeAA9AzgANwK4ADEA5gBFAa4ARwGuADwBrgBMAmwAQADmADYBmABCAOYAUgH0//oCxgBBAU8AHgJOACwCYgA3ApgALwJdADwCggBAAksAQAJ2ADcCggBCAPAAVwDwADsCbAA8AmwATwJsAFkCFgAlA9QANQMWADgC0gBoAuIASQMOAGgCngBoApAAaAMQAEkC+ABoARIAbwIlACoCywBoAmsAaANkAGgDFgBoA1IASQKcAGgDUgBJAtMAaAKAAEECiAAyAvgAXQLuADgETgA8AtIASQLMADYCsABHAa4AYgH0AAkBrgA3Alj/6AI+ADMClABdAjsAOgKUADwCSAA6AWoALQKUADwCZQBdAPkAXgD5//sCMABdAPkAZAO3AF0CZQBdAoAAOgKUAF0ClAA8AZAAXQHxADMBkAAqAmUAUwJGADUDXQA6AjoAQwJMADQCKgA9AeAANwEeAHkB4AA1APwAXQJFAD4ChABCAq4ANQM+ADUBhgA6AgMANwGgACIBwgBKAOYAUgGGAC8CAwBDAhYANAIQAEIDggBCAOYATQDmADsA5gA2AZoATQGaADsBmgA2AdYAbwKoAFIBNwA3ATcAQwLQADcCsgAWArYAMg==); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/9C4B82DF21AA64A37.css b/docs/static/fonts/332720/9C4B82DF21AA64A37.css deleted file mode 100644 index 96c8c1f725..0000000000 --- a/docs/static/fonts/332720/9C4B82DF21AA64A37.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,T1RUTwANAIAAAwBQQ0ZGILkPphQAABIUAAAk2kdERUYAkAAEAAA28AAAACBHUE9TuESiiwAANxAAABwCR1NVQunFLUgAAFMUAAAAgE9TLzJVxiUrAAABQAAAAGBjbWFw0U4uVAAADVwAAASYZ2FzcAAAAAsAAFOUAAAACGhlYWQDcke+AAAA3AAAADZoaGVhB74DqgAAARQAAAAkaG10eNbiGPsAAFOcAAABjG1heHAAY1AAAAABOAAAAAZuYW1lKDUzBAAAAaAAAAu7cG9zdP+4ADIAABH0AAAAIAABAAAAAQBBj0s7+V8PPPUACwPoAAAAANAsAh8AAAAA0CwCH//o/zgEEwMiAAAACAACAAAAAAAAAAEAAAPA/xAAAARO/+j/6AQTAAEAAAAAAAAAAAAAAAAAAABjAABQAABjAAAAAgIsASwABQAEArwCigAAAIwCvAKKAAAB3QAyAPoAAAAAAAAAAAAAAACgAAB/UAAASgAAAAAAAAAASCZDbwAAACPgEgMg/zgAyAPAAPAAAAALAAAAAAH+ArwAIAAgAAIAAAAkAbYAAQAAAAAAAABAAAAAAQAAAAAAAQAjAEAAAQAAAAAAAgAHAGMAAQAAAAAAAwAhAGoAAQAAAAAABAAjAEAAAQAAAAAABQANAIsAAQAAAAAABgAEAJgAAQAAAAAABwBhAJwAAQAAAAAACAANAP0AAQAAAAAACQANAP0AAQAAAAAACgIRAQoAAQAAAAAACwASAxsAAQAAAAAADAASAxsAAQAAAAAADQIRAQoAAQAAAAAADgAqAy0AAQAAAAAAEAAjAEAAAQAAAAAAEQAjAEAAAQAAAAAAEgAjAEAAAwABBAkAAACAA1cAAwABBAkAAQBGA9cAAwABBAkAAgAOBB0AAwABBAkAAwBCBCsAAwABBAkABABGA9cAAwABBAkABQAaBG0AAwABBAkABgAIBIcAAwABBAkABwDCBI8AAwABBAkACAAaBVEAAwABBAkACQAaBVEAAwABBAkACgQiBWsAAwABBAkACwAkCY0AAwABBAkADAAkCY0AAwABBAkADQQiBWsAAwABBAkADgBUCbEAAwABBAkAEABGA9cAAwABBAkAEQBGA9cAAwABBAkAEgBGA9dDb3B5cmlnaHQgKEMpIDIwMDYsIDIwMDcgSG9lZmxlciAmIENvLiBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tQ29weXJpZ2h0IChDKSBIJkNvIHwgdHlwb2dyYXBoeS5jb21SZWd1bGFyMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5VmVyc2lvbiAxLjIwMUZvbnRHb3RoYW0gUm91bmRlZCBpcyBhIHRyYWRlbWFyayBvZiBIb2VmbGVyICYgQ28uLCB3aGljaCBtYXkgYmUgcmVnaXN0ZXJlZCBpbiBjZXJ0YWluIGp1cmlzZGljdGlvbnMuSG9lZmxlciAmIENvLlRoaXMgc29mdHdhcmUgaXMgdGhlIHByb3BlcnR5IG9mIEhvZWZsZXIgJiBDby4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBvciBkb3dubG9hZCB0aGlzIHNvZnR3YXJlLCBvciBpbnN0YWxsIGl0IHVwb24gYW55IGNvbXB1dGVyLCBvciBob3N0IGl0IGZyb20gYW55IGxvY2F0aW9uLiBZb3VyIHJpZ2h0IHRvIHVzZSB0aGlzIHNvZnR3YXJlIGlzIHN1YmplY3QgdG8gdGhlIFRlcm1zIG9mIFNlcnZpY2UgYWdyZWVtZW50IHRoYXQgZXhpc3RzIGJldHdlZW4geW91IGFuZCBIb2VmbGVyICYgQ28uIElmIG5vIHN1Y2ggYWdyZWVtZW50IGV4aXN0cywgeW91IG1heSBub3QgdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpc2l0IGh0dHA6Ly93d3cudHlwb2dyYXBoeS5jb20vd2ViZm9udC1zb2Z0d2FyZSwgb3IgY29udGFjdCBIb2VmbGVyICYgQ28uIGF0IHd3dy50eXBvZ3JhcGh5LmNvbSAxNzEyNDctODg0NzQtMjAxNTA2MjMtMjQyMy0xNDAyMTl3d3cudHlwb2dyYXBoeS5jb21odHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUAQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgADIAMAAwADYALAAgADIAMAAwADcAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAASAAmAEMAbwAgAHwAIAB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AUgBlAGcAdQBsAGEAcgAxADcAMQAyADQANwAtADgAOAA0ADcANAAtADIAMAAxADUAMAA2ADIAMwAtADIANAAyADMALQAxADQAMAAyADEAOQBWAGUAcgBzAGkAbwBuACAAMQAuADIAMAAxAEYAbwBuAHQARwBvAHQAaABhAG0AIABSAG8AdQBuAGQAZQBkACAAaQBzACAAYQAgAHQAcgBhAGQAZQBtAGEAcgBrACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAsACAAdwBoAGkAYwBoACAAbQBhAHkAIABiAGUAIAByAGUAZwBpAHMAdABlAHIAZQBkACAAaQBuACAAYwBlAHIAdABhAGkAbgAgAGoAdQByAGkAcwBkAGkAYwB0AGkAbwBuAHMALgBIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuAFQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIAB0AGgAZQAgAHAAcgBvAHAAZQByAHQAeQAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABZAG8AdQAgAG0AYQB5ACAAbgBvAHQAIABjAG8AcAB5ACwAIABtAG8AZABpAGYAeQAsACAAZABpAHMAdAByAGkAYgB1AHQAZQAsACAAbwByACAAZABvAHcAbgBsAG8AYQBkACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAsACAAbwByACAAaQBuAHMAdABhAGwAbAAgAGkAdAAgAHUAcABvAG4AIABhAG4AeQAgAGMAbwBtAHAAdQB0AGUAcgAsACAAbwByACAAaABvAHMAdAAgAGkAdAAgAGYAcgBvAG0AIABhAG4AeQAgAGwAbwBjAGEAdABpAG8AbgAuACAAWQBvAHUAcgAgAHIAaQBnAGgAdAAgAHQAbwAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHMAdQBiAGoAZQBjAHQAIAB0AG8AIAB0AGgAZQAgAFQAZQByAG0AcwAgAG8AZgAgAFMAZQByAHYAaQBjAGUAIABhAGcAcgBlAGUAbQBlAG4AdAAgAHQAaABhAHQAIABlAHgAaQBzAHQAcwAgAGIAZQB0AHcAZQBlAG4AIAB5AG8AdQAgAGEAbgBkACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAEkAZgAgAG4AbwAgAHMAdQBjAGgAIABhAGcAcgBlAGUAbQBlAG4AdAAgAGUAeABpAHMAdABzACwAIAB5AG8AdQAgAG0AYQB5ACAAbgBvAHQAIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABmAG8AcgAgAGEAbgB5ACAAcAB1AHIAcABvAHMAZQAuACAARgBvAHIAIABtAG8AcgBlACAAaQBuAGYAbwByAG0AYQB0AGkAbwBuACwAIABwAGwAZQBhAHMAZQAgAHYAaQBzAGkAdAAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0ALwB3AGUAYgBmAG8AbgB0AC0AcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABjAG8AbgB0AGEAYwB0ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGEAdAAgAHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtACAAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAvAHcAZQBiAGYAbwBuAHQALQBzAG8AZgB0AHcAYQByAGUAAAAAAwAAAAMAAAAcAAEAAAAAA5IAAwABAAAAHAAEA3YAAACsAIAABgAsACAAIwAvADQANwA/AEQARwBNAF0AXwBjAHEAdAB2AHkAfQCjAKUAqwCuALAAtwC7AMUAxwDWAN0A5QDvAPYA+AD9AQcBDgEQARMBFQEXARkBGwEjAScBKwEtAS8BMQE3AUIBRAFGAUgBUQFUAVYBWAFaAV4BYAFlAWoBbAFuAXABcgF0AXkBewF9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/+cAAAAAAAAAAAAAAAD/8QAA/5z/9v+cAAAAAP/2AAD/8QAAAAAAAAAAAAAAAAAAAAAAFAAA//YAAAAAAAAAAAAAAAD/9gAA//H/8QAAAAAAAAAAAAAAAP/sAAD/7P/x//b/4gAAAAoAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAAAA//sAAAAAAAD/5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/OAAD/9v/2//H/4v/iAAD/2AAA//b/9gAAAAAAAAAAAAD/4gAAAAD/5wAA/87/7P/n/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAP/s/8T/zgAA/84AAAAAAAAAAP/YAAAAAP+c/+z/jf+cAAD/fgAAAAD/9v+wAAD/iAAAAAD/9gAAAAD/+wAA/9j/7P/7AAAAAAAAAAAAAAAAAAD/xAAA/9j/2P+mAAAAAAAA/+wAAAAA/8T/zgAA/8QAAAAAAAD/2AAA/+L/+//JAAD/2P/d/87/xP/YAAAAAAAAAAD/2P/s/+wAAAAA/9gAAP/YAAAAAAAAAAAAAAAAAAAAAAAA/+L/7AAAAAAAAAAAAAAAAP/YAAAAAAAAAAAAAP/7AAAAAAAAAAD/ugAAAAAAAAAAAAAAAP/7AAD/9v/x//YAAAAAAAAAAAAAAAD/+wAA/5wAAP+cAAAADwAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAA8AAAAFAAAACgAAAAoAAAAAAAAAAAAAAAAAAP/JAAAAAP/dAAD/vwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAP/2AAD/7P/xAAD/5wAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+wAAAAAACv/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/9v/xAAD/4v/n/+f/4v/2AAAAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAD/+wAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAA//sAAAAA//H/9v/x//H/+wAAAAD/pv/J/5L/8QAAAAAAAAAAAAAAAP/s/3n/ugAA/+wAAAAAAAD/ef/O/5z/g/+c/6b/zv+D/6b/uv/Y/9j/nAAAAAAAAAAAAAAAAAAA/40AAP+m/84AAP+c/5z/nP+c/5z/kgAAAAD/5wAA/+wAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAP/7AAAAAAAAAAD/nP/YAAD/5wAAAAAAAP/2AAD/7P/2/7oAAAAA//YAAAAAAAD/uv/s/4j/v/+I/9j/5/+//8T/2P/sAAD/2AAAAAAAAAAAAAAAAAAA/8QAAAAA/+wAAP/YAAD/3QAA/9j/yQAAAAD/pv/d/5f/7AAAAAD/9v/2//H/7P/2/7r/0wAA//YAAAAAAAD/v//x/5z/xP+c/93/4v/E/87/3f/x//H/3QAAAAAAAAAAAAAAAAAA/8QAAP+c/+cAAP/d/93/3f/Y/93/yQAAAAAAAP/OAAD/4gAA//YAAP/xAAD/7AAA//YAAAAA//YAAAAAAAD/0wAAAAD/2AAA/87/7P/Y/87/7P/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP/sAAD/2AAA/9gAAAAAAAD/kv/E/37/3QAAAAD/7P/s/+wAAP/2/5z/ugAA//YAAAAAAAD/kv/Y/37/l/9+/7D/2P+X/5z/tf/s/+z/tQAAAAAAAAAAAAAAAAAA/5wAAP+S/+IAAP+1/8T/yf+6/8T/sAAAAAAAAP/YAAD/9gAAAAAAAAAAAAAAAP/2AAD/8QAAAAAAAAAAAAD/5wAAAAD/7AAA/+L/9v/s/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+z/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/3QAAAAAAAAAAAAAAAAAA//sAAAAA/+z/7AAA/+wAAAAAAAAAAAAAAAD/9v+mAAAAAP/OAAD/ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/nAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/7AAAAAD/8QAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/uv/x/+wAAAAA//YAAP/2AAAAAAAAAAD/+wAAAAAAAAAA/+L/3QAA//YAAAAAAAAAAAAAAAAAAAAA/+f/7P/i/+f/8QAAAAAAAP/YAAAAAP+m//EAAP+cAAD/kgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAD/xAAA/8QAAAAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/8QAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/9gAA//b/9gAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/7AAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAD/7AAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/8QAAAAD/9gAAAAAAAP/2//YACgAAAAAAAAAA//H/8QAAAAoADwAAAAAAAAAAAAAAAAAA//v/+//2//sAAAAAAAAAAAAAAAAAAP/OAAD/7P/xAAD/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/YAAAAAP+c//H/iP+cAAD/fgAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/9gAAAAD/8f/2AAAAAAAAAA8AAP/OAAAAAAAAAAD/2AAAAAD/7AAA/+cAAAAA/6v/ugAA/9MAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/sP/2/+wAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAA/+L/2AAAAAAAAAAAAAAAAAAAAAAAAAAA/+f/5//i/+f/8QAAAAAAAP/YAAAAAP+c//H/iP+cAAD/fgAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/9gAAAAD/8f/2AAAAAAAAAAAAAP/OAAAAAAAAAAD/2AAAAAD/7AAA/+cAAAAA/6v/ugAA/8QAAP/sAAD/2AAAAAAAAP+mAAD/2P/d/87/sP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAD/2AAAAAD/9gAA//H/9v/i//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAeAAAAHgAeABT/9gAA/9P/9v/TAAAAAP/2//EAAAAAAAAAAAAAAB4AIwAAAB4AIwA3AAAAAP/TAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+6AAD/2P/d/+z/tQAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+wAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//H/9v/x//EAAAAAAAD/7AAAAAD/9v+mAAD/xP/O/87/nP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAA//YAAAAA/+L/7P/T/+L/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAAAA/+z/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAD/2AAAAAD/5wAAAAD/5wAA/+wAAP/n/+z/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/2/+z/7AAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/sP/x/+wAAAAA/+wAAP/sAAAAAAAAAAD/9gAAAAAAAAAA/+L/zgAA/+wAAAAAAAAAAAAAAAAAAAAA/+L/5//d/+L/7AAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAD/4gAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAAAAP/E//EAAP/OAAD/ugAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAD/3QAA/90AAAAAAAD/pgAA/7AAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/8QAAAAD/8QAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAP/dAAAAAAAA//YAAAAAAA8AAAAAAAAAAAAAAAD/9gAAAAD/nAAA/5wAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/0wAAAAD/2AAAAAAAAP/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAUAAD/4gAAAAD/5wAA/6b/5/+mAAAAAP/n//YAAAAAAAAAAAAAAAAAAAAAABQAIwAAAAAAAP+1AAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/tf/2//EAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAA/+z/3QAA//YAAAAA//YAAAAA//YAAAAA/+z/8f/n//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5wAAP+c/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/iP/YAAD/4gAAAAAAAAAAAAAAAP/s/78AAAAAAAAAAAAAAAD/sAAAAAD/ugAAAAD/5/+6AAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAA/6sAAAAA/+wAAP/OAAD/zgAA/87/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/8QAAAAD/8QAAAAAAAP/x//YAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAAAAAAAAAD/4gAA/6v/5/+r//EAAP/n/+L/8QAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/8QAA//H/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAD/zv/2/+z/5wAA/7r/7P+6//YAAP/s/+z/9gAAAAAAAAAAAAD/9gAAAAAAAAAA//EAAP/EAAAAAAAA//H/9v/2//b/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAD/3QAAAAD/4gAA/+IAAP/i/9P/8QAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAD/zv/2/+z/4gAA/6v/5/+r//EAAP/n/+L/8QAAAAAAAAAAAAD/9gAAAAAAAAAA/+wAAP+6AAAAAAAA//H/9v/2//b/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/0wAAAAD/8QAAAAD/8QAAAAAAAP/x//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEABQBbABgAAAAsAAAAGQAAACAAIwAiADMAAAAyAB8AHwAAAAAAAAAAAAEAAgADAAQABgAHAAgACQAKAAAACwAMAA0ADgAPABAAEQASABMAFAAVABYAHQAbAAAAAAAXABoAHgAhACQAJQAoAAAAAAApAAAAKAAoACsAGgAAADQANgA4ADkAHAAAAAAAAAAAAAAAAAAAACYAAAAAAAAAAAAnAC0AIwAjAC4ALwAgAC4ALwAgAAAAIgAmACcAAQAFAF0ADQAAAAAAIQAOAAAAFQAYABcAKQAAACgAFAAUAAAAAAAAACIAAQAAAAIAAAAAAAIAAwAAAAAAAAACAAAAAgAAAAQABQAGAAcACAAJAAoACwAAABAAEgAAAAwADwATABMAGQAaAA8AHQAeAA8ADwAfAB8AEwAfABYAKgAtAC8AMAAAAAAAEQAAAAAAAAAAAAAAGwAmAAAAAAAAABwAIwAYABgAJAAlABUAJAAlABUAAAAXABsAHAAAACYAAgAOAAUABQAAAAcABwABAAkACQACAAsADgADABAAEgAHABcAHwAKACEALgATADEANwAhADoAOgAoADwAPwApAEEARQAtAE0ATQAyAFIAWwAzAF0AXwA9AAEACAABAAAAAQABAAEAAAABAAAACgAwAD4AAkRGTFQADmxhdG4AGgAEAAAAAP//AAEAAAAEAAAAAP//AAEAAAABc3MwMQAIAAAAAQAAAAIABgAOAAYAAAABABAAAQAAAAEAKAABAAgAAQAOAAEAAQBiAAEABAABAGIAAQAAAAEAAAABAAEABv+fAAEAAQBiAAEAAf//AAoB9AAAASwAAAGaAEUCvAAtAzgANwK4ADEA5gBFAa4ARwGuADwBrgBMAmwAQADmADYBmABCAOYAUgH0//oCmAAvAksAQADwAFcA8AA7AmwAPAJsAE8CbABZAhYAJQMWADgC0gBoAuIASQMOAGgCkABoAxAASQIlACoCywBoAmsAaANkAGgDUgBJApwAaANSAEkC0wBoAoAAQQKIADIC+ABdAu4AOAROADwC0gBJAswANgKwAEcBrgBiAfQACQGuADcCWP/oAj4AMwKUAF0COwA6AkgAOgFqAC0ClAA8AmUAXQD5AF4A+f/7AjAAXQD5AGQDtwBdAmUAXQKAADoClABdApQAPAGQACoCRgA1AjoAQwJMADQB4AA3AR4AeQHgADUCRQA+AoQAQgKuADUDPgA1AYYAOgIDADcBoAAiAcIASgDmAFIBhgAvAgMAQwIWADQCEABCA4IAQgDmAE0A5gA7AOYANgGaAE0BmgA7AZoANgHWAG8CqABSATcANwE3AEMC0AA3ArIAFgK2ADI=); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:font/opentype;base64,T1RUTwALAIAAAwAwQ0ZGIE+2i2MAABCYAAAOb0dERUYASAAEAAAfCAAAACBPUy8yVcclSwAAASAAAABgY21hcO62ywIAAA08AAADOmdhc3AAAAALAAAfKAAAAAhoZWFkAxZHvAAAALwAAAA2aGhlYQdhAwAAAAD0AAAAJGhtdHg9xwbVAAAfMAAAAGxtYXhwABtQAAAAARgAAAAGbmFtZSg1MwQAAAGAAAALu3Bvc3T/uAAyAAAQeAAAACAAAQAAAAEAQS6s5cVfDzz1AAsD6AAAAADQLAIfAAAAANAsAh8AAP84A58DIAAAAAgAAgAAAAAAAAABAAADwP8QAAAD1AAAAAADnwABAAAAAAAAAAAAAAAAAAAAGwAAUAAAGwAAAAICTQEsAAUABAK8AooAAACMArwCigAAAd0AMgD6AAAAAAAAAAAAAAAAoAAAf1AAAEoAAAAAAAAAAEgmQ28AAAAk4BIDIP84AMgDwADwAAAACwAAAAAB/gK8ACAAIAABAAAAJAG2AAEAAAAAAAAAQAAAAAEAAAAAAAEAIwBAAAEAAAAAAAIABwBjAAEAAAAAAAMAIQBqAAEAAAAAAAQAIwBAAAEAAAAAAAUADQCLAAEAAAAAAAYABACYAAEAAAAAAAcAYQCcAAEAAAAAAAgADQD9AAEAAAAAAAkADQD9AAEAAAAAAAoCEQEKAAEAAAAAAAsAEgMbAAEAAAAAAAwAEgMbAAEAAAAAAA0CEQEKAAEAAAAAAA4AKgMtAAEAAAAAABAAIwBAAAEAAAAAABEAIwBAAAEAAAAAABIAIwBAAAMAAQQJAAAAgANXAAMAAQQJAAEARgPXAAMAAQQJAAIADgQdAAMAAQQJAAMAQgQrAAMAAQQJAAQARgPXAAMAAQQJAAUAGgRtAAMAAQQJAAYACASHAAMAAQQJAAcAwgSPAAMAAQQJAAgAGgVRAAMAAQQJAAkAGgVRAAMAAQQJAAoEIgVrAAMAAQQJAAsAJAmNAAMAAQQJAAwAJAmNAAMAAQQJAA0EIgVrAAMAAQQJAA4AVAmxAAMAAQQJABAARgPXAAMAAQQJABEARgPXAAMAAQQJABIARgPXQ29weXJpZ2h0IChDKSAyMDA2LCAyMDA3IEhvZWZsZXIgJiBDby4gaHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbUNvcHlyaWdodCAoQykgSCZDbyB8IHR5cG9ncmFwaHkuY29tUmVndWxhcjE3MTI0Ny04ODQ3NC0yMDE1MDYyMy0yNDIzLTE0MDIxOVZlcnNpb24gMS4yMDFGb250R290aGFtIFJvdW5kZWQgaXMgYSB0cmFkZW1hcmsgb2YgSG9lZmxlciAmIENvLiwgd2hpY2ggbWF5IGJlIHJlZ2lzdGVyZWQgaW4gY2VydGFpbiBqdXJpc2RpY3Rpb25zLkhvZWZsZXIgJiBDby5UaGlzIHNvZnR3YXJlIGlzIHRoZSBwcm9wZXJ0eSBvZiBIb2VmbGVyICYgQ28uIFlvdSBtYXkgbm90IGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgb3IgZG93bmxvYWQgdGhpcyBzb2Z0d2FyZSwgb3IgaW5zdGFsbCBpdCB1cG9uIGFueSBjb21wdXRlciwgb3IgaG9zdCBpdCBmcm9tIGFueSBsb2NhdGlvbi4gWW91ciByaWdodCB0byB1c2UgdGhpcyBzb2Z0d2FyZSBpcyBzdWJqZWN0IHRvIHRoZSBUZXJtcyBvZiBTZXJ2aWNlIGFncmVlbWVudCB0aGF0IGV4aXN0cyBiZXR3ZWVuIHlvdSBhbmQgSG9lZmxlciAmIENvLiBJZiBubyBzdWNoIGFncmVlbWVudCBleGlzdHMsIHlvdSBtYXkgbm90IHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSB2aXNpdCBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUsIG9yIGNvbnRhY3QgSG9lZmxlciAmIENvLiBhdCB3d3cudHlwb2dyYXBoeS5jb20gMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5d3d3LnR5cG9ncmFwaHkuY29taHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbS93ZWJmb250LXNvZnR3YXJlAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMAA2ACwAIAAyADAAMAA3ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgAEgAJgBDAG8AIAB8ACAAdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAFIAZQBnAHUAbABhAHIAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAVgBlAHIAcwBpAG8AbgAgADEALgAyADAAMQBGAG8AbgB0AEcAbwB0AGgAYQBtACAAUgBvAHUAbgBkAGUAZAAgAGkAcwAgAGEAIAB0AHIAYQBkAGUAbQBhAHIAawAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4ALAAgAHcAaABpAGMAaAAgAG0AYQB5ACAAYgBlACAAcgBlAGcAaQBzAHQAZQByAGUAZAAgAGkAbgAgAGMAZQByAHQAYQBpAG4AIABqAHUAcgBpAHMAZABpAGMAdABpAG8AbgBzAC4ASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgBUAGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAaQBzACAAdABoAGUAIABwAHIAbwBwAGUAcgB0AHkAIABvAGYAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAWQBvAHUAIABtAGEAeQAgAG4AbwB0ACAAYwBvAHAAeQAsACAAbQBvAGQAaQBmAHkALAAgAGQAaQBzAHQAcgBpAGIAdQB0AGUALAAgAG8AcgAgAGQAbwB3AG4AbABvAGEAZAAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUALAAgAG8AcgAgAGkAbgBzAHQAYQBsAGwAIABpAHQAIAB1AHAAbwBuACAAYQBuAHkAIABjAG8AbQBwAHUAdABlAHIALAAgAG8AcgAgAGgAbwBzAHQAIABpAHQAIABmAHIAbwBtACAAYQBuAHkAIABsAG8AYwBhAHQAaQBvAG4ALgAgAFkAbwB1AHIAIAByAGkAZwBoAHQAIAB0AG8AIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIABzAHUAYgBqAGUAYwB0ACAAdABvACAAdABoAGUAIABUAGUAcgBtAHMAIABvAGYAIABTAGUAcgB2AGkAYwBlACAAYQBnAHIA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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/A59BE2741B1B5D65A.css b/docs/static/fonts/332720/A59BE2741B1B5D65A.css deleted file mode 100644 index 9d5f7c8977..0000000000 --- a/docs/static/fonts/332720/A59BE2741B1B5D65A.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - - \ No newline at end of file diff --git a/docs/static/fonts/332720/B5A3A718F52798BF7.css b/docs/static/fonts/332720/B5A3A718F52798BF7.css deleted file mode 100644 index 9148477f21..0000000000 --- a/docs/static/fonts/332720/B5A3A718F52798BF7.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/B65C7771D2CCC2100.css b/docs/static/fonts/332720/B65C7771D2CCC2100.css deleted file mode 100644 index a727dfcc29..0000000000 --- a/docs/static/fonts/332720/B65C7771D2CCC2100.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8AAD8/AAA/PwAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAA/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAPz8AAD8/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/Pz8AAAAAPz8AAAAAPz8AAAAAPz8AAD8/PwAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAIwAUAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAA/Pz8/AAA/PwAAAAA/PwAAFAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAA/PwAAAAAAAAAAAAAAAA8AAAAAAD8/AAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAD8/AAA/PwAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAA/PwAAPz8AAD8/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/Pz8/PwAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/AAAAAAAAAAA/PwAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/AAA/PwAAPz8AAAAAPz8AAAAAPz8AAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/AAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8AAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8/AAA/Pz8/AAAAAD8/AAAAAAAAPz8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAPz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAPz8AAAAANwAjAB4AAAAjAB4AAAAAAAAAAAAAAD8/Pz8AAAAAPz8/Pz8AAD8/FAAeAB4AAAAeAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8AAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8/AAA/PwAAAAAAAD8/AAA/PwAAPz8AAD8/Pz8AAAAAPz8AAD8/AAAAAD8/AAAAAAAAAAA/PwAAAAAAAAAAAAA/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAB+PwAAPz8/Pz8AAAAAPz8AAAAAAAA/Pz8/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAD8/PwAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAA/Pz8/Pz8AAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAPz8/PwAAAAA/PwAAPz8AAAAAPz8AAAAAAAAAAD8/AAAPAAAAAAAAAD8/AAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAH4/AAA/Pz8/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/Pz8AAD8/AAAAAAAAAAAAAAAAAAA/Pz8/Pz8/PwAAAAAAAAAAAAAAAAAADwAKAAAAPz8/AAAAAAAAAAAKAD8/Pz8AAAAAAAA/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAD8/AAA/PwAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAD8/Pz8AAAAAPz8AAAAAAAA/Pz8/Pz8AAAAAAAAAAAAAAAAAAAAAPz8AAD8/PwAAAAAAAAAAPz8AAAAAAAAAAD8/AAA/PwAAAAA/Pz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAPz8/PwAAAAAAAAAAAAAAAD8/AAA/Pz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/PwAAPz8AAAAAPz8AAAAAAAAAAAAAPz8AAD8/AAAAAAAAAAAAAAAAPz8AAD8/AAAAAAAAPz8/Pz8/Pz8/AAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAPz8/Pz8/Pz8/Pz8/fj8/P34/Pz8/AAAAAAAAPz8AAD8/Pz8/PwAAPz8/PwAAAAA/P34/Pz8/AAAAAAAAPz8AAD8/AAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8AAD8/AAAAAD8/AAAAAAAAPz8AAAAAPz8AAD8/AAA/PwAAPz8AAD8/AAA/PwAAAAAAAD8/Pz8/Pz8AAD8/Pz8AAD8/AAAAAAAAAAAAAAAAAAA/Pz8/Pz8/Pz8/Pz8/Pz8AAAAAAAA/PwAAPz8/Pz8/Pz8/Pz8AAAAAPz8/Pz8/PwAAAAA/Pz8AAD8/AAA/PwAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAA/Pz8/Pz8/Pz8/Pz8/Pz8AAAAAAAA/PwAAAAA/Pz8/AAA/PwAAAAAAAD8/AAA/Pz8/AAAAAAAAAAA/PwAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8/Pz8/Pz8/PwAAPz8/PwAAPz8AAAAAAAAAAAAAAAAAAD8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/eT8AAAAAAAA/PwAAPz95Pz8AAAAAAAAAAAAAAAA/Pz8/Pz8/AAAAAD8/Pz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAA/Pz8/PwAAPz8/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8KAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/AAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAACgAAAAoAAAAFAAAADwAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAACgAAAA8AAAA/PwAAPz8AAD8/AAAAAAAAAAAAAAAAPz8/PwAAPz8AAAAAAAAAAAAAAAA/PwAAAAAAAAAAPz8AAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAA/Pz8AAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAPz8/PwAAAAAAAAAAPz8/Pz8/AAA/Pz8/AAA/PwAAAAAAAD8/AAA/Pz8AAAAAPz8AAAAAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAPz8/AAA/PwAAAAA/PwAAAAA/PwAAPz8/PwAAAAB+PwAAPz8/Pz8/AAAAAD8/AAAAAAAAAAA/PwAAPz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/Pz8AAD8/AAAAAD8/AAAAAAAAAAAAAD8/Pz8AAD8/AAA/Pz8/Pz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAoAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAD8/PwAAPz8AAAAAAAAAAAAAAAA/PwAAFAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8/PwAAPz8AAAAAAAAAAAAAAAA/Pz8/AAAAAAAAAAAAAAAAAAAAAD8/Pz8AAAAAAAA/PwAAPz8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAPz8/AAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8AAAAAAAAAAD8/Pz8/Pz8AAD8/Pz8/AAA/PwAAAAAAAD8/Pz8/Pz8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAA/Pz8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAA/Pz8/PwAAPz8AAAAAAAA/Pz8/Pz8AAD8/AAAAAAAAAAAAAAAAPz8/Pz8AAD8/AAAAAD8/AAAAAD8/AAA/PwAAAAAAAD8/AAA/Pz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwA8AD8YPxcAAAQAPxkCAHYAaQBgAF8AWgBXAFUAUAA9ADwAOQA3ADIAMQArACcAIwAaABkAGAAXABYAFQAUABMAEQAQAAsACQAHAAUAHwABABQAEgABAD8/VQA/PzkAPz83AAMAPz8VAAEAPz8VAAEAPz9XAD8/VQAjAEkAPz8rAAQAPz9cAD8/VQA/Pz4APz89AD8/IAAFAD8/XAA/P1cAPz9VAD8/PgA/Pz0APz8gAD8/EAAHAD8/PQABAD8/VQAeAEkAPz83AAMAPz9XAD8/VQAeAEkAPz8rAAQAPz9VAD8/SQA/PzcAPz8rAD8/IAA/PwcABgA/P1cAPz9VAD8/SQA/PzkAPz83AD8/KwA/PxAAPz8HAAgAPz83AD8/IAA/PwoAAwAKAFUAPz85AD8/NwA/PysAPz8QAD8/BwAGAD8/KwABAD8/VQA/PysACgAgAD8/EAA/PwcABQA/P1UAPz85AD8/NwA/PyAABAA/PxgAPz8WAD8/FAA/PxMAPz8QAAUAPz8aAD8/GAACAD8/GgA/PxkAPz8XAD8/FgA/PxUAPz8UAD8/EwAKABIAPz8RAHQ/EAAKAD8/GgA/PxgAPz8UAD8/EgA/PxAABQA/PxoAPz8YAD8/FAA/PxMAPz8QAAUAPz8aAD8/GAA/PxIAPz8QAAQAPz8aAD8/GAA/PxYAPz8QAAQAPz8YAD8/FQACAD8/GAA/PxQAPz8TAD8/EgA/PxAABQA/P1cAPz9VAH4/KwA/PxoAPz8ZAD8/GAA/PxcAPz8WAD8/FQA/PxQAPz8TAAoAEgA/PxEAVj8QAA4APz8rAAEAHgBJAD8/KwACAD8/NwABAD8/GAABAHACYgJcAlYCRAIuAhACCgI/AT8BPwE/AT8BPwE/AWoBWAFCATgBDgE/AD8APwA/AD8APwBkAF4AVABOAEgAHwAAAAQAdgIBAD8cAQAAAAEAPwISAAIAAAACABAABgACAAAAAQAAAAEAAQAAABQAbnJlaw4AcHNwYwIAAQAAAAIAPz8AAAAABAABAAAAAgA/PwAAAAAEABwAbnRhbA4AVExGRAIATgA0AAoAAAABAAAAAgAAAAQAAQB4AAEAAQACAAAAAAAYAAAADgAAAAEAAAsfPz8/fn8/P39/Pz8/Pz8/PwsfPz8/fz8/Pz8/Pz8/Pz8/PwsePz8/PwZ9Hz8/Pz8LHz8/Pz8IPz8/Pz8/Bj8IPz8/Pz8/Hz8/P39/Pz8/CD99Pz8/PwseeH1+eHg/fj8HPx4/Pz8/P30/eAdwCwg/Pz8/Pz93Z3V9aD8/Pz8/dz8Hdh55fHx5eT98Pwc/CD8/Pz8/Pz8/Pz8/Px4/Pz8/Cwg/Pz8/Pz8/Pz8/Pz8/fD9/Pz8HPx4/Pz8/P3w/eQdyCFM/bT95eXl5fXI/Px4/Pz8/Cwg/Pz8/Pz8FRz8dPwg/Pz8/Pz8/Pz8/Pz8FRz8dPwg/Pz8/Pz8/Pz8/fz8/Pz8/Pz8FQT8SP0M/Ej8IPz8/Pz8/fz8/Pz9/Cwg/Pz8/Pz8FRz8dPwg/Pz8/Pz8/Pz8/Pz8FRz8dPwg/Pz8/Pz8/fz8/Pz8/Pz8/Pz8FQT8SP0M/Ej8IPz8/Pz8/Hz8/Pz8LHj8/Pz8/fT94B3AeeH19eHg/fT8HPwseen5+eno/fT8HPx4/Pz8/P34/egseAz8/HT8HPx4aPy4gITIlFj8HPx8XPzM/PwseAz86Mh0/Bz8eGj81Pz8/Fj8HPx8XPyUhCx8/Pz99fX9/fQYuPx99P38/Pz8/PwYuPwsIPz8/Pz8/d2d1fWg/Pz8/P3c/B3YeeH19eHg/fT8HPwg/Pz8/Pz8/Pz8/Pz8ePz8/PwseUFBhQAc/Hj1R+j8/Pwc/Hz8/XFMLHj83Py4HPx4tNk0uLz9OPwc/Hz8/Pz8LCHk/Pz8/ewZ4Hj8/Pz8IPz8/Pz8/BV0/CD8/Pz8/Pz8/Pz98PwseeH19eHg/fT8HPx4/Pz8/P30/eAdwPwJyAmACUwItAhYCPwE/AWgBIQEKAT8APwA/AD8AbwBXAD8AGAABAAITABM/FT8/FHo/Dh8/Pz8/Pz8/Pz8/Pz8/Pz8/FT9YPwc/Yj8/bj8/P3V7Pz8Gbj8/Pz8/Pz8/eT8/Pz8/FWhzPwowFT8/Ci8VPz8/CH54P30/Pz90Pz8/P3w/fD97PxU/PwU/CD8/Pz8/Pz8/Pz8/Px4/Pz8/Pz8/PxU/Fz8HfT8fPz8/Pz8/Pz8ePz8/Pz8/Pz8VPxs/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/Px8/Pz8/FXBoBj8/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwU/Pwg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8ePz8/Pz8/Pz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Bz8/FVt3Pwc/cj8/ej8IPz8/Pz8/Hj8/Pz8HPz8/Pz8/eR4/Pz8/Pz8/PwY/Pz8/FXw/ZT8IPz8/Pz8/P3I/ej93P3Z/f3o/BT8/CD8/Pz8/Pz8/Pz9pPz8/Pz8/Pz9jP1Y/YT9sbnlWdT95P24/HmBhYUhNP2o/CD8/Pz8/Pz9wP3c/P3N7fXg/ch9vP3U/Pz8/Pwg/Pz8/fD8VSj8iPwc/fj8/Px8/Pz8/CD8/Pz8/PwU/Pwg/Pz8/Pz8ePz8/Pwd3Pz8/PxUqPwg/P3Q/bD98P30/Pz8/eT9vP28/Pz8/Pz8VFz9iBj8IPz8/Pz8/Pz8/Pz8/Pz8/P3s/Pz8/Pz8/Pz8/Pz8/BT8/Bj8/Pwg/Pz8/Pz8/Pz8/Pz8/Pz9zPz8/Pz8/Pz8/Pz8/Pz8FPz8/PxU/Px56fz97ej9/Pwg/Pz8/Pz91P30/dD8VPz8tPwg/Pz8/Pz8/Pz8/Pz8/P3Q/Pz8FPz8/Pz9yPz8/Pz8/dz8/Pz8/P3o/Pz8/Pz8IPz8/Pz8/Hz8/Pz8/Pz8/FVk/Bz8/eT8IPz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwU/Pz8/FT97Bz9yPz95Pwg/Pz8/Pz8ePz8/Pz8/Pz8/Pz8/Bz8IPz8/Pz8/Bj8/Pz8VPwc/cj8/Pz8ffj8/Pwg/Pz8/Pz8FPz8GPz8/Pz8/cj8/Pz8/FTsrHz8/Pz8/Pz8/Pz8/Pz8/Pz8VPxI/Hz8/P3p5f359CD8/Pz8/PwU/PwY/Pz8Ifz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwY/CD8/Pz8/PxVRPyY/Bj8/Pz8VQT9VPwoyFT8GP2I/P1g/Pwg/Pz8/Pz8GPz8/CD8/Pz8/PwY/Pz8IPz8/Pz8/Bj8/Pz8/FT85PwoyBD8KMRU/PwoyBD8KMRVBPwoxFT9QCjAVPz8KLxU/Pz8OHz8/Pz8GPwg/Pz8/Pz8FST8LP0k/Cz8IPz8/Pz8/Bj8ePz8/Pwc/Px4/Pz8/Pz8/PwV2Pz8xPwg/Pz8/Pz8/Pz8/Pz8FMT92Pz8ePz8/Pz8/Pz8VPz9iPwY/Hz8/Pz8/Pz8/Bmc/Hz8/Pz8/Pz8/Bz8/Px4/Pz8/Pz8/PxUpPxM/Dgg/Pz8/Pz8/Pz8/Hj8jPy0/PwY/Hz8/P35+Pz9+BkwIeT94P3g/dD91P3U/Bj8fPz8/fn4/P34GQQgjP2ciJT8WPwg/Aj8/Rz9XPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Rj9kPz8/Pwo/PwY/Px9+Pz8/Pz8/PwY/Pwg/Pz8/Pz8/Pz8/Pz8GPz8ffj8/Pz8/Pz8GPz8IEj9sPzY/BT8/OVxSSV4/Pz8/Pz8efj8/PxUcPyY/DgorFWc/Pz8OCioVP3E/Pw4KLhZ2PwouFnY/Ci4VPz8/Dh4/VD9HBz8eR1RQSks/Tz8HPx8/Pz8/FXg/fz8mPw4KLRZIPwokFTE/Yj8OCi0WSD8KLRU/P2I/DgosFkg/CiwVRD8/Yj8OCiQVMT8OCi0VPz8OCiwVRD8/Pw4fP38/fX1/f30GXj8ffT9/Pz8/Pz8GXj8VPz8/Dh8/fz99fX9/fQY/Px99P38/Pz8/PwY/PxU/Mw4KKRUPPz8IPz8/Pz8/BRU/Pwg/Pz8/Pz8/BD8/Pz8HPx8/P0slCD8/aFFTWj8/Pz8/Pz9+Pz8/Pz8/Pz8/Pz8/Px4YPzM/IAc/CBA/P0krfQg/BQM/Pwh/Pz8/Pz8VPz8/PzkOCisWYD8IPz8/Pz8/BUc/HT8IPz8/Pz8/Pz8/Pz8/BUc/HT8IPz8/Pz8/Pz8/P38/Pz8/Pz8/BUE/Ej9DPxI/CD8/Pz8/Px9/Pz9/FWc/Pz8mDh5QW2JRBz8eT1s/Pz8/Bz8fPz9fURUxPxU/Hz8/Pz8/Pz8/Bj8/Hz8/Pz8/Pz8/Bj8/FQo/Ez8eP0g/PQc/HjxHTjc4P08/Bz8fPz8/PxUvP1Y/dj8OCiAVPz8OHlFaYFYHPx5WWj8/Pz8/Bz8fPz9gUQQ/Hj9HPz0HPx49R0M8PD9DPwc/Hz8/Pz8VMD91Pzo/Dh9yfn14dj8/Pwc/FUE/Hz8/Pz8GSx5nP24/CD8/Pz8/PwU/ZQg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8FUD8HPz8ePz8/Pz8/Pz8VP0oeNERINgc/HjZFPz8/Pz8/Bz8fPz9JMwQ/Hj88PywHPx4sOz4qKT8/Pwc/Hz8/Pz8VPz9kP1w/DgoqFmA/CD8/Pz8/PwVHPx0/CD8/Pz8/Pz8/Pz8/PwVHPx0/CD8/Pz8/Pz9/Pz8/Pz8/Pz8/PwVBPxI/Qz8SPwg/Pz8/Pz8/Pz8/Pz8VPz0/Jg4fPz8/Pz8/Pz8GcD8fPz8/Pz8/Pz8GcD8VLj8pHlhsXl0HcAg/Pz8/Pz8ePz8/Pwc/Hz8/amUVPz8eP20/Twc/H1BpWEIIP2c/cz90Bz8fWHE/Pwg/Pz8/Pz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/fWw/cD9nP2U/bT91P3k/Pz8/BzQ/Hj8/Pz8/Pz8/B3AIPz8/Pz8/FS8/Qj92Pw4ePzY/JAc/HyU0OyQIP1A/ZT9rPz8/Pz8/Pz8/Pz8/Pz8/Pz8/dD94Pz8/Hj8/Pz8HPx8/P00+CD9ee21vbD8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/FSo/Px5SPys/Iz9LPwc/Hks/KT8iP1E/Uj8rPyM/Sz8HPx9LPyk/Ij9RPwQ/Hl8/Nz8yP1k/Bz8eWT85PzQ/Xz9fPzc/Mj9ZPwc/H1k/OT80P18/FX8yP2o/DgZWPx9/Pz8/Pz8/PwdWPx4/Pz8/Pz8/fQYjVj8fPz8/f34/P38GVj8pVj8fPz8/f38/P38FP0Q/Pz8/CD8/Pz8/P30/P38/fT8/Pz8/PwU/Pz8/Pz8/Pwg/Pz8/Pz8/fj8/Pz8/Pz8/Pz8FPz8/Pz9FPx9/Pz8/Pz8/PwZWPxU/PwQ/Dgg/Pz8/Pz8FeT0GPz8fPz8/fn4/P34HSQo/CEA/S3RhYWZmdlc/Tj8pP1E/Xwg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz9dP2k/Pz8/Pz8/Pz8/Pz8/Bgs/Pz8ffj8/Pz8/Pz8GPz8/Pz8/H34/Pz8/Pz8/BnY/Hj8/Pz8VPz8OCD8/VD89BT8/OT8/Hgg/Pw4/Bz8VPz8NPwhnPyc/Bj8/Bz8fIz8QPwY/Jj8FP3xHfgg/Pz8/P34/ez9/Pz8FPz8IP1Q/Yz9pPz8/Pz8/Pz8/Pz8/Pz8/Pz8/bj9xPz8/BUQ/CD9/P38/fwg/S25XX18/Pz8/Pz8/fz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/BT8/CD8/Pz8/Pz8/fj95PxU/bz9oDgopFQI/Px8/Pz8/Bj8ePz8/fQV3P3sePz8/Pz8/Pz8VPz8hPwA/Dgg/PT9rPz8HPx4/P3Qkez8/Pz8/Pz8HPwg/Pz8/PT8/Pz8/fz8/Pz8/Pz9lJT9leyg/B0AIMj9nYnhMdT9qPzI/B0AIKD9lP2UlPz8/Pz8/P38/Pz8/PxVdPxw/Dh5/Pz9/fz8/PwcOPx4/Pz8/Pz8/fxUCPw0/Pw4IaT0/Sz8kPwc8Hj1aPz8/Pz8/Pz97JFp0PQc8CCQ/S2tpPT8/Pz8/Pz8/Pz8/Pz8/JT8/Pwc/CD8/Pz8/P0g/Zj8/Bz8IPz8/ez8lPz8/Pz8/Pz8/Pz8/PxUfPyo/HD8OHj8/Pz8HPwg/Pz8/Pz8FPD8/Pz8fPz8/f38/P38GEz8efz8/Pwc/CD8/Pz8/PwU8Pz8/H38/Pz8/Pz8/BiE/Fj9NDgg/Pz8/Pz8/Pz8/Pz9+Pz8/P34/Pz8/Pz8/ez95P2w/U2ZpP2oFPz9rP3g/CD8/Pz8/P30/Pz8/fD98Pz8/PwVMP2A/Tj9GPwg/Pz8/P34/fT8/Pz8/Pz8/Pz8FPz9jPwg/Pz8/PxU3Py8/bw4IPz8/Pz8/BXU/ST9qP0A/CD8/Pz8/P34/Pz8/fj8/Pz8/PwVmPzs/ZD86Pwg/Pz8/Pz8/fz8/Pz8/Pz8/Pz8Faj9BP3U/SD8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BXE/Qz9vP0I/CD8/Pz8/Px4/Pz9/FT9dDgg/Pz8/fT8FXz87Pwg/Pz8/Pz9+Pz9/P30/fT8/Pz8FQz8oP0U/KD8IPz8/Pz9+Bj8IP30/Pz8/BUU/KD9FPyk/CD8/Pz8/fT99Pz8/Pz8/Pz8/PwVfPzs/CD8/Pz8/PwY/CD8/Pz98PwU1PyU/NT8mPwg/Pz8/Pz8GPxU/Pz8/Pw4IPz8/Pz8/Bj8IPz8/P34/BWA/YT8IPz8/Pz8/fT8/Pz98P3w/Pz8/BUs/Tj9NP1E/CD8/Pz8/fj99Pz8/Pz8/Pz8/PwViP2I/FT8/aQ4ePz8/Pz8/P3wHQQg/Pz8/HhU/Mz8OPwc/Px58Pz99fT8/Pwc/Px4/P1AkJz8+IQc/Px58Pz99fT8/PxV9Pz8/Pw4eP2A/KgY/Px8/Pz9/fz8/fwdUIj8efT8/fX0/Pz8GIj80Px9/Pz8/Pz8/Pwc0Pz8fPz9gUAg/aD97Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8VPz8/bD8OCD9wP2Q/Pz8/Pz8/fj8/Pz9+Pz8/Pz8/P1Y/Uz9OHkZlVVAHPwhPP3U/dz9zP3I/MD8HPx85UEYoCD9UP04/Wj8/Pz8/Pz8/Pz8/Pz8/Pz8/P3E/ez8/Px4/Pz8/Bz8IPz8/Rj9CPzk/NT8/Bz8fPz8/PxU/Pz8LPw4efT8/fX0/Pz8HED8IKF9VMj9DP3w/Pz8/Pz8/Pz8/PwA/Pzg/PwdQPx4/Pz8/Pz8/fBU/bD8OCicVPz8/Px4/Pz8/Pz8/fAc/Pwg/Pz8/Hg8/KBE/Oj8HPx86PyYRPw8/CD8lP0k/YQcyHn0/P319Pz8/FX0/Pz8OCiYVWj8/Px58Pz99fT8/Pwc/CEhfUEo/Jh4PPxE/Oj8HPx86PxE/Dz8IP1E/Sz8HPz8ePz8/Pz8/P3wVHz8/Dh4NPyg0DD8HPx4PPyk/Cj8NPz8MPwc/Hw8/Lwo/FT8/His/Dj8CPyM/Bz8eIz8QPwM/LD8rPw4/Aj8jPwc/HyM/ED8DPyw/FX8/Pz8OHn0/P319Pz8/Bz8IT2lcUj8uHhU/QA4/Bz8/Hj8/Pz8/Pz98Bz8/HiJGPz8/Pz8/Bz8/Hj8/Pz8/Pz98FT8/Dh59Pz99fT8/Pwc/CFZqWV0/MD8yP1Q/b1JqVlQ/Kx4NP0AUPwc/Px4/Pz8/Pz8/fAc/Px4CP0s/Pz8/PwY/Bz8/Hj8/Pz8/Pz98Bz8/HiFKPz8/Pz8/Bz8/Hj8/Pz8/Pz98FT8/Pw4efT8/fX0/Pz8HRD8ePz8/Pz8/P3wVPwM/Dh59Pz99fT8/PwU/Pz8/Pwg/Pz8/Pz8/fj8/Pz8/Pz8/Pz8FUj9PPz8/XD8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BT8/WD8RPxA/Px4/Pz8/Pz8/fBU/Uw4IPz8/Pz8/Pz8/P38/fz8/Pz9/Pz8/Pz8/Hmd0clsHPz8efT8/fX0/Pz8HPz8fPz8/FT8/VQooFTA/Az8OHn0/P319Pz8/B2g/Hj8/Pz8/Pz98FSw/PwooFTA/Az8OHn0/P319Pz8/Bz8/CE9pXFI/Lh4VP0AOPwc/Px4/Pz8/Pz8/fAc/Px4iRj8/Pz8/Pwc/Px4/Pz8/Pz8/fBU/Pw4eIT0iCD8HPx4KPz8/Pz8/Cz8HPx8HPy8iFT8/Pwg/cz9dPz8/Pz8/Pz8/f38/fj8/Pz8/Pz9RP0g/RB4JP0g4Fz8HQQg/tz8/Hg8/LQ4/Jj8HPx8nPywOPw8/CD8lP0Y/YQc6Hn0/P319Pz8/By4/CD8/Pz8/Pz8/PxU2Pz8/DgY/Hz8/P35/Pz9/B1RZCFE/XXtubnFxfWc/Xj9yP3g/ej8/Pz8/Pz8/Pz8/Pz8/Pz8/Px4/PwY/Mz8ffj8/Pz8/Pz8HMz9QPx4/Pz8/Pz8/fRU/Dz8/Pw4IPz8/Px4aPyAIPzM/Bz8fKD8KPyMePyM/Cj8wJj8/Pz8/BiQ/CBM/PzA/Jz9CbVhjYj8/Pz8/Pz9+Pz8/Pz8/Pz8/PxVkPz8IJD8sPz8JPz8/BT8/FT8/Aj9rDgonFVo/Pz8ePz8/Pz8/P3wHLgg/Pz8/Hg8/KBE/Oj8HPx86PyYRPw8/CD8lP0k/YQc/Px58Pz99fT8/PxVZPz8/Dh4nPw4/BT8jPwc/HyM/ED8GPyY/CD8zP1E/XT8/Pz8/Pz8/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YUE/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8VNj8/PwA/DgogFQ8/awg/Pz8/fz8FFT8/CH4/Pz8/fD8EP1Q+Kj8HPx85Rj8/CD8/Pz8/Pz8/Pz8/Pz8/fj8/Pz8/Pz9MVl5HPyYeGD82Pwc/CBA/Pz8/CD8FAz8/CD8/Pz8/PxVHPz8/OQ4IPz8/Pz8/BWw/ND8IP34/Pz8/Bz8IPz8/Pz8/BWw/ND8IPz8/Pz8/Pz8/P34/Pz8/Pz8/BVw/Gz9ePxs/CD8/Pz8/Px9+Pz9+FT8/Az8/DgolBHU/CiUVSz8/Dgg/Pz8/Pz8FbD80Pwg/Pz8/Pz8HPwg/Pz8/P34FbD80Pwg/Pz8/Pz8/fj8/Pz8/Pz8/Pz8FXD8bP14/Gz8IPz8/Pz8/Hz8/Pz8VPz8/Pw4KJBU/P28KIBV1Pww/DgogBD0/CiAVdT8MPw4eCz8xPzMHPx4oPD8IPwc/Pz8HPx8/PzwDPxU/Pz8IP2k/YD8IPz8/Pz8/fT9/Pz99Pz8/Pz8/P1U/Vj9PPyE/Kz8oZj8/Pz8/Aj8eIT8tPww/Bz8fFT8hJyY/CD9AP04/YT9VP2kgPz8HPx9wPzI/Dj83PxV/Pz8/Dh4VP0Y+PAc/HjRMPwY/Bj8/Pwc/Hz8/PhU/BD8/HihRODUHPx48Uj8/Pz8/Pwc/Hz8/OCgEGz8eJz86BT8IPwc/CDk/TUhuM28/Vz84Pwc/HgE/QQc/DT8NPwc/AT8HPwg/Pz8/PzM/SD8/Bz8fCD8FPyc/FT8/Pw4IPz8/Pz8/BT8/Pz8/FT8fPz8/fX0/P30GOj8efT8/Pwg/Pz8/Pz8FFz8/CD8/Pz8/Px4/Pz99FT89P24OHgU/OUEoBz8eK0M/Az8HPz8/Bz8fPz82BT8VPz8IP28/YT9RP0U/JT8/Bz8fZz88PwM/Qj8IP0E/Uj9TCD8/Pz8/Pz8/Pz8/Pz8/Pz8/P2I/dT8/PyI/KT9qPz9HY01KPwY/HhM/Bj8RPwc/Hxg/Px4/FX8/Pz8OCD9eP1Q/Pz8/Pz8/fz9/Pz99Pz8/Pz/GUD9HP0UeAz9APiYHPx8oSD8FPwg/Pz8/Pz8/Pz8/Pz8/fj98PwU/P3oIeD8/fz99Bj8/H30/Pz8/Pz8/BT8/Pz8/CHVee14/Sh4bPyIRPwc/HxU/PyE/FX8/Pz8OBTI/PzI/PxU/PwYHPx4/Pz97CD8/Pz8/PwVxPxY/CD8/Pz8/fx56P38/BmQ/LB9/Pz8/Pz8/Pwc/Kj8ePz8/Pz8/P30VP1E/Pw4IPwE/Wz9HPz8/Pz8/P30/f38/fT8/Pz8/P1Q/SD8zHi1MPC8HPx8pVT8SPwY/Hj8/P34IPz8/Pz8/BT8/ej8/Hz8/P319Pz99BiI/Hn4/Pz8IPz8/Pz8/BT8/fD8IPxk/Bz8UPz8HPx8OPz8NPxV/Pz8/Dgg/Pz8/Pz8FeT8/PwgiCD9PZEE/CDA/UD8/Pz8/Pz8/Pz8/Pz8/Pz9+Pz8/Pz8/PzVQV0s/Cj8eCz8yAT8HPwg/Pz8EPw8/BVY/aj8/Cz8ffT8/Pz8/Pz8GSD8ePz8/fRU/P3EOBT8GPwg/Pz8/Pz8/Pz8/fz9/Pz8/Pz8FXg4/CD8/Pz8/PwY/Hns/Pz8HKD8ePz8/Pz9/P30VP0c/Pz8OHiU/Kz8xNj8HPx43Pyw/JT8lPyo/Nz8HPx82Py0/LyU/FT8/HkY/Oz8DP1U/Bz8eVT89PwU/Rj9GPzs/Az9VPwc/H1U/PT8FP0Y/FX8/Dgg/Pz8/Pz8FCj9YPwg/Pz8/Pz8/fz8/Pz8/Pz8/Pz8FCj9YPwg/Pz8/Pz8ePz8/fxUDPz8IPw4KIBU/Pw4fP34/fHx+fnwGcD8ffD9+Pz8/Pz8GcD8VP2Q/DgokFTE/DgZZPx8/Pz9+fj8/fgdZP1Y/Hn0/P319Pz8/BlY/WT8ffj8/Pz8/Pz8HWT9WPx4/Pz8/Pz8/fRUaPz8/Pw4FPz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BVokWj8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BT8wAT8/CH8/Pz8/fz9/Pz8/PwUBPz9NMAg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8FPz8kCD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwVNPwE/Pwg/Pz8/Pz8/Pz8/fz8VPD9XP04/Dgg/Pz8/Pz8/Pz8/Pz8rKz8VPzY4Pz84Pz8VPysrPwg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz0/JT8oRz8/Rz8/JT8/PT8/Pz8/Pz8VHz9OPw4IPz8/Pz8/KD0/JT9HPz9HPz8lPygoPT8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8rPxU/OD8/OD8/FT82Pys/Pz8/Pz8/Hz8/Pz8VHz8/Tj8OCiEVYT8OCD89YUhHUQVqP2M/CD8DPz8/Bz8fPz9HKxUKP3cIaydaWEk/Bz8eTVs/Pz8/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AG4AIAB5AGEAbQAgAHUAbwB5ACAALABzAHQAcwBpAHgAZQAgAHQAbgBlAG0AZQBlAHIAZwBhACAAaABjAHUAcwAgAG8AbgAgAGYASQAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIABkAG4AYQAgAHUAbwB5ACAAbgBlAGUAdwB0AGUAYgAgAHMAdABzAGkAeABlACAAdABhAGgAdAAgAHQAbgBlAG0AZQBlAHIAZwBhACAAZQBjAGkAdgByAGUAUwAgAGYAbwAgAHMAbQByAGUAVAAgAGUAaAB0ACAAbwB0ACAAdABjAGUAagBiAHUAcwAgAHMAaQAgAGUAcgBhAHcAdABmAG8AcwAgAHMAaQBoAHQAIABlAHMAdQAgAG8AdAAgAHQAaABnAGkAcgAgAHIAdQBvAFkAIAAuAG4AbwBpAHQAYQBjAG8AbAAgAHkAbgBhACAAbQBvAHIAZgAgAHQAaQAgAHQAcwBvAGgAIAByAG8AIAAsAHIAZQB0AHUAcABtAG8AYwAgAHkAbgBhACAAbgBvAHAAdQAgAHQAaQAgAGwAbABhAHQAcwBuAGkAIAByAG8AIAAsAGUAcgBhAHcAdABmAG8AcwAgAHMAaQBoAHQAIABkAGEAbwBsAG4AdwBvAGQAIAByAG8AIAAsAGUAdAB1AGIAaQByAHQAcwBpAGQAIAAsAHkAZgBpAGQAbwBtACAALAB5AHAAbwBjACAAdABvAG4AIAB5AGEAbQAgAHUAbwBZACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGYAbwAgAHkAdAByAGUAcABvAHIAcAAgAGUAaAB0ACAAcwBpACAAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAVAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIAC4AcwBuAG8AaQB0AGMAaQBkAHMAaQByAHUAagAgAG4AaQBhAHQAcgBlAGMAIABuAGkAIABkAGUAcgBlAHQAcwBpAGcAZQByACAAZQBiACAAeQBhAG0AIABoAGMAaQBoAHcAIAAsAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIABmAG8AIABrAHIAYQBtAGUAZABhAHIAdAAgAGEAIABzAGkAIABkAGUAZABuAHUAbwBSACAAbQBhAGgAdABvAEcAdABuAG8ARgAxADAAMgAu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)); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/BC699FA675F9356E3.css b/docs/static/fonts/332720/BC699FA675F9356E3.css deleted file mode 100644 index fc6add2211..0000000000 --- a/docs/static/fonts/332720/BC699FA675F9356E3.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/C32E9F0C757C29D4A.css b/docs/static/fonts/332720/C32E9F0C757C29D4A.css deleted file mode 100644 index 96c8c1f725..0000000000 --- a/docs/static/fonts/332720/C32E9F0C757C29D4A.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,T1RUTwANAIAAAwBQQ0ZGILkPphQAABIUAAAk2kdERUYAkAAEAAA28AAAACBHUE9TuESiiwAANxAAABwCR1NVQunFLUgAAFMUAAAAgE9TLzJVxiUrAAABQAAAAGBjbWFw0U4uVAAADVwAAASYZ2FzcAAAAAsAAFOUAAAACGhlYWQDcke+AAAA3AAAADZoaGVhB74DqgAAARQAAAAkaG10eNbiGPsAAFOcAAABjG1heHAAY1AAAAABOAAAAAZuYW1lKDUzBAAAAaAAAAu7cG9zdP+4ADIAABH0AAAAIAABAAAAAQBBj0s7+V8PPPUACwPoAAAAANAsAh8AAAAA0CwCH//o/zgEEwMiAAAACAACAAAAAAAAAAEAAAPA/xAAAARO/+j/6AQTAAEAAAAAAAAAAAAAAAAAAABjAABQAABjAAAAAgIsASwABQAEArwCigAAAIwCvAKKAAAB3QAyAPoAAAAAAAAAAAAAAACgAAB/UAAASgAAAAAAAAAASCZDbwAAACPgEgMg/zgAyAPAAPAAAAALAAAAAAH+ArwAIAAgAAIAAAAkAbYAAQAAAAAAAABAAAAAAQAAAAAAAQAjAEAAAQAAAAAAAgAHAGMAAQAAAAAAAwAhAGoAAQAAAAAABAAjAEAAAQAAAAAABQANAIsAAQAAAAAABgAEAJgAAQAAAAAABwBhAJwAAQAAAAAACAANAP0AAQAAAAAACQANAP0AAQAAAAAACgIRAQoAAQAAAAAACwASAxsAAQAAAAAADAASAxsAAQAAAAAADQIRAQoAAQAAAAAADgAqAy0AAQAAAAAAEAAjAEAAAQAAAAAAEQAjAEAAAQAAAAAAEgAjAEAAAwABBAkAAACAA1cAAwABBAkAAQBGA9cAAwABBAkAAgAOBB0AAwABBAkAAwBCBCsAAwABBAkABABGA9cAAwABBAkABQAaBG0AAwABBAkABgAIBIcAAwABBAkABwDCBI8AAwABBAkACAAaBVEAAwABBAkACQAaBVEAAwABBAkACgQiBWsAAwABBAkACwAkCY0AAwABBAkADAAkCY0AAwABBAkADQQiBWsAAwABBAkADgBUCbEAAwABBAkAEABGA9cAAwABBAkAEQBGA9cAAwABBAkAEgBGA9dDb3B5cmlnaHQgKEMpIDIwMDYsIDIwMDcgSG9lZmxlciAmIENvLiBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tQ29weXJpZ2h0IChDKSBIJkNvIHwgdHlwb2dyYXBoeS5jb21SZWd1bGFyMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5VmVyc2lvbiAxLjIwMUZvbnRHb3RoYW0gUm91bmRlZCBpcyBhIHRyYWRlbWFyayBvZiBIb2VmbGVyICYgQ28uLCB3aGljaCBtYXkgYmUgcmVnaXN0ZXJlZCBpbiBjZXJ0YWluIGp1cmlzZGljdGlvbnMuSG9lZmxlciAmIENvLlRoaXMgc29mdHdhcmUgaXMgdGhlIHByb3BlcnR5IG9mIEhvZWZsZXIgJiBDby4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBvciBkb3dubG9hZCB0aGlzIHNvZnR3YXJlLCBvciBpbnN0YWxsIGl0IHVwb24gYW55IGNvbXB1dGVyLCBvciBob3N0IGl0IGZyb20gYW55IGxvY2F0aW9uLiBZb3VyIHJpZ2h0IHRvIHVzZSB0aGlzIHNvZnR3YXJlIGlzIHN1YmplY3QgdG8gdGhlIFRlcm1zIG9mIFNlcnZpY2UgYWdyZWVtZW50IHRoYXQgZXhpc3RzIGJldHdlZW4geW91IGFuZCBIb2VmbGVyICYgQ28uIElmIG5vIHN1Y2ggYWdyZWVtZW50IGV4aXN0cywgeW91IG1heSBub3QgdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpc2l0IGh0dHA6Ly93d3cudHlwb2dyYXBoeS5jb20vd2ViZm9udC1zb2Z0d2FyZSwgb3IgY29udGFjdCBIb2VmbGVyICYgQ28uIGF0IHd3dy50eXBvZ3JhcGh5LmNvbSAxNzEyNDctODg0NzQtMjAxNTA2MjMtMjQyMy0xNDAyMTl3d3cudHlwb2dyYXBoeS5jb21odHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUAQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgADIAMAAwADYALAAgADIAMAAwADcAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAASAAmAEMAbwAgAHwAIAB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AUgBlAGcAdQBsAGEAcgAxADcAMQAyADQANwAtADgAOAA0ADcANAAtADIAMAAxADUAMAA2ADIAMwAtADIANAAyADMALQAxADQAMAAyADEAOQBWAGUAcgBzAGkAbwBuACAAMQAuADIAMAAxAEYAbwBuAHQARwBvAHQAaABhAG0AIABSAG8AdQBuAGQAZQBkACAAaQBzACAAYQAgAHQAcgBhAGQAZQBtAGEAcgBrACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAsACAAdwBoAGkAYwBoACAAbQBhAHkAIABiAGUAIAByAGUAZwBpAHMAdABlAHIAZQBkACAAaQBuACAAYwBlAHIAdABhAGkAbgAgAGoAdQByAGkAcwBkAGkAYwB0AGkAbwBuAHMALgBIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuAFQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIAB0AGgAZQAgAHAAcgBvAHAAZQByAHQAeQAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABZAG8AdQAgAG0AYQB5ACAAbgBvAHQAIABjAG8AcAB5ACwAIABtAG8AZABpAGYAeQAsACAAZABpAHMAdAByAGkAYgB1AHQAZQAsACAAbwByACAAZABvAHcAbgBsAG8AYQBkACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAsACAAbwByACAAaQBuAHMAdABhAGwAbAAgAGkAdAAgAHUAcABvAG4AIABhAG4AeQAgAGMAbwBtAHAAdQB0AGUAcgAsACAAbwByACAAaABvAHMAdAAgAGkAdAAgAGYAcgBvAG0AIABhAG4AeQAgAGwAbwBjAGEAdABpAG8AbgAuACAAWQBvAHUAcgAgAHIAaQBnAGgAdAAgAHQAbwAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHMAdQBiAGoAZQBjAHQAIAB0AG8AIAB0AGgAZQAgAFQAZQByAG0AcwAgAG8AZgAgAFMAZQByAHYAaQBjAGUAIABhAGcAcgBlAGUAbQBlAG4AdAAgAHQAaABhAHQAIABlAHgAaQBzAHQAcwAgAGIAZQB0AHcAZQBlAG4AIAB5AG8AdQAgAGEAbgBkACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAEkAZgAgAG4AbwAgAHMAdQBjAGgAIABhAGcAcgBlAGUAbQBlAG4AdAAgAGUAeABpAHMAdABzACwAIAB5AG8AdQAgAG0AYQB5ACAAbgBvAHQAIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABmAG8AcgAgAGEAbgB5ACAAcAB1AHIAcABvAHMAZQAuACAARgBvAHIAIABtAG8AcgBlACAAaQBuAGYAbwByAG0AYQB0AGkAbwBuACwAIABwAGwAZQBhAHMAZQAgAHYAaQBzAGkAdAAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0ALwB3AGUAYgBmAG8AbgB0AC0AcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABjAG8AbgB0AGEAYwB0ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGEAdAAgAHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtACAAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAvAHcAZQBiAGYAbwBuAHQALQBzAG8AZgB0AHcAYQByAGUAAAAAAwAAAAMAAAAcAAEAAAAAA5IAAwABAAAAHAAEA3YAAACsAIAABgAsACAAIwAvADQANwA/AEQARwBNAF0AXwBjAHEAdAB2AHkAfQCjAKUAqwCuALAAtwC7AMUAxwDWAN0A5QDvAPYA+AD9AQcBDgEQARMBFQEXARkBGwEjAScBKwEtAS8BMQE3AUIBRAFGAUgBUQFUAVYBWAFaAV4BYAFlAWoBbAFuAXABcgF0AXkBewF9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/+cAAAAAAAAAAAAAAAD/8QAA/5z/9v+cAAAAAP/2AAD/8QAAAAAAAAAAAAAAAAAAAAAAFAAA//YAAAAAAAAAAAAAAAD/9gAA//H/8QAAAAAAAAAAAAAAAP/sAAD/7P/x//b/4gAAAAoAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAAAA//sAAAAAAAD/5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/OAAD/9v/2//H/4v/iAAD/2AAA//b/9gAAAAAAAAAAAAD/4gAAAAD/5wAA/87/7P/n/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAP/s/8T/zgAA/84AAAAAAAAAAP/YAAAAAP+c/+z/jf+cAAD/fgAAAAD/9v+wAAD/iAAAAAD/9gAAAAD/+wAA/9j/7P/7AAAAAAAAAAAAAAAAAAD/xAAA/9j/2P+mAAAAAAAA/+wAAAAA/8T/zgAA/8QAAAAAAAD/2AAA/+L/+//JAAD/2P/d/87/xP/YAAAAAAAAAAD/2P/s/+wAAAAA/9gAAP/YAAAAAAAAAAAAAAAAAAAAAAAA/+L/7AAAAAAAAAAAAAAAAP/YAAAAAAAAAAAAAP/7AAAAAAAAAAD/ugAAAAAAAAAAAAAAAP/7AAD/9v/x//YAAAAAAAAAAAAAAAD/+wAA/5wAAP+cAAAADwAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAA8AAAAFAAAACgAAAAoAAAAAAAAAAAAAAAAAAP/JAAAAAP/dAAD/vwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAP/2AAD/7P/xAAD/5wAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+wAAAAAACv/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/9v/xAAD/4v/n/+f/4v/2AAAAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAD/+wAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAA//sAAAAA//H/9v/x//H/+wAAAAD/pv/J/5L/8QAAAAAAAAAAAAAAAP/s/3n/ugAA/+wAAAAAAAD/ef/O/5z/g/+c/6b/zv+D/6b/uv/Y/9j/nAAAAAAAAAAAAAAAAAAA/40AAP+m/84AAP+c/5z/nP+c/5z/kgAAAAD/5wAA/+wAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAP/7AAAAAAAAAAD/nP/YAAD/5wAAAAAAAP/2AAD/7P/2/7oAAAAA//YAAAAAAAD/uv/s/4j/v/+I/9j/5/+//8T/2P/sAAD/2AAAAAAAAAAAAAAAAAAA/8QAAAAA/+wAAP/YAAD/3QAA/9j/yQAAAAD/pv/d/5f/7AAAAAD/9v/2//H/7P/2/7r/0wAA//YAAAAAAAD/v//x/5z/xP+c/93/4v/E/87/3f/x//H/3QAAAAAAAAAAAAAAAAAA/8QAAP+c/+cAAP/d/93/3f/Y/93/yQAAAAAAAP/OAAD/4gAA//YAAP/xAAD/7AAA//YAAAAA//YAAAAAAAD/0wAAAAD/2AAA/87/7P/Y/87/7P/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP/sAAD/2AAA/9gAAAAAAAD/kv/E/37/3QAAAAD/7P/s/+wAAP/2/5z/ugAA//YAAAAAAAD/kv/Y/37/l/9+/7D/2P+X/5z/tf/s/+z/tQAAAAAAAAAAAAAAAAAA/5wAAP+S/+IAAP+1/8T/yf+6/8T/sAAAAAAAAP/YAAD/9gAAAAAAAAAAAAAAAP/2AAD/8QAAAAAAAAAAAAD/5wAAAAD/7AAA/+L/9v/s/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+z/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/3QAAAAAAAAAAAAAAAAAA//sAAAAA/+z/7AAA/+wAAAAAAAAAAAAAAAD/9v+mAAAAAP/OAAD/ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/nAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/7AAAAAD/8QAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/uv/x/+wAAAAA//YAAP/2AAAAAAAAAAD/+wAAAAAAAAAA/+L/3QAA//YAAAAAAAAAAAAAAAAAAAAA/+f/7P/i/+f/8QAAAAAAAP/YAAAAAP+m//EAAP+cAAD/kgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAD/xAAA/8QAAAAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/8QAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/9gAA//b/9gAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/7AAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAD/7AAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/8QAAAAD/9gAAAAAAAP/2//YACgAAAAAAAAAA//H/8QAAAAoADwAAAAAAAAAAAAAAAAAA//v/+//2//sAAAAAAAAAAAAAAAAAAP/OAAD/7P/xAAD/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/YAAAAAP+c//H/iP+cAAD/fgAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/9gAAAAD/8f/2AAAAAAAAAA8AAP/OAAAAAAAAAAD/2AAAAAD/7AAA/+cAAAAA/6v/ugAA/9MAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/sP/2/+wAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAA/+L/2AAAAAAAAAAAAAAAAAAAAAAAAAAA/+f/5//i/+f/8QAAAAAAAP/YAAAAAP+c//H/iP+cAAD/fgAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/9gAAAAD/8f/2AAAAAAAAAAAAAP/OAAAAAAAAAAD/2AAAAAD/7AAA/+cAAAAA/6v/ugAA/8QAAP/sAAD/2AAAAAAAAP+mAAD/2P/d/87/sP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAD/2AAAAAD/9gAA//H/9v/i//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAeAAAAHgAeABT/9gAA/9P/9v/TAAAAAP/2//EAAAAAAAAAAAAAAB4AIwAAAB4AIwA3AAAAAP/TAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+6AAD/2P/d/+z/tQAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+wAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//H/9v/x//EAAAAAAAD/7AAAAAD/9v+mAAD/xP/O/87/nP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAA//YAAAAA/+L/7P/T/+L/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAAAA/+z/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAD/2AAAAAD/5wAAAAD/5wAA/+wAAP/n/+z/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/2/+z/7AAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/sP/x/+wAAAAA/+wAAP/sAAAAAAAAAAD/9gAAAAAAAAAA/+L/zgAA/+wAAAAAAAAAAAAAAAAAAAAA/+L/5//d/+L/7AAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAD/4gAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAAAAP/E//EAAP/OAAD/ugAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAD/3QAA/90AAAAAAAD/pgAA/7AAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/8QAAAAD/8QAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAP/dAAAAAAAA//YAAAAAAA8AAAAAAAAAAAAAAAD/9gAAAAD/nAAA/5wAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/0wAAAAD/2AAAAAAAAP/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAUAAD/4gAAAAD/5wAA/6b/5/+mAAAAAP/n//YAAAAAAAAAAAAAAAAAAAAAABQAIwAAAAAAAP+1AAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/tf/2//EAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAA/+z/3QAA//YAAAAA//YAAAAA//YAAAAA/+z/8f/n//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5wAAP+c/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/iP/YAAD/4gAAAAAAAAAAAAAAAP/s/78AAAAAAAAAAAAAAAD/sAAAAAD/ugAAAAD/5/+6AAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAA/6sAAAAA/+wAAP/OAAD/zgAA/87/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/8QAAAAD/8QAAAAAAAP/x//YAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAAAAAAAAAD/4gAA/6v/5/+r//EAAP/n/+L/8QAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/8QAA//H/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAD/zv/2/+z/5wAA/7r/7P+6//YAAP/s/+z/9gAAAAAAAAAAAAD/9gAAAAAAAAAA//EAAP/EAAAAAAAA//H/9v/2//b/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAD/3QAAAAD/4gAA/+IAAP/i/9P/8QAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAD/zv/2/+z/4gAA/6v/5/+r//EAAP/n/+L/8QAAAAAAAAAAAAD/9gAAAAAAAAAA/+wAAP+6AAAAAAAA//H/9v/2//b/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/0wAAAAD/8QAAAAD/8QAAAAAAAP/x//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEABQBbABgAAAAsAAAAGQAAACAAIwAiADMAAAAyAB8AHwAAAAAAAAAAAAEAAgADAAQABgAHAAgACQAKAAAACwAMAA0ADgAPABAAEQASABMAFAAVABYAHQAbAAAAAAAXABoAHgAhACQAJQAoAAAAAAApAAAAKAAoACsAGgAAADQANgA4ADkAHAAAAAAAAAAAAAAAAAAAACYAAAAAAAAAAAAnAC0AIwAjAC4ALwAgAC4ALwAgAAAAIgAmACcAAQAFAF0ADQAAAAAAIQAOAAAAFQAYABcAKQAAACgAFAAUAAAAAAAAACIAAQAAAAIAAAAAAAIAAwAAAAAAAAACAAAAAgAAAAQABQAGAAcACAAJAAoACwAAABAAEgAAAAwADwATABMAGQAaAA8AHQAeAA8ADwAfAB8AEwAfABYAKgAtAC8AMAAAAAAAEQAAAAAAAAAAAAAAGwAmAAAAAAAAABwAIwAYABgAJAAlABUAJAAlABUAAAAXABsAHAAAACYAAgAOAAUABQAAAAcABwABAAkACQACAAsADgADABAAEgAHABcAHwAKACEALgATADEANwAhADoAOgAoADwAPwApAEEARQAtAE0ATQAyAFIAWwAzAF0AXwA9AAEACAABAAAAAQABAAEAAAABAAAACgAwAD4AAkRGTFQADmxhdG4AGgAEAAAAAP//AAEAAAAEAAAAAP//AAEAAAABc3MwMQAIAAAAAQAAAAIABgAOAAYAAAABABAAAQAAAAEAKAABAAgAAQAOAAEAAQBiAAEABAABAGIAAQAAAAEAAAABAAEABv+fAAEAAQBiAAEAAf//AAoB9AAAASwAAAGaAEUCvAAtAzgANwK4ADEA5gBFAa4ARwGuADwBrgBMAmwAQADmADYBmABCAOYAUgH0//oCmAAvAksAQADwAFcA8AA7AmwAPAJsAE8CbABZAhYAJQMWADgC0gBoAuIASQMOAGgCkABoAxAASQIlACoCywBoAmsAaANkAGgDUgBJApwAaANSAEkC0wBoAoAAQQKIADIC+ABdAu4AOAROADwC0gBJAswANgKwAEcBrgBiAfQACQGuADcCWP/oAj4AMwKUAF0COwA6AkgAOgFqAC0ClAA8AmUAXQD5AF4A+f/7AjAAXQD5AGQDtwBdAmUAXQKAADoClABdApQAPAGQACoCRgA1AjoAQwJMADQB4AA3AR4AeQHgADUCRQA+AoQAQgKuADUDPgA1AYYAOgIDADcBoAAiAcIASgDmAFIBhgAvAgMAQwIWADQCEABCA4IAQgDmAE0A5gA7AOYANgGaAE0BmgA7AZoANgHWAG8CqABSATcANwE3AEMC0AA3ArIAFgK2ADI=); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:font/opentype;base64,T1RUTwALAIAAAwAwQ0ZGIE+2i2MAABCYAAAOb0dERUYASAAEAAAfCAAAACBPUy8yVcclSwAAASAAAABgY21hcO62ywIAAA08AAADOmdhc3AAAAALAAAfKAAAAAhoZWFkAxZHvAAAALwAAAA2aGhlYQdhAwAAAAD0AAAAJGhtdHg9xwbVAAAfMAAAAGxtYXhwABtQAAAAARgAAAAGbmFtZSg1MwQAAAGAAAALu3Bvc3T/uAAyAAAQeAAAACAAAQAAAAEAQS6s5cVfDzz1AAsD6AAAAADQLAIfAAAAANAsAh8AAP84A58DIAAAAAgAAgAAAAAAAAABAAADwP8QAAAD1AAAAAADnwABAAAAAAAAAAAAAAAAAAAAGwAAUAAAGwAAAAICTQEsAAUABAK8AooAAACMArwCigAAAd0AMgD6AAAAAAAAAAAAAAAAoAAAf1AAAEoAAAAAAAAAAEgmQ28AAAAk4BIDIP84AMgDwADwAAAACwAAAAAB/gK8ACAAIAABAAAAJAG2AAEAAAAAAAAAQAAAAAEAAAAAAAEAIwBAAAEAAAAAAAIABwBjAAEAAAAAAAMAIQBqAAEAAAAAAAQAIwBAAAEAAAAAAAUADQCLAAEAAAAAAAYABACYAAEAAAAAAAcAYQCcAAEAAAAAAAgADQD9AAEAAAAAAAkADQD9AAEAAAAAAAoCEQEKAAEAAAAAAAsAEgMbAAEAAAAAAAwAEgMbAAEAAAAAAA0CEQEKAAEAAAAAAA4AKgMtAAEAAAAAABAAIwBAAAEAAAAAABEAIwBAAAEAAAAAABIAIwBAAAMAAQQJAAAAgANXAAMAAQQJAAEARgPXAAMAAQQJAAIADgQdAAMAAQQJAAMAQgQrAAMAAQQJAAQARgPXAAMAAQQJAAUAGgRtAAMAAQQJAAYACASHAAMAAQQJAAcAwgSPAAMAAQQJAAgAGgVRAAMAAQQJAAkAGgVRAAMAAQQJAAoEIgVrAAMAAQQJAAsAJAmNAAMAAQQJAAwAJAmNAAMAAQQJAA0EIgVrAAMAAQQJAA4AVAmxAAMAAQQJABAARgPXAAMAAQQJABEARgPXAAMAAQQJABIARgPXQ29weXJpZ2h0IChDKSAyMDA2LCAyMDA3IEhvZWZsZXIgJiBDby4gaHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbUNvcHlyaWdodCAoQykgSCZDbyB8IHR5cG9ncmFwaHkuY29tUmVndWxhcjE3MTI0Ny04ODQ3NC0yMDE1MDYyMy0yNDIzLTE0MDIxOVZlcnNpb24gMS4yMDFGb250R290aGFtIFJvdW5kZWQgaXMgYSB0cmFkZW1hcmsgb2YgSG9lZmxlciAmIENvLiwgd2hpY2ggbWF5IGJlIHJlZ2lzdGVyZWQgaW4gY2VydGFpbiBqdXJpc2RpY3Rpb25zLkhvZWZsZXIgJiBDby5UaGlzIHNvZnR3YXJlIGlzIHRoZSBwcm9wZXJ0eSBvZiBIb2VmbGVyICYgQ28uIFlvdSBtYXkgbm90IGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgb3IgZG93bmxvYWQgdGhpcyBzb2Z0d2FyZSwgb3IgaW5zdGFsbCBpdCB1cG9uIGFueSBjb21wdXRlciwgb3IgaG9zdCBpdCBmcm9tIGFueSBsb2NhdGlvbi4gWW91ciByaWdodCB0byB1c2UgdGhpcyBzb2Z0d2FyZSBpcyBzdWJqZWN0IHRvIHRoZSBUZXJtcyBvZiBTZXJ2aWNlIGFncmVlbWVudCB0aGF0IGV4aXN0cyBiZXR3ZWVuIHlvdSBhbmQgSG9lZmxlciAmIENvLiBJZiBubyBzdWNoIGFncmVlbWVudCBleGlzdHMsIHlvdSBtYXkgbm90IHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSB2aXNpdCBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUsIG9yIGNvbnRhY3QgSG9lZmxlciAmIENvLiBhdCB3d3cudHlwb2dyYXBoeS5jb20gMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5d3d3LnR5cG9ncmFwaHkuY29taHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbS93ZWJmb250LXNvZnR3YXJlAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMAA2ACwAIAAyADAAMAA3ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgAEgAJgBDAG8AIAB8ACAAdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAFIAZQBnAHUAbABhAHIAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAVgBlAHIAcwBpAG8AbgAgADEALgAyADAAMQBGAG8AbgB0AEcAbwB0AGgAYQBtACAAUgBvAHUAbgBkAGUAZAAgAGkAcwAgAGEAIAB0AHIAYQBkAGUAbQBhAHIAawAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4ALAAgAHcAaABpAGMAaAAgAG0AYQB5ACAAYgBlACAAcgBlAGcAaQBzAHQAZQByAGUAZAAgAGkAbgAgAGMAZQByAHQAYQBpAG4AIABqAHUAcgBpAHMAZABpAGMAdABpAG8AbgBzAC4ASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgBUAGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAaQBzACAAdABoAGUAIABwAHIAbwBwAGUAcgB0AHkAIABvAGYAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAWQBvAHUAIABtAGEAeQAgAG4AbwB0ACAAYwBvAHAAeQAsACAAbQBvAGQAaQBmAHkALAAgAGQAaQBzAHQAcgBpAGIAdQB0AGUALAAgAG8AcgAgAGQAbwB3AG4AbABvAGEAZAAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUALAAgAG8AcgAgAGkAbgBzAHQAYQBsAGwAIABpAHQAIAB1AHAAbwBuACAAYQBuAHkAIABjAG8AbQBwAHUAdABlAHIALAAgAG8AcgAgAGgAbwBzAHQAIABpAHQAIABmAHIAbwBtACAAYQBuAHkAIABsAG8AYwBhAHQAaQBvAG4ALgAgAFkAbwB1AHIAIAByAGkAZwBoAHQAIAB0AG8AIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIABzAHUAYgBqAGUAYwB0ACAAdABvACAAdABoAGUAIABUAGUAcgBtAHMAIABvAGYAIABTAGUAcgB2AGkAYwBlACAAYQBnAHIA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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/CB3CA0F49552DA871.css b/docs/static/fonts/332720/CB3CA0F49552DA871.css deleted file mode 100644 index e78c24bb17..0000000000 --- a/docs/static/fonts/332720/CB3CA0F49552DA871.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/truetype;base64,AAACAAAABAABABwAAQABAAIAAAAAABgAAAAOAAAAAQAKAD8/AQABAGd1bHNvY2gHAgE/AF0AWgBYAFYAVQBSAEcAOwAxACwAKwAoACMAHAAbABkAGAAWABUAFAATAAcABAADAAIAAQAAAB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAyAD8/AAAAAAAAAgAAZQByAGEAdwB0AGYAbwBzAC0AdABuAG8AZgBiAGUAdwAvAG0AbwBjAC4AeQBoAHAAYQByAGcAbwBwAHkAdAAuAHcAdwB3AC8ALwA6AHAAdAB0AGgAbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcAOQAxADIAMAA0ADEALQAzADIANAAyAC0AMwAyADYAMAA1ADEAMAAyAC0ANAA3ADQAOAA4AC0ANwA0ADIAMQA3ADEAIABtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQALgB3AHcAdwAgAHQAYQAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIAB0AGMAYQB0AG4AbwBjACAAcgBvACAALABlAHIAYQB3AHQAZgBvAHMALQB0AG4AbwBmAGIAZQB3AC8AbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcALwAvADoAcAB0AHQAaAAgAHQAaQBzAGkAdgAgAGUAcwBhAGUAbABwACAALABuAG8AaQB0AGEAbQByAG8AZgBuAGkAIABlAHIAbwBtACAAcgBvAEYAIAAuAGUAcwBvAHAAcgB1AHAAIAB5AG4AYQAgAHIAbwBmACAAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAdAAgAGUAcwB1ACAAdABvAG4AIAB5AGEAbQAgAHUAbwB5ACAALABzAHQAcwBpAHgAZQAgAHQAbgBlAG0AZQBlAHIAZwBhACAAaABjAHUAcwAgAG8AbgAgAGYASQAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIABkAG4AYQAgAHUAbwB5ACAAbgBlAGUAdwB0AGUAYgAgAHMAdABzAGkAeABlACAAdABhAGgAdAAgAHQAbgBlAG0AZQBlAHIAZwBhACAAZQBjAGkAdgByAGUAUwAgAGYAbwAgAHMAbQByAGUAVAAgAGUAaAB0ACAAbwB0ACAAdABjAGUAagBiAHUAcwAgAHMAaQAgAGUAcgBhAHcAdABmAG8AcwAgAHMAaQBoAHQAIABlAHMAdQAgAG8AdAAgAHQAaABnAGkAcgAgAHIAdQBvAFkAIAAuAG4AbwBpAHQAYQBjAG8AbAAgAHkAbgBhACAAbQBvAHIAZgAgAHQAaQAgAHQAcwBvAGgAIAByAG8AIAAsAHIAZQB0AHUAcABtAG8AYwAgAHkAbgBhACAAbgBvAHAAdQAgAHQAaQAgAGwAbABhAHQAcwBuAGkAIAByAG8AIAAsAGUAcgBhAHcAdABmAG8AcwAgAHMAaQBoAHQAIABkAGEAbwBsAG4AdwBvAGQAIAByAG8AIAAsAGUAdAB1AGIAaQByAHQAcwBpAGQAIAAsAHkAZgBpAGQAbwBtACAALAB5AHAAbwBjACAAdABvAG4AIAB5AGEAbQAgAHUAbwBZACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGYAbwAgAHkAdAByAGUAcABvAHIAcAAgAGUAaAB0ACAAcwBpACAAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAVAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIAC4AcwBuAG8AaQB0AGMAaQBkAHMAaQByAHUAagAgAG4AaQBhAHQAcgBlAGMAIABuAGkAIABkAGUAcgBlAHQAcwBpAGcAZQByACAAZQBiACAAeQBhAG0AIABoAGMAaQBoAHcAIAAsAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIABmAG8AIABrAHIAYQBtAGUAZABhAHIAdAAgAGEAIABzAGkAIABtAGEAaAB0AG8ARwB0AG4AbwBGADEAMAAzAC4AMQAgAG4AbwBpAHMAcgBlAFYAOQAxADIAMAA0ADEALQAzADIANAAyAC0AMwAyADYAMAA1ADEAMAAyAC0ANAA3ADQAOAA4AC0ANwA0ADIAMQA3ADEAcgBhAGwAdQBnAGUAUgBtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQAIAB8ACAAbwBDACYASAAgACkAQwAoACAAdABoAGcAaQByAHkAcABvAEMAbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcALwAvADoAcAB0AHQAaAAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIAA3ADAAMAAyACAALAA2ADAAMAAyACAAKQBDACgAIAB0AGgAZwBpAHIAeQBwAG8AQwBlcmF3dGZvcy10bm9mYmV3L21vYy55aHBhcmdvcHl0Lnd3dy8vOnB0dGhtb2MueWhwYXJnb3B5dC53d3c5MTIwNDEtMzI0Mi0zMjYwNTEwMi00NzQ4OC03NDIxNzEgbW9jLnlocGFyZ29weXQud3d3IHRhIC5vQyAmIHJlbGZlb0ggdGNhdG5vYyBybyAsZXJhd3Rmb3MtdG5vZmJldy9tb2MueWhwYXJnb3B5dC53d3cvLzpwdHRoIHRpc2l2IGVzYWVscCAsbm9pdGFtcm9mbmkgZXJvbSByb0YgLmVzb3BydXAgeW5hIHJvZiBlcmF3dGZvcyBzaWh0IGVzdSB0b24geWFtIHVveSAsc3RzaXhlIHRuZW1lZXJnYSBoY3VzIG9uIGZJIC5vQyAmIHJlbGZlb0ggZG5hIHVveSBuZWV3dGViIHN0c2l4ZSB0YWh0IHRuZW1lZXJnYSBlY2l2cmVTIGZvIHNtcmVUIGVodCBvdCB0Y2VqYnVzIHNpIGVyYXd0Zm9zIHNpaHQgZXN1IG90IHRoZ2lyIHJ1b1kgLm5vaXRhY29sIHluYSBtb3JmIHRpIHRzb2ggcm8gLHJldHVwbW9jIHluYSBub3B1IHRpIGxsYXRzbmkgcm8gLGVyYXd0Zm9zIHNpaHQgZGFvbG53b2Qgcm8gLGV0dWJpcnRzaWQgLHlmaWRvbSAseXBvYyB0b24geWFtIHVvWSAub0MgJiByZWxmZW9IIGZvIHl0cmVwb3JwIGVodCBzaSBlcmF3dGZvcyBzaWhULm9DICYgcmVsZmVvSC5zbm9pdGNpZHNpcnVqIG5pYXRyZWMgbmkgZGVyZXRzaWdlciBlYiB5YW0gaGNpaHcgLC5vQyAmIHJlbGZlb0ggZm8ga3JhbWVkYXJ0IGEgc2kgbWFodG9HdG5vRjEwMy4xIG5vaXNyZVY5MTIwNDEtMzI0Mi0zMjYwNTEwMi00NzQ4OC03NDIxNzFyYWx1Z2VSbW9jLnlocGFyZ29weXQgfCBvQyZIIClDKCB0aGdpcnlwb0Ntb2MueWhwYXJnb3B5dC53d3cvLzpwdHRoIC5vQyAmIHJlbGZlb0ggNzAwMiAsNjAwMiApQyggdGhnaXJ5cG9DPwNGABIACQQBAAMAPwNGABEA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))); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:font/truetype;base64,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cmVlbWVudCB0aGF0IGV4aXN0cyBiZXR3ZWVuIHlvdSBhbmQgSG9lZmxlciAmIENvLiBJZiBubyBzdWNoIGFncmVlbWVudCBleGlzdHMsIHlvdSBtYXkgbm90IHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSB2aXNpdCBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUsIG9yIGNvbnRhY3QgSG9lZmxlciAmIENvLiBhdCB3d3cudHlwb2dyYXBoeS5jb20gMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5d3d3LnR5cG9ncmFwaHkuY29taHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbS93ZWJmb250LXNvZnR3YXJlAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMAA2ACwAIAAyADAAMAA3ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgAEgAJgBDAG8AIAB8ACAAdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAFIAZQBnAHUAbABhAHIAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAVgBlAHIAcwBpAG8AbgAgADEALgAzADAAMQBGAG8AbgB0AEcAbwB0AGgAYQBtACAAaQBzACAAYQAgAHQAcgBhAGQAZQBtAGEAcgBrACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAsACAAdwBoAGkAYwBoACAAbQBhAHkAIABiAGUAIAByAGUAZwBpAHMAdABlAHIAZQBkACAAaQBuACAAYwBlAHIAdABhAGkAbgAgAGoAdQByAGkAcwBkAGkAYwB0AGkAbwBuAHMALgBIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuAFQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIAB0AGgAZQAgAHAAcgBvAHAAZQByAHQAeQAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABZAG8AdQAgAG0AYQB5ACAAbgBvAHQAIABjAG8AcAB5ACwAIABtAG8AZABpAGYAeQAsACAAZABpAHMAdAByAGkAYgB1AHQAZQAsACAAbwByACAAZABvAHcAbgBsAG8AYQBkACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAsACAAbwByACAAaQBuAHMAdABhAGwAbAAgAGkAdAAgAHUAcABvAG4AIABhAG4AeQAgAGMAbwBtAHAAdQB0AGUAcgAsACAAbwByACAAaABvAHMAdAAgAGkAdAAgAGYAcgBvAG0AIABhAG4AeQAgAGwAbwBjAGEAdABpAG8AbgAuACAAWQBvAHUAcgAgAHIAaQBnAGgAdAAgAHQAbwAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHMAdQBiAGoAZQBjAHQAIAB0AG8AIAB0AGgAZQAgAFQAZQByAG0AcwAgAG8AZgAgAFMAZQByAHYAaQBjAGUAIABhAGcAcgBlAGUAbQBlAG4AdAAgAHQAaABhAHQAIABlAHgAaQBzAHQAcwAgAGIAZQB0AHcAZQBlAG4AIAB5AG8AdQAgAGEAbgBkACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAEkAZgAgAG4AbwAgAHMAdQBjAGgAIABhAGcAcgBlAGUAbQBlAG4AdAAgAGUAeABpAHMAdABzACwAIAB5AG8AdQAgAG0AYQB5ACAAbgBvAHQAIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABmAG8AcgAgAGEAbgB5ACAAcAB1AHIAcABvAHMAZQAuACAARgBvAHIAIABtAG8AcgBlACAAaQBuAGYAbwByAG0AYQB0AGkAbwBuACwAIABwAGwAZQBhAHMAZQAgAHYAaQBzAGkAdAAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0ALwB3AGUAYgBmAG8AbgB0AC0AcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABjAG8AbgB0AGEAYwB0ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGEAdAAgAHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtACAAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAvAHcAZQBiAGYAbwBuAHQALQBzAG8AZgB0AHcAYQByAGUAAAIAAAAAAAD/tQAyAAAAAAAAAAAAAAAAAAAAAAAAAAAAHQAAAAEAAgADAAQABwATABQAFQAWABgAGQAbABwAIwAoACsALAAxADsARwBSAFUAVgBYAFoAXQCjAQIHaGNvc2x1ZwABAAH//wAKAAEAAAAOAAAAGAAAAAAAAgABAAEAHAABAAQAAAACAAA=); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/DBA0DCC14F9DF8F4E.css b/docs/static/fonts/332720/DBA0DCC14F9DF8F4E.css deleted file mode 100644 index 9d5f7c8977..0000000000 --- a/docs/static/fonts/332720/DBA0DCC14F9DF8F4E.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - - \ No newline at end of file diff --git a/docs/static/fonts/332720/E62638AD5B5A9C61A.css b/docs/static/fonts/332720/E62638AD5B5A9C61A.css deleted file mode 100644 index a727dfcc29..0000000000 --- a/docs/static/fonts/332720/E62638AD5B5A9C61A.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8AAD8/AAA/PwAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAA/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAPz8AAD8/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/Pz8AAAAAPz8AAAAAPz8AAAAAPz8AAD8/PwAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAIwAUAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAA/Pz8/AAA/PwAAAAA/PwAAFAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAA/PwAAAAAAAAAAAAAAAA8AAAAAAD8/AAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAD8/AAA/PwAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAA/PwAAPz8AAD8/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/Pz8/PwAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/AAAAAAAAAAA/PwAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/AAA/PwAAPz8AAAAAPz8AAAAAPz8AAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/AAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8AAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8/AAA/Pz8/AAAAAD8/AAAAAAAAPz8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAPz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAPz8AAAAANwAjAB4AAAAjAB4AAAAAAAAAAAAAAD8/Pz8AAAAAPz8/Pz8AAD8/FAAeAB4AAAAeAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8AAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8/AAA/PwAAAAAAAD8/AAA/PwAAPz8AAD8/Pz8AAAAAPz8AAD8/AAAAAD8/AAAAAAAAAAA/PwAAAAAAAAAAAAA/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAB+PwAAPz8/Pz8AAAAAPz8AAAAAAAA/Pz8/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAD8/PwAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAA/Pz8/Pz8AAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAPz8/PwAAAAA/PwAAPz8AAAAAPz8AAAAAAAAAAD8/AAAPAAAAAAAAAD8/AAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAH4/AAA/Pz8/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/Pz8AAD8/AAAAAAAAAAAAAAAAAAA/Pz8/Pz8/PwAAAAAAAAAAAAAAAAAADwAKAAAAPz8/AAAAAAAAAAAKAD8/Pz8AAAAAAAA/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAD8/AAA/PwAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAD8/Pz8AAAAAPz8AAAAAAAA/Pz8/Pz8AAAAAAAAAAAAAAAAAAAAAPz8AAD8/PwAAAAAAAAAAPz8AAAAAAAAAAD8/AAA/PwAAAAA/Pz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAPz8/PwAAAAAAAAAAAAAAAD8/AAA/Pz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/PwAAPz8AAAAAPz8AAAAAAAAAAAAAPz8AAD8/AAAAAAAAAAAAAAAAPz8AAD8/AAAAAAAAPz8/Pz8/Pz8/AAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAPz8/Pz8/Pz8/Pz8/fj8/P34/Pz8/AAAAAAAAPz8AAD8/Pz8/PwAAPz8/PwAAAAA/P34/Pz8/AAAAAAAAPz8AAD8/AAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8AAD8/AAAAAD8/AAAAAAAAPz8AAAAAPz8AAD8/AAA/PwAAPz8AAD8/AAA/PwAAAAAAAD8/Pz8/Pz8AAD8/Pz8AAD8/AAAAAAAAAAAAAAAAAAA/Pz8/Pz8/Pz8/Pz8/Pz8AAAAAAAA/PwAAPz8/Pz8/Pz8/Pz8AAAAAPz8/Pz8/PwAAAAA/Pz8AAD8/AAA/PwAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAA/Pz8/Pz8/Pz8/Pz8/Pz8AAAAAAAA/PwAAAAA/Pz8/AAA/PwAAAAAAAD8/AAA/Pz8/AAAAAAAAAAA/PwAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8/Pz8/Pz8/PwAAPz8/PwAAPz8AAAAAAAAAAAAAAAAAAD8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/eT8AAAAAAAA/PwAAPz95Pz8AAAAAAAAAAAAAAAA/Pz8/Pz8/AAAAAD8/Pz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAA/Pz8/PwAAPz8/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8KAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/AAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAACgAAAAoAAAAFAAAADwAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAACgAAAA8AAAA/PwAAPz8AAD8/AAAAAAAAAAAAAAAAPz8/PwAAPz8AAAAAAAAAAAAAAAA/PwAAAAAAAAAAPz8AAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAA/Pz8AAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAPz8/PwAAAAAAAAAAPz8/Pz8/AAA/Pz8/AAA/PwAAAAAAAD8/AAA/Pz8AAAAAPz8AAAAAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAPz8/AAA/PwAAAAA/PwAAAAA/PwAAPz8/PwAAAAB+PwAAPz8/Pz8/AAAAAD8/AAAAAAAAAAA/PwAAPz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/Pz8AAD8/AAAAAD8/AAAAAAAAAAAAAD8/Pz8AAD8/AAA/Pz8/Pz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAoAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAD8/PwAAPz8AAAAAAAAAAAAAAAA/PwAAFAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8/PwAAPz8AAAAAAAAAAAAAAAA/Pz8/AAAAAAAAAAAAAAAAAAAAAD8/Pz8AAAAAAAA/PwAAPz8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAPz8/AAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8AAAAAAAAAAD8/Pz8/Pz8AAD8/Pz8/AAA/PwAAAAAAAD8/Pz8/Pz8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAA/Pz8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAA/Pz8/PwAAPz8AAAAAAAA/Pz8/Pz8AAD8/AAAAAAAAAAAAAAAAPz8/Pz8AAD8/AAAAAD8/AAAAAD8/AAA/PwAAAAAAAD8/AAA/Pz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwA8AD8YPxcAAAQAPxkCAHYAaQBgAF8AWgBXAFUAUAA9ADwAOQA3ADIAMQArACcAIwAaABkAGAAXABYAFQAUABMAEQAQAAsACQAHAAUAHwABABQAEgABAD8/VQA/PzkAPz83AAMA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HmBhYUhNP2o/CD8/Pz8/Pz9wP3c/P3N7fXg/ch9vP3U/Pz8/Pwg/Pz8/fD8VSj8iPwc/fj8/Px8/Pz8/CD8/Pz8/PwU/Pwg/Pz8/Pz8ePz8/Pwd3Pz8/PxUqPwg/P3Q/bD98P30/Pz8/eT9vP28/Pz8/Pz8VFz9iBj8IPz8/Pz8/Pz8/Pz8/Pz8/P3s/Pz8/Pz8/Pz8/Pz8/BT8/Bj8/Pwg/Pz8/Pz8/Pz8/Pz8/Pz9zPz8/Pz8/Pz8/Pz8/Pz8FPz8/PxU/Px56fz97ej9/Pwg/Pz8/Pz91P30/dD8VPz8tPwg/Pz8/Pz8/Pz8/Pz8/P3Q/Pz8FPz8/Pz9yPz8/Pz8/dz8/Pz8/P3o/Pz8/Pz8IPz8/Pz8/Hz8/Pz8/Pz8/FVk/Bz8/eT8IPz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwU/Pz8/FT97Bz9yPz95Pwg/Pz8/Pz8ePz8/Pz8/Pz8/Pz8/Bz8IPz8/Pz8/Bj8/Pz8VPwc/cj8/Pz8ffj8/Pwg/Pz8/Pz8FPz8GPz8/Pz8/cj8/Pz8/FTsrHz8/Pz8/Pz8/Pz8/Pz8/Pz8VPxI/Hz8/P3p5f359CD8/Pz8/PwU/PwY/Pz8Ifz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwY/CD8/Pz8/PxVRPyY/Bj8/Pz8VQT9VPwoyFT8GP2I/P1g/Pwg/Pz8/Pz8GPz8/CD8/Pz8/PwY/Pz8IPz8/Pz8/Bj8/Pz8/FT85PwoyBD8KMRU/PwoyBD8KMRVBPwoxFT9QCjAVPz8KLxU/Pz8OHz8/Pz8GPwg/Pz8/Pz8FST8LP0k/Cz8IPz8/Pz8/Bj8ePz8/Pwc/Px4/Pz8/Pz8/PwV2Pz8xPwg/Pz8/Pz8/Pz8/Pz8FMT92Pz8ePz8/Pz8/Pz8VPz9iPwY/Hz8/Pz8/Pz8/Bmc/Hz8/Pz8/Pz8/Bz8/Px4/Pz8/Pz8/PxUpPxM/Dgg/Pz8/Pz8/Pz8/Hj8jPy0/PwY/Hz8/P35+Pz9+BkwIeT94P3g/dD91P3U/Bj8fPz8/fn4/P34GQQgjP2ciJT8WPwg/Aj8/Rz9XPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Rj9kPz8/Pwo/PwY/Px9+Pz8/Pz8/PwY/Pwg/Pz8/Pz8/Pz8/Pz8GPz8ffj8/Pz8/Pz8GPz8IEj9sPzY/BT8/OVxSSV4/Pz8/Pz8efj8/PxUcPyY/DgorFWc/Pz8OCioVP3E/Pw4KLhZ2PwouFnY/Ci4VPz8/Dh4/VD9HBz8eR1RQSks/Tz8HPx8/Pz8/FXg/fz8mPw4KLRZIPwokFTE/Yj8OCi0WSD8KLRU/P2I/DgosFkg/CiwVRD8/Yj8OCiQVMT8OCi0VPz8OCiwVRD8/Pw4fP38/fX1/f30GXj8ffT9/Pz8/Pz8GXj8VPz8/Dh8/fz99fX9/fQY/Px99P38/Pz8/PwY/PxU/Mw4KKRUPPz8IPz8/Pz8/BRU/Pwg/Pz8/Pz8/BD8/Pz8HPx8/P0slCD8/aFFTWj8/Pz8/Pz9+Pz8/Pz8/Pz8/Pz8/Px4YPzM/IAc/CBA/P0krfQg/BQM/Pwh/Pz8/Pz8VPz8/PzkOCisWYD8IPz8/Pz8/BUc/HT8IPz8/Pz8/Pz8/Pz8/BUc/HT8IPz8/Pz8/Pz8/P38/Pz8/Pz8/BUE/Ej9DPxI/CD8/Pz8/Px9/Pz9/FWc/Pz8mDh5QW2JRBz8eT1s/Pz8/Bz8fPz9fURUxPxU/Hz8/Pz8/Pz8/Bj8/Hz8/Pz8/Pz8/Bj8/FQo/Ez8eP0g/PQc/HjxHTjc4P08/Bz8fPz8/PxUvP1Y/dj8OCiAVPz8OHlFaYFYHPx5WWj8/Pz8/Bz8fPz9gUQQ/Hj9HPz0HPx49R0M8PD9DPwc/Hz8/Pz8VMD91Pzo/Dh9yfn14dj8/Pwc/FUE/Hz8/Pz8GSx5nP24/CD8/Pz8/PwU/ZQg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8FUD8HPz8ePz8/Pz8/Pz8VP0oeNERINgc/HjZFPz8/Pz8/Bz8fPz9JMwQ/Hj88PywHPx4sOz4qKT8/Pwc/Hz8/Pz8VPz9kP1w/DgoqFmA/CD8/Pz8/PwVHPx0/CD8/Pz8/Pz8/Pz8/PwVHPx0/CD8/Pz8/Pz9/Pz8/Pz8/Pz8/PwVBPxI/Qz8SPwg/Pz8/Pz8/Pz8/Pz8VPz0/Jg4fPz8/Pz8/Pz8GcD8fPz8/Pz8/Pz8GcD8VLj8pHlhsXl0HcAg/Pz8/Pz8ePz8/Pwc/Hz8/amUVPz8eP20/Twc/H1BpWEIIP2c/cz90Bz8fWHE/Pwg/Pz8/Pz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/fWw/cD9nP2U/bT91P3k/Pz8/BzQ/Hj8/Pz8/Pz8/B3AIPz8/Pz8/FS8/Qj92Pw4ePzY/JAc/HyU0OyQIP1A/ZT9rPz8/Pz8/Pz8/Pz8/Pz8/Pz8/dD94Pz8/Hj8/Pz8HPx8/P00+CD9ee21vbD8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/FSo/Px5SPys/Iz9LPwc/Hks/KT8iP1E/Uj8rPyM/Sz8HPx9LPyk/Ij9RPwQ/Hl8/Nz8yP1k/Bz8eWT85PzQ/Xz9fPzc/Mj9ZPwc/H1k/OT80P18/FX8yP2o/DgZWPx9/Pz8/Pz8/PwdWPx4/Pz8/Pz8/fQYjVj8fPz8/f34/P38GVj8pVj8fPz8/f38/P38FP0Q/Pz8/CD8/Pz8/P30/P38/fT8/Pz8/PwU/Pz8/Pz8/Pwg/Pz8/Pz8/fj8/Pz8/Pz8/Pz8FPz8/Pz9FPx9/Pz8/Pz8/PwZWPxU/PwQ/Dgg/Pz8/Pz8FeT0GPz8fPz8/fn4/P34HSQo/CEA/S3RhYWZmdlc/Tj8pP1E/Xwg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz9dP2k/Pz8/Pz8/Pz8/Pz8/Bgs/Pz8ffj8/Pz8/Pz8GPz8/Pz8/H34/Pz8/Pz8/BnY/Hj8/Pz8VPz8OCD8/VD89BT8/OT8/Hgg/Pw4/Bz8VPz8NPwhnPyc/Bj8/Bz8fIz8QPwY/Jj8FP3xHfgg/Pz8/P34/ez9/Pz8FPz8IP1Q/Yz9pPz8/Pz8/Pz8/Pz8/Pz8/Pz8/bj9xPz8/BUQ/CD9/P38/fwg/S25XX18/Pz8/Pz8/fz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/BT8/CD8/Pz8/Pz8/fj95PxU/bz9oDgopFQI/Px8/Pz8/Bj8ePz8/fQV3P3sePz8/Pz8/Pz8VPz8hPwA/Dgg/PT9rPz8HPx4/P3Qkez8/Pz8/Pz8HPwg/Pz8/PT8/Pz8/fz8/Pz8/Pz9lJT9leyg/B0AIMj9nYnhMdT9qPzI/B0AIKD9lP2UlPz8/Pz8/P38/Pz8/PxVdPxw/Dh5/Pz9/fz8/PwcOPx4/Pz8/Pz8/fxUCPw0/Pw4IaT0/Sz8kPwc8Hj1aPz8/Pz8/Pz97JFp0PQc8CCQ/S2tpPT8/Pz8/Pz8/Pz8/Pz8/JT8/Pwc/CD8/Pz8/P0g/Zj8/Bz8IPz8/ez8lPz8/Pz8/Pz8/Pz8/PxUfPyo/HD8OHj8/Pz8HPwg/Pz8/Pz8FPD8/Pz8fPz8/f38/P38GEz8efz8/Pwc/CD8/Pz8/PwU8Pz8/H38/Pz8/Pz8/BiE/Fj9NDgg/Pz8/Pz8/Pz8/Pz9+Pz8/P34/Pz8/Pz8/ez95P2w/U2ZpP2oFPz9rP3g/CD8/Pz8/P30/Pz8/fD98Pz8/PwVMP2A/Tj9GPwg/Pz8/P34/fT8/Pz8/Pz8/Pz8FPz9jPwg/Pz8/PxU3Py8/bw4IPz8/Pz8/BXU/ST9qP0A/CD8/Pz8/P34/Pz8/fj8/Pz8/PwVmPzs/ZD86Pwg/Pz8/Pz8/fz8/Pz8/Pz8/Pz8Faj9BP3U/SD8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BXE/Qz9vP0I/CD8/Pz8/Px4/Pz9/FT9dDgg/Pz8/fT8FXz87Pwg/Pz8/Pz9+Pz9/P30/fT8/Pz8FQz8oP0U/KD8IPz8/Pz9+Bj8IP30/Pz8/BUU/KD9FPyk/CD8/Pz8/fT99Pz8/Pz8/Pz8/PwVfPzs/CD8/Pz8/PwY/CD8/Pz98PwU1PyU/NT8mPwg/Pz8/Pz8GPxU/Pz8/Pw4IPz8/Pz8/Bj8IPz8/P34/BWA/YT8IPz8/Pz8/fT8/Pz98P3w/Pz8/BUs/Tj9NP1E/CD8/Pz8/fj99Pz8/Pz8/Pz8/PwViP2I/FT8/aQ4ePz8/Pz8/P3wHQQg/Pz8/HhU/Mz8OPwc/Px58Pz99fT8/Pwc/Px4/P1AkJz8+IQc/Px58Pz99fT8/PxV9Pz8/Pw4eP2A/KgY/Px8/Pz9/fz8/fwdUIj8efT8/fX0/Pz8GIj80Px9/Pz8/Pz8/Pwc0Pz8fPz9gUAg/aD97Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8VPz8/bD8OCD9wP2Q/Pz8/Pz8/fj8/Pz9+Pz8/Pz8/P1Y/Uz9OHkZlVVAHPwhPP3U/dz9zP3I/MD8HPx85UEYoCD9UP04/Wj8/Pz8/Pz8/Pz8/Pz8/Pz8/P3E/ez8/Px4/Pz8/Bz8IPz8/Rj9CPzk/NT8/Bz8fPz8/PxU/Pz8LPw4efT8/fX0/Pz8HED8IKF9VMj9DP3w/Pz8/Pz8/Pz8/PwA/Pzg/PwdQPx4/Pz8/Pz8/fBU/bD8OCicVPz8/Px4/Pz8/Pz8/fAc/Pwg/Pz8/Hg8/KBE/Oj8HPx86PyYRPw8/CD8lP0k/YQcyHn0/P319Pz8/FX0/Pz8OCiYVWj8/Px58Pz99fT8/Pwc/CEhfUEo/Jh4PPxE/Oj8HPx86PxE/Dz8IP1E/Sz8HPz8ePz8/Pz8/P3wVHz8/Dh4NPyg0DD8HPx4PPyk/Cj8NPz8MPwc/Hw8/Lwo/FT8/His/Dj8CPyM/Bz8eIz8QPwM/LD8rPw4/Aj8jPwc/HyM/ED8DPyw/FX8/Pz8OHn0/P319Pz8/Bz8IT2lcUj8uHhU/QA4/Bz8/Hj8/Pz8/Pz98Bz8/HiJGPz8/Pz8/Bz8/Hj8/Pz8/Pz98FT8/Dh59Pz99fT8/Pwc/CFZqWV0/MD8yP1Q/b1JqVlQ/Kx4NP0AUPwc/Px4/Pz8/Pz8/fAc/Px4CP0s/Pz8/PwY/Bz8/Hj8/Pz8/Pz98Bz8/HiFKPz8/Pz8/Bz8/Hj8/Pz8/Pz98FT8/Pw4efT8/fX0/Pz8HRD8ePz8/Pz8/P3wVPwM/Dh59Pz99fT8/PwU/Pz8/Pwg/Pz8/Pz8/fj8/Pz8/Pz8/Pz8FUj9PPz8/XD8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BT8/WD8RPxA/Px4/Pz8/Pz8/fBU/Uw4IPz8/Pz8/Pz8/P38/fz8/Pz9/Pz8/Pz8/Hmd0clsHPz8efT8/fX0/Pz8HPz8fPz8/FT8/VQooFTA/Az8OHn0/P319Pz8/B2g/Hj8/Pz8/Pz98FSw/PwooFTA/Az8OHn0/P319Pz8/Bz8/CE9pXFI/Lh4VP0AOPwc/Px4/Pz8/Pz8/fAc/Px4iRj8/Pz8/Pwc/Px4/Pz8/Pz8/fBU/Pw4eIT0iCD8HPx4KPz8/Pz8/Cz8HPx8HPy8iFT8/Pwg/cz9dPz8/Pz8/Pz8/f38/fj8/Pz8/Pz9RP0g/RB4JP0g4Fz8HQQg/tz8/Hg8/LQ4/Jj8HPx8nPywOPw8/CD8lP0Y/YQc6Hn0/P319Pz8/By4/CD8/Pz8/Pz8/PxU2Pz8/DgY/Hz8/P35/Pz9/B1RZCFE/XXtubnFxfWc/Xj9yP3g/ej8/Pz8/Pz8/Pz8/Pz8/Pz8/Px4/PwY/Mz8ffj8/Pz8/Pz8HMz9QPx4/Pz8/Pz8/fRU/Dz8/Pw4IPz8/Px4aPyAIPzM/Bz8fKD8KPyMePyM/Cj8wJj8/Pz8/BiQ/CBM/PzA/Jz9CbVhjYj8/Pz8/Pz9+Pz8/Pz8/Pz8/PxVkPz8IJD8sPz8JPz8/BT8/FT8/Aj9rDgonFVo/Pz8ePz8/Pz8/P3wHLgg/Pz8/Hg8/KBE/Oj8HPx86PyYRPw8/CD8lP0k/YQc/Px58Pz99fT8/PxVZPz8/Dh4nPw4/BT8jPwc/HyM/ED8GPyY/CD8zP1E/XT8/Pz8/Pz8/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YUE/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8VNj8/PwA/DgogFQ8/awg/Pz8/fz8FFT8/CH4/Pz8/fD8EP1Q+Kj8HPx85Rj8/CD8/Pz8/Pz8/Pz8/Pz8/fj8/Pz8/Pz9MVl5HPyYeGD82Pwc/CBA/Pz8/CD8FAz8/CD8/Pz8/PxVHPz8/OQ4IPz8/Pz8/BWw/ND8IP34/Pz8/Bz8IPz8/Pz8/BWw/ND8IPz8/Pz8/Pz8/P34/Pz8/Pz8/BVw/Gz9ePxs/CD8/Pz8/Px9+Pz9+FT8/Az8/DgolBHU/CiUVSz8/Dgg/Pz8/Pz8FbD80Pwg/Pz8/Pz8HPwg/Pz8/P34FbD80Pwg/Pz8/Pz8/fj8/Pz8/Pz8/Pz8FXD8bP14/Gz8IPz8/Pz8/Hz8/Pz8VPz8/Pw4KJBU/P28KIBV1Pww/DgogBD0/CiAVdT8MPw4eCz8xPzMHPx4oPD8IPwc/Pz8HPx8/PzwDPxU/Pz8IP2k/YD8IPz8/Pz8/fT9/Pz99Pz8/Pz8/P1U/Vj9PPyE/Kz8oZj8/Pz8/Aj8eIT8tPww/Bz8fFT8hJyY/CD9AP04/YT9VP2kgPz8HPx9wPzI/Dj83PxV/Pz8/Dh4VP0Y+PAc/HjRMPwY/Bj8/Pwc/Hz8/PhU/BD8/HihRODUHPx48Uj8/Pz8/Pwc/Hz8/OCgEGz8eJz86BT8IPwc/CDk/TUhuM28/Vz84Pwc/HgE/QQc/DT8NPwc/AT8HPwg/Pz8/PzM/SD8/Bz8fCD8FPyc/FT8/Pw4IPz8/Pz8/BT8/Pz8/FT8fPz8/fX0/P30GOj8efT8/Pwg/Pz8/Pz8FFz8/CD8/Pz8/Px4/Pz99FT89P24OHgU/OUEoBz8eK0M/Az8HPz8/Bz8fPz82BT8VPz8IP28/YT9RP0U/JT8/Bz8fZz88PwM/Qj8IP0E/Uj9TCD8/Pz8/Pz8/Pz8/Pz8/Pz8/P2I/dT8/PyI/KT9qPz9HY01KPwY/HhM/Bj8RPwc/Hxg/Px4/FX8/Pz8OCD9eP1Q/Pz8/Pz8/fz9/Pz99Pz8/Pz/GUD9HP0UeAz9APiYHPx8oSD8FPwg/Pz8/Pz8/Pz8/Pz8/fj98PwU/P3oIeD8/fz99Bj8/H30/Pz8/Pz8/BT8/Pz8/CHVee14/Sh4bPyIRPwc/HxU/PyE/FX8/Pz8OBTI/PzI/PxU/PwYHPx4/Pz97CD8/Pz8/PwVxPxY/CD8/Pz8/fx56P38/BmQ/LB9/Pz8/Pz8/Pwc/Kj8ePz8/Pz8/P30VP1E/Pw4IPwE/Wz9HPz8/Pz8/P30/f38/fT8/Pz8/P1Q/SD8zHi1MPC8HPx8pVT8SPwY/Hj8/P34IPz8/Pz8/BT8/ej8/Hz8/P319Pz99BiI/Hn4/Pz8IPz8/Pz8/BT8/fD8IPxk/Bz8UPz8HPx8OPz8NPxV/Pz8/Dgg/Pz8/Pz8FeT8/PwgiCD9PZEE/CDA/UD8/Pz8/Pz8/Pz8/Pz8/Pz9+Pz8/Pz8/PzVQV0s/Cj8eCz8yAT8HPwg/Pz8EPw8/BVY/aj8/Cz8ffT8/Pz8/Pz8GSD8ePz8/fRU/P3EOBT8GPwg/Pz8/Pz8/Pz8/fz9/Pz8/Pz8FXg4/CD8/Pz8/PwY/Hns/Pz8HKD8ePz8/Pz9/P30VP0c/Pz8OHiU/Kz8xNj8HPx43Pyw/JT8lPyo/Nz8HPx82Py0/LyU/FT8/HkY/Oz8DP1U/Bz8eVT89PwU/Rj9GPzs/Az9VPwc/H1U/PT8FP0Y/FX8/Dgg/Pz8/Pz8FCj9YPwg/Pz8/Pz8/fz8/Pz8/Pz8/Pz8FCj9YPwg/Pz8/Pz8ePz8/fxUDPz8IPw4KIBU/Pw4fP34/fHx+fnwGcD8ffD9+Pz8/Pz8GcD8VP2Q/DgokFTE/DgZZPx8/Pz9+fj8/fgdZP1Y/Hn0/P319Pz8/BlY/WT8ffj8/Pz8/Pz8HWT9WPx4/Pz8/Pz8/fRUaPz8/Pw4FPz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BVokWj8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BT8wAT8/CH8/Pz8/fz9/Pz8/PwUBPz9NMAg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8FPz8kCD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwVNPwE/Pwg/Pz8/Pz8/Pz8/fz8VPD9XP04/Dgg/Pz8/Pz8/Pz8/Pz8rKz8VPzY4Pz84Pz8VPysrPwg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz0/JT8oRz8/Rz8/JT8/PT8/Pz8/Pz8VHz9OPw4IPz8/Pz8/KD0/JT9HPz9HPz8lPygoPT8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8rPxU/OD8/OD8/FT82Pys/Pz8/Pz8/Hz8/Pz8VHz8/Tj8OCiEVYT8OCD89YUhHUQVqP2M/CD8DPz8/Bz8fPz9HKxUKP3cIaydaWEk/Bz8eTVs/Pz8/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AG4AIAB5AGEAbQAgAHUAbwB5ACAALABzAHQAcwBpAHgAZQAgAHQAbgBlAG0AZQBlAHIAZwBhACAAaABjAHUAcwAgAG8AbgAgAGYASQAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIABkAG4AYQAgAHUAbwB5ACAAbgBlAGUAdwB0AGUAYgAgAHMAdABzAGkAeABlACAAdABhAGgAdAAgAHQAbgBlAG0AZQBlAHIAZwBhACAAZQBjAGkAdgByAGUAUwAgAGYAbwAgAHMAbQByAGUAVAAgAGUAaAB0ACAAbwB0ACAAdABjAGUAagBiAHUAcwAgAHMAaQAgAGUAcgBhAHcAdABmAG8AcwAgAHMAaQBoAHQAIABlAHMAdQAgAG8AdAAgAHQAaABnAGkAcgAgAHIAdQBvAFkAIAAuAG4AbwBpAHQAYQBjAG8AbAAgAHkAbgBhACAAbQBvAHIAZgAgAHQAaQAgAHQAcwBvAGgAIAByAG8AIAAsAHIAZQB0AHUAcABtAG8AYwAgAHkAbgBhACAAbgBvAHAAdQAgAHQAaQAgAGwAbABhAHQAcwBuAGkAIAByAG8AIAAsAGUAcgBhAHcAdABmAG8AcwAgAHMAaQBoAHQAIABkAGEAbwBsAG4AdwBvAGQAIAByAG8AIAAsAGUAdAB1AGIAaQByAHQAcwBpAGQAIAAsAHkAZgBpAGQAbwBtACAALAB5AHAAbwBjACAAdABvAG4AIAB5AGEAbQAgAHUAbwBZACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGYAbwAgAHkAdAByAGUAcABvAHIAcAAgAGUAaAB0ACAAcwBpACAAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAVAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIAC4AcwBuAG8AaQB0AGMAaQBkAHMAaQByAHUAagAgAG4AaQBhAHQAcgBlAGMAIABuAGkAIABkAGUAcgBlAHQAcwBpAGcAZQByACAAZQBiACAAeQBhAG0AIABoAGMAaQBoAHcAIAAsAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIABmAG8AIABrAHIAYQBtAGUAZABhAHIAdAAgAGEAIABzAGkAIABkAGUAZABuAHUAbwBSACAAbQBhAGgAdABvAEcAdABuAG8ARgAxADAAMgAu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)); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/E83A474C5EE950C81.css b/docs/static/fonts/332720/E83A474C5EE950C81.css deleted file mode 100644 index 1eb5423b53..0000000000 --- a/docs/static/fonts/332720/E83A474C5EE950C81.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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))); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:application/x-font-woff;base64,d09GRk9UVE8AABbaAAsAAAAAH5wAAQAAAAAUtAAAAiYAAAaMAAAAAAAAAABDRkYgAAAH6AAADDUAAA5vT7aLY0dERUYAABQgAAAAHQAAACAASAAET1MvMgAAAWQAAABPAAAAYFXHJUtjbWFwAAAGPAAAAZYAAAM67rbLAmdhc3AAABRAAAAACAAAAAgAAAALaGVhZAAAAQgAAAAyAAAANgMWR7xoaGVhAAABPAAAAB0AAAAkB2EDAGhtdHgAABRIAAAAbAAAAGw9xwbVbWF4cAAAAVwAAAAGAAAABgAbUABuYW1lAAABtAAABIcAAAu7KDUzBHBvc3QAAAfUAAAAEwAAACD/uAAyeNpjYGRgYGBkcNRb8/RoPL/NVwZu5hdAEYYLOkzyCPq/BfN8ZgUgl4OBCSQKADP9CZ0AAHjaY2BkYGA+8F8ASF5hAALm+QyMDKhAGgBY0ANpAAAAAABQAAAbAAB42mNgYvJl1GFgZWBh2sPUxcDA0AOhGe8yGDH8YkACCxgY6gMYGLxgfA8153wgpfJAiFnhvwXDCeYDDB+AfG6QHOM/pj0MCkDICAC/ww9/AHjatVRNb9tGEB1ZcvyROIh9TFFg2wZG0kqyqCi2k1NRA45zrGOkyHFFrkTaIpdYLq0IyKG3Hoqi1x76J3rpD+if6K8p0LfDVUzFieoCrQhpH2dn9r03OxARPWj8Tg2qPl/jW+EGfYG3Cq/QGoUeN+kzOve4VctZpS360eNb2PnF4zWS9KvH68j5y+ONGt5c2W5senybdpqfeHynhrdqOXfpy2bH43s1Dds1vMO4SY3WBt6+b37ncYOOm396vEJ3W5963KRvWl953KrlrNL9VurxLVpv/eDxGv3R+tnjdbq/+q3HGzW82fp89cLj2/Rg4yeP79TwVi3nLp1t/ObxvZqG7RrecfhI5zOTjGMrHh49Ev1eb7/tfg/EiVajiTJiVxzproitzZ/t7U2n066d5XpsZB7PuqFOF+tPdo+0eCsWU07VuJxIExwE/cFB5/BwcDDo9HvBk95+/3GnP8BPMOj1g6evlCkSnYmgi91jndnn2sYyFae6zCIViaQQUlgjI5VKcyH0aFFjW0zjJIxFKmdiqIRR46SwyrjCTITKWIn1vDRJESWhBVHRXag/i0FQ6JGdSqMcmY2VyI3OUTq7xiZe65KpMm1FiCa0RaqjZIQ1Aq9JhqVVbaGNiPQ0m2gZ4bwaAW8lWWHlZCISK8oczmU2w1lpjlLDCbEurNsdGZ3y7kSH0mlnfiOqzlstykItnu8MFOXwXIW877ycKZMWzshLZS6TUAk5NkqlKkNGLK1QbyC8QO/sVKlMzGBQZtF7tl+M4Bgno9FX5VVlm0vmPbmuaARDzkNemlwXqiuOEUi105phL2VjbZFPlETtZVLA+Efnbm+qhiPMSGehoSEiEo4XNcPb9QPEP87j9Zqbq6Ej0pTTjAwlNKaYLAl6iOgjrH3q4dmn9jt8AHSCCkUjmuDX4H0XX3dKF6urtzjvGe3hmfLTRWSGmMb5Bn+NObJmiIaIpEv5T3C22xf0Ft9lp5xCy5hKaJLYDaAzgOIB1g4d4nFoAOxcBPSEXfXpMUcGHgVAPeCAntIr9lZAk6YM3AGYqtpjjlh6jtVCgwS7AL8Ge0YR6iK8J6gV2HOqnVoXT1nbBWIa3VvWR9fvKc5O4C4GdpUzrENkCuQ6r47BcuWc0ekMOWKRX72fQ5Xh3IhPs95RAZaP858xt3NQsFYLNZKZ5s6cc/eWI+rur2Kd3cCboNfcqytXGXdS8E26SWjznmbFI/8eeb/OyxDVznmb2QzvaijMwKa515W+Dzu4qkq4D65XEzzu3akoecYyvr2M9VUTlntWUzshxlpwVVU74m6ktVqnKMTbvO9X/g3f5NXMW57zEueppfrFu3iJTpwjEtbq5/dyxkpTzqxu5CVHLnkKFCsc83luLhVPtPDz7JCiN77jhZ87p0BxpoCz6gYlT/zy237B7Bmrc5qrif4Qe52zXWN5f05u0qORv6H5PeTc8ZzvS7GuY5+R8qr8PFR1ae3G2lztnEnPe8ms1Y3/+/+7Pe7jkJmc786SCQ19jvR3vKzP1b3dRIH4D/4fb8LzP/Tmb7O8aiYAeNqtks1LlFEUxp9n0vG7cT4cR5HBIFyIiJBJrRRE1IWFC7VoIYorQ0aTwUEkkOgfiHARIX4iIrgSQUWEIQZDRcr2+hKBa0Ut0HO84ztOgotx4XO4H4dzL7+Hcy+AB7BHCWhmOKpNxqs8zREwawR1SMczPMJjPEENnpu8Ac14gVfoQQiDCGMIw5jELn7gFOd00UMf/QywmGUsZwUrWcV6NrCRLXzJVraxg6/5hp3s4lv2McQBDjLMYY7wPdVRFBwNfgh+PPCoGgelhlyFp8ZDnNyUJL9LkjcN+Qh/Ddl9f2S1dF9/6Z7+1G3d1JhGdUUXdUandFIndFwjgNbGe6amf/JPzuREjuVQ/shvsWRfdmRLvktMvklUNmRd1mRVlmVJFmRe5mRWpmVKxuWrfBHfxbk1Zn22PpVm2q+QQu1mdKPXzP24P+UlwpUI743wJ8Jj6qATKW3SYX+ra6WlOzOQmYXsHDvPtYl46Ipv8pPn3DfueP5vvYCvwPALgUDSb/5trDcuv1EKe14U3bEleS6j25VL40WT/QAAeNpjYGYAg/9bGYwYsAAALMIB6gB42k1WC3wU1dWfPGbmlsci6uCn1tkEDCTKQ0FQMDzSlBBRJDyCoH4oKgUpJTQkDXls9jGv3T2Zmd2Z3Z3dhDfK61NaFcqnolR59KP5qgjVtvgA+SH0V6FqrdyJd/1+353QWn73l5u5e889555z/v9zbgFTXMwUFBSwNQ1rmryPcvc6xv1hgXtboXtbkTuseMmgIiCPfzuhbx+LRwyxb2MYH7oeLx7KFBUUoNqHVj7dsG5184rqhrWtjc+uWNlUUl5dUTL+rrsmjfbme0tqG5b/ZPXyxpKRJdUNY0tWNjWtnTJuXEtLy9im1rUNKxqXrV3ZOvbphp/1W6fm6R9TyLDMUOZ65gbmRmYYcxNzM3MLU8qMZCqYO5hxzGRmJlPHLGAWMouYxcxjzJMFGnNrIT02lZnBtBeMLggWvF5YVrip6OaiTLFQbLGzWWCPsee4Cm4z93/8HF5FDPoxOvYD3w8eGDzgdvJ4sRv9tiMf5U4uEfC3QGblb2HJ4/laAfpkPCM/iMXr3UECfCeTGe4gtmGugKkE+RZYHznsI1/jIvyIIFmybVuWLfa4LWwulAmIQS4QCgX8se8KhbX8+lxg06ZcbpO4g98UyK1fHwisF3278Bt9vxCW88QXnTANRsKo4wvxHasQeYmfaj+8Z8GhqKGYEeiEYJBOEVOxlHfmnfzpORlV8p2ZUDabyWTFP/N4qHn+A/gGLj94hIz+L4Rf4H+jvN5y8BlLScSTkAMnQ6e0moxY9a88sr06iV7hs6FMZ2co1CniFfm3BJg+e96oGMK7eDxszd5lUIPyHP6rAKd6j17SEXmeJ8Ken+6Hd5HvCr4SFHANZvFUXO/XeVxPivD9pIYOlkwl9WKMJ/W4iNyPa0T9NYGUjcNj8CRP8N7P8B24DJddJKPJvZ7YpLvJnaRM9JEteNZWIeAEc7mMkxP7yvlsxGkXY1wIwtGQhohvKRvSJAWCEEyHHTDB7EroCHMvs77OA9uFQCacE91aLpfJ5Lyw+/MDAa/Ci1g8BBcf6oXPEbVeMP4TMlAkA+DBR+omRrW4Chp0ZsJZSEHSTFhvfXBk/1k4A+/XwV0Iqp6ZS9BwRJKklZVkTYEI8lm4lzo++MrH2Ee9AXwj4Y+Tm22EO/BGNpE0bbBQNpzqFPPD+7Pu3cqP/wakjWxkFTmqgII8g+JzHL7+Yn2FP8aPq3xojDgBan+18PdaQkpEIODlOQCyKRva4VlnHsMFgHw6fpsaLv3751jwwjh0+KfkVnE2LG1f2ow24G58GtjvPSdfcFRHJL4etZF9bLzD7EzLtprSHNgAr718ARBmT9eWU9Mjp80gReJMmLW37rCaiJgSNRui8YWIodjSkYVnl56npvEZalm8chn/R79lwp0jN4iEg9lznp6l4lUXcQUeDv8DB5vfeCqhJWL9UHPolNKSchItODD/uSpA5EekiFSSFdQqkLI9M4/O27+st+EUIJPCg530xy+o7k8/PId5XHS6+k4KjPKqyYQVfTvwu2EBj8LsRxh5Ef+49viEXSd2Hj8En/QnlPDvk8F08FWkgJ6C+44/cqJhwpraOTAZUXRRV6fgUaJ7a3H5fUc/pQpOf3jkq68+nF9JZSfeN69cJJeKiTDtxGm6de7i7zCHuYsP3UM3K6fVEEH04Vep7/diHx6P1/YnvOTZ0/VvLdv/8K4Z1KeRo0qJQD0ig74cg0tFXAjv/u6VUzb5STnFdCnMhUXb619VErKuXA1s4Cp50W+e7H32Y6B5OyWQospTl6nmSyfPU9/RJ5Xl1PiE6XdTmPrcwa5GJglfwpkd7x8wdNMECyzFkiEKajwWr1r24+YKeguFTMe1uAmvw1X4QdyO2/AM8gB5kJRVzZk5f9WeI35wjOeSe9GLlAxGT7i73SsikWgHCtWxTQeW/vcUqqOYDC4lI0o/rL7kPw1v7t/35ob5B1e8B+jspVN4Ol5BFuA5JEZHPXmMSETC88kSnPIvwnuFqQvfOIuLPzt74Y+H51ZWTBw9xu97Bw8b5v4n55Ulr8D489X4RXfoNeuheKc77Zr1Yi4QDAb83/2Q9/hPo3731/8sBQ4tBfiYu5Ac479f993O54JOwDsikrfzC/Hb/177yMe46Jqz18r68Nyvt9A6Ecp5TBHB/cJtzl9h7bAtpykOOSeVdvy07ngc8rgrQv5cfrX7OSunpGQIkHT1lj488A+bhc50KCtmwLKsFMIS7sUqeYdNSkk1DVkP/g5Y0aRiIQL4JN0/ypoJIwlJyIYznRACWZYjiLSSg6QDH2IVW0mEr9b3IOU9RQzCEXKYGOQPrKb2Fw3fEbe3b4nQHUoHAuFwh0iO88t6HzhaRnM3hAwdSaZ4MJyCh5bjIeKX8L/HDryDxvIdtPrk0ulukVjuo8I3X00gN3liw8rGl5aM/RTfIlIG3Xb+I1wk+n6FT1Gkj6Yt7Do8wuP5CFKIfRTGoylvryMjvFI9AhcSH75T1F8VyIBxl/EQT27Qub/hwXjAxQoyxJMZdE85GUzT8MRftghXzdNQ4zrKnPsufYSZdE9X2qsN3SGnA6phfP0T5Qhfx191i4bcV4ozYeHyn49e8Nj22cTdk7f9aEvNFjhCyf7mqy+9Jx6Eg+0Hfm7EvDqThUzGm2RLMR/d+fDGhYDKa+omeyXmrouNn6w72dLbDHNpGairX14jPgwLNi96STMUykaaghCdpIRkRg8986e1J2iZS7sb3MA1Ad7Bl06bPur2uhP/EPFe/t+/H6Bt+oMJWBD/Akdee/G3qIr/3k8fzuCULOgcbSh2ohvhke5EXJafyCY6UlIWkM45kLYTOYTvd59g9YTuIcKhcPPKfSQaRqQiP5OUuzNZLSPbAUAxrhNkSQshUt6/Uc1qjpTyxIPe/VVd0VWqLP8EmwikJYd68eiZYW4p56TTjhNOB/3k74Bdt5JNWhR9Nuri06F0UMzfwAXD4aDXR/34PBA3X3m1OUkozoczYUf0XjOlri7YsiVJsiyJ7fkW1qOO6PR3WL/eVyhc84S55mHju4Cf3yiUDLA2CKUD6n4tDB/QXUUntXjEAHw+8c+v/OQPhN1WuMfkEgDxLhlZ22QuLgPtyEjb6HAW6DE9hOzNi2XrKZl7TxJGDHDrSZWQv9C3z73AkZHfzRO6wU515Sgv4xFVlgCFFau7J5m0/TYYmhlE9la6pbCaqRoyoEBnsLUtE9roJ9d/JCixhG3pyWRCVyUppqr+O+8Xtlnqc7lGVd5mKYe4cIyNdWldUao1onT647JsNSr8RVl43pJ6OD1hmDrQYGlGzDANw0xEDVWkr4loVELpVjlJZdt/LyTBtFlDNaMWIMd0Uo5iR/wKqNGYgnZQKf71JQI9oqmmZvlTQN8PaZTdQyNitQHICZBaIpuTdNXYv2IBnCYzHFfpCTCMOG0EiIzB3wjQ1B3Y1pzZYPXABrQt2N3WHgq2iW+TK4IFXSZLr0gv4Kmn/aNnnQI26Lpu0BeUETU0ZGUVLqayMUPTVYiASqsNtG+nxiEWi9FOA1QoiWTuKXwTjbhjZFINext2t24IhdQAdMDqrU27AWXvECI0RC28ZKq2aINp6imk6mxcpUoAReO64d+ctTozPB6OZwupjp7wRkA7t27bs6d5S4O/EdYH2tfFdrRk1saTaYOyGu1d9fKc2mXLnhRhTbp1S/Oi1jWrYRksOvj0b2E/vJjbueeFZ7eGdsOvYe8v9aNI1tlwWzD4C2iBNqdxV/fmnmx3CpHlpEPYamndXNIw6ZWimtiqyVstZRNvR5MRUQZNi8oo3dafMNzymEBzEqfhjcU0M2qqCYsmF5IoSR/NYVqyRcq4qKnJMUWl4ZGSikP5m6CNmSIsnqBxNRK6hdQuNq7F4zGgQ49RcNCRRAmLW7lWUDQz6QdTN3Q9oVIDSjQWpZKI3PpLIW3Qn7viIAI97AHLrwZ4fJMpUGEKt2hUBC0WjdKrxQwwEGHxIaGn3enIdmx6IbG9aVskHAit70RvkT/9i31k3UphlyVt3NoqyfT/Pttaw8l2e3MP/ZDtpyTeXZzsB6BmRE0PxibNtd/XN+xG9wvBvoEpLigYdU/N4q6sQmsOCkUiwaAtZf0ZCiXdppCgUIxRwspRI+UfmNA1yR/gUlSNOFCNmk6G0iJhaKEgBbh/oJNKOU7EDgYjUrAzJTn+gf8Pvh7eOQAAAHjaY2BkYGDgA2IJBhBgYmAEQikgZgHzGAAFaABNAAAAAAEAAf//AAoB9AAAASwAAAD8AF0CeAA9AsYAQQFPAB4CTgAsAmIANwJdADwCggBAAnYANwKCAEID1AA1Ap4AaAL4AGgBEgBvAxYAaALSAEkClAA8AoAAOgGQAF0B8QAzAmUAUwNdADoCKgA9APwAXQK2ADJ42u1VwXLTMBC98xU7PjAwE9uJCU0Axz1kpkCPEA4cFWsdq1haIclx/fesDWkDCW0/oBdJ1mrf7tt9s84vb3UDe3RekVlFs2QaAZqSpDK7VfRtcxUvo8viRa4xCCmC+PtpkbdG/WxRSVCSrxazbL6Il8v5Yh5n09nb6UX2Js7mvMzm02z2LoK0yPdoJDkwQuMq+kTYVOjgpdD2A1w5dBhfk0EfQeuaVVSHYN+nadd1Segt7ZywdZ+UpEeoRpVoPD41+MOIaYfbikyIPVWhEw6jYlMrD4dP4HOoEawjiy70QBVw+lVzl/6aEvhOLWjRg6EAJdl+ApqLWfEulQ9ObduAE2D+kjrTkJCMeRRkNCnjg2gaUAFaSwaE6RlLW3Z144OafBislSM9WhsqReC2jPEdOLWrAwSClosT/iXh2+0NlqN94LNBp/1A5iu6PRcUxM4hajT8ohYB8JYT97DF0CEa6JmgMPIM9c8Vs2b0sj6C+O09Gd0OdTnNqmJSAw/bOkseE7jiC01DvoZteiQ3AdugYN+98kz+6Y0ca1byjWDWp3kzx1MQeFRPefpHfkUu0ZdO2SHJZ808a+YhzRxLJR+aPda9WB9O8Gr9GrLp9GIyrIszof/LIU/v8fLghEQt3I/iI3FLNHyh1kiUQzMF3FnPCnICXa24I0PttwgOd9wPnszsbKBkHQveb1qnvFTlwMQneXof8DCW8fEZzzM8Pfxail+UKUFL); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/EA2EC948C7D7C063B.css b/docs/static/fonts/332720/EA2EC948C7D7C063B.css deleted file mode 100644 index 85e2bd607b..0000000000 --- a/docs/static/fonts/332720/EA2EC948C7D7C063B.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/truetype;base64,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FA4RJhkLF/7IFgwJFA4HDBEMDCMHEhIHBykHBxAQBwcpBgcHBwcAAAAAACQBtgABAAAAAAAAAEAAAAABAAAAAAABACMAQAABAAAAAAACAAcAYwABAAAAAAADACEAagABAAAAAAAEACMAQAABAAAAAAAFAA0AiwABAAAAAAAGAAQAmAABAAAAAAAHAFkAnAABAAAAAAAIAA0A9QABAAAAAAAJAA0A9QABAAAAAAAKAhEBAgABAAAAAAALABIDEwABAAAAAAAMABIDEwABAAAAAAANAhEBAgABAAAAAAAOACoDJQABAAAAAAAQACMAQAABAAAAAAARACMAQAABAAAAAAASACMAQAADAAEECQAAAIADTwADAAEECQABAEYDzwADAAEECQACAA4EFQADAAEECQADAEIEIwADAAEECQAEAEYDzwADAAEECQAFABoEZQADAAEECQAGAAgEfwADAAEECQAHALIEhwADAAEECQAIABoFOQADAAEECQAJABoFOQADAAEECQAKBCIFUwADAAEECQALACQJdQADAAEECQAMACQJdQADAAEECQANBCIFUwADAAEECQAOAFQJmQADAAEECQAQAEYDzwADAAEECQARAEYDzwADAAEECQASAEYDz0NvcHlyaWdodCAoQykgMjAwNiwgMjAwNyBIb2VmbGVyICYgQ28uIGh0dHA6Ly93d3cudHlwb2dyYXBoeS5jb21Db3B5cmlnaHQgKEMpIEgmQ28gfCB0eXBvZ3JhcGh5LmNvbVJlZ3VsYXIxNzEyNDctODg0NzQtMjAxNTA2MjMtMjQyMy0xNDAyMTlWZXJzaW9uIDEuMzAxRm9udEdvdGhhbSBpcyBhIHRyYWRlbWFyayBvZiBIb2VmbGVyICYgQ28uLCB3aGljaCBtYXkgYmUgcmVnaXN0ZXJlZCBpbiBjZXJ0YWluIGp1cmlzZGljdGlvbnMuSG9lZmxlciAmIENvLlRoaXMgc29mdHdhcmUgaXMgdGhlIHByb3BlcnR5IG9mIEhvZWZsZXIgJiBDby4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBvciBkb3dubG9hZCB0aGlzIHNvZnR3YXJlLCBvciBpbnN0YWxsIGl0IHVwb24gYW55IGNvbXB1dGVyLCBvciBob3N0IGl0IGZyb20gYW55IGxvY2F0aW9uLiBZb3VyIHJpZ2h0IHRvIHVzZSB0aGlzIHNvZnR3YXJlIGlzIHN1YmplY3QgdG8gdGhlIFRlcm1zIG9mIFNlcnZpY2UgYWdyZWVtZW50IHRoYXQgZXhpc3RzIGJldHdlZW4geW91IGFuZCBIb2VmbGVyICYgQ28uIElmIG5vIHN1Y2ggYWdyZWVtZW50IGV4aXN0cywgeW91IG1heSBub3QgdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpc2l0IGh0dHA6Ly93d3cudHlwb2dyYXBoeS5jb20vd2ViZm9udC1zb2Z0d2FyZSwgb3IgY29udGFjdCBIb2VmbGVyICYgQ28uIGF0IHd3dy50eXBvZ3JhcGh5LmNvbSAxNzEyNDctODg0NzQtMjAxNTA2MjMtMjQyMy0xNDAyMTl3d3cudHlwb2dyYXBoeS5jb21odHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUAQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgADIAMAAwADYALAAgADIAMAAwADcAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAASAAmAEMAbwAgAHwAIAB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AUgBlAGcAdQBsAGEAcgAxADcAMQAyADQANwAtADgAOAA0ADcANAAtADIAMAAxADUAMAA2ADIAMwAtADIANAAyADMALQAxADQAMAAyADEAOQBWAGUAcgBzAGkAbwBuACAAMQAuADMAMAAxAEYAbwBuAHQARwBvAHQAaABhAG0AIABpAHMAIABhACAAdAByAGEAZABlAG0AYQByAGsAIABvAGYAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACwAIAB3AGgAaQBjAGgAIABtAGEAeQAgAGIAZQAgAHIAZQBnAGkAcwB0AGUAcgBlAGQAIABpAG4AIABjAGUAcgB0AGEAaQBuACAAagB1AHIAaQBzAGQAaQBjAHQAaQBvAG4AcwAuAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AVABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHQAaABlACAAcAByAG8AcABlAHIAdAB5ACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAFkAbwB1ACAAbQBhAHkAIABuAG8AdAAgAGMAbwBwAHkALAAgAG0AbwBkAGkAZgB5ACwAIABkAGkAcwB0AHIAaQBiAHUAdABlACwAIABvAHIAIABkAG8AdwBuAGwAbwBhAGQAIAB0AGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABpAG4AcwB0AGEAbABsACAAaQB0ACAAdQBwAG8AbgAgAGEAbgB5ACAAYwBvAG0AcAB1AHQAZQByACwAIABvAHIAIABoAG8AcwB0ACAAaQB0ACAAZgByAG8AbQAgAGEAbgB5ACAAbABvAGMAYQB0AGkAbwBuAC4AIABZAG8AdQByACAAcgBpAGcAaAB0ACAAdABvACAAdQBzAGUAIAB0AGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAaQBzACAAcwB1AGIAagBlAGMAdAAgAHQAbwAgAHQAaABlACAAVABlAHIAbQBzACAAbwBmACAAUwBlAHIAdgBpAGMAZQAgAGEAZwByAGUAZQBtAGUAbgB0ACAAdABoAGEAdAAgAGUAeABpAHMAdABzACAAYgBlAHQAdwBlAGUAbgAgAHkAbwB1ACAAYQBuAGQAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAASQBmACAAbgBvACAAcwB1AGMAaAAgAGEAZwByAGUAZQBtAGUAbgB0ACAAZQB4AGkAcwB0AHMALAAgAHkAbwB1ACAAbQBhAHkAIABuAG8AdAAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGYAbwByACAAYQBuAHkAIABwAHUAcgBwAG8AcwBlAC4AIABGAG8AcgAgAG0AbwByAGUAIABpAG4AZgBvAHIAbQBhAHQAaQBvAG4ALAAgAHAAbABlAGEAcwBlACAAdgBpAHMAaQB0ACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8A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AAAAAAAAAAAAAAAAAAD/9v/nAAAAAAAAAAAAAAAA//EAAP+c//b/nAAAAAD/9gAA//EAAAAAAAAAAAAAAAAAAAAAABQAAP/2AAAAAAAAAAAAAAAA//YAAP/x//EAAAAAAAAAAAAAAAD/7AAA/+z/8f/2/+IAAAAKAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAAAAP/7AAAAAAAA/+cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAA//b/9v/x/+L/4gAA/9gAAP/2//YAAAAAAAAAAAAA/+IAAAAA/+cAAP/O/+z/5//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nAAD/7P/E/84AAP/OAAAAAAAAAAD/2AAAAAD/nP/s/43/nAAA/34AAAAA//b/sAAA/4gAAAAA//YAAAAA//sAAP/Y/+z/+wAAAAAAAAAAAAAAAAAA/8QAAP/Y/9j/pgAAAAAAAP/sAAAAAP/E/84AAP/EAAAAAAAA/9gAAP/i//v/yQAA/9j/3f/O/8T/2AAAAAAAAAAA/9j/7P/sAAAAAP/YAAD/2AAAAAAAAAAAAAAAAAAAAAAAAP/i/+wAAAAAAAAAAAAAAAD/2AAAAAAAAAAAAAD/+wAAAAAAAAAA/7oAAAAAAAAAAAAAAAD/+wAA//b/8f/2AAAAAAAAAAAAAAAA//sAAP+cAAD/nAAAAA8AAAAKAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAPAAAABQAAAAoAAAAKAAAAAAAAAAAAAAAAAAD/yQAAAAD/3QAA/78AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAD/9gAA/+z/8QAA/+cAAAAAAAAAAAAAAAAAAAAA//YAAAAA//sAAAAAAAr/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAA//b/8QAA/+L/5//n/+L/9gAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAA//sAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAP/7AAAAAP/x//b/8f/x//sAAAAA/6b/yf+S//EAAAAAAAAAAAAAAAD/7P95/7oAAP/sAAAAAAAA/3n/zv+c/4P/nP+m/87/g/+m/7r/2P/Y/5wAAAAAAAAAAAAAAAAAAP+NAAD/pv/OAAD/nP+c/5z/nP+c/5IAAAAA/+cAAP/sAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAD/+wAAAAAAAAAA/5z/2AAA/+cAAAAAAAD/9gAA/+z/9v+6AAAAAP/2AAAAAAAA/7r/7P+I/7//iP/Y/+f/v//E/9j/7AAA/9gAAAAAAAAAAAAAAAAAAP/EAAAAAP/sAAD/2AAA/90AAP/Y/8kAAAAA/6b/3f+X/+wAAAAA//b/9v/x/+z/9v+6/9MAAP/2AAAAAAAA/7//8f+c/8T/nP/d/+L/xP/O/93/8f/x/90AAAAAAAAAAAAAAAAAAP/EAAD/nP/nAAD/3f/d/93/2P/d/8kAAAAAAAD/zgAA/+IAAP/2AAD/8QAA/+wAAP/2AAAAAP/2AAAAAAAA/9MAAAAA/9gAAP/O/+z/2P/O/+z/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/7AAA/9gAAP/YAAAAAAAA/5L/xP9+/90AAAAA/+z/7P/sAAD/9v+c/7oAAP/2AAAAAAAA/5L/2P9+/5f/fv+w/9j/l/+c/7X/7P/s/7UAAAAAAAAAAAAAAAAAAP+cAAD/kv/iAAD/tf/E/8n/uv/E/7AAAAAAAAD/2AAA//YAAAAAAAAAAAAAAAD/9gAA//EAAAAAAAAAAAAA/+cAAAAA/+wAAP/i//b/7P/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/s//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA/7UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/90AAAAAAAAAAAAAAAAAAP/7AAAAAP/s/+wAAP/sAAAAAAAAAAAAAAAA//b/pgAAAAD/zgAA/7oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5wAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAA/+wAAAAA//EAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA/7r/8f/sAAAAAP/2AAD/9gAAAAAAAAAA//sAAAAAAAAAAP/i/90AAP/2AAAAAAAAAAAAAAAAAAAAAP/n/+z/4v/n//EAAAAAAAD/2AAAAAD/pv/xAAD/nAAA/5IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAAAA/8QAAP/EAAAAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAA//EAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAA//YAAP/2//YAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAA/+wAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAAAA/+wAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9gAAAAA//EAAAAA//YAAAAAAAD/9v/2AAoAAAAAAAAAAP/x//EAAAAKAA8AAAAAAAAAAAAAAAAAAP/7//v/9v/7AAAAAAAAAAAAAAAAAAD/zgAA/+z/8QAA/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/nP/x/4j/nAAA/34AAAAAAAAAAAAAAAAAAAAA/+wAAAAA//YAAAAA//H/9gAAAAAAAAAPAAD/zgAAAAAAAAAA/9gAAAAA/+wAAP/nAAAAAP+r/7oAAP/TAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7AAA/7D/9v/sAAAAAP/2AAD/9gAAAAAAAAAAAAAAAAAAAAAAAP/i/9gAAAAAAAAAAAAAAAAAAAAAAAAAAP/n/+f/4v/n//EAAAAAAAD/2AAAAAD/nP/x/4j/nAAA/34AAAAAAAAAAAAAAAAAAAAA/+wAAAAA//YAAAAA//H/9gAAAAAAAAAAAAD/zgAAAAAAAAAA/9gAAAAA/+wAAP/nAAAAAP+r/7oAAP/EAAD/7AAA/9gAAAAAAAD/pgAA/9j/3f/O/7D/4gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAA/9gAAAAA//YAAP/x//b/4v/x//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAHgAAAB4AHgAU//YAAP/T//b/0wAAAAD/9v/xAAAAAAAAAAAAAAAeACMAAAAeACMANwAAAAD/0wAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ugAA/9j/3f/s/7UAAAAAAAAAAAAAAAAAAAAA//YAAAAA//sAAAAAAAD/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/x//b/8f/xAAAAAAAA/+wAAAAA//b/pgAA/8T/zv/O/5z/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/2AAAAAP/i/+z/0//i/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA/7UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAP/s//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAA/9gAAAAA/+cAAAAA/+cAAP/sAAD/5//s//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAD/9v/s/+wAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7AAA/7D/8f/sAAAAAP/sAAD/7AAAAAAAAAAA//YAAAAAAAAAAP/i/84AAP/sAAAAAAAAAAAAAAAAAAAAAP/i/+f/3f/i/+wAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAA/+IAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/xP/xAAD/zgAA/7oAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAA/90AAP/dAAAAAAAA/6YAAP+wAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAA//EAAAAA//EAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAD/3QAAAAAAAP/2AAAAAAAPAAAAAAAAAAAAAAAA//YAAAAA/5wAAP+cAAAAAAAAAAAAAAAAAAAAAP/sAAAAAAAAAAAAAAAA/9MAAAAA/9gAAAAAAAD/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nAAAAFAAA/+IAAAAA/+cAAP+m/+f/pgAAAAD/5//2AAAAAAAAAAAAAAAAAAAAAAAUACMAAAAAAAD/tQAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/7X/9v/xAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAP/s/90AAP/2AAAAAP/2AAAAAP/2AAAAAP/s//H/5//x//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+cAAD/nP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4j/2AAA/+IAAAAAAAAAAAAAAAD/7P+/AAAAAAAAAAAAAAAA/7AAAAAA/7oAAAAA/+f/ugAAAAAAAAAA/84AAAAAAAAAAAAAAAAAAP+rAAAAAP/sAAD/zgAA/84AAP/O/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9gAAAAA//EAAAAA//EAAAAAAAD/8f/2AAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nAAAAAAAAAAAAAAAA/+IAAP+r/+f/q//xAAD/5//i//EAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAAAAAAAAAAAAAAA//EAAP/x//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAAAAAAA/87/9v/s/+cAAP+6/+z/uv/2AAD/7P/s//YAAAAAAAAAAAAA//YAAAAAAAAAAP/xAAD/xAAAAAAAAP/x//b/9v/2//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAAAA/90AAAAA/+IAAP/iAAD/4v/T//EAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAAAAAAAAAAAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nAAAAAAAA/87/9v/s/+IAAP+r/+f/q//xAAD/5//i//EAAAAAAAAAAAAA//YAAAAAAAAAAP/sAAD/ugAAAAAAAP/x//b/9v/2//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9MAAAAA//EAAAAA//EAAAAAAAD/8f/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAcAWwAYAAAALAAAABkAAAAgACMAIgAzAAAAMgAfAB8AAAAAAAAAAAABAAIAAwAEAAYABwAIAAkACgAAAAsADAANAA4ADwAQABEAEgATABQAFQAWAB0AGwAAAAAAFwAaAB4AIQAkACUAKAAAAAAAKQAAACgAKAArABoAAAA0ADYAOAA5ABwAAAAAAAAAAAAAAAAAAAAmAAAAAAAAAAAAJwAtACMAIwAuAC8AIAAuAC8AIAAAACIAJgAnAAEABwBdAA0AAAAAACEADgAAABUAGAAXACkAAAAoABQAFAAAAAAAAAAiAAEAAAACAAAAAAACAAMAAAAAAAAAAgAAAAIAAAAEAAUABgAHAAgACQAKAAsAAAAQABIAAAAMAA8AEwATABkAGgAPAB0AHgAPAA8AHwAfABMAHwAWACoALQAvADAAAAAAABEAAAAAAAAAAAAAABsAJgAAAAAAAAAcACMAGAAYACQAJQAVACQAJQAVAAAAFwAbABwAAAAmAAIADgAHAAcAAAAJAAkAAQALAAsAAgANABAAAwASABQABwAZACEACgAjADAAEwAzADkAIQA8ADwAKAA+AEEAKQBDAEcALQBPAE8AMgBUAF0AMwBfAGEAPQABAAgAAQAAAAEAAQADAAAAAQAAAAoAMAA+AAJERkxUAA5sYXRuABoABAAAAAD//wABAAAABAAAAAD//wABAAAAAXNzMDEACAAAAAEAAAACAAYADgAGAAAAAQAQAAEAAAABACgAAQAIAAEADgABAAEAZAABAAQAAQBkAAEAAAABAAAAAQABAAb/nwABAAEAZA==); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:font/truetype;base64,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cmVlbWVudCB0aGF0IGV4aXN0cyBiZXR3ZWVuIHlvdSBhbmQgSG9lZmxlciAmIENvLiBJZiBubyBzdWNoIGFncmVlbWVudCBleGlzdHMsIHlvdSBtYXkgbm90IHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSB2aXNpdCBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUsIG9yIGNvbnRhY3QgSG9lZmxlciAmIENvLiBhdCB3d3cudHlwb2dyYXBoeS5jb20gMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5d3d3LnR5cG9ncmFwaHkuY29taHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbS93ZWJmb250LXNvZnR3YXJlAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMAA2ACwAIAAyADAAMAA3ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgAEgAJgBDAG8AIAB8ACAAdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAFIAZQBnAHUAbABhAHIAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAVgBlAHIAcwBpAG8AbgAgADEALgAzADAAMQBGAG8AbgB0AEcAbwB0AGgAYQBtACAAaQBzACAAYQAgAHQAcgBhAGQAZQBtAGEAcgBrACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAsACAAdwBoAGkAYwBoACAAbQBhAHkAIABiAGUAIAByAGUAZwBpAHMAdABlAHIAZQBkACAAaQBuACAAYwBlAHIAdABhAGkAbgAgAGoAdQByAGkAcwBkAGkAYwB0AGkAbwBuAHMALgBIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuAFQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIAB0AGgAZQAgAHAAcgBvAHAAZQByAHQAeQAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABZAG8AdQAgAG0AYQB5ACAAbgBvAHQAIABjAG8AcAB5ACwAIABtAG8AZABpAGYAeQAsACAAZABpAHMAdAByAGkAYgB1AHQAZQAsACAAbwByACAAZABvAHcAbgBsAG8AYQBkACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAsACAAbwByACAAaQBuAHMAdABhAGwAbAAgAGkAdAAgAHUAcABvAG4AIABhAG4AeQAgAGMAbwBtAHAAdQB0AGUAcgAsACAAbwByACAAaABvAHMAdAAgAGkAdAAgAGYAcgBvAG0AIABhAG4AeQAgAGwAbwBjAGEAdABpAG8AbgAuACAAWQBvAHUAcgAgAHIAaQBnAGgAdAAgAHQAbwAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHMAdQBiAGoAZQBjAHQAIAB0AG8AIAB0AGgAZQAgAFQAZQByAG0AcwAgAG8AZgAgAFMAZQByAHYAaQBjAGUAIABhAGcAcgBlAGUAbQBlAG4AdAAgAHQAaABhAHQAIABlAHgAaQBzAHQAcwAgAGIAZQB0AHcAZQBlAG4AIAB5AG8AdQAgAGEAbgBkACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAEkAZgAgAG4AbwAgAHMAdQBjAGgAIABhAGcAcgBlAGUAbQBlAG4AdAAgAGUAeABpAHMAdABzACwAIAB5AG8AdQAgAG0AYQB5ACAAbgBvAHQAIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABmAG8AcgAgAGEAbgB5ACAAcAB1AHIAcABvAHMAZQAuACAARgBvAHIAIABtAG8AcgBlACAAaQBuAGYAbwByAG0AYQB0AGkAbwBuACwAIABwAGwAZQBhAHMAZQAgAHYAaQBzAGkAdAAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0ALwB3AGUAYgBmAG8AbgB0AC0AcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABjAG8AbgB0AGEAYwB0ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGEAdAAgAHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtACAAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAvAHcAZQBiAGYAbwBuAHQALQBzAG8AZgB0AHcAYQByAGUAAAIAAAAAAAD/tQAyAAAAAAAAAAAAAAAAAAAAAAAAAAAAHQAAAAEAAgADAAQABwATABQAFQAWABgAGQAbABwAIwAoACsALAAxADsARwBSAFUAVgBYAFoAXQCjAQIHaGNvc2x1ZwABAAH//wAKAAEAAAAOAAAAGAAAAAAAAgABAAEAHAABAAQAAAACAAA=); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/F0E469574253DABD5.css b/docs/static/fonts/332720/F0E469574253DABD5.css deleted file mode 100644 index fc6add2211..0000000000 --- a/docs/static/fonts/332720/F0E469574253DABD5.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/FA4DC96C390FF844F.eot b/docs/static/fonts/332720/FA4DC96C390FF844F.eot deleted file mode 100644 index 0a1e78dcad..0000000000 Binary files a/docs/static/fonts/332720/FA4DC96C390FF844F.eot and /dev/null differ diff --git a/docs/static/images/Mercurial_features_screenshot.png b/docs/static/images/Mercurial_features_screenshot.png deleted file mode 100644 index 77370d6df9..0000000000 Binary files a/docs/static/images/Mercurial_features_screenshot.png and /dev/null differ diff --git a/docs/static/images/blog/2017-02-27/notification.png b/docs/static/images/blog/2017-02-27/notification.png deleted file mode 100644 index 8c2438f24b..0000000000 Binary files a/docs/static/images/blog/2017-02-27/notification.png and /dev/null differ diff --git a/docs/static/images/blog/2017-02-27/poll.png b/docs/static/images/blog/2017-02-27/poll.png deleted file mode 100644 index 3a3b865e8a..0000000000 Binary files a/docs/static/images/blog/2017-02-27/poll.png and /dev/null differ diff --git a/docs/static/images/blog/2017-08-31/quick-open.png b/docs/static/images/blog/2017-08-31/quick-open.png deleted file mode 100644 index 5f77990556..0000000000 Binary files a/docs/static/images/blog/2017-08-31/quick-open.png and /dev/null differ diff --git a/docs/static/images/blog/2017-08-31/settings.png b/docs/static/images/blog/2017-08-31/settings.png deleted file mode 100644 index a1d90c43e5..0000000000 Binary files a/docs/static/images/blog/2017-08-31/settings.png and /dev/null differ diff --git a/docs/static/images/blog/2017-09-12/atom-ide-ui.png b/docs/static/images/blog/2017-09-12/atom-ide-ui.png deleted file mode 100644 index ee4c74239f..0000000000 Binary files a/docs/static/images/blog/2017-09-12/atom-ide-ui.png and /dev/null differ diff --git a/docs/static/images/blog/nuclide-atom-settings.png b/docs/static/images/blog/nuclide-atom-settings.png deleted file mode 100644 index 0e6e57dea9..0000000000 Binary files a/docs/static/images/blog/nuclide-atom-settings.png and /dev/null differ diff --git a/docs/static/images/blog/nuclide-feature-settings.png b/docs/static/images/blog/nuclide-feature-settings.png deleted file mode 100644 index 2ec10785c8..0000000000 Binary files a/docs/static/images/blog/nuclide-feature-settings.png and /dev/null differ diff --git a/docs/static/images/docs/debugger-hhvm-settings.PNG b/docs/static/images/docs/debugger-hhvm-settings.PNG deleted file mode 100644 index 3a8d68fb03..0000000000 Binary files a/docs/static/images/docs/debugger-hhvm-settings.PNG and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-adding-projects.png b/docs/static/images/docs/editor-basics-adding-projects.png deleted file mode 100644 index af90987b96..0000000000 Binary files a/docs/static/images/docs/editor-basics-adding-projects.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-command-palette-intro.png b/docs/static/images/docs/editor-basics-command-palette-intro.png deleted file mode 100644 index 4952eac8b4..0000000000 Binary files a/docs/static/images/docs/editor-basics-command-palette-intro.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-command-palette-search.png b/docs/static/images/docs/editor-basics-command-palette-search.png deleted file mode 100644 index 7d584fd811..0000000000 Binary files a/docs/static/images/docs/editor-basics-command-palette-search.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-distraction-free.png b/docs/static/images/docs/editor-basics-distraction-free.png deleted file mode 100644 index daba559d09..0000000000 Binary files a/docs/static/images/docs/editor-basics-distraction-free.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-distraction.png b/docs/static/images/docs/editor-basics-distraction.png deleted file mode 100644 index 8e788441da..0000000000 Binary files a/docs/static/images/docs/editor-basics-distraction.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-editing-area-symbols.png b/docs/static/images/docs/editor-basics-editing-area-symbols.png deleted file mode 100644 index abe4126038..0000000000 Binary files a/docs/static/images/docs/editor-basics-editing-area-symbols.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-editing-context-aware.png b/docs/static/images/docs/editor-basics-editing-context-aware.png deleted file mode 100644 index 9687ffaf8b..0000000000 Binary files a/docs/static/images/docs/editor-basics-editing-context-aware.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-editing-omnisearch.png b/docs/static/images/docs/editor-basics-editing-omnisearch.png deleted file mode 100644 index e7eb5e70ad..0000000000 Binary files a/docs/static/images/docs/editor-basics-editing-omnisearch.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-editing-panes.png b/docs/static/images/docs/editor-basics-editing-panes.png deleted file mode 100644 index f1b8d5de38..0000000000 Binary files a/docs/static/images/docs/editor-basics-editing-panes.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-explorer-changed-files.png b/docs/static/images/docs/editor-basics-explorer-changed-files.png deleted file mode 100644 index 2bd783f3a5..0000000000 Binary files a/docs/static/images/docs/editor-basics-explorer-changed-files.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-explorer-context-aware.png b/docs/static/images/docs/editor-basics-explorer-context-aware.png deleted file mode 100644 index 6318df42cd..0000000000 Binary files a/docs/static/images/docs/editor-basics-explorer-context-aware.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-file-tree.png b/docs/static/images/docs/editor-basics-file-tree.png deleted file mode 100644 index 9116f66734..0000000000 Binary files a/docs/static/images/docs/editor-basics-file-tree.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-gutter-code-diagnostics.png b/docs/static/images/docs/editor-basics-gutter-code-diagnostics.png deleted file mode 100644 index d8e5e29659..0000000000 Binary files a/docs/static/images/docs/editor-basics-gutter-code-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-gutter-intro.png b/docs/static/images/docs/editor-basics-gutter-intro.png deleted file mode 100644 index c27ed858f1..0000000000 Binary files a/docs/static/images/docs/editor-basics-gutter-intro.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-homepage.png b/docs/static/images/docs/editor-basics-homepage.png deleted file mode 100644 index 20d6c18d2b..0000000000 Binary files a/docs/static/images/docs/editor-basics-homepage.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-intro.png b/docs/static/images/docs/editor-basics-intro.png deleted file mode 100644 index 6df564c953..0000000000 Binary files a/docs/static/images/docs/editor-basics-intro.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-nuclide-package.png b/docs/static/images/docs/editor-basics-nuclide-package.png deleted file mode 100644 index 6af69e0731..0000000000 Binary files a/docs/static/images/docs/editor-basics-nuclide-package.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-nuclide-preferences.png b/docs/static/images/docs/editor-basics-nuclide-preferences.png deleted file mode 100644 index 6e5db93619..0000000000 Binary files a/docs/static/images/docs/editor-basics-nuclide-preferences.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-open-files.png b/docs/static/images/docs/editor-basics-open-files.png deleted file mode 100644 index 27f68cea00..0000000000 Binary files a/docs/static/images/docs/editor-basics-open-files.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-status-bar-connection.png b/docs/static/images/docs/editor-basics-status-bar-connection.png deleted file mode 100644 index 7c8f28c770..0000000000 Binary files a/docs/static/images/docs/editor-basics-status-bar-connection.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-status-bar-diagnostics.png b/docs/static/images/docs/editor-basics-status-bar-diagnostics.png deleted file mode 100644 index 2f379c44b1..0000000000 Binary files a/docs/static/images/docs/editor-basics-status-bar-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-status-bar-intro.png b/docs/static/images/docs/editor-basics-status-bar-intro.png deleted file mode 100644 index 1f36158c53..0000000000 Binary files a/docs/static/images/docs/editor-basics-status-bar-intro.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-uncommitted.png b/docs/static/images/docs/editor-basics-uncommitted.png deleted file mode 100644 index 2f3c7a518e..0000000000 Binary files a/docs/static/images/docs/editor-basics-uncommitted.png and /dev/null differ diff --git a/docs/static/images/docs/editor-keyboard-shortcuts-hyperclick.png b/docs/static/images/docs/editor-keyboard-shortcuts-hyperclick.png deleted file mode 100644 index b72e071d00..0000000000 Binary files a/docs/static/images/docs/editor-keyboard-shortcuts-hyperclick.png and /dev/null differ diff --git a/docs/static/images/docs/editor-setup-atom-install-nuclide.png b/docs/static/images/docs/editor-setup-atom-install-nuclide.png deleted file mode 100644 index 58d6d7b189..0000000000 Binary files a/docs/static/images/docs/editor-setup-atom-install-nuclide.png and /dev/null differ diff --git a/docs/static/images/docs/editor-setup-atom-install-windows.png b/docs/static/images/docs/editor-setup-atom-install-windows.png deleted file mode 100644 index 921dac3ec0..0000000000 Binary files a/docs/static/images/docs/editor-setup-atom-install-windows.png and /dev/null differ diff --git a/docs/static/images/docs/editor-setup-recommended-packages.png b/docs/static/images/docs/editor-setup-recommended-packages.png deleted file mode 100644 index 0692f4d8ec..0000000000 Binary files a/docs/static/images/docs/editor-setup-recommended-packages.png and /dev/null differ diff --git a/docs/static/images/docs/editor-uninstall-reenable-atom-tree-view.png b/docs/static/images/docs/editor-uninstall-reenable-atom-tree-view.png deleted file mode 100644 index 4f2679ea21..0000000000 Binary files a/docs/static/images/docs/editor-uninstall-reenable-atom-tree-view.png and /dev/null differ diff --git a/docs/static/images/docs/feature-buck-command-palette.png b/docs/static/images/docs/feature-buck-command-palette.png deleted file mode 100644 index 4bd7df76f6..0000000000 Binary files a/docs/static/images/docs/feature-buck-command-palette.png and /dev/null differ diff --git a/docs/static/images/docs/feature-buck-nuclide-menu.png b/docs/static/images/docs/feature-buck-nuclide-menu.png deleted file mode 100644 index 7d9261f3c6..0000000000 Binary files a/docs/static/images/docs/feature-buck-nuclide-menu.png and /dev/null differ diff --git a/docs/static/images/docs/feature-buck-task-runner.png b/docs/static/images/docs/feature-buck-task-runner.png deleted file mode 100644 index 0ba34a0b09..0000000000 Binary files a/docs/static/images/docs/feature-buck-task-runner.png and /dev/null differ diff --git a/docs/static/images/docs/feature-context-view-highlight.png b/docs/static/images/docs/feature-context-view-highlight.png deleted file mode 100644 index 2e44f19f37..0000000000 Binary files a/docs/static/images/docs/feature-context-view-highlight.png and /dev/null differ diff --git a/docs/static/images/docs/feature-context-view.png b/docs/static/images/docs/feature-context-view.png deleted file mode 100644 index df8dfe7656..0000000000 Binary files a/docs/static/images/docs/feature-context-view.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-breakpoint-menu.png b/docs/static/images/docs/feature-debugger-basics-breakpoint-menu.png deleted file mode 100644 index 738d14871b..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-breakpoint-menu.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-breakpoints-gutter.png b/docs/static/images/docs/feature-debugger-basics-breakpoints-gutter.png deleted file mode 100644 index 278fc5bc88..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-breakpoints-gutter.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-breakpoints-main-debugging-tab.png b/docs/static/images/docs/feature-debugger-basics-breakpoints-main-debugging-tab.png deleted file mode 100644 index 7802572ca1..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-breakpoints-main-debugging-tab.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-debugger-breakpoint-menu.png b/docs/static/images/docs/feature-debugger-basics-debugger-breakpoint-menu.png deleted file mode 100644 index 738d14871b..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-debugger-breakpoint-menu.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-debugger-example.png b/docs/static/images/docs/feature-debugger-basics-debugger-example.png deleted file mode 100644 index 16141c8e0c..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-debugger-example.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-debugger-watch-menu.png b/docs/static/images/docs/feature-debugger-basics-debugger-watch-menu.png deleted file mode 100644 index d20f8cbd06..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-debugger-watch-menu.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-stepping-example-start-other-module.png b/docs/static/images/docs/feature-debugger-basics-stepping-example-start-other-module.png deleted file mode 100644 index a911da3d11..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-stepping-example-start-other-module.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-stepping-icons.png b/docs/static/images/docs/feature-debugger-basics-stepping-icons.png deleted file mode 100644 index 4faba70c19..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-stepping-icons.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-target-after-attach.png b/docs/static/images/docs/feature-debugger-basics-target-after-attach.png deleted file mode 100644 index 668258d723..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-target-after-attach.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-target-process.png b/docs/static/images/docs/feature-debugger-basics-target-process.png deleted file mode 100644 index 53aa35e975..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-target-process.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-evaluation-ex.png b/docs/static/images/docs/feature-debugger-evaluation-ex.png deleted file mode 100644 index 8b9ddddfaf..0000000000 Binary files a/docs/static/images/docs/feature-debugger-evaluation-ex.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-languages-cpp-attach.png b/docs/static/images/docs/feature-debugger-languages-cpp-attach.png deleted file mode 100644 index b0fff34e7a..0000000000 Binary files a/docs/static/images/docs/feature-debugger-languages-cpp-attach.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-languages-cpp-launch.png b/docs/static/images/docs/feature-debugger-languages-cpp-launch.png deleted file mode 100644 index 4940463a38..0000000000 Binary files a/docs/static/images/docs/feature-debugger-languages-cpp-launch.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-languages-hack-php-filtering.png b/docs/static/images/docs/feature-debugger-languages-hack-php-filtering.png deleted file mode 100644 index 1e98701486..0000000000 Binary files a/docs/static/images/docs/feature-debugger-languages-hack-php-filtering.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-languages-react-native-application-debug-options.png b/docs/static/images/docs/feature-debugger-languages-react-native-application-debug-options.png deleted file mode 100644 index 305a289b5f..0000000000 Binary files a/docs/static/images/docs/feature-debugger-languages-react-native-application-debug-options.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-languages-react-native-application-show-inspector.png b/docs/static/images/docs/feature-debugger-languages-react-native-application-show-inspector.png deleted file mode 100644 index d323ee9d19..0000000000 Binary files a/docs/static/images/docs/feature-debugger-languages-react-native-application-show-inspector.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-languages-react-native-debugging.png b/docs/static/images/docs/feature-debugger-languages-react-native-debugging.png deleted file mode 100644 index 07ab48ed89..0000000000 Binary files a/docs/static/images/docs/feature-debugger-languages-react-native-debugging.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-languages-react-native-server.png b/docs/static/images/docs/feature-debugger-languages-react-native-server.png deleted file mode 100644 index 44022660bf..0000000000 Binary files a/docs/static/images/docs/feature-debugger-languages-react-native-server.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-selection-attach-server.png b/docs/static/images/docs/feature-debugger-selection-attach-server.png deleted file mode 100644 index 57d74eba01..0000000000 Binary files a/docs/static/images/docs/feature-debugger-selection-attach-server.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-stepping-controls.png b/docs/static/images/docs/feature-debugger-stepping-controls.png deleted file mode 100644 index 0574671771..0000000000 Binary files a/docs/static/images/docs/feature-debugger-stepping-controls.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-target-attach.png b/docs/static/images/docs/feature-debugger-target-attach.png deleted file mode 100644 index 37c8f28881..0000000000 Binary files a/docs/static/images/docs/feature-debugger-target-attach.png and /dev/null differ diff --git a/docs/static/images/docs/feature-format-js-after.png b/docs/static/images/docs/feature-format-js-after.png deleted file mode 100644 index 2a75555410..0000000000 Binary files a/docs/static/images/docs/feature-format-js-after.png and /dev/null differ diff --git a/docs/static/images/docs/feature-format-js-before.png b/docs/static/images/docs/feature-format-js-before.png deleted file mode 100644 index 2dcc8a66a5..0000000000 Binary files a/docs/static/images/docs/feature-format-js-before.png and /dev/null differ diff --git a/docs/static/images/docs/feature-format-js-keybindings.png b/docs/static/images/docs/feature-format-js-keybindings.png deleted file mode 100644 index c0be428aba..0000000000 Binary files a/docs/static/images/docs/feature-format-js-keybindings.png and /dev/null differ diff --git a/docs/static/images/docs/feature-format-js-settings.png b/docs/static/images/docs/feature-format-js-settings.png deleted file mode 100644 index df3e1dd080..0000000000 Binary files a/docs/static/images/docs/feature-format-js-settings.png and /dev/null differ diff --git a/docs/static/images/docs/feature-health-overview.png b/docs/static/images/docs/feature-health-overview.png deleted file mode 100644 index 5a91fbf4ae..0000000000 Binary files a/docs/static/images/docs/feature-health-overview.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-blame-access.png b/docs/static/images/docs/feature-hg-blame-access.png deleted file mode 100644 index 7561ac24a8..0000000000 Binary files a/docs/static/images/docs/feature-hg-blame-access.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-blame-gutter.png b/docs/static/images/docs/feature-hg-blame-gutter.png deleted file mode 100644 index b9b65c263f..0000000000 Binary files a/docs/static/images/docs/feature-hg-blame-gutter.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-bookmark.png b/docs/static/images/docs/feature-hg-bookmark.png deleted file mode 100644 index 3fa97f87d7..0000000000 Binary files a/docs/static/images/docs/feature-hg-bookmark.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-file-tree-highlight.png b/docs/static/images/docs/feature-hg-file-tree-highlight.png deleted file mode 100644 index c4889ddcf1..0000000000 Binary files a/docs/static/images/docs/feature-hg-file-tree-highlight.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-line-mod-gutter-setting.png b/docs/static/images/docs/feature-hg-line-mod-gutter-setting.png deleted file mode 100644 index 923ba42925..0000000000 Binary files a/docs/static/images/docs/feature-hg-line-mod-gutter-setting.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-line-modifications.png b/docs/static/images/docs/feature-hg-line-modifications.png deleted file mode 100644 index 69b25c0b06..0000000000 Binary files a/docs/static/images/docs/feature-hg-line-modifications.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-number-of-line-changes.png b/docs/static/images/docs/feature-hg-number-of-line-changes.png deleted file mode 100644 index e116ec2477..0000000000 Binary files a/docs/static/images/docs/feature-hg-number-of-line-changes.png and /dev/null differ diff --git a/docs/static/images/docs/feature-outline-view-click.png b/docs/static/images/docs/feature-outline-view-click.png deleted file mode 100644 index f87f1008b2..0000000000 Binary files a/docs/static/images/docs/feature-outline-view-click.png and /dev/null differ diff --git a/docs/static/images/docs/feature-outline-view.png b/docs/static/images/docs/feature-outline-view.png deleted file mode 100644 index e4009bd0b6..0000000000 Binary files a/docs/static/images/docs/feature-outline-view.png and /dev/null differ diff --git a/docs/static/images/docs/feature-quick-open-filenames.png b/docs/static/images/docs/feature-quick-open-filenames.png deleted file mode 100644 index 46e0ed0553..0000000000 Binary files a/docs/static/images/docs/feature-quick-open-filenames.png and /dev/null differ diff --git a/docs/static/images/docs/feature-quick-open-omnisearch.png b/docs/static/images/docs/feature-quick-open-omnisearch.png deleted file mode 100644 index c72658003c..0000000000 Binary files a/docs/static/images/docs/feature-quick-open-omnisearch.png and /dev/null differ diff --git a/docs/static/images/docs/feature-quick-open-open-files.png b/docs/static/images/docs/feature-quick-open-open-files.png deleted file mode 100644 index 45fba3ced2..0000000000 Binary files a/docs/static/images/docs/feature-quick-open-open-files.png and /dev/null differ diff --git a/docs/static/images/docs/feature-quick-open-toggle-hack-symbols.png b/docs/static/images/docs/feature-quick-open-toggle-hack-symbols.png deleted file mode 100644 index a2dec16ea3..0000000000 Binary files a/docs/static/images/docs/feature-quick-open-toggle-hack-symbols.png and /dev/null differ diff --git a/docs/static/images/docs/feature-quick-open-toggle-recent-files.png b/docs/static/images/docs/feature-quick-open-toggle-recent-files.png deleted file mode 100644 index d662d9aa62..0000000000 Binary files a/docs/static/images/docs/feature-quick-open-toggle-recent-files.png and /dev/null differ diff --git a/docs/static/images/docs/feature-quick-open-toggle-window.png b/docs/static/images/docs/feature-quick-open-toggle-window.png deleted file mode 100644 index 7a4c2f79cf..0000000000 Binary files a/docs/static/images/docs/feature-quick-open-toggle-window.png and /dev/null differ diff --git a/docs/static/images/docs/feature-remote-add-profile.png b/docs/static/images/docs/feature-remote-add-profile.png deleted file mode 100644 index 25b137026c..0000000000 Binary files a/docs/static/images/docs/feature-remote-add-profile.png and /dev/null differ diff --git a/docs/static/images/docs/feature-remote-add-remote-project-file-tree.png b/docs/static/images/docs/feature-remote-add-remote-project-file-tree.png deleted file mode 100644 index ada48c6376..0000000000 Binary files a/docs/static/images/docs/feature-remote-add-remote-project-file-tree.png and /dev/null differ diff --git a/docs/static/images/docs/feature-remote-connect-dialog-box.png b/docs/static/images/docs/feature-remote-connect-dialog-box.png deleted file mode 100644 index a40b9895fe..0000000000 Binary files a/docs/static/images/docs/feature-remote-connect-dialog-box.png and /dev/null differ diff --git a/docs/static/images/docs/feature-remote-connect-menu.png b/docs/static/images/docs/feature-remote-connect-menu.png deleted file mode 100644 index 024d9c9488..0000000000 Binary files a/docs/static/images/docs/feature-remote-connect-menu.png and /dev/null differ diff --git a/docs/static/images/docs/feature-remote-file-tree.png b/docs/static/images/docs/feature-remote-file-tree.png deleted file mode 100644 index e7b20ed475..0000000000 Binary files a/docs/static/images/docs/feature-remote-file-tree.png and /dev/null differ diff --git a/docs/static/images/docs/feature-remote-profiles.png b/docs/static/images/docs/feature-remote-profiles.png deleted file mode 100644 index ede1904050..0000000000 Binary files a/docs/static/images/docs/feature-remote-profiles.png and /dev/null differ diff --git a/docs/static/images/docs/feature-remote-projects-menu.png b/docs/static/images/docs/feature-remote-projects-menu.png deleted file mode 100644 index b4de9825ce..0000000000 Binary files a/docs/static/images/docs/feature-remote-projects-menu.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runer-buck-build-console.png b/docs/static/images/docs/feature-task-runer-buck-build-console.png deleted file mode 100644 index 7277c0ba82..0000000000 Binary files a/docs/static/images/docs/feature-task-runer-buck-build-console.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-buck-build-diagnostics.png b/docs/static/images/docs/feature-task-runner-buck-build-diagnostics.png deleted file mode 100644 index 71aa6bf5e8..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-buck-build-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-buck-build-settings.png b/docs/static/images/docs/feature-task-runner-buck-build-settings.png deleted file mode 100644 index baf21fbaca..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-buck-build-settings.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-buck-build.png b/docs/static/images/docs/feature-task-runner-buck-build.png deleted file mode 100644 index 24b61f1943..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-buck-build.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-buck-debug.png b/docs/static/images/docs/feature-task-runner-buck-debug.png deleted file mode 100644 index 15f6420db6..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-buck-debug.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-buck-run.png b/docs/static/images/docs/feature-task-runner-buck-run.png deleted file mode 100644 index 0d108505f8..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-buck-run.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-buck-test.png b/docs/static/images/docs/feature-task-runner-buck-test.png deleted file mode 100644 index f04b27559d..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-buck-test.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-hack-selection.png b/docs/static/images/docs/feature-task-runner-hack-selection.png deleted file mode 100644 index d6e247d4d9..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-hack-selection.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-hack-toolbar.png b/docs/static/images/docs/feature-task-runner-hack-toolbar.png deleted file mode 100644 index 85cb83f952..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-hack-toolbar.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-hhvm-debug.png b/docs/static/images/docs/feature-task-runner-hhvm-debug.png deleted file mode 100644 index ccdba4ab53..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-hhvm-debug.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-swift-build-output.png b/docs/static/images/docs/feature-task-runner-swift-build-output.png deleted file mode 100644 index 84ab8c66a2..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-swift-build-output.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-swift-build-settings.png b/docs/static/images/docs/feature-task-runner-swift-build-settings.png deleted file mode 100644 index 01618796c0..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-swift-build-settings.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-swift-build-toolbar.png b/docs/static/images/docs/feature-task-runner-swift-build-toolbar.png deleted file mode 100644 index 2ad53c6eed..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-swift-build-toolbar.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-swift-test-output.png b/docs/static/images/docs/feature-task-runner-swift-test-output.png deleted file mode 100644 index 8d7b3c34ff..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-swift-test-output.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-swift-test-toolbar.png b/docs/static/images/docs/feature-task-runner-swift-test-toolbar.png deleted file mode 100644 index 1cfebdf666..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-swift-test-toolbar.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-console.png b/docs/static/images/docs/feature-toolbar-button-console.png deleted file mode 100644 index deafc72c26..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-console.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-context-view.png b/docs/static/images/docs/feature-toolbar-button-context-view.png deleted file mode 100644 index 36cdd45934..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-context-view.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-debugger.png b/docs/static/images/docs/feature-toolbar-button-debugger.png deleted file mode 100644 index a1f7d710e4..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-debugger.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-diagnostics.png b/docs/static/images/docs/feature-toolbar-button-diagnostics.png deleted file mode 100644 index 419cf63b6e..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-distraction-free-mode.png b/docs/static/images/docs/feature-toolbar-button-distraction-free-mode.png deleted file mode 100644 index 2b08f0cebc..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-distraction-free-mode.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-hhvm-toolbar.png b/docs/static/images/docs/feature-toolbar-button-hhvm-toolbar.png deleted file mode 100644 index 24a9324375..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-hhvm-toolbar.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-nuclide-health.png b/docs/static/images/docs/feature-toolbar-button-nuclide-health.png deleted file mode 100644 index 85ea2e5819..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-nuclide-health.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-nuclide-settings.png b/docs/static/images/docs/feature-toolbar-button-nuclide-settings.png deleted file mode 100644 index c64f9dac36..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-nuclide-settings.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-outline-view.png b/docs/static/images/docs/feature-toolbar-button-outline-view.png deleted file mode 100644 index 10faa8c320..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-outline-view.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-settings-view.png b/docs/static/images/docs/feature-toolbar-button-settings-view.png deleted file mode 100644 index 1f3ccada37..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-settings-view.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-task-runner.png b/docs/static/images/docs/feature-toolbar-button-task-runner.png deleted file mode 100644 index 2e4d95200b..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-task-runner.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-test-runner.png b/docs/static/images/docs/feature-toolbar-button-test-runner.png deleted file mode 100644 index d52b9a86d2..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-test-runner.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-find-package.png b/docs/static/images/docs/feature-toolbar-find-package.png deleted file mode 100644 index 0ce0623173..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-find-package.png and /dev/null differ diff --git a/docs/static/images/docs/feature-working-set-add.png b/docs/static/images/docs/feature-working-set-add.png deleted file mode 100644 index 82d04502ec..0000000000 Binary files a/docs/static/images/docs/feature-working-set-add.png and /dev/null differ diff --git a/docs/static/images/docs/feature-working-set-all-working-sets.png b/docs/static/images/docs/feature-working-set-all-working-sets.png deleted file mode 100644 index 0af43b0ff0..0000000000 Binary files a/docs/static/images/docs/feature-working-set-all-working-sets.png and /dev/null differ diff --git a/docs/static/images/docs/feature-working-set-begin.png b/docs/static/images/docs/feature-working-set-begin.png deleted file mode 100644 index 38152ef773..0000000000 Binary files a/docs/static/images/docs/feature-working-set-begin.png and /dev/null differ diff --git a/docs/static/images/docs/feature-working-set-created.png b/docs/static/images/docs/feature-working-set-created.png deleted file mode 100644 index 1719eb5ea1..0000000000 Binary files a/docs/static/images/docs/feature-working-set-created.png and /dev/null differ diff --git a/docs/static/images/docs/feature-working-set-deactivate.png b/docs/static/images/docs/feature-working-set-deactivate.png deleted file mode 100644 index a91cce7e23..0000000000 Binary files a/docs/static/images/docs/feature-working-set-deactivate.png and /dev/null differ diff --git a/docs/static/images/docs/feature-working-set-edit.png b/docs/static/images/docs/feature-working-set-edit.png deleted file mode 100644 index 1c55661aed..0000000000 Binary files a/docs/static/images/docs/feature-working-set-edit.png and /dev/null differ diff --git a/docs/static/images/docs/feature-working-set-not-working-set-file.png b/docs/static/images/docs/feature-working-set-not-working-set-file.png deleted file mode 100644 index b581c25490..0000000000 Binary files a/docs/static/images/docs/feature-working-set-not-working-set-file.png and /dev/null differ diff --git a/docs/static/images/docs/feature-working-set-select-active.png b/docs/static/images/docs/feature-working-set-select-active.png deleted file mode 100644 index c0c1256d4f..0000000000 Binary files a/docs/static/images/docs/feature-working-set-select-active.png and /dev/null differ diff --git a/docs/static/images/docs/help-faqs-bookshelf.png b/docs/static/images/docs/help-faqs-bookshelf.png deleted file mode 100644 index a1de969168..0000000000 Binary files a/docs/static/images/docs/help-faqs-bookshelf.png and /dev/null differ diff --git a/docs/static/images/docs/help-faqs-reveal-file-on-switch.png b/docs/static/images/docs/help-faqs-reveal-file-on-switch.png deleted file mode 100644 index 6ef6d1a615..0000000000 Binary files a/docs/static/images/docs/help-faqs-reveal-file-on-switch.png and /dev/null differ diff --git a/docs/static/images/docs/help-troubleshooting-diagnostic-flags.png b/docs/static/images/docs/help-troubleshooting-diagnostic-flags.png deleted file mode 100644 index 0aa27f1e4c..0000000000 Binary files a/docs/static/images/docs/help-troubleshooting-diagnostic-flags.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-autocomplete.png b/docs/static/images/docs/language-cpp-autocomplete.png deleted file mode 100644 index ca9950b4a5..0000000000 Binary files a/docs/static/images/docs/language-cpp-autocomplete.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-code-diagnostics-gutter-fix.png b/docs/static/images/docs/language-cpp-code-diagnostics-gutter-fix.png deleted file mode 100644 index af50a4cbcc..0000000000 Binary files a/docs/static/images/docs/language-cpp-code-diagnostics-gutter-fix.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-code-diagnostics.png b/docs/static/images/docs/language-cpp-code-diagnostics.png deleted file mode 100644 index c4f81c0c2b..0000000000 Binary files a/docs/static/images/docs/language-cpp-code-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-code-formatting-after.png b/docs/static/images/docs/language-cpp-code-formatting-after.png deleted file mode 100644 index d9bc89e575..0000000000 Binary files a/docs/static/images/docs/language-cpp-code-formatting-after.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-code-formatting-before.png b/docs/static/images/docs/language-cpp-code-formatting-before.png deleted file mode 100644 index d24e716af3..0000000000 Binary files a/docs/static/images/docs/language-cpp-code-formatting-before.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-jump-to-declaration-link.png b/docs/static/images/docs/language-cpp-jump-to-declaration-link.png deleted file mode 100644 index 83436731c0..0000000000 Binary files a/docs/static/images/docs/language-cpp-jump-to-declaration-link.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-jump-to-declaration-result.png b/docs/static/images/docs/language-cpp-jump-to-declaration-result.png deleted file mode 100644 index 27cf36651f..0000000000 Binary files a/docs/static/images/docs/language-cpp-jump-to-declaration-result.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-type-hint-pinned.png b/docs/static/images/docs/language-cpp-type-hint-pinned.png deleted file mode 100644 index ec6310dca6..0000000000 Binary files a/docs/static/images/docs/language-cpp-type-hint-pinned.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-type-hint.png b/docs/static/images/docs/language-cpp-type-hint.png deleted file mode 100644 index d101490c5d..0000000000 Binary files a/docs/static/images/docs/language-cpp-type-hint.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-autocomplete.png b/docs/static/images/docs/language-flow-autocomplete.png deleted file mode 100644 index ac643177b1..0000000000 Binary files a/docs/static/images/docs/language-flow-autocomplete.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-code-diagnostics-gutter.png b/docs/static/images/docs/language-flow-code-diagnostics-gutter.png deleted file mode 100644 index 695dd6ac5c..0000000000 Binary files a/docs/static/images/docs/language-flow-code-diagnostics-gutter.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-code-diagnostics.png b/docs/static/images/docs/language-flow-code-diagnostics.png deleted file mode 100644 index 9b4456ef4e..0000000000 Binary files a/docs/static/images/docs/language-flow-code-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-jump-to-definition-link.png b/docs/static/images/docs/language-flow-jump-to-definition-link.png deleted file mode 100644 index b2bd77532d..0000000000 Binary files a/docs/static/images/docs/language-flow-jump-to-definition-link.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-jump-to-definition-result.png b/docs/static/images/docs/language-flow-jump-to-definition-result.png deleted file mode 100644 index 7d1858173e..0000000000 Binary files a/docs/static/images/docs/language-flow-jump-to-definition-result.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-pinned-typehint.png b/docs/static/images/docs/language-flow-pinned-typehint.png deleted file mode 100644 index 2b67519c46..0000000000 Binary files a/docs/static/images/docs/language-flow-pinned-typehint.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-type-coverage-inline.png b/docs/static/images/docs/language-flow-type-coverage-inline.png deleted file mode 100644 index cdb4dd3ab4..0000000000 Binary files a/docs/static/images/docs/language-flow-type-coverage-inline.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-type-coverage.png b/docs/static/images/docs/language-flow-type-coverage.png deleted file mode 100644 index 37585732fa..0000000000 Binary files a/docs/static/images/docs/language-flow-type-coverage.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-typehint.png b/docs/static/images/docs/language-flow-typehint.png deleted file mode 100644 index 82cc91d778..0000000000 Binary files a/docs/static/images/docs/language-flow-typehint.png and /dev/null differ diff --git a/docs/static/images/docs/language-graphql-autocomplete.png b/docs/static/images/docs/language-graphql-autocomplete.png deleted file mode 100644 index 8369784803..0000000000 Binary files a/docs/static/images/docs/language-graphql-autocomplete.png and /dev/null differ diff --git a/docs/static/images/docs/language-graphql-context-view.png b/docs/static/images/docs/language-graphql-context-view.png deleted file mode 100644 index bd33e5fc64..0000000000 Binary files a/docs/static/images/docs/language-graphql-context-view.png and /dev/null differ diff --git a/docs/static/images/docs/language-graphql-definitionjump.png b/docs/static/images/docs/language-graphql-definitionjump.png deleted file mode 100644 index a077cea57b..0000000000 Binary files a/docs/static/images/docs/language-graphql-definitionjump.png and /dev/null differ diff --git a/docs/static/images/docs/language-graphql-diagnostics-pane.png b/docs/static/images/docs/language-graphql-diagnostics-pane.png deleted file mode 100644 index 43c1cc21fc..0000000000 Binary files a/docs/static/images/docs/language-graphql-diagnostics-pane.png and /dev/null differ diff --git a/docs/static/images/docs/language-graphql-gotodefinition.png b/docs/static/images/docs/language-graphql-gotodefinition.png deleted file mode 100644 index 4d6cc56021..0000000000 Binary files a/docs/static/images/docs/language-graphql-gotodefinition.png and /dev/null differ diff --git a/docs/static/images/docs/language-graphql-inline-error.png b/docs/static/images/docs/language-graphql-inline-error.png deleted file mode 100644 index 78a26d799c..0000000000 Binary files a/docs/static/images/docs/language-graphql-inline-error.png and /dev/null differ diff --git a/docs/static/images/docs/language-graphql-outline-view.png b/docs/static/images/docs/language-graphql-outline-view.png deleted file mode 100644 index ddb93fe2f2..0000000000 Binary files a/docs/static/images/docs/language-graphql-outline-view.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-autocomplete.png b/docs/static/images/docs/language-hack-autocomplete.png deleted file mode 100644 index 1c8341b3aa..0000000000 Binary files a/docs/static/images/docs/language-hack-autocomplete.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-badly-formatted.png b/docs/static/images/docs/language-hack-badly-formatted.png deleted file mode 100644 index c7d3f9229d..0000000000 Binary files a/docs/static/images/docs/language-hack-badly-formatted.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-code-diagnostics-gutter.png b/docs/static/images/docs/language-hack-code-diagnostics-gutter.png deleted file mode 100644 index f1af2d1970..0000000000 Binary files a/docs/static/images/docs/language-hack-code-diagnostics-gutter.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-code-diagnostics.png b/docs/static/images/docs/language-hack-code-diagnostics.png deleted file mode 100644 index 7042893b14..0000000000 Binary files a/docs/static/images/docs/language-hack-code-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-jump-to-definition-link.png b/docs/static/images/docs/language-hack-jump-to-definition-link.png deleted file mode 100644 index 7b6f9a3440..0000000000 Binary files a/docs/static/images/docs/language-hack-jump-to-definition-link.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-jump-to-definition-result.png b/docs/static/images/docs/language-hack-jump-to-definition-result.png deleted file mode 100644 index be64f9c25c..0000000000 Binary files a/docs/static/images/docs/language-hack-jump-to-definition-result.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-pinned-typehint.png b/docs/static/images/docs/language-hack-pinned-typehint.png deleted file mode 100644 index 17161f9784..0000000000 Binary files a/docs/static/images/docs/language-hack-pinned-typehint.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-type-coverage-inline.png b/docs/static/images/docs/language-hack-type-coverage-inline.png deleted file mode 100644 index dab2585e72..0000000000 Binary files a/docs/static/images/docs/language-hack-type-coverage-inline.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-type-coverage.png b/docs/static/images/docs/language-hack-type-coverage.png deleted file mode 100644 index c664e62874..0000000000 Binary files a/docs/static/images/docs/language-hack-type-coverage.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-typehint.png b/docs/static/images/docs/language-hack-typehint.png deleted file mode 100644 index 0184cd8c3e..0000000000 Binary files a/docs/static/images/docs/language-hack-typehint.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-well-formatted.png b/docs/static/images/docs/language-hack-well-formatted.png deleted file mode 100644 index e6360af631..0000000000 Binary files a/docs/static/images/docs/language-hack-well-formatted.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-after-bracket-insert.png b/docs/static/images/docs/language-objc-after-bracket-insert.png deleted file mode 100644 index af847c75e7..0000000000 Binary files a/docs/static/images/docs/language-objc-after-bracket-insert.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-after-colon-indent.png b/docs/static/images/docs/language-objc-after-colon-indent.png deleted file mode 100644 index f8a23978df..0000000000 Binary files a/docs/static/images/docs/language-objc-after-colon-indent.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-auto-bracket-completion-setting.png b/docs/static/images/docs/language-objc-auto-bracket-completion-setting.png deleted file mode 100644 index 73e1be7311..0000000000 Binary files a/docs/static/images/docs/language-objc-auto-bracket-completion-setting.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-autocomplete.png b/docs/static/images/docs/language-objc-autocomplete.png deleted file mode 100644 index 7b4dbe2b1f..0000000000 Binary files a/docs/static/images/docs/language-objc-autocomplete.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-before-bracket-insert.png b/docs/static/images/docs/language-objc-before-bracket-insert.png deleted file mode 100644 index 53665b786e..0000000000 Binary files a/docs/static/images/docs/language-objc-before-bracket-insert.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-before-colon-indent.png b/docs/static/images/docs/language-objc-before-colon-indent.png deleted file mode 100644 index 8826969217..0000000000 Binary files a/docs/static/images/docs/language-objc-before-colon-indent.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-code-diagnostics.png b/docs/static/images/docs/language-objc-code-diagnostics.png deleted file mode 100644 index cf44c30670..0000000000 Binary files a/docs/static/images/docs/language-objc-code-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-jump-to-definition-link.png b/docs/static/images/docs/language-objc-jump-to-definition-link.png deleted file mode 100644 index b846a213ca..0000000000 Binary files a/docs/static/images/docs/language-objc-jump-to-definition-link.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-jump-to-definition-result.png b/docs/static/images/docs/language-objc-jump-to-definition-result.png deleted file mode 100644 index 3d7d1d04e6..0000000000 Binary files a/docs/static/images/docs/language-objc-jump-to-definition-result.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-lint-gutter.png b/docs/static/images/docs/language-objc-lint-gutter.png deleted file mode 100644 index c3f8a06fb9..0000000000 Binary files a/docs/static/images/docs/language-objc-lint-gutter.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-pinned-typehint.png b/docs/static/images/docs/language-objc-pinned-typehint.png deleted file mode 100644 index 45f16c7492..0000000000 Binary files a/docs/static/images/docs/language-objc-pinned-typehint.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-typehint.png b/docs/static/images/docs/language-objc-typehint.png deleted file mode 100644 index 3c6e349fe4..0000000000 Binary files a/docs/static/images/docs/language-objc-typehint.png and /dev/null differ diff --git a/docs/static/images/docs/language-python-autocomplete.png b/docs/static/images/docs/language-python-autocomplete.png deleted file mode 100644 index 3964af52bb..0000000000 Binary files a/docs/static/images/docs/language-python-autocomplete.png and /dev/null differ diff --git a/docs/static/images/docs/language-python-code-diagnostics.png b/docs/static/images/docs/language-python-code-diagnostics.png deleted file mode 100644 index 6258a11cb5..0000000000 Binary files a/docs/static/images/docs/language-python-code-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/language-python-code-format-after.png b/docs/static/images/docs/language-python-code-format-after.png deleted file mode 100644 index c72bf88e1f..0000000000 Binary files a/docs/static/images/docs/language-python-code-format-after.png and /dev/null differ diff --git a/docs/static/images/docs/language-python-code-format-before.png b/docs/static/images/docs/language-python-code-format-before.png deleted file mode 100644 index 3655f81b1b..0000000000 Binary files a/docs/static/images/docs/language-python-code-format-before.png and /dev/null differ diff --git a/docs/static/images/docs/language-python-jump-to-definition-link.png b/docs/static/images/docs/language-python-jump-to-definition-link.png deleted file mode 100644 index f05c4b4ad1..0000000000 Binary files a/docs/static/images/docs/language-python-jump-to-definition-link.png and /dev/null differ diff --git a/docs/static/images/docs/language-python-jump-to-definition-result.png b/docs/static/images/docs/language-python-jump-to-definition-result.png deleted file mode 100644 index ab265880fe..0000000000 Binary files a/docs/static/images/docs/language-python-jump-to-definition-result.png and /dev/null differ diff --git a/docs/static/images/docs/language-python-outline-view.png b/docs/static/images/docs/language-python-outline-view.png deleted file mode 100644 index 1e9f64bd49..0000000000 Binary files a/docs/static/images/docs/language-python-outline-view.png and /dev/null differ diff --git a/docs/static/images/docs/language-swift-autocompletion.png b/docs/static/images/docs/language-swift-autocompletion.png deleted file mode 100644 index a5a6d5b21c..0000000000 Binary files a/docs/static/images/docs/language-swift-autocompletion.png and /dev/null differ diff --git a/docs/static/images/docs/language-swift-toolchain-path-setting.png b/docs/static/images/docs/language-swift-toolchain-path-setting.png deleted file mode 100644 index 498f468518..0000000000 Binary files a/docs/static/images/docs/language-swift-toolchain-path-setting.png and /dev/null differ diff --git a/docs/static/images/docs/platform-android-simulator-output.png b/docs/static/images/docs/platform-android-simulator-output.png deleted file mode 100644 index 0cae1613dc..0000000000 Binary files a/docs/static/images/docs/platform-android-simulator-output.png and /dev/null differ diff --git a/docs/static/images/docs/platform-android-toggle-simulator.png b/docs/static/images/docs/platform-android-toggle-simulator.png deleted file mode 100644 index efc6ae71a1..0000000000 Binary files a/docs/static/images/docs/platform-android-toggle-simulator.png and /dev/null differ diff --git a/docs/static/images/docs/platform-ios-buck-build.png b/docs/static/images/docs/platform-ios-buck-build.png deleted file mode 100644 index 2c7742ecd0..0000000000 Binary files a/docs/static/images/docs/platform-ios-buck-build.png and /dev/null differ diff --git a/docs/static/images/docs/platform-ios-native-autocomplete.png b/docs/static/images/docs/platform-ios-native-autocomplete.png deleted file mode 100644 index a4ae52d973..0000000000 Binary files a/docs/static/images/docs/platform-ios-native-autocomplete.png and /dev/null differ diff --git a/docs/static/images/docs/platform-ios-simulator-output.png b/docs/static/images/docs/platform-ios-simulator-output.png deleted file mode 100644 index a37a26f3c9..0000000000 Binary files a/docs/static/images/docs/platform-ios-simulator-output.png and /dev/null differ diff --git a/docs/static/images/docs/platform-ios-toggle-simulator.png b/docs/static/images/docs/platform-ios-toggle-simulator.png deleted file mode 100644 index 254d19b2b3..0000000000 Binary files a/docs/static/images/docs/platform-ios-toggle-simulator.png and /dev/null differ diff --git a/docs/static/images/docs/platform-react-native-debugger-ex.png b/docs/static/images/docs/platform-react-native-debugger-ex.png deleted file mode 100644 index fcc1a82d7c..0000000000 Binary files a/docs/static/images/docs/platform-react-native-debugger-ex.png and /dev/null differ diff --git a/docs/static/images/docs/platform-react-native-element-inspector.png b/docs/static/images/docs/platform-react-native-element-inspector.png deleted file mode 100644 index 89b3db5652..0000000000 Binary files a/docs/static/images/docs/platform-react-native-element-inspector.png and /dev/null differ diff --git a/docs/static/images/docs/platform-react-native-feature-autocomplete.png b/docs/static/images/docs/platform-react-native-feature-autocomplete.png deleted file mode 100644 index 2db25bb7ff..0000000000 Binary files a/docs/static/images/docs/platform-react-native-feature-autocomplete.png and /dev/null differ diff --git a/docs/static/images/docs/platform-react-native-show-inspector.png b/docs/static/images/docs/platform-react-native-show-inspector.png deleted file mode 100644 index 25801a05c6..0000000000 Binary files a/docs/static/images/docs/platform-react-native-show-inspector.png and /dev/null differ diff --git a/docs/static/images/docs/platform-react-native-start-packager.png b/docs/static/images/docs/platform-react-native-start-packager.png deleted file mode 100644 index 09d9ee5058..0000000000 Binary files a/docs/static/images/docs/platform-react-native-start-packager.png and /dev/null differ diff --git a/docs/static/images/docs/promo-debugger.png b/docs/static/images/docs/promo-debugger.png deleted file mode 100644 index b071518e1d..0000000000 Binary files a/docs/static/images/docs/promo-debugger.png and /dev/null differ diff --git a/docs/static/images/docs/promo-flow.png b/docs/static/images/docs/promo-flow.png deleted file mode 100644 index edf4035a8a..0000000000 Binary files a/docs/static/images/docs/promo-flow.png and /dev/null differ diff --git a/docs/static/images/docs/promo-hack.png b/docs/static/images/docs/promo-hack.png deleted file mode 100644 index 3eb4d3cf5f..0000000000 Binary files a/docs/static/images/docs/promo-hack.png and /dev/null differ diff --git a/docs/static/images/docs/promo-mercurial.png b/docs/static/images/docs/promo-mercurial.png deleted file mode 100644 index 1bef66ebd8..0000000000 Binary files a/docs/static/images/docs/promo-mercurial.png and /dev/null differ diff --git a/docs/static/images/docs/promo-remote-development.png b/docs/static/images/docs/promo-remote-development.png deleted file mode 100644 index a1004843e9..0000000000 Binary files a/docs/static/images/docs/promo-remote-development.png and /dev/null differ diff --git a/docs/static/images/docs/promo-task-runner.png b/docs/static/images/docs/promo-task-runner.png deleted file mode 100644 index 179dd9868e..0000000000 Binary files a/docs/static/images/docs/promo-task-runner.png and /dev/null differ diff --git a/docs/static/images/docs/promo-working-sets.png b/docs/static/images/docs/promo-working-sets.png deleted file mode 100644 index e4b92fed15..0000000000 Binary files a/docs/static/images/docs/promo-working-sets.png and /dev/null differ diff --git a/docs/static/images/docs/quick-start-getting-started-add-project.png b/docs/static/images/docs/quick-start-getting-started-add-project.png deleted file mode 100644 index 73a43ed6f2..0000000000 Binary files a/docs/static/images/docs/quick-start-getting-started-add-project.png and /dev/null differ diff --git a/docs/static/images/docs/quick-start-getting-started-file-tree-view.png b/docs/static/images/docs/quick-start-getting-started-file-tree-view.png deleted file mode 100644 index 350a97774d..0000000000 Binary files a/docs/static/images/docs/quick-start-getting-started-file-tree-view.png and /dev/null differ diff --git a/docs/static/images/docs/quick-start-getting-started-home.png b/docs/static/images/docs/quick-start-getting-started-home.png deleted file mode 100644 index e81c05ee4d..0000000000 Binary files a/docs/static/images/docs/quick-start-getting-started-home.png and /dev/null differ diff --git a/docs/static/images/docs/quick-start-getting-started-quick-launch-menu.png b/docs/static/images/docs/quick-start-getting-started-quick-launch-menu.png deleted file mode 100644 index f3d59ef911..0000000000 Binary files a/docs/static/images/docs/quick-start-getting-started-quick-launch-menu.png and /dev/null differ diff --git a/docs/static/images/docs/quick-start-getting-started-quick-open.png b/docs/static/images/docs/quick-start-getting-started-quick-open.png deleted file mode 100644 index da11b2650f..0000000000 Binary files a/docs/static/images/docs/quick-start-getting-started-quick-open.png and /dev/null differ diff --git a/docs/static/images/docs/quick-start-getting-started-remote-connection-dialog.png b/docs/static/images/docs/quick-start-getting-started-remote-connection-dialog.png deleted file mode 100644 index acc22a73a4..0000000000 Binary files a/docs/static/images/docs/quick-start-getting-started-remote-connection-dialog.png and /dev/null differ diff --git a/docs/static/images/help/troubleshooting-flow-executable-setting.png b/docs/static/images/help/troubleshooting-flow-executable-setting.png deleted file mode 100644 index 5eee008387..0000000000 Binary files a/docs/static/images/help/troubleshooting-flow-executable-setting.png and /dev/null differ diff --git a/docs/static/images/help/troubleshooting-module-not-found.png b/docs/static/images/help/troubleshooting-module-not-found.png deleted file mode 100644 index 43fd988ff9..0000000000 Binary files a/docs/static/images/help/troubleshooting-module-not-found.png and /dev/null differ diff --git a/docs/static/logo.png b/docs/static/logo.png deleted file mode 100644 index bc43aaf81c..0000000000 Binary files a/docs/static/logo.png and /dev/null differ diff --git a/docs/static/logo_nav.png b/docs/static/logo_nav.png deleted file mode 100644 index 0ac0eed7cb..0000000000 Binary files a/docs/static/logo_nav.png and /dev/null differ diff --git a/docs/static/og_image.png b/docs/static/og_image.png deleted file mode 100644 index 79c013f322..0000000000 Binary files a/docs/static/og_image.png and /dev/null differ diff --git a/docs/static/oss_logo.png b/docs/static/oss_logo.png deleted file mode 100644 index 8183e289b1..0000000000 Binary files a/docs/static/oss_logo.png and /dev/null differ diff --git a/docs/static/search.png b/docs/static/search.png deleted file mode 100644 index 222fb660da..0000000000 Binary files a/docs/static/search.png and /dev/null differ diff --git a/flow-libs/adm-zip.js.flow b/flow-libs/adm-zip.js.flow deleted file mode 100644 index bb785b19bd..0000000000 --- a/flow-libs/adm-zip.js.flow +++ /dev/null @@ -1,265 +0,0 @@ -/** - * Copyright (c) 2017-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 - */ - -declare module 'adm-zip' { - declare class ZipEntry { - entryName: string, - +rawEntryName: string, - extra: Buffer, - comment: string, - +name: string, - isDirectory: boolean, - getCompressedData(): Buffer, - getCompressedDataAsync(callback: (data: Buffer) => mixed): void, - setData(value: Buffer | string): void, - getData(password?: string): Buffer, - getDataAsync(callback: (data: Buffer) => mixed, password?: string): void, - attr: number, - header: Buffer, - packHeader(): Buffer, - toString(): string, - } - - declare class ZipFile { - /** - * Returns an array of ZipEntry objects existent in the current opened archive - * @return Array - */ - +entries: Array, - - /** - * Archive comment - * @return {String} - */ - comment: string, - - /** - * Returns a reference to the entry with the given name or null if entry is inexistent - * - * @param entryName - * @return ZipEntry - */ - getEntry(entryName: string): ZipEntry, - - /** - * Adds the given entry to the entry list - * - * @param entry - */ - setEntry(entry: ZipEntry): void, - - /** - * Removes the entry with the given name from the entry list. - * - * If the entry is a directory, then all nested files and directories will be removed - * @param entryName - */ - deleteEntry(entryName: string): void, - - /** - * Iterates and returns all nested files and directories of the given entry - * - * @param entry - * @return Array - */ - getEntryChildren(entry: ZipEntry): Array, - - /** - * Returns the zip file - * - * @return Buffer - */ - compressToBuffer(): Buffer, - - toAsyncBuffer(onSuccess: (out: Buffer)=>mixed, onFail: Function, onItemStart: (name: string)=>mixed, onItemEnd: (name: string)=>mixed): void, - } - - declare class AdmZip { - constructor(): void, - constructor(file: string): void, - constructor(zipData: Buffer): void, - /** - * Extracts the given entry from the archive and returns the content as a Buffer object - * @param entry ZipEntry object or String with the full path of the entry - * - * @return Buffer or Null in case of error - */ - readFile(entry: ZipEntry | string): Buffer, - - /** - * Asynchronous readFile - * @param entry ZipEntry object or String with the full path of the entry - * @param callback - * - * @return Buffer or Null in case of error - */ - readFileAsync(entry: ZipEntry | string, callback: (data: ?Buffer, error: string)=>void): ?Buffer, - - /** - * Extracts the given entry from the archive and returns the content as plain text in the given encoding - * @param entry ZipEntry object or String with the full path of the entry - * @param encoding Optional. If no encoding is specified utf8 is used - * - * @return String - */ - readAsText(entry: ZipEntry | string, encoding?: string): string, - - /** - * Asynchronous readAsText - * @param entry ZipEntry object or String with the full path of the entry - * @param callback - * @param encoding Optional. If no encoding is specified utf8 is used - * - * @return String - */ - readAsTextAsync(entry: ZipEntry | string, callback: (text: string) => mixed, encoding?: string): string, - - /** - * Remove the entry from the file or the entry and all it's nested directories and files if the given entry is a directory - * - * @param entry - */ - deleteFile(entry: ZipEntry | string): void, - - /** - * Adds a comment to the zip. The zip must be rewritten after adding the comment. - * - * @param comment - */ - addZipComment(comment: Buffer): void, - - /** - * Returns the zip comment - * - * @return String - */ - getZipComment(): string, - - /** - * Adds a comment to a specified zipEntry. The zip must be rewritten after adding the comment - * The comment cannot exceed 65535 characters in length - * - * @param entry - * @param comment - */ - addZipEntryComment(entry: ZipEntry, comment: string): void, - - /** - * Returns the comment of the specified entry - * - * @param entry - * @return String - */ - getZipEntryComment(entry: ZipEntry): string, - - /** - * Updates the content of an existing entry inside the archive. The zip must be rewritten after updating the content - * - * @param entry - * @param content - */ - updateFile(entry: ZipEntry, content: Buffer): void, - - /** - * Adds a file from the disk to the archive - * - * @param localPath - */ - addLocalFile(localPath: string, zipPath?: string, zipName?: string): void, - - /** - * Adds a local directory and all its nested files and directories to the archive - * - * @param localPath - * @param zipPath optional path inside zip - * @param filter optional RegExp or Function if files match will - * be included. - */ - addLocalFolder(localPath: string, zipPath?: string, filter?: RegExp | ((string)=>boolean)): void, - - /** - * Allows you to create a entry (file or directory) in the zip file. - * If you want to create a directory the entryName must end in / and a null buffer should be provided. - * Comment and attributes are optional - * - * @param entryName - * @param content - * @param comment - * @param attr - */ - addFile(entryName: string, content: Buffer | null, comment?: string, attr?: number): void, - - /** - * Returns an array of ZipEntry objects representing the files and folders inside the archive - * - * @return Array - */ - getEntries(): Array, - - /** - * Returns a ZipEntry object representing the file or folder specified by ``name``. - * - * @param name - * @return ZipEntry - */ - getEntry(name: string): ZipEntry, - - /** - * Extracts the given entry to the given targetPath - * If the entry is a directory inside the archive, the entire directory and it's subdirectories will be extracted - * - * @param entry ZipEntry object or String with the full path of the entry - * @param targetPath Target folder where to write the file - * @param maintainEntryPath If maintainEntryPath is true and the entry is inside a folder, the entry folder - * will be created in targetPath as well. Default is TRUE - * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true. - * Default is FALSE - * - * @return Boolean - */ - extractEntryTo(entry: ZipEntry | string, targetPath: string, maintainEntryPath?: boolean, overwrite?: boolean): boolean, - - /** - * Extracts the entire archive to the given location - * - * @param targetPath Target location - * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true. - * Default is FALSE - */ - extractAllTo(targetPath: string, overwrite?: boolean): void, - - /** - * Asynchronous extractAllTo - * - * @param targetPath Target location - * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true. - * Default is FALSE - * @param callback - */ - extractAllToAsync(targetPath: string, overwrite?: boolean, callback: (err: ?Error) => mixed): void, - - /** - * Writes the newly created zip file to disk at the specified location or if a zip was opened and no ``targetFileName`` is provided, it will overwrite the opened zip - * - * @param targetFileName - * @param callback - */ - writeZip(targetFileName: string, callback: (err: ?Error) => mixed): void, - - /** - * Returns the content of the entire zip file as a Buffer object - * - * @return Buffer - */ - toBuffer(onSuccess: (out: Buffer)=>mixed, onFail: Function, onItemStart: (name: string)=>mixed, onItemEnd: (name: string)=>mixed): Buffer, - } - - declare export default (data?: Buffer | string) => AdmZip; -} diff --git a/flow-libs/atom-jasmine.js.flow b/flow-libs/atom-jasmine.js.flow deleted file mode 100644 index b4cd47bae6..0000000000 --- a/flow-libs/atom-jasmine.js.flow +++ /dev/null @@ -1,23 +0,0 @@ -/** - * 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 - */ - -// Type declarations for Atom's extensions to Jasmine v1.3 -// https://github.com/atom/atom/blob/master/spec/spec-helper.coffee - -/** Note that waitsForPromise has an optional first argument. */ -declare function waitsForPromise( - optionsOrFunc: {timeout?: number, shouldReject?: boolean, label?: string} | () => Promise, - func?: () => Promise -): void; - -/** - * deltaInMilliseconds defaults to 1. - */ -declare function advanceClock(deltaInMilliseconds?: number): void; diff --git a/flow-libs/atom.js.flow b/flow-libs/atom.js.flow deleted file mode 100644 index e7d91577b1..0000000000 --- a/flow-libs/atom.js.flow +++ /dev/null @@ -1,2172 +0,0 @@ -/** - * 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 - */ - -/** - * Private Classes - */ - -// Octicons v4.4.0. List extracted from the atom-styleguide package. -type atom$Octicon = 'alert' | 'alignment-align' | 'alignment-aligned-to' | 'alignment-unalign' | - 'arrow-down' | 'arrow-left' | 'arrow-right' | 'arrow-small-down' | 'arrow-small-left' | - 'arrow-small-right' | 'arrow-small-up' | 'arrow-up' | 'beaker' | 'beer' | 'bell' | 'bold' | - 'book' | 'bookmark' | 'briefcase' | 'broadcast' | 'browser' | 'bug' | 'calendar' | 'check' | - 'checklist' | 'chevron-down' | 'chevron-left' | 'chevron-right' | 'chevron-up' | 'circle-slash' | - 'circuit-board' | 'clippy' | 'clock' | 'cloud-download' | 'cloud-upload' | 'code' | 'color-mode' | - 'comment' | 'comment-add' | 'comment-discussion' | 'credit-card' | 'dash' | 'dashboard' | - 'database' | 'desktop-download' | 'device-camera' | 'device-camera-video' | 'device-desktop' | - 'device-mobile' | 'diff' | 'diff-added' | 'diff-ignored' | 'diff-modified' | 'diff-removed' | - 'diff-renamed' | 'ellipses' | 'ellipsis' | 'eye' | 'eye-unwatch' | 'eye-watch' | 'file' | - 'file-add' | 'file-binary' | 'file-code' | 'file-directory' | 'file-directory-create' | - 'file-media' | 'file-pdf' | 'file-submodule' | 'file-symlink-directory' | 'file-symlink-file' | - 'file-text' | 'file-zip' | 'flame' | 'fold' | 'gear' | 'gift' | 'gist' | 'gist-fork' | - 'gist-new' | 'gist-private' | 'gist-secret' | 'git-branch' | 'git-branch-create' | - 'git-branch-delete' | 'git-commit' | 'git-compare' | 'git-fork-private' | 'git-merge' | - 'git-pull-request' | 'git-pull-request-abandoned' | 'globe' | 'grabber' | 'graph' | 'heart' | - 'history' | 'home' | 'horizontal-rule' | 'hourglass' | 'hubot' | 'inbox' | 'info' | - 'issue-closed' | 'issue-opened' | 'issue-reopened' | 'italic' | 'jersey' | 'jump-down' | - 'jump-left' | 'jump-right' | 'jump-up' | 'key' | 'keyboard' | 'law' | 'light-bulb' | 'link' | - 'link-external' | 'list-ordered' | 'list-unordered' | 'location' | 'lock' | 'log-in' | 'log-out' | - 'logo-gist' | 'logo-github' | 'mail' | 'mail-read' | 'mail-reply' | 'mark-github' | 'markdown' | - 'megaphone' | 'mention' | 'microscope' | 'milestone' | 'mirror' | 'mirror-private' | - 'mirror-public' | 'mortar-board' | 'move-down' | 'move-left' | 'move-right' | 'move-up' | 'mute' | - 'no-newline' | 'octoface' | 'organization' | 'package' | 'paintcan' | 'pencil' | 'person' | - 'person-add' | 'person-follow' | 'pin' | 'playback-fast-forward' | 'playback-pause' | - 'playback-play' | 'playback-rewind' | 'plug' | 'plus-small' | 'plus' | 'podium' | - 'primitive-dot' | 'primitive-square' | 'pulse' | 'puzzle' | 'question' | 'quote' | 'radio-tower' | - 'remove-close' | 'reply' | 'repo' | 'repo-clone' | 'repo-create' | 'repo-delete' | - 'repo-force-push' | 'repo-forked' | 'repo-pull' | 'repo-push' | 'repo-sync' | 'rocket' | 'rss' | - 'ruby' | 'screen-full' | 'screen-normal' | 'search' | 'search-save' | 'server' | 'settings' | - 'shield' | 'sign-in' | 'sign-out' | 'smiley' | 'split' | 'squirrel' | 'star' | 'star-add' | - 'star-delete' | 'steps' | 'stop' | 'sync' | 'tag' | 'tag-add' | 'tag-remove' | 'tasklist' | - 'telescope' | 'terminal' | 'text-size' | 'three-bars' | 'thumbsdown' | 'thumbsup' | 'tools' | - 'trashcan' | 'triangle-down' | 'triangle-left' | 'triangle-right' | 'triangle-up' | 'type-array'| - 'type-boolean'| 'type-class'| 'type-constant'| 'type-constructor'| 'type-enum'| 'type-field'| - 'type-file'| 'type-function'| 'type-interface'| 'type-method'| 'type-module'| 'type-namespace'| - 'type-number'| 'type-package'| 'type-property'| 'type-string'| 'type-variable' | 'unfold' | - 'unmute' | 'unverified' | 'verified' | 'versions' | 'watch' | 'x' | 'zap'; - -type atom$PaneLocation = 'left' | 'right' | 'bottom' | 'center'; - -declare type atom$Color = { - // Returns a String in the form '#abcdef'. - toHexString(): string; - // Returns a String in the form 'rgba(25, 50, 75, .9)'. - toRGBAString(): string; -} - -declare class atom$Model { - destroy(): void, - isDestroyed(): boolean, -} - -declare class atom$Package { - path: string, - activateTime: number, - mainModule: any, - mainModulePath: string, - metadata: Object, - name: string, - loadTime: number, - getType(): 'atom' | 'textmate' | 'theme', - hasActivationCommands(): boolean, - hasActivationHooks(): boolean, - getActivationHooks(): Array, - onDidDeactivate(cb: () => mixed): IDisposable, - activateNow(): void, - // Undocumented - bundledPackage: boolean, - getCanDeferMainModuleRequireStorageKey(): string, - initializeIfNeeded(): void, -} - -/** - * Essential Classes - */ - -declare type atom$CustomEvent = CustomEvent & { - originalEvent?: Event; -} - -type atom$CommandCallback = (event: atom$CustomEvent) => mixed; - -type atom$CommandDescriptor = { - name: string, - displayName: string, - description?: string, - hiddenInCommandPalette?: boolean, - tags?: Array, -}; - -type atom$CommandListener = atom$CommandCallback | { - displayName?: string, - description?: string, - didDispatch: atom$CommandCallback, -}; - -declare class atom$CommandRegistry { - // Methods - add( - target: string | HTMLElement, - commandNameOrCommands: string | {[commandName: string]: atom$CommandListener}, - listener?: atom$CommandListener, - throwOnInvalidSelector?: boolean, - ): IDisposable, - dispatch(target: HTMLElement, commandName: string, detail?: Object): void, - onDidDispatch(callback: (event: atom$CustomEvent) => mixed): IDisposable, - onWillDispatch(callback: (event: atom$CustomEvent) => mixed): IDisposable, - findCommands(opts: {target: Node}): Array, -} - -declare class atom$CompositeDisposable { - constructor(...disposables: Array): void, - dispose(): void, - - add(...disposables: Array): void, - remove(disposable: IDisposable): void, - clear(): void, -} - -type atom$ConfigType = - 'boolean' | 'string' | 'integer' | 'number' | - 'array' | 'object' | 'color' | 'any'; - -type atom$ConfigSchema = { - default?: mixed, - description?: string, - enum?: Array, - maximum?: number, - minimum?: number, - properties?: Object, - title?: string, - type: Array | atom$ConfigType, -}; - -declare class atom$Config { - // Config Subscription - observe( - keyPath: string, - optionsOrCallback?: - | {scope?: atom$ScopeDescriptorLike} - | (value: mixed) => void, - callback?: (value: mixed) => mixed, - ): IDisposable, - - onDidChange( - keyPathOrCallback: - | string - | (event: {oldValue: mixed, newValue: mixed}) => mixed, - optionsOrCallback?: - | {scope?: atom$ScopeDescriptorLike} - | (event: {oldValue: mixed, newValue: mixed}) => mixed, - callback?: (event: {oldValue: mixed, newValue: mixed}) => mixed - ): IDisposable, - - // Managing Settings - get( - keyPath?: string, - options?: { - excludeSources?: Array, - sources?: Array, - scope?: atom$ScopeDescriptorLike, - } - ): mixed, - - set( - keyPath: string, - value: ?mixed, - options?: { - scopeSelector?: string, - source?: string, - }, - ): boolean, - - unset( - keyPath: string, - options?: { - scopeSelector?: string, - source?: string, - } - ): void, - - getUserConfigPath(): string, - - // Undocumented Methods - getRawValue(keyPath: ?string, options: {excludeSources?: string, sources?: string}): mixed, - getSchema(keyPath: string): atom$ConfigSchema, - save(): void, - setRawValue(keyPath: string, value: mixed): void, - setSchema( - keyPath: string, - schema: atom$ConfigSchema, - ): void, - removeAtKeyPath(keyPath: ?string, value: ?mixed): mixed, -} - -declare class atom$Cursor { - // Event Subscription - onDidChangePosition( - callback: (event: { - oldBufferPosition: atom$Point, - oldScreenPosition: atom$Point, - newBufferPosition: atom$Point, - newScreenPosition: atom$Point, - textChanged: boolean, - Cursor: atom$Cursor, - }) => mixed, - ): IDisposable, - - // Managing Cursor Position - getBufferRow(): number, - getBufferColumn(): number, - getBufferPosition(): atom$Point, - - // Cursor Position Details - // Moving the Cursor - - // Local Positions and Ranges - getCurrentWordBufferRange(options?: {wordRegex: RegExp}): atom$Range, - getCurrentWordPrefix(): string, - - // Visibility - // Comparing to another cursor - // Utilities - wordRegExp(options?: {includeNonWordCharacters: boolean}): RegExp, -} - -declare class atom$Decoration { - destroy(): void, - onDidChangeProperties( - callback: (event: {oldProperties: Object, newProperties: Object}) => mixed - ): IDisposable, - onDidDestroy(callback: () => mixed): IDisposable, - getMarker(): atom$Marker, - getProperties(): Object, - setProperties(properties: mixed): void, -} - -declare class atom$DisplayMarkerLayer { - destroy(): void, - clear(): void, - isDestroyed(): boolean, - markBufferPosition(position: atom$PointLike, options?: MarkerOptions): atom$Marker, - markBufferRange(range: atom$Range | atom$RangeLike, options?: MarkerOptions): atom$Marker, - findMarkers(options: MarkerOptions): Array, - getMarkers(): Array, -} - -declare class atom$LayerDecoration { - destroy(): void, - isDestroyed(): boolean, - getProperties(): Object, - setProperties(properties: mixed): void, - setPropertiesForMarker(marker: atom$Marker, properties: mixed): void, -} - -declare class atom$Disposable { - constructor(disposalAction?: (...args: Array) => any): void, - disposed: boolean, - dispose(): void, -} - -declare class atom$Emitter { - dispose(): void, - on(name: string, callback: (v: any) => mixed): IDisposable, - once(name: string, callback: (v: any) => mixed): IDisposable, - preempt(name: string, callback: (v: any) => void): IDisposable, - // This is a flow hack to prevent emitting more than one value. - // `EventEmitter` allows emitting any number of values - making this a land - // mine, since we tend to think of `emit` as interchangeable. - // This hack only works if the extra value is not `undefined`, so this isn't - // full-proof, but it works for most cases. - emit(name: string, value: any, ...no_extra_args_allowed: Array): void, -} - -declare class atom$Gutter { - name: string, - destroy(): void, - decorateMarker( - marker: atom$Marker, - options?: {'class'?: string, item?: Object | HTMLElement}, - ): atom$Decoration, - show(): void, - hide(): void, - onDidDestroy(callback: () => void): IDisposable, -} - -declare type atom$MarkerChangeEvent = { - oldHeadScreenPosition: atom$Point, - newHeadScreenPosition: atom$Point, - oldTailScreenPosition: atom$Point, - newTailScreenPosition: atom$Point, - - oldHeadBufferPosition: atom$Point, - newHeadBufferPosition: atom$Point, - oldTailBufferPosition: atom$Point, - newTailBufferPosition: atom$Point, - - isValid: boolean, - textChanged: boolean, -} - -declare class atom$Marker { - destroy(): void, - getBufferRange(): atom$Range, - getStartBufferPosition(): atom$Point, - onDidChange(callback: (event: atom$MarkerChangeEvent) => mixed): IDisposable, - isValid(): boolean, - isDestroyed(): boolean, - onDidDestroy(callback: () => mixed): IDisposable, - setBufferRange( - range: atom$RangeLike, - properties?: {reversed: boolean}, - ): void, - id: number, -} - -declare class atom$ServiceHub { - provide(keyPath: string, version: string, service: T): IDisposable, - consume( - keyPath: string, - versionRange: string, - callback: (provider: T) => mixed - ): IDisposable, -} - -type atom$PackageMetadata = { - name: string, - version: string, -}; - -declare class atom$PackageManager { - +initialPackagesActivated: boolean, - - // Event Subscription - onDidLoadInitialPackages(callback: () => void): IDisposable, - onDidActivateInitialPackages(callback: () => void): IDisposable, - onDidActivatePackage(callback: (pkg: atom$Package) => mixed): IDisposable, - onDidDeactivatePackage(callback: (pkg: atom$Package) => mixed): IDisposable, - onDidLoadPackage(callback: (pkg: atom$Package) => mixed): IDisposable, - onDidUnloadPackage(callback: (pkg: atom$Package) => mixed): IDisposable, - onDidTriggerActivationHook(activationHook: string, callback: () => mixed): IDisposable, - - // Package system data - getApmPath(): string, - getPackageDirPaths(): Array, - - // General package data - resolvePackagePath(name: string): ?string, - isBundledPackage(name: string): boolean, - - // Enabling and disabling packages - enablePackage(name: string): ?atom$Package, - disablePackage(name: string): ?atom$Package, - isPackageDisabled(name: string): boolean, - - // Accessing active packages - getActivePackage(name: string): ?atom$Package, - getActivePackages(): Array, - isPackageActive(name: string): boolean, - - // Activating and deactivating packages - activatePackage(name: string): Promise, - - // Accessing loaded packages - getLoadedPackage(name: string): ?atom$Package, - getLoadedPackages(): Array, - isPackageLoaded(name: string): boolean, - - // Accessing available packages - getAvailablePackageNames(): Array, - getAvailablePackageMetadata(): Array, - - // (Undocumented.) - activate(): Promise, - deactivatePackages(): Promise, - deactivatePackage(name: string, suppressSerialization?: boolean): Promise, - emitter: atom$Emitter, - loadPackage(name: string): void, - loadPackages(): void, - serializePackage(pkg: atom$Package): void, - serviceHub: atom$ServiceHub, - packageDirPaths: Array, - triggerActivationHook(hook: string): void, - triggerDeferredActivationHooks(): void, - unloadPackage(name: string): void, - unloadPackages(): void, -} - -declare class atom$StyleManager { - // Event Subscription - - // Reading Style Elements - getStyleElements(): Array, - - // Paths - getUserStyleSheetPath(): string, - - // (Undocumented.) - addStyleSheet( - source: string, - params: { - sourcePath?: string, - context?: boolean, - priority?: number, - skipDeprecatedSelectorsTransformation?: boolean - } - ): IDisposable, -} - -type atom$PaneSplitParams = { - copyActiveItem?: boolean, - items?: Array, -}; - -type atom$PaneSplitOrientation = 'horizontal' | 'vertical'; -type atom$PaneSplitSide = 'before' | 'after'; - -// Undocumented class -declare class atom$applicationDelegate { - focusWindow(): Promise, - open(params: { - pathsToOpen: Array, - newWindow?: boolean, - devMode?: boolean, - safeMode?: boolean, - }): void, -} - -type atom$PaneParams = { - activeItem?: Object, - applicationDelegate: atom$applicationDelegate, - focused?: boolean, - container: Object, - config: atom$Config, - notificationManager: atom$NotificationManager, - deserializerManager: atom$DeserializerManager, - items?: Array, - itemStackIndices?: Array, - flexScale?: number, -}; - -declare class atom$Pane { - // Items - addItem(item: Object, options?: {index?: number, pending?: boolean}): Object, - getItems(): Array, - getActiveItem(): ?Object, - itemAtIndex(index: number): ?Object, - getActiveItemIndex(): number, - activateItem(item: Object): ?Object, - activateItemAtIndex(index: number): void, - moveItemToPane(item: Object, pane: atom$Pane, index: number): void, - destroyItem(item: Object, force?: boolean): boolean | Promise, - itemForURI(uri: string): Object, - - // Event subscriptions. - onDidAddItem(cb: (event: {item: Object, index: number}) => void): IDisposable, - onDidRemoveItem(cb: (event: {item: Object, index: number}) => void): IDisposable, - onWillRemoveItem(cb: (event: {item: Object, index: number}) => void): IDisposable, - onDidDestroy(cb: () => void): IDisposable, - onDidChangeFlexScale(cb: (newFlexScale: number) => void): IDisposable, - onWillDestroy(cb: () => void): IDisposable, - observeActiveItem(cb: (item: ?Object) => void): IDisposable, - - // Lifecycle - isActive(): boolean, - activate(): void, - destroy(): void, - isDestroyed(): void, - - // Splitting - splitLeft(params?: atom$PaneSplitParams): atom$Pane, - splitRight(params?: atom$PaneSplitParams): atom$Pane, - splitUp(params?: atom$PaneSplitParams): atom$Pane, - splitDown(params?: atom$PaneSplitParams): atom$Pane, - split( - orientation: atom$PaneSplitOrientation, - side: atom$PaneSplitSide, - params?: atom$PaneSplitParams, - ): atom$Pane, - - // Undocumented Methods - constructor(params: atom$PaneParams): atom$Pane, - getPendingItem(): atom$PaneItem, - setPendingItem(item: atom$PaneItem): void, - clearPendingItem(): void, - getFlexScale(): number, - getParent(): Object, - removeItem(item: Object, moved: ?boolean): void, - setActiveItem(item: Object): Object, - setFlexScale(flexScale: number): number, - getContainer(): atom$PaneContainer, - - element: HTMLElement, -} - -declare interface atom$PaneItem { - // These are all covariant, meaning that these props are read-only. Therefore we can assign an - // object with more strict requirements to an variable of this type. - +getTitle: () => string, - +getLongTitle?: () => string, - +getIconName?: () => string, - +getURI?: () => ?string, - +onDidChangeIcon?: (cb: (icon: string) => void) => IDisposable, - +onDidChangeTitle?: (cb: (title: string) => void) => IDisposable, - +onDidTerminatePendingState?: (() => mixed) => IDisposable; - +serialize?: () => Object, - +terminatePendingState?: () => void, -} - -// Undocumented class -declare class atom$PaneAxis { - getFlexScale(): number, - setFlexScale(flexScale: number): number, - getItems(): Array, -} - -// Undocumented class -// Note that this is not the same object returned by `atom.workspace.getPaneContainers()`. (Those -// are typed here as AbstractPaneContainers and, in the current implementation, wrap these.) -declare class atom$PaneContainer { - constructor({ - config: atom$Config, - applicationDelegate: atom$applicationDelegate, - notificationManager: atom$NotificationManager, - deserializerManager: atom$DeserializerManager, - }): atom$PaneContainer, - destroy(): void, - getActivePane(): atom$Pane, - getActivePaneItem(): ?Object, - getLocation(): atom$PaneLocation, - getPanes(): Array, - getPaneItems(): Array, - observePanes(cb: (pane: atom$Pane) => void): IDisposable, - onDidAddPane(cb: (event: {pane: atom$Pane}) => void): IDisposable, - onDidDestroyPane(cb: (event: {pane: atom$Pane}) => void): IDisposable, - onWillDestroyPane(cb: (event: {pane: atom$Pane}) => void): IDisposable, - onDidAddPaneItem(cb: (item: atom$PaneItem) => void): IDisposable, - onDidDestroyPaneItem(cb: (item: atom$Pane) => void): IDisposable, - paneForItem(item: Object): ?atom$Pane, - serialize(): Object, -} - -declare class atom$Panel { - // Construction and Destruction - destroy(): void, - - // Event Subscription - onDidChangeVisible(callback: (visible: boolean) => any): IDisposable, - onDidDestroy(callback: (panel: atom$Panel) => any): IDisposable, - - // Panel Details - getElement(): HTMLElement, - getItem(): any, - getPriority(): number, - isVisible(): boolean, - hide(): void, - show(): void, -} - -type atom$PointObject = {row: number, column: number}; - -type atom$PointLike = atom$Point -| [number, number] -| atom$PointObject; - -declare class atom$Point { - static fromObject(object: atom$PointLike, copy: ? boolean): atom$Point, - constructor(row: number, column: number): void, - row: number, - column: number, - copy(): atom$Point, - negate(): atom$Point, - - // Comparison - min(point1: atom$PointLike, point2: atom$PointLike): atom$Point, - compare(other: atom$PointLike): -1 | 0 | 1, - isEqual(otherRange: atom$PointLike): boolean, - isLessThan(other: atom$PointLike): boolean, - isLessThanOrEqual(other: atom$PointLike): boolean, - isGreaterThan(other: atom$PointLike): boolean, - isGreaterThanOrEqual(other: atom$PointLike): boolean, - - // Operations - translate(other: atom$PointLike): atom$Point, - - // Conversion - serialize(): [number, number], - toArray(): [number, number], -} - -type atom$RangeObject = { - start: atom$PointObject, - end: atom$PointObject, -}; - -type atom$RangeLike = atom$Range - | atom$RangeObject // TODO: Flow doesn't really handle the real signature below... - | [atom$PointLike, atom$PointLike] - | { - start: atom$PointLike, - end: atom$PointLike, - }; - -declare class atom$Range { - static fromObject( - object: atom$RangeLike, - copy?: boolean, - ): atom$Range, - constructor(pointA: atom$PointLike, pointB: atom$PointLike): void, - compare(other: atom$Range): number, - start: atom$Point, - end: atom$Point, - isEmpty(): boolean, - isEqual(otherRange: atom$RangeLike): boolean, - intersectsWith(otherRange: atom$RangeLike, exclusive?: boolean): boolean, - containsPoint(point: atom$PointLike, exclusive?: boolean): boolean, - containsRange(other: atom$Range, exclusive?: boolean): boolean, - union(other: atom$Range): atom$Range, - serialize(): Array>, - translate(startDelta: atom$PointLike, endDelta?: atom$PointLike): atom$Range, - getRowCount(): number, - getRows(): Array, -} - -type RawStatusBarTile = { - item: HTMLElement, - priority: number, -}; - -type atom$StatusBarTile = { - getPriority(): number, - getItem(): HTMLElement, - destroy(): void, -}; - -declare class atom$ScopeDescriptor { - constructor(object: {scopes: Array}): void, - getScopesArray(): Array, -} - -type atom$ScopeDescriptorLike = atom$ScopeDescriptor | Array; - -/** - * This API is defined at https://github.com/atom/status-bar. - */ -declare class atom$StatusBar { - addLeftTile(tile: RawStatusBarTile): atom$StatusBarTile, - addRightTile(tile: RawStatusBarTile): atom$StatusBarTile, - getLeftTiles(): Array, - getRightTiles(): Array, -} - -// https://github.com/atom/atom/blob/v1.9.0/src/text-editor-registry.coffee -declare class atom$TextEditorRegistry { - add(editor: atom$TextEditor): IDisposable, - remove(editor: atom$TextEditor): boolean, - observe(callback: (editor: atom$TextEditor) => void): IDisposable, - build: (params: atom$TextEditorParams) => atom$TextEditor, - - // Private - editors: Set, -} - -declare class atom$ThemeManager { - // Event Subscription - /** - * As recent as Atom 1.0.10, the implementation of this method was: - * - * ``` - * onDidChangeActiveThemes: (callback) -> - * @emitter.on 'did-change-active-themes', callback - * @emitter.on 'did-reload-all', callback # TODO: Remove once deprecated pre-1.0 APIs are gone - * ``` - * - * Due to the nature of CoffeeScript, onDidChangeActiveThemes returns a Disposable even though it - * is not documented as doing so. However, the Disposable that it does return removes the - * subscription on the 'did-reload-all' event (which is supposed to be deprecated) rather than the - * 'did-change-active-themes' one. - */ - onDidChangeActiveThemes(callback: () => mixed): IDisposable, - - // Accessing Loaded Themes - getLoadedThemeNames(): Array, - getLoadedThemes(): Array, // TODO: Define undocumented ThemePackage class. - - // Accessing Active Themes - getActiveThemeNames(): Array, - getActiveThemes(): Array, // TODO: Define undocumented ThemePackage class. - - // Managing Enabled Themes - getEnabledThemeNames(): Array, - - // Private - activateThemes(): Promise, - requireStylesheet(stylesheetPath: string): IDisposable, -} - -type atom$TooltipsPlacementOption = 'top' | 'bottom' | 'left' | 'right' | 'auto'; - -type atom$TooltipsAddOptions = { - title?: string, - item?: HTMLElement, - keyBindingCommand?: string, - keyBindingTarget?: HTMLElement, - animation?: boolean, - container?: string | false, - delay?: number | {show: number, hide: number}, - placement?: atom$TooltipsPlacementOption | () => atom$TooltipsPlacementOption, - trigger?: string, -}; - -type atom$Tooltip = { - hide(): void; - getTooltipElement(): HTMLElement, -}; - -declare class atom$TooltipManager { - tooltips: Map>; - add( - target: HTMLElement, - options: atom$TooltipsAddOptions, - ): IDisposable, -} - -type InsertTextOptions = { - select: boolean, - autoIndent: boolean, - autoIndentNewline: boolean, - autoDecreaseIndent: boolean, - normalizeLineEndings: ?boolean, - undo: string, -}; - -type DecorateMarkerParams = { - type: 'line', - class: string, - onlyHead?: boolean, - onlyEmpty?: boolean, - onlyNonEmpty?: boolean, -} | { - type: 'gutter', - item?: HTMLElement, - class?: string, - onlyHead?: boolean, - onlyEmpty?: boolean, - onlyNonEmpty?: boolean, - gutterName?: string, -} | { - type: 'highlight', - class?: string, - gutterName?: string, -} | { - type: 'overlay', - item: Object, - position?: 'head' | 'tail', // Defaults to 'head' when unspecified. -} | { - type: 'block', - item: HTMLElement, - position?: 'before' | 'after', // Defaults to 'before' when unspecified. -}; - -type ChangeCursorPositionEvent = { - oldBufferPosition: atom$Point, - oldScreenPosition: atom$Point, - newBufferPosition: atom$Point, - newScreenPosition: atom$Point, - textChanged: boolean, - cursor: atom$Cursor, -}; - -type MarkerOptions = { - reversed?: boolean, - tailed?: boolean, - invalidate?: 'never' | 'surround' | 'overlap' | 'inside' | 'touch', - exclusive?: boolean, -}; - -type atom$ChangeSelectionRangeEvent = {| - oldBufferRange: atom$Range, - oldScreenRange: atom$Range, - newBufferRange: atom$Range, - newScreenRange: atom$Range, - selection: atom$Selection, -|}; - -declare class atom$TextEditor extends atom$Model { - id: number, - verticalScrollMargin: number, - - // Event Subscription - onDidChange(callback: () => void): IDisposable, - onDidChangePath(callback: (newPath: string) => mixed): IDisposable, - onDidStopChanging(callback: () => mixed): IDisposable, - onDidChangeCursorPosition(callback: (event: ChangeCursorPositionEvent) => mixed): - IDisposable, - onDidDestroy(callback: () => mixed): IDisposable, - onDidSave(callback: (event: {path: string}) => mixed): IDisposable, - getBuffer(): atom$TextBuffer, - observeGrammar(callback: (grammar: atom$Grammar) => mixed): IDisposable, - onWillInsertText(callback: (event: {cancel: () => void, text: string}) => void): - IDisposable, - // Note that the range property of the event is undocumented. - onDidInsertText(callback: (event: {text: string, range: atom$Range}) => mixed): IDisposable, - onDidChangeSoftWrapped(callback: (softWrapped: boolean) => mixed): IDisposable, - onDidChangeSelectionRange(callback: (event: atom$ChangeSelectionRangeEvent) => mixed): IDisposable, - observeSelections(callback: (selection: atom$Selection) => mixed): IDisposable, - - // File Details - getTitle: () => string, - getLongTitle(): string, - /** - * If you open Atom via Spotlight such that it opens with a tab named - * "untitled" that does not correspond to a file on disk, this will return - * null. - */ - getPath(): ?string, - getURI: () => ?string, - insertNewline(): void, - isModified: () => boolean, - isEmpty(): boolean, - getEncoding(): buffer$Encoding, - setEncoding(encoding: string): void, - getTabLength() : number, - getSoftTabs(): boolean, - getIconName(): string, - onDidChangeIcon(cb: (icon: string) => void): IDisposable, - onDidChangeTitle(cb: (title: string) => void): IDisposable, - - // File Operations - save(): Promise, - // DO NOT USE: Doesn't work with remote text buffers! - // saveAs(filePath: string): void, - - // Reading Text - getText(): string, - getTextInBufferRange(range: atom$RangeLike): string, - getLineCount(): number, - getLastScreenRow(): number, - - // Mutating Text - setText(text: string, options?: InsertTextOptions): void, - setTextInBufferRange( - range: atom$RangeLike, - text: string, - options?: { - normalizeLineEndings?: boolean, - undo?: string, - }, - ): atom$Range, - insertText(text: string): Array | false, - mutateSelectedText(fn: (selection: atom$Selection, index: number) => void): void, - delete: () => void, - backspace: () => void, - duplicateLines: () => void, - - // History - createCheckpoint(): atom$TextBufferCheckpoint, - revertToCheckpoint(checkpoint: atom$TextBufferCheckpoint): boolean, - terminatePendingState(): void, - transact(fn: () => mixed, _: void): void, - transact(groupingInterval: number, fn: () => mixed): void, - onDidTerminatePendingState(() => mixed): IDisposable; - - // TextEditor Coordinates - screenPositionForBufferPosition( - bufferPosition: atom$PointLike, - options?: { - wrapBeyondNewlines?: boolean, - wrapAtSoftNewlines?: boolean, - screenLine?: boolean, - }, - ): atom$Point, - bufferPositionForScreenPosition( - screenPosition: atom$PointLike, - options?: { - wrapBeyondNewlines?: boolean, - wrapAtSoftNewlines?: boolean, - screenLine?: boolean, - }, - ): atom$Point, - getEofBufferPosition(): atom$Point, - getVisibleRowRange(): [number, number], - bufferRowForScreenRow(screenRow: number): number, - screenRangeForBufferRange(bufferRange: atom$RangeLike): atom$Range, - - // Decorations - decorateMarker(marker: atom$Marker, decorationParams: DecorateMarkerParams): atom$Decoration, - decorateMarkerLayer( - markerLayer: atom$DisplayMarkerLayer, - decorationParams: DecorateMarkerParams, - ): atom$LayerDecoration, - decorationsForScreenRowRange( - startScreenRow: number, - endScreenRow: number, - ): {[markerId: string]: Array}, - getDecorations(options?: {class?: string, type?: string}): Array, - - // Markers - addMarkerLayer(): atom$DisplayMarkerLayer, - getDefaultMarkerLayer(): atom$DisplayMarkerLayer, - markBufferPosition(position: atom$PointLike, options?: MarkerOptions): atom$Marker, - markBufferRange(range: atom$RangeLike, options?: MarkerOptions): atom$Marker, - markScreenRange(range: atom$RangeLike, options?: MarkerOptions): atom$Marker, - markScreenPosition(position: atom$PointLike, options?: MarkerOptions): atom$Marker, - findMarkers(options: MarkerOptions): Array, - getMarkerCount(): number, - - // Cursors - getCursors(): Array, - setCursorBufferPosition( - position: atom$PointLike, - options?: { - autoscroll?: boolean, - wrapBeyondNewlines?: boolean, - wrapAtSoftNewlines?: boolean, - screenLine?: boolean, - }): void, - getCursorBufferPosition(): atom$Point, - getCursorBufferPositions(): Array, - getCursorScreenPosition(): atom$Point, - getCursorScreenPositions(): Array, - getLastCursor(): atom$Cursor, - addCursorAtBufferPosition(point: atom$PointLike): atom$Cursor, - moveToBeginningOfLine(): void, - moveToEndOfLine(): void, - moveToBottom(): void, - - // Folds - foldCurrentRow(): void, - unfoldCurrentRow(): void, - foldBufferRow(bufferRow: number): void, - unfoldBufferRow(bufferRow: number): void, - - // Selections - getSelectedText(): string, - selectAll(): void, - getSelectedBufferRange(): atom$Range, - getSelectedBufferRanges(): Array, - getSelections(): Array, - selectToBufferPosition(point: atom$Point): void, - setSelectedBufferRange( - bufferRange: atom$RangeLike, - options?: { - reversed?: boolean, - preserveFolds?: boolean, - }, - ): void, - setSelectedBufferRanges( - bufferRanges: Array, - options?: { - reversed?: boolean, - preserveFolds?: boolean, - }, - ): void, - - // Folds - unfoldAll(): void, - - // Searching and Replacing - scanInBufferRange( - regex: RegExp, - range: atom$Range, - iterator: (foundMatch: { - match: mixed, - matchText: string, - range: atom$Range, - stop: () => mixed, - replace: (replaceWith: string) => mixed, - }) => mixed - ): void, - - scan( - regex: RegExp, - iterator: (foundMatch: { - match: mixed, - matchText: string, - range: atom$Range, - stop: () => mixed, - replace: (replaceWith: string) => mixed, - }) => mixed - ): void, - - // Tab Behavior - // Soft Wrap Behavior - // Indentation - indentationForBufferRow(bufferRow: number): number, - setTabLength(tabLength: number): void, - setSoftTabs(softTabs: boolean): void, - - lineTextForBufferRow(bufferRow: number): string, - lineTextForScreenRow(screenRow: number): string, - - // Grammars - getGrammar(): atom$Grammar, - setGrammar(grammar: ?atom$Grammar): void, - - // Clipboard Operations - pasteText: (options?: Object) => void, - copySelectedText: () => void, - - // Managing Syntax Scopes - getRootScopeDescriptor(): atom$ScopeDescriptor, - scopeDescriptorForBufferPosition( - bufferPosition: atom$PointLike, - ): atom$ScopeDescriptor, - - // Gutter - addGutter(options: { - name: string, - priority?: number, - visible?: boolean, - }): atom$Gutter, - observeGutters(callback: (gutter: atom$Gutter) => void): IDisposable, - getGutters(): Array, - gutterWithName(name: string): ?atom$Gutter, - - // Scrolling the TextEditor - scrollToBufferPosition( - position: atom$Point | [?number, ?number], - options?: {center?: boolean} - ): void, - scrollToScreenPosition( - position: atom$Point | [?number, ?number], - options?: {center?: boolean} - ): void, - scrollToScreenRange(screenRange: atom$Range, options?: {clip?: boolean}): void, - scrollToCursorPosition( - options?: {center?: boolean} - ): void, - scrollToBottom(): void, - scrollToTop(): void, - - // TextEditor Rendering - getPlaceholderText(): string, - setPlaceholderText(placeholderText: string): void, - - // This is undocumented, but Nuclide uses it in the AtomTextEditor wrapper. - setLineNumberGutterVisible(lineNumberGutterVisible: boolean): void, - - // Editor Options - setSoftWrapped(softWrapped: boolean): void, - - isFoldedAtBufferRow(row: number): boolean, - getLastBufferRow(): number, - - // Undocumented Methods - getElement(): atom$TextEditorElement, - getDefaultCharWidth(): number, - getLineHeightInPixels(): number, - moveToTop(): void, - tokenForBufferPosition(position: atom$Point | [?number, ?number]): atom$Token, - onDidConflict(callback: () => void): IDisposable, - serialize(): Object, - foldBufferRowRange(startRow: number, endRow: number): void, - getNonWordCharacters(position?: atom$PointLike): string, - scheduleComponentUpdate(): void, -} - -/** - * This is not part of the official Atom 1.0 API. Nevertheless, we need to reach into this object - * via `atom$TextEditorElement` to do some things that we have no other way to do. - */ -declare class atom$TextEditorComponent { - domNode: HTMLElement, - scrollViewNode: HTMLElement, - presenter: atom$TextEditorPresenter, - refs: atom$TextEditorComponentRefs, - linesComponent: atom$LinesComponent, - // NOTE: This is typed as a property to allow overwriting. - startCursorBlinking: () => void, - stopCursorBlinking(): void, - pixelPositionForScreenPosition( - screenPosition: atom$Point, - clip?: boolean, - ): {top: number, left: number}, - screenPositionForMouseEvent(event: MouseEvent): atom$Point, - pixelPositionForMouseEvent( - event: MouseEvent, - linesClientRect?: {top: number, left: number, bottom: number, right: number}, - ): {top: number, left: number, bottom: number, right: number}, - invalidateBlockDecorationDimensions(decoration: atom$Decoration): void, - element: atom$TextEditorElement, - didFocus(): void, - setScrollTop(scrollTop: number): void, - getScrollTop(): number, - - setScrollLeft(scrollLeft: number): void, - getScrollLeft(): number, -} - -/** - * This is not part of the official Atom 1.0 API. Nevertheless, we need to reach into this object - * via `atom$TextEditorComponent` to do some things that we have no other way to do. - */ -declare class atom$TextEditorPresenter { - startBlinkingCursors: () => void, - stopBlinkingCursors(visible: boolean): void, - updateLineNumberGutterState(): void, -} - -/** - * This is not part of the official Atom 1.0 API. Nevertheless, we need it to access - * the deepest dom element receiving DOM events. - */ -declare class atom$LinesComponent { - domNode: HTMLElement, - getDomNode(): HTMLElement, -} - -/** - * This is not part of the official Atom 1.0 API. Nevertheless, we need it to access - * the deepest dom element receiving DOM events. - */ -declare class atom$TextEditorComponentRefs { - lineTiles: HTMLElement, -} - -/** - * This is not part of the official Atom 1.0 API, but it really should be. This is the element that - * is returned when you run `atom.views.getView()`. - */ -declare class atom$TextEditorElement extends HTMLElement { - component: ?atom$TextEditorComponent, - getModel(): atom$TextEditor, - setModel(model: atom$TextEditor): void, - pixelPositionForBufferPosition( - bufferPosition: atom$PointLike, - ): {top: number, left: number}, - pixelPositionForScreenPosition(screenPosition: atom$Point): { - left: number, - top: number, - }, - - setScrollTop(scrollTop: number): void, - getScrollTop(): number, - - setScrollLeft(scrollLeft: number): void, - getScrollLeft(): number, - - getScrollHeight(): number, - getHeight(): number, - - onDidChangeScrollTop(callback: (scrollTop: number) => mixed): IDisposable, - onDidChangeScrollLeft(callback: (scrollLeft: number) => mixed): IDisposable, - - // Called when the editor is attached to the DOM. - onDidAttach(callback: () => mixed): IDisposable, - // Called when the editor is detached from the DOM. - onDidDetach(callback: () => mixed): IDisposable, - - measureDimensions(): void, - - // Undocumented Methods - - // Returns a promise that resolves after the next update. - getNextUpdatePromise(): Promise, - - // `undefined` means no explicit width. `null` sets a zero width (which is almost certainly a - // mistake) so we don't allow it. - setWidth(width: number | void): void, -} - -declare class atom$ViewProvider { - modelConstructor: Function, -} - -declare class atom$ViewRegistry { - // Methods - addViewProvider( - modelConstructor: any, - createView?: (...args: Array) => ?HTMLElement - ): IDisposable, - getView(textEditor: atom$TextEditor): atom$TextEditorElement, - getView(notification: atom$Notification): HTMLElement, - getView(gutter: atom$Gutter): HTMLElement, - getView(panel: atom$Panel): HTMLElement, - getView(workspace: atom$Workspace): HTMLElement, - getView(object: Object): HTMLElement, - providers: Array, -} - -type atom$WorkspaceAddPanelOptions = { - item: Object, - visible?: boolean, - priority?: number, - className?: string, -}; - -type atom$TextEditorParams = { - buffer?: atom$TextBuffer, - lineNumberGutterVisible?: boolean, -}; - -type DestroyPaneItemEvent = { - item: atom$PaneItem, - pane: atom$Pane, - index: number, -}; - -type AddPaneItemEvent = { - item: atom$PaneItem, - pane: atom$Pane, - index: number, -}; - -type OnDidOpenEvent = { - uri: string, - item: mixed, - pane: atom$Pane, - index: number, -}; - -type AddTextEditorEvent = { - textEditor: atom$TextEditor, - pane: atom$Pane, - index: number, -}; - -declare class atom$Workspace { - // Event Subscription - observePanes(cb: (pane: atom$Pane) => void): IDisposable, - observeTextEditors(callback: (editor: atom$TextEditor) => mixed): IDisposable, - observeActiveTextEditor(callback: (editor: atom$TextEditor) => mixed): IDisposable, - onDidAddTextEditor(callback: (event: AddTextEditorEvent) => mixed): IDisposable, - onDidChangeActivePaneItem(callback: (item: mixed) => mixed): IDisposable, - onDidDestroyPaneItem(callback: (event: DestroyPaneItemEvent) => mixed): IDisposable, - onDidAddPaneItem(callback: (event: AddPaneItemEvent) => mixed): IDisposable, - observeActivePaneItem(callback: (item: ?mixed) => mixed): IDisposable, - onDidStopChangingActivePaneItem(callback: (item: ?mixed) => mixed): IDisposable, - observePaneItems(callback: (item: mixed) => mixed): IDisposable, - onWillDestroyPaneItem( - callback: (event: {item: mixed, pane: mixed, index: number}) => mixed - ): IDisposable, - onDidOpen(callback: (event: OnDidOpenEvent) => mixed): IDisposable, - - getElement(): HTMLElement, - - // Opening - open( - uri?: string, - options?: { - activatePane?: ?boolean, - initialLine?: ?number, - initialColumn?: ?number, - pending?: ?boolean, - split?: ?string, - searchAllPanes?: ?boolean, - } - ): Promise, - openURIInPane( - uri?: string, - pane: atom$Pane, - options?: { - initialLine?: number, - initialColumn?: number, - activePane?: boolean, - searchAllPanes?: boolean, - } - ): Promise, - isTextEditor(item: ?mixed): boolean, - /* Optional method because this was added post-1.0. */ - buildTextEditor: ((params: atom$TextEditorParams) => atom$TextEditor), - /* Optional method because this was added in 1.9.0 */ - handleGrammarUsed?: (grammar: atom$Grammar) => void, - reopenItem(): Promise, - addOpener(callback: (uri: string) => any): IDisposable, - hide(uriOrItem: string | Object): void, - toggle(uriOrItem: string | Object): void, - - // Pane Containers - getPaneContainers(): Array, - paneContainerForItem(item: ?mixed): ?atom$AbstractPaneContainer, - - // Pane Items - getPaneItems(): Array, - getActivePaneItem(): ?Object, - getTextEditors(): Array, - getActiveTextEditor(): ?atom$TextEditor, - - // Panes - getPanes(): Array, - getActivePane(): atom$Pane, - activateNextPane(): boolean, - activatePreviousPane(): boolean, - paneForURI(uri: string): atom$Pane, - paneForItem(item: mixed): ?atom$Pane, - - // Panels - panelContainers: {[location: string]: atom$PanelContainer}, - getBottomPanels(): Array, - addBottomPanel(options: atom$WorkspaceAddPanelOptions): atom$Panel, - getLeftPanels(): Array, - addLeftPanel(options: atom$WorkspaceAddPanelOptions): atom$Panel, - getRightPanels(): Array, - addRightPanel(options: atom$WorkspaceAddPanelOptions): atom$Panel, - getTopPanels(): Array, - addTopPanel(options: atom$WorkspaceAddPanelOptions): atom$Panel, - getModalPanels(): Array, - addModalPanel(options: atom$WorkspaceAddPanelOptions): atom$Panel, - getHeaderPanels(): Array, - addHeaderPanel(options: atom$WorkspaceAddPanelOptions): atom$Panel, - - getLeftDock(): atom$Dock, - getRightDock(): atom$Dock, - getBottomDock(): atom$Dock, - getCenter(): atom$WorkspaceCenter, - - // Searching and Replacing - scan( - regex: RegExp, - options: { - paths?: Array, - onPathsSearched?: (numSearched: number) => mixed, - leadingContextLineCount?: number, - trailingContextLineCount?: number, - }, - iterator: ( - ?{ - filePath: string, - matches: Array<{ - leadingContextLines: Array, - lineText: string, - lineTextOffset: number, - range: atom$RangeLike, - matchText: string, - trailingContextLines: Array, - }>, - }, - Error, - ) => mixed, - ): Promise, - - destroyActivePaneItemOrEmptyPane(): void, - destroyActivePaneItem(): void, -} - -declare class atom$AbstractPaneContainer { - activate(): void, - getLocation(): atom$PaneLocation, - getElement(): HTMLElement, - isVisible(): boolean, - show(): void, - hide(): void, - getActivePane(): atom$Pane, - getPanes(): Array, - onDidAddPaneItem((item: {item: Object}) => void): IDisposable, - observePanes(cb: (pane: atom$Pane) => void): IDisposable, - state: { - size: number, - } -} - -declare class atom$Dock extends atom$AbstractPaneContainer { - // This is a woefully incomplete list, items can be added as needed from - // https://github.com/atom/atom/blob/master/src/dock.js - toggle(): void, -} - -declare class atom$WorkspaceCenter extends atom$AbstractPaneContainer { - activate(): void; - - // Pane Items - getPaneItems(): Array, - getActivePaneItem(): ?atom$PaneItem, - getTextEditors(): Array, - getActiveTextEditor(): ?atom$TextEditor, - - observeActivePaneItem(callback: atom$PaneItem => mixed): IDisposable; - onDidChangeActivePaneItem(callback: (item: mixed) => mixed): IDisposable; - onDidAddTextEditor( - callback: (item: { - textEditor: atom$TextEditor, - pane: atom$Pane, - index: number, - }) => mixed, - ): IDisposable; - // This should be removed soon anyway, it's currently deprecated. - paneContainer: Object; -} - -/** - * Extended Classes - */ - -declare class atom$BufferedNodeProcess { } - -declare class atom$BufferedProcess { - // Event Subscription - onWillThrowError( - callback: (errorObject: {error: Object, handle: mixed}) => mixed - ): IDisposable, - // Helper Methods - kill(): void, -} - -declare class atom$Clipboard { - // Methods - write(text: string, metadata?: mixed): void, - read(): string, - readWithMetadata(): { - metadata: ?mixed, - text: string, - }, -} - -declare class atom$ContextMenuManager { - add(itemsBySelector: {[cssSelector: string]: Array}): IDisposable, - itemSets: Array, - - // Undocumented methods - showForEvent(event: Event): void, - templateForEvent(event: Event): Array, -} - -declare class atom$ContextMenuItemSet { - items: Array, - selector: string, -} - -type atom$ContextMenuItem = { - command?: string, - created?: (event: MouseEvent) => void, - enabled?: boolean, - label?: string, - shouldDisplay?: (event: MouseEvent) => boolean, - submenu?: Array, - type?: string, - visible?: boolean, -}; - -type atom$Deserializer = { - name: string, - deserialize: (state: Object) => mixed, -}; - -declare class atom$DeserializerManager { - add(...deserializers: Array): IDisposable, - deserialize(state: Object, params?: Object): mixed, -} - -// Apparently it can sometimes include a `code` property. -declare class atom$GetEntriesError extends Error { - code?: string, -} - -declare class atom$Directory { - constructor(dirname?: string): atom$Directory, - - symlink: boolean, - - // Construction - create(mode?: number): Promise, - - // Event Subscription - onDidChange(callback: () => mixed): IDisposable, - - // Directory Metadata - isFile(): boolean, - isDirectory(): boolean, - exists():Promise, - - // Managing Paths - getPath(): string, - getBaseName(): string, - relativize(fullPath: string): string, - - // Event Subscription - onDidRename(callback: () => void): IDisposable, - onDidDelete(callback: () => void): IDisposable, - - // Traversing - getParent(): atom$Directory, - getFile(filename: string): atom$File, - getSubdirectory(dirname: string): atom$Directory, - getEntries( - callback: ( - error: ?atom$GetEntriesError, - entries: ?Array, - ) => mixed): void, - contains(path: string): boolean, -} - -// These are the methods called on a file by atom-text-buffer -interface atom$Fileish { - existsSync(): boolean, - setEncoding(encoding: string): void, - getEncoding(): ?string, - - onDidRename(callback: () => void): IDisposable, - onDidDelete(callback: () => void): IDisposable, - onDidChange(callback: () => void): IDisposable, - onWillThrowWatchError(callback: () => mixed): IDisposable, - - getPath(): string, - getBaseName(): string, - - createReadStream(): stream$Readable, - createWriteStream(): stream$Writable, -} - -declare class atom$File /* implements atom$Fileish */ { - constructor(filePath?: string, symlink?: boolean): atom$File, - - symlink: boolean, - - // Construction - create(): Promise, - - // File Metadata - isFile(): boolean, - isDirectory(): boolean, - exists(): Promise, - existsSync(): boolean, - setEncoding(encoding: string): void, - getEncoding(): string, - - // Event Subscription - onDidRename(callback: () => void): IDisposable, - onDidDelete(callback: () => void): IDisposable, - onDidChange(callback: () => void): IDisposable, - onWillThrowWatchError(callback: () => mixed): IDisposable, - - // Managing Paths - getPath(): string, - getBaseName(): string, - - // Traversing - getParent(): atom$Directory, - - // Reading and Writing - read(flushCache?: boolean): Promise, - write(text: string): Promise, - writeSync(text: string): void, - createReadStream(): stream$Readable, - createWriteStream(): stream$Writable, -} - -declare class atom$GitRepository extends atom$Repository { - // Unofficial API. - statuses: {[filePath: string]: number}, - // Return the `git-utils` async repo. - getRepo(): atom$GitRepositoryInternal, -} - -declare class atom$Grammar { - name: string, - scopeName: string, - tokenizeLines(text: string): Array>, -} - -type atom$GrammarToken = { - value: string, - scopes: Array, -}; - -declare class atom$GrammarRegistry { - // Event Subscription - onDidAddGrammar(callback: (grammar: atom$Grammar) => void): IDisposable, - - // Managing Grammars - grammarForScopeName(scopeName: string): ?atom$Grammar, - removeGrammarForScopeName(scopeName: string): ?atom$Grammar, - loadGrammarSync(grammarPath: string): atom$Grammar, - selectGrammar(filePath: string, fileContents: string): atom$Grammar, - autoAssignLanguageMode(buffer: atom$TextBuffer): void, - assignLanguageMode(buffer: atom$TextBuffer, languageId: string): void, - - // Private API - clear(): IDisposable, -} - -declare class atom$HistoryManager { - removeProject(paths: Array): void, - getProjects(): Array, -} - -declare class atom$HistoryProject { - get paths(): Array; - get lastOpened(): Date; -} - -// https://github.com/atom/atom-keymap/blob/18f00ac307de5770bb8f98958bd9a13ecffa9e68/src/key-binding.coffee -declare class atom$KeyBinding { - cachedKeyups: ?Array, - command: string, - index: number, - keystrokeArray : Array, - keystrokeCount: number, - keystrokes: string, - priority: number, - selector: string, - source: string, - specificity: number, - - matches(keystroke: string): boolean, - compare(keybinding: atom$KeyBinding): number, - getKeyups(): ?Array, - matchesKeystrokes(userKeystrokes: Array): boolean | 'exact' | 'partial' | 'pendingKeyup', -} - -declare class atom$KeymapManager { - // Event Subscription - onDidMatchBinding(callback: (event: { - keystrokes: string, - binding: atom$KeyBinding, - keyboardEventTarget: HTMLElement, - }) => mixed): IDisposable, - - onDidPartiallyMatchBinding(callback: (event: { - keystrokes: string, - partiallyMatchedBindings: atom$KeyBinding, - keyboardEventTarget: HTMLElement, - }) => mixed): IDisposable, - - onDidFailToMatchBinding(callback: (event: { - keystrokes: string, - partiallyMatchedBindings: atom$KeyBinding, - keyboardEventTarget: HTMLElement, - }) => mixed): IDisposable, - - onDidFailToReadFile(callback: (error: { - message: string, - stack: string, - }) => mixed): IDisposable, - - // Adding and Removing Bindings - add(source: string, bindings: Object): IDisposable, - removeBindingsFromSource(source: string): void, - - // Accessing Bindings - getKeyBindings(): Array, - findKeyBindings(params: { - keystrokes?: string, - command?: string, - target?: HTMLElement, - }): Array, - - // Managing Keymap Files - loadKeymap(path: string, options?: {watch: boolean}): void, - watchKeymap(path: string): void, - - // Managing Keyboard Events - handleKeyboardEvent(event: Event): void, - keystrokeForKeyboardEvent(event: Event): string, - getPartialMatchTimeout(): number, - - static buildKeydownEvent( - key: string, - options: { - target: HTMLElement, - alt?: boolean, - cmd?: boolean, - ctrl?: boolean, - shift?: boolean, - }, - ): Event, -} - -declare class atom$MenuManager { - add(items: Array): IDisposable, - update(): void, - - // Private API - template: Array, -} - -type atom$ProjectSpecification = { - originPath: string, - paths?: Array, - config?: {[string]: mixed} -}; - -declare class atom$Project { - // Event Subscription - onDidChangePaths(callback: (projectPaths: Array) => mixed): IDisposable, - onDidAddBuffer(callback: (buffer: atom$TextBuffer) => mixed): IDisposable, - onDidReplace((settings: atom$ProjectSpecification) => mixed): IDisposable, - observeBuffers(callback: (buffer: atom$TextBuffer) => mixed): IDisposable, - replace?: (newSettings: atom$ProjectSpecification) => void, - // Accessing the git repository - getRepositories(): Array, - repositoryForDirectory(directory: atom$Directory): Promise, - - // Managing Paths - getPaths(): Array, - addPath(projectPath: string, options?: { - emitEvent?: boolean, - exact?: boolean, - mustExist?: boolean, - }): void, - setPaths(paths: Array): void, - removePath(projectPath: string): void, - getDirectories(): Array, - relativizePath(relativizePath?: string): Array, // [projectPath: ?string, relativePath: string] - relativize(filePath: string): string, - contains(path: string): boolean, - - // Private API - findBufferForPath(path: string): ?atom$TextBuffer, - addBuffer(buffer: atom$TextBuffer): void, - removeBuffer(buffer: atom$TextBuffer): void, - getBuffers(): Array, -} - -type TextBufferScanIterator = (arg: { - match: Array, - matchText: string, - range: atom$Range, - stop(): void, - replace(replacement: string): void, -}) => void; - -// This happens to be a number but it would be better if the type could be entirely opaque. All you -// need to know is that if something needs a checkpoint you should only pass it values received from -// TextBuffer::createCheckpoint -type atom$TextBufferCheckpoint = number; - -// TextBuffer did-change/will-change -type atom$TextEditEvent = { - oldRange: atom$Range, - newRange: atom$Range, - oldText: string, - newText: string, -}; - -type atom$AggregatedTextEditEvent = { - changes: Array, -}; - -declare class atom$LanguageMode { - getLanguageId(): string, -} - -declare class atom$TextBuffer { - constructor(text?: string): atom$TextBuffer, - constructor(params?: { - filePath?: string, - text?: string, - }): atom$TextBuffer, - - file: ?atom$File, - - // Mixin - static deserialize: (state: Object, params: Object) => mixed, - static load: (file: string | atom$Fileish, params: Object) => Promise, - - setFile(file: atom$Fileish): void, - - // Events - onWillChange(callback: () => mixed): IDisposable, - onDidChangeText(callback: (event: atom$AggregatedTextEditEvent) => mixed): IDisposable, - onDidStopChanging(callback: () => mixed): IDisposable, - onDidConflict(callback: () => mixed): IDisposable, - onDidChangeModified(callback: () => mixed): IDisposable, - onDidUpdateMarkers(callback: () => mixed): IDisposable, - onDidCreateMarker(callback: () => mixed): IDisposable, - onDidChangePath(callback: () => mixed): IDisposable, - onDidChangeEncoding(callback: () => mixed): IDisposable, - onWillSave(callback: () => mixed): IDisposable, - onDidSave(callback: (event: {path: string}) => mixed): IDisposable, - onDidDelete(callback: () => mixed): IDisposable, - onWillReload(callback: () => mixed): IDisposable, - onDidReload(callback: () => mixed): IDisposable, - onDidDestroy(callback: () => mixed): IDisposable, - onWillThrowWatchError(callback: () => mixed): IDisposable, - - // File Details - // DO NOT USE (T21363106): Doesn't work with remote text buffers! - // setPath(filePath: string): void, - getPath(): ?string, - setEncoding(encoding: string): void, - getEncoding(): string, - getUri(): string, - getId(): string, - getLanguageMode(): atom$LanguageMode, - - // Reading Text - isEmpty(): boolean, - getText(): string, - getTextInRange(range: atom$RangeLike): string, - getLineCount(): number, - getLines(): Array, - getLastLine(): string, - lineForRow(row: number): string, - lineEndingForRow(row: number): string, - lineLengthForRow(row: number): number, - isRowBlank(row: number): boolean, - previousNonBlankRow(startRow: number): ?number, - nextNonBlankRow(startRow: number): ?number, - - // Mutating Text - setText: (text: string) => atom$Range, - setTextInRange(range: atom$RangeLike, text: string, options?: Object): atom$Range, - setTextViaDiff(text: string): void, - insert( - position: atom$Point, - text: string, - options?: { - normalizeLineEndings?: boolean, - undo?: string, - }, - ): atom$Range, - append(text: string, options: ?{ - normalizeLineEndings?: boolean, - undo?: string, - }): atom$Range, - delete(range: atom$Range): atom$Range, - deleteRows(startRow: number, endRow: number): atom$Range, - - // History - undo(): void, - redo(): void, - transact(fn: () => mixed, _: void): void, - transact(groupingInterval: number, fn: () => mixed): void, - clearUndoStack(): void, - createCheckpoint(): atom$TextBufferCheckpoint, - revertToCheckpoint(checkpoint: atom$TextBufferCheckpoint): boolean, - groupChangesSinceCheckpoint(checkpoint: atom$TextBufferCheckpoint): boolean, - // TODO describe the return type more precisely. - getChangesSinceCheckpoint(checkpoint: atom$TextBufferCheckpoint): Array, - - // Search And Replace - scan(regex: RegExp, iterator: TextBufferScanIterator): void, - scanInRange(regex: RegExp, range: atom$Range, iterator: TextBufferScanIterator): void, - backwardsScanInRange(regex: RegExp, range: atom$Range, iterator: TextBufferScanIterator): void, - - // Buffer Range Details - getLastRow(): number, - getRange(): atom$Range, - rangeForRow(row: number, includeNewLine?: boolean): atom$Range, - - // Position/Index mapping - characterIndexForPosition(position: atom$PointLike): number, - positionForCharacterIndex(index: number): atom$Point, - - // Buffer Operations - reload(): void, - load(): Promise, - save(): Promise, - - isInConflict(): boolean, - isModified(): boolean, - - // Private APIs - cachedDiskContents: ?string, - emitter: atom$Emitter, - refcount: number, - loaded: boolean, - wasModifiedBeforeRemove: boolean, - finishLoading(): atom$TextBuffer, - updateCachedDiskContents(flushCache?: boolean, callback?: () => mixed): Promise, - emitModifiedStatusChanged(changed: boolean): void, - destroy(): void, - isDestroyed(): boolean, - applyChange: () => void, - shouldDestroyOnFileDelete?: () => boolean, -} - -declare class atom$Notification { - // Event Subscription - onDidDismiss(callback: () => mixed): IDisposable, - onDidDisplay(callback: () => mixed): IDisposable, - - // Methods - getType(): string, - getMessage(): string, - getOptions(): Object, - dismiss(): void, - isDismissed(): boolean, -} - -type atom$NotificationButton = { - text: string, - className?: string, - onDidClick?: () => mixed, -}; - -type atom$NotificationOptions = { - detail?: string, - dismissable?: boolean, - description?: string, - icon?: string, - stack?: string, - buttons?: Array, -}; - -declare class atom$NotificationManager { - // Events - onDidAddNotification(callback: (notification: atom$Notification) => void): IDisposable, - - // Adding Notifications - add(type: string, message: string, options?: atom$NotificationOptions): atom$Notification, - addSuccess(message: string, options?: atom$NotificationOptions): atom$Notification, - addInfo(message: string, options?: atom$NotificationOptions): atom$Notification, - addWarning(message: string, options?: atom$NotificationOptions): atom$Notification, - addError(message: string, options?: atom$NotificationOptions): atom$Notification, - addFatalError(message: string, options?: atom$NotificationOptions): atom$Notification, - addNotification(notification: atom$Notification): atom$Notification, - - // Getting Notifications - getNotifications(): Array, -} - -// The items in this declaration are available off of `require('atom')`. -// This list is not complete. -declare module 'atom' { - declare var BufferedNodeProcess: typeof atom$BufferedNodeProcess; - declare var BufferedProcess: typeof atom$BufferedProcess; - declare var CompositeDisposable: typeof atom$CompositeDisposable; - declare var Directory: typeof atom$Directory; - declare var Disposable: typeof atom$Disposable; - declare var Emitter: typeof atom$Emitter; - declare var File: typeof atom$File; - declare var GitRepository: typeof atom$GitRepository; - declare var Notification: typeof atom$Notification; - declare var Point: typeof atom$Point; - declare var Range: typeof atom$Range; - declare var TextBuffer: typeof atom$TextBuffer; - declare var TextEditor: typeof atom$TextEditor; -} - -// Make sure that common types can be referenced without the `atom$` prefix -// in type declarations. -declare var Cursor: typeof atom$Cursor; -declare var Panel: typeof atom$Panel; -declare var TextEditor: typeof atom$TextEditor; - -type atom$UnhandledErrorEvent = { - originalError: Object, - message: string, - url: string, - line: number, - column: number, -}; - -// The properties of this type match the properties of the `atom` global. -// This list is not complete. -type AtomGlobal = { - // Properties - appVersion: string, - atomScriptMode: ?boolean, // Added by nuclide-atom-script. - clipboard: atom$Clipboard, - commands: atom$CommandRegistry, - config: atom$Config, - contextMenu: atom$ContextMenuManager, - applicationDelegate: atom$applicationDelegate, - deserializers: atom$DeserializerManager, - grammars: atom$GrammarRegistry, - history: atom$HistoryManager, - keymaps: atom$KeymapManager, - menu: atom$MenuManager, - notifications: atom$NotificationManager, - packages: atom$PackageManager, - styles: atom$StyleManager, - themes: atom$ThemeManager, - textEditors: atom$TextEditorRegistry, - tooltips: atom$TooltipManager, - views: atom$ViewRegistry, - workspace: atom$Workspace, - project: atom$Project, - devMode: boolean, - - // Event Subscription - onWillThrowError(callback: (event: atom$UnhandledErrorEvent) => mixed): IDisposable, - onDidThrowError(callback: (event: atom$UnhandledErrorEvent) => mixed): IDisposable, - whenShellEnvironmentLoaded(callback: () => mixed): IDisposable, - - // Atom Details - inDevMode(): boolean, - inSafeMode(): boolean, - inSpecMode(): boolean, - getVersion(): string, - isReleasedVersion(): boolean, - getWindowLoadTime(): number, - - // This is an undocumented way to reach the Electron BrowserWindow. - // Use `electron.remote.getCurrentWindow` instead. - getCurrentWindow: void, - - // Messaging the User - confirm(options: { - buttons?: Array | {[buttonName: string]: () => mixed}, - detailedMessage?: string, - message: string, - }): ?number, - - open(params: { - pathsToOpen?: Array, - newWindow?: boolean, - devMode?: boolean, - safeMode?: boolean, - }): void, - reload(): void, - - // Undocumented Methods - getConfigDirPath(): string, - showSaveDialogSync(options: Object): string, - loadState(): Promise, - getLoadSettings(): Object, -}; - -declare var atom: AtomGlobal; - -type RepositoryDidChangeStatusCallback = (event: {path: string, pathStatus: number}) => mixed; -type RepositoryLineDiff = { - oldStart: number, - newStart: number, - oldLines: number, - newLines: number, -}; - -// Taken from the interface of [`GitRepository`][1], which is also implemented by -// `HgRepositoryClient`. -// -// [1]: https://github.com/atom/atom/blob/v1.7.3/src/git-repository.coffee -declare class atom$Repository { - constructor(path: string, options?: {refreshOnWindowFocus?: boolean}): void, - - // Event Subscription - onDidChangeStatus: (callback: RepositoryDidChangeStatusCallback) => IDisposable, - onDidChangeStatuses: (callback: () => mixed) => IDisposable, - - // Repository Details - getType: () => string, - getPath: () => string, - getWorkingDirectory: () => string, - getProjectDirectory: () => string, - isProjectAtRoot: () => boolean, - relativize: (aPath: string) => string, - getOriginURL: (aPath: ?string) => ?string, - - // Reading Status - isPathModified: (aPath: string) => boolean, - isPathNew: (aPath: string) => boolean, - isPathIgnored: (aPath: string) => boolean, - getDirectoryStatus: (aPath: string) => number, - getPathStatus: (aPath: string) => number, - getCachedPathStatus: (aPath: string) => ?number, - isStatusModified: (status: number) => boolean, - isStatusNew: (status: number) => boolean, - refreshStatus: () => Promise, - - // Retrieving Diffs - getDiffStats: (filePath: string) => {added: number, deleted: number}, - getLineDiffs: (aPath: string, text: string) => Array, - - // Checking Out - checkoutHead: (aPath: string) => boolean, - checkoutReference: (reference: string, create: boolean) => Promise, - - // Event Subscription - onDidDestroy(callback: () => mixed): IDisposable, - isDestroyed(): boolean, -} - -declare class atom$GitRepositoryInternal { - // Reading Status - isStatusModified: (status: number) => boolean, - isStatusNew: (status: number) => boolean, - isStatusIgnored: (status: number) => boolean, - isStatusStaged: (status: number) => boolean, - isStatusDeleted: (status: number) => boolean, -} - -// One of text or snippet is required. -// TODO(hansonw): use a union + intersection type -type atom$AutocompleteSuggestion = { - text?: string, - snippet?: string, - displayText?: string, - replacementPrefix?: string, - type?: ?string, - leftLabel?: ?string, - leftLabelHTML?: ?string, - rightLabel?: ?string, - rightLabelHTML?: ?string, - className?: ?string, - iconHTML?: ?string, - description?: ?string, - descriptionMarkdown?: ?string, - descriptionMoreURL?: ?string, -}; - -type atom$AutocompleteRequest = { - editor: TextEditor, - bufferPosition: atom$Point, - scopeDescriptor: atom$ScopeDescriptor, - prefix: string, - activatedManually?: boolean, -}; - -type atom$AutocompleteProvider = { - +selector: string, - +getSuggestions: ( - request: atom$AutocompleteRequest, - ) => Promise> | ?Array, - +getSuggestionDetailsOnSelect?: ( - suggestion: atom$AutocompleteSuggestion - ) => Promise, - +disableForSelector?: string, - +inclusionPriority?: number, - +excludeLowerPriority?: boolean, - +suggestionPriority?: number, - +filterSuggestions?: boolean, - +disposable?: () => void, - +onDidInsertSuggestion?: ( - insertedSuggestion: atom$SuggestionInsertedRequest, - ) => void, -}; - -type atom$SuggestionInsertedRequest = { - +editor: atom$TextEditor, - +triggerPosition: atom$Point, - +suggestion: atom$AutocompleteSuggestion, -}; - -// https://github.com/atom/autocomplete-plus/blob/master/README.md#the-watcheditor-api -type atom$AutocompleteWatchEditor = ( - editor: atom$TextEditor, - labels?: Array, -) => IDisposable; - -// Undocumented API. -declare class atom$Token { - value: string, - matchesScopeSelector(selector: string): boolean, -} - -declare class atom$Selection { - clear(): void, - getText(): string, - getBufferRange(): atom$Range, - insertText( - text: string, - options?: { - select?: boolean, - autoIndent?: boolean, - autoIndentNewLine?: boolean, - autoDecreaseIdent?: boolean, - normalizeLineEndings?: boolean, - undo?: boolean, - }, - ): string, -} - -declare class atom$PanelContainer { - dock: atom$Dock, - element: HTMLElement, - emitter: atom$Emitter, - location: atom$PaneLocation, - panels: Array, - subscriptions: atom$CompositeDisposable, - viewRegistry: atom$ViewRegistry, - - getPanels(): Array, -}; diff --git a/flow-libs/bom.js.flow b/flow-libs/bom.js.flow deleted file mode 100644 index 5213ea954d..0000000000 --- a/flow-libs/bom.js.flow +++ /dev/null @@ -1,61 +0,0 @@ -/** - * 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 - */ - -declare type PerformanceEntry$EntryType = - | 'frame' - | 'longtask' - | 'mark' - | 'measure' - | 'navigation' - | 'paint' - | 'resource'; - -declare type PerformanceObserverInit = {| - entryTypes: Array, -|}; - -declare type PerformanceEntryFilterOptions = {| - name?: string, - entryType?: PerformanceEntry$EntryType, - initiatorType?: string, -|}; - -declare type PerformanceObserverEntryList = {| - getEntries( - filterOptions?: PerformanceEntryFilterOptions, - ): Array, - getEntriesByName( - name: string, - type: PerformanceEntry$EntryType, - ): Array, - getEntriesByType(type: PerformanceEntry$EntryType): Array, -|}; - -declare type ResizeObserverEntry = {| - target: HTMLElement, - contentRect: DOMRectReadOnly, -|}; - -declare class PerformanceObserver { - constructor( - callback: (entries: PerformanceObserverEntryList) => void, - observer: this, - ): void, - observe(options: PerformanceObserverInit): void, - disconnect(): void, -} - -declare class ResizeObserver { - constructor(callback: (entries: Array) => void): void, - observe(target: HTMLElement): void, - unobserve(target: HTMLElement): void, - disconnect(): void, -} diff --git a/flow-libs/connect.js.flow b/flow-libs/connect.js.flow deleted file mode 100644 index 8fdd6ff0bd..0000000000 --- a/flow-libs/connect.js.flow +++ /dev/null @@ -1,90 +0,0 @@ -/** - * 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 - */ - -declare class connect$Error extends Error { - code?: number, -} - -type connect$ServerHandle = connect$HandleFunction | http$fixed$Server; -type connect$SimpleHandleFunction = - (req: http$fixed$IncomingMessage, res: http$fixed$ServerResponse) => mixed; -type connect$NextHandleFunction = - (req: http$fixed$IncomingMessage, res: http$fixed$ServerResponse, next: Function) => mixed; -type connect$ErrorHandleFunction = (err: ?connect$Error, req: http$fixed$IncomingMessage, - res: http$fixed$ServerResponse, next: Function) => mixed; -type connect$HandleFunction = - connect$SimpleHandleFunction | connect$NextHandleFunction | connect$ErrorHandleFunction; - -type connect$ServerStackItem = { - route: string, - handle: connect$ServerHandle, -}; - -declare class connect$Server { - (req: http$fixed$IncomingMessage, res: http$fixed$ServerResponse, next?: Function): void, - - route: string, - stack: Array, - - /** - * Utilize the given middleware `handle` to the given `route`, - * defaulting to _/_. This "route" is the mount-point for the - * middleware, when given a value other than _/_ the middleware - * is only effective when that segment is present in the request's - * pathname. - * - * For example if we were to mount a function at _/admin_, it would - * be invoked on _/admin_, and _/admin/settings_, however it would - * not be invoked for _/_, or _/posts_. - * - * @public - */ - use(fn: connect$HandleFunction): connect$Server, - use(route: string, fn: connect$HandleFunction): connect$Server, - - /** - * Handle server requests, punting them down - * the middleware stack. - * - * @private - */ - handle(req: http$fixed$IncomingMessage, res: http$fixed$ServerResponse, next: Function): void, - - /** - * Listen for connections. - * - * This method takes the same arguments - * as node's `http$fixed$Server#listen()`. - * - * HTTP and HTTPS: - * - * If you run your application both as HTTP - * and HTTPS you may wrap them individually, - * since your Connect "server" is really just - * a JavaScript `Function`. - * - * var connect = require('connect') - * , http = require('http') - * , https = require('https'); - * - * var app = connect(); - * - * http$fixed$createServer(app).listen(80); - * https.createServer(options, app).listen(443); - * - * @api public - */ - listen(port: number, hostname?: string, backlog?: number, callback?: Function): http$fixed$Server, - listen(port: number, hostname?: string, callback?: Function): http$fixed$Server, - listen(path: string, callback?: Function): http$fixed$Server, - listen(handle: any, listeningListener?: Function): http$fixed$Server, -} - -type connect$module = () => connect$Server; diff --git a/flow-libs/diffparser.js.flow b/flow-libs/diffparser.js.flow deleted file mode 100644 index f3c082080f..0000000000 --- a/flow-libs/diffparser.js.flow +++ /dev/null @@ -1,43 +0,0 @@ -/** - * 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 - */ - -type diffparser$FileName = string; - -type diffparser$FileDiff = { - annotation?: string, // Added for convenience; no annotations returned by diffparser.parse - from: diffparser$FileName, - to: diffparser$FileName, - chunks: Array, - deletions: number, - additions: number, - index?: Array, -}; - -type diffparser$Hunk = { - content: string, - changes: Array, - oldStart: number, - oldLines: number, - newStart: number, - newLines: number, -}; - -type diffparser$Change = { - type: diffparser$ChangeType, - content: string, - ln: number, - position: number, -}; - -type diffparser$ChangeType = 'del' | 'add' | 'normal'; - -declare module 'diffparser' { - declare export default function parse(diff: string): Array; -} diff --git a/flow-libs/electron.js.flow b/flow-libs/electron.js.flow deleted file mode 100644 index 2d581dd39f..0000000000 --- a/flow-libs/electron.js.flow +++ /dev/null @@ -1,925 +0,0 @@ -/** - * 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 - */ - -// The properties on this module depend on whether the importer is the main -// process or a renderer process. -declare module 'electron' { - // Main process: - declare var app: ?electron$app; - declare var autoUpdater: ?electron$autoUpdater; - // $FlowFixMe - declare var BrowserWindow: ?typeof electron$BrowserWindow; - declare var contentTracing: ?electron$contentTracing; - declare var dialog: ?electron$dialog; - declare var globalShortcut: ?electron$globalShortcut; - declare var ipcMain: ?electron$IpcMain; - // $FlowFixMe - declare var Menu: ?typeof electron$Menu; - // $FlowFixMe - declare var MenuItem: ?typeof electron$MenuItem; - declare var powerMonitor: ?electron$powerMonitor; - declare var powerSaveBlocker: ?electron$powerSaveBlocker; - declare var protocol: ?electron$protocol; - declare var session: ?electron$session; - declare var electron$Tray: ?typeof electron$Tray; - declare var webContents: ?electron$webContents; - - // Renderer process: - declare var desktopCapturer: ?electron$desktopCapturer; - declare var ipcRenderer: ?electron$IpcRenderer; - declare var remote: ?electron$remote; - declare var webFrame: ?electron$webFrame; - - // Both: - declare var clipboard: electron$clipboard; - declare var crashReporter: electron$crashReporter; - declare var nativeImage: electron$nativeImage; - declare var screen: electron$Screen; - declare var shell: electron$shell; - - declare type electron$BrowserWindow = electron$BrowserWindow; - declare type electron$Menu = electron$Menu; - declare type electron$MenuItem = electron$MenuItem; - declare type electron$NativeImage = electron$NativeImage; - declare type electron$Screen = electron$Screen; - declare type electron$WebContents = electron$WebContents; -} - -// very common struct -type electron$rect = { - x: number, - y: number, - width: number, - height: number, -}; - -//------------------------------------------------------------------------------ -// Custom DOM Elements -//------------------------------------------------------------------------------ - -/** - * https://github.com/electron/electron/blob/master/docs/api/file-object.md - */ - -// HTML5 File API but with a `path` attribute added. - -/** - * https://github.com/electron/electron/blob/master/docs/api/web-view-tag.md - */ - -declare class WebviewElement extends HTMLElement { - src: string, - nodeintegration: boolean, - disablewebsecurity: boolean, - - executeJavaScript(code: string, userGesture: ?boolean): void, - getTitle(): string, - // This used to be `getUrl`, but the old version was dropped in the electron bundled with Atom - // 1.12, and the new version exists at least in Atom 1.10.2 onward. - getURL(): string, - // Not sure when this was introduced - stop?: () => void, - insertCSS(code: string): void, - send(channel: string, ...args: Array): void, - openDevTools(): void, -} - -/** - * https://github.com/electron/electron/blob/master/docs/api/window-open.md - */ - -// window.open - -//------------------------------------------------------------------------------ -// Modules for the Main Process -//------------------------------------------------------------------------------ - -/** - * https://github.com/electron/electron/blob/master/docs/api/app.md - */ - -type electron$app = { - quit(): void, - exit(exitCode?: number): void, - relaunch(options?: {args?: Array, execPath?: string}): void, - isReady(): boolean, - focus(): void, - getAppPath(): string, - getPath(name: string): string, - setPath(name: string, path: string): void, - getVersion(): string, - getName(): string, - setName(name: string): void, - getLocale(): string, - makeSingleInstance(callback: (argv: Array, workingDirectory: string) => void): boolean, - releaseSingleInstance(): void, - disableHardwareAcceleration(): void, -}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/auto-updater.md - */ - -type electron$autoUpdater = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/browser-window.md - */ - -type electron$BrowserWindowOptions = { - width?: number, - height?: number, - x?: number, - y?: number, - useContentSize?: boolean, - center?: boolean, - minWidth?: number, - minHeight?: number, - maxWidth?: number, - maxHeight?: number, - resizable?: boolean, - movable?: boolean, - minimizable?: boolean, - maximizable?: boolean, - closable?: boolean, - focusable?: boolean, - alwaysOnTop?: boolean, - fullscreen?: boolean, - fullscreenable?: boolean, - skipTaskbar?: boolean, - kiosk?: boolean, - title?: string, - icon?: electron$NativeImage, - show?: boolean, - frame?: boolean, - parent?: electron$BrowserWindow, - modal?: boolean, - acceptFirstMouse?: boolean, - disableAutoHideCursor?: boolean, - autoHideMenuBar?: boolean, - enableLargerThanScreen?: boolean, - backgroundColor?: string, - hasShadow?: boolean, - darkTheme?: boolean, - transparent?: boolean, - type?: 'desktop' | 'dock' | 'toolbar' | 'splash' | 'notification' | - /* macOS */ 'desktop' | 'textured' | - /* Windows */ 'toolbar', - titleBarStyle?: 'default' | 'hidden' | 'hidden-inset', - thickFrame?: boolean, - webPreferences?: electron$BrowserWindowWebPreferences, -}; - -type electron$BrowserWindowWebPreferences = { - nodeIntegration?: boolean, - preload?: string, - session?: electron$session, - partition?: string, - zoomFactor?: number, - javascript?: boolean, - webSecurity?: boolean, - allowDisplayingInsecureContent?: boolean, - allowRunningInsecureContent?: boolean, - images?: boolean, - textAreasAreResizable?: boolean, - webgl?: boolean, - webaudio?: boolean, - plugins?: boolean, - experimentalFeatures?: boolean, - experimentalCanvasFeatures?: boolean, - scrollBounce?: boolean, - blinkFeatures?: string, - disableBlinkFeatures?: string, - defaultFontFamily?: { - standard?: string, - serif?: string, - sansSerif?: string, - monospace?: string, - }, - defaultFontSize?: number, - defaultMonospaceFontSize?: number, - minimumFontSize?: number, - defaultEncoding?: string, - backgroundThrottling?: boolean, - offscreen?: boolean, -}; - -type electron$BrowserWindowEvents = - | 'page-title-updated' - | 'close' - | 'closed' - | 'unresponsive' - | 'responsive' - | 'blur' - | 'focus' - | 'show' - | 'hide' - | 'ready-to-show' - | 'maximize' - | 'unmaximize' - | 'minimize' - | 'restore' - | 'resize' - | 'move' - | 'moved' - | 'enter-full-screen' - | 'leave-full-screen' - | 'enter-html-full-screen' - | 'leave-html-full-screen' - | 'context-menu' - | 'app-command' // Windows - | 'scroll-touch-begin' // macOS - | 'scroll-touch-end' // macOS - | 'swipe'; // macOS - -type electron$BrowserWindowListener = ( - event: electron$BrowserWindowEvents, - callback: (event: Object, ...args: Array) => void, -) => electron$BrowserWindow; - -declare class electron$BrowserWindow { - constructor(options: electron$BrowserWindowOptions): void, - on: electron$BrowserWindowListener, - once: electron$BrowserWindowListener, - removeAllListeners(event?: electron$BrowserWindowEvents): electron$BrowserWindow, - removeListener(event?: electron$BrowserWindowEvents, callback: Function): electron$BrowserWindow, - send(channel: string, ...args: Array): void, - - static getAllWindows(): Array, - static getFocusedWindow(): ?electron$BrowserWindow, - static fromWebContents(webContents: electron$WebContents): ?electron$BrowserWindow, - static fromId(id: number): ?electron$BrowserWindow, - static addDevToolsExtension(path: string): void, - static removeDevToolsExtension(name: string): void, - static getDevToolsExtensions(): {[name: string]: {[name: string]: string}}, - - webContents: electron$WebContents, - id: number, - destroy(): void, - close(): void, - focus(): void, - blur(): void, - isFocused(): boolean, - show(): void, - showInactive(): void, - hide(): void, - isVisible(): boolean, - isModal(): boolean, - maximize(): void, - unmaximize(): void, - isMaximized(): boolean, - minimize(): void, - restore(): void, - isMinimized(): boolean, - setFullScreen(flag: boolean): void, - isFullScreen(): boolean, - setAspectRatio(aspectRatio: number, extraSize?: {width: number, height: number}): void, // macOS - setBounds(options: electron$rect, /* macOS */ animate?: boolean): void, - getBounds(): electron$rect, - setSize(width: number, height: number, /* macOS */ animate?: boolean): void, - getSize(): [number, number], - setContentSize(width: number, height: number, /* macOS */ animate?: boolean): void, - getContentSize(): [number, number], - setMinimumSize(width: number, height: number): void, - getMinimumSize(): [number, number], - setMaximumSize(width: number, height: number): void, - getMaximumSize(): [number, number], - setResizable(resizable: boolean): void, - isResizable(): boolean, - setMovable(movable: boolean): void, // macOS Windows - isMovable(): boolean, // macOS Windows - setMinimizable(minimizable: boolean): void, // macOS Windows - isMinimizable(): boolean, // macOS Windows - setMaximizable(maximizable: boolean): void, // macOS Windows - isMaximizable(): boolean, // macOS Windows - setFullScreenable(fullscreenable: boolean): void, - isFullScreenable(): boolean, - setClosable(closable: boolean): void, // macOS Windows - isClosable(): boolean, // macOS Windows - setAlwaysOnTop(flag: boolean): void, - isAlwaysOnTop(): boolean, - center(): void, - setPosition(x: number, y: number, /* macOS */ animate?: boolean): void, - getPosition(): [number, number], - setTitle(title: string): void, - getTitle(): string, - setSheetOffset(offsetY: number, offsetX?: number): void, // macOS - flashFrame(flag: boolean): void, - setSkipTaskbar(skip: boolean): void, - setKiosk(flag: boolean): void, - isKiosk(): boolean, - getNativeWindowHandle(): Buffer, - hookWindowMessage(message: number, callback: Function): void, // Windows - isWindowMessageHooked(message: number): boolean, // Windows - unhookWindowMessage(message: number): void, // Windows - unhookAllWindowMessages(): void, // Windows - setRepresentedFilename(filename: string): void, // macOS - getRepresentedFilename(): string, // macOS - setDocumentEdited(edited: boolean): void, // macOS - isDocumentEdited(): boolean, // macOS - focusOnWebView(): void, - blurWebView(): void, - capturePage(rect: electron$rect, callback: (image: electron$NativeImage) => void): void, - capturePage(callback: (image: electron$NativeImage) => void): void, - loadURL( - url: string, - options?: {httpReferrer?: string, userAgent?: string, extraHeaders?: string}, - ): void, - reload(): void, - setMenu(menu: ?electron$Menu): void, // Linux Windows - setProgressBar(progress: number): void, - setOverlayIcon(overlay: electron$NativeImage, description: string): void, // Windows - setHasShadow(hasShadow: boolean): void, // macOS - hasShadow(): boolean, // macOS - setThumbarButtons(buttons: Array<{ - icon: electron$NativeImage, - click: Function, - tooltip?: string, - flags?: Array<'enabled' | 'disabled' | 'dismissonclick' | 'nobackground' | - 'hidden' | 'noninteractive'>, - }>): void, // Windows - setThumbnailClip(region: electron$rect): void, // Windows - showDefinitionForSelection(): void, // macOS - setIcon(icon: electron$NativeImage): void, // Windows Linux - setAutoHideMenuBar(hide: boolean): void, - isMenuBarAutoHide(): boolean, - setMenuBarVisibility(visible: boolean): void, - isMenuBarVisible(): boolean, - setVisibleOnAllWorkspaces(visible: boolean): void, - isVisibleOnAllWorkspaces(): boolean, - setIgnoreMouseEvents(ignore: boolean): void, - setContentProtection(enable: boolean): void, // macOS Windows - setFocusable(focusable: boolean): void, // Windows - setParentWindow(parent: electron$BrowserWindow): void, // Linux macOS - getParentWindow(): ?electron$BrowserWindow, - getChildWindows(): Array, - - // Atom sets this during window setup (see: src/main-process/atom-window.coffee). - loadSettings?: Object, -} - -/** - * https://github.com/electron/electron/blob/master/docs/api/content-tracing.md - */ - -type electron$contentTracing = { - startRecording( - options: {categoryFilter: string, traceOptions: string}, - callback: () => mixed, - ): boolean, - - stopRecording( - resultFilePath: ?string, - callback: (resultFilePath: string) => mixed, - ): void, -}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/dialog.md - */ - -type electron$dialog = { - showOpenDialog( - browserWindow?: electron$BrowserWindow, - options: electron$dialogOpenOptions, - callback?: Function, - ): Array, - showSaveDialog( - browserWindow?: electron$BrowserWindow, - options: electron$dialogSaveOptions, - callback?: Function, - ): string, - showMessageBox( - browserWindow?: electron$BrowserWindow, - options: electron$dialogMessageBoxOptions, - callback?: Function, - ): number, - showErrorBox(title: string, content: string): void, -}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/dialog.md - * See `dialog.showOpenDialog()` - */ - -type electron$dialogOpenOptions = { - title?: string, - defaultPath?: string, - buttonLabel?: string, - filters?: Array, - properties?: Array, -}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/dialog.md - * See `dialog.showSaveDialog()` - */ - -type electron$dialogSaveOptions = { - title?: string, - defaultPath?: string, - buttonLabel?: string, - filters?: Array, -}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/dialog.md - * See `dialog.showMessageBox()` - */ - -type electron$dialogMessageBoxOptions = { - type?: string, - buttons?: Array, - defaultId?: number, - title?: string, - message?: string, - detail?: string, - icon?: electron$NativeImage, - cancelId?: number, - noLink?: boolean, -}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/global-shortcut.md - */ - -type electron$globalShortcut = { - register: (string, () => void) => boolean, - isRegistered: (string) => boolean, - unregister: (string) => void, - unregisterAll: () => void, -}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/ipc-main.md - */ - -declare class electron$IpcMain extends events$EventEmitter {} - -/** - * https://github.com/electron/electron/blob/master/docs/api/menu.md - */ - -declare class electron$Menu { - static setApplicationMenu(menu: electron$Menu): void, - static getApplicationMenu(): ?electron$Menu, - static sendActionToFirstResponder(action: string): void, - static buildFromTemplate(templates: Array): electron$Menu, - popup({| - window?: electron$BrowserWindow, - x?: number, - y?: number, - positioningItem?: number, - callback?: Function, - // Note: this is always true in Electron 2.0+. - async?: boolean, - |}): void, - closePopup(window?: electron$BrowserWindow): void, - append(menuItem: electron$MenuItem): void, - insert(pos: number, menuItem: electron$MenuItem): void, - items: Array, -} - -/** - * https://github.com/electron/electron/blob/master/docs/api/menu-item.md - */ - -type electron$MenuItemOptions = { - click?: ( - menuItem: electron$MenuItem, - browserWindow: electron$BrowserWindow, - event: Object - ) => void, - role?: 'undo' | 'redo' | 'cut' | 'copy' | 'paste' | 'pasteandmatchstyle' | - 'selectall' | 'delete' | 'minimize' | 'close' | 'quit' | 'togglefullscreen' | - // macOS-only - 'about' | 'hide' | 'hideothers' | 'unhide' | 'front' | 'zoom' | 'window' | - 'help' | 'services', - type?: 'normal' | 'separator' | 'submenu' | 'checkbox' | 'radio', - label?: string, - sublabel?: string, - accelerator?: string, - icon?: electron$NativeImage, - enabled?: boolean, - visible?: boolean, - checked?: boolean, - submenu?: electron$MenuItem | electron$MenuItemOptions, - id?: string, - position?: string, -}; - -declare class electron$MenuItem { - constructor(options: electron$MenuItemOptions): void, - enabled: boolean, - visible: boolean, - checked: boolean, -} - -/** - * https://github.com/electron/electron/blob/master/docs/api/power-monitor.md - */ - -type electron$powerMonitor = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/power-save-blocker.md - */ - -type electron$powerSaveBlocker = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/protocol.md - */ - -type electron$protocol = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/session.md - */ - -type electron$session = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/system-preferences.md - */ - -type electron$systemPreferences = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/tray.md - */ - -declare class electron$Tray {} - -/** - * https://github.com/electron/electron/blob/master/docs/api/web-contents.md - */ - -type electron$InputEventModifiers = - Array<'shift' | 'control' | 'alt' | 'meta' | - 'isKeypad' | 'isAutoRepeat' | 'leftButtonDown' | 'middleButtonDown' | - 'rightButtonDown' | 'capsLock' | 'numLock' | 'left' | 'right'>; - -declare class electron$WebContents extends events$EventEmitter { - loadURL( - url: string, - options?: {httpReferrer?: string, userAgent?: string, extraHeaders?: string}, - ): void, - downloadURL(url: string): void, - getURL(): string, - getTitle(): string, - isDestroyed(): boolean, - isFocused(): boolean, - isLoading(): boolean, - isLoadingMainFrame(): boolean, - isWaitingForResponse(): boolean, - stop(): void, - reload(): void, - reloadIgnoringCache(): void, - canGoBack(): boolean, - canGoForward(): boolean, - canGoToOffset(offset: number): boolean, - clearHistory(): void, - goBack(): void, - goForward(): void, - goToIndex(index: number): void, - goToOffset(index: number): void, - isCrashed(): boolean, - setUserAgent(userAgent: string): void, - getUserAgent(): string, - insertCSS(css: string): void, - // Keep `result` as mixed (and not any) to make this unsafe function less so. - executeJavaScript(code: string, callback: (result: mixed) => void): void, - executeJavaScript(code: string, userGesture?: boolean, callback?: (result: mixed) => void): void, - setAudioMuted(muted: boolean): void, - isAudioMuted(): boolean, - setZoomFactor(factor: number): void, - getZoomFactor(callback: (factor: number) => void): void, - setZoomLevel(level: number): void, - getZoomLevel(callback: (level: number) => void): void, - setZoomLevelLimits(minimumLevel: number, maximumLevel: number): void, - setVisualZoomLevelLimits(minimumLevel: number, maximumLevel: number): void, - setLayoutZoomLevelLimits(minimumLevel: number, maximumLevel: number): void, - undo(): void, - redo(): void, - cut(): void, - copy(): void, - copyImageAt(x: number, y: number): void, - paste(): void, - pasteAndMatchStyle(): void, - delete(): void, - selectAll(): void, - unselect(): void, - replace(text: string): void, - replaceMisspelling(text: string): void, - insertText(text: string): void, - inserfindInPagetText( - text: string, - options?: { - forward?: boolean, - findNext?: boolean, - matchCase?: boolean, - wordStart?: boolean, - medialCapitalAsWordStart?: boolean, - }, - ): void, - stopFindInPage(action: 'clearSelection' | 'keepSelection' | 'activateSelection'): void, - capturePage(rect: electron$rect, callback: (image: electron$NativeImage) => void): void, - capturePage(callback: (image: electron$NativeImage) => void): void, - hasServiceWorker(callback: (result: boolean) => void): void, - unregisterServiceWorker(callback: (result: boolean) => void): void, - print(options?: {silent?: boolean, printBackground?: boolean}): void, - printToPDF(options: { - marginsType: number, - pageSize: string, - pageSize: string, - printBackground: boolean, - printSelectionOnly: boolean, - landscape: boolean, - }, callback: (err: ?mixed, data: ?Buffer) => void): void, - addWorkSpace(path: string): void, - removeWorkSpace(path: string): void, - openDevTools(options?: {mode: 'right' | 'bottom' | 'undocked' | 'detach'}): void, - closeDevTools(): void, - isDevToolsOpened(): boolean, - isDevToolsFocused(): boolean, - toggleDevTools(): void, - inspectElement(x: number, y: number): void, - inspectServiceWorker(): void, - send(channel: string, ...args: Array): void, - enableDeviceEmulation(parameters: { - screenPosition?: 'desktop' | 'mobile', - screenSize: {width: number, height: number}, - viewPosition?: {x: number, y: number}, - deviceScaleFactor?: number, - viewSize?: {width: number, height: number}, - fitToView?: boolean, - offset?: {x: number, y: number}, - scale?: number, - }): void, - disableDeviceEmulation(): void, - sendInputEvent( - event: - { - type: 'keyDown' | 'keyUp' | 'char', - modifiers?: electron$InputEventModifiers, - keyCode: string, - } | { - type: 'mouseDown' | 'mouseUp' | 'mouseEnter' | 'mouseLeave' | 'contextMenu', - modifiers?: electron$InputEventModifiers, - x: number, - y: number, - button: 'left' | 'middle' | 'right', - globalX: number, - globalY: number, - movementX: number, - movementY: number, - clickCount: number, - } | { - type: 'mouseWheel', - modifiers?: electron$InputEventModifiers, - x: number, - y: number, - button: 'left' | 'middle' | 'right', - globalX: number, - globalY: number, - movementX: number, - movementY: number, - clickCount: number, - deltaX: number, - deltaY: number, - wheelTicksX: number, - wheelTicksY: number, - accelerationRatioX: number, - accelerationRatioY: number, - hasPreciseScrollingDeltas: boolean, - canScroll: boolean, - }, - ): void, - beginFrameSubscription( - callback: (frameBuffer: Buffer, dirtyRect: electron$rect) => void, - ): void, - beginFrameSubscription( - onlyDirty?: boolean, - callback: (frameBuffer: Buffer, dirtyRect: electron$rect) => void, - ): void, - endFrameSubscription(): void, - startDrag(item: {file: string, icon: electron$NativeImage}): void, - savePage( - fullPath: string, - saveType: 'HTMLOnly' | 'HTMLComplete' | 'MHTML', - callback: (error: ?mixed) => void, - ): void, - showDefinitionForSelection(): void, - isOffscreen(): boolean, - startPainting(): void, - stopPainting(): void, - isPainting(): boolean, - setFrameRate(fps: number): void, - getFrameRate(): ?number, - - id: number, - session: electron$session, - hostWebContents: ?electron$WebContents, - devToolsWebContents: ?electron$WebContents, - debugger: ?electron$Debugger, -} - -declare class electron$Debugger extends events$EventEmitter { - attach(protocolVersion?: string): void, - isAttached(): boolean, - detach(): void, - sendCommand( - method: string, - callback?: (error: ?mixed, result: ?mixed) => void, - ): void, - sendCommand( - method: string, - commandParams?: Object, - callback?: (error: ?mixed, result: ?mixed) => void, - ): void, -} - -type electron$webContents = { - getAllWebContents(): Array, - getFocusedWebContents: ?electron$WebContents, - fromId(id: number): ?electron$WebContents, -}; - -//------------------------------------------------------------------------------ -// Modules for the Renderer Process (Web Page) -//------------------------------------------------------------------------------ - -/** - * https://github.com/electron/electron/blob/master/docs/api/desktop-capturer.md - */ - -type electron$desktopCapturer = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/ipc-renderer.md - */ - -declare class electron$IpcRenderer { - on(channel: string, callback: (...args: Array) => void): electron$IpcRenderer, - once(channel: string, callback: (...args: Array) => void): electron$IpcRenderer, - removeListener(channel: string, callback: (...args: Array) => void): electron$IpcRenderer, - removeAllListeners(channel?: string): electron$IpcRenderer, - send(channel: string, ...args: Array): void, - sendSync(channel: string, ...args: Array): void, - sendTo(windowId: number, channel: string, ...args: Array): void, - sendToHost(channel: string, ...args: Array): void, -} - -/** - * https://github.com/electron/electron/blob/master/docs/api/remote.md - */ - -type electron$remote = { - // main process built-in modules: - app: electron$app, - autoUpdater: electron$autoUpdater, - BrowserWindow: typeof electron$BrowserWindow, - contentTracing: electron$contentTracing, - dialog: electron$dialog, - globalShortcut: electron$globalShortcut, - ipcMain: electron$IpcMain, - Menu: typeof electron$Menu, - MenuItem: typeof electron$MenuItem, - powerMonitor: electron$powerMonitor, - powerSaveBlocker: electron$powerSaveBlocker, - protocol: electron$protocol, - session: electron$session, - electron$Tray: typeof electron$Tray, - webContents: electron$webContents, - // methods: - require(module: string): any, - getCurrentWindow(): electron$BrowserWindow, - getCurrentWebContents(): electron$WebContents, - getGlobal(name: string): ?mixed, - process: typeof process, -}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/web-frame.md - */ - -type electron$webFrame = { - registerURLSchemeAsBypassingCSP(scheme: string): void, -}; - - -//------------------------------------------------------------------------------ -// Modules for Both Processes -//------------------------------------------------------------------------------ - -/** - * https://github.com/electron/electron/blob/master/docs/api/clipboard.md - */ - -type electron$clipboard = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/crash-reporter.md - */ - -type electron$crashReporter = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/native-image.md - */ - -type electron$nativeImage = { - createEmpty(): electron$NativeImage, - createFromPath(path: string): electron$NativeImage, - createFromBuffer(buffer: Buffer, scaleFactor?: number): electron$NativeImage, - createFromDataURL(dataURL: string): electron$NativeImage, -}; - -declare class electron$NativeImage { - toPNG(): Uint8Array, - toJPEG(quality: number): Uint8Array, - toBitmap(): Uint8Array, - toDataURL(): string, - getNativeHandle(): Uint8Array, - isEmpty(): boolean, - getSize(): {width: number, height: number}, - setTemplateImage(option: boolean): void, - isTemplateImage(): boolean, -} - -/** - * https://github.com/electron/electron/blob/master/docs/api/screen.md - */ - -type electron$Display = { - id: number, - rotation: 0 | 90 | 180 | 270, - scaleFactor: number, - touchSupport: 'available' | 'unavailable' | 'unknown', - bounds: electron$rect, - size: {height: number, width: number}, - workArea: electron$rect, - workAreaSize: {height: number, width: number}, -}; - -type electron$DisplayEvents = - 'display-added' - | 'display-removed' - | 'display-metrics-changed'; - -type electron$ScreenListener = ( - event: electron$DisplayEvents, - callback: ( - event: Object, - display: electron$Display, - changedMetrics?: Array<'bounds' | 'workArea' | 'scaleFactor' | 'rotation'>, - ) => void, -) => electron$Screen; - -declare class electron$Screen { - on: electron$ScreenListener, - once: electron$ScreenListener, - removeAllListeners(event?: electron$DisplayEvents): electron$Screen, - removeListener(event?: electron$DisplayEvents, callback: Function): electron$Screen, - getCursorScreenPoint(): {x: number, y: number}, - getPrimaryDisplay(): electron$Display, - getAllDisplays(): Array, - getDisplayNearestPoint(point: {x: number, y: number}): electron$Display, - getDisplayMatching(rect: electron$rect): electron$Display, -} - -/** - * https://github.com/electron/electron/blob/master/docs/api/shell.md - */ - -type electron$shell = { - showItemInFolder(fullPath: string): void, - openItem(fullPath: string): void, - openExternal(url: string, options?: {activate: boolean}): void, - moveItemToTrash(fullPath: string): boolean, - beep(): void, - // Windows-only - writeShortcutLink( - shortcutPath: string, - operation?: 'create' | 'update' | 'replace', - options?: { - target: string, - cwd?: string, - args?: string, - description?: string, - icon?: string, - iconIndex?: number, - appUserModelId?: string, - } - ): void, - // Windows-only - readShortcutLink(shortcutPath: string): void, -}; diff --git a/flow-libs/event-kit.js.flow b/flow-libs/event-kit.js.flow deleted file mode 100644 index 67af4f8fd4..0000000000 --- a/flow-libs/event-kit.js.flow +++ /dev/null @@ -1,15 +0,0 @@ -/** - * 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 - */ - -declare module 'event-kit' { - declare var Emitter: typeof atom$Emitter; - declare var Disposable: typeof atom$Disposable; - declare var CompositeDisposable: typeof atom$CompositeDisposable; -} diff --git a/flow-libs/jasmine.js.flow b/flow-libs/jasmine.js.flow deleted file mode 100644 index 0904fa6770..0000000000 --- a/flow-libs/jasmine.js.flow +++ /dev/null @@ -1,102 +0,0 @@ -/** - * 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 - */ - -// Type declarations for Jasmine v1.3 -// https://jasmine.github.io/1.3/introduction.html - -// Disabling Specs and Suites -// https://jasmine.github.io/1.3/introduction.html#section-Disabling_Specs_and_Suites -declare function xdescribe(title: string, spec: () => mixed): void; -declare function xit(title: string, spec: () => mixed): void; - -// Spies -// https://jasmine.github.io/1.3/introduction.html#section-Spies -type JasmineSpyCall = { - args: Array, -}; - -type JasmineSpy = { - (...args: Array): any, - andCallFake(fake: (...args: Array) => mixed): JasmineSpy, - andCallThrough(): JasmineSpy, - argsForCall: Array>, - andReturn(value: T): JasmineSpy, - andThrow(error: mixed): JasmineSpy, - callCount: number, - calls: Array, - identity: string, - mostRecentCall: JasmineSpyCall, - wasCalled: boolean, - reset(): void, -}; - -declare function spyOn(object: Object, method: string): JasmineSpy; - -// Mocking the JavaScript Clock -// https://jasmine.github.io/1.3/introduction.html#section-Mocking_the_JavaScript_Clock -type JasmineMockClock = { - tick(milliseconds: number): void, - useMock(): void, -}; - -// Asynchronous Support -// https://jasmine.github.io/1.3/introduction.html#section-Asynchronous_Support -declare function runs(func: () => mixed): void; - -// Apparently the arguments for waitsFor() can be specified in any order. -type WaitsForArg = string | number | () => mixed; - -declare function waitsFor( - latchFunction?: WaitsForArg, failureMessage?: WaitsForArg, timeout?: WaitsForArg): void; - -declare function waits(milliseconds: number): void; - -type JasmineEnvironment = { - currentSpec: { - fail(message: string): void, - }, - defaultTimeoutInterval: number, - afterEach: afterEach, - beforeEach: beforeEach, - describe: any, - it: any, -}; - -type JasmineSpec = { - addMatchers(matchersPrototype: {[methodName: string]: (expected: any) => boolean}): void, -}; - -type JasmineMatchers = { - message: () => string, -}; - -// Jasmine global -declare var jasmine: { - // Default timeout. - DEFAULT_TIMEOUT_INTERVAL: number, - - Clock: JasmineMockClock, - Matchers: JasmineMatchers, - any(expected: string | Object): mixed, - - /** - * This is a non-standard method that Atom adds to Jasmine via spec-helper.coffee. - * Ideally, we would declare this in atom-jasmine.js, but we can't extend this global here. - */ - attachToDOM(element: Element): ?HTMLElement, - - createSpy: (name?: string) => JasmineSpy, - createSpyObj: (name: string, spyNames: Array) => {[key: string]: JasmineSpy}, - getEnv: () => JasmineEnvironment, - pp: (value: mixed) => string, - unspy: (obj: Object, methodName: string) => void, - useMockClock: () => void, - useRealClock: () => void, -}; diff --git a/flow-libs/jest.js.flow b/flow-libs/jest.js.flow deleted file mode 100644 index 8fcb53bd43..0000000000 --- a/flow-libs/jest.js.flow +++ /dev/null @@ -1,652 +0,0 @@ -// Fork of the flow-typed definitions for Jest. -// Modified to make sure types are compatible with existing Jasmine -// (TODO:T28636463) unify types and use original flow-typed definitions -// List of modifications: -// - modified some matchers to accept optional message arg (_?: any) -// - removed `declare jasmine` -type JestMockFn, TReturn> = { - (...args: TArguments): TReturn, - /** - * An object for introspecting mock calls - */ - mock: { - /** - * An array that represents all calls that have been made into this mock - * function. Each call is represented by an array of arguments that were - * passed during the call. - */ - calls: Array, - /** - * An array that contains all the object instances that have been - * instantiated from this mock function. - */ - instances: Array - }, - /** - * Resets all information stored in the mockFn.mock.calls and - * mockFn.mock.instances arrays. Often this is useful when you want to clean - * up a mock's usage data between two assertions. - */ - mockClear(): void, - /** - * Resets all information stored in the mock. This is useful when you want to - * completely restore a mock back to its initial state. - */ - mockReset(): void, - /** - * Removes the mock and restores the initial implementation. This is useful - * when you want to mock functions in certain test cases and restore the - * original implementation in others. Beware that mockFn.mockRestore only - * works when mock was created with jest.spyOn. Thus you have to take care of - * restoration yourself when manually assigning jest.fn(). - */ - mockRestore(): void, - /** - * Accepts a function that should be used as the implementation of the mock. - * The mock itself will still record all calls that go into and instances - * that come from itself -- the only difference is that the implementation - * will also be executed when the mock is called. - */ - mockImplementation( - fn: (...args: TArguments) => TReturn - ): JestMockFn, - /** - * Accepts a function that will be used as an implementation of the mock for - * one call to the mocked function. Can be chained so that multiple function - * calls produce different results. - */ - mockImplementationOnce( - fn: (...args: TArguments) => TReturn - ): JestMockFn, - /** - * Accepts a string to use in test result output in place of "jest.fn()" to - * indicate which mock function is being referenced. - */ - mockName(name: string): JestMockFn, - /** - * Just a simple sugar function for returning `this` - */ - mockReturnThis(): void, - /** - * Deprecated: use jest.fn(() => value) instead - */ - mockReturnValue(value: TReturn): JestMockFn, - /** - * Sugar for only returning a value once inside your mock - */ - mockReturnValueOnce(value: TReturn): JestMockFn -}; - -type JestAsymmetricEqualityType = { - /** - * A custom Jasmine equality tester - */ - asymmetricMatch(value: mixed): boolean -}; - -type JestCallsType = { - allArgs(): mixed, - all(): mixed, - any(): boolean, - count(): number, - first(): mixed, - mostRecent(): mixed, - reset(): void -}; - -type JestClockType = { - install(): void, - mockDate(date: Date): void, - tick(milliseconds?: number): void, - uninstall(): void -}; - -type JestMatcherResult = { - message?: string | (() => string), - pass: boolean -}; - -type JestMatcher = (actual: any, expected: any) => JestMatcherResult; - -type JestPromiseType = { - /** - * Use rejects to unwrap the reason of a rejected promise so any other - * matcher can be chained. If the promise is fulfilled the assertion fails. - */ - rejects: JestExpectType, - /** - * Use resolves to unwrap the value of a fulfilled promise so any other - * matcher can be chained. If the promise is rejected the assertion fails. - */ - resolves: JestExpectType -}; - -/** - * Jest allows functions and classes to be used as test names in test() and - * describe() - */ -type JestTestName = string | Function; - -/** - * Plugin: jest-enzyme - */ -type EnzymeMatchersType = { - toBeChecked(): void, - toBeDisabled(): void, - toBeEmpty(): void, - toBeEmptyRender(): void, - toBePresent(): void, - toContainReact(element: React$Element): void, - toExist(): void, - toHaveClassName(className: string): void, - toHaveHTML(html: string): void, - toHaveProp: ((propKey: string, propValue?: any) => void) & ((props: Object) => void), - toHaveRef(refName: string): void, - toHaveState: ((stateKey: string, stateValue?: any) => void) & ((state: Object) => void), - toHaveStyle: ((styleKey: string, styleValue?: any) => void) & ((style: Object) => void), - toHaveTagName(tagName: string): void, - toHaveText(text: string): void, - toIncludeText(text: string): void, - toHaveValue(value: any): void, - toMatchElement(element: React$Element): void, - toMatchSelector(selector: string): void -}; - -// DOM testing library extensions https://github.com/kentcdodds/dom-testing-library#custom-jest-matchers -type DomTestingLibraryType = { - toBeInTheDOM(): void, - toHaveTextContent(content: string): void, - toHaveAttribute(name: string, expectedValue?: string): void -}; - -type JestExpectType = { - not: JestExpectType & EnzymeMatchersType & DomTestingLibraryType, - - not: JestExpectType & EnzymeMatchersType, - diffJson: Function, - toEqualAtomRange: Function, - toEqualAtomRanges: Function, - diffLines: Function, - - /** - * If you have a mock function, you can use .lastCalledWith to test what - * arguments it was last called with. - */ - lastCalledWith(...args: Array): void, - /** - * toBe just checks that a value is what you expect. It uses === to check - * strict equality. - */ - toBe(value: any, _?: any): void, - /** - * Use .toHaveBeenCalled to ensure that a mock function got called. - */ - toBeCalled(): void, - /** - * Use .toBeCalledWith to ensure that a mock function was called with - * specific arguments. - */ - toBeCalledWith(...args: Array): void, - /** - * Using exact equality with floating point numbers is a bad idea. Rounding - * means that intuitive things fail. - */ - toBeCloseTo(num: number, delta: any): void, - /** - * Use .toBeDefined to check that a variable is not undefined. - */ - toBeDefined(_?: any): void, - /** - * Use .toBeFalsy when you don't care what a value is, you just want to - * ensure a value is false in a boolean context. - */ - toBeFalsy(_?: any): void, - /** - * To compare floating point numbers, you can use toBeGreaterThan. - */ - toBeGreaterThan(number: number): void, - /** - * To compare floating point numbers, you can use toBeGreaterThanOrEqual. - */ - toBeGreaterThanOrEqual(number: number): void, - /** - * To compare floating point numbers, you can use toBeLessThan. - */ - toBeLessThan(number: number): void, - /** - * To compare floating point numbers, you can use toBeLessThanOrEqual. - */ - toBeLessThanOrEqual(number: number): void, - /** - * Use .toBeInstanceOf(Class) to check that an object is an instance of a - * class. - */ - toBeInstanceOf(cls: Class<*>): void, - /** - * .toBeNull() is the same as .toBe(null) but the error messages are a bit - * nicer. - */ - toBeNull(_?: any): void, - /** - * Use .toBeTruthy when you don't care what a value is, you just want to - * ensure a value is true in a boolean context. - */ - toBeTruthy(_?: any): void, - /** - * Use .toBeUndefined to check that a variable is undefined. - */ - toBeUndefined(): void, - /** - * Use .toContain when you want to check that an item is in a list. For - * testing the items in the list, this uses ===, a strict equality check. - */ - toContain(item: any): void, - /** - * Use .toContainEqual when you want to check that an item is in a list. For - * testing the items in the list, this matcher recursively checks the - * equality of all fields, rather than checking for object identity. - */ - toContainEqual(item: any): void, - /** - * Use .toEqual when you want to check that two objects have the same value. - * This matcher recursively checks the equality of all fields, rather than - * checking for object identity. - */ - toEqual(value: any, _?: any): void, - /** - * Use .toHaveBeenCalled to ensure that a mock function got called. - */ - toHaveBeenCalled(): void, - /** - * Use .toHaveBeenCalledTimes to ensure that a mock function got called exact - * number of times. - */ - toHaveBeenCalledTimes(number: number): void, - /** - * Use .toHaveBeenCalledWith to ensure that a mock function was called with - * specific arguments. - */ - toHaveBeenCalledWith(...args: Array): void, - /** - * Use .toHaveBeenLastCalledWith to ensure that a mock function was last called - * with specific arguments. - */ - toHaveBeenLastCalledWith(...args: Array): void, - /** - * Check that an object has a .length property and it is set to a certain - * numeric value. - */ - toHaveLength(number: number): void, - /** - * - */ - toHaveProperty(propPath: string, value?: any): void, - /** - * Use .toMatch to check that a string matches a regular expression or string. - */ - toMatch(regexpOrString: RegExp | string): void, - /** - * Use .toMatchObject to check that a javascript object matches a subset of the properties of an object. - */ - toMatchObject(object: Object | Array): void, - /** - * This ensures that a React component matches the most recent snapshot. - */ - toMatchSnapshot(name?: string): void, - /** - * Use .toThrow to test that a function throws when it is called. - * If you want to test that a specific error gets thrown, you can provide an - * argument to toThrow. The argument can be a string for the error message, - * a class for the error, or a regex that should match the error. - * - * Alias: .toThrowError - */ - toThrow(message?: string | Error | Class | RegExp): void, - toThrowError(message?: string | Error | Class | RegExp): void, - /** - * Use .toThrowErrorMatchingSnapshot to test that a function throws a error - * matching the most recent snapshot when it is called. - */ - toThrowErrorMatchingSnapshot(): void -}; - -type JestObjectType = { - /** - * Disables automatic mocking in the module loader. - * - * After this method is called, all `require()`s will return the real - * versions of each module (rather than a mocked version). - */ - disableAutomock(): JestObjectType, - /** - * An un-hoisted version of disableAutomock - */ - autoMockOff(): JestObjectType, - /** - * Enables automatic mocking in the module loader. - */ - enableAutomock(): JestObjectType, - /** - * An un-hoisted version of enableAutomock - */ - autoMockOn(): JestObjectType, - /** - * Clears the mock.calls and mock.instances properties of all mocks. - * Equivalent to calling .mockClear() on every mocked function. - */ - clearAllMocks(): JestObjectType, - /** - * Resets the state of all mocks. Equivalent to calling .mockReset() on every - * mocked function. - */ - resetAllMocks(): JestObjectType, - /** - * Restores all mocks back to their original value. - */ - restoreAllMocks(): JestObjectType, - /** - * Removes any pending timers from the timer system. - */ - clearAllTimers(): void, - /** - * The same as `mock` but not moved to the top of the expectation by - * babel-jest. - */ - doMock(moduleName: string, moduleFactory?: any): JestObjectType, - /** - * The same as `unmock` but not moved to the top of the expectation by - * babel-jest. - */ - dontMock(moduleName: string): JestObjectType, - /** - * Returns a new, unused mock function. Optionally takes a mock - * implementation. - */ - fn, TReturn>( - implementation?: (...args: TArguments) => TReturn - ): JestMockFn, - /** - * Determines if the given function is a mocked function. - */ - isMockFunction(fn: Function): boolean, - /** - * Given the name of a module, use the automatic mocking system to generate a - * mocked version of the module for you. - */ - genMockFromModule(moduleName: string): any, - /** - * Mocks a module with an auto-mocked version when it is being required. - * - * The second argument can be used to specify an explicit module factory that - * is being run instead of using Jest's automocking feature. - * - * The third argument can be used to create virtual mocks -- mocks of modules - * that don't exist anywhere in the system. - */ - mock( - moduleName: string, - moduleFactory?: any, - options?: Object - ): JestObjectType, - /** - * Returns the actual module instead of a mock, bypassing all checks on - * whether the module should receive a mock implementation or not. - */ - requireActual(moduleName: string): any, - /** - * Returns a mock module instead of the actual module, bypassing all checks - * on whether the module should be required normally or not. - */ - requireMock(moduleName: string): any, - /** - * Resets the module registry - the cache of all required modules. This is - * useful to isolate modules where local state might conflict between tests. - */ - resetModules(): JestObjectType, - /** - * Exhausts the micro-task queue (usually interfaced in node via - * process.nextTick). - */ - runAllTicks(): void, - /** - * Exhausts the macro-task queue (i.e., all tasks queued by setTimeout(), - * setInterval(), and setImmediate()). - */ - runAllTimers(): void, - /** - * Exhausts all tasks queued by setImmediate(). - */ - runAllImmediates(): void, - /** - * Executes only the macro task queue (i.e. all tasks queued by setTimeout() - * or setInterval() and setImmediate()). - */ - advanceTimersByTime(msToRun: number): void, - /** - * Executes only the macro task queue (i.e. all tasks queued by setTimeout() - * or setInterval() and setImmediate()). - * - * Renamed to `advanceTimersByTime`. - */ - runTimersToTime(msToRun: number): void, - /** - * Executes only the macro-tasks that are currently pending (i.e., only the - * tasks that have been queued by setTimeout() or setInterval() up to this - * point) - */ - runOnlyPendingTimers(): void, - /** - * Explicitly supplies the mock object that the module system should return - * for the specified module. Note: It is recommended to use jest.mock() - * instead. - */ - setMock(moduleName: string, moduleExports: any): JestObjectType, - /** - * Indicates that the module system should never return a mocked version of - * the specified module from require() (e.g. that it should always return the - * real module). - */ - unmock(moduleName: string): JestObjectType, - /** - * Instructs Jest to use fake versions of the standard timer functions - * (setTimeout, setInterval, clearTimeout, clearInterval, nextTick, - * setImmediate and clearImmediate). - */ - useFakeTimers(): JestObjectType, - /** - * Instructs Jest to use the real versions of the standard timer functions. - */ - useRealTimers(): JestObjectType, - /** - * Creates a mock function similar to jest.fn but also tracks calls to - * object[methodName]. - */ - spyOn(object: Object, methodName: string): JestMockFn, - /** - * Set the default timeout interval for tests and before/after hooks in milliseconds. - * Note: The default timeout interval is 5 seconds if this method is not called. - */ - setTimeout(timeout: number): JestObjectType -}; - -type JestSpyType = { - calls: JestCallsType -}; - -/** Runs this function after every test inside this context */ -declare function afterEach( - fn: (done: () => void) => ?Promise, - timeout?: number -): void; -/** Runs this function before every test inside this context */ -declare function beforeEach( - fn: (done: () => void) => ?Promise, - timeout?: number -): void; -/** Runs this function after all tests have finished inside this context */ -declare function afterAll( - fn: (done: () => void) => ?Promise, - timeout?: number -): void; -/** Runs this function before any tests have started inside this context */ -declare function beforeAll( - fn: (done: () => void) => ?Promise, - timeout?: number -): void; - -/** A context for grouping tests together */ -declare var describe: { - /** - * Creates a block that groups together several related tests in one "test suite" - */ - (name: JestTestName, fn: () => void): void, - - /** - * Only run this describe block - */ - only(name: JestTestName, fn: () => void): void, - - /** - * Skip running this describe block - */ - skip(name: JestTestName, fn: () => void): void -}; - -/** An individual test unit */ -declare var it: { - /** - * An individual test unit - * - * @param {JestTestName} Name of Test - * @param {Function} Test - * @param {number} Timeout for the test, in milliseconds. - */ - ( - name: JestTestName, - fn?: (done: () => void) => ?Promise, - timeout?: number - ): void, - /** - * Only run this test - * - * @param {JestTestName} Name of Test - * @param {Function} Test - * @param {number} Timeout for the test, in milliseconds. - */ - only( - name: JestTestName, - fn?: (done: () => void) => ?Promise, - timeout?: number - ): void, - /** - * Skip running this test - * - * @param {JestTestName} Name of Test - * @param {Function} Test - * @param {number} Timeout for the test, in milliseconds. - */ - skip( - name: JestTestName, - fn?: (done: () => void) => ?Promise, - timeout?: number - ): void, - /** - * Run the test concurrently - * - * @param {JestTestName} Name of Test - * @param {Function} Test - * @param {number} Timeout for the test, in milliseconds. - */ - concurrent( - name: JestTestName, - fn?: (done: () => void) => ?Promise, - timeout?: number - ): void -}; -declare function fit( - name: JestTestName, - fn: (done: () => void) => ?Promise, - timeout?: number -): void; -/** An individual test unit */ -declare var test: typeof it; -/** A disabled group of tests */ -declare var xdescribe: typeof describe; -/** A focused group of tests */ -declare var fdescribe: typeof describe; -/** A disabled individual test */ -declare var xit: typeof it; -/** A disabled individual test */ -declare var xtest: typeof it; - -type JestPrettyFormatColors = { - comment: { close: string, open: string }, - content: { close: string, open: string }, - prop: { close: string, open: string }, - tag: { close: string, open: string }, - value: { close: string, open: string }, -}; - -type JestPrettyFormatIndent = string => string; -type JestPrettyFormatRefs = Array; -type JestPrettyFormatPrint = any => string; -type JestPrettyFormatStringOrNull = string | null; - -type JestPrettyFormatOptions = {| - callToJSON: boolean, - edgeSpacing: string, - escapeRegex: boolean, - highlight: boolean, - indent: number, - maxDepth: number, - min: boolean, - plugins: JestPrettyFormatPlugins, - printFunctionName: boolean, - spacing: string, - theme: {| - comment: string, - content: string, - prop: string, - tag: string, - value: string, - |}, -|}; - -type JestPrettyFormatPlugin = { - print: ( - val: any, - serialize: JestPrettyFormatPrint, - indent: JestPrettyFormatIndent, - opts: JestPrettyFormatOptions, - colors: JestPrettyFormatColors, - ) => string, - test: any => boolean, -}; - -type JestPrettyFormatPlugins = Array; - -/** The expect function is used every time you want to test a value */ -declare var expect: { - /** The object that you want to make assertions against */ - (value: any): JestExpectType & JestPromiseType & EnzymeMatchersType & DomTestingLibraryType, - /** Add additional Jasmine matchers to Jest's roster */ - extend(matchers: { [name: string]: JestMatcher }): void, - /** Add a module that formats application-specific data structures. */ - addSnapshotSerializer(pluginModule: JestPrettyFormatPlugin): void, - assertions(expectedAssertions: number): void, - hasAssertions(): void, - any(value: mixed): JestAsymmetricEqualityType, - anything(): any, - arrayContaining(value: Array): Array, - objectContaining(value: Object): Object, - /** Matches any received string that contains the exact expected string. */ - stringContaining(value: string): string, - stringMatching(value: string | RegExp): string -}; - -// TODO handle return type -// http://jasmine.github.io/2.4/introduction.html#section-Spies -// declare function spyOn(value: mixed, method: string): Object; - -/** Holds all functions related to manipulating test runner */ -declare var jest: JestObjectType; diff --git a/flow-libs/need-to-upstream-to-flow-lib.js.flow b/flow-libs/need-to-upstream-to-flow-lib.js.flow deleted file mode 100644 index db1b92f809..0000000000 --- a/flow-libs/need-to-upstream-to-flow-lib.js.flow +++ /dev/null @@ -1,138 +0,0 @@ -/** - * 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 - */ - -/* - * APIs listed in this file are ones that should be built into Flow and need to be upstreamed. - */ - -type IDisposable = { - dispose(): mixed, -}; - -/* - * These Notification & NotificationOptions definitions are not exhaustive while standardization, - * browser, and Electron support remain incomplete. - */ -type NotificationOptions = { - body?: string, - icon?: string, -}; - -declare class Notification { - constructor( - message: string, - options?: NotificationOptions, - ): void, - onclick: () => void, -} - -// T9254051 - Fix flow http/https definitions. -declare class http$fixed$Server extends events$EventEmitter { - listen(port: number, hostname?: string, backlog?: number, callback?: Function): http$fixed$Server, - listen(path: string, callback?: Function): http$fixed$Server, - listen(handle: Object, callback?: Function): http$fixed$Server, - close(callback?: Function): http$fixed$Server, - address(): {port: number, fmaily: string, address: string}, - maxHeadersCount: number, -} - -declare class http$fixed$IncomingMessage extends stream$Readable { - headers: Object, - httpVersion: string, - method: string, - trailers: Object, - setTimeout(msecs: number, callback: Function): void, - socket: any, // TODO net.Socket - statusCode: number, - url: string, - connection: { destroy: () => void }, -} - -declare class http$fixed$ClientRequest extends stream$Writable { -} - -declare class http$fixed$ServerResponse { - setHeader(name: string, value: string): void, - statusCode: number, - write(value: string): void, - end(): void, -} - -declare class https$fixed { - Server: typeof http$fixed$Server, - createServer( - options: Object, - requestListener?: ( - request: http$fixed$IncomingMessage, - response: http$fixed$ServerResponse, - ) => void, - ): http$fixed$Server, - request( - options: Object | string, - callback: (response: http$fixed$IncomingMessage) => void - ): http$fixed$ClientRequest, - get( - options: Object | string, - callback: (response: http$fixed$IncomingMessage) => void - ): http$fixed$ClientRequest, -} - -declare class http$fixed { - Server: typeof http$fixed$Server, - createServer( - requestListener?: ( - request: http$fixed$IncomingMessage, - response: http$fixed$ServerResponse, - ) => void - ): http$fixed$Server, - request( - options: Object | string, - callback: (response: http$fixed$IncomingMessage) => void - ): http$fixed$ClientRequest, - get( - options: Object | string, - callback: (response: http$fixed$IncomingMessage) => void - ): http$fixed$ClientRequest, -} - -declare class module$Module { - constructor( - id?: string, - parent?: string | module$Module - ): void, - id: ?string, - exports: any, - parent?: string | module$Module, - filename?: string, - loaded: boolean, - children: Array, - paths: Array, - _compile: (content: string, filename: string) => void, - - static _resolveFilename(filename: string, module: any): string, -} - -declare module 'module' { - declare module.exports: typeof module$Module; -} - -declare module 'console' { - declare module.exports: any; -} - -declare interface net$ListenOptions { - port?: number, - host?: string, - backlog?: number, - path?: string, - exclusive?: boolean, -} - -declare export var module: module$Module; diff --git a/flow-libs/need-to-upstream-to-pty.js.flow b/flow-libs/need-to-upstream-to-pty.js.flow deleted file mode 100644 index 8d4895cbb5..0000000000 --- a/flow-libs/need-to-upstream-to-pty.js.flow +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (c) 2017-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 - */ - -/* - * APIs listed in this file are ones that should be built into nuclide-prebuilt-libs/pty and need to be upstreamed. - */ - -declare module 'nuclide-prebuilt-libs/pty' { - declare export type ProcessEnv = { - +[key: string]: string; - }; - - declare export type IPtyForkOptions = { - name?: string; - cols?: number; - rows?: number; - cwd?: string; - env?: ProcessEnv; - uid?: number; - gid?: number; - }; - - declare export type IPtyOpenOptions = { - cols?: number; - rows?: number; - }; -} diff --git a/flow-libs/nuclide.flow.js b/flow-libs/nuclide.flow.js deleted file mode 100644 index 3d5be7f431..0000000000 --- a/flow-libs/nuclide.flow.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * 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 strict - * @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; -} diff --git a/flow-libs/relay.js.flow b/flow-libs/relay.js.flow deleted file mode 100644 index 1c1d7a19cf..0000000000 --- a/flow-libs/relay.js.flow +++ /dev/null @@ -1,46 +0,0 @@ -/** - * 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 - */ - - type Variables = {[name: string]: any}; - type RefetchOptions = { - force?: boolean, // Refetch from the server ignoring anything in the cache. - }; - - type RelayPaginationProp = { - /** - * Check if there is at least one more page. - */ - hasMore: () => boolean, - - /** - * Check if there are pending requests. - */ - isLoading: () => boolean, - - /** - * Execute the pagination query. Relay will infer the pagination direction (either 'forward' - * or 'backward') from the query parameters. `pageSize` is the additional number of items - * to load. - */ - loadMore: ( - pageSize: number, - callback: ?(error: ?Error) => void, - options: ?RefetchOptions - ) => ?IDisposable, - - /** - * Refetch the items in the connection (with potentially new variables). - */ - refetchConnection:( - totalCount: number, - callback: (error: ?Error) => void, - refetchVariables: ?Variables, - ) => ?IDisposable, - } diff --git a/flow-libs/simple-text-buffer.js.flow b/flow-libs/simple-text-buffer.js.flow deleted file mode 100644 index 7cc09d460b..0000000000 --- a/flow-libs/simple-text-buffer.js.flow +++ /dev/null @@ -1,105 +0,0 @@ -/** - * 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 - */ - -declare class simpleTextBuffer$TextBuffer { - constructor(contents: string): void, - - // Mixin - static deserialize: (state: Object, params: Object) => mixed, - - // Events - onWillChange(callback: (event: atom$TextEditEvent) => mixed): IDisposable, - onDidChange(callback: (event: atom$TextEditEvent) => mixed): IDisposable, - onDidStopChanging(callback: () => mixed): IDisposable, - onDidChangeModified(callback: () => mixed): IDisposable, - onDidChangeEncoding(callback: () => mixed): IDisposable, - onDidDestroy(callback: () => mixed): IDisposable, - - // File Details - setEncoding(encoding: string): void, - getEncoding(): string, - getId(): string, - - // Reading Text - isEmpty(): boolean, - getText(): string, - getTextInRange(range: atom$RangeLike): string, - getLineCount(): number, - getLines(): Array, - getLastLine(): string, - lineForRow(row: number): string, - lineEndingForRow(row: number): string, - lineLengthForRow(row: number): number, - isRowBlank(row: number): boolean, - previousNonBlankRow(startRow: number): ?number, - nextNonBlankRow(startRow: number): ?number, - - // Mutating Text - setText(text: string): atom$Range, - setTextInRange( - range: atom$RangeLike, text: string, options?: Object): atom$Range, - setTextViaDiff(text: string): void, - insert( - position: atom$Point, - text: string, - options?: { - normalizeLineEndings?: boolean, - undo?: string, - }, - ): atom$Range, - append(text: string, options: ?{ - normalizeLineEndings?: boolean, - undo?: string, - }): atom$Range, - delete(range: atom$Range): atom$Range, - deleteRows(startRow: number, endRow: number): atom$Range, - - // History - undo(): void, - redo(): void, - transact(fn: () => mixed, _: void): void, - transact(groupingInterval: number, fn: () => mixed): void, - clearUndoStack(): void, - createCheckpoint(): atom$TextBufferCheckpoint, - revertToCheckpoint(checkpoint: atom$TextBufferCheckpoint): boolean, - groupChangesSinceCheckpoint(checkpoint: atom$TextBufferCheckpoint): boolean, - // TODO describe the return type more precisely. - getChangesSinceCheckpoint(checkpoint: atom$TextBufferCheckpoint): Array, - - // Search And Replace - scanInRange(regex: RegExp, range: atom$Range, iterator: TextBufferScanIterator): void, - backwardsScanInRange( - regex: RegExp, range: atom$Range, iterator: TextBufferScanIterator): void, - - // Buffer Range Details - getLastRow(): number, - getRange(): atom$Range, - rangeForRow(row: number, includeNewLine?: boolean): atom$Range, - - // Position/Index mapping - characterIndexForPosition(position: atom$PointLike): number, - positionForCharacterIndex(index: number): atom$Point, - - // Private APIs - emitter: atom$Emitter, - refcount: number, - changeCount: number, - destroy(): void, - isDestroyed(): boolean, - - static Point: typeof atom$Point, - static Range: typeof atom$Range, -} - -declare module 'simple-text-buffer' { - declare export var Point: typeof atom$Point; - declare export var Range: typeof atom$Range; - declare export default typeof simpleTextBuffer$TextBuffer; -} diff --git a/flow-libs/ssh2-streams.js.flow b/flow-libs/ssh2-streams.js.flow deleted file mode 100644 index 94f878661e..0000000000 --- a/flow-libs/ssh2-streams.js.flow +++ /dev/null @@ -1,2154 +0,0 @@ -/** - * Copyright (c) 2017-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 - */ - -// Type definitions for ssh2-streams v0.1.9 -// Project: https://github.com/mscdex/ssh2-streams -// TypeScript Definitions by: Ron Buckton - -declare module 'ssh2-streams' { - declare type ParsedKey = { - fulltype: string; - type: string; - extra: string; - comment: string; - encryption: string; - private: Buffer; - privateOrig: Buffer; - public: Buffer; - publicOrig: Buffer; - ppk?: boolean; - privateMAC?: string; - } - - declare class SSH2Stream extends stream$Transform { - /** - * The number of bytes sent since the last keying. This metric can be useful in determining when to call rekey(). - */ - bytesSent: number; - - /** - * The number of bytes received since the last keying. This metric can be useful in determining when to call rekey(). - */ - bytesReceived: number; - - /** - * Creates and returns a new SSH2Stream instance. - */ - constructor(config?: SSH2StreamConfig): void; - - /** - * (Client/Server) - * Writes a dummy GLOBAL_REQUEST packet (specifically "keepalive@openssh.com") that requests a reply. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - ping(): boolean; - - /** - * (Client/Server) - * Writes a disconnect packet and closes the stream. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - disconnect(reasonCode?: number): boolean; - - /** - * (Client/Server) - * Starts the re-keying process. Incoming/Outgoing packets are buffered until the re-keying - * process has finished. Returns `false` to indicate that no more packets should be written - * until the `NEWKEYS` event is seen. - */ - rekey(): boolean; - - /** - * (Client/Server) - * Writes a request success packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - requestSuccess(data?: Buffer): boolean; - - /** - * (Client/Server) - * Writes a request failure packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - requestFailure(): boolean; - - /** - * (Client/Server) - * Writes a channel success packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - channelSuccess(channel: number): boolean; - - /** - * (Client/Server) - * Writes a channel failure packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - channelFailure(channel: number): boolean; - - /** - * (Client/Server) - * Writes a channel EOF packet for the given `channel`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - channelEOF(channel: number): boolean; - - /** - * (Client/Server) - * Writes a channel close packet for the given `channel`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - channelClose(channel: number): boolean; - - /** - * (Client/Server) - * Writes a channel window adjust packet for the given `channel` where `amount` is the - * number of bytes to add to the channel window. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - channelWindowAdjust(channel: number, amount: number): boolean; - - /** - * (Client/Server) - * Writes a channel data packet for the given `channel` where `data` is a _Buffer_ or _string_. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - channelData(channel: number, data: string | Buffer): boolean; - - /** - * (Client/Server) - * Writes a channel extended data packet for the given `channel` where `data is a _Buffer_ - * or _string_. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - channelExtData(channel: number, data: string | Buffer, type: number): boolean; - - /** - * (Client/Server) - * Writes a channel open confirmation packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - channelOpenConfirm( - remoteChannel: number, - localChannel: number, - initWindow: number, - maxPacket: number - ): boolean; - - /** - * (Client/Server) - * Writes a channel open failure packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - channelOpenFail( - remoteChannel: number, - reasonCode: number, - description?: string, - lang?: string - ): boolean; - - /** - * (Client-only) - * Writes a service request packet for `serviceName`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - service(serviceName: string): boolean; - - /** - * (Client-only) - * Writes a tcpip forward global request packet. `wantReply` defaults to `true`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - tcpipForward( - bindAddr: string, - bindPort: number, - wantReply?: boolean - ): boolean; - - /** - * (Client-only) - * Writes a cancel tcpip forward global request packet. `wantReply` defaults to `true`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - cancelTcpipForward( - bindAddr: string, - bindPort: number, - wantReply?: boolean - ): boolean; - - /** - * (Client-only) - * Writes a password userauth request packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - authPassword(username: string, password: string): boolean; - - /** - * (Client-only) - * Writes a publickey userauth request packet. `pubKey` is the object returned from using - * `utils.parseKey()` on a private or public key. If `cbSign` is not present, a pubkey - * check userauth packet is written. Otherwise `cbSign` is called with `(blob, callback)`, - * where `blob` is the data to sign with the private key and the resulting signature - * _Buffer_ is passed to `callback` as the first argument. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - authPK( - username: string, - pubKey: ParsedKey, - cbSign?: ( - blob: Buffer, - callback: (signedBlob: Buffer) => mixed - ) => mixed - ): boolean; - - /** - * (Client-only) - * Writes a hostbased userauth request packet. `pubKey` is the object returned from using - * `utils.parseKey()` on a private or public key. `cbSign` is called with `(blob, callback)`, - * where `blob` is the data to sign with the private key and the resulting signature - * _Buffer_ is passed to `callback` as the first argument. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - authHostBased( - username: string, - pubKey: ParsedKey, - localHostname: string, - localUsername: string, - cbSign?: ( - blob: Buffer, - callback: (signedBlob: Buffer) => mixed - ) => mixed - ): boolean; - - /** - * (Client-only) - * Writes a keyboard-interactive userauth request packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - authKeyboard(username: string): boolean; - - /** - * (Client-only) - * Writes a "none" userauth request packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - authNone(username: string): boolean; - - /** - * (Client-only) - * Writes a userauth info response packet. `responses` is an _array_ of zero or more strings - * corresponding to responses to prompts previously sent by the server. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - authInfoRes(responses?: string[]): boolean; - - /** - * (Client-only) - * Writes a direct tcpip channel open packet. `config` must contain `srcIP`, `srcPort`, - * `dstIP`, and `dstPort`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - directTcpip( - channel: number, - initWindow: number, - maxPacket: number, - config: TcpipForwardingConfig - ): boolean; - - /** - * (Client-only) - * Writes a session channel open packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - session(channel: number, initWindow: number, maxPacket: number): boolean; - - /** - * (Client-only) - * Writes an `auth-agent-req@openssh.com` channel request packet. `wantReply` defaults to - * `true`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - openssh_agentForward(channel: number, wantReply?: boolean): boolean; - - /** - * (Client-only) - * Writes a window change channel request packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - windowChange( - channel: number, - rows: number, - cols: number, - height: number, - width: number - ): boolean; - - /** - * (Client-only) - * Writes a pty channel request packet. If `terminalType` is falsey, `vt100` is used. - * `terminalModes` can be the raw bytes, an _object_ of the terminal modes to set, or a falsey value for no modes. `wantReply` defaults to `true`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - pty( - channel: number, - rows: number, - cols: number, - height: number, - width: number, - terminalType?: string, - terminalModes?: any, - wantReply?: boolean - ): boolean; - - /** - * (Client-only) - * Writes an env channel request packet. `value` can be a _string_ or _Buffer_. `wantReply` - * defaults to `true`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - env( - channel: number, - key: string, - value: string | Buffer, - wantReply?: boolean - ): boolean; - - /** - * (Client-only) - * Writes a shell channel request packet. `wantReply` defaults to `true`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - shell(channel: number, wantReply?: boolean): boolean; - - /** - * (Client-only) - * Writes an exec channel request packet. `wantReply` defaults to `true`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - exec(channel: number, command: string, wantReply?: boolean): boolean; - - /** - * (Client-only) - * Writes a signal channel request packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - signal(channel: number, signalName: string): boolean; - - /** - * (Client-only) - * Writes an X11 forward channel request packet. `wantReply` defaults to `true`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - x11Forward( - channel: number, - config: X11ForwardingConfig, - wantReply?: boolean - ): boolean; - - /** - * (Client-only) - * Writes a subsystem channel request packet. `name` is the name of the subsystem (e.g. - * `sftp` or `netconf`). `wantReply` defaults to `true`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - subsystem(channel: number, name: string, wantReply?: boolean): boolean; - - /** - * (Client-only) - * Writes a no-more-sessions@openssh.com request packet. `wantReply` defaults to `true`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - openssh_noMoreSessions(wantReply?: boolean): boolean; - - /** - * (Client-only) - * Writes a streamlocal-forward@openssh.com request packet. `wantReply` defaults to `true`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - openssh_streamLocalForward(socketPath: string, wantReply?: boolean): boolean; - - /** - * (Client-only) - * Writes a cancel-streamlocal-forward@openssh.com request packet. `wantReply` defaults to - * `true`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - openssh_cancelStreamLocalForward( - socketPath: string, - wantReply?: boolean - ): boolean; - - /** - * (Client-only) - * Writes a direct-streamlocal@openssh.com channel open packet. `config` must contain - * `socketPath`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - openssh_directStreamLocal( - channel: number, - initWindow: number, - maxPacket: number, - config: SocketForwardingConfig - ): boolean; - - /** - * (Server-only) - * Writes a service accept packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - serviceAccept(serviceName: string): boolean; - - /** - * (Server-only) - * Writes a userauth failure packet. `authMethods` is an _array_ of authentication methods - * that can continue. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - authFailure(authMethods?: string[], partialSuccess?: boolean): boolean; - - /** - * (Server-only) - * Writes a userauth success packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - authSuccess(): boolean; - - /** - * (Server-only) - * Writes a userauth PK OK packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - authPKOK(keyAlgorithm: string, keyData: Buffer): boolean; - - /** - * (Server-only) - * Writes a userauth info request packet. `prompts` is an array of `Prompt` objects. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - authInfoReq(name: string, instructions: string, prompts: Prompt[]): boolean; - - /** - * (Server-only) - * Writes a forwarded tcpip channel open packet. `info` must contain `boundAddr`, - * `boundPort`, `remoteAddr`, and `remotePort`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - forwardedTcpip( - channel: number, - initWindow: number, - maxPacket: number, - info: ForwardedTcpip - ): boolean; - - /** - * (Server-only) - * Writes an X11 channel open packet. `info` must contain `originAddr` and `originPort`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - x11( - channel: number, - initWindow: number, - maxPacket: number, - info: ForwardedX11 - ): boolean; - - /** - * (Server-only) - * Writes an forwarded-streamlocal@openssh.com channel open packet. `info` must contain - * `socketPath`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - openssh_forwardedStreamLocal( - channel: number, - initWindow: number, - maxPacket: number, - info: ForwardedSocket - ): boolean; - - /** - * (Server-only) - * Writes an exit status channel request packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - exitStatus(channel: number, exitCode: number): boolean; - - /** - * (Server-only) - * Writes an exit signal channel request packet. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - exitSignal( - channel: number, - signalName: string, - coreDumped: boolean, - errorMessage: string - ): boolean; - - /** - * (Client/Server) - * Emitted when the protocol header is seen. - */ - on(event: 'header', listener: (header: Header) => mixed): this; - - /** - * (Client/Server) - */ - on( - event: 'GLOBAL_REQUEST', - listener: ( - reqName: string, - wantReply: boolean, - request: ?(GlobalRequest | Buffer) - ) => mixed - ): this; - - /** - * (Client/Server) - */ - on( - event: 'DISCONNECT', - listener: ( - reason: string, - reasonCode: number, - description: string - ) => mixed - ): this; - - /** - * (Client/Server) - */ - on(event: 'DEBUG', listener: (message: string) => mixed): this; - - /** - * (Client/Server) - */ - on(event: 'NEWKEYS', listener: () => mixed): this; - - /** - * (Client/Server) - */ - on( - event: 'REQUEST_SUCCESS', - listener: (resData: Buffer) => mixed - ): this; - - /** - * (Client/Server) - */ - on(event: 'REQUEST_FAILURE', listener: () => mixed): this; - - /** - * (Client/Server) - */ - on( - event: 'CHANNEL_OPEN', - listener: (channelInfo: ChannelOpenInfo) => mixed - ): this; - - /** - * (Client/Server) - */ - on( - event: 'CHANNEL_OPEN_CONFIRMATION:0', - listener: (channelInfo: ChannelOpenConfirmationInfo) => mixed - ): this; - - /** - * (Client/Server) - */ - on( - event: 'CHANNEL_OPEN_FAILURE:0', - listener: (failInfo: ChannelOpenFailureInfo) => mixed - ): this; - - /** - * (Client/Server) - */ - on( - event: 'CHANNEL_REQUEST:0', - listener: (request: ChannelRequest) => mixed - ): this; - - /** - * (Client/Server) - */ - on( - event: 'CHANNEL_DATA:0', - listener: (data: Buffer) => mixed - ): this; - - /** - * (Client/Server) - */ - on( - event: 'CHANNEL_EXTENDED_DATA:0', - listener: (type: number, data: Buffer) => mixed - ): this; - - /** - * (Client/Server) - */ - on( - event: 'CHANNEL_WINDOW_ADJUST:0', - listener: (bytesToAdd: number) => mixed - ): this; - - /** - * (Client/Server) - */ - on(event: 'CHANNEL_SUCCESS:0', listener: () => mixed): this; - - /** - * (Client/Server) - */ - on(event: 'CHANNEL_FAILURE:0', listener: () => mixed): this; - - /** - * (Client/Server) - */ - on(event: 'CHANNEL_EOF:0', listener: () => mixed): this; - - /** - * (Client/Server) - */ - on(event: 'CHANNEL_CLOSE:0', listener: () => mixed): this; - - /** - * (Client-only) - * This event allows you to verify a host's key. If `callback` is called with `true`, the - * handshake continues. Otherwise a disconnection will occur if `callback` is called with - * `false`. The default behavior is to auto-allow any host key if there are no handlers - * for this event. - */ - on( - event: 'fingerprint', - listener: ( - hostKey: Buffer, - callback: (success: boolean) => mixed - ) => mixed - ): this; - - /** - * (Client-only) - */ - on( - event: 'SERVICE_ACCEPT', - listener: (serviceName: string) => mixed - ): this; - - /** - * (Client-only) - */ - on( - event: 'USERAUTH_PASSWD_CHANGEREQ', - listener: (message: string) => mixed - ): this; - - /** - * (Client-only) - */ - on( - event: 'USERAUTH_INFO_REQUEST', - listener: ( - name: string, - instructions: string, - lang: string, - prompts: Prompt[] - ) => mixed - ): this; - - /** - * (Client-only) - */ - on(event: 'USERAUTH_PK_OK', listener: () => mixed): this; - - /** - * (Client-only) - */ - on(event: 'USERAUTH_SUCCESS', listener: () => mixed): this; - - /** - * (Client-only) - */ - on( - event: 'USERAUTH_FAILURE', - listener: ( - methodsContinue: string[], - partialSuccess: boolean - ) => mixed - ): this; - - /** - * (Client-only) - */ - on( - event: 'USERAUTH_BANNER', - listener: (message: string) => mixed - ): this; - - /** - * (Server-only) - */ - on( - event: 'SERVICE_REQUEST', - listener: (serviceName: string) => mixed - ): this; - - /** - * (Server-only) - */ - on( - event: 'USERAUTH_REQUEST', - listener: ( - username: string, - serviceName: string, - authMethod: string, - authMethodData: AuthMethodData - ) => mixed - ): this; - - /** - * (Server-only) - */ - on( - event: 'USERAUTH_INFO_RESPONSE', - listener: (responses: string[]) => mixed - ): this; - - /** - * Emitted when the connection has authenticated. - */ - on(event: 'ready', listener: () => mixed): this; - - /** - * Emitted when the socket has disconnected. - */ - on(event: 'end', listener: () => mixed): this; - - /** - * Emitted when the client socket was closed. - */ - on(event: 'close', listener: () => mixed): this; - - /** - * Emitted when more requests/data can be sent to the stream. - */ - on(event: 'continue', listener: () => mixed): this; - - /** - * Emitted when an error occurred. - */ - on(event: 'error', listener: (err: any) => mixed): this; - - on(event: string, listener: Function): this - } - - declare type SSH2StreamConfig = { - /** - * Set to true to create an instance in server mode. - */ - server?: boolean; - - /** - * If in server mode, an object keyed on host key format. - */ - hostKeys?: HostKeys; - - /** - * A message that is sent to clients immediately upon connection, before handshaking begins. - */ - banner?: string; - - /** - * A custom server software name/version identifier. - * @default 'ssh2js' + moduleVersion + 'srv' - */ - ident?: string; - - /** - * This is the maximum packet size that will be accepted. It should be 35000 bytes or larger to be compatible with other SSH2 implementations. - * @default 35000 - */ - maxPacketSize?: number; - - /** - * This is the highWaterMark to use for the parser stream. - * @default 32 * 1024 - */ - highWaterMark?: number; - - /** - * This option allows you to explicitly override the default transport layer algorithms used for the connection. Each value must be an array of valid algorithms for that category. The order of the algorithms in the arrays are important, with the most favorable being first. - */ - algorithms?: Algorithms; - - /** - * Set this to a function that receives a single string argument to get detailed (local) debug information. - */ - debug?: (information: string) => any; - } - - declare type HostKeys = { - [format: string]: HostKey; - } - - declare type HostKey = { - privatekey: ParsedKey; - publickey: ParsedKey; - } - - /** - * Overrides for the default transport layer algorithms used for the connection. - * - * The order of the algorithms in the arrays are important, with the most favorable being first. - */ - declare type Algorithms = { - kex?: string[]; - cipher?: string[]; - serverHostKey?: string[]; - hmac?: string[]; - compress?: string[]; - } - - declare type Header = { - /** - * (Client-only) An optional greeting message presented by the server. - */ - greeting?: string; - - /** - * The raw identification string sent by the remote party. - */ - identRaw: string; - - /** - * Contains various version information parsed from identRaw. - */ - versions: Versions; - - /** - * Any text that comes after the software name/version. - */ - comments: string; - } - - declare type Versions = { - /** - * The SSH protocol version supported by the remote party. - */ - protocol: string; - - /** - * The software name and version used by the remote party. - */ - software: string; - } - - declare type TcpipForwardGlobalRequest = { - /** - * The IP address to start/stop binding to. - */ - bindAddr: string; - - /** - * The port to start/stop binding to. - */ - bindPort: number; - } - - declare type openssh_StreamLocalForwardGlobalRequest = { - socketPath: string; - } - - declare type GlobalRequest = TcpipForwardGlobalRequest | - openssh_StreamLocalForwardGlobalRequest | - Buffer; - - declare type ChannelOpenConfirmationInfo = { - recipient: number; - sender: number; - window: number; - packetSize: number; - } - - declare type ChannelOpenFailureInfo = { - recipient: number; - reasonCode: number; - reason: string; - description: string; - } - - declare type X11ChannelInfo = { - +type: 'x11'; - sender: number; - window: number; - packetSize: number; - data: X11ChannelData; - } - - declare type X11ChannelData = { - srcIP: string; - srcPort: number; - } - - declare type ForwardedTcpipChannelInfo = { - +type: 'forwarded-tcpip'; - sender: number; - window: number; - packetSize: number; - data: TcpipChannelData; - } - - declare type DirectTcpipChannelInfo = { - +type: 'direct-tcpip'; - sender: number; - window: number; - packetSize: number; - data: TcpipChannelData; - } - - declare type TcpipChannelData = { - srcIP: string; - srcPort: number; - destIP: string; - destPort: number; - } - - declare type openssh_ForwardedStreamLocalChannelInfo = { - +type: 'forwarded-streamlocal@openssh.com'; - sender: number; - window: number; - packetSize: number; - data: SocketChannelData; - } - - declare type openssh_DirectStreamLocalChannelInfo = { - +type: 'direct-streamlocal@openssh.com'; - sender: number; - window: number; - packetSize: number; - data: SocketChannelData; - } - - declare type SocketChannelData = { - socketPath: string; - } - - declare type openssh_AuthAgentChannelInfo = { - +type: 'auth-agent@openssh.com'; - sender: number; - window: number; - packetSize: number; - } - - declare type SessionChannelInfo = { - +type: 'session'; - sender: number; - window: number; - packetSize: number; - } - - declare type ChannelOpenInfo = X11ChannelInfo | - ForwardedTcpipChannelInfo | - openssh_ForwardedStreamLocalChannelInfo | - openssh_AuthAgentChannelInfo | - DirectTcpipChannelInfo | - openssh_DirectStreamLocalChannelInfo | - SessionChannelInfo; - - declare type ExitStatusChannelRequest = { - +request: 'exit-status'; - recipient: number; - code: number; - } - - declare type ExitSignalChannelRequest = { - +request: 'exit-signal'; - recipient: number; - signal: string; - coredump: boolean; - description: string; - } - - declare type PseudoTtyChannelRequest = { - +request: 'pty-req'; - recipient: number; - wantReply: boolean; - term: string; - cols: number; - rows: number; - width: number; - height: number; - modes: any; - } - - declare type WindowChangeChannelRequest = { - +request: 'window-change'; - recipient: number; - cols: number; - rows: number; - width: number; - height: number; - } - - declare type X11ChannelRequest = { - +request: 'x11-req'; - recipient: number; - wantReply: boolean; - single: boolean; - protocol: string; - cookie: string; - screen: number; - } - - declare type EnvChannelRequest = { - +request: 'env'; - recipient: number; - wantReply: boolean; - key: string; - val: string; - } - - declare type ShellChannelRequest = { - +request: 'shell'; - recipient: number; - wantReply: boolean; - } - - declare type ExecChannelRequest = { - +request: 'exec'; - recipient: number; - wantReply: boolean; - command: string; - } - - declare type SubsystemChannelRequest = { - +request: 'subsystem'; - recipient: number; - wantReply: boolean; - subsystem: string; - } - - declare type SignalChannelRequest = { - +request: 'signal'; - recipient: number; - signal: string; - } - - declare type FlowControlChannelRequest = { - +request: 'xon-xoff'; - recipient: number; - clientControl: boolean; - } - - declare type openssh_AuthAgentChannelRequest = { - +request: 'auth-agent-req@openssh.com'; - recipient: number; - } - - declare type ChannelRequest = ExitStatusChannelRequest | - ExitSignalChannelRequest | - PseudoTtyChannelRequest | - WindowChangeChannelRequest | - X11ChannelRequest | - EnvChannelRequest | - ShellChannelRequest | - ExecChannelRequest | - SubsystemChannelRequest | - SignalChannelRequest | - FlowControlChannelRequest; - - declare type PublicKeyAuthMethodData = { - keyAlgo: string; - key: Buffer; - signature?: Buffer; - blob?: Buffer; - } - - declare type HostbasedAuthMethodData = { - keyAlgo: string; - key: Buffer; - signature?: Buffer; - blob?: Buffer; - localHostname: string; - localUsername: string; - } - - declare type AuthMethodData = string | PublicKeyAuthMethodData | HostbasedAuthMethodData; - - declare type TcpipForwardingConfig = { - /** - * Source IP address of outgoing connection. - */ - srcIP: string; - - /** - * Source port of outgoing connection. - */ - srcPort: number; - - /** - * Destination IP address of outgoing connection. - */ - destIP: string; - - /** - * Destination port of outgoing connection. - */ - destPort: number; - } - - declare type X11ForwardingConfig = { - /** - * true if only a single connection should be forwarded. - */ - single: boolean; - - /** - * The name of the X11 authentication method used (e.g. MIT-MAGIC-COOKIE-1). - */ - protocol: string; - - /** - * The X11 authentication cookie encoded in hexadecimal. - */ - cookie: string; - - /** - * The screen number to forward X11 connections for. - */ - screen: number; - } - - declare type SocketForwardingConfig = { - socketPath: string; - } - - declare interface Prompt { - prompt: string; - echo?: boolean; - } - - declare type ForwardedTcpip = { - bindAddr: string; - bindPort: number; - remoteAddr: string; - remotePort: number; - } - - declare type ForwardedX11 = { - originAddr: string; - originPort: number; - } - - declare type ForwardedSocket = { - socketPath: string; - } - - declare class SFTPStream extends stream$Transform { - /** - * Creates and returns a new SFTPStream instance. - */ - constructor(remoteIdentRaw: string): void, - - /** - * Creates and returns a new SFTPStream instance. - */ - constructor(cfg?: SFTPStreamConfig, remoteIdentRaw?: string): void, - - /** - * Converts string flags (e.g. `'r'`, `'a+'`, etc.) to the appropriate - * `SFTPStream.OPEN_MODE` flag mask. - * - * Returns `null` if conversion failed. - */ - static stringToFlags(flagsStr: string): number, - - /** - * Converts flag mask (e.g. number containing `SFTPStream.OPEN_MODE` values) to the - * appropriate string value. - * - * Returns `null` if conversion failed. - */ - static flagsToString(flagsMask: number): string, - - /** - * (Client-only) - * Downloads a file at `remotePath` to `localPath` using parallel reads for faster throughput. - */ - fastGet( - remotePath: string, - localPath: string, - options: TransferOptions, - callback: (err: any) => mixed - ): void, - - /** - * (Client-only) - * Downloads a file at `remotePath` to `localPath` using parallel reads for faster throughput. - */ - fastGet( - remotePath: string, - localPath: string, - callback: (err: any) => mixed - ): void, - - /** - * (Client-only) - * Uploads a file from `localPath` to `remotePath` using parallel reads for faster throughput. - */ - fastPut( - localPath: string, - remotePath: string, - options: TransferOptions, - callback: (err: any) => mixed - ): void, - - /** - * (Client-only) - * Uploads a file from `localPath` to `remotePath` using parallel reads for faster throughput. - */ - fastPut( - localPath: string, - remotePath: string, - callback: (err: any) => mixed - ): void, - - /** - * (Client-only) - * Returns a new readable stream for `path`. - */ - createReadStream(path: string, options?: ReadStreamOptions): stream$Readable, - - /** - * (Client-only) - * Returns a new writable stream for `path`. - */ - createWriteStream( - path: string, - options?: WriteStreamOptions - ): stream$Writable, - - /** - * Reads a file - * @param options either the encoding (string) or a bag of options - */ - readFile(path: string, options?: string | ReadFileOptions, callback?: (error: any, data: string | Buffer) => mixed): void; - - /** - * Writes to a file - * @param options either the encoding (string) or a bag of options - */ - writeFile(path: string, data: string | Buffer, options?: string | WriteFileOptions, callback?: (error: any) => mixed): void; - - /** - * Appends to a file - * @param options either the encoding (string) or a bag of options - */ - appendFile(path: string, data: string | Buffer, options?: string | AppendFileOptions, callback?: (error: any) => mixed): void; - - /** - * (Client-only) - * Opens a file `filename` for `mode` with optional `attributes`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - open( - filename: string, - flags: ReadFlags | WriteFlags | AppendFlags, - attributes: InputAttributes, - callback: (err: any, handle: Buffer) => mixed - ): boolean, - - /** - * (Client-only) - * Opens a file `filename` for `mode`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - open( - filename: string, - flags: ReadFlags | WriteFlags | AppendFlags, - callback: (err: any, handle: Buffer) => mixed - ): boolean, - - /** - * (Client-only) - * Closes the resource associated with `handle` given by `open()` or `opendir()`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - close(handle: Buffer, callback: (err: any) => mixed): boolean, - - /** - * (Client-only) - * Reads `length` bytes from the resource associated with `handle` starting at `position` - * and stores the bytes in `buffer` starting at `offset`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - readData( - handle: Buffer, - buffer: Buffer, - offset: number, - length: number, - position: number, - callback: ( - err: any, - bytesRead: number, - buffer: Buffer, - position: number - ) => mixed - ): boolean, - - /** - * (Client-only) - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - writeData( - handle: Buffer, - buffer: Buffer, - offset: number, - length: number, - position: number, - callback: (err: any) => mixed - ): boolean, - - /** - * (Client-only) - * Retrieves attributes for the resource associated with `handle`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - fstat( - handle: Buffer, - callback: (err: any, stats: Stats) => mixed - ): boolean, - - /** - * (Client-only) - * Sets the attributes defined in `attributes` for the resource associated with `handle`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - fsetstat( - handle: Buffer, - attributes: InputAttributes, - callback: (err: any) => mixed - ): boolean, - - /** - * (Client-only) - * Sets the access time and modified time for the resource associated with `handle`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - futimes( - handle: Buffer, - atime: number | Date, - mtime: number | Date, - callback: (err: any) => mixed - ): boolean, - - /** - * (Client-only) - * Sets the owner for the resource associated with `handle`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - fchown( - handle: Buffer, - uid: number, - gid: number, - callback: (err: any) => mixed - ): boolean, - - /** - * (Client-only) - * Sets the mode for the resource associated with `handle`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - fchmod( - handle: Buffer, - mode: number | string, - callback: (err: any) => mixed - ): boolean, - - /** - * (Client-only) - * Opens a directory `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - opendir( - path: string, - callback: (err: any, handle: Buffer) => mixed - ): boolean, - - /** - * (Client-only) - * Retrieves a directory listing. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - readdir( - location: string | Buffer, - callback: (err: any, list: FileEntry[]) => mixed - ): boolean, - - /** - * (Client-only) - * Checks whether the given file or path exists. - */ - exists(path: string, callback: (exists: boolean) => mixed): void, - - /** - * (Client-only) - * Removes the file/symlink at `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - unlink(path: string, callback: (err: any) => mixed): boolean, - - /** - * (Client-only) - * Renames/moves `srcPath` to `destPath`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - rename( - srcPath: string, - destPath: string, - callback: (err: any) => mixed - ): boolean, - - /** - * (Client-only) - * Creates a new directory `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - mkdir( - path: string, - attributes: InputAttributes, - callback: (err: any) => mixed - ): boolean, - - /** - * (Client-only) - * Creates a new directory `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - mkdir(path: string, callback: (err: any) => mixed): boolean, - - /** - * (Client-only) - * Removes the directory at `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - rmdir(path: string, callback: (err: any) => mixed): boolean, - - /** - * (Client-only) - * Retrieves attributes for `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - stat( - path: string, - callback: (err: any, stats: Stats) => mixed - ): boolean, - - /** - * (Client-only) - * Retrieves attributes for `path`. If `path` is a symlink, the link itself is stat'ed - * instead of the resource it refers to. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - lstat( - path: string, - callback: (err: any, stats: Stats) => mixed - ): boolean, - - /** - * (Client-only) - * Sets the attributes defined in `attributes` for `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - setstat( - path: string, - attributes: InputAttributes, - callback: (err: any) => mixed - ): boolean, - - /** - * (Client-only) - * Sets the access time and modified time for `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - utimes( - path: string, - atime: number | Date, - mtime: number | Date, - callback: (err: any) => mixed - ): boolean, - - /** - * (Client-only) - * Sets the owner for `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - chown( - path: string, - uid: number, - gid: number, - callback: (err: any) => mixed - ): boolean, - - /** - * (Client-only) - * Sets the mode for `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - chmod( - path: string, - mode: number | string, - callback: (err: any) => mixed - ): boolean, - - /** - * (Client-only) - * Retrieves the target for a symlink at `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - readlink( - path: string, - callback: (err: any, target: string) => mixed - ): boolean, - - /** - * (Client-only) - * Creates a symlink at `linkPath` to `targetPath`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - symlink( - targetPath: string, - linkPath: string, - callback: (err: any) => mixed - ): boolean, - - /** - * (Client-only) - * Resolves `path` to an absolute path. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - realpath( - path: string, - callback: (err: any, absPath: string) => mixed - ): boolean, - - /** - * (Client-only, OpenSSH extension) - * Performs POSIX rename(3) from `srcPath` to `destPath`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - ext_openssh_rename( - srcPath: string, - destPath: string, - callback: (err: any) => mixed - ): boolean, - - /** - * (Client-only, OpenSSH extension) - * Performs POSIX statvfs(2) on `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - ext_openssh_statvfs( - path: string, - callback: (err: any, fsInfo: any) => mixed - ): boolean, - - /** - * (Client-only, OpenSSH extension) - * Performs POSIX fstatvfs(2) on open handle `handle`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - ext_openssh_fstatvfs( - handle: Buffer, - callback: (err: any, fsInfo: any) => mixed - ): boolean, - - /** - * (Client-only, OpenSSH extension) - * Performs POSIX link(2) to create a hard link to `targetPath` at `linkPath`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - ext_openssh_hardlink( - targetPath: string, - linkPath: string, - callback: (err: any) => mixed - ): boolean, - - /** - * (Client-only, OpenSSH extension) - * Performs POSIX fsync(3) on the open handle `handle`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - ext_openssh_fsync( - handle: Buffer, - callback: (err: any, fsInfo: any) => mixed - ): boolean, - - /** - * (Server-only) - * Sends a status response for the request identified by `id`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - status(reqID: number, statusCode: number, message?: string): boolean, - - /** - * (Server-only) - * Sends a handle response for the request identified by `id`. - * - * @param handle A handle must be less than 256 bytes and is an opaque value that could - * merely contain the value of a backing file descriptor or some other unique, - * custom value. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - handle(reqID: number, handle: Buffer): boolean, - - /** - * (Server-only) - * Sends a data response for the request identified by `id`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - data(reqID: number, data: string | Buffer, encoding?: string): boolean, - - /** - * (Server-only) - * Sends a name response for the request identified by `id`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - name(reqID: number, names: FileEntry[]): boolean, - - /** - * (Server-only) - * Sends an attrs response for the request identified by `id`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - attrs(reqID: number, attrs: Attributes): boolean, - - /** - * (Client/Server) - * Emitted after initial protocol version check has passed. - */ - on(event: 'ready', listener: () => mixed): this, - - /** - * (Server-only) - * Emitted when the client requests to open a file. - * - * Respond with: - * * `handle()` - This indicates a successful opening of the file and passes the given handle back to the client to use to refer to this open file for future operations (e.g. reading, writing, closing). - * * `status()` - Use this to indicate a failure to open the requested file. - */ - on( - event: 'OPEN', - listener: ( - reqID: number, - filename: string, - flags: number, - attrs: InputAttributes - ) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests to read data from a file handle. - * - * Respond with: - * * `data()` - Use this to send the requested chunk of data back to the client. The amount of data sent is allowed to be less than the `length` requested. - * * `status()` - Use this to indicate either end of file (`STATUS_CODE.EOF`) has been reached (`offset` is past the end of the file) or if an error occurred while reading the requested part of the file. - */ - on( - event: 'READ', - listener: ( - reqID: number, - handle: Buffer, - offset: number, - length: number - ) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests to write data to a file handle. - * - * Respond with: - * * `status()` - Use this to indicate success/failure of the write to the file. - */ - on( - event: 'WRITE', - listener: ( - reqID: number, - handle: Buffer, - offset: number, - data: Buffer - ) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests attributes for the resource associated with `handle`. - * - * Respond with: - * * `attrs()` - Use this to send the attributes for the requested file/directory back to the client. - * * `status()` - Use this to indicate an error occurred while accessing the file/directory. - */ - on( - event: 'FSTAT', - listener: (reqID: number, handle: Buffer) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests to write attributes for the resource associated with `handle`. - * - * Respond with: - * * `status()` - Use this to indicates success/failure of the setting of the given file/directory attributes. - */ - on( - event: 'FSETSTAT', - listener: ( - reqID: number, - handle: Buffer, - attrs: InputAttributes - ) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests to close a handle. - * - * Respond with: - * * `status()` - Use this to indicate success (`STATUS_CODE.OK`) or failure of the closing of the file identified by `handle`. - */ - on( - event: 'CLOSE', - listener: (reqID: number, handle: Buffer) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests to open a directory. - * - * Respond with: - * * `handle()` - This indicates a successful opening of the directory and passes the given handle back to the client to use to refer to this open directory for future operations (e.g. reading directory contents, closing). - * * `status()` - Use this to indicate a failure to open the requested directory. - */ - on( - event: 'OPENDIR', - listener: (reqID: number, path: string) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests to read the contents of a directory. - * - * Respond with: - * * `name()` - Use this to send one or more directory listings for the open directory back to the client. - * * `status()` - Use this to indicate either end of directory contents (`STATUS_CODE.EOF`) or if an error occurred while reading the directory contents. - */ - on( - event: 'READDIR', - listener: (reqID: number, handle: Buffer) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests attributes for a path. If `path` is a symlink, the - * link itself should stat'ed instead of the resource it refers to. - * - * Respond with: - * * `attrs()` - Use this to send the attributes for the requested file/directory back to the client. - * * `status()` - Use this to indicate an error occurred while accessing the file/directory. - */ - on( - event: 'LSTAT', - listener: (reqID: number, path: string) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests attributes for a path. - * - * Respond with: - * * `attrs()` - Use this to send the attributes for the requested file/directory back to the client. - * * `status()` - Use this to indicate an error occurred while accessing the file/directory. - */ - on( - event: 'STAT', - listener: (reqID: number, path: string) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests to delete a file or symlink. - * - * Respond with: - * * `status()` - Use this to indicate success/failure of the removal of the file at `path`. - */ - on( - event: 'REMOVE', - listener: (reqID: number, path: string) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests to remove a directory. - * - * Respond with: - * * `status()` - Use this to indicate success/failure of the removal of the directory at `path`. - */ - on( - event: 'RMDIR', - listener: (reqID: number, path: string) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests the absolute path for a path. - * - * Respond with: - * * `name()` - Use this to respond with a normalized version of `path`. No file/directory attributes are required to be sent in this response. - * * `status()` - Use this to indicate a failure in normalizing `path`. - */ - on( - event: 'REALPATH', - listener: (reqID: number, path: string) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests the target for a symlink at `path`. - * - * Respond with: - * * `name()` - Use this to respond with the target of the symlink at `path`. No file/directory attributes are required to be sent in this response. - * * `status()` - Use this to indicate a failure in reading the symlink at `path`. - */ - on( - event: 'READLINK', - listener: (reqID: number, path: string) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests to set the attributes defined in `attrs` for `path`. - * - * Respond with: - * * `status()` - Use this to indicates success/failure of the setting of the given file/directory attributes. - */ - on( - event: 'SETSTAT', - listener: ( - reqID: number, - path: string, - attrs: InputAttributes - ) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests a new directory be created. - * - * Respond with: - * * `status()` - Use this to indicate success/failure of the creation of the directory at `path`. - */ - on( - event: 'MKDIR', - listener: ( - reqID: number, - path: string, - attrs: InputAttributes - ) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests a path be renamed. - * - * Respond with: - * * `status()` - Use this to indicate success/failure of the renaming of the file/directory at `oldPath` to `newPath`. - */ - on( - event: 'RENAME', - listener: ( - reqID: number, - oldPath: string, - newPath: string - ) => mixed - ): this, - - /** - * (Server-only) - * Emitted when the client requests a new symlink be created for a path. - * - * Respond with: - * * `status()` - Use this to indicate success/failure of the symlink creation. - */ - on( - event: 'SYMLINK', - listener: ( - reqID: number, - linkPath: string, - targetPath: string - ) => mixed - ): this, - - /** - * Emitted when the socket has disconnected. - */ - on(event: 'end', listener: () => mixed): this, - - /** - * Emitted when the client socket was closed. - */ - on(event: 'close', listener: () => mixed): this, - - /** - * Emitted when more requests/data can be sent to the stream. - */ - on(event: 'continue', listener: () => mixed): this, - - /** - * Emitted when an error occurred. - */ - on(event: 'error', listener: (err: any) => mixed): this, - - on(event: string, listener: Function): this - } - - /** - * Contains the various status codes (for use especially with SFTPStream#status()) - */ - declare var SFTPStream$STATUS_CODE$OK: 0; - declare var SFTPStream$STATUS_CODE$EOF: 1; - declare var SFTPStream$STATUS_CODE$NO_SUCH_FILE: 2; - declare var SFTPStream$STATUS_CODE$PERMISSION_DENIED: 3; - declare var SFTPStream$STATUS_CODE$FAILURE: 4; - declare var SFTPStream$STATUS_CODE$BAD_MESSAGE: 5; - declare var SFTPStream$STATUS_CODE$NO_CONNECTION: 6; - declare var SFTPStream$STATUS_CODE$CONNECTION_LOST: 7; - declare var SFTPStream$STATUS_CODE$OP_UNSUPPORTED: 8; - declare type SFTPStream$STATUS_CODE = - typeof SFTPStream$STATUS_CODE$OK | - typeof SFTPStream$STATUS_CODE$EOF | - typeof SFTPStream$STATUS_CODE$NO_SUCH_FILE | - typeof SFTPStream$STATUS_CODE$PERMISSION_DENIED | - typeof SFTPStream$STATUS_CODE$FAILURE | - typeof SFTPStream$STATUS_CODE$BAD_MESSAGE | - typeof SFTPStream$STATUS_CODE$NO_CONNECTION | - typeof SFTPStream$STATUS_CODE$CONNECTION_LOST | - typeof SFTPStream$STATUS_CODE$OP_UNSUPPORTED; - - /** - * Contains the various open file flags - */ - declare var SFTPStream$OPEN_MODE$READ: 0x00000001; - declare var SFTPStream$OPEN_MODE$WRITE: 0x00000002; - declare var SFTPStream$OPEN_MODE$APPEND: 0x00000004; - declare var SFTPStream$OPEN_MODE$CREAT: 0x00000008; - declare var SFTPStream$OPEN_MODE$TRUNC: 0x00000010; - declare var SFTPStream$OPEN_MODE$EXCL: 0x00000020; - declare type SFTPStream$OPEN_MODE = - typeof SFTPStream$OPEN_MODE$READ | - typeof SFTPStream$OPEN_MODE$WRITE | - typeof SFTPStream$OPEN_MODE$APPEND | - typeof SFTPStream$OPEN_MODE$CREAT | - typeof SFTPStream$OPEN_MODE$TRUNC | - typeof SFTPStream$OPEN_MODE$EXCL; - - declare type SFTPStreamConfig = { - /** - * Set to true to create an instance in server mode. - */ - server?: boolean; - - /** - * This is the highWaterMark to use for the stream. - */ - highWaterMark?: number; - - /** - * Set this to a function that receives a single string argument to get detailed (local) debug information. - */ - debug?: (information: string) => any; - } - - declare type TransferOptions = { - /** - * Number of concurrent reads - */ - concurrency?: number; - - /** - * Size of each read in bytes - */ - chunkSize?: number; - - /** - * Called every time a part of a file was transferred - */ - step?: (total_transferred: number, chunk: number, total: number) => mixed; - } - - declare type ReadStreamOptions = { - flags?: string; - encoding?: string; - handle?: Buffer; - mode?: number; - autoClose?: boolean; - start?: number; - end?: number; - } - - declare type WriteStreamOptions = { - flags?: string; - encoding?: string; - mode?: number; - } - - declare type ReadFlags = 'r' | 'r+'; - declare type WriteFlags = 'w' | 'wx' | 'xw' | 'w+' | 'wx+' | 'xw+'; - declare type AppendFlags = 'a' | 'ax' | 'xa' | 'a+' | 'ax+' | 'xa+'; - - declare type ReadFileOptions = { - flag?: ReadFlags; - encoding?: ?string; - } - - declare type WriteFileOptions = { - flag?: WriteFlags | AppendFlags; - encoding?: ?string; - mode?: number; - } - - declare type AppendFileOptions = { - flag?: WriteFlags; - encoding?: ?string; - mode?: number; - } - - declare type FileEntry = { - filename: string; - longname: string; - attrs: Attributes; - } - - declare type InputAttributes = { - mode?: number | string; - uid?: number; - gid?: number; - size?: number; - atime?: number | Date; - mtime?: number | Date; - } - - declare type Attributes = { - mode: number; - uid: number; - gid: number; - size: number; - atime: number; - mtime: number; - } - - declare type Stats = Attributes & { - isDirectory(): boolean; - isFile(): boolean; - isBlockDevice(): boolean; - isCharacterDevice(): boolean; - isSymbolicLink(): boolean; - isFIFO(): boolean; - isSocket(): boolean; - } - - declare function utils$parseKey(keyData: string | Buffer): ParsedKey | Error; - declare function utils$genPublicKey(privKeyInfo: ParsedKey): ParsedKey; - declare function utils$decryptKey(privKeyInfo: ParsedKey, passphrase: string): void; -} diff --git a/flow-libs/ssh2.js.flow b/flow-libs/ssh2.js.flow deleted file mode 100644 index b88a9552f0..0000000000 --- a/flow-libs/ssh2.js.flow +++ /dev/null @@ -1,1949 +0,0 @@ -/** - * Copyright (c) 2017-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 - */ - -// Type definitions for ssh2 v0.5.x -// Project: https://github.com/mscdex/ssh2 -// TypeScript Definitions by: Qubo , Ron Buckton - -declare module 'ssh2' { - import type { - Algorithms, - AppendFileOptions, - AppendFlags, - Header, - Prompt, - SFTPStream, - InputAttributes, - Attributes, - Stats, - TransferOptions, - ReadFlags, - ReadFileOptions, - ReadStreamOptions, - WriteFlags, - WriteFileOptions, - WriteStreamOptions, - FileEntry - } from 'ssh2-streams'; - - // TODO(siegebell): made a class to allow returning `this` type, but is possibly an interface - declare class Channel extends stream$Duplex { - /** If `true` only sends `EOF` when `end()` is called. */ - allowHalfOpen: boolean; - /** Standard input for the Channel. */ - +stdin: this; - /** Standard output for the Channel. */ - +stdout: this; - /** Standard error for the Channel. */ - +stderr: stream$Readable | stream$Writable; - /** Indicates whether this is a server or client channel. */ - +server: boolean; - /** The channel type, usually "session". */ - +type: ?string; - /** The channel subtype, usually "exec", "shell", or undefined. */ - +subtype: ?string; - - /** - * Sends EOF to the remote side. - * - * Returns false if you should wait for the continue event before sending any more traffic. - */ - eof(): boolean; - - /** - * Closes the channel on both sides. - * - * Returns false if you should wait for the continue event before sending any more traffic. - */ - close(): boolean; - - /** - * Shuts down the channel on this side. - */ - destroy(): void; - } - - // TODO(siegebell): made a class to allow returning `this` type, but is possibly an interface - declare class ClientChannel extends Channel { - /** Standard error for the Channel. */ - +stderr: stream$Readable; - /** Indicates whether this is a server or client channel. */ - +server: false; - - /** - * Lets the server know that the local terminal window has been resized. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - setWindow(rows: number, cols: number, height: number, width: number): boolean; - - /** - * Sends a POSIX signal to the current process on the server. Valid signal names are: - * 'ABRT', 'ALRM', 'FPE', 'HUP', 'ILL', 'INT', 'KILL', 'PIPE', 'QUIT', 'SEGV', 'TERM', - * 'USR1', and 'USR2'. - * - * Some server implementations may ignore this request if they do not support signals. - * - * Note: If you are trying to send SIGINT and you find `signal()` doesn't work, try writing - * `'\x03'` to the Channel stream instead. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - signal(signalName: string): boolean; - - /** - * Emitted once the channel is completely closed on both the client and the server. - */ - on( - event: 'close', - listener: ( - exitCode: number | null, - exitSignal?: string, - exitDump?: string, - description?: string, - language?: string, - ) => mixed, - ): this; - - /** - * An `exit` event *may* (the SSH2 spec says it is optional) be emitted when the process - * finishes. If the process finished normally, the process's return value is passed to - * the `exit` callback. - */ - on( - event: 'exit', - listener: ( - exitCode: number | null, - signalName?: string, - didCoreDump?: boolean, - description?: string, - language?: string, - ) => mixed, - ): this; - - on(event: string, listener: Function): this; - } - - declare class ServerChannel extends Channel { - /** Standard error for the Channel. */ - +stderr: stream$Writable; - /** Indicates whether this is a server or client channel. */ - +server: true; - - /** - * Sends an exit status code to the client. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - exit(exitCode: number): boolean; - - /** - * Sends an exit signal to the client. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - exit(name: string, coreDumped: boolean, msg: string): boolean; - - /** - * Emitted once the channel is completely closed on both the client and the server. - */ - on(event: 'close', listener: () => mixed): this; - - on(event: string, listener: Function): this; - } - - declare class Client extends events$EventEmitter { - config: Object; - - // Client-events - - /** - * Emitted when a notice was sent by the server upon connection. - */ - on(event: 'banner', listener: (message: string) => mixed): this; - - /** - * Emitted when authentication was successful. - */ - on(event: 'ready', listener: () => mixed): this; - - /** - * Emitted when an incoming forwarded TCP connection is being requested. - * - * Calling `accept()` accepts the connection and returns a `Channel` object. - * Calling `reject()` rejects the connection and no further action is needed. - */ - on( - event: 'tcp connection', - listener: ( - details: TcpConnectionDetails, - accept: () => ClientChannel, - reject: () => mixed - ) => mixed - ): this; - - /** - * Emitted when an incoming X11 connection is being requested. - * - * Calling `accept()` accepts the connection and returns a `Channel` object. - * Calling `reject()` rejects the connection and no further action is needed. - */ - on( - event: 'x11', - listener: ( - details: X11Details, - accept: () => ClientChannel, - reject: () => mixed - ) => mixed - ): this; - - /** - * Emitted when the server is asking for replies to the given `prompts` for keyboard- - * interactive user authentication. - * - * * `name` is generally what you'd use as a window title (for GUI apps). - * * `prompts` is an array of `Prompt` objects. - * - * The answers for all prompts must be provided as an array of strings and passed to - * `finish` when you are ready to continue. - * - * NOTE: It's possible for the server to come back and ask more questions. - */ - on( - event: 'keyboard-interactive', - listener: ( - name: string, - instructions: string, - lang: string, - prompts: Prompt[], - finish: (responses: string[]) => mixed - ) => mixed - ): this; - - /** - * Emitted when the server has requested that the user's password be changed, if using - * password-based user authentication. - * - * Call `done` with the new password. - */ - on( - event: 'change password', - listener: ( - message: string, - lang: string, - done: (password: string) => mixed - ) => mixed - ): this; - - /** - * Emitted when more requests/data can be sent to the server (after a `Client` method - * returned `false`). - */ - on(event: 'continue', listener: () => mixed): this; - - /** - * Emitted when an error occurred. - */ - on( - event: 'error', - listener: (err: Error & ClientErrorExtensions) => mixed - ): this; - - /** - * Emitted when the socket was disconnected. - */ - on(event: 'end', listener: () => mixed): this; - - /** - * Emitted when the socket was closed. - */ - on( - event: 'close', - listener: (hadError: boolean) => mixed - ): this; - - /** - * Emitted when the socket has timed out. - */ - on(event: 'timeout', listener: () => mixed): this; - - /** - * Emitted when the socket has connected. - */ - on(event: 'connect', listener: () => mixed): this; - - /** - * Emitted when the server responds with a greeting message. - */ - on( - event: 'greeting', - listener: (greeting: string) => mixed - ): this; - - on(event: string, listener: Function): this; - - // Client-methods - - /** - * Creates and returns a new Client instance. - */ - constructor(): void; - - /** - * Attempts a connection to a server. - */ - connect(config: ConnectConfig): void; - - /** - * Executes a command on the server. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - * - * @param command The command to execute. - * @param options Options for the command. - * @param callback The callback to execute when the command has completed. - */ - exec( - command: string, - options?: ExecOptions, - callback: (err: Error, channel: ClientChannel) => mixed - ): boolean; - - /** - * Starts an interactive shell session on the server. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - * - * @param window Either an object containing containing pseudo-tty settings, `false` to suppress creation of a pseudo-tty. - * @param options Options for the command. - * @param callback The callback to execute when the channel has been created. - */ - shell( - window?: PseudoTtyOptions | false, - options?: ShellOptions, - callback: (err: Error, channel: ClientChannel) => mixed - ): boolean; - - /** - * Bind to `remoteAddr` on `remotePort` on the server and forward incoming TCP connections. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - * - * @param remoteAddr The remote address to bind on the server. The following lists several special values for `remoteAddr` and their respective bindings: - * - * | address | description - * |:--------------|:----------- - * | `''` | Listen on all protocol families supported by the server - * | `'0.0.0.0'` | Listen on all IPv4 addresses - * | `'::'` | Listen on all IPv6 addresses - * | `'localhost'` | Listen on the loopback interface for all protocol families - * | `'127.0.0.1'` | Listen on the loopback interfaces for IPv4 - * | `'::1'` | Listen on the loopback interfaces for IPv6 - * - * @param remotePort The remote port to bind on the server. If this value is `0`, the actual bound port is provided to `callback`. - * @param callback An optional callback that is invoked when the remote address is bound. - */ - forwardIn( - remoteAddr: string, - remotePort: number, - callback?: (err: Error, bindPort: number) => mixed - ): boolean; - - /** - * Unbind from `remoteAddr` on `remotePort` on the server and stop forwarding incoming TCP - * connections. Until `callback` is called, more connections may still come in. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - * - * @param remoteAddr The remote address to unbind on the server. - * @param remotePort The remote port to unbind on the server. - * @param callback An optional callback that is invoked when the remote address is unbound. - */ - unforwardIn( - remoteAddr: string, - remotePort: number, - callback?: (err: Error) => mixed - ): boolean; - - /** - * Open a connection with `srcIP` and `srcPort` as the originating address and port and - * `dstIP` and `dstPort` as the remote destination address and port. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - * - * @param srcIP The originating address. - * @param srcPort The originating port. - * @param dstIP The destination address. - * @param dstPort The destination port. - * @param callback The callback that is invoked when the address is bound. - */ - forwardOut( - srcIP: string, - srcPort: number, - dstIP: string, - dstPort: number, - callback: (err: Error, channel: ClientChannel) => mixed - ): boolean; - - /** - * Starts an SFTP session. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - * - * @param callback The callback that is invoked when the SFTP session has started. - */ - sftp(callback: (err: Error, sftp: SFTPWrapper) => mixed): boolean; - - /** - * Invokes `subsystem` on the server. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - * - * @param subsystem The subsystem to start on the server. - * @param callback The callback that is invoked when the subsystem has started. - */ - subsys( - subsystem: string, - callback: (err: Error, channel: ClientChannel) => mixed - ): boolean; - - /** - * Disconnects the socket. - */ - end(): void; - - /** - * Destroys the socket. - */ - destroy(): void; - - /** - * OpenSSH extension that sends a request to reject any new sessions (e.g. exec, shell, - * sftp, subsys) for this connection. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - openssh_noMoreSessions(callback?: (err: Error) => mixed): boolean; - - /** - * OpenSSH extension that binds to a UNIX domain socket at `socketPath` on the server and - * forwards incoming connections. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - openssh_forwardInStreamLocal( - socketPath: string, - callback?: (err: Error) => mixed - ): boolean; - - /** - * OpenSSH extension that unbinds from a UNIX domain socket at `socketPath` on the server - * and stops forwarding incoming connections. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - openssh_unforwardInStreamLocal( - socketPath: string, - callback?: (err: Error) => mixed - ): boolean; - - /** - * OpenSSH extension that opens a connection to a UNIX domain socket at `socketPath` on - * the server. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - openssh_forwardOutStreamLocal( - socketPath: string, - callback?: (err: Error, channel: ClientChannel) => mixed - ): boolean; - } - - declare type ConnectConfig = { - /** Hostname or IP address of the server. */ - host?: string; - /** Port number of the server. */ - port?: number; - /** Only connect via resolved IPv4 address for `host`. */ - forceIPv4?: boolean; - /** Only connect via resolved IPv6 address for `host`. */ - forceIPv6?: boolean; - /** The host's key is hashed using this method and passed to `hostVerifier`. */ - hostHash?: 'md5' | 'sha1'; - /** Verifies a hexadecimal hash of the host's key. */ - hostVerifier?: (keyHash: string) => boolean; - /** Username for authentication. */ - username?: string; - /** Password for password-based user authentication. */ - password?: string; - /** Path to ssh-agent's UNIX socket for ssh-agent-based user authentication (or 'pageant' when using Pagent on Windows). */ - agent?: ?string; - /** Buffer or string that contains a private key for either key-based or hostbased user authentication (OpenSSH format). */ - privateKey?: Buffer | string; - /** For an encrypted private key, this is the passphrase used to decrypt it. */ - passphrase?: string; - /** Along with `localUsername` and `privateKey`, set this to a non-empty string for hostbased user authentication. */ - localHostname?: string; - /** Along with `localHostname` and `privateKey`, set this to a non-empty string for hostbased user authentication. */ - localUsername?: string; - /** Try keyboard-interactive user authentication if primary user authentication method fails. */ - tryKeyboard?: boolean; - /** How often (in milliseconds) to send SSH-level keepalive packets to the server. Set to 0 to disable. */ - keepaliveInterval?: number; - /** How many consecutive, unanswered SSH-level keepalive packets that can be sent to the server before disconnection. */ - keepaliveCountMax?: number; - /** * How long (in milliseconds) to wait for the SSH handshake to complete. */ - readyTimeout?: number; - /** Performs a strict server vendor check before sending vendor-specific requests. */ - strictVendor?: boolean; - /** A `ReadableStream` to use for communicating with the server instead of creating and using a new TCP connection (useful for connection hopping). */ - sock?: ReadableStream; - /** Set to `true` to use OpenSSH agent forwarding (`auth-agent@openssh.com`) for the life of the connection. */ - agentForward?: boolean; - /** Explicit overrides for the default transport layer algorithms used for the connection. */ - algorithms?: Algorithms; - /** A function that receives a single string argument to get detailed (local) debug information. */ - debug?: (information: string) => any; - } - - declare type TcpConnectionDetails = { - /** The originating IP of the connection. */ - srcIP: string; - /** The originating port of the connection. */ - srcPort: number; - /** The remote IP the connection was received on (given in earlier call to `forwardIn()`). */ - destIP: string; - /** The remote port the connection was received on (given in earlier call to `forwardIn()`). */ - destPort: number; - } - - declare type X11Details = { - /** The originating IP of the connection. */ - srcIP: string; - /** The originating port of the connection. */ - srcPort: number; - } - - declare type ClientErrorExtensions = { - /** Indicates 'client-socket' for socket-level errors and 'client-ssh' for SSH disconnection messages. */ - level?: string; - /** Additional detail for 'client-ssh' messages. */ - description?: string; - } - - declare type ExecOptions = { - /** An environment to use for the execution of the command. */ - env?: any; - /** Set to `true` to allocate a pseudo-tty with defaults, or an object containing specific pseudo-tty settings. */ - pty?: true | PseudoTtyOptions; - /** Set either to `true` to use defaults, a number to specify a specific screen number, or an object containing x11 settings. */ - x11?: boolean | number | X11Options; - } - - declare type ShellOptions = { - /** Set either to `true` to use defaults, a number to specify a specific screen number, or an object containing x11 settings. */ - x11?: boolean | number | X11Options; - } - - declare type X11Options = { - /** Whether to allow just a single connection (default: `false`).*/ - single?: boolean; - /** The Screen number to use (default: `0`). */ - screen?: number; - } - - declare type PseudoTtyOptions = { - /** The number of rows (default: `24`). */ - rows?: number; - /** The number of columns (default: `80`). */ - cols?: number; - /** The height in pixels (default: `480`). */ - height?: number; - /** The width in pixels (default: `640`). */ - width?: number; - /** The value to use for $TERM (default: `'vt100'`) */ - term?: string; - } - - declare class Server extends events$EventEmitter { - static KEEPALIVE_INTERVAL: number; - static KEEPALIVE_CLIENT_INTERVAL: number; - static KEEPALIVE_CLIENT_COUNT_MAX: number; - - // Server events - - /** - * Emitted when a new client has connected. - */ - on( - event: 'connection', - listener: (client: Connection, info: ClientInfo) => mixed - ): this; - - /** - * Emitted when an error occurs. - */ - on(event: 'error', listener: (err: Error) => mixed): this; - - /** - * Emitted when the server has been bound after calling `server.listen()`. - */ - on(event: 'listening', listener: () => mixed): this; - - /** - * Emitted when the server closes. Note that if connections exist, this event is not emitted until all connections are ended. - */ - on(event: 'close', listener: () => mixed): this; - - on(event: string, listener: Function): this; - - // Server methods - - /** - * Creates and returns a new Server instance. - * - * @param config Server configuration properties. - * @param connectionListener if supplied, is added as a connection listener. - */ - constructor( - config: ServerConfig, - connectionListener?: (client: Connection, info: ClientInfo) => mixed - ): void; - - /** - * Creates and returns a new Server instance. - * - * @param config Server configuration properties. - * @param connectionListener if supplied, is added as a connection listener. - */ - static createServer( - config: ServerConfig, - connectionListener?: (client: Connection, info: ClientInfo) => mixed - ): Server; - - /** - * Start a local socket server listening for connections on the given `path`. - * - * This function is asynchronous. When the server has been bound, `listening` event will be emitted. - * - * @param path A UNIX domain socket path. - * @param backlog The maximum length of the queue of pending connections. - * @param callback An optional callback to add to the `listening` event of the server. - */ - listen( - path: string, - backlog?: number, - callback?: () => mixed - ): this; - - /** - * Start a local socket server listening for connections on the given `path`. - * - * This function is asynchronous. When the server has been bound, `listening` event will be emitted. - * - * @param path A UNIX domain socket path. - * @param callback An optional callback to add to the `listening` event of the server. - */ - listen(path: string, callback?: () => mixed): this; - - /** - * This will cause the server to accept connections on the specified handle, but it is - * presumed that the file descriptor or handle has already been bound to a port or domain - * socket. - * - * This function is asynchronous. When the server has been bound, `listening` event will be emitted. - * - * @param handle Either a server or socket (anything with an underlying `_handle` member), or an `{fd: number}` object. - * @param backlog The maximum length of the queue of pending connections. - * @param callback An optional callback to add to the `listening` event of the server. - */ - listen( - handle: net$Server | net$Socket | { fd: number }, - backlog?: number, - callback?: () => mixed - ): this; - - /** - * This will cause the server to accept connections on the specified handle, but it is - * presumed that the file descriptor or handle has already been bound to a port or domain - * socket. - * - * This function is asynchronous. When the server has been bound, `listening` event will be emitted. - * - * @param handle Either a server or socket (anything with an underlying `_handle` member), or an `{fd: number}` object. - * @param callback An optional callback to add to the `listening` event of the server. - */ - listen( - handle: net$Server | net$Socket | { fd: number }, - callback?: () => mixed - ): this; - - /** - * This will cause the server to accept connections using the specified options. - * - * This function is asynchronous. When the server has been bound, `listening` event will be emitted. - * - * @param options Connection options. - * @param callback An optional callback to add to the `listening` event of the server. - */ - listen( - options: net$ListenOptions, - callback?: () => mixed - ): this; - - /** - * Begin accepting connections on the specified port and hostname. - * - * This function is asynchronous. When the server has been bound, `listening` event will be emitted. - * - * @param port The port on which to start listening. If this value is `undefined` or `0`, - * the operating system will define a random port which can be retrieved later - * using `server.address().port`. - * @param hostname The hostname to bind. If `hostname` is omitted, the server will accept - * conections on any IPv6 address (`::`) when IPv6 is available, or any IPv4 - * address (`0.0.0.0`) otherwise. - * @param backlog The maximum length of the queue of pending connections. - * @param callback An optional callback to add to the `listening` event of the server. - */ - listen( - port: number, - hostname?: string, - backlog?: number, - callback?: () => mixed - ): this; - - /** - * Begin accepting connections on the specified port and hostname. - * - * This function is asynchronous. When the server has been bound, `listening` event will be emitted. - * - * @param port The port on which to start listening. If this value is `undefined` or `0`, - * the operating system will define a random port which can be retrieved later - * using `server.address().port`. - * @param hostname The hostname to bind. If `hostname` is omitted, the server will accept - * conections on any IPv6 address (`::`) when IPv6 is available, or any IPv4 - * address (`0.0.0.0`) otherwise. - * @param callback An optional callback to add to the `listening` event of the server. - */ - listen( - port: number, - hostname?: string, - callback?: () => mixed - ): this; - - /** - * Begin accepting connections on the specified port. - * - * This function is asynchronous. When the server has been bound, `listening` event will be emitted. - * - * @param port The port on which to start listening. If this value is `undefined` or `0`, - * the operating system will define a random port which can be retrieved later - * using `server.address().port`. - * @param backlog The maximum length of the queue of pending connections. - * @param callback An optional callback to add to the `listening` event of the server. - */ - listen( - port: number, - backlog?: number, - callback?: () => mixed - ): this; - - /** - * Begin accepting connections on the specified port. - * - * This function is asynchronous. When the server has been bound, `listening` event will be emitted. - * - * @param port The port on which to start listening. If this value is `undefined` or `0`, - * the operating system will define a random port which can be retrieved later - * using `server.address().port`. - * @param callback An optional callback to add to the `listening` event of the server. - */ - listen(port: number, callback?: () => mixed): this; - - /** - * Begin accepting connections on a random port. - * - * This function is asynchronous. When the server has been bound, `listening` event will be emitted. - * - * @param callback An optional callback to add to the `listening` event of the server. - */ - listen(callback?: () => mixed): this; - - /** - * Returns the bound address, the address family name, and port of the server as reported - * by the operating system. - */ - address(): { port: number; family: string; address: string; }; - - /** - * Asynchronously get the number of concurrent connections on the server. - */ - getConnections( - callback: (err: Error, count: number) => mixed - ): void; - - /** - * Stops the server from accepting new connections and keeps existing connections. This - * function is asynchronous, the server is finally closed when all connections are ended - * and the server emits a 'close' event. - * - * @param callback Optional callback that will be called once the `close` event occurs. - * Unlike that event, it will be called with an `Error` as its only argument if the - * server was not open when it was closed. - */ - close(callback?: (err: Error) => mixed): this; - - /** - * Opposite of `unref`, calling `ref` on a previously unrefd server will not let the - * program exit if it's the only server left (the default behavior). If the server is - * refd calling `ref` again will have no effect. - */ - ref(): void; - - /** - * Calling `unref` on a server will allow the program to exit if this is the only active - * server in the event system. If the server is already unrefd calling `unref` again - * will have no effect. - */ - unref(): void; - } - - declare type ServerConfig = { - /** An array of host private keys. */ - hostKeys: (Buffer | string | EncryptedPrivateKey)[]; - /** Explicit overrides for the default transport layer algorithms used for the connection. */ - algorithms?: Algorithms; - /** A message that is sent to clients immediately upon connection, before handshaking begins. */ - banner?: string; - /** A custom server software name/version identifier. */ - ident?: string; - /** This is the highWaterMark to use for the parser stream (default: `32 * 1024`). */ - highWaterMark?: number; - /** This is the maximum packet size that will be accepted. It should be 35000 bytes or larger to be compatible with other SSH2 implementations. */ - maxPacketSize?: number; - /** A function that receives a single string argument to get detailed (local) debug information. */ - debug?: (information: string) => any; - } - - declare type EncryptedPrivateKey = { - /** A Buffer or string that contains a private key. */ - key: Buffer | string; - /** The passphrase to decrypt a private key. */ - passphrase?: string; - } - - declare type ClientInfo = { - /** The remote address of the connection. */ - ip: string; - /** Information about the client. */ - header: Header; - } - - // TODO(siegebell): made a class to allow returning `this` type, but is possibly an interface - declare class Connection extends events$EventEmitter { - // Connection events - - /** - * Emitted when the client has requested authentication. - */ - on(event: 'authentication', - listener: (authCtx: AuthContext) => mixed): this; - - /** - * Emitted when the client has been successfully authenticated. - */ - on(event: 'ready', listener: () => mixed): this; - - /** - * Emitted when the client has requested a new session. - * Sessions are used to start interactive shells, execute commands, request X11 forwarding, etc. - */ - on(event: 'session', - listener: (accept: () => Session, - reject: () => boolean) => mixed): this; - - /** - * Emitted when the client has requested an outbound (TCP) connection. - */ - on(event: 'tcpip', - listener: (accept: () => ServerChannel, - reject: () => boolean, - info: TcpipRequestInfo) => mixed): this; - - /** - * Emitted when the client has requested a connection to a UNIX domain socket. - */ - on( - event: 'openssh.streamlocal', - listener: ( - accept: () => ServerChannel, - reject: () => boolean, - info: SocketRequestInfo - ) => mixed - ): this; - - /** - * Emitted when the client has sent a global request for name. - * If info.bindPort === 0, you should pass the chosen port to accept so that the client will know what port was bound. - */ - on( - event: 'request', - listener: ( - accept: (chosenPort?: number) => mixed, - reject: () => mixed, - name: 'tcpip-forward' | 'cancel-tcpip-forward', - info: TcpipBindInfo - ) => mixed - ): this; - - /** - * Emitted when the client has sent a global request for name. - */ - on( - event: 'request', - listener: ( - accept: () => mixed, - reject: () => mixed, - name: 'streamlocal-forward@openssh.com' | 'cancel-streamlocal-forward@openssh.com', - info: SocketBindInfo - ) => mixed - ): this; - - /** - * Emitted when the client has sent a global request for name. - * If info.bindPort === 0, you should pass the chosen port to accept so that the client will know what port was bound. - */ - on( - event: 'request', - listener: ( - accept: (chosenPort?: number) => mixed, - reject: () => mixed, - name: string, - info: TcpipBindInfo | SocketBindInfo - ) => mixed - ): this; - - /** - * Emitted when the client has finished rekeying (either client or server initiated). - */ - on(event: 'rekey', listener: () => mixed): this; - - /** - * Emitted when more requests/data can be sent to the client (after a Connection method returned false). - */ - on(event: 'continue', listener: () => mixed): this; - - /** - * Emitted when an error occurrs. - */ - on(event: 'error', listener: (err: Error) => mixed): this; - - /** - * Emitted when the socket has disconnected. - */ - on(event: 'end', listener: () => mixed): this; - - /** - * Emitted when the client socket was closed. - */ - on(event: 'close', listener: (hadError: boolean) => mixed): this; - - on(event: string, listener: Function): this; - - noMoreSessions: boolean; - authenticated: boolean; - - // Connection methods - - /** - * Closes the client connection. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - end(): boolean; - - /** - * Alert the client of an incoming X11 client connection from `originAddr` on port `originPort`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - x11( - originAddr: string, - originPort: number, - callback: (err: Error, channel: ServerChannel) => mixed - ): boolean; - - /** - * Alert the client of an incoming TCP connection on `boundAddr` on port `boundPort` from - * `remoteAddr` on port `remotePort`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - forwardOut( - boundAddr: string, - boundPort: number, - remoteAddr: string, - remotePort: number, - callback: (err: Error, channel: ServerChannel) => mixed - ): boolean; - - /** - * Initiates a rekeying with the client. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - * - * @param callback An optional callback added as a one-time handler for the `rekey` event. - */ - rekey(callback?: (err: Error) => mixed): boolean; - - /** - * Alert the client of an incoming UNIX domain socket connection on socketPath. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - openssh_forwardOutStreamLocal( - socketPath: string, - callback: (err: Error, channel: ServerChannel) => mixed - ): boolean; - } - - // TODO(siegebell): made a class to allow returning `this` type, but is possibly an interface - declare class AuthContextBase extends events$EventEmitter { - /** The client's username. */ - username: string; - /** The service requesting authentication. */ - service: string; - /** The method of authentication. */ - +method: string; - - /** - * Accepts the authentication request. - */ - accept(): void; - - /** - * Rejects the authentication request. - */ - reject(): void; - - /** - * Rejects the authentication request. - */ - reject(isPartialSuccess: boolean): void; - - /** - * Rejects the authentication request. - */ - reject(authMethodsLeft?: string[], isPartialSuccess?: boolean): void; - - /** - * Emitted when the client aborts the authentication request. - */ - on(event: 'abort', listener: (err: Error) => mixed): this; - - on(event: string, listener: Function): this; - } - - declare interface KeyboardAuthContext extends AuthContextBase { - /** The method of authentication. */ - +method: 'keyboard-interactive'; - - /** A list of preferred authentication "sub-methods" sent by the client. */ - submethods: string[]; - - /** - * Send prompts to the client. - * @param prompts The prompts to send to the client. - * @param callback A callback to call with the responses from the client. - */ - prompt( - prompts: string | Prompt | (string | Prompt)[], - callback: () => mixed - ): void; - - /** - * Send prompts to the client. - * @param prompts The prompts to send to the client. - * @param title The title for the prompt. - * @param callback A callback to call with the responses from the client. - */ - prompt( - prompts: string | Prompt | (string | Prompt)[], - title: string, - callback: () => mixed - ): void; - - /** - * Send prompts to the client. - * @param prompts The prompts to send to the client. - * @param title The title for the prompt. - * @param instructions Instructions for the client. - * @param callback A callback to call with the responses from the client. - */ - prompt( - prompts: string | Prompt | (string | Prompt)[], - title: string, - instructions: string, - callback: () => mixed - ): void; - } - - declare interface PublicKeyAuthContext extends AuthContextBase { - /** The method of authentication. */ - +method: 'publickey'; - /** The public key sent by the client. */ - key: PublicKey; - /** The signature to verify, or `undefined` if the client is only checking the validity of the key. */ - signature: ?Buffer; - /** The signature algorithm, or `undefined` if the client is only checking the validity of the key. */ - sigAlgo: ?string; - /** The data used to verify the key, or `undefined` if the client is only checking the validity of the key. */ - blob: ?Buffer; - } - - declare type PublicKey = { - /** The name of the key algorithm. */ - algo: string; - /** The actual key data. */ - data: Buffer; - } - - declare interface HostbasedAuthContext extends AuthContextBase { - /** The method of authentication. */ - +method: 'hostbased'; - /** The public key sent by the client. */ - key: PublicKey; - /** The signature to verify, or `undefined` if the client is only checking the validity of the key. */ - signature: ?Buffer; - /** The signature algorithm, or `undefined` if the client is only checking the validity of the key. */ - sigAlgo: ?string; - /** The data used to verify the key, or `undefined` if the client is only checking the validity of the key. */ - blob: ?Buffer; - /** The local hostname of the client. */ - localHostname: string; - /** The local username of the client. */ - localUsername: string; - } - - declare interface PasswordAuthContext extends AuthContextBase { - /** The method of authentication. */ - +method: 'password'; - /** The password sent by the client. */ - password: string; - } - - declare interface NoneAuthContext extends AuthContextBase { - /** The method of authentication. */ - +method: 'none'; - } - - declare type AuthContext = KeyboardAuthContext | - PublicKeyAuthContext | - HostbasedAuthContext | - PasswordAuthContext | - NoneAuthContext; - - declare type TcpipRequestInfo = { - /** Source IP address of outgoing connection. */ - srcIP: string; - /** Source port of outgoing connection. */ - srcPort: number; - /** Destination IP address of outgoing connection. */ - destIP: string; - /** Destination port of outgoing connection. */ - destPort: number; - } - - declare type SocketRequestInfo = { - /** Destination socket path of outgoing connection. */ - socketPath: string; - } - - declare type TcpipBindInfo = { - /** The IP address to start/stop binding to. */ - bindAddr: string; - /** The port to start/stop binding to. */ - bindPort: number; - } - - declare type SocketBindInfo = { - /** The socket path to start/stop binding to. */ - socketPath: string; - } - - // TODO(siegebell): made a class to allow returning `this` type, but is possibly an interface - declare class Session extends events$EventEmitter { - // Session events - - /** - * Emitted when the client requested allocation of a pseudo-TTY for this session. - */ - on( - event: 'pty', - listener: ( - accept: () => boolean, - reject: () => boolean, - info: PseudoTtyInfo - ) => mixed - ): this; - - /** - * Emitted when the client reported a change in window dimensions during this session. - */ - on( - event: 'window-change', - listener: (accept: () => boolean, reject: () => boolean, info: WindowChangeInfo) => mixed - ): this; - - /** - * Emitted when the client requested X11 forwarding. - */ - on( - event: 'x11', - listener: ( - accept: () => boolean, - reject: () => boolean, - info: X11Info - ) => mixed - ): this; - - /** - * Emitted when the client requested an environment variable to be set for this session. - */ - on( - event: 'env', - listener: ( - accept: () => boolean, - reject: () => boolean, - info: SetEnvInfo - ) => mixed - ): this; - - /** - * Emitted when the client has sent a POSIX signal. - */ - on( - event: 'signal', - listener: ( - accept: () => boolean, - reject: () => boolean, - info: SignalInfo - ) => mixed - ): this; - - /** - * Emitted when the client has requested incoming ssh-agent requests be forwarded to them. - */ - on( - event: 'auth-agent', - listener: ( - accept: () => boolean, - reject: () => boolean - ) => mixed - ): this; - - /** - * Emitted when the client has requested an interactive shell. - */ - on( - event: 'shell', - listener: ( - accept: () => ServerChannel, - reject: () => boolean - ) => mixed - ): this; - - /** - * Emitted when the client has requested execution of a command string. - */ - on( - event: 'exec', - listener: ( - accept: () => ServerChannel, - reject: () => boolean, - info: ExecInfo - ) => mixed - ): this; - - /** - * Emitted when the client has requested the SFTP subsystem. - */ - on( - event: 'sftp', - listener: ( - accept: () => SFTPStream, - reject: () => boolean - ) => mixed - ): this; - - /** - * Emitted when the client has requested an arbitrary subsystem. - */ - on( - event: 'subsystem', - listener: ( - accept: () => ServerChannel, - reject: () => boolean, - info: SubsystemInfo - ) => mixed - ): this; - - /** - * Emitted when the session has closed. - */ - on(event: 'close', listener: () => mixed): this; - - on(event: string, listener: Function): this; - } - - declare type PseudoTtyInfo = { - /** The number of columns for the pseudo-TTY. */ - cols: number; - /** The number of rows for the pseudo-TTY. */ - rows: number; - /** The width of the pseudo-TTY in pixels. */ - width: number; - /** The height of the pseudo-TTY in pixels. */ - height: number; - /** Contains the requested terminal modes of the pseudo-TTY. */ - modes: TerminalModes; - } - - declare type TerminalModes = { - [mode: string]: ?number; - /** Interrupt character; `255` if none. Not all of these characters are supported on all systems. */ - VINTR?: number; - /** The quit character (sends `SIGQUIT` signal on POSIX systems). */ - VQUIT?: number; - /** Erase the character to left of the cursor. */ - VERASE?: number; - /** Kill the current input line. */ - VKILL?: number; - /** End-of-file character (sends `EOF` from the terminal). */ - VEOF?: number; - /** End-of-line character in addition to carriage return and/or linefeed. */ - VEOL?: number; - /** Additional end-of-line character. */ - VEOL2?: number; - /** Continues paused output (normally control-Q). */ - VSTART?: number; - /** Pauses output (normally control-S). */ - VSTOP?: number; - /** Suspends the current program. */ - VSUSP?: number; - /** Another suspend character. */ - VDSUSP?: number; - /** Reprints the current input line. */ - VREPRINT?: number; - /** Erases a word left of cursor. */ - VWERASE?: number; - /** Enter the next character typed literally, even if it is a special character */ - VLNEXT?: number; - /** Character to flush output. */ - VFLUSH?: number; - /** Switch to a different shell layer. */ - VSWTCH?: number; - /** Prints system status line (load, command, pid, etc). */ - VSTATUS?: number; - /** Toggles the flushing of terminal output. */ - VDISCARD?: number; - /** The ignore parity flag. The parameter SHOULD be `0` if this flag is FALSE, and `1` if it is TRUE. */ - IGNPAR?: 0 | 1; - /** Mark parity and framing errors. */ - PARMRK?: 0 | 1; - /** Enable checking of parity errors. */ - INPCK?: 0 | 1; - /** Strip 8th bit off characters. */ - ISTRIP?: 0 | 1; - /** Map NL into CR on input. */ - INLCR?: 0 | 1; - /** Ignore CR on input. */ - IGNCR?: 0 | 1; - /** Map CR to NL on input. */ - ICRNL?: 0 | 1; - /** Translate uppercase characters to lowercase. */ - IUCLC?: 0 | 1; - /** Enable output flow control. */ - IXON?: 0 | 1; - /** Any char will restart after stop. */ - IXANY?: 0 | 1; - /** Enable input flow control. */ - IXOFF?: 0 | 1; - /** Ring bell on input queue full. */ - IMAXBEL?: 0 | 1; - /** Enable signals INTR, QUIT, [D]SUSP. */ - ISIG?: 0 | 1; - /** Canonicalize input lines. */ - ICANON?: 0 | 1; - /** Enable input and output of uppercase characters by preceding their lowercase equivalents with `\`. */ - XCASE?: 0 | 1; - /** Enable echoing. */ - ECHO?: 0 | 1; - /** Visually erase chars. */ - ECHOE?: 0 | 1; - /** Kill character discards current line. */ - ECHOK?: 0 | 1; - /** Echo NL even if ECHO is off. */ - ECHONL?: 0 | 1; - /** Don't flush after interrupt. */ - NOFLSH?: 0 | 1; - /** Stop background jobs from output. */ - TOSTOP?: 0 | 1; - /** Enable extensions. */ - IEXTEN?: 0 | 1; - /** Echo control characters as ^(Char). */ - ECHOCTL?: 0 | 1; - /** Visual erase for line kill. */ - ECHOKE?: 0 | 1; - /** Retype pending input. */ - PENDIN?: 0 | 1; - /** Enable output processing. */ - OPOST?: 0 | 1; - /** Convert lowercase to uppercase. */ - OLCUC?: 0 | 1; - /** Map NL to CR-NL. */ - ONLCR?: 0 | 1; - /** Translate carriage return to newline (output). */ - OCRNL?: 0 | 1; - /** Translate newline to carriage return-newline (output). */ - ONOCR?: 0 | 1; - /** Newline performs a carriage return (output). */ - ONLRET?: 0 | 1; - /** 7 bit mode. */ - CS7?: 0 | 1; - /** 8 bit mode. */ - CS8?: 0 | 1; - /** Parity enable. */ - PARENB?: 0 | 1; - /** Odd parity, else even. */ - PARODD?: 0 | 1; - /** Specifies the input baud rate in bits per second. */ - TTY_OP_ISPEED?: number; - /** Specifies the output baud rate in bits per second. */ - TTY_OP_OSPEED?: number; - } - - declare type WindowChangeInfo = { - /** The number of columns for the pseudo-TTY. */ - cols: number; - /** The number of rows for the pseudo-TTY. */ - rows: number; - /** The width of the pseudo-TTY in pixels. */ - width: number; - /** The height of the pseudo-TTY in pixels. */ - height: number; - } - - declare type X11Info = { - /** true if only a single connection should be forwarded. */ - single: boolean; - /** The name of the X11 authentication method used. */ - protocol: string; - /** The X11 authentication cookie encoded in hexadecimal. */ - cookie: string; - /** The screen number for which to forward X11 connections. */ - screen: number; - } - - declare type SetEnvInfo = { - /** The environment variable's name. */ - key: string; - /** The environment variable's value. */ - value: string; - } - - declare type SignalInfo = { - /** The signal name (e.g. SIGUSR1). */ - name: string; - } - - declare type ExecInfo = { - /** The command line to be executed. */ - command: string; - } - - declare type SubsystemInfo = { - /** The name of the subsystem. */ - name: string; - } - - // TODO(siegebell): made a class to allow returning `this` type, but is possibly an interface - declare class SFTPWrapper extends events$EventEmitter { - /** - * (Client-only) - * Downloads a file at `remotePath` to `localPath` using parallel reads for faster throughput. - */ - fastGet( - remotePath: string, - localPath: string, - options: TransferOptions, - callback: (err: any) => mixed - ): void; - - /** - * (Client-only) - * Downloads a file at `remotePath` to `localPath` using parallel reads for faster throughput. - */ - fastGet( - remotePath: string, - localPath: string, - callback: (err: any) => mixed - ): void; - - /** - * (Client-only) - * Uploads a file from `localPath` to `remotePath` using parallel reads for faster throughput. - */ - fastPut( - localPath: string, - remotePath: string, - options: TransferOptions, - callback: (err: any) => mixed - ): void; - - /** - * (Client-only) - * Uploads a file from `localPath` to `remotePath` using parallel reads for faster throughput. - */ - fastPut( - localPath: string, - remotePath: string, - callback: (err: any) => mixed - ): void; - - /** - * (Client-only) - * Returns a new readable stream for `path`. - */ - createReadStream(path: string, options?: ReadStreamOptions): stream$Readable; - - /** - * (Client-only) - * Returns a new writable stream for `path`. - */ - createWriteStream( - path: string, - options?: WriteStreamOptions - ): stream$Writable; - - /** - * (Client-only) - * Opens a file `filename` for `mode` with optional `attributes`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - open( - filename: string, - mode: string, - attributes: InputAttributes, - callback: (err: any, handle: Buffer) => mixed - ): boolean; - - /** - * (Client-only) - * Opens a file `filename` for `mode`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - open( - filename: string, - mode: string, - callback: (err: any, handle: Buffer) => mixed - ): boolean; - - /** - * (Client-only) - * Closes the resource associated with `handle` given by `open()` or `opendir()`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - close(handle: Buffer, callback: (err: any) => mixed): boolean; - - /** - * (Client-only) - * Reads `length` bytes from the resource associated with `handle` starting at `position` - * and stores the bytes in `buffer` starting at `offset`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - read( - handle: Buffer, - buffer: Buffer, - offset: number, - length: number, - position: number, - callback: ( - err: any, - bytesRead: number, - buffer: Buffer, - position: number - ) => mixed - ): boolean; - - /** - * (Client-only) - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - write( - handle: Buffer, - buffer: Buffer, - offset: number, - length: number, - position: number, - callback: (err: any) => mixed - ): boolean; - - /** - * (Client-only) - * Retrieves attributes for the resource associated with `handle`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - fstat( - handle: Buffer, - callback: (err: any, stats: Stats) => mixed - ): boolean; - - /** - * (Client-only) - * Sets the attributes defined in `attributes` for the resource associated with `handle`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - fsetstat( - handle: Buffer, - attributes: InputAttributes, - callback: (err: any) => mixed - ): boolean; - - /** - * (Client-only) - * Sets the access time and modified time for the resource associated with `handle`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - futimes( - handle: Buffer, - atime: number | Date, - mtime: number | Date, - callback: (err: any) => mixed - ): boolean; - - /** - * (Client-only) - * Sets the owner for the resource associated with `handle`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - fchown( - handle: Buffer, - uid: number, - gid: number, - callback: (err: any) => mixed - ): boolean; - - /** - * (Client-only) - * Sets the mode for the resource associated with `handle`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - fchmod( - handle: Buffer, - mode: number | string, - callback: (err: any) => mixed - ): boolean; - - /** - * (Client-only) - * Opens a directory `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - opendir( - path: string, - callback: (err: any, handle: Buffer) => mixed - ): boolean; - - /** - * (Client-only) - * Retrieves a directory listing. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - readdir( - location: string | Buffer, - callback: (err: any, list: FileEntry[]) => mixed - ): boolean; - - /** - * Reads a file - * @param options either the encoding (string) or a bag of options - */ - readFile(path: string, options?: string | ReadFileOptions, callback?: (error: any, data: string | Buffer) => mixed): void; - - /** - * Writes to a file - * @param options either the encoding (string) or a bag of options - */ - writeFile(path: string, data: string | Buffer, options?: string | WriteFileOptions, callback?: (error: any) => mixed): void; - - /** - * Appends to a file - * @param options either the encoding (string) or a bag of options - */ - appendFile(path: string, data: string | Buffer, options?: string | AppendFileOptions, callback?: (error: any) => mixed): void; - - /** - * (Client-only) - * Checks whether the given file or path exists. - */ - exists(path: string, callback: (exists: boolean) => mixed): void; - - /** - * (Client-only) - * Removes the file/symlink at `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - unlink(path: string, callback: (err: any) => mixed): boolean; - - /** - * (Client-only) - * Renames/moves `srcPath` to `destPath`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - rename( - srcPath: string, - destPath: string, - callback: (err: any) => mixed - ): boolean; - - /** - * (Client-only) - * Creates a new directory `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - mkdir( - path: string, - attributes: InputAttributes, - callback: (err: any) => mixed - ): boolean; - - /** - * (Client-only) - * Creates a new directory `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - mkdir(path: string, callback: (err: any) => mixed): boolean; - - /** - * (Client-only) - * Removes the directory at `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - rmdir(path: string, callback: (err: any) => mixed): boolean; - - /** - * (Client-only) - * Retrieves attributes for `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - stat( - path: string, - callback: (err: any, stats: Stats) => mixed - ): boolean; - - /** - * (Client-only) - * Retrieves attributes for `path`. If `path` is a symlink, the link itself is stat'ed - * instead of the resource it refers to. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - lstat( - path: string, - callback: (err: any, stats: Stats) => mixed - ): boolean; - - /** - * (Client-only) - * Sets the attributes defined in `attributes` for `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - setstat( - path: string, - attributes: InputAttributes, - callback: (err: any) => mixed - ): boolean; - - /** - * (Client-only) - * Sets the access time and modified time for `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - utimes( - path: string, - atime: number | Date, - mtime: number | Date, - callback: (err: any) => mixed - ): boolean; - - /** - * (Client-only) - * Sets the owner for `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - chown( - path: string, - uid: number, - gid: number, - callback: (err: any) => mixed - ): boolean; - - /** - * (Client-only) - * Sets the mode for `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - chmod( - path: string, - mode: number | string, - callback: (err: any) => mixed - ): boolean; - - /** - * (Client-only) - * Retrieves the target for a symlink at `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - readlink( - path: string, - callback: (err: any, target: string) => mixed - ): boolean; - - /** - * (Client-only) - * Creates a symlink at `linkPath` to `targetPath`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - symlink( - targetPath: string, - linkPath: string, - callback: (err: any) => mixed - ): boolean; - - /** - * (Client-only) - * Resolves `path` to an absolute path. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - realpath( - path: string, - callback: (err: any, absPath: string) => mixed - ): boolean; - - /** - * (Client-only, OpenSSH extension) - * Performs POSIX rename(3) from `srcPath` to `destPath`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - ext_openssh_rename( - srcPath: string, - destPath: string, - callback: (err: any) => mixed - ): boolean; - - /** - * (Client-only, OpenSSH extension) - * Performs POSIX statvfs(2) on `path`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - ext_openssh_statvfs( - path: string, - callback: (err: any, fsInfo: any) => mixed - ): boolean; - - /** - * (Client-only, OpenSSH extension) - * Performs POSIX fstatvfs(2) on open handle `handle`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - ext_openssh_fstatvfs( - handle: Buffer, - callback: (err: any, fsInfo: any) => mixed - ): boolean; - - /** - * (Client-only, OpenSSH extension) - * Performs POSIX link(2) to create a hard link to `targetPath` at `linkPath`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - ext_openssh_hardlink( - targetPath: string, - linkPath: string, - callback: (err: any) => mixed - ): boolean; - - /** - * (Client-only, OpenSSH extension) - * Performs POSIX fsync(3) on the open handle `handle`. - * - * Returns `false` if you should wait for the `continue` event before sending any more traffic. - */ - ext_openssh_fsync( - handle: Buffer, - callback: (err: any, fsInfo: any) => mixed - ): boolean; - - /** - * Ends the stream. - */ - end(): void; - - /** - * Emitted when an error occurred. - */ - on(event: 'error', listener: (err: any) => mixed): this; - - /** - * Emitted when the session has ended. - */ - on(event: 'end', listener: () => mixed): this; - - /** - * Emitted when the session has closed. - */ - on(event: 'close', listener: () => mixed): this; - - /** - * Emitted when more requests/data can be sent to the stream. - */ - on(event: 'continue', listener: () => mixed): this; - - on(event: string, listener: Function): this; - } -} diff --git a/flow-libs/suda-toolbar.js.flow b/flow-libs/suda-toolbar.js.flow deleted file mode 100644 index 2b6af67962..0000000000 --- a/flow-libs/suda-toolbar.js.flow +++ /dev/null @@ -1,34 +0,0 @@ -/** - * 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 - */ - -type toolbar$ButtonSpec = { - priority?: number, - tooltip?: string, - iconset?: string, - icon?: string, - callback?: string | (() => void), -} - -type toolbar$ToolbarManager = { - addButton(options: toolbar$ButtonSpec): toolbar$ToolbarButtonView, - addSpacer(options: { - priority?: number, - }): toolbar$ToolbarButtonView, - removeItems(): void, - onDidDestroy(callback: () => void): IDisposable, -}; - -type toolbar$ToolbarButtonView = { - setEnabled(enabled: boolean): void, - destroy(): void, - element: HTMLElement, -}; - -type toolbar$GetToolbar = (group: string) => toolbar$ToolbarManager; diff --git a/flow-libs/uuid.js.flow b/flow-libs/uuid.js.flow deleted file mode 100644 index 968d8ce83f..0000000000 --- a/flow-libs/uuid.js.flow +++ /dev/null @@ -1,19 +0,0 @@ -/** - * 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 - */ - -/** - * The `uuid` generates RFC-compliant UUIDs in JavaScript. It has a more - * extensive API than the one defined here, but this all we use from it. - * - * {@link https://github.com/broofa/node-uuid} - */ -declare module 'uuid' { - declare function v4(): string; -} diff --git a/flow-libs/vscode-debugprotocol.js.flow b/flow-libs/vscode-debugprotocol.js.flow deleted file mode 100644 index 38826f7e27..0000000000 --- a/flow-libs/vscode-debugprotocol.js.flow +++ /dev/null @@ -1,1509 +0,0 @@ -/** - * 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 - */ - -// Ported from https://github.com/Microsoft/vscode-debugadapter-node/blob/master/protocol/src/debugProtocol.ts - -declare module 'vscode-debugprotocol' { - declare interface base$ProtocolMessage { - /** Sequence number. */ - seq: number; - /** One of 'request', 'response', or 'event'. */ - +type: 'request' | 'response' | 'event'; - } - - declare type ProtocolMessage = Request | Event | Response; - - declare interface base$Request extends base$ProtocolMessage { - type: 'request'; - /** The command to execute. */ - +command: string; - /** Object containing arguments for the command. */ - +arguments?: any; - } - - /** Server-initiated event. */ - declare interface DebugEvent extends base$ProtocolMessage { - type: 'event'; - /** Type of event. */ - +event: string; - /** Event-specific information. */ - +body?: any; - } - - /** Response to a request. */ - declare interface base$Response extends base$ProtocolMessage { - type: 'response'; - /** Sequence number of the corresponding request. */ - request_seq: number; - /** Outcome of the request. */ - success: boolean; - /** The command requested. */ - command: string; - /** Contains error message if success == false. */ - message?: string; - /** Contains request result if success is true and optional error details if success is false. */ - +body?: any; - } - - declare interface InitializedEvent extends DebugEvent { - event: 'initialized'; - } - - declare interface StoppedEvent extends DebugEvent { - event: 'stopped'; - body: { - /** The reason for the event (such as: 'step', 'breakpoint', 'exception', 'pause', 'entry'). - For backward compatibility this string is shown in the UI if the 'description' attribute is missing (but it must not be translated). - */ - reason: string, - /** The full reason for the event, e.g. 'Paused on exception'. This string is shown in the UI as is. */ - description?: string, - /** The thread which was stopped. */ - threadId?: number, - /** Additional information. E.g. if reason is 'exception', text contains the exception name. This string is shown in the UI. */ - text?: string, - /** If allThreadsStopped is true, a debug adapter can announce that all threads have stopped. - * The client should use this information to enable that all threads can be expanded to access their stacktraces. - * If the attribute is missing or false, only the thread with the given threadId can be expanded. - */ - allThreadsStopped?: boolean, - }; - } - - declare interface ContinuedEvent extends DebugEvent { - event: 'continued'; - body: { - /** The thread which was continued. */ - threadId: number, - /** If allThreadsContinued is true, a debug adapter can announce that all threads have continued. */ - allThreadsContinued?: boolean, - }; - } - - /** Event message for 'exited' event type. - The event indicates that the debuggee has exited. - */ - declare interface ExitedEvent extends DebugEvent { - event: 'exited'; - body: { - /** The exit code returned from the debuggee. */ - exitCode: number, - }; - } - - /** Event message for 'terminated' event types. - The event indicates that debugging of the debuggee has terminated. - */ - declare interface TerminatedEvent extends DebugEvent { - event: 'terminated'; - body?: { - /** A debug adapter may set 'restart' to true to request that the front end restarts the session. */ - restart?: boolean, - }; - } - - /** Event message for 'thread' event type. - The event indicates that a thread has started or exited. - */ - declare interface ThreadEvent extends DebugEvent { - event: 'thread'; - body: { - /** The reason for the event (such as: 'started', 'exited'). */ - reason: string, - /** The identifier of the thread. */ - threadId: number, - }; - } - - /** Event message for 'output' event type. - The event indicates that the target has produced some output. - */ - declare interface OutputEvent extends DebugEvent { - event: 'output'; - body: { - /** The category of output (such as: 'console', 'stdout', 'stderr', 'telemetry'). If not specified, 'console' is assumed. */ - category?: string, - /** The output to report. */ - output: string, - /** An optional source location where the output was produced. */ - source?: Source, - /** An optional source location line where the output was produced. */ - line?: number, - /** An optional source location column where the output was produced. */ - column?: number, - /** If an attribute 'variablesReference' exists and its value is > 0, the output contains objects which can be retrieved by passing variablesReference to the VariablesRequest. */ - variablesReference?: number, - /** Optional data to report. For the 'telemetry' category the data will be sent to telemetry, for the other categories the data is shown in JSON format. */ - data?: any, - }; - } - - /** Event message for 'breakpoint' event type. - The event indicates that some information about a breakpoint has changed. - */ - declare interface BreakpointEvent extends DebugEvent { - event: 'breakpoint'; - body: { - /** The reason for the event (such as: 'changed', 'new'). */ - reason: string, - /** The breakpoint. */ - breakpoint: Breakpoint, - }; - } - - /** Event message for 'module' event type. - The event indicates that some information about a module has changed. - */ - declare interface ModuleEvent extends DebugEvent { - event: 'module'; - body: { - /** The reason for the event. */ - reason: 'new' | 'changed' | 'removed', - /** The new, changed, or removed module. In case of 'removed' only the module id is used. */ - module: Module, - }; - } - - declare interface LoadedSourceEvent extends DebugEvent { - event: 'loadedSource'; - body: { - /** The reason for the event. */ - reason: 'new' | 'changed' | 'removed', - /** The new, changed, or removed source. */ - source: Source, - }; - } - - /** runInTerminal request; value of command field is 'runInTerminal'. - With this request a debug adapter can run a command in a terminal. - */ - declare interface RunInTerminalRequest extends base$Request { - command: 'runInTerminal'; - arguments: RunInTerminalRequestArguments; - } - - /** Arguments for 'runInTerminal' request. */ - declare type RunInTerminalRequestArguments = { - /** What kind of terminal to launch. */ - kind?: 'integrated' | 'external', - /** Optional title of the terminal. */ - title?: string, - /** Working directory of the command. */ - cwd: string, - /** List of arguments. The first argument is the command to run. */ - args: string[], - /** Environment key-value pairs that are added to the default environment. */ - env?: {[key: string]: string}, - }; - - /** Response to Initialize request. */ - declare interface RunInTerminalResponse extends base$Response { - body: { - /** The process ID. */ - processId?: number, - }; - } - - /** On error that is whenever 'success' is false, the body can provide more details. */ - declare interface ErrorResponse extends base$Response { - body: { - /** An optional, structured error message. */ - error?: Message, - }; - } - - /** Initialize request; value of command field is 'initialize'. */ - declare interface InitializeRequest extends base$Request { - command: 'initialize'; - arguments: InitializeRequestArguments; - } - - /** Arguments for 'initialize' request. */ - declare type InitializeRequestArguments = { - /** The ID of the (frontend) client using this adapter. */ - clientID?: string, - /** The ID of the debug adapter. */ - adapterID: string, - /** If true all line numbers are 1-based (default). */ - linesStartAt1?: boolean, - /** If true all column numbers are 1-based (default). */ - columnsStartAt1?: boolean, - /** Determines in what format paths are specified. Possible values are 'path' or 'uri'. The default is 'path', which is the native format. */ - pathFormat?: string, - /** Client supports the optional type attribute for variables. */ - supportsVariableType?: boolean, - /** Client supports the paging of variables. */ - supportsVariablePaging?: boolean, - /** Client supports the runInTerminal request. */ - supportsRunInTerminalRequest?: boolean, - }; - - /** Response to 'initialize' request. */ - declare interface InitializeResponse extends base$Response { - /** The capabilities of this debug adapter. */ - body?: Capabilities; - } - - /** ConfigurationDone request; value of command field is 'configurationDone'. - The client of the debug protocol must send this request at the end of the sequence of configuration requests (which was started by the InitializedEvent). - */ - declare interface ConfigurationDoneRequest extends base$Request { - command: 'configurationDone'; - arguments?: ConfigurationDoneArguments; - } - - /** Arguments for 'configurationDone' request. - The configurationDone request has no standardized attributes. - */ - declare type ConfigurationDoneArguments = {}; - - /** Response to 'configurationDone' request. This is just an acknowledgement, so no body field is required. */ - declare interface ConfigurationDoneResponse extends base$Response {} - - /** Launch request; value of command field is 'launch'. */ - declare interface LaunchRequest extends base$Request { - command: 'launch'; - arguments: LaunchRequestArguments; - } - - /** Arguments for 'launch' request. */ - declare type LaunchRequestArguments = { - /** If noDebug is true the launch request should launch the program without enabling debugging. */ - noDebug?: boolean, - }; - - /** Response to 'launch' request. Extending the capabilities is allowed here. */ - declare interface LaunchResponse extends base$Response { - body?: Capabilities; - } - - /** Attach request; value of command field is 'attach'. */ - declare interface AttachRequest extends base$Request { - command: 'attach'; - arguments: AttachRequestArguments; - } - - /** Arguments for 'attach' request. - The attach request has no standardized attributes. - */ - declare interface AttachRequestArguments {} - - /** Response to 'attach' request. Extending the capabilities is allowed here. */ - declare interface AttachResponse extends base$Response { - body?: Capabilities; - } - - /** Restart request; value of command field is 'restart'. - Restarts a debug session. If the capability 'supportsRestartRequest' is missing or has the value false, - the client will implement 'restart' by terminating the debug adapter first and then launching it anew. - A debug adapter can override this default behaviour by implementing a restart request - and setting the capability 'supportsRestartRequest' to true. - */ - declare interface RestartRequest extends base$Request { - command: 'restart'; - arguments?: RestartArguments; - } - - /** Arguments for 'restart' request. - The restart request has no standardized attributes. - */ - declare type RestartArguments = {}; - - /** Response to 'restart' request. This is just an acknowledgement, so no body field is required. */ - declare interface RestartResponse extends base$Response {} - - /** Disconnect request; value of command field is 'disconnect'. */ - declare interface DisconnectRequest extends base$Request { - command: 'disconnect'; - arguments?: DisconnectArguments; - } - - /** Arguments for 'disconnect' request. */ - declare type DisconnectArguments = { - /** Indicates whether the debuggee should be terminated when the debugger is disconnected. - If unspecified, the debug adapter is free to do whatever it thinks is best. - A client can only rely on this attribute being properly honored if a debug adapter returns true for the 'supportTerminateDebuggee' capability. - */ - terminateDebuggee?: boolean, - }; - - /** Response to 'disconnect' request. This is just an acknowledgement, so no body field is required. */ - declare interface DisconnectResponse extends base$Response {} - - /** SetBreakpoints request; value of command field is 'setBreakpoints'. - Sets multiple breakpoints for a single source and clears all previous breakpoints in that source. - To clear all breakpoint for a source, specify an empty array. - When a breakpoint is hit, a StoppedEvent (event type 'breakpoint') is generated. - */ - declare interface SetBreakpointsRequest extends base$Request { - command: 'setBreakpoints'; - arguments: SetBreakpointsArguments; - } - - /** Arguments for 'setBreakpoints' request. */ - declare type SetBreakpointsArguments = { - /** The source location of the breakpoints; either source.path or source.reference must be specified. */ - source: Source, - /** The code locations of the breakpoints. */ - breakpoints?: SourceBreakpoint[], - /** Deprecated: The code locations of the breakpoints. */ - lines?: number[], - /** A value of true indicates that the underlying source has been modified which results in new breakpoint locations. */ - sourceModified?: boolean, - }; - - /** Response to 'setBreakpoints' request. - Returned is information about each breakpoint created by this request. - This includes the actual code location and whether the breakpoint could be verified. - The breakpoints returned are in the same order as the elements of the 'breakpoints' - (or the deprecated 'lines') in the SetBreakpointsArguments. - */ - declare interface SetBreakpointsResponse extends base$Response { - body: { - /** Information about the breakpoints. The array elements are in the same order as the elements of the 'breakpoints' (or the deprecated 'lines') in the SetBreakpointsArguments. */ - breakpoints: Breakpoint[], - }; - } - - /** SetFunctionBreakpoints request; value of command field is 'setFunctionBreakpoints'. - Sets multiple function breakpoints and clears all previous function breakpoints. - To clear all function breakpoint, specify an empty array. - When a function breakpoint is hit, a StoppedEvent (event type 'function breakpoint') is generated. - */ - declare interface SetFunctionBreakpointsRequest extends base$Request { - command: 'setFunctionBreakpoints'; - arguments: SetFunctionBreakpointsArguments; - } - - /** Arguments for 'setFunctionBreakpoints' request. */ - declare type SetFunctionBreakpointsArguments = { - /** The function names of the breakpoints. */ - breakpoints: FunctionBreakpoint[], - }; - - /** Response to 'setFunctionBreakpoints' request. - Returned is information about each breakpoint created by this request. - */ - declare interface SetFunctionBreakpointsResponse extends base$Response { - body: { - /** Information about the breakpoints. The array elements correspond to the elements of the 'breakpoints' array. */ - breakpoints: Breakpoint[], - }; - } - - /** SetExceptionBreakpoints request; value of command field is 'setExceptionBreakpoints'. - The request configures the debuggers response to thrown exceptions. If an exception is configured to break, a StoppedEvent is fired (event type 'exception'). - */ - declare interface SetExceptionBreakpointsRequest extends base$Request { - command: 'setExceptionBreakpoints'; - arguments: SetExceptionBreakpointsArguments; - } - - /** Arguments for 'setExceptionBreakpoints' request. */ - declare type SetExceptionBreakpointsArguments = { - /** IDs of checked exception options. The set of IDs is returned via the 'exceptionBreakpointFilters' capability. */ - filters: string[], - /** Configuration options for selected exceptions. */ - exceptionOptions?: ExceptionOptions[], - }; - - /** Response to 'setExceptionBreakpoints' request. This is just an acknowledgement, so no body field is required. */ - declare interface SetExceptionBreakpointsResponse extends base$Response {} - - /** Continue request; value of command field is 'continue'. - The request starts the debuggee to run again. - */ - declare interface ContinueRequest extends base$Request { - command: 'continue'; - arguments: ContinueArguments; - } - - /** Arguments for 'continue' request. */ - declare type ContinueArguments = { - /** Continue execution for the specified thread (if possible). If the backend cannot continue on a single thread but will continue on all threads, it should set the allThreadsContinued attribute in the response to true. */ - threadId: number, - }; - - /** Response to 'continue' request. */ - declare interface ContinueResponse extends base$Response { - body: { - /** If true, the continue request has ignored the specified thread and continued all threads instead. If this attribute is missing a value of 'true' is assumed for backward compatibility. */ - allThreadsContinued?: boolean, - }; - } - - declare interface nuclide_ContinueToLocationRequest extends base$Request { - command: 'nuclide_continueToLocation'; - arguments: nuclide_ContinueToLocationArguments; - } - - /** Arguments for 'nuclide_continueToLocation' request. */ - declare interface nuclide_ContinueToLocationArguments { - /** The source location for which the goto targets are determined. */ - source: Source; - /** The line location for which the goto targets are determined. */ - line: number; - /** An optional column location for which the goto targets are determined. */ - column?: number; - /** Thread ID the location is associated with. */ - threadId?: number; - } - - /** Response to 'nuclide_continueToLocation' request. */ - declare interface nuclide_ContinueToLocationResponse extends base$Response {} - - /** Next request; value of command field is 'next'. - The request starts the debuggee to run again for one step. - The debug adapter first sends the NextResponse and then a StoppedEvent (event type 'step') after the step has completed. - */ - declare interface NextRequest extends base$Request { - command: 'next'; - arguments: NextArguments; - } - - /** Arguments for 'next' request. */ - declare type NextArguments = { - /** Execute 'next' for this thread. */ - threadId: number, - }; - - /** Response to 'next' request. This is just an acknowledgement, so no body field is required. */ - declare interface NextResponse extends base$Response {} - - /** StepIn request; value of command field is 'stepIn'. - The request starts the debuggee to step into a function/method if possible. - If it cannot step into a target, 'stepIn' behaves like 'next'. - The debug adapter first sends the StepInResponse and then a StoppedEvent (event type 'step') after the step has completed. - If there are multiple function/method calls (or other targets) on the source line, - the optional argument 'targetId' can be used to control into which target the 'stepIn' should occur. - The list of possible targets for a given source line can be retrieved via the 'stepInTargets' request. - */ - declare interface StepInRequest extends base$Request { - command: 'stepIn'; - arguments: StepInArguments; - } - - /** Arguments for 'stepIn' request. */ - declare type StepInArguments = { - /** Execute 'stepIn' for this thread. */ - threadId: number, - /** Optional id of the target to step into. */ - targetId?: number, - }; - - /** Response to 'stepIn' request. This is just an acknowledgement, so no body field is required. */ - declare interface StepInResponse extends base$Response {} - - /** StepOut request; value of command field is 'stepOut'. - The request starts the debuggee to run again for one step. - The debug adapter first sends the StepOutResponse and then a StoppedEvent (event type 'step') after the step has completed. - */ - declare interface StepOutRequest extends base$Request { - command: 'stepOut'; - arguments: StepOutArguments; - } - - /** Arguments for 'stepOut' request. */ - declare type StepOutArguments = { - /** Execute 'stepOut' for this thread. */ - threadId: number, - }; - - /** Response to 'stepOut' request. This is just an acknowledgement, so no body field is required. */ - declare interface StepOutResponse extends base$Response {} - - /** StepBack request; value of command field is 'stepBack'. - The request starts the debuggee to run one step backwards. - The debug adapter first sends the StepBackResponse and then a StoppedEvent (event type 'step') after the step has completed. Clients should only call this request if the capability supportsStepBack is true. - */ - declare interface StepBackRequest extends base$Request { - command: 'stepBack'; - arguments: StepBackArguments; - } - - /** Arguments for 'stepBack' request. */ - declare type StepBackArguments = { - /** Exceute 'stepBack' for this thread. */ - threadId: number, - }; - - /** Response to 'stepBack' request. This is just an acknowledgement, so no body field is required. */ - declare interface StepBackResponse extends base$Response {} - - /** ReverseContinue request; value of command field is 'reverseContinue'. - The request starts the debuggee to run backward. Clients should only call this request if the capability supportsStepBack is true. - */ - declare interface ReverseContinueRequest extends base$Request { - command: 'reverseContinue'; - arguments: ReverseContinueArguments; - } - - /** Arguments for 'reverseContinue' request. */ - declare type ReverseContinueArguments = { - /** Exceute 'reverseContinue' for this thread. */ - threadId: number, - }; - - /** Response to 'reverseContinue' request. This is just an acknowledgement, so no body field is required. */ - declare interface ReverseContinueResponse extends base$Response {} - - /** RestartFrame request; value of command field is 'restartFrame'. - The request restarts execution of the specified stackframe. - The debug adapter first sends the RestartFrameResponse and then a StoppedEvent (event type 'restart') after the restart has completed. - */ - declare interface RestartFrameRequest extends base$Request { - command: 'restartFrame'; - arguments: RestartFrameArguments; - } - - /** Arguments for 'restartFrame' request. */ - declare type RestartFrameArguments = { - /** Restart this stackframe. */ - frameId: number, - }; - - /** Response to 'restartFrame' request. This is just an acknowledgement, so no body field is required. */ - declare interface RestartFrameResponse extends base$Response {} - - /** Goto request; value of command field is 'goto'. - The request sets the location where the debuggee will continue to run. - This makes it possible to skip the execution of code or to executed code again. - The code between the current location and the goto target is not executed but skipped. - The debug adapter first sends the GotoResponse and then a StoppedEvent (event type 'goto'). - */ - declare interface GotoRequest extends base$Request { - command: 'goto'; - arguments: GotoArguments; - } - - /** Arguments for 'goto' request. */ - declare type GotoArguments = { - /** Set the goto target for this thread. */ - threadId: number, - /** The location where the debuggee will continue to run. */ - targetId: number, - }; - - /** Response to 'goto' request. This is just an acknowledgement, so no body field is required. */ - declare interface GotoResponse extends base$Response {} - - /** Pause request; value of command field is 'pause'. - The request suspenses the debuggee. - The debug adapter first sends the PauseResponse and then a StoppedEvent (event type 'pause') after the thread has been paused successfully. - */ - declare interface PauseRequest extends base$Request { - command: 'pause'; - arguments: PauseArguments; - } - - /** Arguments for 'pause' request. */ - declare type PauseArguments = { - /** Pause execution for this thread. */ - threadId: number, - }; - - /** Response to 'pause' request. This is just an acknowledgement, so no body field is required. */ - declare interface PauseResponse extends base$Response {} - - /** StackTrace request; value of command field is 'stackTrace'. The request returns a stacktrace from the current execution state. */ - declare interface StackTraceRequest extends base$Request { - command: 'stackTrace'; - arguments: StackTraceArguments; - } - - /** Arguments for 'stackTrace' request. */ - declare type StackTraceArguments = { - /** Retrieve the stacktrace for this thread. */ - threadId: number, - /** The index of the first frame to return; if omitted frames start at 0. */ - startFrame?: number, - /** The maximum number of frames to return. If levels is not specified or 0, all frames are returned. */ - levels?: number, - /** Specifies details on how to format the stack frames. */ - format?: StackFrameFormat, - }; - - /** Response to 'stackTrace' request. */ - declare interface StackTraceResponse extends base$Response { - body: { - /** The frames of the stackframe. If the array has length zero, there are no stackframes available. - This means that there is no location information available. - */ - stackFrames: StackFrame[], - /** The total number of frames available. */ - totalFrames?: number, - }; - } - - /** Scopes request; value of command field is 'scopes'. - The request returns the variable scopes for a given stackframe ID. - */ - declare interface ScopesRequest extends base$Request { - command: 'scopes'; - arguments: ScopesArguments; - } - - /** Arguments for 'scopes' request. */ - declare type ScopesArguments = { - /** Retrieve the scopes for this stackframe. */ - frameId: number, - }; - - /** Response to 'scopes' request. */ - declare interface ScopesResponse extends base$Response { - body: { - /** The scopes of the stackframe. If the array has length zero, there are no scopes available. */ - scopes: Scope[], - }; - } - - /** Variables request; value of command field is 'variables'. - Retrieves all child variables for the given variable reference. - An optional filter can be used to limit the fetched children to either named or indexed children. - */ - declare interface VariablesRequest extends base$Request { - command: 'variables'; - arguments: VariablesArguments; - } - - /** Arguments for 'variables' request. */ - declare type VariablesArguments = { - /** The Variable reference. */ - variablesReference: number, - /** Optional filter to limit the child variables to either named or indexed. If omitted, both types are fetched. */ - filter?: 'indexed' | 'named', - /** The index of the first variable to return; if omitted children start at 0. */ - start?: number, - /** The number of variables to return. If count is missing or 0, all variables are returned. */ - count?: number, - /** Specifies details on how to format the Variable values. */ - format?: ValueFormat, - }; - - /** Response to 'variables' request. */ - declare interface VariablesResponse extends base$Response { - body: { - /** All (or a range) of variables for the given variable reference. */ - variables: Variable[], - }; - } - - /** setVariable request; value of command field is 'setVariable'. - Set the variable with the given name in the variable container to a new value. - */ - declare interface SetVariableRequest extends base$Request { - command: 'setVariable'; - arguments: SetVariableArguments; - } - - /** Arguments for 'setVariable' request. */ - declare type SetVariableArguments = { - /** The reference of the variable container. */ - variablesReference: number, - /** The name of the variable. */ - name: string, - /** The value of the variable. */ - value: string, - /** Specifies details on how to format the response value. */ - format?: ValueFormat, - }; - - /** Response to 'setVariable' request. */ - declare interface SetVariableResponse extends base$Response { - body: { - /** The new value of the variable. */ - value: string, - /** The type of the new value. Typically shown in the UI when hovering over the value. */ - type?: string, - /** If variablesReference is > 0, the new value is structured and its children can be retrieved by passing variablesReference to the VariablesRequest. */ - variablesReference?: number, - /** The number of named child variables. - The client can use this optional information to present the variables in a paged UI and fetch them in chunks. - */ - namedVariables?: number, - /** The number of indexed child variables. - The client can use this optional information to present the variables in a paged UI and fetch them in chunks. - */ - indexedVariables?: number, - }; - } - - /** Source request; value of command field is 'source'. - The request retrieves the source code for a given source reference. - */ - declare interface SourceRequest extends base$Request { - command: 'source'; - arguments: SourceArguments; - } - - /** Arguments for 'source' request. */ - declare type SourceArguments = { - /** Specifies the source content to load. Either source.path or source.sourceReference must be specified. */ - source?: Source, - /** The reference to the source. This is the same as source.sourceReference. This is provided for backward compatibility since old backends do not understand the 'source' attribute. */ - sourceReference: number, - }; - - /** Response to 'source' request. */ - declare interface SourceResponse extends base$Response { - body: { - /** Content of the source reference. */ - content: string, - /** Optional content type (mime type) of the source. */ - mimeType?: string, - }; - } - - /** Thread request; value of command field is 'threads'. - The request retrieves a list of all threads. - */ - declare interface ThreadsRequest extends base$Request { - command: 'threads'; - } - - /** Response to 'threads' request. */ - declare interface ThreadsResponse extends base$Response { - body: { - /** All threads. */ - threads: Thread[], - }; - } - - /** Modules can be retrieved from the debug adapter with the ModulesRequest which can either return all modules or a range of modules to support paging. */ - declare interface ModulesRequest extends base$Request { - command: 'modules'; - arguments: ModulesArguments; - } - - /** Arguments for 'modules' request. */ - declare type ModulesArguments = { - /** The index of the first module to return; if omitted modules start at 0. */ - startModule?: number, - /** The number of modules to return. If moduleCount is not specified or 0, all modules are returned. */ - moduleCount?: number, - }; - - /** Response to 'modules' request. */ - declare interface ModulesResponse extends base$Response { - body: { - /** All modules or range of modules. */ - modules: Module[], - /** The total number of modules available. */ - totalModules?: number, - }; - } - - /** Evaluate request; value of command field is 'evaluate'. - Evaluates the given expression in the context of the top most stack frame. - The expression has access to any variables and arguments that are in scope. - */ - declare interface EvaluateRequest extends base$Request { - command: 'evaluate'; - arguments: EvaluateArguments; - } - - /** Arguments for 'evaluate' request. */ - declare type EvaluateArguments = { - /** The expression to evaluate. */ - expression: string, - /** Evaluate the expression in the scope of this stack frame. If not specified, the expression is evaluated in the global scope. */ - frameId?: number, - /** The context in which the evaluate request is run. Possible values are 'watch' if evaluate is run in a watch, 'repl' if run from the REPL console, or 'hover' if run from a data hover. */ - context?: string, - /** Specifies details on how to format the Evaluate result. */ - format?: ValueFormat, - }; - - /** Response to 'evaluate' request. */ - declare interface EvaluateResponse extends base$Response { - body: { - /** The result of the evaluate request. */ - result: string, - /** The optional type of the evaluate result. */ - type?: string, - /** If variablesReference is > 0, the evaluate result is structured and its children can be retrieved by passing variablesReference to the VariablesRequest. */ - variablesReference: number, - /** The number of named child variables. - The client can use this optional information to present the variables in a paged UI and fetch them in chunks. - */ - namedVariables?: number, - /** The number of indexed child variables. - The client can use this optional information to present the variables in a paged UI and fetch them in chunks. - */ - indexedVariables?: number, - }; - } - - /** StepInTargets request; value of command field is 'stepInTargets'. - This request retrieves the possible stepIn targets for the specified stack frame. - These targets can be used in the 'stepIn' request. - The StepInTargets may only be called if the 'supportsStepInTargetsRequest' capability exists and is true. - */ - declare interface StepInTargetsRequest extends base$Request { - command: 'stepInTargets'; - arguments: StepInTargetsArguments; - } - - /** Arguments for 'stepInTargets' request. */ - declare type StepInTargetsArguments = { - /** The stack frame for which to retrieve the possible stepIn targets. */ - frameId: number, - }; - - /** Response to 'stepInTargets' request. */ - declare interface StepInTargetsResponse extends base$Response { - body: { - /** The possible stepIn targets of the specified source location. */ - targets: StepInTarget[], - }; - } - - /** GotoTargets request; value of command field is 'gotoTargets'. - This request retrieves the possible goto targets for the specified source location. - These targets can be used in the 'goto' request. - The GotoTargets request may only be called if the 'supportsGotoTargetsRequest' capability exists and is true. - */ - declare interface GotoTargetsRequest extends base$Request { - command: 'gotoTargets'; - arguments: GotoTargetsArguments; - } - - /** Arguments for 'gotoTargets' request. */ - declare type GotoTargetsArguments = { - /** The source location for which the goto targets are determined. */ - source: Source, - /** The line location for which the goto targets are determined. */ - line: number, - /** An optional column location for which the goto targets are determined. */ - column?: number, - }; - - /** Response to 'gotoTargets' request. */ - declare interface GotoTargetsResponse extends base$Response { - body: { - /** The possible goto targets of the specified location. */ - targets: GotoTarget[], - }; - } - - /** CompletionsRequest request; value of command field is 'completions'. - Returns a list of possible completions for a given caret position and text. - The CompletionsRequest may only be called if the 'supportsCompletionsRequest' capability exists and is true. - */ - declare interface CompletionsRequest extends base$Request { - command: 'completions'; - arguments: CompletionsArguments; - } - - /** Arguments for 'completions' request. */ - declare type CompletionsArguments = { - /** Returns completions in the scope of this stack frame. If not specified, the completions are returned for the global scope. */ - frameId?: number, - /** One or more source lines. Typically this is the text a user has typed into the debug console before he asked for completion. */ - text: string, - /** The character position for which to determine the completion proposals. */ - column: number, - /** An optional line for which to determine the completion proposals. If missing the first line of the text is assumed. */ - line?: number, - }; - - /** Response to 'completions' request. */ - declare interface CompletionsResponse extends base$Response { - body: { - /** The possible completions for . */ - targets: CompletionItem[], - }; - } - - /** ExceptionInfoRequest request; value of command field is 'exceptionInfo'. - Retrieves the details of the exception that caused the StoppedEvent to be raised. - */ - declare interface ExceptionInfoRequest extends base$Request { - command: 'exceptionInfo'; - arguments: ExceptionInfoArguments; - } - - /** Arguments for 'exceptionInfo' request. */ - declare interface ExceptionInfoArguments { - /** Thread for which exception information should be retrieved. */ - threadId: number; - } - - /** Response to 'exceptionInfo' request. */ - declare interface ExceptionInfoResponse extends base$Response { - body: { - /** ID of the exception that was thrown. */ - exceptionId: string, - /** Descriptive text for the exception provided by the debug adapter. */ - description?: string, - /** Mode that caused the exception notification to be raised. */ - breakMode: ExceptionBreakMode, - /** Detailed information about the exception. */ - details?: ExceptionDetails, - }; - } - - declare interface CustomRequest extends base$Request {} - declare interface CustomResponse extends base$Response {} - - declare type Request = - | RunInTerminalRequest - | InitializeRequest - | ConfigurationDoneRequest - | LaunchRequest - | AttachRequest - | RestartRequest - | DisconnectRequest - | SetBreakpointsRequest - | SetFunctionBreakpointsRequest - | SetExceptionBreakpointsRequest - | ContinueRequest - | NextRequest - | StepInRequest - | StepOutRequest - | StepBackRequest - | ReverseContinueRequest - | RestartFrameRequest - | GotoRequest - | PauseRequest - | StackTraceRequest - | ScopesRequest - | VariablesRequest - | SetVariableRequest - | SourceRequest - | ThreadsRequest - | ModulesRequest - | EvaluateRequest - | StepInTargetsRequest - | GotoTargetsRequest - | CompletionsRequest - | ExceptionInfoRequest - | nuclide_ContinueToLocationRequest - | CustomRequest; - declare type Response = - | RunInTerminalResponse - | InitializeResponse - | ConfigurationDoneResponse - | LaunchResponse - | AttachResponse - | RestartResponse - | DisconnectResponse - | SetBreakpointsResponse - | SetFunctionBreakpointsResponse - | SetExceptionBreakpointsResponse - | ContinueResponse - | NextResponse - | StepInResponse - | StepOutResponse - | StepBackResponse - | ReverseContinueResponse - | RestartFrameResponse - | GotoResponse - | PauseResponse - | StackTraceResponse - | ScopesResponse - | VariablesResponse - | SetVariableResponse - | SourceResponse - | ThreadsResponse - | ModulesResponse - | EvaluateResponse - | StepInTargetsResponse - | GotoTargetsResponse - | CompletionsResponse - | ExceptionInfoResponse - | nuclide_ContinueToLocationResponse - | CustomResponse; - declare type Event = - | InitializedEvent - | StoppedEvent - | ContinuedEvent - | ExitedEvent - | TerminatedEvent - | ThreadEvent - | OutputEvent - | BreakpointEvent - | ModuleEvent - | LoadedSourceEvent; - - declare type Capabilities = { - /** The debug adapter supports the configurationDoneRequest. */ - supportsConfigurationDoneRequest?: boolean, - /** The debug adapter supports function breakpoints. */ - supportsFunctionBreakpoints?: boolean, - /** The debug adapter supports conditional breakpoints. */ - supportsConditionalBreakpoints?: boolean, - /** The debug adapter supports breakpoints that break execution after a specified number of hits. */ - supportsHitConditionalBreakpoints?: boolean, - /** The debug adapter supports a (side effect free) evaluate request for data hovers. */ - supportsEvaluateForHovers?: boolean, - /** Available filters or options for the setExceptionBreakpoints request. */ - exceptionBreakpointFilters?: ExceptionBreakpointsFilter[], - /** The debug adapter supports stepping back via the stepBack and reverseContinue requests. */ - supportsStepBack?: boolean, - /** The debug adapter supports setting a variable to a value. */ - supportsSetVariable?: boolean, - /** The debug adapter supports restarting a frame. */ - supportsRestartFrame?: boolean, - /** The debug adapter supports the gotoTargetsRequest. */ - supportsGotoTargetsRequest?: boolean, - /** The debug adapter supports the stepInTargetsRequest. */ - supportsStepInTargetsRequest?: boolean, - /** The debug adapter supports the completionsRequest. */ - supportsCompletionsRequest?: boolean, - /** The debug adapter supports the modules request. */ - supportsModulesRequest?: boolean, - /** The set of additional module information exposed by the debug adapter. */ - // additionalModuleColumns?: ColumnDescriptor[]; - /** Checksum algorithms supported by the debug adapter. */ - // supportedChecksumAlgorithms?: ChecksumAlgorithm[]; - /** The debug adapter supports the RestartRequest. In this case a client should not implement 'restart' by terminating and relaunching the adapter but by calling the RestartRequest. */ - supportsRestartRequest?: boolean, - /** The debug adapter supports 'exceptionOptions' on the setExceptionBreakpoints request. */ - supportsExceptionOptions?: boolean, - /** The debug adapter supports a 'format' attribute on the stackTraceRequest, variablesRequest, and evaluateRequest. */ - supportsValueFormattingOptions?: boolean, - /** The debug adapter supports the exceptionInfo request. */ - supportsExceptionInfoRequest?: boolean, - /** The debug adapter supports the 'terminateDebuggee' attribute on the 'disconnect' request. */ - supportTerminateDebuggee?: boolean, - /** The debug adapter supports custom `continueToLocation` logic. - * This is not part of the standard Visual Studio Code debug protocol. - */ - supportsContinueToLocation?: boolean, - - /** Experimental support for terminate thread - this is currently proposed as - * an addition to the protocol but not added yet. - * Tracked by VS Code issue: https://github.com/Microsoft/vscode-debugadapter-node/issues/150 - */ - supportsTerminateThreadsRequest?: boolean, - }; - - /** An ExceptionBreakpointsFilter is shown in the UI as an option for configuring how exceptions are dealt with. */ - declare type ExceptionBreakpointsFilter = { - /** The internal ID of the filter. This value is passed to the setExceptionBreakpoints request. */ - filter: string, - /** The name of the filter. This will be shown in the UI. */ - label: string, - /** Initial value of the filter. If not specified a value 'false' is assumed. */ - default?: boolean, - }; - - /** A structured message object. Used to return errors from requests. */ - declare type Message = { - /** Unique identifier for the message. */ - id: number, - /** A format string for the message. Embedded variables have the form '{name}'. - If variable name starts with an underscore character, the variable does not contain user data (PII) and can be safely used for telemetry purposes. - */ - format: string, - /** An object used as a dictionary for looking up the variables in the format string. */ - variables?: {[key: string]: string}, - /** If true send to telemetry. */ - sendTelemetry?: boolean, - /** If true show user. */ - showUser?: boolean, - /** An optional url where additional information about this message can be found. */ - url?: string, - /** An optional label that is presented to the user as the UI for opening the url. */ - urlLabel?: string, - }; - - /** A Module object represents a row in the modules view. - Two attributes are mandatory: an id identifies a module in the modules view and is used in a ModuleEvent for identifying a module for adding, updating or deleting. - The name is used to minimally render the module in the UI. - - Additional attributes can be added to the module. They will show up in the module View if they have a corresponding ColumnDescriptor. - - To avoid an unnecessary proliferation of additional attributes with similar semantics but different names - we recommend to re-use attributes from the 'recommended' list below first, and only introduce new attributes if nothing appropriate could be found. - */ - declare type Module = { - /** Unique identifier for the module. */ - id: number | string, - /** A name of the module. */ - name: string, - /** optional but recommended attributes. - always try to use these first before introducing additional attributes. - - Logical full path to the module. The exact definition is implementation defined, but usually this would be a full path to the on-disk file for the module. - */ - path?: string, - /** True if the module is optimized. */ - isOptimized?: boolean, - /** True if the module is considered 'user code' by a debugger that supports 'Just My Code'. */ - isUserCode?: boolean, - /** Version of Module. */ - version?: string, - /** User understandable description of if symbols were found for the module (ex: 'Symbols Loaded', 'Symbols not found', etc. */ - symbolStatus?: string, - /** Logical full path to the symbol file. The exact definition is implementation defined. */ - symbolFilePath?: string, - /** Module created or modified. */ - dateTimeStamp?: string, - /** Address range covered by this module. */ - addressRange?: string, - }; - - /** A ColumnDescriptor specifies what module attribute to show in a column of the ModulesView, how to format it, and what the column's label should be. - It is only used if the underlying UI actually supports this level of customization. - */ - declare type ColumnDescriptor = { - /** Name of the attribute rendered in this column. */ - attributeName: string, - /** Header UI label of column. */ - label: string, - /** Format to use for the rendered values in this column. TBD how the format strings looks like. */ - format?: string, - /** Datatype of values in this column. Defaults to 'string' if not specified. */ - type?: 'string' | 'number' | 'boolean' | 'unixTimestampUTC', - /** Width of this column in characters (hint only). */ - width?: number, - }; - - /** The ModulesViewDescriptor is the container for all declarative configuration options of a ModuleView. - For now it only specifies the columns to be shown in the modules view. - */ - declare type ModulesViewDescriptor = { - columns: ColumnDescriptor[], - }; - - /** A Thread */ - declare type Thread = { - /** Unique identifier for the thread. */ - id: number, - /** A name of the thread. */ - name: string, - }; - - /** A Source is a descriptor for source code. It is returned from the debug adapter as part of a StackFrame and it is used by clients when specifying breakpoints. */ - declare type Source = { - /** The short name of the source. Every source returned from the debug adapter has a name. When sending a source to the debug adapter this name is optional. */ - name?: string, - /** The path of the source to be shown in the UI. It is only used to locate and load the content of the source if no sourceReference is specified (or its vaule is 0). */ - path?: string, - /** If sourceReference > 0 the contents of the source must be retrieved through the SourceRequest (even if a path is specified). A sourceReference is only valid for a session, so it must not be used to persist a source. */ - sourceReference?: number, - /** An optional hint for how to present the source in the UI. A value of 'deemphasize' can be used to indicate that the source is not available or that it is skipped on stepping. */ - presentationHint?: 'emphasize' | 'deemphasize', - /** The (optional) origin of this source: possible values 'internal module', 'inlined content from source map', etc. */ - origin?: string, - /** Optional data that a debug adapter might want to loop through the client. The client should leave the data intact and persist it across sessions. The client should not interpret the data. */ - adapterData?: any, - /** The checksums associated with this file. */ - checksums?: Checksum[], - }; - - /** A Stackframe contains the source location. */ - declare type StackFrame = { - /** An identifier for the stack frame. It must be unique across all threads. This id can be used to retrieve the scopes of the frame with the 'scopesRequest' or to restart the execution of a stackframe. */ - id: number, - /** The name of the stack frame, typically a method name. */ - name: string, - /** The optional source of the frame. */ - source?: Source, - /** The line within the file of the frame. If source is null or doesn't exist, line is 0 and must be ignored. */ - line: number, - /** The column within the line. If source is null or doesn't exist, column is 0 and must be ignored. */ - column: number, - /** An optional end line of the range covered by the stack frame. */ - endLine?: number, - /** An optional end column of the range covered by the stack frame. */ - endColumn?: number, - /** The module associated with this frame, if any. */ - moduleId?: number | string, - /** An optional hint for how to present this frame in the UI. A value of 'label' can be used to indicate that the frame is an artificial frame that is used as a visual label or separator. */ - presentationHint?: 'normal' | 'label', - }; - - /** A Scope is a named container for variables. Optionally a scope can map to a source or a range within a source. */ - declare type Scope = { - /** Name of the scope such as 'Arguments', 'Locals'. */ - name: string, - /** The variables of this scope can be retrieved by passing the value of variablesReference to the VariablesRequest. */ - variablesReference: number, - /** The number of named variables in this scope. - The client can use this optional information to present the variables in a paged UI and fetch them in chunks. - */ - namedVariables?: number, - /** The number of indexed variables in this scope. - The client can use this optional information to present the variables in a paged UI and fetch them in chunks. - */ - indexedVariables?: number, - /** If true, the number of variables in this scope is large or expensive to retrieve. */ - expensive: boolean, - /** Optional source for this scope. */ - source?: Source, - /** Optional start line of the range covered by this scope. */ - line?: number, - /** Optional start column of the range covered by this scope. */ - column?: number, - /** Optional end line of the range covered by this scope. */ - endLine?: number, - /** Optional end column of the range covered by this scope. */ - endColumn?: number, - }; - - /** A Variable is a name/value pair. - Optionally a variable can have a 'type' that is shown if space permits or when hovering over the variable's name. - An optional 'kind' is used to render additional properties of the variable, e.g. different icons can be used to indicate that a variable is public or private. - If the value is structured (has children), a handle is provided to retrieve the children with the VariablesRequest. - If the number of named or indexed children is large, the numbers should be returned via the optional 'namedVariables' and 'indexedVariables' attributes. - The client can use this optional information to present the children in a paged UI and fetch them in chunks. - */ - declare type Variable = { - /** The variable's name. */ - name: string, - /** The variable's value. This can be a multi-line text, e.g. for a function the body of a function. */ - value: string, - /** The type of the variable's value. Typically shown in the UI when hovering over the value. */ - type?: string, - /** Properties of a variable that can be used to determine how to render the variable in the UI. */ - presentationHint?: VariablePresentationHint, - /** Properties of a variable that can be used to determine how to render the variable in the UI. Format of the string value: TBD. */ - kind?: string, - /** Optional evaluatable name of this variable which can be passed to the 'EvaluateRequest' to fetch the variable's value. */ - evaluateName?: string, - /** If variablesReference is > 0, the variable is structured and its children can be retrieved by passing variablesReference to the VariablesRequest. */ - variablesReference: number, - /** The number of named child variables. - The client can use this optional information to present the children in a paged UI and fetch them in chunks. - */ - namedVariables?: number, - /** The number of indexed child variables. - The client can use this optional information to present the children in a paged UI and fetch them in chunks. - */ - indexedVariables?: number, - }; - - /** Optional properties of a variable that can be used to determine how to render the variable in the UI. */ - declare type VariablePresentationHint = { - /** The kind of variable. Before introducing additional values, try to use the listed values. - Values: - 'property': Indicates that the object is a property. - 'method': Indicates that the object is a method. - 'class': Indicates that the object is a class. - 'data': Indicates that the object is data. - 'event': Indicates that the object is an event. - 'baseClass': Indicates that the object is a base class. - 'innerClass': Indicates that the object is an inner class. - 'interface': Indicates that the object is an interface. - 'mostDerivedClass': Indicates that the object is the most derived class. - 'virtual': Indicates that the object is virtual, that means it is a synthetic object introduced by the adapter for rendering purposes, e.g. an index range for large arrays. - etc. - */ - kind?: string, - /** Set of attributes represented as an array of strings. Before introducing additional values, try to use the listed values. - Values: - 'static': Indicates that the object is static. - 'constant': Indicates that the object is a constant. - 'readOnly': Indicates that the object is read only. - 'rawString': Indicates that the object is a raw string. - 'hasObjectId': Indicates that the object can have an Object ID created for it. - 'canHaveObjectId': Indicates that the object has an Object ID associated with it. - 'hasSideEffects': Indicates that the evaluation had side effects. - etc. - */ - attributes?: string[], - /** Visibility of variable. Before introducing additional values, try to use the listed values. - Values: 'public', 'private', 'protected', 'internal', 'final', etc. - */ - visibility?: string, - }; - - /** Properties of a breakpoint passed to the setBreakpoints request. */ - declare type SourceBreakpoint = { - /** The source line of the breakpoint. */ - line: number, - /** An optional source column of the breakpoint. */ - column?: ?number, - /** An optional expression for conditional breakpoints. */ - condition?: ?string, - /** An optional expression that controls how many hits of the breakpoint are ignored. The backend is expected to interpret the expression as needed. */ - hitCondition?: ?string, - }; - - /** Properties of a breakpoint passed to the setFunctionBreakpoints request. */ - declare type FunctionBreakpoint = { - /** The name of the function. */ - name: string, - /** An optional expression for conditional breakpoints. */ - condition?: ?string, - /** An optional expression that controls how many hits of the breakpoint are ignored. The backend is expected to interpret the expression as needed. */ - hitCondition?: ?string, - }; - - /** Information about a Breakpoint created in setBreakpoints or setFunctionBreakpoints. */ - declare type Breakpoint = { - /** An optional unique identifier for the breakpoint. */ - id?: number, - /** If true breakpoint could be set (but not necessarily at the desired location). */ - verified: boolean, - /** An optional message about the state of the breakpoint. This is shown to the user and can be used to explain why a breakpoint could not be verified. */ - message?: string, - /** The source where the breakpoint is located. */ - source?: Source, - /** The start line of the actual range covered by the breakpoint. */ - line?: number, - /** An optional start column of the actual range covered by the breakpoint. */ - column?: number, - /** An optional end line of the actual range covered by the breakpoint. */ - endLine?: number, - /** An optional end column of the actual range covered by the breakpoint. If no end line is given, then the end column is assumed to be in the start line. */ - endColumn?: number, - - /** Nuclide custom extensions **/ - nuclide_hitCount?: number, - }; - - /** A StepInTarget can be used in the 'stepIn' request and determines into which single target the stepIn request should step. */ - declare type StepInTarget = { - /** Unique identifier for a stepIn target. */ - id: number, - /** The name of the stepIn target (shown in the UI). */ - label: string, - }; - - /** A GotoTarget describes a code location that can be used as a target in the 'goto' request. - The possible goto targets can be determined via the 'gotoTargets' request. - */ - declare type GotoTarget = { - /** Unique identifier for a goto target. This is used in the goto request. */ - id: number, - /** The name of the goto target (shown in the UI). */ - label: string, - /** The line of the goto target. */ - line: number, - /** An optional column of the goto target. */ - column?: number, - /** An optional end line of the range covered by the goto target. */ - endLine?: number, - /** An optional end column of the range covered by the goto target. */ - endColumn?: number, - }; - - /** CompletionItems are the suggestions returned from the CompletionsRequest. */ - declare type CompletionItem = { - /** The label of this completion item. By default this is also the text that is inserted when selecting this completion. */ - label: string, - /** If text is not falsy then it is inserted instead of the label. */ - text?: string, - /** The item's type. Typically the client uses this information to render the item in the UI with an icon. */ - type?: CompletionItemType, - /** This value determines the location (in the CompletionsRequest's 'text' attribute) where the completion text is added. - If missing the text is added at the location specified by the CompletionsRequest's 'column' attribute. - */ - start?: number, - /** This value determines how many characters are overwritten by the completion text. - If missing the value 0 is assumed which results in the completion text being inserted. - */ - length?: number, - }; - - /** Some predefined types for the CompletionItem. Please note that not all clients have specific icons for all of them. */ - declare type CompletionItemType = - | 'method' - | 'function' - | 'constructor' - | 'field' - | 'variable' - | 'class' - | 'interface' - | 'module' - | 'property' - | 'unit' - | 'value' - | 'enum' - | 'keyword' - | 'snippet' - | 'text' - | 'color' - | 'file' - | 'reference' - | 'customcolor'; - - /** Names of checksum algorithms that may be supported by a debug adapter. */ - declare type ChecksumAlgorithm = 'MD5' | 'SHA1' | 'SHA256' | 'timestamp'; - - /** The checksum of an item calculated by the specified algorithm. */ - declare type Checksum = { - /** The algorithm used to calculate this checksum. */ - algorithm: ChecksumAlgorithm, - /** Value of the checksum. */ - checksum: string, - }; - - /** Provides formatting information for a value. */ - declare type ValueFormat = { - /** Display the value in hex. */ - hex?: boolean, - }; - - /** Provides formatting information for a stack frame. */ - declare type StackFrameFormat = ValueFormat & { - /** Displays parameters for the stack frame. */ - parameters?: boolean, - /** Displays the types of parameters for the stack frame. */ - parameterTypes?: boolean, - /** Displays the names of parameters for the stack frame. */ - parameterNames?: boolean, - /** Displays the values of parameters for the stack frame. */ - parameterValues?: boolean, - /** Displays the line number of the stack frame. */ - line?: boolean, - /** Displays the module of the stack frame. */ - module?: boolean, - }; - - /** An ExceptionOptions assigns configuration options to a set of exceptions. */ - declare type ExceptionOptions = { - /** A path that selects a single or multiple exceptions in a tree. If 'path' is missing, the whole tree is selected. By convention the first segment of the path is a category that is used to group exceptions in the UI. */ - path?: ExceptionPathSegment[], - /** Condition when a thrown exception should result in a break. */ - breakMode: ExceptionBreakMode, - }; - - /** This enumeration defines all possible conditions when a thrown exception should result in a break. - never: never breaks, - always: always breaks, - unhandled: breaks when excpetion unhandled, - userUnhandled: breaks if the exception is not handled by user code. - */ - declare type ExceptionBreakMode = - | 'never' - | 'always' - | 'unhandled' - | 'userUnhandled'; - - /** An ExceptionPathSegment represents a segment in a path that is used to match leafs or nodes in a tree of exceptions. If a segment consists of more than one name, it matches the names provided if 'negate' is false or missing or it matches anything except the names provided if 'negate' is true. */ - declare type ExceptionPathSegment = { - /** If false or missing this segment matches the names provided, otherwise it matches anything except the names provided. */ - negate?: boolean, - /** Depending on the value of 'negate' the names that should match or not match. */ - names: string[], - }; - - /** Detailed information about an exception that has occurred. */ - declare type ExceptionDetails = { - /** Message contained in the exception. */ - message?: string, - /** Short type name of the exception object. */ - typeName?: string, - /** Fully-qualified type name of the exception object. */ - fullTypeName?: string, - /** Optional expression that can be evaluated in the current scope to obtain the exception object. */ - evaluateName?: string, - /** Stack trace at the time the exception was thrown. */ - stackTrace?: string, - /** Details of the exception contained by this exception, if any. */ - innerException?: ExceptionDetails[], - }; -} diff --git a/flow-libs/vscode-jsonrpc.js.flow b/flow-libs/vscode-jsonrpc.js.flow deleted file mode 100644 index 33bbe6d2aa..0000000000 --- a/flow-libs/vscode-jsonrpc.js.flow +++ /dev/null @@ -1,947 +0,0 @@ -/** - * 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 - */ - -// From https://github.com/Microsoft/vscode-languageserver-node/blob/master/jsonrpc/src/main.ts -// For v3.3.0 -// TODO: Contribute this back to flow-typed. - -declare module 'vscode-jsonrpc' { - // thenable.d.ts - - declare type Thenable = Promise; - - // events.d.ts - - declare export interface Disposable { - /** - * Dispose this object. - */ - dispose(): void; - } - - // declare var Disposable: { - // create(func: () => void): Disposable; - // } - /** - * Represents a typed event. - */ - declare export interface Event { - /** - * - * @param listener The listener function will be call when the event happens. - * @param thisArgs The 'this' which will be used when calling the event listener. - * @param disposables An array to which a {{IDisposable}} will be added. The - * @return - */ - ( - listener: (e: T) => any, - thisArgs?: any, - disposables?: Disposable[], - ): Disposable; - } - // declare export namespace Event = { - // const None: Event; - // } - declare export interface EmitterOptions { - onFirstListenerAdd?: Function; - onLastListenerRemove?: Function; - } - declare export class Emitter { - // private _options; - // private static _noop; - // private _event; - // private _callbacks; - constructor(_options?: EmitterOptions): void; - /** - * For the public to allow to subscribe - * to events from this Emitter - */ - +event: Event; - /** - * To be kept private to fire an event to - * subscribers - */ - fire(event: T): any; - dispose(): void; - } - - // cancellation.d.ts - - /** - * Defines a CancellationToken. This interface is not - * intended to be implemented. A CancellationToken must - * be created via a CancellationTokenSource. - */ - declare export interface CancellationToken { - /** - * Is `true` when the token has been cancelled, `false` otherwise. - */ - +isCancellationRequested: boolean; - /** - * An [event](#Event) which fires upon cancellation. - */ - +onCancellationRequested: Event; - } - // declare export namespace CancellationToken { - // const None: CancellationToken; - // const Cancelled: CancellationToken; - // is(value: any): boolean; - // } - declare export class CancellationTokenSource { - // private _token; - +token: CancellationToken; - cancel(): void; - dispose(): void; - } - - // messages.d.ts - - /** - * A language server message - */ - declare export interface Message { - jsonrpc: string; - } - /** - * Request message - */ - declare export interface RequestMessage extends Message { - /** - * The request id. - */ - id: number | string; - /** - * The method to be invoked. - */ - method: string; - /** - * The method's params. - */ - params?: any; - } - /** - * Predefined error codes. - */ - declare export var ErrorCodes: { - ParseError: number, - InvalidRequest: number, - MethodNotFound: number, - InvalidParams: number, - InternalError: number, - serverErrorStart: number, - serverErrorEnd: number, - ServerNotInitialized: number, - UnknownErrorCode: number, - RequestCancelled: number, - MessageWriteError: number, - MessageReadError: number, - }; - declare export interface ResponseErrorLiteral { - /** - * A number indicating the error type that occured. - */ - code: number; - /** - * A string providing a short decription of the error. - */ - message: string; - /** - * A Primitive or Structured value that contains additional - * information about the error. Can be omitted. - */ - data?: D; - } - /** - * A error object return in a response in case a request - * has failed. - */ - declare export class ResponseError extends Error { - +code: number; - +data: D; - constructor(code: number, message: string, data?: D): void; - toJson(): ResponseErrorLiteral; - } - /** - * A response message. - */ - declare export interface ResponseMessage extends Message { - /** - * The request id. - */ - id: number | string | null; - /** - * The result of a request. This can be omitted in - * the case of an error. - */ - result?: any; - /** - * The error object in case a request fails. - */ - error?: ResponseErrorLiteral; - } - /** - * An interface to type messages. - */ - declare export interface MessageType { - +method: string; - +numberOfParams: number; - } - /** - * An abstract implementation of a MessageType. - */ - declare class AbstractMessageType { - // private _method; - // private _numberOfParams; - constructor(_method: string, _numberOfParams: number): void; - +method: string; - +numberOfParams: number; - } - /** - * End marker interface for request and notification types. - */ - declare interface _EM { - _$endMarker$_: number; - } - /** - * Classes to type request response pairs - */ - declare export type RequestType0 = { - // private _?; - +method: string, - }; - declare export type RequestType = { - // private _?; - +method: string, - }; - declare export type RequestType1 = { - // private _?; - +method: string, - }; - declare export type RequestType2 = { - // private _?; - +method: string, - }; - declare export type RequestType3 = { - // private _?; - +method: string, - }; - declare export type RequestType4 = { - // private _?; - +method: string, - }; - declare export type RequestType5 = { - // private _?; - +method: string, - }; - declare export type RequestType6 = { - // private _?; - +method: string, - }; - declare export type RequestType7 = { - // private _?; - +method: string, - }; - declare export type RequestType8 = { - // private _?; - +method: string, - }; - declare export type RequestType9< - P1, - P2, - P3, - P4, - P5, - P6, - P7, - P8, - P9, - R, - E, - RO, - > = { - // private _?; - +method: string, - }; - /** - * Notification Message - */ - declare interface NotificationMessage extends Message { - /** - * The method to be invoked. - */ - method: string; - /** - * The notification's params. - */ - params?: any; - } - declare export type NotificationType = { - // private _?; - +method: string, - }; - declare export type NotificationType0 = { - // private _?; - +method: string, - }; - declare export type NotificationType1 = { - // private _?; - +method: string, - }; - declare export type NotificationType2 = { - // private _?; - +method: string, - }; - declare export type NotificationType3 = { - // private _?; - +method: string, - }; - declare export type NotificationType4 = { - // private _?; - +method: string, - }; - declare export type NotificationType5 = { - // private _?; - +method: string, - }; - declare export type NotificationType6 = { - // private _?; - +method: string, - }; - declare export type NotificationType7 = { - // private _?; - +method: string, - }; - declare export type NotificationType8 = { - // private _?; - +method: string, - }; - declare export type NotificationType9< - P1, - P2, - P3, - P4, - P5, - P6, - P7, - P8, - P9, - RO, - > = { - // private _?; - +method: string, - }; - /** - * Tests if the given message is a request message - */ - declare function isRequestMessage(message: Message | void): boolean; - /** - * Tests if the given message is a notification message - */ - declare function isNotificationMessage(message: Message | void): boolean; - /** - * Tests if the given message is a response message - */ - declare function isReponseMessage(message: Message | void): boolean; - - // messageReader.d.ts - - declare export interface DataCallback { - (data: Message): void; - } - declare export interface PartialMessageInfo { - +messageToken: number; - +waitingTime: number; - } - declare export interface MessageReader { - +onError: Event; - +onClose: Event; - +onPartialMessage: Event; - listen(callback: DataCallback): void; - dispose(): void; - } - declare class AbstractMessageReader { - // private errorEmitter; - // private closeEmitter; - // private partialMessageEmitter; - constructor(): void; - dispose(): void; - +onError: Event; - /* protected */ fireError(error: any): void; - +onClose: Event; - /* protected */ fireClose(): void; - +onPartialMessage: Event; - /* protected */ firePartialMessage(info: PartialMessageInfo): void; - /* private */ asError(error: any): any; - } - declare export class StreamMessageReader extends AbstractMessageReader { - readable: stream$Readable; - // private callback; - // private buffer; - // private nextMessageLength; - // private messageToken; - // private partialMessageTimer; - // private _partialMessageTimeout; - constructor(readable: stream$Readable, encoding?: string): void; - partialMessageTimeout: number; - listen(callback: DataCallback): void; - /* private */ onData(data: any): any; - // private clearPartialMessageTimer(); - // private setPartialMessageTimer(); - } - declare export class IPCMessageReader extends AbstractMessageReader { - // private process; - constructor(process: Process | child_process$ChildProcess): void; - listen(callback: DataCallback): void; - } - declare export class SocketMessageReader extends StreamMessageReader { - constructor(socket: net$Socket, encoding?: string): void; - } - - // messageWriter.d.ts - - declare export interface MessageWriter { - +onError: Event<[Error, Message | void, number | void]>; - +onClose: Event; - write(msg: Message): void; - dispose(): void; - } - declare class AbstractMessageWriter { - // private errorEmitter; - // private closeEmitter; - constructor(): void; - dispose(): void; - +onError: Event<[Error, Message | void, number | void]>; - // protected fireError(error: any, message?: Message, count?: number): void; - +onClose: Event; - // protected fireClose(): void; - // private asError(error); - } - declare export class StreamMessageWriter extends AbstractMessageWriter { - // private writable; - // private encoding; - // private errorCount; - constructor(writable: stream$Writable, encoding?: string): void; - write(msg: Message): void; - } - declare export class IPCMessageWriter extends AbstractMessageWriter { - // private process; - // private queue; - // private sending; - // private errorCount; - constructor(process: Process | child_process$ChildProcess): void; - write(msg: Message): void; - doWriteMessage(msg: Message): void; - } - declare export class SocketMessageWriter extends AbstractMessageWriter { - // private socket; - // private queue; - // private sending; - // private encoding; - // private errorCount; - constructor(socket: net$Socket, encoding?: string): void; - write(msg: Message): void; - doWriteMessage(msg: Message): void; - // private handleError(error, msg); - } - - // pipeSupport.d.ts - - declare export function generateRandomPipeName(): string; - declare export interface PipeTransport { - onConnected(): Thenable<[MessageReader, MessageWriter]>; - } - declare export function createClientPipeTransport( - pipeName: string, - encoding?: string, - ): Thenable; - declare export function createServerPipeTransport( - pipeName: string, - encoding?: string, - ): [MessageReader, MessageWriter]; - - // main.d.ts - - declare type HandlerResult = - | R - | ResponseError - | Thenable - | Thenable>; - declare interface StarRequestHandler { - (method: string, ...params: any[]): HandlerResult; - } - declare interface GenericRequestHandler { - (...params: any[]): HandlerResult; - } - declare interface RequestHandler0 { - (token: CancellationToken): HandlerResult; - } - declare interface RequestHandler { - (params: P, token: CancellationToken): HandlerResult; - } - declare interface RequestHandler1 { - (p1: P1, token: CancellationToken): HandlerResult; - } - declare interface RequestHandler2 { - (p1: P1, p2: P2, token: CancellationToken): HandlerResult; - } - declare interface RequestHandler3 { - (p1: P1, p2: P2, p3: P3, token: CancellationToken): HandlerResult; - } - declare interface RequestHandler4 { - ( - p1: P1, - p2: P2, - p3: P3, - p4: P4, - token: CancellationToken, - ): HandlerResult; - } - declare interface RequestHandler5 { - ( - p1: P1, - p2: P2, - p3: P3, - p4: P4, - p5: P5, - token: CancellationToken, - ): HandlerResult; - } - declare interface RequestHandler6 { - ( - p1: P1, - p2: P2, - p3: P3, - p4: P4, - p5: P5, - p6: P6, - token: CancellationToken, - ): HandlerResult; - } - declare interface RequestHandler7 { - ( - p1: P1, - p2: P2, - p3: P3, - p4: P4, - p5: P5, - p6: P6, - p7: P7, - token: CancellationToken, - ): HandlerResult; - } - declare interface RequestHandler8 { - ( - p1: P1, - p2: P2, - p3: P3, - p4: P4, - p5: P5, - p6: P6, - p7: P7, - p8: P8, - token: CancellationToken, - ): HandlerResult; - } - declare interface RequestHandler9 { - ( - p1: P1, - p2: P2, - p3: P3, - p4: P4, - p5: P5, - p6: P6, - p7: P7, - p8: P8, - p9: P9, - token: CancellationToken, - ): HandlerResult; - } - declare interface StarNotificationHandler { - (method: string, ...params: any[]): void; - } - declare interface GenericNotificationHandler { - (...params: any[]): void; - } - declare interface NotificationHandler0 { - (): void; - } - declare interface NotificationHandler

{ - (params: P): void; - } - declare interface NotificationHandler1 { - (p1: P1): void; - } - declare interface NotificationHandler2 { - (p1: P1, p2: P2): void; - } - declare interface NotificationHandler3 { - (p1: P1, p2: P2, p3: P3): void; - } - declare interface NotificationHandler4 { - (p1: P1, p2: P2, p3: P3, p4: P4): void; - } - declare interface NotificationHandler5 { - (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5): void; - } - declare interface NotificationHandler6 { - (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6): void; - } - declare interface NotificationHandler7 { - (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7): void; - } - declare interface NotificationHandler8 { - (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8): void; - } - declare interface NotificationHandler9 { - ( - p1: P1, - p2: P2, - p3: P3, - p4: P4, - p5: P5, - p6: P6, - p7: P7, - p8: P8, - p9: P9, - ): void; - } - declare interface Logger { - error(message: string): void; - warn(message: string): void; - info(message: string): void; - log(message: string): void; - } - declare export var Trace: { - Off: 0, - Messages: 1, - Verbose: 2, - fromString(value: string): $Values, - toString(value: $Values): TraceValues, - }; - declare type TraceValues = 'off' | 'messages' | 'verbose'; - declare interface SetTraceParams { - value: TraceValues; - } - declare export var SetTraceNotification: { - type: NotificationType, - }; - declare interface LogTraceParams { - message: string; - verbose?: string; - } - declare export var LogTraceNotification: { - type: NotificationType, - }; - declare interface Tracer { - log(message: string, data?: string): void; - } - declare export var ConnectionErrors: { - /** - * The connection is closed. - */ - Closed: 1, - /** - * The connection got disposed. - */ - Disposed: 2, - /** - * The connection is already in listening mode. - */ - AlreadyListening: 3, - }; - declare export class ConnectionError extends Error { - +code: $Values; - constructor(code: $Values, message: string): void; - } - // declare type MessageQueue = LinkedMap; - declare type ConnectionStrategy = { - cancelUndispatched?: ( - message: Message, - next: (message: Message) => ResponseMessage | void, - ) => ResponseMessage | void, - }; - // declare export var ConnectionStrategy: { - // is(value: any): boolean, - // }; - declare export interface MessageConnection { - sendRequest( - type: RequestType0, - token?: CancellationToken, - ): Thenable; - sendRequest( - type: RequestType, - params: P, - token?: CancellationToken, - ): Thenable; - sendRequest( - type: RequestType1, - p1: P1, - token?: CancellationToken, - ): Thenable; - sendRequest( - type: RequestType2, - p1: P1, - p2: P2, - token?: CancellationToken, - ): Thenable; - sendRequest( - type: RequestType3, - p1: P1, - p2: P2, - p3: P3, - token?: CancellationToken, - ): Thenable; - sendRequest( - type: RequestType4, - p1: P1, - p2: P2, - p3: P3, - p4: P4, - token?: CancellationToken, - ): Thenable; - sendRequest( - type: RequestType5, - p1: P1, - p2: P2, - p3: P3, - p4: P4, - p5: P5, - token?: CancellationToken, - ): Thenable; - sendRequest( - type: RequestType6, - p1: P1, - p2: P2, - p3: P3, - p4: P4, - p5: P5, - p6: P6, - token?: CancellationToken, - ): Thenable; - sendRequest( - type: RequestType7, - p1: P1, - p2: P2, - p3: P3, - p4: P4, - p5: P5, - p6: P6, - p7: P7, - token?: CancellationToken, - ): Thenable; - sendRequest( - type: RequestType8, - p1: P1, - p2: P2, - p3: P3, - p4: P4, - p5: P5, - p6: P6, - p7: P7, - p8: P8, - token?: CancellationToken, - ): Thenable; - sendRequest( - type: RequestType9, - p1: P1, - p2: P2, - p3: P3, - p4: P4, - p5: P5, - p6: P6, - p7: P7, - p8: P8, - p9: P9, - token?: CancellationToken, - ): Thenable; - sendRequest(method: string, ...params: any[]): Thenable; - onRequest( - type: RequestType0, - handler: RequestHandler0, - ): void; - onRequest( - type: RequestType1, - handler: RequestHandler1, - ): void; - onRequest( - type: RequestType2, - handler: RequestHandler2, - ): void; - onRequest( - type: RequestType3, - handler: RequestHandler3, - ): void; - onRequest( - type: RequestType4, - handler: RequestHandler4, - ): void; - onRequest( - type: RequestType5, - handler: RequestHandler5, - ): void; - onRequest( - type: RequestType6, - handler: RequestHandler6, - ): void; - onRequest( - type: RequestType7, - handler: RequestHandler7, - ): void; - onRequest( - type: RequestType8, - handler: RequestHandler8, - ): void; - onRequest( - type: RequestType9, - handler: RequestHandler9, - ): void; - onRequest(method: string, handler: GenericRequestHandler): void; - onRequest(handler: StarRequestHandler): void; - sendNotification(type: NotificationType0): void; - sendNotification(type: NotificationType, params?: P): void; - sendNotification(type: NotificationType1, p1: P1): void; - sendNotification( - type: NotificationType2, - p1: P1, - p2: P2, - ): void; - sendNotification( - type: NotificationType3, - p1: P1, - p2: P2, - p3: P3, - ): void; - sendNotification( - type: NotificationType4, - p1: P1, - p2: P2, - p3: P3, - p4: P4, - ): void; - sendNotification( - type: NotificationType5, - p1: P1, - p2: P2, - p3: P3, - p4: P4, - p5: P5, - ): void; - sendNotification( - type: NotificationType6, - p1: P1, - p2: P2, - p3: P3, - p4: P4, - p5: P5, - p6: P6, - ): void; - sendNotification( - type: NotificationType7, - p1: P1, - p2: P2, - p3: P3, - p4: P4, - p5: P5, - p6: P6, - p7: P7, - ): void; - sendNotification( - type: NotificationType8, - p1: P1, - p2: P2, - p3: P3, - p4: P4, - p5: P5, - p6: P6, - p7: P7, - p8: P8, - ): void; - sendNotification( - type: NotificationType9, - p1: P1, - p2: P2, - p3: P3, - p4: P4, - p5: P5, - p6: P6, - p7: P7, - p8: P8, - p9: P9, - ): void; - sendNotification(method: string, ...params: any[]): void; - onNotification( - type: NotificationType0, - handler: NotificationHandler0, - ): void; - onNotification( - type: NotificationType1, - handler: NotificationHandler1, - ): void; - onNotification( - type: NotificationType2, - handler: NotificationHandler2, - ): void; - onNotification( - type: NotificationType3, - handler: NotificationHandler3, - ): void; - onNotification( - type: NotificationType4, - handler: NotificationHandler4, - ): void; - onNotification( - type: NotificationType5, - handler: NotificationHandler5, - ): void; - onNotification( - type: NotificationType6, - handler: NotificationHandler6, - ): void; - onNotification( - type: NotificationType7, - handler: NotificationHandler7, - ): void; - onNotification( - type: NotificationType8, - handler: NotificationHandler8, - ): void; - onNotification( - type: NotificationType9, - handler: NotificationHandler9, - ): void; - onNotification(method: string, handler: GenericNotificationHandler): void; - onNotification(handler: StarNotificationHandler): void; - trace( - value: $Values, - tracer: Tracer, - sendNotification?: boolean, - ): void; - onError: Event<[Error, Message, number]>; - onClose: Event; - onUnhandledNotification: Event; - listen(): void; - onDispose: Event; - dispose(): void; - inspect(): void; - } - declare export function createMessageConnection( - reader: MessageReader, - writer: MessageWriter, - logger: Logger, - strategy?: ConnectionStrategy, - ): MessageConnection; - declare export function createMessageConnection( - inputStream: stream$Readable, - outputStream: stream$Writable, - logger: Logger, - strategy?: ConnectionStrategy, - ): MessageConnection; -} diff --git a/flow-libs/vscode-languageclient.js.flow b/flow-libs/vscode-languageclient.js.flow deleted file mode 100644 index 275f6d4b41..0000000000 --- a/flow-libs/vscode-languageclient.js.flow +++ /dev/null @@ -1,161 +0,0 @@ -/** - * 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 - */ - -declare module 'vscode-languageclient' { - import type { - ClientCapabilities, - DocumentSelector, - InitializeError, - InitializeParams, - MessageReader, - MessageWriter, - ServerCapabilities, - } from 'vscode-languageserver-protocol'; - - declare type ExecutableOptions = { - cwd?: string, - stdio?: string | string[], - env?: any, - detached?: boolean, - }; - - declare type Executable = { - command: string, - args?: string[], - options?: ExecutableOptions, - }; - - declare type ForkOptions = { - cwd?: string, - env?: any, - encoding?: string, - execArgv?: string[], - }; - - declare type TransportKind = 'stdio' | 'ipc' | 'pipe'; - - declare type NodeModule = { - module: string, - transport?: TransportKind, - args?: string[], - runtime?: string, - options?: ForkOptions, - }; - - declare export type StreamInfo = { - writer: stream$Writable, - reader: stream$Readable, - detached?: boolean, - }; - - declare type ChildProcessInfo = { - process: child_process$ChildProcess, - detached: boolean, - }; - - declare type MessageTransports = { - reader: MessageReader, - writer: MessageWriter, - detached?: boolean, - }; - - declare export type ServerOptions = - | Executable - | {run: Executable, debug: Executable} - | {run: NodeModule, debug: NodeModule} - | NodeModule - | (() => Thenable< - | child_process$ChildProcess - | StreamInfo - | MessageTransports - | ChildProcessInfo, - >); - - declare export interface StaticFeature { - /** - * Called to fill the initialize params. - * - * @params the initialize params. - */ - fillInitializeParams?: (params: InitializeParams) => void; - - /** - * Called to fill in the client capabilities this feature implements. - * - * @param capabilities The client capabilities to fill. - */ - fillClientCapabilities(capabilities: ClientCapabilities): void; - - /** - * Initialize the feature. This method is called on a feature instance - * when the client has successfully received the initalize request from - * the server and before the client sends the initialized notification - * to the server. - * - * @param capabilities the server capabilities - * @param documentSelector the document selector pass to the client's constuctor. - * May be `undefined` if the client was created without a selector. - */ - initialize( - capabilities: ServerCapabilities, - documentSelector: ?DocumentSelector, - ): void; - } - - declare export interface LanguageClientOptions { - documentSelector?: DocumentSelector | Array; - // synchronize?: SynchronizeOptions; - // diagnosticCollectionName?: string; - // outputChannel?: OutputChannel; - outputChannelName?: string; - // revealOutputChannelOn?: RevealOutputChannelOn; - /** - * The encoding use to read stdout and stderr. Defaults - * to 'utf8' if ommitted. - */ - stdioEncoding?: string; - // initializationOptions?: any | (() => any); - // initializationFailedHandler?: (error: ResponseError | Error | any) => boolean; - // errorHandler?: ErrorHandler; - // middleware?: Middleware; - // uriConverters?: { - // code2Protocol: c2p.URIConverter, - // protocol2Code: p2c.URIConverter, - // }; - // workspaceFolder?: VWorkspaceFolder; - } - - declare export class LanguageClient { - constructor( - name: string, - serverOptions: ServerOptions, - clientOptions: LanguageClientOptions, - forceDebug?: boolean, - ): void; - constructor( - id: string, - name: string, - serverOptions: ServerOptions, - clientOptions: LanguageClientOptions, - forceDebug?: boolean, - ): void; - constructor( - arg1: string, - arg2: ServerOptions | string, - arg3: LanguageClientOptions | ServerOptions, - arg4?: boolean | LanguageClientOptions, - arg5?: boolean, - ): void; - - start(): IDisposable; - registerFeature(feature: StaticFeature): void; - } -} diff --git a/flow-libs/vscode-languageserver-protocol.js.flow b/flow-libs/vscode-languageserver-protocol.js.flow deleted file mode 100644 index bbf246230c..0000000000 --- a/flow-libs/vscode-languageserver-protocol.js.flow +++ /dev/null @@ -1,982 +0,0 @@ -/** - * 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 - */ - -// Flow definitions for Microsoft's Language Server Protocol -// https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md -// https://github.com/Microsoft/language-server-protocol/blob/master/versions/protocol-2-x.md - -declare module 'vscode-languageserver-protocol' { - // Structures - - declare type Position = { - // Line position in a document (zero-based). - line: number, - // Character offset on a line in a document (zero-based). - character: number, - }; - - declare type Range = { - // The range's start position. - start: Position, - // The range's end position. - end: Position, - }; - - declare type Location = { - // The location's URI. - uri: string, - // The position within the URI. - range: Range, - }; - - declare export type DocumentFilter = - | { - /** A language id, like `typescript`. */ - language: string, - /** A Uri [scheme](#Uri.scheme), like `file` or `untitled`. */ - scheme?: string, - /** A glob pattern, like `*.{ts,js}`. */ - pattern?: string, - } - | { - /** A language id, like `typescript`. */ - language?: string, - /** A Uri [scheme](#Uri.scheme), like `file` or `untitled`. */ - scheme: string, - /** A glob pattern, like `*.{ts,js}`. */ - pattern?: string, - } - | { - /** A language id, like `typescript`. */ - language?: string, - /** A Uri [scheme](#Uri.scheme), like `file` or `untitled`. */ - scheme?: string, - /** A glob pattern, like `*.{ts,js}`. */ - pattern: string, - }; - - declare export type DocumentSelector = Array; - - declare type Diagnostic = { - // The range at which the message applies. - range: Range, - // The diagnostic's severity. Can be omitted. If omitted it is up to the - // client to interpret diagnostics as error, warning, info or hint. - severity?: number, - // The diagnostic's code. Can be omitted. - code?: number | string, - // A human-readable string describing the source of this - // diagnostic, e.g. 'typescript' or 'super lint'. - source?: string, - // The diagnostic's message. - message: string, - // Any related locations. - relatedLocations?: RelatedLocation[], - }; - - declare type RelatedLocation = { - location: Location, - message: string, - }; - - declare export var DiagnosticSeverity: { - // Reports an error. - Error: 1, - // Reports a warning. - Warning: 2, - // Reports an information. - Information: 3, - // Reports a hint. - Hint: 4, - }; - - declare type Command = { - // Title of the command, like `save`. - title: string, - // The identifier of the actual command handler. - command: string, - // Arguments that the command handler should be invoked with. - arguments?: any[], - }; - - declare type TextEdit = { - // The range of the text document to be manipulated. To insert - // text into a document create a range where start === end. - range: Range, - // The string to be inserted. For delete operations use an empty string. - newText: string, - }; - - declare type WorkspaceEdit = { - // Holds changes to existing resources. - changes?: {[uri: string]: TextEdit[]}, - - // An array of `TextDocumentEdit`s to express changes to n different text documents - // where each text document edit addresses a specific version of a text document. - // Whether a client supports versioned document edits is expressed via - // `WorkspaceClientCapabilities.workspaceEdit.documentChanges`. - documentChanges?: TextDocumentEdit[], - }; - - declare type TextDocumentIdentifier = { - // The text document's URI. - uri: string, - }; - - declare type TextDocumentItem = { - // The text document's URI. - uri: string, - // The text document's language identifier. - languageId: string, - // The version number of this document (it will strictly increase after each - // change, including undo/redo). - version: number, - // The content of the opened text document. - text: string, - }; - - declare type VersionedTextDocumentIdentifier = TextDocumentIdentifier & { - // The version number of this document. - version: number, - }; - - declare type TextDocumentPositionParams = { - // The text document. - textDocument: TextDocumentIdentifier, - // The position inside the text document. - position: Position, - }; - - // General - - declare export var ErrorCodes: { - ParseError: -32700, - InvalidRequest: -32600, - MethodNotFound: -32601, - InvalidParams: -32602, - InternalError: -32603, - serverErrorStart: -32099, - serverErrorEnd: -32000, - ServerNotInitialized: -32002, - UnknownErrorCode: -32001, - // eslint-disable-next-line nuclide-internal/api-spelling - RequestCancelled: -32800, - }; - - declare export type InitializeParams = { - // The process Id of the parent process that started - // the server. Is null if the process has not been started by another process. - // If the parent process is not alive then the server should exit - // (see exit notification) its process. - processId?: number, - // The rootPath of the workspace. Is null if no folder is open. - rootPath?: string, - // The rootUri of the workspace. Is null if no folder is open. If both - // `rootPath` and `rootUri` are set rootUri` wins. - rootUri?: string, // TODO: this should be DocumentUri - // User provided initialization options. - initializationOptions?: any, - // The capabilities provided by the client (editor) - capabilities: ClientCapabilities, - // The initial trace setting. If omitted trace is disabled ('off') - trace?: 'off' | 'messages' | 'verbose', - }; - - // Workspace specific client capabilities. - declare type WorkspaceClientCapabilities = {| - // The client supports applying batch edits to the workspace by supporting - // the request 'workspace/applyEdit' - applyEdit?: boolean, - // Capabilities specific to `WorkspaceEdit`s - workspaceEdit?: {| - // The client supports versioned document changes in `WorkspaceEdit`s - documentChanges?: boolean, - |}, - // Capabilities specific to `workspace/didChangeConfiguration` notification. - didChangeConfiguration?: {| - // Did change configuration notification supports dynamic registration. - dynamicRegistration?: boolean, - |}, - // Capabilities specific to `workspace/didChangeWatchedFiles` notification. - didChangeWatchedFiles?: {| - // Did change watched files notification supports dynamic registration. - dynamicRegistration?: boolean, - |}, - // Capabilities specific to the `workspace/symbol` request. - symbol?: {| - // Symbol request supports dynamic registration. - dynamicRegistration?: boolean, - |}, - // Capabilities specific to the `workspace/executeCommand` request. - executeCommand?: {| - // Execute command supports dynamic registration. - dynamicRegistration?: boolean, - |}, - |}; - - // Text document specific client capabilities. - declare type TextDocumentClientCapabilities = {| - synchronization?: {| - // Whether text document synchronization supports dynamic registration. - dynamicRegistration?: boolean, - // The client supports sending will save notifications. - willSave?: boolean, - // The client supports sending a will save request and - // waits for a response providing text edits which will - // be applied to the document before it is saved. - willSaveWaitUntil?: boolean, - // The client supports did save notifications. - didSave?: boolean, - |}, - // Capabilities specific to the `textDocument/completion` - completion?: {| - dynamicRegistration?: boolean, - // The client supports the following `CompletionItem` specific capabilities - completionItem?: {| - // Client supports snippets as insert text. - // A snippet can define tab stops and placeholders with `$1`, `$2` - // and `${3:foo}`. `$0` defines the final tab stop, it defaults to - // the end of the snippet. Placeholders with equal identifiers are linked - // that is typing in one will update others too. - snippetSupport?: boolean, - |}, - |}, - // Capabilities specific to the `textDocument/hover` - hover?: {| - dynamicRegistration?: boolean, - |}, - // Capabilities specific to the `textDocument/signatureHelp` - signatureHelp?: {| - dynamicRegistration?: boolean, - |}, - // Capabilities specific to the `textDocument/references` - references?: {| - dynamicRegistration?: boolean, - |}, - // Capabilities specific to the `textDocument/documentHighlight` - documentHighlight?: {| - dynamicRegistration?: boolean, - |}, - // Capabilities specific to the `textDocument/documentSymbol` - documentSymbol?: {| - dynamicRegistration?: boolean, - |}, - // Capabilities specific to the `textDocument/formatting` - formatting?: {| - dynamicRegistration?: boolean, - |}, - // Capabilities specific to the `textDocument/rangeFormatting` - rangeFormatting?: {| - dynamicRegistration?: boolean, - |}, - // Capabilities specific to the `textDocument/onTypeFormatting` - onTypeFormatting?: {| - dynamicRegistration?: boolean, - |}, - // Capabilities specific to the `textDocument/definition` - definition?: {| - dynamicRegistration?: boolean, - |}, - // Capabilities specific to the `textDocument/codeAction` - codeAction?: {| - dynamicRegistration?: boolean, - |}, - // Capabilities specific to the `textDocument/codeLens` - codeLens?: {| - dynamicRegistration?: boolean, - |}, - // Capabilities specific to the `textDocument/documentLink` - documentLink?: {| - dynamicRegistration?: boolean, - |}, - // Capabilities specific to the `textDocument/rename` - rename?: {| - dynamicRegistration?: boolean, - |}, - |}; - - declare type WindowClientCapabilities = {| - // Capabilities specific to the `window/progress` notification. - progress?: {| - // Progress notification supports dynamic registration. - dynamicRegistration?: boolean, - |}, - // Capabilities specific to the `window/actionRequired` notification. - actionRequired?: {| - // ActionRequired notification supports dynamic registration. - dynamicRegistration?: boolean, - |}, - |}; - - declare export type ClientCapabilities = {| - // Workspace specific client capabilities. - workspace?: WorkspaceClientCapabilities, - // Text document specific client capabilities. - textDocument?: TextDocumentClientCapabilities, - // Window specific client capabilities. (Nuclide-only) - window?: WindowClientCapabilities, - // Experimental client capabilities. - experimental?: mixed, - |}; - - declare type InitializeResult = { - // The capabilities the language server provides. - capabilities: ServerCapabilities, - }; - - declare export type InitializeError = { - // Indicates whether the client should retry to send the - // initilize request after showing the message provided - // in the ResponseError. - retry: boolean, - }; - - // Defines how the host (editor) should sync document changes to the language server. - declare export var TextDocumentSyncKind: { - // Documents should not be synced at all. - None: 0, - // Documents are synced by always sending the full content of the document. - Full: 1, - // Documents are synced by sending the full content on open. After that only incremental - // updates to the document are sent. - Incremental: 2, - }; - - // Completion options. - declare type CompletionOptions = { - // The server provides support to resolve additional information for a completion item. - resolveProvider?: boolean, - // The characters that trigger completion automatically. - triggerCharacters?: string[], - }; - - // Signature help options. - declare type SignatureHelpOptions = { - // The characters that trigger signature help automatically. - triggerCharacters?: string[], - }; - - // Code Lens options. - declare type CodeLensOptions = { - // Code lens has a resolve provider as well. - resolveProvider?: boolean, - }; - - // Format document on type options - declare type DocumentOnTypeFormattingOptions = { - // A character on which formatting should be triggered, like `};`. - firstTriggerCharacter: string, - // More trigger characters. - moreTriggerCharacter?: string[], - }; - - // Save options. - declare type SaveOptions = { - // The client is supposed to include the content on save. - includeText?: boolean, - }; - - declare type TextDocumentSyncOptions = { - // Open and close notifications are sent to the server. - openClose?: boolean, - // Change notifications are sent to the server. One of TextDocumentSyncKind. - change?: number, - // Will save notifications are sent to the server. - willSave?: boolean, - // Will save wait until requests are sent to the server. - willSaveWaitUntil?: boolean, - // Save notifications are sent to the server. - save?: SaveOptions, - }; - - declare export type ServerCapabilities = { - // Defines how text documents are synced. If a number, is one of TextDocumentSyncKind - textDocumentSync?: TextDocumentSyncOptions | number, - // The server provides hover support. - hoverProvider?: boolean, - // The server provides completion support. - completionProvider?: CompletionOptions, - // The server provides signature help support. - signatureHelpProvider?: SignatureHelpOptions, - // The server provides goto definition support. - definitionProvider?: boolean, - // The server provides find references support. - referencesProvider?: boolean, - // The server provides document highlight support. - documentHighlightProvider?: boolean, - // The server provides document symbol support. - documentSymbolProvider?: boolean, - // The server provides workspace symbol support. - workspaceSymbolProvider?: boolean, - // The server provides code actions. - codeActionProvider?: boolean, - // The server provides code lens. - codeLensProvider?: CodeLensOptions, - // The server provides document formatting. - documentFormattingProvider?: boolean, - // The server provides document range formatting. - documentRangeFormattingProvider?: boolean, - // The server provides document formatting on typing. - documentOnTypeFormattingProvider?: DocumentOnTypeFormattingOptions, - // The server provides rename support. - renameProvider?: boolean, - // The server provides type coverage support. - typeCoverageProvider?: boolean, - // The server responds to rage requests - rageProvider?: boolean, - }; - - declare type RageItem = { - // Title convention is [host:]/path/file[:meta] - if ommitted, client picks - title?: string, - // Arbitrary text for the rage report - data: string, - }; - - // Document - - declare type PublishDiagnosticsParams = { - // The URI for which diagnostic information is reported. - uri: string, - // An array of diagnostic information items. - diagnostics: Diagnostic[], - }; - - // Represents a collection of [completion items](#CompletionItem) to be presented in the editor. - declare type CompletionList = { - // This list it not complete. Further typing should result in recomputing this list. - isIncomplete: boolean, - // The completion items. - items: CompletionItem[], - }; - - // Defines whether the insert text in a completion item should be interpreted as plain text or a snippet. - declare export var InsertTextFormat: { - PlainText: 1, - Snippet: 2, - }; - - declare type MarkupKind = 'plaintext' | 'markdown'; - - declare type MarkupContent = { - // The type of the Markup - kind: MarkupKind, - - // The content itself - value: string, - }; - - declare type CompletionItem = { - // The label of this completion item. By default - // also the text that is inserted when selecting - // this completion. - label: string, - // The kind of this completion item. Based of the kind an icon is chosen by the editor. - kind?: number, - // A human-readable string with additional information - // about this item, like type or symbol information. - detail?: string, - // (Nuclide-specific) A human-readable string that should be displayed along - // with the label. This is typically a subset of what's present in detail - // and/or documentation fields; those fields, however, are typically - // only shown when the user selects a label. If absent, then it won't be - // displayed alongside the label. - inlineDetail?: string, - // (Nuclide-specific) The type of the item, if applicable. The editor may - // chose to also display this along with the label. The type is typically - // a subset of what's present in detail and/or documentation fields; by - // putting the information here as well, the editor has more flexibility. - // If absent, then the type of the item won't be displayed. - itemType?: string, - // A human-readable string that represents a doc-comment. - documentation?: string | MarkupContent, - // A string that should be used when comparing this item - // with other items. When `falsy` the label is used. - sortText?: string, - // A string that should be used when filtering a set of - // completion items. When `falsy` the label is used. - filterText?: string, - // A string that should be inserted a document when selecting - // this completion. When `falsy` the label is used. - insertText?: string, - // The format of the insert text. The format applies to both the `insertText` property - // and the `newText` property of a provided `textEdit`. - insertTextFormat?: number, - // An edit which is applied to a document when selecting - // this completion. When an edit is provided the value of - // insertText is ignored. - textEdit?: TextEdit, - // An optional array of additional text edits that are applied when - // selecting this completion. Edits must not overlap with the main edit - // nor with themselves. - additionalTextEdits?: TextEdit[], - // An optional command that is executed *after* inserting this completion. *Note* that - // additional modifications to the current document should be described with the - // additionalTextEdits-property. - command?: Command, - // An data entry field that is preserved on a completion item between - // a completion and a completion resolve request. - data?: any, - }; - - // The kind of a completion entry. - declare export var CompletionItemKind: { - Text: 1, - Method: 2, - Function: 3, - Constructor: 4, - Field: 5, - Variable: 6, - Class: 7, - Interface: 8, - Module: 9, - Property: 10, - Unit: 11, - Value: 12, - Enum: 13, - Keyword: 14, - Snippet: 15, - Color: 16, - File: 17, - Reference: 18, - }; - - // The result of a hover request. - declare type Hover = { - // The hover's content - contents: MarkedString | MarkedString[], - // An optional range is a range inside a text document - // that is used to visualize a hover, e.g. by changing the background color. - range?: Range, - }; - - /** - * The marked string is rendered: - * - as markdown if it is represented as a string - * - as code block of the given language if it is represented as a pair of a language and a value - * - * The pair of a language and a value is an equivalent to markdown: - * ```${language}; - * ${value}; - * ``` - */ - declare type MarkedString = string | {language: string, value: string}; - - /** - * Signature help represents the signature of something - * callable. There can be multiple signature but only one - * active and only one active parameter. - */ - declare type SignatureHelp = { - // One or more signatures. - signatures: SignatureInformation[], - // The active signature. - activeSignature?: number, - // The active parameter of the active signature. - activeParameter?: number, - }; - - /** - * Represents the signature of something callable. A signature - * can have a label, like a function-name, a doc-comment, and - * a set of parameters. - */ - declare type SignatureInformation = { - // The label of this signature. Will be shown in the UI. - label: string, - // The human-readable doc-comment of this signature. Will be shown in the UI but can be omitted. - documentation?: string, - // The parameters of this signature. - parameters?: ParameterInformation[], - }; - - /** - * Represents a parameter of a callable-signature. A parameter can - * have a label and a doc-comment. - */ - declare type ParameterInformation = { - // The label of this parameter. Will be shown in the UI. - label: string, - // The human-readable doc-comment of this parameter. Will be shown in the UI but can be omitted. - documentation?: string, - }; - - declare type ReferenceParams = TextDocumentPositionParams & { - context: ReferenceContext, - }; - - declare type ReferenceContext = { - // Include the declaration of the current symbol. - includeDeclaration: boolean, - }; - - /** - * A document highlight is a range inside a text document which deserves - * special attention. Usually a document highlight is visualized by changing - * the background color of its range. - * - */ - declare type DocumentHighlight = { - // The range this highlight applies to. - range: Range, - // The highlight kind, default is DocumentHighlightKind.Text. - kind?: number, - }; - - declare export var DocumentHighlightKind: { - // A textual occurrance. - Text: 1, - // Read-access of a symbol, like reading a variable. - Read: 2, - // Write-access of a symbol, like writing to a variable. - Write: 3, - }; - - declare type DocumentSymbolParams = { - // The text document. - textDocument: TextDocumentIdentifier, - }; - - /** - * Represents information about programming constructs like variables, classes, - * interfaces etc. - */ - declare type SymbolInformation = { - // The name of this symbol. - name: string, - // The kind of this symbol. - kind: number, - // The location of this symbol. - location: Location, - // The name of the symbol containing this symbol. - containerName?: string, - }; - - declare export var SymbolKind: { - File: 1, - Module: 2, - Namespace: 3, - Package: 4, - Class: 5, - Method: 6, - Property: 7, - Field: 8, - Constructor: 9, - Enum: 10, - Interface: 11, - Function: 12, - Variable: 13, - Constant: 14, - String: 15, - Number: 16, - Boolean: 17, - Array: 18, - }; - - // The parameters of a Workspace Symbol Request. - declare type WorkspaceSymbolParams = { - // A non-empty query string. - query: string, - }; - - // Params for the CodeActionRequest - declare type CodeActionParams = { - // The document in which the command was invoked. - textDocument: TextDocumentIdentifier, - // The range for which the command was invoked. - range: Range, - // Context carrying additional information. - context: CodeActionContext, - }; - - // Contains additional diagnostic information about the context in which a code action is run. - declare type CodeActionContext = { - // An array of diagnostics. - diagnostics: Diagnostic[], - }; - - declare type CodeLensParams = { - // The document to request code lens for. - textDocument: TextDocumentIdentifier, - }; - - /** - * A code lens represents a command that should be shown along with - * source text, like the number of references, a way to run tests, etc. - * - * A code lens is _unresolved_ when no command is associated to it. For performance - * reasons the creation of a code lens and resolving should be done in two stages. - */ - declare type CodeLens = { - // The range in which this code lens is valid. Should only span a single line. - range: Range, - // The command this code lens represents. - command?: Command, - // A data entry field that is preserved on a code lens item between a code lens - // and a code lens resolve request. - data?: any, - }; - - declare type DocumentLinkParams = { - // The document to provide document links for. - textDocument: TextDocumentIdentifier, - }; - - /** - * A document link is a range in a text document that links to an internal or - * external resource, like another - * text document or a web site. - */ - declare type DocumentLink = { - // The range this link applies to. - range: Range, - // The uri this link points to. - target: string, - }; - - declare type DocumentFormattingParams = { - // The document to format. - textDocument: TextDocumentIdentifier, - // The format options. - options: FormattingOptions, - }; - - // Value-object describing what options formatting should use. - declare type FormattingOptions = { - // Signature for further properties. - [key: string]: boolean | number | string, - // Size of a tab in spaces. - tabSize: number, - // Prefer spaces over tabs. - insertSpaces: boolean, - }; - - declare type DocumentRangeFormattingParams = { - // The document to format. - textDocument: TextDocumentIdentifier, - // The range to format. - range: Range, - // The format options. - options: FormattingOptions, - }; - - declare type DocumentOnTypeFormattingParams = { - // The document to format. - textDocument: TextDocumentIdentifier, - // The position at which this request was sent. - position: Position, - // The character that has been typed. - ch: string, - // The format options. - options: FormattingOptions, - }; - - declare type RenameParams = { - // The document to format. - textDocument: TextDocumentIdentifier, - // The position at which this request was sent. - position: Position, - /** - * The new name of the symbol. If the given name is not valid the - * request must return a [ResponseError](#ResponseError) with an - * appropriate message set. - */ - newName: string, - }; - - // TypeCoverageParams: a nuclide-specific way to show type coverage for a file - declare type TypeCoverageParams = { - textDocument: TextDocumentIdentifier, // The text document. - }; - - declare type TypeCoverageResult = { - coveredPercent: number, // what percent of the file is covered? - uncoveredRanges: UncoveredRange[], - }; - - declare type UncoveredRange = { - range: Range, - message: string, // human-readable explanation, maybe with suggested fix - }; - - // Window - - declare type ShowMessageParams = { - // The message type. See {@link MessageType};. - type: number, - // The actual message. - message: string, - }; - - declare export var MessageType: { - // An error message. - Error: 1, - // A warning message. - Warning: 2, - // An information message. - Info: 3, - // A log message. - Log: 4, - }; - - declare type ShowMessageRequestParams = { - // The message type. See {@link MessageType}; - type: number, - // The actual message - message: string, - // The message action items to present. - actions?: MessageActionItem[], - }; - - declare type MessageActionItem = { - // A short title like 'Retry', 'Open Log' etc. - title: string, - }; - - declare type LogMessageParams = { - // The message type. See {@link MessageType}; - type: number, - // The actual message - message: string, - }; - - declare type ProgressParams = { - // The id of this progress report (so we can update/close it) - id: number | string, - // A message/tooltip for this progress report; pass `null` when done. - label: string | null, - }; - - declare type ActionRequiredParams = { - // The id of this action-required report (so we can close it) - id: string | number, - // A message/tooltip. Pass `null` when action is no longer required. - label: string | null, - }; - - // Workspace - - declare type DidChangeConfigurationParams = { - // The actual changed settings - settings: any, - }; - - declare type DidOpenTextDocumentParams = { - // The document that was opened. - textDocument: TextDocumentItem, - }; - - declare type DidChangeTextDocumentParams = { - // The document that did change. The version number points - // to the version after all provided content changes have - // been applied. - textDocument: VersionedTextDocumentIdentifier, - // The actual content changes. - contentChanges: TextDocumentContentChangeEvent[], - }; - - // An event describing a change to a text document. If range and rangeLength are omitted - // the new text is considered to be the full content of the document. - declare type TextDocumentContentChangeEvent = { - // The range of the document that changed. - range?: Range, - // The length of the range that got replaced. - rangeLength?: number, - // The new text of the document. - text: string, - }; - - declare type DidCloseTextDocumentParams = { - // The document that was closed. - textDocument: TextDocumentIdentifier, - }; - - declare type DidSaveTextDocumentParams = { - // The document that was saved. - textDocument: TextDocumentIdentifier, - // Optional the content when saved. Depends on the includeText value - // when the save notifcation was requested. - text: ?string, - }; - - declare type DidChangeWatchedFilesParams = { - // The actual file events. - changes: FileEvent[], - }; - - // The file event type. - declare export var FileChangeType: { - // The file got created. - Created: 1, - // The file got changed. - Changed: 2, - // The file got deleted. - Deleted: 3, - }; - - // An event describing a file change. - declare type FileEvent = { - // The file's URI. - uri: string, - // The change type. - type: number, - }; - - declare type ExecuteCommandParams = { - // The identifier of the actual command handler. - command: string, - // Arguments that the command should be invoked with. - arguments?: any[], - }; - - declare type ApplyWorkspaceEditParams = { - // The edits to apply. - edit: WorkspaceEdit, - }; - - declare type ApplyWorkspaceEditResponse = { - // Indicates whether the edit was applied or not. - applied: boolean, - }; - - declare type TextDocumentEdit = { - // The text document to change. - textDocument: VersionedTextDocumentIdentifier, - // The edits to be applied. - edits: TextEdit[], - }; - - declare interface Message { - jsonrpc: string; - } - - declare type DataCallback = (data: Message) => void; - - declare interface PartialMessageInfo { - +messageToken: number; - +waitingTime: number; - } - - declare export interface MessageReader { - +onError: Event; - +onClose: Event; - +onPartialMessage: Event; - listen(callback: DataCallback): void; - dispose(): void; - } - - declare export interface MessageWriter { - +onError: Event; - +onClose: Event; - write(msg: Message): void; - dispose(): void; - } -} diff --git a/flow-libs/vscode-uri.js.flow b/flow-libs/vscode-uri.js.flow deleted file mode 100644 index 416687d65b..0000000000 --- a/flow-libs/vscode-uri.js.flow +++ /dev/null @@ -1,84 +0,0 @@ -/** - * 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 - */ - -declare module 'vscode-uri' { - /** - * Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986. - * This class is a simple parser which creates the basic component paths - * (http://tools.ietf.org/html/rfc3986#section-3) with minimal validation - * and encoding. - * - * foo://example.com:8042/over/there?name=ferret#nose - * \_/ \______________/\_________/ \_________/ \__/ - * | | | | | - * scheme authority path query fragment - * | _____________________|__ - * / \ / \ - * urn:example:animal:ferret:nose - * - * - */ - declare export default class URI { - static isUri(thing: mixed): boolean; - /** - * scheme is the 'http' part of 'http://www.msft.com/some/path?query#fragment'. - * The part before the first colon. - */ - +scheme: string; - /** - * authority is the 'www.msft.com' part of 'http://www.msft.com/some/path?query#fragment'. - * The part between the first double slashes and the next slash. - */ - +authority: string; - /** - * path is the '/some/path' part of 'http://www.msft.com/some/path?query#fragment'. - */ - +path: string; - /** - * query is the 'query' part of 'http://www.msft.com/some/path?query#fragment'. - */ - +query: string; - /** - * fragment is the 'fragment' part of 'http://www.msft.com/some/path?query#fragment'. - */ - +fragment: string; - /** - * Returns a string representing the corresponding file system path of this URI. - * Will handle UNC paths and normalize windows drive letters to lower-case. Also - * uses the platform specific path separator. Will *not* validate the path for - * invalid characters and semantics. Will *not* look at the scheme of this URI. - */ - +fsPath: string; - with(change: { - scheme?: string, - authority?: string, - path?: string, - query?: string, - fragment?: string, - }): URI; - static parse(value: string): URI; - static file(path: string): URI; - static from(components: { - scheme?: string, - authority?: string, - path?: string, - query?: string, - fragment?: string, - }): URI; - /** - * - * @param skipEncoding Do not encode the result, default is `false` - */ - toString(skipEncoding?: boolean): string; - toJSON(): any; - static revive(data: any): URI; - } -} diff --git a/flow-libs/vscode.js.flow b/flow-libs/vscode.js.flow deleted file mode 100644 index b2fbd43233..0000000000 --- a/flow-libs/vscode.js.flow +++ /dev/null @@ -1,6866 +0,0 @@ -// flow-typed signature: bf33a49e587a84791b989cd1f0afd101 -// flow-typed version: b43dff3e0e/vscode_v1.1.10/flow_>=v0.28.x - -declare module 'vscode' { - - /** - * The version of the editor. - */ - declare export var version: string; - - /** - * Represents a reference to a command. Provides a title which - * will be used to represent a command in the UI and, optionally, - * an array of arguments which will be passed to the command handler - * function when invoked. - */ - declare export interface Command { - /** - * Title of the command, like `save`. - */ - title: string; - - /** - * The identifier of the actual command handler. - * @see [commands.registerCommand](#commands.registerCommand). - */ - command: string; - - /** - * A tooltip for for command, when represented in the UI. - */ - tooltip?: string; - - /** - * Arguments that the command handler should be - * invoked with. - */ - arguments?: any[]; - } - - /** - * Represents a line of text, such as a line of source code. - * - * TextLine objects are __immutable__. When a [document](#TextDocument) changes, - * previously retrieved lines will not represent the latest state. - */ - declare export interface TextLine { - - /** - * The zero-based line number. - */ - +lineNumber: number; - - /** - * The text of this line without the line separator characters. - */ - +text: string; - - /** - * The range this line covers without the line separator characters. - */ - +range: Range; - - /** - * The range this line covers with the line separator characters. - */ - +rangeIncludingLineBreak: Range; - - /** - * The offset of the first character which is not a whitespace character as defined - * by `/\s/`. **Note** that if a line is all whitespaces the length of the line is returned. - */ - +firstNonWhitespaceCharacterIndex: number; - - /** - * Whether this line is whitespace only, shorthand - * for [TextLine.firstNonWhitespaceCharacterIndex](#TextLine.firstNonWhitespaceCharacterIndex) === [TextLine.text.length](#TextLine.text). - */ - +isEmptyOrWhitespace: boolean; - } - - /** - * Represents a text document, such as a source file. Text documents have - * [lines](#TextLine) and knowledge about an underlying resource like a file. - */ - declare export interface TextDocument { - - /** - * The associated URI for this document. Most documents have the __file__-scheme, indicating that they - * represent files on disk. However, some documents may have other schemes indicating that they are not - * available on disk. - */ - +uri: Uri; - - /** - * The file system path of the associated resource. Shorthand - * notation for [TextDocument.uri.fsPath](#TextDocument.uri). Independent of the uri scheme. - */ - +fileName: string; - - /** - * Is this document representing an untitled file. - */ - +isUntitled: boolean; - - /** - * The identifier of the language associated with this document. - */ - +languageId: string; - - /** - * The version number of this document (it will strictly increase after each - * change, including undo/redo). - */ - +version: number; - - /** - * `true` if there are unpersisted changes. - */ - +isDirty: boolean; - - /** - * `true` if the document have been closed. A closed document isn't synchronized anymore - * and won't be re-used when the same resource is opened again. - */ - +isClosed: boolean; - - /** - * Save the underlying file. - * - * @return A promise that will resolve to true when the file - * has been saved. If the file was not dirty or the save failed, - * will return false. - */ - save(): Thenable; - - /** - * The [end of line](#EndOfLine) sequence that is predominately - * used in this document. - */ - +eol: EndOfLineType; - - /** - * The number of lines in this document. - */ - +lineCount: number; - - /** - * Returns a text line denoted by the line number. Note - * that the returned object is *not* live and changes to the - * document are not reflected. - * - * @param line A line number in [0, lineCount). - * @return A [line](#TextLine). - */ - lineAt(line: number): TextLine; - - /** - * Returns a text line denoted by the position. Note - * that the returned object is *not* live and changes to the - * document are not reflected. - * - * The position will be [adjusted](#TextDocument.validatePosition). - * - * @see [TextDocument.lineAt](#TextDocument.lineAt) - * @param position A position. - * @return A [line](#TextLine). - */ - lineAt(position: Position): TextLine; - - /** - * Converts the position to a zero-based offset. - * - * The position will be [adjusted](#TextDocument.validatePosition). - * - * @param position A position. - * @return A valid zero-based offset. - */ - offsetAt(position: Position): number; - - /** - * Converts a zero-based offset to a position. - * - * @param offset A zero-based offset. - * @return A valid [position](#Position). - */ - positionAt(offset: number): Position; - - /** - * Get the text of this document. A substring can be retrieved by providing - * a range. The range will be [adjusted](#TextDocument.validateRange). - * - * @param range Include only the text included by the range. - * @return The text inside the provided range or the entire text. - */ - getText(range?: Range): string; - - /** - * Get a word-range at the given position. By default words are defined by - * common separators, like space, -, _, etc. In addition, per languge custom - * [word definitions](#LanguageConfiguration.wordPattern) can be defined. It - * is also possible to provide a custom regular expression. - * - * * *Note 1:* A custom regular expression must not match the empty string and - * if it does, it will be ignored. - * * *Note 2:* A custom regular expression will fail to match multiline strings - * and in the name of speed regular expressions should not match words with - * spaces. Use [`TextLine.text`](#TextLine.text) for more complex, non-wordy, scenarios. - * - * The position will be [adjusted](#TextDocument.validatePosition). - * - * @param position A position. - * @param regex Optional regular expression that describes what a word is. - * @return A range spanning a word, or `undefined`. - */ - getWordRangeAtPosition(position: Position, regex?: RegExp): ?Range; - - /** - * Ensure a range is completely contained in this document. - * - * @param range A range. - * @return The given range or a new, adjusted range. - */ - validateRange(range: Range): Range; - - /** - * Ensure a position is contained in the range of this document. - * - * @param position A position. - * @return The given position or a new, adjusted position. - */ - validatePosition(position: Position): Position; - } - - /** - * Represents a line and character position, such as - * the position of the cursor. - * - * Position objects are __immutable__. Use the [with](#Position.with) or - * [translate](#Position.translate) methods to derive new positions - * from an existing position. - */ - declare export class Position { - - /** - * The zero-based line value. - */ - +line: number; - - /** - * The zero-based character value. - */ - +character: number; - - /** - * @param line A zero-based line value. - * @param character A zero-based character value. - */ - constructor(line: number, character: number): void; - - /** - * Check if this position is before `other`. - * - * @param other A position. - * @return `true` if position is on a smaller line - * or on the same line on a smaller character. - */ - isBefore(other: Position): boolean; - - /** - * Check if this position is before or equal to `other`. - * - * @param other A position. - * @return `true` if position is on a smaller line - * or on the same line on a smaller or equal character. - */ - isBeforeOrEqual(other: Position): boolean; - - /** - * Check if this position is after `other`. - * - * @param other A position. - * @return `true` if position is on a greater line - * or on the same line on a greater character. - */ - isAfter(other: Position): boolean; - - /** - * Check if this position is after or equal to `other`. - * - * @param other A position. - * @return `true` if position is on a greater line - * or on the same line on a greater or equal character. - */ - isAfterOrEqual(other: Position): boolean; - - /** - * Check if this position is equal to `other`. - * - * @param other A position. - * @return `true` if the line and character of the given position are equal to - * the line and character of this position. - */ - isEqual(other: Position): boolean; - - /** - * Compare this to `other`. - * - * @param other A position. - * @return A number smaller than zero if this position is before the given position, - * a number greater than zero if this position is after the given position, or zero when - * this and the given position are equal. - */ - compareTo(other: Position): number; - - /** - * Create a new position relative to this position. - * - * @param lineDelta Delta value for the line value, default is `0`. - * @param characterDelta Delta value for the character value, default is `0`. - * @return A position which line and character is the sum of the current line and - * character and the corresponding deltas. - */ - translate(lineDelta?: number, characterDelta?: number): Position; - - /** - * Derived a new position relative to this position. - * - * @param change An object that describes a delta to this position. - * @return A position that reflects the given delta. Will return `this` position if the change - * is not changing anything. - */ - translate(change: { lineDelta?: number; characterDelta?: number; }): Position; - - /** - * Create a new position derived from this position. - * - * @param line Value that should be used as line value, default is the [existing value](#Position.line) - * @param character Value that should be used as character value, default is the [existing value](#Position.character) - * @return A position where line and character are replaced by the given values. - */ - with(line?: number, character?: number): Position; - - /** - * Derived a new position from this position. - * - * @param change An object that describes a change to this position. - * @return A position that reflects the given change. Will return `this` position if the change - * is not changing anything. - */ - with(change: { line?: number; character?: number; }): Position; - } - - /** - * A range represents an ordered pair of two positions. - * It is guaranteed that [start](#Range.start).isBeforeOrEqual([end](#Range.end)) - * - * Range objects are __immutable__. Use the [with](#Range.with), - * [intersection](#Range.intersection), or [union](#Range.union) methods - * to derive new ranges from an existing range. - */ - declare export class Range { - - /** - * The start position. It is before or equal to [end](#Range.end). - */ - +start: Position; - - /** - * The end position. It is after or equal to [start](#Range.start). - */ - +end: Position; - - /** - * Create a new range from two positions. If `start` is not - * before or equal to `end`, the values will be swapped. - * - * @param start A position. - * @param end A position. - */ - constructor(start: Position, end: Position): void; - - /** - * Create a new range from number coordinates. It is a shorter equivalent of - * using `new Range(new Position(startLine, startCharacter), new Position(endLine, endCharacter))` - * - * @param startLine A zero-based line value. - * @param startCharacter A zero-based character value. - * @param endLine A zero-based line value. - * @param endCharacter A zero-based character value. - */ - constructor(startLine: number, startCharacter: number, endLine: number, endCharacter: number): void; - - /** - * `true` if `start` and `end` are equal. - */ - isEmpty: boolean; - - /** - * `true` if `start.line` and `end.line` are equal. - */ - isSingleLine: boolean; - - /** - * Check if a position or a range is contained in this range. - * - * @param positionOrRange A position or a range. - * @return `true` if the position or range is inside or equal - * to this range. - */ - contains(positionOrRange: Position | Range): boolean; - - /** - * Check if `other` equals this range. - * - * @param other A range. - * @return `true` when start and end are [equal](#Position.isEqual) to - * start and end of this range. - */ - isEqual(other: Range): boolean; - - /** - * Intersect `range` with this range and returns a new range or `undefined` - * if the ranges have no overlap. - * - * @param range A range. - * @return A range of the greater start and smaller end positions. Will - * return undefined when there is no overlap. - */ - intersection(range: Range): ?Range; - - /** - * Compute the union of `other` with this range. - * - * @param other A range. - * @return A range of smaller start position and the greater end position. - */ - union(other: Range): Range; - - /** - * Derived a new range from this range. - * - * @param start A position that should be used as start. The default value is the [current start](#Range.start). - * @param end A position that should be used as end. The default value is the [current end](#Range.end). - * @return A range derived from this range with the given start and end position. - * If start and end are not different `this` range will be returned. - */ - with(start?: Position, end?: Position): Range; - - /** - * Derived a new range from this range. - * - * @param change An object that describes a change to this range. - * @return A range that reflects the given change. Will return `this` range if the change - * is not changing anything. - */ - with(change: { start?: Position, end?: Position }): Range; - } - - /** - * Represents a text selection in an editor. - */ - declare export class Selection extends Range { - - /** - * The position at which the selection starts. - * This position might be before or after [active](#Selection.active). - */ - anchor: Position; - - /** - * The position of the cursor. - * This position might be before or after [anchor](#Selection.anchor). - */ - active: Position; - - /** - * Create a selection from two postions. - * - * @param anchor A position. - * @param active A position. - */ - constructor(anchor: Position, active: Position): void; - - /** - * Create a selection from four coordinates. - * - * @param anchorLine A zero-based line value. - * @param anchorCharacter A zero-based character value. - * @param activeLine A zero-based line value. - * @param activeCharacter A zero-based character value. - */ - constructor(anchorLine: number, anchorCharacter: number, activeLine: number, activeCharacter: number): void; - - /** - * A selection is reversed if [active](#Selection.active).isBefore([anchor](#Selection.anchor)). - */ - isReversed: boolean; - } - - /** - * Represents sources that can cause [selection change events](#window.onDidChangeTextEditorSelection). - */ - declare export var TextEditorSelectionChangeKind: { - /** - * Selection changed due to typing in the editor. - */ - +Keyboard: 1, - /** - * Selection change due to clicking in the editor. - */ - +Mouse: 2, - /** - * Selection changed because a command ran. - */ - +Command: 3 - } - declare export type TextEditorSelectionChangeKindType = $Values; - - /** - * Represents an event describing the change in a [text editor's selections](#TextEditor.selections). - */ - declare export interface TextEditorSelectionChangeEvent { - /** - * The [text editor](#TextEditor) for which the selections have changed. - */ - textEditor: TextEditor; - /** - * The new value for the [text editor's selections](#TextEditor.selections). - */ - selections: Selection[]; - /** - * The [change kind](#TextEditorSelectionChangeKind) which has triggered this - * event. Can be `undefined`. - */ - kind?: TextEditorSelectionChangeKindType; - } - - /** - * Represents an event describing the change in a [text editor's options](#TextEditor.options). - */ - declare export interface TextEditorOptionsChangeEvent { - /** - * The [text editor](#TextEditor) for which the options have changed. - */ - textEditor: TextEditor; - /** - * The new value for the [text editor's options](#TextEditor.options). - */ - options: TextEditorOptions; - } - - /** - * Represents an event describing the change of a [text editor's view column](#TextEditor.viewColumn). - */ - declare export interface TextEditorViewColumnChangeEvent { - /** - * The [text editor](#TextEditor) for which the options have changed. - */ - textEditor: TextEditor; - /** - * The new value for the [text editor's view column](#TextEditor.viewColumn). - */ - viewColumn: ViewColumnType; - } - - /** - * Rendering style of the cursor. - */ - declare export var TextEditorCursorStyle: { - /** - * Render the cursor as a vertical thick line. - */ - +Line: 1, - /** - * Render the cursor as a block filled. - */ - +Block: 2, - /** - * Render the cursor as a thick horizontal line. - */ - +Underline: 3, - /** - * Render the cursor as a vertical thin line. - */ - +LineThin: 4, - /** - * Render the cursor as a block outlined. - */ - +BlockOutline: 5, - /** - * Render the cursor as a thin horizontal line. - */ - +UnderlineThin: 6 - }; - declare export type TextEditorCursorStyleType = $Values; - - /** - * Rendering style of the line numbers. - */ - declare export var TextEditorLineNumbersStyle: { - /** - * Do not render the line numbers. - */ - +Off: 0, - /** - * Render the line numbers. - */ - +On: 1, - /** - * Render the line numbers with values relative to the primary cursor location. - */ - +Relative: 2 - } - declare export type TextEditorLineNumbersStyleType = $Values; - - /** - * Represents a [text editor](#TextEditor)'s [options](#TextEditor.options). - */ - declare export interface TextEditorOptions { - - /** - * The size in spaces a tab takes. This is used for two purposes: - * - the rendering width of a tab character; - * - the number of spaces to insert when [insertSpaces](#TextEditorOptions.insertSpaces) is true. - * - * When getting a text editor's options, this property will always be a number (resolved). - * When setting a text editor's options, this property is optional and it can be a number or `"auto"`. - */ - tabSize?: number | string; - - /** - * When pressing Tab insert [n](#TextEditorOptions.tabSize) spaces. - * When getting a text editor's options, this property will always be a boolean (resolved). - * When setting a text editor's options, this property is optional and it can be a boolean or `"auto"`. - */ - insertSpaces?: boolean | string; - - /** - * The rendering style of the cursor in this editor. - * When getting a text editor's options, this property will always be present. - * When setting a text editor's options, this property is optional. - */ - cursorStyle?: TextEditorCursorStyleType; - - /** - * Render relative line numbers w.r.t. the current line number. - * When getting a text editor's options, this property will always be present. - * When setting a text editor's options, this property is optional. - */ - lineNumbers?: TextEditorLineNumbersStyleType; - } - - /** - * Represents a handle to a set of decorations - * sharing the same [styling options](#DecorationRenderOptions) in a [text editor](#TextEditor). - * - * To get an instance of a `TextEditorDecorationType` use - * [createTextEditorDecorationType](#window.createTextEditorDecorationType). - */ - declare export interface TextEditorDecorationType { - - /** - * Internal representation of the handle. - */ - +key: string; - - /** - * Remove this decoration type and all decorations on all text editors using it. - */ - dispose(): void; - } - - /** - * Represents different [reveal](#TextEditor.revealRange) strategies in a text editor. - */ - declare export var TextEditorRevealType: { - /** - * The range will be revealed with as little scrolling as possible. - */ - +Default: 0, - /** - * The range will always be revealed in the center of the viewport. - */ - +InCenter: 1, - /** - * If the range is outside the viewport, it will be revealed in the center of the viewport. - * Otherwise, it will be revealed with as little scrolling as possible. - */ - +InCenterIfOutsideViewport: 2, - /** - * The range will always be revealed at the top of the viewport. - */ - +AtTop: 3 - } - declare export type TextEditorRevealTypeType = $Values; - - /** - * Represents different positions for rendering a decoration in an [overview ruler](#DecorationRenderOptions.overviewRulerLane). - * The overview ruler supports three lanes. - */ - declare export var OverviewRulerLane: { - +Left: 1, - +Center: 2, - +Right: 4, - +Full: 7 - } - declare export type OverviewRulerLaneType = $Values; - - /** - * Describes the behavior of decorations when typing/editing at their edges. - */ - declare export var DecorationRangeBehavior: { - /** - * The decoration's range will widen when edits occur at the start or end. - */ - +OpenOpen: 0, - /** - * The decoration's range will not widen when edits occur at the start of end. - */ - +ClosedClosed: 1, - /** - * The decoration's range will widen when edits occur at the start, but not at the end. - */ - +OpenClosed: 2, - /** - * The decoration's range will widen when edits occur at the end, but not at the start. - */ - +ClosedOpen: 3 - } - declare export type DecorationRangeBehaviorType = $Values; - - /** - * Represents options to configure the behavior of showing a [document](#TextDocument) in an [editor](#TextEditor). - */ - declare export interface TextDocumentShowOptions { - /** - * An optional view column in which the [editor](#TextEditor) should be shown. - * The default is the [one](#ViewColumn.One), other values are adjusted to - * be `Min(column, columnCount + 1)`, the [active](#ViewColumn.Active)-column is - * not adjusted. - */ - viewColumn?: ViewColumnType; - - /** - * An optional flag that when `true` will stop the [editor](#TextEditor) from taking focus. - */ - preserveFocus?: boolean; - - /** - * An optional flag that controls if an [editor](#TextEditor)-tab will be replaced - * with the next editor or if it will be kept. - */ - preview?: boolean; - - /** - * An optional selection to apply for the document in the [editor](#TextEditor). - */ - selection?: Range; - } - - /** - * A reference to one of the workbench colors as defined in https://code.visualstudio.com/docs/getstarted/theme-color-reference. - * Using a theme color is preferred over a custom color as it gives theme authors and users the possibility to change the color. - */ - declare export class ThemeColor { - - /** - * Creates a reference to a theme color. - * @param id of the color. The available colors are listed in https://code.visualstudio.com/docs/getstarted/theme-color-reference. - */ - constructor(id: string): void; - } - - /** - * Represents theme specific rendering styles for a [text editor decoration](#TextEditorDecorationType). - */ - declare export interface ThemableDecorationRenderOptions { - /** - * Background color of the decoration. Use rgba() and define transparent background colors to play well with other decorations. - * Alternatively a color from the color registry can be [referenced](#ThemeColor). - */ - backgroundColor?: string | ThemeColor; - - /** - * CSS styling property that will be applied to text enclosed by a decoration. - */ - outline?: string; - - /** - * CSS styling property that will be applied to text enclosed by a decoration. - * Better use 'outline' for setting one or more of the individual outline properties. - */ - outlineColor?: string | ThemeColor; - - /** - * CSS styling property that will be applied to text enclosed by a decoration. - * Better use 'outline' for setting one or more of the individual outline properties. - */ - outlineStyle?: string; - - /** - * CSS styling property that will be applied to text enclosed by a decoration. - * Better use 'outline' for setting one or more of the individual outline properties. - */ - outlineWidth?: string; - - /** - * CSS styling property that will be applied to text enclosed by a decoration. - */ - border?: string; - - /** - * CSS styling property that will be applied to text enclosed by a decoration. - * Better use 'border' for setting one or more of the individual border properties. - */ - borderColor?: string | ThemeColor; - - /** - * CSS styling property that will be applied to text enclosed by a decoration. - * Better use 'border' for setting one or more of the individual border properties. - */ - borderRadius?: string; - - /** - * CSS styling property that will be applied to text enclosed by a decoration. - * Better use 'border' for setting one or more of the individual border properties. - */ - borderSpacing?: string; - - /** - * CSS styling property that will be applied to text enclosed by a decoration. - * Better use 'border' for setting one or more of the individual border properties. - */ - borderStyle?: string; - - /** - * CSS styling property that will be applied to text enclosed by a decoration. - * Better use 'border' for setting one or more of the individual border properties. - */ - borderWidth?: string; - - /** - * CSS styling property that will be applied to text enclosed by a decoration. - */ - fontStyle?: string; - - /** - * CSS styling property that will be applied to text enclosed by a decoration. - */ - fontWeight?: string; - - /** - * CSS styling property that will be applied to text enclosed by a decoration. - */ - textDecoration?: string; - - /** - * CSS styling property that will be applied to text enclosed by a decoration. - */ - cursor?: string; - - /** - * CSS styling property that will be applied to text enclosed by a decoration. - */ - color?: string | ThemeColor; - - /** - * CSS styling property that will be applied to text enclosed by a decoration. - */ - letterSpacing?: string; - - /** - * An **absolute path** or an URI to an image to be rendered in the gutter. - */ - gutterIconPath?: string | Uri; - - /** - * Specifies the size of the gutter icon. - * Available values are 'auto', 'contain', 'cover' and any percentage value. - * For further information: https://msdn.microsoft.com/en-us/library/jj127316(v=vs.85).aspx - */ - gutterIconSize?: string; - - /** - * The color of the decoration in the overview ruler. Use rgba() and define transparent colors to play well with other decorations. - */ - overviewRulerColor?: string | ThemeColor; - - /** - * Defines the rendering options of the attachment that is inserted before the decorated text - */ - before?: ThemableDecorationAttachmentRenderOptions; - - /** - * Defines the rendering options of the attachment that is inserted after the decorated text - */ - after?: ThemableDecorationAttachmentRenderOptions; - } - - declare export interface ThemableDecorationAttachmentRenderOptions { - /** - * Defines a text content that is shown in the attachment. Either an icon or a text can be shown, but not both. - */ - contentText?: string; - /** - * An **absolute path** or an URI to an image to be rendered in the attachment. Either an icon - * or a text can be shown, but not both. - */ - contentIconPath?: string | Uri; - /** - * CSS styling property that will be applied to the decoration attachment. - */ - border?: string; - /** - * CSS styling property that will be applied to text enclosed by a decoration. - */ - borderColor?: string | ThemeColor; - /** - * CSS styling property that will be applied to the decoration attachment. - */ - fontStyle?: string; - /** - * CSS styling property that will be applied to the decoration attachment. - */ - fontWeight?: string; - /** - * CSS styling property that will be applied to the decoration attachment. - */ - textDecoration?: string; - /** - * CSS styling property that will be applied to the decoration attachment. - */ - color?: string | ThemeColor; - /** - * CSS styling property that will be applied to the decoration attachment. - */ - backgroundColor?: string | ThemeColor; - /** - * CSS styling property that will be applied to the decoration attachment. - */ - margin?: string; - /** - * CSS styling property that will be applied to the decoration attachment. - */ - width?: string; - /** - * CSS styling property that will be applied to the decoration attachment. - */ - height?: string; - } - - /** - * Represents rendering styles for a [text editor decoration](#TextEditorDecorationType). - */ - declare export interface DecorationRenderOptions extends ThemableDecorationRenderOptions { - /** - * Should the decoration be rendered also on the whitespace after the line text. - * Defaults to `false`. - */ - isWholeLine?: boolean; - - /** - * Customize the growing behavior of the decoration when edits occur at the edges of the decoration's range. - * Defaults to `DecorationRangeBehavior.OpenOpen`. - */ - rangeBehavior?: DecorationRangeBehaviorType; - - /** - * The position in the overview ruler where the decoration should be rendered. - */ - overviewRulerLane?: OverviewRulerLaneType; - - /** - * Overwrite options for light themes. - */ - light?: ThemableDecorationRenderOptions; - - /** - * Overwrite options for dark themes. - */ - dark?: ThemableDecorationRenderOptions; - } - - /** - * Represents options for a specific decoration in a [decoration set](#TextEditorDecorationType). - */ - declare export interface DecorationOptions { - - /** - * Range to which this decoration is applied. The range must not be empty. - */ - range: Range; - - /** - * A message that should be rendered when hovering over the decoration. - */ - hoverMessage?: MarkedString | MarkedString[]; - - /** - * Render options applied to the current decoration. For performance reasons, keep the - * number of decoration specific options small, and use decoration types whereever possible. - */ - renderOptions?: DecorationInstanceRenderOptions; - } - - declare export interface ThemableDecorationInstanceRenderOptions { - /** - * Defines the rendering options of the attachment that is inserted before the decorated text - */ - before?: ThemableDecorationAttachmentRenderOptions; - - /** - * Defines the rendering options of the attachment that is inserted after the decorated text - */ - after?: ThemableDecorationAttachmentRenderOptions; - } - - declare export interface DecorationInstanceRenderOptions extends ThemableDecorationInstanceRenderOptions { - /** - * Overwrite options for light themes. - */ - light?: ThemableDecorationInstanceRenderOptions; - - /** - * Overwrite options for dark themes. - */ - dark?: ThemableDecorationInstanceRenderOptions; - } - - /** - * Represents an editor that is attached to a [document](#TextDocument). - */ - declare export interface TextEditor { - - /** - * The document associated with this text editor. The document will be the same for the entire lifetime of this text editor. - */ - document: TextDocument; - - /** - * The primary selection on this text editor. Shorthand for `TextEditor.selections[0]`. - */ - selection: Selection; - - /** - * The selections in this text editor. The primary selection is always at index 0. - */ - selections: Selection[]; - - /** - * Text editor options. - */ - options: TextEditorOptions; - - /** - * The column in which this editor shows. Will be `undefined` in case this - * isn't one of the three main editors, e.g an embedded editor. - */ - viewColumn?: ViewColumnType; - - /** - * Perform an edit on the document associated with this text editor. - * - * The given callback-function is invoked with an [edit-builder](#TextEditorEdit) which must - * be used to make edits. Note that the edit-builder is only valid while the - * callback executes. - * - * @param callback A function which can create edits using an [edit-builder](#TextEditorEdit). - * @param options The undo/redo behavior around this edit. By default, undo stops will be created before and after this edit. - * @return A promise that resolves with a value indicating if the edits could be applied. - */ - edit(callback: (editBuilder: TextEditorEdit) => void, options?: { undoStopBefore: boolean; undoStopAfter: boolean; }): Thenable; - - /** - * Insert a [snippet](#SnippetString) and put the editor into snippet mode. "Snippet mode" - * means the editor adds placeholders and additionals cursors so that the user can complete - * or accept the snippet. - * - * @param snippet The snippet to insert in this edit. - * @param location Position or range at which to insert the snippet, defaults to the current editor selection or selections. - * @param options The undo/redo behavior around this edit. By default, undo stops will be created before and after this edit. - * @return A promise that resolves with a value indicating if the snippet could be inserted. Note that the promise does not signal - * that the snippet is completely filled-in or accepted. - */ - insertSnippet(snippet: SnippetString, location?: Position | Range | Position[] | Range[], options?: { undoStopBefore: boolean; undoStopAfter: boolean; }): Thenable; - - /** - * Adds a set of decorations to the text editor. If a set of decorations already exists with - * the given [decoration type](#TextEditorDecorationType), they will be replaced. - * - * @see [createTextEditorDecorationType](#window.createTextEditorDecorationType). - * - * @param decorationType A decoration type. - * @param rangesOrOptions Either [ranges](#Range) or more detailed [options](#DecorationOptions). - */ - setDecorations(decorationType: TextEditorDecorationType, rangesOrOptions: Range[] | DecorationOptions[]): void; - - /** - * Scroll as indicated by `revealType` in order to reveal the given range. - * - * @param range A range. - * @param revealType The scrolling strategy for revealing `range`. - */ - revealRange(range: Range, revealType?: TextEditorRevealTypeType): void; - } - - /** - * Represents an end of line character sequence in a [document](#TextDocument). - */ - declare export var EndOfLine: { - /** - * The line feed `\n` character. - */ - +LF: 1, - /** - * The carriage return line feed `\r\n` sequence. - */ - +CRLF: 2 - } - declare export type EndOfLineType = $Values; - - /** - * A complex edit that will be applied in one transaction on a TextEditor. - * This holds a description of the edits and if the edits are valid (i.e. no overlapping regions, document was not changed in the meantime, etc.) - * they can be applied on a [document](#TextDocument) associated with a [text editor](#TextEditor). - * - */ - declare export interface TextEditorEdit { - /** - * Replace a certain text region with a new value. - * You can use \r\n or \n in `value` and they will be normalized to the current [document](#TextDocument). - * - * @param location The range this operation should remove. - * @param value The new text this operation should insert after removing `location`. - */ - replace(location: Position | Range | Selection, value: string): void; - - /** - * Insert text at a location. - * You can use \r\n or \n in `value` and they will be normalized to the current [document](#TextDocument). - * Although the equivalent text edit can be made with [replace](#TextEditorEdit.replace), `insert` will produce a different resulting selection (it will get moved). - * - * @param location The position where the new text should be inserted. - * @param value The new text this operation should insert. - */ - insert(location: Position, value: string): void; - - /** - * Delete a certain text region. - * - * @param location The range this operation should remove. - */ - delete(location: Range | Selection): void; - - /** - * Set the end of line sequence. - * - * @param endOfLine The new end of line for the [document](#TextDocument). - */ - setEndOfLine(endOfLine: EndOfLineType): void; - } - - /** - * A universal resource identifier representing either a file on disk - * or another resource, like untitled resources. - */ - declare export class Uri { - - /** - * Create an URI from a file system path. The [scheme](#Uri.scheme) - * will be `file`. - * - * @param path A file system or UNC path. - * @return A new Uri instance. - */ - static file(path: string): Uri; - - /** - * Create an URI from a string. Will throw if the given value is not - * valid. - * - * @param value The string value of an Uri. - * @return A new Uri instance. - */ - static parse(value: string): Uri; - - /** - * Use the `file` and `parse` factory functions to create new `Uri` objects. - */ - // private constructor(scheme: string, authority: string, path: string, query: string, fragment: string): void; - - /** - * Scheme is the `http` part of `http://www.msft.com/some/path?query#fragment`. - * The part before the first colon. - */ - +scheme: string; - - /** - * Authority is the `www.msft.com` part of `http://www.msft.com/some/path?query#fragment`. - * The part between the first double slashes and the next slash. - */ - +authority: string; - - /** - * Path is the `/some/path` part of `http://www.msft.com/some/path?query#fragment`. - */ - +path: string; - - /** - * Query is the `query` part of `http://www.msft.com/some/path?query#fragment`. - */ - +query: string; - - /** - * Fragment is the `fragment` part of `http://www.msft.com/some/path?query#fragment`. - */ - +fragment: string; - - /** - * The string representing the corresponding file system path of this Uri. - * - * Will handle UNC paths and normalize windows drive letters to lower-case. Also - * uses the platform specific path separator. Will *not* validate the path for - * invalid characters and semantics. Will *not* look at the scheme of this Uri. - */ - +fsPath: string; - - /** - * Derive a new Uri from this Uri. - * - * ```ts - * let file = Uri.parse('before:some/file/path'); - * let other = file.with({ scheme: 'after' }); - * assert.ok(other.toString() === 'after:some/file/path'); - * ``` - * - * @param change An object that describes a change to this Uri. To unset components use `null` or - * the empty string. - * @return A new Uri that reflects the given change. Will return `this` Uri if the change - * is not changing anything. - */ - with(change: { scheme?: string; authority?: string; path?: string; query?: string; fragment?: string }): Uri; - - /** - * Returns a string representation of this Uri. The representation and normalization - * of a URI depends on the scheme. The resulting string can be safely used with - * [Uri.parse](#Uri.parse). - * - * @param skipEncoding Do not percentage-encode the result, defaults to `false`. Note that - * the `#` and `?` characters occuring in the path will always be encoded. - * @returns A string representation of this Uri. - */ - toString(skipEncoding?: boolean): string; - - /** - * Returns a JSON representation of this Uri. - * - * @return An object. - */ - toJSON(): any; - } - - /** - * A cancellation token is passed to an asynchronous or long running - * operation to request cancellation, like cancelling a request - * for completion items because the user continued to type. - * - * To get an instance of a `CancellationToken` use a - * [CancellationTokenSource](#CancellationTokenSource). - */ - declare export interface CancellationToken { - - /** - * Is `true` when the token has been cancelled, `false` otherwise. - */ - isCancellationRequested: boolean; - - /** - * An [event](#Event) which fires upon cancellation. - */ - onCancellationRequested: Event; - } - - /** - * A cancellation source creates and controls a [cancellation token](#CancellationToken). - */ - declare export class CancellationTokenSource { - - /** - * The cancellation token of this source. - */ - token: CancellationToken; - - /** - * Signal cancellation on the token. - */ - cancel(): void; - - /** - * Dispose object and free resources. Will call [cancel](#CancellationTokenSource.cancel). - */ - dispose(): void; - } - - declare export type IDisposable = { - dispose(): any; - }; - - /** - * Represents a type which can release resources, such - * as event listening or a timer. - */ - declare export class Disposable { - - /** - * Combine many disposable-likes into one. Use this method - * when having objects with a dispose function which are not - * instances of Disposable. - * - * @param disposableLikes Objects that have at least a `dispose`-function member. - * @return Returns a new disposable which, upon dispose, will - * dispose all provided disposables. - */ - static from(...disposableLikes: { +dispose: () => any }[]): Disposable; - - /** - * Creates a new Disposable calling the provided function - * on dispose. - * @param callOnDispose Function that disposes something. - */ - constructor(callOnDispose: Function): void; - - /** - * Dispose this object. - */ - dispose(): any; - } - - /** - * Represents a typed event. - * - * A function that represents an event to which you subscribe by calling it with - * a listener function as argument. - * - * @sample `item.onDidChange(function(event) { console.log("Event happened: " + event); });` - */ - declare export interface Event { - - /** - * A function that represents an event to which you subscribe by calling it with - * a listener function as argument. - * - * @param listener The listener function will be called when the event happens. - * @param thisArgs The `this`-argument which will be used when calling the event listener. - * @param disposables An array to which a [disposable](#Disposable) will be added. - * @return A disposable which unsubscribes the event listener. - */ - (listener: (e: T) => any, thisArgs?: any, disposables?: Disposable[]): Disposable; - } - - /** - * An event emitter can be used to create and manage an [event](#Event) for others - * to subscribe to. One emitter always owns one event. - * - * Use this class if you want to provide event from within your extension, for instance - * inside a [TextDocumentContentProvider](#TextDocumentContentProvider) or when providing - * API to other extensions. - */ - declare export class EventEmitter { - - /** - * The event listeners can subscribe to. - */ - event: Event; - - /** - * Notify all subscribers of the [event](EventEmitter#event). Failure - * of one or more listener will not fail this function call. - * - * @param data The event object. - */ - fire(data?: T): void; - - /** - * Dispose this object and free resources. - */ - dispose(): void; - } - - /** - * A file system watcher notifies about changes to files and folders - * on disk. - * - * To get an instance of a `FileSystemWatcher` use - * [createFileSystemWatcher](#workspace.createFileSystemWatcher). - */ - declare export interface FileSystemWatcher extends Disposable { - - /** - * true if this file system watcher has been created such that - * it ignores creation file system events. - */ - ignoreCreateEvents: boolean; - - /** - * true if this file system watcher has been created such that - * it ignores change file system events. - */ - ignoreChangeEvents: boolean; - - /** - * true if this file system watcher has been created such that - * it ignores delete file system events. - */ - ignoreDeleteEvents: boolean; - - /** - * An event which fires on file/folder creation. - */ - onDidCreate: Event; - - /** - * An event which fires on file/folder change. - */ - onDidChange: Event; - - /** - * An event which fires on file/folder deletion. - */ - onDidDelete: Event; - } - - /** - * A text document content provider allows to add documents - * to the editor, such as source from a dll or generated html from md. - * - * Content providers are [registered](#workspace.registerTextDocumentContentProvider) - * for a [uri-scheme](#Uri.scheme). When a uri with that scheme is to - * be [loaded](#workspace.openTextDocument) the content provider is - * asked. - */ - declare export interface TextDocumentContentProvider { - - /** - * An event to signal a resource has changed. - */ - onDidChange?: Event; - - /** - * Provide textual content for a given uri. - * - * The editor will use the returned string-content to create a readonly - * [document](#TextDocument). Resources allocated should be released when - * the corresponding document has been [closed](#workspace.onDidCloseTextDocument). - * - * @param uri An uri which scheme matches the scheme this provider was [registered](#workspace.registerTextDocumentContentProvider) for. - * @param token A cancellation token. - * @return A string or a thenable that resolves to such. - */ - provideTextDocumentContent(uri: Uri, token: CancellationToken): ProviderResult; - } - - /** - * Represents an item that can be selected from - * a list of items. - */ - declare export interface QuickPickItem { - - /** - * A human readable string which is rendered prominent. - */ - label: string; - - /** - * A human readable string which is rendered less prominent. - */ - description: string; - - /** - * A human readable string which is rendered less prominent. - */ - detail?: string; - } - - /** - * Options to configure the behavior of the quick pick UI. - */ - declare export interface QuickPickOptions { - /** - * An optional flag to include the description when filtering the picks. - */ - matchOnDescription?: boolean; - - /** - * An optional flag to include the detail when filtering the picks. - */ - matchOnDetail?: boolean; - - /** - * An optional string to show as place holder in the input box to guide the user what to pick on. - */ - placeHolder?: string; - - /** - * Set to `true` to keep the picker open when focus moves to another part of the editor or to another window. - */ - ignoreFocusOut?: boolean; - - /** - * An optional function that is invoked whenever an item is selected. - */ - +onDidSelectItem?: (item: QuickPickItem | string) => any; - } - - /** - * Options to configure the behaviour of the [workspace folder](#WorkspaceFolder) pick UI. - */ - declare export interface WorkspaceFolderPickOptions { - - /** - * An optional string to show as place holder in the input box to guide the user what to pick on. - */ - placeHolder?: string; - - /** - * Set to `true` to keep the picker open when focus moves to another part of the editor or to another window. - */ - ignoreFocusOut?: boolean; - } - - /** - * Options to configure the behaviour of a file open dialog. - * - * * Note 1: A dialog can select files, folders, or both. This is not true for Windows - * which enforces to open either files or folder, but *not both*. - * * Note 2: Explictly setting `canSelectFiles` and `canSelectFolders` to `false` is futile - * and the editor then silently adjusts the options to select files. - */ - declare export interface OpenDialogOptions { - /** - * The resource the dialog shows when opened. - */ - defaultUri?: Uri; - - /** - * A human-readable string for the open button. - */ - openLabel?: string; - - /** - * Allow to select files, defaults to `true`. - */ - canSelectFiles?: boolean; - - /** - * Allow to select folders, defaults to `false`. - */ - canSelectFolders?: boolean; - - /** - * Allow to select many files or folders. - */ - canSelectMany?: boolean; - - /** - * A set of file filters that are used by the dialog. Each entry is a human readable label, - * like "TypeScript", and an array of extensions, e.g. - * ```ts - * { - * 'Images': ['png', 'jpg'] - * 'TypeScript': ['ts', 'tsx'] - * } - * ``` - */ - filters?: { [name: string]: string[] }; - } - - /** - * Options to configure the behaviour of a file save dialog. - */ - declare export interface SaveDialogOptions { - /** - * The resource the dialog shows when opened. - */ - defaultUri?: Uri; - - /** - * A human-readable string for the save button. - */ - saveLabel?: string; - - /** - * A set of file filters that are used by the dialog. Each entry is a human readable label, - * like "TypeScript", and an array of extensions, e.g. - * ```ts - * { - * 'Images': ['png', 'jpg'] - * 'TypeScript': ['ts', 'tsx'] - * } - * ``` - */ - filters?: { [name: string]: string[] }; - } - - /** - * Represents an action that is shown with an information, warning, or - * error message. - * - * @see [showInformationMessage](#window.showInformationMessage) - * @see [showWarningMessage](#window.showWarningMessage) - * @see [showErrorMessage](#window.showErrorMessage) - */ - declare export interface MessageItem { - - /** - * A short title like 'Retry', 'Open Log' etc. - */ - title: string; - - /** - * Indicates that this item replaces the default - * 'Close' action. - */ - isCloseAffordance?: boolean; - } - - /** - * Options to configure the behavior of the message. - * - * @see [showInformationMessage](#window.showInformationMessage) - * @see [showWarningMessage](#window.showWarningMessage) - * @see [showErrorMessage](#window.showErrorMessage) - */ - declare export interface MessageOptions { - - /** - * Indicates that this message should be modal. - */ - modal?: boolean; - } - - /** - * Options to configure the behavior of the input box UI. - */ - declare export interface InputBoxOptions { - - /** - * The value to prefill in the input box. - */ - value?: string; - - /** - * Selection of the prefilled [`value`](#InputBoxOptions.value). Defined as tuple of two number where the - * first is the inclusive start index and the second the exclusive end index. When `undefined` the whole - * word will be selected, when empty (start equals end) only the cursor will be set, - * otherwise the defined range will be selected. - */ - valueSelection?: [number, number]; - - /** - * The text to display underneath the input box. - */ - prompt?: string; - - /** - * An optional string to show as place holder in the input box to guide the user what to type. - */ - placeHolder?: string; - - /** - * Set to `true` to show a password prompt that will not show the typed value. - */ - password?: boolean; - - /** - * Set to `true` to keep the input box open when focus moves to another part of the editor or to another window. - */ - ignoreFocusOut?: boolean; - - /** - * An optional function that will be called to validate input and to give a hint - * to the user. - * - * @param value The current value of the input box. - * @return A human readable string which is presented as diagnostic message. - * Return `undefined`, `null`, or the empty string when 'value' is valid. - */ - +validateInput?: (value: string) => ?string | Thenable; - } - - /** - * A relative pattern is a helper to construct glob patterns that are matched - * relatively to a base path. The base path can either be an absolute file path - * or a [workspace folder](#WorkspaceFolder). - */ - declare export class RelativePattern { - - /** - * A base file path to which this pattern will be matched against relatively. - */ - base: string; - - /** - * A file glob pattern like `*.{ts,js}` that will be matched on file paths - * relative to the base path. - * - * Example: Given a base of `/home/work/folder` and a file path of `/home/work/folder/index.js`, - * the file glob pattern will match on `index.js`. - */ - pattern: string; - - /** - * Creates a new relative pattern object with a base path and pattern to match. This pattern - * will be matched on file paths relative to the base path. - * - * @param base A base file path to which this pattern will be matched against relatively. - * @param pattern A file glob pattern like `*.{ts,js}` that will be matched on file paths - * relative to the base path. - */ - constructor(base: WorkspaceFolder | string, pattern: string): void - } - - /** - * A file glob pattern to match file paths against. This can either be a glob pattern string - * (like `**​/*.{ts,js}` or `*.{ts,js}`) or a [relative pattern](#RelativePattern). - * - * Glob patterns can have the following syntax: - * * `*` to match one or more characters in a path segment - * * `?` to match on one character in a path segment - * * `**` to match any number of path segments, including none - * * `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files) - * * `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …) - * * `[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`) - */ - declare export type GlobPattern = string | RelativePattern; - - /** - * A document filter denotes a document by different properties like - * the [language](#TextDocument.languageId), the [scheme](#Uri.scheme) of - * its resource, or a glob-pattern that is applied to the [path](#TextDocument.fileName). - * - * @sample A language filter that applies to typescript files on disk: `{ language: 'typescript', scheme: 'file' }` - * @sample A language filter that applies to all package.json paths: `{ language: 'json', pattern: '**​/package.json' }` - */ - declare export interface DocumentFilter { - - /** - * A language id, like `typescript`. - */ - language?: string; - - /** - * A Uri [scheme](#Uri.scheme), like `file` or `untitled`. - */ - scheme?: string; - - /** - * A [glob pattern](#GlobPattern) that is matched on the absolute path of the document. Use a [relative pattern](#RelativePattern) - * to filter documents to a [workspace folder](#WorkspaceFolder). - */ - pattern?: GlobPattern; - } - - /** - * A language selector is the combination of one or many language identifiers - * and [language filters](#DocumentFilter). - * - * @sample `let sel:DocumentSelector = 'typescript'`; - * @sample `let sel:DocumentSelector = ['typescript', { language: 'json', pattern: '**​/tsconfig.json' }]`; - */ - declare export type DocumentSelector = string | DocumentFilter | (string | DocumentFilter)[]; - - /** - * A provider result represents the values a provider, like the [`HoverProvider`](#HoverProvider), - * may return. For once this is the actual result type `T`, like `Hover`, or a thenable that resolves - * to that type `T`. In addition, `null` and `undefined` can be returned - either directly or from a - * thenable. - * - * The snippets below are all valid implementions of the [`HoverProvider`](#HoverProvider): - * - * ```ts - * let a: HoverProvider = { - * provideHover(doc, pos, token): ProviderResult { - * return new Hover('Hello World'); - * } - * } - * - * let b: HoverProvider = { - * provideHover(doc, pos, token): ProviderResult { - * return new Promise(resolve => { - * resolve(new Hover('Hello World')); - * }); - * } - * } - * - * let c: HoverProvider = { - * provideHover(doc, pos, token): ProviderResult { - * return; // undefined - * } - * } - * ``` - */ - declare export type ProviderResult = ?T | Thenable; - - /** - * Kind of a code action. - * - * Kinds are a hierarchical list of identifiers separated by `.`, e.g. `"refactor.extract.function"`. - */ - declare export class CodeActionKind { - /** - * Empty kind. - */ - static +Empty: CodeActionKind; - - /** - * Base kind for quickfix actions. - */ - static +QuickFix: CodeActionKind; - - /** - * Base kind for refactoring actions. - */ - static +Refactor: CodeActionKind; - - /** - * Base kind for refactoring extraction actions. - * - * Example extract actions: - * - * - Extract method - * - Extract function - * - Extract variable - * - Extract interface from class - * - ... - */ - static +RefactorExtract: CodeActionKind; - - /** - * Base kind for refactoring inline actions. - * - * Example inline actions: - * - * - Inline function - * - Inline variable - * - Inline constant - * - ... - */ - static +RefactorInline: CodeActionKind; - - /** - * Base kind for refactoring rewrite actions. - * - * Example rewrite actions: - * - * - Convert JavaScript function to class - * - Add or remove parameter - * - Encapsulate field - * - Make method static - * - Move method to base class - * - ... - */ - static +RefactorRewrite: CodeActionKind; - - // private constructor(value: string): void; - - /** - * String value of the kind, e.g. `"refactor.extract.function"`. - */ - +value?: string; - - /** - * Create a new kind by appending a more specific selector to the current kind. - * - * Does not modify the current kind. - */ - append(parts: string): CodeActionKind; - - /** - * Does this kind contain `other`? - * - * The kind `"refactor"` for example contains `"refactor.extract"` and ``"refactor.extract.function"`, but not `"unicorn.refactor.extract"` or `"refactory.extract"` - * - * @param other Kind to check. - */ - contains(other: CodeActionKind): boolean; - } - - /** - * Contains additional diagnostic information about the context in which - * a [code action](#CodeActionProvider.provideCodeActions) is run. - */ - declare export interface CodeActionContext { - /** - * An array of diagnostics. - */ - +diagnostics: Diagnostic[]; - - /** - * Requested kind of actions to return. - * - * Actions not of this kind are filtered out before being shown by the lightbulb. - */ - +only?: CodeActionKind; - } - - /** - * A code action represents a change that can be performed in code, e.g. to fix a problem or - * to refactor code. - * - * A CodeAction must set either [`edit`](CodeAction#edit) and/or a [`command`](CodeAction#command). If both are supplied, the `edit` is applied first, then the command is executed. - */ - declare export class CodeAction { - - /** - * A short, human-readable, title for this code action. - */ - title: string; - - /** - * A [workspace edit](#WorkspaceEdit) this code action performs. - */ - edit?: WorkspaceEdit; - - /** - * [Diagnostics](#Diagnostic) that this code action resolves. - */ - diagnostics?: Diagnostic[]; - - /** - * A [command](#Command) this code action executes. - */ - command?: Command; - - /** - * [Kind](#CodeActionKind) of the code action. - * - * Used to filter code actions. - */ - kind?: CodeActionKind; - - /** - * Creates a new code action. - * - * A code action must have at least a [title](#CodeAction.title) and either [edits](#CodeAction.edit) - * or a [command](#CodeAction.command). - * - * @param title The title of the code action. - * @param kind The kind of the code action. - */ - constructor(title: string, kind?: CodeActionKind): void; - } - - /** - * The code action interface defines the contract between extensions and - * the [light bulb](https://code.visualstudio.com/docs/editor/editingevolved#_code-action) feature. - * - * A code action can be any command that is [known](#commands.getCommands) to the system. - */ - declare export interface CodeActionProvider { - - /** - * Provide commands for the given document and range. - * - * @param document The document in which the command was invoked. - * @param range The range for which the command was invoked. - * @param context Context carrying additional information. - * @param token A cancellation token. - * @return An array of commands, quick fixes, or refactorings or a thenable of such. The lack of a result can be - * signaled by returning `undefined`, `null`, or an empty array. - */ - provideCodeActions(document: TextDocument, range: Range, context: CodeActionContext, token: CancellationToken): ProviderResult<(Command | CodeAction)[]>; - } - - /** - * A code lens represents a [command](#Command) that should be shown along with - * source text, like the number of references, a way to run tests, etc. - * - * A code lens is _unresolved_ when no command is associated to it. For performance - * reasons the creation of a code lens and resolving should be done to two stages. - * - * @see [CodeLensProvider.provideCodeLenses](#CodeLensProvider.provideCodeLenses) - * @see [CodeLensProvider.resolveCodeLens](#CodeLensProvider.resolveCodeLens) - */ - declare export class CodeLens { - - /** - * The range in which this code lens is valid. Should only span a single line. - */ - range: Range; - - /** - * The command this code lens represents. - */ - command?: Command; - - /** - * `true` when there is a command associated. - */ - +isResolved: boolean; - - /** - * Creates a new code lens object. - * - * @param range The range to which this code lens applies. - * @param command The command associated to this code lens. - */ - constructor(range: Range, command?: Command): void; - } - - /** - * A code lens provider adds [commands](#Command) to source text. The commands will be shown - * as dedicated horizontal lines in between the source text. - */ - declare export interface CodeLensProvider { - - /** - * An optional event to signal that the code lenses from this provider have changed. - */ - onDidChangeCodeLenses?: Event; - - /** - * Compute a list of [lenses](#CodeLens). This call should return as fast as possible and if - * computing the commands is expensive implementors should only return code lens objects with the - * range set and implement [resolve](#CodeLensProvider.resolveCodeLens). - * - * @param document The document in which the command was invoked. - * @param token A cancellation token. - * @return An array of code lenses or a thenable that resolves to such. The lack of a result can be - * signaled by returning `undefined`, `null`, or an empty array. - */ - provideCodeLenses(document: TextDocument, token: CancellationToken): ProviderResult; - - /** - * This function will be called for each visible code lens, usually when scrolling and after - * calls to [compute](#CodeLensProvider.provideCodeLenses)-lenses. - * - * @param codeLens code lens that must be resolved. - * @param token A cancellation token. - * @return The given, resolved code lens or thenable that resolves to such. - */ - +resolveCodeLens?: (codeLens: CodeLens, token: CancellationToken) => ProviderResult; - } - - /** - * The definition of a symbol represented as one or many [locations](#Location). - * For most programming languages there is only one location at which a symbol is - * defined. - */ - declare export type Definition = Location | Location[]; - - /** - * The definition provider interface defines the contract between extensions and - * the [go to definition](https://code.visualstudio.com/docs/editor/editingevolved#_go-to-definition) - * and peek definition features. - */ - declare export interface DefinitionProvider { - - /** - * Provide the definition of the symbol at the given position and document. - * - * @param document The document in which the command was invoked. - * @param position The position at which the command was invoked. - * @param token A cancellation token. - * @return A definition or a thenable that resolves to such. The lack of a result can be - * signaled by returning `undefined` or `null`. - */ - provideDefinition(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; - } - - /** - * The implemenetation provider interface defines the contract between extensions and - * the go to implementation feature. - */ - declare export interface ImplementationProvider { - - /** - * Provide the implementations of the symbol at the given position and document. - * - * @param document The document in which the command was invoked. - * @param position The position at which the command was invoked. - * @param token A cancellation token. - * @return A definition or a thenable that resolves to such. The lack of a result can be - * signaled by returning `undefined` or `null`. - */ - provideImplementation(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; - } - - /** - * The type definition provider defines the contract between extensions and - * the go to type definition feature. - */ - declare export interface TypeDefinitionProvider { - - /** - * Provide the type definition of the symbol at the given position and document. - * - * @param document The document in which the command was invoked. - * @param position The position at which the command was invoked. - * @param token A cancellation token. - * @return A definition or a thenable that resolves to such. The lack of a result can be - * signaled by returning `undefined` or `null`. - */ - provideTypeDefinition(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; - } - - /** - * The MarkdownString represents human readable text that supports formatting via the - * markdown syntax. Standard markdown is supported, also tables, but no embedded html. - */ - declare export class MarkdownString { - - /** - * The markdown string. - */ - value: string; - - /** - * Indicates that this markdown string is from a trusted source. Only *trusted* - * markdown supports links that execute commands, e.g. `[Run it](command:myCommandId)`. - */ - isTrusted?: boolean; - - /** - * Creates a new markdown string with the given value. - * - * @param value Optional, initial value. - */ - constructor(value?: string): void; - - /** - * Appends and escapes the given string to this markdown string. - * @param value Plain text. - */ - appendText(value: string): MarkdownString; - - /** - * Appends the given string 'as is' to this markdown string. - * @param value Markdown string. - */ - appendMarkdown(value: string): MarkdownString; - - /** - * Appends the given string as codeblock using the provided language. - * @param value A code snippet. - * @param language An optional [language identifier](#languages.getLanguages). - */ - appendCodeblock(value: string, language?: string): MarkdownString; - } - - /** - * ~~MarkedString can be used to render human readable text. It is either a markdown string - * or a code-block that provides a language and a code snippet. Note that - * markdown strings will be sanitized - that means html will be escaped.~~ - * - * @deprecated This type is deprecated, please use [`MarkdownString`](#MarkdownString) instead. - */ - declare export type MarkedString = MarkdownString | string | { language: string; value: string }; - - /** - * A hover represents additional information for a symbol or word. Hovers are - * rendered in a tooltip-like widget. - */ - declare export class Hover { - - /** - * The contents of this hover. - */ - contents: MarkedString[]; - - /** - * The range to which this hover applies. When missing, the - * editor will use the range at the current position or the - * current position itself. - */ - range?: Range; - - /** - * Creates a new hover object. - * - * @param contents The contents of the hover. - * @param range The range to which the hover applies. - */ - constructor(contents: MarkedString | MarkedString[], range?: Range): void; - } - - /** - * The hover provider interface defines the contract between extensions and - * the [hover](https://code.visualstudio.com/docs/editor/intellisense)-feature. - */ - declare export interface HoverProvider { - - /** - * Provide a hover for the given position and document. Multiple hovers at the same - * position will be merged by the editor. A hover can have a range which defaults - * to the word range at the position when omitted. - * - * @param document The document in which the command was invoked. - * @param position The position at which the command was invoked. - * @param token A cancellation token. - * @return A hover or a thenable that resolves to such. The lack of a result can be - * signaled by returning `undefined` or `null`. - */ - provideHover(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; - } - - /** - * A document highlight kind. - */ - declare export var DocumentHighlightKind: { - - /** - * A textual occurrence. - */ - +Text: 0, - - /** - * Read-access of a symbol, like reading a variable. - */ - +Read: 1, - - /** - * Write-access of a symbol, like writing to a variable. - */ - +Write: 2 - } - declare export type DocumentHighlightKindType = $Values; - - /** - * A document highlight is a range inside a text document which deserves - * special attention. Usually a document highlight is visualized by changing - * the background color of its range. - */ - declare export class DocumentHighlight { - - /** - * The range this highlight applies to. - */ - range: Range; - - /** - * The highlight kind, default is [text](#DocumentHighlightKind.Text). - */ - kind?: DocumentHighlightKindType; - - /** - * Creates a new document highlight object. - * - * @param range The range the highlight applies to. - * @param kind The highlight kind, default is [text](#DocumentHighlightKind.Text). - */ - constructor(range: Range, kind?: DocumentHighlightKindType): void; - } - - /** - * The document highlight provider interface defines the contract between extensions and - * the word-highlight-feature. - */ - declare export interface DocumentHighlightProvider { - - /** - * Provide a set of document highlights, like all occurrences of a variable or - * all exit-points of a function. - * - * @param document The document in which the command was invoked. - * @param position The position at which the command was invoked. - * @param token A cancellation token. - * @return An array of document highlights or a thenable that resolves to such. The lack of a result can be - * signaled by returning `undefined`, `null`, or an empty array. - */ - provideDocumentHighlights(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; - } - - /** - * A symbol kind. - */ - declare export var SymbolKind: { - +File: 0, - +Module: 1, - +Namespace: 2, - +Package: 3, - +Class: 4, - +Method: 5, - +Property: 6, - +Field: 7, - +Constructor: 8, - +Enum: 9, - +Interface: 10, - +Function: 11, - +Variable: 12, - +Constant: 13, - +String: 14, - +Number: 15, - +Boolean: 16, - +Array: 17, - +Object: 18, - +Key: 19, - +Null: 20, - +EnumMember: 21, - +Struct: 22, - +Event: 23, - +Operator: 24, - +TypeParameter: 25 - } - declare export type SymbolKindType = $Values; - - /** - * Represents information about programming constructs like variables, classes, - * interfaces etc. - */ - declare export class SymbolInformation { - - /** - * The name of this symbol. - */ - name: string; - - /** - * The name of the symbol containing this symbol. - */ - containerName: string; - - /** - * The kind of this symbol. - */ - kind: SymbolKindType; - - /** - * The location of this symbol. - */ - location: Location; - - /** - * Creates a new symbol information object. - * - * @param name The name of the symbol. - * @param kind The kind of the symbol. - * @param containerName The name of the symbol containing the symbol. - * @param location The the location of the symbol. - */ - constructor(name: string, kind: SymbolKindType, containerName: string, location: Location): void; - - /** - * ~~Creates a new symbol information object.~~ - * - * @deprecated Please use the constructor taking a [location](#Location) object. - * - * @param name The name of the symbol. - * @param kind The kind of the symbol. - * @param range The range of the location of the symbol. - * @param uri The resource of the location of symbol, defaults to the current document. - * @param containerName The name of the symbol containing the symbol. - */ - constructor(name: string, kind: SymbolKindType, range: Range, uri?: Uri, containerName?: string): void; - } - - /** - * The document symbol provider interface defines the contract between extensions and - * the [go to symbol](https://code.visualstudio.com/docs/editor/editingevolved#_go-to-symbol)-feature. - */ - declare export interface DocumentSymbolProvider { - - /** - * Provide symbol information for the given document. - * - * @param document The document in which the command was invoked. - * @param token A cancellation token. - * @return An array of document highlights or a thenable that resolves to such. The lack of a result can be - * signaled by returning `undefined`, `null`, or an empty array. - */ - provideDocumentSymbols(document: TextDocument, token: CancellationToken): ProviderResult; - } - - /** - * The workspace symbol provider interface defines the contract between extensions and - * the [symbol search](https://code.visualstudio.com/docs/editor/editingevolved#_open-symbol-by-name)-feature. - */ - declare export interface WorkspaceSymbolProvider { - - /** - * Project-wide search for a symbol matching the given query string. It is up to the provider - * how to search given the query string, like substring, indexOf etc. To improve performance implementors can - * skip the [location](#SymbolInformation.location) of symbols and implement `resolveWorkspaceSymbol` to do that - * later. - * - * The `query`-parameter should be interpreted in a *relaxed way* as the editor will apply its own highlighting - * and scoring on the results. A good rule of thumb is to match case-insensitive and to simply check that the - * characters of *query* appear in their order in a candidate symbol. Don't use prefix, substring, or similar - * strict matching. - * - * @param query A non-empty query string. - * @param token A cancellation token. - * @return An array of document highlights or a thenable that resolves to such. The lack of a result can be - * signaled by returning `undefined`, `null`, or an empty array. - */ - provideWorkspaceSymbols(query: string, token: CancellationToken): ProviderResult; - - /** - * Given a symbol fill in its [location](#SymbolInformation.location). This method is called whenever a symbol - * is selected in the UI. Providers can implement this method and return incomplete symbols from - * [`provideWorkspaceSymbols`](#WorkspaceSymbolProvider.provideWorkspaceSymbols) which often helps to improve - * performance. - * - * @param symbol The symbol that is to be resolved. Guaranteed to be an instance of an object returned from an - * earlier call to `provideWorkspaceSymbols`. - * @param token A cancellation token. - * @return The resolved symbol or a thenable that resolves to that. When no result is returned, - * the given `symbol` is used. - */ - +resolveWorkspaceSymbol?: (symbol: SymbolInformation, token: CancellationToken) => ProviderResult; - } - - /** - * Value-object that contains additional information when - * requesting references. - */ - declare export interface ReferenceContext { - - /** - * Include the declaration of the current symbol. - */ - includeDeclaration: boolean; - } - - /** - * The reference provider interface defines the contract between extensions and - * the [find references](https://code.visualstudio.com/docs/editor/editingevolved#_peek)-feature. - */ - declare export interface ReferenceProvider { - - /** - * Provide a set of project-wide references for the given position and document. - * - * @param document The document in which the command was invoked. - * @param position The position at which the command was invoked. - * @param context - * @param token A cancellation token. - * @return An array of locations or a thenable that resolves to such. The lack of a result can be - * signaled by returning `undefined`, `null`, or an empty array. - */ - provideReferences(document: TextDocument, position: Position, context: ReferenceContext, token: CancellationToken): ProviderResult; - } - - /** - * A text edit represents edits that should be applied - * to a document. - */ - declare export class TextEdit { - - /** - * Utility to create a replace edit. - * - * @param range A range. - * @param newText A string. - * @return A new text edit object. - */ - static replace(range: Range, newText: string): TextEdit; - - /** - * Utility to create an insert edit. - * - * @param position A position, will become an empty range. - * @param newText A string. - * @return A new text edit object. - */ - static insert(position: Position, newText: string): TextEdit; - - /** - * Utility to create a delete edit. - * - * @param range A range. - * @return A new text edit object. - */ - static delete(range: Range): TextEdit; - - /** - * Utility to create an eol-edit. - * - * @param eol An eol-sequence - * @return A new text edit object. - */ - static setEndOfLine(eol: EndOfLineType): TextEdit; - - /** - * The range this edit applies to. - */ - range: Range; - - /** - * The string this edit will insert. - */ - newText: string; - - /** - * The eol-sequence used in the document. - * - * *Note* that the eol-sequence will be applied to the - * whole document. - */ - newEol: EndOfLineType; - - /** - * Create a new TextEdit. - * - * @param range A range. - * @param newText A string. - */ - constructor(range: Range, newText: string): void; - } - - /** - * A workspace edit represents textual and files changes for - * multiple resources and documents. - */ - declare export class WorkspaceEdit { - - /** - * The number of affected resources. - */ - +size: number; - - /** - * Replace the given range with given text for the given resource. - * - * @param uri A resource identifier. - * @param range A range. - * @param newText A string. - */ - replace(uri: Uri, range: Range, newText: string): void; - - /** - * Insert the given text at the given position. - * - * @param uri A resource identifier. - * @param position A position. - * @param newText A string. - */ - insert(uri: Uri, position: Position, newText: string): void; - - /** - * Delete the text at the given range. - * - * @param uri A resource identifier. - * @param range A range. - */ - delete(uri: Uri, range: Range): void; - - /** - * Check if this edit affects the given resource. - * @param uri A resource identifier. - * @return `true` if the given resource will be touched by this edit. - */ - has(uri: Uri): boolean; - - /** - * Set (and replace) text edits for a resource. - * - * @param uri A resource identifier. - * @param edits An array of text edits. - */ - set(uri: Uri, edits: TextEdit[]): void; - - /** - * Get the text edits for a resource. - * - * @param uri A resource identifier. - * @return An array of text edits. - */ - get(uri: Uri): TextEdit[]; - - /** - * Get all text edits grouped by resource. - * - * @return A shallow copy of `[Uri, TextEdit[]]`-tuples. - */ - entries(): [Uri, TextEdit[]][]; - } - - /** - * A snippet string is a template which allows to insert text - * and to control the editor cursor when insertion happens. - * - * A snippet can define tab stops and placeholders with `$1`, `$2` - * and `${3:foo}`. `$0` defines the final tab stop, it defaults to - * the end of the snippet. Variables are defined with `$name` and - * `${name:default value}`. The full snippet syntax is documented - * [here](http://code.visualstudio.com/docs/editor/userdefinedsnippets#_creating-your-own-snippets). - */ - declare export class SnippetString { - - /** - * The snippet string. - */ - value: string; - - constructor(value?: string): void; - - /** - * Builder-function that appends the given string to - * the [`value`](#SnippetString.value) of this snippet string. - * - * @param string A value to append 'as given'. The string will be escaped. - * @return This snippet string. - */ - appendText(string: string): SnippetString; - - /** - * Builder-function that appends a tabstop (`$1`, `$2` etc) to - * the [`value`](#SnippetString.value) of this snippet string. - * - * @param number The number of this tabstop, defaults to an auto-incremet - * value starting at 1. - * @return This snippet string. - */ - appendTabstop(number?: number): SnippetString; - - /** - * Builder-function that appends a placeholder (`${1:value}`) to - * the [`value`](#SnippetString.value) of this snippet string. - * - * @param value The value of this placeholder - either a string or a function - * with which a nested snippet can be created. - * @param number The number of this tabstop, defaults to an auto-incremet - * value starting at 1. - * @return This snippet string. - */ - appendPlaceholder(value: string | ((snippet: SnippetString) => any), number?: number): SnippetString; - - /** - * Builder-function that appends a variable (`${VAR}`) to - * the [`value`](#SnippetString.value) of this snippet string. - * - * @param name The name of the variable - excluding the `$`. - * @param defaultValue The default value which is used when the variable name cannot - * be resolved - either a string or a function with which a nested snippet can be created. - * @return This snippet string. - */ - appendVariable(name: string, defaultValue: string | ((snippet: SnippetString) => any)): SnippetString; - } - - /** - * The rename provider interface defines the contract between extensions and - * the [rename](https://code.visualstudio.com/docs/editor/editingevolved#_rename-symbol)-feature. - */ - declare export interface RenameProvider { - - /** - * Provide an edit that describes changes that have to be made to one - * or many resources to rename a symbol to a different name. - * - * @param document The document in which the command was invoked. - * @param position The position at which the command was invoked. - * @param newName The new name of the symbol. If the given name is not valid, the provider must return a rejected promise. - * @param token A cancellation token. - * @return A workspace edit or a thenable that resolves to such. The lack of a result can be - * signaled by returning `undefined` or `null`. - */ - provideRenameEdits(document: TextDocument, position: Position, newName: string, token: CancellationToken): ProviderResult; - } - - /** - * Value-object describing what options formatting should use. - */ - declare export interface FormattingOptions { - - /** - * Size of a tab in spaces. - */ - tabSize: number; - - /** - * Prefer spaces over tabs. - */ - insertSpaces: boolean; - - /** - * Signature for further properties. - */ - [key: string]: boolean | number | string; - } - - /** - * The document formatting provider interface defines the contract between extensions and - * the formatting-feature. - */ - declare export interface DocumentFormattingEditProvider { - - /** - * Provide formatting edits for a whole document. - * - * @param document The document in which the command was invoked. - * @param options Options controlling formatting. - * @param token A cancellation token. - * @return A set of text edits or a thenable that resolves to such. The lack of a result can be - * signaled by returning `undefined`, `null`, or an empty array. - */ - provideDocumentFormattingEdits(document: TextDocument, options: FormattingOptions, token: CancellationToken): ProviderResult; - } - - /** - * The document formatting provider interface defines the contract between extensions and - * the formatting-feature. - */ - declare export interface DocumentRangeFormattingEditProvider { - - /** - * Provide formatting edits for a range in a document. - * - * The given range is a hint and providers can decide to format a smaller - * or larger range. Often this is done by adjusting the start and end - * of the range to full syntax nodes. - * - * @param document The document in which the command was invoked. - * @param range The range which should be formatted. - * @param options Options controlling formatting. - * @param token A cancellation token. - * @return A set of text edits or a thenable that resolves to such. The lack of a result can be - * signaled by returning `undefined`, `null`, or an empty array. - */ - provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): ProviderResult; - } - - /** - * The document formatting provider interface defines the contract between extensions and - * the formatting-feature. - */ - declare export interface OnTypeFormattingEditProvider { - - /** - * Provide formatting edits after a character has been typed. - * - * The given position and character should hint to the provider - * what range the position to expand to, like find the matching `{` - * when `}` has been entered. - * - * @param document The document in which the command was invoked. - * @param position The position at which the command was invoked. - * @param ch The character that has been typed. - * @param options Options controlling formatting. - * @param token A cancellation token. - * @return A set of text edits or a thenable that resolves to such. The lack of a result can be - * signaled by returning `undefined`, `null`, or an empty array. - */ - provideOnTypeFormattingEdits(document: TextDocument, position: Position, ch: string, options: FormattingOptions, token: CancellationToken): ProviderResult; - } - - /** - * Represents a parameter of a callable-signature. A parameter can - * have a label and a doc-comment. - */ - declare export class ParameterInformation { - - /** - * The label of this signature. Will be shown in - * the UI. - */ - label: string; - - /** - * The human-readable doc-comment of this signature. Will be shown - * in the UI but can be omitted. - */ - documentation?: string | MarkdownString; - - /** - * Creates a new parameter information object. - * - * @param label A label string. - * @param documentation A doc string. - */ - constructor(label: string, documentation?: string | MarkdownString): void; - } - - /** - * Represents the signature of something callable. A signature - * can have a label, like a function-name, a doc-comment, and - * a set of parameters. - */ - declare export class SignatureInformation { - - /** - * The label of this signature. Will be shown in - * the UI. - */ - label: string; - - /** - * The human-readable doc-comment of this signature. Will be shown - * in the UI but can be omitted. - */ - documentation?: string | MarkdownString; - - /** - * The parameters of this signature. - */ - parameters: ParameterInformation[]; - - /** - * Creates a new signature information object. - * - * @param label A label string. - * @param documentation A doc string. - */ - constructor(label: string, documentation?: string | MarkdownString): void; - } - - /** - * Signature help represents the signature of something - * callable. There can be multiple signatures but only one - * active and only one active parameter. - */ - declare export class SignatureHelp { - - /** - * One or more signatures. - */ - signatures: SignatureInformation[]; - - /** - * The active signature. - */ - activeSignature: number; - - /** - * The active parameter of the active signature. - */ - activeParameter: number; - } - - /** - * The signature help provider interface defines the contract between extensions and - * the [parameter hints](https://code.visualstudio.com/docs/editor/intellisense)-feature. - */ - declare export interface SignatureHelpProvider { - - /** - * Provide help for the signature at the given position and document. - * - * @param document The document in which the command was invoked. - * @param position The position at which the command was invoked. - * @param token A cancellation token. - * @return Signature help or a thenable that resolves to such. The lack of a result can be - * signaled by returning `undefined` or `null`. - */ - provideSignatureHelp(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; - } - - /** - * Completion item kinds. - */ - declare export var CompletionItemKind: { - +Text: 0, - +Method: 1, - +Function: 2, - +Constructor: 3, - +Field: 4, - +Variable: 5, - +Class: 6, - +Interface: 7, - +Module: 8, - +Property: 9, - +Unit: 10, - +Value: 11, - +Enum: 12, - +Keyword: 13, - +Snippet: 14, - +Color: 15, - +Reference: 17, - +File: 16, - +Folder: 18, - +EnumMember: 19, - +Constant: 20, - +Struct: 21, - +Event: 22, - +Operator: 23, - +TypeParameter: 24 - } - declare export type CompletionItemKindType = $Values; - - /** - * A completion item represents a text snippet that is proposed to complete text that is being typed. - * - * It is suffient to create a completion item from just a [label](#CompletionItem.label). In that - * case the completion item will replace the [word](#TextDocument.getWordRangeAtPosition) - * until the cursor with the given label or [insertText](#CompletionItem.insertText). Otherwise the - * the given [edit](#CompletionItem.textEdit) is used. - * - * When selecting a completion item in the editor its defined or synthesized text edit will be applied - * to *all* cursors/selections whereas [additionalTextEdits](CompletionItem.additionalTextEdits) will be - * applied as provided. - * - * @see [CompletionItemProvider.provideCompletionItems](#CompletionItemProvider.provideCompletionItems) - * @see [CompletionItemProvider.resolveCompletionItem](#CompletionItemProvider.resolveCompletionItem) - */ - declare export class CompletionItem { - - /** - * The label of this completion item. By default - * this is also the text that is inserted when selecting - * this completion. - */ - label: string; - - /** - * The kind of this completion item. Based on the kind - * an icon is chosen by the editor. - */ - kind?: CompletionItemKindType; - - /** - * A human-readable string with additional information - * about this item, like type or symbol information. - */ - detail?: string; - - /** - * A human-readable string that represents a doc-comment. - */ - documentation?: string | MarkdownString; - - /** - * A string that should be used when comparing this item - * with other items. When `falsy` the [label](#CompletionItem.label) - * is used. - */ - sortText?: string; - - /** - * A string that should be used when filtering a set of - * completion items. When `falsy` the [label](#CompletionItem.label) - * is used. - */ - filterText?: string; - - /** - * A string or snippet that should be inserted in a document when selecting - * this completion. When `falsy` the [label](#CompletionItem.label) - * is used. - */ - insertText?: string | SnippetString; - - /** - * A range of text that should be replaced by this completion item. - * - * Defaults to a range from the start of the [current word](#TextDocument.getWordRangeAtPosition) to the - * current position. - * - * *Note:* The range must be a [single line](#Range.isSingleLine) and it must - * [contain](#Range.contains) the position at which completion has been [requested](#CompletionItemProvider.provideCompletionItems). - */ - range?: Range; - - /** - * An optional set of characters that when pressed while this completion is active will accept it first and - * then type that character. *Note* that all commit characters should have `length=1` and that superfluous - * characters will be ignored. - */ - commitCharacters?: string[]; - - /** - * An optional array of additional [text edits](#TextEdit) that are applied when - * selecting this completion. Edits must not overlap with the main [edit](#CompletionItem.textEdit) - * nor with themselves. - */ - additionalTextEdits?: TextEdit[]; - - /** - * An optional [command](#Command) that is executed *after* inserting this completion. *Note* that - * additional modifications to the current document should be described with the - * [additionalTextEdits](#CompletionItem.additionalTextEdits)-property. - */ - command?: Command; - - /** - * Creates a new completion item. - * - * Completion items must have at least a [label](#CompletionItem.label) which then - * will be used as insert text as well as for sorting and filtering. - * - * @param label The label of the completion. - * @param kind The [kind](#CompletionItemKind) of the completion. - */ - constructor(label: string, kind?: CompletionItemKindType): void; - } - - /** - * Represents a collection of [completion items](#CompletionItem) to be presented - * in the editor. - */ - declare export class CompletionList { - - /** - * This list is not complete. Further typing should result in recomputing - * this list. - */ - isIncomplete?: boolean; - - /** - * The completion items. - */ - items: CompletionItem[]; - - /** - * Creates a new completion list. - * - * @param items The completion items. - * @param isIncomplete The list is not complete. - */ - constructor(items?: CompletionItem[], isIncomplete?: boolean): void; - } - - /** - * How a [completion provider](#CompletionItemProvider) was triggered - */ - declare export var CompletionTriggerKind: { - /** - * Completion was triggered normally. - */ - +Invoke: 0, - /** - * Completion was triggered by a trigger character. - */ - +TriggerCharacter: 1, - /** - * Completion was re-triggered as current completion list is incomplete - */ - +TriggerForIncompleteCompletions: 2 - } - declare export type CompletionTriggerKindType = $Values; - - /** - * Contains additional information about the context in which - * [completion provider](#CompletionItemProvider.provideCompletionItems) is triggered. - */ - declare export interface CompletionContext { - /** - * How the completion was triggered. - */ - +triggerKind: CompletionTriggerKindType; - - /** - * Character that triggered the completion item provider. - * - * `undefined` if provider was not triggered by a character. - * - * The trigger character is already in the document when the completion provider is triggered. - */ - +triggerCharacter?: string; - } - - /** - * The completion item provider interface defines the contract between extensions and - * [IntelliSense](https://code.visualstudio.com/docs/editor/intellisense). - * - * Providers can delay the computation of the [`detail`](#CompletionItem.detail) - * and [`documentation`](#CompletionItem.documentation) properties by implementing the - * [`resolveCompletionItem`](#CompletionItemProvider.resolveCompletionItem)-function. However, properties that - * are needed for the inital sorting and filtering, like `sortText`, `filterText`, `insertText`, and `range`, must - * not be changed during resolve. - * - * Providers are asked for completions either explicitly by a user gesture or -depending on the configuration- - * implicitly when typing words or trigger characters. - */ - declare export interface CompletionItemProvider { - - /** - * Provide completion items for the given position and document. - * - * @param document The document in which the command was invoked. - * @param position The position at which the command was invoked. - * @param token A cancellation token. - * @param context How the completion was triggered. - * - * @return An array of completions, a [completion list](#CompletionList), or a thenable that resolves to either. - * The lack of a result can be signaled by returning `undefined`, `null`, or an empty array. - */ - provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken, context: CompletionContext): ProviderResult; - - /** - * Given a completion item fill in more data, like [doc-comment](#CompletionItem.documentation) - * or [details](#CompletionItem.detail). - * - * The editor will only resolve a completion item once. - * - * @param item A completion item currently active in the UI. - * @param token A cancellation token. - * @return The resolved completion item or a thenable that resolves to of such. It is OK to return the given - * `item`. When no result is returned, the given `item` will be used. - */ - +resolveCompletionItem?: (item: CompletionItem, token: CancellationToken) => ProviderResult; - } - - - /** - * A document link is a range in a text document that links to an internal or external resource, like another - * text document or a web site. - */ - declare export class DocumentLink { - - /** - * The range this link applies to. - */ - range: Range; - - /** - * The uri this link points to. - */ - target?: Uri; - - /** - * Creates a new document link. - * - * @param range The range the document link applies to. Must not be empty. - * @param target The uri the document link points to. - */ - constructor(range: Range, target?: Uri): void; - } - - /** - * The document link provider defines the contract between extensions and feature of showing - * links in the editor. - */ - declare export interface DocumentLinkProvider { - - /** - * Provide links for the given document. Note that the editor ships with a default provider that detects - * `http(s)` and `file` links. - * - * @param document The document in which the command was invoked. - * @param token A cancellation token. - * @return An array of [document links](#DocumentLink) or a thenable that resolves to such. The lack of a result - * can be signaled by returning `undefined`, `null`, or an empty array. - */ - provideDocumentLinks(document: TextDocument, token: CancellationToken): ProviderResult; - - /** - * Given a link fill in its [target](#DocumentLink.target). This method is called when an incomplete - * link is selected in the UI. Providers can implement this method and return incomple links - * (without target) from the [`provideDocumentLinks`](#DocumentLinkProvider.provideDocumentLinks) method which - * often helps to improve performance. - * - * @param link The link that is to be resolved. - * @param token A cancellation token. - */ - +resolveDocumentLink?: (link: DocumentLink, token: CancellationToken) => ProviderResult; - } - - /** - * Represents a color in RGBA space. - */ - declare export class Color { - - /** - * The red component of this color in the range [0-1]. - */ - +red: number; - - /** - * The green component of this color in the range [0-1]. - */ - +green: number; - - /** - * The blue component of this color in the range [0-1]. - */ - +blue: number; - - /** - * The alpha component of this color in the range [0-1]. - */ - +alpha: number; - - /** - * Creates a new color instance. - * - * @param red The red component. - * @param green The green component. - * @param blue The bluew component. - * @param alpha The alpha component. - */ - constructor(red: number, green: number, blue: number, alpha: number): void; - } - - /** - * Represents a color range from a document. - */ - declare export class ColorInformation { - - /** - * The range in the document where this color appers. - */ - range: Range; - - /** - * The actual color value for this color range. - */ - color: Color; - - /** - * Creates a new color range. - * - * @param range The range the color appears in. Must not be empty. - * @param color The value of the color. - * @param format The format in which this color is currently formatted. - */ - constructor(range: Range, color: Color): void; - } - - /** - * A color presentation object describes how a [`color`](#Color) should be represented as text and what - * edits are required to refer to it from source code. - * - * For some languages one color can have multiple presentations, e.g. css can represent the color red with - * the constant `Red`, the hex-value `#ff0000`, or in rgba and hsla forms. In csharp other representations - * apply, e.g `System.Drawing.Color.Red`. - */ - declare export class ColorPresentation { - - /** - * The label of this color presentation. It will be shown on the color - * picker header. By default this is also the text that is inserted when selecting - * this color presentation. - */ - label: string; - - /** - * An [edit](#TextEdit) which is applied to a document when selecting - * this presentation for the color. When `falsy` the [label](#ColorPresentation.label) - * is used. - */ - textEdit?: TextEdit; - - /** - * An optional array of additional [text edits](#TextEdit) that are applied when - * selecting this color presentation. Edits must not overlap with the main [edit](#ColorPresentation.textEdit) nor with themselves. - */ - additionalTextEdits?: TextEdit[]; - - /** - * Creates a new color presentation. - * - * @param label The label of this color presentation. - */ - constructor(label: string): void; - } - - /** - * The document color provider defines the contract between extensions and feature of - * picking and modifying colors in the editor. - */ - declare export interface DocumentColorProvider { - - /** - * Provide colors for the given document. - * - * @param document The document in which the command was invoked. - * @param token A cancellation token. - * @return An array of [color informations](#ColorInformation) or a thenable that resolves to such. The lack of a result - * can be signaled by returning `undefined`, `null`, or an empty array. - */ - provideDocumentColors(document: TextDocument, token: CancellationToken): ProviderResult; - - /** - * Provide [representations](#ColorPresentation) for a color. - * - * @param color The color to show and insert. - * @param context A context object with additional information - * @param token A cancellation token. - * @return An array of color presentations or a thenable that resolves to such. The lack of a result - * can be signaled by returning `undefined`, `null`, or an empty array. - */ - provideColorPresentations(color: Color, context: { document: TextDocument, range: Range }, token: CancellationToken): ProviderResult; - } - - /** - * A tuple of two characters, like a pair of - * opening and closing brackets. - */ - declare export type CharacterPair = [string, string]; - - /** - * Describes how comments for a language work. - */ - declare export interface CommentRule { - - /** - * The line comment token, like `// this is a comment` - */ - lineComment?: string; - - /** - * The block comment character pair, like `/* block comment */` - */ - blockComment?: CharacterPair; - } - - /** - * Describes indentation rules for a language. - */ - declare export interface IndentationRule { - /** - * If a line matches this pattern, then all the lines after it should be unindendented once (until another rule matches). - */ - decreaseIndentPattern: RegExp; - /** - * If a line matches this pattern, then all the lines after it should be indented once (until another rule matches). - */ - increaseIndentPattern: RegExp; - /** - * If a line matches this pattern, then **only the next line** after it should be indented once. - */ - indentNextLinePattern?: RegExp; - /** - * If a line matches this pattern, then its indentation should not be changed and it should not be evaluated against the other rules. - */ - unIndentedLinePattern?: RegExp; - } - - /** - * Describes what to do with the indentation when pressing Enter. - */ - declare export var IndentAction: { - /** - * Insert new line and copy the previous line's indentation. - */ - +None: 0, - /** - * Insert new line and indent once (relative to the previous line's indentation). - */ - +Indent: 1, - /** - * Insert two new lines: - * - the first one indented which will hold the cursor - * - the second one at the same indentation level - */ - +IndentOutdent: 2, - /** - * Insert new line and outdent once (relative to the previous line's indentation). - */ - +Outdent: 3 - } - declare export type IndentActionType = $Values; - - /** - * Describes what to do when pressing Enter. - */ - declare export interface EnterAction { - /** - * Describe what to do with the indentation. - */ - indentAction: IndentActionType; - /** - * Describes text to be appended after the new line and after the indentation. - */ - appendText?: string; - /** - * Describes the number of characters to remove from the new line's indentation. - */ - removeText?: number; - } - - /** - * Describes a rule to be evaluated when pressing Enter. - */ - declare export interface OnEnterRule { - /** - * This rule will only execute if the text before the cursor matches this regular expression. - */ - beforeText: RegExp; - /** - * This rule will only execute if the text after the cursor matches this regular expression. - */ - afterText?: RegExp; - /** - * The action to execute. - */ - action: EnterAction; - } - - /** - * The language configuration interfaces defines the contract between extensions - * and various editor features, like automatic bracket insertion, automatic indentation etc. - */ - declare export interface LanguageConfiguration { - /** - * The language's comment settings. - */ - comments?: CommentRule; - /** - * The language's brackets. - * This configuration implicitly affects pressing Enter around these brackets. - */ - brackets?: CharacterPair[]; - /** - * The language's word definition. - * If the language supports Unicode identifiers (e.g. JavaScript), it is preferable - * to provide a word definition that uses exclusion of known separators. - * e.g.: A regex that matches anything except known separators (and dot is allowed to occur in a floating point number): - * /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g - */ - wordPattern?: RegExp; - /** - * The language's indentation settings. - */ - indentationRules?: IndentationRule; - /** - * The language's rules to be evaluated when pressing Enter. - */ - onEnterRules?: OnEnterRule[]; - } - - /** - * The configuration target - */ - declare export var ConfigurationTarget: { - /** - * Global configuration - */ - +Global: 1, - - /** - * Workspace configuration - */ - +Workspace: 2, - - /** - * Workspace folder configuration - */ - +WorkspaceFolder: 3 - } - declare export type ConfigurationTargetType = $Values; - - /** - * Represents the configuration. It is a merged view of - * - * - Default configuration - * - Global configuration - * - Workspace configuration (if available) - * - Workspace folder configuration of the requested resource (if available) - * - * *Global configuration* comes from User Settings and shadows Defaults. - * - * *Workspace configuration* comes from Workspace Settings and shadows Global configuration. - * - * *Workspace Folder configuration* comes from `.vscode` folder under one of the [workspace folders](#workspace.workspaceFolders). - * - * *Note:* Workspace and Workspace Folder configurations contains `launch` and `tasks` settings. Their basename will be - * part of the section identifier. The following snippets shows how to retrieve all configurations - * from `launch.json`: - * - * ```ts - * // launch.json configuration - * const config = workspace.getConfiguration('launch', vscode.window.activeTextEditor.document.uri); - * - * // retrieve values - * const values = config.get('configurations'); - * ``` - * - * Refer to [Settings](https://code.visualstudio.com/docs/getstarted/settings) for more information. - */ - declare export interface WorkspaceConfiguration { - /** - * Return a value from this configuration. - * - * @param section Configuration name, supports _dotted_ names. - * @param defaultValue A value should be returned when no value could be found, is `undefined`. - * @return The value `section` denotes or the default. - */ - get(section: string, defaultValue?: T): T; - - /** - * Check if this configuration has a certain value. - * - * @param section Configuration name, supports _dotted_ names. - * @return `true` if the section doesn't resolve to `undefined`. - */ - has(section: string): boolean; - - /** - * Retrieve all information about a configuration setting. A configuration value - * often consists of a *default* value, a global or installation-wide value, - * a workspace-specific value and a folder-specific value. - * - * The *effective* value (returned by [`get`](#WorkspaceConfiguration.get)) - * is computed like this: `defaultValue` overwritten by `globalValue`, - * `globalValue` overwritten by `workspaceValue`. `workspaceValue` overwritten by `workspaceFolderValue`. - * Refer to [Settings Inheritence](https://code.visualstudio.com/docs/getstarted/settings) - * for more information. - * - * *Note:* The configuration name must denote a leaf in the configuration tree - * (`editor.fontSize` vs `editor`) otherwise no result is returned. - * - * @param section Configuration name, supports _dotted_ names. - * @return Information about a configuration setting or `undefined`. - */ - inspect(section: string): ?{ key: string; defaultValue?: T; globalValue?: T; workspaceValue?: T, workspaceFolderValue?: T }; - - /** - * Update a configuration value. The updated configuration values are persisted. - * - * A value can be changed in - * - * - [Global configuration](#ConfigurationTarget.Global): Changes the value for all instances of the editor. - * - [Workspace configuration](#ConfigurationTarget.Workspace): Changes the value for current workspace, if available. - * - [Workspace folder configuration](#ConfigurationTarget.WorkspaceFolder): Changes the value for the - * [Workspace folder](#workspace.workspaceFolders) to which the current [configuration](#WorkspaceConfiguration) is scoped to. - * - * *Note 1:* Setting a global value in the presence of a more specific workspace value - * has no observable effect in that workspace, but in others. Setting a workspace value - * in the presence of a more specific folder value has no observable effect for the resources - * under respective [folder](#workspace.workspaceFolders), but in others. Refer to - * [Settings Inheritence](https://code.visualstudio.com/docs/getstarted/settings) for more information. - * - * *Note 2:* To remove a configuration value use `undefined`, like so: `config.update('somekey', undefined)` - * - * Will throw error when - * - Writing a configuration which is not registered. - * - Writing a configuration to workspace or folder target when no workspace is opened - * - Writing a configuration to folder target when there is no folder settings - * - Writing to folder target without passing a resource when getting the configuration (`workspace.getConfiguration(section, resource)`) - * - Writing a window configuration to folder target - * - * @param section Configuration name, supports _dotted_ names. - * @param value The new value. - * @param configurationTarget The [configuration target](#ConfigurationTarget) or a boolean value. - * - If `true` configuration target is `ConfigurationTarget.Global`. - * - If `false` configuration target is `ConfigurationTarget.Workspace`. - * - If `undefined` or `null` configuration target is - * `ConfigurationTarget.WorkspaceFolder` when configuration is resource specific - * `ConfigurationTarget.Workspace` otherwise. - */ - update(section: string, value: any, configurationTarget?: ConfigurationTargetType | boolean): Thenable; - - /** - * Readable dictionary that backs this configuration. - */ - +[key: string]: any; - } - - /** - * Represents a location inside a resource, such as a line - * inside a text file. - */ - declare export class Location { - - /** - * The resource identifier of this location. - */ - uri: Uri; - - /** - * The document range of this location. - */ - range: Range; - - /** - * Creates a new location object. - * - * @param uri The resource identifier. - * @param rangeOrPosition The range or position. Positions will be converted to an empty range. - */ - constructor(uri: Uri, rangeOrPosition: Range | Position): void; - } - - /** - * Represents the severity of diagnostics. - */ - declare export var DiagnosticSeverity: { - - /** - * Something not allowed by the rules of a language or other means. - */ - +Error: 0, - - /** - * Something suspicious but allowed. - */ - +Warning: 1, - - /** - * Something to inform about but not a problem. - */ - +Information: 2, - - /** - * Something to hint to a better way of doing it, like proposing - * a refactoring. - */ - +Hint: 3 - } - declare export type DiagnosticSeverityType = $Values; - - /** - * Represents a diagnostic, such as a compiler error or warning. Diagnostic objects - * are only valid in the scope of a file. - */ - declare export class Diagnostic { - - /** - * The range to which this diagnostic applies. - */ - range: Range; - - /** - * The human-readable message. - */ - message: string; - - /** - * A human-readable string describing the source of this - * diagnostic, e.g. 'typescript' or 'super lint'. - */ - source: string; - - /** - * The severity, default is [error](#DiagnosticSeverity.Error). - */ - severity: ConfigurationTargetType; - - /** - * A code or identifier for this diagnostics. Will not be surfaced - * to the user, but should be used for later processing, e.g. when - * providing [code actions](#CodeActionContext). - */ - code: string | number; - - /** - * Creates a new diagnostic object. - * - * @param range The range to which this diagnostic applies. - * @param message The human-readable message. - * @param severity The severity, default is [error](#DiagnosticSeverity.Error). - */ - constructor(range: Range, message: string, severity?: ConfigurationTargetType): void; - } - - /** - * A diagnostics collection is a container that manages a set of - * [diagnostics](#Diagnostic). Diagnostics are always scopes to a - * diagnostics collection and a resource. - * - * To get an instance of a `DiagnosticCollection` use - * [createDiagnosticCollection](#languages.createDiagnosticCollection). - */ - declare export interface DiagnosticCollection { - - /** - * The name of this diagnostic collection, for instance `typescript`. Every diagnostic - * from this collection will be associated with this name. Also, the task framework uses this - * name when defining [problem matchers](https://code.visualstudio.com/docs/editor/tasks#_defining-a-problem-matcher). - */ - +name: string; - - /** - * Assign diagnostics for given resource. Will replace - * existing diagnostics for that resource. - * - * @param uri A resource identifier. - * @param diagnostics Array of diagnostics or `undefined` - */ - set(uri: Uri, diagnostics: ?Diagnostic[]): void; - - /** - * Replace all entries in this collection. - * - * Diagnostics of multiple tuples of the same uri will be merged, e.g - * `[[file1, [d1]], [file1, [d2]]]` is equivalent to `[[file1, [d1, d2]]]`. - * If a diagnostics item is `undefined` as in `[file1, undefined]` - * all previous but not subsequent diagnostics are removed. - * - * @param entries An array of tuples, like `[[file1, [d1, d2]], [file2, [d3, d4, d5]]]`, or `undefined`. - */ - set(entries: [Uri, ?Diagnostic[]][]): void; - - /** - * Remove all diagnostics from this collection that belong - * to the provided `uri`. The same as `#set(uri, undefined)`. - * - * @param uri A resource identifier. - */ - delete(uri: Uri): void; - - /** - * Remove all diagnostics from this collection. The same - * as calling `#set(undefined)`; - */ - clear(): void; - - /** - * Iterate over each entry in this collection. - * - * @param callback Function to execute for each entry. - * @param thisArg The `this` context used when invoking the handler function. - */ - forEach(callback: (uri: Uri, diagnostics: Diagnostic[], collection: DiagnosticCollection) => any, thisArg?: any): void; - - /** - * Get the diagnostics for a given resource. *Note* that you cannot - * modify the diagnostics-array returned from this call. - * - * @param uri A resource identifier. - * @returns An immutable array of [diagnostics](#Diagnostic) or `undefined`. - */ - get(uri: Uri): ?Diagnostic[]; - - /** - * Check if this collection contains diagnostics for a - * given resource. - * - * @param uri A resource identifier. - * @returns `true` if this collection has diagnostic for the given resource. - */ - has(uri: Uri): boolean; - - /** - * Dispose and free associated resources. Calls - * [clear](#DiagnosticCollection.clear). - */ - dispose(): void; - } - - /** - * Denotes a column in the editor window. Columns are - * used to show editors side by side. - */ - declare export var ViewColumn: { - /** - * A *symbolic* editor column representing the currently - * active column. This value can be used when opening editors, but the - * *resolved* [viewColumn](#TextEditor.viewColumn)-value of editors will always - * be `One`, `Two`, `Three`, or `undefined` but never `Active`. - */ - +Active: -1, - /** - * The left most editor column. - */ - +One: 1, - /** - * The center editor column. - */ - +Two: 2, - /** - * The right most editor column. - */ - +Three: 3 - } - declare export type ViewColumnType = $Values; - - /** - * An output channel is a container for textual information. - * - * To get an instance of an `OutputChannel` use - * [createOutputChannel](#window.createOutputChannel). - */ - declare export interface OutputChannel { - - /** - * The human-readable name of this output channel. - */ - +name: string; - - /** - * Append the given value to the channel. - * - * @param value A string, falsy values will not be printed. - */ - append(value: string): void; - - /** - * Append the given value and a line feed character - * to the channel. - * - * @param value A string, falsy values will be printed. - */ - appendLine(value: string): void; - - /** - * Removes all output from the channel. - */ - clear(): void; - - /** - * Reveal this channel in the UI. - * - * @param preserveFocus When `true` the channel will not take focus. - */ - show(preserveFocus?: boolean): void; - - /** - * Hide this channel from the UI. - */ - hide(): void; - - /** - * Dispose and free associated resources. - */ - dispose(): void; - } - - /** - * Represents the alignment of status bar items. - */ - declare export var StatusBarAlignment: { - - /** - * Aligned to the left side. - */ - +Left: 1, - - /** - * Aligned to the right side. - */ - +Right: 2 - } - declare export type StatusBarAlignmentType = $Values; - - /** - * A status bar item is a status bar contribution that can - * show text and icons and run a command on click. - */ - declare export interface StatusBarItem { - - /** - * The alignment of this item. - */ - +alignment: StatusBarAlignmentType; - - /** - * The priority of this item. Higher value means the item should - * be shown more to the left. - */ - +priority: number; - - /** - * The text to show for the entry. You can embed icons in the text by leveraging the syntax: - * - * `My text $(icon-name) contains icons like $(icon'name) this one.` - * - * Where the icon-name is taken from the [octicon](https://octicons.github.com) icon set, e.g. - * `light-bulb`, `thumbsup`, `zap` etc. - */ - text: string; - - /** - * The tooltip text when you hover over this entry. - */ - tooltip: ?string; - - /** - * The foreground color for this entry. - */ - color: ?(string | ThemeColor); - - /** - * The identifier of a command to run on click. The command must be - * [known](#commands.getCommands). - */ - command: ?string; - - /** - * Shows the entry in the status bar. - */ - show(): void; - - /** - * Hide the entry in the status bar. - */ - hide(): void; - - /** - * Dispose and free associated resources. Call - * [hide](#StatusBarItem.hide). - */ - dispose(): void; - } - - /** - * Defines a generalized way of reporting progress updates. - */ - declare export interface Progress { - - /** - * Report a progress update. - * @param value A progress item, like a message or an updated percentage value - */ - report(value: T): void; - } - - /** - * An individual terminal instance within the integrated terminal. - */ - declare export interface Terminal { - - /** - * The name of the terminal. - */ - +name: string; - - /** - * The process ID of the shell process. - */ - +processId: Thenable; - - /** - * Send text to the terminal. The text is written to the stdin of the underlying pty process - * (shell) of the terminal. - * - * @param text The text to send. - * @param addNewLine Whether to add a new line to the text being sent, this is normally - * required to run a command in the terminal. The character(s) added are \n or \r\n - * depending on the platform. This defaults to `true`. - */ - sendText(text: string, addNewLine?: boolean): void; - - /** - * Show the terminal panel and reveal this terminal in the UI. - * - * @param preserveFocus When `true` the terminal will not take focus. - */ - show(preserveFocus?: boolean): void; - - /** - * Hide the terminal panel if this terminal is currently showing. - */ - hide(): void; - - /** - * Dispose and free associated resources. - */ - dispose(): void; - } - - /** - * Represents an extension. - * - * To get an instance of an `Extension` use [getExtension](#extensions.getExtension). - */ - declare export interface Extension { - - /** - * The canonical extension identifier in the form of: `publisher.name`. - */ - +id: string; - - /** - * The absolute file path of the directory containing this extension. - */ - +extensionPath: string; - - /** - * `true` if the extension has been activated. - */ - +isActive: boolean; - - /** - * The parsed contents of the extension's package.json. - */ - +packageJSON: any; - - /** - * The public API exported by this extension. It is an invalid action - * to access this field before this extension has been activated. - */ - +exports: T; - - /** - * Activates this extension and returns its public API. - * - * @return A promise that will resolve when this extension has been activated. - */ - activate(): Thenable; - } - - /** - * An extension context is a collection of utilities private to an - * extension. - * - * An instance of an `ExtensionContext` is provided as the first - * parameter to the `activate`-call of an extension. - */ - declare export interface ExtensionContext { - - /** - * An array to which disposables can be added. When this - * extension is deactivated the disposables will be disposed. - */ - subscriptions: { dispose(): any }[]; - - /** - * A memento object that stores state in the context - * of the currently opened [workspace](#workspace.workspaceFolders). - */ - workspaceState: Memento; - - /** - * A memento object that stores state independent - * of the current opened [workspace](#workspace.workspaceFolders). - */ - globalState: Memento; - - /** - * The absolute file path of the directory containing the extension. - */ - extensionPath: string; - - /** - * Get the absolute path of a resource contained in the extension. - * - * @param relativePath A relative path to a resource contained in the extension. - * @return The absolute path of the resource. - */ - asAbsolutePath(relativePath: string): string; - - /** - * An absolute file path of a workspace specific directory in which the extension - * can store private state. The directory might not exist on disk and creation is - * up to the extension. However, the parent directory is guaranteed to be existent. - * - * Use [`workspaceState`](#ExtensionContext.workspaceState) or - * [`globalState`](#ExtensionContext.globalState) to store key value data. - */ - storagePath: ?string; - - /* BEGIN PROPOSED *******************************************************************************/ - /** - * This extension's logger - */ - logger: Logger; - - /** - * Path where an extension can write log files. - * - * Extensions must create this directory before writing to it. The parent directory will always exist. - */ - +logDirectory: string; - /* END PROPOSED *********************************************************************************/ - } - - /** - * A memento represents a storage utility. It can store and retrieve - * values. - */ - declare export interface Memento { - - /** - * Return a value. - * - * @param key A string. - * @param defaultValue A value that should be returned when there is no - * value (`undefined`) with the given key. - * @return The stored value or the defaultValue. - */ - get(key: string, defaultValue?: T): T; - - /** - * Store a value. The value must be JSON-stringifyable. - * - * @param key A string. - * @param value A value. MUST not contain cyclic references. - */ - update(key: string, value: any): Thenable; - } - - /** - * Controls the behaviour of the terminal's visibility. - */ - declare export var TaskRevealKind: { - /** - * Always brings the terminal to front if the task is executed. - */ - +Always: 1, - - /** - * Only brings the terminal to front if a problem is detected executing the task - * (e.g. the task couldn't be started because). - */ - +Silent: 2, - - /** - * The terminal never comes to front when the task is executed. - */ - +Never: 3 - } - declare export type TaskRevealKindType = $Values; - - /** - * Controls how the task channel is used between tasks - */ - declare export var TaskPanelKind: { - - /** - * Shares a panel with other tasks. This is the default. - */ - +Shared: 1, - - /** - * Uses a dedicated panel for this tasks. The panel is not - * shared with other tasks. - */ - +Dedicated: 2, - - /** - * Creates a new panel whenever this task is executed. - */ - +New: 3 - } - declare export type TaskPanelKindType = $Values; - - /** - * Controls how the task is presented in the UI. - */ - declare export interface TaskPresentationOptions { - /** - * Controls whether the task output is reveal in the user interface. - * Defaults to `RevealKind.Always`. - */ - reveal?: TaskRevealKindType; - - /** - * Controls whether the command associated with the task is echoed - * in the user interface. - */ - echo?: boolean; - - /** - * Controls whether the panel showing the task output is taking focus. - */ - focus?: boolean; - - /** - * Controls if the task panel is used for this task only (dedicated), - * shared between tasks (shared) or if a new panel is created on - * every task execution (new). Defaults to `TaskInstanceKind.Shared` - */ - panel?: TaskPanelKindType; - } - - /** - * A grouping for tasks. The editor by default supports the - * 'Clean', 'Build', 'RebuildAll' and 'Test' group. - */ - declare export class TaskGroup { - - /** - * The clean task group; - */ - static Clean: TaskGroup; - - /** - * The build task group; - */ - static Build: TaskGroup; - - /** - * The rebuild all task group; - */ - static Rebuild: TaskGroup; - - /** - * The test all task group; - */ - static Test: TaskGroup; - - // private constructor(id: string, label: string): void; - } - - - /** - * A structure that defines a task kind in the system. - * The value must be JSON-stringifyable. - */ - declare export interface TaskDefinition { - /** - * The task definition describing the task provided by an extension. - * Usually a task provider defines more properties to identify - * a task. They need to be defined in the package.json of the - * extension under the 'taskDefinitions' extension point. The npm - * task definition for example looks like this - * ```typescript - * interface NpmTaskDefinition extends TaskDefinition { - * script: string; - * } - * ``` - */ - +type: string; - - /** - * Additional attributes of a concrete task definition. - */ - [name: string]: any; - } - - /** - * Options for a process execution - */ - declare export interface ProcessExecutionOptions { - /** - * The current working directory of the executed program or shell. - * If omitted the tools current workspace root is used. - */ - cwd?: string; - - /** - * The additional environment of the executed program or shell. If omitted - * the parent process' environment is used. If provided it is merged with - * the parent process' environment. - */ - env?: { [key: string]: string }; - } - - /** - * The execution of a task happens as an external process - * without shell interaction. - */ - declare export class ProcessExecution { - - /** - * Creates a process execution. - * - * @param process The process to start. - * @param args Arguments to be passed to the process. - * @param options Optional options for the started process. - */ - constructor(process: string, args?: string[], options?: ProcessExecutionOptions): void; - - /** - * The process to be executed. - */ - process: string; - - /** - * The arguments passed to the process. Defaults to an empty array. - */ - args: string[]; - - /** - * The process options used when the process is executed. - * Defaults to undefined. - */ - options?: ProcessExecutionOptions; - } - - /** - * Options for a shell execution - */ - declare export interface ShellExecutionOptions { - /** - * The shell executable. - */ - executable?: string; - - /** - * The arguments to be passed to the shell executable used to run the task. - */ - shellArgs?: string[]; - - /** - * The current working directory of the executed shell. - * If omitted the tools current workspace root is used. - */ - cwd?: string; - - /** - * The additional environment of the executed shell. If omitted - * the parent process' environment is used. If provided it is merged with - * the parent process' environment. - */ - env?: { [key: string]: string }; - } - - - declare export class ShellExecution { - /** - * Creates a process execution. - * - * @param commandLine The command line to execute. - * @param options Optional options for the started the shell. - */ - constructor(commandLine: string, options?: ShellExecutionOptions): void; - - /** - * The shell command line - */ - commandLine: string; - - /** - * The shell options used when the command line is executed in a shell. - * Defaults to undefined. - */ - options?: ShellExecutionOptions; - } - - /** - * The scope of a task. - */ - declare export var TaskScope: { - /** - * The task is a global task - */ - +Global: 1, - - /** - * The task is a workspace task - */ - +Workspace: 2 - } - declare export type TaskScopeType = $Values; - - /** - * A task to execute - */ - declare export class Task { - - /** - * Creates a new task. - * - * @param definition The task definition as defined in the taskDefinitions extension point. - * @param target Specifies the task's target. It is either a global or a workspace task or a task for a specific workspace folder. - * @param name The task's name. Is presented in the user interface. - * @param source The task's source (e.g. 'gulp', 'npm', ...). Is presented in the user interface. - * @param execution The process or shell execution. - * @param problemMatchers the names of problem matchers to use, like '$tsc' - * or '$eslint'. Problem matchers can be contributed by an extension using - * the `problemMatchers` extension point. - */ - constructor(taskDefinition: TaskDefinition, target?: WorkspaceFolder | typeof TaskScope.Global | typeof TaskScope.Workspace, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]): void; - - /** - * The task's definition. - */ - definition: TaskDefinition; - - /** - * The task's scope. - */ - scope?: typeof TaskScope.Global | typeof TaskScope.Workspace | WorkspaceFolder; - - /** - * The task's name - */ - name: string; - - /** - * The task's execution engine - */ - execution: ProcessExecution | ShellExecution; - - /** - * Whether the task is a background task or not. - */ - isBackground: boolean; - - /** - * A human-readable string describing the source of this - * shell task, e.g. 'gulp' or 'npm'. - */ - source: string; - - /** - * The task group this tasks belongs to. See TaskGroup - * for a predefined set of available groups. - * Defaults to undefined meaning that the task doesn't - * belong to any special group. - */ - group?: TaskGroup; - - /** - * The presentation options. Defaults to an empty literal. - */ - presentationOptions: TaskPresentationOptions; - - /** - * The problem matchers attached to the task. Defaults to an empty - * array. - */ - problemMatchers: string[]; - } - - /** - * A task provider allows to add tasks to the task service. - * A task provider is registered via #workspace.registerTaskProvider. - */ - declare export interface TaskProvider { - /** - * Provides tasks. - * @param token A cancellation token. - * @return an array of tasks - */ - provideTasks(token?: CancellationToken): ProviderResult; - - /** - * Resolves a task that has no [`execution`](#Task.execution) set. Tasks are - * often created from information found in the `task.json`-file. Such tasks miss - * the information on how to execute them and a task provider must fill in - * the missing information in the `resolveTask`-method. - * - * @param task The task to resolve. - * @param token A cancellation token. - * @return The resolved task - */ - resolveTask(task: Task, token?: CancellationToken): ProviderResult; - } - - /** - * Namespace describing the environment the editor runs in. - */ - declare export var env: { - - /** - * The application name of the editor, like 'VS Code'. - * - * @readonly - */ - appName: string; - - /** - * The application root folder from which the editor is running. - * - * @readonly - */ - appRoot: string; - - /** - * Represents the preferred user-language, like `de-CH`, `fr`, or `en-US`. - * - * @readonly - */ - language: string; - - /** - * A unique identifier for the computer. - * - * @readonly - */ - machineId: string; - - /** - * A unique identifier for the current session. - * Changes each time the editor is started. - * - * @readonly - */ - sessionId: string; - } - - /** - * Namespace for dealing with commands. In short, a command is a function with a - * unique identifier. The function is sometimes also called _command handler_. - * - * Commands can be added to the editor using the [registerCommand](#commands.registerCommand) - * and [registerTextEditorCommand](#commands.registerTextEditorCommand) functions. Commands - * can be executed [manually](#commands.executeCommand) or from a UI gesture. Those are: - * - * * palette - Use the `commands`-section in `package.json` to make a command show in - * the [command palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette). - * * keybinding - Use the `keybindings`-section in `package.json` to enable - * [keybindings](https://code.visualstudio.com/docs/getstarted/keybindings#_customizing-shortcuts) - * for your extension. - * - * Commands from other extensions and from the editor itself are accessible to an extension. However, - * when invoking an editor command not all argument types are supported. - * - * This is a sample that registers a command handler and adds an entry for that command to the palette. First - * register a command handler with the identifier `extension.sayHello`. - * ```javascript - * commands.registerCommand('extension.sayHello', () => { - * window.showInformationMessage('Hello World!'); - * }); - * ``` - * Second, bind the command identifier to a title under which it will show in the palette (`package.json`). - * ```json - * { - * "contributes": { - * "commands": [{ - * "command": "extension.sayHello", - * "title": "Hello World" - * }] - * } - * } - * ``` - */ - declare export var commands: { - - /** - * Registers a command that can be invoked via a keyboard shortcut, - * a menu item, an action, or directly. - * - * Registering a command with an existing command identifier twice - * will cause an error. - * - * @param command A unique identifier for the command. - * @param callback A command handler function. - * @param thisArg The `this` context used when invoking the handler function. - * @return Disposable which unregisters this command on disposal. - */ - registerCommand(command: string, callback: (...args: any[]) => any, thisArg?: any): Disposable; - - /** - * Registers a text editor command that can be invoked via a keyboard shortcut, - * a menu item, an action, or directly. - * - * Text editor commands are different from ordinary [commands](#commands.registerCommand) as - * they only execute when there is an active editor when the command is called. Also, the - * command handler of an editor command has access to the active editor and to an - * [edit](#TextEditorEdit)-builder. - * - * @param command A unique identifier for the command. - * @param callback A command handler function with access to an [editor](#TextEditor) and an [edit](#TextEditorEdit). - * @param thisArg The `this` context used when invoking the handler function. - * @return Disposable which unregisters this command on disposal. - */ - registerTextEditorCommand(command: string, callback: (textEditor: TextEditor, edit: TextEditorEdit, ...args: any[]) => void, thisArg?: any): Disposable; - - /** - * Executes the command denoted by the given command identifier. - * - * * *Note 1:* When executing an editor command not all types are allowed to - * be passed as arguments. Allowed are the primitive types `string`, `boolean`, - * `number`, `undefined`, and `null`, as well as [`Position`](#Position), [`Range`](#Range), [`Uri`](#Uri) and [`Location`](#Location). - * * *Note 2:* There are no restrictions when executing commands that have been contributed - * by extensions. - * - * @param command Identifier of the command to execute. - * @param rest Parameters passed to the command function. - * @return A thenable that resolves to the returned value of the given command. `undefined` when - * the command handler function doesn't return anything. - */ - executeCommand(command: string, ...rest: any[]): Thenable; - - /** - * Retrieve the list of all available commands. Commands starting an underscore are - * treated as internal commands. - * - * @param filterInternal Set `true` to not see internal commands (starting with an underscore) - * @return Thenable that resolves to a list of command ids. - */ - getCommands(filterInternal?: boolean): Thenable; - - /* BEGIN PROPOSED *******************************************************************************/ - /** - * Registers a diff information command that can be invoked via a keyboard shortcut, - * a menu item, an action, or directly. - * - * Diff information commands are different from ordinary [commands](#commands.registerCommand) as - * they only execute when there is an active diff editor when the command is called, and the diff - * information has been computed. Also, the command handler of an editor command has access to - * the diff information. - * - * @param command A unique identifier for the command. - * @param callback A command handler function with access to the [diff information](#LineChange). - * @param thisArg The `this` context used when invoking the handler function. - * @return Disposable which unregisters this command on disposal. - */ - registerDiffInformationCommand(command: string, callback: (diff: LineChange[], ...args: any[]) => any, thisArg?: any): Disposable; - /* END PROPOSED *********************************************************************************/ - } - - /** - * Represents the state of a window. - */ - declare export interface WindowState { - - /** - * Whether the current window is focused. - */ - +focused: boolean; - } - - /** - * Namespace for dealing with the current window of the editor. That is visible - * and active editors, as well as, UI elements to show messages, selections, and - * asking for user input. - */ - declare export var window: { - - /** - * The currently active editor or `undefined`. The active editor is the one - * that currently has focus or, when none has focus, the one that has changed - * input most recently. - */ - activeTextEditor: ?TextEditor; - - /** - * The currently visible editors or an empty array. - */ - visibleTextEditors: TextEditor[]; - - /** - * An [event](#Event) which fires when the [active editor](#window.activeTextEditor) - * has changed. *Note* that the event also fires when the active editor changes - * to `undefined`. - */ - +onDidChangeActiveTextEditor: Event; - - /** - * An [event](#Event) which fires when the array of [visible editors](#window.visibleTextEditors) - * has changed. - */ - +onDidChangeVisibleTextEditors: Event; - - /** - * An [event](#Event) which fires when the selection in an editor has changed. - */ - +onDidChangeTextEditorSelection: Event; - - /** - * An [event](#Event) which fires when the options of an editor have changed. - */ - +onDidChangeTextEditorOptions: Event; - - /** - * An [event](#Event) which fires when the view column of an editor has changed. - */ - +onDidChangeTextEditorViewColumn: Event; - - /** - * An [event](#Event) which fires when a terminal is disposed. - */ - +onDidCloseTerminal: Event; - - /** - * Represents the current window's state. - * - * @readonly - */ - state: WindowState; - - /** - * An [event](#Event) which fires when the focus state of the current window - * changes. The value of the event represents whether the window is focused. - */ - +onDidChangeWindowState: Event; - - /** - * Show the given document in a text editor. A [column](#ViewColumn) can be provided - * to control where the editor is being shown. Might change the [active editor](#window.activeTextEditor). - * - * @param document A text document to be shown. - * @param column A view column in which the [editor](#TextEditor) should be shown. The default is the [one](#ViewColumn.One), other values - * are adjusted to be `Min(column, columnCount + 1)`, the [active](#ViewColumn.Active)-column is - * not adjusted. - * @param preserveFocus When `true` the editor will not take focus. - * @return A promise that resolves to an [editor](#TextEditor). - */ - showTextDocument(document: TextDocument, column?: ViewColumnType, preserveFocus?: boolean): Thenable; - - /** - * Show the given document in a text editor. [Options](#TextDocumentShowOptions) can be provided - * to control options of the editor is being shown. Might change the [active editor](#window.activeTextEditor). - * - * @param document A text document to be shown. - * @param options [Editor options](#TextDocumentShowOptions) to configure the behavior of showing the [editor](#TextEditor). - * @return A promise that resolves to an [editor](#TextEditor). - */ - showTextDocument(document: TextDocument, options?: TextDocumentShowOptions): Thenable; - - /** - * A short-hand for `openTextDocument(uri).then(document => showTextDocument(document, options))`. - * - * @see [openTextDocument](#openTextDocument) - * - * @param uri A resource identifier. - * @param options [Editor options](#TextDocumentShowOptions) to configure the behavior of showing the [editor](#TextEditor). - * @return A promise that resolves to an [editor](#TextEditor). - */ - showTextDocument(uri: Uri, options?: TextDocumentShowOptions): Thenable; - - /** - * Create a TextEditorDecorationType that can be used to add decorations to text editors. - * - * @param options Rendering options for the decoration type. - * @return A new decoration type instance. - */ - createTextEditorDecorationType(options: DecorationRenderOptions): TextEditorDecorationType; - - /** - * Show an information message to users. Optionally provide an array of items which will be presented as - * clickable buttons. - * - * @param message The message to show. - * @param options Configures the behaviour of the message. - * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. - */ - showInformationMessage(message: string, options?: MessageOptions, ...items: string[]): Thenable; - - /** - * Show an information message. - * - * @see [showInformationMessage](#window.showInformationMessage) - * - * @param message The message to show. - * @param options Configures the behaviour of the message. - * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. - */ - showInformationMessage(message: string, options?: MessageOptions, ...items: T[]): Thenable; - - /** - * Show a warning message. - * - * @see [showInformationMessage](#window.showInformationMessage) - * - * @param message The message to show. - * @param options Configures the behaviour of the message. - * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. - */ - showWarningMessage(message: string, options?: MessageOptions, ...items: string[]): Thenable; - - /** - * Show a warning message. - * - * @see [showInformationMessage](#window.showInformationMessage) - * - * @param message The message to show. - * @param options Configures the behaviour of the message. - * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. - */ - showWarningMessage(message: string, options?: MessageOptions, ...items: T[]): Thenable; - - /** - * Show an error message. - * - * @see [showInformationMessage](#window.showInformationMessage) - * - * @param message The message to show. - * @param options Configures the behaviour of the message. - * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. - */ - showErrorMessage(message: string, options?: MessageOptions, ...items: string[]): Thenable; - - /** - * Show an error message. - * - * @see [showInformationMessage](#window.showInformationMessage) - * - * @param message The message to show. - * @param options Configures the behaviour of the message. - * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. - */ - showErrorMessage(message: string, options?: MessageOptions, ...items: T[]): Thenable; - - /** - * Shows a selection list. - * - * @param items An array of strings, or a promise that resolves to an array of strings. - * @param options Configures the behavior of the selection list. - * @param token A token that can be used to signal cancellation. - * @return A promise that resolves to the selection or `undefined`. - */ - showQuickPick(items: string[] | Thenable, options?: QuickPickOptions, token?: CancellationToken): Thenable; - - /** - * Shows a selection list. - * - * @param items An array of items, or a promise that resolves to an array of items. - * @param options Configures the behavior of the selection list. - * @param token A token that can be used to signal cancellation. - * @return A promise that resolves to the selected item or `undefined`. - */ - showQuickPick(items: T[] | Thenable, options?: QuickPickOptions, token?: CancellationToken): Thenable; - - /** - * Shows a selection list of [workspace folders](#workspace.workspaceFolders) to pick from. - * Returns `undefined` if no folder is open. - * - * @param options Configures the behavior of the workspace folder list. - * @return A promise that resolves to the workspace folder or `undefined`. - */ - showWorkspaceFolderPick(options?: WorkspaceFolderPickOptions): Thenable; - - /** - * Shows a file open dialog to the user which allows to select a file - * for opening-purposes. - * - * @param options Options that control the dialog. - * @returns A promise that resolves to the selected resources or `undefined`. - */ - showOpenDialog(options: OpenDialogOptions): Thenable; - - /** - * Shows a file save dialog to the user which allows to select a file - * for saving-purposes. - * - * @param options Options that control the dialog. - * @returns A promise that resolves to the selected resource or `undefined`. - */ - showSaveDialog(options: SaveDialogOptions): Thenable; - - /** - * Opens an input box to ask the user for input. - * - * The returned value will be `undefined` if the input box was canceled (e.g. pressing ESC). Otherwise the - * returned value will be the string typed by the user or an empty string if the user did not type - * anything but dismissed the input box with OK. - * - * @param options Configures the behavior of the input box. - * @param token A token that can be used to signal cancellation. - * @return A promise that resolves to a string the user provided or to `undefined` in case of dismissal. - */ - showInputBox(options?: InputBoxOptions, token?: CancellationToken): Thenable; - - /** - * Create a new [output channel](#OutputChannel) with the given name. - * - * @param name Human-readable string which will be used to represent the channel in the UI. - */ - createOutputChannel(name: string): OutputChannel; - - /** - * Set a message to the status bar. This is a short hand for the more powerful - * status bar [items](#window.createStatusBarItem). - * - * @param text The message to show, supports icon substitution as in status bar [items](#StatusBarItem.text). - * @param hideAfterTimeout Timeout in milliseconds after which the message will be disposed. - * @return A disposable which hides the status bar message. - */ - setStatusBarMessage(text: string, hideAfterTimeout: number): Disposable; - - /** - * Set a message to the status bar. This is a short hand for the more powerful - * status bar [items](#window.createStatusBarItem). - * - * @param text The message to show, supports icon substitution as in status bar [items](#StatusBarItem.text). - * @param hideWhenDone Thenable on which completion (resolve or reject) the message will be disposed. - * @return A disposable which hides the status bar message. - */ - setStatusBarMessage(text: string, hideWhenDone: Thenable): Disposable; - - /** - * Set a message to the status bar. This is a short hand for the more powerful - * status bar [items](#window.createStatusBarItem). - * - * *Note* that status bar messages stack and that they must be disposed when no - * longer used. - * - * @param text The message to show, supports icon substitution as in status bar [items](#StatusBarItem.text). - * @return A disposable which hides the status bar message. - */ - setStatusBarMessage(text: string): Disposable; - - /** - * Show progress in the editor. Progress is shown while running the given callback - * and while the promise it returned isn't resolved nor rejected. The location at which - * progress should show (and other details) is defined via the passed [`ProgressOptions`](#ProgressOptions). - * - * @param task A callback returning a promise. Progress state can be reported with - * the provided [progress](#Progress)-object. - * @return The thenable the task-callback returned. - */ - withProgress(options: ProgressOptions, task: (progress: Progress<{ message?: string; }>) => Thenable): Thenable; - - /** - * Creates a status bar [item](#StatusBarItem). - * - * @param alignment The alignment of the item. - * @param priority The priority of the item. Higher values mean the item should be shown more to the left. - * @return A new status bar item. - */ - createStatusBarItem(alignment?: StatusBarAlignmentType, priority?: number): StatusBarItem; - - /** - * Creates a [Terminal](#Terminal). The cwd of the terminal will be the workspace directory - * if it exists, regardless of whether an explicit customStartPath setting exists. - * - * @param name Optional human-readable string which will be used to represent the terminal in the UI. - * @param shellPath Optional path to a custom shell executable to be used in the terminal. - * @param shellArgs Optional args for the custom shell executable, this does not work on Windows (see #8429) - * @return A new Terminal. - */ - createTerminal(name?: string, shellPath?: string, shellArgs?: string[]): Terminal; - - /** - * Creates a [Terminal](#Terminal). The cwd of the terminal will be the workspace directory - * if it exists, regardless of whether an explicit customStartPath setting exists. - * - * @param options A TerminalOptions object describing the characteristics of the new terminal. - * @return A new Terminal. - */ - createTerminal(options: TerminalOptions): Terminal; - - /** - * Register a [TreeDataProvider](#TreeDataProvider) for the view contributed using the extension point `views`. - * @param viewId Id of the view contributed using the extension point `views`. - * @param treeDataProvider A [TreeDataProvider](#TreeDataProvider) that provides tree data for the view - */ - registerTreeDataProvider(viewId: string, treeDataProvider: TreeDataProvider): Disposable; - - /* BEGIN PROPOSED *******************************************************************************/ - registerDecorationProvider(provider: DecorationProvider): Disposable; - /* END PROPOSED *********************************************************************************/ - } - - /** - * A data provider that provides tree data - */ - declare export interface TreeDataProvider { - /** - * An optional event to signal that an element or root has changed. - * This will trigger the view to update the changed element/root and its children recursively (if shown). - * To signal that root has changed, do not pass any argument or pass `undefined` or `null`. - */ - onDidChangeTreeData?: Event; - - /** - * Get [TreeItem](#TreeItem) representation of the `element` - * - * @param element The element for which [TreeItem](#TreeItem) representation is asked for. - * @return [TreeItem](#TreeItem) representation of the element - */ - getTreeItem(element: T): TreeItem | Thenable; - - /** - * Get the children of `element` or root if no element is passed. - * - * @param element The element from which the provider gets children. Can be `undefined`. - * @return Children of `element` or root if no element is passed. - */ - getChildren(element?: T): ProviderResult; - } - - declare export class TreeItem { - /** - * A human-readable string describing this item. When `falsy`, it is derived from [resourceUri](#TreeItem.resourceUri). - */ - label?: string; - - /** - * Optional id for the tree item that has to be unique across tree. The id is used to preserve the selection and expansion state of the tree item. - * - * If not provided, an id is generated using the tree item's label. **Note** that when labels change, ids will change and that selection and expansion state cannot be kept stable anymore. - */ - id?: string; - - /** - * The icon path for the tree item. When `falsy`, it is derived from [resourceUri](#TreeItem.resourceUri). - */ - iconPath?: string | Uri | { light: string | Uri; dark: string | Uri }; - - /** - * The [uri](#Uri) of the resource representing this item. - * - * Will be used to derive the [label](#TreeItem.label), when it is not provided. - * Will be used to derive the icon from current file icon theme, when [iconPath](#TreeItem.iconPath) is not provided. - */ - resourceUri?: Uri; - - /** - * The [command](#Command) which should be run when the tree item is selected. - */ - command?: Command; - - /** - * [TreeItemCollapsibleState](#TreeItemCollapsibleState) of the tree item. - */ - collapsibleState?: TreeItemCollapsibleStateType; - - /** - * Context value of the tree item. This can be used to contribute item specific actions in the tree. - * For example, a tree item is given a context value as `folder`. When contributing actions to `view/item/context` - * using `menus` extension point, you can specify context value for key `viewItem` in `when` expression like `viewItem == folder`. - * ``` - * "contributes": { - * "menus": { - * "view/item/context": [ - * { - * "command": "extension.deleteFolder", - * "when": "viewItem == folder" - * } - * ] - * } - * } - * ``` - * This will show action `extension.deleteFolder` only for items with `contextValue` is `folder`. - */ - contextValue?: string; - - /** - * @param label A human-readable string describing this item - * @param collapsibleState [TreeItemCollapsibleState](#TreeItemCollapsibleState) of the tree item. Default is [TreeItemCollapsibleState.None](#TreeItemCollapsibleState.None) - */ - constructor(label: string, collapsibleState?: TreeItemCollapsibleStateType): void; - - /** - * @param resourceUri The [uri](#Uri) of the resource representing this item. - * @param collapsibleState [TreeItemCollapsibleState](#TreeItemCollapsibleState) of the tree item. Default is [TreeItemCollapsibleState.None](#TreeItemCollapsibleState.None) - */ - constructor(resourceUri: Uri, collapsibleState?: TreeItemCollapsibleStateType): void; - } - - /** - * Collapsible state of the tree item - */ - declare export var TreeItemCollapsibleState: { - /** - * Determines an item can be neither collapsed nor expanded. Implies it has no children. - */ - +None: 0, - /** - * Determines an item is collapsed - */ - +Collapsed: 1, - /** - * Determines an item is expanded - */ - +Expanded: 2 - } - declare export type TreeItemCollapsibleStateType = $Values; - - /** - * Value-object describing what options a terminal should use. - */ - declare export interface TerminalOptions { - /** - * A human-readable string which will be used to represent the terminal in the UI. - */ - name?: string; - - /** - * A path to a custom shell executable to be used in the terminal. - */ - shellPath?: string; - - /** - * Args for the custom shell executable, this does not work on Windows (see #8429) - */ - shellArgs?: string[]; - - /** - * A path for the current working directory to be used for the terminal. - */ - cwd?: string; - - /** - * Object with environment variables that will be added to the VS Code process. - */ - env?: { [key: string]: string | null }; - } - - /** - * A location in the editor at which progress information can be shown. It depends on the - * location how progress is visually represented. - */ - declare export var ProgressLocation: { - - /** - * Show progress for the source control viewlet, as overlay for the icon and as progress bar - * inside the viewlet (when visible). - */ - +SourceControl: 1, - - /** - * Show progress in the status bar of the editor. - */ - +Window: 10 - } - declare export type ProgressLocationType = $Values; - - /** - * Value-object describing where and how progress should show. - */ - declare export interface ProgressOptions { - - /** - * The location at which progress should show. - */ - location: ProgressLocationType; - - /** - * A human-readable string which will be used to describe the - * operation. - */ - title?: string; - } - - /** - * An event describing an individual change in the text of a [document](#TextDocument). - */ - declare export interface TextDocumentContentChangeEvent { - /** - * The range that got replaced. - */ - range: Range; - /** - * The length of the range that got replaced. - */ - rangeLength: number; - /** - * The new text for the range. - */ - text: string; - } - - /** - * An event describing a transactional [document](#TextDocument) change. - */ - declare export interface TextDocumentChangeEvent { - - /** - * The affected document. - */ - document: TextDocument; - - /** - * An array of content changes. - */ - contentChanges: TextDocumentContentChangeEvent[]; - } - - /** - * Represents reasons why a text document is saved. - */ - declare export var TextDocumentSaveReason: { - - /** - * Manually triggered, e.g. by the user pressing save, by starting debugging, - * or by an API call. - */ - +Manual: 1, - - /** - * Automatic after a delay. - */ - +AfterDelay: 2, - - /** - * When the editor lost focus. - */ - +FocusOut: 3 - } - declare export type TextDocumentSaveReasonType = $Values; - - /** - * An event that is fired when a [document](#TextDocument) will be saved. - * - * To make modifications to the document before it is being saved, call the - * [`waitUntil`](#TextDocumentWillSaveEvent.waitUntil)-function with a thenable - * that resolves to an array of [text edits](#TextEdit). - */ - declare export interface TextDocumentWillSaveEvent { - - /** - * The document that will be saved. - */ - document: TextDocument; - - /** - * The reason why save was triggered. - */ - reason: TextDocumentSaveReasonType; - - /** - * Allows to pause the event loop and to apply [pre-save-edits](#TextEdit). - * Edits of subsequent calls to this function will be applied in order. The - * edits will be *ignored* if concurrent modifications of the document happened. - * - * *Note:* This function can only be called during event dispatch and not - * in an asynchronous manner: - * - * ```ts - * workspace.onWillSaveTextDocument(event => { - * // async, will *throw* an error - * setTimeout(() => event.waitUntil(promise)); - * - * // sync, OK - * event.waitUntil(promise); - * }) - * ``` - * - * @param thenable A thenable that resolves to [pre-save-edits](#TextEdit). - */ - waitUntil(thenable: Thenable): void; - - /** - * Allows to pause the event loop until the provided thenable resolved. - * - * *Note:* This function can only be called during event dispatch. - * - * @param thenable A thenable that delays saving. - */ - waitUntil(thenable: Thenable): void; - } - - /** - * An event describing a change to the set of [workspace folders](#workspace.workspaceFolders). - */ - declare export interface WorkspaceFoldersChangeEvent { - /** - * Added workspace folders. - */ - +added: WorkspaceFolder[]; - - /** - * Removed workspace folders. - */ - +removed: WorkspaceFolder[]; - } - - /** - * A workspace folder is one of potentially many roots opened by the editor. All workspace folders - * are equal which means there is no notion of an active or master workspace folder. - */ - declare export interface WorkspaceFolder { - - /** - * The associated uri for this workspace folder. - * - * *Note:* The [Uri](#Uri)-type was intentionally chosen such that future releases of the editor can support - * workspace folders that are not stored on the local disk, e.g. `ftp://server/workspaces/foo`. - */ - +uri: Uri; - - /** - * The name of this workspace folder. Defaults to - * the basename of its [uri-path](#Uri.path) - */ - +name: string; - - /** - * The ordinal number of this workspace folder. - */ - +index: number; - } - - /** - * Namespace for dealing with the current workspace. A workspace is the representation - * of the folder that has been opened. There is no workspace when just a file but not a - * folder has been opened. - * - * The workspace offers support for [listening](#workspace.createFileSystemWatcher) to fs - * events and for [finding](#workspace.findFiles) files. Both perform well and run _outside_ - * the editor-process so that they should be always used instead of nodejs-equivalents. - */ - declare export var workspace: { - - /** - * List of workspace folders or `undefined` when no folder is open. - * *Note* that the first entry corresponds to the value of `rootPath`. - * - * @readonly - */ - workspaceFolders: ?WorkspaceFolder[]; - - /** - * The name of the workspace. `undefined` when no folder - * has been opened. - * - * @readonly - */ - name: ?string; - - /** - * An event that is emitted when a workspace folder is added or removed. - */ - +onDidChangeWorkspaceFolders: Event; - - /** - * Returns the [workspace folder](#WorkspaceFolder) that contains a given uri. - * * returns `undefined` when the given uri doesn't match any workspace folder - * * returns the *input* when the given uri is a workspace folder itself - * - * @param uri An uri. - * @return A workspace folder or `undefined` - */ - getWorkspaceFolder(uri: Uri): ?WorkspaceFolder; - - /** - * Returns a path that is relative to the workspace folder or folders. - * - * When there are no [workspace folders](#workspace.workspaceFolders) or when the path - * is not contained in them, the input is returned. - * - * @param pathOrUri A path or uri. When a uri is given its [fsPath](#Uri.fsPath) is used. - * @param includeWorkspaceFolder When `true` and when the given path is contained inside a - * workspace folder the name of the workspace is prepended. Defaults to `true` when there are - * multiple workspace folders and `false` otherwise. - * @return A path relative to the root or the input. - */ - asRelativePath(pathOrUri: string | Uri, includeWorkspaceFolder?: boolean): string; - - /** - * Creates a file system watcher. - * - * A glob pattern that filters the file events on their absolute path must be provided. Optionally, - * flags to ignore certain kinds of events can be provided. To stop listening to events the watcher must be disposed. - * - * *Note* that only files within the current [workspace folders](#workspace.workspaceFolders) can be watched. - * - * @param globPattern A [glob pattern](#GlobPattern) that is applied to the absolute paths of created, changed, - * and deleted files. Use a [relative pattern](#RelativePattern) to limit events to a certain [workspace folder](#WorkspaceFolder). - * @param ignoreCreateEvents Ignore when files have been created. - * @param ignoreChangeEvents Ignore when files have been changed. - * @param ignoreDeleteEvents Ignore when files have been deleted. - * @return A new file system watcher instance. - */ - createFileSystemWatcher(globPattern: GlobPattern, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean): FileSystemWatcher; - - /** - * Find files across all [workspace folders](#workspace.workspaceFolders) in the workspace. - * - * @sample `findFiles('**​/*.js', '**​/node_modules/**', 10)` - * @param include A [glob pattern](#GlobPattern) that defines the files to search for. The glob pattern - * will be matched against the file paths of resulting matches relative to their workspace. Use a [relative pattern](#RelativePattern) - * to restrict the search results to a [workspace folder](#WorkspaceFolder). - * @param exclude A [glob pattern](#GlobPattern) that defines files and folders to exclude. The glob pattern - * will be matched against the file paths of resulting matches relative to their workspace. When `undefined` only default excludes will - * apply, when `null` no excludes will apply. - * @param maxResults An upper-bound for the result. - * @param token A token that can be used to signal cancellation to the underlying search engine. - * @return A thenable that resolves to an array of resource identifiers. Will return no results if no - * [workspace folders](#workspace.workspaceFolders) are opened. - */ - findFiles(include: GlobPattern, exclude?: GlobPattern | null, maxResults?: number, token?: CancellationToken): Thenable; - - /** - * Save all dirty files. - * - * @param includeUntitled Also save files that have been created during this session. - * @return A thenable that resolves when the files have been saved. - */ - saveAll(includeUntitled?: boolean): Thenable; - - /** - * Make changes to one or many resources as defined by the given - * [workspace edit](#WorkspaceEdit). - * - * When applying a workspace edit, the editor implements an 'all-or-nothing'-strategy, - * that means failure to load one document or make changes to one document will cause - * the edit to be rejected. - * - * @param edit A workspace edit. - * @return A thenable that resolves when the edit could be applied. - */ - applyEdit(edit: WorkspaceEdit): Thenable; - - /** - * All text documents currently known to the system. - * - * @readonly - */ - textDocuments: TextDocument[]; - - /** - * Opens a document. Will return early if this document is already open. Otherwise - * the document is loaded and the [didOpen](#workspace.onDidOpenTextDocument)-event fires. - * - * The document is denoted by an [uri](#Uri). Depending on the [scheme](#Uri.scheme) the - * following rules apply: - * * `file`-scheme: Open a file on disk, will be rejected if the file does not exist or cannot be loaded. - * * `untitled`-scheme: A new file that should be saved on disk, e.g. `untitled:c:\frodo\new.js`. The language - * will be derived from the file name. - * * For all other schemes the registered text document content [providers](#TextDocumentContentProvider) are consulted. - * - * *Note* that the lifecycle of the returned document is owned by the editor and not by the extension. That means an - * [`onDidClose`](#workspace.onDidCloseTextDocument)-event can occur at any time after opening it. - * - * @param uri Identifies the resource to open. - * @return A promise that resolves to a [document](#TextDocument). - */ - openTextDocument(uri: Uri): Thenable; - - /** - * A short-hand for `openTextDocument(Uri.file(fileName))`. - * - * @see [openTextDocument](#openTextDocument) - * @param fileName A name of a file on disk. - * @return A promise that resolves to a [document](#TextDocument). - */ - openTextDocument(fileName: string): Thenable; - - /** - * Opens an untitled text document. The editor will prompt the user for a file - * path when the document is to be saved. The `options` parameter allows to - * specify the *language* and/or the *content* of the document. - * - * @param options Options to control how the document will be created. - * @return A promise that resolves to a [document](#TextDocument). - */ - openTextDocument(options?: { language?: string; content?: string; }): Thenable; - - /** - * Register a text document content provider. - * - * Only one provider can be registered per scheme. - * - * @param scheme The uri-scheme to register for. - * @param provider A content provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerTextDocumentContentProvider(scheme: string, provider: TextDocumentContentProvider): Disposable; - - /** - * An event that is emitted when a [text document](#TextDocument) is opened. - * - * To add an event listener when a visible text document is opened, use the [TextEditor](#TextEditor) events in the - * [window](#window) namespace. Note that: - * - * - The event is emitted before the [document](#TextDocument) is updated in the - * [active text editor](#window.activeTextEditor) - * - When a [text document](#TextDocument) is already open (e.g.: open in another [visible text editor](#window.visibleTextEditors)) this event is not emitted - * - */ - +onDidOpenTextDocument: Event; - - /** - * An event that is emitted when a [text document](#TextDocument) is disposed. - * - * To add an event listener when a visible text document is closed, use the [TextEditor](#TextEditor) events in the - * [window](#window) namespace. Note that this event is not emitted when a [TextEditor](#TextEditor) is closed - * but the document remains open in another [visible text editor](#window.visibleTextEditors). - */ - +onDidCloseTextDocument: Event; - - /** - * An event that is emitted when a [text document](#TextDocument) is changed. This usually happens - * when the [contents](#TextDocument.getText) changes but also when other things like the - * [dirty](#TextDocument.isDirty)-state changes. - */ - +onDidChangeTextDocument: Event; - - /** - * An event that is emitted when a [text document](#TextDocument) will be saved to disk. - * - * *Note 1:* Subscribers can delay saving by registering asynchronous work. For the sake of data integrity the editor - * might save without firing this event. For instance when shutting down with dirty files. - * - * *Note 2:* Subscribers are called sequentially and they can [delay](#TextDocumentWillSaveEvent.waitUntil) saving - * by registering asynchronous work. Protection against misbehaving listeners is implemented as such: - * * there is an overall time budget that all listeners share and if that is exhausted no further listener is called - * * listeners that take a long time or produce errors frequently will not be called anymore - * - * The current thresholds are 1.5 seconds as overall time budget and a listener can misbehave 3 times before being ignored. - */ - +onWillSaveTextDocument: Event; - - /** - * An event that is emitted when a [text document](#TextDocument) is saved to disk. - */ - +onDidSaveTextDocument: Event; - - /** - * Get a workspace configuration object. - * - * When a section-identifier is provided only that part of the configuration - * is returned. Dots in the section-identifier are interpreted as child-access, - * like `{ myExt: { setting: { doIt: true }}}` and `getConfiguration('myExt.setting').get('doIt') === true`. - * - * When a resource is provided, configuration scoped to that resource is returned. - * - * @param section A dot-separated identifier. - * @param resource A resource for which the configuration is asked for - * @return The full configuration or a subset. - */ - getConfiguration(section?: string, resource?: Uri): WorkspaceConfiguration; - - /** - * An event that is emitted when the [configuration](#WorkspaceConfiguration) changed. - */ - +onDidChangeConfiguration: Event; - - /** - * Register a task provider. - * - * @param type The task kind type this provider is registered for. - * @param provider A task provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerTaskProvider(type: string, provider: TaskProvider): Disposable; - - /** - * Register a filesystem provider for a given scheme, e.g. `ftp`. - * - * There can only be one provider per scheme and an error is being thrown when a scheme - * has been claimed by another provider or when it is reserved. - * - * @param scheme The uri-[scheme](#Uri.scheme) the provider registers for. - * @param provider The filesystem provider. - * @param options Immutable metadata about the provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerFileSystemProvider(scheme: string, provider: FileSystemProvider, options: { isCaseSensitive?: boolean }): Disposable; - - /* BEGIN PROPOSED *******************************************************************************/ - registerSearchProvider(scheme: string, provider: SearchProvider): Disposable; - - /** - * This method replaces `deleteCount` [workspace folders](#workspace.workspaceFolders) starting at index `start` - * by an optional set of `workspaceFoldersToAdd` on the `vscode.workspace.workspaceFolders` array. This "splice" - * behavior can be used to add, remove and change workspace folders in a single operation. - * - * If the first workspace folder is added, removed or changed, the currently executing extensions (including the - * one that called this method) will be terminated and restarted so that the (deprecated) `rootPath` property is - * updated to point to the first workspace folder. - * - * Use the [`onDidChangeWorkspaceFolders()`](#onDidChangeWorkspaceFolders) event to get notified when the - * workspace folders have been updated. - * - * **Example:** adding a new workspace folder at the end of workspace folders - * ```typescript - * workspace.updateWorkspaceFolders(workspace.workspaceFolders ? workspace.workspaceFolders.length : 0, null, { uri: ...}); - * ``` - * - * **Example:** removing the first workspace folder - * ```typescript - * workspace.updateWorkspaceFolders(0, 1); - * ``` - * - * **Example:** replacing an existing workspace folder with a new one - * ```typescript - * workspace.updateWorkspaceFolders(0, 1, { uri: ...}); - * ``` - * - * It is valid to remove an existing workspace folder and add it again with a different name - * to rename that folder. - * - * **Note:** it is not valid to call [updateWorkspaceFolders()](#updateWorkspaceFolders) multiple times - * without waiting for the [`onDidChangeWorkspaceFolders()`](#onDidChangeWorkspaceFolders) to fire. - * - * @param start the zero-based location in the list of currently opened [workspace folders](#WorkspaceFolder) - * from which to start deleting workspace folders. - * @param deleteCount the optional number of workspace folders to remove. - * @param workspaceFoldersToAdd the optional variable set of workspace folders to add in place of the deleted ones. - * Each workspace is identified with a mandatory URI and an optional name. - * @return true if the operation was successfully started and false otherwise if arguments were used that would result - * in invalid workspace folder state (e.g. 2 folders with the same URI). - */ - updateWorkspaceFolders(start: number, deleteCount: ?number, ...workspaceFoldersToAdd: { uri: Uri, name?: string }[]): boolean; - /* END PROPOSED *********************************************************************************/ - } - - /** - * An event describing the change in Configuration - */ - declare export interface ConfigurationChangeEvent { - - /** - * Returns `true` if the given section for the given resource (if provided) is affected. - * - * @param section Configuration name, supports _dotted_ names. - * @param resource A resource Uri. - * @return `true` if the given section for the given resource (if provided) is affected. - */ - affectsConfiguration(section: string, resource?: Uri): boolean; - } - - /** - * Namespace for participating in language-specific editor [features](https://code.visualstudio.com/docs/editor/editingevolved), - * like IntelliSense, code actions, diagnostics etc. - * - * Many programming languages exist and there is huge variety in syntaxes, semantics, and paradigms. Despite that, features - * like automatic word-completion, code navigation, or code checking have become popular across different tools for different - * programming languages. - * - * The editor provides an API that makes it simple to provide such common features by having all UI and actions already in place and - * by allowing you to participate by providing data only. For instance, to contribute a hover all you have to do is provide a function - * that can be called with a [TextDocument](#TextDocument) and a [Position](#Position) returning hover info. The rest, like tracking the - * mouse, positioning the hover, keeping the hover stable etc. is taken care of by the editor. - * - * ```javascript - * languages.registerHoverProvider('javascript', { - * provideHover(document, position, token) { - * return new Hover('I am a hover!'); - * } - * }); - * ``` - * - * Registration is done using a [document selector](#DocumentSelector) which is either a language id, like `javascript` or - * a more complex [filter](#DocumentFilter) like `{ language: 'typescript', scheme: 'file' }`. Matching a document against such - * a selector will result in a [score](#languages.match) that is used to determine if and how a provider shall be used. When - * scores are equal the provider that came last wins. For features that allow full arity, like [hover](#languages.registerHoverProvider), - * the score is only checked to be `>0`, for other features, like [IntelliSense](#languages.registerCompletionItemProvider) the - * score is used for determining the order in which providers are asked to participate. - */ - declare export var languages: { - - /** - * Return the identifiers of all known languages. - * @return Promise resolving to an array of identifier strings. - */ - getLanguages(): Thenable; - - /** - * Compute the match between a document [selector](#DocumentSelector) and a document. Values - * greater than zero mean the selector matches the document. - * - * A match is computed according to these rules: - * 1. When [`DocumentSelector`](#DocumentSelector) is an array, compute the match for each contained `DocumentFilter` or language identifier and take the maximum value. - * 2. A string will be desugared to become the `language`-part of a [`DocumentFilter`](#DocumentFilter), so `"fooLang"` is like `{ language: "fooLang" }`. - * 3. A [`DocumentFilter`](#DocumentFilter) will be matched against the document by comparing its parts with the document. The following rules apply: - * 1. When the `DocumentFilter` is empty (`{}`) the result is `0` - * 2. When `scheme`, `language`, or `pattern` are defined but one doesn’t match, the result is `0` - * 3. Matching against `*` gives a score of `5`, matching via equality or via a glob-pattern gives a score of `10` - * 4. The result is the maximun value of each match - * - * Samples: - * ```js - * // default document from disk (file-scheme) - * doc.uri; //'file:///my/file.js' - * doc.languageId; // 'javascript' - * match('javascript', doc); // 10; - * match({language: 'javascript'}, doc); // 10; - * match({language: 'javascript', scheme: 'file'}, doc); // 10; - * match('*', doc); // 5 - * match('fooLang', doc); // 0 - * match(['fooLang', '*'], doc); // 5 - * - * // virtual document, e.g. from git-index - * doc.uri; // 'git:/my/file.js' - * doc.languageId; // 'javascript' - * match('javascript', doc); // 10; - * match({language: 'javascript', scheme: 'git'}, doc); // 10; - * match('*', doc); // 5 - * ``` - * - * @param selector A document selector. - * @param document A text document. - * @return A number `>0` when the selector matches and `0` when the selector does not match. - */ - match(selector: DocumentSelector, document: TextDocument): number; - - /** - * Create a diagnostics collection. - * - * @param name The [name](#DiagnosticCollection.name) of the collection. - * @return A new diagnostic collection. - */ - createDiagnosticCollection(name?: string): DiagnosticCollection; - - /** - * Register a completion provider. - * - * Multiple providers can be registered for a language. In that case providers are sorted - * by their [score](#languages.match) and groups of equal score are sequentially asked for - * completion items. The process stops when one or many providers of a group return a - * result. A failing provider (rejected promise or exception) will not fail the whole - * operation. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider A completion provider. - * @param triggerCharacters Trigger completion when the user types one of the characters, like `.` or `:`. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerCompletionItemProvider(selector: DocumentSelector, provider: CompletionItemProvider, ...triggerCharacters: string[]): Disposable; - - /** - * Register a code action provider. - * - * Multiple providers can be registered for a language. In that case providers are asked in - * parallel and the results are merged. A failing provider (rejected promise or exception) will - * not cause a failure of the whole operation. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider A code action provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerCodeActionsProvider(selector: DocumentSelector, provider: CodeActionProvider): Disposable; - - /** - * Register a code lens provider. - * - * Multiple providers can be registered for a language. In that case providers are asked in - * parallel and the results are merged. A failing provider (rejected promise or exception) will - * not cause a failure of the whole operation. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider A code lens provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerCodeLensProvider(selector: DocumentSelector, provider: CodeLensProvider): Disposable; - - /** - * Register a definition provider. - * - * Multiple providers can be registered for a language. In that case providers are asked in - * parallel and the results are merged. A failing provider (rejected promise or exception) will - * not cause a failure of the whole operation. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider A definition provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerDefinitionProvider(selector: DocumentSelector, provider: DefinitionProvider): Disposable; - - /** - * Register an implementation provider. - * - * Multiple providers can be registered for a language. In that case providers are asked in - * parallel and the results are merged. A failing provider (rejected promise or exception) will - * not cause a failure of the whole operation. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider An implementation provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerImplementationProvider(selector: DocumentSelector, provider: ImplementationProvider): Disposable; - - /** - * Register a type definition provider. - * - * Multiple providers can be registered for a language. In that case providers are asked in - * parallel and the results are merged. A failing provider (rejected promise or exception) will - * not cause a failure of the whole operation. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider A type definition provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerTypeDefinitionProvider(selector: DocumentSelector, provider: TypeDefinitionProvider): Disposable; - - /** - * Register a hover provider. - * - * Multiple providers can be registered for a language. In that case providers are asked in - * parallel and the results are merged. A failing provider (rejected promise or exception) will - * not cause a failure of the whole operation. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider A hover provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerHoverProvider(selector: DocumentSelector, provider: HoverProvider): Disposable; - - /** - * Register a document highlight provider. - * - * Multiple providers can be registered for a language. In that case providers are sorted - * by their [score](#languages.match) and groups sequentially asked for document highlights. - * The process stops when a provider returns a `non-falsy` or `non-failure` result. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider A document highlight provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerDocumentHighlightProvider(selector: DocumentSelector, provider: DocumentHighlightProvider): Disposable; - - /** - * Register a document symbol provider. - * - * Multiple providers can be registered for a language. In that case providers are asked in - * parallel and the results are merged. A failing provider (rejected promise or exception) will - * not cause a failure of the whole operation. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider A document symbol provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerDocumentSymbolProvider(selector: DocumentSelector, provider: DocumentSymbolProvider): Disposable; - - /** - * Register a workspace symbol provider. - * - * Multiple providers can be registered. In that case providers are asked in parallel and - * the results are merged. A failing provider (rejected promise or exception) will not cause - * a failure of the whole operation. - * - * @param provider A workspace symbol provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerWorkspaceSymbolProvider(provider: WorkspaceSymbolProvider): Disposable; - - /** - * Register a reference provider. - * - * Multiple providers can be registered for a language. In that case providers are asked in - * parallel and the results are merged. A failing provider (rejected promise or exception) will - * not cause a failure of the whole operation. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider A reference provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerReferenceProvider(selector: DocumentSelector, provider: ReferenceProvider): Disposable; - - /** - * Register a reference provider. - * - * Multiple providers can be registered for a language. In that case providers are sorted - * by their [score](#languages.match) and the best-matching provider is used. Failure - * of the selected provider will cause a failure of the whole operation. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider A rename provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerRenameProvider(selector: DocumentSelector, provider: RenameProvider): Disposable; - - /** - * Register a formatting provider for a document. - * - * Multiple providers can be registered for a language. In that case providers are sorted - * by their [score](#languages.match) and the best-matching provider is used. Failure - * of the selected provider will cause a failure of the whole operation. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider A document formatting edit provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerDocumentFormattingEditProvider(selector: DocumentSelector, provider: DocumentFormattingEditProvider): Disposable; - - /** - * Register a formatting provider for a document range. - * - * *Note:* A document range provider is also a [document formatter](#DocumentFormattingEditProvider) - * which means there is no need to [register](registerDocumentFormattingEditProvider) a document - * formatter when also registering a range provider. - * - * Multiple providers can be registered for a language. In that case providers are sorted - * by their [score](#languages.match) and the best-matching provider is used. Failure - * of the selected provider will cause a failure of the whole operation. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider A document range formatting edit provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerDocumentRangeFormattingEditProvider(selector: DocumentSelector, provider: DocumentRangeFormattingEditProvider): Disposable; - - /** - * Register a formatting provider that works on type. The provider is active when the user enables the setting `editor.formatOnType`. - * - * Multiple providers can be registered for a language. In that case providers are sorted - * by their [score](#languages.match) and the best-matching provider is used. Failure - * of the selected provider will cause a failure of the whole operation. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider An on type formatting edit provider. - * @param firstTriggerCharacter A character on which formatting should be triggered, like `}`. - * @param moreTriggerCharacter More trigger characters. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerOnTypeFormattingEditProvider(selector: DocumentSelector, provider: OnTypeFormattingEditProvider, firstTriggerCharacter: string, ...moreTriggerCharacter: string[]): Disposable; - - /** - * Register a signature help provider. - * - * Multiple providers can be registered for a language. In that case providers are sorted - * by their [score](#languages.match) and called sequentially until a provider returns a - * valid result. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider A signature help provider. - * @param triggerCharacters Trigger signature help when the user types one of the characters, like `,` or `(`. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerSignatureHelpProvider(selector: DocumentSelector, provider: SignatureHelpProvider, ...triggerCharacters: string[]): Disposable; - - /** - * Register a document link provider. - * - * Multiple providers can be registered for a language. In that case providers are asked in - * parallel and the results are merged. A failing provider (rejected promise or exception) will - * not cause a failure of the whole operation. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider A document link provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerDocumentLinkProvider(selector: DocumentSelector, provider: DocumentLinkProvider): Disposable; - - /** - * Register a color provider. - * - * Multiple providers can be registered for a language. In that case providers are asked in - * parallel and the results are merged. A failing provider (rejected promise or exception) will - * not cause a failure of the whole operation. - * - * @param selector A selector that defines the documents this provider is applicable to. - * @param provider A color provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerColorProvider(selector: DocumentSelector, provider: DocumentColorProvider): Disposable; - - /** - * Set a [language configuration](#LanguageConfiguration) for a language. - * - * @param language A language identifier like `typescript`. - * @param configuration Language configuration. - * @return A [disposable](#Disposable) that unsets this configuration. - */ - setLanguageConfiguration(language: string, configuration: LanguageConfiguration): Disposable; - } - - /** - * Represents the input box in the Source Control viewlet. - */ - declare export interface SourceControlInputBox { - - /** - * Setter and getter for the contents of the input box. - */ - value: string; - - /** - * A string to show as place holder in the input box to guide the user. - */ - placeholder: string; - - /* BEGIN PROPOSED *******************************************************************************/ - /** - * A validation function for the input box. It's possible to change - * the validation provider simply by setting this property to a different function. - */ - +validateInput?: (value: string, cursorPosition: number) => ProviderResult; - /* END PROPOSED *********************************************************************************/ - } - - declare export interface QuickDiffProvider { - - /** - * Provide a [uri](#Uri) to the original resource of any given resource uri. - * - * @param uri The uri of the resource open in a text editor. - * @param token A cancellation token. - * @return A thenable that resolves to uri of the matching original resource. - */ - +provideOriginalResource?: (uri: Uri, token: CancellationToken) => ProviderResult; - } - - /** - * The theme-aware decorations for a - * [source control resource state](#SourceControlResourceState). - */ - declare export interface SourceControlResourceThemableDecorations { - - /** - * The icon path for a specific - * [source control resource state](#SourceControlResourceState). - */ - +iconPath?: string | Uri; - } - - /** - * The decorations for a [source control resource state](#SourceControlResourceState). - * Can be independently specified for light and dark themes. - */ - declare export interface SourceControlResourceDecorations extends SourceControlResourceThemableDecorations { - - /** - * Whether the [source control resource state](#SourceControlResourceState) should - * be striked-through in the UI. - */ - +strikeThrough?: boolean; - - /** - * Whether the [source control resource state](#SourceControlResourceState) should - * be faded in the UI. - */ - +faded?: boolean; - - /** - * The title for a specific - * [source control resource state](#SourceControlResourceState). - */ - +tooltip?: string; - - /** - * The light theme decorations. - */ - +light?: SourceControlResourceThemableDecorations; - - /** - * The dark theme decorations. - */ - +dark?: SourceControlResourceThemableDecorations; - - /* BEGIN PROPOSED *******************************************************************************/ - source?: string; - letter?: string; - color?: ThemeColor; - /* END PROPOSED *********************************************************************************/ - } - - /** - * An source control resource state represents the state of an underlying workspace - * resource within a certain [source control group](#SourceControlResourceGroup). - */ - declare export interface SourceControlResourceState { - - /** - * The [uri](#Uri) of the underlying resource inside the workspace. - */ - +resourceUri: Uri; - - /** - * The [command](#Command) which should be run when the resource - * state is open in the Source Control viewlet. - */ - +command?: Command; - - /** - * The [decorations](#SourceControlResourceDecorations) for this source control - * resource state. - */ - +decorations?: SourceControlResourceDecorations; - } - - /** - * A source control resource group is a collection of - * [source control resource states](#SourceControlResourceState). - */ - declare export interface SourceControlResourceGroup { - - /** - * The id of this source control resource group. - */ - +id: string; - - /** - * The label of this source control resource group. - */ - label: string; - - /** - * Whether this source control resource group is hidden when it contains - * no [source control resource states](#SourceControlResourceState). - */ - hideWhenEmpty?: boolean; - - /** - * This group's collection of - * [source control resource states](#SourceControlResourceState). - */ - resourceStates: SourceControlResourceState[]; - - /** - * Dispose this source control resource group. - */ - dispose(): void; - } - - /** - * An source control is able to provide [resource states](#SourceControlResourceState) - * to the editor and interact with the editor in several source control related ways. - */ - declare export interface SourceControl { - - /** - * The id of this source control. - */ - +id: string; - - /** - * The human-readable label of this source control. - */ - +label: string; - - /** - * The (optional) Uri of the root of this source control. - */ - +rootUri: ?Uri; - - /** - * The [input box](#SourceControlInputBox) for this source control. - */ - +inputBox: SourceControlInputBox; - - /** - * The UI-visible count of [resource states](#SourceControlResourceState) of - * this source control. - * - * Equals to the total number of [resource state](#SourceControlResourceState) - * of this source control, if undefined. - */ - count?: number; - - /** - * An optional [quick diff provider](#QuickDiffProvider). - */ - quickDiffProvider?: QuickDiffProvider; - - /** - * Optional commit template string. - * - * The Source Control viewlet will populate the Source Control - * input with this value when appropriate. - */ - commitTemplate?: string; - - /** - * Optional accept input command. - * - * This command will be invoked when the user accepts the value - * in the Source Control input. - */ - acceptInputCommand?: Command; - - /** - * Optional status bar commands. - * - * These commands will be displayed in the editor's status bar. - */ - statusBarCommands?: Command[]; - - /** - * Create a new [resource group](#SourceControlResourceGroup). - */ - createResourceGroup(id: string, label: string): SourceControlResourceGroup; - - /** - * Dispose this source control. - */ - dispose(): void; - } - - declare export var scm: { - - /** - * Creates a new [source control](#SourceControl) instance. - * - * @param id An `id` for the source control. Something short, eg: `git`. - * @param label A human-readable string for the source control. Eg: `Git`. - * @param rootUri An optional Uri of the root of the source control. Eg: `Uri.parse(workspaceRoot)`. - * @return An instance of [source control](#SourceControl). - */ - createSourceControl(id: string, label: string, rootUri?: Uri): SourceControl; - } - - /** - * Configuration for a debug session. - */ - declare export interface DebugConfiguration { - /** - * The type of the debug session. - */ - type: string; - - /** - * The name of the debug session. - */ - name: string; - - /** - * The request type of the debug session. - */ - request: string; - - /** - * Port of a debugger running locally. If set, VS Code will attempt to - * connect to 127.0.0.1 on this port instead of trying to spawn the debugger - * process itself. - */ - debugServer?: number; - - /** - * Additional debug type specific properties. - */ - [key: string]: any; - } - - /** - * A debug session. - */ - declare export interface DebugSession { - - /** - * The unique ID of this debug session. - */ - +id: string; - - /** - * The debug session's type from the [debug configuration](#DebugConfiguration). - */ - +type: string; - - /** - * The debug session's name from the [debug configuration](#DebugConfiguration). - */ - +name: string; - - /** - * Send a custom request to the debug adapter. - */ - customRequest(command: string, args?: any): Thenable; - } - - /** - * A custom Debug Adapter Protocol event received from a [debug session](#DebugSession). - */ - declare export interface DebugSessionCustomEvent { - /** - * The [debug session](#DebugSession) for which the custom event was received. - */ - session: DebugSession; - - /** - * Type of event. - */ - event: string; - - /** - * Event specific information. - */ - body?: any; - } - - /** - * A debug configuration provider allows to add the initial debug configurations to a newly created launch.json - * and to resolve a launch configuration before it is used to start a new debug session. - * A debug configuration provider is registered via #debug.registerDebugConfigurationProvider. - */ - declare export interface DebugConfigurationProvider { - /** - * Provides initial [debug configuration](#DebugConfiguration). If more than one debug configuration provider is - * registered for the same type, debug configurations are concatenated in arbitrary order. - * - * @param folder The workspace folder for which the configurations are used or undefined for a folderless setup. - * @param token A cancellation token. - * @return An array of [debug configurations](#DebugConfiguration). - */ - +provideDebugConfigurations?: (folder: ?WorkspaceFolder, token?: CancellationToken) => ProviderResult; - - /** - * Resolves a [debug configuration](#DebugConfiguration) by filling in missing values or by adding/changing/removing attributes. - * If more than one debug configuration provider is registered for the same type, the resolveDebugConfiguration calls are chained - * in arbitrary order and the initial debug configuration is piped through the chain. - * Returning the value 'undefined' prevents the debug session from starting. - * - * @param folder The workspace folder from which the configuration originates from or undefined for a folderless setup. - * @param debugConfiguration The [debug configuration](#DebugConfiguration) to resolve. - * @param token A cancellation token. - * @return The resolved debug configuration or undefined. - */ - +resolveDebugConfiguration?: (folder: ?WorkspaceFolder, debugConfiguration: DebugConfiguration, token?: CancellationToken) => ProviderResult; - - /* BEGIN PROPOSED *******************************************************************************/ - /** - * This optional method is called just before a debug adapter is started to determine its excutable path and arguments. - * Registering more than one debugAdapterExecutable for a type results in an error. - * @param folder The workspace folder from which the configuration originates from or undefined for a folderless setup. - * @param token A cancellation token. - * @return a [debug adapter's executable and optional arguments](#DebugAdapterExecutable) or undefined. - */ - +debugAdapterExecutable?: (folder: ?WorkspaceFolder, token?: CancellationToken) => ProviderResult; - /* END PROPOSED *********************************************************************************/ - - } - - /** - * Represents the debug console. - */ - declare export interface DebugConsole { - /** - * Append the given value to the debug console. - * - * @param value A string, falsy values will not be printed. - */ - append(value: string): void; - - /** - * Append the given value and a line feed character - * to the debug console. - * - * @param value A string, falsy values will be printed. - */ - appendLine(value: string): void; - } - - /** - * Namespace for dealing with debug sessions. - */ - declare export var debug: { - - /** - * The currently active [debug session](#DebugSession) or `undefined`. The active debug session is the one - * represented by the debug action floating window or the one currently shown in the drop down menu of the debug action floating window. - * If no debug session is active, the value is `undefined`. - */ - activeDebugSession: ?DebugSession; - - /** - * The currently active [debug console](#DebugConsole). - */ - activeDebugConsole: DebugConsole; - - /** - * List of breakpoints. - */ - breakpoints: Breakpoint[]; - - /** - * An [event](#Event) which fires when the [active debug session](#debug.activeDebugSession) - * has changed. *Note* that the event also fires when the active debug session changes - * to `undefined`. - */ - +onDidChangeActiveDebugSession: Event; - - /** - * An [event](#Event) which fires when a new [debug session](#DebugSession) has been started. - */ - +onDidStartDebugSession: Event; - - /** - * An [event](#Event) which fires when a custom DAP event is received from the [debug session](#DebugSession). - */ - +onDidReceiveDebugSessionCustomEvent: Event; - - /** - * An [event](#Event) which fires when a [debug session](#DebugSession) has terminated. - */ - +onDidTerminateDebugSession: Event; - - /** - * An event that is emitted when a breakpoint is added, removed, or changed. - */ - +onDidChangeBreakpoints: Event; - - /** - * Register a [debug configuration provider](#DebugConfigurationProvider) for a specifc debug type. - * More than one provider can be registered for the same type. - * - * @param type The debug type for which the provider is registered. - * @param provider The [debug configuration provider](#DebugConfigurationProvider) to register. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. - */ - registerDebugConfigurationProvider(debugType: string, provider: DebugConfigurationProvider): Disposable; - - /** - * Start debugging by using either a named launch or named compound configuration, - * or by directly passing a [DebugConfiguration](#DebugConfiguration). - * The named configurations are looked up in '.vscode/launch.json' found in the given folder. - * Before debugging starts, all unsaved files are saved and the launch configurations are brought up-to-date. - * Folder specific variables used in the configuration (e.g. '${workspaceFolder}') are resolved against the given folder. - * @param folder The [workspace folder](#WorkspaceFolder) for looking up named configurations and resolving variables or `undefined` for a non-folder setup. - * @param nameOrConfiguration Either the name of a debug or compound configuration or a [DebugConfiguration](#DebugConfiguration) object. - * @return A thenable that resolves when debugging could be successfully started. - */ - startDebugging(folder: ?WorkspaceFolder, nameOrConfiguration: string | DebugConfiguration): Thenable; - - /** - * Add breakpoints. - * @param breakpoints The breakpoints to add. - */ - addBreakpoints(breakpoints: Breakpoint[]): void; - - /** - * Remove breakpoints. - * @param breakpoints The breakpoints to remove. - */ - removeBreakpoints(breakpoints: Breakpoint[]): void; - } - - /** - * Namespace for dealing with installed extensions. Extensions are represented - * by an [extension](#Extension)-interface which allows to reflect on them. - * - * Extension writers can provide APIs to other extensions by returning their API public - * surface from the `activate`-call. - * - * ```javascript - * export function activate(context: vscode.ExtensionContext) { - * let api = { - * sum(a, b) { - * return a + b; - * }, - * mul(a, b) { - * return a * b; - * } - * }; - * // 'export' public api-surface - * return api; - * } - * ``` - * When depending on the API of another extension add an `extensionDependency`-entry - * to `package.json`, and use the [getExtension](#extensions.getExtension)-function - * and the [exports](#Extension.exports)-property, like below: - * - * ```javascript - * let mathExt = extensions.getExtension('genius.math'); - * let importedApi = mathExt.exports; - * - * console.log(importedApi.mul(42, 1)); - * ``` - */ - declare export var extensions: { - - /** - * Get an extension by its full identifier in the form of: `publisher.name`. - * - * @param extensionId An extension identifier. - * @return An extension or `undefined`. - */ - getExtension(extensionId: string): ?Extension; - - /** - * Get an extension its full identifier in the form of: `publisher.name`. - * - * @param extensionId An extension identifier. - * @return An extension or `undefined`. - */ - getExtension(extensionId: string): ?Extension; - - /** - * All extensions currently known to the system. - */ - all: Extension[]; - } - - /** - * Enumeration of file types. - */ - declare export var FileType: { - /** - * The file type is unknown. - */ - Unknown: 0, - /** - * A regular file. - */ - File: 1, - /** - * A directory. - */ - Directory: 2, - /** - * A symbolic link to a file. - */ - SymbolicLink: 64 - } - declare export type FileTypeType = $Values; - - /** - * The `FileStat`-type represents metadata about a file. - */ - declare export type FileStat = { - /** - * The type of the file, e.g. is a regular file, a directory, or symbolic link - * to a file. - */ - type: FileTypeType; - - /** - * The creation timestamp in milliseconds. - */ - ctime: number; - - /** - * The modification timestamp in milliseconds. - */ - mtime: number; - - /** - * The size in bytes. - */ - size: number; - } - - /** - * A type that filesystem providers should use to signal errors. - * - * This class has factory methods for common error-cases, like `EntryNotFound` when - * a file or folder doesn't exist, use them like so: `throw vscode.FileSystemError.EntryNotFound(someUri);` - */ - declare export class FileSystemError extends Error { - /** - * Create an error to signal that a file or folder wasn't found. - * @param messageOrUri Message or uri. - */ - static FileNotFound(messageOrUri?: string | Uri): FileSystemError; - - /** - * Create an error to signal that a file or folder already exists, e.g. when - * creating but not overwriting a file. - * @param messageOrUri Message or uri. - */ - static FileExists(messageOrUri?: string | Uri): FileSystemError; - - /** - * Create an error to signal that a file is not a folder. - * @param messageOrUri Message or uri. - */ - static FileNotADirectory(messageOrUri?: string | Uri): FileSystemError; - - /** - * Create an error to signal that a file is a folder. - * @param messageOrUri Message or uri. - */ - static FileIsADirectory(messageOrUri?: string | Uri): FileSystemError; - - /** - * Create an error to signal that an operation lacks required permissions. - * @param messageOrUri Message or uri. - */ - static NoPermissions(messageOrUri?: string | Uri): FileSystemError; - - /** - * Create an error to signal that the file system is unavailable or too busy to - * complete a request. - * @param messageOrUri Message or uri. - */ - static Unavailable(messageOrUri?: string | Uri): FileSystemError; - - /** - * Creates a new filesystem error. - * - * @param messageOrUri Message or uri. - */ - constructor(messageOrUri?: string | Uri) : void; - } - - declare export var FileChangeType: { - Changed: 1, - Created: 2, - Deleted: 3 - } - declare export type FileChangeTypeType = $Values; - - /** - * The event filesystem providers must use to signal a file change. - */ - declare export interface FileChangeEvent { - /** - * The type of change. - */ - type: FileChangeTypeType; - - /** - * The uri of the file that has changed. - */ - uri: Uri; - } - - /** - * The filesystem provider defines what the editor needs to read, write, discover, - * and to manage files and folders. It allows extensions to serve files from remote places, - * like ftp-servers, and to seamlessly integrate those into the editor. - * - * * *Note 1:* The filesystem provider API works with [uris](#Uri) and assumes hierarchical - * paths, e.g. `foo:/my/path` is a child of `foo:/my/` and a parent of `foo:/my/path/deeper`. - * * *Note 2:* There is an activation event `onFileSystem:` that fires when a file - * or folder is being accessed. - * - */ - declare export interface FileSystemProvider { - - /** - * An event to signal that a resource has been created, changed, or deleted. This - * event should fire for resources that are being [watched](#FileSystemProvider.watch) - * by clients of this provider. - */ - +onDidChangeFile: Event; - - /** - * Subscribe to events in the file or folder denoted by `uri`. - * @param uri The uri of the file to be watched. - * @param options Configures the watch. - * @returns A disposable that tells the provider to stop watching this `uri`. - */ - watch(uri: Uri, options: { recursive: boolean; excludes: string[] }): Disposable; - - /** - * Retrieve metadata about a file. - * - * @param uri The uri of the file to retrieve meta data about. - * @return The file metadata about the file. - * @throws [`FileNotFound`](#FileSystemError.FileNotFound) when `uri` doesn't exist. - */ - stat(uri: Uri): FileStat | Thenable; - - /** - * Retrieve the meta data of all entries of a [directory](#FileType.Directory) - * - * @param uri The uri of the folder. - * @return An array of name/type-tuples or a thenable that resolves to such. - * @throws [`FileNotFound`](#FileSystemError.FileNotFound) when `uri` doesn't exist. - */ - readDirectory(uri: Uri): [string, FileTypeType][] | Thenable<[string, FileTypeType][]>; - - /** - * Create a new directory. *Note* that new files are created via `write`-calls. - * - * @param uri The uri of the new folder. - * @returns Metadata about the created directory or a thenable that resolves to such. - * @throws [`FileNotFound`](#FileSystemError.FileNotFound) when the parent of `uri` doesn't exist. - * @throws [`FileExists`](#FileSystemError.FileExists) when `uri` already exists. - * @throws [`NoPermissions`](#FileSystemError.NoPermissions) when permissions aren't sufficient. - */ - createDirectory(uri: Uri): void | Thenable; - - /** - * Read the entire contents of a file. - * - * @param uri The uri of the file. - * @return An array of bytes or a thenable that resolves to such. - * @throws [`FileNotFound`](#FileSystemError.FileNotFound) when `uri` doesn't exist. - */ - readFile(uri: Uri): Uint8Array | Thenable; - - /** - * Write data to a file, replacing its entire contents. - * - * @param uri The uri of the file. - * @param content The new content of the file. - * @param options Defines is missing files should or must be created. - * @throws [`FileNotFound`](#FileSystemError.FileNotFound) when `uri` doesn't exist and `create` is not set. - * @throws [`FileNotFound`](#FileSystemError.FileNotFound) when the parent of `uri` doesn't exist and `create` is set. - * @throws [`FileExists`](#FileSystemError.FileExists) when `uri` already exists and `overwrite` is set. - * @throws [`NoPermissions`](#FileSystemError.NoPermissions) when permissions aren't sufficient. - */ - writeFile(uri: Uri, content: Uint8Array, options: { create: boolean, overwrite: boolean }): void | Thenable; - - /** - * Delete a file. - * - * @param uri The resource that is to be deleted. - * @param options Defines if deletion of folders is recursive. - * @throws [`FileNotFound`](#FileSystemError.FileNotFound) when `uri` doesn't exist. - * @throws [`NoPermissions`](#FileSystemError.NoPermissions) when permissions aren't sufficient. - */ - delete(uri: Uri, options: { recursive: boolean }): void | Thenable; - - /** - * Rename a file or folder. - * - * @param oldUri The existing file or folder. - * @param newUri The target location. - * @param options Defines if existing files should be overwriten. - * @returns Metadata about the renamed file or a thenable that resolves to such. - * @throws [`FileNotFound`](#FileSystemError.FileNotFound) when `oldUri` doesn't exist. - * @throws [`FileNotFound`](#FileSystemError.FileNotFound) when parent of `newUri` doesn't exist - * @throws [`FileExists`](#FileSystemError.FileExists) when `newUri` exists and when the `overwrite` option is not `true`. - * @throws [`NoPermissions`](#FileSystemError.NoPermissions) when permissions aren't sufficient. - */ - rename(oldUri: Uri, newUri: Uri, options: { overwrite: boolean }): void | Thenable; - - /** - * Copy files or folders. Implementing this function is optional but it will speedup - * the copy operation. - * - * @param source The existing file or folder. - * @param destination The destination location. - * @param options Defines if existing files should be overwriten. - * @returns Metadata about the copied file or a thenable that resolves to such. - * @throws [`FileNotFound`](#FileSystemError.FileNotFound) when `source` doesn't exist - * @throws [`FileNotFound`](#FileSystemError.FileNotFound) when parent of `destination` doesn't exist - * @throws [`FileExists`](#FileSystemError.FileExists) when `destination` exists and when the `overwrite` option is not `true`. - * @throws [`NoPermissions`](#FileSystemError.NoPermissions) when permissions aren't sufficient. - */ - +copy?: (source: Uri, destination: Uri, options: { overwrite: boolean }) => void | Thenable; - } - - /* BEGIN PROPOSED *******************************************************************************/ - declare export interface TextSearchQuery { - pattern: string; - isRegExp?: boolean; - isCaseSensitive?: boolean; - isWordMatch?: boolean; - } - - declare export interface TextSearchOptions { - includes: GlobPattern[]; - excludes: GlobPattern[]; - } - - declare export interface TextSearchResult { - uri: Uri; - range: Range; - preview: { leading: string, matching: string, trailing: string }; - } - - declare export interface SearchProvider { - +provideFileSearchResults?: (query: string, progress: Progress, token: CancellationToken) => Thenable; - +provideTextSearchResults?: (query: TextSearchQuery, options: TextSearchOptions, progress: Progress, token: CancellationToken) => Thenable; - } - - /** - * The contiguous set of modified lines in a diff. - */ - declare export interface LineChange { - +originalStartLineNumber: number; - +originalEndLineNumber: number; - +modifiedStartLineNumber: number; - +modifiedEndLineNumber: number; - } - - //#region decorations - //todo@joh -> make class - declare export interface DecorationData { - priority?: number; - title?: string; - bubble?: boolean; - abbreviation?: string; - color?: ThemeColor; - source?: string; - } - - declare export interface DecorationProvider { - onDidChangeDecorations: Event; - provideDecoration(uri: Uri, token: CancellationToken): ProviderResult; - } - - /** - * An event describing a change to the set of [breakpoints](#debug.Breakpoint). - */ - declare export interface BreakpointsChangeEvent { - /** - * Added breakpoints. - */ - +added: Breakpoint[]; - - /** - * Removed breakpoints. - */ - +removed: Breakpoint[]; - - /** - * Changed breakpoints. - */ - +changed: Breakpoint[]; - } - - /** - * The base class of all breakpoint types. - */ - declare export class Breakpoint { - /** - * Is breakpoint enabled. - */ - +enabled: boolean; - /** - * An optional expression for conditional breakpoints. - */ - +condition?: string; - /** - * An optional expression that controls how many hits of the breakpoint are ignored. - */ - +hitCondition?: string; - - // protected constructor(enabled?: boolean, condition?: string, hitCondition?: string); - } - - /** - * A breakpoint specified by a source location. - */ - declare export class SourceBreakpoint extends Breakpoint { - /** - * The source and line position of this breakpoint. - */ - +location: Location; - - /** - * Create a new breakpoint for a source location. - */ - constructor(location: Location, enabled?: boolean, condition?: string, hitCondition?: string): void; - } - - /** - * A breakpoint specified by a function name. - */ - declare export class FunctionBreakpoint extends Breakpoint { - /** - * The name of the function to which this breakpoint is attached. - */ - +functionName: string; - - /** - * Create a new function breakpoint. - */ - constructor(functionName: string, enabled?: boolean, condition?: string, hitCondition?: string): void; - } - - /** - * Represents a debug adapter executable and optional arguments passed to it. - */ - declare export class DebugAdapterExecutable { - /** - * The command path of the debug adapter executable. - * A command must be either an absolute path or the name of an executable looked up via the PATH environment variable. - * The special value 'node' will be mapped to VS Code's built-in node runtime. - */ - +command: string; - - /** - * Optional arguments passed to the debug adapter executable. - */ - +args: string[]; - - /** - * Create a new debug adapter specification. - */ - constructor(command: string, args?: string[]): void; - } - - /** - * The severity level of a log message - */ - declare export var LogLevel: { - Trace: 1, - Debug: 2, - Info: 3, - Warning: 4, - Error: 5, - Critical: 6, - Off: 7 - } - declare export type LogLevelType = $Values; - - /** - * A logger for writing to an extension's log file, and accessing its dedicated log directory. - */ - declare export interface Logger { - +onDidChangeLogLevel: Event; - +currentLevel: LogLevelType; - +logDirectory: Thenable; - - trace(message: string, ...args: any[]): void; - debug(message: string, ...args: any[]): void; - info(message: string, ...args: any[]): void; - warn(message: string, ...args: any[]): void; - error(message: string | Error, ...args: any[]): void; - critical(message: string | Error, ...args: any[]): void; - } - - declare export interface RenameInitialValue { - range: Range; - text?: string; - } - - /** - * Represents the validation type of the Source Control input. - */ - declare export var SourceControlInputBoxValidationType: { - - /** - * Something not allowed by the rules of a language or other means. - */ - Error: 0, - - /** - * Something suspicious but allowed. - */ - Warning: 1, - - /** - * Something to inform about but not a problem. - */ - Information: 2 - } - declare export type SourceControlInputBoxValidationTypeType = $Values; - - declare export interface SourceControlInputBoxValidation { - - /** - * The validation message to display. - */ - +message: string; - - /** - * The validation type. - */ - +type: SourceControlInputBoxValidationTypeType; - } - /* END PROPOSED *********************************************************************************/ - -} - -/** - * Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise, - * and others. This API makes no assumption about what promise libary is being used which - * enables reusing existing code without migrating to a specific promise implementation. Still, - * we recommend the use of native promises which are available in this editor. - */ -declare type Thenable = Promise; diff --git a/flow-libs/ws.js.flow b/flow-libs/ws.js.flow deleted file mode 100644 index b6763550f9..0000000000 --- a/flow-libs/ws.js.flow +++ /dev/null @@ -1,53 +0,0 @@ -/** - * 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 - */ - -/** - * https://github.com/websockets/ws/blob/master/doc/ws.md - */ - -declare module 'ws' { - declare class ws$Server extends events$EventEmitter { - // TODO properly type the options object - constructor(options: Object): void, - close(): void, - } - - declare class ws$WebSocket extends events$EventEmitter { - constructor( - address: string | Array, - options?: ?Object, - ): ws$WebSocket, - constructor( - address: string, - protocols: string | Array, - options: Object, - ): ws$WebSocket, - static Server: typeof ws$Server, - - onopen?: () => mixed, - onclose?: () => mixed, - onerror?: () => mixed, - - send(message: string | Buffer, ack?: (error: ?Object) => void): void, - send( - message: string | Buffer, - options: Object, - ack: (error: ?Object) => void, - ): void, - close(): void, - close(statusCode: number, message: string): void, - terminate(): void, - ping(data: ?string, mask?: boolean, failSilently?: boolean): void, - url: string, - } - - declare module.exports: typeof ws$WebSocket; -} diff --git a/flow-typed/README.md b/flow-typed/README.md deleted file mode 100644 index 66f90f9a56..0000000000 --- a/flow-typed/README.md +++ /dev/null @@ -1,14 +0,0 @@ -## flow-typed - -The definitions under the `npm` folder here are pulled down from -[`flow-typed`](https://github.com/flowtype/flow-typed). Please do not change these files directly. - -### Updating these definitions - -1. Put up a pull request on [`flow-typed`](https://github.com/flowtype/flow-typed) with the proposed changes. Include tests. -2. Once it's merged, update the files here by either bothering @nmote, or - - `npm install -g flow-typed` (as of this writing, it's in beta so you will need to install `flow-typed@2.0.0-beta4` to get the CLI). - - `flow-typed install packageName -f flowVersion -o`, where: - - `packageName` is the name of the package (e.g. `classnames` or `rxjs`) - - `flowVersion` is the Flow version we are currently using e.g. `0.25.0` - - `-o` just indicates the the existing defs should be overwritten diff --git a/flow-typed/npm/chalk_v1.x.x.js b/flow-typed/npm/chalk_v1.x.x.js deleted file mode 100644 index 9cabf16bcd..0000000000 --- a/flow-typed/npm/chalk_v1.x.x.js +++ /dev/null @@ -1,114 +0,0 @@ -// flow-typed signature: b1a2d646047879188d7e44cb218212b5 -// flow-typed version: b43dff3e0e/chalk_v1.x.x/flow_>=v0.19.x - -type $npm$chalk$StyleElement = { - open: string; - close: string; -}; - -type $npm$chalk$Chain = $npm$chalk$Style & (...text: any[]) => string; - -type $npm$chalk$Style = { - // General - reset: $npm$chalk$Chain; - bold: $npm$chalk$Chain; - dim: $npm$chalk$Chain; - italic: $npm$chalk$Chain; - underline: $npm$chalk$Chain; - inverse: $npm$chalk$Chain; - strikethrough: $npm$chalk$Chain; - - // Text colors - black: $npm$chalk$Chain; - red: $npm$chalk$Chain; - green: $npm$chalk$Chain; - yellow: $npm$chalk$Chain; - blue: $npm$chalk$Chain; - magenta: $npm$chalk$Chain; - cyan: $npm$chalk$Chain; - white: $npm$chalk$Chain; - gray: $npm$chalk$Chain; - grey: $npm$chalk$Chain; - - // Background colors - bgBlack: $npm$chalk$Chain; - bgRed: $npm$chalk$Chain; - bgGreen: $npm$chalk$Chain; - bgYellow: $npm$chalk$Chain; - bgBlue: $npm$chalk$Chain; - bgMagenta: $npm$chalk$Chain; - bgCyan: $npm$chalk$Chain; - bgWhite: $npm$chalk$Chain; -}; - -type $npm$chalk$StyleMap = { - // General - reset: $npm$chalk$StyleElement; - bold: $npm$chalk$StyleElement; - dim: $npm$chalk$StyleElement; - italic: $npm$chalk$StyleElement; - underline: $npm$chalk$StyleElement; - inverse: $npm$chalk$StyleElement; - strikethrough: $npm$chalk$StyleElement; - - // Text colors - black: $npm$chalk$StyleElement; - red: $npm$chalk$StyleElement; - green: $npm$chalk$StyleElement; - yellow: $npm$chalk$StyleElement; - blue: $npm$chalk$StyleElement; - magenta: $npm$chalk$StyleElement; - cyan: $npm$chalk$StyleElement; - white: $npm$chalk$StyleElement; - gray: $npm$chalk$StyleElement; - - // Background colors - bgBlack: $npm$chalk$StyleElement; - bgRed: $npm$chalk$StyleElement; - bgGreen: $npm$chalk$StyleElement; - bgYellow: $npm$chalk$StyleElement; - bgBlue: $npm$chalk$StyleElement; - bgMagenta: $npm$chalk$StyleElement; - bgCyan: $npm$chalk$StyleElement; - bgWhite: $npm$chalk$StyleElement; -}; - -declare module "chalk" { - declare var enabled: boolean; - declare var supportsColor: boolean; - declare var styles: $npm$chalk$StyleMap; - - declare function stripColor(value: string): any; - declare function hasColor(str: string): boolean; - - // General - declare var reset: $npm$chalk$Chain; - declare var bold: $npm$chalk$Chain; - declare var dim: $npm$chalk$Chain; - declare var italic: $npm$chalk$Chain; - declare var underline: $npm$chalk$Chain; - declare var inverse: $npm$chalk$Chain; - declare var strikethrough: $npm$chalk$Chain; - - // Text colors - declare var black: $npm$chalk$Chain; - declare var red: $npm$chalk$Chain; - declare var green: $npm$chalk$Chain; - declare var yellow: $npm$chalk$Chain; - declare var blue: $npm$chalk$Chain; - declare var magenta: $npm$chalk$Chain; - declare var cyan: $npm$chalk$Chain; - declare var white: $npm$chalk$Chain; - declare var gray: $npm$chalk$Chain; - declare var grey: $npm$chalk$Chain; - - // Background colors - declare var bgBlack: $npm$chalk$Chain; - declare var bgRed: $npm$chalk$Chain; - declare var bgGreen: $npm$chalk$Chain; - declare var bgYellow: $npm$chalk$Chain; - declare var bgBlue: $npm$chalk$Chain; - declare var bgMagenta: $npm$chalk$Chain; - declare var bgCyan: $npm$chalk$Chain; - declare var bgWhite: $npm$chalk$Chain; -} diff --git a/flow-typed/npm/classnames_v2.x.x.js b/flow-typed/npm/classnames_v2.x.x.js deleted file mode 100644 index 7dae310a97..0000000000 --- a/flow-typed/npm/classnames_v2.x.x.js +++ /dev/null @@ -1,22 +0,0 @@ -// flow-typed signature: 24cdb511d3752119d012d31eab9e5c8d -// flow-typed version: 7a7121569e/classnames_v2.x.x/flow_>=v0.25.x - -type $npm$classnames$Classes = - | string - | { [className: string]: * } - | Array - | false - | void - | null; - -declare module 'classnames' { - declare module.exports: (...classes: Array<$npm$classnames$Classes>) => string; -} - -declare module 'classnames/bind' { - declare module.exports: $Exports<'classnames'>; -} - -declare module 'classnames/dedupe' { - declare module.exports: $Exports<'classnames'>; -} diff --git a/flow-typed/npm/dedent_v0.7.x.js b/flow-typed/npm/dedent_v0.7.x.js deleted file mode 100644 index 65595397d8..0000000000 --- a/flow-typed/npm/dedent_v0.7.x.js +++ /dev/null @@ -1,11 +0,0 @@ -// flow-typed signature: 097b2887f219dba3f2df79cfe16c063b -// flow-typed version: d4e3edcf09/dedent_v0.7.x/flow_>=v0.25.x - -// @flow - -declare module 'dedent' { - declare module.exports: ( - strings: string | Array, - ...values: Array - ) => string; -} diff --git a/flow-typed/npm/double-ended-queue_v2.1.x.js b/flow-typed/npm/double-ended-queue_v2.1.x.js deleted file mode 100644 index adb7f3b85a..0000000000 --- a/flow-typed/npm/double-ended-queue_v2.1.x.js +++ /dev/null @@ -1,29 +0,0 @@ -declare module "double-ended-queue" { - declare export default class Deque { - length: number, - - constructor(capacity?: number | Array | void): Deque, - - toArray: () => Array, - push: (item: T) => number, - pop: () => ?T, - shift: () => ?T, - unshift: (item: T) => number, - peekBack: () => ?T, - peekFront: () => ?T, - get: (index: number) => ?T, - isEmpty: () => boolean, - clear: () => void, - toString: () => string, - - // aliases - valueOf: () => string, // toString - removeFront: () => ?T, // shift - removeBack: () => ?T, // pop - insertFront: (item: T) => number, // unshift - insertBack: (item: T) => number, // push - enqueue: (item: T) => number, // push - dequeue: () => ?T, // shift - toJSON: () => Array // toArray - } -} diff --git a/flow-typed/npm/escape-html_v1.x.x.js b/flow-typed/npm/escape-html_v1.x.x.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/flow-typed/npm/escape-string-regexp_v1.x.x.js b/flow-typed/npm/escape-string-regexp_v1.x.x.js deleted file mode 100644 index b2842c27b3..0000000000 --- a/flow-typed/npm/escape-string-regexp_v1.x.x.js +++ /dev/null @@ -1,6 +0,0 @@ -// flow-typed signature: ed810fce1a8248c9f857e4b34ac68c14 -// flow-typed version: 94e9f7e0a4/escape-string-regexp_v1.x.x/flow_>=v0.28.x - -declare module 'escape-string-regexp' { - declare module.exports: (input: string) => string; -} diff --git a/flow-typed/npm/flow-bin_v0.x.x.js b/flow-typed/npm/flow-bin_v0.x.x.js deleted file mode 100644 index c538e2086f..0000000000 --- a/flow-typed/npm/flow-bin_v0.x.x.js +++ /dev/null @@ -1,6 +0,0 @@ -// flow-typed signature: 6a5610678d4b01e13bbfbbc62bdaf583 -// flow-typed version: 3817bc6980/flow-bin_v0.x.x/flow_>=v0.25.x - -declare module "flow-bin" { - declare module.exports: string; -} diff --git a/flow-typed/npm/idb-keyval_v2.x.x.js b/flow-typed/npm/idb-keyval_v2.x.x.js deleted file mode 100644 index 40580bfed1..0000000000 --- a/flow-typed/npm/idb-keyval_v2.x.x.js +++ /dev/null @@ -1,25 +0,0 @@ -// flow-typed signature: 57ecb560d39f9264e4d18131dd961c8b -// flow-typed version: d679eeac2f/idb-keyval_v2.x.x/flow_>=v0.34.x - -// Derived from TS typings at https://github.com/jakearchibald/idb-keyval/blob/b49b4e9fbf2f5deb63598f9cf0d9899d2f89dc95/typings.d.ts - -declare module 'idb-keyval' { - declare interface IDBKeyVal { - /** Add a new value or update an existing one */ - set(key: Key, value: Value): Promise, - - /** Get a value by key */ - get(key: Key): Promise, - - /** Get all keys in the database */ - keys(): Promise>, - - /** Delete an entry in the database by key */ - delete(key: Key): Promise, - - /** Delete all entries in the database */ - clear(): Promise, - } - - declare module.exports: IDBKeyVal; -} diff --git a/flow-typed/npm/idb_v2.x.x.js b/flow-typed/npm/idb_v2.x.x.js deleted file mode 100644 index d80acbb1e4..0000000000 --- a/flow-typed/npm/idb_v2.x.x.js +++ /dev/null @@ -1,428 +0,0 @@ -// flow-typed signature: 266e43152fad31355599ae324f4f5924 -// flow-typed version: 42ca8a9a47/idb_v2.x.x/flow_>=v0.34.x - -// Derived from TS typings at https://github.com/jakearchibald/idb/blob/c8bab898f01bacab96097f87c1e42a0c19e01425/lib/idb.d.ts - -type IDBArrayKey = Array; -type IDBValidKey = number | string | Date | IDBArrayKey; - -// TODO: upstream this to Flow DOM definitions -declare class DOMStringList { - +length: number; - // Comment syntax here as @@iterator is invalid syntax for eslint and babylon - /*:: @@iterator(): Iterator; */ - contains(str: string): boolean; - item(index: number): string | null; - [index: number]: string; -} - -declare module 'idb' { - /** This is your entry point to the API. It's exposed to the global scope unless you're using a module system such as browserify, in which case it's the exported object. */ - declare module.exports: IDBStatic; - - /** - * This is a tiny library that mirrors IndexedDB, but replaces IDBRequest objects with promises. - * This is your entry point to the API. It's exposed to the global scope unless you're using a module system such as browserify, in which case it's the exported object. - */ - declare interface IDBStatic { - /** - * This method returns a promise that resolves to a DB. - * @param name The name of the database. - * @param version Optional. The version to open the database with. If the version is not provided and the database exists, then a connection to the database will be opened without changing its version. If the version is not provided and the database does not exist, then it will be created with version 1. - * @param upgradeCallback Optional. Called if version is greater than the version last opened. It's similar to IDB's onupgradeneeded. The callback receives an instance of UpgradeDB. - * @returns A Promise that passes the DB once it has been opened. - */ - open( - name: string, - version?: number, - upgradeCallback?: (db: UpgradeDB) => void - ): Promise; - - /** - * Behaves like indexedDB.deleteDatabase, but returns a promise. - * @param name The name of the database. - * @returns A Promise that completes once the DB has been removed. - */ - delete(name: string): Promise; - } - - /** Similar to equivalent IDBDatabase. */ - declare interface DB { - /** A DOMString that contains the name of the connected database. */ - +name: string; - - /** A 64-bit integer that contains the version of the connected database. When a database is first created, this attribute is an empty string. */ - +version: number; - - /** A DOMStringList that contains a list of the names of the object stores currently in the connected database. */ - +objectStoreNames: DOMStringList; - - /** Returns immediately and closes the connection to a database in a separate thread. */ - close(): void; - - /** - * Immediately returns a transaction object (Transaction) containing the IDBTransaction.objectStore method, which you can use to access your object store. Runs in a separate thread. - * @param storeNames The names of object stores and indexes that are in the scope of the new transaction, declared as an array of strings. Specify only the object stores that you need to access. - * If you need to access only one object store, you can specify its name as a string. - * @param mode Optional. The types of access that can be performed in the transaction. Transactions are opened in one of three modes: 'readonly' or 'readwrite'. 'versionchange' mode can't be specified here. If you don't provide the parameter, the default access mode is readonly. To avoid slowing things down, don't open a readwrite transaction unless you actually need to write into the database. - * @returns The transaction object. - */ - transaction( - storeNames: string | Array, - mode?: 'readonly' | 'readwrite' - ): Transaction; - } - - /** Represent the equivalent IDBDatabase during an upgrade. */ - declare interface UpgradeDB { - /** A DOMString that contains the name of the connected database. */ - +name: string; - - /** A 64-bit integer that contains the version of the connected database. When a database is first created, this attribute is an empty string. */ - +version: number; - - /** The previous version of the DB seen by the browser, or 0 if it's new */ - +oldVersion: number; - - /** A DOMStringList that contains a list of the names of the object stores currently in the connected database. */ - +objectStoreNames: DOMStringList; - - /** This is a property rather than a method. It's a Transaction representing the upgrade transaction */ - +transaction: Transaction; - - /** - * Creates and returns a new object store or index. - * @param name The name of the new object store to be created. Note that it is possible to create an object store with an empty name. - * @param optionalParameters Optional. An options object whose attributes are optional parameters to the method. - * @returns The new object store. - */ - createObjectStore( - name: string, - optionalParameters?: { - keyPath?: string, - autoIncrement?: boolean, - } - ): ObjectStore; - - /** - * Destroys the object store with the given name in the connected database, along with any indexes that reference it. - * @param name The name of the object store to be removed. - */ - deleteObjectStore(name: string): void; - } - - /** Wrapper of IDBTransaction that presents the asynchronous operations as a Promise. */ - declare interface Transaction { - /** Resolves when transaction completes, rejects if transaction aborts or errors. */ - +complete: Promise; - - /** Returns a DOMStringList of the names of IDBObjectStore objects. */ - +objectStoreNames: DOMStringList; - - /** The mode for isolating access to data in the object stores that are in the scope of the transaction. For possible values, see the Constants section below. The default value is readonly. */ - +mode: 'readonly' | 'readwrite' | 'versionchange'; - - /** Rolls back all the changes to objects in the database associated with this transaction. If this transaction has been aborted or completed, then this method throws an error event. */ - abort(): void; - - /** - * Returns an ObjectStore object representing an object store that is part of the scope of this transaction. - * @param name The name of the requested object store. - * @returns The object store in the context of the transaction. - */ - objectStore(name: string): ObjectStore; - } - - /** Common interface for ObjectStore and Index, since bothe provide these cursor methods */ - declare interface HasCursor { - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) resolves a new cursor object. - * Used for iterating through an object store by primary key with a cursor. - * @param range Optional. A key or IDBKeyRange to be queried. If a single valid key is passed, this will default to a range containing only that key. If nothing is passed, this will default to a key range that selects all the records in this object store. - * @param direction Optional. An IDBCursorDirection telling the cursor what direction to travel. Defaults to "next". - * @returns A promise that resolves with the cursor once it has been opened. - */ - openCursor( - range?: IDBKeyRange | IDBValidKey | null, - direction?: 'next' | 'nextunique' | 'prev' | 'prevunique' - ): Promise; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) resolves a new cursor object. - * Used for iterating through an object store with a key. - * @param range Optional. A key or IDBKeyRange to be queried. If a single valid key is passed, this will default to a range containing only that key. If nothing is passed, this will default to a key range that selects all the records in this object store. - * @param direction Optional. An IDBCursorDirection telling the cursor what direction to travel. Defaults to "next". - * @returns A promise that resolves with the cursor once it has been opened. - */ - openKeyCursor( - range?: IDBKeyRange | IDBValidKey | null, - direction?: 'next' | 'nextunique' | 'prev' | 'prevunique' - ): Promise; - - /** - * Due to the microtask issues in some browsers, iterating over a cursor using promises doesn't always work. - * So in the mean time, iterateCursor maps to openCursor, takes identical arguments, plus an additional callback that receives an IDBCursor - */ - iterateCursor(callback: (c: Cursor) => void): void; - iterateCursor( - range: IDBKeyRange | IDBValidKey | null, - callback: (c: Cursor) => void - ): void; - iterateCursor( - range: IDBKeyRange | IDBValidKey | null, - direction: 'next' | 'nextunique' | 'prev' | 'prevunique', - callback: (c: Cursor) => void - ): void; - - /** - * Due to the microtask issues in some browsers, iterating over a cursor using promises doesn't always work. - * So in the mean time, iterateKeyCursor maps to openKeyCursor, takes identical arguments, plus an additional callback that receives an IDBCursor - */ - iterateKeyCursor(callback: (c: Cursor) => void): void; - iterateKeyCursor( - range: IDBKeyRange | IDBValidKey | null, - callback: (c: Cursor) => void - ): void; - iterateKeyCursor( - range: IDBKeyRange | IDBValidKey | null, - direction: 'next' | 'nextunique' | 'prev' | 'prevunique', - callback: (c: Cursor) => void - ): void; - } - - /** Wrapper of IDBObjectStore that presents the asynchronous operations as Promises. */ - declare interface ObjectStore extends HasCursor { - /** The name of this object store. Settable only during upgrades. */ - name: string; - - /** The key path of this object store. If this attribute is null, the application must provide a key for each modification operation. */ - +keyPath: string | Array; - - /** A list of the names of indexes on objects in this object store. */ - +indexNames: DOMStringList; - - /** The value of the auto increment flag for this object store. */ - +autoIncrement: boolean; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) creates a structured clone of the value, and updates the cloned value in the object store. - * This is for updating existing records in an object store when the transaction's mode is readwrite. - * @param value The value to be stored. - * @param key Optional. The key to use to identify the record. If unspecified, it results to null. - * @returns A promise that resolves with the new key when the underlying put IDBRequest is successful. - */ - put(value: any, key?: IDBKeyRange | IDBValidKey): Promise; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) creates a structured clone of the value, and stores the cloned value in the object store. - * This is for adding new records to an object store. - * @param value The value to be stored. - * @param key Optional. The key to use to identify the record. If unspecified, it results to null. - * @returns A promise that resolves with the new key when the underlying add IDBRequest is successful. - */ - add(value: any, key?: IDBKeyRange | IDBValidKey): Promise; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) deletes the store object specified. - * This is for deleting individual records out of an object store. - * @param key The key of the record to be deleted, or an IDBKeyRange to delete all records with keys in range. - * @returns A promise that resolves when the underlying delete IDBRequest is successful. - */ - delete(key: IDBKeyRange | IDBValidKey): Promise; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) clears the object store. - * This is for deleting all current records out of an object store. - * @returns A promise that resolves when the underlying clear IDBRequest is successful. - */ - clear(): Promise; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) resolves with the store object store selected by the specified key. - * This is for retrieving specific records from an object store. - * @param key The key or key range that identifies the record to be retrieved. - * @returns A promise that resolves with the item when the underlying get IDBRequest is successful. - */ - get(key: any): Promise; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) resolves with the objects in the object store matching the specified parameter or all objects in the store if no parameters are given. - * @param query Optional. A key or IDBKeyRange to be queried. If nothing is passed, this will default to a key range that selects all the records in this object store. - * @param count Optional. Specifies the number of values to return if more than one is found. If it is lower than 0 or greater than 232-1 a TypeError exception will be thrown. - * @returns A promise that resolves with the items when the underlying getAll IDBRequest is successful. - */ - getAll( - query?: IDBKeyRange | IDBValidKey, - count?: number - ): Promise>; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) finds either the given key or the primary key, if key is an IDBKeyRange. - * @param key The key or key range that identifies the record to be retrieved. - * @returns A promise that resolves with the item when the underlying get IDBRequest is successful. - */ - getKey(key: IDBKeyRange | IDBValidKey): Promise; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) resolves with record keys for all the objects matching the specified parameter or all record keys in the store if no parameters are given. - * @param query Optional. A key or IDBKeyRange to be queried. If nothing is passed, this will default to a key range that selects all the records in this object store. - * @param count Optional. Specifies the number of values to return if more than one is found. If it is lower than 0 or greater than 232-1 a TypeError exception will be thrown. - * @returns A promise that resolves with the record keys when the underlying getAllKeys IDBRequest is successful. - */ - getAllKeys(query?: IDBKeyRange, count?: number): Promise>; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) counts the matching records. - * If no arguments are provided, it returns the total number of records in the store. - * @param key A key or IDBKeyRange object that specifies a range of records you want to count. - * @returns A promise that resolves with the total when the underlying count IDBRequest is successful. - */ - count(key?: IDBKeyRange | IDBValidKey): Promise; - - /** - * Creates a new index during a version upgrade, returning a new Index object in the connected database. - * @param name The name of the index to create. It is possible to create an index with an empty name. - * @param keyPath The key path for the index to use. It is possible to create an index with an empty keyPath, and also to pass in an array as a keyPath. - * @param optionalParameters Additional options: unique and multiEntry. - * @returns The newly created index. - */ - createIndex( - name: string, - keyPath: string | Array, - optionalParameters?: { - unique?: boolean, - multiEntry?: boolean, - locale?: string | 'auto' | null, - } - ): Index; - - /** - * Destroys the specified index in the connected database, used during a version upgrade. - * @param indexName The name of the existing index to remove. - */ - deleteIndex(indexName: string): void; - - /** - * Opens an index from this object store after which it can, for example, be used to return a sequence of records sorted by that index using a cursor. - * @param name The name of the existing index to get. - * @returns The specified index. - */ - index(name: string): Index; - } - - /** Wrapper of IDBIndex that presents the asynchronous operations as Promises. */ - declare interface Index extends HasCursor { - /** The name of this index. */ - +name: string; - - /** The key path of this index. If null, this index is not auto-populated. */ - +keyPath: string | Array; - - /** - * Affects how the index behaves when the result of evaluating the index's key path yields an array. - * If true, there is one record in the index for each item in an array of keys. - * If false, then there is one record for each key that is an array. - */ - +multiEntry: boolean; - - /** If true, this index does not allow duplicate values for a key. */ - +unique: boolean; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) counts the matching records. - * If no arguments are provided, it returns the total number of records in the store. - * @param key A key or IDBKeyRange object that specifies a range of records you want to count. - * @returns A promise that resolves with the total when the underlying count IDBRequest is successful. - */ - count(key?: IDBKeyRange | IDBValidKey): Promise; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) resolves with the store object store selected by the specified key. - * This is for retrieving specific records from an object store. - * @param key The key or key range that identifies the record to be retrieved. - * @returns A promise that resolves with the item when the underlying get IDBRequest is successful. - */ - get(key: IDBKeyRange | IDBValidKey): Promise; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) finds either the given key or the primary key, if key is an IDBKeyRange. - * @param key The key or key range that identifies the record to be retrieved. - * @returns A promise that resolves with the item when the underlying get IDBRequest is successful. - */ - getKey(key: IDBKeyRange | IDBValidKey): Promise; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) resolves with the objects in the object store matching the specified parameter or all objects in the store if no parameters are given. - * @param query Optional. A key or IDBKeyRange to be queried. If nothing is passed, this will default to a key range that selects all the records in this object store. - * @param count Optional. Specifies the number of values to return if more than one is found. If it is lower than 0 or greater than 232-1 a TypeError exception will be thrown. - * @returns A promise that resolves with the items when the underlying getAll IDBRequest is successful. - */ - getAll( - query?: IDBKeyRange | IDBValidKey, - count?: number - ): Promise>; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) resolves with record keys for all the objects matching the specified parameter or all record keys in the store if no parameters are given. - * @param query Optional. A key or IDBKeyRange to be queried. If nothing is passed, this will default to a key range that selects all the records in this object store. - * @param count Optional. Specifies the number of values to return if more than one is found. If it is lower than 0 or greater than 232-1 a TypeError exception will be thrown. - * @returns A promise that resolves with the record keys when the underlying getAllKeys IDBRequest is successful. - */ - getAllKeys(query?: IDBKeyRange, count?: number): Promise>; - } - - /** Wrapper of IDBCursor that presents the asynchronous operations as Promises. */ - declare interface Cursor { - /** The key for the record at the cursor's position. If the cursor is outside its range, this is set to undefined. The cursor's key can be any data type. */ - +key: IDBKeyRange | IDBValidKey; - - /** The cursor's current effective primary key. If the cursor is currently being iterated or has iterated outside its range, this is set to undefined. The cursor's primary key can be any data type. */ - +primaryKey: any; - - /** The direction of traversal of the cursor. */ - +direction: 'next' | 'nextunique' | 'prev' | 'prevunique'; - - /** The current value under the cursor. */ - +value: any; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) deletes the record at the cursor's position, without changing the cursor's position. - * This can be used to delete specific records. - * @returns A promise that resolves when the underlying delete IDBRequest is successful. - */ - delete(): Promise; - - /** - * Returns a Promise of an IDBRequest object that (in a separate thread) updates the value at the current position of the cursor in the object store. - * This can be used to update specific records. - * @param value The value to write over the current cursor location. - * @returns A promise that resolves when the underlying update IDBRequest is successful. - */ - update(value: any): Promise; - - /** - * Sets the number times a cursor should move its position forward. - * @param count The number of times to move the cursor forward. - * @returns The cursor after having been moved forward the specified number of times. - */ - advance(count: number): Promise; - - /** - * Advances the cursor to the next position along its direction, to the item whose key matches the optional key parameter. - * @param key Optional. The key to position the cursor at. If no key is specified, the cursor advances to the immediate next position, based on the its direction. - * @returns The cursor after having been continued to the next or specified record. - */ - continue(key?: IDBKeyRange | IDBValidKey): Promise; - - /** - * Sets the cursor to the given index key and primary key given as arguments. - * @param key The key to position the cursor at. - * @param primaryKey The primary key to position the cursor at. - * @returns The cursor after having been continued to the next or specified record. - */ - continuePrimaryKey( - key?: IDBKeyRange | IDBValidKey, - primaryKey?: any - ): Promise; - } -} diff --git a/flow-typed/npm/invariant_v2.x.x.js b/flow-typed/npm/invariant_v2.x.x.js deleted file mode 100644 index 14974ead54..0000000000 --- a/flow-typed/npm/invariant_v2.x.x.js +++ /dev/null @@ -1 +0,0 @@ -// Empty stub to prevent flow-typed from installing its own definition diff --git a/flow-typed/npm/json-stringify-safe_v5.x.x.js b/flow-typed/npm/json-stringify-safe_v5.x.x.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/flow-typed/npm/lodash_v4.x.x.js b/flow-typed/npm/lodash_v4.x.x.js deleted file mode 100644 index e3e131c220..0000000000 --- a/flow-typed/npm/lodash_v4.x.x.js +++ /dev/null @@ -1,4207 +0,0 @@ -// flow-typed signature: 554384bc1c2235537d0c15bf2acefe99 -// flow-typed version: c5a8c20937/lodash_v4.x.x/flow_>=v0.55.x - -declare module "lodash" { - declare type __CurriedFunction1 = (...r: [AA]) => R; - declare type CurriedFunction1 = __CurriedFunction1; - - declare type __CurriedFunction2 = (( - ...r: [AA] - ) => CurriedFunction1) & - ((...r: [AA, BB]) => R); - declare type CurriedFunction2 = __CurriedFunction2; - - declare type __CurriedFunction3 = (( - ...r: [AA] - ) => CurriedFunction2) & - ((...r: [AA, BB]) => CurriedFunction1) & - ((...r: [AA, BB, CC]) => R); - declare type CurriedFunction3 = __CurriedFunction3< - A, - B, - C, - R, - *, - *, - * - >; - - declare type __CurriedFunction4< - A, - B, - C, - D, - R, - AA: A, - BB: B, - CC: C, - DD: D - > = ((...r: [AA]) => CurriedFunction3) & - ((...r: [AA, BB]) => CurriedFunction2) & - ((...r: [AA, BB, CC]) => CurriedFunction1) & - ((...r: [AA, BB, CC, DD]) => R); - declare type CurriedFunction4 = __CurriedFunction4< - A, - B, - C, - D, - R, - *, - *, - *, - * - >; - - declare type __CurriedFunction5< - A, - B, - C, - D, - E, - R, - AA: A, - BB: B, - CC: C, - DD: D, - EE: E - > = ((...r: [AA]) => CurriedFunction4) & - ((...r: [AA, BB]) => CurriedFunction3) & - ((...r: [AA, BB, CC]) => CurriedFunction2) & - ((...r: [AA, BB, CC, DD]) => CurriedFunction1) & - ((...r: [AA, BB, CC, DD, EE]) => R); - declare type CurriedFunction5 = __CurriedFunction5< - A, - B, - C, - D, - E, - R, - *, - *, - *, - *, - * - >; - - declare type __CurriedFunction6< - A, - B, - C, - D, - E, - F, - R, - AA: A, - BB: B, - CC: C, - DD: D, - EE: E, - FF: F - > = ((...r: [AA]) => CurriedFunction5) & - ((...r: [AA, BB]) => CurriedFunction4) & - ((...r: [AA, BB, CC]) => CurriedFunction3) & - ((...r: [AA, BB, CC, DD]) => CurriedFunction2) & - ((...r: [AA, BB, CC, DD, EE]) => CurriedFunction1) & - ((...r: [AA, BB, CC, DD, EE, FF]) => R); - declare type CurriedFunction6 = __CurriedFunction6< - A, - B, - C, - D, - E, - F, - R, - *, - *, - *, - *, - *, - * - >; - - declare type Curry = (((...r: [A]) => R) => CurriedFunction1) & - (((...r: [A, B]) => R) => CurriedFunction2) & - (((...r: [A, B, C]) => R) => CurriedFunction3) & - (( - (...r: [A, B, C, D]) => R - ) => CurriedFunction4) & - (( - (...r: [A, B, C, D, E]) => R - ) => CurriedFunction5) & - (( - (...r: [A, B, C, D, E, F]) => R - ) => CurriedFunction6); - - declare type UnaryFn = (a: A) => R; - - declare type TemplateSettings = { - escape?: RegExp, - evaluate?: RegExp, - imports?: Object, - interpolate?: RegExp, - variable?: string - }; - - declare type TruncateOptions = { - length?: number, - omission?: string, - separator?: RegExp | string - }; - - declare type DebounceOptions = { - leading?: boolean, - maxWait?: number, - trailing?: boolean - }; - - declare type ThrottleOptions = { - leading?: boolean, - trailing?: boolean - }; - - declare type NestedArray = Array>; - - declare type matchesIterateeShorthand = Object; - declare type matchesPropertyIterateeShorthand = [string, any]; - declare type propertyIterateeShorthand = string; - - declare type OPredicate = - | ((value: A, key: string, object: O) => any) - | matchesIterateeShorthand - | matchesPropertyIterateeShorthand - | propertyIterateeShorthand; - - declare type OIterateeWithResult = - | Object - | string - | ((value: V, key: string, object: O) => R); - declare type OIteratee = OIterateeWithResult; - declare type OFlatMapIteratee = OIterateeWithResult>; - - declare type Predicate = - | ((value: T, index: number, array: Array) => any) - | matchesIterateeShorthand - | matchesPropertyIterateeShorthand - | propertyIterateeShorthand; - - declare type _ValueOnlyIteratee = (value: T) => mixed; - declare type ValueOnlyIteratee = _ValueOnlyIteratee | string; - declare type _Iteratee = ( - item: T, - index: number, - array: ?Array - ) => mixed; - declare type Iteratee = _Iteratee | Object | string; - declare type FlatMapIteratee = - | ((item: T, index: number, array: ?Array) => Array) - | Object - | string; - declare type Comparator = (item: T, item2: T) => boolean; - - declare type MapIterator = - | ((item: T, index: number, array: Array) => U) - | propertyIterateeShorthand; - - declare type OMapIterator = - | ((item: T, key: string, object: O) => U) - | propertyIterateeShorthand; - - declare class Lodash { - // Array - chunk(array: ?Array, size?: number): Array>; - compact(array: Array): Array; - concat(base: Array, ...elements: Array): Array; - difference(array: ?Array, values?: Array): Array; - differenceBy( - array: ?Array, - values: Array, - iteratee: ValueOnlyIteratee - ): T[]; - differenceWith(array: T[], values: T[], comparator?: Comparator): T[]; - drop(array: ?Array, n?: number): Array; - dropRight(array: ?Array, n?: number): Array; - dropRightWhile(array: ?Array, predicate?: Predicate): Array; - dropWhile(array: ?Array, predicate?: Predicate): Array; - fill( - array: ?Array, - value: U, - start?: number, - end?: number - ): Array; - findIndex( - array: ?$ReadOnlyArray, - predicate?: Predicate, - fromIndex?: number - ): number; - findLastIndex( - array: ?$ReadOnlyArray, - predicate?: Predicate, - fromIndex?: number - ): number; - // alias of _.head - first(array: ?Array): T; - flatten(array: Array | X>): Array; - flattenDeep(array: any[]): Array; - flattenDepth(array: any[], depth?: number): any[]; - fromPairs(pairs: Array<[A, B]>): { [key: A]: B }; - head(array: ?Array): T; - indexOf(array: ?Array, value: T, fromIndex?: number): number; - initial(array: ?Array): Array; - intersection(...arrays: Array>): Array; - //Workaround until (...parameter: T, parameter2: U) works - intersectionBy(a1: Array, iteratee?: ValueOnlyIteratee): Array; - intersectionBy( - a1: Array, - a2: Array, - iteratee?: ValueOnlyIteratee - ): Array; - intersectionBy( - a1: Array, - a2: Array, - a3: Array, - iteratee?: ValueOnlyIteratee - ): Array; - intersectionBy( - a1: Array, - a2: Array, - a3: Array, - a4: Array, - iteratee?: ValueOnlyIteratee - ): Array; - //Workaround until (...parameter: T, parameter2: U) works - intersectionWith(a1: Array, comparator: Comparator): Array; - intersectionWith( - a1: Array, - a2: Array, - comparator: Comparator - ): Array; - intersectionWith( - a1: Array, - a2: Array, - a3: Array, - comparator: Comparator - ): Array; - intersectionWith( - a1: Array, - a2: Array, - a3: Array, - a4: Array, - comparator: Comparator - ): Array; - join(array: ?Array, separator?: string): string; - last(array: ?Array): T; - lastIndexOf(array: ?Array, value: T, fromIndex?: number): number; - nth(array: T[], n?: number): T; - pull(array: ?Array, ...values?: Array): Array; - pullAll(array: ?Array, values: Array): Array; - pullAllBy( - array: ?Array, - values: Array, - iteratee?: ValueOnlyIteratee - ): Array; - pullAllWith(array?: T[], values: T[], comparator?: Function): T[]; - pullAt(array: ?Array, ...indexed?: Array): Array; - pullAt(array: ?Array, indexed?: Array): Array; - remove(array: ?Array, predicate?: Predicate): Array; - reverse(array: ?Array): Array; - slice(array: ?Array, start?: number, end?: number): Array; - sortedIndex(array: ?Array, value: T): number; - sortedIndexBy( - array: ?Array, - value: T, - iteratee?: ValueOnlyIteratee - ): number; - sortedIndexOf(array: ?Array, value: T): number; - sortedLastIndex(array: ?Array, value: T): number; - sortedLastIndexBy( - array: ?Array, - value: T, - iteratee?: ValueOnlyIteratee - ): number; - sortedLastIndexOf(array: ?Array, value: T): number; - sortedUniq(array: ?Array): Array; - sortedUniqBy(array: ?Array, iteratee?: (value: T) => mixed): Array; - tail(array: ?Array): Array; - take(array: ?Array, n?: number): Array; - takeRight(array: ?Array, n?: number): Array; - takeRightWhile(array: ?Array, predicate?: Predicate): Array; - takeWhile(array: ?Array, predicate?: Predicate): Array; - union(...arrays?: Array>): Array; - //Workaround until (...parameter: T, parameter2: U) works - unionBy(a1: Array, iteratee?: ValueOnlyIteratee): Array; - unionBy( - a1: Array, - a2: Array, - iteratee?: ValueOnlyIteratee - ): Array; - unionBy( - a1: Array, - a2: Array, - a3: Array, - iteratee?: ValueOnlyIteratee - ): Array; - unionBy( - a1: Array, - a2: Array, - a3: Array, - a4: Array, - iteratee?: ValueOnlyIteratee - ): Array; - //Workaround until (...parameter: T, parameter2: U) works - unionWith(a1: Array, comparator?: Comparator): Array; - unionWith( - a1: Array, - a2: Array, - comparator?: Comparator - ): Array; - unionWith( - a1: Array, - a2: Array, - a3: Array, - comparator?: Comparator - ): Array; - unionWith( - a1: Array, - a2: Array, - a3: Array, - a4: Array, - comparator?: Comparator - ): Array; - uniq(array: ?Array): Array; - uniqBy(array: ?Array, iteratee?: ValueOnlyIteratee): Array; - uniqWith(array: ?Array, comparator?: Comparator): Array; - unzip(array: ?Array): Array; - unzipWith(array: ?Array, iteratee?: Iteratee): Array; - without(array: ?Array, ...values?: Array): Array; - xor(...array: Array>): Array; - //Workaround until (...parameter: T, parameter2: U) works - xorBy(a1: Array, iteratee?: ValueOnlyIteratee): Array; - xorBy( - a1: Array, - a2: Array, - iteratee?: ValueOnlyIteratee - ): Array; - xorBy( - a1: Array, - a2: Array, - a3: Array, - iteratee?: ValueOnlyIteratee - ): Array; - xorBy( - a1: Array, - a2: Array, - a3: Array, - a4: Array, - iteratee?: ValueOnlyIteratee - ): Array; - //Workaround until (...parameter: T, parameter2: U) works - xorWith(a1: Array, comparator?: Comparator): Array; - xorWith( - a1: Array, - a2: Array, - comparator?: Comparator - ): Array; - xorWith( - a1: Array, - a2: Array, - a3: Array, - comparator?: Comparator - ): Array; - xorWith( - a1: Array, - a2: Array, - a3: Array, - a4: Array, - comparator?: Comparator - ): Array; - zip(a1: A[], a2: B[]): Array<[A, B]>; - zip(a1: A[], a2: B[], a3: C[]): Array<[A, B, C]>; - zip(a1: A[], a2: B[], a3: C[], a4: D[]): Array<[A, B, C, D]>; - zip( - a1: A[], - a2: B[], - a3: C[], - a4: D[], - a5: E[] - ): Array<[A, B, C, D, E]>; - - zipObject(props?: Array, values?: Array): { [key: K]: V }; - zipObjectDeep(props?: any[], values?: any): Object; - //Workaround until (...parameter: T, parameter2: U) works - zipWith(a1: NestedArray, iteratee?: Iteratee): Array; - zipWith( - a1: NestedArray, - a2: NestedArray, - iteratee?: Iteratee - ): Array; - zipWith( - a1: NestedArray, - a2: NestedArray, - a3: NestedArray, - iteratee?: Iteratee - ): Array; - zipWith( - a1: NestedArray, - a2: NestedArray, - a3: NestedArray, - a4: NestedArray, - iteratee?: Iteratee - ): Array; - - // Collection - countBy(array: ?Array, iteratee?: ValueOnlyIteratee): Object; - countBy(object: T, iteratee?: ValueOnlyIteratee): Object; - // alias of _.forEach - each(array: ?Array, iteratee?: Iteratee): Array; - each(object: T, iteratee?: OIteratee): T; - // alias of _.forEachRight - eachRight(array: ?Array, iteratee?: Iteratee): Array; - eachRight(object: T, iteratee?: OIteratee): T; - every(array: ?Array, iteratee?: Iteratee): boolean; - every(object: T, iteratee?: OIteratee): boolean; - filter(array: ?Array, predicate?: Predicate): Array; - filter( - object: T, - predicate?: OPredicate - ): Array; - find( - array: ?$ReadOnlyArray, - predicate?: Predicate, - fromIndex?: number - ): T | void; - find( - object: T, - predicate?: OPredicate, - fromIndex?: number - ): V; - findLast( - array: ?$ReadOnlyArray, - predicate?: Predicate, - fromIndex?: number - ): T | void; - findLast( - object: T, - predicate?: OPredicate - ): V; - flatMap(array: ?Array, iteratee?: FlatMapIteratee): Array; - flatMap( - object: T, - iteratee?: OFlatMapIteratee - ): Array; - flatMapDeep( - array: ?Array, - iteratee?: FlatMapIteratee - ): Array; - flatMapDeep( - object: T, - iteratee?: OFlatMapIteratee - ): Array; - flatMapDepth( - array: ?Array, - iteratee?: FlatMapIteratee, - depth?: number - ): Array; - flatMapDepth( - object: T, - iteratee?: OFlatMapIteratee, - depth?: number - ): Array; - forEach(array: ?Array, iteratee?: Iteratee): Array; - forEach(object: T, iteratee?: OIteratee): T; - forEachRight(array: ?Array, iteratee?: Iteratee): Array; - forEachRight(object: T, iteratee?: OIteratee): T; - groupBy( - array: ?Array, - iteratee?: ValueOnlyIteratee - ): { [key: V]: Array }; - groupBy( - object: T, - iteratee?: ValueOnlyIteratee - ): { [key: V]: Array }; - includes(array: ?Array, value: T, fromIndex?: number): boolean; - includes(object: T, value: any, fromIndex?: number): boolean; - includes(str: string, value: string, fromIndex?: number): boolean; - invokeMap( - array: ?Array, - path: ((value: T) => Array | string) | Array | string, - ...args?: Array - ): Array; - invokeMap( - object: T, - path: ((value: any) => Array | string) | Array | string, - ...args?: Array - ): Array; - keyBy( - array: ?Array, - iteratee?: ValueOnlyIteratee - ): { [key: V]: ?T }; - keyBy( - object: T, - iteratee?: ValueOnlyIteratee - ): { [key: V]: ?A }; - map(array: ?Array, iteratee?: MapIterator): Array; - map( - object: ?T, - iteratee?: OMapIterator - ): Array; - map( - str: ?string, - iteratee?: (char: string, index: number, str: string) => any - ): string; - orderBy( - array: ?Array, - iteratees?: Array> | string, - orders?: Array<"asc" | "desc"> | string - ): Array; - orderBy( - object: T, - iteratees?: Array> | string, - orders?: Array<"asc" | "desc"> | string - ): Array; - partition( - array: ?Array, - predicate?: Predicate - ): [Array, Array]; - partition( - object: T, - predicate?: OPredicate - ): [Array, Array]; - reduce( - array: ?Array, - iteratee?: ( - accumulator: U, - value: T, - index: number, - array: ?Array - ) => U, - accumulator?: U - ): U; - reduce( - object: T, - iteratee?: (accumulator: U, value: any, key: string, object: T) => U, - accumulator?: U - ): U; - reduceRight( - array: ?Array, - iteratee?: ( - accumulator: U, - value: T, - index: number, - array: ?Array - ) => U, - accumulator?: U - ): U; - reduceRight( - object: T, - iteratee?: (accumulator: U, value: any, key: string, object: T) => U, - accumulator?: U - ): U; - reject(array: ?Array, predicate?: Predicate): Array; - reject( - object: T, - predicate?: OPredicate - ): Array; - sample(array: ?Array): T; - sample(object: T): V; - sampleSize(array: ?Array, n?: number): Array; - sampleSize(object: T, n?: number): Array; - shuffle(array: ?Array): Array; - shuffle(object: T): Array; - size(collection: Array | Object): number; - some(array: ?Array, predicate?: Predicate): boolean; - some( - object?: ?T, - predicate?: OPredicate - ): boolean; - sortBy(array: ?Array, ...iteratees?: Array>): Array; - sortBy(array: ?Array, iteratees?: Array>): Array; - sortBy( - object: T, - ...iteratees?: Array> - ): Array; - sortBy(object: T, iteratees?: Array>): Array; - - // Date - now(): number; - - // Function - after(n: number, fn: Function): Function; - ary(func: Function, n?: number): Function; - before(n: number, fn: Function): Function; - bind(func: Function, thisArg: any, ...partials: Array): Function; - bindKey(obj: Object, key: string, ...partials: Array): Function; - curry: Curry; - curry(func: Function, arity?: number): Function; - curryRight(func: Function, arity?: number): Function; - debounce(func: F, wait?: number, options?: DebounceOptions): F; - defer(func: Function, ...args?: Array): number; - delay(func: Function, wait: number, ...args?: Array): number; - flip(func: Function): Function; - memoize(func: F, resolver?: Function): F; - negate(predicate: Function): Function; - once(func: Function): Function; - overArgs(func: Function, ...transforms: Array): Function; - overArgs(func: Function, transforms: Array): Function; - partial(func: Function, ...partials: any[]): Function; - partialRight(func: Function, ...partials: Array): Function; - partialRight(func: Function, partials: Array): Function; - rearg(func: Function, ...indexes: Array): Function; - rearg(func: Function, indexes: Array): Function; - rest(func: Function, start?: number): Function; - spread(func: Function): Function; - throttle( - func: Function, - wait?: number, - options?: ThrottleOptions - ): Function; - unary(func: Function): Function; - wrap(value: any, wrapper: Function): Function; - - // Lang - castArray(value: *): any[]; - clone(value: T): T; - cloneDeep(value: T): T; - cloneDeepWith( - value: T, - customizer?: ?(value: T, key: number | string, object: T, stack: any) => U - ): U; - cloneWith( - value: T, - customizer?: ?(value: T, key: number | string, object: T, stack: any) => U - ): U; - conformsTo( - source: T, - predicates: T & { [key: string]: (x: any) => boolean } - ): boolean; - eq(value: any, other: any): boolean; - gt(value: any, other: any): boolean; - gte(value: any, other: any): boolean; - isArguments(value: any): boolean; - isArray(value: any): boolean; - isArrayBuffer(value: any): boolean; - isArrayLike(value: any): boolean; - isArrayLikeObject(value: any): boolean; - isBoolean(value: any): boolean; - isBuffer(value: any): boolean; - isDate(value: any): boolean; - isElement(value: any): boolean; - isEmpty(value: any): boolean; - isEqual(value: any, other: any): boolean; - isEqualWith( - value: T, - other: U, - customizer?: ( - objValue: any, - otherValue: any, - key: number | string, - object: T, - other: U, - stack: any - ) => boolean | void - ): boolean; - isError(value: any): boolean; - isFinite(value: any): boolean; - isFunction(value: Function): true; - isFunction(value: number | string | void | null | Object): false; - isInteger(value: any): boolean; - isLength(value: any): boolean; - isMap(value: any): boolean; - isMatch(object?: ?Object, source: Object): boolean; - isMatchWith( - object: T, - source: U, - customizer?: ( - objValue: any, - srcValue: any, - key: number | string, - object: T, - source: U - ) => boolean | void - ): boolean; - isNaN(value: any): boolean; - isNative(value: any): boolean; - isNil(value: any): boolean; - isNull(value: any): boolean; - isNumber(value: any): boolean; - isObject(value: any): boolean; - isObjectLike(value: any): boolean; - isPlainObject(value: any): boolean; - isRegExp(value: any): boolean; - isSafeInteger(value: any): boolean; - isSet(value: any): boolean; - isString(value: string): true; - isString( - value: number | boolean | Function | void | null | Object | Array - ): false; - isSymbol(value: any): boolean; - isTypedArray(value: any): boolean; - isUndefined(value: any): boolean; - isWeakMap(value: any): boolean; - isWeakSet(value: any): boolean; - lt(value: any, other: any): boolean; - lte(value: any, other: any): boolean; - toArray(value: any): Array; - toFinite(value: any): number; - toInteger(value: any): number; - toLength(value: any): number; - toNumber(value: any): number; - toPlainObject(value: any): Object; - toSafeInteger(value: any): number; - toString(value: any): string; - - // Math - add(augend: number, addend: number): number; - ceil(number: number, precision?: number): number; - divide(dividend: number, divisor: number): number; - floor(number: number, precision?: number): number; - max(array: ?Array): T; - maxBy(array: ?Array, iteratee?: Iteratee): T; - mean(array: Array<*>): number; - meanBy(array: Array, iteratee?: Iteratee): number; - min(array: ?Array): T; - minBy(array: ?Array, iteratee?: Iteratee): T; - multiply(multiplier: number, multiplicand: number): number; - round(number: number, precision?: number): number; - subtract(minuend: number, subtrahend: number): number; - sum(array: Array<*>): number; - sumBy(array: Array, iteratee?: Iteratee): number; - - // number - clamp(number: number, lower?: number, upper: number): number; - inRange(number: number, start?: number, end: number): boolean; - random(lower?: number, upper?: number, floating?: boolean): number; - - // Object - assign(object?: ?Object, ...sources?: Array): Object; - assignIn(a: A, b: B): A & B; - assignIn(a: A, b: B, c: C): A & B & C; - assignIn(a: A, b: B, c: C, d: D): A & B & C & D; - assignIn(a: A, b: B, c: C, d: D, e: E): A & B & C & D & E; - assignInWith( - object: T, - s1: A, - customizer?: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A - ) => any | void - ): Object; - assignInWith( - object: T, - s1: A, - s2: B, - customizer?: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A | B - ) => any | void - ): Object; - assignInWith( - object: T, - s1: A, - s2: B, - s3: C, - customizer?: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A | B | C - ) => any | void - ): Object; - assignInWith( - object: T, - s1: A, - s2: B, - s3: C, - s4: D, - customizer?: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A | B | C | D - ) => any | void - ): Object; - assignWith( - object: T, - s1: A, - customizer?: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A - ) => any | void - ): Object; - assignWith( - object: T, - s1: A, - s2: B, - customizer?: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A | B - ) => any | void - ): Object; - assignWith( - object: T, - s1: A, - s2: B, - s3: C, - customizer?: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A | B | C - ) => any | void - ): Object; - assignWith( - object: T, - s1: A, - s2: B, - s3: C, - s4: D, - customizer?: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A | B | C | D - ) => any | void - ): Object; - at(object?: ?Object, ...paths: Array): Array; - at(object?: ?Object, paths: Array): Array; - create(prototype: T, properties?: Object): $Supertype; - defaults(object?: ?Object, ...sources?: Array): Object; - defaultsDeep(object?: ?Object, ...sources?: Array): Object; - // alias for _.toPairs - entries(object?: ?Object): NestedArray; - // alias for _.toPairsIn - entriesIn(object?: ?Object): NestedArray; - // alias for _.assignIn - extend(a: A, b: B): A & B; - extend(a: A, b: B, c: C): A & B & C; - extend(a: A, b: B, c: C, d: D): A & B & C & D; - extend(a: A, b: B, c: C, d: D, e: E): A & B & C & D & E; - // alias for _.assignInWith - extendWith( - object: T, - s1: A, - customizer?: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A - ) => any | void - ): Object; - extendWith( - object: T, - s1: A, - s2: B, - customizer?: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A | B - ) => any | void - ): Object; - extendWith( - object: T, - s1: A, - s2: B, - s3: C, - customizer?: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A | B | C - ) => any | void - ): Object; - extendWith( - object: T, - s1: A, - s2: B, - s3: C, - s4: D, - customizer?: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A | B | C | D - ) => any | void - ): Object; - findKey( - object?: ?T, - predicate?: OPredicate - ): string | void; - findLastKey( - object?: ?T, - predicate?: OPredicate - ): string | void; - forIn(object?: ?Object, iteratee?: OIteratee<*>): Object; - forInRight(object?: ?Object, iteratee?: OIteratee<*>): Object; - forOwn(object?: ?Object, iteratee?: OIteratee<*>): Object; - forOwnRight(object?: ?Object, iteratee?: OIteratee<*>): Object; - functions(object?: ?Object): Array; - functionsIn(object?: ?Object): Array; - get( - object?: ?Object | ?Array, - path?: ?Array | string, - defaultValue?: any - ): any; - has(object?: ?Object, path?: ?Array | string): boolean; - hasIn(object?: ?Object, path?: ?Array | string): boolean; - invert(object?: ?Object, multiVal?: boolean): Object; - invertBy(object: ?Object, iteratee?: Function): Object; - invoke( - object?: ?Object, - path?: ?Array | string, - ...args?: Array - ): any; - keys(object?: ?{ [key: K]: any }): Array; - keys(object?: ?Object): Array; - keysIn(object?: ?Object): Array; - mapKeys(object?: ?Object, iteratee?: OIteratee<*>): Object; - mapValues(object?: ?Object, iteratee?: OIteratee<*>): Object; - merge(object?: ?Object, ...sources?: Array): Object; - mergeWith( - object: T, - customizer?: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A - ) => any | void - ): Object; - mergeWith( - object: T, - s1: A, - s2: B, - customizer?: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A | B - ) => any | void - ): Object; - mergeWith( - object: T, - s1: A, - s2: B, - s3: C, - customizer?: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A | B | C - ) => any | void - ): Object; - mergeWith( - object: T, - s1: A, - s2: B, - s3: C, - s4: D, - customizer?: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A | B | C | D - ) => any | void - ): Object; - omit(object?: ?Object, ...props: Array): Object; - omit(object?: ?Object, props: Array): Object; - omitBy( - object?: ?T, - predicate?: OPredicate - ): Object; - pick(object?: ?Object, ...props: Array): Object; - pick(object?: ?Object, props: Array): Object; - pickBy( - object?: ?T, - predicate?: OPredicate - ): Object; - result( - object?: ?Object, - path?: ?Array | string, - defaultValue?: any - ): any; - set(object?: ?Object, path?: ?Array | string, value: any): Object; - setWith( - object: T, - path?: ?Array | string, - value: any, - customizer?: (nsValue: any, key: string, nsObject: T) => any - ): Object; - toPairs(object?: ?Object | Array<*>): NestedArray; - toPairsIn(object?: ?Object): NestedArray; - transform( - collection: Object | Array, - iteratee?: OIteratee<*>, - accumulator?: any - ): any; - unset(object?: ?Object, path?: ?Array | string): boolean; - update(object: Object, path: string[] | string, updater: Function): Object; - updateWith( - object: Object, - path: string[] | string, - updater: Function, - customizer?: Function - ): Object; - values(object?: ?Object): Array; - valuesIn(object?: ?Object): Array; - - // Seq - // harder to read, but this is _() - (value: any): any; - chain(value: T): any; - tap(value: T, interceptor: (value: T) => any): T; - thru(value: T1, interceptor: (value: T1) => T2): T2; - // TODO: _.prototype.* - - // String - camelCase(string?: ?string): string; - capitalize(string?: string): string; - deburr(string?: string): string; - endsWith(string?: string, target?: string, position?: number): boolean; - escape(string?: string): string; - escapeRegExp(string?: string): string; - kebabCase(string?: string): string; - lowerCase(string?: string): string; - lowerFirst(string?: string): string; - pad(string?: string, length?: number, chars?: string): string; - padEnd(string?: string, length?: number, chars?: string): string; - padStart(string?: string, length?: number, chars?: string): string; - parseInt(string: string, radix?: number): number; - repeat(string?: string, n?: number): string; - replace( - string?: string, - pattern: RegExp | string, - replacement: ((string: string) => string) | string - ): string; - snakeCase(string?: string): string; - split( - string?: string, - separator: RegExp | string, - limit?: number - ): Array; - startCase(string?: string): string; - startsWith(string?: string, target?: string, position?: number): boolean; - template(string?: string, options?: TemplateSettings): Function; - toLower(string?: string): string; - toUpper(string?: string): string; - trim(string?: string, chars?: string): string; - trimEnd(string?: string, chars?: string): string; - trimStart(string?: string, chars?: string): string; - truncate(string?: string, options?: TruncateOptions): string; - unescape(string?: string): string; - upperCase(string?: string): string; - upperFirst(string?: string): string; - words(string?: string, pattern?: RegExp | string): Array; - - // Util - attempt(func: Function, ...args: Array): any; - bindAll(object?: ?Object, methodNames: Array): Object; - bindAll(object?: ?Object, ...methodNames: Array): Object; - cond(pairs: NestedArray): Function; - conforms(source: Object): Function; - constant(value: T): () => T; - defaultTo( - value: T1, - defaultValue: T2 - ): T1; - // NaN is a number instead of its own type, otherwise it would behave like null/void - defaultTo(value: T1, defaultValue: T2): T1 | T2; - defaultTo(value: T1, defaultValue: T2): T2; - flow: $ComposeReverse; - flow(funcs?: Array): Function; - flowRight: $Compose; - flowRight(funcs?: Array): Function; - identity(value: T): T; - iteratee(func?: any): Function; - matches(source: Object): Function; - matchesProperty(path?: ?Array | string, srcValue: any): Function; - method(path?: ?Array | string, ...args?: Array): Function; - methodOf(object?: ?Object, ...args?: Array): Function; - mixin( - object?: T, - source: Object, - options?: { chain: boolean } - ): T; - noConflict(): Lodash; - noop(...args: Array): void; - nthArg(n?: number): Function; - over(...iteratees: Array): Function; - over(iteratees: Array): Function; - overEvery(...predicates: Array): Function; - overEvery(predicates: Array): Function; - overSome(...predicates: Array): Function; - overSome(predicates: Array): Function; - property(path?: ?Array | string): Function; - propertyOf(object?: ?Object): Function; - range(start: number, end: number, step?: number): Array; - range(end: number, step?: number): Array; - rangeRight(start: number, end: number, step?: number): Array; - rangeRight(end: number, step?: number): Array; - runInContext(context?: Object): Function; - - stubArray(): Array<*>; - stubFalse(): false; - stubObject(): {}; - stubString(): ""; - stubTrue(): true; - times(n: number, ...rest: Array): Array; - times(n: number, iteratee: (i: number) => T): Array; - toPath(value: any): Array; - uniqueId(prefix?: string): string; - - // Properties - VERSION: string; - templateSettings: TemplateSettings; - } - - declare module.exports: Lodash; -} - -declare module "lodash/fp" { - declare type __CurriedFunction1 = (...r: [AA]) => R; - declare type CurriedFunction1 = __CurriedFunction1; - - declare type __CurriedFunction2 = (( - ...r: [AA] - ) => CurriedFunction1) & - ((...r: [AA, BB]) => R); - declare type CurriedFunction2 = __CurriedFunction2; - - declare type __CurriedFunction3 = (( - ...r: [AA] - ) => CurriedFunction2) & - ((...r: [AA, BB]) => CurriedFunction1) & - ((...r: [AA, BB, CC]) => R); - declare type CurriedFunction3 = __CurriedFunction3< - A, - B, - C, - R, - *, - *, - * - >; - - declare type __CurriedFunction4< - A, - B, - C, - D, - R, - AA: A, - BB: B, - CC: C, - DD: D - > = ((...r: [AA]) => CurriedFunction3) & - ((...r: [AA, BB]) => CurriedFunction2) & - ((...r: [AA, BB, CC]) => CurriedFunction1) & - ((...r: [AA, BB, CC, DD]) => R); - declare type CurriedFunction4 = __CurriedFunction4< - A, - B, - C, - D, - R, - *, - *, - *, - * - >; - - declare type __CurriedFunction5< - A, - B, - C, - D, - E, - R, - AA: A, - BB: B, - CC: C, - DD: D, - EE: E - > = ((...r: [AA]) => CurriedFunction4) & - ((...r: [AA, BB]) => CurriedFunction3) & - ((...r: [AA, BB, CC]) => CurriedFunction2) & - ((...r: [AA, BB, CC, DD]) => CurriedFunction1) & - ((...r: [AA, BB, CC, DD, EE]) => R); - declare type CurriedFunction5 = __CurriedFunction5< - A, - B, - C, - D, - E, - R, - *, - *, - *, - *, - * - >; - - declare type __CurriedFunction6< - A, - B, - C, - D, - E, - F, - R, - AA: A, - BB: B, - CC: C, - DD: D, - EE: E, - FF: F - > = ((...r: [AA]) => CurriedFunction5) & - ((...r: [AA, BB]) => CurriedFunction4) & - ((...r: [AA, BB, CC]) => CurriedFunction3) & - ((...r: [AA, BB, CC, DD]) => CurriedFunction2) & - ((...r: [AA, BB, CC, DD, EE]) => CurriedFunction1) & - ((...r: [AA, BB, CC, DD, EE, FF]) => R); - declare type CurriedFunction6 = __CurriedFunction6< - A, - B, - C, - D, - E, - F, - R, - *, - *, - *, - *, - *, - * - >; - - declare type Curry = (((...r: [A]) => R) => CurriedFunction1) & - (((...r: [A, B]) => R) => CurriedFunction2) & - (((...r: [A, B, C]) => R) => CurriedFunction3) & - (( - (...r: [A, B, C, D]) => R - ) => CurriedFunction4) & - (( - (...r: [A, B, C, D, E]) => R - ) => CurriedFunction5) & - (( - (...r: [A, B, C, D, E, F]) => R - ) => CurriedFunction6); - - declare type UnaryFn = (a: A) => R; - - declare type TemplateSettings = { - escape?: RegExp, - evaluate?: RegExp, - imports?: Object, - interpolate?: RegExp, - variable?: string - }; - - declare type TruncateOptions = { - length?: number, - omission?: string, - separator?: RegExp | string - }; - - declare type DebounceOptions = { - leading?: boolean, - maxWait?: number, - trailing?: boolean - }; - - declare type ThrottleOptions = { - leading?: boolean, - trailing?: boolean - }; - - declare type NestedArray = Array>; - - declare type matchesIterateeShorthand = Object; - declare type matchesPropertyIterateeShorthand = [string, any]; - declare type propertyIterateeShorthand = string; - - declare type OPredicate = - | ((value: A) => any) - | matchesIterateeShorthand - | matchesPropertyIterateeShorthand - | propertyIterateeShorthand; - - declare type OIterateeWithResult = Object | string | ((value: V) => R); - declare type OIteratee = OIterateeWithResult; - declare type OFlatMapIteratee = OIterateeWithResult>; - - declare type Predicate = - | ((value: T) => any) - | matchesIterateeShorthand - | matchesPropertyIterateeShorthand - | propertyIterateeShorthand; - - declare type _ValueOnlyIteratee = (value: T) => mixed; - declare type ValueOnlyIteratee = _ValueOnlyIteratee | string; - declare type _Iteratee = (item: T) => mixed; - declare type Iteratee = _Iteratee | Object | string; - declare type FlatMapIteratee = - | ((item: T) => Array) - | Object - | string; - declare type Comparator = (item: T, item2: T) => boolean; - - declare type MapIterator = ((item: T) => U) | propertyIterateeShorthand; - - declare type OMapIterator = - | ((item: T) => U) - | propertyIterateeShorthand; - - declare class Lodash { - // Array - chunk(size: number): (array: Array) => Array>; - chunk(size: number, array: Array): Array>; - compact(array: Array): Array; - concat | T, B: Array | U>( - base: A - ): (elements: B) => Array; - concat | T, B: Array | U>( - base: A, - elements: B - ): Array; - difference(values: Array): (array: Array) => Array; - difference(values: Array, array: Array): Array; - differenceBy( - iteratee: ValueOnlyIteratee - ): ((values: Array) => (array: Array) => T[]) & - ((values: Array, array: Array) => T[]); - differenceBy( - iteratee: ValueOnlyIteratee, - values: Array - ): (array: Array) => T[]; - differenceBy( - iteratee: ValueOnlyIteratee, - values: Array, - array: Array - ): T[]; - differenceWith( - values: T[] - ): ((comparator: Comparator) => (array: T[]) => T[]) & - ((comparator: Comparator, array: T[]) => T[]); - differenceWith( - values: T[], - comparator: Comparator - ): (array: T[]) => T[]; - differenceWith(values: T[], comparator: Comparator, array: T[]): T[]; - drop(n: number): (array: Array) => Array; - drop(n: number, array: Array): Array; - dropLast(n: number): (array: Array) => Array; - dropLast(n: number, array: Array): Array; - dropRight(n: number): (array: Array) => Array; - dropRight(n: number, array: Array): Array; - dropRightWhile(predicate: Predicate): (array: Array) => Array; - dropRightWhile(predicate: Predicate, array: Array): Array; - dropWhile(predicate: Predicate): (array: Array) => Array; - dropWhile(predicate: Predicate, array: Array): Array; - dropLastWhile(predicate: Predicate): (array: Array) => Array; - dropLastWhile(predicate: Predicate, array: Array): Array; - fill( - start: number - ): (( - end: number - ) => ((value: U) => (array: Array) => Array) & - ((value: U, array: Array) => Array)) & - ((end: number, value: U) => (array: Array) => Array) & - ((end: number, value: U, array: Array) => Array); - fill( - start: number, - end: number - ): ((value: U) => (array: Array) => Array) & - ((value: U, array: Array) => Array); - fill( - start: number, - end: number, - value: U - ): (array: Array) => Array; - fill( - start: number, - end: number, - value: U, - array: Array - ): Array; - findIndex(predicate: Predicate): (array: $ReadOnlyArray) => number; - findIndex(predicate: Predicate, array: $ReadOnlyArray): number; - findIndexFrom( - predicate: Predicate - ): ((fromIndex: number) => (array: $ReadOnlyArray) => number) & - ((fromIndex: number, array: $ReadOnlyArray) => number); - findIndexFrom( - predicate: Predicate, - fromIndex: number - ): (array: $ReadOnlyArray) => number; - findIndexFrom( - predicate: Predicate, - fromIndex: number, - array: $ReadOnlyArray - ): number; - findLastIndex( - predicate: Predicate - ): (array: $ReadOnlyArray) => number; - findLastIndex(predicate: Predicate, array: $ReadOnlyArray): number; - findLastIndexFrom( - predicate: Predicate - ): ((fromIndex: number) => (array: $ReadOnlyArray) => number) & - ((fromIndex: number, array: $ReadOnlyArray) => number); - findLastIndexFrom( - predicate: Predicate, - fromIndex: number - ): (array: $ReadOnlyArray) => number; - findLastIndexFrom( - predicate: Predicate, - fromIndex: number, - array: $ReadOnlyArray - ): number; - // alias of _.head - first(array: Array): T; - flatten(array: Array | X>): Array; - unnest(array: Array | X>): Array; - flattenDeep(array: any[]): Array; - flattenDepth(depth: number): (array: any[]) => any[]; - flattenDepth(depth: number, array: any[]): any[]; - fromPairs(pairs: Array<[A, B]>): { [key: A]: B }; - head(array: Array): T; - indexOf(value: T): (array: Array) => number; - indexOf(value: T, array: Array): number; - indexOfFrom( - value: T - ): ((fromIndex: number) => (array: Array) => number) & - ((fromIndex: number, array: Array) => number); - indexOfFrom(value: T, fromIndex: number): (array: Array) => number; - indexOfFrom(value: T, fromIndex: number, array: Array): number; - initial(array: Array): Array; - init(array: Array): Array; - intersection(a1: Array): (a2: Array) => Array; - intersection(a1: Array, a2: Array): Array; - intersectionBy( - iteratee: ValueOnlyIteratee - ): ((a1: Array) => (a2: Array) => Array) & - ((a1: Array, a2: Array) => Array); - intersectionBy( - iteratee: ValueOnlyIteratee, - a1: Array - ): (a2: Array) => Array; - intersectionBy( - iteratee: ValueOnlyIteratee, - a1: Array, - a2: Array - ): Array; - intersectionWith( - comparator: Comparator - ): ((a1: Array) => (a2: Array) => Array) & - ((a1: Array, a2: Array) => Array); - intersectionWith( - comparator: Comparator, - a1: Array - ): (a2: Array) => Array; - intersectionWith( - comparator: Comparator, - a1: Array, - a2: Array - ): Array; - join(separator: string): (array: Array) => string; - join(separator: string, array: Array): string; - last(array: Array): T; - lastIndexOf(value: T): (array: Array) => number; - lastIndexOf(value: T, array: Array): number; - lastIndexOfFrom( - value: T - ): ((fromIndex: number) => (array: Array) => number) & - ((fromIndex: number, array: Array) => number); - lastIndexOfFrom( - value: T, - fromIndex: number - ): (array: Array) => number; - lastIndexOfFrom(value: T, fromIndex: number, array: Array): number; - nth(n: number): (array: T[]) => T; - nth(n: number, array: T[]): T; - pull(value: T): (array: Array) => Array; - pull(value: T, array: Array): Array; - pullAll(values: Array): (array: Array) => Array; - pullAll(values: Array, array: Array): Array; - pullAllBy( - iteratee: ValueOnlyIteratee - ): ((values: Array) => (array: Array) => Array) & - ((values: Array, array: Array) => Array); - pullAllBy( - iteratee: ValueOnlyIteratee, - values: Array - ): (array: Array) => Array; - pullAllBy( - iteratee: ValueOnlyIteratee, - values: Array, - array: Array - ): Array; - pullAllWith( - comparator: Function - ): ((values: T[]) => (array: T[]) => T[]) & - ((values: T[], array: T[]) => T[]); - pullAllWith(comparator: Function, values: T[]): (array: T[]) => T[]; - pullAllWith(comparator: Function, values: T[], array: T[]): T[]; - pullAt(indexed: Array): (array: Array) => Array; - pullAt(indexed: Array, array: Array): Array; - remove(predicate: Predicate): (array: Array) => Array; - remove(predicate: Predicate, array: Array): Array; - reverse(array: Array): Array; - slice( - start: number - ): ((end: number) => (array: Array) => Array) & - ((end: number, array: Array) => Array); - slice(start: number, end: number): (array: Array) => Array; - slice(start: number, end: number, array: Array): Array; - sortedIndex(value: T): (array: Array) => number; - sortedIndex(value: T, array: Array): number; - sortedIndexBy( - iteratee: ValueOnlyIteratee - ): ((value: T) => (array: Array) => number) & - ((value: T, array: Array) => number); - sortedIndexBy( - iteratee: ValueOnlyIteratee, - value: T - ): (array: Array) => number; - sortedIndexBy( - iteratee: ValueOnlyIteratee, - value: T, - array: Array - ): number; - sortedIndexOf(value: T): (array: Array) => number; - sortedIndexOf(value: T, array: Array): number; - sortedLastIndex(value: T): (array: Array) => number; - sortedLastIndex(value: T, array: Array): number; - sortedLastIndexBy( - iteratee: ValueOnlyIteratee - ): ((value: T) => (array: Array) => number) & - ((value: T, array: Array) => number); - sortedLastIndexBy( - iteratee: ValueOnlyIteratee, - value: T - ): (array: Array) => number; - sortedLastIndexBy( - iteratee: ValueOnlyIteratee, - value: T, - array: Array - ): number; - sortedLastIndexOf(value: T): (array: Array) => number; - sortedLastIndexOf(value: T, array: Array): number; - sortedUniq(array: Array): Array; - sortedUniqBy( - iteratee: (value: T) => mixed - ): (array: Array) => Array; - sortedUniqBy(iteratee: (value: T) => mixed, array: Array): Array; - tail(array: Array): Array; - take(n: number): (array: Array) => Array; - take(n: number, array: Array): Array; - takeRight(n: number): (array: Array) => Array; - takeRight(n: number, array: Array): Array; - takeLast(n: number): (array: Array) => Array; - takeLast(n: number, array: Array): Array; - takeRightWhile(predicate: Predicate): (array: Array) => Array; - takeRightWhile(predicate: Predicate, array: Array): Array; - takeLastWhile(predicate: Predicate): (array: Array) => Array; - takeLastWhile(predicate: Predicate, array: Array): Array; - takeWhile(predicate: Predicate): (array: Array) => Array; - takeWhile(predicate: Predicate, array: Array): Array; - union(a1: Array): (a2: Array) => Array; - union(a1: Array, a2: Array): Array; - unionBy( - iteratee: ValueOnlyIteratee - ): ((a1: Array) => (a2: Array) => Array) & - ((a1: Array, a2: Array) => Array); - unionBy( - iteratee: ValueOnlyIteratee, - a1: Array - ): (a2: Array) => Array; - unionBy( - iteratee: ValueOnlyIteratee, - a1: Array, - a2: Array - ): Array; - unionWith( - comparator: Comparator - ): ((a1: Array) => (a2: Array) => Array) & - ((a1: Array, a2: Array) => Array); - unionWith( - comparator: Comparator, - a1: Array - ): (a2: Array) => Array; - unionWith( - comparator: Comparator, - a1: Array, - a2: Array - ): Array; - uniq(array: Array): Array; - uniqBy(iteratee: ValueOnlyIteratee): (array: Array) => Array; - uniqBy(iteratee: ValueOnlyIteratee, array: Array): Array; - uniqWith(comparator: Comparator): (array: Array) => Array; - uniqWith(comparator: Comparator, array: Array): Array; - unzip(array: Array): Array; - unzipWith(iteratee: Iteratee): (array: Array) => Array; - unzipWith(iteratee: Iteratee, array: Array): Array; - without(values: Array): (array: Array) => Array; - without(values: Array, array: Array): Array; - xor(a1: Array): (a2: Array) => Array; - xor(a1: Array, a2: Array): Array; - symmetricDifference(a1: Array): (a2: Array) => Array; - symmetricDifference(a1: Array, a2: Array): Array; - xorBy( - iteratee: ValueOnlyIteratee - ): ((a1: Array) => (a2: Array) => Array) & - ((a1: Array, a2: Array) => Array); - xorBy( - iteratee: ValueOnlyIteratee, - a1: Array - ): (a2: Array) => Array; - xorBy( - iteratee: ValueOnlyIteratee, - a1: Array, - a2: Array - ): Array; - symmetricDifferenceBy( - iteratee: ValueOnlyIteratee - ): ((a1: Array) => (a2: Array) => Array) & - ((a1: Array, a2: Array) => Array); - symmetricDifferenceBy( - iteratee: ValueOnlyIteratee, - a1: Array - ): (a2: Array) => Array; - symmetricDifferenceBy( - iteratee: ValueOnlyIteratee, - a1: Array, - a2: Array - ): Array; - xorWith( - comparator: Comparator - ): ((a1: Array) => (a2: Array) => Array) & - ((a1: Array, a2: Array) => Array); - xorWith( - comparator: Comparator, - a1: Array - ): (a2: Array) => Array; - xorWith(comparator: Comparator, a1: Array, a2: Array): Array; - symmetricDifferenceWith( - comparator: Comparator - ): ((a1: Array) => (a2: Array) => Array) & - ((a1: Array, a2: Array) => Array); - symmetricDifferenceWith( - comparator: Comparator, - a1: Array - ): (a2: Array) => Array; - symmetricDifferenceWith( - comparator: Comparator, - a1: Array, - a2: Array - ): Array; - zip(a1: A[]): (a2: B[]) => Array<[A, B]>; - zip(a1: A[], a2: B[]): Array<[A, B]>; - zipAll(arrays: Array>): Array; - zipObject(props?: Array): (values?: Array) => { [key: K]: V }; - zipObject(props?: Array, values?: Array): { [key: K]: V }; - zipObj(props: Array): (values: Array) => Object; - zipObj(props: Array, values: Array): Object; - zipObjectDeep(props: any[]): (values: any) => Object; - zipObjectDeep(props: any[], values: any): Object; - zipWith( - iteratee: Iteratee - ): ((a1: NestedArray) => (a2: NestedArray) => Array) & - ((a1: NestedArray, a2: NestedArray) => Array); - zipWith( - iteratee: Iteratee, - a1: NestedArray - ): (a2: NestedArray) => Array; - zipWith( - iteratee: Iteratee, - a1: NestedArray, - a2: NestedArray - ): Array; - // Collection - countBy( - iteratee: ValueOnlyIteratee - ): (collection: Array | { [id: any]: T }) => { [string]: number }; - countBy( - iteratee: ValueOnlyIteratee, - collection: Array | { [id: any]: T } - ): { [string]: number }; - // alias of _.forEach - each( - iteratee: Iteratee | OIteratee - ): (collection: Array | { [id: any]: T }) => Array; - each( - iteratee: Iteratee | OIteratee, - collection: Array | { [id: any]: T } - ): Array; - // alias of _.forEachRight - eachRight( - iteratee: Iteratee | OIteratee - ): (collection: Array | { [id: any]: T }) => Array; - eachRight( - iteratee: Iteratee | OIteratee, - collection: Array | { [id: any]: T } - ): Array; - every( - iteratee: Iteratee | OIteratee - ): (collection: Array | { [id: any]: T }) => boolean; - every( - iteratee: Iteratee | OIteratee, - collection: Array | { [id: any]: T } - ): boolean; - all( - iteratee: Iteratee | OIteratee - ): (collection: Array | { [id: any]: T }) => boolean; - all( - iteratee: Iteratee | OIteratee, - collection: Array | { [id: any]: T } - ): boolean; - filter( - predicate: Predicate | OPredicate - ): (collection: Array | { [id: any]: T }) => Array; - filter( - predicate: Predicate | OPredicate, - collection: Array | { [id: any]: T } - ): Array; - find( - predicate: Predicate | OPredicate - ): (collection: $ReadOnlyArray | { [id: any]: T }) => T | void; - find( - predicate: Predicate | OPredicate, - collection: $ReadOnlyArray | { [id: any]: T } - ): T | void; - findFrom( - predicate: Predicate | OPredicate - ): (( - fromIndex: number - ) => (collection: $ReadOnlyArray | { [id: any]: T }) => T | void) & - (( - fromIndex: number, - collection: $ReadOnlyArray | { [id: any]: T } - ) => T | void); - findFrom( - predicate: Predicate | OPredicate, - fromIndex: number - ): (collection: Array | { [id: any]: T }) => T | void; - findFrom( - predicate: Predicate | OPredicate, - fromIndex: number, - collection: $ReadOnlyArray | { [id: any]: T } - ): T | void; - findLast( - predicate: Predicate | OPredicate - ): (collection: $ReadOnlyArray | { [id: any]: T }) => T | void; - findLast( - predicate: Predicate | OPredicate, - collection: $ReadOnlyArray | { [id: any]: T } - ): T | void; - findLastFrom( - predicate: Predicate | OPredicate - ): (( - fromIndex: number - ) => (collection: $ReadOnlyArray | { [id: any]: T }) => T | void) & - (( - fromIndex: number, - collection: $ReadOnlyArray | { [id: any]: T } - ) => T | void); - findLastFrom( - predicate: Predicate | OPredicate, - fromIndex: number - ): (collection: $ReadOnlyArray | { [id: any]: T }) => T | void; - findLastFrom( - predicate: Predicate | OPredicate, - fromIndex: number, - collection: $ReadOnlyArray | { [id: any]: T } - ): T | void; - flatMap( - iteratee: FlatMapIteratee | OFlatMapIteratee - ): (collection: Array | { [id: any]: T }) => Array; - flatMap( - iteratee: FlatMapIteratee | OFlatMapIteratee, - collection: Array | { [id: any]: T } - ): Array; - flatMapDeep( - iteratee: FlatMapIteratee | OFlatMapIteratee - ): (collection: Array | { [id: any]: T }) => Array; - flatMapDeep( - iteratee: FlatMapIteratee | OFlatMapIteratee, - collection: Array | { [id: any]: T } - ): Array; - flatMapDepth( - iteratee: FlatMapIteratee | OFlatMapIteratee - ): (( - depth: number - ) => (collection: Array | { [id: any]: T }) => Array) & - ((depth: number, collection: Array | { [id: any]: T }) => Array); - flatMapDepth( - iteratee: FlatMapIteratee | OFlatMapIteratee, - depth: number - ): (collection: Array | { [id: any]: T }) => Array; - flatMapDepth( - iteratee: FlatMapIteratee | OFlatMapIteratee, - depth: number, - collection: Array | { [id: any]: T } - ): Array; - forEach( - iteratee: Iteratee | OIteratee - ): (collection: Array | { [id: any]: T }) => Array; - forEach( - iteratee: Iteratee | OIteratee, - collection: Array | { [id: any]: T } - ): Array; - forEachRight( - iteratee: Iteratee | OIteratee - ): (collection: Array | { [id: any]: T }) => Array; - forEachRight( - iteratee: Iteratee | OIteratee, - collection: Array | { [id: any]: T } - ): Array; - groupBy( - iteratee: ValueOnlyIteratee - ): (collection: Array | { [id: any]: T }) => { [key: V]: Array }; - groupBy( - iteratee: ValueOnlyIteratee, - collection: Array | { [id: any]: T } - ): { [key: V]: Array }; - includes(value: string): (str: string) => boolean; - includes(value: string, str: string): boolean; - includes(value: T): (collection: Array | { [id: any]: T }) => boolean; - includes(value: T, collection: Array | { [id: any]: T }): boolean; - contains(value: string): (str: string) => boolean; - contains(value: string, str: string): boolean; - contains(value: T): (collection: Array | { [id: any]: T }) => boolean; - contains(value: T, collection: Array | { [id: any]: T }): boolean; - includesFrom( - value: string - ): ((fromIndex: number) => (str: string) => boolean) & - ((fromIndex: number, str: string) => boolean); - includesFrom(value: string, fromIndex: number): (str: string) => boolean; - includesFrom(value: string, fromIndex: number, str: string): boolean; - includesFrom( - value: T - ): ((fromIndex: number) => (collection: Array) => boolean) & - ((fromIndex: number, collection: Array) => boolean); - includesFrom( - value: T, - fromIndex: number - ): (collection: Array) => boolean; - includesFrom(value: T, fromIndex: number, collection: Array): boolean; - invokeMap( - path: ((value: T) => Array | string) | Array | string - ): (collection: Array | { [id: any]: T }) => Array; - invokeMap( - path: ((value: T) => Array | string) | Array | string, - collection: Array | { [id: any]: T } - ): Array; - invokeArgsMap( - path: ((value: T) => Array | string) | Array | string - ): (( - collection: Array | { [id: any]: T } - ) => (args: Array) => Array) & - (( - collection: Array | { [id: any]: T }, - args: Array - ) => Array); - invokeArgsMap( - path: ((value: T) => Array | string) | Array | string, - collection: Array | { [id: any]: T } - ): (args: Array) => Array; - invokeArgsMap( - path: ((value: T) => Array | string) | Array | string, - collection: Array | { [id: any]: T }, - args: Array - ): Array; - keyBy( - iteratee: ValueOnlyIteratee - ): (collection: Array | { [id: any]: T }) => { [key: V]: T }; - keyBy( - iteratee: ValueOnlyIteratee, - collection: Array | { [id: any]: T } - ): { [key: V]: T }; - indexBy( - iteratee: ValueOnlyIteratee - ): (collection: Array | { [id: any]: T }) => { [key: V]: T }; - indexBy( - iteratee: ValueOnlyIteratee, - collection: Array | { [id: any]: T } - ): { [key: V]: T }; - map( - iteratee: MapIterator | OMapIterator - ): (collection: Array | { [id: any]: T }) => Array; - map( - iteratee: MapIterator | OMapIterator, - collection: Array | { [id: any]: T } - ): Array; - map(iteratee: (char: string) => any): (str: string) => string; - map(iteratee: (char: string) => any, str: string): string; - pluck( - iteratee: MapIterator | OMapIterator - ): (collection: Array | { [id: any]: T }) => Array; - pluck( - iteratee: MapIterator | OMapIterator, - collection: Array | { [id: any]: T } - ): Array; - pluck(iteratee: (char: string) => any): (str: string) => string; - pluck(iteratee: (char: string) => any, str: string): string; - orderBy( - iteratees: Array | OIteratee<*>> | string - ): (( - orders: Array<"asc" | "desc"> | string - ) => (collection: Array | { [id: any]: T }) => Array) & - (( - orders: Array<"asc" | "desc"> | string, - collection: Array | { [id: any]: T } - ) => Array); - orderBy( - iteratees: Array | OIteratee<*>> | string, - orders: Array<"asc" | "desc"> | string - ): (collection: Array | { [id: any]: T }) => Array; - orderBy( - iteratees: Array | OIteratee<*>> | string, - orders: Array<"asc" | "desc"> | string, - collection: Array | { [id: any]: T } - ): Array; - partition( - predicate: Predicate | OPredicate - ): (collection: Array | { [id: any]: T }) => [Array, Array]; - partition( - predicate: Predicate | OPredicate, - collection: Array | { [id: any]: T } - ): [Array, Array]; - reduce( - iteratee: (accumulator: U, value: T) => U - ): ((accumulator: U) => (collection: Array | { [id: any]: T }) => U) & - ((accumulator: U, collection: Array | { [id: any]: T }) => U); - reduce( - iteratee: (accumulator: U, value: T) => U, - accumulator: U - ): (collection: Array | { [id: any]: T }) => U; - reduce( - iteratee: (accumulator: U, value: T) => U, - accumulator: U, - collection: Array | { [id: any]: T } - ): U; - reduceRight( - iteratee: (value: T, accumulator: U) => U - ): ((accumulator: U) => (collection: Array | { [id: any]: T }) => U) & - ((accumulator: U, collection: Array | { [id: any]: T }) => U); - reduceRight( - iteratee: (value: T, accumulator: U) => U, - accumulator: U - ): (collection: Array | { [id: any]: T }) => U; - reduceRight( - iteratee: (value: T, accumulator: U) => U, - accumulator: U, - collection: Array | { [id: any]: T } - ): U; - reject( - predicate: Predicate | OPredicate - ): (collection: Array | { [id: any]: T }) => Array; - reject( - predicate: Predicate | OPredicate, - collection: Array | { [id: any]: T } - ): Array; - sample(collection: Array | { [id: any]: T }): T; - sampleSize( - n: number - ): (collection: Array | { [id: any]: T }) => Array; - sampleSize(n: number, collection: Array | { [id: any]: T }): Array; - shuffle(collection: Array | { [id: any]: T }): Array; - size(collection: Array | Object): number; - some( - predicate: Predicate | OPredicate - ): (collection: Array | { [id: any]: T }) => boolean; - some( - predicate: Predicate | OPredicate, - collection: Array | { [id: any]: T } - ): boolean; - any( - predicate: Predicate | OPredicate - ): (collection: Array | { [id: any]: T }) => boolean; - any( - predicate: Predicate | OPredicate, - collection: Array | { [id: any]: T } - ): boolean; - sortBy( - iteratees: Array | OIteratee> | Iteratee | OIteratee - ): (collection: Array | { [id: any]: T }) => Array; - sortBy( - iteratees: Array | OIteratee> | Iteratee | OIteratee, - collection: Array | { [id: any]: T } - ): Array; - - // Date - now(): number; - - // Function - after(fn: Function): (n: number) => Function; - after(fn: Function, n: number): Function; - ary(func: Function): Function; - nAry(n: number): (func: Function) => Function; - nAry(n: number, func: Function): Function; - before(fn: Function): (n: number) => Function; - before(fn: Function, n: number): Function; - bind(func: Function): (thisArg: any) => Function; - bind(func: Function, thisArg: any): Function; - bindKey(obj: Object): (key: string) => Function; - bindKey(obj: Object, key: string): Function; - curry: Curry; - curryN(arity: number): (func: Function) => Function; - curryN(arity: number, func: Function): Function; - curryRight(func: Function): Function; - curryRightN(arity: number): (func: Function) => Function; - curryRightN(arity: number, func: Function): Function; - debounce(wait: number): (func: F) => F; - debounce(wait: number, func: F): F; - defer(func: Function): number; - delay(wait: number): (func: Function) => number; - delay(wait: number, func: Function): number; - flip(func: Function): Function; - memoize(func: F): F; - negate(predicate: Function): Function; - complement(predicate: Function): Function; - once(func: Function): Function; - overArgs(func: Function): (transforms: Array) => Function; - overArgs(func: Function, transforms: Array): Function; - useWith(func: Function): (transforms: Array) => Function; - useWith(func: Function, transforms: Array): Function; - partial(func: Function): (partials: any[]) => Function; - partial(func: Function, partials: any[]): Function; - partialRight(func: Function): (partials: Array) => Function; - partialRight(func: Function, partials: Array): Function; - rearg(indexes: Array): (func: Function) => Function; - rearg(indexes: Array, func: Function): Function; - rest(func: Function): Function; - unapply(func: Function): Function; - restFrom(start: number): (func: Function) => Function; - restFrom(start: number, func: Function): Function; - spread(func: Function): Function; - apply(func: Function): Function; - spreadFrom(start: number): (func: Function) => Function; - spreadFrom(start: number, func: Function): Function; - throttle(wait: number): (func: Function) => Function; - throttle(wait: number, func: Function): Function; - unary(func: Function): Function; - wrap(wrapper: Function): (value: any) => Function; - wrap(wrapper: Function, value: any): Function; - - // Lang - castArray(value: *): any[]; - clone(value: T): T; - cloneDeep(value: T): T; - cloneDeepWith( - customizer: (value: T, key: number | string, object: T, stack: any) => U - ): (value: T) => U; - cloneDeepWith( - customizer: (value: T, key: number | string, object: T, stack: any) => U, - value: T - ): U; - cloneWith( - customizer: (value: T, key: number | string, object: T, stack: any) => U - ): (value: T) => U; - cloneWith( - customizer: (value: T, key: number | string, object: T, stack: any) => U, - value: T - ): U; - conformsTo( - predicates: T & { [key: string]: (x: any) => boolean } - ): (source: T) => boolean; - conformsTo( - predicates: T & { [key: string]: (x: any) => boolean }, - source: T - ): boolean; - where( - predicates: T & { [key: string]: (x: any) => boolean } - ): (source: T) => boolean; - where( - predicates: T & { [key: string]: (x: any) => boolean }, - source: T - ): boolean; - conforms( - predicates: T & { [key: string]: (x: any) => boolean } - ): (source: T) => boolean; - conforms( - predicates: T & { [key: string]: (x: any) => boolean }, - source: T - ): boolean; - eq(value: any): (other: any) => boolean; - eq(value: any, other: any): boolean; - identical(value: any): (other: any) => boolean; - identical(value: any, other: any): boolean; - gt(value: any): (other: any) => boolean; - gt(value: any, other: any): boolean; - gte(value: any): (other: any) => boolean; - gte(value: any, other: any): boolean; - isArguments(value: any): boolean; - isArray(value: any): boolean; - isArrayBuffer(value: any): boolean; - isArrayLike(value: any): boolean; - isArrayLikeObject(value: any): boolean; - isBoolean(value: any): boolean; - isBuffer(value: any): boolean; - isDate(value: any): boolean; - isElement(value: any): boolean; - isEmpty(value: any): boolean; - isEqual(value: any): (other: any) => boolean; - isEqual(value: any, other: any): boolean; - equals(value: any): (other: any) => boolean; - equals(value: any, other: any): boolean; - isEqualWith( - customizer: ( - objValue: any, - otherValue: any, - key: number | string, - object: T, - other: U, - stack: any - ) => boolean | void - ): ((value: T) => (other: U) => boolean) & - ((value: T, other: U) => boolean); - isEqualWith( - customizer: ( - objValue: any, - otherValue: any, - key: number | string, - object: T, - other: U, - stack: any - ) => boolean | void, - value: T - ): (other: U) => boolean; - isEqualWith( - customizer: ( - objValue: any, - otherValue: any, - key: number | string, - object: T, - other: U, - stack: any - ) => boolean | void, - value: T, - other: U - ): boolean; - isError(value: any): boolean; - isFinite(value: any): boolean; - isFunction(value: Function): true; - isFunction(value: number | string | void | null | Object): false; - isInteger(value: any): boolean; - isLength(value: any): boolean; - isMap(value: any): boolean; - isMatch(source: Object): (object: Object) => boolean; - isMatch(source: Object, object: Object): boolean; - whereEq(source: Object): (object: Object) => boolean; - whereEq(source: Object, object: Object): boolean; - isMatchWith( - customizer: ( - objValue: any, - srcValue: any, - key: number | string, - object: T, - source: U - ) => boolean | void - ): ((source: U) => (object: T) => boolean) & - ((source: U, object: T) => boolean); - isMatchWith( - customizer: ( - objValue: any, - srcValue: any, - key: number | string, - object: T, - source: U - ) => boolean | void, - source: U - ): (object: T) => boolean; - isMatchWith( - customizer: ( - objValue: any, - srcValue: any, - key: number | string, - object: T, - source: U - ) => boolean | void, - source: U, - object: T - ): boolean; - isNaN(value: any): boolean; - isNative(value: any): boolean; - isNil(value: any): boolean; - isNull(value: any): boolean; - isNumber(value: any): boolean; - isObject(value: any): boolean; - isObjectLike(value: any): boolean; - isPlainObject(value: any): boolean; - isRegExp(value: any): boolean; - isSafeInteger(value: any): boolean; - isSet(value: any): boolean; - isString(value: string): true; - isString( - value: number | boolean | Function | void | null | Object | Array - ): false; - isSymbol(value: any): boolean; - isTypedArray(value: any): boolean; - isUndefined(value: any): boolean; - isWeakMap(value: any): boolean; - isWeakSet(value: any): boolean; - lt(value: any): (other: any) => boolean; - lt(value: any, other: any): boolean; - lte(value: any): (other: any) => boolean; - lte(value: any, other: any): boolean; - toArray(value: any): Array; - toFinite(value: any): number; - toInteger(value: any): number; - toLength(value: any): number; - toNumber(value: any): number; - toPlainObject(value: any): Object; - toSafeInteger(value: any): number; - toString(value: any): string; - - // Math - add(augend: number): (addend: number) => number; - add(augend: number, addend: number): number; - ceil(number: number): number; - divide(dividend: number): (divisor: number) => number; - divide(dividend: number, divisor: number): number; - floor(number: number): number; - max(array: Array): T; - maxBy(iteratee: Iteratee): (array: Array) => T; - maxBy(iteratee: Iteratee, array: Array): T; - mean(array: Array<*>): number; - meanBy(iteratee: Iteratee): (array: Array) => number; - meanBy(iteratee: Iteratee, array: Array): number; - min(array: Array): T; - minBy(iteratee: Iteratee): (array: Array) => T; - minBy(iteratee: Iteratee, array: Array): T; - multiply(multiplier: number): (multiplicand: number) => number; - multiply(multiplier: number, multiplicand: number): number; - round(number: number): number; - subtract(minuend: number): (subtrahend: number) => number; - subtract(minuend: number, subtrahend: number): number; - sum(array: Array<*>): number; - sumBy(iteratee: Iteratee): (array: Array) => number; - sumBy(iteratee: Iteratee, array: Array): number; - - // number - clamp( - lower: number - ): ((upper: number) => (number: number) => number) & - ((upper: number, number: number) => number); - clamp(lower: number, upper: number): (number: number) => number; - clamp(lower: number, upper: number, number: number): number; - inRange( - start: number - ): ((end: number) => (number: number) => boolean) & - ((end: number, number: number) => boolean); - inRange(start: number, end: number): (number: number) => boolean; - inRange(start: number, end: number, number: number): boolean; - random(lower: number): (upper: number) => number; - random(lower: number, upper: number): number; - - // Object - assign(object: Object): (source: Object) => Object; - assign(object: Object, source: Object): Object; - assignAll(objects: Array): Object; - assignInAll(objects: Array): Object; - extendAll(objects: Array): Object; - assignIn(a: A): (b: B) => A & B; - assignIn(a: A, b: B): A & B; - assignInWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A - ) => any | void - ): ((object: T) => (s1: A) => Object) & ((object: T, s1: A) => Object); - assignInWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A - ) => any | void, - object: T - ): (s1: A) => Object; - assignInWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A - ) => any | void, - object: T, - s1: A - ): Object; - assignWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A - ) => any | void - ): ((object: T) => (s1: A) => Object) & ((object: T, s1: A) => Object); - assignWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A - ) => any | void, - object: T - ): (s1: A) => Object; - assignWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A - ) => any | void, - object: T, - s1: A - ): Object; - assignInAllWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: Object, - source: Object - ) => any | void - ): (objects: Array) => Object; - assignInAllWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: Object, - source: Object - ) => any | void, - objects: Array - ): Object; - extendAllWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: Object, - source: Object - ) => any | void - ): (objects: Array) => Object; - extendAllWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: Object, - source: Object - ) => any | void, - objects: Array - ): Object; - assignAllWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: Object, - source: Object - ) => any | void - ): (objects: Array) => Object; - assignAllWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: Object, - source: Object - ) => any | void, - objects: Array - ): Object; - at(paths: Array): (object: Object) => Array; - at(paths: Array, object: Object): Array; - props(paths: Array): (object: Object) => Array; - props(paths: Array, object: Object): Array; - paths(paths: Array): (object: Object) => Array; - paths(paths: Array, object: Object): Array; - create(prototype: T): $Supertype; - defaults(source: Object): (object: Object) => Object; - defaults(source: Object, object: Object): Object; - defaultsAll(objects: Array): Object; - defaultsDeep(source: Object): (object: Object) => Object; - defaultsDeep(source: Object, object: Object): Object; - defaultsDeepAll(objects: Array): Object; - // alias for _.toPairs - entries(object: Object): NestedArray; - // alias for _.toPairsIn - entriesIn(object: Object): NestedArray; - // alias for _.assignIn - extend(a: A): (b: B) => A & B; - extend(a: A, b: B): A & B; - // alias for _.assignInWith - extendWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A - ) => any | void - ): ((object: T) => (s1: A) => Object) & ((object: T, s1: A) => Object); - extendWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A - ) => any | void, - object: T - ): (s1: A) => Object; - extendWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A - ) => any | void, - object: T, - s1: A - ): Object; - findKey( - predicate: OPredicate - ): (object: T) => string | void; - findKey( - predicate: OPredicate, - object: T - ): string | void; - findLastKey( - predicate: OPredicate - ): (object: T) => string | void; - findLastKey( - predicate: OPredicate, - object: T - ): string | void; - forIn(iteratee: OIteratee<*>): (object: Object) => Object; - forIn(iteratee: OIteratee<*>, object: Object): Object; - forInRight(iteratee: OIteratee<*>): (object: Object) => Object; - forInRight(iteratee: OIteratee<*>, object: Object): Object; - forOwn(iteratee: OIteratee<*>): (object: Object) => Object; - forOwn(iteratee: OIteratee<*>, object: Object): Object; - forOwnRight(iteratee: OIteratee<*>): (object: Object) => Object; - forOwnRight(iteratee: OIteratee<*>, object: Object): Object; - functions(object: Object): Array; - functionsIn(object: Object): Array; - get(path: Array | string): (object: Object | Array) => any; - get(path: Array | string, object: Object | Array): any; - prop(path: Array | string): (object: Object | Array) => any; - prop(path: Array | string, object: Object | Array): any; - path(path: Array | string): (object: Object | Array) => any; - path(path: Array | string, object: Object | Array): any; - getOr( - defaultValue: any - ): (( - path: Array | string - ) => (object: Object | Array) => any) & - ((path: Array | string, object: Object | Array) => any); - getOr( - defaultValue: any, - path: Array | string - ): (object: Object | Array) => any; - getOr( - defaultValue: any, - path: Array | string, - object: Object | Array - ): any; - propOr( - defaultValue: any - ): (( - path: Array | string - ) => (object: Object | Array) => any) & - ((path: Array | string, object: Object | Array) => any); - propOr( - defaultValue: any, - path: Array | string - ): (object: Object | Array) => any; - propOr( - defaultValue: any, - path: Array | string, - object: Object | Array - ): any; - pathOr( - defaultValue: any - ): (( - path: Array | string - ) => (object: Object | Array) => any) & - ((path: Array | string, object: Object | Array) => any); - pathOr( - defaultValue: any, - path: Array | string - ): (object: Object | Array) => any; - pathOr( - defaultValue: any, - path: Array | string, - object: Object | Array - ): any; - has(path: Array | string): (object: Object) => boolean; - has(path: Array | string, object: Object): boolean; - hasIn(path: Array | string): (object: Object) => boolean; - hasIn(path: Array | string, object: Object): boolean; - invert(object: Object): Object; - invertObj(object: Object): Object; - invertBy(iteratee: Function): (object: Object) => Object; - invertBy(iteratee: Function, object: Object): Object; - invoke(path: Array | string): (object: Object) => any; - invoke(path: Array | string, object: Object): any; - invokeArgs( - path: Array | string - ): ((object: Object) => (args: Array) => any) & - ((object: Object, args: Array) => any); - invokeArgs( - path: Array | string, - object: Object - ): (args: Array) => any; - invokeArgs( - path: Array | string, - object: Object, - args: Array - ): any; - keys(object: { [key: K]: any }): Array; - keys(object: Object): Array; - keysIn(object: Object): Array; - mapKeys(iteratee: OIteratee<*>): (object: Object) => Object; - mapKeys(iteratee: OIteratee<*>, object: Object): Object; - mapValues(iteratee: OIteratee<*>): (object: Object) => Object; - mapValues(iteratee: OIteratee<*>, object: Object): Object; - merge(object: Object): (source: Object) => Object; - merge(object: Object, source: Object): Object; - mergeAll(objects: Array): Object; - mergeWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A | B - ) => any | void - ): ((object: T) => (s1: A) => Object) & ((object: T, s1: A) => Object); - mergeWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A | B - ) => any | void, - object: T - ): (s1: A) => Object; - mergeWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: T, - source: A | B - ) => any | void, - object: T, - s1: A - ): Object; - mergeAllWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: Object, - source: Object - ) => any | void - ): (objects: Array) => Object; - mergeAllWith( - customizer: ( - objValue: any, - srcValue: any, - key: string, - object: Object, - source: Object - ) => any | void, - objects: Array - ): Object; - omit(props: Array): (object: Object) => Object; - omit(props: Array, object: Object): Object; - omitAll(props: Array): (object: Object) => Object; - omitAll(props: Array, object: Object): Object; - omitBy( - predicate: OPredicate - ): (object: T) => Object; - omitBy(predicate: OPredicate, object: T): Object; - pick(props: Array): (object: Object) => Object; - pick(props: Array, object: Object): Object; - pickAll(props: Array): (object: Object) => Object; - pickAll(props: Array, object: Object): Object; - pickBy( - predicate: OPredicate - ): (object: T) => Object; - pickBy(predicate: OPredicate, object: T): Object; - result(path: Array | string): (object: Object) => any; - result(path: Array | string, object: Object): any; - set( - path: Array | string - ): ((value: any) => (object: Object) => Object) & - ((value: any, object: Object) => Object); - set(path: Array | string, value: any): (object: Object) => Object; - set(path: Array | string, value: any, object: Object): Object; - assoc( - path: Array | string - ): ((value: any) => (object: Object) => Object) & - ((value: any, object: Object) => Object); - assoc(path: Array | string, value: any): (object: Object) => Object; - assoc(path: Array | string, value: any, object: Object): Object; - assocPath( - path: Array | string - ): ((value: any) => (object: Object) => Object) & - ((value: any, object: Object) => Object); - assocPath( - path: Array | string, - value: any - ): (object: Object) => Object; - assocPath(path: Array | string, value: any, object: Object): Object; - setWith( - customizer: (nsValue: any, key: string, nsObject: T) => any - ): (( - path: Array | string - ) => ((value: any) => (object: T) => Object) & - ((value: any, object: T) => Object)) & - ((path: Array | string, value: any) => (object: T) => Object) & - ((path: Array | string, value: any, object: T) => Object); - setWith( - customizer: (nsValue: any, key: string, nsObject: T) => any, - path: Array | string - ): ((value: any) => (object: T) => Object) & - ((value: any, object: T) => Object); - setWith( - customizer: (nsValue: any, key: string, nsObject: T) => any, - path: Array | string, - value: any - ): (object: T) => Object; - setWith( - customizer: (nsValue: any, key: string, nsObject: T) => any, - path: Array | string, - value: any, - object: T - ): Object; - toPairs(object: Object | Array<*>): NestedArray; - toPairsIn(object: Object): NestedArray; - transform( - iteratee: OIteratee<*> - ): ((accumulator: any) => (collection: Object | Array) => any) & - ((accumulator: any, collection: Object | Array) => any); - transform( - iteratee: OIteratee<*>, - accumulator: any - ): (collection: Object | Array) => any; - transform( - iteratee: OIteratee<*>, - accumulator: any, - collection: Object | Array - ): any; - unset(path: Array | string): (object: Object) => boolean; - unset(path: Array | string, object: Object): boolean; - dissoc(path: Array | string): (object: Object) => boolean; - dissoc(path: Array | string, object: Object): boolean; - dissocPath(path: Array | string): (object: Object) => boolean; - dissocPath(path: Array | string, object: Object): boolean; - update( - path: string[] | string - ): ((updater: Function) => (object: Object) => Object) & - ((updater: Function, object: Object) => Object); - update( - path: string[] | string, - updater: Function - ): (object: Object) => Object; - update(path: string[] | string, updater: Function, object: Object): Object; - updateWith( - customizer: Function - ): (( - path: string[] | string - ) => ((updater: Function) => (object: Object) => Object) & - ((updater: Function, object: Object) => Object)) & - (( - path: string[] | string, - updater: Function - ) => (object: Object) => Object) & - ((path: string[] | string, updater: Function, object: Object) => Object); - updateWith( - customizer: Function, - path: string[] | string - ): ((updater: Function) => (object: Object) => Object) & - ((updater: Function, object: Object) => Object); - updateWith( - customizer: Function, - path: string[] | string, - updater: Function - ): (object: Object) => Object; - updateWith( - customizer: Function, - path: string[] | string, - updater: Function, - object: Object - ): Object; - values(object: Object): Array; - valuesIn(object: Object): Array; - - tap(interceptor: (value: T) => any): (value: T) => T; - tap(interceptor: (value: T) => any, value: T): T; - thru(interceptor: (value: T1) => T2): (value: T1) => T2; - thru(interceptor: (value: T1) => T2, value: T1): T2; - - // String - camelCase(string: string): string; - capitalize(string: string): string; - deburr(string: string): string; - endsWith(target: string): (string: string) => boolean; - endsWith(target: string, string: string): boolean; - escape(string: string): string; - escapeRegExp(string: string): string; - kebabCase(string: string): string; - lowerCase(string: string): string; - lowerFirst(string: string): string; - pad(length: number): (string: string) => string; - pad(length: number, string: string): string; - padChars( - chars: string - ): ((length: number) => (string: string) => string) & - ((length: number, string: string) => string); - padChars(chars: string, length: number): (string: string) => string; - padChars(chars: string, length: number, string: string): string; - padEnd(length: number): (string: string) => string; - padEnd(length: number, string: string): string; - padCharsEnd( - chars: string - ): ((length: number) => (string: string) => string) & - ((length: number, string: string) => string); - padCharsEnd(chars: string, length: number): (string: string) => string; - padCharsEnd(chars: string, length: number, string: string): string; - padStart(length: number): (string: string) => string; - padStart(length: number, string: string): string; - padCharsStart( - chars: string - ): ((length: number) => (string: string) => string) & - ((length: number, string: string) => string); - padCharsStart(chars: string, length: number): (string: string) => string; - padCharsStart(chars: string, length: number, string: string): string; - parseInt(radix: number): (string: string) => number; - parseInt(radix: number, string: string): number; - repeat(n: number): (string: string) => string; - repeat(n: number, string: string): string; - replace( - pattern: RegExp | string - ): (( - replacement: ((string: string) => string) | string - ) => (string: string) => string) & - (( - replacement: ((string: string) => string) | string, - string: string - ) => string); - replace( - pattern: RegExp | string, - replacement: ((string: string) => string) | string - ): (string: string) => string; - replace( - pattern: RegExp | string, - replacement: ((string: string) => string) | string, - string: string - ): string; - snakeCase(string: string): string; - split(separator: RegExp | string): (string: string) => Array; - split(separator: RegExp | string, string: string): Array; - startCase(string: string): string; - startsWith(target: string): (string: string) => boolean; - startsWith(target: string, string: string): boolean; - template(string: string): Function; - toLower(string: string): string; - toUpper(string: string): string; - trim(string: string): string; - trimChars(chars: string): (string: string) => string; - trimChars(chars: string, string: string): string; - trimEnd(string: string): string; - trimCharsEnd(chars: string): (string: string) => string; - trimCharsEnd(chars: string, string: string): string; - trimStart(string: string): string; - trimCharsStart(chars: string): (string: string) => string; - trimCharsStart(chars: string, string: string): string; - truncate(options: TruncateOptions): (string: string) => string; - truncate(options: TruncateOptions, string: string): string; - unescape(string: string): string; - upperCase(string: string): string; - upperFirst(string: string): string; - words(string: string): Array; - - // Util - attempt(func: Function): any; - bindAll(methodNames: Array): (object: Object) => Object; - bindAll(methodNames: Array, object: Object): Object; - cond(pairs: NestedArray): Function; - constant(value: T): () => T; - always(value: T): () => T; - defaultTo( - defaultValue: T2 - ): (value: T1) => T1; - defaultTo( - defaultValue: T2, - value: T1 - ): T1; - // NaN is a number instead of its own type, otherwise it would behave like null/void - defaultTo(defaultValue: T2): (value: T1) => T1 | T2; - defaultTo(defaultValue: T2, value: T1): T1 | T2; - defaultTo(defaultValue: T2): (value: T1) => T2; - defaultTo(defaultValue: T2, value: T1): T2; - flow: $ComposeReverse; - flow(funcs: Array): Function; - pipe: $ComposeReverse; - pipe(funcs: Array): Function; - flowRight: $Compose; - flowRight(funcs: Array): Function; - compose: $Compose; - compose(funcs: Array): Function; - identity(value: T): T; - iteratee(func: any): Function; - matches(source: Object): (object: Object) => boolean; - matches(source: Object, object: Object): boolean; - matchesProperty(path: Array | string): (srcValue: any) => Function; - matchesProperty(path: Array | string, srcValue: any): Function; - propEq(path: Array | string): (srcValue: any) => Function; - propEq(path: Array | string, srcValue: any): Function; - pathEq(path: Array | string): (srcValue: any) => Function; - pathEq(path: Array | string, srcValue: any): Function; - method(path: Array | string): Function; - methodOf(object: Object): Function; - mixin( - object: T - ): ((source: Object) => (options: { chain: boolean }) => T) & - ((source: Object, options: { chain: boolean }) => T); - mixin( - object: T, - source: Object - ): (options: { chain: boolean }) => T; - mixin( - object: T, - source: Object, - options: { chain: boolean } - ): T; - noConflict(): Lodash; - noop(...args: Array): void; - nthArg(n: number): Function; - over(iteratees: Array): Function; - juxt(iteratees: Array): Function; - overEvery(predicates: Array): Function; - allPass(predicates: Array): Function; - overSome(predicates: Array): Function; - anyPass(predicates: Array): Function; - property( - path: Array | string - ): (object: Object | Array) => any; - property(path: Array | string, object: Object | Array): any; - propertyOf(object: Object): (path: Array | string) => Function; - propertyOf(object: Object, path: Array | string): Function; - range(start: number): (end: number) => Array; - range(start: number, end: number): Array; - rangeStep( - step: number - ): ((start: number) => (end: number) => Array) & - ((start: number, end: number) => Array); - rangeStep(step: number, start: number): (end: number) => Array; - rangeStep(step: number, start: number, end: number): Array; - rangeRight(start: number): (end: number) => Array; - rangeRight(start: number, end: number): Array; - rangeStepRight( - step: number - ): ((start: number) => (end: number) => Array) & - ((start: number, end: number) => Array); - rangeStepRight(step: number, start: number): (end: number) => Array; - rangeStepRight(step: number, start: number, end: number): Array; - runInContext(context: Object): Function; - - stubArray(): Array<*>; - stubFalse(): false; - F(): false; - stubObject(): {}; - stubString(): ""; - stubTrue(): true; - T(): true; - times(iteratee: (i: number) => T): (n: number) => Array; - times(iteratee: (i: number) => T, n: number): Array; - toPath(value: any): Array; - uniqueId(prefix: string): string; - - __: any; - placeholder: any; - - convert(options: { - cap?: boolean, - curry?: boolean, - fixed?: boolean, - immutable?: boolean, - rearg?: boolean - }): void; - - // Properties - VERSION: string; - templateSettings: TemplateSettings; - } - - declare module.exports: Lodash; -} - -declare module "lodash/chunk" { - declare module.exports: $PropertyType<$Exports<"lodash">, "chunk">; -} - -declare module "lodash/compact" { - declare module.exports: $PropertyType<$Exports<"lodash">, "compact">; -} - -declare module "lodash/concat" { - declare module.exports: $PropertyType<$Exports<"lodash">, "concat">; -} - -declare module "lodash/difference" { - declare module.exports: $PropertyType<$Exports<"lodash">, "difference">; -} - -declare module "lodash/differenceBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "differenceBy">; -} - -declare module "lodash/differenceWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "differenceWith">; -} - -declare module "lodash/drop" { - declare module.exports: $PropertyType<$Exports<"lodash">, "drop">; -} - -declare module "lodash/dropRight" { - declare module.exports: $PropertyType<$Exports<"lodash">, "dropRight">; -} - -declare module "lodash/dropRightWhile" { - declare module.exports: $PropertyType<$Exports<"lodash">, "dropRightWhile">; -} - -declare module "lodash/dropWhile" { - declare module.exports: $PropertyType<$Exports<"lodash">, "dropWhile">; -} - -declare module "lodash/fill" { - declare module.exports: $PropertyType<$Exports<"lodash">, "fill">; -} - -declare module "lodash/findIndex" { - declare module.exports: $PropertyType<$Exports<"lodash">, "findIndex">; -} - -declare module "lodash/findLastIndex" { - declare module.exports: $PropertyType<$Exports<"lodash">, "findLastIndex">; -} - -declare module "lodash/first" { - declare module.exports: $PropertyType<$Exports<"lodash">, "first">; -} - -declare module "lodash/flatten" { - declare module.exports: $PropertyType<$Exports<"lodash">, "flatten">; -} - -declare module "lodash/flattenDeep" { - declare module.exports: $PropertyType<$Exports<"lodash">, "flattenDeep">; -} - -declare module "lodash/flattenDepth" { - declare module.exports: $PropertyType<$Exports<"lodash">, "flattenDepth">; -} - -declare module "lodash/fromPairs" { - declare module.exports: $PropertyType<$Exports<"lodash">, "fromPairs">; -} - -declare module "lodash/head" { - declare module.exports: $PropertyType<$Exports<"lodash">, "head">; -} - -declare module "lodash/indexOf" { - declare module.exports: $PropertyType<$Exports<"lodash">, "indexOf">; -} - -declare module "lodash/initial" { - declare module.exports: $PropertyType<$Exports<"lodash">, "initial">; -} - -declare module "lodash/intersection" { - declare module.exports: $PropertyType<$Exports<"lodash">, "intersection">; -} - -declare module "lodash/intersectionBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "intersectionBy">; -} - -declare module "lodash/intersectionWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "intersectionWith">; -} - -declare module "lodash/join" { - declare module.exports: $PropertyType<$Exports<"lodash">, "join">; -} - -declare module "lodash/last" { - declare module.exports: $PropertyType<$Exports<"lodash">, "last">; -} - -declare module "lodash/lastIndexOf" { - declare module.exports: $PropertyType<$Exports<"lodash">, "lastIndexOf">; -} - -declare module "lodash/nth" { - declare module.exports: $PropertyType<$Exports<"lodash">, "nth">; -} - -declare module "lodash/pull" { - declare module.exports: $PropertyType<$Exports<"lodash">, "pull">; -} - -declare module "lodash/pullAll" { - declare module.exports: $PropertyType<$Exports<"lodash">, "pullAll">; -} - -declare module "lodash/pullAllBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "pullAllBy">; -} - -declare module "lodash/pullAllWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "pullAllWith">; -} - -declare module "lodash/pullAt" { - declare module.exports: $PropertyType<$Exports<"lodash">, "pullAt">; -} - -declare module "lodash/remove" { - declare module.exports: $PropertyType<$Exports<"lodash">, "remove">; -} - -declare module "lodash/reverse" { - declare module.exports: $PropertyType<$Exports<"lodash">, "reverse">; -} - -declare module "lodash/slice" { - declare module.exports: $PropertyType<$Exports<"lodash">, "slice">; -} - -declare module "lodash/sortedIndex" { - declare module.exports: $PropertyType<$Exports<"lodash">, "sortedIndex">; -} - -declare module "lodash/sortedIndexBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "sortedIndexBy">; -} - -declare module "lodash/sortedIndexOf" { - declare module.exports: $PropertyType<$Exports<"lodash">, "sortedIndexOf">; -} - -declare module "lodash/sortedLastIndex" { - declare module.exports: $PropertyType<$Exports<"lodash">, "sortedLastIndex">; -} - -declare module "lodash/sortedLastIndexBy" { - declare module.exports: $PropertyType< - $Exports<"lodash">, - "sortedLastIndexBy" - >; -} - -declare module "lodash/sortedLastIndexOf" { - declare module.exports: $PropertyType< - $Exports<"lodash">, - "sortedLastIndexOf" - >; -} - -declare module "lodash/sortedUniq" { - declare module.exports: $PropertyType<$Exports<"lodash">, "sortedUniq">; -} - -declare module "lodash/sortedUniqBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "sortedUniqBy">; -} - -declare module "lodash/tail" { - declare module.exports: $PropertyType<$Exports<"lodash">, "tail">; -} - -declare module "lodash/take" { - declare module.exports: $PropertyType<$Exports<"lodash">, "take">; -} - -declare module "lodash/takeRight" { - declare module.exports: $PropertyType<$Exports<"lodash">, "takeRight">; -} - -declare module "lodash/takeRightWhile" { - declare module.exports: $PropertyType<$Exports<"lodash">, "takeRightWhile">; -} - -declare module "lodash/takeWhile" { - declare module.exports: $PropertyType<$Exports<"lodash">, "takeWhile">; -} - -declare module "lodash/union" { - declare module.exports: $PropertyType<$Exports<"lodash">, "union">; -} - -declare module "lodash/unionBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "unionBy">; -} - -declare module "lodash/unionWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "unionWith">; -} - -declare module "lodash/uniq" { - declare module.exports: $PropertyType<$Exports<"lodash">, "uniq">; -} - -declare module "lodash/uniqBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "uniqBy">; -} - -declare module "lodash/uniqWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "uniqWith">; -} - -declare module "lodash/unzip" { - declare module.exports: $PropertyType<$Exports<"lodash">, "unzip">; -} - -declare module "lodash/unzipWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "unzipWith">; -} - -declare module "lodash/without" { - declare module.exports: $PropertyType<$Exports<"lodash">, "without">; -} - -declare module "lodash/xor" { - declare module.exports: $PropertyType<$Exports<"lodash">, "xor">; -} - -declare module "lodash/xorBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "xorBy">; -} - -declare module "lodash/xorWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "xorWith">; -} - -declare module "lodash/zip" { - declare module.exports: $PropertyType<$Exports<"lodash">, "zip">; -} - -declare module "lodash/zipObject" { - declare module.exports: $PropertyType<$Exports<"lodash">, "zipObject">; -} - -declare module "lodash/zipObjectDeep" { - declare module.exports: $PropertyType<$Exports<"lodash">, "zipObjectDeep">; -} - -declare module "lodash/zipWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "zipWith">; -} - -declare module "lodash/countBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "countBy">; -} - -declare module "lodash/each" { - declare module.exports: $PropertyType<$Exports<"lodash">, "each">; -} - -declare module "lodash/eachRight" { - declare module.exports: $PropertyType<$Exports<"lodash">, "eachRight">; -} - -declare module "lodash/every" { - declare module.exports: $PropertyType<$Exports<"lodash">, "every">; -} - -declare module "lodash/filter" { - declare module.exports: $PropertyType<$Exports<"lodash">, "filter">; -} - -declare module "lodash/find" { - declare module.exports: $PropertyType<$Exports<"lodash">, "find">; -} - -declare module "lodash/findLast" { - declare module.exports: $PropertyType<$Exports<"lodash">, "findLast">; -} - -declare module "lodash/flatMap" { - declare module.exports: $PropertyType<$Exports<"lodash">, "flatMap">; -} - -declare module "lodash/flatMapDeep" { - declare module.exports: $PropertyType<$Exports<"lodash">, "flatMapDeep">; -} - -declare module "lodash/flatMapDepth" { - declare module.exports: $PropertyType<$Exports<"lodash">, "flatMapDepth">; -} - -declare module "lodash/forEach" { - declare module.exports: $PropertyType<$Exports<"lodash">, "forEach">; -} - -declare module "lodash/forEachRight" { - declare module.exports: $PropertyType<$Exports<"lodash">, "forEachRight">; -} - -declare module "lodash/groupBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "groupBy">; -} - -declare module "lodash/includes" { - declare module.exports: $PropertyType<$Exports<"lodash">, "includes">; -} - -declare module "lodash/invokeMap" { - declare module.exports: $PropertyType<$Exports<"lodash">, "invokeMap">; -} - -declare module "lodash/keyBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "keyBy">; -} - -declare module "lodash/map" { - declare module.exports: $PropertyType<$Exports<"lodash">, "map">; -} - -declare module "lodash/orderBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "orderBy">; -} - -declare module "lodash/partition" { - declare module.exports: $PropertyType<$Exports<"lodash">, "partition">; -} - -declare module "lodash/reduce" { - declare module.exports: $PropertyType<$Exports<"lodash">, "reduce">; -} - -declare module "lodash/reduceRight" { - declare module.exports: $PropertyType<$Exports<"lodash">, "reduceRight">; -} - -declare module "lodash/reject" { - declare module.exports: $PropertyType<$Exports<"lodash">, "reject">; -} - -declare module "lodash/sample" { - declare module.exports: $PropertyType<$Exports<"lodash">, "sample">; -} - -declare module "lodash/sampleSize" { - declare module.exports: $PropertyType<$Exports<"lodash">, "sampleSize">; -} - -declare module "lodash/shuffle" { - declare module.exports: $PropertyType<$Exports<"lodash">, "shuffle">; -} - -declare module "lodash/size" { - declare module.exports: $PropertyType<$Exports<"lodash">, "size">; -} - -declare module "lodash/some" { - declare module.exports: $PropertyType<$Exports<"lodash">, "some">; -} - -declare module "lodash/sortBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "sortBy">; -} - -declare module "lodash/now" { - declare module.exports: $PropertyType<$Exports<"lodash">, "now">; -} - -declare module "lodash/after" { - declare module.exports: $PropertyType<$Exports<"lodash">, "after">; -} - -declare module "lodash/ary" { - declare module.exports: $PropertyType<$Exports<"lodash">, "ary">; -} - -declare module "lodash/before" { - declare module.exports: $PropertyType<$Exports<"lodash">, "before">; -} - -declare module "lodash/bind" { - declare module.exports: $PropertyType<$Exports<"lodash">, "bind">; -} - -declare module "lodash/bindKey" { - declare module.exports: $PropertyType<$Exports<"lodash">, "bindKey">; -} - -declare module "lodash/curry" { - declare module.exports: $PropertyType<$Exports<"lodash">, "curry">; -} - -declare module "lodash/curryRight" { - declare module.exports: $PropertyType<$Exports<"lodash">, "curryRight">; -} - -declare module "lodash/debounce" { - declare module.exports: $PropertyType<$Exports<"lodash">, "debounce">; -} - -declare module "lodash/defer" { - declare module.exports: $PropertyType<$Exports<"lodash">, "defer">; -} - -declare module "lodash/delay" { - declare module.exports: $PropertyType<$Exports<"lodash">, "delay">; -} - -declare module "lodash/flip" { - declare module.exports: $PropertyType<$Exports<"lodash">, "flip">; -} - -declare module "lodash/memoize" { - declare module.exports: $PropertyType<$Exports<"lodash">, "memoize">; -} - -declare module "lodash/negate" { - declare module.exports: $PropertyType<$Exports<"lodash">, "negate">; -} - -declare module "lodash/once" { - declare module.exports: $PropertyType<$Exports<"lodash">, "once">; -} - -declare module "lodash/overArgs" { - declare module.exports: $PropertyType<$Exports<"lodash">, "overArgs">; -} - -declare module "lodash/partial" { - declare module.exports: $PropertyType<$Exports<"lodash">, "partial">; -} - -declare module "lodash/partialRight" { - declare module.exports: $PropertyType<$Exports<"lodash">, "partialRight">; -} - -declare module "lodash/rearg" { - declare module.exports: $PropertyType<$Exports<"lodash">, "rearg">; -} - -declare module "lodash/rest" { - declare module.exports: $PropertyType<$Exports<"lodash">, "rest">; -} - -declare module "lodash/spread" { - declare module.exports: $PropertyType<$Exports<"lodash">, "spread">; -} - -declare module "lodash/throttle" { - declare module.exports: $PropertyType<$Exports<"lodash">, "throttle">; -} - -declare module "lodash/unary" { - declare module.exports: $PropertyType<$Exports<"lodash">, "unary">; -} - -declare module "lodash/wrap" { - declare module.exports: $PropertyType<$Exports<"lodash">, "wrap">; -} - -declare module "lodash/castArray" { - declare module.exports: $PropertyType<$Exports<"lodash">, "castArray">; -} - -declare module "lodash/clone" { - declare module.exports: $PropertyType<$Exports<"lodash">, "clone">; -} - -declare module "lodash/cloneDeep" { - declare module.exports: $PropertyType<$Exports<"lodash">, "cloneDeep">; -} - -declare module "lodash/cloneDeepWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "cloneDeepWith">; -} - -declare module "lodash/cloneWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "cloneWith">; -} - -declare module "lodash/conformsTo" { - declare module.exports: $PropertyType<$Exports<"lodash">, "conformsTo">; -} - -declare module "lodash/eq" { - declare module.exports: $PropertyType<$Exports<"lodash">, "eq">; -} - -declare module "lodash/gt" { - declare module.exports: $PropertyType<$Exports<"lodash">, "gt">; -} - -declare module "lodash/gte" { - declare module.exports: $PropertyType<$Exports<"lodash">, "gte">; -} - -declare module "lodash/isArguments" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isArguments">; -} - -declare module "lodash/isArray" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isArray">; -} - -declare module "lodash/isArrayBuffer" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isArrayBuffer">; -} - -declare module "lodash/isArrayLike" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isArrayLike">; -} - -declare module "lodash/isArrayLikeObject" { - declare module.exports: $PropertyType< - $Exports<"lodash">, - "isArrayLikeObject" - >; -} - -declare module "lodash/isBoolean" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isBoolean">; -} - -declare module "lodash/isBuffer" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isBuffer">; -} - -declare module "lodash/isDate" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isDate">; -} - -declare module "lodash/isElement" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isElement">; -} - -declare module "lodash/isEmpty" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isEmpty">; -} - -declare module "lodash/isEqual" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isEqual">; -} - -declare module "lodash/isEqualWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isEqualWith">; -} - -declare module "lodash/isError" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isError">; -} - -declare module "lodash/isFinite" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isFinite">; -} - -declare module "lodash/isFunction" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isFunction">; -} - -declare module "lodash/isInteger" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isInteger">; -} - -declare module "lodash/isLength" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isLength">; -} - -declare module "lodash/isMap" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isMap">; -} - -declare module "lodash/isMatch" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isMatch">; -} - -declare module "lodash/isMatchWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isMatchWith">; -} - -declare module "lodash/isNaN" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isNaN">; -} - -declare module "lodash/isNative" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isNative">; -} - -declare module "lodash/isNil" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isNil">; -} - -declare module "lodash/isNull" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isNull">; -} - -declare module "lodash/isNumber" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isNumber">; -} - -declare module "lodash/isObject" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isObject">; -} - -declare module "lodash/isObjectLike" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isObjectLike">; -} - -declare module "lodash/isPlainObject" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isPlainObject">; -} - -declare module "lodash/isRegExp" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isRegExp">; -} - -declare module "lodash/isSafeInteger" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isSafeInteger">; -} - -declare module "lodash/isSet" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isSet">; -} - -declare module "lodash/isString" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isString">; -} - -declare module "lodash/isSymbol" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isSymbol">; -} - -declare module "lodash/isTypedArray" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isTypedArray">; -} - -declare module "lodash/isUndefined" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isUndefined">; -} - -declare module "lodash/isWeakMap" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isWeakMap">; -} - -declare module "lodash/isWeakSet" { - declare module.exports: $PropertyType<$Exports<"lodash">, "isWeakSet">; -} - -declare module "lodash/lt" { - declare module.exports: $PropertyType<$Exports<"lodash">, "lt">; -} - -declare module "lodash/lte" { - declare module.exports: $PropertyType<$Exports<"lodash">, "lte">; -} - -declare module "lodash/toArray" { - declare module.exports: $PropertyType<$Exports<"lodash">, "toArray">; -} - -declare module "lodash/toFinite" { - declare module.exports: $PropertyType<$Exports<"lodash">, "toFinite">; -} - -declare module "lodash/toInteger" { - declare module.exports: $PropertyType<$Exports<"lodash">, "toInteger">; -} - -declare module "lodash/toLength" { - declare module.exports: $PropertyType<$Exports<"lodash">, "toLength">; -} - -declare module "lodash/toNumber" { - declare module.exports: $PropertyType<$Exports<"lodash">, "toNumber">; -} - -declare module "lodash/toPlainObject" { - declare module.exports: $PropertyType<$Exports<"lodash">, "toPlainObject">; -} - -declare module "lodash/toSafeInteger" { - declare module.exports: $PropertyType<$Exports<"lodash">, "toSafeInteger">; -} - -declare module "lodash/toString" { - declare module.exports: $PropertyType<$Exports<"lodash">, "toString">; -} - -declare module "lodash/add" { - declare module.exports: $PropertyType<$Exports<"lodash">, "add">; -} - -declare module "lodash/ceil" { - declare module.exports: $PropertyType<$Exports<"lodash">, "ceil">; -} - -declare module "lodash/divide" { - declare module.exports: $PropertyType<$Exports<"lodash">, "divide">; -} - -declare module "lodash/floor" { - declare module.exports: $PropertyType<$Exports<"lodash">, "floor">; -} - -declare module "lodash/max" { - declare module.exports: $PropertyType<$Exports<"lodash">, "max">; -} - -declare module "lodash/maxBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "maxBy">; -} - -declare module "lodash/mean" { - declare module.exports: $PropertyType<$Exports<"lodash">, "mean">; -} - -declare module "lodash/meanBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "meanBy">; -} - -declare module "lodash/min" { - declare module.exports: $PropertyType<$Exports<"lodash">, "min">; -} - -declare module "lodash/minBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "minBy">; -} - -declare module "lodash/multiply" { - declare module.exports: $PropertyType<$Exports<"lodash">, "multiply">; -} - -declare module "lodash/round" { - declare module.exports: $PropertyType<$Exports<"lodash">, "round">; -} - -declare module "lodash/subtract" { - declare module.exports: $PropertyType<$Exports<"lodash">, "subtract">; -} - -declare module "lodash/sum" { - declare module.exports: $PropertyType<$Exports<"lodash">, "sum">; -} - -declare module "lodash/sumBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "sumBy">; -} - -declare module "lodash/clamp" { - declare module.exports: $PropertyType<$Exports<"lodash">, "clamp">; -} - -declare module "lodash/inRange" { - declare module.exports: $PropertyType<$Exports<"lodash">, "inRange">; -} - -declare module "lodash/random" { - declare module.exports: $PropertyType<$Exports<"lodash">, "random">; -} - -declare module "lodash/assign" { - declare module.exports: $PropertyType<$Exports<"lodash">, "assign">; -} - -declare module "lodash/assignIn" { - declare module.exports: $PropertyType<$Exports<"lodash">, "assignIn">; -} - -declare module "lodash/assignInWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "assignInWith">; -} - -declare module "lodash/assignWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "assignWith">; -} - -declare module "lodash/at" { - declare module.exports: $PropertyType<$Exports<"lodash">, "at">; -} - -declare module "lodash/create" { - declare module.exports: $PropertyType<$Exports<"lodash">, "create">; -} - -declare module "lodash/defaults" { - declare module.exports: $PropertyType<$Exports<"lodash">, "defaults">; -} - -declare module "lodash/defaultsDeep" { - declare module.exports: $PropertyType<$Exports<"lodash">, "defaultsDeep">; -} - -declare module "lodash/entries" { - declare module.exports: $PropertyType<$Exports<"lodash">, "entries">; -} - -declare module "lodash/entriesIn" { - declare module.exports: $PropertyType<$Exports<"lodash">, "entriesIn">; -} - -declare module "lodash/extend" { - declare module.exports: $PropertyType<$Exports<"lodash">, "extend">; -} - -declare module "lodash/extendWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "extendWith">; -} - -declare module "lodash/findKey" { - declare module.exports: $PropertyType<$Exports<"lodash">, "findKey">; -} - -declare module "lodash/findLastKey" { - declare module.exports: $PropertyType<$Exports<"lodash">, "findLastKey">; -} - -declare module "lodash/forIn" { - declare module.exports: $PropertyType<$Exports<"lodash">, "forIn">; -} - -declare module "lodash/forInRight" { - declare module.exports: $PropertyType<$Exports<"lodash">, "forInRight">; -} - -declare module "lodash/forOwn" { - declare module.exports: $PropertyType<$Exports<"lodash">, "forOwn">; -} - -declare module "lodash/forOwnRight" { - declare module.exports: $PropertyType<$Exports<"lodash">, "forOwnRight">; -} - -declare module "lodash/functions" { - declare module.exports: $PropertyType<$Exports<"lodash">, "functions">; -} - -declare module "lodash/functionsIn" { - declare module.exports: $PropertyType<$Exports<"lodash">, "functionsIn">; -} - -declare module "lodash/get" { - declare module.exports: $PropertyType<$Exports<"lodash">, "get">; -} - -declare module "lodash/has" { - declare module.exports: $PropertyType<$Exports<"lodash">, "has">; -} - -declare module "lodash/hasIn" { - declare module.exports: $PropertyType<$Exports<"lodash">, "hasIn">; -} - -declare module "lodash/invert" { - declare module.exports: $PropertyType<$Exports<"lodash">, "invert">; -} - -declare module "lodash/invertBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "invertBy">; -} - -declare module "lodash/invoke" { - declare module.exports: $PropertyType<$Exports<"lodash">, "invoke">; -} - -declare module "lodash/keys" { - declare module.exports: $PropertyType<$Exports<"lodash">, "keys">; -} - -declare module "lodash/keysIn" { - declare module.exports: $PropertyType<$Exports<"lodash">, "keysIn">; -} - -declare module "lodash/mapKeys" { - declare module.exports: $PropertyType<$Exports<"lodash">, "mapKeys">; -} - -declare module "lodash/mapValues" { - declare module.exports: $PropertyType<$Exports<"lodash">, "mapValues">; -} - -declare module "lodash/merge" { - declare module.exports: $PropertyType<$Exports<"lodash">, "merge">; -} - -declare module "lodash/mergeWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "mergeWith">; -} - -declare module "lodash/omit" { - declare module.exports: $PropertyType<$Exports<"lodash">, "omit">; -} - -declare module "lodash/omitBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "omitBy">; -} - -declare module "lodash/pick" { - declare module.exports: $PropertyType<$Exports<"lodash">, "pick">; -} - -declare module "lodash/pickBy" { - declare module.exports: $PropertyType<$Exports<"lodash">, "pickBy">; -} - -declare module "lodash/result" { - declare module.exports: $PropertyType<$Exports<"lodash">, "result">; -} - -declare module "lodash/set" { - declare module.exports: $PropertyType<$Exports<"lodash">, "set">; -} - -declare module "lodash/setWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "setWith">; -} - -declare module "lodash/toPairs" { - declare module.exports: $PropertyType<$Exports<"lodash">, "toPairs">; -} - -declare module "lodash/toPairsIn" { - declare module.exports: $PropertyType<$Exports<"lodash">, "toPairsIn">; -} - -declare module "lodash/transform" { - declare module.exports: $PropertyType<$Exports<"lodash">, "transform">; -} - -declare module "lodash/unset" { - declare module.exports: $PropertyType<$Exports<"lodash">, "unset">; -} - -declare module "lodash/update" { - declare module.exports: $PropertyType<$Exports<"lodash">, "update">; -} - -declare module "lodash/updateWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "updateWith">; -} - -declare module "lodash/values" { - declare module.exports: $PropertyType<$Exports<"lodash">, "values">; -} - -declare module "lodash/valuesIn" { - declare module.exports: $PropertyType<$Exports<"lodash">, "valuesIn">; -} - -declare module "lodash/chain" { - declare module.exports: $PropertyType<$Exports<"lodash">, "chain">; -} - -declare module "lodash/tap" { - declare module.exports: $PropertyType<$Exports<"lodash">, "tap">; -} - -declare module "lodash/thru" { - declare module.exports: $PropertyType<$Exports<"lodash">, "thru">; -} - -declare module "lodash/camelCase" { - declare module.exports: $PropertyType<$Exports<"lodash">, "camelCase">; -} - -declare module "lodash/capitalize" { - declare module.exports: $PropertyType<$Exports<"lodash">, "capitalize">; -} - -declare module "lodash/deburr" { - declare module.exports: $PropertyType<$Exports<"lodash">, "deburr">; -} - -declare module "lodash/endsWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "endsWith">; -} - -declare module "lodash/escape" { - declare module.exports: $PropertyType<$Exports<"lodash">, "escape">; -} - -declare module "lodash/escapeRegExp" { - declare module.exports: $PropertyType<$Exports<"lodash">, "escapeRegExp">; -} - -declare module "lodash/kebabCase" { - declare module.exports: $PropertyType<$Exports<"lodash">, "kebabCase">; -} - -declare module "lodash/lowerCase" { - declare module.exports: $PropertyType<$Exports<"lodash">, "lowerCase">; -} - -declare module "lodash/lowerFirst" { - declare module.exports: $PropertyType<$Exports<"lodash">, "lowerFirst">; -} - -declare module "lodash/pad" { - declare module.exports: $PropertyType<$Exports<"lodash">, "pad">; -} - -declare module "lodash/padEnd" { - declare module.exports: $PropertyType<$Exports<"lodash">, "padEnd">; -} - -declare module "lodash/padStart" { - declare module.exports: $PropertyType<$Exports<"lodash">, "padStart">; -} - -declare module "lodash/parseInt" { - declare module.exports: $PropertyType<$Exports<"lodash">, "parseInt">; -} - -declare module "lodash/repeat" { - declare module.exports: $PropertyType<$Exports<"lodash">, "repeat">; -} - -declare module "lodash/replace" { - declare module.exports: $PropertyType<$Exports<"lodash">, "replace">; -} - -declare module "lodash/snakeCase" { - declare module.exports: $PropertyType<$Exports<"lodash">, "snakeCase">; -} - -declare module "lodash/split" { - declare module.exports: $PropertyType<$Exports<"lodash">, "split">; -} - -declare module "lodash/startCase" { - declare module.exports: $PropertyType<$Exports<"lodash">, "startCase">; -} - -declare module "lodash/startsWith" { - declare module.exports: $PropertyType<$Exports<"lodash">, "startsWith">; -} - -declare module "lodash/template" { - declare module.exports: $PropertyType<$Exports<"lodash">, "template">; -} - -declare module "lodash/toLower" { - declare module.exports: $PropertyType<$Exports<"lodash">, "toLower">; -} - -declare module "lodash/toUpper" { - declare module.exports: $PropertyType<$Exports<"lodash">, "toUpper">; -} - -declare module "lodash/trim" { - declare module.exports: $PropertyType<$Exports<"lodash">, "trim">; -} - -declare module "lodash/trimEnd" { - declare module.exports: $PropertyType<$Exports<"lodash">, "trimEnd">; -} - -declare module "lodash/trimStart" { - declare module.exports: $PropertyType<$Exports<"lodash">, "trimStart">; -} - -declare module "lodash/truncate" { - declare module.exports: $PropertyType<$Exports<"lodash">, "truncate">; -} - -declare module "lodash/unescape" { - declare module.exports: $PropertyType<$Exports<"lodash">, "unescape">; -} - -declare module "lodash/upperCase" { - declare module.exports: $PropertyType<$Exports<"lodash">, "upperCase">; -} - -declare module "lodash/upperFirst" { - declare module.exports: $PropertyType<$Exports<"lodash">, "upperFirst">; -} - -declare module "lodash/words" { - declare module.exports: $PropertyType<$Exports<"lodash">, "words">; -} - -declare module "lodash/attempt" { - declare module.exports: $PropertyType<$Exports<"lodash">, "attempt">; -} - -declare module "lodash/bindAll" { - declare module.exports: $PropertyType<$Exports<"lodash">, "bindAll">; -} - -declare module "lodash/cond" { - declare module.exports: $PropertyType<$Exports<"lodash">, "cond">; -} - -declare module "lodash/conforms" { - declare module.exports: $PropertyType<$Exports<"lodash">, "conforms">; -} - -declare module "lodash/constant" { - declare module.exports: $PropertyType<$Exports<"lodash">, "constant">; -} - -declare module "lodash/defaultTo" { - declare module.exports: $PropertyType<$Exports<"lodash">, "defaultTo">; -} - -declare module "lodash/flow" { - declare module.exports: $PropertyType<$Exports<"lodash">, "flow">; -} - -declare module "lodash/flowRight" { - declare module.exports: $PropertyType<$Exports<"lodash">, "flowRight">; -} - -declare module "lodash/identity" { - declare module.exports: $PropertyType<$Exports<"lodash">, "identity">; -} - -declare module "lodash/iteratee" { - declare module.exports: $PropertyType<$Exports<"lodash">, "iteratee">; -} - -declare module "lodash/matches" { - declare module.exports: $PropertyType<$Exports<"lodash">, "matches">; -} - -declare module "lodash/matchesProperty" { - declare module.exports: $PropertyType<$Exports<"lodash">, "matchesProperty">; -} - -declare module "lodash/method" { - declare module.exports: $PropertyType<$Exports<"lodash">, "method">; -} - -declare module "lodash/methodOf" { - declare module.exports: $PropertyType<$Exports<"lodash">, "methodOf">; -} - -declare module "lodash/mixin" { - declare module.exports: $PropertyType<$Exports<"lodash">, "mixin">; -} - -declare module "lodash/noConflict" { - declare module.exports: $PropertyType<$Exports<"lodash">, "noConflict">; -} - -declare module "lodash/noop" { - declare module.exports: $PropertyType<$Exports<"lodash">, "noop">; -} - -declare module "lodash/nthArg" { - declare module.exports: $PropertyType<$Exports<"lodash">, "nthArg">; -} - -declare module "lodash/over" { - declare module.exports: $PropertyType<$Exports<"lodash">, "over">; -} - -declare module "lodash/overEvery" { - declare module.exports: $PropertyType<$Exports<"lodash">, "overEvery">; -} - -declare module "lodash/overSome" { - declare module.exports: $PropertyType<$Exports<"lodash">, "overSome">; -} - -declare module "lodash/property" { - declare module.exports: $PropertyType<$Exports<"lodash">, "property">; -} - -declare module "lodash/propertyOf" { - declare module.exports: $PropertyType<$Exports<"lodash">, "propertyOf">; -} - -declare module "lodash/range" { - declare module.exports: $PropertyType<$Exports<"lodash">, "range">; -} - -declare module "lodash/rangeRight" { - declare module.exports: $PropertyType<$Exports<"lodash">, "rangeRight">; -} - -declare module "lodash/runInContext" { - declare module.exports: $PropertyType<$Exports<"lodash">, "runInContext">; -} - -declare module "lodash/stubArray" { - declare module.exports: $PropertyType<$Exports<"lodash">, "stubArray">; -} - -declare module "lodash/stubFalse" { - declare module.exports: $PropertyType<$Exports<"lodash">, "stubFalse">; -} - -declare module "lodash/stubObject" { - declare module.exports: $PropertyType<$Exports<"lodash">, "stubObject">; -} - -declare module "lodash/stubString" { - declare module.exports: $PropertyType<$Exports<"lodash">, "stubString">; -} - -declare module "lodash/stubTrue" { - declare module.exports: $PropertyType<$Exports<"lodash">, "stubTrue">; -} - -declare module "lodash/times" { - declare module.exports: $PropertyType<$Exports<"lodash">, "times">; -} - -declare module "lodash/toPath" { - declare module.exports: $PropertyType<$Exports<"lodash">, "toPath">; -} - -declare module "lodash/uniqueId" { - declare module.exports: $PropertyType<$Exports<"lodash">, "uniqueId">; -} diff --git a/flow-typed/npm/log4js_v1.x.x.js b/flow-typed/npm/log4js_v1.x.x.js deleted file mode 100644 index 4c9927c9e1..0000000000 --- a/flow-typed/npm/log4js_v1.x.x.js +++ /dev/null @@ -1,44 +0,0 @@ -// flow-typed signature: c69efc63ea2cb8646a8685b0e937fb25 -// flow-typed version: b43dff3e0e/log4js_v1.x.x/flow_>=v0.25.x - -type log4js$Logger = { - level: string, - setLevel(level: string): void, - removeLevel(): void, - isLevelEnabled(level: string): boolean, - - log(...args: Array): void, - trace(...args: Array): void, - debug(...args: Array): void, - info(...args: Array): void, - warn(...args: Array): void, - error(...args: Array): void, - fatal(...args: Array): void, - mark(...args: Array): void, -} - -type log4js$Appender = { - type: string, -} - -type log4js$Config = { - appenders?: Array, - levels?: {[name: string]: string}, -} - -declare module 'log4js' { - declare module.exports: { - getLogger(category?: string): log4js$Logger, - - configure( - configurationFileOrObject: string | log4js$Config, - options?: Object, - ): void, - - shutdown(callback: () => mixed): void, - - connectLogger(logger: log4js$Logger, options?: Object): any, - - levels: Object, - } -} diff --git a/flow-typed/npm/lru-cache_v4.0.x.js b/flow-typed/npm/lru-cache_v4.0.x.js deleted file mode 100644 index 96313bf178..0000000000 --- a/flow-typed/npm/lru-cache_v4.0.x.js +++ /dev/null @@ -1,27 +0,0 @@ -// flow-typed signature: 2e415f033284600956b323d56d206449 -// flow-typed version: b43dff3e0e/lru-cache_v4.0.x/flow_>=v0.20.0 - -declare module 'lru-cache' { - - declare type LRUCache = { - set: (key: K, value: V, maxAge?: number) => void; - get: (key: K) => V; - peek: (key: K) => V; - del: (key: K) => void; - reset: () => void; - has: (key: K) => boolean; - dump: () => Array<{k: K, v: V}>, - // TODO add the rest of the things documented at https://www.npmjs.com/package/lru-cache - }; - - declare type Options = { - max?: number; - maxAge?: number; - length?: (value: V, key: K) => number; - dispose?: (key: K, value: V) => void; - stale?: boolean; - }; - - // TODO You can supply just an integer (max size), or even nothing at all. - declare module.exports: (options: Options) => LRUCache; -} diff --git a/flow-typed/npm/marked_v0.3.x.js b/flow-typed/npm/marked_v0.3.x.js deleted file mode 100644 index 3af9af1be1..0000000000 --- a/flow-typed/npm/marked_v0.3.x.js +++ /dev/null @@ -1,163 +0,0 @@ -// flow-typed signature: 85ea5a515c42c00188d893614f410655 -// flow-typed version: 72fe9c1b53/marked_v0.3.x/flow_>=v0.28.x - -type marked$AlignFlag = 'left' | 'right' | 'center' - -type marked$NodeCallback = (e: ?Error, d: ?T) => void - -class marked$Renderer { - options: marked$MarkedOptions; - code: (c: string, l: string) => string; - blockquote: (q: string) => string; - html: (h: string) => string; - heading: (t: string, l: number) => string; - hr: () => string; - list: (b: string, o: boolean) => string; - listitem: (t: string) => string; - paragraph: (t: string) => string; - table: (h: string, b: string) => string; - tablerow: (c: string) => string; - tablecell: (c: string, f: ?marked$AlignFlag) => string; - heading: (t: string, l: number) => string; - strong: (t: string) => string; - em: (t: string) => string; - codespan: (c: string) => string; - br: () => string; - del: (t: string) => string; - link: (h: string, ti: string, te: string) => string; - image: (h: string, ti: string, te: string) => string; - text: (t: string) => string; - constructor(o?: marked$MarkedOptions): marked$Renderer { - return this; - } -} - -type marked$HighlightFunction = - ((c: string, l: string, cb: marked$NodeCallback) => void) - | ((c: string, cb: marked$NodeCallback) => void) - | ((c: string, l?: string) => string) - -type marked$MarkedOptions = { - highlight?: marked$HighlightFunction; - renderer?: marked$Renderer; - gfm?: boolean; - tables?: boolean; - breaks?: boolean; - pedantic?: boolean; - sanitize?: boolean; - smartLists?: boolean; - smartypants?: boolean; -} - -/* - * marked$Tokens - */ - -type marked$Space = { type: 'space'; } -type marked$Code = { type: 'code'; text: string; lang?: string; } -type marked$Heading = { type: 'heading'; depth: number; text: string; } -type marked$Table = { type: 'table'; header: string; align: Array ; cells: Array> } -type marked$Hr = { type: 'hr'; } -type marked$BlockquoteStart = { type: 'blockquote_start' } -type marked$BlockquoteEnd = { type: 'blockquote_end' } -type marked$ListStart = { type: 'list_start' } -type marked$ListEnd = { type: 'list_end' } -type marked$Paragraph = { type: 'paragraph'; pre: boolean; text: string; } -type marked$Html = { type: 'paragraph'; pre: boolean; text: string; } -type marked$Text = { type: 'text'; text: string; } - -type marked$Token = - marked$Space - | marked$Code - | marked$Heading - | marked$Table - | marked$Hr - | marked$BlockquoteStart - | marked$BlockquoteEnd - | marked$ListStart - | marked$ListEnd - | marked$Paragraph - | marked$Html - | marked$Text - -type marked$Link = { - title: ?string; - href: string; -} - -type marked$Tokens = { links: Array } & Array; - -type marked$NoopRule = { - (i: mixed): void; - exec: (i: mixed) => void; -} - -type marked$Rule = RegExp | marked$NoopRule - -type marked$lex = (t: string) => marked$Tokens; - -class marked$Lexer { - static lexer: (t: string, o?: marked$MarkedOptions) => marked$Tokens; - static rules: { [key: string]: marked$Rule }; - rules: { [key: string]: marked$Rule }; - lex: marked$lex; - tokens: marked$Tokens; - options: marked$MarkedOptions; - constructor(o?: marked$MarkedOptions): marked$Lexer { - return this; - } -} - -class marked$Parser { - static parse: (t: marked$Tokens, o?: marked$MarkedOptions) => string; - parse: (t: marked$Tokens) => string; - next: () => marked$Token; - peek: () => marked$Token; - parsemarked$Text: () => string; - tok: () => string; - tokens: marked$Tokens; - token: ?marked$Token; - options: marked$MarkedOptions; - renderer: marked$Renderer; - constructor(o?: marked$MarkedOptions): marked$Parser { - return this; - } -} - -class marked$InlineLexer { - static rules: Array; - static output: (s: string, l: Array, o?: marked$MarkedOptions) => string; - output: (s: string) => string; - outputmarked$Link: (c: Array, l: marked$Link) => string; - smartypants: (t: string) => string; - mangle: (t: string) => string; - options: marked$MarkedOptions; - links: Array; - rules: Array; - renderer: marked$Renderer; - constructor(l: Array, o?: marked$MarkedOptions): marked$InlineLexer { - return this; - } -} - -type marked$Marked = { - (md: string, o: marked$MarkedOptions, cb: marked$NodeCallback): void; - (md: string, cb: marked$NodeCallback): void; - (md: string, o?: marked$MarkedOptions): string; - setOptions: (o: marked$MarkedOptions) => void; - defaults: marked$MarkedOptions; - Parser: typeof marked$Parser; - parser: typeof marked$Parser.parse; - Lexer: typeof marked$Lexer; - lexer: typeof marked$Lexer.lexer; - InlineLexer: typeof marked$InlineLexer; - inlinelexer: marked$InlineLexer.output; - Renderer: typeof marked$Renderer; - parse: marked$Marked; -} - - -declare module marked { - declare export default marked$Marked; -} - diff --git a/flow-typed/npm/mkdirp_v0.5.x.js b/flow-typed/npm/mkdirp_v0.5.x.js deleted file mode 100644 index e26f9a4be7..0000000000 --- a/flow-typed/npm/mkdirp_v0.5.x.js +++ /dev/null @@ -1,13 +0,0 @@ -// flow-typed signature: 82aa0feffc2bbd64dce3bec492f5d601 -// flow-typed version: 3315d89a00/mkdirp_v0.5.x/flow_>=v0.25.0 - -declare module 'mkdirp' { - declare type Options = number | { mode?: number; fs?: mixed }; - - declare type Callback = (err: ?Error, path: ?string) => void; - - declare module.exports: { - (path: string, options?: Options | Callback, callback?: Callback): void; - sync(path: string, options?: Options): void; - }; -} diff --git a/flow-typed/npm/prettier_v1.x.x.js b/flow-typed/npm/prettier_v1.x.x.js deleted file mode 100644 index 0c24491525..0000000000 --- a/flow-typed/npm/prettier_v1.x.x.js +++ /dev/null @@ -1,178 +0,0 @@ -// flow-typed signature: 4eed8da2dc730dc33e7710b465eaa44b -// flow-typed version: cc7a557b34/prettier_v1.x.x/flow_>=v0.56.x - -declare module "prettier" { - declare type AST = Object; - declare type Doc = Object; - declare type FastPath = Object; - - declare type PrettierParserName = - | "babylon" - | "flow" - | "typescript" - | "postcss" - | "css" - | "less" - | "scss" - | "json" - | "graphql" - | "markdown" - | "vue"; - - declare type PrettierParser = { - [name: PrettierParserName]: (text: string, options?: Object) => AST - }; - - declare type CustomParser = ( - text: string, - parsers: PrettierParser, - options: Options - ) => AST; - - declare type Options = {| - printWidth?: number, - tabWidth?: number, - useTabs?: boolean, - semi?: boolean, - singleQuote?: boolean, - trailingComma?: "none" | "es5" | "all", - bracketSpacing?: boolean, - jsxBracketSameLine?: boolean, - arrowParens?: "avoid" | "always", - rangeStart?: number, - rangeEnd?: number, - parser?: PrettierParserName | CustomParser, - filepath?: string, - requirePragma?: boolean, - insertPragma?: boolean, - proseWrap?: "always" | "never" | "preserve", - plugins?: Array - |}; - - declare type Plugin = { - languages: SupportLanguage, - parsers: { [parserName: string]: Parser }, - printers: { [astFormat: string]: Printer } - }; - - declare type Parser = { - parse: ( - text: string, - parsers: { [parserName: string]: Parser }, - options: Object - ) => AST, - astFormat: string - }; - - declare type Printer = { - print: ( - path: FastPath, - options: Object, - print: (path: FastPath) => Doc - ) => Doc, - embed: ( - path: FastPath, - print: (path: FastPath) => Doc, - textToDoc: (text: string, options: Object) => Doc, - options: Object - ) => ?Doc - }; - - declare type CursorOptions = {| - cursorOffset: number, - printWidth?: $PropertyType, - tabWidth?: $PropertyType, - useTabs?: $PropertyType, - semi?: $PropertyType, - singleQuote?: $PropertyType, - trailingComma?: $PropertyType, - bracketSpacing?: $PropertyType, - jsxBracketSameLine?: $PropertyType, - arrowParens?: $PropertyType, - parser?: $PropertyType, - filepath?: $PropertyType, - requirePragma?: $PropertyType, - insertPragma?: $PropertyType, - proseWrap?: $PropertyType, - plugins?: $PropertyType - |}; - - declare type CursorResult = {| - formatted: string, - cursorOffset: number - |}; - - declare type ResolveConfigOptions = {| - useCache?: boolean, - config?: string, - editorconfig?: boolean - |}; - - declare type SupportLanguage = { - name: string, - since: string, - parsers: Array, - group?: string, - tmScope: string, - aceMode: string, - codemirrorMode: string, - codemirrorMimeType: string, - aliases?: Array, - extensions: Array, - filenames?: Array, - linguistLanguageId: number, - vscodeLanguageIds: Array - }; - - declare type SupportOption = {| - since: string, - type: "int" | "boolean" | "choice" | "path", - deprecated?: string, - redirect?: SupportOptionRedirect, - description: string, - oppositeDescription?: string, - default: SupportOptionValue, - range?: SupportOptionRange, - choices?: SupportOptionChoice - |}; - - declare type SupportOptionRedirect = {| - options: string, - value: SupportOptionValue - |}; - - declare type SupportOptionRange = {| - start: number, - end: number, - step: number - |}; - - declare type SupportOptionChoice = {| - value: boolean | string, - description?: string, - since?: string, - deprecated?: string, - redirect?: SupportOptionValue - |}; - - declare type SupportOptionValue = number | boolean | string; - - declare type SupportInfo = {| - languages: Array, - options: Array - |}; - - declare type Prettier = {| - format: (source: string, options?: Options) => string, - check: (source: string, options?: Options) => boolean, - formatWithCursor: (source: string, options: CursorOptions) => CursorResult, - resolveConfig: { - (filePath: string, options?: ResolveConfigOptions): Promise, - sync(filePath: string, options?: ResolveConfigOptions): Promise - }, - clearConfigCache: () => void, - getSupportInfo: (version?: string) => SupportInfo - |}; - - declare export default Prettier; -} diff --git a/flow-typed/npm/react-redux_v5.x.x.js b/flow-typed/npm/react-redux_v5.x.x.js deleted file mode 100644 index 30380824d6..0000000000 --- a/flow-typed/npm/react-redux_v5.x.x.js +++ /dev/null @@ -1,114 +0,0 @@ -// flow-typed signature: f0d96df48e9abc14bcc1405ba2a47dde -// flow-typed version: 83053e4020/react-redux_v5.x.x/flow_>=v0.53.x - -// flow-typed signature: 8db7b853f57c51094bf0ab8b2650fd9c -// flow-typed version: ab8db5f14d/react-redux_v5.x.x/flow_>=v0.30.x - -import type { Dispatch, Store } from "redux"; - -declare module "react-redux" { - /* - - S = State - A = Action - OP = OwnProps - SP = StateProps - DP = DispatchProps - - */ - - declare type MapStateToProps = ( - state: S, - ownProps: OP - ) => ((state: S, ownProps: OP) => SP) | SP; - - declare type MapDispatchToProps = - | ((dispatch: Dispatch, ownProps: OP) => DP) - | DP; - - declare type MergeProps = ( - stateProps: SP, - dispatchProps: DP, - ownProps: OP - ) => P; - - declare type Context = { store: Store<*, *> }; - - declare class ConnectedComponent extends React$Component { - static WrappedComponent: Class>, - getWrappedInstance(): React$Component

, - props: OP, - state: void - } - - declare type ConnectedComponentClass = Class< - ConnectedComponent - >; - - declare type Connector = ( - component: React$ComponentType

- ) => ConnectedComponentClass; - - declare class Provider extends React$Component<{ - store: Store, - children?: any - }> {} - - declare function createProvider( - storeKey?: string, - subKey?: string - ): Provider<*, *>; - - declare type ConnectOptions = { - pure?: boolean, - withRef?: boolean - }; - - declare type Null = null | void; - - declare function connect( - ...rest: Array // <= workaround for https://github.com/facebook/flow/issues/2360 - ): Connector } & OP>>; - - declare function connect( - mapStateToProps: Null, - mapDispatchToProps: Null, - mergeProps: Null, - options: ConnectOptions - ): Connector } & OP>>; - - declare function connect( - mapStateToProps: MapStateToProps, - mapDispatchToProps: Null, - mergeProps: Null, - options?: ConnectOptions - ): Connector } & OP>>; - - declare function connect( - mapStateToProps: Null, - mapDispatchToProps: MapDispatchToProps, - mergeProps: Null, - options?: ConnectOptions - ): Connector>; - - declare function connect( - mapStateToProps: MapStateToProps, - mapDispatchToProps: MapDispatchToProps, - mergeProps: Null, - options?: ConnectOptions - ): Connector>; - - declare function connect( - mapStateToProps: MapStateToProps, - mapDispatchToProps: Null, - mergeProps: MergeProps, - options?: ConnectOptions - ): Connector; - - declare function connect( - mapStateToProps: MapStateToProps, - mapDispatchToProps: MapDispatchToProps, - mergeProps: MergeProps, - options?: ConnectOptions - ): Connector; -} diff --git a/flow-typed/npm/reselect_v3.x.x.js b/flow-typed/npm/reselect_v3.x.x.js deleted file mode 100644 index be78f5e8ce..0000000000 --- a/flow-typed/npm/reselect_v3.x.x.js +++ /dev/null @@ -1,753 +0,0 @@ -// flow-typed signature: 0199525b667f385f2e61dbeae3215f21 -// flow-typed version: b43dff3e0e/reselect_v3.x.x/flow_>=v0.28.x - -declare module 'reselect' { - declare type Selector = { - (state: TState, props: TProps, ...rest: any[]): TResult; - }; - - declare type SelectorCreator = { - ( - selector1: Selector, - selector2: Selector, - selector3: Selector, - selector4: Selector, - selector5: Selector, - selector6: Selector, - selector7: Selector, - selector8: Selector, - selector9: Selector, - selector10: Selector, - selector11: Selector, - selector12: Selector, - selector13: Selector, - selector14: Selector, - selector15: Selector, - selector16: Selector, - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8, - arg9: T9, - arg10: T10, - arg11: T11, - arg12: T12, - arg13: T13, - arg14: T14, - arg15: T15, - arg16: T16 - ) => TResult - ): Selector; - ( - selectors: [ - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector - ], - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8, - arg9: T9, - arg10: T10, - arg11: T11, - arg12: T12, - arg13: T13, - arg14: T14, - arg15: T15, - arg16: T16 - ) => TResult - ): Selector; - - ( - selector1: Selector, - selector2: Selector, - selector3: Selector, - selector4: Selector, - selector5: Selector, - selector6: Selector, - selector7: Selector, - selector8: Selector, - selector9: Selector, - selector10: Selector, - selector11: Selector, - selector12: Selector, - selector13: Selector, - selector14: Selector, - selector15: Selector, - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8, - arg9: T9, - arg10: T10, - arg11: T11, - arg12: T12, - arg13: T13, - arg14: T14, - arg15: T15 - ) => TResult - ): Selector; - ( - selectors: [ - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector - ], - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8, - arg9: T9, - arg10: T10, - arg11: T11, - arg12: T12, - arg13: T13, - arg14: T14, - arg15: T15 - ) => TResult - ): Selector; - - ( - selector1: Selector, - selector2: Selector, - selector3: Selector, - selector4: Selector, - selector5: Selector, - selector6: Selector, - selector7: Selector, - selector8: Selector, - selector9: Selector, - selector10: Selector, - selector11: Selector, - selector12: Selector, - selector13: Selector, - selector14: Selector, - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8, - arg9: T9, - arg10: T10, - arg11: T11, - arg12: T12, - arg13: T13, - arg14: T14 - ) => TResult - ): Selector; - ( - selectors: [ - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector - ], - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8, - arg9: T9, - arg10: T10, - arg11: T11, - arg12: T12, - arg13: T13, - arg14: T14 - ) => TResult - ): Selector; - - ( - selector1: Selector, - selector2: Selector, - selector3: Selector, - selector4: Selector, - selector5: Selector, - selector6: Selector, - selector7: Selector, - selector8: Selector, - selector9: Selector, - selector10: Selector, - selector11: Selector, - selector12: Selector, - selector13: Selector, - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8, - arg9: T9, - arg10: T10, - arg11: T11, - arg12: T12, - arg13: T13 - ) => TResult - ): Selector; - ( - selectors: [ - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector - ], - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8, - arg9: T9, - arg10: T10, - arg11: T11, - arg12: T12, - arg13: T13 - ) => TResult - ): Selector; - - ( - selector1: Selector, - selector2: Selector, - selector3: Selector, - selector4: Selector, - selector5: Selector, - selector6: Selector, - selector7: Selector, - selector8: Selector, - selector9: Selector, - selector10: Selector, - selector11: Selector, - selector12: Selector, - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8, - arg9: T9, - arg10: T10, - arg11: T11, - arg12: T12 - ) => TResult - ): Selector; - ( - selectors: [ - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector - ], - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8, - arg9: T9, - arg10: T10, - arg11: T11, - arg12: T12 - ) => TResult - ): Selector; - - ( - selector1: Selector, - selector2: Selector, - selector3: Selector, - selector4: Selector, - selector5: Selector, - selector6: Selector, - selector7: Selector, - selector8: Selector, - selector9: Selector, - selector10: Selector, - selector11: Selector, - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8, - arg9: T9, - arg10: T10, - arg11: T11 - ) => TResult - ): Selector; - ( - selectors: [ - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector - ], - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8, - arg9: T9, - arg10: T10, - arg11: T11 - ) => TResult - ): Selector; - - ( - selector1: Selector, - selector2: Selector, - selector3: Selector, - selector4: Selector, - selector5: Selector, - selector6: Selector, - selector7: Selector, - selector8: Selector, - selector9: Selector, - selector10: Selector, - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8, - arg9: T9, - arg10: T10 - ) => TResult - ): Selector; - ( - selectors: [ - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector - ], - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8, - arg9: T9, - arg10: T10 - ) => TResult - ): Selector; - - ( - selector1: Selector, - selector2: Selector, - selector3: Selector, - selector4: Selector, - selector5: Selector, - selector6: Selector, - selector7: Selector, - selector8: Selector, - selector9: Selector, - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8, - arg9: T9 - ) => TResult - ): Selector; - ( - selectors: [ - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector - ], - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8, - arg9: T9 - ) => TResult - ): Selector; - - ( - selector1: Selector, - selector2: Selector, - selector3: Selector, - selector4: Selector, - selector5: Selector, - selector6: Selector, - selector7: Selector, - selector8: Selector, - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8 - ) => TResult - ): Selector; - ( - selectors: [ - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector - ], - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7, - arg8: T8 - ) => TResult - ): Selector; - - ( - selector1: Selector, - selector2: Selector, - selector3: Selector, - selector4: Selector, - selector5: Selector, - selector6: Selector, - selector7: Selector, - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7 - ) => TResult - ): Selector; - ( - selectors: [ - Selector, - Selector, - Selector, - Selector, - Selector, - Selector, - Selector - ], - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6, - arg7: T7 - ) => TResult - ): Selector; - - ( - selector1: Selector, - selector2: Selector, - selector3: Selector, - selector4: Selector, - selector5: Selector, - selector6: Selector, - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6 - ) => TResult - ): Selector; - ( - selectors: [ - Selector, - Selector, - Selector, - Selector, - Selector, - Selector - ], - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5, - arg6: T6 - ) => TResult - ): Selector; - - ( - selector1: Selector, - selector2: Selector, - selector3: Selector, - selector4: Selector, - selector5: Selector, - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5 - ) => TResult - ): Selector; - ( - selectors: [ - Selector, - Selector, - Selector, - Selector, - Selector - ], - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4, - arg5: T5 - ) => TResult - ): Selector; - - ( - selector1: Selector, - selector2: Selector, - selector3: Selector, - selector4: Selector, - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4 - ) => TResult - ): Selector; - ( - selectors: [ - Selector, - Selector, - Selector, - Selector - ], - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3, - arg4: T4 - ) => TResult - ): Selector; - - ( - selector1: Selector, - selector2: Selector, - selector3: Selector, - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3 - ) => TResult - ): Selector; - ( - selectors: [ - Selector, - Selector, - Selector - ], - resultFunc: ( - arg1: T1, - arg2: T2, - arg3: T3 - ) => TResult - ): Selector; - - ( - selector1: Selector, - selector2: Selector, - resultFunc: ( - arg1: T1, - arg2: T2 - ) => TResult - ): Selector; - ( - selectors: [ - Selector, - Selector - ], - resultFunc: ( - arg1: T1, - arg2: T2 - ) => TResult - ): Selector; - - ( - selector1: Selector, - resultFunc: ( - arg1: T1 - ) => TResult - ): Selector; - ( - selectors: [ - Selector - ], - resultFunc: ( - arg1: T1 - ) => TResult - ): Selector; - }; - - declare type Reselect = { - createSelector: SelectorCreator; - - defaultMemoize: ( - func: TFunc, - equalityCheck?: (a: any, b: any) => boolean - ) => TFunc; - - createSelectorCreator: ( - memoize: Function, - ...memoizeOptions: any[] - ) => SelectorCreator; - - createStructuredSelector: ( - inputSelectors: { - [k: string | number]: Selector - }, - selectorCreator?: SelectorCreator - ) => Selector; - }; - - declare module.exports: Reselect; -}; diff --git a/flow-typed/npm/rimraf_v2.x.x.js b/flow-typed/npm/rimraf_v2.x.x.js deleted file mode 100644 index 13b85249c4..0000000000 --- a/flow-typed/npm/rimraf_v2.x.x.js +++ /dev/null @@ -1,18 +0,0 @@ -// flow-typed signature: 1dff23447d5e18f5ac2b05aaec7cfb74 -// flow-typed version: a453e98ea2/rimraf_v2.x.x/flow_>=v0.25.0 - -declare module 'rimraf' { - declare type Options = { - maxBusyTries?: number, - emfileWait?: number, - glob?: boolean, - disableGlob?: boolean - }; - - declare type Callback = (err: ?Error, path: ?string) => void; - - declare module.exports: { - (f: string, opts?: Options | Callback, callback?: Callback): void; - sync(path: string, opts?: Options): void; - }; -} diff --git a/flow-typed/npm/rxjs_v5.0.x.js b/flow-typed/npm/rxjs_v5.0.x.js deleted file mode 100644 index 50a5f3e3ac..0000000000 --- a/flow-typed/npm/rxjs_v5.0.x.js +++ /dev/null @@ -1,1503 +0,0 @@ -// flow-typed signature: 4aae218bc9c7bbec427ed4b027decad2 -// flow-typed version: e59aa15f07/rxjs_v5.0.x/flow_>=v0.34.x - -// FIXME(samgoldman) Remove top-level interface once Babel supports -// `declare interface` syntax. -// FIXME(samgoldman) Remove this once rxjs$Subject can mixin rxjs$Observer -interface rxjs$IObserver<-T> { - closed?: boolean; - next(value: T): mixed; - error(error: any): mixed; - complete(): mixed; -} - -type rxjs$PartialObserver<-T> = - | { - +next: (value: T) => mixed, - +error?: (error: any) => mixed, - +complete?: () => mixed - } - | { - +next?: (value: T) => mixed, - +error: (error: any) => mixed, - +complete?: () => mixed - } - | { - +next?: (value: T) => mixed, - +error?: (error: any) => mixed, - +complete: () => mixed - }; - -interface rxjs$ISubscription { - unsubscribe(): void; -} - -type rxjs$TeardownLogic = rxjs$ISubscription | (() => void); - -type rxjs$EventListenerOptions = - | { - capture?: boolean, - passive?: boolean, - once?: boolean - } - | boolean; - -type rxjs$ObservableInput = rxjs$Observable | Promise | Iterable; - -type rxjs$OperatorFunction = (rxjs$Observable) => rxjs$Observable; -type rxjs$OperatorFunctionLast> = ( - rxjs$Observable -) => R; - -type rxjs$NotificationKind = 'N' | 'C' | 'E'; -type rxjs$Notification = { - error: any, - hasValue: true, - kind: rxjs$NotificationKind, - value: T, -} | { - error: any, - hasValue: false, - kind: rxjs$NotificationKind, - value: void, -}; - -declare class rxjs$Observable<+T> { - static bindCallback( - callbackFunc: (callback: (_: void) => any) => any, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): () => rxjs$Observable; - static bindCallback( - callbackFunc: (callback: (result: U) => any) => any, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): () => rxjs$Observable; - static bindCallback( - callbackFunc: (v1: T, callback: (result: U) => any) => any, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): (v1: T) => rxjs$Observable; - static bindCallback( - callbackFunc: (v1: T, v2: T2, callback: (result: U) => any) => any, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): (v1: T, v2: T2) => rxjs$Observable; - static bindCallback( - callbackFunc: (v1: T, v2: T2, v3: T3, callback: (result: U) => any) => any, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): (v1: T, v2: T2, v3: T3) => rxjs$Observable; - static bindCallback( - callbackFunc: ( - v1: T, - v2: T2, - v3: T3, - v4: T4, - callback: (result: U) => any - ) => any, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): (v1: T, v2: T2, v3: T3, v4: T4) => rxjs$Observable; - static bindCallback( - callbackFunc: ( - v1: T, - v2: T2, - v3: T3, - v4: T4, - v5: T5, - callback: (result: U) => any - ) => any, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5) => rxjs$Observable; - static bindCallback( - callbackFunc: ( - v1: T, - v2: T2, - v3: T3, - v4: T4, - v5: T5, - v6: T6, - callback: (result: U) => any - ) => any, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6) => rxjs$Observable; - static bindCallback( - callbackFunc: (callback: (...args: Array) => any) => any, - selector: (...args: Array) => U, - scheduler?: rxjs$SchedulerClass - ): () => rxjs$Observable; - static bindCallback( - callbackFunc: (v1: T, callback: (...args: Array) => any) => any, - selector: (...args: Array) => U, - scheduler?: rxjs$SchedulerClass - ): (v1: T) => rxjs$Observable; - static bindCallback( - callbackFunc: ( - v1: T, - v2: T2, - callback: (...args: Array) => any - ) => any, - selector: (...args: Array) => U, - scheduler?: rxjs$SchedulerClass - ): (v1: T, v2: T2) => rxjs$Observable; - static bindCallback( - callbackFunc: ( - v1: T, - v2: T2, - v3: T3, - callback: (...args: Array) => any - ) => any, - selector: (...args: Array) => U, - scheduler?: rxjs$SchedulerClass - ): (v1: T, v2: T2, v3: T3) => rxjs$Observable; - static bindCallback( - callbackFunc: ( - v1: T, - v2: T2, - v3: T3, - v4: T4, - callback: (...args: Array) => any - ) => any, - selector: (...args: Array) => U, - scheduler?: rxjs$SchedulerClass - ): (v1: T, v2: T2, v3: T3, v4: T4) => rxjs$Observable; - static bindCallback( - callbackFunc: ( - v1: T, - v2: T2, - v3: T3, - v4: T4, - v5: T5, - callback: (...args: Array) => any - ) => any, - selector: (...args: Array) => U, - scheduler?: rxjs$SchedulerClass - ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5) => rxjs$Observable; - static bindCallback( - callbackFunc: ( - v1: T, - v2: T2, - v3: T3, - v4: T4, - v5: T5, - v6: T6, - callback: (...args: Array) => any - ) => any, - selector: (...args: Array) => U, - scheduler?: rxjs$SchedulerClass - ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6) => rxjs$Observable; - static bindCallback( - callbackFunc: Function, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): (...args: Array) => rxjs$Observable; - static bindCallback( - callbackFunc: Function, - selector?: (...args: Array) => T, - scheduler?: rxjs$SchedulerClass - ): (...args: Array) => rxjs$Observable; - - static bindNodeCallback( - callbackFunc: (callback: (err: any, result: U) => any) => any, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): () => rxjs$Observable; - static bindNodeCallback( - callbackFunc: (v1: T, callback: (err: any, result: U) => any) => any, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): (v1: T) => rxjs$Observable; - static bindNodeCallback( - callbackFunc: ( - v1: T, - v2: T2, - callback: (err: any, result: U) => any - ) => any, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): (v1: T, v2: T2) => rxjs$Observable; - static bindNodeCallback( - callbackFunc: ( - v1: T, - v2: T2, - v3: T3, - callback: (err: any, result: U) => any - ) => any, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): (v1: T, v2: T2, v3: T3) => rxjs$Observable; - static bindNodeCallback( - callbackFunc: ( - v1: T, - v2: T2, - v3: T3, - v4: T4, - callback: (err: any, result: U) => any - ) => any, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): (v1: T, v2: T2, v3: T3, v4: T4) => rxjs$Observable; - static bindNodeCallback( - callbackFunc: ( - v1: T, - v2: T2, - v3: T3, - v4: T4, - v5: T5, - callback: (err: any, result: U) => any - ) => any, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5) => rxjs$Observable; - static bindNodeCallback( - callbackFunc: ( - v1: T, - v2: T2, - v3: T3, - v4: T4, - v5: T5, - v6: T6, - callback: (err: any, result: U) => any - ) => any, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6) => rxjs$Observable; - static bindNodeCallback( - callbackFunc: Function, - selector?: void, - scheduler?: rxjs$SchedulerClass - ): (...args: Array) => rxjs$Observable; - static bindNodeCallback( - callbackFunc: Function, - selector?: (...args: Array) => T, - scheduler?: rxjs$SchedulerClass - ): (...args: Array) => rxjs$Observable; - - static concat(...sources: rxjs$Observable[]): rxjs$Observable; - - static create( - subscribe: ( - observer: rxjs$Observer - ) => rxjs$ISubscription | Function | void - ): rxjs$Observable; - - static defer( - observableFactory: () => rxjs$Observable | Promise - ): rxjs$Observable; - - static from( - input: rxjs$ObservableInput, - scheduler?: rxjs$SchedulerClass - ): rxjs$Observable; - - static fromEvent( - element: any, - eventName: string, - ...none: Array - ): rxjs$Observable; - static fromEvent( - element: any, - eventName: string, - options: rxjs$EventListenerOptions, - ...none: Array - ): rxjs$Observable; - static fromEvent( - element: any, - eventName: string, - selector: () => T, - ...none: Array - ): rxjs$Observable; - static fromEvent( - element: any, - eventName: string, - options: rxjs$EventListenerOptions, - selector: () => T - ): rxjs$Observable; - - static fromEventPattern( - addHandler: (handler: (item: T) => void) => void, - removeHandler: (handler: (item: T) => void) => void, - selector?: () => T - ): rxjs$Observable; - - static fromPromise(promise: Promise): rxjs$Observable; - - static empty(): rxjs$Observable; - - static interval(period: number): rxjs$Observable; - - static timer( - initialDelay: number | Date, - period?: number, - scheduler?: rxjs$SchedulerClass - ): rxjs$Observable; - - static merge( - source0: rxjs$Observable, - source1: rxjs$Observable - ): rxjs$Observable; - static merge( - source0: rxjs$Observable, - source1: rxjs$Observable, - source2: rxjs$Observable - ): rxjs$Observable; - static merge(...sources: rxjs$Observable[]): rxjs$Observable; - - static never(): rxjs$Observable; - - static of(...values: T[]): rxjs$Observable; - - static range( - start?: number, - count?: number, - scheduler?: rxjs$SchedulerClass - ): rxjs$Observable; - - static throw(error: any): rxjs$Observable; - - audit( - durationSelector: (value: T) => rxjs$Observable | Promise - ): rxjs$Observable; - - auditTime( - duration: number, - scheduler?: rxjs$SchedulerClass - ): rxjs$Observable; - - race(other: rxjs$Observable): rxjs$Observable; - - repeat(count?: number): rxjs$Observable; - - buffer(bufferBoundaries: rxjs$Observable): rxjs$Observable>; - - bufferCount( - bufferSize: number, - startBufferEvery?: number - ): rxjs$Observable>; - - bufferTime( - bufferTimeSpan: number, - bufferCreationInterval?: number, - maxBufferSize?: number, - scheduler?: rxjs$SchedulerClass - ): rxjs$Observable>; - - bufferToggle( - openings: rxjs$Observable | Promise, - closingSelector: (value: U) => rxjs$Observable | Promise - ): rxjs$Observable>; - - bufferWhen( - closingSelector: () => rxjs$Observable - ): rxjs$Observable>; - - catch( - selector: (err: any, caught: rxjs$Observable) => rxjs$Observable - ): rxjs$Observable; - - concat(...sources: rxjs$Observable[]): rxjs$Observable; - - concatAll(): rxjs$Observable; - - concatMap( - f: (value: T, index: number) => rxjs$ObservableInput, - _: void - ): rxjs$Observable; - concatMap( - f: (value: T, index: number) => rxjs$ObservableInput, - resultSelector: ( - outerValue: T, - innerValue: U, - outerIndex: number, - innerIndex: number - ) => V - ): rxjs$Observable; - - debounceTime( - dueTime: number, - scheduler?: rxjs$SchedulerClass - ): rxjs$Observable; - - defaultIfEmpty(defaultValue: U): rxjs$Observable; - - delay(dueTime: number, scheduler?: rxjs$SchedulerClass): rxjs$Observable; - - distinctUntilChanged(compare?: (x: T, y: T) => boolean): rxjs$Observable; - - distinct( - keySelector?: (value: T) => U, - flushes?: rxjs$Observable - ): rxjs$Observable; - - distinctUntilKeyChanged( - key: string, - compare?: (x: mixed, y: mixed) => boolean - ): rxjs$Observable; - - elementAt(index: number, defaultValue?: T): rxjs$Observable; - - exhaustMap( - project: (value: T, index: number) => rxjs$ObservableInput, - _: void - ): rxjs$Observable; - exhaustMap( - project: (value: T, index: number) => rxjs$ObservableInput, - resultSelector: ( - outerValue: T, - innerValue: U, - outerIndex: number, - innerIndex: number - ) => V - ): rxjs$Observable; - - expand( - project: (value: T, index: number) => rxjs$Observable, - concurrent?: number, - scheduler?: rxjs$SchedulerClass - ): rxjs$Observable; - - filter(predicate: typeof Boolean): rxjs$Observable<$NonMaybeType>; - filter( - predicate: (value: T, index: number) => boolean, - thisArg?: any - ): rxjs$Observable; - - finally(f: () => mixed): rxjs$Observable; - - first( - predicate?: (value: T, index: number, source: rxjs$Observable) => boolean - ): rxjs$Observable; - first( - predicate: ?( - value: T, - index: number, - source: rxjs$Observable - ) => boolean, - resultSelector: (value: T, index: number) => U - ): rxjs$Observable; - first( - predicate: ?( - value: T, - index: number, - source: rxjs$Observable - ) => boolean, - resultSelector: ?(value: T, index: number) => U, - defaultValue: U - ): rxjs$Observable; - - groupBy( - keySelector: (value: T) => K, - _: void - ): rxjs$Observable>; - groupBy( - keySelector: (value: T) => K, - elementSelector: (value: T) => V, - durationSelector?: ( - grouped: rxjs$GroupedObservable - ) => rxjs$Observable - ): rxjs$Observable>; - - ignoreElements(): rxjs$Observable; - - last( - predicate?: (value: T, index: number, source: rxjs$Observable) => boolean - ): rxjs$Observable; - last( - predicate: ?( - value: T, - index: number, - source: rxjs$Observable - ) => boolean, - resultSelector: (value: T, index: number) => U - ): rxjs$Observable; - last( - predicate: ?( - value: T, - index: number, - source: rxjs$Observable - ) => boolean, - resultSelector: ?(value: T, index: number) => U, - defaultValue: U - ): rxjs$Observable; - - let( - project: (self: rxjs$Observable) => rxjs$Observable - ): rxjs$Observable; - - // Alias for `let` - letBind( - project: (self: rxjs$Observable) => rxjs$Observable - ): rxjs$Observable; - - switch(): T; // assumption: T is Observable - - // Alias for `mergeMap` - flatMap( - project: (value: T, index: number) => rxjs$ObservableInput, - concurrency?: number - ): rxjs$Observable; - flatMap( - project: (value: T, index: number) => rxjs$ObservableInput, - resultSelector: ( - outerValue: T, - innerValue: U, - outerIndex: number, - innerIndex: number - ) => V, - concurrency?: number - ): rxjs$Observable; - - flatMapTo(innerObservable: rxjs$Observable): rxjs$Observable; - - flatMapTo( - innerObservable: rxjs$Observable, - resultSelector: ( - outerValue: T, - innerValue: U, - outerIndex: number, - innerIndex: number - ) => V, - concurrent?: number - ): rxjs$Observable; - - switchMap( - project: (value: T, index: number) => rxjs$ObservableInput, - _: void - ): rxjs$Observable; - switchMap( - project: (value: T, index: number) => rxjs$ObservableInput, - resultSelector: ( - outerValue: T, - innerValue: U, - outerIndex: number, - innerIndex: number - ) => V - ): rxjs$Observable; - - switchMapTo(innerObservable: rxjs$Observable): rxjs$Observable; - - materialize(): rxjs$Observable>; - - map(f: (value: T) => U): rxjs$Observable; - - mapTo(value: U): rxjs$Observable; - - merge(other: rxjs$Observable): rxjs$Observable; - - mergeAll(): rxjs$Observable; - - mergeMap( - project: (value: T, index: number) => rxjs$ObservableInput, - concurrency?: number - ): rxjs$Observable; - mergeMap( - project: (value: T, index: number) => rxjs$ObservableInput, - resultSelector: ( - outerValue: T, - innerValue: U, - outerIndex: number, - innerIndex: number - ) => V, - concurrency?: number - ): rxjs$Observable; - - mergeMapTo(innerObservable: rxjs$Observable): rxjs$Observable; - - mergeMapTo( - innerObservable: rxjs$Observable, - resultSelector: ( - outerValue: T, - innerValue: U, - outerIndex: number, - innerIndex: number - ) => V, - concurrent?: number - ): rxjs$Observable; - - multicast( - subjectOrSubjectFactory: rxjs$Subject | (() => rxjs$Subject) - ): rxjs$ConnectableObservable; - - observeOn(scheduler: rxjs$SchedulerClass): rxjs$Observable; - - pairwise(): rxjs$Observable<[T, T]>; - - partition( - predicate: (value: T, index: number) => boolean, - thisArg: any - ): [rxjs$Observable, rxjs$Observable]; - - pipe(): rxjs$Observable; - - pipe(op1: rxjs$OperatorFunctionLast): A; - - pipe( - op1: rxjs$OperatorFunction, - op2: rxjs$OperatorFunctionLast - ): B; - - pipe( - op1: rxjs$OperatorFunction, - op2: rxjs$OperatorFunction, - op3: rxjs$OperatorFunctionLast - ): C; - - pipe( - op1: rxjs$OperatorFunction, - op2: rxjs$OperatorFunction, - op3: rxjs$OperatorFunction, - op4: rxjs$OperatorFunctionLast - ): D; - - pipe( - op1: rxjs$OperatorFunction, - op2: rxjs$OperatorFunction, - op3: rxjs$OperatorFunction, - op4: rxjs$OperatorFunction, - op5: rxjs$OperatorFunctionLast - ): E; - - publish(): rxjs$ConnectableObservable; - - publishLast(): rxjs$ConnectableObservable; - - reduce( - accumulator: ( - acc: U, - currentValue: T, - index: number, - source: rxjs$Observable - ) => U, - seed: U - ): rxjs$Observable; - - sample(notifier: rxjs$Observable): rxjs$Observable; - - sampleTime( - delay: number, - scheduler?: rxjs$SchedulerClass - ): rxjs$Observable; - - publishReplay( - bufferSize?: number, - windowTime?: number, - scheduler?: rxjs$SchedulerClass - ): rxjs$ConnectableObservable; - - retry(retryCount: ?number): rxjs$Observable; - - retryWhen( - notifier: (errors: rxjs$Observable) => rxjs$Observable - ): rxjs$Observable; - - scan(f: (acc: U, value: T) => U, initialValue: U): rxjs$Observable; - - share(): rxjs$Observable; - - skip(count: number): rxjs$Observable; - - skipUntil(other: rxjs$Observable | Promise): rxjs$Observable; - - skipWhile( - predicate: (value: T, index: number) => boolean - ): rxjs$Observable; - - startWith(...values: Array): rxjs$Observable; - - subscribeOn(scheduler: rxjs$SchedulerClass): rxjs$Observable; - - take(count: number): rxjs$Observable; - - takeLast(count: number): rxjs$Observable; - - takeUntil(other: rxjs$Observable): rxjs$Observable; - - takeWhile( - predicate: (value: T, index: number) => boolean - ): rxjs$Observable; - - do( - onNext?: (value: T) => mixed, - onError?: (error: any) => mixed, - onCompleted?: () => mixed - ): rxjs$Observable; - do(observer: { - next?: (value: T) => mixed, - error?: (error: any) => mixed, - complete?: () => mixed - }): rxjs$Observable; - - throttleTime(duration: number): rxjs$Observable; - - timeout(due: number | Date, _: void): rxjs$Observable; - - timeoutWith( - due: number | Date, - withObservable: rxjs$Observable, - scheduler?: rxjs$SchedulerClass - ): rxjs$Observable; - - toArray(): rxjs$Observable; - - toPromise(): Promise; - - subscribe(observer: rxjs$PartialObserver): rxjs$Subscription; - subscribe( - onNext: ?(value: T) => mixed, - onError: ?(error: any) => mixed, - onCompleted: ?() => mixed - ): rxjs$Subscription; - - static combineLatest( - a: rxjs$Observable, - resultSelector: (a: A) => B - ): rxjs$Observable; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - resultSelector: (a: A, b: B) => C - ): rxjs$Observable; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - resultSelector: (a: A, b: B, c: C) => D - ): rxjs$Observable; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D) => E - ): rxjs$Observable; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E) => F - ): rxjs$Observable; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G - ): rxjs$Observable; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H - ): rxjs$Observable; - - static combineLatest(a: rxjs$Observable, _: void): rxjs$Observable<[A]>; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B]>; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C]>; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C, D]>; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C, D, E]>; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C, D, E, F]>; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C, D, E, F, G]>; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - h: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C, D, E, F, G, H]>; - - combineLatest(a: rxjs$Observable, _: void): rxjs$Observable<[T, A]>; - - combineLatest( - a: rxjs$Observable, - resultSelector: (a: A) => B - ): rxjs$Observable; - - combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - resultSelector: (a: A, b: B) => C - ): rxjs$Observable; - - combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - resultSelector: (a: A, b: B, c: C) => D - ): rxjs$Observable; - - combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D) => E - ): rxjs$Observable; - - combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E) => F - ): rxjs$Observable; - - combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G - ): rxjs$Observable; - - combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H - ): rxjs$Observable; - - static zip( - a: rxjs$Observable, - resultSelector: (a: A) => B - ): rxjs$Observable; - - static zip( - a: rxjs$Observable, - b: rxjs$Observable, - resultSelector: (a: A, b: B) => C - ): rxjs$Observable; - - static zip( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - resultSelector: (a: A, b: B, c: C) => D - ): rxjs$Observable; - - static zip( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D) => E - ): rxjs$Observable; - - static zip( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E) => F - ): rxjs$Observable; - - static zip( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G - ): rxjs$Observable; - - static zip( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H - ): rxjs$Observable; - - static zip(a: rxjs$Observable, _: void): rxjs$Observable<[A]>; - - static zip( - a: rxjs$Observable, - b: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B]>; - - static zip( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C]>; - - static zip( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C, D]>; - - static zip( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C, D, E]>; - - static zip( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C, D, E, F]>; - - static zip( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C, D, E, F, G]>; - - static zip( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - h: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C, D, E, F, G, H]>; - - zip(a: rxjs$Observable, _: void): rxjs$Observable<[T, A]>; - - zip( - a: rxjs$Observable, - resultSelector: (a: A) => B - ): rxjs$Observable; - - zip( - a: rxjs$Observable, - b: rxjs$Observable, - resultSelector: (a: A, b: B) => C - ): rxjs$Observable; - - zip( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - resultSelector: (a: A, b: B, c: C) => D - ): rxjs$Observable; - - zip( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D) => E - ): rxjs$Observable; - - zip( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E) => F - ): rxjs$Observable; - - zip( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G - ): rxjs$Observable; - - zip( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H - ): rxjs$Observable; - - static forkJoin( - a: rxjs$Observable, - resultSelector: (a: A) => B - ): rxjs$Observable; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - resultSelector: (a: A, b: B) => C - ): rxjs$Observable; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - resultSelector: (a: A, b: B, c: C) => D - ): rxjs$Observable; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D) => E - ): rxjs$Observable; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E) => F - ): rxjs$Observable; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G - ): rxjs$Observable; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H - ): rxjs$Observable; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B]>; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C]>; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C, D]>; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C, D, E]>; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C, D, E, F]>; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C, D, E, F, G]>; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - h: rxjs$Observable, - _: void - ): rxjs$Observable<[A, B, C, D, E, F, G, H]>; - - static forkJoin( - a: Array>, - _: void - ): rxjs$Observable>; - - static forkJoin( - a: Array>, - _: void - ): rxjs$Observable; - - static forkJoin( - a: Array>, - resultSelector: (...values: Array) => B - ): rxjs$Observable; - - static forkJoin( - a: Array>, - resultSelector: (...values: Array) => A - ): rxjs$Observable; - - window( - windowBoundaries: rxjs$Observable - ): rxjs$Observable>; - windowCount( - windowSize: number, - startWindowEvery?: number - ): rxjs$Observable>; - windowToggle( - openings: rxjs$Observable, - closingSelector: (value: A) => rxjs$Observable - ): rxjs$Observable>; - windowWhen( - closingSelector: () => rxjs$Observable - ): rxjs$Observable>; - - withLatestFrom(a: rxjs$Observable, _: void): rxjs$Observable<[T, A]>; - - withLatestFrom( - a: rxjs$Observable, - resultSelector: (a: A) => B - ): rxjs$Observable; - - withLatestFrom( - a: rxjs$Observable, - b: rxjs$Observable, - resultSelector: (a: A, b: B) => C - ): rxjs$Observable; - - withLatestFrom( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - resultSelector: (a: A, b: B, c: C) => D - ): rxjs$Observable; - - withLatestFrom( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D) => E - ): rxjs$Observable; - - withLatestFrom( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E) => F - ): rxjs$Observable; - - withLatestFrom( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G - ): rxjs$Observable; - - withLatestFrom( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H - ): rxjs$Observable; - - static using( - resourceFactory: () => ?R, - observableFactory: (resource: R) => rxjs$Observable | Promise | void - ): rxjs$Observable; - - _subscribe(observer: rxjs$Subscriber): rxjs$Subscription; - - _isScalar: boolean; - source: ?rxjs$Observable; - operator: ?rxjs$Operator; -} - -declare class rxjs$ConnectableObservable extends rxjs$Observable { - connect(): rxjs$Subscription; - refCount(): rxjs$Observable; -} - -declare class rxjs$GroupedObservable extends rxjs$Observable { - key: K; -} - -declare class rxjs$Observer { - next(value: T): mixed; - - error(error: any): mixed; - - complete(): mixed; -} - -declare interface rxjs$Operator { - call(subscriber: rxjs$Subscriber, source: any): rxjs$TeardownLogic; -} - -// FIXME(samgoldman) should be `mixins rxjs$Observable, rxjs$Observer` -// once Babel parsing support exists: https://phabricator.babeljs.io/T6821 -declare class rxjs$Subject extends rxjs$Observable { - asObservable(): rxjs$Observable; - - observers: Array>; - - unsubscribe(): void; - - // Copied from rxjs$Observer - next(value: T): mixed; - error(error: any): mixed; - complete(): mixed; - - // For use in subclasses only: - _next(value: T): void; -} - -declare class rxjs$AnonymousSubject extends rxjs$Subject { - source: ?rxjs$Observable; - destination: ?rxjs$Observer; - - constructor( - destination?: rxjs$IObserver, - source?: rxjs$Observable - ): void; - next(value: T): void; - error(err: any): void; - complete(): void; -} - -declare class rxjs$BehaviorSubject extends rxjs$Subject { - constructor(initialValue: T): void; - - getValue(): T; -} - -declare class rxjs$ReplaySubject extends rxjs$Subject { - constructor( - bufferSize?: number, - windowTime?: number, - scheduler?: rxjs$SchedulerClass - ): void; -} - -declare class rxjs$Subscription { - unsubscribe(): void; - add(teardown: rxjs$TeardownLogic): rxjs$Subscription; -} - -declare class rxjs$Subscriber extends rxjs$Subscription { - static create( - next?: (x?: T) => void, - error?: (e?: any) => void, - complete?: () => void - ): rxjs$Subscriber; - - constructor( - destinationOrNext?: rxjs$PartialObserver | ((value: T) => void), - error?: (e?: any) => void, - complete?: () => void - ): void; - next(value?: T): void; - error(err?: any): void; - complete(): void; - unsubscribe(): void; -} - -declare class rxjs$SchedulerClass { - schedule( - work: (state?: T) => void, - delay?: number, - state?: T - ): rxjs$Subscription; -} - -declare class rxjs$TimeoutError extends Error {} - -declare module "rxjs" { - declare module.exports: { - Observable: typeof rxjs$Observable, - Observer: typeof rxjs$Observer, - ConnectableObservable: typeof rxjs$ConnectableObservable, - Subject: typeof rxjs$Subject, - Subscriber: typeof rxjs$Subscriber, - AnonymousSubject: typeof rxjs$AnonymousSubject, - BehaviorSubject: typeof rxjs$BehaviorSubject, - ReplaySubject: typeof rxjs$ReplaySubject, - Scheduler: { - asap: rxjs$SchedulerClass, - queue: rxjs$SchedulerClass, - animationFrame: rxjs$SchedulerClass, - async: rxjs$SchedulerClass - }, - Subscription: typeof rxjs$Subscription, - TimeoutError: typeof rxjs$TimeoutError - }; -} - -declare module "rxjs/Observable" { - declare module.exports: { - Observable: typeof rxjs$Observable - }; -} - -declare module "rxjs/Observer" { - declare module.exports: { - Observer: typeof rxjs$Observer - }; -} - -declare module "rxjs/BehaviorSubject" { - declare module.exports: { - BehaviorSubject: typeof rxjs$BehaviorSubject - }; -} - -declare module "rxjs/ReplaySubject" { - declare module.exports: { - ReplaySubject: typeof rxjs$ReplaySubject - }; -} - -declare module "rxjs/Subject" { - declare module.exports: { - Subject: typeof rxjs$Subject, - AnonymousSubject: typeof rxjs$AnonymousSubject - }; -} - -declare module "rxjs/Subscriber" { - declare module.exports: { - Subscriber: typeof rxjs$Subscriber - }; -} - -declare module "rxjs/Subscription" { - declare module.exports: { - Subscription: typeof rxjs$Subscription - }; -} - -declare module "rxjs/testing/TestScheduler" { - declare module.exports: { - TestScheduler: typeof rxjs$SchedulerClass - }; -} diff --git a/flow-typed/npm/semver_v5.1.x.js b/flow-typed/npm/semver_v5.1.x.js deleted file mode 100644 index d10661216c..0000000000 --- a/flow-typed/npm/semver_v5.1.x.js +++ /dev/null @@ -1,110 +0,0 @@ -// flow-typed signature: 1d1f54a0e3983f7bd1d91411d7e64f22 -// flow-typed version: 99dfe36842/semver_v5.1.x/flow_>=v0.20.x - -declare module 'semver' { - declare type Release = - 'major' | - 'premajor' | - 'minor' | - 'preminor' | - 'patch' | - 'prepatch' | - 'prerelease'; - - // The supported comparators are taken from the source here: - // https://github.com/npm/node-semver/blob/8bd070b550db2646362c9883c8d008d32f66a234/semver.js#L623 - declare type Operator = - '===' | - '!==' | - '==' | - '=' | - '' | // Not sure why you would want this, but whatever. - '!=' | - '>' | - '>=' | - '<' | - '<='; - - declare class SemVer { - build: Array; - loose: ?boolean; - major: number; - minor: number; - patch: number; - prerelease: Array; - raw: string; - version: string; - - constructor(version: string | SemVer, loose?: boolean): SemVer; - compare(other: string | SemVer): -1 | 0 | 1; - compareMain(other: string | SemVer): -1 | 0 | 1; - comparePre(other: string | SemVer): -1 | 0 | 1; - format(): string; - inc(release: Release, identifier: string): this; - } - - declare class Comparator { - loose?: boolean; - operator: Operator; - semver: SemVer; - value: string; - - constructor(comp: string | Comparator, loose?: boolean): Comparator; - parse(comp: string): void; - test(version: string): boolean; - } - - declare class Range { - loose: ?boolean; - raw: string; - set: Array>; - - constructor(range: string | Range, loose?: boolean): Range; - format(): string; - parseRange(range: string): Array; - test(version: string): boolean; - toString(): string; - } - - declare var SEMVER_SPEC_VERSION: string; - declare var re: Array; - declare var src: Array; - - // Functions - declare function valid(v: string | SemVer, loose?: boolean): string | null; - declare function clean(v: string | SemVer, loose?: boolean): string | null; - declare function inc(v: string | SemVer, release: Release, loose?: boolean, identifier?: string): string | null; - declare function inc(v: string | SemVer, release: Release, identifier: string): string | null; - declare function major(v: string | SemVer, loose?: boolean): number; - declare function minor(v: string | SemVer, loose?: boolean): number; - declare function patch(v: string | SemVer, loose?: boolean): number; - - // Comparison - declare function gt(v1: string | SemVer, v2: string | SemVer, loose?: boolean): boolean; - declare function gte(v1: string | SemVer, v2: string | SemVer, loose?: boolean): boolean; - declare function lt(v1: string | SemVer, v2: string | SemVer, loose?: boolean): boolean; - declare function lte(v1: string | SemVer, v2: string | SemVer, loose?: boolean): boolean; - declare function eq(v1: string | SemVer, v2: string | SemVer, loose?: boolean): boolean; - declare function neq(v1: string | SemVer, v2: string | SemVer, loose?: boolean): boolean; - declare function cmp(v1: string | SemVer, comparator: Operator, v2: string | SemVer, loose?: boolean): boolean; - declare function compare(v1: string | SemVer, v2: string | SemVer, loose?: boolean): -1 | 0 | 1; - declare function rcompare(v1: string | SemVer, v2: string | SemVer, loose?: boolean): -1 | 0 | 1; - declare function compareLoose(v1: string | SemVer, v2: string | SemVer): -1 | 0 | 1; - declare function diff(v1: string | SemVer, v2: string | SemVer): ?Release; - declare function sort(list: Array, loose?: boolean): Array; - declare function rsort(list: Array, loose?: boolean): Array; - declare function compareIdentifiers(v1: string | SemVer, v2: string | SemVer): -1 | 0 | 1; - declare function rcompareIdentifiers(v1: string | SemVer, v2: string | SemVer): -1 | 0 | 1; - - // Ranges - declare function validRange(range: string | Range, loose?: boolean): string | null; - declare function satisfies(version: string | SemVer, range: string | Range, loose?: boolean): boolean; - declare function maxSatisfying(versions: Array, range: string | Range, loose?: boolean): string | SemVer | null; - declare function gtr(version: string | SemVer, range: string | Range, loose?: boolean): boolean; - declare function ltr(version: string | SemVer, range: string | Range, loose?: boolean): boolean; - declare function outside(version: string | SemVer, range: string | Range, hilo: '>' | '<', loose?: boolean): boolean; - - // Not explicitly documented, or deprecated - declare function parse(version: string, loose?: boolean): ?SemVer; - declare function toComparators(range: string | Range, loose?: boolean): Array>; -} diff --git a/flow-typed/npm/smoothscroll-polyfill_v0.x.x.js b/flow-typed/npm/smoothscroll-polyfill_v0.x.x.js deleted file mode 100644 index d973f9eaf0..0000000000 --- a/flow-typed/npm/smoothscroll-polyfill_v0.x.x.js +++ /dev/null @@ -1,8 +0,0 @@ -// flow-typed signature: f5d1cd32fd86e3c7b132d220e88b3454 -// flow-typed version: 463c76ef0c/smoothscroll-polyfill_v0.x.x/flow_>=v0.47.x - -declare module "smoothscroll-polyfill" { - declare module.exports: { - polyfill: () => void - }; -} diff --git a/flow-typed/npm/strip-ansi_v3.x.x.js b/flow-typed/npm/strip-ansi_v3.x.x.js deleted file mode 100644 index d36b7653a6..0000000000 --- a/flow-typed/npm/strip-ansi_v3.x.x.js +++ /dev/null @@ -1,6 +0,0 @@ -// flow-typed signature: 8b05dd8048f5193e21269eab58859283 -// flow-typed version: 94e9f7e0a4/strip-ansi_v3.x.x/flow_>=v0.28.x - -declare module 'strip-ansi' { - declare module.exports: (input: string) => string; -} diff --git a/flow-typed/npm/strip-json-comments_v2.x.x.js b/flow-typed/npm/strip-json-comments_v2.x.x.js deleted file mode 100644 index 6650343790..0000000000 --- a/flow-typed/npm/strip-json-comments_v2.x.x.js +++ /dev/null @@ -1,9 +0,0 @@ -// flow-typed signature: 355bccb70c51fc8f5126d5130c2ff1de -// flow-typed version: b43dff3e0e/strip-json-comments_v2.x.x/flow_>=v0.25.x - -declare module 'strip-json-comments' { - declare module.exports: ( - input: string, - options?: { whitespace: boolean } - ) => string; -} diff --git a/flow-typed/npm/uuid_v3.x.x.js b/flow-typed/npm/uuid_v3.x.x.js deleted file mode 100644 index bf8d507b36..0000000000 --- a/flow-typed/npm/uuid_v3.x.x.js +++ /dev/null @@ -1,102 +0,0 @@ -// flow-typed signature: 3cf668e64747095cab0bb360cf2fb34f -// flow-typed version: d659bd0cb8/uuid_v3.x.x/flow_>=v0.32.x - -declare module "uuid" { - declare class uuid { - static ( - options?: {| - random?: number[], - rng?: () => number[] | Buffer - |}, - buffer?: number[] | Buffer, - offset?: number - ): string, - - static v1( - options?: {| - node?: number[], - clockseq?: number, - msecs?: number | Date, - nsecs?: number - |}, - buffer?: number[] | Buffer, - offset?: number - ): string, - - static v4( - options?: {| - random?: number[], - rng?: () => number[] | Buffer - |}, - buffer?: number[] | Buffer, - offset?: number - ): string - } - declare module.exports: Class; -} - -declare module "uuid/v1" { - declare class v1 { - static ( - options?: {| - node?: number[], - clockseq?: number, - msecs?: number | Date, - nsecs?: number - |}, - buffer?: number[] | Buffer, - offset?: number - ): string - } - - declare module.exports: Class; -} - -declare module "uuid/v3" { - declare class v3 { - static ( - name?: string | number[], - namespace?: string | number[], - buffer?: number[] | Buffer, - offset?: number - ): string, - - static name: string, - static DNS: string, - static URL: string - } - - declare module.exports: Class; -} - -declare module "uuid/v4" { - declare class v4 { - static ( - options?: {| - random?: number[], - rng?: () => number[] | Buffer - |}, - buffer?: number[] | Buffer, - offset?: number - ): string - } - - declare module.exports: Class; -} - -declare module "uuid/v5" { - declare class v5 { - static ( - name?: string | number[], - namespace?: string | number[], - buffer?: number[] | Buffer, - offset?: number - ): string, - - static name: string, - static DNS: string, - static URL: string - } - - declare module.exports: Class; -} diff --git a/flow-typed/npm/xterm_v3.x.x.js b/flow-typed/npm/xterm_v3.x.x.js deleted file mode 100644 index d8a4002467..0000000000 --- a/flow-typed/npm/xterm_v3.x.x.js +++ /dev/null @@ -1,258 +0,0 @@ -// flow-typed signature: 648842eba230bb7a0960d21a0dc2fe5e -// flow-typed version: d94fd329cc/xterm_v3.x.x/flow_>=v0.56.x - -declare module "xterm" { - declare export type FontWeight = - | "normal" - | "bold" - | "100" - | "200" - | "300" - | "400" - | "500" - | "600" - | "700" - | "800" - | "900"; - - declare export type Theme = $Shape<{ - foreground: string, - background: string, - cursor: string, - cursorAccent: string, - selection: string, - black: string, - red: string, - green: string, - yellow: string, - blue: string, - magenta: string, - cyan: string, - white: string, - brightBlack: string, - brightRed: string, - brightGreen: string, - brightYellow: string, - brightBlue: string, - brightMagenta: string, - brightCyan: string, - brightWhite: string - }>; - - declare export type TerminalOptions = $Shape<{ - allowTransparency: boolean, - bellSound: string, - bellStyle: "none" | "sound", - cols: number, - cursorBlink: boolean, - cursorStyle: "block" | "underline" | "bar", - disableStdin: boolean, - enableBold: boolean, - fontSize: number, - fontFamily: string, - fontWeight: FontWeight, - fontWeightBold: FontWeight, - letterSpacing: number, - lineHeight: number, - macOptionIsMeta: boolean, - rightClickSelectsWord: boolean, - rows: number, - screenReaderMode: boolean, - scrollback: number, - tabStopWidth: number, - theme: Theme, - }>; - - declare export type LinkMatcherOptions = $Shape<{ - matchIndex: number, - validationCallback: ( - uri: string, - callback: (isValid: boolean) => void - ) => void, - tooltipCallback: (event: MouseEvent, uri: string) => boolean | void, - leaveCallback: (event: MouseEvent, uri: string) => boolean | void, - priority: number, - willLinkActivate: (event: MouseEvent, uri: string) => boolean - }>; - - declare export type Disposable = {| - dispose(): void - |}; - - declare export type Marker = {| - ...Disposable, - +id: number, - +isDisposed: boolean, - +line: number - |}; - - declare export type LocalizableStrings = {| - blankLine: string, - promptLabel: string, - tooMuchOutput: string - |}; - - declare export class Terminal { - element: HTMLElement; - textarea: HTMLTextAreaElement; - rows: number; - cols: number; - markers: Marker[]; - static strings: LocalizableStrings; - constructor(options?: TerminalOptions): Terminal; - blur(): void; - focus(): void; - on( - type: "blur" | "focus" | "linefeed" | "selection", - listener: () => void - ): void; - on(type: "data", listener: (...args: any[]) => void): void; - on( - type: "key", - listener: (key?: string, event?: KeyboardEvent) => void - ): void; - on( - type: "keypress" | "keydown", - listener: (event?: KeyboardEvent) => void - ): void; - on( - type: "refresh", - listener: (data?: { start: number, end: number }) => void - ): void; - on( - type: "resize", - listener: (data?: { cols: number, rows: number }) => void - ): void; - on(type: "scroll", listener: (ydisp?: number) => void): void; - on(type: "title", listener: (title?: string) => void): void; - on(type: string, listener: (...args: any[]) => void): void; - off( - type: | "blur" - | "focus" - | "linefeed" - | "selection" - | "data" - | "key" - | "keypress" - | "keydown" - | "refresh" - | "resize" - | "scroll" - | "title" - | string, - listener: (...args: any[]) => void - ): void; - emit(type: string, data?: any): void; - addDisposableListener( - type: string, - handler: (...args: any[]) => void - ): Disposable; - resize(columns: number, rows: number): void; - writeln(data: string): void; - open(parent: HTMLElement): void; - attachCustomKeyEventHandler( - customKeyEventHandler: (event: KeyboardEvent) => boolean - ): void; - registerLinkMatcher( - regex: RegExp, - handler: (event: MouseEvent, uri: string) => void, - options?: LinkMatcherOptions - ): number; - deregisterLinkMatcher(matcherId: number): void; - addMarker(cursorYOffset: number): Marker; - hasSelection(): boolean; - getSelection(): string; - clearSelection(): void; - selectAll(): void; - selectLines(start: number, end: number): void; - destroy(): void; - scrollLines(amount: number): void; - scrollPages(pageCount: number): void; - scrollToTop(): void; - scrollToBottom(): void; - scrollToLine(line: number): void; - clear(): void; - write(data: string): void; - getOption( - key: | "bellSound" - | "bellStyle" - | "cursorStyle" - | "fontFamily" - | "fontWeight" - | "fontWeightBold" - | "termName" - ): string; - getOption( - key: | "allowTransparency" - | "cancelEvents" - | "convertEol" - | "cursorBlink" - | "debug" - | "disableStdin" - | "enableBold" - | "macOptionIsMeta" - | "rightClickSelectsWord" - | "popOnBell" - | "screenKeys" - | "useFlowControl" - | "visualBell" - ): boolean; - getOption(key: "colors"): Array; - getOption( - key: | "cols" - | "fontSize" - | "letterSpacing" - | "lineHeight" - | "rows" - | "tabStopWidth" - | "scrollback" - ): number; - getOption(key: "handler"): (data: string) => void; - getOption(key: string): any; - setOption( - key: "fontFamily" | "termName" | "bellSound", - value: string - ): void; - setOption(key: "fontWeight" | "fontWeightBold", value: ?FontWeight): void; - setOption( - key: "bellStyle", - value: null | "none" | "visual" | "sound" | "both" - ): void; - setOption( - key: "cursorStyle", - value: null | "block" | "underline" | "bar" - ): void; - setOption( - key: | "allowTransparency" - | "cancelEvents" - | "convertEol" - | "cursorBlink" - | "debug" - | "disableStdin" - | "enableBold" - | "macOptionIsMeta" - | "popOnBell" - | "rightClickSelectsWord" - | "screenKeys" - | "useFlowControl" - | "visualBell", - value: boolean - ): void; - setOption(key: "colors", value: Array): void; - setOption( - key: | "fontSize" - | "letterSpacing" - | "lineHeight" - | "tabStopWidth" - | "scrollback", - value: number - ): void; - setOption(key: "handler", value: (data: string) => void): void; - setOption(key: "theme", value: Theme): void; - setOption(key: "cols" | "rows", value: number): void; - setOption(key: string, value: any): void; - refresh(start: number, end: number): void; - reset(): void; - static applyAddon(addon: any): void; - } -} diff --git a/jest/__atom_tests__/builtin-modules-test.js b/jest/__atom_tests__/builtin-modules-test.js index 3a85cde1a8..63bc40cbee 100644 --- a/jest/__atom_tests__/builtin-modules-test.js +++ b/jest/__atom_tests__/builtin-modules-test.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +7,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ @@ -15,4 +17,4 @@ test('pass', () => { expect(atom).toBeDefined(); expect(electron).toBeDefined(); -}); +}); \ No newline at end of file diff --git a/jest/__atom_tests__/fake_timers-test.js b/jest/__atom_tests__/fake_timers-test.js index 0cf03eaaaa..b82b9158a1 100644 --- a/jest/__atom_tests__/fake_timers-test.js +++ b/jest/__atom_tests__/fake_timers-test.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +7,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ @@ -13,4 +15,4 @@ test('fake timers are not available yet', () => { expect(() => { jest.useFakeTimers(); }).toThrow('fakeTimers are not supproted in atom environment'); -}); +}); \ No newline at end of file diff --git a/jest/__atom_tests__/sample-1-test.js b/jest/__atom_tests__/sample-1-test.js index ca717f8a1a..900530c094 100644 --- a/jest/__atom_tests__/sample-1-test.js +++ b/jest/__atom_tests__/sample-1-test.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,10 +7,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ test('atom', () => { expect(1).toBe(1); -}); +}); \ No newline at end of file diff --git a/jest/__atom_tests__/sample-2-test.js b/jest/__atom_tests__/sample-2-test.js index ddfedf4249..5c7b250a7b 100644 --- a/jest/__atom_tests__/sample-2-test.js +++ b/jest/__atom_tests__/sample-2-test.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,10 +7,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ test('atom', () => { expect(2).toBe(2); -}); +}); \ No newline at end of file diff --git a/jest/__mocks__/emptyObject.js b/jest/__mocks__/emptyObject.js index 6978cae610..290fcbce11 100644 --- a/jest/__mocks__/emptyObject.js +++ b/jest/__mocks__/emptyObject.js @@ -1,3 +1,5 @@ +"use strict"; + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,9 +7,9 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ // eslint-disable-next-line nuclide-internal/no-commonjs -module.exports = {}; +module.exports = {}; \ No newline at end of file diff --git a/jest/__mocks__/log4js.js b/jest/__mocks__/log4js.js index a83144064a..932886a07d 100644 --- a/jest/__mocks__/log4js.js +++ b/jest/__mocks__/log4js.js @@ -1,3 +1,8 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,11 +10,11 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -const logger: log4js$Logger = { +const logger = { debug: jest.fn(), error: jest.fn(), fatal: jest.fn(), @@ -22,15 +27,15 @@ const logger: log4js$Logger = { removeLevel: jest.fn(), setLevel: jest.fn(), trace: jest.fn(), - warn: jest.fn(), + warn: jest.fn() }; -export const getLogger = (name: string): log4js$Logger => logger; +const getLogger = exports.getLogger = name => logger; const log4js = { getLogger, // $FlowFixMe - configure: jest.fn(), + configure: jest.fn() }; -export default log4js; +exports.default = log4js; \ No newline at end of file diff --git a/jest/__tests__/waits_for-test.js b/jest/__tests__/waits_for-test.js index d19712dca4..26244254e7 100644 --- a/jest/__tests__/waits_for-test.js +++ b/jest/__tests__/waits_for-test.js @@ -1,28 +1,32 @@ -/** - * 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 strict - * @format - */ +'use strict'; -import waitsFor from '../waits_for'; +var _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../waits_for')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } it('waits', async () => { let condition = false; - Promise.resolve().then(() => (condition = true)); - await waitsFor(() => condition); -}); + Promise.resolve().then(() => condition = true); + await (0, (_waits_for || _load_waits_for()).default)(() => condition); +}); /** + * 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. + * + * strict + * @format + */ it("can't wait anymore", async () => { - await expect(waitsFor(() => false, undefined, 1)).rejects.toThrow( - 'but it never did', - ); + await expect((0, (_waits_for || _load_waits_for()).default)(() => false, undefined, 1)).rejects.toThrow('but it never did'); }); it('gives a message', async () => { - await expect(waitsFor(() => false, 'lol', 1)).rejects.toThrow('lol'); -}); + await expect((0, (_waits_for || _load_waits_for()).default)(() => false, 'lol', 1)).rejects.toThrow('lol'); +}); \ No newline at end of file diff --git a/jest/setup.js b/jest/setup.js index e48fabf944..b5bef26a07 100644 --- a/jest/setup.js +++ b/jest/setup.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,10 +7,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ jest.mock('log4js'); -global.NUCLIDE_DO_NOT_LOG = true; +global.NUCLIDE_DO_NOT_LOG = true; \ No newline at end of file diff --git a/jest/setupTestFrameworkScriptFile.atom.js b/jest/setupTestFrameworkScriptFile.atom.js index 8d36966bdb..f3c2b8272c 100644 --- a/jest/setupTestFrameworkScriptFile.atom.js +++ b/jest/setupTestFrameworkScriptFile.atom.js @@ -1,3 +1,5 @@ +"use strict"; + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +7,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ @@ -14,4 +16,4 @@ beforeEach(async () => { }); // Disable prompt to download react devtools in atom tests -window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = {isDisabled: true}; +window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = { isDisabled: true }; \ No newline at end of file diff --git a/jest/waits_for.js b/jest/waits_for.js index 0843df7422..941a86847c 100644 --- a/jest/waits_for.js +++ b/jest/waits_for.js @@ -1,3 +1,9 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,23 +11,15 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ /* * Async implementation of Jasmine's waitsFor() */ -export default (async function waitsFor( - fn: () => boolean, - message?: string, - timeout: number = 1000, -) { - const error = new Error( - message != null - ? message - : 'Expected the function to start returning "true" but it never did', - ); +exports.default = async function waitsFor(fn, message, timeout = 1000) { + const error = new Error(message != null ? message : 'Expected the function to start returning "true" but it never did'); const startTime = Date.now(); while (!Boolean(fn())) { if (Date.now() - startTime > timeout) { @@ -30,4 +28,4 @@ export default (async function waitsFor( // eslint-disable-next-line no-await-in-loop await new Promise(resolve => setTimeout(resolve, 50)); } -}); +}; \ No newline at end of file diff --git a/lib/ReactPerfMonitor.js b/lib/ReactPerfMonitor.js index a0ceff1fd4..615491d115 100644 --- a/lib/ReactPerfMonitor.js +++ b/lib/ReactPerfMonitor.js @@ -1,3 +1,17 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../pkg/nuclide-analytics'); +} + +const DURATION_REPORTING_THRESHOLD_MS = 7; // report react-measured events > 7ms + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,25 +19,17 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ /* eslint-env browser */ -import {track} from '../pkg/nuclide-analytics'; - -const DURATION_REPORTING_THRESHOLD_MS = 7; // report react-measured events > 7ms - const REACT_EMOJI = '\u269B'; const WARNING_EMOJI = '\u26D4'; // parse "mount" from '\u269B MarkedStringSnippet [mount]' -const LIFECYCLE_RE = new RegExp( - `(${REACT_EMOJI}|${WARNING_EMOJI}) (\\S+) \\[(\\S+)\\]`, -); -const METHOD_RE = new RegExp( - `(${REACT_EMOJI}|${WARNING_EMOJI}) (\\S+)\\.(\\S+)$`, -); +const LIFECYCLE_RE = new RegExp(`(${REACT_EMOJI}|${WARNING_EMOJI}) (\\S+) \\[(\\S+)\\]`); +const METHOD_RE = new RegExp(`(${REACT_EMOJI}|${WARNING_EMOJI}) (\\S+)\\.(\\S+)$`); /** * Monitor important measurements while React renders out components. @@ -35,42 +41,40 @@ const METHOD_RE = new RegExp( * does not emit performance measurements, so it is not worth intercepting * events in that case. */ -export default class ReactPerfMonitor { - _disposed: boolean = false; +class ReactPerfMonitor { constructor() { + this._disposed = false; + const oldMeasure = performance.measure.bind(performance); // $FlowFixMe Patching intentionally :) performance.measure = function measure(name, startMark, endMark) { oldMeasure(name, startMark, endMark); - if ( - !this._disposed && - (name.startsWith(REACT_EMOJI) || name.startsWith(WARNING_EMOJI)) && - name[2] !== '(' // high-level react processes aren't interesting + if (!this._disposed && (name.startsWith(REACT_EMOJI) || name.startsWith(WARNING_EMOJI)) && name[2] !== '(' // high-level react processes aren't interesting ) { - const [entry] = performance.getEntriesByName(name, 'measure'); + const [entry] = performance.getEntriesByName(name, 'measure'); - let component; - let lifecycle; - let method; - const lifecycleResult = name.match(LIFECYCLE_RE); - const methodResult = name.match(METHOD_RE); - if (lifecycleResult) { - [, , component, lifecycle] = lifecycleResult; - } else if (methodResult) { - [, , component, method] = methodResult; - } + let component; + let lifecycle; + let method; + const lifecycleResult = name.match(LIFECYCLE_RE); + const methodResult = name.match(METHOD_RE); + if (lifecycleResult) { + [,, component, lifecycle] = lifecycleResult; + } else if (methodResult) { + [,, component, method] = methodResult; + } - if (entry && entry.duration >= DURATION_REPORTING_THRESHOLD_MS) { - track('react-performance', { - duration: entry.duration.toString(), - eventName: name.slice(2), // remove the emoji - component, - lifecycle, - method, - }); + if (entry && entry.duration >= DURATION_REPORTING_THRESHOLD_MS) { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('react-performance', { + duration: entry.duration.toString(), + eventName: name.slice(2), // remove the emoji + component, + lifecycle, + method + }); + } } - } }; } @@ -78,3 +82,4 @@ export default class ReactPerfMonitor { this._disposed = true; } } +exports.default = ReactPerfMonitor; \ No newline at end of file diff --git a/lib/installDevTools.js b/lib/installDevTools.js index 6d568e5ab7..9a98ddb8a7 100644 --- a/lib/installDevTools.js +++ b/lib/installDevTools.js @@ -1,3 +1,42 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = installDevTools; + +var _electron = _interopRequireDefault(require('electron')); + +var _os = _interopRequireDefault(require('os')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../modules/nuclide-commons/nuclideUri')); +} + +var _fs = _interopRequireDefault(require('fs')); + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../modules/nuclide-commons/UniversalDisposable')); +} + +var _ReactPerfMonitor; + +function _load_ReactPerfMonitor() { + return _ReactPerfMonitor = _interopRequireDefault(require('./ReactPerfMonitor')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,32 +44,20 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import electron from 'electron'; -import invariant from 'assert'; -import os from 'os'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import fs from 'fs'; -import nullthrows from 'nullthrows'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import ReactPerfMonitor from './ReactPerfMonitor'; - const extensionIDsToLoad = [ - // React DevTools - 'fmkadmapgofadopljbjfkapdkoienihi', -]; +// React DevTools +'fmkadmapgofadopljbjfkapdkoienihi']; // eslint-disable-next-line no-console const log = console.debug || console.log; let installed; -export default function installDevTools(): IDisposable { - const disposable = new UniversalDisposable(new ReactPerfMonitor()); +function installDevTools() { + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(new (_ReactPerfMonitor || _load_ReactPerfMonitor()).default()); if (installed) { return disposable; @@ -38,43 +65,28 @@ export default function installDevTools(): IDisposable { const chromeHome = getChromeHomeDir(); const profileDirs = getProfileDirs(chromeHome); - nullthrows(electron.webFrame).registerURLSchemeAsBypassingCSP( - 'chrome-extension', - ); - const remote = nullthrows(electron.remote); + (0, (_nullthrows || _load_nullthrows()).default)(_electron.default.webFrame).registerURLSchemeAsBypassingCSP('chrome-extension'); + const remote = (0, (_nullthrows || _load_nullthrows()).default)(_electron.default.remote); for (const extensionID of extensionIDsToLoad) { remote.BrowserWindow.removeDevToolsExtension(extensionID); - const extensionVersions = getVersionDirsForExtension( - profileDirs, - extensionID, - ); + const extensionVersions = getVersionDirsForExtension(profileDirs, extensionID); if (extensionVersions == null || extensionVersions.length === 0) { - log( - `Unable to load extension ${extensionID}. Make sure it is installed in one of your Chrome profiles.`, - ); + log(`Unable to load extension ${extensionID}. Make sure it is installed in one of your Chrome profiles.`); continue; } - const namesWithTimes = extensionVersions.map(dirname => ({ - ...fs.statSync(dirname), - dirname, + const namesWithTimes = extensionVersions.map(dirname => Object.assign({}, _fs.default.statSync(dirname), { + dirname })); const latest = namesWithTimes.sort((a, b) => a.mtimeMs - b.mtimeMs)[0]; - let latestManifest: ?{name: string}; + let latestManifest; try { - latestManifest = JSON.parse( - fs.readFileSync( - nuclideUri.join(latest.dirname, 'manifest.json'), - 'utf-8', - ), - ); + latestManifest = JSON.parse(_fs.default.readFileSync((_nuclideUri || _load_nuclideUri()).default.join(latest.dirname, 'manifest.json'), 'utf-8')); } catch (e) { - log( - `Unable to read or parse a valid manifest for extension ${extensionID}`, - ); + log(`Unable to read or parse a valid manifest for extension ${extensionID}`); } if (latest != null && latestManifest != null) { @@ -87,38 +99,30 @@ export default function installDevTools(): IDisposable { return disposable; } -function getChromeHomeDir(): NuclideUri { +function getChromeHomeDir() { switch (process.platform) { case 'darwin': - return nuclideUri.join( - os.homedir(), - 'Library', - 'Application Support', - 'Google', - 'Chrome', - ); + return (_nuclideUri || _load_nuclideUri()).default.join(_os.default.homedir(), 'Library', 'Application Support', 'Google', 'Chrome'); case 'win32': - invariant(process.env.LOCALAPPDATA != null); - return nuclideUri.join( - process.env.LOCALAPPDATA, - 'Google', - 'Chrome', - 'User Data', - ); + if (!(process.env.LOCALAPPDATA != null)) { + throw new Error('Invariant violation: "process.env.LOCALAPPDATA != null"'); + } + + return (_nuclideUri || _load_nuclideUri()).default.join(process.env.LOCALAPPDATA, 'Google', 'Chrome', 'User Data'); default: - return nuclideUri.join(os.homedir(), '.config', 'google-chrome'); + return (_nuclideUri || _load_nuclideUri()).default.join(_os.default.homedir(), '.config', 'google-chrome'); } } -function getProfileDirs(chromeHome: NuclideUri) { - const profileDirs = [nuclideUri.join(chromeHome, 'Default')]; +function getProfileDirs(chromeHome) { + const profileDirs = [(_nuclideUri || _load_nuclideUri()).default.join(chromeHome, 'Default')]; let done; let profileNum = 1; while (!done) { try { - const profilePath = nuclideUri.join(chromeHome, `Profile ${profileNum}`); - fs.statSync(profilePath); + const profilePath = (_nuclideUri || _load_nuclideUri()).default.join(chromeHome, `Profile ${profileNum}`); + _fs.default.statSync(profilePath); profileDirs.push(profilePath); profileNum++; } catch (e) { @@ -129,21 +133,12 @@ function getProfileDirs(chromeHome: NuclideUri) { return profileDirs; } -function getVersionDirsForExtension( - profileDirs: Array, - extensionID: string, -): ?Array { +function getVersionDirsForExtension(profileDirs, extensionID) { for (const profileDir of profileDirs) { - const extensionPath = nuclideUri.join( - profileDir, - 'Extensions', - extensionID, - ); + const extensionPath = (_nuclideUri || _load_nuclideUri()).default.join(profileDir, 'Extensions', extensionID); try { - return fs - .readdirSync(extensionPath) - .filter(base => !base.startsWith('.')) // Remove .DS_Store and others - .map(base => nuclideUri.join(extensionPath, base)); + return _fs.default.readdirSync(extensionPath).filter(base => !base.startsWith('.')) // Remove .DS_Store and others + .map(base => (_nuclideUri || _load_nuclideUri()).default.join(extensionPath, base)); } catch (e) {} } -} +} \ No newline at end of file diff --git a/lib/installErrorReporter.js b/lib/installErrorReporter.js index 140f03db50..35607de59d 100644 --- a/lib/installErrorReporter.js +++ b/lib/installErrorReporter.js @@ -1,3 +1,24 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = installErrorReporter; + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../modules/nuclide-commons/UniversalDisposable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,38 +26,28 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import {getLogger} from 'log4js'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - let disposable; -export default function installErrorReporter(): IDisposable { +function installErrorReporter() { if (disposable != null) { throw new Error('installErrorReporter was called multiple times.'); } window.addEventListener('unhandledrejection', onUnhandledRejection); - disposable = new UniversalDisposable( - atom.onWillThrowError(onUnhandledException), - atom.notifications.onDidAddNotification(handleAtomNotification), - () => { - window.removeEventListener('unhandledrejection', onUnhandledRejection); - disposable = null; - }, - ); + disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(atom.onWillThrowError(onUnhandledException), atom.notifications.onDidAddNotification(handleAtomNotification), () => { + window.removeEventListener('unhandledrejection', onUnhandledRejection); + disposable = null; + }); return disposable; } function onUnhandledException(event) { try { - getLogger('installErrorReporter').error( - `Caught unhandled exception: ${event.message}`, - event.originalError, - ); + (0, (_log4js || _load_log4js()).getLogger)('installErrorReporter').error(`Caught unhandled exception: ${event.message}`, event.originalError); } catch (e) { // Ensure we don't recurse forever. Even under worst case scenarios. } @@ -44,39 +55,30 @@ function onUnhandledException(event) { function onUnhandledRejection(event) { try { - getLogger('installErrorReporter').error( - 'Caught unhandled rejection', - event.reason, - ); + (0, (_log4js || _load_log4js()).getLogger)('installErrorReporter').error('Caught unhandled rejection', event.reason); } catch (e) { // Ensure we don't recurse forever. Even under worst case scenarios. } } -function isNuclideInCallStack(callStack: Array) { +function isNuclideInCallStack(callStack) { const ignoreCallSitesFromThisFile = callSite => { const fileName = callSite.getFileName(); return fileName != null && !fileName.includes('installErrorReporter.js'); }; - const containsNuclideWord = callSite => - callSite - .toString() - .toLowerCase() - .includes('nuclide'); - - return callStack - .filter(ignoreCallSitesFromThisFile) - .some(containsNuclideWord); + const containsNuclideWord = callSite => callSite.toString().toLowerCase().includes('nuclide'); + + return callStack.filter(ignoreCallSitesFromThisFile).some(containsNuclideWord); } -function handleAtomNotification(notification: atom$Notification) { +function handleAtomNotification(notification) { // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) if (notification.type !== 'error' && notification.type !== 'fatal') { return; } const error = Error(notification.getMessage()); - const {stack} = notification.getOptions(); + const { stack } = notification.getOptions(); if (typeof stack === 'string' && stack) { error.stack = stack; } else { @@ -87,6 +89,6 @@ function handleAtomNotification(notification: atom$Notification) { // $FlowFixMe: getRawStack() is missing from Error() const rawStack = error.getRawStack(); if (rawStack == null || isNuclideInCallStack(rawStack)) { - getLogger('atom-error-notification').error(error); + (0, (_log4js || _load_log4js()).getLogger)('atom-error-notification').error(error); } -} +} \ No newline at end of file diff --git a/lib/main.js b/lib/main.js index afd727e833..1ff42cdeb2 100644 --- a/lib/main.js +++ b/lib/main.js @@ -1,3 +1,125 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.handleURI = exports.serialize = exports.deactivate = exports.activate = exports.config = undefined; + +var _monkeyPatchProjectConfigs; + +function _load_monkeyPatchProjectConfigs() { + return _monkeyPatchProjectConfigs = _interopRequireDefault(require('./monkeyPatchProjectConfigs')); +} + +require('./preload-dependencies'); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../modules/nuclide-commons/nuclideUri')); +} + +var _promise; + +function _load_promise() { + return _promise = require('../modules/nuclide-commons/promise'); +} + +var _FeatureLoader; + +function _load_FeatureLoader() { + return _FeatureLoader = _interopRequireDefault(require('../modules/nuclide-commons-atom/FeatureLoader')); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../modules/nuclide-commons-atom/feature-config')); +} + +var _fs = _interopRequireDefault(require('fs')); + +var _electron = _interopRequireDefault(require('electron')); + +var _path = _interopRequireDefault(require('path')); + +var _atomPackageDeps; + +function _load_atomPackageDeps() { + return _atomPackageDeps = require('atom-package-deps'); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _semver; + +function _load_semver() { + return _semver = _interopRequireDefault(require('semver')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = _interopRequireDefault(require('log4js')); +} + +var _installErrorReporter; + +function _load_installErrorReporter() { + return _installErrorReporter = _interopRequireDefault(require('./installErrorReporter')); +} + +var _installDevTools; + +function _load_installDevTools() { + return _installDevTools = _interopRequireDefault(require('./installDevTools')); +} + +var _package; + +function _load_package() { + return _package = _interopRequireDefault(require('../package.json')); +} + +var _deepLink; + +function _load_deepLink() { + return _deepLink = require('../pkg/commons-atom/deep-link'); +} + +var _nuclideLogging; + +function _load_nuclideLogging() { + return _nuclideLogging = require('../pkg/nuclide-logging'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../modules/nuclide-commons/UniversalDisposable')); +} + +var _featureGroups; + +function _load_featureGroups() { + return _featureGroups = _interopRequireDefault(require('./featureGroups.json')); +} + +var _dompurify; + +function _load_dompurify() { + return _dompurify = _interopRequireDefault(require('dompurify')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Monkeypatch project APIs into Atom. This can be removed after this functionality has been +// upstreamed, i.e. when `atom.project.replace()` and `atom.project.getSpecification()` are +// available. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +127,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ @@ -19,101 +141,68 @@ * */ -import type {Feature} from 'nuclide-commons-atom/FeatureLoader'; - -import monkeyPatchProjectConfigs from './monkeyPatchProjectConfigs'; -import './preload-dependencies'; - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {sleep} from 'nuclide-commons/promise'; -import FeatureLoader from 'nuclide-commons-atom/FeatureLoader'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import fs from 'fs'; -import invariant from 'assert'; -import electron from 'electron'; +(0, (_monkeyPatchProjectConfigs || _load_monkeyPatchProjectConfigs()).default)(); // eslint-disable-next-line nuclide-internal/prefer-nuclide-uri -import path from 'path'; -import {install as atomPackageDepsInstall} from 'atom-package-deps'; -import nullthrows from 'nullthrows'; -import semver from 'semver'; -import log4js from 'log4js'; - -import installErrorReporter from './installErrorReporter'; -import installDevTools from './installDevTools'; -import nuclidePackageJson from '../package.json'; -import {sendDeepLink} from '../pkg/commons-atom/deep-link'; -import {initializeLogging, getDefaultConfig} from '../pkg/nuclide-logging'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import pubFeatureGroups from './featureGroups.json'; -import createDOMPurify from 'dompurify'; -// Monkeypatch project APIs into Atom. This can be removed after this functionality has been -// upstreamed, i.e. when `atom.project.replace()` and `atom.project.getSpecification()` are -// available. -monkeyPatchProjectConfigs(); -let featureGroups = pubFeatureGroups; +let featureGroups = (_featureGroups || _load_featureGroups()).default; try { // $eslint-disable-next-line $FlowFB const fbFeatureGroups = require('./fb-featureGroups.json'); featureGroups = mergeFeatureGroups(featureGroups, fbFeatureGroups); } catch (e) {} -const domPurify = createDOMPurify(); +const domPurify = (0, (_dompurify || _load_dompurify()).default)(); // The minimum version of Atom required to run Nuclide. Anything less than this and users will get // a redbox and Nuclide will not activate. const MINIMUM_SUPPORTED_ATOM_VERSION = '1.25.0'; // Install the error reporting even before Nuclide is activated. -let errorReporterDisposable = installErrorReporter(); +let errorReporterDisposable = (0, (_installErrorReporter || _load_installErrorReporter()).default)(); // Install the logger config before Nuclide is activated. -initializeLogging(); +(0, (_nuclideLogging || _load_nuclideLogging()).initializeLogging)(); -const {remote} = electron; -invariant(remote != null); +const { remote } = _electron.default; + +if (!(remote != null)) { + throw new Error('Invariant violation: "remote != null"'); +} const baseConfig = { installRecommendedPackages: { default: false, - description: - 'On start up, check for and install Atom packages recommended for use with Nuclide. The' + - " list of packages can be found in the package-deps setting in this package's" + - ' "package.json" file. Disabling this setting will not uninstall packages it previously' + - ' installed. Restart Atom after changing this setting for it to take effect.', + description: 'On start up, check for and install Atom packages recommended for use with Nuclide. The' + " list of packages can be found in the package-deps setting in this package's" + ' "package.json" file. Disabling this setting will not uninstall packages it previously' + ' installed. Restart Atom after changing this setting for it to take effect.', title: 'Install Recommended Packages on Startup', type: 'boolean', - order: 0, + order: 0 }, useLocalRpc: { default: !atom.inSpecMode(), - description: - 'Use a RPC process for local services. This ensures better compatibility between the local' + - ' and remote case and improves local performance. Requires restart to take' + - ' effect.', + description: 'Use a RPC process for local services. This ensures better compatibility between the local' + ' and remote case and improves local performance. Requires restart to take' + ' effect.', title: 'Use RPC for local services.', type: 'boolean', - order: 0, - }, + order: 0 + } }; // Nuclide packages for Atom are called "features" -const FEATURES_DIR = path.join(__dirname, '../pkg'); -const features: Array = []; +const FEATURES_DIR = _path.default.join(__dirname, '../pkg'); +const features = []; /** * Get the "package.json" of all the features. */ -fs.readdirSync(FEATURES_DIR).forEach(item => { +_fs.default.readdirSync(FEATURES_DIR).forEach(item => { // Optimization: Our directories don't have periods - this must be a file if (item.indexOf('.') !== -1) { return; } - const featurePath = path.join(FEATURES_DIR, item); - const filename = path.join(featurePath, 'package.json'); + const featurePath = _path.default.join(FEATURES_DIR, item); + const filename = _path.default.join(featurePath, 'package.json'); let src; try { - src = fs.readFileSync(filename, 'utf8'); + src = _fs.default.readFileSync(filename, 'utf8'); } catch (err) { if (err && (err.code === 'ENOENT' || err.code === 'ENOTDIR')) { return; @@ -126,25 +215,32 @@ fs.readdirSync(FEATURES_DIR).forEach(item => { } const pkg = JSON.parse(src); if (pkg.nuclide && pkg.nuclide.packageType === 'Atom') { - invariant(pkg.name); + if (!pkg.name) { + throw new Error('Invariant violation: "pkg.name"'); + } + features.push({ pkg, - path: featurePath, + path: featurePath }); } }); // atom-ide-ui packages are a lot more consistent. function addFeature(directory, name) { - const featurePath = path.join(directory, name); - const filename = path.join(featurePath, 'package.json'); + const featurePath = _path.default.join(directory, name); + const filename = _path.default.join(featurePath, 'package.json'); try { - const src = fs.readFileSync(filename, 'utf8'); + const src = _fs.default.readFileSync(filename, 'utf8'); const pkg = JSON.parse(src); - invariant(pkg.name); + + if (!pkg.name) { + throw new Error('Invariant violation: "pkg.name"'); + } + features.push({ pkg, - path: featurePath, + path: featurePath }); } catch (err) { if (err.code !== 'ENOENT' && err.code !== 'ENOTDIR') { @@ -153,88 +249,70 @@ function addFeature(directory, name) { } } -const MODULES_DIR = path.join(__dirname, '../modules'); -const ATOM_IDE_DIR = path.join(MODULES_DIR, 'atom-ide-ui/pkg'); +const MODULES_DIR = _path.default.join(__dirname, '../modules'); +const ATOM_IDE_DIR = _path.default.join(MODULES_DIR, 'atom-ide-ui/pkg'); -fs.readdirSync(ATOM_IDE_DIR).forEach(name => addFeature(ATOM_IDE_DIR, name)); -fs.readdirSync(MODULES_DIR) - .filter(name => name.startsWith('atom-ide-debugger-')) - .forEach(name => addFeature(MODULES_DIR, name)); +_fs.default.readdirSync(ATOM_IDE_DIR).forEach(name => addFeature(ATOM_IDE_DIR, name)); +_fs.default.readdirSync(MODULES_DIR).filter(name => name.startsWith('atom-ide-debugger-')).forEach(name => addFeature(MODULES_DIR, name)); const shouldInitialize = ensureAtomVersion(); let featureLoader; if (shouldInitialize) { - featureLoader = new FeatureLoader({ - path: path.resolve(__dirname, '..'), + featureLoader = new (_FeatureLoader || _load_FeatureLoader()).default({ + path: _path.default.resolve(__dirname, '..'), features, - featureGroups, + featureGroups }); featureLoader.load(); } -export const config = shouldInitialize - ? {...baseConfig, ...nullthrows(featureLoader).getConfig()} - : undefined; +const config = exports.config = shouldInitialize ? Object.assign({}, baseConfig, (0, (_nullthrows || _load_nullthrows()).default)(featureLoader).getConfig()) : undefined; let disposables; function _activate() { // These need to be re-activated after de-activation. if (errorReporterDisposable == null) { - errorReporterDisposable = installErrorReporter(); - log4js.configure(getDefaultConfig()); + errorReporterDisposable = (0, (_installErrorReporter || _load_installErrorReporter()).default)(); + (_log4js || _load_log4js()).default.configure((0, (_nuclideLogging || _load_nuclideLogging()).getDefaultConfig)()); } if (atom.inDevMode() && process.env.SANDCASTLE == null) { - installDevTools(); + (0, (_installDevTools || _load_installDevTools()).default)(); } // Add the "Nuclide" menu, if it's not there already. - disposables = new UniversalDisposable( - atom.menu.add([ - { - // On Windows, menu labels have an & before a letter to indicate which - // ALT key combination maps to that menu. In our case, Alt+N should open - // the Nuclide menu. - label: process.platform === 'win32' ? '&Nuclide' : 'Nuclide', - submenu: [ - { - label: `Version ${nuclidePackageJson.version}`, - enabled: false, - }, - ], - }, - { - label: process.platform === 'win32' ? '&Go' : 'Go', - // an empty submenu is required to manipulate its position below - submenu: [], - }, - ]), - ); + disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(atom.menu.add([{ + // On Windows, menu labels have an & before a letter to indicate which + // ALT key combination maps to that menu. In our case, Alt+N should open + // the Nuclide menu. + label: process.platform === 'win32' ? '&Nuclide' : 'Nuclide', + submenu: [{ + label: `Version ${(_package || _load_package()).default.version}`, + enabled: false + }] + }, { + label: process.platform === 'win32' ? '&Go' : 'Go', + // an empty submenu is required to manipulate its position below + submenu: [] + }])); // Manually manipulate the menu template order. - const insertIndex = atom.menu.template.findIndex( - item => item.role === 'window' || item.role === 'help', - ); + const insertIndex = atom.menu.template.findIndex(item => item.role === 'window' || item.role === 'help'); if (insertIndex !== -1) { - const nuclideIndex = atom.menu.template.findIndex( - item => item.label === 'Nuclide', - ); + const nuclideIndex = atom.menu.template.findIndex(item => item.label === 'Nuclide'); const menuItem = atom.menu.template.splice(nuclideIndex, 1)[0]; const newIndex = insertIndex > nuclideIndex ? insertIndex - 1 : insertIndex; atom.menu.template.splice(newIndex, 0, menuItem); atom.menu.update(); } - const goInsertIndex = atom.menu.template.findIndex( - item => item.label === 'Packages', - ); + const goInsertIndex = atom.menu.template.findIndex(item => item.label === 'Packages'); if (goInsertIndex !== -1) { const goIndex = atom.menu.template.findIndex(item => item.label === 'Go'); const menuItem = atom.menu.template.splice(goIndex, 1)[0]; - const newIndex = - goInsertIndex > goIndex ? goInsertIndex - 1 : goInsertIndex; + const newIndex = goInsertIndex > goIndex ? goInsertIndex - 1 : goInsertIndex; atom.menu.template.splice(newIndex, 0, menuItem); atom.menu.update(); } @@ -242,9 +320,7 @@ function _activate() { // Remove all remote directories up front to prevent packages from using remote URIs // before they are ready. The nuclide-remote-projects package manually // serializes/deserializes and then reloads these during the activation phase. - atom.project.setPaths( - atom.project.getPaths().filter(uri => !nuclideUri.isRemote(uri)), - ); + atom.project.setPaths(atom.project.getPaths().filter(uri => !(_nuclideUri || _load_nuclideUri()).default.isRemote(uri))); // Activate all of the loaded features. Technically, this will be a no-op // generally because Atom [will activate all loaded packages][1]. However, @@ -257,59 +333,53 @@ function _activate() { // Install public, 3rd-party Atom packages listed in this package's 'package-deps' setting. Run // this *after* other packages are activated so they can modify this setting if desired before // installation is attempted. - if (featureConfig.get('installRecommendedPackages')) { + if ((_featureConfig || _load_featureConfig()).default.get('installRecommendedPackages')) { // Workaround for restoring multiple Atom windows. This prevents having all // the windows trying to install the deps at the same time - often clobbering // each other's install. const firstWindowId = remote.BrowserWindow.getAllWindows()[0].id; const currentWindowId = remote.getCurrentWindow().id; if (firstWindowId === currentWindowId) { - atomPackageDepsInstall('nuclide', /* promptUser */ false); + (0, (_atomPackageDeps || _load_atomPackageDeps()).install)('nuclide', /* promptUser */false); } } const menusToSort = ['Nuclide', 'View']; - disposables.add( - atom.packages.onDidActivateInitialPackages(() => { + disposables.add(atom.packages.onDidActivateInitialPackages(() => { + sortMenuGroups(menusToSort); + + if (!(disposables != null)) { + throw new Error('Invariant violation: "disposables != null"'); + } + + disposables.add(atom.packages.onDidActivatePackage(() => { sortMenuGroups(menusToSort); - invariant(disposables != null); - disposables.add( - atom.packages.onDidActivatePackage(() => { - sortMenuGroups(menusToSort); - }), - ); - }), - ); + })); + })); patchNotificationManager(); } function patchNotificationManager() { - const {addNotification} = atom.notifications; + const { addNotification } = atom.notifications; // Patch the notification functions to make sure they only display cleaned // HTML output. // $FlowIgnore - property not writeable - atom.notifications.addNotification = (notification: atom$Notification) => { + atom.notifications.addNotification = notification => { // $FlowIgnore - internal property notification.message = domPurify.sanitize(notification.message); return addNotification.bind(atom.notifications)(notification); }; } -function sortLabelValue(label: ?string) { +function sortLabelValue(label) { // Ignore the Windows accelerator key hint when sorting, the & doesn't // actually appear in the UX so it shouldn't affect the sort. return String(label).replace('&', ''); } -function sortSubmenuGroup( - menuItems: Array<{ - label: string, - }>, - startIndex: number, - itemCount: number, -) { +function sortSubmenuGroup(menuItems, startIndex, itemCount) { // Sort a subset of the items in the menu of length itemCount beginning // at startIndex. const itemsToSort = menuItems.splice(startIndex, itemCount); @@ -325,35 +395,24 @@ function sortSubmenuGroup( menuItems.splice(startIndex, 0, ...itemsToSort); } -function mergeFeatureGroups( - firstGroup: {[string]: Array}, - secondGroup: {[string]: Array}, -): {[string]: Array} { +function mergeFeatureGroups(firstGroup, secondGroup) { const mergedObject = {}; for (const key in firstGroup) { - mergedObject[key] = [ - ...(firstGroup[key] || []), - ...(secondGroup[key] || []), - ]; + mergedObject[key] = [...(firstGroup[key] || []), ...(secondGroup[key] || [])]; } for (const key in secondGroup) { - mergedObject[key] = [ - ...(firstGroup[key] || []), - ...(secondGroup[key] || []), - ]; + mergedObject[key] = [...(firstGroup[key] || []), ...(secondGroup[key] || [])]; } return mergedObject; } -function sortMenuGroups(menuNames: Array) { +function sortMenuGroups(menuNames) { for (const menuName of menuNames) { // Sorts the items in a menu alphabetically. If the menu contains one or more // separators, then the items within each separator subgroup will be sorted // with respect to each other, but items will remain in the same groups, and // the separators will not be moved. - const menu = atom.menu.template.find( - m => sortLabelValue(m.label) === menuName, - ); + const menu = atom.menu.template.find(m => sortLabelValue(m.label) === menuName); if (menu == null) { continue; } @@ -369,38 +428,40 @@ function sortMenuGroups(menuNames: Array) { // Sort any remaining items after the last separator. if (sortStart < menu.submenu.length) { - sortSubmenuGroup( - menu.submenu, - sortStart, - menu.submenu.length - sortStart, - ); + sortSubmenuGroup(menu.submenu, sortStart, menu.submenu.length - sortStart); } } atom.menu.update(); } -function _deactivate(): Promise { - invariant(disposables != null); +function _deactivate() { + if (!(disposables != null)) { + throw new Error('Invariant violation: "disposables != null"'); + } + featureLoader.deactivate(); disposables.dispose(); disposables = null; - invariant(errorReporterDisposable != null); + + if (!(errorReporterDisposable != null)) { + throw new Error('Invariant violation: "errorReporterDisposable != null"'); + } + errorReporterDisposable.dispose(); errorReporterDisposable = null; return Promise.race([ - // Prevent Atom from exiting until log4js shutdown completes. - new Promise(resolve => log4js.shutdown(resolve)), - // But guard against log4js misbehaving. - sleep(1000), - ]); + // Prevent Atom from exiting until log4js shutdown completes. + new Promise(resolve => (_log4js || _load_log4js()).default.shutdown(resolve)), + // But guard against log4js misbehaving. + (0, (_promise || _load_promise()).sleep)(1000)]); } function _serialize() { featureLoader.serialize(); } -function _handleURI({pathname, query}: url$urlObject, uri: string): void { +function _handleURI({ pathname, query }, uri) { if (pathname == null || pathname === '') { atom.notifications.addError(`Invalid URI ${uri}: must have a path.`); return; @@ -409,47 +470,34 @@ function _handleURI({pathname, query}: url$urlObject, uri: string): void { // Atom waits for Nuclide to initialize before sending the URI through. // So, at this point it should be fairly safe to delegate to nuclide-deep-link. - sendDeepLink(remote.getCurrentWindow(), message, query || {}); + (0, (_deepLink || _load_deepLink()).sendDeepLink)(remote.getCurrentWindow(), message, query || {}); } function ensureAtomVersion() { - if (semver.lt(atom.getVersion(), MINIMUM_SUPPORTED_ATOM_VERSION)) { - const notification = atom.notifications.addError( - '**Atom Upgrade Required**', - { - description: - `Nuclide requires Atom ${MINIMUM_SUPPORTED_ATOM_VERSION}. **All of its functionality will` + - ' be disabled until you upgrade.**', - dismissable: true, - buttons: [ - { - text: 'Quit Atom', - className: 'icon icon-stop', - onDidClick() { - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'application:quit', - ); - }, - }, - { - text: 'Continue without Nuclide', - className: 'nuclide-min-atom-button', - onDidClick() { - notification.dismiss(); - }, - }, - ], - }, - ); + if ((_semver || _load_semver()).default.lt(atom.getVersion(), MINIMUM_SUPPORTED_ATOM_VERSION)) { + const notification = atom.notifications.addError('**Atom Upgrade Required**', { + description: `Nuclide requires Atom ${MINIMUM_SUPPORTED_ATOM_VERSION}. **All of its functionality will` + ' be disabled until you upgrade.**', + dismissable: true, + buttons: [{ + text: 'Quit Atom', + className: 'icon icon-stop', + onDidClick() { + atom.commands.dispatch(atom.views.getView(atom.workspace), 'application:quit'); + } + }, { + text: 'Continue without Nuclide', + className: 'nuclide-min-atom-button', + onDidClick() { + notification.dismiss(); + } + }] + }); // Hide the normal close button so that people need to use our custom button to close (and are // hopefully, as a result, more aware of what we're saying). Unfortunately, Atom doesn't provide // access to this view so we have to find it. const continueButton = document.querySelector('.nuclide-min-atom-button'); - const notificationEl = - continueButton && continueButton.closest('atom-notification'); - const closeButton = - notificationEl && notificationEl.querySelector('.close'); + const notificationEl = continueButton && continueButton.closest('atom-notification'); + const closeButton = notificationEl && notificationEl.querySelector('.close'); if (closeButton != null) { closeButton.style.display = 'none'; } @@ -458,7 +506,7 @@ function ensureAtomVersion() { return true; } -export const activate = shouldInitialize ? _activate : undefined; -export const deactivate = shouldInitialize ? _deactivate : undefined; -export const serialize = shouldInitialize ? _serialize : undefined; -export const handleURI = shouldInitialize ? _handleURI : undefined; +const activate = exports.activate = shouldInitialize ? _activate : undefined; +const deactivate = exports.deactivate = shouldInitialize ? _deactivate : undefined; +const serialize = exports.serialize = shouldInitialize ? _serialize : undefined; +const handleURI = exports.handleURI = shouldInitialize ? _handleURI : undefined; \ No newline at end of file diff --git a/lib/monkeyPatchProjectConfigs.js b/lib/monkeyPatchProjectConfigs.js index 97747c3d53..f4a480dab4 100644 --- a/lib/monkeyPatchProjectConfigs.js +++ b/lib/monkeyPatchProjectConfigs.js @@ -1,24 +1,41 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _isPlainObject2; + +function _load_isPlainObject() { + return _isPlainObject2 = _interopRequireDefault(require('lodash/isPlainObject')); +} + +exports.default = monkeyPatchProjectConfigs; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../modules/nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +let currentProjectSpec; /** + * 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. + * + * + * @format + */ // TODO: Remove this file once `atom.project.replace()` and `atom.project.getSpecification()` have // been upstreamed. https://github.com/atom/atom/pull/16845. // $eslint-disable-next-line -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {isPlainObject} from 'lodash'; - -let currentProjectSpec; - -export default function monkeyPatchProjectConfigs() { +function monkeyPatchProjectConfigs() { if (atom.project.replace == null) { updateConfigGet(); addConfigResetProjectSettings(); @@ -32,9 +49,9 @@ export default function monkeyPatchProjectConfigs() { const replaceProject = atom.project.replace; if (replaceProject != null) { atom.project.replace = projectSpecification => { - let formatted = {...projectSpecification}; - if ((formatted: any).atom != null) { - formatted = {...formatted, ...(formatted: any).atom}; + let formatted = Object.assign({}, projectSpecification); + if (formatted.atom != null) { + formatted = Object.assign({}, formatted, formatted.atom); delete formatted.atom; } currentProjectSpec = formatted; @@ -64,15 +81,10 @@ const addReplace = () => { // If no path is specified, set to directory of originPath. if (!Array.isArray(projectSpecification.paths)) { - projectSpecification.paths = [ - nuclideUri.dirname(projectSpecification.originPath), - ]; + projectSpecification.paths = [(_nuclideUri || _load_nuclideUri()).default.dirname(projectSpecification.originPath)]; } // $FlowIgnore - atom.config.resetProjectSettings( - projectSpecification.config, - projectSpecification.originPath, - ); + atom.config.resetProjectSettings(projectSpecification.config, projectSpecification.originPath); // $FlowIgnore atom.project.setPaths(projectSpecification.paths); @@ -105,20 +117,16 @@ const updateConfigGet = () => { // $FlowIgnore atom.config.getRawValue = (keyPath, options = {}) => { let value; - if ( - !options.excludeSources || - // $FlowIgnore - !options.excludeSources.includes(atom.config.mainSource) - ) { + if (!options.excludeSources || + // $FlowIgnore + !options.excludeSources.includes(atom.config.mainSource)) { // $FlowIgnore value = getValueAtKeyPath(atom.config.settings, keyPath); // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) if (atom.config.projectFile != null) { const projectValue = getValueAtKeyPath( - // $FlowIgnore - atom.config.projectSettings, - keyPath, - ); + // $FlowIgnore + atom.config.projectSettings, keyPath); value = projectValue === undefined ? value : projectValue; } } @@ -132,7 +140,7 @@ const updateConfigGet = () => { if (value != null) { // $FlowIgnore value = atom.config.deepClone(value); - if (isPlainObject(value) && isPlainObject(defaultValue)) { + if ((0, (_isPlainObject2 || _load_isPlainObject()).default)(value) && (0, (_isPlainObject2 || _load_isPlainObject()).default)(defaultValue)) { // $FlowIgnore atom.config.deepDefaults(value, defaultValue); } @@ -146,14 +154,12 @@ const updateConfigGet = () => { atom.config.setRawValue = (keyPath, value, options = {}) => { const source = options.source ? options.source : undefined; const settingsToChange = - // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - source === atom.config.projectFile ? 'projectSettings' : 'settings'; + // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) + source === atom.config.projectFile ? 'projectSettings' : 'settings'; const defaultValue = getValueAtKeyPath( - // $FlowIgnore - atom.config.defaultSettings, - keyPath, - ); + // $FlowIgnore + atom.config.defaultSettings, keyPath); if (isEqual(defaultValue, value)) { if (keyPath != null) { @@ -184,7 +190,7 @@ const updateConfigGet = () => { if (args.length > 1) { if (typeof args[0] === 'string' || args[0] == null) { [keyPath, options] = args; - ({scope} = options); + ({ scope } = options); } } else { [keyPath] = args; @@ -208,9 +214,7 @@ const updateConfigGet = () => { // $FlowIgnore if (!atom.config.settingsLoaded) { // $FlowIgnore - atom.config.pendingOperations.push(() => - atom.config.set(keyPath, value, options), - ); + atom.config.pendingOperations.push(() => atom.config.set(keyPath, value, options)); } const scopeSelector = options.scopeSelector; @@ -220,9 +224,7 @@ const updateConfigGet = () => { // $FlowIgnore if (source && !scopeSelector && source !== atom.config.projectFile) { - throw new Error( - "::set with a 'source' and no 'sourceSelector' is not yet implemented!", - ); + throw new Error("::set with a 'source' and no 'sourceSelector' is not yet implemented!"); } if (source == null) { // $FlowIgnore @@ -243,16 +245,14 @@ const updateConfigGet = () => { atom.config.setRawScopedValue(keyPath, value, source, scopeSelector); } else { // $FlowIgnore - atom.config.setRawValue(keyPath, value, {source}); + atom.config.setRawValue(keyPath, value, { source }); } if ( - // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - source === atom.config.mainSource && - shouldSave && - // $FlowIgnore - atom.config.settingsLoaded - ) { + // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) + source === atom.config.mainSource && shouldSave && + // $FlowIgnore + atom.config.settingsLoaded) { // $FlowIgnore atom.config.requestSave(); } @@ -264,24 +264,14 @@ const updateConfigGet = () => { const newScopeDescriptor = ScopeDescriptor.fromObject(scopeDescriptor); // $FlowIgnore - const result = atom.config.scopedSettingsStore.getPropertyValue( - newScopeDescriptor.getScopeChain(), - keyPath, - options, - ); + const result = atom.config.scopedSettingsStore.getPropertyValue(newScopeDescriptor.getScopeChain(), keyPath, options); // $FlowIgnore - const legacyScopeDescriptor = atom.config.getLegacyScopeDescriptorForNewScopeDescriptor( - newScopeDescriptor, - ); + const legacyScopeDescriptor = atom.config.getLegacyScopeDescriptorForNewScopeDescriptor(newScopeDescriptor); if (result != null) { return result; } else if (legacyScopeDescriptor) { // $FlowIgnore - return atom.config.scopedSettingsStore.getPropertyValue( - legacyScopeDescriptor.getScopeChain(), - keyPath, - options, - ); + return atom.config.scopedSettingsStore.getPropertyValue(legacyScopeDescriptor.getScopeChain(), keyPath, options); } }; @@ -290,32 +280,19 @@ const updateConfigGet = () => { let result; let scope; if (options != null) { - ({scope} = options); + ({ scope } = options); } if (scope != null) { const scopeDescriptor = ScopeDescriptor.fromObject(scope); // $FlowIgnore - result = atom.config.scopedSettingsStore.getAll( - scopeDescriptor.getScopeChain(), - keyPath, - options, - ); + result = atom.config.scopedSettingsStore.getAll(scopeDescriptor.getScopeChain(), keyPath, options); // $FlowIgnore - const legacyScopeDescriptor = atom.config.getLegacyScopeDescriptorForNewScopeDescriptor( - scopeDescriptor, - ); + const legacyScopeDescriptor = atom.config.getLegacyScopeDescriptorForNewScopeDescriptor(scopeDescriptor); if (legacyScopeDescriptor) { - result.push( - ...Array.from( - // $FlowIgnore - atom.config.scopedSettingsStore.getAll( - legacyScopeDescriptor.getScopeChain(), - keyPath, - options, - ) || [], - ), - ); + result.push(...Array.from( + // $FlowIgnore + atom.config.scopedSettingsStore.getAll(legacyScopeDescriptor.getScopeChain(), keyPath, options) || [])); } } else { result = []; @@ -324,7 +301,7 @@ const updateConfigGet = () => { const globalValue = atom.config.getRawValue(keyPath, options); // $FlowIgnore if (globalValue) { - result.push({scopeSelector: '*', value: globalValue}); + result.push({ scopeSelector: '*', value: globalValue }); } return result; @@ -334,10 +311,7 @@ const updateConfigGet = () => { atom.config.legacyScopeAliases = new Map(); // $FlowIgnore - atom.config.setLegacyScopeAliasForNewScope = ( - languageId, - legacyScopeName, - ) => { + atom.config.setLegacyScopeAliasForNewScope = (languageId, legacyScopeName) => { // $FlowIgnore atom.config.legacyScopeAliases.set(languageId, legacyScopeName); }; @@ -352,14 +326,13 @@ const updateConfigGet = () => { const newScopeDescriptor = ScopeDescriptor.fromObject(scopeDescriptor); // $FlowIgnore const legacyAlias = atom.config.legacyScopeAliases.get( - // $FlowIgnore - newScopeDescriptor.scopes[0], - ); + // $FlowIgnore + newScopeDescriptor.scopes[0]); if (legacyAlias) { // $FlowIgnore const scopes = newScopeDescriptor.scopes.slice(); scopes[0] = legacyAlias; - return new ScopeDescriptor({scopes}); + return new ScopeDescriptor({ scopes }); } }; }; @@ -378,8 +351,8 @@ const addConfigResetProjectSettings = () => { // $FlowIgnore atom.config.resetScopedSettings = (newScopedSettings, options = {}) => { const source = - // $FlowIgnore - options.source == null ? atom.config.mainSource : options.source; + // $FlowIgnore + options.source == null ? atom.config.mainSource : options.source; // $FlowIgnore const priority = atom.config.priorityForSource(source); @@ -391,19 +364,15 @@ const addConfigResetProjectSettings = () => { let settings = newScopedSettings[scopeSelector]; // $FlowIgnore settings = atom.config.makeValueConformToSchema(null, settings, { - suppressException: true, + suppressException: true }); const validatedSettings = {}; validatedSettings[scopeSelector] = withoutEmptyObjects(settings); if (validatedSettings[scopeSelector] != null) { // $FlowIgnore - atom.config.scopedSettingsStore.addProperties( - source, - validatedSettings, - { - priority, - }, - ); + atom.config.scopedSettingsStore.addProperties(source, validatedSettings, { + priority + }); } } // $FlowIgnore @@ -429,7 +398,7 @@ const addConfigResetProjectSettings = () => { newSettings = newSettings['*']; delete scopedSettings['*']; // $FlowIgnore - atom.config.resetScopedSettings(scopedSettings, {source}); + atom.config.resetScopedSettings(scopedSettings, { source }); } // $FlowIgnore @@ -440,7 +409,7 @@ const addConfigResetProjectSettings = () => { atom.config.settingsLoaded = true; for (const key in newSettings) { const value = newSettings[key]; - atom.config.set(key, value, {save: false, source}); + atom.config.set(key, value, { save: false, source }); } // $FlowIgnore if (atom.config.pendingOperations.length) { @@ -470,7 +439,7 @@ const addConfigResetProjectSettings = () => { if (atom.config.projectFile != null) { // $FlowIgnore atom.config._resetSettings(newSettings, { - source: atom.config.projectFile, + source: atom.config.projectFile }); } else { // $FlowIgnore @@ -502,8 +471,8 @@ const addConfigResetProjectSettings = () => { // $FlowIgnore atom.config.resetUserSettings = (newScopedSettings, options = {}) => { const source = - // $FlowIgnore - options.source == null ? atom.config.mainSource : options.source; + // $FlowIgnore + options.source == null ? atom.config.mainSource : options.source; // $FlowIgnore const priority = atom.config.priorityForSource(source); @@ -515,19 +484,15 @@ const addConfigResetProjectSettings = () => { let settings = newScopedSettings[scopeSelector]; // $FlowIgnore settings = atom.config.makeValueConformToSchema(null, settings, { - suppressException: true, + suppressException: true }); const validatedSettings = {}; validatedSettings[scopeSelector] = withoutEmptyObjects(settings); if (validatedSettings[scopeSelector] != null) { // $FlowIgnore - atom.config.scopedSettingsStore.addProperties( - source, - validatedSettings, - { - priority, - }, - ); + atom.config.scopedSettingsStore.addProperties(source, validatedSettings, { + priority + }); } } // $FlowIgnore @@ -540,7 +505,7 @@ class ScopeDescriptor { if (scopes != null && Array.isArray(scopes.scopes)) { return scopes; } else { - return new ScopeDescriptor({scopes}); + return new ScopeDescriptor({ scopes }); } } @@ -552,7 +517,7 @@ class ScopeDescriptor { // // * `object` {Object} // * `scopes` {Array} of {String}s - constructor({scopes}) { + constructor({ scopes }) { // $FlowIgnore this.scopes = scopes; } @@ -619,15 +584,11 @@ function splitKeyPath(keyPath) { for (let i = 0, len = keyPath.length; i < len; i++) { const char = keyPath[i]; if (char === '.' && (i === 0 || keyPath[i - 1] !== '\\')) { - keyPathArray.push( - keyPath.substring(startIndex, i).replace(ESCAPED_DOT, '.'), - ); + keyPathArray.push(keyPath.substring(startIndex, i).replace(ESCAPED_DOT, '.')); startIndex = i + 1; } } - keyPathArray.push( - keyPath.substr(startIndex, keyPath.length).replace(ESCAPED_DOT, '.'), - ); + keyPathArray.push(keyPath.substr(startIndex, keyPath.length).replace(ESCAPED_DOT, '.')); return keyPathArray; } @@ -682,7 +643,7 @@ const getValueAtKeyPath = (o, keyPath) => { const withoutEmptyObjects = o => { const object = o; let resultObject; - if (isPlainObject(object)) { + if ((0, (_isPlainObject2 || _load_isPlainObject()).default)(object)) { for (const key in object) { const value = object[key]; const newValue = withoutEmptyObjects(value); @@ -700,11 +661,7 @@ const withoutEmptyObjects = o => { }; const isEqual = (x, y) => { - if ( - typeof x === 'object' && - x != null && - (typeof y === 'object' && y != null) - ) { + if (typeof x === 'object' && x != null && typeof y === 'object' && y != null) { if (Object.keys(x).length !== Object.keys(y).length) { return false; } @@ -723,4 +680,4 @@ const isEqual = (x, y) => { } else { return true; } -}; +}; \ No newline at end of file diff --git a/lib/preload-dependencies.js b/lib/preload-dependencies.js index 1373e6dcd0..74a3bc57f7 100644 --- a/lib/preload-dependencies.js +++ b/lib/preload-dependencies.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +7,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ @@ -27,8 +29,8 @@ require('immutable'); require('log4js'); require('react'); require('react-dom'); -require('redux'); -require('rxjs'); +require('redux/dist/redux.min.js'); +require('rxjs/bundles/Rx.min.js'); // Single out fs-plus since we can probably remove it one day. -require('fs-plus'); +require('fs-plus'); \ No newline at end of file diff --git a/lib/test-runner.js b/lib/test-runner.js index aa1e933446..d1b97b3146 100644 --- a/lib/test-runner.js +++ b/lib/test-runner.js @@ -1,3 +1,30 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _fs = _interopRequireDefault(require('fs')); + +var _testHelpers; + +function _load_testHelpers() { + return _testHelpers = require('../modules/nuclide-commons/test-helpers'); +} + +var _patchAtomConsole; + +function _load_patchAtomConsole() { + return _patchAtomConsole = _interopRequireDefault(require('../modules/nuclide-commons/patch-atom-console')); +} + +var _path = _interopRequireDefault(require('path')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +(0, (_patchAtomConsole || _load_patchAtomConsole()).default)(); + +// eslint-disable-next-line nuclide-internal/prefer-nuclide-uri /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,37 +32,22 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {TestRunnerParams, ExitCode} from './types'; - -import fs from 'fs'; -import {writeCoverage} from 'nuclide-commons/test-helpers'; -import patchAtomConsole from 'nuclide-commons/patch-atom-console'; - -// eslint-disable-next-line nuclide-internal/prefer-nuclide-uri -import path from 'path'; +const integrationTestsDir = _path.default.join(__dirname, '../spec'); -patchAtomConsole(); - -const integrationTestsDir = path.join(__dirname, '../spec'); - -export default (async function(params: TestRunnerParams): Promise { - const isIntegrationTest = params.testPaths.some(testPath => - testPath.startsWith(integrationTestsDir), - ); +exports.default = async function (params) { + const isIntegrationTest = params.testPaths.some(testPath => testPath.startsWith(integrationTestsDir)); const isApmTest = !isIntegrationTest; // It's assumed that all of the tests belong to the same package. const pkg = getPackage(params.testPaths[0]); if (pkg == null) { - throw new Error( - `Couldn't find a parent "package.json" for ${params.testPaths[0]}`, - ); + throw new Error(`Couldn't find a parent "package.json" for ${params.testPaths[0]}`); } - const nuclideConfig = pkg.atomConfig || (pkg.nuclide && pkg.nuclide.config); + const nuclideConfig = pkg.atomConfig || pkg.nuclide && pkg.nuclide.config; const statusCode = await params.legacyTestRunner({ logFile: params.logFile, @@ -68,9 +80,7 @@ export default (async function(params: TestRunnerParams): Promise { jasmine.getEnv().afterEach(() => { if (atomGlobal.confirm.calls.length) { - const details = atomGlobal.confirm.argsForCall.map( - (args, i) => `call #${i} with ${JSON.stringify(args)}`, - ); + const details = atomGlobal.confirm.argsForCall.map((args, i) => `call #${i} with ${JSON.stringify(args)}`); throw new Error('atom.confirm was called.\n' + details); } }); @@ -82,22 +92,19 @@ export default (async function(params: TestRunnerParams): Promise { // and it doesn't load for unit tests, it's necessary to manually // construct any default config that they define. Object.keys(nuclideConfig).forEach(key => { - atomGlobal.config.setSchema( - `${pkg.name}.${key}`, - nuclideConfig[key], - ); + atomGlobal.config.setSchema(`${pkg.name}.${key}`, nuclideConfig[key]); }); }); } return atomGlobal; - }, + } }); await new Promise(resolve => { const temp = require('temp'); if (statusCode === 0) { - writeCoverage(); + (0, (_testHelpers || _load_testHelpers()).writeCoverage)(); // Atom intercepts "process.exit" so we have to do our own manual cleanup. temp.cleanup((err, stats) => { resolve(); @@ -114,16 +121,16 @@ export default (async function(params: TestRunnerParams): Promise { }); return statusCode; -}); +}; function getPackage(start) { - let current = path.resolve(start); + let current = _path.default.resolve(start); while (true) { - const filename = path.join(current, 'package.json'); - if (fs.existsSync(filename)) { - return JSON.parse(fs.readFileSync(filename, 'utf8')); + const filename = _path.default.join(current, 'package.json'); + if (_fs.default.existsSync(filename)) { + return JSON.parse(_fs.default.readFileSync(filename, 'utf8')); } else { - const next = path.join(current, '..'); + const next = _path.default.join(current, '..'); if (next === current) { return null; } else { @@ -131,4 +138,4 @@ function getPackage(start) { } } } -} +} \ No newline at end of file diff --git a/lib/types.js b/lib/types.js index 682bd576bf..9a390c31f7 100644 --- a/lib/types.js +++ b/lib/types.js @@ -1,44 +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 - */ - -// http://flight-manual.atom.io/hacking-atom/sections/writing-specs/#customizing-your-test-runner -export type TestRunnerParams = { - /** Absolute paths to tests to run. Could be paths to files or directories. */ - testPaths: Array, - /** Creates the `atom` global object. */ - buildAtomEnvironment: (params: BuildAtomEnvironmentParams) => AtomGlobal, - /** Currently undocumented, but seemingly necessary to use buildAtomEnvironment(). */ - buildDefaultApplicationDelegate: () => Object, - /** An optional path to a log file to which test output should be logged. */ - logFile: ?string, - /** A boolean indicating whether or not the tests are running headless. */ - headless: boolean, - /** The legacy Jasmine runner */ - legacyTestRunner: (params: LegacyTestRunnerParams) => Promise, -}; - -// https://github.com/atom/atom/blob/v1.6.2/spec/jasmine-test-runner.coffee -export type LegacyTestRunnerParams = { - logFile: ?string, - headless: boolean, - testPaths: Array, - buildAtomEnvironment: (params: BuildAtomEnvironmentParams) => AtomGlobal, -}; - -export type BuildAtomEnvironmentParams = { - applicationDelegate: Object, - window: Object, - document: Object, - configDirPath?: string, - enablePersistence?: boolean, -}; - -export type ExitCode = number; +"use strict"; \ No newline at end of file diff --git a/modules/atom-ide-debugger-java-android/AndroidJavaDebuggerHelpers.js b/modules/atom-ide-debugger-java-android/AndroidJavaDebuggerHelpers.js index 5cdc77d2a0..0214ff04ab 100644 --- a/modules/atom-ide-debugger-java-android/AndroidJavaDebuggerHelpers.js +++ b/modules/atom-ide-debugger-java-android/AndroidJavaDebuggerHelpers.js @@ -1,3 +1,63 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.launchAndroidServiceOrActivity = launchAndroidServiceOrActivity; +exports.getPidFromPackageName = getPidFromPackageName; +exports.getAdbAttachPortTargetInfo = getAdbAttachPortTargetInfo; +exports.createJavaVspProcessInfo = createJavaVspProcessInfo; +exports.createJavaVspIProcessConfig = createJavaVspIProcessConfig; + +var _nuclideDebuggerCommon; + +function _load_nuclideDebuggerCommon() { + return _nuclideDebuggerCommon = require('../nuclide-debugger-common'); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _utils; + +function _load_utils() { + return _utils = require('../atom-ide-debugger-java/utils'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../nuclide-commons/UniversalDisposable')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _consumeFirstProvider; + +function _load_consumeFirstProvider() { + return _consumeFirstProvider = _interopRequireDefault(require('../nuclide-commons-atom/consumeFirstProvider')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../nuclide-commons/nuclideUri')); +} + +var _nuclideAdb; + +function _load_nuclideAdb() { + return _nuclideAdb = require('../nuclide-adb'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Only one AdbProcessInfo can be active at a time. Since it ties up a forwarded +// adb port, new instances need to wait for the previous one to clean up before +// they can begin debugging. /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,103 +66,36 @@ * LICENSE file in 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 {SshTunnelService} from 'nuclide-adb/lib/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - IProcessConfig, - VSAdapterExecutableInfo, -} from 'nuclide-debugger-common'; -import type { - JavaTargetConfig, - JavaAttachPortTargetConfig, -} from 'atom-ide-debugger-java/JavaDebuggerHelpersService'; -import type {Device} from 'nuclide-debugger-common/types'; - -import {VsAdapterTypes} from 'nuclide-debugger-common'; -import nullthrows from 'nullthrows'; -import invariant from 'assert'; -import { - getJavaDebuggerHelpersServiceByNuclideUri, - getCustomControlButtonsForJavaSourcePaths, - getSourcePathClickSubscriptionsOnVspInstance, -} from 'atom-ide-debugger-java/utils'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Subject} from 'rxjs'; -import consumeFirstProvider from 'nuclide-commons-atom/consumeFirstProvider'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {VspProcessInfo} from 'nuclide-debugger-common'; -import {getAdbServiceByNuclideUri} from 'nuclide-adb'; - -// Only one AdbProcessInfo can be active at a time. Since it ties up a forwarded -// adb port, new instances need to wait for the previous one to clean up before -// they can begin debugging. -let cleanupSubject: ?Subject = null; +let cleanupSubject = null; const DEBUG_JAVA_DEBUGGER = false; -export type AndroidDebugTargetInfo = { - pid: number, - attach: boolean, -}; - -export async function launchAndroidServiceOrActivity( - adbServiceUri: NuclideUri, - service: ?string, - activity: ?string, - action: ?string, - device: Device, - packageName: string, -): Promise { - const adbService = getAdbServiceByNuclideUri(adbServiceUri); +async function launchAndroidServiceOrActivity(adbServiceUri, service, activity, action, device, packageName) { + const adbService = (0, (_nuclideAdb || _load_nuclideAdb()).getAdbServiceByNuclideUri)(adbServiceUri); if (service != null) { await adbService.launchService(device, packageName, service || '', true); } else if (activity != null && action != null) { // First query the device to be sure the activity exists in the specified package. // This will allow us to bubble up a useful error message instead of a cryptic // adb failure if the user simply mistyped the activity or package name. - const activityExists = await adbService.activityExists( - device, - packageName, - activity || '', - ); + const activityExists = await adbService.activityExists(device, packageName, activity || ''); if (!activityExists) { const packages = await adbService.getAllAvailablePackages(device); - const availableActivities = new Set( - packages.filter(line => line.includes(packageName + '/')), - ); - atom.notifications.addError( - `Activity ${activity || ''} does not exist in package ` + - packageName + - '\n' + - 'Did you mean one of these activities: ' + - '\n' + - Array.from(availableActivities) - .map(activityLine => activityLine.split('/')[1]) - .join('\n'), - ); + const availableActivities = new Set(packages.filter(line => line.includes(packageName + '/'))); + atom.notifications.addError(`Activity ${activity || ''} does not exist in package ` + packageName + '\n' + 'Did you mean one of these activities: ' + '\n' + Array.from(availableActivities).map(activityLine => activityLine.split('/')[1]).join('\n')); } - await adbService.launchActivity( - device, - packageName, - activity || '', - true, - action, - ); + await adbService.launchActivity(device, packageName, activity || '', true, action); } } -export async function getPidFromPackageName( - adbServiceUri: NuclideUri, - device: Device, - packageName: string, -): Promise { - const adbService = getAdbServiceByNuclideUri(adbServiceUri); +async function getPidFromPackageName(adbServiceUri, device, packageName) { + const adbService = (0, (_nuclideAdb || _load_nuclideAdb()).getAdbServiceByNuclideUri)(adbServiceUri); const pid = await adbService.getPidFromPackageName(device, packageName); if (!Number.isInteger(pid)) { throw new Error(`Fail to get pid for package: ${packageName}`); @@ -110,38 +103,19 @@ export async function getPidFromPackageName( return pid; } -export async function getAdbAttachPortTargetInfo( - device: Device, - adbServiceUri: NuclideUri, - targetUri: NuclideUri, - pid: ?number, - subscriptions: UniversalDisposable, -): Promise { - const tunnelRequired = - nuclideUri.isLocal(adbServiceUri) && nuclideUri.isRemote(targetUri); - const tunnelService = tunnelRequired - ? (await consumeFirstProvider('nuclide.ssh-tunnel'): ?SshTunnelService) - : null; - const adbService = getAdbServiceByNuclideUri(adbServiceUri); +async function getAdbAttachPortTargetInfo(device, adbServiceUri, targetUri, pid, subscriptions) { + const tunnelRequired = (_nuclideUri || _load_nuclideUri()).default.isLocal(adbServiceUri) && (_nuclideUri || _load_nuclideUri()).default.isRemote(targetUri); + const tunnelService = tunnelRequired ? await (0, (_consumeFirstProvider || _load_consumeFirstProvider()).default)('nuclide.ssh-tunnel') : null; + const adbService = (0, (_nuclideAdb || _load_nuclideAdb()).getAdbServiceByNuclideUri)(adbServiceUri); // tunnel Service's getAvailableServerPort does something weird where it // wants adbServiceUri to be either '' or 'localhost' - const adbPort = tunnelRequired - ? await nullthrows(tunnelService).getAvailableServerPort( - nuclideUri.isLocal(adbServiceUri) ? 'localhost' : adbServiceUri, - ) - : await getJavaDebuggerHelpersServiceByNuclideUri( - adbServiceUri, - ).getPortForJavaDebugger(); - const forwardSpec = await adbService.forwardJdwpPortToPid( - device, - adbPort, - pid || 0, - ); + const adbPort = tunnelRequired ? await (0, (_nullthrows || _load_nullthrows()).default)(tunnelService).getAvailableServerPort((_nuclideUri || _load_nuclideUri()).default.isLocal(adbServiceUri) ? 'localhost' : adbServiceUri) : await (0, (_utils || _load_utils()).getJavaDebuggerHelpersServiceByNuclideUri)(adbServiceUri).getPortForJavaDebugger(); + const forwardSpec = await adbService.forwardJdwpPortToPid(device, adbPort, pid || 0); if (cleanupSubject != null) { await cleanupSubject.toPromise(); } - cleanupSubject = new Subject(); + cleanupSubject = new _rxjsBundlesRxMinJs.Subject(); subscriptions.add(async () => { const result = await adbService.removeJdwpForwardSpec(device, forwardSpec); if (result.trim().startsWith('error')) { @@ -163,18 +137,20 @@ export async function getAdbAttachPortTargetInfo( resolve(adbPort); return; } - invariant(tunnelService); - const debuggerPort = await tunnelService.getAvailableServerPort( - targetUri, - ); + + if (!tunnelService) { + throw new Error('Invariant violation: "tunnelService"'); + } + + const debuggerPort = await tunnelService.getAvailableServerPort(targetUri); const tunnel = { description: 'Java debugger', from: { - host: nuclideUri.getHostname(targetUri), + host: (_nuclideUri || _load_nuclideUri()).default.getHostname(targetUri), port: debuggerPort, - family: 4, + family: 4 }, - to: {host: 'localhost', port: adbPort, family: 4}, + to: { host: 'localhost', port: adbPort, family: 4 } }; const openTunnel = tunnelService.openTunnels([tunnel]).share(); subscriptions.add(openTunnel.subscribe()); @@ -187,60 +163,28 @@ export async function getAdbAttachPortTargetInfo( return { debugMode: 'attach', machineName: 'localhost', - port: attachPort, + port: attachPort }; } -export async function createJavaVspProcessInfo( - targetUri: NuclideUri, - config: JavaTargetConfig, - clickEvents: rxjs$Subject, -): Promise { - const processConfig = await createJavaVspIProcessConfig( - targetUri, - config, - clickEvents, - ); - const info = new VspProcessInfo( - processConfig.targetUri, - processConfig.debugMode, - processConfig.adapterType, - processConfig.adapterExecutable, - processConfig.config, - {threads: true}, - { - customControlButtons: getCustomControlButtonsForJavaSourcePaths( - clickEvents, - ), - threadsComponentTitle: 'Threads', - }, - ); - - const subscriptions = new UniversalDisposable(); - subscriptions.add( - ...getSourcePathClickSubscriptionsOnVspInstance( - targetUri, - info, - clickEvents, - ), - ); +async function createJavaVspProcessInfo(targetUri, config, clickEvents) { + const processConfig = await createJavaVspIProcessConfig(targetUri, config, clickEvents); + const info = new (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VspProcessInfo(processConfig.targetUri, processConfig.debugMode, processConfig.adapterType, processConfig.adapterExecutable, processConfig.config, { threads: true }, { + customControlButtons: (0, (_utils || _load_utils()).getCustomControlButtonsForJavaSourcePaths)(clickEvents), + threadsComponentTitle: 'Threads' + }); + + const subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + subscriptions.add(...(0, (_utils || _load_utils()).getSourcePathClickSubscriptionsOnVspInstance)(targetUri, info, clickEvents)); info.addCustomDisposable(subscriptions); return info; } -async function getJavaVSAdapterExecutableInfo( - targetUri: NuclideUri, -): Promise { - return getJavaDebuggerHelpersServiceByNuclideUri( - targetUri, - ).getJavaVSAdapterExecutableInfo(DEBUG_JAVA_DEBUGGER); +async function getJavaVSAdapterExecutableInfo(targetUri) { + return (0, (_utils || _load_utils()).getJavaDebuggerHelpersServiceByNuclideUri)(targetUri).getJavaVSAdapterExecutableInfo(DEBUG_JAVA_DEBUGGER); } -export async function createJavaVspIProcessConfig( - targetUri: NuclideUri, - config: JavaTargetConfig, - clickEvents: rxjs$Subject, -): Promise { +async function createJavaVspIProcessConfig(targetUri, config, clickEvents) { const adapterExecutable = await getJavaVSAdapterExecutableInfo(targetUri); // If you have built using debug information, then print the debug server port: if (DEBUG_JAVA_DEBUGGER) { @@ -250,32 +194,20 @@ export async function createJavaVspIProcessConfig( console.log('Java Debugger Debug Port:', port); } catch (error) { /* eslint-disable no-console */ - console.log( - 'Could not find debug server port from adapter executable', - adapterExecutable, - ); + console.log('Could not find debug server port from adapter executable', adapterExecutable); } } return { targetUri, debugMode: config.debugMode, - adapterType: VsAdapterTypes.JAVA, + adapterType: (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsAdapterTypes.JAVA, adapterExecutable, config, - capabilities: {threads: true}, + capabilities: { threads: true }, properties: { - customControlButtons: getCustomControlButtonsForJavaSourcePaths( - clickEvents, - ), - threadsComponentTitle: 'Threads', - }, + customControlButtons: (0, (_utils || _load_utils()).getCustomControlButtonsForJavaSourcePaths)(clickEvents), + threadsComponentTitle: 'Threads' + } }; -} - -export type AndroidDebugInfo = {| - attach: boolean, - subscriptions: UniversalDisposable, - pid: number, - attachPortTargetInfo: JavaAttachPortTargetConfig, -|}; +} \ No newline at end of file diff --git a/modules/atom-ide-debugger-java-android/SourceFilePathsModal.js b/modules/atom-ide-debugger-java-android/SourceFilePathsModal.js index e819e90d23..480fea9d9d 100644 --- a/modules/atom-ide-debugger-java-android/SourceFilePathsModal.js +++ b/modules/atom-ide-debugger-java-android/SourceFilePathsModal.js @@ -1,160 +1,220 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {ListView, ListViewItem} from 'nuclide-commons-ui/ListView'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; -import {Button, ButtonTypes} from 'nuclide-commons-ui/Button'; -import nullthrows from 'nullthrows'; -import {track} from 'nuclide-commons/analytics'; - -type PropsType = { - initialSourcePaths: Array, - sourcePathsChanged: (Array) => void, - onClosed: () => void, -}; - -type StateType = { - currentPaths: Array, -}; - -export class SourceFilePathsModal extends React.Component< - PropsType, - StateType, -> { - _newSourcePath: ?AtomInput; - _savedSourcePaths: Array = []; - state = { - currentPaths: this.props.initialSourcePaths.slice(0), - }; - - _getSourcePathControls(): Array> { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SourceFilePathsModal = undefined; + +var _react = _interopRequireWildcard(require('react')); + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../nuclide-commons-ui/AtomInput'); +} + +var _ListView; + +function _load_ListView() { + return _ListView = require('../nuclide-commons-ui/ListView'); +} + +var _ButtonGroup; + +function _load_ButtonGroup() { + return _ButtonGroup = require('../nuclide-commons-ui/ButtonGroup'); +} + +var _Button; + +function _load_Button() { + return _Button = require('../nuclide-commons-ui/Button'); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _analytics; + +function _load_analytics() { + return _analytics = 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; } } + +class SourceFilePathsModal extends _react.Component { + constructor(...args) { + var _temp; + + return _temp = super(...args), this._savedSourcePaths = [], this.state = { + currentPaths: this.props.initialSourcePaths.slice(0) + }, this._addItem = () => { + const text = (0, (_nullthrows || _load_nullthrows()).default)(this._newSourcePath).getText().trim().replace(/;/g, ''); // Do not allow semicolons since we are using them + // to delimit paths. TODO: handle paths that actually contain ;'s? + + if (text !== '') { + this.state.currentPaths.push(text); + (0, (_nullthrows || _load_nullthrows()).default)(this._newSourcePath).setText(''); + this.setState({ + currentPaths: this.state.currentPaths + }); + } + }, this._cancelClick = () => { + this.setState({ + currentPaths: this._savedSourcePaths + }); + this.props.onClosed(); + (0, (_analytics || _load_analytics()).track)('fb-java-debugger-source-dialog-cancel', {}); + }, this._handleSaveClick = () => { + this._addItem(); + this._savedSourcePaths = this.state.currentPaths.slice(0); + this.props.sourcePathsChanged(this._savedSourcePaths); + this.props.onClosed(); + (0, (_analytics || _load_analytics()).track)('fb-java-debugger-source-dialog-saved', {}); + }, _temp; + } + + _getSourcePathControls() { const items = []; const paths = Array.from(new Set(this.state.currentPaths)); if (paths.length === 0) { - return [ - -

- , - ]; + return [_react.createElement( + (_ListView || _load_ListView()).ListViewItem, + { key: 0, index: 0 }, + _react.createElement( + 'div', + null, + _react.createElement( + 'i', + null, + '(No custom source file paths have been specified)' + ) + ) + )]; } paths.forEach((path, idx) => { - items.push( - -
- { - this.state.currentPaths.splice(idx, 1); - this.setState({ - currentPaths: this.state.currentPaths, - }); - }} - /> - {path} -
-
, - ); + items.push(_react.createElement( + (_ListView || _load_ListView()).ListViewItem, + { key: idx, index: idx }, + _react.createElement( + 'div', + { className: 'block' }, + _react.createElement('i', { + className: 'icon icon-x nuclide-source-content-x', + title: 'Remove path', + onClick: () => { + this.state.currentPaths.splice(idx, 1); + this.setState({ + currentPaths: this.state.currentPaths + }); + } + }), + _react.createElement( + 'span', + null, + path + ) + ) + )); }); return items; } - _addItem = () => { - const text = nullthrows(this._newSourcePath) - .getText() - .trim() - .replace(/;/g, ''); // Do not allow semicolons since we are using them - // to delimit paths. TODO: handle paths that actually contain ;'s? - - if (text !== '') { - this.state.currentPaths.push(text); - nullthrows(this._newSourcePath).setText(''); - this.setState({ - currentPaths: this.state.currentPaths, - }); - } - }; - - render(): React.Node { + render() { const sourcePaths = this._getSourcePathControls(); - return ( -
-
-

Configure source file paths:

-
- - Nuclide will automatically search for source in your project root - paths. You can add additional search paths here. - -
-
- { - this._newSourcePath = input; - }} - initialValue="" - autofocus={true} - placeholderText="Add a source file path..." - /> - -
-
- {sourcePaths} -
-
-
- - - - -
-
+ return _react.createElement( + 'div', + { className: 'sourcepath-modal' }, + _react.createElement( + 'div', + { className: 'select-list' }, + _react.createElement( + 'h2', + null, + 'Configure source file paths:' + ), + _react.createElement( + 'div', + { className: 'nuclide-source-add-content' }, + _react.createElement( + 'span', + null, + 'Nuclide will automatically search for source in your project root paths. You can add additional search paths here.' + ) + ), + _react.createElement( + 'div', + { className: 'sourcepath-add-bar' }, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + className: 'sourcepath-pane', + ref: input => { + this._newSourcePath = input; + }, + initialValue: '', + autofocus: true, + placeholderText: 'Add a source file path...' + }), + _react.createElement( + (_Button || _load_Button()).Button, + { + onClick: this._addItem, + title: 'Add Path', + className: 'sourcepath-add-button' }, + _react.createElement('i', { className: 'icon icon-plus' }) + ) + ), + _react.createElement( + 'div', + { className: 'sourcepath-sources' }, + _react.createElement( + (_ListView || _load_ListView()).ListView, + { alternateBackground: true }, + sourcePaths + ) + ) + ), + _react.createElement( + 'div', + { + className: 'sourcepath-buttons', + style: { display: 'flex', flexDirection: 'row-reverse' } }, + _react.createElement( + (_ButtonGroup || _load_ButtonGroup()).ButtonGroup, + null, + _react.createElement( + (_Button || _load_Button()).Button, + { tabIndex: '17', onClick: this._cancelClick }, + 'Cancel' + ), + _react.createElement( + (_Button || _load_Button()).Button, + { + buttonType: (_Button || _load_Button()).ButtonTypes.PRIMARY, + tabIndex: '16', + onClick: this._handleSaveClick }, + 'Save' + ) + ) + ) ); } - _cancelClick = (): void => { - this.setState({ - currentPaths: this._savedSourcePaths, - }); - this.props.onClosed(); - track('fb-java-debugger-source-dialog-cancel', {}); - }; - - _handleSaveClick = (): void => { - this._addItem(); - this._savedSourcePaths = this.state.currentPaths.slice(0); - this.props.sourcePathsChanged(this._savedSourcePaths); - this.props.onClosed(); - track('fb-java-debugger-source-dialog-saved', {}); - }; } +exports.SourceFilePathsModal = SourceFilePathsModal; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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-debugger-java-android/main.js b/modules/atom-ide-debugger-java-android/main.js index ed34b8e4dd..a5966cc771 100644 --- a/modules/atom-ide-debugger-java-android/main.js +++ b/modules/atom-ide-debugger-java-android/main.js @@ -1,48 +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 type { - NuclideDebuggerProvider, - DebuggerConfigurationProvider, -} from 'nuclide-debugger-common'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import {VsAdapterTypes} from 'nuclide-debugger-common'; -import {AutoGenLaunchAttachProvider} from 'nuclide-debugger-common/AutoGenLaunchAttachProvider'; -import {getJavaAndroidConfig, resolveConfiguration} from './utils'; +'use strict'; + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../nuclide-commons-atom/createPackage')); +} + +var _nuclideDebuggerCommon; + +function _load_nuclideDebuggerCommon() { + return _nuclideDebuggerCommon = require('../nuclide-debugger-common'); +} + +var _AutoGenLaunchAttachProvider; + +function _load_AutoGenLaunchAttachProvider() { + return _AutoGenLaunchAttachProvider = require('../nuclide-debugger-common/AutoGenLaunchAttachProvider'); +} + +var _utils; + +function _load_utils() { + return _utils = require('./utils'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class Activation { constructor() {} dispose() {} - createDebuggerProvider(): NuclideDebuggerProvider { + createDebuggerProvider() { return { - type: VsAdapterTypes.JAVA_ANDROID, + type: (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsAdapterTypes.JAVA_ANDROID, getLaunchAttachProvider: connection => { - return new AutoGenLaunchAttachProvider( - 'Java - Android', - connection, - getJavaAndroidConfig(), - ); - }, + return new (_AutoGenLaunchAttachProvider || _load_AutoGenLaunchAttachProvider()).AutoGenLaunchAttachProvider('Java - Android', connection, (0, (_utils || _load_utils()).getJavaAndroidConfig)()); + } }; } - createDebuggerConfigurator(): DebuggerConfigurationProvider { + createDebuggerConfigurator() { return { - resolveConfiguration, - adapterType: VsAdapterTypes.JAVA_ANDROID, + resolveConfiguration: (_utils || _load_utils()).resolveConfiguration, + adapterType: (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsAdapterTypes.JAVA_ANDROID }; } -} +} /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 + */ -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/modules/atom-ide-debugger-java-android/utils.js b/modules/atom-ide-debugger-java-android/utils.js index feb8715dee..0290d32f17 100644 --- a/modules/atom-ide-debugger-java-android/utils.js +++ b/modules/atom-ide-debugger-java-android/utils.js @@ -1,70 +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 strict-local - * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - AutoGenConfig, - IProcessConfig, - ControlButtonSpecification, - DebuggerConfigAction, -} from 'nuclide-debugger-common/types'; -import type {Device} from 'nuclide-debugger-common/types'; - -import idx from 'idx'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Subject} from 'rxjs'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {VsAdapterTypes} from 'nuclide-debugger-common/constants'; -import { - getJavaDebuggerHelpersServiceByNuclideUri, - getSourcePathClickSubscriptions, -} from 'atom-ide-debugger-java/utils'; -import nullthrows from 'nullthrows'; -import { - getAdbAttachPortTargetInfo, - launchAndroidServiceOrActivity, - getPidFromPackageName, -} from './AndroidJavaDebuggerHelpers'; - -export const NUCLIDE_DEBUGGER_DEV_GK = 'nuclide_debugger_dev'; - -export function getJavaAndroidConfig(): AutoGenConfig { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.NUCLIDE_DEBUGGER_DEV_GK = undefined; +exports.getJavaAndroidConfig = getJavaAndroidConfig; +exports.getCustomControlButtonsForJavaSourcePaths = getCustomControlButtonsForJavaSourcePaths; +exports.resolveConfiguration = resolveConfiguration; + +var _idx; + +function _load_idx() { + return _idx = _interopRequireDefault(require('idx')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../nuclide-commons/nuclideUri')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../nuclide-commons/UniversalDisposable')); +} + +var _constants; + +function _load_constants() { + return _constants = require('../nuclide-debugger-common/constants'); +} + +var _utils; + +function _load_utils() { + return _utils = require('../atom-ide-debugger-java/utils'); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _AndroidJavaDebuggerHelpers; + +function _load_AndroidJavaDebuggerHelpers() { + return _AndroidJavaDebuggerHelpers = require('./AndroidJavaDebuggerHelpers'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const NUCLIDE_DEBUGGER_DEV_GK = exports.NUCLIDE_DEBUGGER_DEV_GK = 'nuclide_debugger_dev'; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ + +function getJavaAndroidConfig() { const deviceAndPackage = { name: 'deviceAndPackage', type: 'deviceAndPackage', description: '', required: true, - visible: true, + visible: true }; const activity = { name: 'activity', type: 'string', description: 'com.example.app.main.MainActivity', required: false, - visible: true, + visible: true }; const service = { name: 'service', type: 'string', description: '.example.package.path.MyServiceClass', required: false, - visible: true, + visible: true }; const intent = { name: 'intent', type: 'string', description: 'android.intent.action.MAIN', required: false, - visible: true, + visible: true }; const deviceAndProcess = { @@ -72,178 +101,120 @@ export function getJavaAndroidConfig(): AutoGenConfig { type: 'deviceAndProcess', description: '', required: true, - visible: true, + visible: true }; const selectSources = { name: 'selectSources', type: 'selectSources', description: '', required: true, - visible: true, + visible: true }; return { launch: { launch: true, - vsAdapterType: VsAdapterTypes.JAVA_ANDROID, + vsAdapterType: (_constants || _load_constants()).VsAdapterTypes.JAVA_ANDROID, threads: true, properties: [deviceAndPackage, activity, service, intent, selectSources], cwdPropertyName: 'cwd', - header: null, + header: null }, attach: { launch: false, - vsAdapterType: VsAdapterTypes.JAVA_ANDROID, + vsAdapterType: (_constants || _load_constants()).VsAdapterTypes.JAVA_ANDROID, threads: true, properties: [deviceAndProcess, selectSources], - header: null, - }, + header: null + } }; } -export function getCustomControlButtonsForJavaSourcePaths( - clickEvents: rxjs$Subject, -): ControlButtonSpecification[] { - return [ - { - icon: 'file-code', - title: 'Set Source Path', - onClick: () => clickEvents.next(), - }, - ]; +function getCustomControlButtonsForJavaSourcePaths(clickEvents) { + return [{ + icon: 'file-code', + title: 'Set Source Path', + onClick: () => clickEvents.next() + }]; } -function _getPackageName(debugMode: DebuggerConfigAction, config): string { - return nullthrows( - debugMode === 'launch' - ? (idx(config, _ => _.deviceAndPackage.selectedPackage): ?string) - : (idx(config, _ => _.deviceAndProcess.selectedProcess.name): ?string), - ); +function _getPackageName(debugMode, config) { + var _ref, _ref2, _ref3, _ref4, _ref5; + + return (0, (_nullthrows || _load_nullthrows()).default)(debugMode === 'launch' ? (_ref = config) != null ? (_ref2 = _ref.deviceAndPackage) != null ? _ref2.selectedPackage : _ref2 : _ref : (_ref3 = config) != null ? (_ref4 = _ref3.deviceAndProcess) != null ? (_ref5 = _ref4.selectedProcess) != null ? _ref5.name : _ref5 : _ref4 : _ref3); } -function _getDevice(debugMode: DebuggerConfigAction, config): Device { - return nullthrows( - debugMode === 'launch' - ? (idx(config, _ => _.deviceAndPackage.device): ?Device) - : (idx(config, _ => _.deviceAndProcess.device): ?Device), - ); +function _getDevice(debugMode, config) { + var _ref6, _ref7, _ref8, _ref9; + + return (0, (_nullthrows || _load_nullthrows()).default)(debugMode === 'launch' ? (_ref6 = config) != null ? (_ref7 = _ref6.deviceAndPackage) != null ? _ref7.device : _ref7 : _ref6 : (_ref8 = config) != null ? (_ref9 = _ref8.deviceAndProcess) != null ? _ref9.device : _ref9 : _ref8); } -async function _getPid( - debugMode: DebuggerConfigAction, - config, - adbServiceUri: string, - device: Device, - packageName: string, -): Promise { - const selectedProcessPidString = idx( - config, - _ => _.deviceAndProcess.selectedProcess.pid, - ); +async function _getPid(debugMode, config, adbServiceUri, device, packageName) { + var _ref10, _ref11, _ref12; + + const selectedProcessPidString = (_ref10 = config) != null ? (_ref11 = _ref10.deviceAndProcess) != null ? (_ref12 = _ref11.selectedProcess) != null ? _ref12.pid : _ref12 : _ref11 : _ref10; const selectedProcessPid = parseInt(selectedProcessPidString, 10); - const pid = - debugMode === 'attach' && selectedProcessPidString != null - ? selectedProcessPid - : await getPidFromPackageName(adbServiceUri, device, packageName); + const pid = debugMode === 'attach' && selectedProcessPidString != null ? selectedProcessPid : await (0, (_AndroidJavaDebuggerHelpers || _load_AndroidJavaDebuggerHelpers()).getPidFromPackageName)(adbServiceUri, device, packageName); if (isNaN(pid)) { - throw new Error( - 'Selected process pid is not a number: ' + - JSON.stringify(selectedProcessPidString), - ); + throw new Error('Selected process pid is not a number: ' + JSON.stringify(selectedProcessPidString)); } return pid; } -function _getResolvedTargetUri(targetUri: NuclideUri, config) { - const selectSources: ?string = idx(config, _ => _.selectSources); +function _getResolvedTargetUri(targetUri, config) { + var _ref13; + + const selectSources = (_ref13 = config) != null ? _ref13.selectSources : _ref13; return selectSources != null ? selectSources : targetUri; } -function _getAdbServiceUri(unresolvedTargetUri: NuclideUri, config) { - const adbServiceUri: ?string = idx(config, _ => _.adbServiceUri); +function _getAdbServiceUri(unresolvedTargetUri, config) { + var _ref14; + + const adbServiceUri = (_ref14 = config) != null ? _ref14.adbServiceUri : _ref14; return adbServiceUri != null ? adbServiceUri : unresolvedTargetUri; } -export async function resolveConfiguration( - configuration: IProcessConfig, -): Promise { +async function resolveConfiguration(configuration) { // adapterType === VsAdapterTypes.JAVA_ANDROID - const {config, debugMode, targetUri} = configuration; + const { config, debugMode, targetUri } = configuration; const adbServiceUri = _getAdbServiceUri(targetUri, config); const resolvedTargetUri = _getResolvedTargetUri(targetUri, config); const packageName = _getPackageName(debugMode, config); const device = _getDevice(debugMode, config); if (debugMode === 'launch') { - const {service, intent, activity} = config; - await launchAndroidServiceOrActivity( - adbServiceUri, - (service: ?string), - (activity: ?string), - (intent: ?string) /* intent and action are the same */, - device, - packageName, - ); + const { service, intent, activity } = config; + await (0, (_AndroidJavaDebuggerHelpers || _load_AndroidJavaDebuggerHelpers()).launchAndroidServiceOrActivity)(adbServiceUri, service, activity, intent, /* intent and action are the same */ + device, packageName); } - const pid = await _getPid( - debugMode, - config, - adbServiceUri, - device, - packageName, - ); - - const subscriptions = new UniversalDisposable(); - const attachPortTargetConfig = await getAdbAttachPortTargetInfo( - device, - adbServiceUri, - resolvedTargetUri, - pid, - subscriptions, - ); - - const customDisposable = - configuration.customDisposable || new UniversalDisposable(); + const pid = await _getPid(debugMode, config, adbServiceUri, device, packageName); + + const subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + const attachPortTargetConfig = await (0, (_AndroidJavaDebuggerHelpers || _load_AndroidJavaDebuggerHelpers()).getAdbAttachPortTargetInfo)(device, adbServiceUri, resolvedTargetUri, pid, subscriptions); + + const customDisposable = configuration.customDisposable || new (_UniversalDisposable || _load_UniversalDisposable()).default(); customDisposable.add(subscriptions); - const sdkSourcePath = - config.sdkVersion != null - ? await getJavaDebuggerHelpersServiceByNuclideUri( - resolvedTargetUri, - ).getSdkVersionSourcePath(config.sdkVersion) - : null; - const sdkSourcePathResolved = - sdkSourcePath != null ? nuclideUri.getPath(sdkSourcePath) : sdkSourcePath; - const additionalSourcePaths = - sdkSourcePathResolved != null ? [sdkSourcePathResolved] : []; - - const clickEvents = new Subject(); + const sdkSourcePath = config.sdkVersion != null ? await (0, (_utils || _load_utils()).getJavaDebuggerHelpersServiceByNuclideUri)(resolvedTargetUri).getSdkVersionSourcePath(config.sdkVersion) : null; + const sdkSourcePathResolved = sdkSourcePath != null ? (_nuclideUri || _load_nuclideUri()).default.getPath(sdkSourcePath) : sdkSourcePath; + const additionalSourcePaths = sdkSourcePathResolved != null ? [sdkSourcePathResolved] : []; + + const clickEvents = new _rxjsBundlesRxMinJs.Subject(); const onInitializeCallback = async session => { - customDisposable.add( - ...getSourcePathClickSubscriptions( - resolvedTargetUri, - session, - clickEvents, - additionalSourcePaths, - ), - ); + customDisposable.add(...(0, (_utils || _load_utils()).getSourcePathClickSubscriptions)(resolvedTargetUri, session, clickEvents, additionalSourcePaths)); }; - return { - ...configuration, + return Object.assign({}, configuration, { targetUri: resolvedTargetUri, debugMode: attachPortTargetConfig.debugMode, - adapterExecutable: await getJavaDebuggerHelpersServiceByNuclideUri( - resolvedTargetUri, - ).getJavaVSAdapterExecutableInfo(false), - properties: { - ...configuration.properties, - customControlButtons: getCustomControlButtonsForJavaSourcePaths( - clickEvents, - ), - }, + adapterExecutable: await (0, (_utils || _load_utils()).getJavaDebuggerHelpersServiceByNuclideUri)(resolvedTargetUri).getJavaVSAdapterExecutableInfo(false), + properties: Object.assign({}, configuration.properties, { + customControlButtons: getCustomControlButtonsForJavaSourcePaths(clickEvents) + }), config: attachPortTargetConfig, customDisposable, - onInitializeCallback, - }; -} + onInitializeCallback + }); +} \ No newline at end of file diff --git a/modules/atom-ide-debugger-java/JavaDebuggerHelpersService.js b/modules/atom-ide-debugger-java/JavaDebuggerHelpersService.js index ac10ae4d66..b56ae1ccaa 100644 --- a/modules/atom-ide-debugger-java/JavaDebuggerHelpersService.js +++ b/modules/atom-ide-debugger-java/JavaDebuggerHelpersService.js @@ -1,77 +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 strict-local - * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {VSAdapterExecutableInfo} from 'nuclide-debugger-common'; - -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import os from 'os'; -import {runCommand} from 'nuclide-commons/process'; -import {Observable} from 'rxjs'; -import {getAvailableServerPort} from 'nuclide-commons/serverPort'; - -export type JavaLaunchTargetConfig = {| - +debugMode: 'launch', - +entryPointClass: string, - +classPath: string, - +runArgs?: ?Array, -|}; - -export type JavaAttachPortTargetConfig = {| - +debugMode: 'attach', - +machineName: string, - +port: number, -|}; - -export type JavaTargetConfig = - | JavaLaunchTargetConfig - | JavaAttachPortTargetConfig; - -export type TerminalLaunchInfo = {| - +launchCommand: string, - +launchCwd: NuclideUri, - +targetExecutable: NuclideUri, - +launchArgs: Array, - +attachPort: number, - +attachHost: string, -|}; - -const JAVA = 'java'; - -function _getAndroidHomeDir(): NuclideUri { - return (process.env.ANDROID_HOME: ?string) || '/opt/android_sdk'; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getPortForJavaDebugger = getPortForJavaDebugger; +exports.getJavaVSAdapterExecutableInfo = getJavaVSAdapterExecutableInfo; +exports.prepareForTerminalLaunch = prepareForTerminalLaunch; +exports.javaDebugWaitForJdwpProcessStart = javaDebugWaitForJdwpProcessStart; +exports.javaDebugWaitForJdwpProcessExit = javaDebugWaitForJdwpProcessExit; +exports.getAndroidSDKVersionFromApk = getAndroidSDKVersionFromApk; +exports.getSdkVersionSourcePath = getSdkVersionSourcePath; + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../nuclide-commons/fsPromise')); } -export async function getPortForJavaDebugger(): Promise { - return getAvailableServerPort(); +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 _os = _interopRequireDefault(require('os')); + +var _process; + +function _load_process() { + return _process = require('../nuclide-commons/process'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _serverPort; + +function _load_serverPort() { + return _serverPort = require('../nuclide-commons/serverPort'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const JAVA = 'java'; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ + +function _getAndroidHomeDir() { + return process.env.ANDROID_HOME || '/opt/android_sdk'; +} + +async function getPortForJavaDebugger() { + return (0, (_serverPort || _load_serverPort()).getAvailableServerPort)(); } -export async function getJavaVSAdapterExecutableInfo( - debug: boolean, -): Promise { +async function getJavaVSAdapterExecutableInfo(debug) { return { command: JAVA, - args: await _getJavaArgs(debug), + args: await _getJavaArgs(debug) }; } -export async function prepareForTerminalLaunch( - config: JavaLaunchTargetConfig, -): Promise { - const {classPath, entryPointClass} = config; - const launchPath = nuclideUri.expandHomeDir(classPath); - const attachPort = await getAvailableServerPort(); +async function prepareForTerminalLaunch(config) { + const { classPath, entryPointClass } = config; + const launchPath = (_nuclideUri || _load_nuclideUri()).default.expandHomeDir(classPath); + const attachPort = await (0, (_serverPort || _load_serverPort()).getAvailableServerPort)(); // Note: the attach host is passed to the Java debugger engine, which // runs on the RPC side of Nuclide, so it is fine to always pass localhost @@ -83,142 +89,94 @@ export async function prepareForTerminalLaunch( launchCommand: 'java', launchCwd: launchPath, targetExecutable: launchPath, - launchArgs: [ - '-Xdebug', - `-Xrunjdwp:transport=dt_socket,address=${attachHost}:${attachPort},server=y,suspend=y`, - '-classpath', - launchPath, - entryPointClass, - ...(config.runArgs || []), - ], + launchArgs: ['-Xdebug', `-Xrunjdwp:transport=dt_socket,address=${attachHost}:${attachPort},server=y,suspend=y`, '-classpath', launchPath, entryPointClass, ...(config.runArgs || [])] }); } -export async function javaDebugWaitForJdwpProcessStart( - jvmSuspendArgs: string, -): Promise { +async function javaDebugWaitForJdwpProcessStart(jvmSuspendArgs) { return new Promise(resolve => { - const disposable = new UniversalDisposable(); - disposable.add( - Observable.interval(1000) - .mergeMap(async () => { - const line = await _findJdwpProcess(jvmSuspendArgs); - if (line != null) { - disposable.dispose(); - resolve(); - } - }) - .timeout(30000) - .subscribe(), - ); + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + disposable.add(_rxjsBundlesRxMinJs.Observable.interval(1000).mergeMap(async () => { + const line = await _findJdwpProcess(jvmSuspendArgs); + if (line != null) { + disposable.dispose(); + resolve(); + } + }).timeout(30000).subscribe()); }); } -export async function javaDebugWaitForJdwpProcessExit( - jvmSuspendArgs: string, -): Promise { +async function javaDebugWaitForJdwpProcessExit(jvmSuspendArgs) { return new Promise(resolve => { - const disposable = new UniversalDisposable(); + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(); let pidLine = null; - disposable.add( - Observable.interval(1000) - .mergeMap(async () => { - const line = await _findJdwpProcess(jvmSuspendArgs); - if (line != null) { - if (pidLine != null && pidLine !== line) { - // The matching target process line has changed, so the process - // we were watching is now gone. - disposable.dispose(); - resolve(); - } - pidLine = line; - } else { - disposable.dispose(); - resolve(); - } - }) - .subscribe(), - ); + disposable.add(_rxjsBundlesRxMinJs.Observable.interval(1000).mergeMap(async () => { + const line = await _findJdwpProcess(jvmSuspendArgs); + if (line != null) { + if (pidLine != null && pidLine !== line) { + // The matching target process line has changed, so the process + // we were watching is now gone. + disposable.dispose(); + resolve(); + } + pidLine = line; + } else { + disposable.dispose(); + resolve(); + } + }).subscribe()); }); } -async function _getJavaArgs(debug: boolean): Promise> { - const baseJavaArgs = [ - '-classpath', - await _getClassPath(), - 'com.facebook.nuclide.debugger.JavaDbg', - '--vsp', - ]; - const debugArgs = debug - ? [ - '-Xdebug', - '-Xrunjdwp:transport=dt_socket,address=127.0.0.1:' + - (await getAvailableServerPort()).toString() + - ',server=y,suspend=n', - ] - : []; +async function _getJavaArgs(debug) { + const baseJavaArgs = ['-classpath', await _getClassPath(), 'com.facebook.nuclide.debugger.JavaDbg', '--vsp']; + const debugArgs = debug ? ['-Xdebug', '-Xrunjdwp:transport=dt_socket,address=127.0.0.1:' + (await (0, (_serverPort || _load_serverPort()).getAvailableServerPort)()).toString() + ',server=y,suspend=n'] : []; return debugArgs.concat(baseJavaArgs); } -async function _getClassPath(): Promise { - const serverJarPath = nuclideUri.join( - __dirname, - 'Build', - 'java_debugger_server.jar', - ); - - if (!(await fsPromise.exists(serverJarPath))) { - throw new Error( - `Could not locate the java debugger server jar: ${serverJarPath}. ` + - 'Please check your Nuclide installation.', - ); +async function _getClassPath() { + const serverJarPath = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, 'Build', 'java_debugger_server.jar'); + + if (!(await (_fsPromise || _load_fsPromise()).default.exists(serverJarPath))) { + throw new Error(`Could not locate the java debugger server jar: ${serverJarPath}. ` + 'Please check your Nuclide installation.'); } // Determining JDK lib path varies by platform. let toolsJarPath; - switch (os.platform()) { + switch (_os.default.platform()) { case 'win32': toolsJarPath = (process.env.JAVA_HOME || '') + '\\lib\\tools.jar'; break; - case 'linux': { - // Find java - const java = (await runCommand('which', ['java']).toPromise()).trim(); - const javaHome = await fsPromise.realpath(java); - - const matches = /(.*)\/java/.exec(javaHome); - toolsJarPath = matches.length > 1 ? matches[1] + '/../lib/tools.jar' : ''; - break; - } + case 'linux': + { + // Find java + const java = (await (0, (_process || _load_process()).runCommand)('which', ['java']).toPromise()).trim(); + const javaHome = await (_fsPromise || _load_fsPromise()).default.realpath(java); + + const matches = /(.*)\/java/.exec(javaHome); + toolsJarPath = matches.length > 1 ? matches[1] + '/../lib/tools.jar' : ''; + break; + } case 'darwin': - default: { - const javaHome = (await runCommand( - '/usr/libexec/java_home', - ).toPromise()).trim(); - toolsJarPath = javaHome + '/lib/tools.jar'; + default: + { + const javaHome = (await (0, (_process || _load_process()).runCommand)('/usr/libexec/java_home').toPromise()).trim(); + toolsJarPath = javaHome + '/lib/tools.jar'; - break; - } + break; + } } - if (!(await fsPromise.exists(toolsJarPath))) { - throw new Error( - `Could not locate required JDK tools jar: ${toolsJarPath}. Is the JDK installed?`, - ); + if (!(await (_fsPromise || _load_fsPromise()).default.exists(toolsJarPath))) { + throw new Error(`Could not locate required JDK tools jar: ${toolsJarPath}. Is the JDK installed?`); } - return nuclideUri.joinPathList([serverJarPath, toolsJarPath]); + return (_nuclideUri || _load_nuclideUri()).default.joinPathList([serverJarPath, toolsJarPath]); } -async function _findJdwpProcess(jvmSuspendArgs: string): Promise { - const commands = await runCommand( - 'ps', - ['-eww', '-o', 'pid,args'], - {}, - ).toPromise(); - - const procs = commands - .toString() - .split('\n') - .filter(line => line.includes(jvmSuspendArgs)); +async function _findJdwpProcess(jvmSuspendArgs) { + const commands = await (0, (_process || _load_process()).runCommand)('ps', ['-eww', '-o', 'pid,args'], {}).toPromise(); + + const procs = commands.toString().split('\n').filter(line => line.includes(jvmSuspendArgs)); const line = procs.length === 1 ? procs[0] : null; return line; } @@ -228,37 +186,23 @@ async function _findJdwpProcess(jvmSuspendArgs: string): Promise { // somewhat arbitrarily chosen value. const MAX_BUFFER_FOR_AAPT_CALL = 512 * 1024 * 1024; -export async function getAndroidSDKVersionFromApk( - apkPath: string, -): Promise { +async function getAndroidSDKVersionFromApk(apkPath) { const androidHome = _getAndroidHomeDir(); - const buildToolsDir = nuclideUri.join(androidHome, 'build-tools'); - if (await fsPromise.exists(buildToolsDir)) { - const subDirs = await fsPromise.readdir(buildToolsDir); + const buildToolsDir = (_nuclideUri || _load_nuclideUri()).default.join(androidHome, 'build-tools'); + if (await (_fsPromise || _load_fsPromise()).default.exists(buildToolsDir)) { + const subDirs = await (_fsPromise || _load_fsPromise()).default.readdir(buildToolsDir); if (subDirs.length !== 0) { - const aaptPath = nuclideUri.join(buildToolsDir, subDirs[0], 'aapt'); - if ( - (await fsPromise.exists(aaptPath)) && - (await fsPromise.exists(apkPath)) - ) { - const aaptListForApk = await runCommand( - aaptPath, - ['list', '-a', apkPath], - {maxBuffer: MAX_BUFFER_FOR_AAPT_CALL}, - ).toPromise(); + const aaptPath = (_nuclideUri || _load_nuclideUri()).default.join(buildToolsDir, subDirs[0], 'aapt'); + if ((await (_fsPromise || _load_fsPromise()).default.exists(aaptPath)) && (await (_fsPromise || _load_fsPromise()).default.exists(apkPath))) { + const aaptListForApk = await (0, (_process || _load_process()).runCommand)(aaptPath, ['list', '-a', apkPath], { maxBuffer: MAX_BUFFER_FOR_AAPT_CALL }).toPromise(); const lines = aaptListForApk.split('\n'); - const targetSdkVersionLines = lines.filter(line => - line.includes('targetSdkVersion'), - ); + const targetSdkVersionLines = lines.filter(line => line.includes('targetSdkVersion')); if (targetSdkVersionLines.length === 1) { const targetSdkVersionLine = targetSdkVersionLines[0]; // targetSdkVersionLine is of the format: // A: android:targetSdkVersion(0x)=(type 0x)0x // so we split by 'x' and take the 4th element - const decimalNumber = parseInt( - targetSdkVersionLine.split('x')[3], - 16, - ); + const decimalNumber = parseInt(targetSdkVersionLine.split('x')[3], 16); if (Number.isInteger(decimalNumber)) { return String(decimalNumber); } @@ -270,48 +214,29 @@ export async function getAndroidSDKVersionFromApk( return ''; } -export async function getSdkVersionSourcePath( - sdkVersion: string, -): Promise { +async function getSdkVersionSourcePath(sdkVersion) { if (Number.isNaN(parseInt(sdkVersion, 10))) { - atom.notifications.addWarning( - 'Unable to find Android Sdk Sources for version: ' + sdkVersion, - ); + atom.notifications.addWarning('Unable to find Android Sdk Sources for version: ' + sdkVersion); return null; } - const sourcesDirectory = nuclideUri.join( - _getAndroidHomeDir(), - 'sources', - 'android-' + sdkVersion, - ); - if (await fsPromise.exists(sourcesDirectory)) { + const sourcesDirectory = (_nuclideUri || _load_nuclideUri()).default.join(_getAndroidHomeDir(), 'sources', 'android-' + sdkVersion); + if (await (_fsPromise || _load_fsPromise()).default.exists(sourcesDirectory)) { return sourcesDirectory; } - const sdkManagerPath = nuclideUri.join( - _getAndroidHomeDir(), - 'tools/bin/sdkmanager', - ); - if (await fsPromise.exists(sdkManagerPath)) { - await runCommand(sdkManagerPath, ['sources;android-' + sdkVersion]); + const sdkManagerPath = (_nuclideUri || _load_nuclideUri()).default.join(_getAndroidHomeDir(), 'tools/bin/sdkmanager'); + if (await (_fsPromise || _load_fsPromise()).default.exists(sdkManagerPath)) { + await (0, (_process || _load_process()).runCommand)(sdkManagerPath, ['sources;android-' + sdkVersion]); // try again - if (await fsPromise.exists(sourcesDirectory)) { + if (await (_fsPromise || _load_fsPromise()).default.exists(sourcesDirectory)) { return sourcesDirectory; } else { - atom.notifications.addWarning( - 'sdkmanager was unable to install android sources. ' + - 'Debugger will be missing Android Sdk Sources.', - ); + atom.notifications.addWarning('sdkmanager was unable to install android sources. ' + 'Debugger will be missing Android Sdk Sources.'); } } else { - atom.notifications.addWarning( - 'sdkmanager not found at: ' + - sdkManagerPath + - '. Please install sdkmanager and try again to get Android SDK source' + - ' information while debugging.', - ); + atom.notifications.addWarning('sdkmanager not found at: ' + sdkManagerPath + '. Please install sdkmanager and try again to get Android SDK source' + ' information while debugging.'); } return null; -} +} \ No newline at end of file diff --git a/modules/atom-ide-debugger-java/JavaDebuggerHelpersServiceProxy.js b/modules/atom-ide-debugger-java/JavaDebuggerHelpersServiceProxy.js new file mode 100644 index 0000000000..0147049468 --- /dev/null +++ b/modules/atom-ide-debugger-java/JavaDebuggerHelpersServiceProxy.js @@ -0,0 +1,594 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + + remoteModule.getPortForJavaDebugger = function () { + return _client.callRemoteFunction("JavaDebuggerHelpersService/getPortForJavaDebugger", "promise", _client.marshalArguments(Array.from(arguments), [])).then(value => { + return _client.unmarshal(value, { + kind: "number" + }); + }); + }; + + remoteModule.getJavaVSAdapterExecutableInfo = function (arg0) { + return _client.callRemoteFunction("JavaDebuggerHelpersService/getJavaVSAdapterExecutableInfo", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "debug", + type: { + kind: "boolean" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "VSAdapterExecutableInfo" + }); + }); + }; + + remoteModule.prepareForTerminalLaunch = function (arg0) { + return _client.callRemoteFunction("JavaDebuggerHelpersService/prepareForTerminalLaunch", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "config", + type: { + kind: "named", + name: "JavaLaunchTargetConfig" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "TerminalLaunchInfo" + }); + }); + }; + + remoteModule.javaDebugWaitForJdwpProcessStart = function (arg0) { + return _client.callRemoteFunction("JavaDebuggerHelpersService/javaDebugWaitForJdwpProcessStart", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "jvmSuspendArgs", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.javaDebugWaitForJdwpProcessExit = function (arg0) { + return _client.callRemoteFunction("JavaDebuggerHelpersService/javaDebugWaitForJdwpProcessExit", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "jvmSuspendArgs", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.getAndroidSDKVersionFromApk = function (arg0) { + return _client.callRemoteFunction("JavaDebuggerHelpersService/getAndroidSDKVersionFromApk", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "apkPath", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }); + }; + + remoteModule.getSdkVersionSourcePath = function (arg0) { + return _client.callRemoteFunction("JavaDebuggerHelpersService/getSdkVersionSourcePath", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "sdkVersion", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "NuclideUri" + } + }); + }); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + JavaLaunchTargetConfig: { + kind: "alias", + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 24 + }, + name: "JavaLaunchTargetConfig", + definition: { + kind: "object", + fields: [{ + name: "debugMode", + type: { + kind: "string-literal", + value: "launch" + }, + optional: false + }, { + name: "entryPointClass", + type: { + kind: "string" + }, + optional: false + }, { + name: "classPath", + type: { + kind: "string" + }, + optional: false + }, { + name: "runArgs", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, + optional: true + }] + } + }, + JavaAttachPortTargetConfig: { + kind: "alias", + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 31 + }, + name: "JavaAttachPortTargetConfig", + definition: { + kind: "object", + fields: [{ + name: "debugMode", + type: { + kind: "string-literal", + value: "attach" + }, + optional: false + }, { + name: "machineName", + type: { + kind: "string" + }, + optional: false + }, { + name: "port", + type: { + kind: "number" + }, + optional: false + }] + } + }, + JavaTargetConfig: { + kind: "alias", + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 37 + }, + name: "JavaTargetConfig", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "debugMode", + type: { + kind: "string-literal", + value: "launch" + }, + optional: false + }, { + name: "entryPointClass", + type: { + kind: "string" + }, + optional: false + }, { + name: "classPath", + type: { + kind: "string" + }, + optional: false + }, { + name: "runArgs", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, + optional: true + }] + }, { + kind: "object", + fields: [{ + name: "debugMode", + type: { + kind: "string-literal", + value: "attach" + }, + optional: false + }, { + name: "machineName", + type: { + kind: "string" + }, + optional: false + }, { + name: "port", + type: { + kind: "number" + }, + optional: false + }] + }], + discriminantField: "debugMode" + } + }, + TerminalLaunchInfo: { + kind: "alias", + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 41 + }, + name: "TerminalLaunchInfo", + definition: { + kind: "object", + fields: [{ + name: "launchCommand", + type: { + kind: "string" + }, + optional: false + }, { + name: "launchCwd", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "targetExecutable", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "launchArgs", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "attachPort", + type: { + kind: "number" + }, + optional: false + }, { + name: "attachHost", + type: { + kind: "string" + }, + optional: false + }] + } + }, + getPortForJavaDebugger: { + kind: "function", + name: "getPortForJavaDebugger", + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 56 + }, + type: { + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 56 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "number" + } + } + } + }, + VSAdapterExecutableInfo: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 38 + }, + name: "VSAdapterExecutableInfo", + definition: { + kind: "object", + fields: [{ + name: "command", + type: { + kind: "string" + }, + optional: false + }, { + name: "args", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: false + }] + } + }, + getJavaVSAdapterExecutableInfo: { + kind: "function", + name: "getJavaVSAdapterExecutableInfo", + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 60 + }, + type: { + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 60 + }, + kind: "function", + argumentTypes: [{ + name: "debug", + type: { + kind: "boolean" + } + }], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "VSAdapterExecutableInfo" + } + } + } + }, + prepareForTerminalLaunch: { + kind: "function", + name: "prepareForTerminalLaunch", + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 69 + }, + type: { + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 69 + }, + kind: "function", + argumentTypes: [{ + name: "config", + type: { + kind: "named", + name: "JavaLaunchTargetConfig" + } + }], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "TerminalLaunchInfo" + } + } + } + }, + javaDebugWaitForJdwpProcessStart: { + kind: "function", + name: "javaDebugWaitForJdwpProcessStart", + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 97 + }, + type: { + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 97 + }, + kind: "function", + argumentTypes: [{ + name: "jvmSuspendArgs", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + javaDebugWaitForJdwpProcessExit: { + kind: "function", + name: "javaDebugWaitForJdwpProcessExit", + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 117 + }, + type: { + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 117 + }, + kind: "function", + argumentTypes: [{ + name: "jvmSuspendArgs", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + getAndroidSDKVersionFromApk: { + kind: "function", + name: "getAndroidSDKVersionFromApk", + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 231 + }, + type: { + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 231 + }, + kind: "function", + argumentTypes: [{ + name: "apkPath", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "string" + } + } + } + }, + getSdkVersionSourcePath: { + kind: "function", + name: "getSdkVersionSourcePath", + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 273 + }, + type: { + location: { + type: "source", + fileName: "JavaDebuggerHelpersService.js", + line: 273 + }, + kind: "function", + argumentTypes: [{ + name: "sdkVersion", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "NuclideUri" + } + } + } + } + } + } +}); \ No newline at end of file diff --git a/modules/atom-ide-debugger-java/SourceFilePathsModal.js b/modules/atom-ide-debugger-java/SourceFilePathsModal.js index 20479d746b..9a264daf79 100644 --- a/modules/atom-ide-debugger-java/SourceFilePathsModal.js +++ b/modules/atom-ide-debugger-java/SourceFilePathsModal.js @@ -1,157 +1,220 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict-local - * @format - */ - -import * as React from 'react'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {ListView, ListViewItem} from 'nuclide-commons-ui/ListView'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; -import {Button, ButtonTypes} from 'nuclide-commons-ui/Button'; -import nullthrows from 'nullthrows'; -import {track} from 'nuclide-commons/analytics'; - -type Props = { - initialSourcePaths: Array, - sourcePathsChanged: (Array) => void, - onClosed: () => void, -}; - -type State = { - currentPaths: Array, -}; - -export class SourceFilePathsModal extends React.Component { - _newSourcePath: ?AtomInput; - _savedSourcePaths: Array = []; - state = { - currentPaths: this.props.initialSourcePaths.slice(0), - }; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SourceFilePathsModal = undefined; + +var _react = _interopRequireWildcard(require('react')); + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../nuclide-commons-ui/AtomInput'); +} + +var _ListView; + +function _load_ListView() { + return _ListView = require('../nuclide-commons-ui/ListView'); +} + +var _ButtonGroup; + +function _load_ButtonGroup() { + return _ButtonGroup = require('../nuclide-commons-ui/ButtonGroup'); +} + +var _Button; + +function _load_Button() { + return _Button = require('../nuclide-commons-ui/Button'); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _analytics; + +function _load_analytics() { + return _analytics = 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; } } + +class SourceFilePathsModal extends _react.Component { + constructor(...args) { + var _temp; + + return _temp = super(...args), this._savedSourcePaths = [], this.state = { + currentPaths: this.props.initialSourcePaths.slice(0) + }, this._addItem = () => { + const text = (0, (_nullthrows || _load_nullthrows()).default)(this._newSourcePath).getText().trim().replace(/;/g, ''); // Do not allow semicolons since we are using them + // to delimit paths. TODO: handle paths that actually contain ;'s? + + if (text !== '') { + this.state.currentPaths.push(text); + (0, (_nullthrows || _load_nullthrows()).default)(this._newSourcePath).setText(''); + this.setState({ + currentPaths: this.state.currentPaths + }); + } + }, this._cancelClick = () => { + this.setState({ + currentPaths: this._savedSourcePaths + }); + this.props.onClosed(); + (0, (_analytics || _load_analytics()).track)('fb-java-debugger-source-dialog-cancel', {}); + }, this._handleSaveClick = () => { + this._addItem(); + this._savedSourcePaths = this.state.currentPaths.slice(0); + this.props.sourcePathsChanged(this._savedSourcePaths); + this.props.onClosed(); + (0, (_analytics || _load_analytics()).track)('fb-java-debugger-source-dialog-saved', {}); + }, _temp; + } _getSourcePathControls() { const items = []; const paths = Array.from(new Set(this.state.currentPaths)); if (paths.length === 0) { - return [ - -
- (No custom source file paths have been specified) -
-
, - ]; + return [_react.createElement( + (_ListView || _load_ListView()).ListViewItem, + { key: 0, index: 0 }, + _react.createElement( + 'div', + null, + _react.createElement( + 'i', + null, + '(No custom source file paths have been specified)' + ) + ) + )]; } paths.forEach((path, idx) => { - items.push( - -
- { - this.state.currentPaths.splice(idx, 1); - this.setState({ - currentPaths: this.state.currentPaths, - }); - }} - /> - {path} -
-
, - ); + items.push(_react.createElement( + (_ListView || _load_ListView()).ListViewItem, + { key: idx, index: idx }, + _react.createElement( + 'div', + { className: 'block' }, + _react.createElement('i', { + className: 'icon icon-x nuclide-source-content-x', + title: 'Remove path', + onClick: () => { + this.state.currentPaths.splice(idx, 1); + this.setState({ + currentPaths: this.state.currentPaths + }); + } + }), + _react.createElement( + 'span', + null, + path + ) + ) + )); }); return items; } - _addItem = () => { - const text = nullthrows(this._newSourcePath) - .getText() - .trim() - .replace(/;/g, ''); // Do not allow semicolons since we are using them - // to delimit paths. TODO: handle paths that actually contain ;'s? - - if (text !== '') { - this.state.currentPaths.push(text); - nullthrows(this._newSourcePath).setText(''); - this.setState({ - currentPaths: this.state.currentPaths, - }); - } - }; - - render(): React.Node { + render() { const sourcePaths = this._getSourcePathControls(); - return ( -
-
-

Configure source file paths:

-
- - Nuclide will automatically search for source in your project root - paths. You can add additional search paths here. - -
-
- { - this._newSourcePath = input; - }} - initialValue="" - autofocus={true} - placeholderText="Add a source file path..." - /> - -
-
- {sourcePaths} -
-
-
- - - - -
-
+ return _react.createElement( + 'div', + { className: 'sourcepath-modal' }, + _react.createElement( + 'div', + { className: 'select-list' }, + _react.createElement( + 'h2', + null, + 'Configure source file paths:' + ), + _react.createElement( + 'div', + { className: 'nuclide-source-add-content' }, + _react.createElement( + 'span', + null, + 'Nuclide will automatically search for source in your project root paths. You can add additional search paths here.' + ) + ), + _react.createElement( + 'div', + { className: 'sourcepath-add-bar' }, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + className: 'sourcepath-pane', + ref: input => { + this._newSourcePath = input; + }, + initialValue: '', + autofocus: true, + placeholderText: 'Add a source file path...' + }), + _react.createElement( + (_Button || _load_Button()).Button, + { + onClick: this._addItem, + title: 'Add Path', + className: 'sourcepath-add-button' }, + _react.createElement('i', { className: 'icon icon-plus' }) + ) + ), + _react.createElement( + 'div', + { className: 'sourcepath-sources' }, + _react.createElement( + (_ListView || _load_ListView()).ListView, + { alternateBackground: true }, + sourcePaths + ) + ) + ), + _react.createElement( + 'div', + { + className: 'sourcepath-buttons', + style: { display: 'flex', flexDirection: 'row-reverse' } }, + _react.createElement( + (_ButtonGroup || _load_ButtonGroup()).ButtonGroup, + null, + _react.createElement( + (_Button || _load_Button()).Button, + { tabIndex: '17', onClick: this._cancelClick }, + 'Cancel' + ), + _react.createElement( + (_Button || _load_Button()).Button, + { + buttonType: (_Button || _load_Button()).ButtonTypes.PRIMARY, + tabIndex: '16', + onClick: this._handleSaveClick }, + 'Save' + ) + ) + ) ); } - _cancelClick = (): void => { - this.setState({ - currentPaths: this._savedSourcePaths, - }); - this.props.onClosed(); - track('fb-java-debugger-source-dialog-cancel', {}); - }; - - _handleSaveClick = (): void => { - this._addItem(); - this._savedSourcePaths = this.state.currentPaths.slice(0); - this.props.sourcePathsChanged(this._savedSourcePaths); - this.props.onClosed(); - track('fb-java-debugger-source-dialog-saved', {}); - }; } +exports.SourceFilePathsModal = SourceFilePathsModal; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-debugger-java/main.js b/modules/atom-ide-debugger-java/main.js index 68cf69eb3e..a9b5c9e9f4 100644 --- a/modules/atom-ide-debugger-java/main.js +++ b/modules/atom-ide-debugger-java/main.js @@ -1,3 +1,31 @@ +'use strict'; + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../nuclide-commons-atom/createPackage')); +} + +var _nuclideDebuggerCommon; + +function _load_nuclideDebuggerCommon() { + return _nuclideDebuggerCommon = require('../nuclide-debugger-common'); +} + +var _AutoGenLaunchAttachProvider; + +function _load_AutoGenLaunchAttachProvider() { + return _AutoGenLaunchAttachProvider = require('../nuclide-debugger-common/AutoGenLaunchAttachProvider'); +} + +var _utils; + +function _load_utils() { + return _utils = require('./utils'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,57 +34,37 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type { - NuclideDebuggerProvider, - DebuggerConfigurationProvider, -} from 'nuclide-debugger-common/types'; -import type {DebuggerSourcePathsService} from './types'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import {VsAdapterTypes} from 'nuclide-debugger-common'; -import {AutoGenLaunchAttachProvider} from 'nuclide-debugger-common/AutoGenLaunchAttachProvider'; -import { - getJavaConfig, - setRpcService, - resolveConfiguration, - setSourcePathsService, -} from './utils'; - class Activation { constructor() {} dispose() {} - createDebuggerProvider(): NuclideDebuggerProvider { + createDebuggerProvider() { return { - type: VsAdapterTypes.JAVA, + type: (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsAdapterTypes.JAVA, getLaunchAttachProvider: connection => { - return new AutoGenLaunchAttachProvider( - 'Java - Desktop', - connection, - getJavaConfig(), - ); - }, + return new (_AutoGenLaunchAttachProvider || _load_AutoGenLaunchAttachProvider()).AutoGenLaunchAttachProvider('Java - Desktop', connection, (0, (_utils || _load_utils()).getJavaConfig)()); + } }; } - createDebuggerConfigurator(): DebuggerConfigurationProvider { + createDebuggerConfigurator() { return { - resolveConfiguration, - adapterType: VsAdapterTypes.JAVA, + resolveConfiguration: (_utils || _load_utils()).resolveConfiguration, + adapterType: (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsAdapterTypes.JAVA }; } - consumeRpcService(rpcService: nuclide$RpcService): IDisposable { - return setRpcService(rpcService); + consumeRpcService(rpcService) { + return (0, (_utils || _load_utils()).setRpcService)(rpcService); } - consumeSourcePathsService(sourcePathsService: DebuggerSourcePathsService) { - return setSourcePathsService(sourcePathsService); + consumeSourcePathsService(sourcePathsService) { + return (0, (_utils || _load_utils()).setSourcePathsService)(sourcePathsService); } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/modules/atom-ide-debugger-java/spec/fixtures/java/SimpleClass.java b/modules/atom-ide-debugger-java/spec/fixtures/java/SimpleClass.java deleted file mode 100644 index c7d401a02d..0000000000 --- a/modules/atom-ide-debugger-java/spec/fixtures/java/SimpleClass.java +++ /dev/null @@ -1,29 +0,0 @@ -public class SimpleClass { - private String name; - private int id; - - public static void main(String[] args) { - String name = "Not Aman Agarwal"; - int id = 1234567890; - SimpleClass tc = new SimpleClass(name, id); - tc.print(); - tc.setName("Definitely Not Aman Agarwal"); - tc.print(); - tc.setName("You got me, it's Aman Agarwal"); - tc.print(); - } - - public SimpleClass(String name, int id) { - this.name = name; - this.id = id; - } - - public SimpleClass setName(String newName) { - name = newName; - return this; - } - - public void print() { - System.out.println("Name: " + name + " with id: " + id); - } -} diff --git a/modules/atom-ide-debugger-java/spec/vscode-java-debugger-spec.js b/modules/atom-ide-debugger-java/spec/vscode-java-debugger-spec.js deleted file mode 100644 index 6fd53aa5c8..0000000000 --- a/modules/atom-ide-debugger-java/spec/vscode-java-debugger-spec.js +++ /dev/null @@ -1,387 +0,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. - * - * @flow - * @format - */ - -import {getLogger} from 'log4js'; -import * as DebugProtocol from 'vscode-debugprotocol'; -import * as fs from 'fs'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {runCommand} from 'nuclide-commons/process'; -import VsDebugSession from 'nuclide-debugger-common/VsDebugSession'; -import {getJavaVSAdapterExecutableInfo} from '../JavaDebuggerHelpersService'; - -const logger = getLogger('vscode-java-debugger-spec'); -const JAVA_FIXTURES = nuclideUri.join(__dirname, 'fixtures', 'java'); -const THREAD_ID = 1; -const JAVA_DEBUGGER_PKG = nuclideUri.join(__dirname, '..'); - -function makeSource(name: string): DebugProtocol.Source { - return { - name, - path: nuclideUri.join(JAVA_FIXTURES, name), - }; -} - -async function checkResponse( - responsePromise: Promise, - additionalValidation?: T => void, -): Promise { - const response = await responsePromise; - expect(response.success).toBeTruthy( - `Expected successful response, got ${JSON.stringify(response)}`, - ); - - if (additionalValidation != null) { - additionalValidation(response); - } - - return response; -} - -async function checkLine( - session: VsDebugSession, - expectedLine: number, -): Promise { - await checkResponse(session.stackTrace({threadId: THREAD_ID}), response => { - expect(response.body.stackFrames[0].line).toBe(expectedLine); - }); -} - -async function withSessionLaunch( - className: string, - breakpoints?: DebugProtocol.SetBreakpointsArguments, - sessionContinuation: (VsDebugSession, any) => Promise, -): Promise { - let session = null; - try { - session = new VsDebugSession( - process.pid.toString(), - logger, - await getJavaVSAdapterExecutableInfo(false), - ); - await checkResponse( - session.initialize({ - adapterID: 'java', - clientID: 'Nuclide-Spec', - columnsStartAt1: true, - linesStartAt1: true, - pathFormat: 'path', - }), - ); - - await Promise.all([ - checkResponse( - session.launch({ - classPath: JAVA_FIXTURES, - entryPointClass: className, - }), - ), - session - .observeThreadEvents() - .take(4) - .toPromise(), - session - .observeInitializeEvents() - .take(1) - .toPromise(), - ]); - - await checkResponse(session.setExceptionBreakpoints({filters: []})); - - let unverifiedBreakpoints = []; - if (breakpoints != null) { - await checkResponse(session.setBreakpoints(breakpoints), response => { - unverifiedBreakpoints = response.body.breakpoints.filter( - bp => !bp.verified, - ); - }); - } - - await checkResponse(session.configurationDone()); - - await session - .observeContinuedEvents() - .take(1) - .toPromise(); - - await sessionContinuation(session, unverifiedBreakpoints); - } catch (error) { - logger.error('error in withSessionLaunch', error, error.stack); - throw error; - } finally { - if (session != null) { - session.dispose(); - } - } -} - -async function continueSession(session: VsDebugSession): Promise { - await Promise.all([ - session - .observeContinuedEvents() - .take(1) - .toPromise(), - checkResponse(session.continue({threadId: THREAD_ID})), - ]); -} - -async function verifyUnverifiedBreakpoints( - session: VsDebugSession, - unverifiedBreakpoints: any, -): Promise { - if (unverifiedBreakpoints.length > 0) { - let allBreakpointsVerified = false; - await session - .observeBreakpointEvents() - .take(unverifiedBreakpoints.length) - .toArray() - .toPromise() - .then(result => (allBreakpointsVerified = true)); - - expect(allBreakpointsVerified).toBeTruthy( - `The following breakpoints could not be set: ${JSON.stringify( - unverifiedBreakpoints, - )}`, - ); - } -} - -// eslint-disable-next-line jasmine/no-disabled-tests -xdescribe('vscode-java-debugger', () => { - let hasDoneSetup = false; - beforeEach(() => { - waitsForPromise({timeout: 120000}, async () => { - if (hasDoneSetup) { - return; - } - - await runCommand('env', ['-u', 'NO_BUCKD', './scripts/build'], { - cwd: JAVA_DEBUGGER_PKG, - }).toPromise(); - - const javaFiles = await new Promise((resolve, reject) => { - fs.readdir(JAVA_FIXTURES, (err, files) => { - if (err) { - reject(err); - } - - resolve(files.filter(file => file.endsWith('.java'))); - }); - }); - - await Promise.all( - javaFiles.map(file => - runCommand('javac', ['-g', file], {cwd: JAVA_FIXTURES}).toPromise(), - ), - ); - - hasDoneSetup = true; - }); - }); - - afterEach(() => { - // The java debugger, when it launches a script, uses a port. We need to - // wait between each test case to give the system a moment to realize - // that the port has been free'd up. - waits(2000); - }); - - it('launches and outputs console messages', () => { - waitsForPromise({timeout: 10000}, async () => { - await withSessionLaunch( - 'SimpleClass', - { - source: makeSource('SimpleClass.java'), - breakpoints: [{line: 11}], - }, - async (session, unverifiedBreakpoints) => { - await session - .observeOutputEvents() - .filter(response => response.body.category === 'stdout') - .map(response => response.body.output) - .take(1) - .toPromise() - .then(output => { - expect(output).toEqual( - 'Name: Not Aman Agarwal with id: 1234567890\n', - ); - }); - }, - ); - }); - }); - - it('breaks at a breakpoint', () => { - waitsForPromise({timeout: 10000}, async () => { - await withSessionLaunch( - 'SimpleClass', - { - source: makeSource('SimpleClass.java'), - breakpoints: [{line: 11}], - }, - async (session, unverifiedBreakpoints) => { - await verifyUnverifiedBreakpoints(session, unverifiedBreakpoints); - - await session - .observeStopEvents() - .take(1) - .toPromise(); - - await checkLine(session, 11); - }, - ); - }); - }); - - it('sets multiple breakpoints', () => { - waitsForPromise({timeout: 10000}, async () => { - await withSessionLaunch( - 'SimpleClass', - { - source: makeSource('SimpleClass.java'), - breakpoints: [{line: 8}, {line: 23}], - }, - async (session, unverifiedBreakpoints) => { - await verifyUnverifiedBreakpoints(session, unverifiedBreakpoints); - - await session - .observeStopEvents() - .take(1) - .toPromise(); - await checkLine(session, 8); - - await continueSession(session); - - await session - .observeStopEvents() - .take(1) - .toPromise(); - await checkLine(session, 23); - }, - ); - }); - }); - - it('supports step-over, step-in, and step-out', () => { - waitsForPromise({timeout: 10000}, async () => { - await withSessionLaunch( - 'SimpleClass', - { - source: makeSource('SimpleClass.java'), - breakpoints: [{line: 11}], - }, - async (session, unverifiedBreakpoints) => { - await verifyUnverifiedBreakpoints(session, unverifiedBreakpoints); - - await session - .observeStopEvents() - .take(1) - .toPromise(); - await checkLine(session, 11); - - await checkResponse(session.next({threadId: THREAD_ID})); - await checkLine(session, 12); - - await checkResponse(session.stepIn({threadId: THREAD_ID})); - await checkLine(session, 22); - - await checkResponse(session.stepOut({threadId: THREAD_ID})); - await checkLine(session, 12); - }, - ); - }); - }); - - it('evaluates expressions', () => { - waitsForPromise({timeout: 10000}, async () => { - await withSessionLaunch( - 'SimpleClass', - { - source: makeSource('SimpleClass.java'), - breakpoints: [{line: 11}], - }, - async (session, unverifiedBreakpoints) => { - await verifyUnverifiedBreakpoints(session, unverifiedBreakpoints); - - await session - .observeStopEvents() - .take(1) - .toPromise(); - await checkLine(session, 11); - - const frameId = (await checkResponse( - session.stackTrace({threadId: THREAD_ID}), - )).body.stackFrames[0].id; - await checkResponse( - session.evaluate({expression: 'tc', frameId}), - response => { - // we do not check the exact id of the class because any changes made in the class - // preparation code causes this id to change, I may add the id back into the test - // once the Java debugger codebase has stabilized - expect( - response.body.result.includes( - 'class SimpleClass (loaded by instance of sun.misc.Launcher$AppClassLoader(id=', - ), - ).toBeTruthy(); - }, - ); - }, - ); - }); - }); - - it('checks threads', () => { - waitsForPromise({timeout: 10000}, async () => { - await withSessionLaunch( - 'SimpleClass', - { - source: makeSource('SimpleClass.java'), - breakpoints: [{line: 11}], - }, - async (session, unverifiedBreakpoints) => { - await verifyUnverifiedBreakpoints(session, unverifiedBreakpoints); - - await session - .observeStopEvents() - .take(1) - .toPromise(); - - await checkLine(session, 11); - - await checkResponse(session.threads(), response => { - const {threads} = response.body; - expect(threads.length).toEqual(4); - const threadNames = new Set(threads.map(t => t.name)); - const THREAD_NAMES = [ - 'Signal Dispatcher', - 'Finalizer', - 'Reference Handler', - 'main', - ]; - expect( - THREAD_NAMES.every(name => { - const foundThread = threadNames.has(name); - expect(foundThread).toBeTruthy( - 'Could not find thread with name: ' + name, - ); - return foundThread; - }), - ).toBeTruthy('We are missing some threads'); - expect( - threads.filter(t => t.name === 'main' && t.id === 1).length, - ).toBe(1, 'Main thread not found with correct id'); - }); - }, - ); - }); - }); - // end -}); diff --git a/modules/atom-ide-debugger-java/types.js b/modules/atom-ide-debugger-java/types.js index 415a4319cb..a726efc43f 100644 --- a/modules/atom-ide-debugger-java/types.js +++ b/modules/atom-ide-debugger-java/types.js @@ -1,30 +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 strict-local - * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -export type SuggestedProjectPath = { - projectPath: NuclideUri, - suggested: boolean, - hostLabel: string, -}; - -export interface DebuggerSourcePathsService { - addKnownSubdirectoryPaths( - remote: boolean, - translatedPath: string, - searchPaths: Array, - ): void; - observeSuggestedAndroidProjectPaths( - callback: (Array) => void, - ): IDisposable; -} +'use strict'; \ No newline at end of file diff --git a/modules/atom-ide-debugger-java/utils.js b/modules/atom-ide-debugger-java/utils.js index 1b10adc46b..ba4ff6e5fc 100644 --- a/modules/atom-ide-debugger-java/utils.js +++ b/modules/atom-ide-debugger-java/utils.js @@ -1,3 +1,85 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.NUCLIDE_DEBUGGER_DEV_GK = undefined; +exports.getJavaConfig = getJavaConfig; +exports.getCustomControlButtonsForJavaSourcePaths = getCustomControlButtonsForJavaSourcePaths; +exports.getDefaultSourceSearchPaths = getDefaultSourceSearchPaths; +exports.getSavedPathsFromConfig = getSavedPathsFromConfig; +exports.persistSourcePathsToConfig = persistSourcePathsToConfig; +exports.getDialogValues = getDialogValues; +exports.getSourcePathString = getSourcePathString; +exports.getSourcePathClickSubscriptionsOnVspInstance = getSourcePathClickSubscriptionsOnVspInstance; +exports.getSourcePathClickSubscriptions = getSourcePathClickSubscriptions; +exports.resolveConfiguration = resolveConfiguration; +exports.setSourcePathsService = setSourcePathsService; +exports.setRpcService = setRpcService; +exports.getJavaDebuggerHelpersServiceByNuclideUri = getJavaDebuggerHelpersServiceByNuclideUri; + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../nuclide-commons-atom/feature-config')); +} + +var _showModal; + +function _load_showModal() { + return _showModal = _interopRequireDefault(require('../nuclide-commons-ui/showModal')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../nuclide-commons/nuclideUri')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _react = _interopRequireWildcard(require('react')); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../nuclide-commons/UniversalDisposable')); +} + +var _constants; + +function _load_constants() { + return _constants = require('../nuclide-debugger-common/constants'); +} + +var _JavaDebuggerHelpersService; + +function _load_JavaDebuggerHelpersService() { + return _JavaDebuggerHelpersService = _interopRequireWildcard(require('./JavaDebuggerHelpersService')); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _SourceFilePathsModal; + +function _load_SourceFilePathsModal() { + return _SourceFilePathsModal = require('./SourceFilePathsModal'); +} + +var _analytics; + +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. @@ -6,115 +88,78 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type {ISession} from 'atom-ide-ui/pkg/atom-ide-debugger/lib/types'; -import type { - AutoGenConfig, - IProcessConfig, - ControlButtonSpecification, - IVspInstance, -} from 'nuclide-debugger-common/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {DebuggerSourcePathsService} from './types'; - -import typeof * as JavaDebuggerHelpersService from './JavaDebuggerHelpersService'; - -import featureConfig from 'nuclide-commons-atom/feature-config'; -import showModal from 'nuclide-commons-ui/showModal'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Subject, Observable} from 'rxjs'; -import * as React from 'react'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {VsAdapterTypes} from 'nuclide-debugger-common/constants'; -import * as JavaDebuggerHelpersServiceLocal from './JavaDebuggerHelpersService'; -import nullthrows from 'nullthrows'; -import {SourceFilePathsModal} from './SourceFilePathsModal'; -import {track} from 'nuclide-commons/analytics'; - -let _sourcePathsService: ?DebuggerSourcePathsService; -let _rpcService: ?nuclide$RpcService = null; - -export const NUCLIDE_DEBUGGER_DEV_GK = 'nuclide_debugger_dev'; - -export function getJavaConfig(): AutoGenConfig { +let _sourcePathsService; +let _rpcService = null; + +const NUCLIDE_DEBUGGER_DEV_GK = exports.NUCLIDE_DEBUGGER_DEV_GK = 'nuclide_debugger_dev'; + +function getJavaConfig() { const entryPointClass = { name: 'entryPointClass', type: 'string', description: 'Input the Java entry point name you want to launch', required: true, - visible: true, + visible: true }; const classPath = { name: 'classPath', type: 'string', description: 'Java class path', required: true, - visible: true, + visible: true }; const javaJdwpPort = { name: 'javaJdwpPort', type: 'number', description: 'Java debugger port', required: true, - visible: true, + visible: true }; return { launch: { launch: true, - vsAdapterType: VsAdapterTypes.JAVA, + vsAdapterType: (_constants || _load_constants()).VsAdapterTypes.JAVA, threads: true, properties: [entryPointClass, classPath], cwdPropertyName: 'cwd', - header: null, + header: null }, attach: { launch: false, - vsAdapterType: VsAdapterTypes.JAVA, + vsAdapterType: (_constants || _load_constants()).VsAdapterTypes.JAVA, threads: true, properties: [javaJdwpPort], - header: null, - }, + header: null + } }; } -export function getCustomControlButtonsForJavaSourcePaths( - clickEvents: rxjs$Subject, -): ControlButtonSpecification[] { - return [ - { - icon: 'file-code', - title: 'Set Source Path', - onClick: () => clickEvents.next(), - }, - ]; +function getCustomControlButtonsForJavaSourcePaths(clickEvents) { + return [{ + icon: 'file-code', + title: 'Set Source Path', + onClick: () => clickEvents.next() + }]; } -export function getDefaultSourceSearchPaths( - targetUri: NuclideUri, -): Array { - const searchPaths: Array = []; - const remote = nuclideUri.isRemote(targetUri); +function getDefaultSourceSearchPaths(targetUri) { + const searchPaths = []; + const remote = (_nuclideUri || _load_nuclideUri()).default.isRemote(targetUri); // Add all the project root paths as potential source locations the Java debugger server should // check for resolving source. // NOTE: the Java debug server will just ignore any directory path that doesn't exist. atom.project.getPaths().forEach(path => { - if ( - (remote && nuclideUri.isRemote(path)) || - (!remote && nuclideUri.isLocal(path)) - ) { - const translatedPath = remote ? nuclideUri.getPath(path) : path; + if (remote && (_nuclideUri || _load_nuclideUri()).default.isRemote(path) || !remote && (_nuclideUri || _load_nuclideUri()).default.isLocal(path)) { + const translatedPath = remote ? (_nuclideUri || _load_nuclideUri()).default.getPath(path) : path; searchPaths.push(translatedPath); if (_sourcePathsService != null) { - _sourcePathsService.addKnownSubdirectoryPaths( - remote, - translatedPath, - searchPaths, - ); + _sourcePathsService.addKnownSubdirectoryPaths(remote, translatedPath, searchPaths); } } }); @@ -122,48 +167,36 @@ export function getDefaultSourceSearchPaths( return searchPaths; } -export function getSavedPathsFromConfig(): Array { - const paths = featureConfig.get('nuclide-debugger-java.sourceFilePaths'); +function getSavedPathsFromConfig() { + const paths = (_featureConfig || _load_featureConfig()).default.get('nuclide-debugger-java.sourceFilePaths'); // flowlint-next-line sketchy-null-mixed:off if (paths && typeof paths === 'string') { - return (paths: string).split(';'); + return paths.split(';'); } else { - featureConfig.set('nuclide-debugger-java.sourceFilePaths', ''); + (_featureConfig || _load_featureConfig()).default.set('nuclide-debugger-java.sourceFilePaths', ''); } return []; } -export function persistSourcePathsToConfig( - newSourcePaths: Array, -): void { - featureConfig.set( - 'nuclide-debugger-java.sourceFilePaths', - newSourcePaths.join(';'), - ); +function persistSourcePathsToConfig(newSourcePaths) { + (_featureConfig || _load_featureConfig()).default.set('nuclide-debugger-java.sourceFilePaths', newSourcePaths.join(';')); } -export function getDialogValues( - clickEvents: rxjs$Subject, -): rxjs$Observable> { +function getDialogValues(clickEvents) { let userSourcePaths = getSavedPathsFromConfig(); return clickEvents.switchMap(() => { - return Observable.create(observer => { - const modalDisposable = showModal( - ({dismiss}) => ( - ) => { - userSourcePaths = newPaths; - persistSourcePathsToConfig(newPaths); - observer.next(newPaths); - }} - onClosed={dismiss} - /> - ), - {className: 'sourcepath-modal-container'}, - ); - - track('fb-java-debugger-source-dialog-shown'); + return _rxjsBundlesRxMinJs.Observable.create(observer => { + const modalDisposable = (0, (_showModal || _load_showModal()).default)(({ dismiss }) => _react.createElement((_SourceFilePathsModal || _load_SourceFilePathsModal()).SourceFilePathsModal, { + initialSourcePaths: userSourcePaths, + sourcePathsChanged: newPaths => { + userSourcePaths = newPaths; + persistSourcePathsToConfig(newPaths); + observer.next(newPaths); + }, + onClosed: dismiss + }), { className: 'sourcepath-modal-container' }); + + (0, (_analytics || _load_analytics()).track)('fb-java-debugger-source-dialog-shown'); return () => { modalDisposable.dispose(); }; @@ -171,106 +204,67 @@ export function getDialogValues( }); } -export function getSourcePathString(searchPaths: Array): string { +function getSourcePathString(searchPaths) { return searchPaths.join(';'); } -export function getSourcePathClickSubscriptionsOnVspInstance( - targetUri: NuclideUri, - vspInstance: IVspInstance, - clickEvents: rxjs$Subject, -): ((() => mixed) | rxjs$ISubscription | IDisposable)[] { +function getSourcePathClickSubscriptionsOnVspInstance(targetUri, vspInstance, clickEvents) { const defaultValues = getDefaultSourceSearchPaths(targetUri); - return [ - getDialogValues(clickEvents) - .startWith(getSavedPathsFromConfig()) - .subscribe(userValues => { - vspInstance.customRequest('setSourcePath', { - sourcePath: getSourcePathString(defaultValues.concat(userValues)), - }); - }), - clickEvents, - ]; + return [getDialogValues(clickEvents).startWith(getSavedPathsFromConfig()).subscribe(userValues => { + vspInstance.customRequest('setSourcePath', { + sourcePath: getSourcePathString(defaultValues.concat(userValues)) + }); + }), clickEvents]; } -export function getSourcePathClickSubscriptions( - targetUri: NuclideUri, - debugSession: ISession, - clickEvents: rxjs$Subject, - additionalSourcePaths?: Array = [], -): ((() => mixed) | rxjs$ISubscription | IDisposable)[] { - const defaultValues = getDefaultSourceSearchPaths(targetUri).concat( - additionalSourcePaths, - ); - return [ - getDialogValues(clickEvents) - .startWith(getSavedPathsFromConfig()) - .subscribe(userValues => { - debugSession.custom('setSourcePath', { - sourcePath: getSourcePathString(defaultValues.concat(userValues)), - }); - }), - clickEvents, - ]; +function getSourcePathClickSubscriptions(targetUri, debugSession, clickEvents, additionalSourcePaths = []) { + const defaultValues = getDefaultSourceSearchPaths(targetUri).concat(additionalSourcePaths); + return [getDialogValues(clickEvents).startWith(getSavedPathsFromConfig()).subscribe(userValues => { + debugSession.custom('setSourcePath', { + sourcePath: getSourcePathString(defaultValues.concat(userValues)) + }); + }), clickEvents]; } -export async function resolveConfiguration( - configuration: IProcessConfig, -): Promise { - const {adapterExecutable, targetUri} = configuration; +async function resolveConfiguration(configuration) { + const { adapterExecutable, targetUri } = configuration; if (adapterExecutable == null) { throw new Error('Cannot resolve configuration for unset adapterExecutable'); } - const subscriptions = new UniversalDisposable(); - const clickEvents = new Subject(); - const customDisposable = - configuration.customDisposable || new UniversalDisposable(); + const subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + const clickEvents = new _rxjsBundlesRxMinJs.Subject(); + const customDisposable = configuration.customDisposable || new (_UniversalDisposable || _load_UniversalDisposable()).default(); customDisposable.add(subscriptions); - const javaAdapterExecutable = await getJavaDebuggerHelpersServiceByNuclideUri( - targetUri, - ).getJavaVSAdapterExecutableInfo(false); - return { - ...configuration, - properties: { - ...configuration.properties, - customControlButtons: getCustomControlButtonsForJavaSourcePaths( - clickEvents, - ), - }, + const javaAdapterExecutable = await getJavaDebuggerHelpersServiceByNuclideUri(targetUri).getJavaVSAdapterExecutableInfo(false); + return Object.assign({}, configuration, { + properties: Object.assign({}, configuration.properties, { + customControlButtons: getCustomControlButtonsForJavaSourcePaths(clickEvents) + }), adapterExecutable: javaAdapterExecutable, customDisposable, onInitializeCallback: async session => { - customDisposable.add( - ...getSourcePathClickSubscriptions(targetUri, session, clickEvents), - ); - }, - }; + customDisposable.add(...getSourcePathClickSubscriptions(targetUri, session, clickEvents)); + } + }); } -export function setSourcePathsService( - sourcePathsService: DebuggerSourcePathsService, -) { +function setSourcePathsService(sourcePathsService) { _sourcePathsService = sourcePathsService; } -export function setRpcService(rpcService: nuclide$RpcService): IDisposable { +function setRpcService(rpcService) { _rpcService = rpcService; - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { _rpcService = null; }); } -export function getJavaDebuggerHelpersServiceByNuclideUri( - uri: NuclideUri, -): JavaDebuggerHelpersService { - if (_rpcService == null && !nuclideUri.isRemote(uri)) { - return JavaDebuggerHelpersServiceLocal; +function getJavaDebuggerHelpersServiceByNuclideUri(uri) { + if (_rpcService == null && !(_nuclideUri || _load_nuclideUri()).default.isRemote(uri)) { + return _JavaDebuggerHelpersService || _load_JavaDebuggerHelpersService(); } - return nullthrows(_rpcService).getServiceByNuclideUri( - 'JavaDebuggerHelpersService', - uri, - ); -} + return (0, (_nullthrows || _load_nullthrows()).default)(_rpcService).getServiceByNuclideUri('JavaDebuggerHelpersService', uri); +} \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/DEVELOPMENT b/modules/atom-ide-debugger-native-gdb/DEVELOPMENT deleted file mode 100644 index e27a0b58b0..0000000000 --- a/modules/atom-ide-debugger-native-gdb/DEVELOPMENT +++ /dev/null @@ -1,3 +0,0 @@ -This file exists to indicate that the source should be transpiled. - -During publishing, all files are pre-transpiled and this file is ignored. diff --git a/modules/atom-ide-debugger-native-gdb/lib/Breakpoints.js b/modules/atom-ide-debugger-native-gdb/lib/Breakpoints.js index 512270a769..e8e114ed1b 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/Breakpoints.js +++ b/modules/atom-ide-debugger-native-gdb/lib/Breakpoints.js @@ -1,31 +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 HandleMap from './HandleMap'; - -export class Breakpoint { - _id: ?number; - _source: ?string; - _line: ?number; - _condition: ?string; - _verified: boolean; - - constructor( - id: ?number, - source: ?string, - line: ?number, - condition: ?string, - verified: boolean, - ) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Breakpoint = undefined; + +var _HandleMap; + +function _load_HandleMap() { + return _HandleMap = _interopRequireDefault(require('./HandleMap')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Breakpoint { + + constructor(id, source, line, condition, verified) { this._id = id; this._source = source; this._line = line; @@ -33,63 +23,75 @@ export class Breakpoint { this._verified = verified; } - get id(): ?number { + get id() { return this._id; } - setId(n: number): void { + setId(n) { this._id = n; } - get source(): ?string { + get source() { return this._source; } - get line(): ?number { + get line() { return this._line; } - get condition(): ?string { + get condition() { return this._condition; } - get verified(): boolean { + get verified() { return this._verified; } - setVerified(): void { + setVerified() { this._verified = true; } } -export default class Breakpoints { - _breakpoints: HandleMap; +exports.Breakpoint = Breakpoint; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 Breakpoints { constructor() { - this._breakpoints = new HandleMap(); + this._breakpoints = new (_HandleMap || _load_HandleMap()).default(); } - addBreakpoint(bkpt: Breakpoint): number { + addBreakpoint(bkpt) { return this._breakpoints.put(bkpt); } - removeBreakpoint(bkpt: Breakpoint): void { + removeBreakpoint(bkpt) { this._breakpoints.removeObject(bkpt); } - handleForBreakpoint(bkpt: Breakpoint): ?number { + handleForBreakpoint(bkpt) { return this._breakpoints.getHandleByObject(bkpt); } - breakpointByHandle(handle: number): ?Breakpoint { + breakpointByHandle(handle) { return this._breakpoints.getObjectByHandle(handle); } - breakpointByDebuggerId(id: number): ?Breakpoint { + breakpointByDebuggerId(id) { return this._breakpoints.allObjects.find(_ => id === _.id); } - breakpointsWithNoDebuggerId(): Array { + breakpointsWithNoDebuggerId() { return this._breakpoints.allObjects.filter(_ => _.id == null); } } +exports.default = Breakpoints; \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/DebugSymbolsSize.js b/modules/atom-ide-debugger-native-gdb/lib/DebugSymbolsSize.js index 22df084f58..09cf555db0 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/DebugSymbolsSize.js +++ b/modules/atom-ide-debugger-native-gdb/lib/DebugSymbolsSize.js @@ -1,20 +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 strict-local - * @format - */ +'use strict'; -import fsPromise from 'nuclide-commons/fsPromise'; -import {runCommand} from 'nuclide-commons/process'; -import {Observable} from 'rxjs'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.debugSymSizeByProcess = debugSymSizeByProcess; +exports.debugSymSizeByBinary = debugSymSizeByBinary; -export async function debugSymSizeByProcess(pid: number): Promise { +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../nuclide-commons/fsPromise')); +} + +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 }; } + +async function debugSymSizeByProcess(pid) { // Only support Linux for now. readelf is part of binutils and should be // on every Linux distro that has any dev tools installed. if (process.platform !== 'linux') { @@ -23,15 +31,25 @@ export async function debugSymSizeByProcess(pid: number): Promise { // If we have the /proc file system, we can get the executable trivially const procExe = `/proc/${pid}/exe`; - if (await fsPromise.exists(procExe)) { + if (await (_fsPromise || _load_fsPromise()).default.exists(procExe)) { return debugSymSizeByBinary(procExe); } // If /proc isn't available, we could do some ugly parsing of ps here. 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. + * + * strict-local + * @format + */ -export async function debugSymSizeByBinary(binary: string): Promise { +async function debugSymSizeByBinary(binary) { // this pipeline parses the output of readelf to find debug sections. // readelf -WS lists the various sections in the format // [Nr] Name Type Address Off Size ES Flg Lk Inf Al @@ -44,27 +62,14 @@ export async function debugSymSizeByBinary(binary: string): Promise { const SIZE_COLUMN = 5; return new Promise((resolve, reject) => { try { - runCommand('readelf', ['-WS', binary]) - .catch(_ => Observable.of('')) - .map(stdout => - stdout - .split(/\n/) - // filter out just the section lines on [##] - .filter(line => /\[\s*\d+\]/.test(line)) - // Remove spaces from the single-digit section indices, so we can - // safely split on spaces (i.e. '[ 1]' becomes '[1]') - .map(line => - line - .replace(/\[\s*(\d+)\]/, '[$1]') - .trim() - .split(/\s+/), - ) - .filter(tuple => /(debug|stab)/.test(tuple[NAME_COLUMN])) - .reduce((sum, tuple) => sum + parseInt(tuple[SIZE_COLUMN], 16), 0), - ) - .subscribe(value => resolve(value)); + (0, (_process || _load_process()).runCommand)('readelf', ['-WS', binary]).catch(_ => _rxjsBundlesRxMinJs.Observable.of('')).map(stdout => stdout.split(/\n/) + // filter out just the section lines on [##] + .filter(line => /\[\s*\d+\]/.test(line)) + // Remove spaces from the single-digit section indices, so we can + // safely split on spaces (i.e. '[ 1]' becomes '[1]') + .map(line => line.replace(/\[\s*(\d+)\]/, '[$1]').trim().split(/\s+/)).filter(tuple => /(debug|stab)/.test(tuple[NAME_COLUMN])).reduce((sum, tuple) => sum + parseInt(tuple[SIZE_COLUMN], 16), 0)).subscribe(value => resolve(value)); } catch (ex) { reject(ex); } }); -} +} \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/Disassemble.js b/modules/atom-ide-debugger-native-gdb/lib/Disassemble.js index 98f18e1bb5..1f4b09b1a3 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/Disassemble.js +++ b/modules/atom-ide-debugger-native-gdb/lib/Disassemble.js @@ -1,43 +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 bigInt from 'big-integer'; -import {dataDisassembleResult} from './MITypes'; -import HandleMap from './HandleMap'; -import MIProxy from './MIProxy'; -import StackFrames from './StackFrames'; - -type SourceRef = { - stackFrameHandle: number, - startingPoint: ?string, -}; - -export default class Disassemble { - _client: MIProxy; - _stackFrames: StackFrames; - _handleMap: HandleMap; - _sourceRefByStackFrameHandle: Map; - - constructor(client: MIProxy, stackFrames: StackFrames) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _bigInteger; + +function _load_bigInteger() { + return _bigInteger = _interopRequireDefault(require('big-integer')); +} + +var _MITypes; + +function _load_MITypes() { + return _MITypes = require('./MITypes'); +} + +var _HandleMap; + +function _load_HandleMap() { + return _HandleMap = _interopRequireDefault(require('./HandleMap')); +} + +var _MIProxy; + +function _load_MIProxy() { + return _MIProxy = _interopRequireDefault(require('./MIProxy')); +} + +var _StackFrames; + +function _load_StackFrames() { + return _StackFrames = _interopRequireDefault(require('./StackFrames')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Disassemble { + + constructor(client, stackFrames) { this._client = client; this._stackFrames = stackFrames; - this._handleMap = new HandleMap(); + this._handleMap = new (_HandleMap || _load_HandleMap()).default(); this._sourceRefByStackFrameHandle = new Map(); } - sourceReferenceForStackFrame(stackFrameHandle: number): number { + sourceReferenceForStackFrame(stackFrameHandle) { let handle = this._sourceRefByStackFrameHandle.get(stackFrameHandle); if (handle == null) { - const sourceRef = {stackFrameHandle, startingPoint: undefined}; + const sourceRef = { stackFrameHandle, startingPoint: undefined }; handle = this._handleMap.put(sourceRef); this._sourceRefByStackFrameHandle.set(stackFrameHandle, handle); } @@ -45,7 +56,7 @@ export default class Disassemble { return handle; } - async getDisassembly(sourceRef: number): Promise { + async getDisassembly(sourceRef) { const source = this._handleMap.getObjectByHandle(sourceRef); if (source == null) { throw new Error(`Invalid source reference ${sourceRef}`); @@ -53,62 +64,59 @@ export default class Disassemble { let startingAddress = source.startingPoint; if (startingAddress == null) { - source.startingPoint = await this._getFrameAddress( - source.stackFrameHandle, - ); + source.startingPoint = await this._getFrameAddress(source.stackFrameHandle); startingAddress = source.startingPoint; } const hexPattern = /^0x([0-9a-fA-F]+)$/; const match = startingAddress.match(hexPattern); if (match == null) { - throw new Error( - `Failed to disassemble because value ${startingAddress} is not a valid hex address`, - ); + throw new Error(`Failed to disassemble because value ${startingAddress} is not a valid hex address`); } - const start = bigInt(match[1], 16); + const start = (0, (_bigInteger || _load_bigInteger()).default)(match[1], 16); // $TODO find a good balance between useful and performant. For now // just disassemble 4k worth of code, which is a fair bit but still comes // back quickly const end = start.add(4096); - const command = `data-disassemble -s 0x${start.toString( - 16, - )} -e 0x${end.toString(16)} -- 0`; + const command = `data-disassemble -s 0x${start.toString(16)} -e 0x${end.toString(16)} -- 0`; const response = await this._client.sendCommand(command); if (!response.done) { throw new Error(`Failed to disassemble for source handle ${sourceRef}`); } - const instructions = dataDisassembleResult(response); + const instructions = (0, (_MITypes || _load_MITypes()).dataDisassembleResult)(response); return instructions.asm_insns.map(_ => `${_.address} ${_.inst}`).join('\n'); } - async _getFrameAddress(stackFrameHandle: number): Promise { + async _getFrameAddress(stackFrameHandle) { const frameRef = this._stackFrames.stackFrameByHandle(stackFrameHandle); if (frameRef == null) { - throw new Error( - `Could not discover stack frame handle ${stackFrameHandle} for disassembly`, - ); + throw new Error(`Could not discover stack frame handle ${stackFrameHandle} for disassembly`); } - const frames = await this._stackFrames.stackFramesForThread( - frameRef.threadId, - frameRef.frameIndex, - 1, - ); + const frames = await this._stackFrames.stackFramesForThread(frameRef.threadId, frameRef.frameIndex, 1); const frame = frames.stackFrames[0]; if (frame == null || frame.addr == null) { - throw new Error( - `Could not retrieve stack frame for handle ${stackFrameHandle} for disassembly`, - ); + throw new Error(`Could not retrieve stack frame for handle ${stackFrameHandle} for disassembly`); } return frame.addr; } } +exports.default = Disassemble; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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-debugger-native-gdb/lib/ExceptionBreakpoints.js b/modules/atom-ide-debugger-native-gdb/lib/ExceptionBreakpoints.js index a4ac39e773..11c4fa4cf1 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/ExceptionBreakpoints.js +++ b/modules/atom-ide-debugger-native-gdb/lib/ExceptionBreakpoints.js @@ -1,34 +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 strict-local - * @format - */ - -import type {MIStoppedEventResult} from './MITypes'; -import type {StopReason} from './MIDebugSession'; - -import invariant from 'assert'; -import MIProxy from './MIProxy'; -import {breakInsertResult, toCommandError} from './MITypes'; - -export default class ExceptionBreakpoints { - _throwHelper = '__cxa_throw'; - _client: MIProxy; - _throwBreakpoint: ?number; - _stopOnSignals: boolean; - - constructor(client: MIProxy) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _MIProxy; + +function _load_MIProxy() { + return _MIProxy = _interopRequireDefault(require('./MIProxy')); +} + +var _MITypes; + +function _load_MITypes() { + return _MITypes = require('./MITypes'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class ExceptionBreakpoints { + + constructor(client) { + this._throwHelper = '__cxa_throw'; + this._client = client; this._stopOnSignals = false; } - shouldIgnoreBreakpoint(result: MIStoppedEventResult): boolean { + shouldIgnoreBreakpoint(result) { if (this._isSignal(result) && !this._stopOnSignals) { return true; } @@ -39,29 +38,29 @@ export default class ExceptionBreakpoints { return false; } - stopEventReason(result: MIStoppedEventResult): ?StopReason { + stopEventReason(result) { if (this._isSignal(result)) { return { reason: 'exception', - description: 'Uncaught exception', + description: 'Uncaught exception' }; } if (this._isOurBreakpoint(result)) { return { reason: 'exception', - description: 'Thrown exception', + description: 'Thrown exception' }; } return null; } - _isSignal(result: MIStoppedEventResult): boolean { + _isSignal(result) { return result.reason === 'signal-received'; } - _isOurBreakpoint(result: MIStoppedEventResult): boolean { + _isOurBreakpoint(result) { if (result.reason !== 'breakpoint-hit') { return false; } @@ -74,7 +73,7 @@ export default class ExceptionBreakpoints { return parseInt(bpt, 10) === this._throwBreakpoint; } - async setExceptionBreakpointFilters(filters: Array): Promise { + async setExceptionBreakpointFilters(filters) { this._stopOnSignals = filters.includes('uncaught'); const enableThrown = filters.includes('thrown'); @@ -85,36 +84,38 @@ export default class ExceptionBreakpoints { } } - async _setBreakpoint(): Promise { - const result = await this._client.sendCommand( - `break-insert -f ${this._throwHelper}`, - ); + async _setBreakpoint() { + const result = await this._client.sendCommand(`break-insert -f ${this._throwHelper}`); if (result.error) { - throw new Error( - `Error setting thrown exception breakpoint ${ - toCommandError(result).msg - }`, - ); + throw new Error(`Error setting thrown exception breakpoint ${(0, (_MITypes || _load_MITypes()).toCommandError)(result).msg}`); } - const bt = breakInsertResult(result); + const bt = (0, (_MITypes || _load_MITypes()).breakInsertResult)(result); this._throwBreakpoint = parseInt(bt.bkpt[0].number, 10); } - async _clearBreakpoint(): Promise { + async _clearBreakpoint() { const breakpointId = this._throwBreakpoint; - invariant(breakpointId != null); - const result = await this._client.sendCommand( - `break-delete ${breakpointId}`, - ); + if (!(breakpointId != null)) { + throw new Error('Invariant violation: "breakpointId != null"'); + } + + const result = await this._client.sendCommand(`break-delete ${breakpointId}`); if (result.error) { - throw new Error( - `Error clearing thrown exception breakpoint ${ - toCommandError(result).msg - }`, - ); + throw new Error(`Error clearing thrown exception breakpoint ${(0, (_MITypes || _load_MITypes()).toCommandError)(result).msg}`); } } } +exports.default = ExceptionBreakpoints; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/ExpressionVariableReference.js b/modules/atom-ide-debugger-native-gdb/lib/ExpressionVariableReference.js index b9e5132fe6..07381fd4ee 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/ExpressionVariableReference.js +++ b/modules/atom-ide-debugger-native-gdb/lib/ExpressionVariableReference.js @@ -1,3 +1,31 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _MIDebugSession; + +function _load_MIDebugSession() { + return _MIDebugSession = require('./MIDebugSession'); +} + +var _MIProxy; + +function _load_MIProxy() { + return _MIProxy = _interopRequireDefault(require('./MIProxy')); +} + +var _VariableReference; + +function _load_VariableReference() { + return _VariableReference = _interopRequireDefault(require('./VariableReference')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// An ExpressionVariableReference refers to a watch or hover expression rather +// than a variable rooted in a stack frame scope. /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,81 +34,58 @@ * LICENSE file in 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 {Variable} from 'vscode-debugprotocol'; - -import {logVerbose} from './MIDebugSession'; -import MIProxy from './MIProxy'; -import VariableReference from './VariableReference'; - -// An ExpressionVariableReference refers to a watch or hover expression rather -// than a variable rooted in a stack frame scope. -export default class ExpressionVariableReference extends VariableReference { - constructor( - client: MIProxy, - variables: Variables, - threadId: ?number, - frameIndex: ?number, - expression: string, - ) { - super({client, variables, expression, threadId, frameIndex}); +class ExpressionVariableReference extends (_VariableReference || _load_VariableReference()).default { + constructor(client, variables, threadId, frameIndex, expression) { + super({ client, variables, expression, threadId, frameIndex }); } // Unlike variable enumeration, getVariables here can only return exactly // one variable. - async getVariables(start: ?number, count: ?number): Promise> { + async getVariables(start, count) { const value = await this.getValue(); const typeClass = await this.getTypeClass(value); const resolvedType = await this.getType(); - logVerbose( - `eval name ${ - this._expression - } type ${resolvedType} value ${value} typeClass ${typeClass}`, - ); + (0, (_MIDebugSession || _load_MIDebugSession()).logVerbose)(`eval name ${this._expression} type ${resolvedType} value ${value} typeClass ${typeClass}`); - let variable: Variable = { + let variable = { name: this._expression, value, type: resolvedType, - variablesReference: 0, + variablesReference: 0 }; if (typeClass !== 'simple') { - const handle = this._variables.nestedVariableReference( - this, - this._expression, - await this._getVarName(), - ); + const handle = this._variables.nestedVariableReference(this, this._expression, (await this._getVarName())); const childCount = await this.getChildCount(); if (typeClass === 'indexed') { - variable = { - ...variable, + variable = Object.assign({}, variable, { indexedVariables: childCount, - variablesReference: handle, - }; + variablesReference: handle + }); } else if (typeClass === 'named') { - variable = { - ...variable, + variable = Object.assign({}, variable, { namedVariables: childCount, - variablesReference: handle, - }; + variablesReference: handle + }); } } return [variable]; } - get needsDeletion(): boolean { + get needsDeletion() { return true; } - get qualifiedName(): string { + get qualifiedName() { return `eval.${this._expression}`; } } +exports.default = ExpressionVariableReference; \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/FunctionBreakpoints.js b/modules/atom-ide-debugger-native-gdb/lib/FunctionBreakpoints.js index be9eed30b7..dcb3228280 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/FunctionBreakpoints.js +++ b/modules/atom-ide-debugger-native-gdb/lib/FunctionBreakpoints.js @@ -1,63 +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 * as DebugProtocol from 'vscode-debugprotocol'; -import invariant from 'assert'; -import Breakpoints from './Breakpoints'; -import {Breakpoint} from './Breakpoints'; -import {logVerbose} from './MIDebugSession'; -import MIProxy from './MIProxy'; -import {MIResultRecord} from './MIRecord'; -import {breakInsertResult, toCommandError} from './MITypes'; - -class FunctionBreakpoint extends Breakpoint { - _functionName: string; - - constructor( - id: ?number, - source: ?string, - line: ?number, - functionName: string, - verified: boolean, - ) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _vscodeDebugprotocol; + +function _load_vscodeDebugprotocol() { + return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol')); +} + +var _Breakpoints; + +function _load_Breakpoints() { + return _Breakpoints = _interopRequireDefault(require('./Breakpoints')); +} + +var _Breakpoints2; + +function _load_Breakpoints2() { + return _Breakpoints2 = require('./Breakpoints'); +} + +var _MIDebugSession; + +function _load_MIDebugSession() { + return _MIDebugSession = require('./MIDebugSession'); +} + +var _MIProxy; + +function _load_MIProxy() { + return _MIProxy = _interopRequireDefault(require('./MIProxy')); +} + +var _MIRecord; + +function _load_MIRecord() { + return _MIRecord = require('./MIRecord'); +} + +var _MITypes; + +function _load_MITypes() { + return _MITypes = require('./MITypes'); +} + +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 FunctionBreakpoint extends (_Breakpoints2 || _load_Breakpoints2()).Breakpoint { + + constructor(id, source, line, functionName, verified) { super(id, source, line, null, verified); this._functionName = functionName; } - get functionName(): string { + get functionName() { return this._functionName; } -} - -type AddRemoveSets = { - addFunctions: Array, - removeBreakpoints: Array, -}; - -export default class FunctionBreakpoints { - _client: MIProxy; - _breakpoints: Breakpoints; - _breakpointsByFunction: Map; - - constructor(client: MIProxy, breakpoints: Breakpoints) { +} /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 FunctionBreakpoints { + + constructor(client, breakpoints) { this._client = client; this._breakpoints = breakpoints; this._breakpointsByFunction = new Map(); } // Returns a an array of breakpoints in the same order as the source - async setFunctionBreakpoints( - functions: Array, - ): Promise> { + async setFunctionBreakpoints(functions) { const addRemove = this._computeAddRemoveSets(functions); if (!this._client.isConnected()) { @@ -66,41 +90,33 @@ export default class FunctionBreakpoints { await this._addRemoveBreakpointsViaProxy(addRemove); } - return [...this._breakpointsByFunction.values()].map(_ => - this._breakpointToProtocolBreakpoint(_), - ); + return [...this._breakpointsByFunction.values()].map(_ => this._breakpointToProtocolBreakpoint(_)); } - async setCachedBreakpoints(): Promise> { - const cachedBreakpoints = ((this._breakpoints.breakpointsWithNoDebuggerId(): any): Array< - FunctionBreakpoint, - >); + async setCachedBreakpoints() { + const cachedBreakpoints = this._breakpoints.breakpointsWithNoDebuggerId(); - const results = await Promise.all( - cachedBreakpoints.map(_ => { - return this._setBreakpoint(_.functionName); - }), - ); + const results = await Promise.all(cachedBreakpoints.map(_ => { + return this._setBreakpoint(_.functionName); + })); results.forEach((response, index) => { if (response.done) { - const result = breakInsertResult(response); + const result = (0, (_MITypes || _load_MITypes()).breakInsertResult)(response); const bkpt = result.bkpt[0]; - logVerbose(`breakpoint ${JSON.stringify(bkpt)}`); + (0, (_MIDebugSession || _load_MIDebugSession()).logVerbose)(`breakpoint ${JSON.stringify(bkpt)}`); cachedBreakpoints[index].setId(parseInt(bkpt.number, 10)); if (bkpt.pending == null) { - logVerbose(`breakpoint ${index} is now verified`); + (0, (_MIDebugSession || _load_MIDebugSession()).logVerbose)(`breakpoint ${index} is now verified`); cachedBreakpoints[index].setVerified(); } } }); - return cachedBreakpoints - .filter(_ => _.verified) - .map(_ => this._breakpointToProtocolBreakpoint(_)); + return cachedBreakpoints.filter(_ => _.verified).map(_ => this._breakpointToProtocolBreakpoint(_)); } - getBreakpointByHandle(handle: number): ?Breakpoint { + getBreakpointByHandle(handle) { return this._breakpoints.breakpointByHandle(handle); } @@ -108,26 +124,20 @@ export default class FunctionBreakpoints { // a delta from the current set. We must compute the delta manually // to update the MI debugger. // - _computeAddRemoveSets(functions: Array): AddRemoveSets { - const existingBreakpoints: Array = [ - ...this._breakpointsByFunction.values(), - ]; + _computeAddRemoveSets(functions) { + const existingBreakpoints = [...this._breakpointsByFunction.values()]; const existingFunctions = existingBreakpoints.map(_ => _.functionName); - const removeBreakpoints = existingBreakpoints.filter( - _ => !functions.includes(_.functionName), - ); + const removeBreakpoints = existingBreakpoints.filter(_ => !functions.includes(_.functionName)); - const addFunctions: Array = functions.filter( - _ => !existingFunctions.includes(_), - ); + const addFunctions = functions.filter(_ => !existingFunctions.includes(_)); - return {addFunctions, removeBreakpoints}; + return { addFunctions, removeBreakpoints }; } // If we're called before the proxy is set up, we need to cache the breakpoints // until gdb is launched - _cacheBreakpointsInConfiguration(addRemove: AddRemoveSets): void { + _cacheBreakpointsInConfiguration(addRemove) { for (const bpt of addRemove.removeBreakpoints) { this._breakpoints.removeBreakpoint(bpt); this._breakpointsByFunction.delete(bpt.functionName); @@ -141,13 +151,11 @@ export default class FunctionBreakpoints { }); } - async _addRemoveBreakpointsViaProxy(addRemove: AddRemoveSets): Promise { - const promises: Array> = []; + async _addRemoveBreakpointsViaProxy(addRemove) { + const promises = []; if (addRemove.removeBreakpoints.length !== 0) { - const removeCommand = `break-delete ${addRemove.removeBreakpoints - .map(_ => _.id) - .join(' ')}`; + const removeCommand = `break-delete ${addRemove.removeBreakpoints.map(_ => _.id).join(' ')}`; promises.push(this._client.sendCommand(removeCommand)); } @@ -159,14 +167,14 @@ export default class FunctionBreakpoints { if (addRemove.removeBreakpoints.length !== 0) { const removeResult = results.shift(); - invariant(removeResult != null); + + if (!(removeResult != null)) { + throw new Error('Invariant violation: "removeResult != null"'); + } + if (removeResult.result.error) { // this means our internal state is out of sync with the debugger - throw new Error( - `Failed to remove breakpoints which should have existed (${ - toCommandError(removeResult).msg - })`, - ); + throw new Error(`Failed to remove breakpoints which should have existed (${(0, (_MITypes || _load_MITypes()).toCommandError)(removeResult).msg})`); } } @@ -177,65 +185,76 @@ export default class FunctionBreakpoints { const failure = results.find(_ => !_.done); if (failure != null) { - throw new Error( - `Failed to add function breakpokints (${toCommandError(failure).msg})`, - ); + throw new Error(`Failed to add function breakpokints (${(0, (_MITypes || _load_MITypes()).toCommandError)(failure).msg})`); } results.forEach(_ => { - logVerbose(JSON.stringify(_)); - const result = breakInsertResult(_); + (0, (_MIDebugSession || _load_MIDebugSession()).logVerbose)(JSON.stringify(_)); + const result = (0, (_MITypes || _load_MITypes()).breakInsertResult)(_); // We may get back a list of multiple sub breakpoints, each with a source/line, // but the protocol only supports one location right now. const bkpt = result.bkpt[0]; - invariant(bkpt != null); + + if (!(bkpt != null)) { + throw new Error('Invariant violation: "bkpt != null"'); + } + const location = bkpt['original-location']; - invariant(location != null); + + if (!(location != null)) { + throw new Error('Invariant violation: "location != null"'); + } // MI returns the location back as '-function functioname' + + const funcMatch = location.match(/^-function (.*)$/); - invariant(funcMatch != null); + + if (!(funcMatch != null)) { + throw new Error('Invariant violation: "funcMatch != null"'); + } + const functionName = funcMatch[1]; - invariant(functionName != null); + + if (!(functionName != null)) { + throw new Error('Invariant violation: "functionName != null"'); + } const verified = bkpt.pending == null; - const breakpoint = new FunctionBreakpoint( - parseInt(bkpt.number, 10), - bkpt.file, - parseInt(bkpt.line, 10), - functionName, - verified, - ); + const breakpoint = new FunctionBreakpoint(parseInt(bkpt.number, 10), bkpt.file, parseInt(bkpt.line, 10), functionName, verified); this._breakpoints.addBreakpoint(breakpoint); this._breakpointsByFunction.set(breakpoint.functionName, breakpoint); }); } - async _setBreakpoint(functionName: string): Promise { + async _setBreakpoint(functionName) { // -f means insert unverified breakpoint rather than error if fn not found const cmd = `break-insert -f --function ${functionName}`; return this._client.sendCommand(cmd); } - _breakpointToProtocolBreakpoint( - breakpoint: FunctionBreakpoint, - ): DebugProtocol.Breakpoint { + _breakpointToProtocolBreakpoint(breakpoint) { const handle = this._breakpoints.handleForBreakpoint(breakpoint); - invariant(handle != null); + + if (!(handle != null)) { + throw new Error('Invariant violation: "handle != null"'); + } + let bkpt = { id: handle, verified: breakpoint.verified, - source: {sourceReference: 0}, + source: { sourceReference: 0 } }; if (breakpoint.source != null) { - bkpt.source = {...bkpt.source, path: breakpoint.source}; + bkpt.source = Object.assign({}, bkpt.source, { path: breakpoint.source }); } if (breakpoint.line != null) { - bkpt = {...bkpt, line: breakpoint.line}; + bkpt = Object.assign({}, bkpt, { line: breakpoint.line }); } return bkpt; } } +exports.default = FunctionBreakpoints; \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/HandleMap.js b/modules/atom-ide-debugger-native-gdb/lib/HandleMap.js index db8d4e0345..67db04f4f8 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/HandleMap.js +++ b/modules/atom-ide-debugger-native-gdb/lib/HandleMap.js @@ -1,3 +1,8 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,19 +11,15 @@ * LICENSE file in 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 class HandleMap { - DEFAULT_STARTING_HANDLE = 1000; +class HandleMap { - _startingHandle: number; - _objectsByHandle: Map; - _handlesByObject: Map; - _nextHandle: number; + constructor(nextHandle) { + this.DEFAULT_STARTING_HANDLE = 1000; - constructor(nextHandle: ?number) { this._startingHandle = nextHandle == null ? 1000 : nextHandle; this.clear(); } @@ -29,11 +30,11 @@ export default class HandleMap { this._handlesByObject = new Map(); } - get allObjects(): Array { + get allObjects() { return Array.from(this._objectsByHandle.values()); } - put(obj: T): number { + put(obj) { // maintain 1:1 mapping let handle = this._handlesByObject.get(obj); if (handle == null) { @@ -45,15 +46,15 @@ export default class HandleMap { return handle; } - getObjectByHandle(handle: number): ?T { + getObjectByHandle(handle) { return this._objectsByHandle.get(handle); } - getHandleByObject(obj: T): ?number { + getHandleByObject(obj) { return this._handlesByObject.get(obj); } - removeHandle(handle: number): void { + removeHandle(handle) { const obj = this._objectsByHandle.get(handle); if (obj != null) { this._handlesByObject.delete(obj); @@ -61,7 +62,7 @@ export default class HandleMap { } } - removeObject(obj: T): void { + removeObject(obj) { const handle = this._handlesByObject.get(obj); if (handle != null) { this._handlesByObject.delete(obj); @@ -69,7 +70,8 @@ export default class HandleMap { } } - toString(): string { + toString() { return JSON.stringify([...this._objectsByHandle]); } } +exports.default = HandleMap; \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/MIDebugSession.js b/modules/atom-ide-debugger-native-gdb/lib/MIDebugSession.js index 6c3dddfefe..c39c63d7b6 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/MIDebugSession.js +++ b/modules/atom-ide-debugger-native-gdb/lib/MIDebugSession.js @@ -1,118 +1,127 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 {ITerminal} from 'nuclide-prebuilt-libs/pty'; - -import { - BreakpointEvent, - logger, - Logger, - LoggingDebugSession, - InitializedEvent, - OutputEvent, - StoppedEvent, - TerminatedEvent, - ThreadEvent, -} from 'vscode-debugadapter'; -import Breakpoints from './Breakpoints'; -import SourceBreakpoints from './SourceBreakpoints'; -import * as DebugProtocol from 'vscode-debugprotocol'; -import Disassemble from './Disassemble'; -import ExceptionBreakpoints from './ExceptionBreakpoints'; -import FunctionBreakpoints from './FunctionBreakpoints'; -import invariant from 'assert'; -import MIProxy from './MIProxy'; -import {MIAsyncRecord, MIResultRecord} from './MIRecord'; -import * as pty from 'nuclide-prebuilt-libs/pty'; -import os from 'os'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import { - breakpointModifiedEventResult, - stoppedEventResult, - toCommandError, - threadInfoResult, -} from './MITypes'; -import StackFrames from './StackFrames'; -import Variables from './Variables'; -import {debugSymSizeByProcess, debugSymSizeByBinary} from './DebugSymbolsSize'; - -export type StopReason = { - reason: string, - description: string, -}; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.logVerbose = logVerbose; + +var _vscodeDebugadapter; + +function _load_vscodeDebugadapter() { + return _vscodeDebugadapter = require('vscode-debugadapter'); +} + +var _Breakpoints; + +function _load_Breakpoints() { + return _Breakpoints = _interopRequireDefault(require('./Breakpoints')); +} + +var _SourceBreakpoints; + +function _load_SourceBreakpoints() { + return _SourceBreakpoints = _interopRequireDefault(require('./SourceBreakpoints')); +} + +var _vscodeDebugprotocol; + +function _load_vscodeDebugprotocol() { + return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol')); +} + +var _Disassemble; + +function _load_Disassemble() { + return _Disassemble = _interopRequireDefault(require('./Disassemble')); +} + +var _ExceptionBreakpoints; + +function _load_ExceptionBreakpoints() { + return _ExceptionBreakpoints = _interopRequireDefault(require('./ExceptionBreakpoints')); +} + +var _FunctionBreakpoints; + +function _load_FunctionBreakpoints() { + return _FunctionBreakpoints = _interopRequireDefault(require('./FunctionBreakpoints')); +} + +var _MIProxy; + +function _load_MIProxy() { + return _MIProxy = _interopRequireDefault(require('./MIProxy')); +} + +var _MIRecord; + +function _load_MIRecord() { + return _MIRecord = require('./MIRecord'); +} + +var _pty; + +function _load_pty() { + return _pty = _interopRequireWildcard(require('nuclide-prebuilt-libs/pty')); +} + +var _os = _interopRequireDefault(require('os')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../nuclide-commons/nuclideUri')); +} + +var _MITypes; + +function _load_MITypes() { + return _MITypes = require('./MITypes'); +} + +var _StackFrames; + +function _load_StackFrames() { + return _StackFrames = _interopRequireDefault(require('./StackFrames')); +} + +var _Variables; + +function _load_Variables() { + return _Variables = _interopRequireDefault(require('./Variables')); +} + +var _DebugSymbolsSize; + +function _load_DebugSymbolsSize() { + return _DebugSymbolsSize = require('./DebugSymbolsSize'); +} + +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 }; } // NB that trace is not actually exposed in package.json as it's only used for // debugging the adapter itself -type LaunchRequestArguments = { - ...DebugProtocol.LaunchRequestArguments, - program: string, - cwd: ?string, - args: ?Array, - env: Array, - sourcePath: string, - debuggerRoot: ?string, - trace: ?boolean, -}; - -type AttachRequestArguments = { - ...DebugProtocol.AttachRequestArguments, - pid: number, - sourcePath: string, - debuggerRoot: ?string, - stopOnAttach: ?boolean, - trace: ?boolean, -}; - -class MIDebugSession extends LoggingDebugSession { - _hasTarget: boolean; - _configurationDone: boolean; - _client: MIProxy; - _breakpoints: Breakpoints; - _sourceBreakpoints: SourceBreakpoints; - _functionBreakpoints: FunctionBreakpoints; - _disassemble: Disassemble; - _exceptionBreakpoints: ExceptionBreakpoints; - _stackFrames: StackFrames; - _variables: Variables; - _targetIO: ?ITerminal; - _asyncHandlers: Map void>; - _attachPID: ?number; - _running: boolean; - _expectingPause: boolean; - _pauseQueue: Array<() => Promise>; - _continueOnAttach: boolean; - _stepping: boolean; - _steppingThread: number = 0; - _configurationDoneResponse: ?DebugProtocol.ConfigurationDoneResponse; +class MIDebugSession extends (_vscodeDebugadapter || _load_vscodeDebugadapter()).LoggingDebugSession { constructor() { - const logfile = nuclideUri.join(os.tmpdir(), 'native-debugger-vsp.log'); + const logfile = (_nuclideUri || _load_nuclideUri()).default.join(_os.default.tmpdir(), 'native-debugger-vsp.log'); super(logfile); + this._steppingThread = 0; this._hasTarget = false; this._configurationDone = false; - const client = new MIProxy(); + const client = new (_MIProxy || _load_MIProxy()).default(); this._client = client; - this._breakpoints = new Breakpoints(); - this._sourceBreakpoints = new SourceBreakpoints(client, this._breakpoints); - this._functionBreakpoints = new FunctionBreakpoints( - client, - this._breakpoints, - ); - this._exceptionBreakpoints = new ExceptionBreakpoints(client); - this._stackFrames = new StackFrames(client); - this._disassemble = new Disassemble(client, this._stackFrames); - this._variables = new Variables(client, this._stackFrames); + this._breakpoints = new (_Breakpoints || _load_Breakpoints()).default(); + this._sourceBreakpoints = new (_SourceBreakpoints || _load_SourceBreakpoints()).default(client, this._breakpoints); + this._functionBreakpoints = new (_FunctionBreakpoints || _load_FunctionBreakpoints()).default(client, this._breakpoints); + this._exceptionBreakpoints = new (_ExceptionBreakpoints || _load_ExceptionBreakpoints()).default(client); + this._stackFrames = new (_StackFrames || _load_StackFrames()).default(client); + this._disassemble = new (_Disassemble || _load_Disassemble()).default(client, this._stackFrames); + this._variables = new (_Variables || _load_Variables()).default(client, this._stackFrames); this._expectingPause = false; this._continueOnAttach = false; @@ -130,54 +139,40 @@ class MIDebugSession extends LoggingDebugSession { client.on('async', record => this._asyncRecord(record)); - this._asyncHandlers = new Map([ - [ - 'stopped', - record => { - this._onAsyncStopped(record); - }, - ], - ['thread-created', record => this._onAsyncThread(record, true)], - ['thread-exited', record => this._onAsyncThread(record, false)], - ['breakpoint-modified', record => this._onBreakpointModified(record)], - ]); + this._asyncHandlers = new Map([['stopped', record => { + this._onAsyncStopped(record); + }], ['thread-created', record => this._onAsyncThread(record, true)], ['thread-exited', record => this._onAsyncThread(record, false)], ['breakpoint-modified', record => this._onBreakpointModified(record)]]); this._pauseQueue = []; } - _asyncRecord(record: MIAsyncRecord): void { + _asyncRecord(record) { const handler = this._asyncHandlers.get(record.asyncClass); if (handler != null) { handler(record); } } - start(inStream: ReadableStream, outStream: WritableStream): void { + start(inStream, outStream) { super.start(inStream, outStream); logVerbose(`using node ${process.version} at ${process.execPath}`); } - initializeRequest( - response: DebugProtocol.InitializeResponse, - args: DebugProtocol.InitializeRequestArguments, - ): void { + initializeRequest(response, args) { response.body = response.body || {}; response.body.supportsFunctionBreakpoints = true; response.body.supportsConfigurationDoneRequest = true; response.body.supportsSetVariable = true; response.body.supportsValueFormattingOptions = true; - response.body.exceptionBreakpointFilters = [ - { - filter: 'uncaught', - label: 'Uncaught exceptions', - default: false, - }, - { - filter: 'thrown', - label: 'Thrown exceptions', - default: false, - }, - ]; + response.body.exceptionBreakpointFilters = [{ + filter: 'uncaught', + label: 'Uncaught exceptions', + default: false + }, { + filter: 'thrown', + label: 'Thrown exceptions', + default: false + }]; this.sendResponse(response); @@ -185,17 +180,11 @@ class MIDebugSession extends LoggingDebugSession { // notably we will get a launchRequest *before* configuration done, and actually before the breakpoint // requests. so we have to be careful to bring up the debugger in the launch request, then set the // initial breakpoints, and not actually start the program until configuration done. - this.sendEvent(new InitializedEvent()); + this.sendEvent(new (_vscodeDebugadapter || _load_vscodeDebugadapter()).InitializedEvent()); } - async launchRequest( - response: DebugProtocol.LaunchResponse, - args: LaunchRequestArguments, - ): Promise { - logger.setup( - args.trace === true ? Logger.LogLevel.Verbose : Logger.LogLevel.Error, - true, - ); + async launchRequest(response, args) { + (_vscodeDebugadapter || _load_vscodeDebugadapter()).logger.setup(args.trace === true ? (_vscodeDebugadapter || _load_vscodeDebugadapter()).Logger.LogLevel.Verbose : (_vscodeDebugadapter || _load_vscodeDebugadapter()).Logger.LogLevel.Error, true); let environment = {}; if (args.env != null) { @@ -206,60 +195,31 @@ class MIDebugSession extends LoggingDebugSession { } const key = _.substr(0, equal); const value = _.substr(equal + 1); - environment = { - ...environment, - [key]: value, - }; + environment = Object.assign({}, environment, { + [key]: value + }); }); } - const debuggerRoot = - args.debuggerRoot != null ? args.debuggerRoot : args.sourcePath; + const debuggerRoot = args.debuggerRoot != null ? args.debuggerRoot : args.sourcePath; this._client.start('gdb', ['-q', '--interpreter=mi2'], environment); - if ( - debuggerRoot != null && - debuggerRoot.trim() !== '' && - !(await this._sendWithFailureCheck( - response, - `environment-directory -r "${debuggerRoot}"`, - )) - ) { + if (debuggerRoot != null && debuggerRoot.trim() !== '' && !(await this._sendWithFailureCheck(response, `environment-directory -r "${debuggerRoot}"`))) { return; } - if ( - args.cwd != null && - args.cwd.trim() !== '' && - !(await this._sendWithFailureCheck( - response, - `environment-cd ${args.cwd}`, - )) - ) { + if (args.cwd != null && args.cwd.trim() !== '' && !(await this._sendWithFailureCheck(response, `environment-cd ${args.cwd}`))) { return; } - if ( - args.args != null && - !(await this._sendWithFailureCheck( - response, - `exec-arguments ${args.args.join(' ')}`, - )) - ) { + if (args.args != null && !(await this._sendWithFailureCheck(response, `exec-arguments ${args.args.join(' ')}`))) { return; } - this._showSymbolLoadingSizeWarning( - await debugSymSizeByBinary(args.program), - ); + this._showSymbolLoadingSizeWarning((await (0, (_DebugSymbolsSize || _load_DebugSymbolsSize()).debugSymSizeByBinary)(args.program))); - if ( - !(await this._sendWithFailureCheck( - response, - `file-exec-and-symbols ${args.program}`, - )) - ) { + if (!(await this._sendWithFailureCheck(response, `file-exec-and-symbols ${args.program}`))) { return; } @@ -271,28 +231,14 @@ class MIDebugSession extends LoggingDebugSession { this.sendResponse(response); } - async attachRequest( - response: DebugProtocol.AttachResponse, - args: AttachRequestArguments, - ): Promise { - logger.setup( - args.trace === true ? Logger.LogLevel.Verbose : Logger.LogLevel.Error, - true, - ); + async attachRequest(response, args) { + (_vscodeDebugadapter || _load_vscodeDebugadapter()).logger.setup(args.trace === true ? (_vscodeDebugadapter || _load_vscodeDebugadapter()).Logger.LogLevel.Verbose : (_vscodeDebugadapter || _load_vscodeDebugadapter()).Logger.LogLevel.Error, true); - const debuggerRoot = - args.debuggerRoot != null ? args.debuggerRoot : args.sourcePath; + const debuggerRoot = args.debuggerRoot != null ? args.debuggerRoot : args.sourcePath; this._client.start('gdb', ['-q', '--interpreter=mi2'], null); - if ( - debuggerRoot != null && - debuggerRoot.trim() !== '' && - !(await this._sendWithFailureCheck( - response, - `environment-directory -r "${debuggerRoot}"`, - )) - ) { + if (debuggerRoot != null && debuggerRoot.trim() !== '' && !(await this._sendWithFailureCheck(response, `environment-directory -r "${debuggerRoot}"`))) { return; } @@ -303,10 +249,7 @@ class MIDebugSession extends LoggingDebugSession { this.sendResponse(response); } - async disconnectRequest( - response: DebugProtocol.DisconnectResponse, - request: DebugProtocol.DisconnectRequest, - ): Promise { + async disconnectRequest(response, request) { this._stepping = false; this._steppingThread = 0; this._runWhenStopped(async () => { @@ -319,10 +262,7 @@ class MIDebugSession extends LoggingDebugSession { }); } - async configurationDoneRequest( - response: DebugProtocol.ConfigurationDoneResponse, - args: DebugProtocol.ConfigurationDoneArguments, - ): Promise { + async configurationDoneRequest(response, args) { this._configurationDone = true; if (!(await this._initializeTargetIO(response))) { @@ -335,11 +275,9 @@ class MIDebugSession extends LoggingDebugSession { const pid = this._attachPID; if (pid != null) { - this._showSymbolLoadingSizeWarning(await debugSymSizeByProcess(pid)); + this._showSymbolLoadingSizeWarning((await (0, (_DebugSymbolsSize || _load_DebugSymbolsSize()).debugSymSizeByProcess)(pid))); - if ( - !(await this._sendWithFailureCheck(response, `target-attach ${pid}`)) - ) { + if (!(await this._sendWithFailureCheck(response, `target-attach ${pid}`))) { return; } @@ -356,14 +294,12 @@ class MIDebugSession extends LoggingDebugSession { } } - async _showSymbolLoadingSizeWarning(size: ?number): Promise { + async _showSymbolLoadingSizeWarning(size) { if (size == null) { // generic "this operation can be slow" message since we don't know how // large they are. Since we're not sure if this is really an issue, // just log to console. - this._logToConsole( - 'Reading executable symbols (for huge executables, this can take up to 2-3 minutes).\n', - ); + this._logToConsole('Reading executable symbols (for huge executables, this can take up to 2-3 minutes).\n'); return; } @@ -380,48 +316,33 @@ class MIDebugSession extends LoggingDebugSession { const HUGE_SYMBOL_SIZE_LIMIT = ONE_GIG; if (size > HUGE_SYMBOL_SIZE_LIMIT) { - return this._nuclideWarningDialog( - `The symbols for your executable are very large (${( - size / ONE_GIG - ).toFixed(2)}G). Loading them may take several minutes.`, - ); + return this._nuclideWarningDialog(`The symbols for your executable are very large (${(size / ONE_GIG).toFixed(2)}G). Loading them may take several minutes.`); } if (size > SYMBOL_SIZE_LIMIT) { - return this._nuclideWarningDialog( - `The symbols for your executable are fairly large (${( - size / ONE_MEG - ).toFixed(2)}M). It may take up to a minute to load them.`, - ); + return this._nuclideWarningDialog(`The symbols for your executable are fairly large (${(size / ONE_MEG).toFixed(2)}M). It may take up to a minute to load them.`); } } - async setBreakPointsRequest( - response: DebugProtocol.SetBreakpointsResponse, - args: DebugProtocol.SetBreakpointsArguments, - ): Promise { + async setBreakPointsRequest(response, args) { this._runWhenStopped(async () => { try { - const source = - args.source.path != null ? args.source.path : args.source.name; - invariant(source != null); + const source = args.source.path != null ? args.source.path : args.source.name; + + if (!(source != null)) { + throw new Error('Invariant violation: "source != null"'); + } const breakpoints = args.breakpoints; if (breakpoints == null) { - this._sendFailureResponse( - response, - 'No breakpoints specified in breakpoints request', - ); + this._sendFailureResponse(response, 'No breakpoints specified in breakpoints request'); return; } - const protocolBreakpoints = await this._sourceBreakpoints.setSourceBreakpoints( - source, - breakpoints, - ); + const protocolBreakpoints = await this._sourceBreakpoints.setSourceBreakpoints(source, breakpoints); response.body = { - breakpoints: protocolBreakpoints, + breakpoints: protocolBreakpoints }; this.sendResponse(response); @@ -431,28 +352,20 @@ class MIDebugSession extends LoggingDebugSession { }); } - async setFunctionBreakPointsRequest( - response: DebugProtocol.SetFunctionBreakpointsResponse, - args: DebugProtocol.SetFunctionBreakpointsArguments, - ): Promise { + async setFunctionBreakPointsRequest(response, args) { this._runWhenStopped(async () => { try { const breakpoints = args.breakpoints; if (breakpoints == null) { - this._sendFailureResponse( - response, - 'No breakpoints specified in breakpoints request', - ); + this._sendFailureResponse(response, 'No breakpoints specified in breakpoints request'); return; } const functions = breakpoints.map(_ => _.name); - const breakpointsOut = await this._functionBreakpoints.setFunctionBreakpoints( - functions, - ); + const breakpointsOut = await this._functionBreakpoints.setFunctionBreakpoints(functions); response.body = { - breakpoints: breakpointsOut, + breakpoints: breakpointsOut }; this.sendResponse(response); @@ -462,43 +375,33 @@ class MIDebugSession extends LoggingDebugSession { }); } - async _sendCachedBreakpoints(): Promise { + async _sendCachedBreakpoints() { logVerbose('_sendCachedBreakpoints'); - const changedBreakpoints = [ - ...(await this._sourceBreakpoints.setCachedBreakpoints()), - ...(await this._functionBreakpoints.setCachedBreakpoints()), - ]; + const changedBreakpoints = [...(await this._sourceBreakpoints.setCachedBreakpoints()), ...(await this._functionBreakpoints.setCachedBreakpoints())]; changedBreakpoints.forEach(breakpoint => { - const event = new BreakpointEvent(); + const event = new (_vscodeDebugadapter || _load_vscodeDebugadapter()).BreakpointEvent(); event.body = { reason: 'changed', - breakpoint, + breakpoint }; this.sendEvent(event); }); } - async setExceptionBreakPointsRequest( - response: DebugProtocol.SetExceptionBreakpointsResponse, - args: DebugProtocol.SetExceptionBreakpointsArguments, - ): Promise { + async setExceptionBreakPointsRequest(response, args) { try { - await this._exceptionBreakpoints.setExceptionBreakpointFilters( - args.filters, - ); + await this._exceptionBreakpoints.setExceptionBreakpointFilters(args.filters); this.sendResponse(response); } catch (error) { this._sendFailureResponse(response, error.message); } } - async threadsRequest(response: DebugProtocol.ThreadsResponse): Promise { + async threadsRequest(response) { this._runWhenStopped(async () => { - const threadRecord: MIResultRecord = await this._client.sendCommand( - 'thread-info', - ); + const threadRecord = await this._client.sendCommand('thread-info'); try { if (!threadRecord.done) { @@ -506,15 +409,15 @@ class MIDebugSession extends LoggingDebugSession { return; } - const threads = threadInfoResult(threadRecord).threads; + const threads = (0, (_MITypes || _load_MITypes()).threadInfoResult)(threadRecord).threads; response.body = { threads: threads.map(_ => { return { id: parseInt(_.id, 10), - name: _['target-id'], + name: _['target-id'] }; - }), + }) }; this.sendResponse(response); @@ -524,37 +427,23 @@ class MIDebugSession extends LoggingDebugSession { }); } - async stackTraceRequest( - response: DebugProtocol.StackTraceResponse, - args: DebugProtocol.StackTraceArguments, - ): Promise { - await this._setOutputFormat( - args.format != null && args.format.hex != null && args.format.hex, - ); + async stackTraceRequest(response, args) { + await this._setOutputFormat(args.format != null && args.format.hex != null && args.format.hex); - response.body = await this._stackFrames.stackFramesForThread( - args.threadId, - args.startFrame, - args.levels, - ); + response.body = await this._stackFrames.stackFramesForThread(args.threadId, args.startFrame, args.levels); try { - response.body.stackFrames = await Promise.all( - response.body.stackFrames.map(async frame => { - let source = frame.source; - if (source == null || source.path == null) { - source = { - sourceReference: await this._disassemble.sourceReferenceForStackFrame( - frame.id, - ), - }; - } - return { - ...frame, - source, + response.body.stackFrames = await Promise.all(response.body.stackFrames.map(async frame => { + let source = frame.source; + if (source == null || source.path == null) { + source = { + sourceReference: await this._disassemble.sourceReferenceForStackFrame(frame.id) }; - }), - ); + } + return Object.assign({}, frame, { + source + }); + })); this.sendResponse(response); } catch (err) { @@ -562,25 +451,17 @@ class MIDebugSession extends LoggingDebugSession { } } - async sourceRequest( - response: DebugProtocol.SourceResponse, - args: DebugProtocol.SourceArguments, - ): Promise { + async sourceRequest(response, args) { try { - const content = await this._disassemble.getDisassembly( - args.sourceReference, - ); - response.body = {content}; + const content = await this._disassemble.getDisassembly(args.sourceReference); + response.body = { content }; this.sendResponse(response); } catch (err) { this._sendFailureResponse(response, err.message); } } - async pauseRequest( - response: DebugProtocol.PauseResponse, - args: DebugProtocol.PauseArguments, - ): Promise { + async pauseRequest(response, args) { try { this._expectingPause = true; this._client.pause(); @@ -590,53 +471,34 @@ class MIDebugSession extends LoggingDebugSession { } } - async continueRequest( - response: DebugProtocol.ContinueResponse, - args: DebugProtocol.ContinueRequest, - ): Promise { + async continueRequest(response, args) { return this._executeCommon('exec-continue', null, response); } - async nextRequest( - response: DebugProtocol.NextResponse, - args: DebugProtocol.NextArguments, - ): Promise { + async nextRequest(response, args) { this._stepping = true; this._steppingThread = args.threadId; return this._executeCommon('exec-next', args.threadId, response); } - async stepInRequest( - response: DebugProtocol.StepInResponse, - args: DebugProtocol.StepInArguments, - ): Promise { + async stepInRequest(response, args) { this._stepping = true; this._steppingThread = args.threadId; return this._executeCommon('exec-step', args.threadId, response); } - async stepOutRequest( - response: DebugProtocol.StepOutResponse, - args: DebugProtocol.StepOutArguments, - ): Promise { + async stepOutRequest(response, args) { this._stepping = true; this._steppingThread = args.threadId; return this._executeCommon('exec-finish', args.threadId, response); } - async _executeCommon( - execCommand: string, - threadId: ?number, - response: DebugProtocol.Response, - ): Promise { + async _executeCommon(execCommand, threadId, response) { try { const thread = threadId != null ? `--thread ${threadId}` : ''; const result = await this._client.sendCommand(`${execCommand} ${thread}`); if (!result.running) { - this._sendFailureResponse( - response, - `Failed to ${execCommand} program ${toCommandError(result).msg}`, - ); + this._sendFailureResponse(response, `Failed to ${execCommand} program ${(0, (_MITypes || _load_MITypes()).toCommandError)(result).msg}`); return; } @@ -647,55 +509,39 @@ class MIDebugSession extends LoggingDebugSession { } } - async scopesRequest( - response: DebugProtocol.ScopesResponse, - args: DebugProtocol.ScopesArguments, - ): Promise { + async scopesRequest(response, args) { try { - const varref = this._variables.variableReferenceForStackFrame( - args.frameId, - ); - - const scopes = [ - { - name: 'Locals', - variablesReference: varref, - expensive: false, - }, - ]; + const varref = this._variables.variableReferenceForStackFrame(args.frameId); + + const scopes = [{ + name: 'Locals', + variablesReference: varref, + expensive: false + }]; const regVarref = await this._variables.registersVariableReference(); if (regVarref != null) { scopes.push({ name: 'Registers', variablesReference: regVarref, - expensive: false, + expensive: false }); } - response.body = {scopes}; + response.body = { scopes }; this.sendResponse(response); } catch (err) { this._sendFailureResponse(response, err.message); } } - async variablesRequest( - response: DebugProtocol.VariablesResponse, - args: DebugProtocol.VariablesArguments, - ): Promise { - await this._setOutputFormat( - args.format != null && args.format.hex != null && args.format.hex, - ); + async variablesRequest(response, args) { + await this._setOutputFormat(args.format != null && args.format.hex != null && args.format.hex); try { - const variables = await this._variables.getVariables( - args.variablesReference, - args.start, - args.count, - ); + const variables = await this._variables.getVariables(args.variablesReference, args.start, args.count); - response.body = {variables}; + response.body = { variables }; this.sendResponse(response); } catch (err) { @@ -703,24 +549,13 @@ class MIDebugSession extends LoggingDebugSession { } } - async setVariableRequest( - response: DebugProtocol.SetVariableResponse, - args: DebugProtocol.SetVariableArguments, - ): Promise { - await this._setOutputFormat( - args.format != null && args.format.hex != null && args.format.hex, - ); + async setVariableRequest(response, args) { + await this._setOutputFormat(args.format != null && args.format.hex != null && args.format.hex); try { - const varref = this._variables.getVariableReference( - args.variablesReference, - ); + const varref = this._variables.getVariableReference(args.variablesReference); if (varref == null) { - throw new Error( - `setVariableRequest: invalid variable reference ${ - args.variablesReference - }`, - ); + throw new Error(`setVariableRequest: invalid variable reference ${args.variablesReference}`); } const varSet = await varref.setChildValue(args.name, args.value); @@ -732,17 +567,12 @@ class MIDebugSession extends LoggingDebugSession { } } - async evaluateRequest( - response: DebugProtocol.EvaluateResponse, - args: DebugProtocol.EvaluateArguments, - ): Promise { - await this._setOutputFormat( - args.format != null && args.format.hex != null && args.format.hex, - ); + async evaluateRequest(response, args) { + await this._setOutputFormat(args.format != null && args.format.hex != null && args.format.hex); try { - let threadId: ?number; - let frameIndex: ?number; + let threadId; + let frameIndex; const frameId = args.frameId; if (frameId != null) { @@ -754,17 +584,14 @@ class MIDebugSession extends LoggingDebugSession { frameIndex = stackFrame.frameIndex; } - const handle = this._variables.expressionVariableReference( - threadId, - frameIndex, - args.expression, - ); + const handle = this._variables.expressionVariableReference(threadId, frameIndex, args.expression); const variables = await this._variables.getVariables(handle); - invariant( - variables.length === 1, - 'call should return 1 element or throw on error', - ); + + if (!(variables.length === 1)) { + throw new Error('call should return 1 element or throw on error'); + } + const variable = variables[0]; response.body = { @@ -772,7 +599,7 @@ class MIDebugSession extends LoggingDebugSession { type: variable.type, variablesReference: variable.variablesReference, namedVariables: variable.namedVariables, - indexedVariables: variable.indexedVariables, + indexedVariables: variable.indexedVariables }; this.sendResponse(response); @@ -781,18 +608,16 @@ class MIDebugSession extends LoggingDebugSession { } } - async _setOutputFormat(hex: boolean): Promise { + async _setOutputFormat(hex) { this._client.sendCommand(`gdb-set output-radix ${hex ? 16 : 10}`); } - async _initializeTargetIO( - response: DebugProtocol.ConfigurationDoneResponse, - ): Promise { + async _initializeTargetIO(response) { // $TODO Windows // gdb uses a pty to pipe target (what it calls inferior) output separately from // MI traffic. set up a pty and handlers. - const targetIO = pty.open({}); + const targetIO = (_pty || _load_pty()).open({}); this._targetIO = targetIO; targetIO.on('data', line => this._onTargetIO(line)); @@ -802,35 +627,30 @@ class MIDebugSession extends LoggingDebugSession { // if there's an error such as the actual debugger crashing, shut down cleanly targetIO.once('error', () => this._onTargetTerminated()); - if ( - !(await this._sendWithFailureCheck( - response, - `inferior-tty-set ${targetIO.ptyName}`, - )) - ) { + if (!(await this._sendWithFailureCheck(response, `inferior-tty-set ${targetIO.ptyName}`))) { return false; } return true; } - _onTargetIO(line: string): void { - const event = new OutputEvent(); + _onTargetIO(line) { + const event = new (_vscodeDebugadapter || _load_vscodeDebugadapter()).OutputEvent(); event.body = { category: 'stdout', - output: line, + output: line }; this.sendEvent(event); } - _onTargetTerminated(): void { - this.sendEvent(new TerminatedEvent()); + _onTargetTerminated() { + this.sendEvent(new (_vscodeDebugadapter || _load_vscodeDebugadapter()).TerminatedEvent()); this._hasTarget = false; this._configurationDone = false; } - async _runWhenStopped(fn: () => Promise): Promise { + async _runWhenStopped(fn) { if (!this._running) { return fn(); } @@ -851,39 +671,32 @@ class MIDebugSession extends LoggingDebugSession { } } - async _processPauseQueue(): Promise { + async _processPauseQueue() { const fns = this._pauseQueue.slice(); this._pauseQueue = []; await Promise.all(fns.map(fn => fn())); } - _pauseIfThereAreQueuedCommands(): void { + _pauseIfThereAreQueuedCommands() { if (this._pauseQueue.length !== 0) { this._client.pause(); } } - async _onAsyncStopped(record: MIAsyncRecord): Promise { - const stopped = stoppedEventResult(record); + async _onAsyncStopped(record) { + const stopped = (0, (_MITypes || _load_MITypes()).stoppedEventResult)(record); await this._processPauseQueue(); // if we're stepping and we get a signal in the stepping thread, then // we shouldn't ignore the signal, even if exception breakpoints aren't // enabled - const signalWhileStepping = - this._stepping && - stopped.reason === 'signal-received' && - stopped['thread-id'] === this._steppingThread; + const signalWhileStepping = this._stepping && stopped.reason === 'signal-received' && stopped['thread-id'] === this._steppingThread; // A received signal means one of two things: SIGINT sent to gdb to drop // into command mode (pausing the target), or an unexpected signal which // is an exception to break on. - if ( - !this._expectingPause && - this._exceptionBreakpoints.shouldIgnoreBreakpoint(stopped) && - !signalWhileStepping - ) { + if (!this._expectingPause && this._exceptionBreakpoints.shouldIgnoreBreakpoint(stopped) && !signalWhileStepping) { this._running = true; await this._client.sendCommand('exec-continue'); // we are really running again. if any commands came in from the UI during @@ -919,10 +732,7 @@ class MIDebugSession extends LoggingDebugSession { return; } else if (stopped.reason === 'signal-received') { this._expectingPause = false; - } else if ( - stopped.reason === 'exited-normally' || - stopped.reason === 'exited-signalled' - ) { + } else if (stopped.reason === 'exited-normally' || stopped.reason === 'exited-signalled') { this._onTargetTerminated(); return; } else if (stopped.reason == null) { @@ -940,91 +750,84 @@ class MIDebugSession extends LoggingDebugSession { } } - const event = new StoppedEvent(); + const event = new (_vscodeDebugadapter || _load_vscodeDebugadapter()).StoppedEvent(); event.body = { reason, description, threadId: parseInt(stopped['thread-id'], 10), preserveFocusHint: false, - allThreadsStopped: true, + allThreadsStopped: true }; this.sendEvent(event); } - _onAsyncThread(record: MIAsyncRecord, started: boolean): void { + _onAsyncThread(record, started) { // NB that using a handle table is not needed for threads, because the MI // interface defines a thread id which is exactly the same thing. const id = record.result.id; - const event = new ThreadEvent(); + const event = new (_vscodeDebugadapter || _load_vscodeDebugadapter()).ThreadEvent(); event.body = { reason: started ? 'started' : 'exited', - threadId: parseInt(id, 10), + threadId: parseInt(id, 10) }; this.sendEvent(event); } - async _warnIfNoSymbols(program: string): Promise { + async _warnIfNoSymbols(program) { const result = await this._client.sendCommand('file-list-exec-source-file'); - if ( - result.error && - toCommandError(result).msg.startsWith('No symbol table') - ) { - return this._nuclideWarningDialog( - `Symbols were not found in ${program}. It will run, but breakpoints will not work. Please recompile your program with the proper flags to include debugging symbols (typically -g).`, - ); + if (result.error && (0, (_MITypes || _load_MITypes()).toCommandError)(result).msg.startsWith('No symbol table')) { + return this._nuclideWarningDialog(`Symbols were not found in ${program}. It will run, but breakpoints will not work. Please recompile your program with the proper flags to include debugging symbols (typically -g).`); } } - async _sendWithFailureCheck( - response: DebugProtocol.Response, - command: string, - ): Promise { + async _sendWithFailureCheck(response, command) { const result = await this._client.sendCommand(command); if (result.error) { - this._sendFailureResponse(response, toCommandError(result).msg); + this._sendFailureResponse(response, (0, (_MITypes || _load_MITypes()).toCommandError)(result).msg); return false; } return true; } - async _nuclideWarningDialog(output: string): Promise { - const event = new OutputEvent(); + async _nuclideWarningDialog(output) { + const event = new (_vscodeDebugadapter || _load_vscodeDebugadapter()).OutputEvent(); event.body = { category: 'nuclide_notification', data: { - type: 'warning', + type: 'warning' }, - output, + output }; return this.sendEvent(event); } - async _logToConsole(output: string): Promise { - const event = new OutputEvent(); + async _logToConsole(output) { + const event = new (_vscodeDebugadapter || _load_vscodeDebugadapter()).OutputEvent(); event.body = { category: 'stdout', data: { - type: 'warning', + type: 'warning' }, - output, + output }; return this.sendEvent(event); } - _onBreakpointModified(record: MIAsyncRecord): void { - const result = breakpointModifiedEventResult(record); - const breakpoint = this._breakpoints.breakpointByDebuggerId( - parseInt(result.bkpt[0].number, 10), - ); + _onBreakpointModified(record) { + const result = (0, (_MITypes || _load_MITypes()).breakpointModifiedEventResult)(record); + const breakpoint = this._breakpoints.breakpointByDebuggerId(parseInt(result.bkpt[0].number, 10)); if (breakpoint != null && !breakpoint.verified) { const handle = this._breakpoints.handleForBreakpoint(breakpoint); - invariant(handle != null); + + if (!(handle != null)) { + throw new Error('Invariant violation: "handle != null"'); + } breakpoint.setVerified(); @@ -1032,32 +835,39 @@ class MIDebugSession extends LoggingDebugSession { id: handle, verified: true, source: { - source: breakpoint.source, + source: breakpoint.source }, - line: breakpoint.line, + line: breakpoint.line }; - const event = new BreakpointEvent(); + const event = new (_vscodeDebugadapter || _load_vscodeDebugadapter()).BreakpointEvent(); event.body = { reason: 'changed', - breakpoint: protocolBreakpoint, + breakpoint: protocolBreakpoint }; this.sendEvent(event); } } - _sendFailureResponse( - response: DebugProtocol.Response, - message?: string, - ): void { + _sendFailureResponse(response, message) { response.success = false; response.message = message; this.sendResponse(response); } -} - -function timestamp(): string { +} /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 timestamp() { let ts = `${new Date().getTime()}`; // This code put seperators in the timestamp in groups of thousands @@ -1082,8 +892,8 @@ function timestamp(): string { return fmt; } -export function logVerbose(line: string): void { - logger.verbose(`${timestamp()} ${line}`); +function logVerbose(line) { + (_vscodeDebugadapter || _load_vscodeDebugadapter()).logger.verbose(`${timestamp()} ${line}`); } -LoggingDebugSession.run(MIDebugSession); +(_vscodeDebugadapter || _load_vscodeDebugadapter()).LoggingDebugSession.run(MIDebugSession); \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/MILineParser.js b/modules/atom-ide-debugger-native-gdb/lib/MILineParser.js index c7af4265cb..64ef4cc8f8 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/MILineParser.js +++ b/modules/atom-ide-debugger-native-gdb/lib/MILineParser.js @@ -1,58 +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 - */ +'use strict'; -/** - * A parser for MI output records. See the grammar at - * https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Output-Syntax.html#GDB_002fMI-Output-Syntax - */ - -import type { - AsyncRecordType, - MICommandResult, - ResultClass, - StreamTarget, - Value, -} from './MIRecord'; - -import {logVerbose} from './MIDebugSession'; -import { - MIAsyncRecord, - MIRecord, - MIResultRecord, - MIStreamRecord, -} from './MIRecord'; - -export default class MILineParser { - _completeInput: string = ''; - _line: string = ''; - - _lineParserDispatch: Map MIRecord> = new Map([ - ['~', (token: ?number) => this._parseStream('console', token)], - ['@', (token: ?number) => this._parseStream('target', token)], - ['&', (token: ?number) => this._parseStream('log', token)], - ['^', (token: ?number) => this._parseResult(token)], - ['*', (token: ?number) => this._parseAsyncOutput('async-exec', token)], - ['+', (token: ?number) => this._parseAsyncOutput('async-status', token)], - ['=', (token: ?number) => this._parseAsyncOutput('async-notify', token)], - ]); - - parseMILine(line: string): MIRecord { +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _MIDebugSession; + +function _load_MIDebugSession() { + return _MIDebugSession = require('./MIDebugSession'); +} + +var _MIRecord; + +function _load_MIRecord() { + return _MIRecord = require('./MIRecord'); +} + +class MILineParser { + constructor() { + this._completeInput = ''; + this._line = ''; + this._lineParserDispatch = new Map([['~', token => this._parseStream('console', token)], ['@', token => this._parseStream('target', token)], ['&', token => this._parseStream('log', token)], ['^', token => this._parseResult(token)], ['*', token => this._parseAsyncOutput('async-exec', token)], ['+', token => this._parseAsyncOutput('async-status', token)], ['=', token => this._parseAsyncOutput('async-notify', token)]]); + this._cEncoded = new Map([['a', 'a'], ['b', '\b'], ['f', '\f'], ['n', '\n'], ['t', '\t'], ['v', '\v']]); + this._valueParsers = new Map([['"', () => this._parseCStringTail()], ['{', () => this._parseTuple()], ['[', () => this._parseList()]]); + } + + parseMILine(line) { this._completeInput = line; // gdb still sends the prompt, but it isn't significant, so just return an // empty record. let trimmed = line.trim(); if (trimmed.startsWith('(gdb)')) { - return new MIRecord(); + return new (_MIRecord || _load_MIRecord()).MIRecord(); } let end = 0; @@ -69,7 +49,7 @@ export default class MILineParser { if (parser == null) { const error = `Line is not an MI record at: '${line}'`; - logVerbose(error); + (0, (_MIDebugSession || _load_MIDebugSession()).logVerbose)(error); throw new Error(error); } @@ -80,28 +60,17 @@ export default class MILineParser { // console-stream-output -> "~" c-string nl // target-stream-output -> "@" c-string nl // log-stream-output -> "&" c-string nl - _parseStream(target: StreamTarget, token: ?number): MIRecord { + _parseStream(target, token) { if (token != null) { - throw new Error( - `Token is not expected on stream record: '${this._completeInput}'`, - ); + throw new Error(`Token is not expected on stream record: '${this._completeInput}'`); } const text = this._parseCString(); - return new MIStreamRecord(target, text); + return new (_MIRecord || _load_MIRecord()).MIStreamRecord(target, text); } - _cEncoded: Map = new Map([ - ['a', 'a'], - ['b', '\b'], - ['f', '\f'], - ['n', '\n'], - ['t', '\t'], - ['v', '\v'], - ]); - // parse a C string as returned by gdb - _parseCString(): string { + _parseCString() { const match = this._line.match(/^"(.*)/); if (match == null) { throw new Error(`Value is not quoted as a C string at: ${this._line}`); @@ -113,13 +82,9 @@ export default class MILineParser { // result-record -> [token] "^" result-class ( "," result )* nl // result-class -> "done" | "running" | "connected" | "error" | "exit" - _parseResult(token: ?number): MIRecord { + _parseResult(token) { let end = 0; - while ( - this._line[end] != null && - this._line[end] >= 'a' && - this._line[end] <= 'z' - ) { + while (this._line[end] != null && this._line[end] >= 'a' && this._line[end] <= 'z') { end++; } @@ -132,7 +97,7 @@ export default class MILineParser { const result = this._parseResultMap(); - return new MIResultRecord(token, result, resultClass); + return new (_MIRecord || _load_MIRecord()).MIResultRecord(token, result, resultClass); } // exec-async-output -> [ token ] "*" async-output nl @@ -141,16 +106,12 @@ export default class MILineParser { // async-output -> async-class ( "," result )* // matches the header of an async record - _parseAsyncOutput(type: AsyncRecordType, token: ?number): MIRecord { + _parseAsyncOutput(type, token) { // NB the grammar doesn't precisely specify what characters may // constitute async-class, but throughout gdb the convention is // lower-case alphabetics so it's probably safe to assume that. let end = 0; - while ( - this._line[end] != null && - ((this._line[end] >= 'a' && this._line[end] <= 'z') || - this._line[end] === '-') - ) { + while (this._line[end] != null && (this._line[end] >= 'a' && this._line[end] <= 'z' || this._line[end] === '-')) { end++; } @@ -166,13 +127,13 @@ export default class MILineParser { result = this._parseResultMap(); } - return new MIAsyncRecord(token, result, asyncClass, type); + return new (_MIRecord || _load_MIRecord()).MIAsyncRecord(token, result, asyncClass, type); } // at this point we have (, result)+ nl from multiple rules // - _parseResultMap(): MICommandResult { - const result: MICommandResult = {}; + _parseResultMap() { + const result = {}; while (this._line != null) { if (this._line[0] !== ',') { @@ -216,15 +177,11 @@ export default class MILineParser { // list -> "[]" | "[" value ( "," value )* "]" | "[" result ( "," result )* "]" // matches the leading part of a value - _valueParsers: Map any> = new Map([ - ['"', () => this._parseCStringTail()], - ['{', () => this._parseTuple()], - ['[', () => this._parseList()], - ]); - _parseValue(): Value { + + _parseValue() { this._line = this._line.trim(); - const handler: ?() => any = this._valueParsers.get(this._line[0]); + const handler = this._valueParsers.get(this._line[0]); this._line = this._line.substr(1); if (handler == null) { @@ -236,7 +193,7 @@ export default class MILineParser { // tuple -> "{}" | "{" result ( "," result )* "}" // The leading { has already been removed - _parseTuple(endChar: string = '}'): Value { + _parseTuple(endChar = '}') { if (this._line[0] === endChar) { this._line = this._line.substr(1); return {}; @@ -269,8 +226,8 @@ export default class MILineParser { // // matches a result (varname=value) - _parseList(): Value { - const result: Array = []; + _parseList() { + const result = []; if (this._line[0] === ']') { this._line = this._line.substr(1); @@ -290,7 +247,7 @@ export default class MILineParser { const varname = this._line.substr(0, equals); this._line = this._line.substr(equals + 1); const value = this._parseValue(); - result.push({[varname]: value}); + result.push({ [varname]: value }); } this._line = this._line.trim(); @@ -309,14 +266,8 @@ export default class MILineParser { return result; } - _ensureResultClass(resultClass: string): ResultClass { - if ( - resultClass !== 'done' && - resultClass !== 'running' && - resultClass !== 'connected' && - resultClass !== 'error' && - resultClass !== 'exit' - ) { + _ensureResultClass(resultClass) { + if (resultClass !== 'done' && resultClass !== 'running' && resultClass !== 'connected' && resultClass !== 'error' && resultClass !== 'exit') { throw new Error(`Result class expected at '${this._line}'`); } @@ -325,16 +276,16 @@ export default class MILineParser { // $TODO escapes that include values, e.g. "A\x42C" should be "ABC" // Parse a C string for which the leading quote has already been stripped - _parseCStringTail(): string { - let parsed: string = ''; - let ended: boolean = false; - let escaped: boolean = false; - let i: number; + _parseCStringTail() { + let parsed = ''; + let ended = false; + let escaped = false; + let i; for (i = 0; i < this._line.length && !ended; i++) { - const c: string = this._line[i]; + const c = this._line[i]; if (escaped) { - const translated: ?string = this._cEncoded.get(c); + const translated = this._cEncoded.get(c); parsed += translated != null ? translated : c; escaped = false; } else if (c === '\\') { @@ -354,3 +305,19 @@ export default class MILineParser { return parsed; } } +exports.default = MILineParser; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 + */ + +/** + * A parser for MI output records. See the grammar at + * https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Output-Syntax.html#GDB_002fMI-Output-Syntax + */ \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/MIProxy.js b/modules/atom-ide-debugger-native-gdb/lib/MIProxy.js index acb2b50843..98b19384e7 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/MIProxy.js +++ b/modules/atom-ide-debugger-native-gdb/lib/MIProxy.js @@ -1,81 +1,66 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict-local - * @format - */ - -import * as child_process from 'child_process'; - -import invariant from 'assert'; -import {logVerbose} from './MIDebugSession'; - -import MILineParser from './MILineParser'; -import { - MIAsyncRecord, - MIRecord, - MIResultRecord, - MIStreamRecord, -} from './MIRecord'; - -export type StreamTarget = 'console' | 'target' | 'log'; - -import EventEmitter from 'events'; - -type PendingCommand = { - command: string, - resolve: (result: MIResultRecord) => void, -}; - -export default class MIProxy extends EventEmitter { - _miServer: ?child_process$ChildProcess; - _parser: MILineParser; - _lastPartialString: string; - _nextToken: number; - _pendingCommands: Map; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _child_process = _interopRequireWildcard(require('child_process')); + +var _MIDebugSession; + +function _load_MIDebugSession() { + return _MIDebugSession = require('./MIDebugSession'); +} + +var _MILineParser; + +function _load_MILineParser() { + return _MILineParser = _interopRequireDefault(require('./MILineParser')); +} + +var _MIRecord; + +function _load_MIRecord() { + return _MIRecord = require('./MIRecord'); +} + +var _events = _interopRequireDefault(require('events')); + +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 MIProxy extends _events.default { constructor() { super(); - this._parser = new MILineParser(); + this._parser = new (_MILineParser || _load_MILineParser()).default(); this._nextToken = 1; this._lastPartialString = ''; this._pendingCommands = new Map(); } - isConnected(): boolean { + isConnected() { return this._miServer != null; } - start( - executable: string, - args: Array, - env: ?{[string]: string}, - ): void { + start(executable, args, env) { if (this._miServer != null) { this.stop(); } let options = {}; if (env != null) { - options = { - ...options, - env: { - ...process.env, - ...env, - }, - }; + options = Object.assign({}, options, { + env: Object.assign({}, process.env, env) + }); } - const proc = child_process.spawn(executable, args, options); + const proc = _child_process.spawn(executable, args, options); this._miServer = proc; - proc.stdout.on('data', (buffer: Buffer) => this._onData(buffer)); + proc.stdout.on('data', buffer => this._onData(buffer)); proc.on('error', err => { this.emit('error', err); }); @@ -84,7 +69,7 @@ export default class MIProxy extends EventEmitter { }); } - pause(): void { + pause() { const server = this._miServer; if (server == null) { return; @@ -93,90 +78,86 @@ export default class MIProxy extends EventEmitter { server.kill('SIGINT'); } - stop(): void { + stop() { if (this._miServer != null) { this._miServer.disconnect(); this._miServer = null; } } - async sendCommand(command: string): Promise { + async sendCommand(command) { return new Promise((resolve, reject) => { const dbg = this._miServer; if (dbg == null) { - reject( - new Error('Attempt to send a command when no MI server connected'), - ); + reject(new Error('Attempt to send a command when no MI server connected')); return; } const token = this._nextToken++; - const pendingCommand: PendingCommand = { + const pendingCommand = { command, token, - resolve: (record: MIResultRecord) => {}, + resolve: record => {} }; pendingCommand.resolve = resolve; this._pendingCommands.set(token, pendingCommand); const tokenizedCommand = `${token}-${command}\n`; - logVerbose(`MIProxy sending command '${tokenizedCommand}' to server`); + (0, (_MIDebugSession || _load_MIDebugSession()).logVerbose)(`MIProxy sending command '${tokenizedCommand}' to server`); dbg.stdin.write(tokenizedCommand); }); } - _onData(buffer: Buffer): void { + _onData(buffer) { // NB data coming back from gdb will be ASCII, and data from the target - // does not come over this channel. - const str: string = this._lastPartialString + buffer.toString('ASCII'); + const str = this._lastPartialString + buffer.toString('ASCII'); - const tailSplit: number = str.lastIndexOf('\n'); + const tailSplit = str.lastIndexOf('\n'); if (tailSplit === -1) { this._lastPartialString = str; return; } this._lastPartialString = str.substr(tailSplit + 1); - str - .substr(0, tailSplit) - .split('\n') - .forEach((line: string) => this._onLine(line.trim())); + str.substr(0, tailSplit).split('\n').forEach(line => this._onLine(line.trim())); } - _onLine(line: string): void { + _onLine(line) { if (line === '') { return; } - logVerbose(`proxy received line ${line}`); + (0, (_MIDebugSession || _load_MIDebugSession()).logVerbose)(`proxy received line ${line}`); const parsed = this._parser.parseMILine(line); this._emitRecord(parsed, line); } - _emitRecord(record: MIRecord, line: string): void { - if (record instanceof MIResultRecord) { + _emitRecord(record, line) { + if (record instanceof (_MIRecord || _load_MIRecord()).MIResultRecord) { const token = record.token; - invariant(token != null, 'token should always exist in a result record'); + + if (!(token != null)) { + throw new Error('token should always exist in a result record'); + } + const pending = this._pendingCommands.get(token); if (pending != null) { pending.resolve(record); this._pendingCommands.delete(token); return; } - logVerbose( - `Received response with token ${token} which matches no pending command`, - ); + (0, (_MIDebugSession || _load_MIDebugSession()).logVerbose)(`Received response with token ${token} which matches no pending command`); } - if (record instanceof MIAsyncRecord) { + if (record instanceof (_MIRecord || _load_MIRecord()).MIAsyncRecord) { this.emit('async', record); - } else if (record instanceof MIStreamRecord) { + } else if (record instanceof (_MIRecord || _load_MIRecord()).MIStreamRecord) { if (!this._hackForAttachPermissions(record)) { this.emit('stream', record); } } } - _hackForAttachPermissions(record: MIStreamRecord): boolean { + _hackForAttachPermissions(record) { if (record.streamTarget !== 'log') { return false; } @@ -185,9 +166,7 @@ export default class MIProxy extends EventEmitter { return false; } - const attach = [...this._pendingCommands].find( - _ => _[1].command.match(/target-attach/) != null, - ); + const attach = [...this._pendingCommands].find(_ => _[1].command.match(/target-attach/) != null); if (attach == null) { return false; @@ -203,14 +182,21 @@ export default class MIProxy extends EventEmitter { // MI failure in this case; it prints a message to the log saying how // to fix the problem but the command never actually completes. Hence // this hack... - const failure = new MIResultRecord( - token, - {msg: record.text.replace('\n', ' ')}, - 'error', - ); + const failure = new (_MIRecord || _load_MIRecord()).MIResultRecord(token, { msg: record.text.replace('\n', ' ') }, 'error'); command.resolve(failure); this._pendingCommands.delete(token); return true; } } +exports.default = MIProxy; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/MIRecord.js b/modules/atom-ide-debugger-native-gdb/lib/MIRecord.js index 95e3ecdc99..1b1031663a 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/MIRecord.js +++ b/modules/atom-ide-debugger-native-gdb/lib/MIRecord.js @@ -1,3 +1,12 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +class MIRecord {} + +exports.MIRecord = MIRecord; // A stream record represents output. It is not tied to a particular +// command sent by the client. /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,121 +15,95 @@ * LICENSE file in 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 AsyncRecordType = 'async-exec' | 'async-status' | 'async-notify'; - -export type StreamTarget = 'console' | 'target' | 'log'; - -export type ResultClass = 'done' | 'running' | 'connected' | 'error' | 'exit'; - -export type Value = string | MICommandResult | Array; - -export type MICommandResult = {[string]: Value}; +class MIStreamRecord extends MIRecord { -export class MIRecord {} - -// A stream record represents output. It is not tied to a particular -// command sent by the client. -export class MIStreamRecord extends MIRecord { - _streamTarget: StreamTarget; - _text: string; - - constructor(streamTarget: StreamTarget, text: string) { + constructor(streamTarget, text) { super(); this._streamTarget = streamTarget; this._text = text; } - get streamTarget(): StreamTarget { + get streamTarget() { return this._streamTarget; } - get text(): string { + get text() { return this._text; } } -// A command response record represents an event initiated by a command the +exports.MIStreamRecord = MIStreamRecord; // A command response record represents an event initiated by a command the // client issued, either directly or indirectly. Command responses optionally // have a numeric token specified by the client when the command was issued. -export class MICommandResponseRecord extends MIRecord { - _token: ?number; - _result: MICommandResult; - constructor(token: ?number, result: MICommandResult) { +class MICommandResponseRecord extends MIRecord { + + constructor(token, result) { super(); this._token = token; this._result = result; } - get token(): ?number { + get token() { return this._token; } - get result(): MICommandResult { + get result() { return this._result; } } -// An async record represents an event that happened as a side effect of +exports.MICommandResponseRecord = MICommandResponseRecord; // An async record represents an event that happened as a side effect of // a command, but is not the actual command result. -export class MIAsyncRecord extends MICommandResponseRecord { - _recordType: AsyncRecordType; - _asyncClass: string; - - constructor( - token: ?number, - result: MICommandResult, - asyncClass: string, - recordType: AsyncRecordType, - ) { + +class MIAsyncRecord extends MICommandResponseRecord { + + constructor(token, result, asyncClass, recordType) { super(token, result); this._asyncClass = asyncClass; this._recordType = recordType; } - get asyncClass(): string { + get asyncClass() { return this._asyncClass; } - get recordType(): AsyncRecordType { + get recordType() { return this._recordType; } } -// A result record is the direct result of a command sent from the client -export class MIResultRecord extends MICommandResponseRecord { - _resultClass: ResultClass; +exports.MIAsyncRecord = MIAsyncRecord; // A result record is the direct result of a command sent from the client + +class MIResultRecord extends MICommandResponseRecord { - constructor( - token: ?number, - result: MICommandResult, - resultClass: ResultClass, - ) { + constructor(token, result, resultClass) { super(token, result); this._resultClass = resultClass; } - get resultClass(): ResultClass { + get resultClass() { return this._resultClass; } - get done(): boolean { + get done() { return this._resultClass === 'done'; } - get error(): boolean { + get error() { return this._resultClass === 'error'; } - get running(): boolean { + get running() { return this._resultClass === 'running'; } } +exports.MIResultRecord = MIResultRecord; \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/MIRegisterValue.js b/modules/atom-ide-debugger-native-gdb/lib/MIRegisterValue.js index 4b0b12baba..dfc745185c 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/MIRegisterValue.js +++ b/modules/atom-ide-debugger-native-gdb/lib/MIRegisterValue.js @@ -1,174 +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 - */ +'use strict'; -// The MI documentation doesn't cover this, but gdb will return structured values -// for registers which contain packed arrays of simple types (MMX et al.) -// Furthermore, if the register can hold different widths of values, then -// there is an intermediate node for each possible representation it can hold. -// -// The syntax is similar to MI result record values: -// value => simple_value | named_list | indexed_list -// simple_value => float-value | integer-value -// named_list => '{' identifer '=' value ( ',' identifier '=' value ) * '}' -// indexed_list => '{' value ( ',' value ) * '}' -// - -import invariant from 'assert'; - -export type MINamedRegisterValue = { - name: string, - expressionSuffix: string, - value: MIRegisterValue, -}; - -export class MIRegisterValue { - toString(): string { +Object.defineProperty(exports, "__esModule", { + value: true +}); +class MIRegisterValue { + toString() { return ''; } - isContainer(): boolean { + isContainer() { return false; } - containedValues(): Array { + containedValues() { return []; } - get containerKeyIsString(): boolean { + get containerKeyIsString() { return false; } - get length(): number { + get length() { return 0; } - valueAt(index: string): ?MIRegisterValue { + valueAt(index) { return null; } } -export class MIRegisterSimpleValue extends MIRegisterValue { - _value: string; +exports.MIRegisterValue = MIRegisterValue; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 + */ - constructor(value: string) { +// The MI documentation doesn't cover this, but gdb will return structured values +// for registers which contain packed arrays of simple types (MMX et al.) +// Furthermore, if the register can hold different widths of values, then +// there is an intermediate node for each possible representation it can hold. +// +// The syntax is similar to MI result record values: +// value => simple_value | named_list | indexed_list +// simple_value => float-value | integer-value +// named_list => '{' identifer '=' value ( ',' identifier '=' value ) * '}' +// indexed_list => '{' value ( ',' value ) * '}' +// + +class MIRegisterSimpleValue extends MIRegisterValue { + + constructor(value) { super(); this._value = value; } - get value(): string { + get value() { return this._value; } - toString(): string { + toString() { return this._value; } } -export class MIRegisterNamedValues extends MIRegisterValue { - _values: Map; +exports.MIRegisterSimpleValue = MIRegisterSimpleValue; +class MIRegisterNamedValues extends MIRegisterValue { - constructor(values: Map) { + constructor(values) { super(); this._values = values; } - isContainer(): boolean { + isContainer() { return true; } - get names(): Array { + get names() { return [...this._values.keys()]; } - get containerKeyIsString(): boolean { + get containerKeyIsString() { return true; } - get length(): number { + get length() { return this._values.size; } - valueAt(index: string): ?MIRegisterValue { + valueAt(index) { return this._values.get(index); } - containedValues(): Array { + containedValues() { return [...this._values].map(entry => { return { name: entry[0], expressionSuffix: `.${entry[0]}`, - value: entry[1], + value: entry[1] }; }); } - toString(): string { - return `{${[...this._values] - .map(([k, v]) => `${k}:${v.toString()}`) - .join(',')}}`; + toString() { + return `{${[...this._values].map(([k, v]) => `${k}:${v.toString()}`).join(',')}}`; } } -export class MIRegisterIndexedValues extends MIRegisterValue { - _values: Array; +exports.MIRegisterNamedValues = MIRegisterNamedValues; +class MIRegisterIndexedValues extends MIRegisterValue { - constructor(values: Array) { + constructor(values) { super(); this._values = values; } - isContainer(): boolean { + isContainer() { return true; } - get length(): number { + get length() { return this._values.length; } - valueAt(index: string): ?MIRegisterValue { + valueAt(index) { return this._values[parseInt(index, 10)]; } - get values(): Array { + get values() { return this._values; } - containedValues(): Array { + containedValues() { return this._values.map((entry, index) => { return { name: `${index}`, expressionSuffix: `[${index}]`, - value: entry, + value: entry }; }); } - toString(): string { + toString() { return `[${this._values.map(_ => _.toString()).join(',')}]`; } } -export class MIRegisterValueParser { - _originalExpression: string; - _expression: string; +exports.MIRegisterIndexedValues = MIRegisterIndexedValues; +class MIRegisterValueParser { - // matches name = something - _namePattern: RegExp = /^\s*([a-zA-Z_][a-zA-Z_0-9]*)\s*=(.*)/; + constructor(expression) { + this._namePattern = /^\s*([a-zA-Z_][a-zA-Z_0-9]*)\s*=(.*)/; - constructor(expression: string) { this._originalExpression = expression; } - parse(): MIRegisterValue { + // matches name = something + + + parse() { this._expression = this._originalExpression; const value = this._parse(); @@ -178,7 +173,7 @@ export class MIRegisterValueParser { return value; } - _parse(): MIRegisterValue { + _parse() { this._expression = this._expression.trim(); if (this._expression === '') { @@ -188,7 +183,10 @@ export class MIRegisterValueParser { if (this._expression[0] !== '{') { // expression value goes until the next ',', '}', or end of string. const match = this._expression.match(/^([^,}]*)(.*)$/); - invariant(match != null); + + if (!(match != null)) { + throw new Error('Invariant violation: "match != null"'); + } const [, value, rest] = match; @@ -207,8 +205,8 @@ export class MIRegisterValueParser { return this._parseIndexedList(); } - _parseIndexedList(): MIRegisterValue { - const values: Array = []; + _parseIndexedList() { + const values = []; while (true) { const value = this._parse(); @@ -227,10 +225,7 @@ export class MIRegisterValueParser { // gdb/MI will sometimes reformat an array if it contains multiple repeated // values. This is great for saving space in displayable output, but we want // the expansion to be available to be expanded in tree display. - _expandArrayInto( - value: MIRegisterValue, - values: Array, - ): boolean { + _expandArrayInto(value, values) { if (value instanceof MIRegisterSimpleValue) { const repeatedValuePattern = /^(.*) $/; const match = value.value.match(repeatedValuePattern); @@ -247,8 +242,8 @@ export class MIRegisterValueParser { return false; } - _parseNamedList(): MIRegisterValue { - const values: Map = new Map(); + _parseNamedList() { + const values = new Map(); while (true) { const match = this._expression.match(this._namePattern); @@ -269,7 +264,7 @@ export class MIRegisterValueParser { return new MIRegisterNamedValues(values); } - _checkEndOfList(): boolean { + _checkEndOfList() { this._expression = this._expression.trim(); if (this._expression !== '') { const sepChar = this._expression[0]; @@ -284,3 +279,4 @@ export class MIRegisterValueParser { throw new Error('Improperly formatted list in register value'); } } +exports.MIRegisterValueParser = MIRegisterValueParser; \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/MITypes.js b/modules/atom-ide-debugger-native-gdb/lib/MITypes.js index cc347e2a16..74bb57565f 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/MITypes.js +++ b/modules/atom-ide-debugger-native-gdb/lib/MITypes.js @@ -1,3 +1,36 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.toCommandError = toCommandError; +exports.breakInsertResult = breakInsertResult; +exports.dataEvaluateExpressionResult = dataEvaluateExpressionResult; +exports.dataListRegisterNamesResult = dataListRegisterNamesResult; +exports.dataListRegisterValuesResult = dataListRegisterValuesResult; +exports.threadInfoResult = threadInfoResult; +exports.stackInfoDepthResult = stackInfoDepthResult; +exports.stackListFramesResult = stackListFramesResult; +exports.stackListVariablesResult = stackListVariablesResult; +exports.varCreateResult = varCreateResult; +exports.varListChildrenResult = varListChildrenResult; +exports.varInfoNumChildrenResult = varInfoNumChildrenResult; +exports.varInfoTypeResult = varInfoTypeResult; +exports.varEvaluateExpressionResult = varEvaluateExpressionResult; +exports.varAssignResult = varAssignResult; +exports.stoppedEventResult = stoppedEventResult; +exports.breakpointModifiedEventResult = breakpointModifiedEventResult; +exports.dataDisassembleResult = dataDisassembleResult; + +var _MIRecord; + +function _load_MIRecord() { + return _MIRecord = require('./MIRecord'); +} + +// Type conversions from a generic MI record to command-specfic results + +// failure from any command where resultClass is 'error' /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,281 +39,167 @@ * LICENSE file in 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 {MIAsyncRecord, MIResultRecord} from './MIRecord'; - -// Type conversions from a generic MI record to command-specfic results +function toCommandError(record) { + if (!record.error) { + throw new Error('Invariant violation: "record.error"'); + } -// failure from any command where resultClass is 'error' -export type MICommandError = { - msg: string, -}; - -export function toCommandError(record: MIResultRecord): MICommandError { - invariant(record.error); - return ((record.result: any): MICommandError); + return record.result; } // break-insert -export type MIBreakpoint = { - number: string, - line?: string, - 'original-location'?: string, - file?: string, - fullname?: string, - pending?: string, -}; - -export type MIBreakInsertResult = { - bkpt: [MIBreakpoint], -}; - -export function breakInsertResult(record: MIResultRecord): MIBreakInsertResult { - invariant(!record.error); - return ((record.result: any): MIBreakInsertResult); +function breakInsertResult(record) { + if (!!record.error) { + throw new Error('Invariant violation: "!record.error"'); + } + + return record.result; } // data-evaluate-expression -export type MIDataEvaluateExpressionResult = { - value: string, -}; - -export function dataEvaluateExpressionResult( - record: MIResultRecord, -): MIDataEvaluateExpressionResult { - invariant(!record.error); - return ((record.result: any): MIDataEvaluateExpressionResult); +function dataEvaluateExpressionResult(record) { + if (!!record.error) { + throw new Error('Invariant violation: "!record.error"'); + } + + return record.result; } // data-list-register-names -export type MIDataListRegisterNamesResult = { - 'register-names': Array, -}; - -export function dataListRegisterNamesResult( - record: MIResultRecord, -): MIDataListRegisterNamesResult { - invariant(!record.error); - return ((record.result: any): MIDataListRegisterNamesResult); +function dataListRegisterNamesResult(record) { + if (!!record.error) { + throw new Error('Invariant violation: "!record.error"'); + } + + return record.result; } // data-list-register-values -export type MIDataListRegisterValuesResult = { - 'register-values': Array<{ - number: string, - value: string, - }>, -}; - -export function dataListRegisterValuesResult( - record: MIResultRecord, -): MIDataListRegisterValuesResult { - invariant(!record.error); - return ((record.result: any): MIDataListRegisterValuesResult); +function dataListRegisterValuesResult(record) { + if (!!record.error) { + throw new Error('Invariant violation: "!record.error"'); + } + + return record.result; } // thread-info -export type MIThreadInfo = { - id: string, // this is a globally unique id for the thread - 'target-id': string, // this is an id that is only unique in the target the thread is running in - details?: string, - name?: string, - frame: MIStackFrame, - state: 'stopped' | 'running', - core?: string, -}; - -export type MIThreadInfoResult = { - threads: [MIThreadInfo], - 'current-thread-id': string, -}; - -export function threadInfoResult(record: MIResultRecord): MIThreadInfoResult { - invariant(!record.error); - return ((record.result: any): MIThreadInfoResult); +function threadInfoResult(record) { + if (!!record.error) { + throw new Error('Invariant violation: "!record.error"'); + } + + return record.result; } // stack-info-depth -export type MIStackInfoDepthResult = { - depth: string, -}; - -export function stackInfoDepthResult( - record: MIResultRecord, -): MIStackInfoDepthResult { - invariant(!record.error); - return ((record.result: any): MIStackInfoDepthResult); +function stackInfoDepthResult(record) { + if (!!record.error) { + throw new Error('Invariant violation: "!record.error"'); + } + + return record.result; } // stack-list-frames -export type MIStackFrame = { - level: string, // a decimal integer, 0 is the most recent frame - addr: string, - func: string, - file?: string, - fullname?: string, - line?: string, - from?: string, -}; - -export type MIStackListFramesResult = { - stack: Array<{ - frame: MIStackFrame, - }>, -}; - -export function stackListFramesResult( - record: MIResultRecord, -): MIStackListFramesResult { - invariant(!record.error); - return ((record.result: any): MIStackListFramesResult); +function stackListFramesResult(record) { + if (!!record.error) { + throw new Error('Invariant violation: "!record.error"'); + } + + return record.result; } // stack-list-variables -export type MIVariable = { - name: string, - arg?: string, // if present, flags if variable is a function argument - value?: string, // if missing, means this is a container (array, struct, etc.) -}; - -export type MIStackListVariablesResult = { - variables: Array, -}; - -export function stackListVariablesResult( - record: MIResultRecord, -): MIStackListVariablesResult { - invariant(!record.error); - return ((record.result: any): MIStackListVariablesResult); +function stackListVariablesResult(record) { + if (!!record.error) { + throw new Error('Invariant violation: "!record.error"'); + } + + return record.result; } // var-create -export type MIVarCreateResult = { - name: string, - numchild: string, - value: string, - type: string, - 'thread-id': string, - has_more: string, -}; - -export function varCreateResult(record: MIResultRecord): MIVarCreateResult { - invariant(!record.error); - return ((record.result: any): MIVarCreateResult); +function varCreateResult(record) { + if (!!record.error) { + throw new Error('Invariant violation: "!record.error"'); + } + + return record.result; } // var-list-children -export type MIVarChild = { - child: { - name: string, - exp: string, - numchild: string, - value?: string, - type: string, - 'thread-id': string, - }, -}; - -export type MIVarListChildrenResult = { - numchild: string, - children: Array, - has_more: string, -}; - -export function varListChildrenResult( - record: MIResultRecord, -): MIVarListChildrenResult { - invariant(!record.error); - return ((record.result: any): MIVarListChildrenResult); +function varListChildrenResult(record) { + if (!!record.error) { + throw new Error('Invariant violation: "!record.error"'); + } + + return record.result; } // var-info-num-children -export type MIVarInfoNumChildrenResult = { - numchild: string, -}; - -export function varInfoNumChildrenResult( - record: MIResultRecord, -): MIVarInfoNumChildrenResult { - invariant(!record.error); - return ((record.result: any): MIVarInfoNumChildrenResult); +function varInfoNumChildrenResult(record) { + if (!!record.error) { + throw new Error('Invariant violation: "!record.error"'); + } + + return record.result; } // var-info-type -export type MIVarInfoTypeResult = { - type: string, -}; +function varInfoTypeResult(record) { + if (!!record.error) { + throw new Error('Invariant violation: "!record.error"'); + } -export function varInfoTypeResult(record: MIResultRecord): MIVarInfoTypeResult { - invariant(!record.error); - return ((record.result: any): MIVarInfoTypeResult); + return record.result; } // var-evaluate-expression -export type MIVarEvaluateExpressionResult = { - value: string, -}; - -export function varEvaluateExpressionResult( - record: MIResultRecord, -): MIVarEvaluateExpressionResult { - invariant(!record.error); - return ((record.result: any): MIVarEvaluateExpressionResult); +function varEvaluateExpressionResult(record) { + if (!!record.error) { + throw new Error('Invariant violation: "!record.error"'); + } + + return record.result; } // var-assign -export type MIVarAssignResult = { - value: string, -}; +function varAssignResult(record) { + if (!!record.error) { + throw new Error('Invariant violation: "!record.error"'); + } -export function varAssignResult(record: MIResultRecord): MIVarAssignResult { - invariant(!record.error); - return ((record.result: any): MIVarAssignResult); + return record.result; } // stopped async event -export type MIStoppedEventResult = { - reason: string, - bkptno: ?string, - 'thread-id': string, -}; - -export function stoppedEventResult( - record: MIAsyncRecord, -): MIStoppedEventResult { - invariant(record.asyncClass === 'stopped'); - return ((record.result: any): MIStoppedEventResult); +function stoppedEventResult(record) { + if (!(record.asyncClass === 'stopped')) { + throw new Error('Invariant violation: "record.asyncClass === \'stopped\'"'); + } + + return record.result; } // breakpoint modified event -export type MIBreakpointModifiedEventResult = { - bkpt: [MIBreakpoint], -}; - -export function breakpointModifiedEventResult( - record: MIAsyncRecord, -): MIBreakpointModifiedEventResult { - invariant(record.asyncClass === 'breakpoint-modified'); - return ((record.result: any): MIBreakpointModifiedEventResult); +function breakpointModifiedEventResult(record) { + if (!(record.asyncClass === 'breakpoint-modified')) { + throw new Error('Invariant violation: "record.asyncClass === \'breakpoint-modified\'"'); + } + + return record.result; } // data-disassemble result -export type MIDisassembleInstruction = { - address: string, - inst: string, -}; - -export type MIDataDisassembleResult = { - asm_insns: Array, -}; - -export function dataDisassembleResult( - record: MIResultRecord, -): MIDataDisassembleResult { - invariant(!record.error); - return ((record.result: any): MIDataDisassembleResult); -} +function dataDisassembleResult(record) { + if (!!record.error) { + throw new Error('Invariant violation: "!record.error"'); + } + + return record.result; +} \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/NestedVariableReference.js b/modules/atom-ide-debugger-native-gdb/lib/NestedVariableReference.js index da043f2997..b9e868eabb 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/NestedVariableReference.js +++ b/modules/atom-ide-debugger-native-gdb/lib/NestedVariableReference.js @@ -1,43 +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 type {Variable} from 'vscode-debugprotocol'; - -import invariant from 'assert'; -import MIProxy from './MIProxy'; -import {toCommandError, varListChildrenResult} from './MITypes'; -import VariableReference from './VariableReference'; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _MIProxy; + +function _load_MIProxy() { + return _MIProxy = _interopRequireDefault(require('./MIProxy')); +} + +var _MITypes; + +function _load_MITypes() { + return _MITypes = require('./MITypes'); +} + +var _VariableReference; + +function _load_VariableReference() { + return _VariableReference = _interopRequireDefault(require('./VariableReference')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // A NestedVariableReference refers to a set of variables in another variable // (struct, union, etc.) -export default class NestedVariableReference extends VariableReference { - _type: ?string; - _qualifiedName: string; - _needsDeletion: boolean; - - constructor( - client: MIProxy, - variables: Variables, - container: VariableReference, - expression: string, // exp is the expression in the source language naming the variable - varName: ?string, // name is the internal gdb variable name, used to get the value - ) { +class NestedVariableReference extends (_VariableReference || _load_VariableReference()).default { + + constructor(client, variables, container, expression, // exp is the expression in the source language naming the variable + varName) // name is the internal gdb variable name, used to get the value + { super({ client, variables, expression, threadId: container.threadId, frameIndex: container.frameIndex, - varName, + varName }); // We will lazily create the variable binding to MI, so we only // have to do it for ones the user actually wants to drill into. @@ -49,62 +49,72 @@ export default class NestedVariableReference extends VariableReference { this._needsDeletion = varName == null; } - async getVariables(start: ?number, count: ?number): Promise> { + async getVariables(start, count) { if (this._varName == null) { await this._createVariableBinding(this._expression); } const varName = this._varName; - invariant(varName != null); + + if (!(varName != null)) { + throw new Error('Invariant violation: "varName != null"'); + } // var-list-children -no-values name from to (zero-based, from 'from and up to and including 'to') + + const command = `var-list-children --no-values ${varName}`; const result = await this._client.sendCommand(command); if (result.error) { - throw new Error( - `Error getting variable's children (${toCommandError(result).msg})`, - ); + throw new Error(`Error getting variable's children (${(0, (_MITypes || _load_MITypes()).toCommandError)(result).msg})`); } - const miVariables = varListChildrenResult(result).children; + const miVariables = (0, (_MITypes || _load_MITypes()).varListChildrenResult)(result).children; const resolvedStart = start == null ? 0 : start; - const resolvedEnd = - count == null ? miVariables.length - resolvedStart : start + count; - - return Promise.all( - miVariables.slice(resolvedStart, resolvedEnd).map(async _ => { - const child = _.child; - - const handle = this._variables.nestedVariableReference( - this, - child.exp, - child.name, - ); - - return this.variableFromVarRefHandle(handle, child.exp, child.type); - }), - ); + const resolvedEnd = count == null ? miVariables.length - resolvedStart : start + count; + + return Promise.all(miVariables.slice(resolvedStart, resolvedEnd).map(async _ => { + const child = _.child; + + const handle = this._variables.nestedVariableReference(this, child.exp, child.name); + + return this.variableFromVarRefHandle(handle, child.exp, child.type); + })); } - get needsDeletion(): boolean { + get needsDeletion() { return this._needsDeletion; } - async _getVarName(): Promise { + async _getVarName() { if (this._varName != null) { return this._varName; } await this._createVariableBinding(this._expression); const varName = this._varName; - invariant(varName != null); + + if (!(varName != null)) { + throw new Error('Invariant violation: "varName != null"'); + } return varName; } - get qualifiedName(): string { + get qualifiedName() { return this._qualifiedName; } } +exports.default = NestedVariableReference; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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-debugger-native-gdb/lib/RegisterElementVariableReference.js b/modules/atom-ide-debugger-native-gdb/lib/RegisterElementVariableReference.js index 18bfb9687d..40933e7a84 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/RegisterElementVariableReference.js +++ b/modules/atom-ide-debugger-native-gdb/lib/RegisterElementVariableReference.js @@ -1,70 +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 {MINamedRegisterValue} from './MIRegisterValue'; -import type {SetChildResponse} from './VariableReference'; -import type {Variable} from 'vscode-debugprotocol'; -import type {VariableTypeClass} from './VariableReference'; - -import invariant from 'assert'; -import MIProxy from './MIProxy'; -import {MIRegisterValue} from './MIRegisterValue'; -import RegistersVariableReference from './RegistersVariableReference'; -import {toCommandError, dataEvaluateExpressionResult} from './MITypes'; -import VariableReference from './VariableReference'; -import Variables from './Variables'; - -export default class RegisterElementVariableReference extends VariableReference { - _value: MIRegisterValue; - _name: string; - _containedVariables: Array; - _childrenByName: Map; - - constructor( - client: MIProxy, - variables: Variables, - name: string, - expression: string, - value: MIRegisterValue, - ) { - super({client, variables, expression}); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _MIProxy; + +function _load_MIProxy() { + return _MIProxy = _interopRequireDefault(require('./MIProxy')); +} + +var _MIRegisterValue; + +function _load_MIRegisterValue() { + return _MIRegisterValue = require('./MIRegisterValue'); +} + +var _RegistersVariableReference; + +function _load_RegistersVariableReference() { + return _RegistersVariableReference = _interopRequireDefault(require('./RegistersVariableReference')); +} + +var _MITypes; + +function _load_MITypes() { + return _MITypes = require('./MITypes'); +} + +var _VariableReference; + +function _load_VariableReference() { + return _VariableReference = _interopRequireDefault(require('./VariableReference')); +} + +var _Variables; + +function _load_Variables() { + return _Variables = _interopRequireDefault(require('./Variables')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class RegisterElementVariableReference extends (_VariableReference || _load_VariableReference()).default { + + constructor(client, variables, name, expression, value) { + super({ client, variables, expression }); this._value = value; this._name = name; this._containedVariables = this._value.containedValues().map(v => { - return RegistersVariableReference.variableFromRegisterValue( - this._variables, - v.name, - `${this._expression}${v.expressionSuffix}`, - v.value, - ); + return (_RegistersVariableReference || _load_RegistersVariableReference()).default.variableFromRegisterValue(this._variables, v.name, `${this._expression}${v.expressionSuffix}`, v.value); }); - this._childrenByName = new Map( - this._value.containedValues().map(v => [v.name, v]), - ); + this._childrenByName = new Map(this._value.containedValues().map(v => [v.name, v])); } - async getVariables(start: ?number, count: ?number): Promise> { + async getVariables(start, count) { const resolvedStart = start == null ? 0 : start; const resolvedCount = count == null ? await this.getChildCount() : count; - return this._containedVariables.slice( - resolvedStart, - resolvedStart + resolvedCount, - ); + return this._containedVariables.slice(resolvedStart, resolvedStart + resolvedCount); } - async getTypeClass(value: string): Promise { + async getTypeClass(value) { if (!this._value.isContainer()) { return 'simple'; } @@ -76,51 +75,57 @@ export default class RegisterElementVariableReference extends VariableReference return 'indexed'; } - async getType(): Promise { + async getType() { if (!this._value.isContainer()) { return 'int'; } return '[]'; } - async getValue(): Promise { + async getValue() { return this._value.toString(); } - async getChildCount(): Promise { + async getChildCount() { return this._value.length; } - async setChildValue(name: string, value: string): Promise { + async setChildValue(name, value) { const nestedValue = this._childrenByName.get(name); - invariant(nestedValue != null); + + if (!(nestedValue != null)) { + throw new Error('Invariant violation: "nestedValue != null"'); + } if (nestedValue.value.isContainer()) { - throw new Error( - 'Cannot edit aggregate value directly, please edit individual components.', - ); + throw new Error('Cannot edit aggregate value directly, please edit individual components.'); } - const result = await this._client.sendCommand( - `data-evaluate-expression ${this._expression}${ - nestedValue.expressionSuffix - }=${value}`, - ); + const result = await this._client.sendCommand(`data-evaluate-expression ${this._expression}${nestedValue.expressionSuffix}=${value}`); if (result.error) { - throw new Error( - `Unable to change register value ${toCommandError(result).msg}`, - ); + throw new Error(`Unable to change register value ${(0, (_MITypes || _load_MITypes()).toCommandError)(result).msg}`); } - const newValue = dataEvaluateExpressionResult(result).value; + const newValue = (0, (_MITypes || _load_MITypes()).dataEvaluateExpressionResult)(result).value; return { value: newValue, - type: await this.getType(), + type: await this.getType() }; } - get needsDeletion(): boolean { + get needsDeletion() { return false; } } +exports.default = RegisterElementVariableReference; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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-debugger-native-gdb/lib/RegistersVariableReference.js b/modules/atom-ide-debugger-native-gdb/lib/RegistersVariableReference.js index ab3c725585..8905e04efa 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/RegistersVariableReference.js +++ b/modules/atom-ide-debugger-native-gdb/lib/RegistersVariableReference.js @@ -1,140 +1,125 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 {SetChildResponse} from './VariableReference'; -import type {Variable} from 'vscode-debugprotocol'; - -import invariant from 'assert'; -import { - toCommandError, - dataEvaluateExpressionResult, - dataListRegisterNamesResult, - dataListRegisterValuesResult, -} from './MITypes'; -import MIProxy from './MIProxy'; -import {MIRegisterValue, MIRegisterValueParser} from './MIRegisterValue'; -import VariableReference from './VariableReference'; - -export default class RegistersVariableReference extends VariableReference { - _registerIndices: Array; - _registerNames: Map; - - constructor(client: MIProxy, variables: Variables) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _MITypes; + +function _load_MITypes() { + return _MITypes = require('./MITypes'); +} + +var _MIProxy; + +function _load_MIProxy() { + return _MIProxy = _interopRequireDefault(require('./MIProxy')); +} + +var _MIRegisterValue; + +function _load_MIRegisterValue() { + return _MIRegisterValue = require('./MIRegisterValue'); +} + +var _VariableReference; + +function _load_VariableReference() { + return _VariableReference = _interopRequireDefault(require('./VariableReference')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class RegistersVariableReference extends (_VariableReference || _load_VariableReference()).default { + + constructor(client, variables) { super({ client, variables, expression: '', typeClass: 'named', - type: 'register-file', + type: 'register-file' }); } - async getVariables(start: ?number, count: ?number): Promise> { + async getVariables(start, count) { const resolvedStart = start == null ? 0 : start; const resolvedCount = count == null ? await this.getChildCount() : count; await this._ensureRegisterIndicesExist(); - const indices = this._registerIndices.slice( - resolvedStart, - resolvedStart + resolvedCount, - ); + const indices = this._registerIndices.slice(resolvedStart, resolvedStart + resolvedCount); - const result = await this._client.sendCommand( - `data-list-register-values --skip-unavailable x ${indices.join(' ')}`, - ); + const result = await this._client.sendCommand(`data-list-register-values --skip-unavailable x ${indices.join(' ')}`); if (result.error) { - throw new Error( - `Could not fetch register values ${toCommandError(result).msg}`, - ); + throw new Error(`Could not fetch register values ${(0, (_MITypes || _load_MITypes()).toCommandError)(result).msg}`); } - return dataListRegisterValuesResult(result)['register-values'].map(_ => { + return (0, (_MITypes || _load_MITypes()).dataListRegisterValuesResult)(result)['register-values'].map(_ => { const name = this._registerNames.get(parseInt(_.number, 10)); - invariant(name != null); - const value = new MIRegisterValueParser(_.value).parse(); + if (!(name != null)) { + throw new Error('Invariant violation: "name != null"'); + } + + const value = new (_MIRegisterValue || _load_MIRegisterValue()).MIRegisterValueParser(_.value).parse(); - return RegistersVariableReference.variableFromRegisterValue( - this._variables, - name, - `$${name}`, // registers are denoted $reg in gdb expressions - value, - ); + return RegistersVariableReference.variableFromRegisterValue(this._variables, name, `$${name}`, // registers are denoted $reg in gdb expressions + value); }); } - static variableFromRegisterValue( - variables: Variables, - name: string, - expression: string, - value: MIRegisterValue, - ): Variable { - let variable: Variable = { + static variableFromRegisterValue(variables, name, expression, value) { + let variable = { name, value: value.toString(), type: 'int', - variablesReference: 0, + variablesReference: 0 }; if (value.isContainer()) { - const varref = variables.registerElementVariableReference( - value, - name, - expression, - ); + const varref = variables.registerElementVariableReference(value, name, expression); if (value.containerKeyIsString) { - variable = { - ...variable, + variable = Object.assign({}, variable, { type: '{}', variablesReference: varref, namedVariables: value.length, presentationHint: { - kind: 'readOnly', - }, - }; + kind: 'readOnly' + } + }); } else { - variable = { - ...variable, + variable = Object.assign({}, variable, { type: '[]', variablesReference: varref, indexedVariables: value.length, presentationHint: { - kind: 'readOnly', - }, - }; + kind: 'readOnly' + } + }); } } return variable; } - async getType(): Promise { + async getType() { return '[]'; } // The value of a container variable is a summary of the value // of its contents. - async getValue(): Promise { + async getValue() { return '...'; } - async getChildCount(): Promise { + async getChildCount() { await this._ensureRegisterIndicesExist(); return this._registerIndices.length; } - async _ensureRegisterIndicesExist(): Promise { + async _ensureRegisterIndicesExist() { if (this._registerIndices != null) { return; } @@ -148,44 +133,47 @@ export default class RegistersVariableReference extends VariableReference { const result = await this._client.sendCommand('data-list-register-names'); if (result.error) { - throw new Error( - `Failed to fetch register names ${toCommandError(result).msg}`, - ); + throw new Error(`Failed to fetch register names ${(0, (_MITypes || _load_MITypes()).toCommandError)(result).msg}`); } - dataListRegisterNamesResult(result)['register-names'].forEach( - (name, index) => { - if (name !== '') { - this._registerIndices.push(index); - this._registerNames.set(index, name); - } - }, - ); + (0, (_MITypes || _load_MITypes()).dataListRegisterNamesResult)(result)['register-names'].forEach((name, index) => { + if (name !== '') { + this._registerIndices.push(index); + this._registerNames.set(index, name); + } + }); } - async setChildValue(name: string, value: string): Promise { - const result = await this._client.sendCommand( - `data-evaluate-expression $${name}=${value}`, - ); + async setChildValue(name, value) { + const result = await this._client.sendCommand(`data-evaluate-expression $${name}=${value}`); if (result.error) { - throw new Error( - `Unable to change register value ${toCommandError(result).msg}`, - ); + throw new Error(`Unable to change register value ${(0, (_MITypes || _load_MITypes()).toCommandError)(result).msg}`); } - const newValue = dataEvaluateExpressionResult(result).value; + const newValue = (0, (_MITypes || _load_MITypes()).dataEvaluateExpressionResult)(result).value; return { value: newValue, - type: await this.getType(), + type: await this.getType() }; } - get qualifiedName(): string { + get qualifiedName() { return 'registers'; } - get needsDeletion(): boolean { + get needsDeletion() { return false; } } +exports.default = RegistersVariableReference; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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-debugger-native-gdb/lib/RunTranspiledServer.js b/modules/atom-ide-debugger-native-gdb/lib/RunTranspiledServer.js index d68ab5a165..2b68223fea 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/RunTranspiledServer.js +++ b/modules/atom-ide-debugger-native-gdb/lib/RunTranspiledServer.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,7 +8,7 @@ * LICENSE file in 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 */ @@ -18,7 +20,7 @@ const fs = require('fs'); const path = require('path'); if (fs.existsSync(path.join(__dirname, '../DEVELOPMENT'))) { // eslint-disable-next-line nuclide-internal/modules-dependencies - require('nuclide-node-transpiler'); + require('../../nuclide-node-transpiler'); } -require('./MIDebugSession'); +require('./MIDebugSession'); \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/ScopeVariableReference.js b/modules/atom-ide-debugger-native-gdb/lib/ScopeVariableReference.js index 3f427a4905..535ce534da 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/ScopeVariableReference.js +++ b/modules/atom-ide-debugger-native-gdb/lib/ScopeVariableReference.js @@ -1,3 +1,30 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _MIProxy; + +function _load_MIProxy() { + return _MIProxy = _interopRequireDefault(require('./MIProxy')); +} + +var _MITypes; + +function _load_MITypes() { + return _MITypes = require('./MITypes'); +} + +var _VariableReference; + +function _load_VariableReference() { + return _VariableReference = _interopRequireDefault(require('./VariableReference')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// a ScopeVariableReference refers to a set of variables in a stack frame /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,31 +33,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 */ -import type {SetChildResponse} from './VariableReference'; -import type {Variable} from 'vscode-debugprotocol'; - -import invariant from 'assert'; -import MIProxy from './MIProxy'; -import { - stackListVariablesResult, - toCommandError, - varAssignResult, - varCreateResult, -} from './MITypes'; -import VariableReference from './VariableReference'; - -// a ScopeVariableReference refers to a set of variables in a stack frame -export default class ScopeVariableReference extends VariableReference { - constructor( - client: MIProxy, - variables: Variables, - threadId: number, - frameIndex: number, - ) { +class ScopeVariableReference extends (_VariableReference || _load_VariableReference()).default { + constructor(client, variables, threadId, frameIndex) { super({ client, variables, @@ -38,83 +46,71 @@ export default class ScopeVariableReference extends VariableReference { threadId, frameIndex, typeClass: 'named', - type: 'scope', + type: 'scope' }); } - async getVariables(start: ?number, count: ?number): Promise> { + async getVariables(start, count) { // By definition, a scope variable must have a stack frame. - invariant(this.threadId != null); - invariant(this.frameIndex != null); + if (!(this.threadId != null)) { + throw new Error('Invariant violation: "this.threadId != null"'); + } + + if (!(this.frameIndex != null)) { + throw new Error('Invariant violation: "this.frameIndex != null"'); + } - const command = `stack-list-variables --thread ${this.threadId} --frame ${ - this.frameIndex - } --no-values`; + const command = `stack-list-variables --thread ${this.threadId} --frame ${this.frameIndex} --no-values`; const result = await this._client.sendCommand(command); if (result.error) { - throw new Error( - `Error retrieving variables for stack frame (${ - toCommandError(result).msg - })`, - ); + throw new Error(`Error retrieving variables for stack frame (${(0, (_MITypes || _load_MITypes()).toCommandError)(result).msg})`); } - const miVariables = stackListVariablesResult(result).variables; + const miVariables = (0, (_MITypes || _load_MITypes()).stackListVariablesResult)(result).variables; const resolvedStart = start == null ? 0 : start; - const resolvedEnd = - count == null ? miVariables.length - resolvedStart : start + count; + const resolvedEnd = count == null ? miVariables.length - resolvedStart : start + count; - return Promise.all( - miVariables.slice(resolvedStart, resolvedEnd).map(async _ => { - const handle = this._variables.nestedVariableReference(this, _.name); + return Promise.all(miVariables.slice(resolvedStart, resolvedEnd).map(async _ => { + const handle = this._variables.nestedVariableReference(this, _.name); - return this.variableFromVarRefHandle(handle, _.name, null); - }), - ); + return this.variableFromVarRefHandle(handle, _.name, null); + })); } - async setChildValue(name: string, value: string): Promise { + async setChildValue(name, value) { const varResult = await this._client.sendCommand(`var-create - * ${name}`); if (varResult.error) { - throw new Error( - `Could not get variable ${name} to set: ${ - toCommandError(varResult).msg - }`, - ); + throw new Error(`Could not get variable ${name} to set: ${(0, (_MITypes || _load_MITypes()).toCommandError)(varResult).msg}`); } - const varInfo = varCreateResult(varResult); + const varInfo = (0, (_MITypes || _load_MITypes()).varCreateResult)(varResult); - const assignResult = await this._client.sendCommand( - `var-assign ${varInfo.name} ${value}`, - ); + const assignResult = await this._client.sendCommand(`var-assign ${varInfo.name} ${value}`); if (assignResult.error) { - throw new Error( - `Unable to set ${name} to {value}: ${toCommandError(assignResult).msg}`, - ); + throw new Error(`Unable to set ${name} to {value}: ${(0, (_MITypes || _load_MITypes()).toCommandError)(assignResult).msg}`); } - const assign = varAssignResult(assignResult); + const assign = (0, (_MITypes || _load_MITypes()).varAssignResult)(assignResult); await this._client.sendCommand(`var-delete ${varInfo.name}`); return { value: assign.value, type: varInfo.type, - variablesReference: 0, + variablesReference: 0 }; } - async getValue(): Promise { + async getValue() { return ''; } - get qualifiedName(): string { + get qualifiedName() { return 'scope'; } - async getChildCount(): Promise { + async getChildCount() { if (this._childCount != null) { return this._childCount; } @@ -124,3 +120,4 @@ export default class ScopeVariableReference extends VariableReference { return variables.length; } } +exports.default = ScopeVariableReference; \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/SourceBreakpoints.js b/modules/atom-ide-debugger-native-gdb/lib/SourceBreakpoints.js index 7196223e9e..e6f606f3f8 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/SourceBreakpoints.js +++ b/modules/atom-ide-debugger-native-gdb/lib/SourceBreakpoints.js @@ -1,3 +1,49 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _vscodeDebugprotocol; + +function _load_vscodeDebugprotocol() { + return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol')); +} + +var _Breakpoints; + +function _load_Breakpoints() { + return _Breakpoints = require('./Breakpoints'); +} + +var _Breakpoints2; + +function _load_Breakpoints2() { + return _Breakpoints2 = _interopRequireDefault(require('./Breakpoints')); +} + +var _MIProxy; + +function _load_MIProxy() { + return _MIProxy = _interopRequireDefault(require('./MIProxy')); +} + +var _MIRecord; + +function _load_MIRecord() { + return _MIRecord = require('./MIRecord'); +} + +var _MITypes; + +function _load_MITypes() { + return _MITypes = require('./MITypes'); +} + +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. @@ -6,41 +52,23 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import * as DebugProtocol from 'vscode-debugprotocol'; -import invariant from 'assert'; -import {Breakpoint} from './Breakpoints'; -import Breakpoints from './Breakpoints'; -import MIProxy from './MIProxy'; -import {MIResultRecord} from './MIRecord'; -import {breakInsertResult, toCommandError} from './MITypes'; - -type AddRemoveSets = { - addBreakpoints: Array, - removeBreakpoints: Array, -}; - -export default class SourceBreakpoints { - _client: MIProxy; - _breakpoints: Breakpoints; - - // by source and line - _reverseMap: Map>; +class SourceBreakpoints { - constructor(client: MIProxy, breakpoints: Breakpoints) { + constructor(client, breakpoints) { this._client = client; this._breakpoints = breakpoints; this._reverseMap = new Map(); } // Returns a map from the requested lines to the breakpoint handles - async setSourceBreakpoints( - path: string, - breakpoints: Array, - ): Promise> { + + + // by source and line + async setSourceBreakpoints(path, breakpoints) { const addRemove = this._computeAddRemoveSets(path, breakpoints); if (!this._client.isConnected()) { @@ -49,29 +77,31 @@ export default class SourceBreakpoints { await this._addRemoveBreakpointsViaProxy(path, addRemove); } - return this._allBreakpointsForPath(path).map(bkpt => - this._breakpointToProtocolBreakpoint(bkpt), - ); + return this._allBreakpointsForPath(path).map(bkpt => this._breakpointToProtocolBreakpoint(bkpt)); } // Set pre-configuration breakpoints - async setCachedBreakpoints(): Promise> { + async setCachedBreakpoints() { const cachedBreakpoints = this._breakpoints.breakpointsWithNoDebuggerId(); - const results = await Promise.all( - cachedBreakpoints.map(_ => { - const source = _.source; - const line = _.line; - invariant(source != null); - invariant(line != null); + const results = await Promise.all(cachedBreakpoints.map(_ => { + const source = _.source; + const line = _.line; - return this._setBreakpoint(source, line, _.condition); - }), - ); + if (!(source != null)) { + throw new Error('Invariant violation: "source != null"'); + } + + if (!(line != null)) { + throw new Error('Invariant violation: "line != null"'); + } + + return this._setBreakpoint(source, line, _.condition); + })); results.forEach((response, index) => { if (response.done) { - const result = breakInsertResult(response); + const result = (0, (_MITypes || _load_MITypes()).breakInsertResult)(response); const bkpt = result.bkpt[0]; cachedBreakpoints[index].setId(parseInt(bkpt.number, 10)); if (bkpt.pending == null) { @@ -80,45 +110,37 @@ export default class SourceBreakpoints { } }); - return cachedBreakpoints - .filter(_ => _.verified) - .map(_ => this._breakpointToProtocolBreakpoint(_)); + return cachedBreakpoints.filter(_ => _.verified).map(_ => this._breakpointToProtocolBreakpoint(_)); } // We are given the set of lines which should be set for a file, not // a delta from the current set. We must compute the delta manually // to update the MI debugger. // - _computeAddRemoveSets( - path: string, - breakpoints: Array, - ): AddRemoveSets { + _computeAddRemoveSets(path, breakpoints) { const existingBreakpoints = this._allBreakpointsForPath(path); - const existingLines: Array = existingBreakpoints.map(_ => { + const existingLines = existingBreakpoints.map(_ => { const line = _.line; - invariant(line != null); + + if (!(line != null)) { + throw new Error('Invariant violation: "line != null"'); + } + return line; }); const lines = breakpoints.map(_ => _.line); - const removeBreakpoints = existingBreakpoints.filter( - _ => !lines.includes(_.line), - ); + const removeBreakpoints = existingBreakpoints.filter(_ => !lines.includes(_.line)); - const addBreakpoints: Array< - DebugProtocol.SourceBreakpoint, - > = breakpoints.filter(_ => !existingLines.includes(_.line)); + const addBreakpoints = breakpoints.filter(_ => !existingLines.includes(_.line)); - return {addBreakpoints, removeBreakpoints}; + return { addBreakpoints, removeBreakpoints }; } // If we're called before the proxy is set up, we need to cache the breakpoints // until gdb is launched - _cacheBreakpointsInConfiguration( - path: string, - addRemove: AddRemoveSets, - ): void { + _cacheBreakpointsInConfiguration(path, addRemove) { let forSource = this._reverseMap.get(path); if (forSource == null) { forSource = new Map(); @@ -135,30 +157,22 @@ export default class SourceBreakpoints { addRemove.addBreakpoints.forEach((breakpoint, index) => { const line = breakpoint.line; - const newBreakpoint = new Breakpoint( - null, - path, - line, - breakpoint.condition, - false, - ); + const newBreakpoint = new (_Breakpoints || _load_Breakpoints()).Breakpoint(null, path, line, breakpoint.condition, false); + + if (!(forSource != null)) { + throw new Error('Invariant violation: "forSource != null"'); + } - invariant(forSource != null); forSource.set(line, newBreakpoint); this._breakpoints.addBreakpoint(newBreakpoint); }); } - async _addRemoveBreakpointsViaProxy( - path: string, - addRemove: AddRemoveSets, - ): Promise { - const promises: Array> = []; + async _addRemoveBreakpointsViaProxy(path, addRemove) { + const promises = []; if (addRemove.removeBreakpoints.length !== 0) { - const removeCommand = `break-delete ${addRemove.removeBreakpoints - .map(_ => _.id) - .join(' ')}`; + const removeCommand = `break-delete ${addRemove.removeBreakpoints.map(_ => _.id).join(' ')}`; promises.push(this._client.sendCommand(removeCommand)); } @@ -170,14 +184,14 @@ export default class SourceBreakpoints { if (addRemove.removeBreakpoints.length !== 0) { const removeResult = results.shift(); - invariant(removeResult != null); + + if (!(removeResult != null)) { + throw new Error('Invariant violation: "removeResult != null"'); + } + if (removeResult.result.error) { // this means our internal state is out of sync with the debugger - throw new Error( - `Failed to remove breakpoints which should have existed (${ - toCommandError(removeResult).msg - })`, - ); + throw new Error(`Failed to remove breakpoints which should have existed (${(0, (_MITypes || _load_MITypes()).toCommandError)(removeResult).msg})`); } } @@ -196,70 +210,70 @@ export default class SourceBreakpoints { const failure = results.find(_ => !_.done); if (failure != null) { - throw new Error( - `Failed adding new source breakpoints ${toCommandError(failure).msg}`, - ); + throw new Error(`Failed adding new source breakpoints ${(0, (_MITypes || _load_MITypes()).toCommandError)(failure).msg}`); } results.forEach((response, index) => { - const result = breakInsertResult(response); + const result = (0, (_MITypes || _load_MITypes()).breakInsertResult)(response); const bkpt = result.bkpt[0]; - invariant(bkpt != null); + + if (!(bkpt != null)) { + throw new Error('Invariant violation: "bkpt != null"'); + } // NB gdb will not return the line number of a pending breakpoint, so // use the one we were given + + const line = addRemove.addBreakpoints[index].line; - const breakpoint = new Breakpoint( - parseInt(bkpt.number, 10), - path, - line, - addRemove.addBreakpoints[index].condition, - bkpt.pending == null, - ); + const breakpoint = new (_Breakpoints || _load_Breakpoints()).Breakpoint(parseInt(bkpt.number, 10), path, line, addRemove.addBreakpoints[index].condition, bkpt.pending == null); + + if (!(forSource != null)) { + throw new Error('Invariant violation: "forSource != null"'); + } - invariant(forSource != null); forSource.set(line, breakpoint); this._breakpoints.addBreakpoint(breakpoint); }); } - async _setBreakpoint( - source: string, - line: number, - condition: ?string, - ): Promise { - const conditionFlag = - condition == null || condition.trim() === '' - ? '' - : `-c "${condition.replace('"', '\\"')}"`; + async _setBreakpoint(source, line, condition) { + const conditionFlag = condition == null || condition.trim() === '' ? '' : `-c "${condition.replace('"', '\\"')}"`; const cmd = `break-insert -f --source ${source} --line ${line} ${conditionFlag}`; return this._client.sendCommand(cmd); } - _allBreakpointsForPath(path: string): Array { + _allBreakpointsForPath(path) { let forSource = this._reverseMap.get(path); forSource = forSource != null ? [...forSource] : []; return forSource.map(_ => _[1]); } - _breakpointToProtocolBreakpoint(bkpt: Breakpoint): DebugProtocol.Breakpoint { + _breakpointToProtocolBreakpoint(bkpt) { const handle = this._breakpoints.handleForBreakpoint(bkpt); - invariant(handle != null, 'Could not find source breakpoint handle'); - invariant(bkpt.line != null); + + if (!(handle != null)) { + throw new Error('Could not find source breakpoint handle'); + } + + if (!(bkpt.line != null)) { + throw new Error('Invariant violation: "bkpt.line != null"'); + } const bptRet = { id: handle, verified: bkpt.verified, source: { - sourceReference: 0, + sourceReference: 0 }, - line: bkpt.line, + line: bkpt.line }; if (bkpt.source != null) { - bptRet.source = {...bptRet.source, path: bkpt.source}; + bptRet.source = Object.assign({}, bptRet.source, { path: bkpt.source }); } return bptRet; } } +exports.default = SourceBreakpoints; \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/StackFrames.js b/modules/atom-ide-debugger-native-gdb/lib/StackFrames.js index 2d6a7a5c6f..f42fe31c10 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/StackFrames.js +++ b/modules/atom-ide-debugger-native-gdb/lib/StackFrames.js @@ -1,3 +1,35 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _HandleMap; + +function _load_HandleMap() { + return _HandleMap = _interopRequireDefault(require('./HandleMap')); +} + +var _MIProxy; + +function _load_MIProxy() { + return _MIProxy = _interopRequireDefault(require('./MIProxy')); +} + +var _vscodeDebugadapter; + +function _load_vscodeDebugadapter() { + return _vscodeDebugadapter = require('vscode-debugadapter'); +} + +var _MITypes; + +function _load_MITypes() { + return _MITypes = require('./MITypes'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,37 +38,15 @@ * LICENSE file in 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 HandleMap from './HandleMap'; -import MIProxy from './MIProxy'; -import {StackFrame} from 'vscode-debugadapter'; -import { - stackInfoDepthResult, - stackListFramesResult, - toCommandError, -} from './MITypes'; - -export type CachedStackFrame = { - threadId: number, - frameIndex: number, -}; - -type StackTraceResponseBody = { - stackFrames: Array, - totalFrames?: number, -}; - -export default class StackFrames { - _client: MIProxy; - _frames: HandleMap; - _frameIdsByThreadAndLevel: Map>; - - constructor(client: MIProxy) { +class StackFrames { + + constructor(client) { this._client = client; - this._frames = new HandleMap(); + this._frames = new (_HandleMap || _load_HandleMap()).default(); this._frameIdsByThreadAndLevel = new Map(); } @@ -45,42 +55,27 @@ export default class StackFrames { this._frameIdsByThreadAndLevel.clear(); } - stackFrameByHandle(handle: number): ?CachedStackFrame { + stackFrameByHandle(handle) { return this._frames.getObjectByHandle(handle); } - async stackFramesForThread( - threadId: number, - startFrame: ?number, - levels: ?number, - ): Promise { - const depthResult = await this._client.sendCommand( - `stack-info-depth --thread ${threadId}`, - ); + async stackFramesForThread(threadId, startFrame, levels) { + const depthResult = await this._client.sendCommand(`stack-info-depth --thread ${threadId}`); if (!depthResult.done) { - throw new Error( - `Protocol error retrieving stack depth (${ - toCommandError(depthResult).msg - })`, - ); + throw new Error(`Protocol error retrieving stack depth (${(0, (_MITypes || _load_MITypes()).toCommandError)(depthResult).msg})`); } - const depth = parseInt(stackInfoDepthResult(depthResult).depth, 10); + const depth = parseInt((0, (_MITypes || _load_MITypes()).stackInfoDepthResult)(depthResult).depth, 10); const lowFrame = startFrame == null ? 0 : startFrame; - const highFrame = - (levels == null ? lowFrame + depth : lowFrame + levels) - 1; + const highFrame = (levels == null ? lowFrame + depth : lowFrame + levels) - 1; const command = `stack-list-frames --thread ${threadId} --no-frame-filters ${lowFrame} ${highFrame}`; const frameResult = await this._client.sendCommand(command); if (!frameResult.done) { - throw new Error( - `Protocol error retrieving stack frames (${ - toCommandError(frameResult).msg - })`, - ); + throw new Error(`Protocol error retrieving stack frames (${(0, (_MITypes || _load_MITypes()).toCommandError)(frameResult).msg})`); } - const frames = stackListFramesResult(frameResult); + const frames = (0, (_MITypes || _load_MITypes()).stackListFramesResult)(frameResult); return { totalFrames: depth, @@ -88,28 +83,20 @@ export default class StackFrames { const level = parseInt(_.frame.level, 10); return { id: this._handleForFrame(threadId, level), - name: - _.frame.func != null - ? _.frame.func - : _.frame.from != null - ? _.frame.from - : _.frame.addr, - source: - _.frame.file == null && _.frame.fullname == null - ? undefined - : { - name: _.frame.file, - path: _.frame.fullname, - }, + name: _.frame.func != null ? _.frame.func : _.frame.from != null ? _.frame.from : _.frame.addr, + source: _.frame.file == null && _.frame.fullname == null ? undefined : { + name: _.frame.file, + path: _.frame.fullname + }, line: _.frame.line == null ? 0 : parseInt(_.frame.line, 10), column: 0, - addr: _.frame.addr, + addr: _.frame.addr }; - }), + }) }; } - _handleForFrame(threadId: number, frameIndex: number): number { + _handleForFrame(threadId, frameIndex) { let mapForThread = this._frameIdsByThreadAndLevel.get(threadId); if (mapForThread == null) { mapForThread = new Map(); @@ -120,7 +107,7 @@ export default class StackFrames { if (frame == null) { const cachedFrame = { threadId, - frameIndex, + frameIndex }; frame = this._frames.put(cachedFrame); mapForThread.set(frameIndex, frame); @@ -129,3 +116,4 @@ export default class StackFrames { return frame; } } +exports.default = StackFrames; \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/VariableReference.js b/modules/atom-ide-debugger-native-gdb/lib/VariableReference.js index 8808761899..00d1cc024a 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/VariableReference.js +++ b/modules/atom-ide-debugger-native-gdb/lib/VariableReference.js @@ -1,3 +1,29 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _MIDebugSession; + +function _load_MIDebugSession() { + return _MIDebugSession = require('./MIDebugSession'); +} + +var _MITypes; + +function _load_MITypes() { + return _MITypes = require('./MITypes'); +} + +var _MIProxy; + +function _load_MIProxy() { + return _MIProxy = _interopRequireDefault(require('./MIProxy')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,58 +32,13 @@ * LICENSE file in 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 {Variable} from 'vscode-debugprotocol'; - -import {logVerbose} from './MIDebugSession'; -import invariant from 'assert'; -import { - toCommandError, - varAssignResult, - varCreateResult, - varEvaluateExpressionResult, - varInfoNumChildrenResult, - varInfoTypeResult, - varListChildrenResult, -} from './MITypes'; -import MIProxy from './MIProxy'; - -export type VariableTypeClass = 'simple' | 'named' | 'indexed'; - -type VariableReferenceConstructorArgs = { - client: MIProxy, - variables: Variables, - expression: string, - threadId?: ?number, - frameIndex?: ?number, - typeClass?: ?VariableTypeClass, - type?: ?string, - varName?: ?string, -}; - -export type SetChildResponse = { - value: string, - type?: string, - variablesReference?: number, - namedVariables?: number, - indexedVariables?: number, -}; - -export default class VariableReference { - _client: MIProxy; - _variables: Variables; - _childCount: ?number; - _threadId: ?number; - _frameIndex: ?number; - _expression: string; - _varName: ?string; - _typeClass: ?VariableTypeClass; - _type: ?string; - - constructor(args: VariableReferenceConstructorArgs) { +class VariableReference { + + constructor(args) { this._client = args.client; this._variables = args.variables; this._expression = args.expression; @@ -68,17 +49,15 @@ export default class VariableReference { this._varName = args.varName; } - async getVariables(start: ?number, count: ?number): Promise> { - throw new Error( - 'Base class VariableReference.getVariables called (abstract method)', - ); + async getVariables(start, count) { + throw new Error('Base class VariableReference.getVariables called (abstract method)'); } // typeClass describes what type of container the variable's type is // simple variables are not containers // named variables have named members: struct, union, class // indexed variables are native arrays and pointers - async getTypeClass(value: string): Promise { + async getTypeClass(value) { // it would seem to make sense to infer the type class from the actual // type. but that doesn't work, because the actual type may be a typedef, // and that's what MI will return. we can't recover the underlying type @@ -88,7 +67,7 @@ export default class VariableReference { return this._typeClass; } - let type: VariableTypeClass = 'simple'; + let type = 'simple'; if (value === '') { // For C++ code, gdb inserts an extra level of hierarchy that doesn't @@ -117,7 +96,7 @@ export default class VariableReference { return type; } - async getType(): Promise { + async getType() { if (this._type != null) { return this._type; } @@ -125,33 +104,27 @@ export default class VariableReference { const varName = await this._getVarName(); const result = await this._client.sendCommand(`var-info-type ${varName}`); if (result.error) { - throw new Error( - `Error determining variable's type (${toCommandError(result).msg})`, - ); + throw new Error(`Error determining variable's type (${(0, (_MITypes || _load_MITypes()).toCommandError)(result).msg})`); } - this._type = varInfoTypeResult(result).type; + this._type = (0, (_MITypes || _load_MITypes()).varInfoTypeResult)(result).type; return this._type; } // The value of a container variable is a summary of the value // of its contents. - async getValue(): Promise { + async getValue() { const varName = await this._getVarName(); - const result = await this._client.sendCommand( - `var-evaluate-expression ${varName}`, - ); + const result = await this._client.sendCommand(`var-evaluate-expression ${varName}`); if (result.error) { - throw new Error( - `Error determining variable's value (${toCommandError(result).msg})`, - ); + throw new Error(`Error determining variable's value (${(0, (_MITypes || _load_MITypes()).toCommandError)(result).msg})`); } - return varEvaluateExpressionResult(result).value; + return (0, (_MITypes || _load_MITypes()).varEvaluateExpressionResult)(result).value; } - async getChildCount(): Promise { + async getChildCount() { if (this._childCount != null) { return this._childCount; } @@ -165,19 +138,16 @@ export default class VariableReference { } // otherwise, we have to ask - const result = await this._client.sendCommand( - `var-info-num-children ${varName}`, - ); + const result = await this._client.sendCommand(`var-info-num-children ${varName}`); if (result.error) { - throw new Error( - `Error determining the number of children (${ - toCommandError(result).msg - })`, - ); + throw new Error(`Error determining the number of children (${(0, (_MITypes || _load_MITypes()).toCommandError)(result).msg})`); } - const childCountStr = varInfoNumChildrenResult(result).numchild; - invariant(childCountStr != null); + const childCountStr = (0, (_MITypes || _load_MITypes()).varInfoNumChildrenResult)(result).numchild; + + if (!(childCountStr != null)) { + throw new Error('Invariant violation: "childCountStr != null"'); + } const childCount = parseInt(childCountStr, 10); this._childCount = childCount; @@ -185,157 +155,134 @@ export default class VariableReference { return childCount; } - async setChildValue(name: string, value: string): Promise { + async setChildValue(name, value) { const varname = await this._getVarName(); - const childrenResult = await this._client.sendCommand( - `var-list-children ${varname}`, - ); + const childrenResult = await this._client.sendCommand(`var-list-children ${varname}`); if (childrenResult.error) { - throw new Error( - `Error getting the children of ${varname} ${ - toCommandError(childrenResult).msg - }`, - ); + throw new Error(`Error getting the children of ${varname} ${(0, (_MITypes || _load_MITypes()).toCommandError)(childrenResult).msg}`); } - const children = varListChildrenResult(childrenResult); + const children = (0, (_MITypes || _load_MITypes()).varListChildrenResult)(childrenResult); const child = children.children.find(_ => _.child.exp === name); if (child == null) { throw new Error(`Cannot find variable ${name} to modify`); } - const assignResult = await this._client.sendCommand( - `var-assign ${child.child.name} ${value}`, - ); + const assignResult = await this._client.sendCommand(`var-assign ${child.child.name} ${value}`); if (assignResult.error) { - throw new Error( - `Unable to set ${name} to {$value}: ${ - toCommandError(assignResult).msg - }`, - ); + throw new Error(`Unable to set ${name} to {$value}: ${(0, (_MITypes || _load_MITypes()).toCommandError)(assignResult).msg}`); } - const assign = varAssignResult(assignResult); + const assign = (0, (_MITypes || _load_MITypes()).varAssignResult)(assignResult); return { value: assign.value, type: child.child.type, - variablesReference: 0, + variablesReference: 0 }; } - async deleteResources(): Promise { + async deleteResources() { if (this.needsDeletion && this._varName != null) { - const result = await this._client.sendCommand( - `var-delete ${this._varName}`, - ); + const result = await this._client.sendCommand(`var-delete ${this._varName}`); if (result.error) { // don't throw here, because we can still continue safely, but log the error. - logVerbose(`Error deleting variable ${toCommandError(result).msg}`); + (0, (_MIDebugSession || _load_MIDebugSession()).logVerbose)(`Error deleting variable ${(0, (_MITypes || _load_MITypes()).toCommandError)(result).msg}`); } } } - get qualifiedName(): string { - throw new Error( - 'Base class VariableReference.getQualifiedName called (abstract method)', - ); + get qualifiedName() { + throw new Error('Base class VariableReference.getQualifiedName called (abstract method)'); } - get needsDeletion(): boolean { + get needsDeletion() { return false; } - get threadId(): ?number { + get threadId() { return this._threadId; } - get frameIndex(): ?number { + get frameIndex() { return this._frameIndex; } - async variableFromVarRefHandle( - handle: number, - name: string, - type: ?string, - ): Promise { + async variableFromVarRefHandle(handle, name, type) { const varref = this._variables.getVariableReference(handle); - invariant(varref != null); + + if (!(varref != null)) { + throw new Error('Invariant violation: "varref != null"'); + } const value = await varref.getValue(); const typeClass = await varref.getTypeClass(value); const resolvedType = type == null ? await varref.getType() : type; - logVerbose( - `name ${name} type ${resolvedType} value ${value} typeClass ${typeClass}`, - ); + (0, (_MIDebugSession || _load_MIDebugSession()).logVerbose)(`name ${name} type ${resolvedType} value ${value} typeClass ${typeClass}`); - let variable: Variable = { + let variable = { name, value, type: resolvedType, - variablesReference: 0, + variablesReference: 0 }; if (typeClass !== 'simple') { const childCount = await varref.getChildCount(); if (typeClass === 'indexed') { - variable = { - ...variable, + variable = Object.assign({}, variable, { indexedVariables: childCount, - variablesReference: handle, - }; + variablesReference: handle + }); } else if (typeClass === 'named') { - variable = { - ...variable, + variable = Object.assign({}, variable, { namedVariables: childCount, - variablesReference: handle, - }; + variablesReference: handle + }); } } return variable; } - async _createVariableBinding(expression: string): Promise { + async _createVariableBinding(expression) { // '-' means to let gdb create a unique name for the binding // '*' means use the current frame (which we specify via --thread/--frame) - // '@' means a floating variable which should be evaluatable anywhere - - let command: string; + let command; if (this.threadId != null && this.frameIndex != null) { - command = `var-create --thread ${this.threadId} --frame ${ - this.frameIndex - } - * ${expression}`; + command = `var-create --thread ${this.threadId} --frame ${this.frameIndex} - * ${expression}`; } else { command = `var-create - @ ${expression}`; } const result = await this._client.sendCommand(command); if (result.error) { - throw new Error( - `Error creating variable binding (${toCommandError(result).msg})`, - ); + throw new Error(`Error creating variable binding (${(0, (_MITypes || _load_MITypes()).toCommandError)(result).msg})`); } - const varResult = varCreateResult(result); + const varResult = (0, (_MITypes || _load_MITypes()).varCreateResult)(result); this._varName = varResult.name; this._childCount = parseInt(varResult.numchild, 10); return varResult.name; } - async _getVarName(): Promise { + async _getVarName() { if (this._varName != null) { return this._varName; } await this._createVariableBinding(this._expression); const varName = this._varName; - invariant(varName != null); + + if (!(varName != null)) { + throw new Error('Invariant violation: "varName != null"'); + } return varName; } } +exports.default = VariableReference; \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/lib/Variables.js b/modules/atom-ide-debugger-native-gdb/lib/Variables.js index 84e11c7f8c..d8b5c79a3a 100644 --- a/modules/atom-ide-debugger-native-gdb/lib/Variables.js +++ b/modules/atom-ide-debugger-native-gdb/lib/Variables.js @@ -1,52 +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 strict-local - * @format - */ - -import type {Variable} from 'vscode-debugprotocol'; - -import HandleMap from './HandleMap'; -import MIProxy from './MIProxy'; -import ExpressionVariableReference from './ExpressionVariableReference'; -import {MIRegisterValue} from './MIRegisterValue'; -import NestedVariableReference from './NestedVariableReference'; -import RegisterElementVariableReference from './RegisterElementVariableReference'; -import RegistersVariableReference from './RegistersVariableReference'; -import ScopeVariableReference from './ScopeVariableReference'; -import StackFrames from './StackFrames'; -import VariableReference from './VariableReference'; - -export default class Variables { - _client: MIProxy; - _frames: StackFrames; - _variables: HandleMap; - _scopeIndex: Map>; // by thread, then frame index - _nestedReferenceIndex: Map>>; // by thread, frame index, varname - _registerElementReferenceIndex: Map; // by register expression - _varsNeedingDeletion: Set; - _registersVariableReference: ?number; - - constructor(client: MIProxy, frames: StackFrames) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _HandleMap; + +function _load_HandleMap() { + return _HandleMap = _interopRequireDefault(require('./HandleMap')); +} + +var _MIProxy; + +function _load_MIProxy() { + return _MIProxy = _interopRequireDefault(require('./MIProxy')); +} + +var _ExpressionVariableReference; + +function _load_ExpressionVariableReference() { + return _ExpressionVariableReference = _interopRequireDefault(require('./ExpressionVariableReference')); +} + +var _MIRegisterValue; + +function _load_MIRegisterValue() { + return _MIRegisterValue = require('./MIRegisterValue'); +} + +var _NestedVariableReference; + +function _load_NestedVariableReference() { + return _NestedVariableReference = _interopRequireDefault(require('./NestedVariableReference')); +} + +var _RegisterElementVariableReference; + +function _load_RegisterElementVariableReference() { + return _RegisterElementVariableReference = _interopRequireDefault(require('./RegisterElementVariableReference')); +} + +var _RegistersVariableReference; + +function _load_RegistersVariableReference() { + return _RegistersVariableReference = _interopRequireDefault(require('./RegistersVariableReference')); +} + +var _ScopeVariableReference; + +function _load_ScopeVariableReference() { + return _ScopeVariableReference = _interopRequireDefault(require('./ScopeVariableReference')); +} + +var _StackFrames; + +function _load_StackFrames() { + return _StackFrames = _interopRequireDefault(require('./StackFrames')); +} + +var _VariableReference; + +function _load_VariableReference() { + return _VariableReference = _interopRequireDefault(require('./VariableReference')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Variables { + // by register expression + // by thread, then frame index + constructor(client, frames) { this._client = client; this._frames = frames; - this._variables = new HandleMap(); + this._variables = new (_HandleMap || _load_HandleMap()).default(); this._scopeIndex = new Map(); this._nestedReferenceIndex = new Map(); this._registerElementReferenceIndex = new Map(); this._varsNeedingDeletion = new Set(); - } + } // by thread, frame index, varname + - async clearCachedVariables(): Promise { - await Promise.all( - [...this._varsNeedingDeletion].map(async _ => _.deleteResources()), - ); + async clearCachedVariables() { + await Promise.all([...this._varsNeedingDeletion].map(async _ => _.deleteResources())); this._varsNeedingDeletion.clear(); this._variables.clear(); @@ -56,12 +91,10 @@ export default class Variables { this._registersVariableReference = null; } - variableReferenceForStackFrame(frameId: number): number { + variableReferenceForStackFrame(frameId) { const frame = this._frames.stackFrameByHandle(frameId); if (frame == null) { - throw new Error( - `Attempt to find or create varref for unknown stack frame ${frameId}`, - ); + throw new Error(`Attempt to find or create varref for unknown stack frame ${frameId}`); } let threadMap = this._scopeIndex.get(frame.threadId); @@ -72,12 +105,7 @@ export default class Variables { let varref = threadMap.get(frame.frameIndex); if (varref == null) { - const scopeVarRef = new ScopeVariableReference( - this._client, - this, - frame.threadId, - frame.frameIndex, - ); + const scopeVarRef = new (_ScopeVariableReference || _load_ScopeVariableReference()).default(this._client, this, frame.threadId, frame.frameIndex); varref = this._variables.put(scopeVarRef); threadMap.set(frame.frameIndex, varref); } @@ -85,50 +113,30 @@ export default class Variables { return varref; } - registersVariableReference(): ?number { + registersVariableReference() { if (this._registersVariableReference != null) { return this._registersVariableReference; } - const varref = this._variables.put( - new RegistersVariableReference(this._client, this), - ); + const varref = this._variables.put(new (_RegistersVariableReference || _load_RegistersVariableReference()).default(this._client, this)); this._registersVariableReference = varref; return varref; } - registerElementVariableReference( - value: MIRegisterValue, - name: string, - expression: string, - ): number { + registerElementVariableReference(value, name, expression) { let varref = this._registerElementReferenceIndex.get(expression); if (varref == null) { - varref = this._variables.put( - new RegisterElementVariableReference( - this._client, - this, - name, - expression, - value, - ), - ); + varref = this._variables.put(new (_RegisterElementVariableReference || _load_RegisterElementVariableReference()).default(this._client, this, name, expression, value)); } return varref; } - nestedVariableReference( - container: VariableReference, - exp: string, - name: ?string, - ): number { - const resolvedThreadId = - container.threadId == null ? -1 : container.threadId; - const resolvedFrameIndex = - container.frameIndex == null ? -1 : container.frameIndex; + nestedVariableReference(container, exp, name) { + const resolvedThreadId = container.threadId == null ? -1 : container.threadId; + const resolvedFrameIndex = container.frameIndex == null ? -1 : container.frameIndex; let threadMap = this._nestedReferenceIndex.get(resolvedThreadId); if (threadMap == null) { @@ -148,13 +156,7 @@ export default class Variables { return handle; } - const varref = new NestedVariableReference( - this._client, - this, - container, - exp, - name, - ); + const varref = new (_NestedVariableReference || _load_NestedVariableReference()).default(this._client, this, container, exp, name); if (varref.needsDeletion) { this._varsNeedingDeletion.add(varref); @@ -166,11 +168,7 @@ export default class Variables { return handle; } - expressionVariableReference( - threadId: ?number, - frameIndex: ?number, - expression: string, - ): number { + expressionVariableReference(threadId, frameIndex, expression) { const resolvedThreadId = threadId == null ? -1 : threadId; const resolvedFrameIndex = frameIndex == null ? -1 : frameIndex; @@ -192,13 +190,7 @@ export default class Variables { return handle; } - const varref = new ExpressionVariableReference( - this._client, - this, - threadId, - frameIndex, - expression, - ); + const varref = new (_ExpressionVariableReference || _load_ExpressionVariableReference()).default(this._client, this, threadId, frameIndex, expression); if (varref.needsDeletion) { this._varsNeedingDeletion.add(varref); @@ -210,15 +202,11 @@ export default class Variables { return handle; } - getVariableReference(handle: number): ?VariableReference { + getVariableReference(handle) { return this._variables.getObjectByHandle(handle); } - async getVariables( - varrefHandle: number, - start: ?number, - count: ?number, - ): Promise> { + async getVariables(varrefHandle, start, count) { const varref = this._variables.getObjectByHandle(varrefHandle); if (varref == null) { throw new Error(`Attempt to access invalid varref ${varrefHandle}`); @@ -227,3 +215,14 @@ export default class Variables { return varref.getVariables(start, count); } } +exports.default = 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/main.js b/modules/atom-ide-debugger-native-gdb/main.js index 7814e8c71e..b954fc2a40 100644 --- a/modules/atom-ide-debugger-native-gdb/main.js +++ b/modules/atom-ide-debugger-native-gdb/main.js @@ -1,3 +1,37 @@ +'use strict'; + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../nuclide-commons-atom/createPackage')); +} + +var _autogenUtils; + +function _load_autogenUtils() { + return _autogenUtils = require('../nuclide-debugger-common/autogen-utils'); +} + +var _constants; + +function _load_constants() { + return _constants = require('../nuclide-debugger-common/constants'); +} + +var _AutoGenLaunchAttachProvider; + +function _load_AutoGenLaunchAttachProvider() { + return _AutoGenLaunchAttachProvider = require('../nuclide-debugger-common/AutoGenLaunchAttachProvider'); +} + +var _utils; + +function _load_utils() { + return _utils = require('./utils'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,48 +40,32 @@ * LICENSE file in 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 { - NuclideDebuggerProvider, - DebuggerConfigurationProvider, -} from 'nuclide-debugger-common/types'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import {getNativeAutoGenConfig} from 'nuclide-debugger-common/autogen-utils'; -import {VsAdapterTypes} from 'nuclide-debugger-common/constants'; -import {AutoGenLaunchAttachProvider} from 'nuclide-debugger-common/AutoGenLaunchAttachProvider'; -import {resolveConfiguration} from './utils'; - class Activation { constructor() {} dispose() {} - createDebuggerProvider(): NuclideDebuggerProvider { + createDebuggerProvider() { return { - type: VsAdapterTypes.NATIVE_GDB, + type: (_constants || _load_constants()).VsAdapterTypes.NATIVE_GDB, getLaunchAttachProvider: connection => { - return new AutoGenLaunchAttachProvider( - 'Native - GDB (C/C++)', - connection, - getNativeAutoGenConfig(VsAdapterTypes.NATIVE_GDB), - async () => { - // GDB not available on Win32. - return Promise.resolve(process.platform !== 'win32'); - }, - ); - }, + return new (_AutoGenLaunchAttachProvider || _load_AutoGenLaunchAttachProvider()).AutoGenLaunchAttachProvider('Native - GDB (C/C++)', connection, (0, (_autogenUtils || _load_autogenUtils()).getNativeAutoGenConfig)((_constants || _load_constants()).VsAdapterTypes.NATIVE_GDB), async () => { + // GDB not available on Win32. + return Promise.resolve(process.platform !== 'win32'); + }); + } }; } - createDebuggerConfigurator(): DebuggerConfigurationProvider { + createDebuggerConfigurator() { return { - resolveConfiguration, - adapterType: VsAdapterTypes.NATIVE_GDB, + resolveConfiguration: (_utils || _load_utils()).resolveConfiguration, + adapterType: (_constants || _load_constants()).VsAdapterTypes.NATIVE_GDB }; } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/spec/BreakpointsSpec.js b/modules/atom-ide-debugger-native-gdb/spec/BreakpointsSpec.js deleted file mode 100644 index 8b6477f9f5..0000000000 --- a/modules/atom-ide-debugger-native-gdb/spec/BreakpointsSpec.js +++ /dev/null @@ -1,299 +0,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. - * - * @flow - * @format - */ - -import Breakpoints from '../lib/Breakpoints'; -import SourceBreakpoints from '../lib/SourceBreakpoints'; -import MIProxy from '../lib/MIProxy'; -import {MIResultRecord} from '../lib/MIRecord'; - -type Command = { - operation: 'insert' | 'delete' | 'invalid', - invalid: string, - ids: Array, - path: string, - line: number, -}; - -// The mock class emulates the MI behavior of break-insert and break-delete, -// including a mapping of ids on the debugger side for each breakpoint. -class MIProxyMock extends MIProxy { - _sentCommands: Array; - _nextId: number; - _idsByLine: Map; - - constructor() { - super(); - this._sentCommands = []; - this._nextId = 1; - this._idsByLine = new Map(); - } - - isConnected() { - return true; - } - - async sendCommand(command: string): Promise { - let parsedCommand = { - operation: 'invalid', - invalid: command, - ids: [], - path: '', - line: -1, - }; - - let result: MIResultRecord = new MIResultRecord(null, {}, 'error'); - - const match = command.match(/^([^ ]+) *(.*)$/); - - if (match != null) { - const [, op, args] = match; - - if (op === 'break-delete') { - const ids = args - .split(/ +/) - .filter(_ => _.length !== 0) - .map(_ => parseInt(_, 10)); - - this._idsByLine = new Map( - [...this._idsByLine].filter(_ => !ids.includes(_[1])), - ); - - parsedCommand = { - ...parsedCommand, - operation: 'delete', - ids, - }; - - result = new MIResultRecord(null, {}, 'done'); - } else if (op === 'break-insert') { - const insertArgs = args.match(/^-f --source (.*) --line ([0-9]+)\s*$/); - if (insertArgs != null) { - const [, path, lineStr] = insertArgs; - const line = parseInt(lineStr, 10); - parsedCommand = { - ...parsedCommand, - operation: 'insert', - path, - line, - }; - - const id = this._nextId++; - this._idsByLine.set(line, id); - - result = new MIResultRecord( - null, - { - bkpt: [ - { - number: `${id}`, - type: 'breakpoint', - disp: 'keep', - enabled: 'y', - addr: '0x0000000100000eff', - func: 'main', - file: path, - fullname: path, - line: `${line}`, - 'thread-groups': ['i1'], - times: '0', - 'original-location': `${path}:${line}`, - }, - ], - }, - 'done', - ); - } - } - } - - this.sentCommands.push(parsedCommand); - - return result; - } - - clearCommands(): void { - this._sentCommands = []; - } - - idForLine(line: number): ?number { - return this._idsByLine.get(line); - } - - get sentCommands(): Array { - return this._sentCommands; - } -} - -describe('Breakpoints', () => { - let proxy: MIProxyMock; - let breakpoints: SourceBreakpoints; - - beforeEach(() => { - proxy = new MIProxyMock(); - breakpoints = new SourceBreakpoints(proxy, new Breakpoints()); - }); - - it('should set a breakpoint', done => { - breakpoints.setSourceBreakpoints('foo.c', [{line: 42}]).then(bkptsOut => { - const invalid = proxy.sentCommands.filter(_ => _.operation === 'invalid'); - expect(invalid.length).toEqual( - 0, - `Should not have any invalid commands (${JSON.stringify(invalid)})`, - ); - - const deletes = proxy.sentCommands.filter(_ => _.operation === 'delete'); - expect(deletes.length).toEqual( - 0, - `Should not have any breakpoint delete commands (${JSON.stringify( - deletes, - )})`, - ); - - const inserts = proxy.sentCommands.filter(_ => _.operation === 'insert'); - expect(inserts.length).toEqual( - 1, - `Should have exactly one breakpoint insert command (${JSON.stringify( - inserts, - )})`, - ); - - const insert = inserts[0]; - expect(insert).toBeDefined(); - - expect(insert.path).toEqual('foo.c'); - expect(insert.line).toEqual(42); - - expect(bkptsOut.length).toEqual(1, 'Should return one breakpoint'); - - expect(bkptsOut[0].line).toEqual( - 42, - 'The returned breakpoint map should have our line in it', - ); - - done(); - }); - }); - - it('should send multiple inserts for multiple breakpoints', done => { - const lines = [4, 8, 15, 16, 23, 42]; - const breakpointsIn = lines.map(_ => { - return {line: _}; - }); - breakpoints - .setSourceBreakpoints('island.c', breakpointsIn) - .then(bkptsOut => { - const inserts = proxy.sentCommands.filter( - _ => _.operation === 'insert', - ); - expect(inserts.length).toEqual( - lines.length, - `Should have exactly ${ - lines.length - } breakpoint insert commands (${JSON.stringify(inserts)})`, - ); - - // we don't impose that the commands are done in any sort of order - inserts.sort((left, right) => left.line - right.line); - - for (let i = 0; i < lines.length; i++) { - expect(inserts[i]).toBeDefined( - 'There should be one insert command per line', - ); - expect(inserts[i].path).toEqual( - 'island.c', - 'The insert command should have the proper file', - ); - expect(inserts[i].line).toEqual( - lines[i], - 'The insert command should have the proper line', - ); - } - - expect(bkptsOut.length).toEqual( - lines.length, - 'The returned handle map should have all of the given lines', - ); - - for (const line of lines) { - const bkpt = bkptsOut.find(_ => _.line === line); - - expect(bkpt).toBeDefined( - 'Each given line should be in the returned array', - ); - } - - done(); - }); - }); - - it('should send one delete command for multiple breakpoints', done => { - const lines = [4, 8, 15, 16, 23, 42]; - const breakpointsIn = lines.map(_ => { - return {line: _}; - }); - breakpoints - .setSourceBreakpoints('island.c', breakpointsIn) - .then(bkptsOut => { - proxy.clearCommands(); - - for (const line of lines) { - const bkpt = bkptsOut.find(_ => _.line === line); - expect(bkpt).toBeDefined( - 'Each given line should be in the handle map', - ); - } - - const linesToRemove = [8, 42]; - const newLines = lines.filter(_ => !linesToRemove.includes(_)); - const idsToRemove = linesToRemove.map(_ => proxy.idForLine(_)); - - const newBreakpointsIn = newLines.map(_ => { - return {line: _}; - }); - breakpoints - .setSourceBreakpoints('island.c', newBreakpointsIn) - .then(newMap => { - expect(proxy.sentCommands.length).toEqual( - 1, - 'All deletions should be done by a single command', - ); - const command = proxy.sentCommands[0]; - expect(command).toBeDefined(); - expect(command.ids.length).toEqual( - lines.length - newLines.length, - 'The delete command should cover all removed lines', - ); - - for (const id of idsToRemove) { - expect(id).toBeDefined(); - expect(command.ids.includes(id)).toBeTruthy( - 'The gdb id of each removed breakpoint should be on the delete command', - ); - } - - expect(newMap.length).toEqual( - newLines.length, - 'The returned handle map should contain all remaining lines', - ); - - for (const line of newLines) { - const bkpt = newMap.find(_ => _.line === line); - expect(bkpt).toBeDefined( - 'All remaining lines should be returned', - ); - } - - done(); - }); - }); - }); -}); diff --git a/modules/atom-ide-debugger-native-gdb/spec/MILineParserSpec.js b/modules/atom-ide-debugger-native-gdb/spec/MILineParserSpec.js deleted file mode 100644 index 1cb280448d..0000000000 --- a/modules/atom-ide-debugger-native-gdb/spec/MILineParserSpec.js +++ /dev/null @@ -1,329 +0,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. - * - * @flow strict-local - * @format - */ - -import invariant from 'assert'; -import MILineParser from '../lib/MILineParser'; -import { - MIAsyncRecord, - MIRecord, - MIResultRecord, - MIStreamRecord, -} from '../lib/MIRecord'; - -describe('MILineParser', () => { - let parser; - - beforeEach(() => { - parser = new MILineParser(); - }); - - describe('when given invalid input', () => { - it('should throw an exception on invalid leading character', () => { - const corruptEvent = '!'; - let thrown = false; - - try { - parser.parseMILine(corruptEvent); - } catch (error) { - expect(error.message).toEqual("Line is not an MI record at: '!'"); - thrown = true; - } - expect(thrown).toBe(true); - }); - - it('should throw an exception on a badly formatted token', () => { - const corruptEvent = '3.14159~"a float is not a valid token"'; - let thrown = false; - - try { - parser.parseMILine(corruptEvent); - } catch (error) { - expect(error.message).toEqual( - 'Line is not an MI record at: \'3.14159~"a float is not a valid token"\'', - ); - thrown = true; - } - expect(thrown).toBe(true); - }); - }); - - describe('when given the debugger prompt', () => { - it('should return an empty record', () => { - const event = '(gdb) '; - const record = parser.parseMILine(event); - - expect(record.constructor).toBe(MIRecord.prototype.constructor); - }); - }); - - describe('when given stream output events', () => { - it('should parse console output properly', () => { - const consoleEvent = '~"some console text"'; - const record = parser.parseMILine(consoleEvent); - - expect(record instanceof MIStreamRecord).toBe(true); - invariant(record instanceof MIStreamRecord); - - expect(record.streamTarget).toEqual('console'); - expect(record.text).toEqual('some console text'); - }); - - it('should parse target output properly', () => { - const consoleEvent = '@"some target text"'; - const record = parser.parseMILine(consoleEvent); - - expect(record instanceof MIStreamRecord).toBe(true); - invariant(record instanceof MIStreamRecord); - - expect(record.streamTarget).toEqual('target'); - expect(record.text).toEqual('some target text'); - }); - - it('should parse log output properly', () => { - const consoleEvent = '&"some log text"'; - const record = parser.parseMILine(consoleEvent); - - expect(record instanceof MIStreamRecord).toBe(true); - invariant(record instanceof MIStreamRecord); - - expect(record.streamTarget).toEqual('log'); - expect(record.text).toEqual('some log text'); - }); - - it('should parse escaped characters in strings properly', () => { - const consoleEvent = '~"this string has \\"bel\\\'s\\" on \\b\\b\\b"'; - const record = parser.parseMILine(consoleEvent); - - expect(record instanceof MIStreamRecord).toBe(true); - invariant(record instanceof MIStreamRecord); - - expect(record.streamTarget).toEqual('console'); - expect(record.text).toEqual('this string has "bel\'s" on \b\b\b'); - }); - - it('should throw an exception on an unterminated string', () => { - const corruptEvent = '~"this string is not terminated'; - let thrown = false; - - try { - parser.parseMILine(corruptEvent); - } catch (error) { - expect(error.message).toEqual( - "End quote missing on string at: 'this string is not terminated'", - ); - thrown = true; - } - - expect(thrown).toBe(true); - }); - - it('should throw an exception if a stream event starts with a token', () => { - const corruptEvent = '4~"this string has a token."'; - let thrown = false; - - try { - parser.parseMILine(corruptEvent); - } catch (error) { - expect(error.message).toEqual( - 'Token is not expected on stream record: \'4~"this string has a token."\'', - ); - thrown = true; - } - - expect(thrown).toBe(true); - }); - }); - - describe('when given result output', () => { - it('should parse empty output properly', () => { - const output = '^done'; - const record = parser.parseMILine(output); - - expect(record instanceof MIResultRecord).toBe(true); - - if (record instanceof MIResultRecord) { - expect(record.token).toBe(null); - expect(record.resultClass).toEqual('done'); - expect(record.result).toEqual({}); - } - }); - - it('should parse simple result output properly', () => { - const output = '42^done,one="1",two="2"'; - const record = parser.parseMILine(output); - - expect(record instanceof MIResultRecord).toBe(true); - - if (record instanceof MIResultRecord) { - expect(record.token).toEqual(42); - expect(record.resultClass).toEqual('done'); - expect(record.result).toEqual({one: '1', two: '2'}); - } - }); - - it('should parse an empty tuple in result output properly', () => { - const output = '42^error,one={}'; - const record = parser.parseMILine(output); - - expect(record instanceof MIResultRecord).toBe(true); - - if (record instanceof MIResultRecord) { - expect(record.token).toEqual(42); - expect(record.resultClass).toEqual('error'); - expect(record.result).toEqual({one: {}}); - } - }); - - it('should parse a tuple in result output properly', () => { - const output = '42^running,one={two="2",three="3"}'; - const record = parser.parseMILine(output); - - expect(record instanceof MIResultRecord).toBe(true); - - if (record instanceof MIResultRecord) { - expect(record.token).toEqual(42); - expect(record.resultClass).toEqual('running'); - expect(record.result).toEqual({one: {two: '2', three: '3'}}); - } - }); - - it('should parse an empty list in result output properly', () => { - const output = '42^connected,one=[]'; - const record = parser.parseMILine(output); - - expect(record instanceof MIResultRecord).toBe(true); - - if (record instanceof MIResultRecord) { - expect(record.token).toEqual(42); - expect(record.resultClass).toEqual('connected'); - expect(record.result).toEqual({one: []}); - } - }); - - it('should parse a value list in result output properly', () => { - const output = '42^exit,one=["2","3"]'; - const record = parser.parseMILine(output); - - expect(record instanceof MIResultRecord).toBe(true); - - if (record instanceof MIResultRecord) { - expect(record.token).toEqual(42); - expect(record.resultClass).toEqual('exit'); - expect(record.result).toEqual({one: ['2', '3']}); - } - }); - - it('should parse a result list in result output properly', () => { - const output = '42^done,one=[two="2",three="3"]'; - const record = parser.parseMILine(output); - - expect(record instanceof MIResultRecord).toBe(true); - - if (record instanceof MIResultRecord) { - expect(record.token).toEqual(42); - expect(record.resultClass).toEqual('done'); - expect(record.result).toEqual({one: [{two: '2'}, {three: '3'}]}); - } - }); - - it('should parse a compex result list in result output properly', () => { - const output = '42^done,one={two="2",inner={four="4",five=[]},three="3"}'; - const record = parser.parseMILine(output); - - expect(record instanceof MIResultRecord).toBe(true); - - if (record instanceof MIResultRecord) { - expect(record.token).toEqual(42); - expect(record.resultClass).toEqual('done'); - expect(record.result).toEqual({ - one: { - two: '2', - inner: {four: '4', five: []}, - three: '3', - }, - }); - } - }); - - it('should throw an exception on an invalid result class', () => { - const output = '42^invalid'; - - let thrown = false; - try { - parser.parseMILine(output); - } catch (error) { - expect(error.message).toEqual("Result class expected at 'invalid'"); - thrown = true; - } - - expect(thrown).toBe(true); - }); - }); - - describe('when given async output', () => { - it('should parse empty async exec output properly', () => { - const asyncOutput = '*stopped'; - const record = parser.parseMILine(asyncOutput); - - expect(record instanceof MIAsyncRecord).toBe(true); - - if (record instanceof MIAsyncRecord) { - expect(record.token).toBe(null); - expect(record.recordType).toEqual('async-exec'); - expect(record.asyncClass).toEqual('stopped'); - expect(record.result).toEqual({}); - } - }); - - it('should parse empty async status output properly', () => { - const asyncOutput = '1+stopped'; - const record = parser.parseMILine(asyncOutput); - - expect(record instanceof MIAsyncRecord).toBe(true); - - if (record instanceof MIAsyncRecord) { - expect(record.token).toBe(1); - expect(record.recordType).toEqual('async-status'); - expect(record.asyncClass).toEqual('stopped'); - expect(record.result).toEqual({}); - } - }); - - it('should parse empty async notify output properly', () => { - const asyncOutput = '2=stopped'; - const record = parser.parseMILine(asyncOutput); - - expect(record instanceof MIAsyncRecord).toBe(true); - - if (record instanceof MIAsyncRecord) { - expect(record.token).toBe(2); - expect(record.recordType).toEqual('async-notify'); - expect(record.asyncClass).toEqual('stopped'); - expect(record.result).toEqual({}); - } - }); - - it('should parse simple async notify output', () => { - const asyncOutput = '2=stopped,one={two="three"}'; - const record = parser.parseMILine(asyncOutput); - - expect(record instanceof MIAsyncRecord).toBe(true); - - if (record instanceof MIAsyncRecord) { - expect(record.token).toBe(2); - expect(record.recordType).toEqual('async-notify'); - expect(record.asyncClass).toEqual('stopped'); - expect(record.result).toEqual({one: {two: 'three'}}); - } - }); - }); -}); diff --git a/modules/atom-ide-debugger-native-gdb/spec/MIProxySpec.js b/modules/atom-ide-debugger-native-gdb/spec/MIProxySpec.js deleted file mode 100644 index 3ca7e09867..0000000000 --- a/modules/atom-ide-debugger-native-gdb/spec/MIProxySpec.js +++ /dev/null @@ -1,40 +0,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. - * - * @flow - * @format - */ - -import MIProxy from '../lib/MIProxy'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - -describe('MIProxy', () => { - let proxy; - - beforeEach(() => { - proxy = new MIProxy(); - proxy.start('node', [ - nuclideUri.join(__dirname, '../test-support/RunMIMockServer.js'), - ]); - }); - - it('should talk to the MI server', done => { - proxy.sendCommand('foo').then(response => { - expect(response.resultClass).toEqual('error'); - done(); - }); - }); - - it('should send back results', done => { - proxy.sendCommand('list-features').then(response => { - expect(response.resultClass).toEqual('done'); - expect(response.result).toEqual({features: ['argle', 'bargle', 'blab']}); - done(); - }); - }); -}); diff --git a/modules/atom-ide-debugger-native-gdb/spec/MIRegisterValueSpec.js b/modules/atom-ide-debugger-native-gdb/spec/MIRegisterValueSpec.js deleted file mode 100644 index ec6cbb935f..0000000000 --- a/modules/atom-ide-debugger-native-gdb/spec/MIRegisterValueSpec.js +++ /dev/null @@ -1,126 +0,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. - * - * @flow strict-local - * @format - */ - -import invariant from 'assert'; - -import { - MIRegisterSimpleValue, - MIRegisterIndexedValues, - MIRegisterNamedValues, - MIRegisterValueParser, -} from '../lib/MIRegisterValue'; - -describe('MIRegisterValue', () => { - it('should parse a simple value', () => { - const textValue = '0x7fff5fbff1d4'; - const parser = new MIRegisterValueParser(textValue); - const value = parser.parse(); - - expect(value instanceof MIRegisterSimpleValue).toBeTruthy(); - invariant(value instanceof MIRegisterSimpleValue); - - expect(value.value).toBe('0x7fff5fbff1d4'); - }); - - it('should parse an indexed list', () => { - const textValue = '{0xc3, 0xf5}'; - const parser = new MIRegisterValueParser(textValue); - const value = parser.parse(); - - expect(value instanceof MIRegisterIndexedValues).toBeTruthy(); - invariant(value instanceof MIRegisterIndexedValues); - expect(value.length).toBe(2); - - const value0 = value.valueAt('0'); - expect(value0 instanceof MIRegisterSimpleValue).toBeTruthy(); - invariant(value0 instanceof MIRegisterSimpleValue); - expect(value0.value).toBe('0xc3'); - - const value1 = value.valueAt('1'); - expect(value1 instanceof MIRegisterSimpleValue).toBeTruthy(); - invariant(value1 instanceof MIRegisterSimpleValue); - expect(value1.value).toBe('0xf5'); - }); - - it('should parse an indexed list with compressed entries', () => { - const textValue = '{0xc3, 0xf5 }'; - const parser = new MIRegisterValueParser(textValue); - const value = parser.parse(); - - expect(value instanceof MIRegisterIndexedValues).toBeTruthy(); - invariant(value instanceof MIRegisterIndexedValues); - expect(value.length).toBe(3); - - const value0 = value.valueAt('0'); - expect(value0 instanceof MIRegisterSimpleValue).toBeTruthy(); - invariant(value0 instanceof MIRegisterSimpleValue); - expect(value0.value).toBe('0xc3'); - - const value1 = value.valueAt('1'); - expect(value1 instanceof MIRegisterSimpleValue).toBeTruthy(); - invariant(value1 instanceof MIRegisterSimpleValue); - expect(value1.value).toBe('0xf5'); - - const value2 = value.valueAt('2'); - expect(value2 instanceof MIRegisterSimpleValue).toBeTruthy(); - invariant(value2 instanceof MIRegisterSimpleValue); - expect(value2.value).toBe('0xf5'); - }); - - it('should parse a named list', () => { - const textValue = '{a = 0xc3, b = 0xf5}'; - const parser = new MIRegisterValueParser(textValue); - const value = parser.parse(); - - expect(value instanceof MIRegisterNamedValues).toBeTruthy(); - invariant(value instanceof MIRegisterNamedValues); - expect(value.names.length).toBe(2); - expect(value.names.includes('a')).toBeTruthy(); - expect(value.names.includes('b')).toBeTruthy(); - - const value0 = value.valueAt('a'); - expect(value0 instanceof MIRegisterSimpleValue).toBeTruthy(); - invariant(value0 instanceof MIRegisterSimpleValue); - expect(value0.value).toBe('0xc3'); - - const value1 = value.valueAt('b'); - expect(value1 instanceof MIRegisterSimpleValue).toBeTruthy(); - invariant(value1 instanceof MIRegisterSimpleValue); - expect(value1.value).toBe('0xf5'); - }); - - it('should parse a nested structure', () => { - const textValue = '{a = {0xc3, 0xf5}}'; - const parser = new MIRegisterValueParser(textValue); - const value = parser.parse(); - - expect(value instanceof MIRegisterNamedValues).toBeTruthy(); - invariant(value instanceof MIRegisterNamedValues); - expect(value.names.length).toBe(1); - expect(value.names.includes('a')).toBeTruthy(); - - const valuea = value.valueAt('a'); - expect(valuea instanceof MIRegisterIndexedValues).toBeTruthy(); - invariant(valuea instanceof MIRegisterIndexedValues); - expect(valuea.length).toBe(2); - - const value0 = valuea.valueAt('0'); - expect(value0 instanceof MIRegisterSimpleValue).toBeTruthy(); - invariant(value0 instanceof MIRegisterSimpleValue); - expect(value0.value).toBe('0xc3'); - - const value1 = valuea.valueAt('1'); - expect(value1 instanceof MIRegisterSimpleValue).toBeTruthy(); - invariant(value1 instanceof MIRegisterSimpleValue); - expect(value1.value).toBe('0xf5'); - }); -}); diff --git a/modules/atom-ide-debugger-native-gdb/spec/StackFramesSpec.js b/modules/atom-ide-debugger-native-gdb/spec/StackFramesSpec.js deleted file mode 100644 index f48c8eb787..0000000000 --- a/modules/atom-ide-debugger-native-gdb/spec/StackFramesSpec.js +++ /dev/null @@ -1,257 +0,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. - * - * @flow strict-local - * @format - */ - -import type {Value} from '../lib/MIRecord'; - -import invariant from 'assert'; -import StackFrames from '../lib/StackFrames'; -import MIProxy from '../lib/MIProxy'; -import {MIResultRecord} from '../lib/MIRecord'; - -// The mock class emulates the MI behavior of stack-info-depth and stack-list-frames -class MIProxyMock extends MIProxy { - _fakeStackData: Map>; // thread-id -> stack data - - constructor() { - super(); - this._fakeStackData = new Map([ - [ - 1, - [ - { - // A frame that has symbols - frame: { - level: '0', - addr: '0x000000010000a042', - func: 'main', - file: 'ring_singleton.c', - fullname: '/home/sauron/git/ring_singleton.c', - line: '394', - }, - }, - { - // A frame that's in the runtime w/o symbols - frame: { - level: '1', - addr: '0x0000000100cf5617', - func: '??', - }, - }, - { - // A frame that's in the runtime w/o symbols - frame: { - level: '2', - addr: '0x0000000102cf5617', - func: '??', - from: 'libc.so', - }, - }, - ], - ], - [ - 2, - [ - { - // A frame that has symbols - frame: { - level: '0', - addr: '0x000000010000f00d', - func: 'main', - file: 'dwarf_ring.c', - fullname: '/home/sauron/git/dwarf_ring.c', - line: '79', - }, - }, - { - // A frame that has symbols - frame: { - level: '1', - addr: '0x00000001000ab5fc', - func: 'ring_timeslice', - file: 'ring_dispatch.c', - fullname: '/home/sauron/git/ring_dispatch.c', - line: '79', - }, - }, - { - // A frame that's in the runtime w/o symbols - frame: { - level: '2', - addr: '0x0000000100141593', - func: '??', - }, - }, - { - // A frame that's in the runtime w/o symbols - frame: { - level: '3', - addr: '0x0000000102fffffe', - func: '??', - from: 'libc.so', - }, - }, - ], - ], - ]); - } - - async sendCommand(command: string): Promise { - let result: MIResultRecord = new MIResultRecord( - null, - {msg: `Invalid command "${command}"`}, - 'error', - ); - - const match = command.match(/^([^ ]+) *(.*)$/); - - if (match != null) { - const [, op, args] = match; - - if (op === 'stack-info-depth') { - const depthArgs = args.match(/^--thread ([0-9]+)$/); - if (depthArgs != null) { - const [, thread] = depthArgs; - invariant(thread != null); - - const threadId = parseInt(thread, 10); - const stackData = this._fakeStackData.get(threadId); - if (stackData == null) { - result = new MIResultRecord( - null, - { - msg: `Invalid thread id: ${threadId}`, - }, - 'error', - ); - } else { - result = new MIResultRecord( - null, - { - depth: `${stackData.length}`, - }, - 'done', - ); - } - } - } else if (op === 'stack-list-frames') { - const listArgs = args.match( - /^--thread ([0-9]+) --no-frame-filters ([0-9]+) ([0-9]+)$/, - ); - if (listArgs != null) { - const [, thread, lowFrame, highFrame] = listArgs; - invariant(thread != null); - invariant(lowFrame != null); - invariant(highFrame != null); - - const threadId = parseInt(thread, 10); - const low = parseInt(lowFrame, 10); - const high = parseInt(highFrame, 10); - - const stackData = this._fakeStackData.get(threadId); - - if (stackData == null) { - result = new MIResultRecord( - null, - { - msg: `Invalid thread id: ${threadId}`, - }, - 'error', - ); - } else if (low >= stackData.length) { - result = new MIResultRecord( - null, - {msg: '-stack-list-frames: Not enough frames in stack.'}, - 'error', - ); - } else { - const stack = stackData.slice(low, high + 1); - result = new MIResultRecord(null, {stack}, 'done'); - } - } - } - } - - return result; - } -} - -describe('StackFrames', () => { - let proxy: MIProxyMock; - let stackFrames: StackFrames; - - beforeEach(() => { - proxy = new MIProxyMock(); - stackFrames = new StackFrames(proxy); - }); - - it('should return stack frames', done => { - stackFrames - .stackFramesForThread(1) - .then(body => { - expect(body.totalFrames).toBe(3); - expect(body.stackFrames.length).toBe(3); - - expect(body.stackFrames[0].id).toBeDefined(); - expect(body.stackFrames[0].name).toBe('main'); - expect(body.stackFrames[0].source).toBeDefined(); - expect(body.stackFrames[0].source.name).toBe('ring_singleton.c'); - expect(body.stackFrames[0].source.path).toBe( - '/home/sauron/git/ring_singleton.c', - ); - expect(body.stackFrames[0].line).toBe(394); - expect(body.stackFrames[0].column).toBe(0); - - expect(body.stackFrames[1].id).toBeDefined(); - expect(body.stackFrames[1].name).toBe('??'); - expect(body.stackFrames[1].source).toBeUndefined(); - expect(body.stackFrames[1].line).toBe(0); - expect(body.stackFrames[1].column).toBe(0); - - expect(body.stackFrames[2].id).toBeDefined(); - expect(body.stackFrames[2].name).toBe('??'); - expect(body.stackFrames[2].source).toBeUndefined(); - expect(body.stackFrames[2].line).toBe(0); - expect(body.stackFrames[2].column).toBe(0); - - done(); - }) - .catch(error => { - expect(true).toBe(false, error.message); - done(); - }); - }); - - it('should return selected stack frames', done => { - stackFrames - .stackFramesForThread(2, 1, 1) - .then(body => { - expect(body.totalFrames).toBe(4); - expect(body.stackFrames.length).toBe(1); - - expect(body.stackFrames[0].id).toBeDefined(); - expect(body.stackFrames[0].name).toBe('ring_timeslice'); - expect(body.stackFrames[0].source).toBeDefined(); - expect(body.stackFrames[0].source.name).toBe('ring_dispatch.c'); - expect(body.stackFrames[0].source.path).toBe( - '/home/sauron/git/ring_dispatch.c', - ); - expect(body.stackFrames[0].line).toBe(79); - expect(body.stackFrames[0].column).toBe(0); - - done(); - }) - .catch(error => { - expect(true).toBe(false, error.message); - done(); - }); - }); -}); diff --git a/modules/atom-ide-debugger-native-gdb/spec/VariablesSpec.js b/modules/atom-ide-debugger-native-gdb/spec/VariablesSpec.js deleted file mode 100644 index 64e1fc5cb2..0000000000 --- a/modules/atom-ide-debugger-native-gdb/spec/VariablesSpec.js +++ /dev/null @@ -1,150 +0,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. - * - * @flow strict-local - * @format - */ - -import type {CachedStackFrame} from '../lib/StackFrames'; - -import MIProxy from '../lib/MIProxy'; -import {MIResultRecord} from '../lib/MIRecord'; -import StackFrames from '../lib/StackFrames'; -import Variables from '../lib/Variables'; - -class MockStackFrames extends StackFrames { - stackFrameByHandle(handle: number): ?CachedStackFrame { - return { - threadId: 1, - frameIndex: 0, - }; - } -} - -type StoredVar = { - value: string, - type: string, -}; - -// The mock class emulates the MI behavior of stack-list-variables -class MIProxyMock extends MIProxy { - _nextVar = 1; - _vars: Map = new Map(); - - constructor() { - super(); - } - - async sendCommand(command: string): Promise { - let result: MIResultRecord = new MIResultRecord( - null, - {msg: `Invalid command "${command}"`}, - 'error', - ); - - const match = command.match(/^([^ ]+) *(.*)$/); - - if (match != null) { - const [, op, args] = match; - - if (op === 'stack-list-variables') { - const listArgs = args.match( - /^--thread ([0-9]+) --frame ([0-9]+) --no-values$/, - ); - if (listArgs != null) { - const vars = { - variables: [ - {name: 'intval', value: '42', type: 'int'}, - {name: 'structval', type: 'mystruct'}, - ], - }; - - result = new MIResultRecord(null, vars, 'done'); - } - } else if (op === 'var-create') { - const varCreateArgs = args.match( - /^--thread ([0-9]+) --frame ([0-9]+) - [@*] (.*)$/, - ); - if (varCreateArgs != null) { - const [, thread, , exp] = varCreateArgs; - const name = `var${this._nextVar++}`; - const created = { - name, - numchild: '0', - value: exp === 'intval' ? '42' : '...', - type: exp === 'intval' ? 'int' : 'mystruct', - 'thread-id': thread, - has_more: '0', - }; - - this._vars.set(created.name, { - value: created.value, - type: created.type, - }); - - result = new MIResultRecord(null, created, 'done'); - } - } else if (op === 'var-evaluate-expression') { - const value = this._vars.get(args); - const body = { - value: value == null ? '??' : value.value, - }; - - result = new MIResultRecord(null, body, 'done'); - } else if (op === 'var-info-type') { - const value = this._vars.get(args); - const body = { - type: value == null ? '??' : value.type, - }; - - result = new MIResultRecord(null, body, 'done'); - } - } - - return result; - } -} - -describe('Variables', () => { - let proxy: MIProxyMock; - let stackFrames: MockStackFrames; - let variables: Variables; - - beforeEach(() => { - proxy = new MIProxyMock(); - stackFrames = new MockStackFrames(proxy); - variables = new Variables(proxy, stackFrames); - }); - - it('getVariables() should return variables', done => { - const varref = variables.variableReferenceForStackFrame(1000); - variables - .getVariables(varref) - .then(vars => { - expect(vars.length).toBe(2); - - expect(vars[0].name).toBe('intval'); - expect(vars[0].type).toBe('int'); - expect(vars[0].value).toBe('42'); - expect(vars[0].variablesReference).toBe(0); - - expect(vars[1].name).toBe('structval'); - expect(vars[1].type).toBe('mystruct'); - expect(vars[1].value).toBe('...'); - - // $$TODO when indexed variables are supported - // expect(vars[1].variablesReference !== 0).toBeTruthy(); - - done(); - }) - .catch(error => { - expect(true).toBe(false, error.message); - done(); - }); - }); -}); diff --git a/modules/atom-ide-debugger-native-gdb/test-support/MockMIServer.js b/modules/atom-ide-debugger-native-gdb/test-support/MockMIServer.js index dbd7cc9f6a..9d9519bb0a 100644 --- a/modules/atom-ide-debugger-native-gdb/test-support/MockMIServer.js +++ b/modules/atom-ide-debugger-native-gdb/test-support/MockMIServer.js @@ -1,3 +1,15 @@ +'use strict'; + +var _readline = _interopRequireDefault(require('readline')); + +var _yargs; + +function _load_yargs() { + return _yargs = _interopRequireDefault(require('yargs')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,47 +18,32 @@ * LICENSE file in 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 simple app that pretends to be an MI server for tests */ -import readline from 'readline'; -import yargs from 'yargs'; - -const rl = readline.createInterface({ +const rl = _readline.default.createInterface({ input: process.stdin, - output: process.stdout, + output: process.stdout }); -type Handler = ( - positionals: Array, - args: Object, - token: number, -) => void; - -function writeResult(token: number, resultClass: string, result: string): void { +function writeResult(token, resultClass, result) { process.stdout.write(`${token}^${resultClass},${result}\n`); } -const handlers: Map = new Map([ - ['list-features', listFeatures], -]); +const handlers = new Map([['list-features', listFeatures]]); -function listFeatures( - positionals: Array, - args: Object, - token: number, -): void { +function listFeatures(positionals, args, token) { writeResult(token, 'done', 'features=["argle", "bargle", "blab"]'); } -function respondTo(line: string): void { +function respondTo(line) { process.stderr.write(`got line ${line}`); - const args = yargs.parse(line.split(/\s+/)); + const args = (_yargs || _load_yargs()).default.parse(line.split(/\s+/)); const positionals = args._; if (positionals.length === 0) { @@ -61,25 +58,17 @@ function respondTo(line: string): void { if (match == null) { // Untokenized commands come back as an error on the log stream process.stdout.write(`&"${first}\\n"\n`); - process.stdout.write( - `&"Undefined command: \\"${first}\\". Try \\"help\\"."\n`, - ); + process.stdout.write(`&"Undefined command: \\"${first}\\". Try \\"help\\"."\n`); // ... as well as returning a real error - process.stdout.write( - `^error,msg="Undefined command: \\"${first}\\". Try \\"help\\"."\n`, - ); + process.stdout.write(`^error,msg="Undefined command: \\"${first}\\". Try \\"help\\"."\n`); return; } const [, token, command] = match; const handler = handlers.get(command); if (handler == null) { - writeResult( - token, - 'error', - 'msg="Undefined command: \\"${command}\\". Try \\"help\\"."', - ); + writeResult(token, 'error', 'msg="Undefined command: \\"${command}\\". Try \\"help\\"."'); return; } @@ -88,4 +77,4 @@ function respondTo(line: string): void { process.stderr.write('mock server running\n'); -rl.on('line', line => respondTo(line)).on('close', _ => process.exit(0)); +rl.on('line', line => respondTo(line)).on('close', _ => process.exit(0)); \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/test-support/RunMIMockServer.js b/modules/atom-ide-debugger-native-gdb/test-support/RunMIMockServer.js index 43f228c7d8..45bbdf4438 100644 --- a/modules/atom-ide-debugger-native-gdb/test-support/RunMIMockServer.js +++ b/modules/atom-ide-debugger-native-gdb/test-support/RunMIMockServer.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,7 +8,7 @@ * LICENSE file in 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 */ @@ -15,5 +17,5 @@ */ // eslint-disable-next-line nuclide-internal/modules-dependencies -require('nuclide-node-transpiler'); -require('./MockMIServer'); +require('../../nuclide-node-transpiler'); +require('./MockMIServer'); \ No newline at end of file diff --git a/modules/atom-ide-debugger-native-gdb/utils.js b/modules/atom-ide-debugger-native-gdb/utils.js index 34e7731ac6..88d4257bf9 100644 --- a/modules/atom-ide-debugger-native-gdb/utils.js +++ b/modules/atom-ide-debugger-native-gdb/utils.js @@ -1,3 +1,16 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.resolveConfiguration = resolveConfiguration; + +var _nuclideDebuggerCommon; + +function _load_nuclideDebuggerCommon() { + return _nuclideDebuggerCommon = require('../nuclide-debugger-common'); +} + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,44 +19,32 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type {IProcessConfig} from 'nuclide-debugger-common/types'; +async function resolveConfiguration(configuration) { + let sourcePath = configuration.config.sourcePath; -import {getVSCodeDebuggerAdapterServiceByNuclideUri} from 'nuclide-debugger-common'; -import invariant from 'assert'; - -export async function resolveConfiguration( - configuration: IProcessConfig, -): Promise { - let sourcePath: ?string = configuration.config.sourcePath; - - const debuggerService = getVSCodeDebuggerAdapterServiceByNuclideUri( - configuration.targetUri, - ); + const debuggerService = (0, (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).getVSCodeDebuggerAdapterServiceByNuclideUri)(configuration.targetUri); if (sourcePath == null || sourcePath.trim() === '') { if (configuration.debugMode === 'launch') { - sourcePath = await debuggerService.getBuckRootFromUri( - configuration.config.program, - ); + sourcePath = await debuggerService.getBuckRootFromUri(configuration.config.program); } else { - sourcePath = await debuggerService.getBuckRootFromPid( - configuration.config.pid, - ); + sourcePath = await debuggerService.getBuckRootFromPid(configuration.config.pid); } } - invariant(sourcePath != null); + if (!(sourcePath != null)) { + throw new Error('Invariant violation: "sourcePath != null"'); + } + sourcePath = await debuggerService.realpath(sourcePath); - return { - ...configuration, - config: { - ...configuration.config, - sourcePath, - }, - }; -} + return Object.assign({}, configuration, { + config: Object.assign({}, configuration.config, { + sourcePath + }) + }); +} \ No newline at end of file diff --git a/modules/atom-ide-debugger-node/main.js b/modules/atom-ide-debugger-node/main.js index 9be05c6fe0..3dc98ec042 100644 --- a/modules/atom-ide-debugger-node/main.js +++ b/modules/atom-ide-debugger-node/main.js @@ -1,58 +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 - */ - -import type { - AutoGenConfig, - NuclideDebuggerProvider, -} from 'nuclide-debugger-common/types'; -import * as React from 'react'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import {VsAdapterTypes} from 'nuclide-debugger-common/constants'; -import {AutoGenLaunchAttachProvider} from 'nuclide-debugger-common/AutoGenLaunchAttachProvider'; +'use strict'; + +var _react = _interopRequireWildcard(require('react')); + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../nuclide-commons-atom/createPackage')); +} + +var _constants; + +function _load_constants() { + return _constants = require('../nuclide-debugger-common/constants'); +} + +var _AutoGenLaunchAttachProvider; + +function _load_AutoGenLaunchAttachProvider() { + return _AutoGenLaunchAttachProvider = require('../nuclide-debugger-common/AutoGenLaunchAttachProvider'); +} + +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 Activation { constructor() {} dispose() {} - createDebuggerProvider(): NuclideDebuggerProvider { + createDebuggerProvider() { return { - type: VsAdapterTypes.NODE, + type: (_constants || _load_constants()).VsAdapterTypes.NODE, getLaunchAttachProvider: connection => { - return new AutoGenLaunchAttachProvider( - 'Node', - connection, - getNodeConfig(), - ); - }, + return new (_AutoGenLaunchAttachProvider || _load_AutoGenLaunchAttachProvider()).AutoGenLaunchAttachProvider('Node', connection, getNodeConfig()); + } }; } -} +} /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 getNodeConfig(): AutoGenConfig { +function getNodeConfig() { const program = { name: 'program', type: 'string', description: 'Absolute path to the program.', required: true, - visible: true, + visible: true }; const cwd = { name: 'cwd', type: 'string', - description: - 'Absolute path to the working directory of the program being debugged.', + description: 'Absolute path to the working directory of the program being debugged.', required: true, - visible: true, + visible: true }; const stopOnEntry = { name: 'stopOnEntry', @@ -60,7 +69,7 @@ function getNodeConfig(): AutoGenConfig { description: 'Automatically stop program after launch.', defaultValue: false, required: false, - visible: true, + visible: true }; const args = { @@ -70,34 +79,31 @@ function getNodeConfig(): AutoGenConfig { description: 'Command line arguments passed to the program.', defaultValue: [], required: false, - visible: true, + visible: true }; const runtimeExecutable = { name: 'runtimeExecutable', type: 'string', - description: - '(Optional) Runtime to use, an absolute path or the name of a runtime available on PATH', + description: '(Optional) Runtime to use, an absolute path or the name of a runtime available on PATH', required: false, - visible: true, + visible: true }; const env = { name: 'env', type: 'object', - description: - '(Optional) Environment variables (e.g. SHELL=/bin/bash PATH=/bin)', + description: '(Optional) Environment variables (e.g. SHELL=/bin/bash PATH=/bin)', defaultValue: {}, required: false, - visible: true, + visible: true }; const outFiles = { name: 'outFiles', type: 'array', itemType: 'string', - description: - '(Optional) When source maps are enabled, these glob patterns specify the generated JavaScript files', + description: '(Optional) When source maps are enabled, these glob patterns specify the generated JavaScript files', defaultValue: [], required: false, - visible: true, + visible: true }; const protocol = { name: 'protocol', @@ -105,7 +111,7 @@ function getNodeConfig(): AutoGenConfig { description: '', defaultValue: 'inspector', required: false, - visible: false, + visible: false }; const port = { @@ -113,40 +119,37 @@ function getNodeConfig(): AutoGenConfig { type: 'number', description: 'Port', required: true, - visible: true, + visible: true }; return { launch: { launch: true, - vsAdapterType: VsAdapterTypes.NODE, + vsAdapterType: (_constants || _load_constants()).VsAdapterTypes.NODE, threads: false, - properties: [ - program, - cwd, - stopOnEntry, - args, - runtimeExecutable, - env, - outFiles, - protocol, - ], + properties: [program, cwd, stopOnEntry, args, runtimeExecutable, env, outFiles, protocol], scriptPropertyName: 'program', cwdPropertyName: 'cwd', scriptExtension: '.js', - header: ( -

This is intended to debug node.js files (for node version 6.3+).

- ), + header: _react.createElement( + 'p', + null, + 'This is intended to debug node.js files (for node version 6.3+).' + ) }, attach: { launch: false, - vsAdapterType: VsAdapterTypes.NODE, + vsAdapterType: (_constants || _load_constants()).VsAdapterTypes.NODE, threads: false, properties: [port], scriptExtension: '.js', - header:

Attach to a running node.js process

, - }, + header: _react.createElement( + 'p', + null, + 'Attach to a running node.js process' + ) + } }; } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/modules/atom-ide-debugger-ocaml/DEVELOPMENT b/modules/atom-ide-debugger-ocaml/DEVELOPMENT deleted file mode 100644 index e27a0b58b0..0000000000 --- a/modules/atom-ide-debugger-ocaml/DEVELOPMENT +++ /dev/null @@ -1,3 +0,0 @@ -This file exists to indicate that the source should be transpiled. - -During publishing, all files are pre-transpiled and this file is ignored. diff --git a/modules/atom-ide-debugger-ocaml/lib/OCamlDebugProxy.js b/modules/atom-ide-debugger-ocaml/lib/OCamlDebugProxy.js index 63572b81f8..7f3ef3e00b 100644 --- a/modules/atom-ide-debugger-ocaml/lib/OCamlDebugProxy.js +++ b/modules/atom-ide-debugger-ocaml/lib/OCamlDebugProxy.js @@ -1,3 +1,20 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.OCamlDebugProxy = exports.PROMPT = undefined; + +var _child_process = _interopRequireDefault(require('child_process')); + +var _vscodeDebugadapter; + +function _load_vscodeDebugadapter() { + return _vscodeDebugadapter = require('vscode-debugadapter'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,55 +23,42 @@ * LICENSE file in 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 child_process from 'child_process'; -import {logger} from 'vscode-debugadapter'; +const PROMPT = exports.PROMPT = '(ocd) '; -export const PROMPT = '(ocd) '; - -function stripPrompt(s: string): string { +function stripPrompt(s) { return s.substr(0, s.length - PROMPT.length); } -export type DebugFinishedResults = - | {kind: 'finished'} - | {kind: 'error', message: string}; - -export class OCamlDebugProxy { - _debuggerProcess: child_process$ChildProcess; - _programFinishedCallback: DebugFinishedResults => void; +class OCamlDebugProxy { - constructor( - command: string, - debuggerArguments: Array, - programFinishedCallback: DebugFinishedResults => void, - ) { + constructor(command, debuggerArguments, programFinishedCallback) { this._programFinishedCallback = programFinishedCallback; - logger.verbose(`Running "${command} ${debuggerArguments.join(' ')}"`); - this._debuggerProcess = child_process.spawn(command, debuggerArguments); + (_vscodeDebugadapter || _load_vscodeDebugadapter()).logger.verbose(`Running "${command} ${debuggerArguments.join(' ')}"`); + this._debuggerProcess = _child_process.default.spawn(command, debuggerArguments); this._debuggerProcess.stdout.on('data', data => { - logger.verbose(`STDOUT:${data.toString()}`); + (_vscodeDebugadapter || _load_vscodeDebugadapter()).logger.verbose(`STDOUT:${data.toString()}`); }); this._debuggerProcess.stderr.on('data', data => { const dataString = data.toString(); - logger.verbose(`STDERR:${dataString}`); + (_vscodeDebugadapter || _load_vscodeDebugadapter()).logger.verbose(`STDERR:${dataString}`); if (/^Program not found\.$/m.test(dataString)) { - logger.error(dataString); + (_vscodeDebugadapter || _load_vscodeDebugadapter()).logger.error(dataString); this._programFinishedCallback({ kind: 'error', - message: `Invalid executable path ${command}`, + message: `Invalid executable path ${command}` }); } }); } - attachOnPromptListener(onBreak: (s: string) => void): () => void { + attachOnPromptListener(onBreak) { let buffer = ''; const onData = data => { buffer += data; @@ -73,26 +77,26 @@ export class OCamlDebugProxy { this._debuggerProcess.kill(); } - async pause(): Promise { + async pause() { this._debuggerProcess.kill('SIGINT'); await this.waitForPrompt(); } - async resume(): Promise { + async resume() { await this.send('run'); } - send(command: string): Promise { - logger.verbose(`STDIN:${command}`); + send(command) { + (_vscodeDebugadapter || _load_vscodeDebugadapter()).logger.verbose(`STDIN:${command}`); this._debuggerProcess.stdin.write(`${command}\n`); return this.waitForPrompt(); } - waitForPrompt(): Promise { + waitForPrompt() { return new Promise((resolve, reject) => { const dispose = this.attachOnPromptListener(data => { if (data.match(/Time: \d+\nProgram exit.\n?$/)) { - this._programFinishedCallback({kind: 'finished'}); + this._programFinishedCallback({ kind: 'finished' }); } dispose(); @@ -101,3 +105,4 @@ export class OCamlDebugProxy { }); } } +exports.OCamlDebugProxy = OCamlDebugProxy; \ No newline at end of file diff --git a/modules/atom-ide-debugger-ocaml/lib/OCamlDebugger.js b/modules/atom-ide-debugger-ocaml/lib/OCamlDebugger.js index 1c6a2db969..dff0288910 100644 --- a/modules/atom-ide-debugger-ocaml/lib/OCamlDebugger.js +++ b/modules/atom-ide-debugger-ocaml/lib/OCamlDebugger.js @@ -1,48 +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 { - DebugSession, - InitializedEvent, - logger, - LoggingDebugSession, - OutputEvent, - TerminatedEvent, - Thread, - StoppedEvent, -} from 'vscode-debugadapter'; -import * as DebugProtocol from 'vscode-debugprotocol'; -import {Session} from './Session'; - -export const THREAD_ID = 1; - -export type OCamlDebugStartInfo = { - ocamldebugExecutable: string, - executablePath: string, - arguments: Array, - environmentVariables: Array, - workingDirectory: string, - includeDirectories: Array, - breakAfterStart: boolean, - logLevel: number, -}; - -export type LaunchRequestArguments = DebugProtocol.LaunchRequestArguments & - OCamlDebugStartInfo; - -class OCamlDebugSession extends LoggingDebugSession { - _session: Session; - _started = false; - _breakAfterStart: boolean; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.THREAD_ID = undefined; + +var _vscodeDebugadapter; + +function _load_vscodeDebugadapter() { + return _vscodeDebugadapter = require('vscode-debugadapter'); +} + +var _vscodeDebugprotocol; + +function _load_vscodeDebugprotocol() { + return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol')); +} + +var _Session; + +function _load_Session() { + return _Session = require('./Session'); +} + +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 THREAD_ID = exports.THREAD_ID = 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 + */ + +class OCamlDebugSession extends (_vscodeDebugadapter || _load_vscodeDebugadapter()).LoggingDebugSession { /** * Creates a new debug adapter that is used for one debug session. @@ -52,14 +47,12 @@ class OCamlDebugSession extends LoggingDebugSession { super('ocaml-debug'); // this debugger uses zero-based lines and columns + this._started = false; this.setDebuggerLinesStartAt1(true); this.setDebuggerColumnsStartAt1(true); } - _catchAsyncRequestError( - response: ?DebugProtocol.base$Response, - fn: () => Promise, - ) { + _catchAsyncRequestError(response, fn) { fn().catch(error => { const errorMessage = error.stack || error.message || String(error); if (response != null) { @@ -68,19 +61,13 @@ class OCamlDebugSession extends LoggingDebugSession { response.body = { error: { id: -1, - format: errorMessage, - }, + format: errorMessage + } }; this.sendResponse(response); } - this.sendEvent( - new OutputEvent( - `OCaml Debugger ran into an error:\n\`${errorMessage}\``, - 'nuclide_notification', - {type: 'error'}, - ), - ); - this.sendEvent(new TerminatedEvent()); + this.sendEvent(new (_vscodeDebugadapter || _load_vscodeDebugadapter()).OutputEvent(`OCaml Debugger ran into an error:\n\`${errorMessage}\``, 'nuclide_notification', { type: 'error' })); + this.sendEvent(new (_vscodeDebugadapter || _load_vscodeDebugadapter()).TerminatedEvent()); }); } @@ -88,78 +75,53 @@ class OCamlDebugSession extends LoggingDebugSession { * The 'initialize' request is the first request called by the frontend * to interrogate the features the debug adapter provides. */ - initializeRequest( - response: DebugProtocol.InitializeResponse, - args: DebugProtocol.InitializeRequestArguments, - ): void { + initializeRequest(response, args) { response.body = { supportsConfigurationDoneRequest: true, - supportsEvaluateForHovers: true, + supportsEvaluateForHovers: true // TODO: requires Nuclide UI support. // supportsStepBack: true, }; this.sendResponse(response); } - launchRequest( - response: DebugProtocol.LaunchResponse, - args: LaunchRequestArguments, - ): void { + launchRequest(response, args) { this._catchAsyncRequestError(response, async () => { - const config = { - ...args, - }; + const config = Object.assign({}, args); // make sure to 'Stop' the buffered logging if 'trace' is not set - logger.setup(config.logLevel, false); + (_vscodeDebugadapter || _load_vscodeDebugadapter()).logger.setup(config.logLevel, false); - this._session = await Session.start( - config, - breakPointId => this._handleBreakpointHitEvent(breakPointId), - error => this._handleProgramExitedEvent(error), - ); + this._session = await (_Session || _load_Session()).Session.start(config, breakPointId => this._handleBreakpointHitEvent(breakPointId), error => this._handleProgramExitedEvent(error)); this._breakAfterStart = config.breakAfterStart; // Now send the initialized event as we're ready to process breakpoint requests - this.sendEvent(new InitializedEvent()); + this.sendEvent(new (_vscodeDebugadapter || _load_vscodeDebugadapter()).InitializedEvent()); this.sendResponse(response); - this.sendEvent(new StoppedEvent('Program entry', THREAD_ID)); + this.sendEvent(new (_vscodeDebugadapter || _load_vscodeDebugadapter()).StoppedEvent('Program entry', THREAD_ID)); }); } - setBreakPointsRequest( - response: DebugProtocol.SetBreakpointsResponse, - args: DebugProtocol.SetBreakpointsArguments, - ): void { + setBreakPointsRequest(response, args) { this._catchAsyncRequestError(response, async () => { - const breakpoints = await this._session.setBreakpointsByUri( - args.breakpoints || [], - args.source.path, - args.source.name, - ); + const breakpoints = await this._session.setBreakpointsByUri(args.breakpoints || [], args.source.path, args.source.name); response.body = { - breakpoints, + breakpoints }; this.sendResponse(response); }); } - setExceptionBreakPointsRequest( - response: DebugProtocol.SetExceptionBreakpointsResponse, - args: DebugProtocol.SetExceptionBreakpointsArguments, - ): void { + setExceptionBreakPointsRequest(response, args) { this.sendResponse(response); } - configurationDoneRequest( - response: DebugProtocol.ConfigurationDoneResponse, - args: DebugProtocol.ConfigurationDoneRequest, - ): void { + configurationDoneRequest(response, args) { this._catchAsyncRequestError(response, async () => { if (this._breakAfterStart) { - this.sendEvent(new StoppedEvent('Program start', THREAD_ID)); + this.sendEvent(new (_vscodeDebugadapter || _load_vscodeDebugadapter()).StoppedEvent('Program start', THREAD_ID)); } else { await this._session.resume(); } @@ -168,123 +130,93 @@ class OCamlDebugSession extends LoggingDebugSession { }); } - threadsRequest(response: DebugProtocol.ThreadsResponse): void { + threadsRequest(response) { response.body = { - threads: [new Thread(THREAD_ID, 'Please, this is OCaml')], + threads: [new (_vscodeDebugadapter || _load_vscodeDebugadapter()).Thread(THREAD_ID, 'Please, this is OCaml')] }; this.sendResponse(response); } - stackTraceRequest( - response: DebugProtocol.StackTraceResponse, - args: DebugProtocol.StackTraceArguments, - ): void { + stackTraceRequest(response, args) { this._catchAsyncRequestError(response, async () => { response.body = { - stackFrames: await this._session.getStack(), + stackFrames: await this._session.getStack() }; this.sendResponse(response); }); } - scopesRequest( - response: DebugProtocol.ScopesResponse, - args: DebugProtocol.ScopesArguments, - ): void { + scopesRequest(response, args) { this._catchAsyncRequestError(response, async () => { this.sendResponse(response); }); } - variablesRequest( - response: DebugProtocol.VariablesResponse, - args: DebugProtocol.VariablesArguments, - ): void { + variablesRequest(response, args) { this._catchAsyncRequestError(response, async () => { this.sendResponse(response); }); } - evaluateRequest( - response: DebugProtocol.EvaluateResponse, - args: DebugProtocol.EvaluateArguments, - ): void { + evaluateRequest(response, args) { this._catchAsyncRequestError(response, async () => { - const result = await this._session.evaluate( - args.frameId, - args.expression, - ); + const result = await this._session.evaluate(args.frameId, args.expression); response.body = { result, - variablesReference: 0, + variablesReference: 0 }; this.sendResponse(response); }); } - continueRequest( - response: DebugProtocol.ContinueResponse, - args: DebugProtocol.ContinueArguments, - ): void { + continueRequest(response, args) { this._catchAsyncRequestError(response, async () => { await this._session.resume(); this.sendResponse(response); }); } - pauseRequest( - response: DebugProtocol.PauseResponse, - args: DebugProtocol.PauseArguments, - ): void { + pauseRequest(response, args) { this._catchAsyncRequestError(null, async () => { await this._session.pause(); this.sendResponse(response); }); } - nextRequest( - response: DebugProtocol.NextResponse, - args: DebugProtocol.NextArguments, - ): void { + nextRequest(response, args) { this._catchAsyncRequestError(null, async () => { await this._session.stepOver(); this.sendResponse(response); - this.sendEvent(new StoppedEvent('Stepped', THREAD_ID)); + this.sendEvent(new (_vscodeDebugadapter || _load_vscodeDebugadapter()).StoppedEvent('Stepped', THREAD_ID)); }); } - stepInRequest( - response: DebugProtocol.StepInResponse, - args: DebugProtocol.StepInArguments, - ): void { + stepInRequest(response, args) { this._catchAsyncRequestError(null, async () => { await this._session.stepInto(); this.sendResponse(response); - this.sendEvent(new StoppedEvent('Stepped', THREAD_ID)); + this.sendEvent(new (_vscodeDebugadapter || _load_vscodeDebugadapter()).StoppedEvent('Stepped', THREAD_ID)); }); } - stepOutRequest( - response: DebugProtocol.StepOutResponse, - args: DebugProtocol.StepOutArguments, - ): void { + stepOutRequest(response, args) { this._catchAsyncRequestError(null, async () => { await this._session.stepOut(); this.sendResponse(response); - this.sendEvent(new StoppedEvent('Stepped', THREAD_ID)); + this.sendEvent(new (_vscodeDebugadapter || _load_vscodeDebugadapter()).StoppedEvent('Stepped', THREAD_ID)); }); } - _handleBreakpointHitEvent(breakpointId: string): Promise { - this.sendEvent(new StoppedEvent('Breakpoint hit', THREAD_ID)); + _handleBreakpointHitEvent(breakpointId) { + this.sendEvent(new (_vscodeDebugadapter || _load_vscodeDebugadapter()).StoppedEvent('Breakpoint hit', THREAD_ID)); return Promise.resolve(); } - _handleProgramExitedEvent(error: ?string): Promise { - this.sendEvent(new TerminatedEvent()); + _handleProgramExitedEvent(error) { + this.sendEvent(new (_vscodeDebugadapter || _load_vscodeDebugadapter()).TerminatedEvent()); return Promise.resolve(); } } -DebugSession.run(OCamlDebugSession); +(_vscodeDebugadapter || _load_vscodeDebugadapter()).DebugSession.run(OCamlDebugSession); \ No newline at end of file diff --git a/modules/atom-ide-debugger-ocaml/lib/Session.js b/modules/atom-ide-debugger-ocaml/lib/Session.js index 217a80ebac..2fa1f72de1 100644 --- a/modules/atom-ide-debugger-ocaml/lib/Session.js +++ b/modules/atom-ide-debugger-ocaml/lib/Session.js @@ -1,63 +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 type { - Breakpoint, - StackFrame, - SourceBreakpoint, -} from 'vscode-debugprotocol'; -import type {OCamlDebugStartInfo} from './OCamlDebugger'; -import invariant from 'assert'; -import {OCamlDebugProxy} from './OCamlDebugProxy'; -import NuclideUri from 'nuclide-commons/nuclideUri'; -import url from 'url'; -import {logger} from 'vscode-debugadapter'; - -function uriToModuleName(uri: string) { - const pathname = uri.startsWith('file://') ? url.parse(uri).pathname : uri; - invariant(pathname != null && pathname !== ''); - const fileName = NuclideUri.basename(pathname).replace(/\.[^.]+$/, ''); - return fileName.charAt(0).toUpperCase() + fileName.substr(1); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Session = undefined; + +var _OCamlDebugProxy; + +function _load_OCamlDebugProxy() { + return _OCamlDebugProxy = require('./OCamlDebugProxy'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../nuclide-commons/nuclideUri')); } -function extractList( - text: string, - prefix: string, - keepLines: boolean, - empty: T, - f: (s: string[]) => T, -): T { +var _url = _interopRequireDefault(require('url')); + +var _vscodeDebugadapter; + +function _load_vscodeDebugadapter() { + return _vscodeDebugadapter = require('vscode-debugadapter'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function uriToModuleName(uri) { + const pathname = uri.startsWith('file://') ? _url.default.parse(uri).pathname : uri; + + if (!(pathname != null && pathname !== '')) { + throw new Error('Invariant violation: "pathname != null && pathname !== \'\'"'); + } + + const fileName = (_nuclideUri || _load_nuclideUri()).default.basename(pathname).replace(/\.[^.]+$/, ''); + return fileName.charAt(0).toUpperCase() + fileName.substr(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 + */ + +function extractList(text, prefix, keepLines, empty, f) { const i = text.indexOf(prefix); if (i < 0) { return empty; } const t = text.substr(i + prefix.length); - const parts = keepLines - ? t.split(/\r?\n/g) - : t.replace(/[\s\r\n]+/g, ' ').split(' '); + const parts = keepLines ? t.split(/\r?\n/g) : t.replace(/[\s\r\n]+/g, ' ').split(' '); const list = parts.map(s => s.trim()).filter(s => s.length > 0); return f(list); } class Lock { - _inner: Promise; - _expected: number; constructor() { this._inner = Promise.resolve(0); this._expected = 0; } - async enter(): Promise<{exitLock(): void}> { + async enter() { const curCount = await this._inner; if (curCount !== this._expected) { // Sometimes we get multiple Promises waiting on the same _inner, so if we @@ -65,34 +74,18 @@ class Lock { return this.enter(); } - let e: () => void; + let e; this._inner = new Promise(resolve => { this._expected++; e = () => resolve(this._expected); }); - return {exitLock: () => e()}; + return { exitLock: () => e() }; } } -export class Session { - _debugProxy: OCamlDebugProxy; - _modules: Set; - _shortNamesToPaths: Map; - _breakpoints: Map>; - _lock: Lock; - _disposeOnBreakListener: ?() => void; - - _onBreakpointHit: (breakpointId: string) => Promise; - _onProgramExit: (errorText: ?string) => Promise; - - _paused: boolean; - - constructor( - debugProxy: OCamlDebugProxy, - modules: Set, - onBreakpointHit: (breakpointId: string) => Promise, - onProgramExit: (errorText: ?string) => Promise, - ) { +class Session { + + constructor(debugProxy, modules, onBreakpointHit, onProgramExit) { this._debugProxy = debugProxy; this._modules = modules; this._onProgramExit = onProgramExit; @@ -104,7 +97,7 @@ export class Session { this._lock = new Lock(); } - async getStack(): Promise { + async getStack() { const output = await this._send('backtrace'); return extractList(output, 'Backtrace:', true, [], lines => { const frames = []; @@ -121,8 +114,8 @@ export class Session { line: Number(m[4]), column: Number(m[5]), source: { - path, - }, + path + } }); } } @@ -130,19 +123,19 @@ export class Session { }); } - stepOver(): Promise { + stepOver() { return this._step('next'); } - async stepOut(): Promise { + async stepOut() { return this._step('finish'); } - stepInto(): Promise { + stepInto() { return this._step('step 1'); } - async evaluate(frameId: ?number, expr: string): Promise { + async evaluate(frameId, expr) { return this._runWithLock(async () => { if (frameId != null) { await this._send(`frame ${frameId}`); @@ -154,20 +147,16 @@ export class Session { }); } - async _step(command: string): Promise { + async _step(command) { await this._send(command); } - async setBreakpointsByUri( - breakpoints: SourceBreakpoint[], - uri: ?string, - shortname: ?string, - ): Promise { + async setBreakpointsByUri(breakpoints, uri, shortname) { const mapFailedBreakpoint = bp => { return { line: bp.line, column: bp.column || 0, - verified: false, + verified: false }; }; @@ -175,47 +164,37 @@ export class Session { // requested breakpoints, so instead of returning an empty list if something // goes wrong we just have to return a bunch of unverified breakpoints. if (uri == null || shortname == null) { - logger.error( - `Could not set breakpoint: ${JSON.stringify({uri, shortname})}.`, - ); + (_vscodeDebugadapter || _load_vscodeDebugadapter()).logger.error(`Could not set breakpoint: ${JSON.stringify({ uri, shortname })}.`); return breakpoints.map(mapFailedBreakpoint); } const moduleName = uriToModuleName(uri); if (!this._modules.has(moduleName)) { - logger.error( - `Could not set breakpoint: ${moduleName} is not part of the executable.`, - ); + (_vscodeDebugadapter || _load_vscodeDebugadapter()).logger.error(`Could not set breakpoint: ${moduleName} is not part of the executable.`); return breakpoints.map(mapFailedBreakpoint); } const existingBreakpoints = this._breakpoints.get(uri); if (existingBreakpoints) { - await Promise.all( - existingBreakpoints.map(this.deleteBreakpoint.bind(this)), - ); + await Promise.all(existingBreakpoints.map(this.deleteBreakpoint.bind(this))); } this._shortNamesToPaths.set(shortname, uri); - const breakpointsPromise = breakpoints.map(async bp => - this._pauseAndLock(async () => { - const result = await this._send(`break @${moduleName} ${bp.line}`); - logger.verbose(result); - const m = /^Breakpoint (\d+) at \d+: file (.+), line (\d+), characters (\d+)-(\d+)$/m.exec( - result, - ); - if (m) { - return { - id: Number(m[1]), - line: Number(m[3]), - column: Number(m[4]), - verified: true, - }; - } + const breakpointsPromise = breakpoints.map(async bp => this._pauseAndLock(async () => { + const result = await this._send(`break @${moduleName} ${bp.line}`); + (_vscodeDebugadapter || _load_vscodeDebugadapter()).logger.verbose(result); + const m = /^Breakpoint (\d+) at \d+: file (.+), line (\d+), characters (\d+)-(\d+)$/m.exec(result); + if (m) { + return { + id: Number(m[1]), + line: Number(m[3]), + column: Number(m[4]), + verified: true + }; + } - return mapFailedBreakpoint(bp); - }), - ); + return mapFailedBreakpoint(bp); + })); const breakpointsToReturn = await Promise.all(breakpointsPromise); this._breakpoints.set(uri, breakpointsToReturn); @@ -223,7 +202,7 @@ export class Session { return breakpointsToReturn; } - deleteBreakpoint(breakpoint: Breakpoint): Promise { + deleteBreakpoint(breakpoint) { const breakpointId = breakpoint.id; if (breakpointId != null) { return this._pauseAndLock(async () => { @@ -234,7 +213,7 @@ export class Session { return Promise.resolve(); } - async pause(): Promise { + async pause() { if (this._paused) { return true; } @@ -247,51 +226,45 @@ export class Session { return false; } - resume(): void { + resume() { this._paused = false; - this._disposeOnBreakListener = this._debugProxy.attachOnPromptListener( - output => { - const lines = output - .replace(/\r?\n/g, '\n') - .split('\n') - .filter(l => l.length > 0) - .reverse(); - const handleEvent = (breakpointId: ?string, error?: string) => { - this._runWithLock(() => { - this._paused = true; - if (breakpointId != null) { - return this._onBreakpointHit(breakpointId); - } else { - return this._onProgramExit(error); - } - }); - }; - for (const line of lines) { - let m = /^Unhandled exception: (.+)$/.exec(line); - if (m) { - return handleEvent(undefined, m[1]); - } - if (line === 'Program end.') { - return handleEvent(undefined, undefined); - } - m = /^Breakpoint: (\d+)/.exec(line); - if (m) { - return handleEvent(m[1], undefined); + this._disposeOnBreakListener = this._debugProxy.attachOnPromptListener(output => { + const lines = output.replace(/\r?\n/g, '\n').split('\n').filter(l => l.length > 0).reverse(); + const handleEvent = (breakpointId, error) => { + this._runWithLock(() => { + this._paused = true; + if (breakpointId != null) { + return this._onBreakpointHit(breakpointId); + } else { + return this._onProgramExit(error); } + }); + }; + for (const line of lines) { + let m = /^Unhandled exception: (.+)$/.exec(line); + if (m) { + return handleEvent(undefined, m[1]); } - }, - ); + if (line === 'Program end.') { + return handleEvent(undefined, undefined); + } + m = /^Breakpoint: (\d+)/.exec(line); + if (m) { + return handleEvent(m[1], undefined); + } + } + }); this._debugProxy.resume(); } - dispose(): void { + dispose() { if (this._debugProxy) { this._debugProxy.kill(); } } - async _runWithLock(f: () => Promise): Promise { - const {exitLock} = await this._lock.enter(); + async _runWithLock(f) { + const { exitLock } = await this._lock.enter(); try { return await f(); } finally { @@ -299,7 +272,7 @@ export class Session { } } - async _pauseAndLock(f: () => Promise): Promise { + async _pauseAndLock(f) { return this._runWithLock(async () => { const wasPaused = await this.pause(); try { @@ -312,10 +285,7 @@ export class Session { }); } - static async _startOcamlDebug( - startInfo: OCamlDebugStartInfo, - onProgramExit: (error: ?string) => Promise, - ): Promise { + static async _startOcamlDebug(startInfo, onProgramExit) { const debuggerArguments = []; for (const includeDir of startInfo.includeDirectories) { debuggerArguments.push('-I', includeDir); @@ -333,52 +303,35 @@ export class Session { debuggerArguments.push(executablePath); } - const command = - startInfo.ocamldebugExecutable !== '' - ? startInfo.ocamldebugExecutable - : 'ocamldebug'; + const command = startInfo.ocamldebugExecutable !== '' ? startInfo.ocamldebugExecutable : 'ocamldebug'; debuggerArguments.push(...startInfo.arguments); - const ocamlDebug = new OCamlDebugProxy( - command, - debuggerArguments, - result => { - onProgramExit(result.kind === 'finished' ? null : result.message); - }, - ); + const ocamlDebug = new (_OCamlDebugProxy || _load_OCamlDebugProxy()).OCamlDebugProxy(command, debuggerArguments, result => { + onProgramExit(result.kind === 'finished' ? null : result.message); + }); await ocamlDebug.waitForPrompt(); await ocamlDebug.send('goto 0'); return ocamlDebug; } - static async start( - startInfo: OCamlDebugStartInfo, - onBreakpointHit: (breakpointId: string) => Promise, - onProgramExit: (error: ?string) => Promise, - ): Promise { + static async start(startInfo, onBreakpointHit, onProgramExit) { const ocamlDebug = await Session._startOcamlDebug(startInfo, onProgramExit); const modulesText = await ocamlDebug.send('info modules'); - logger.verbose(`MODULES ${modulesText}`); - return new Session( - ocamlDebug, - Session._extractModules(modulesText), - onBreakpointHit, - onProgramExit, - ); + (_vscodeDebugadapter || _load_vscodeDebugadapter()).logger.verbose(`MODULES ${modulesText}`); + return new Session(ocamlDebug, Session._extractModules(modulesText), onBreakpointHit, onProgramExit); } - _send(command: string): Promise { + _send(command) { return this._debugProxy.send(command); } - static _extractModules(modulesText: string): Set { - return extractList(modulesText, 'Used modules:', false, new Set(), l => - l.reduce((acc, v) => { - acc.add(v); - return acc; - }, new Set()), - ); + static _extractModules(modulesText) { + return extractList(modulesText, 'Used modules:', false, new Set(), l => l.reduce((acc, v) => { + acc.add(v); + return acc; + }, new Set())); } } +exports.Session = Session; \ No newline at end of file diff --git a/modules/atom-ide-debugger-ocaml/lib/main.js b/modules/atom-ide-debugger-ocaml/lib/main.js index f1673663be..3172908882 100644 --- a/modules/atom-ide-debugger-ocaml/lib/main.js +++ b/modules/atom-ide-debugger-ocaml/lib/main.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 - */ +'use strict'; -import type { - AutoGenConfig, - AutoGenLaunchConfig, - NuclideDebuggerProvider, -} from 'nuclide-debugger-common/types'; +var _createPackage; -import createPackage from 'nuclide-commons-atom/createPackage'; -import {VsAdapterTypes} from 'nuclide-debugger-common/constants'; -import {AutoGenLaunchAttachProvider} from 'nuclide-debugger-common/AutoGenLaunchAttachProvider'; -import {Logger} from 'vscode-debugadapter'; +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../nuclide-commons-atom/createPackage')); +} + +var _constants; + +function _load_constants() { + return _constants = require('../../nuclide-debugger-common/constants'); +} + +var _AutoGenLaunchAttachProvider; + +function _load_AutoGenLaunchAttachProvider() { + return _AutoGenLaunchAttachProvider = require('../../nuclide-debugger-common/AutoGenLaunchAttachProvider'); +} + +var _vscodeDebugadapter; + +function _load_vscodeDebugadapter() { + return _vscodeDebugadapter = require('vscode-debugadapter'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class Activation { constructor() {} dispose() {} - createDebuggerProvider(): NuclideDebuggerProvider { + createDebuggerProvider() { return { - type: VsAdapterTypes.OCAML, + type: (_constants || _load_constants()).VsAdapterTypes.OCAML, getLaunchAttachProvider: connection => { - return new AutoGenLaunchAttachProvider( - 'OCaml', - connection, - getOCamlAutoGenConfig(), - ); - }, + return new (_AutoGenLaunchAttachProvider || _load_AutoGenLaunchAttachProvider()).AutoGenLaunchAttachProvider('OCaml', connection, getOCamlAutoGenConfig()); + } }; } -} +} /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 getOCamlAutoGenConfig(): AutoGenConfig { +function getOCamlAutoGenConfig() { const debugExecutable = { name: 'ocamldebugExecutable', type: 'string', description: 'Path to ocamldebug or launch script', required: true, - visible: true, + visible: true }; const executablePath = { name: 'executablePath', type: 'string', - description: - 'Input the executable path you want to launch (leave blank if using an ocamldebug launch script)', + description: 'Input the executable path you want to launch (leave blank if using an ocamldebug launch script)', required: false, - visible: true, + visible: true }; const argumentsProperty = { name: 'arguments', @@ -62,7 +72,7 @@ function getOCamlAutoGenConfig(): AutoGenConfig { description: 'Arguments to the executable', required: false, defaultValue: [], - visible: true, + visible: true }; const environmentVariables = { name: 'environmentVariables', @@ -71,24 +81,23 @@ function getOCamlAutoGenConfig(): AutoGenConfig { description: 'Environment variables (e.g. SHELL=/bin/bash PATH=/bin)', required: false, defaultValue: [], - visible: true, + visible: true }; const workingDirectory = { name: 'workingDirectory', type: 'string', description: 'Working directory for the launched executable', required: true, - visible: true, + visible: true }; const additionalIncludeDirectories = { name: 'includeDirectories', type: 'array', itemType: 'string', - description: - 'Additional include directories that debugger will use to search for source code', + description: 'Additional include directories that debugger will use to search for source code', required: false, defaultValue: [], - visible: true, + visible: true }; const breakAfterStart = { name: 'breakAfterStart', @@ -96,39 +105,30 @@ function getOCamlAutoGenConfig(): AutoGenConfig { description: '', required: false, defaultValue: true, - visible: true, + visible: true }; const logLevel = { name: 'logLevel', type: 'string', description: '', required: false, - defaultValue: Logger.LogLevel.Verbose, - visible: false, + defaultValue: (_vscodeDebugadapter || _load_vscodeDebugadapter()).Logger.LogLevel.Verbose, + visible: false }; - const autoGenLaunchConfig: AutoGenLaunchConfig = { + const autoGenLaunchConfig = { launch: true, - vsAdapterType: VsAdapterTypes.OCAML, + vsAdapterType: (_constants || _load_constants()).VsAdapterTypes.OCAML, threads: false, - properties: [ - debugExecutable, - executablePath, - argumentsProperty, - environmentVariables, - workingDirectory, - additionalIncludeDirectories, - breakAfterStart, - logLevel, - ], + properties: [debugExecutable, executablePath, argumentsProperty, environmentVariables, workingDirectory, additionalIncludeDirectories, breakAfterStart, logLevel], scriptPropertyName: 'executable', cwdPropertyName: 'working directory', - header: null, + header: null }; return { launch: autoGenLaunchConfig, - attach: null, + attach: 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-debugger-ocaml/spec/fixtures/README.md b/modules/atom-ide-debugger-ocaml/spec/fixtures/README.md deleted file mode 100644 index 82afe3324b..0000000000 --- a/modules/atom-ide-debugger-ocaml/spec/fixtures/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# How to compile the test project -`ocamlc -g -o .byte .ml` - -Note that the `.cmi` and `.cmo` files are not necessary for the test to run and -do not need to be checked in. - -# How to debug the test project manually -`./ocamldebug .byte` diff --git a/modules/atom-ide-debugger-ocaml/spec/fixtures/infinite_loop.ml b/modules/atom-ide-debugger-ocaml/spec/fixtures/infinite_loop.ml deleted file mode 100644 index a9beb741a6..0000000000 --- a/modules/atom-ide-debugger-ocaml/spec/fixtures/infinite_loop.ml +++ /dev/null @@ -1,7 +0,0 @@ -let loop_forever () = -let rec loop_forever_helper num = - loop_forever_helper (num + 1) in -loop_forever_helper 0 - -let () = - loop_forever () diff --git a/modules/atom-ide-debugger-ocaml/spec/fixtures/simple.ml b/modules/atom-ide-debugger-ocaml/spec/fixtures/simple.ml deleted file mode 100644 index c656d3246d..0000000000 --- a/modules/atom-ide-debugger-ocaml/spec/fixtures/simple.ml +++ /dev/null @@ -1,32 +0,0 @@ -(** Add a lot of fields to make sure that the watch window/identifier hovering - don't truncate fields. *) -type t = { - name : string; - id : int; - field1: string; - field2: string; - field3: string; - field4: string; - field5: string; -} - -let print_t (my_t: t) = - Printf.printf "{name=\"%s\"; id=%d}\n" my_t.name my_t.id - -let main () = - let my_thing = { - name = "My t"; - id = 1349; - field1 = "Field 1"; - field2 = "Field 2"; - field3 = "Field 3"; - field4 = "Field 4"; - field5 = "Field 5" - } in ( - print_t my_thing; - print_t { my_thing with name = "My different t" }; - print_t { my_thing with name = "My very different t" }; - print_t { my_thing with name = "My extremely different t" }) - -let () = - main () diff --git a/modules/atom-ide-debugger-ocaml/spec/vscode-ocaml-spec.js b/modules/atom-ide-debugger-ocaml/spec/vscode-ocaml-spec.js deleted file mode 100644 index 66230374cb..0000000000 --- a/modules/atom-ide-debugger-ocaml/spec/vscode-ocaml-spec.js +++ /dev/null @@ -1,255 +0,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. - * - * @flow - * @format - */ - -import * as DebugProtocol from 'vscode-debugprotocol'; -import * as fs from 'fs'; -import {getLogger} from 'log4js'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {runCommand} from 'nuclide-commons/process'; -import VsDebugSession from 'nuclide-debugger-common/VsDebugSession'; -import {Logger} from 'vscode-debugadapter'; -import {THREAD_ID} from '../lib/OCamlDebugger'; - -const logger = getLogger('ocaml-debugger-spec'); -const adapterInfo = { - command: 'node', - args: [nuclideUri.join(__dirname, '../lib/vscode-debugger-entry.js')], -}; -const OCAML_FIXTURES = nuclideUri.join(__dirname, 'fixtures'); - -function makeSource(name: string): DebugProtocol.Source { - return { - name, - path: nuclideUri.join(OCAML_FIXTURES, name), - }; -} - -async function checkResponse( - responsePromise: Promise, - additionalValidation?: T => void, -): Promise { - const response = await responsePromise; - expect(response.success).toBeTruthy( - `Expected successful response, got ${JSON.stringify(response)}`, - ); - - if (additionalValidation != null) { - additionalValidation(response); - } - - return response; -} - -async function withSession( - executableName: string, - breakpoints?: DebugProtocol.SetBreakpointsArguments, - sessionContinuation: VsDebugSession => Promise, -): Promise { - const session = new VsDebugSession( - process.pid.toString(), - logger, - adapterInfo, - ); - try { - await checkResponse( - session.initialize({adapterID: 'id', pathFormat: 'path'}), - ); - await checkResponse( - session.launch({ - ocamldebugExecutable: 'ocamldebug', - executablePath: nuclideUri.join(__dirname, 'fixtures', executableName), - arguments: [], - environmentVariables: [], - workingDirectory: OCAML_FIXTURES, - includeDirectories: [], - breakAfterStart: false, - logLevel: Logger.Verbose, - }), - ); - - if (breakpoints != null) { - await checkResponse(session.setBreakpoints(breakpoints), response => { - const unverifiedBreakpoints = response.body.breakpoints.filter( - bp => !bp.verified, - ); - expect(unverifiedBreakpoints.length).toBe( - 0, - `The following breakpoints could not be set: ${JSON.stringify( - unverifiedBreakpoints, - )}`, - ); - }); - } - - await checkResponse(session.configurationDone()); - - await sessionContinuation(session); - } finally { - session.dispose(); - } -} - -async function waitForEvent( - eventStream: rxjs$Observable, -): Promise { - await eventStream.take(1).toPromise(); -} - -const waitForBreak = (debugSession: VsDebugSession) => - waitForEvent(debugSession.observeStopEvents()); - -async function checkLine( - debugSession: VsDebugSession, - expectedLine: number, -): Promise { - await checkResponse( - debugSession.stackTrace({threadId: THREAD_ID}), - response => { - expect(response.body.stackFrames[0].line).toBe(expectedLine); - }, - ); -} - -describe('ocaml-debugger', () => { - if (process.env.SANDCASTLE == null) { - return; - } - - let hasDoneSetup = false; - beforeEach(() => { - waitsForPromise(async () => { - if (hasDoneSetup) { - return; - } - - jasmine.getEnv().defaultTimeoutInterval = 10000; - - const mlFiles = await new Promise((resolve, reject) => { - fs.readdir(OCAML_FIXTURES, (err, files) => { - if (err) { - reject(err); - } - - resolve(files.filter(file => file.endsWith('.ml'))); - }); - }); - - await Promise.all( - mlFiles.map(file => - runCommand( - 'ocamlc', - ['-g', '-o', file.replace(/(\S+)\.ml$/, '$1.byte'), file], - {cwd: OCAML_FIXTURES}, - ).toPromise(), - ), - ); - - hasDoneSetup = true; - }); - }); - - it('can print values', () => { - waitsForPromise(() => - withSession( - 'simple.byte', - { - source: makeSource('simple.ml'), - breakpoints: [{line: 14}], - }, - async debugSession => { - await waitForBreak(debugSession); - await checkResponse( - debugSession.evaluate({expression: 'my_t'}), - response => { - expect(response.body.result).toBe(`t = - {name = "My t"; id = 1349; field1 = "Field 1"; field2 = "Field 2"; - field3 = "Field 3"; field4 = "Field 4"; field5 = "Field 5"}`); - }, - ); - }, - ), - ); - }); - - it('can set multiple breakpoints', () => { - waitsForPromise(() => - withSession( - 'simple.byte', - { - source: makeSource('simple.ml'), - breakpoints: [{line: 14}, {line: 26}], - }, - async debugSession => { - const waitCheckAndContinue = async (expectedLine: number) => { - await waitForBreak(debugSession); - await checkLine(debugSession, expectedLine); - await checkResponse(debugSession.continue({threadId: THREAD_ID})); - }; - - // ocamldebug will hit breakpoint 14 as soon as it enters the - // function, but won't hit 26 as a pre-execution breakpoint, only a - // post-execution breakpoint. It's not the most predictable debugger - // for people used to other ones. - await waitCheckAndContinue(14); - await waitCheckAndContinue(26); - }, - ), - ); - }); - - it('supports step-over, step-in, and step-out', () => { - waitsForPromise(() => - withSession( - 'simple.byte', - { - source: makeSource('simple.ml'), - breakpoints: [{line: 26}], - }, - async debugSession => { - await waitForBreak(debugSession); - await checkLine(debugSession, 26); - - await checkResponse(debugSession.next({threadId: THREAD_ID})); - await checkLine(debugSession, 27); - - await checkResponse(debugSession.stepIn({threadId: THREAD_ID})); - await checkLine(debugSession, 14); - - await checkResponse(debugSession.stepOut({threadId: THREAD_ID})); - await checkLine(debugSession, 28); - - // OCaml *always* performs tail call optimization, so even if we - // wanted to we couldn't hit line 29, since it's the lst line in - // `main ()` so the function it calls is just directly inlined. - }, - ), - ); - }); - - it('can set breakpoints even whilst in an infinite loop', () => { - // This is important since ocamldebug is single threaded, so it can't - // respond to user input while it's currently executing the program. - waitsForPromise(() => - withSession('infinite_loop.byte', undefined, async debugSession => { - await checkResponse( - debugSession.setBreakpoints({ - source: makeSource('infinite_loop.byte'), - breakpoints: [{line: 3}], - }), - ); - - await waitForBreak(debugSession); - await debugSession.disconnect(); - }), - ); - }); -}); diff --git a/modules/atom-ide-debugger-python/RemoteDebuggerCommandService.js b/modules/atom-ide-debugger-python/RemoteDebuggerCommandService.js index fcb1460b16..a05cf4b18f 100644 --- a/modules/atom-ide-debugger-python/RemoteDebuggerCommandService.js +++ b/modules/atom-ide-debugger-python/RemoteDebuggerCommandService.js @@ -1,3 +1,31 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.observeRemoteDebugCommands = observeRemoteDebugCommands; +exports.observeAttachDebugTargets = observeAttachDebugTargets; + +var _http = _interopRequireDefault(require('http')); + +var _net = _interopRequireDefault(require('net')); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _promise; + +function _load_promise() { + return _promise = require('../nuclide-commons/promise'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,83 +34,47 @@ * LICENSE file in 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 http from 'http'; -import net from 'net'; -import {Observable, Subject} from 'rxjs'; -import {getLogger} from 'log4js'; -import {sleep} from 'nuclide-commons/promise'; - let isServerSetup = false; -export type RemoteDebugCommandRequest = { - type: 'python', - command: 'attach', - target: PythonDebuggerAttachTarget, -}; - -export type PythonDebuggerAttachTarget = { - port: number, - localRoot: ?string, - remoteRoot: ?string, - debugOptions: ?Array, - id: ?string, -}; - -const debugRequests: Subject = new Subject(); -const attachReady: Map = new Map(); +const debugRequests = new _rxjsBundlesRxMinJs.Subject(); +const attachReady = new Map(); const DEBUGGER_REGISTRY_PORT = 9615; -export function observeRemoteDebugCommands(): ConnectableObservable< - RemoteDebugCommandRequest, -> { +function observeRemoteDebugCommands() { let setupStep; if (!isServerSetup) { - setupStep = Observable.fromPromise(setupServer()).ignoreElements(); + setupStep = _rxjsBundlesRxMinJs.Observable.fromPromise(setupServer()).ignoreElements(); } else { - setupStep = Observable.empty(); + setupStep = _rxjsBundlesRxMinJs.Observable.empty(); } return setupStep.concat(debugRequests).publish(); } -export function observeAttachDebugTargets(): ConnectableObservable< - Array, -> { +function observeAttachDebugTargets() { // Validate attach-ready values with the processes with used ports (ready to attach). // Note: we can't use process ids because we could be debugging processes inside containers // where the process ids don't map to the host running this code. - return Observable.interval(3000) - .startWith(0) - .switchMap(() => - Promise.all( - Array.from(attachReady.values()).map(async target => { - if (!(await isPortUsed(target.port))) { - attachReady.delete(target.port); - } - }), - ), - ) - .map(() => Array.from(attachReady.values())) - .publish(); + return _rxjsBundlesRxMinJs.Observable.interval(3000).startWith(0).switchMap(() => Promise.all(Array.from(attachReady.values()).map(async target => { + if (!(await isPortUsed(target.port))) { + attachReady.delete(target.port); + } + }))).map(() => Array.from(attachReady.values())).publish(); } -function isPortUsed(port: number): Promise { +function isPortUsed(port) { const tryConnectPromise = new Promise((resolve, reject) => { - const client = new net.Socket(); - client - .once('connect', () => { - cleanUp(); - resolve(true); - }) - .once('error', err => { - cleanUp(); - resolve(err.code !== 'ECONNREFUSED'); - }); + const client = new _net.default.Socket(); + client.once('connect', () => { + cleanUp(); + resolve(true); + }).once('error', err => { + cleanUp(); + resolve(err.code !== 'ECONNREFUSED'); + }); function cleanUp() { client.removeAllListeners('connect'); @@ -92,72 +84,69 @@ function isPortUsed(port: number): Promise { client.unref(); } - client.connect({port, host: '127.0.0.1'}); + client.connect({ port, host: '127.0.0.1' }); }); // Trying to connect can take multiple seconds, then times out (if the server is busy). // Hence, we need to fallback to `true`. - const connectTimeoutPromise = sleep(1000).then(() => true); + const connectTimeoutPromise = (0, (_promise || _load_promise()).sleep)(1000).then(() => true); return Promise.race([tryConnectPromise, connectTimeoutPromise]); } -function setupServer(): Promise { +function setupServer() { return new Promise((resolve, reject) => { - http - .createServer((req, res) => { - if (req.method !== 'POST') { - res.writeHead(500, {'Content-Type': 'text/html'}); - res.end('Invalid request'); - } else { - let body = ''; - req.on('data', data => { - body += data; - }); - req.on('end', () => { - handleJsonRequest(JSON.parse(body), res); - }); - } - }) - .on('error', reject) - .listen((DEBUGGER_REGISTRY_PORT: any), () => { - isServerSetup = true; - resolve(); - }); + _http.default.createServer((req, res) => { + if (req.method !== 'POST') { + res.writeHead(500, { 'Content-Type': 'text/html' }); + res.end('Invalid request'); + } else { + let body = ''; + req.on('data', data => { + body += data; + }); + req.on('end', () => { + handleJsonRequest(JSON.parse(body), res); + }); + } + }).on('error', reject).listen(DEBUGGER_REGISTRY_PORT, () => { + isServerSetup = true; + resolve(); + }); }); } function handleJsonRequest(body, res) { - res.writeHead(200, {'Content-Type': 'application/json'}); - const {domain, command, type} = body; + res.writeHead(200, { 'Content-Type': 'application/json' }); + const { domain, command, type } = body; let success = false; if (domain !== 'debug' || type !== 'python') { - res.end(JSON.stringify({success})); + res.end(JSON.stringify({ success })); return; } if (command === 'enable-attach') { const port = Number(body.port); - const {options} = body; + const { options } = body; const target = { port, id: options.id, localRoot: options.localRoot, remoteRoot: options.remoteRoot, - debugOptions: options.debugOptions, + debugOptions: options.debugOptions }; attachReady.set(port, target); - getLogger().info('Remote debug target is ready to attach', target); + (0, (_log4js || _load_log4js()).getLogger)().info('Remote debug target is ready to attach', target); success = true; } else if (command === 'attach') { const port = Number(body.port); - getLogger().info('Remote debug target attach request', body); + (0, (_log4js || _load_log4js()).getLogger)().info('Remote debug target attach request', body); const target = attachReady.get(port); if (target != null) { debugRequests.next({ type, command, - target, + target }); success = true; } } - res.end(JSON.stringify({success})); -} + res.end(JSON.stringify({ success })); +} \ No newline at end of file diff --git a/modules/atom-ide-debugger-python/RemoteDebuggerCommandServiceProxy.js b/modules/atom-ide-debugger-python/RemoteDebuggerCommandServiceProxy.js new file mode 100644 index 0000000000..6b74036a9a --- /dev/null +++ b/modules/atom-ide-debugger-python/RemoteDebuggerCommandServiceProxy.js @@ -0,0 +1,234 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + + remoteModule.observeRemoteDebugCommands = function () { + return _client.callRemoteFunction("RemoteDebuggerCommandService/observeRemoteDebugCommands", "observable", _client.marshalArguments(Array.from(arguments), [])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "RemoteDebugCommandRequest" + }); + }).publish(); + }; + + remoteModule.observeAttachDebugTargets = function () { + return _client.callRemoteFunction("RemoteDebuggerCommandService/observeAttachDebugTargets", "observable", _client.marshalArguments(Array.from(arguments), [])).map(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "PythonDebuggerAttachTarget" + } + }); + }).publish(); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + PythonDebuggerAttachTarget: { + kind: "alias", + location: { + type: "source", + fileName: "RemoteDebuggerCommandService.js", + line: 29 + }, + name: "PythonDebuggerAttachTarget", + definition: { + kind: "object", + fields: [{ + name: "port", + type: { + kind: "number" + }, + optional: false + }, { + name: "localRoot", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "remoteRoot", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "debugOptions", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, + optional: false + }, { + name: "id", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }] + } + }, + RemoteDebugCommandRequest: { + kind: "alias", + location: { + type: "source", + fileName: "RemoteDebuggerCommandService.js", + line: 23 + }, + name: "RemoteDebugCommandRequest", + definition: { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "python" + }, + optional: false + }, { + name: "command", + type: { + kind: "string-literal", + value: "attach" + }, + optional: false + }, { + name: "target", + type: { + kind: "named", + name: "PythonDebuggerAttachTarget" + }, + optional: false + }] + } + }, + observeRemoteDebugCommands: { + kind: "function", + name: "observeRemoteDebugCommands", + location: { + type: "source", + fileName: "RemoteDebuggerCommandService.js", + line: 41 + }, + type: { + location: { + type: "source", + fileName: "RemoteDebuggerCommandService.js", + line: 41 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "RemoteDebugCommandRequest" + } + } + } + }, + observeAttachDebugTargets: { + kind: "function", + name: "observeAttachDebugTargets", + location: { + type: "source", + fileName: "RemoteDebuggerCommandService.js", + line: 53 + }, + type: { + location: { + type: "source", + fileName: "RemoteDebuggerCommandService.js", + line: 53 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "observable", + type: { + kind: "array", + type: { + kind: "named", + name: "PythonDebuggerAttachTarget" + } + } + } + } + } + } +}); \ No newline at end of file diff --git a/modules/atom-ide-debugger-python/main.js b/modules/atom-ide-debugger-python/main.js index f3f9897618..49d80bb127 100644 --- a/modules/atom-ide-debugger-python/main.js +++ b/modules/atom-ide-debugger-python/main.js @@ -1,83 +1,104 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict-local - * @format - */ - -import type { - AutoGenConfig, - NuclideDebuggerProvider, -} from 'nuclide-debugger-common/types'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import * as React from 'react'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import {VsAdapterTypes} from 'nuclide-debugger-common/constants'; -import {AutoGenLaunchAttachProvider} from 'nuclide-debugger-common/AutoGenLaunchAttachProvider'; -import {listenToRemoteDebugCommands, setRpcService} from './utils'; - -export const NUCLIDE_PYTHON_DEBUGGER_DEX_URI = - 'https://our.intern.facebook.com/intern/dex/python-and-fbcode/debugging/#nuclide'; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.NUCLIDE_PYTHON_DEBUGGER_DEX_URI = undefined; +exports.getPythonAutoGenConfig = getPythonAutoGenConfig; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../nuclide-commons/UniversalDisposable')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../nuclide-commons-atom/createPackage')); +} + +var _constants; + +function _load_constants() { + return _constants = require('../nuclide-debugger-common/constants'); +} + +var _AutoGenLaunchAttachProvider; + +function _load_AutoGenLaunchAttachProvider() { + return _AutoGenLaunchAttachProvider = require('../nuclide-debugger-common/AutoGenLaunchAttachProvider'); +} + +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 }; } + +const NUCLIDE_PYTHON_DEBUGGER_DEX_URI = exports.NUCLIDE_PYTHON_DEBUGGER_DEX_URI = 'https://our.intern.facebook.com/intern/dex/python-and-fbcode/debugging/#nuclide'; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ class Activation { - _subscriptions: UniversalDisposable; constructor() { - this._subscriptions = new UniversalDisposable( - listenToRemoteDebugCommands(), - ); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default((0, (_utils || _load_utils()).listenToRemoteDebugCommands)()); } dispose() { this._subscriptions.dispose(); } - consumeRpcService(rpcService: nuclide$RpcService): IDisposable { - return setRpcService(rpcService); + consumeRpcService(rpcService) { + return (0, (_utils || _load_utils()).setRpcService)(rpcService); } - createDebuggerProvider(): NuclideDebuggerProvider { + createDebuggerProvider() { return { - type: VsAdapterTypes.PYTHON, + type: (_constants || _load_constants()).VsAdapterTypes.PYTHON, getLaunchAttachProvider: connection => { - return new AutoGenLaunchAttachProvider( - 'Python', - connection, - getPythonAutoGenConfig(), - ); - }, + return new (_AutoGenLaunchAttachProvider || _load_AutoGenLaunchAttachProvider()).AutoGenLaunchAttachProvider('Python', connection, getPythonAutoGenConfig()); + } }; } } -export function getPythonAutoGenConfig(): AutoGenConfig { +function getPythonAutoGenConfig() { const program = { name: 'program', type: 'string', description: 'Absolute path to the program.', required: true, - visible: true, + visible: true }; const pythonPath = { name: 'pythonPath', type: 'string', description: 'Path to python executable.', required: true, - visible: true, + visible: true }; const cwd = { name: 'cwd', type: 'string', - description: - '(Optional) Absolute path to the working directory of the program being debugged. Default is the root directory of the file.', + description: '(Optional) Absolute path to the working directory of the program being debugged. Default is the root directory of the file.', required: true, - visible: true, + visible: true }; const args = { name: 'args', @@ -86,7 +107,7 @@ export function getPythonAutoGenConfig(): AutoGenConfig { description: 'Command line arguments passed to the program', defaultValue: [], required: false, - visible: true, + visible: true }; const stopOnEntry = { name: 'stopOnEntry', @@ -94,7 +115,7 @@ export function getPythonAutoGenConfig(): AutoGenConfig { description: 'Automatically stop after launch.', defaultValue: false, required: false, - visible: true, + visible: true }; const debugOptions = { name: 'debugOptions', @@ -103,52 +124,47 @@ export function getPythonAutoGenConfig(): AutoGenConfig { description: 'Advanced options, view read me for further details.', defaultValue: ['WaitOnAbnormalExit', 'WaitOnNormalExit', 'RedirectOutput'], required: false, - visible: false, + visible: false }; const env = { name: 'env', type: 'object', - description: - '(Optional) Environment variables (e.g. SHELL=/bin/bash PATH=/bin)', + description: '(Optional) Environment variables (e.g. SHELL=/bin/bash PATH=/bin)', defaultValue: {}, required: false, - visible: true, + visible: true }; return { launch: { launch: true, - vsAdapterType: VsAdapterTypes.PYTHON, + vsAdapterType: (_constants || _load_constants()).VsAdapterTypes.PYTHON, threads: true, - properties: [ - program, - pythonPath, - cwd, - args, - stopOnEntry, - debugOptions, - env, - ], + properties: [program, pythonPath, cwd, args, stopOnEntry, debugOptions, env], scriptPropertyName: 'program', scriptExtension: '.py', cwdPropertyName: 'cwd', - header: isNuclideEnvironment() ? ( -
- ) : null, + header: isNuclideEnvironment() ? _react.createElement( + 'p', + null, + 'This is intended to debug python script files.', + _react.createElement('br', null), + 'To debug buck targets, you should', + ' ', + _react.createElement( + 'a', + { href: NUCLIDE_PYTHON_DEBUGGER_DEX_URI }, + 'use the buck toolbar instead' + ), + '.' + ) : null }, - attach: null, + attach: null }; } -function isNuclideEnvironment(): boolean { +function isNuclideEnvironment() { return atom.packages.isPackageLoaded('nuclide'); } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/modules/atom-ide-debugger-python/utils.js b/modules/atom-ide-debugger-python/utils.js index d88aeac1a8..9bd8ff592d 100644 --- a/modules/atom-ide-debugger-python/utils.js +++ b/modules/atom-ide-debugger-python/utils.js @@ -1,3 +1,78 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.setRpcService = setRpcService; +exports.listenToRemoteDebugCommands = listenToRemoteDebugCommands; +exports.getRemoteDebuggerCommandServiceByNuclideUri = getRemoteDebuggerCommandServiceByNuclideUri; + +var _debugger; + +function _load_debugger() { + return _debugger = require('../nuclide-commons-atom/debugger'); +} + +var _projects; + +function _load_projects() { + return _projects = require('../nuclide-commons-atom/projects'); +} + +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 _nuclideDebuggerCommon; + +function _load_nuclideDebuggerCommon() { + return _nuclideDebuggerCommon = require('../nuclide-debugger-common'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _analytics; + +function _load_analytics() { + return _analytics = require('../nuclide-commons/analytics'); +} + +var _RemoteDebuggerCommandService; + +function _load_RemoteDebuggerCommandService() { + return _RemoteDebuggerCommandService = _interopRequireWildcard(require('./RemoteDebuggerCommandService')); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +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. @@ -6,163 +81,93 @@ * LICENSE file in 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 { - PythonDebuggerAttachTarget, - RemoteDebugCommandRequest, -} from './RemoteDebuggerCommandService'; -import typeof * as RemoteDebuggerCommandService from './RemoteDebuggerCommandService'; - -import {getDebuggerService} from 'nuclide-commons-atom/debugger'; -import {observeAddedHostnames} from 'nuclide-commons-atom/projects'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {fastDebounce} from 'nuclide-commons/observable'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {VspProcessInfo, VsAdapterTypes} from 'nuclide-debugger-common'; -import {Observable} from 'rxjs'; -import {track} from 'nuclide-commons/analytics'; -import * as RemoteDebuggerCommandServiceLocal from './RemoteDebuggerCommandService'; -import nullthrows from 'nullthrows'; -import {getLogger} from 'log4js'; - -let _rpcService: ?nuclide$RpcService = null; - -async function getPythonAttachTargetProcessInfo( - targetRootUri: NuclideUri, - target: PythonDebuggerAttachTarget, -): Promise { - return new VspProcessInfo( - targetRootUri, - 'attach', - VsAdapterTypes.PYTHON, - null, - getPythonAttachTargetConfig(target), - {threads: true}, - ); -} - -function getPythonAttachTargetConfig( - target: PythonDebuggerAttachTarget, -): Object { +let _rpcService = null; + +async function getPythonAttachTargetProcessInfo(targetRootUri, target) { + return new (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VspProcessInfo(targetRootUri, 'attach', (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsAdapterTypes.PYTHON, null, getPythonAttachTargetConfig(target), { threads: true }); +} + +function getPythonAttachTargetConfig(target) { return { localRoot: target.localRoot, remoteRoot: target.remoteRoot, port: target.port, - host: '127.0.0.1', + host: '127.0.0.1' }; } -export function setRpcService(rpcService: nuclide$RpcService): IDisposable { +function setRpcService(rpcService) { _rpcService = rpcService; - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { _rpcService = null; }); } -export function listenToRemoteDebugCommands(): IDisposable { - const addedHostnames = observeAddedHostnames().startWith('local'); +function listenToRemoteDebugCommands() { + const addedHostnames = (0, (_projects || _load_projects()).observeAddedHostnames)().startWith('local'); const remoteDebuggerServices = addedHostnames.flatMap(hostname => { - const rootUri = - hostname === 'local' ? '' : nuclideUri.createRemoteUri(hostname, '/'); + const rootUri = hostname === 'local' ? '' : (_nuclideUri || _load_nuclideUri()).default.createRemoteUri(hostname, '/'); const service = getRemoteDebuggerCommandServiceByNuclideUri(rootUri); if (service == null) { - getLogger().error('null remote command service for uri:', rootUri); - return Observable.empty(); + (0, (_log4js || _load_log4js()).getLogger)().error('null remote command service for uri:', rootUri); + return _rxjsBundlesRxMinJs.Observable.empty(); } else { - return Observable.of({service, rootUri}); + return _rxjsBundlesRxMinJs.Observable.of({ service, rootUri }); } }); - return new UniversalDisposable( - remoteDebuggerServices - .flatMap(({service, rootUri}) => { - return service - .observeAttachDebugTargets() - .refCount() - .map(targets => findDuplicateAttachTargetIds(targets)); - }) - - .subscribe(duplicateTargetIds => - notifyDuplicateDebugTargets(duplicateTargetIds), - ), - remoteDebuggerServices - .flatMap(({service, rootUri}) => { - return service - .observeRemoteDebugCommands() - .refCount() - .catch(error => { - // eslint-disable-next-line no-console - console.warn( - 'Failed to listen to remote debug commands - ' + - 'You could be running locally with two Atom windows. ' + - `IsLocal: ${String(rootUri === '')}`, - ); - return Observable.empty(); - }) - .map((command: RemoteDebugCommandRequest) => ({rootUri, command})); - }) - .let(fastDebounce(500)) - .subscribe(async ({rootUri, command}) => { - const attachProcessInfo = await getPythonAttachTargetProcessInfo( - rootUri, - command.target, - ); - const debuggerService = await getDebuggerService(); - track('fb-python-debugger-auto-attach'); - debuggerService.startDebugging(attachProcessInfo); - // Otherwise, we're already debugging that target. - }), - ); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(remoteDebuggerServices.flatMap(({ service, rootUri }) => { + return service.observeAttachDebugTargets().refCount().map(targets => findDuplicateAttachTargetIds(targets)); + }).subscribe(duplicateTargetIds => notifyDuplicateDebugTargets(duplicateTargetIds)), remoteDebuggerServices.flatMap(({ service, rootUri }) => { + return service.observeRemoteDebugCommands().refCount().catch(error => { + // eslint-disable-next-line no-console + console.warn('Failed to listen to remote debug commands - ' + 'You could be running locally with two Atom windows. ' + `IsLocal: ${String(rootUri === '')}`); + return _rxjsBundlesRxMinJs.Observable.empty(); + }).map(command => ({ rootUri, command })); + }).let((0, (_observable || _load_observable()).fastDebounce)(500)).subscribe(async ({ rootUri, command }) => { + const attachProcessInfo = await getPythonAttachTargetProcessInfo(rootUri, command.target); + const debuggerService = await (0, (_debugger || _load_debugger()).getDebuggerService)(); + (0, (_analytics || _load_analytics()).track)('fb-python-debugger-auto-attach'); + debuggerService.startDebugging(attachProcessInfo); + // Otherwise, we're already debugging that target. + })); } let shouldNotifyDuplicateTargets = true; let duplicateTargetsNotification; -function notifyDuplicateDebugTargets(duplicateTargetIds: Set): void { - if ( - duplicateTargetIds.size > 0 && - shouldNotifyDuplicateTargets && - duplicateTargetsNotification == null - ) { +function notifyDuplicateDebugTargets(duplicateTargetIds) { + if (duplicateTargetIds.size > 0 && shouldNotifyDuplicateTargets && duplicateTargetsNotification == null) { const formattedIds = Array.from(duplicateTargetIds).join(', '); - duplicateTargetsNotification = atom.notifications.addInfo( - `Debugger: duplicate attach targets: \`${formattedIds}\``, - { - buttons: [ - { - onDidClick: () => { - shouldNotifyDuplicateTargets = false; - if (duplicateTargetsNotification != null) { - duplicateTargetsNotification.dismiss(); - } - }, - text: 'Ignore', - }, - ], - description: - `Nuclide debugger detected duplicate attach targets with ids (${formattedIds}) ` + - 'That could be instagram running multiple processes - check out https://our.intern.facebook.com/intern/dex/instagram-server/debugging-with-nuclide/', - dismissable: true, - }, - ); + duplicateTargetsNotification = atom.notifications.addInfo(`Debugger: duplicate attach targets: \`${formattedIds}\``, { + buttons: [{ + onDidClick: () => { + shouldNotifyDuplicateTargets = false; + if (duplicateTargetsNotification != null) { + duplicateTargetsNotification.dismiss(); + } + }, + text: 'Ignore' + }], + description: `Nuclide debugger detected duplicate attach targets with ids (${formattedIds}) ` + 'That could be instagram running multiple processes - check out https://our.intern.facebook.com/intern/dex/instagram-server/debugging-with-nuclide/', + dismissable: true + }); duplicateTargetsNotification.onDidDismiss(() => { duplicateTargetsNotification = null; }); } } -function findDuplicateAttachTargetIds( - targets: Array, -): Set { +function findDuplicateAttachTargetIds(targets) { const targetIds = new Set(); const duplicateTargetIds = new Set(); targets.forEach(target => { - const {id} = target; + const { id } = target; if (id == null) { return; } @@ -175,15 +180,10 @@ function findDuplicateAttachTargetIds( return duplicateTargetIds; } -export function getRemoteDebuggerCommandServiceByNuclideUri( - uri: NuclideUri, -): RemoteDebuggerCommandService { - if (_rpcService == null && !nuclideUri.isRemote(uri)) { - return RemoteDebuggerCommandServiceLocal; +function getRemoteDebuggerCommandServiceByNuclideUri(uri) { + if (_rpcService == null && !(_nuclideUri || _load_nuclideUri()).default.isRemote(uri)) { + return _RemoteDebuggerCommandService || _load_RemoteDebuggerCommandService(); } - return nullthrows(_rpcService).getServiceByNuclideUri( - 'RemoteDebuggerCommandService', - uri, - ); -} + return (0, (_nullthrows || _load_nullthrows()).default)(_rpcService).getServiceByNuclideUri('RemoteDebuggerCommandService', uri); +} \ No newline at end of file diff --git a/modules/atom-ide-debugger-react-native/main.js b/modules/atom-ide-debugger-react-native/main.js index 8f4039b52a..8f5aae59cc 100644 --- a/modules/atom-ide-debugger-react-native/main.js +++ b/modules/atom-ide-debugger-react-native/main.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 type { - AutoGenConfig, - NuclideDebuggerProvider, - DebuggerConfigurationProvider, - AutoGenProperty, - IProcessConfig, -} from 'nuclide-debugger-common/types'; -import type {GatekeeperService} from 'nuclide-commons-atom/types'; - -import createPackage from 'nuclide-commons-atom/createPackage'; - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {AutoGenLaunchAttachProvider} from 'nuclide-debugger-common/AutoGenLaunchAttachProvider'; -import {VsAdapterTypes} from 'nuclide-debugger-common/constants'; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.resolveConfiguration = resolveConfiguration; + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../nuclide-commons-atom/createPackage')); +} + +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 _AutoGenLaunchAttachProvider; + +function _load_AutoGenLaunchAttachProvider() { + return _AutoGenLaunchAttachProvider = require('../nuclide-debugger-common/AutoGenLaunchAttachProvider'); +} + +var _constants; + +function _load_constants() { + return _constants = require('../nuclide-debugger-common/constants'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class Activation { - _gkService: ?GatekeeperService; constructor() { this._gkService = null; @@ -35,84 +45,80 @@ class Activation { dispose() {} - createDebuggerProvider(): NuclideDebuggerProvider { + createDebuggerProvider() { return { - type: VsAdapterTypes.REACT_NATIVE, + type: (_constants || _load_constants()).VsAdapterTypes.REACT_NATIVE, getLaunchAttachProvider: connection => { - return new AutoGenLaunchAttachProvider( - 'React Native', - connection, - getReactNativeConfig(), - async () => { - // This debugger is enabled for non-Facebook users, and Facebook - // users inside the Gatekeeper nuclide_debugger_reactnative - return this._gkService == null - ? Promise.resolve(true) - : this._gkService.passesGK('nuclide_debugger_reactnative'); - }, - ); - }, + return new (_AutoGenLaunchAttachProvider || _load_AutoGenLaunchAttachProvider()).AutoGenLaunchAttachProvider('React Native', connection, getReactNativeConfig(), async () => { + // This debugger is enabled for non-Facebook users, and Facebook + // users inside the Gatekeeper nuclide_debugger_reactnative + return this._gkService == null ? Promise.resolve(true) : this._gkService.passesGK('nuclide_debugger_reactnative'); + }); + } }; } - consumeGatekeeperService(service: GatekeeperService): IDisposable { + consumeGatekeeperService(service) { this._gkService = service; - return new UniversalDisposable(() => (this._gkService = null)); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => this._gkService = null); } - createDebuggerConfigurator(): DebuggerConfigurationProvider { + createDebuggerConfigurator() { return { resolveConfiguration, - adapterType: VsAdapterTypes.REACT_NATIVE, + adapterType: (_constants || _load_constants()).VsAdapterTypes.REACT_NATIVE }; } +} /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 _deriveProgramFromWorkspace(workspacePath) { + return (_nuclideUri || _load_nuclideUri()).default.getPath((_nuclideUri || _load_nuclideUri()).default.join(workspacePath, '.vscode', 'launchReactNative.js')); } -function _deriveProgramFromWorkspace(workspacePath: string): string { - return nuclideUri.getPath( - nuclideUri.join(workspacePath, '.vscode', 'launchReactNative.js'), - ); +function _deriveOutDirFromWorkspace(workspacePath) { + return (_nuclideUri || _load_nuclideUri()).default.getPath((_nuclideUri || _load_nuclideUri()).default.join(workspacePath, '.vscode', '.react')); } -function _deriveOutDirFromWorkspace(workspacePath: string): string { - return nuclideUri.getPath( - nuclideUri.join(workspacePath, '.vscode', '.react'), - ); -} - -function getReactNativeConfig(): AutoGenConfig { +function getReactNativeConfig() { const workspace = { name: 'workspace', type: 'string', description: 'Absolute path containing package.json', required: true, - visible: true, + visible: true }; const sourceMaps = { name: 'sourceMaps', type: 'boolean', - description: - 'Whether to use JavaScript source maps to map the generated bundled code back to its original sources', + description: 'Whether to use JavaScript source maps to map the generated bundled code back to its original sources', defaultValue: false, required: false, - visible: true, + visible: true }; const outDir = { name: 'outDir', type: 'string', - description: - 'The location of the generated JavaScript code (the bundle file). Normally this should be "${workspaceRoot}/.vscode/.react"', + description: 'The location of the generated JavaScript code (the bundle file). Normally this should be "${workspaceRoot}/.vscode/.react"', required: false, - visible: true, + visible: true }; const sourceMapPathOverrides = { name: 'sourceMapPathOverrides', type: 'json', - description: - 'A set of mappings for rewriting the locations of source files from what the sourcemap says, to their locations on disk. See README for details.', + description: 'A set of mappings for rewriting the locations of source files from what the sourcemap says, to their locations on disk. See README for details.', defaultValue: {}, required: false, - visible: true, + visible: true }; const port = { name: 'port', @@ -120,16 +126,10 @@ function getReactNativeConfig(): AutoGenConfig { description: 'Debug port to attach to. Default is 8081.', defaultValue: 8081, required: false, - visible: true, + visible: true }; - const attachProperties: AutoGenProperty[] = [ - workspace, - sourceMaps, - outDir, - sourceMapPathOverrides, - port, - ]; + const attachProperties = [workspace, sourceMaps, outDir, sourceMapPathOverrides, port]; const platform = { name: 'platform', @@ -138,7 +138,7 @@ function getReactNativeConfig(): AutoGenConfig { description: '', defaultValue: 'ios', required: true, - visible: true, + visible: true }; const target = { name: 'target', @@ -147,7 +147,7 @@ function getReactNativeConfig(): AutoGenConfig { description: '', defaultValue: 'simulator', required: true, - visible: true, + visible: true }; const launchProperties = [platform, target].concat(attachProperties); @@ -155,30 +155,28 @@ function getReactNativeConfig(): AutoGenConfig { return { launch: { launch: true, - vsAdapterType: VsAdapterTypes.REACT_NATIVE, + vsAdapterType: (_constants || _load_constants()).VsAdapterTypes.REACT_NATIVE, threads: false, properties: launchProperties, scriptPropertyName: null, cwdPropertyName: 'workspace', scriptExtension: '.js', - header: null, + header: null }, attach: { launch: false, - vsAdapterType: VsAdapterTypes.REACT_NATIVE, + vsAdapterType: (_constants || _load_constants()).VsAdapterTypes.REACT_NATIVE, threads: false, properties: attachProperties, cwdPropertyName: 'workspace', scriptExtension: '.js', - header: null, - }, + header: null + } }; } -export async function resolveConfiguration( - configuration: IProcessConfig, -): Promise { - const {config} = configuration; +async function resolveConfiguration(configuration) { + const { config } = configuration; if (config.outDir == null) { config.outDir = _deriveOutDirFromWorkspace(config.workspace); } @@ -187,4 +185,4 @@ export async function resolveConfiguration( return configuration; } -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/DEVELOPMENT b/modules/atom-ide-ui/DEVELOPMENT deleted file mode 100644 index e27a0b58b0..0000000000 --- a/modules/atom-ide-ui/DEVELOPMENT +++ /dev/null @@ -1,3 +0,0 @@ -This file exists to indicate that the source should be transpiled. - -During publishing, all files are pre-transpiled and this file is ignored. diff --git a/modules/atom-ide-ui/index.js b/modules/atom-ide-ui/index.js index fe18950654..8c8887acd0 100644 --- a/modules/atom-ide-ui/index.js +++ b/modules/atom-ide-ui/index.js @@ -1,127 +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 strict-local - * @format - */ +'use strict'; -export type { - BusySignalOptions, - BusySignalService, -} from './pkg/atom-ide-busy-signal/lib/types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -export type { - CodeAction, - CodeActionProvider, -} from './pkg/atom-ide-code-actions/lib/types'; +var _RemoteControlService; -export type { - CodeFormatProvider, - RangeCodeFormatProvider, - FileCodeFormatProvider, - OnTypeCodeFormatProvider, - OnSaveCodeFormatProvider, -} from './pkg/atom-ide-code-format/lib/types'; +function _load_RemoteControlService() { + return _RemoteControlService = require('./pkg/atom-ide-debugger/lib/RemoteControlService'); +} -export type { - CodeHighlightProvider, -} from './pkg/atom-ide-code-highlight/lib/types'; +Object.defineProperty(exports, 'DebuggerService', { + enumerable: true, + get: function () { + return _interopRequireDefault(_RemoteControlService || _load_RemoteControlService()).default; + } +}); -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'; +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 cec5474a73..aeca1d6663 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,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 - */ +'use strict'; -import type {BusyMessage} from './types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.BusyMessageInstance = undefined; -import invariant from 'assert'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; +var _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'); +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../../nuclide-commons/UniversalDisposable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class BusyMessageInstance { // These things might be modified afterwards: - _currentTitle: ?string = null; - _isVisibleForDebounce: boolean = true; - _isVisibleForFile: boolean = true; - _revealTooltip: boolean = false; - - constructor( - publishCallback: () => void, - creationOrder: number, - waitingFor: 'computer' | 'user', - onDidClick: ?() => void, - disposables: UniversalDisposable, - ) { + + // These things are set at construction-time: + constructor(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 +31,15 @@ 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 +60,66 @@ 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); - return ( - this._isVisibleForFile && - this._isVisibleForDebounce && - this._currentTitle != null - ); + isVisible() { + if (!!this._disposables.disposed) { + throw new Error('Invariant violation: "!this._disposables.disposed"'); + } + + return this._isVisibleForFile && this._isVisibleForDebounce && 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(); } } -// This is how we declare that a type fulfills an interface in Flow: -(((null: any): BusyMessageInstance): BusyMessage); +exports.BusyMessageInstance = BusyMessageInstance; // This is how we declare that a type fulfills an interface in Flow: +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 8de7bfb64c..f81b40bf3b 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,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,23 +11,19 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type {BusySignalOptions, BusyMessage} from './types'; -import type {MessageStore} from './MessageStore'; - -export default class BusySignalSingleton { - _messageStore: MessageStore; +class BusySignalSingleton { - constructor(messageStore: MessageStore) { + constructor(messageStore) { this._messageStore = messageStore; } dispose() {} - reportBusy(title: string, options?: BusySignalOptions): BusyMessage { + reportBusy(title, options) { return this._messageStore.add(title, options || {}); } @@ -33,11 +34,7 @@ export default class BusySignalSingleton { * Used to indicate that some work is ongoing while the given asynchronous * function executes. */ - async reportBusyWhile( - title: string, - f: () => Promise, - options?: BusySignalOptions, - ): Promise { + async reportBusyWhile(title, f, options) { const busySignal = this.reportBusy(title, options); try { return await f(); @@ -46,3 +43,4 @@ export default class BusySignalSingleton { } } } +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 7a54f563c7..254528dec1 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,36 @@ +'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,100 +39,87 @@ * LICENSE file in 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([]); +class MessageStore { + constructor() { + this._counter = 0; + this._messages = new Set(); + this._currentVisibleMessages = []; + this._messageStream = new _rxjsBundlesRxMinJs.BehaviorSubject([]); + } - getMessageStream(): Observable> { + 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'; + const waitingFor = 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)); + 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. // So both tests above should necessary fail. // If the messageStore was disposed, then every message in it should // already have been disposed, as per above. + + messageDisposables.remove(teardown); message.setIsVisibleForDebounce(true); }, BUSY_DEBOUNCE_DELAY); @@ -110,10 +130,7 @@ export class MessageStore { message.setIsVisibleForFile(false); const file = options.onlyForFile; const teardown = atom.workspace.observeActivePaneItem(item => { - const activePane = - item != null && typeof item.getPath === 'function' - ? String(item.getPath()) - : null; + const activePane = item != null && typeof item.getPath === 'function' ? String(item.getPath()) : null; const newVisible = activePane === file; message.setIsVisibleForFile(newVisible); }); @@ -133,3 +150,4 @@ export class MessageStore { 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 553e662c36..13a6e3bc45 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,43 @@ +'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 +46,47 @@ * LICENSE file in 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 strict-local + * strict-local * @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) { +function StatusBarTileComponent(props) { let element; if (props.waitingForUser) { - element = ; + 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; - - constructor( - statusBar: atom$StatusBar, - messageStream: Observable>, - ) { +class StatusBarTile { + + constructor(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 +94,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 +108,24 @@ 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, + onDidClick: onDidClicks.length > 0 ? () => onDidClicks.forEach(callback => callback()) : null }; - ReactDOM.render(, this._item); + _reactDom.default.render(_react.createElement(StatusBarTileComponent, props), this._item); - const revealTooltip = messages.some(message => - message.shouldRevealTooltip(), - ); + const revealTooltip = messages.some(message => 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. @@ -121,10 +133,7 @@ export default class StatusBarTile { // There are two reasons to refresh the tooltip (bringing it back): // 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) - ) { + if (messages.length > 0 && (revealTooltip || this._isMouseOverItem || this._isMouseOverTooltip)) { this._ensureTooltip(); } else { this._isMouseOverItem = false; @@ -134,7 +143,7 @@ export default class StatusBarTile { } } - _disposeTooltip(): void { + _disposeTooltip() { if (this._tooltip != null) { this._tooltip.dispose(); this._tooltip = null; @@ -142,7 +151,7 @@ export default class StatusBarTile { } } - _ensureTooltip(): void { + _ensureTooltip() { if (this._tooltip != null) { return; } @@ -152,14 +161,18 @@ export default class StatusBarTile { body.appendChild(document.createElement('br')); } const titleElement = message.getTitleElement(); - invariant(titleElement != null); + + 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) { @@ -177,12 +190,8 @@ export default class StatusBarTile { } } - _startLeaveTimeoutIfNecessary(): void { - if ( - !this._isMouseOverItem && - this._isMouseOverTooltip === 0 && - this._leaveTimeoutId == null - ) { + _startLeaveTimeoutIfNecessary() { + if (!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 +200,11 @@ 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 698cadaff6..de545c78b7 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,3 +1,37 @@ +'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. @@ -6,45 +40,32 @@ * LICENSE file in 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 strict-local + * strict-local * @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); + 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 38a0a1cda4..a726efc43f 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 deleted file mode 100644 index ca08601906..0000000000 --- a/modules/atom-ide-ui/pkg/atom-ide-busy-signal/spec/BusySignalInstance-spec.js +++ /dev/null @@ -1,152 +0,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. - * - * @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); - 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); - }); - }); - - it('should record messages before and after a call', () => { - expect(messages.length).toBe(0); - singleton.reportBusyWhile('foo', () => Promise.resolve(5), options); - expect(messages.length).toBe(1); - waitsFor( - () => 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(() => {}); - expect(messages.length).toBe(1); - waitsFor( - () => messages.length === 2, - 'It should publish a second message', - 100, - ); - }); - - it('should properly display duplicate messages', () => { - const dispose1 = singleton.reportBusy('foo', options); - expect(messages.length).toBe(1); - expect(messages[0]).toEqual(['foo']); - - const dispose2 = singleton.reportBusy('foo', options); - expect(messages.length).toBe(2); - expect(messages[1]).toEqual(['foo', 'foo']); - - dispose2.dispose(); - expect(messages.length).toBe(3); - expect(messages[2]).toEqual(['foo']); - - dispose1.dispose(); - expect(messages.length).toBe(4); - expect(messages[3]).toEqual([]); - }); - - describe('when onlyForFile is provided', () => { - let editor1: atom$TextEditor = (null: any); - let editor2: atom$TextEditor = (null: any); - let editor3: atom$TextEditor = (null: any); - 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(); - }); - }); - - afterEach(() => { - [editor1, editor2, editor3].forEach(editor => editor.destroy()); - }); - - it('should only display for the proper text editor', () => { - atom.workspace.getActivePane().activateItem(editor1); - - const disposable = singleton.reportBusy('foo', { - onlyForFile: file2, - ...options, - }); - expect(messages).toEqual([]); - - atom.workspace.getActivePane().activateItem(editor2); - expect(messages.length).toBe(1); - expect(messages[0]).toEqual(['foo']); - - atom.workspace.getActivePane().activateItem(editor3); - expect(messages.length).toBe(2); - expect(messages[1]).toEqual([]); - - atom.workspace.getActivePane().activateItem(editor2); - expect(messages.length).toBe(3); - expect(messages[2]).toEqual(['foo']); - - disposable.dispose(); - expect(messages.length).toBe(4); - expect(messages[3]).toEqual([]); - }); - }); - - it('correctly sets revealTooltip when provided', () => { - waitsForPromise(async () => { - function getCurrentMessages() { - return messageStore - .getMessageStream() - .take(1) - .toPromise(); - } - - singleton.reportBusy('foo', { - debounce: false, - revealTooltip: true, - }); - const curMessages = await getCurrentMessages(); - expect(curMessages.length).toBe(1); - expect(curMessages[0].shouldRevealTooltip()).toBe(true); - }); - }); -}); 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 5ed74eb49d..f509d29635 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,185 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict-local - * @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 { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.CodeActionManager = undefined; + +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. + * + * strict-local + * @format + */ + +async function actionsToMessage(location, actions) { 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]), + apply: actions[i].apply.bind(actions[i]) })); return { location, solutions, excerpt: 'Select an action', severity: 'info', - kind: 'action', + kind: 'action' }; } -export class CodeActionManager { - _providerRegistry: ProviderRegistry; - _disposables: UniversalDisposable; - _linterDelegate: ?IndieLinterDelegate; - _diagnosticUpdater: ?DiagnosticUpdater; +class CodeActionManager { constructor() { - this._providerRegistry = new ProviderRegistry(); - this._disposables = new UniversalDisposable(this._selectionSubscriber()); + 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> { + async _genAllCodeActions(editor, range, diagnostics) { const codeActionRequests = []; - for (const provider of this._providerRegistry.getAllProvidersForEditor( - editor, - )) { - codeActionRequests.push( - provider.getCodeActions(editor, range, diagnostics), - ); + for (const provider of this._providerRegistry.getAllProvidersForEditor(editor)) { + codeActionRequests.push(provider.getCodeActions(editor, range, diagnostics)); } - return arrayFlatten(arrayCompact(await Promise.all(codeActionRequests))); + return (0, (_collection || _load_collection()).arrayFlatten)((0, (_collection || _load_collection()).arrayCompact)((await 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 483761bccf..fea1b09c74 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,3 +1,19 @@ +'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. @@ -6,43 +22,35 @@ * LICENSE file in 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 strict-local + * strict-local * @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(); + 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 50d863cb8c..a726efc43f 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 strict-local - * @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 deleted file mode 100644 index 825aaf85d8..0000000000 --- a/modules/atom-ide-ui/pkg/atom-ide-code-actions/spec/CodeActionManager-spec.js +++ /dev/null @@ -1,81 +0,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. - * - * @flow - * @format - */ - -import os from 'os'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - -import {CodeActionManager} from '../lib/CodeActionManager'; - -describe('CodeActionManager', () => { - let manager; - let provider; - let delegate; - let editor; - beforeEach(() => { - jasmine.useMockClock(); - waitsForPromise(async () => { - editor = await atom.workspace.open( - nuclideUri.join(os.tmpdir(), 'test.txt'), - ); - editor.setText('abc\ndef\nghi'); - - manager = new CodeActionManager(); - provider = { - priority: 1, - grammarScopes: ['text.plain.null-grammar'], - async getCodeActions(_e, _r, _d) { - return []; - }, - }; - delegate = { - clearMessages: () => {}, - setAllMessages: _messages => {}, - }; - manager._linterDelegate = (delegate: any); - manager.addProvider(provider); - }); - }); - - it('finds code actions on highlight change and updates linter', () => { - const actions = [ - { - apply() {}, - async getTitle() { - return 'Mock action'; - }, - dispose() {}, - }, - ]; - const spyActions = spyOn(provider, 'getCodeActions').andReturn(actions); - const spyLinter = spyOn(delegate, 'setAllMessages'); - - runs(() => { - advanceClock(1); // trigger debounce - editor.selectAll(); - advanceClock(501); - }); - - waitsFor( - () => 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); - }); - }); -}); 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 4015ced963..f4142322d8 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,63 +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'; -import type {BusySignalService} from '../../atom-ide-busy-signal/lib/types'; -import type { - FileCodeFormatProvider, - OnSaveCodeFormatProvider, - OnTypeCodeFormatProvider, - RangeCodeFormatProvider, -} from './types'; - -import {getFormatOnSave, getFormatOnType} from './config'; -import {Range} from 'atom'; -import {getLogger} from 'log4js'; -import ProviderRegistry from 'nuclide-commons-atom/ProviderRegistry'; -import {applyTextEditsToBuffer} from 'nuclide-commons-atom/text-edit'; -import {observeEditorDestroy} from 'nuclide-commons-atom/text-editor'; -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 {Observable, Subject} from 'rxjs'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -// Save events are critical, so don't allow providers to block them. -const SAVE_TIMEOUT = 2500; +var _config; -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; +function _load_config() { + return _config = require('./config'); +} + +var _atom = require('atom'); + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _ProviderRegistry; + +function _load_ProviderRegistry() { + return _ProviderRegistry = _interopRequireDefault(require('../../../../nuclide-commons-atom/ProviderRegistry')); +} + +var _textEdit; + +function _load_textEdit() { + return _textEdit = require('../../../../nuclide-commons-atom/text-edit'); +} + +var _textEditor; + +function _load_textEditor() { + return _textEditor = require('../../../../nuclide-commons-atom/text-editor'); +} + +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 _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +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; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 { 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(); } /** @@ -66,69 +93,44 @@ export default class CodeFormatManager { * By handling all events in a central location, we ensure that no buffer * runs into race conditions with simultaneous formatters. */ - _subscribeToEvents(): rxjs$Subscription { + _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(cb => - atom.workspace.observeTextEditors(cb), - ).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() - ); + const editorEvents = (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => atom.workspace.observeTextEditors(cb)).mergeMap(editor => this._getEditorEventStream(editor)); + + return _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), - ); + _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 () => { @@ -141,83 +143,59 @@ 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(); - }, - ); + return this._formatCodeOnTypeInTextEditor(editor, event.edit).catch(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()) - ); + 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()); 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.', - ); + throw new Error('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(() => { + _formatCodeInTextEditor(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(); @@ -229,47 +207,29 @@ 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 => { + if (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(); + const newPosition = newCursor != null ? buffer.positionForCharacterIndex(newCursor) : editor.getCursorBufferPosition(); // We call setCursorBufferPosition even when there is no newCursor, // because it unselects the text selection. @@ -277,24 +237,21 @@ 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(() => { + _formatCodeOnTypeInTextEditor(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 `{`). @@ -302,7 +259,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(); @@ -320,99 +277,74 @@ 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(), - 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.'); - } - }) - .finally(() => { - if (provider.keepCursorPosition) { - editor.setCursorBufferPosition(cursorPosition); - } - }); + return (_observable || _load_observable()).microtask.switchMap(() => provider.formatAtPosition(editor, editor.getCursorBufferPosition(), 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.'); + } + }).finally(() => { + if (provider.keepCursorPosition) { + editor.setCursorBufferPosition(cursorPosition); + } + }); }); } - _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)) { - return this._formatCodeInTextEditor( - editor, - editor.getBuffer().getRange(), - ).ignoreElements(); + } else if ((0, (_config || _load_config()).getFormatOnSave)(editor)) { + return this._formatCodeInTextEditor(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) : ''; - return busySignalService.reportBusyWhile( - `Formatting code in ${displayPath}`, - () => promise, - {revealTooltip}, - ); + const displayPath = path != null ? (_nuclideUri || _load_nuclideUri()).default.basename(path) : ''; + return busySignalService.reportBusyWhile(`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; }); } @@ -422,7 +354,8 @@ export default class CodeFormatManager { } } -function shouldFormatOnType(event: atom$TextEditEvent): boolean { +exports.default = CodeFormatManager; +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: // @@ -456,12 +389,10 @@ function shouldFormatOnType(event: atom$TextEditEvent): boolean { * 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 { +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 b80cc1e37f..1b2ea8579a 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,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 - */ +'use strict'; -import featureConfig from 'nuclide-commons-atom/feature-config'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getFormatOnSave = getFormatOnSave; +exports.getFormatOnType = getFormatOnType; -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; -} +var _featureConfig; -export function getFormatOnType(): boolean { - return featureConfig.getWithDefaults( - 'atom-ide-code-format.formatOnType', - false, - ); +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 8e84d5e992..2adc5d7301 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,3 +1,19 @@ +'use strict'; + +var _createPackage; + +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. @@ -6,41 +22,21 @@ * LICENSE file in 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 strict-local + * strict-local * @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(); + this.codeFormatManager = new (_CodeFormatManager || _load_CodeFormatManager()).default(); } - consumeLegacyProvider(provider: CodeFormatProvider): IDisposable { + consumeLegacyProvider(provider) { // Legacy providers used `selector` / `inclusionPriority`. - provider.grammarScopes = - provider.grammarScopes || - (provider.selector != null ? provider.selector.split(', ') : null); - provider.priority = - provider.priority != null - ? provider.priority - : // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - provider.inclusionPriority != null - ? provider.inclusionPriority - : 0; + provider.grammarScopes = provider.grammarScopes || (provider.selector != null ? provider.selector.split(', ') : null); + provider.priority = provider.priority != null ? provider.priority : // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) + provider.inclusionPriority != null ? provider.inclusionPriority : 0; if (provider.formatCode) { return this.consumeRangeProvider(provider); } else if (provider.formatEntireFile) { @@ -53,23 +49,23 @@ 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); } @@ -78,4 +74,4 @@ class Activation { } } -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 7a8c2a2085..a726efc43f 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,97 +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 strict-local - * @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, - keepCursorPosition: boolean, -|}; - -/** - * 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 deleted file mode 100644 index 2388beba17..0000000000 --- a/modules/atom-ide-ui/pkg/atom-ide-code-format/spec/CodeFormatManager-spec.js +++ /dev/null @@ -1,159 +0,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. - * - * @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); - }); - }); - - it('formats an editor on request', () => { - waitsForPromise(async () => { - const manager = new CodeFormatManager(); - manager.addRangeProvider({ - grammarScopes: ['text.plain.null-grammar'], - priority: 1, - formatCode: () => - Promise.resolve([ - { - oldRange: new Range([0, 0], [0, 3]), - oldText: 'abc', - newText: 'def', - }, - ]), - }); - - textEditor.setText('abc'); - atom.commands.dispatch( - atom.views.getView(textEditor), - 'code-format:format-code', - ); - waitsFor(() => textEditor.getText() === 'def'); - }); - }); - - it('format an editor using formatEntireFile', () => { - waitsForPromise(async () => { - const manager = new CodeFormatManager(); - manager.addFileProvider({ - grammarScopes: ['text.plain.null-grammar'], - priority: 1, - formatEntireFile: () => Promise.resolve({formatted: 'ghi'}), - }); - - textEditor.setText('abc'); - atom.commands.dispatch( - atom.views.getView(textEditor), - 'code-format:format-code', - ); - waitsFor(() => textEditor.getText() === 'ghi'); - }); - }); - - it('formats an editor on type', () => { - waitsForPromise(async () => { - spyOn(config, 'getFormatOnType').andReturn(true); - const manager = new CodeFormatManager(); - const provider = { - grammarScopes: ['text.plain.null-grammar'], - priority: 1, - formatAtPosition: () => - Promise.resolve([ - { - oldRange: new Range([0, 0], [0, 3]), - oldText: 'abc', - newText: 'def', - }, - ]), - keepCursorPosition: false, - }; - const spy = spyOn(provider, 'formatAtPosition').andCallThrough(); - manager.addOnTypeProvider(provider); - - textEditor.setText('a'); - textEditor.setCursorBufferPosition([0, 1]); - textEditor.insertText('b'); - textEditor.insertText('c'); - - waitsFor(() => textEditor.getText() === 'def'); - runs(() => { - // 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(); - manager.addOnSaveProvider({ - grammarScopes: ['text.plain.null-grammar'], - priority: 1, - formatOnSave: () => - Promise.resolve([ - { - oldRange: new Range([0, 0], [0, 3]), - oldText: 'abc', - newText: 'def', - }, - ]), - }); - - textEditor.setText('abc'); - await textEditor.save(); - expect(textEditor.getText()).toBe('def'); - }); - }); - - it('should still save on timeout', () => { - waitsForPromise(async () => { - jasmine.Clock.useMock(); - spyOn(config, 'getFormatOnSave').andReturn(true); - const manager = new CodeFormatManager(); - manager.addRangeProvider({ - grammarScopes: ['text.plain.null-grammar'], - priority: 1, - formatCode: () => new Promise(() => {}), - }); - - 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); - - runs(() => { - jasmine.Clock.tick(3000); - }); - - // Hitting the timeout will force the 2nd save through. - waitsFor(() => spy.callCount === 2); - - // The real save should still go through. - waitsForPromise(() => savePromise); - - // Sanity check. - runs(() => expect(spy.callCount).toBe(2)); - }); - }); -}); 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 cb79ee917e..066f9e1ad9 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,3 +1,49 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +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. @@ -6,97 +52,55 @@ * LICENSE file in 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; +class CodeHighlightManager { constructor() { - this._providers = new ProviderRegistry(); + 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() { + 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(async position => { + return { + editor, + ranges: await this._getHighlightedRanges(editor, position) + }; + }).takeUntil(destroyEvents); + }).subscribe(({ editor, ranges }) => { + if (ranges != null) { + this._highlightRanges(editor, ranges); + } + }); } - async _getHighlightedRanges( - editor: atom$TextEditor, - position: atom$Point, - ): Promise> { + async _getHighlightedRanges(editor, position) { const provider = this._providers.getProviderForEditor(editor); if (!provider) { return null; @@ -105,36 +109,31 @@ export default class CodeHighlightManager { try { return await provider.highlight(editor, position); } catch (e) { - getLogger('code-highlight').error('Error getting code highlights', 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)); + _isPositionInHighlightedRanges(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); } @@ -143,3 +142,4 @@ export default class CodeHighlightManager { 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 2444af619f..f40ddb2153 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,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 strict-local - * @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); } -} +} /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ -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-highlight/lib/types.js b/modules/atom-ide-ui/pkg/atom-ide-code-highlight/lib/types.js index 5a398375a4..9a390c31f7 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 strict - * @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 deleted file mode 100644 index d1466e7f46..0000000000 --- a/modules/atom-ide-ui/pkg/atom-ide-code-highlight/spec/CodeHighlightManager-spec.js +++ /dev/null @@ -1,102 +0,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. - * - * @flow strict-local - * @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'), - ); - editor.setText('abc\ndef\nghi'); - - manager = new CodeHighlightManager(); - provider = { - priority: 1, - grammarScopes: ['text.plain.null-grammar'], - highlight: (_editor, position) => Promise.resolve([]), - }; - manager.addProvider(provider); - }); - }); - - it('updates highlights on cursor move', () => { - const ranges = [new Range([0, 0], [0, 3])]; - const spy = spyOn(provider, 'highlight').andReturn(ranges); - - // Just opening the editor should trigger highlights. - runs(() => { - advanceClock(1); // editor debounce - expect(spy).toHaveBeenCalled(); - }); - - // (once the promise resolves). - waitsFor(() => manager._markers.length === 1); - - runs(() => { - ranges[0] = new Range([1, 0], [1, 3]); - editor.setCursorBufferPosition(new Point(1, 0)); - advanceClock(300); // trigger debounce - // Old markers should be cleared immediately. - expect(manager._markers.length).toBe(0); - expect(spy.callCount).toBe(2); - }); - - waitsFor(() => manager._markers.length === 1); - - // If we're still inside the range, don't fire a new event. - runs(() => { - editor.setCursorBufferPosition(new Point(1, 1)); - expect(spy.callCount).toBe(2); - }); - - waitsForPromise(() => - atom.workspace.open(nuclideUri.join(os.tmpdir(), 'test2.txt')), - ); - - runs(() => { - // Opening a new editor should clear out old markers. - advanceClock(1); - expect(manager._markers.length).toBe(0); - }); - }); - - it('updates highlights on change', () => { - const ranges = [new Range([0, 0], [0, 1])]; - const spy = spyOn(provider, 'highlight').andReturn(ranges); - - runs(() => { - advanceClock(1); - editor.insertText('a'); - advanceClock(3000); // trigger typing debounce - expect(spy).toHaveBeenCalled(); - }); - - // Wait for the promise to resolve. - waitsFor(() => manager._markers.length === 1); - - runs(() => { - editor.insertText('b'); - // Clear out immediately. - expect(manager._markers.length).toBe(0); - }); - }); -}); diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ConsoleServiceClient.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ConsoleServiceClient.js index 370a78f6b8..c7e445b46c 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ConsoleServiceClient.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ConsoleServiceClient.js @@ -1,45 +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 - */ +'use strict'; -import type {Observable} from 'rxjs'; -import type {Level} from './types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -type Send = (event: Object) => void; -type Events = Observable; - -export default function(send: Send, eventsFromService: Events) { +exports.default = function (send, eventsFromService) { return { // TODO: Update these to be `(object: any, ...objects: Array): void` to allow for logging objects. - log(...args: Array): void { + log(...args) { send(createMessageEvent('log', args)); }, - error(...args: Array): void { + error(...args) { send(createMessageEvent('error', args)); }, - warn(...args: Array): void { + warn(...args) { send(createMessageEvent('warning', args)); }, - info(...args: Array): void { + info(...args) { send(createMessageEvent('info', args)); }, - success(...args: Array): void { + success(...args) { send(createMessageEvent('success', args)); - }, + } }; -} +}; -function createMessageEvent(level: Level, args: Array) { +function createMessageEvent(level, args) { return { type: 'message', - data: {level, args}, + data: { level, args } }; -} +} /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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/getCurrentExecutorId.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/getCurrentExecutorId.js index 9efcc7bada..87dfc7b71d 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,24 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict-local - * @format - */ +'use strict'; -import type {AppState} from './types'; - -export default function getCurrentExecutorId(state: AppState): ?string { - let {currentExecutorId} = state; +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. + * + * strict-local + * @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 e98b4ced13..4d857ef8a0 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,131 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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, - 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'; +'use strict'; + +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 _reduxMin; + +function _load_reduxMin() { + return _reduxMin = require('redux/dist/redux.min.js'); +} + +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 { - _disposables: UniversalDisposable; - _rawState: ?Object; - _store: Store; - constructor(rawState: ?Object) { + 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; - // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - 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; + // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) + 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, (_reduxMin || _load_reduxMin()).createStore)((_Reducers || _load_Reducers()).default, initialState, (0, (_reduxMin || _load_reduxMin()).applyMiddleware)((0, (_reduxObservable || _load_reduxObservable()).createEpicMiddleware)(rootEpic))); } return this._store; } @@ -117,42 +134,40 @@ 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, - }), - ); + toolBar.addButton((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: atom$AutocompleteWatchEditor): 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(() => { // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) 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'], @@ -165,33 +180,27 @@ class Activation { 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})); - }, + return Array.from(seen).filter(text => text.startsWith(prefix)).map(text => ({ 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 }); } @@ -206,7 +215,7 @@ class Activation { * 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 { + provideConsole() { // Create a local, nullable reference so that the service consumers don't keep the Activation // instance in memory. let activation = this; @@ -214,65 +223,71 @@ 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); - 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, - }), - ); + append(message) { + if (!(activation != null && !disposed)) { + throw new Error('Invariant violation: "activation != null && !disposed"'); + } + + activation._getStore().dispatch((_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; @@ -281,23 +296,22 @@ 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; @@ -306,71 +320,60 @@ class Activation { }); return executor => { - invariant( - activation != null, - 'Executor registration attempted after deactivation', - ); - activation._getStore().dispatch(Actions.registerExecutor(executor)); - return new UniversalDisposable(() => { + 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(), + records: 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; } @@ -378,4 +381,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 98883affb0..b1d0622afc 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,20 +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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = parseText; + +var _react = _interopRequireWildcard(require('react')); + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../../nuclide-commons-atom/feature-config')); +} -import * as React from 'react'; -import featureConfig from '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 + */ -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'; /** @@ -23,12 +43,10 @@ const TASK_PATTERN = '\\b[tT]\\d+\\b'; * 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_PATTERNS = `(${DIFF_PATTERN})|(${TASK_PATTERN})|(${(_string || _load_string()).URL_REGEX.source})`; const CLICKABLE_RE = new RegExp(CLICKABLE_PATTERNS, 'g'); -function toString(value: mixed): string { +function toString(value) { return typeof value === 'string' ? value : ''; } @@ -38,9 +56,7 @@ function toString(value: mixed): string { * 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> { +function parseText(text) { const chunks = []; let lastIndex = 0; let index = 0; @@ -53,26 +69,20 @@ export default function parseText( const matchedText = match[0]; // Add all the text since our last match. - chunks.push( - text.slice(lastIndex, CLICKABLE_RE.lastIndex - matchedText.length), - ); + 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'), - ); + const url = toString((_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'), - ); + const url = toString((_featureConfig || _load_featureConfig()).default.get('atom-ide-console.taskUrlPattern')); if (url !== '') { href = url.replace('%s', matchedText.slice(1)); } @@ -82,19 +92,16 @@ 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 +110,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 7a2c5ddebc..5daf2150c8 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,3 +1,22 @@ +'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. @@ -6,25 +25,14 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type {DisplayableRecord} from './types'; +function recordsChanged(a, b) { + var _ref, _ref2; -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) - ); + 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]; +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 7d581b6a37..59a8f6df0f 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,3 +1,25 @@ +'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. @@ -6,67 +28,54 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type { - Action, - Executor, - OutputProvider, - OutputProviderStatus, - Record, - RecordProvider, - SourceInfo, -} 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 { +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}, + payload: { record } }; } -export function registerExecutor(executor: Executor): Action { +function registerExecutor(executor) { return { type: REGISTER_EXECUTOR, - payload: {executor}, + payload: { executor } }; } -export function execute(code: string): Action { +function execute(code) { return { type: EXECUTE, - payload: {code}, + payload: { code } }; } -export function registerOutputProvider(outputProvider: OutputProvider): Action { +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, + 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. @@ -80,93 +89,82 @@ export function registerOutputProvider(outputProvider: OutputProvider): Action { sourceId: outputProvider.id, scopeName: null, // Eventually, we'll want to allow providers to specify custom timestamps for records. - timestamp: new Date(), - })), - }); + timestamp: new Date() + })) + })); } -export function registerRecordProvider(recordProvider: RecordProvider): Action { +function registerRecordProvider(recordProvider) { return { type: REGISTER_RECORD_PROVIDER, - payload: {recordProvider}, + payload: { recordProvider } }; } -export function registerSource(source: SourceInfo): Action { +function registerSource(source) { return { type: REGISTER_SOURCE, - payload: {source}, + payload: { source } }; } -export function unregisterRecordProvider( - recordProvider: RecordProvider, -): Action { +function unregisterRecordProvider(recordProvider) { return removeSource(recordProvider.id); } -export function unregisterOutputProvider( - outputProvider: OutputProvider, -): Action { +function unregisterOutputProvider(outputProvider) { return removeSource(outputProvider.id); } -export function selectExecutor(executorId: string): Action { +function selectExecutor(executorId) { return { type: SELECT_EXECUTOR, - payload: {executorId}, + payload: { executorId } }; } -export function setMaxMessageCount(maxMessageCount: number): Action { +function setMaxMessageCount(maxMessageCount) { return { type: SET_MAX_MESSAGE_COUNT, - payload: {maxMessageCount}, + payload: { maxMessageCount } }; } -export function removeSource(sourceId: string): Action { +function removeSource(sourceId) { return { type: REMOVE_SOURCE, - payload: {sourceId}, + payload: { sourceId } }; } -export function unregisterExecutor(executor: Executor): Action { +function unregisterExecutor(executor) { return removeSource(executor.id); } -export function updateStatus( - providerId: string, - status: OutputProviderStatus, -): Action { +function updateStatus(providerId, status) { return { type: UPDATE_STATUS, - payload: {providerId, status}, + payload: { providerId, status } }; } -export function setCreatePasteFunction( - createPasteFunction: ?CreatePasteFunction, -): Action { +function setCreatePasteFunction(createPasteFunction) { return { type: SET_CREATE_PASTE_FUNCTION, - payload: {createPasteFunction}, + payload: { createPasteFunction } }; } -export function setWatchEditor( - watchEditor: ?atom$AutocompleteWatchEditor, -): Action { +function setWatchEditor(watchEditor) { return { type: SET_WATCH_EDITOR_FUNCTION, - payload: {watchEditor}, + payload: { watchEditor } }; } -export function setFontSize(fontSize: number): Action { +function setFontSize(fontSize) { return { type: SET_FONT_SIZE, - payload: {fontSize}, + 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 ec0c9614cf..2226c75b5d 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,47 +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 strict-local - * @format - */ +'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')); +} -import type {Action, Store} from '../types'; -import type {ActionsObservable} from 'nuclide-commons/redux-observable'; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -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'; +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. */ -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({ +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 => ({ - ...message, + 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, - })), + executor + })) }); }); } @@ -49,90 +66,90 @@ export function registerExecutorEpic( /** * 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()); +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @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 - invariant(currentExecutorId); + + if (!currentExecutorId) { + throw new Error('Invariant violation: "currentExecutorId"'); + } const executor = store.getState().executors.get(currentExecutorId); - invariant(executor != null); + + 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); - }) - ); + + + 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); + }); }); } -export function trackEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions - .ofType(Actions.EXECUTE) - .map(action => ({type: 'console:execute'})) - .do(analytics.trackEvent) - .ignoreElements(); +function trackEpic(actions, store) { + return actions.ofType((_Actions || _load_Actions()).EXECUTE).map(action => ({ type: 'console:execute' })).do((_analytics || _load_analytics()).default.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; +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); + const messageActions = recordProvider.records.map((_Actions || _load_Actions()).recordReceived); // TODO: Can this be delayed until sometime after registration? const statusActions = - // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - 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); + // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) + 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 62d3a7277b..54dac5df10 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,3 +1,30 @@ +'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. @@ -6,191 +33,149 @@ * LICENSE file in 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 strict-local + * strict-local * @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') - ) { +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], - ); + 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) - ); + const areTagsEqual = !recATags && !recBTags || recATags && recBTags && (0, (_collection || _load_collection()).arrayEqual)(recATags, recBTags); + + return areRelevantPropertiesEqual && !Boolean(doesDataExist) && Boolean(areTagsEqual); } -export default function accumulateState( - state: AppState, - action: Action, -): AppState { +function accumulateState(state, action) { 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); - } + case (_Actions || _load_Actions()).RECORD_RECEIVED: + { + const { record } = action.payload; + let nextRecords = state.records; - if (nextRecords.size > state.maxMessageCount) { - // We could only have gone over by one. - nextRecords = nextRecords.shift(); - } + // 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 { - ...state, - records: nextRecords, - }; - } - case Actions.SET_MAX_MESSAGE_COUNT: { - const {maxMessageCount} = action.payload; - if (maxMessageCount <= 0) { - return state; + 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)() + }); + } + case (_Actions || _load_Actions()).REGISTER_EXECUTOR: + { + const { executor } = action.payload; + return Object.assign({}, state, { + executors: new Map(state.executors).set(executor.id, executor) + }); + } + 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 || _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, - 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( - 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, - }; - } } 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 517dcda6b2..a726efc43f 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,310 +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 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: ?atom$AutocompleteWatchEditor, - }, - } - | { - 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 badf247230..d9d12056ad 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,3 +1,103 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Console = exports.WORKSPACE_VIEW_URI = undefined; + +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. @@ -6,71 +106,15 @@ * LICENSE file in 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, -}; - -// -// 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 WORKSPACE_VIEW_URI = exports.WORKSPACE_VIEW_URI = 'atom://nuclide/console'; -const ERROR_TRANSCRIBING_MESSAGE = - "// Nuclide couldn't find the right text to display"; +const ERROR_TRANSCRIBING_MESSAGE = "// Nuclide couldn't find the right text to display"; const INITIAL_RECORD_HEIGHT = 21; /** @@ -78,59 +122,93 @@ const INITIAL_RECORD_HEIGHT = 21; * (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; +class Console { - // Associates Records with their display state (height, expansionStateId). - _displayableRecords: WeakMap; + constructor(options) { + 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 = async () => { + 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 + }); + }; - _nextRecordId: number; - _titleChanges: Observable; - _model: Model; - _store: Store; - _element: ?HTMLElement; - _destroyed: ReplaySubject; + 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); + }; - constructor(options: Options) { const { store, initialFilterText, initialEnableRegExpFilter, - initialUnselectedSourceIds, + initialUnselectedSourceIds } = options; - this._model = new Model({ + this._model = new (_Model || _load_Model()).default({ displayableRecords: [], filterText: initialFilterText == null ? '' : initialFilterText, enableRegExpFilter: Boolean(initialEnableRegExpFilter), - unselectedSourceIds: - initialUnselectedSourceIds == null ? [] : initialUnselectedSourceIds, + 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(); + 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(); } - getIconName(): string { + // 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(): string { + getTitle() { const enabledProviderCount = this._store.getState().providers.size; - const {unselectedSourceIds} = this._model.state; + 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 @@ -142,9 +220,7 @@ export class 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, - ); + const selectedSource = sources.find(source => unselectedSourceIds.indexOf(source.id) === -1); if (selectedSource) { return `Console: ${selectedSource.name}`; } @@ -153,21 +229,21 @@ export class Console { return 'Console'; } - getDefaultLocation(): string { + getDefaultLocation() { return 'bottom'; } - getURI(): string { + getURI() { return WORKSPACE_VIEW_URI; } - onDidChangeTitle(callback: (title: string) => mixed): IDisposable { - return new UniversalDisposable(this._titleChanges.subscribe(callback)); + onDidChangeTitle(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(this._titleChanges.subscribe(callback)); } - _getSources(): Array { - const {providers, providerStatuses, records} = this._store.getState(); - return this._getSourcesMemoized({providers, providerStatuses, records}); + _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 @@ -175,203 +251,118 @@ export class Console { // 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 { + + destroy() { this._destroyed.next(); } - copy(): Console { + copy() { return new Console({ store: this._store, initialFilterText: this._model.state.filterText, initialEnableRegExpFilter: this._model.state.enableRegExpFilter, - initialUnselectedSourceIds: this._model.state.unselectedSourceIds, + initialUnselectedSourceIds: this._model.state.unselectedSourceIds }); } - _getBoundActionCreators(): BoundActionCreators { + _getBoundActionCreators() { if (this._actionCreators == null) { this._actionCreators = { execute: code => { - this._store.dispatch(Actions.execute(code)); + this._store.dispatch((_Actions || _load_Actions()).execute(code)); }, selectExecutor: executorId => { - this._store.dispatch(Actions.selectExecutor(executorId)); + this._store.dispatch((_Actions || _load_Actions()).selectExecutor(executorId)); }, clearRecords: () => { - this._store.dispatch(Actions.clearRecords()); - }, + this._store.dispatch((_Actions || _load_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, - ); + _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, - ); + 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, + filteredRecords }; } - getElement(): HTMLElement { + getElement() { 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 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 = bindObservableAsProps(props, ConsoleView); - return (this._element = renderReactRoot()); + 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(): ConsolePersistedState { + serialize() { const { filterText, enableRegExpFilter, - unselectedSourceIds, + unselectedSourceIds } = this._model.state; return { deserializer: 'nuclide.Console', filterText, enableRegExpFilter, - unselectedSourceIds, + 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(); + _getDisplayableRecords() { + const { records } = this._store.getState(); const displayableRecords = Array(records.size); records.forEach((record, i) => { displayableRecords[i] = this._toDisplayableRecord(record); @@ -384,7 +375,7 @@ export class Console { * per-Console instance because the same record can have different heights in different * containers. */ - _toDisplayableRecord(record: Record): DisplayableRecord { + _toDisplayableRecord(record) { const displayableRecord = this._displayableRecords.get(record); if (displayableRecord != null) { return displayableRecord; @@ -393,34 +384,28 @@ export class Console { id: this._nextRecordId++, record, height: INITIAL_RECORD_HEIGHT, - expansionStateId: {}, + expansionStateId: {} }; this._displayableRecords.set(record, newDisplayableRecord); return newDisplayableRecord; } } -function getSources(options: { - records: List, - providers: Map, - providerStatuses: Map, -}): Array { - const {providers, providerStatuses, records} = options; +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]; - }), - ); + 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. @@ -431,7 +416,7 @@ function getSources(options: { name: record.sourceId, status: 'stopped', start: undefined, - stop: undefined, + stop: undefined }); } }); @@ -439,54 +424,29 @@ function getSources(options: { return Array.from(mapOfSources.values()); } -function filterRecords( - displayableRecords: Array, - selectedSourceIds: Array, - filterPattern: ?RegExp, - filterSources: boolean, -): Array { +function filterRecords(displayableRecords, selectedSourceIds, filterPattern, filterSources) { if (!filterSources && filterPattern == null) { return displayableRecords; } - return displayableRecords.filter(({record}) => { + 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)) - ); + 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 { +async function serializeRecordObject(executor, visited, data, text, level) { const getText = record => { let indent = ''; for (let i = 0; i < level; i++) { indent += '\t'; } - return ( - indent + - (record.description != null - ? record.description - : record.value != null - ? record.value - : '') - ); + return indent + (record.description != null ? record.description : record.value != null ? record.value : ''); }; if (data.objectId == null) { @@ -508,98 +468,55 @@ async function serializeRecordObject( const childProperties = (await executor.getProperties(id).toPromise()) || []; const serializedProps = childProperties.map(childProp => { - return serializeRecordObject( - executor, - visited, - childProp.value, - '', - level + 1, - ); + 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 => - displayable.record.kind === 'message' || - displayable.record.kind === 'request' || - displayable.record.kind === 'response', - ) - .map(async displayable => { - const record = displayable.record; - const level = - record.level != null ? record.level.toString().toUpperCase() : 'LOG'; - const timestamp = record.timestamp.toLocaleString(); - let text = - record.text || - (record.data && record.data.value) || - ERROR_TRANSCRIBING_MESSAGE; - - 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( - executor, - new Set(), - record.data, - '', - 0, - ); - } +async function createPaste(createPasteImpl, records) { + const linePromises = records.filter(displayable => displayable.record.kind === 'message' || displayable.record.kind === 'request' || displayable.record.kind === 'response').map(async displayable => { + const record = displayable.record; + const level = record.level != null ? record.level.toString().toUpperCase() : 'LOG'; + const timestamp = record.timestamp.toLocaleString(); + let text = record.text || record.data && record.data.value || ERROR_TRANSCRIBING_MESSAGE; + + 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(executor, new Set(), record.data, '', 0); } + } - return `[${level}][${record.sourceId}][${timestamp}]\t ${text}`; - }); + return `[${level}][${record.sourceId}][${timestamp}]\t ${text}`; + }); 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.', - ); + atom.notifications.addWarning('There is nothing in your console to Paste! Check your console filters and try again.'); return; } atom.notifications.addInfo('Creating Paste...'); try { - const uri = await createPasteImpl( - lines, - { - title: 'Nuclide Console Paste', - }, - 'console paste', - ); + const uri = await 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)}`, - ); + atom.notifications.addError(`Failed to create paste: ${String(error.message || error)}`); return; } - const errorMessages = error.stdout - .trim() - .split('\n') - .map(JSON.parse) - .map(e => e.message); + 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, + dismissable: true }); } -} +} \ 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 ad422645ea..d42476b054 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,188 +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 {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 { - _filterComponent: ?RegExpFilter; - - focusFilter = (): void => { - if (this._filterComponent != null) { - this._filterComponent.focus(); - } - }; +'use strict'; - _handleClearButtonClick = (event: SyntheticMouseEvent<>): void => { - this.props.clear(); - }; +Object.defineProperty(exports, "__esModule", { + value: true +}); - _handleCreatePasteButtonClick = (event: SyntheticMouseEvent<>): void => { - if (this.props.createPaste != null) { - this.props.createPaste(); - } - }; +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')); +} - _handleFilterChange = (value: RegExpFilterChange): void => { - this.props.onFilterChange(value); - }; +var _Button; - _renderProcessControlButton(source: Source): ?React.Element { +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.focusFilter = () => { + if (this._filterComponent != null) { + this._filterComponent.focus(); + } + }, this._handleClearButtonClick = event => { + this.props.clear(); + }, this._handleCreatePasteButtonClick = event => { + if (this.props.createPaste != null) { + this.props.createPaste(); + } + }, 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; - } + 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(); - invariant(action != null); + + if (!(action != null)) { + throw new Error('Invariant violation: "action != null"'); + } + action(); }; - return ( - + return _react.createElement( + (_Button || _load_Button()).Button, + { + className: 'pull-right console-process-control-button', + icon: icon, + onClick: clickHandler }, + label ); } - _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() { + 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 : _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 : _react.createElement( + (_Button || _load_Button()).Button, + { + className: 'inline-block', + size: (_Button || _load_Button()).ButtonSizes.SMALL, + onClick: this._handleCreatePasteButtonClick + // eslint-disable-next-line nuclide-internal/jsx-simple-callback-refs + , ref: (0, (_addTooltip || _load_addTooltip()).default)({ + title: 'Creates a Paste from the current contents of the console' + }) }, + 'Create Paste' ); - }; - - 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, - })); - - const sourceButton = - options.length === 0 ? null : ( - - ); - const pasteButton = - this.props.createPaste == null ? null : ( - - ); - - return ( - - - {sourceButton} - (this._filterComponent = component)} - value={{ - text: this.props.filterText, - isRegExp: this.props.enableRegExpFilter, - invalid: this.props.invalidFilterInput, - }} - onChange={this._handleFilterChange} - /> - - - {pasteButton} - - - + return _react.createElement( + (_Toolbar || _load_Toolbar()).Toolbar, + { location: 'top' }, + _react.createElement( + (_ToolbarLeft || _load_ToolbarLeft()).ToolbarLeft, + null, + sourceButton, + _react.createElement((_RegExpFilter || _load_RegExpFilter()).default, { + ref: component => this._filterComponent = component, + value: { + text: this.props.filterText, + isRegExp: this.props.enableRegExpFilter, + 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 { +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) { @@ -193,15 +224,13 @@ function sortAlpha(a: string, b: string): number { return 0; } -type LabelProps = { - selectedOptions: Array<{value: string, label: string}>, -}; - -function MultiSelectLabel(props: LabelProps): React.Element { - const {selectedOptions} = props; - const label = - selectedOptions.length === 1 - ? selectedOptions[0].label - : `${selectedOptions.length} Sources`; - return Showing: {label}; -} +function MultiSelectLabel(props) { + const { selectedOptions } = props; + const 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 b1206e1cc6..40a15e8e80 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,3 +1,90 @@ +'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 _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 _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +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')); +} + +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. /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,373 +93,267 @@ * LICENSE file in 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, -} from '../types'; -import type {RegExpFilterChange} from 'nuclide-commons-ui/RegExpFilter'; - -import {macrotask} from 'nuclide-commons/observable'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -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 nullthrows from 'nullthrows'; -import shallowEqual from 'shallowequal'; -import recordsChanged from '../recordsChanged'; -import StyleSheet from 'nuclide-commons-ui/StyleSheet'; - -type Props = { - displayableRecords: Array, - history: Array, - clearRecords: () => void, - createPaste: ?() => Promise, - watchEditor: ?atom$AutocompleteWatchEditor, - 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, -}; - -// Maximum time (ms) for the console to try scrolling to the bottom. const MAXIMUM_SCROLLING_TIME = 3000; let count = 0; -export default class ConsoleView extends React.Component { - _consoleBodyEl: ?HTMLDivElement; - _consoleHeaderComponent: ?ConsoleHeader; - _disposables: UniversalDisposable; - _isScrolledNearBottom: boolean; - _id: number; - _inputArea: ?InputArea; +class ConsoleView extends _react.Component { - // 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; + constructor(props) { + super(props); + + this._getExecutor = id => { + return this.props.executors.get(id); + }; - _outputTable: ?OutputTable; + 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; + }; - constructor(props: Props) { - super(props); this.state = { - unseenMessages: false, + unseenMessages: false }; - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._isScrolledNearBottom = true; this._continuouslyScrollToBottom = false; this._id = count++; } - componentDidMount(): void { + // 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. + + + 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. - macrotask.subscribe(() => { - this._startScrollToBottom(); - }), - () => { - if (this._scrollingThrottle != null) { - this._scrollingThrottle.unsubscribe(); + // 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(); + } + }, atom.commands.add('atom-workspace', { + // eslint-disable-next-line nuclide-internal/atom-apis + 'atom-ide-console:focus-console-prompt': () => { + if (this._inputArea != null) { + this._inputArea.focus(); } - }, - atom.commands.add('atom-workspace', { - // eslint-disable-next-line nuclide-internal/atom-apis - 'atom-ide-console:focus-console-prompt': () => { - if (this._inputArea != null) { - this._inputArea.focus(); - } - }, - }), - atom.commands.add( - nullthrows(this._consoleBodyEl), - 'atom-ide:filter', - () => this._focusFilter(), - ), - ); + } + }), atom.commands.add((0, (_nullthrows || _load_nullthrows()).default)(this._consoleBodyEl), 'atom-ide:filter', () => this._focusFilter())); } - componentWillUnmount(): void { + componentWillUnmount() { this._disposables.dispose(); } - componentDidUpdate(prevProps: Props): void { + 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, - ) - ) { + if (this._isScrolledNearBottom && (0, (_recordsChanged || _load_recordsChanged()).default)(prevProps.displayableRecords, this.props.displayableRecords)) { this._startScrollToBottom(); } } - _focusFilter(): void { + _focusFilter() { if (this._consoleHeaderComponent != null) { this._consoleHeaderComponent.focusFilter(); } } - _renderPromptButton(): React.Element { - invariant(this.props.currentExecutor != null); - const {currentExecutor} = this.props; + _renderPromptButton() { + if (!(this.props.currentExecutor != null)) { + throw new Error('Invariant violation: "this.props.currentExecutor != null"'); + } + + const { currentExecutor } = this.props; const options = Array.from(this.props.executors.values()).map(executor => ({ id: executor.id, - label: executor.name, + label: executor.name })); - return ( - - ); + return _react.createElement((_PromptButton || _load_PromptButton()).default, { + value: currentExecutor.id, + onChange: this.props.selectExecutor, + options: options, + children: currentExecutor.name + }); } - _isScrolledToBottom( - offsetHeight: number, - scrollHeight: number, - scrollTop: number, - ): boolean { + _isScrolledToBottom(offsetHeight, scrollHeight, scrollTop) { return scrollHeight - (offsetHeight + scrollTop) < 5; } - componentWillReceiveProps(nextProps: Props): void { + componentWillReceiveProps(nextProps) { // If the messages were cleared, hide the notification. if (nextProps.displayableRecords.length === 0) { this._isScrolledNearBottom = true; - this.setState({unseenMessages: false}); + 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}); + // 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: Props, nextState: State): boolean { - return ( - !shallowEqual(this.props, nextProps) || - !shallowEqual(this.state, nextState) - ); + shouldComponentUpdate(nextProps, nextState) { + return !(0, (_shallowequal || _load_shallowequal()).default)(this.props, nextProps) || !(0, (_shallowequal || _load_shallowequal()).default)(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 ( -
- - (this._consoleHeaderComponent = component)} - selectedSourceIds={this.props.selectedSourceIds} - sources={this.props.sources} - onFilterChange={this.props.updateFilter} - onSelectedSourcesChange={this.props.selectSources} - /> - {/* - 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 - */} -
(this._consoleBodyEl = el)}> -
- - =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()} -
-
+ ` + }), + _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, + ref: component => this._consoleHeaderComponent = component, + selectedSourceIds: this.props.selectedSourceIds, + sources: this.props.sources, + onFilterChange: this.props.updateFilter, + onSelectedSourcesChange: this.props.selectSources + }), + _react.createElement( + 'div', + { + className: 'console-body atom-ide-filterable', + id: 'console-font-size-' + this._id, + ref: el => this._consoleBodyEl = el }, + _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() + ) ); } - _getMultiLineTip(): string { - const {currentExecutor} = this.props; + _getMultiLineTip() { + const { currentExecutor } = this.props; if (currentExecutor == null) { return ''; } - const keyCombo = - process.platform === 'darwin' - ? // Option + Enter on Mac - '\u2325 + \u23CE' - : // Shift + Enter on Windows and Linux. - 'Shift + Enter'; + const keyCombo = process.platform === 'darwin' ? // Option + Enter on Mac + '\u2325 + \u23CE' : // Shift + Enter on Windows and Linux. + 'Shift + Enter'; return `Tip: ${keyCombo} to insert a newline`; } - _renderPrompt(): ?React.Element { - const {currentExecutor} = this.props; + _renderPrompt() { + const { currentExecutor } = this.props; if (currentExecutor == null) { return; } - return ( -
- {this._renderPromptButton()} - (this._inputArea = component)} - scopeName={currentExecutor.scopeName} - onSubmit={this._executePrompt} - history={this.props.history} - watchEditor={this.props.watchEditor} - placeholderText={this._getMultiLineTip()} - /> -
+ return _react.createElement( + 'div', + { className: 'console-prompt' }, + this._renderPromptButton(), + _react.createElement((_InputArea || _load_InputArea()).default, { + ref: component => this._inputArea = component, + scopeName: currentExecutor.scopeName, + onSubmit: this._executePrompt, + history: this.props.history, + watchEditor: this.props.watchEditor, + placeholderText: this._getMultiLineTip() + }) ); } - _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, - ); + _handleScrollEnd(offsetHeight, scrollHeight, scrollTop) { + const isScrolledToBottom = this._isScrolledToBottom(offsetHeight, scrollHeight, scrollTop); this._isScrolledNearBottom = isScrolledToBottom; this._stopScrollToBottom(); this.setState({ - unseenMessages: this.state.unseenMessages && !this._isScrolledNearBottom, + 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; - }; } +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 8f9e510bc5..bc92a2e8ff 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,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 strict - * @format - */ +'use strict'; -import * as React from 'react'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -type Props = { - filteredRecordCount: number, - onReset: () => void, -}; +var _react = _interopRequireWildcard(require('react')); -export default class FilteredMessagesReminder extends React.Component { - handleClick = (e: SyntheticEvent<>) => { - e.preventDefault(); - this.props.onReset(); - }; +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 {filteredRecordCount} = this.props; +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.
-
-
+ return _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. + * + * strict + * @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 9f70b78ef8..c173f84b7f 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,179 +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 strict-local - * @format - */ - -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: ?atom$AutocompleteWatchEditor, - onDidTextBufferChange?: (event: atom$AggregatedTextEditEvent) => mixed, - placeholderText?: string, -}; - -type State = { - historyIndex: number, - draft: string, -}; - -const ENTER_KEY_CODE = 13; +'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 }; } + +const ENTER_KEY_CODE = 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. + * + * strict-local + * @format + */ + const UP_KEY_CODE = 38; const DOWN_KEY_CODE = 40; -export default class InputArea extends React.Component { - _keySubscription: ?rxjs$ISubscription; - _textEditorModel: ?atom$TextEditor; +class InputArea extends _react.Component { - constructor(props: Props) { + constructor(props) { super(props); - this.state = { - historyIndex: -1, - draft: '', + + this.focus = () => { + if (this._textEditorModel != null) { + this._textEditorModel.getElement().focus(); + } }; - } - focus = (): void => { - if (this._textEditorModel != null) { - this._textEditorModel.getElement().focus(); - } - }; - - _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) { - if (!isAutocompleteOpen) { - event.preventDefault(); - event.stopImmediatePropagation(); + this._submit = () => { + // Clear the text and trigger the `onSubmit` callback + const editor = this._textEditorModel; + if (editor == null) { + return; + } - if (event.ctrlKey || event.altKey || event.shiftKey) { - editor.insertNewline(); - return; - } + const text = editor.getText(); + if (text === '') { + return; + } - this._submit(); + 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'])); } - } else if ( - event.which === UP_KEY_CODE && - (editor.getLineCount() <= 1 || editor.getCursorBufferPosition().row === 0) - ) { - if (this.props.history.length === 0 || isAutocompleteOpen) { - return; + return disposable; + }; + + this._handleTextEditor = component => { + if (this._keySubscription) { + this._textEditorModel = null; + this._keySubscription.unsubscribe(); } - 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}); + if (component) { + this._textEditorModel = component.getModel(); + const el = _reactDom.default.findDOMNode(component); + this._keySubscription = _rxjsBundlesRxMinJs.Observable.fromEvent(el, 'keydown').subscribe(this._handleKeyDown); } - 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) { + }; + + 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 { - editor.setText( - this.props.history[this.props.history.length - historyIndex - 1], - ); + if (event.which === ENTER_KEY_CODE) { + if (!isAutocompleteOpen) { + 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]); + } 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]); + } } - } - }; - - render(): React.Node { - const grammar = - this.props.scopeName == null - ? null - : atom.grammars.grammarForScopeName(this.props.scopeName); - return ( -
- -
+ }; + + this.state = { + historyIndex: -1, + draft: '' + }; + } + + render() { + const grammar = 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, + placeholderText: this.props.placeholderText + }) ); } } +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 f0ed5085bc..1997929dc8 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,3 +1,21 @@ +'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. @@ -6,33 +24,21 @@ * LICENSE file in 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 strict + * strict * @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, - }, - ); - return ( -
- - New Messages -
+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 _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 1342b586bd..4977505629 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,3 +1,65 @@ +'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 + + +/* eslint-disable react/no-unused-prop-types */ /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,121 +68,146 @@ * LICENSE file in 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, -}; -/* 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; +class OutputTable extends _react.Component { // This is a from react-virtualized (untyped library) - _list: ?React.Element; - _wrapper: ?HTMLElement; - _renderedRecords: Map; + constructor(props) { + super(props); - // The currently rendered range. - _startIndex: number; - _stopIndex: number; - _refs: Subject; + this._handleRef = node => { + this._refs.next(node); + }; - constructor(props: Props) { - super(props); - this._disposable = new UniversalDisposable(); - this._hasher = new Hasher(); + 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 nuclide-internal/jsx-simple-callback-refs + , { 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; + } + 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, + 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); - }), - ); + 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); + })); } - componentDidUpdate(prevProps: Props, prevState: State): void { - if ( - this._list != null && - recordsChanged( - prevProps.displayableRecords, - this.props.displayableRecords, - ) - ) { + // 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(), - ); + this._renderedRecords.forEach(recordView => recordView.measureAndNotifyHeight()); } } @@ -128,143 +215,38 @@ export default class OutputTable extends React.Component { 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} -
+ 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 ); } - _handleListRender = (opts: {startIndex: number, stopIndex: number}): void => { - this._startIndex = opts.startIndex; - this._stopIndex = opts.stopIndex; - }; - - scrollToBottom(): void { + scrollToBottom() { 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 ( -
- { - 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 { + _containerRendered() { 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) { - 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); - }; } +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 84ba1cbedd..a60df308b0 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,36 +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 - */ +'use strict'; -import invariant from 'assert'; -import * as React from 'react'; -import electron from 'electron'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -const {remote} = electron; -invariant(remote != null); +var _react = _interopRequireWildcard(require('react')); -type PromptOption = { - id: string, - label: string, -}; +var _electron = _interopRequireDefault(require('electron')); -type Props = { - value: string, - onChange: (value: string) => void, - children: ?any, - options: Array, -}; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -export default class PromptButton extends React.Component { - _menu: ?electron$Menu; +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 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({ x: event.clientX, y: event.clientY, async: true }); + this._menu = menu; + }, _temp; + } componentWillUnmount() { if (this._menu != null) { @@ -38,29 +54,18 @@ export default class PromptButton extends React.Component { } } - render(): React.Node { - return ( - - {this.props.children} - - + 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' }) ); } - _handleClick = (event: SyntheticMouseEvent<>): void => { - 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({x: event.clientX, y: event.clientY, async: true}); - this._menu = menu; - }; } +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 cb2e8d976b..ff07f28ee4 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,67 +1,127 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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)} - -); +'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, className: 'nuclide-console-default-text-colors' }, + (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; -export default class RecordView extends React.Component { - _wrapper: ?HTMLElement; - _debouncedMeasureAndNotifyHeight: () => void; - _rafDisposable: ?rxjs$Subscription; +class RecordView extends _react.Component { - constructor(props: Props) { + 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, - ); + + 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() { @@ -76,13 +136,17 @@ export default class RecordView extends React.Component { } } - _renderContent(displayableRecord: DisplayableRecord): React.Element { - const {record} = displayableRecord; + _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 || ' '}
; + return _react.createElement( + 'pre', + null, + record.text || ' ' + ); } else if (record.kind === 'response') { const executor = this.props.getExecutor(record.sourceId); return this._renderNestedValueComponent(displayableRecord, executor); @@ -94,130 +158,112 @@ export default class RecordView extends React.Component { const text = record.text || ' '; if (record.format === 'ansi') { - return {text}; + return _react.createElement( + (_Ansi || _load_Ansi()).default, + { renderSegment: AnsiRenderSegment }, + text + ); } - return
{parseText(text)}
; + return _react.createElement( + 'pre', + null, + (0, (_parseText || _load_parseText()).default)(text) + ); } } - shouldComponentUpdate(nextProps: Props): boolean { - return !shallowEqual(this.props, nextProps); + shouldComponentUpdate(nextProps) { + return !(0, (_shallowequal || _load_shallowequal()).default)(this.props, nextProps); } - _renderNestedValueComponent( - displayableRecord: DisplayableRecord, - provider: ?OutputProvider | ?Executor, - ): React.Element { - const {record, expansionStateId} = displayableRecord; + _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 ( - - ); + return _react.createElement((_LazyNestedValueComponent || _load_LazyNestedValueComponent()).LazyNestedValueComponent, { + className: 'console-lazy-nested-value', + evaluationResult: record.data, + fetchChildren: getProperties, + simpleValueComponent: simpleValueComponent, + shouldCacheChildren: true, + expansionStateId: expansionStateId + }); } - render(): React.Node { - const {displayableRecord} = this.props; - const {record} = displayableRecord; - const {level, kind, timestamp, sourceId} = record; + render() { + const { displayableRecord } = this.props; + const { record } = displayableRecord; + const { level, kind, timestamp, sourceId } = record; - const classNames = classnames('console-record', `level-${level || 'log'}`, { + const classNames = (0, (_classnames || _load_classnames()).default)('console-record', `level-${level || 'log'}`, { request: kind === 'request', - response: kind === 'response', + response: kind === 'response' }); const iconName = getIconName(record); // flowlint-next-line sketchy-null-string:off - const icon = iconName ? : null; - const sourceLabel = this.props.showSourceLabel ? ( - - {sourceId} - + 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 = ( -
{timestampLabel}
+ const timestampLabel = Date.now() - timestamp > ONE_DAY ? timestamp.toLocaleString() : timestamp.toLocaleTimeString(); + renderedTimestamp = _react.createElement( + 'div', + { className: 'console-record-timestamp' }, + timestampLabel ); } - return ( - - {/* $FlowFixMe(>=0.53.0) Flow suppress */} -
- {icon} -
- {displayableRecord.record.repeatCount > 1 && ( -
- {displayableRecord.record.repeatCount} -
- )} -
- {this._renderContent(displayableRecord)} -
-
- {sourceLabel} - {renderedTimestamp} -
-
+ 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 + ) ); } - 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 { +exports.default = RecordView; +function getComponent(type) { switch (type) { case 'text': - return props => TextRenderer(props.evaluationResult); + 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'; @@ -232,7 +278,7 @@ function getHighlightClassName(level: Level): string { } } -function getIconName(record: Record): ?string { +function getIconName(record) { switch (record.kind) { case 'request': return 'chevron-right'; @@ -249,4 +295,4 @@ function getIconName(record: Record): ?string { case 'error': return 'stop'; } -} +} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/spec/ConsoleView-spec.js b/modules/atom-ide-ui/pkg/atom-ide-console/spec/ConsoleView-spec.js deleted file mode 100644 index f717720722..0000000000 --- a/modules/atom-ide-ui/pkg/atom-ide-console/spec/ConsoleView-spec.js +++ /dev/null @@ -1,63 +0,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. - * - * @flow - * @format - */ - -import invariant from 'assert'; -import * as React from 'react'; -import ReactDom from 'react-dom'; -import TestUtils from 'react-dom/test-utils'; -import ConsoleView from '../lib/ui/ConsoleView'; - -describe('ConsoleView', () => { - it('focuses the filter when "/" is pressed', () => { - const consoleView: ConsoleView = (TestUtils.renderIntoDocument( - {}} - createPaste={null} - currentExecutor={null} - displayableRecords={[]} - enableRegExpFilter={true} - execute={() => {}} - executors={new Map()} - filterText={''} - filteredRecordCount={0} - fontSize={12} - getProvider={() => {}} - history={[]} - invalidFilterInput={false} - onDisplayableRecordHeightChange={() => {}} - resetAllFilters={() => {}} - selectExecutor={() => {}} - selectSources={() => {}} - selectedSourceIds={[]} - sources={[]} - updateFilter={() => {}} - watchEditor={null} - />, - ): any); - - const workspaceEl = atom.views.getView(atom.workspace); - const consoleViewNode = ReactDom.findDOMNode(consoleView); - invariant(consoleViewNode != null); - workspaceEl.appendChild(consoleViewNode); - - const consoleHeaderComponent = consoleView._consoleHeaderComponent; - invariant(consoleHeaderComponent != null); - const filterFocusSpy = spyOn(consoleHeaderComponent, 'focusFilter'); - - const consoleBodyTarget = workspaceEl.querySelector('.console-body'); - invariant(consoleBodyTarget != null); - atom.commands.dispatch(consoleBodyTarget, 'atom-ide:filter'); - - expect(filterFocusSpy).toHaveBeenCalled(); - workspaceEl.removeChild(consoleViewNode); - }); -}); 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 deleted file mode 100644 index 2a6f1143a7..0000000000 --- a/modules/atom-ide-ui/pkg/atom-ide-console/spec/Epics-spec.js +++ /dev/null @@ -1,59 +0,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. - * - * @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'; - -describe('Epics', () => { - describe('registerOutputProviderEpic', () => { - it('observes the status', () => { - const mockStore = { - dispatch: () => {}, - getState: () => (({}: any): AppState), - }; - let setStatus; - const provider = { - id: 'test', - messages: Observable.never(), - observeStatus: cb => { - setStatus = cb; - }, - start: () => {}, - stop: () => {}, - }; - const actions = new ActionsObservable( - Observable.of(Actions.registerOutputProvider(provider)), - ); - let results = []; - Epics.registerRecordProviderEpic(actions, mockStore).subscribe( - results.push.bind(results), - ); - invariant(setStatus != null); - setStatus('running'); - setStatus('stopped'); - setStatus('running'); - results = results.filter(action => action.type === 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']); - }); - }); -}); 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 deleted file mode 100644 index febf34f8ad..0000000000 --- a/modules/atom-ide-ui/pkg/atom-ide-console/spec/Reducers-spec.js +++ /dev/null @@ -1,214 +0,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. - * - * @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 => {}), - }; -} 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 deleted file mode 100644 index 914754472c..0000000000 --- a/modules/atom-ide-ui/pkg/atom-ide-console/spec/getCurrentExecutorId-spec.js +++ /dev/null @@ -1,40 +0,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. - * - * @flow strict-local - * @format - */ - -import getCurrentExecutorId from '../lib/getCurrentExecutorId'; -import * as Immutable from 'immutable'; -import {createDummyExecutor} from './Reducers-spec'; - -const baseAppState = { - createPasteFunction: null, - currentExecutorId: 'a', - maxMessageCount: Number.POSITIVE_INFINITY, - executors: new Map([['a', createDummyExecutor('a')]]), - providers: new Map(), - providerStatuses: new Map(), - records: Immutable.List(), - history: [], -}; - -describe('getCurrentExecutorId', () => { - it('gets the current executor', () => { - expect(getCurrentExecutorId(baseAppState)).toBe('a'); - }); - - it('returns an executor even if the current id is null', () => { - const appState = { - ...baseAppState, - currentExecutorId: null, - }; - expect(getCurrentExecutorId(appState)).toBe('a'); - }); -}); 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 deleted file mode 100644 index 7c1d0495a9..0000000000 --- a/modules/atom-ide-ui/pkg/atom-ide-console/spec/parseText-spec.js +++ /dev/null @@ -1,31 +0,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. - * - * @flow strict-local - * @format - */ - -import parseText from '../lib/parseText'; - -describe('parseText', () => { - it('parses url pattern', () => { - const chunks = parseText('Message: https://facebook.com'); - expect(chunks.length).toBe(3); - expect(chunks[0]).toBe('Message: '); - expect(chunks[2]).toBe(''); - - const reactElement = chunks[1]; - expect(typeof reactElement).toBe('object'); // type React.Element - - if (typeof reactElement === 'object') { - expect(reactElement.type).toBe('a'); - expect(reactElement.props.href).toBe('https://facebook.com'); - expect(reactElement.props.children).toBe('https://facebook.com'); - } - }); -}); 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 2d4204764d..41bbcddc32 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,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 - */ - -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({ +'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', + CLOSE: 'CLOSE' }); const IconsForAction = { [DATATIP_ACTIONS.PIN]: 'pin', - [DATATIP_ACTIONS.CLOSE]: 'x', + [DATATIP_ACTIONS.CLOSE]: 'x' }; -type DatatipComponentProps = { - action: string, - actionTitle: string, - className?: string, - datatip: Datatip, - onActionClick: Function, -}; +class DatatipComponent extends _react.Component { + constructor(...args) { + var _temp; -export class DatatipComponent extends React.Component { - handleActionClick = (event: SyntheticEvent<>) => { - this.props.onActionClick(); - }; + return _temp = super(...args), this.handleActionClick = event => { + this.props.onActionClick(); + }, _temp; + } - render(): React.Node { - const { + render() { + const _props = this.props, + { className, action, actionTitle, datatip, - onActionClick, - ...props - } = this.props; + 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} -
+ return _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 2b20f81e51..7541743b52 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,3 +1,100 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DatatipManager = undefined; + +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 _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 _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. @@ -6,67 +103,25 @@ * LICENSE file in 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 { - 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; const TRACK_SAMPLE_RATE = 10; -type PinClickHandler = (editor: atom$TextEditor, datatip: Datatip) => void; - -type DatatipResult = { - datatip: Datatip, - provider: AnyDatatipProvider, -}; - -function getProviderName(provider: AnyDatatipProvider): string { +function getProviderName(provider) { if (provider.providerName == null) { - getLogger('datatip').error('Datatip provider has no name', provider); + (0, (_log4js || _load_log4js()).getLogger)('datatip').error('Datatip provider has no name', provider); return 'unknown'; } return provider.providerName; } -function getBufferPosition( - editor: TextEditor, - editorView: atom$TextEditorElement, - event: ?MouseEvent, -): null | atom$Point { +function getBufferPosition(editor, editorView, event) { if (!event) { return null; } @@ -78,150 +133,110 @@ function getBufferPosition( const screenPosition = text.screenPositionForMouseEvent(event); const pixelPosition = text.pixelPositionForMouseEvent(event); - const pixelPositionFromScreenPosition = text.pixelPositionForScreenPosition( - screenPosition, - ); + const pixelPositionFromScreenPosition = text.pixelPositionForScreenPosition(screenPosition); // Distance (in pixels) between screenPosition and the cursor. - const horizontalDistance = - pixelPosition.left - pixelPositionFromScreenPosition.left; + 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() - ) { + 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), - ); +async function getDatatipResults(providers, editor, position, invoke) { + const filteredDatatipProviders = Array.from(providers.getAllProvidersForEditor(editor)); if (filteredDatatipProviders.length === 0) { return []; } - const promises = filteredDatatipProviders.map( - async (provider: TProvider): Promise => { - const name = getProviderName(provider); - try { - return await analytics.trackTimingSampled( - name + '.datatip', - async (): Promise => { - const datatip: ?Datatip = await invoke(provider); - if (!datatip) { - return null; - } - return {datatip, provider}; - }, - TRACK_SAMPLE_RATE, - {path: editor.getPath()}, - ); - } catch (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); + const promises = filteredDatatipProviders.map(async provider => { + const name = getProviderName(provider); + try { + return await (_analytics || _load_analytics()).default.trackTimingSampled(name + '.datatip', async () => { + const datatip = await invoke(provider); + if (!datatip) { + return null; + } + return { datatip, provider }; + }, TRACK_SAMPLE_RATE, { path: editor.getPath() }); + } catch (e) { + (0, (_log4js || _load_log4js()).getLogger)('datatip').error(`Error getting datatip from provider ${name}`, e); + return null; + } + }); + if ((_featureConfig || _load_featureConfig()).default.get('atom-ide-datatip.onlyTopDatatip')) { + const result = await (0, (_promise || _load_promise()).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, editor, - onPinClick, -}: PinnableDatatipProps): React.Element { + 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 { +function mountDatatipWithMarker(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, + 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); - }, - ), - ); + 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', + VISIBLE: 'VISIBLE' }); -type State = $Keys; -function ensurePositiveNumber(value: any, defaultValue: number): number { + +function ensurePositiveNumber(value, defaultValue) { if (typeof value !== 'number' || value < 0) { return defaultValue; } @@ -229,40 +244,14 @@ 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, - ) { + + constructor(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'); @@ -276,179 +265,126 @@ class DatatipManagerForEditor { this._lastFetchedFromCursorPosition = false; 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; - } + this._subscriptions.add((_featureConfig || _load_featureConfig()).default.observe('atom-ide-datatip.datatipDebounceDelay', () => this._setStartFetchingDebounce()), (_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 = getModifierKeysFromMouseEvent(e); - if (this._datatipState === DatatipState.HIDDEN) { - this._startFetchingDebounce(); - } else { - this._hideIfOutside(); - } - }), - Observable.fromEvent(this._editorView, 'mouseleave').subscribe(() => { - this._lastMoveEvent = null; + 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() { if (this._lastFetchedFromCursorPosition) { this._startFetching(() => this._editor.getCursorBufferPosition()); } else { - this._startFetching(() => - getBufferPosition(this._editor, this._editorView, this._lastMoveEvent), - ); + this._startFetching(() => 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; @@ -460,7 +396,7 @@ class DatatipManagerForEditor { } } - async _startFetching(getPosition: () => ?atom$Point): Promise { + async _startFetching(getPosition) { const position = getPosition(); if (!position) { return; @@ -475,21 +411,13 @@ class DatatipManagerForEditor { this._setState(DatatipState.HIDDEN); } - if ( - this._blacklistedPosition && - data.range && - data.range.containsPoint(this._blacklistedPosition) - ) { + if (this._blacklistedPosition && data.range && data.range.containsPoint(this._blacklistedPosition)) { this._setState(DatatipState.HIDDEN); return; } const currentPosition = getPosition(); - if ( - !currentPosition || - !data.range || - !data.range.containsPoint(currentPosition) - ) { + if (!currentPosition || !data.range || !data.range.containsPoint(currentPosition)) { this._setState(DatatipState.HIDDEN); return; } @@ -507,115 +435,78 @@ class DatatipManagerForEditor { if (this._markerDisposable) { this._markerDisposable.dispose(); } - this._markerDisposable = mountDatatipWithMarker( - this._editor, - this._datatipElement, - data.range, - data.renderedProviders, - currentPosition, - ); + this._markerDisposable = mountDatatipWithMarker(this._editor, this._datatipElement, data.range, data.renderedProviders, currentPosition); } - async _fetch(position: atom$Point): Promise> { + async _fetch(position) { this._setState(DatatipState.FETCHING); - let results: Promise>; - if ( - this._lastPosition != null && - position.isEqual(this._lastPosition) && - this._lastResultsPromise != null - ) { + let results; + if (this._lastPosition != null && position.isEqual(this._lastPosition) && this._lastResultsPromise != null) { results = this._lastResultsPromise; } else { - this._lastResultsPromise = getDatatipResults( - this._datatipProviders, - this._editor, - position, - provider => provider.datatip(this._editor, position), - ); + this._lastResultsPromise = getDatatipResults(this._datatipProviders, this._editor, position, provider => provider.datatip(this._editor, position)); results = this._lastResultsPromise; this._lastPosition = position; } - return (await results).concat( - await getDatatipResults( - this._modifierDatatipProviders, - this._editor, - position, - provider => - provider.modifierDatatip(this._editor, position, this._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, - }> { + async _fetchAndRender(position) { const datatipsAndProviders = await this._fetch(position); if (datatipsAndProviders.length === 0) { return null; } const range = datatipsAndProviders[0].datatip.range; - analytics.track('datatip-popup', { + (_analytics || _load_analytics()).default.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), + rangeEndColumn: String(range.end.column) }); - const renderedProviders = ( -
- {datatipsAndProviders.map(({datatip, provider}) => ( - - ))} -
+ const renderedProviders = _react.createElement( + 'div', + null, + datatipsAndProviders.map(({ datatip, provider }) => _react.createElement(PinnableDatatip, { + datatip: datatip, + editor: this._editor, + key: getProviderName(provider), + onPinClick: this._handlePinClicked + })) ); return { range, - renderedProviders, + 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 { - if ( - this._datatipState === DatatipState.HIDDEN || - this._datatipState === DatatipState.FETCHING - ) { + _hideOrCancel() { + if (this._datatipState === DatatipState.HIDDEN || this._datatipState === DatatipState.FETCHING) { if (this._blacklistedPosition == null) { - this._blacklistedPosition = getBufferPosition( - this._editor, - this._editorView, - this._lastMoveEvent, - ); + this._blacklistedPosition = getBufferPosition(this._editor, this._editorView, this._lastMoveEvent); } return; } @@ -623,7 +514,7 @@ class DatatipManagerForEditor { this._setState(DatatipState.HIDDEN); } - _hideIfOutside(): void { + _hideIfOutside() { if (this._datatipState !== DatatipState.VISIBLE) { return; } @@ -635,7 +526,7 @@ class DatatipManagerForEditor { } } - _hideIfOutsideImmediate(): void { + _hideIfOutsideImmediate() { if (this._datatipState !== DatatipState.VISIBLE) { return; } @@ -648,60 +539,50 @@ class DatatipManagerForEditor { return; } - const currentPosition = getBufferPosition( - this._editor, - this._editorView, - this._lastMoveEvent, - ); - if ( - currentPosition && - this._range && - this._range.containsPoint(currentPosition) - ) { + const currentPosition = getBufferPosition(this._editor, this._editorView, this._lastMoveEvent); + if (currentPosition && this._range && this._range.containsPoint(currentPosition)) { return; } this._setState(DatatipState.HIDDEN); } - createPinnedDataTip( - datatip: Datatip, - editor: TextEditor, - options?: PinnedDatatipOptions, - ): PinnedDatatip { - const pinnedDatatip = new PinnedDatatip(datatip, editor, { - ...options, + createPinnedDataTip(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; } - _handlePinClicked = (editor: TextEditor, datatip: Datatip) => { - analytics.track('datatip-pinned-open'); - const startTime = performanceNow(); +} + +var _initialiseProps = function () { + this._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', - }), - ); + this._pinnedDatatips.add(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' + })); }; - _toggleDatatip = (e?: atom$CustomEvent) => { + this._toggleDatatip = e => { + var _ref, _ref2; + if (atom.workspace.getActiveTextEditor() !== this._editor) { return; } @@ -710,24 +591,19 @@ 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; + const forceShow = maybeEventType === 'keydown' && performance.now() - this._lastHiddenTime > 100; const forceHide = maybeEventType === 'keyup'; - const forceToggle = - maybeEventType !== 'keydown' && maybeEventType !== 'keyup'; + const forceToggle = 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) { @@ -735,7 +611,9 @@ class DatatipManagerForEditor { } }; - _copyDatatipToClipboard = async () => { + this._copyDatatipToClipboard = async () => { + var _ref3, _ref4; + if (atom.workspace.getActiveTextEditor() !== this._editor) { return; } @@ -744,10 +622,10 @@ class DatatipManagerForEditor { if (pos == null) { return; } - const results: Array = await this._fetch(pos); + const results = await this._fetch(pos); this._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; } @@ -763,66 +641,47 @@ class DatatipManagerForEditor { } atom.clipboard.write(value); - atom.notifications.addInfo( - `Copied data tip to clipboard: \`\`\`${value}\`\`\``, - ); + atom.notifications.addInfo(`Copied data tip to clipboard: \`\`\`${value}\`\`\``); }; -} +}; -export class DatatipManager { - _datatipProviders: ProviderRegistry; - _modifierDatatipProviders: ProviderRegistry; - _editorManagers: Map; - _subscriptions: UniversalDisposable; +class DatatipManager { 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._subscriptions.add( - atom.workspace.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()); - }), - ); + this._datatipProviders = new (_ProviderRegistry || _load_ProviderRegistry()).default(); + this._modifierDatatipProviders = new (_ProviderRegistry || _load_ProviderRegistry()).default(); + + this._subscriptions.add(atom.workspace.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 { + createPinnedDataTip(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', - ); + throw new Error('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(); @@ -830,3 +689,4 @@ export class DatatipManager { 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 7336a48af0..1d483b9445 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,51 +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 {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 { +'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 ( -
- ); + return _react.createElement('div', { + className: 'datatip-marked-container', + dangerouslySetInnerHTML: { + __html: domPurify.sanitize((0, (_marked || _load_marked()).default)(chunk.value, { + breaks: true + })) + }, + 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 4337d8e368..b0f9661046 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,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 {TextBuffer} from 'atom'; -import * as React from 'react'; -import {AtomTextEditor} from 'nuclide-commons-ui/AtomTextEditor'; +'use strict'; -// Complex types can end up being super long. Truncate them. -const MAX_LENGTH = 100; +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _atom = require('atom'); + +var _react = _interopRequireWildcard(require('react')); + +var _AtomTextEditor; + +function _load_AtomTextEditor() { + return _AtomTextEditor = require('../../../../nuclide-commons-ui/AtomTextEditor'); +} -type Props = { - value: string, - grammar: atom$Grammar, -}; +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; } } -type State = { - isExpanded: boolean, -}; +// 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 + */ -export default class MarkedStringSnippet extends React.Component { - state = { - isExpanded: false, - }; +class MarkedStringSnippet extends _react.Component { + constructor(...args) { + var _temp; - render(): React.Node { - const {grammar, value} = this.props; + 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, - ); - return ( -
) => { - this.setState({isExpanded: !this.state.isExpanded}); + const buffer = new _atom.TextBuffer(shouldTruncate ? value.substr(0, MAX_LENGTH) + '...' : value); + return _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 2f3670cfe4..7321dac57c 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,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 {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; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PinnedDatatip = undefined; + +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 _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 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$(): Observable { +function documentMouseMove$() { if (_mouseMove$ == null) { - _mouseMove$ = Observable.fromEvent(document, 'mousemove'); + _mouseMove$ = _rxjsBundlesRxMinJs.Observable.fromEvent(document, 'mousemove'); } return _mouseMove$; } let _mouseUp$; -function documentMouseUp$(): Observable { +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; - - constructor( - datatip: Datatip, - editor: TextEditor, - params: PinnedDatatipParams, - ) { - this._subscriptions = new UniversalDisposable(); - this._subscriptions.add( - new UniversalDisposable(() => params.onDispose(this)), - ); +class PinnedDatatip { + + constructor(datatip, editor, params) { + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._subscriptions.add(new (_UniversalDisposable || _load_UniversalDisposable()).default(() => params.onDispose(this))); this._datatip = datatip; this._editor = editor; this._marker = null; @@ -103,75 +86,62 @@ export class PinnedDatatip { this._checkedScrollable = false; 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(); - } - }), - ); - this._hostElement.addEventListener( - 'mouseenter', - this._boundHandleMouseEnter, - ); - this._hostElement.addEventListener( - 'mouseleave', - this._boundHandleMouseLeave, - ); - this._subscriptions.add( - new UniversalDisposable(() => { - this._hostElement.removeEventListener( - 'mouseenter', - this._boundHandleMouseEnter, - ); - this._hostElement.removeEventListener( - 'mouseleave', - this._boundHandleMouseLeave, - ); - }), - ); + this._subscriptions.add(_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); + this._hostElement.addEventListener('mouseleave', this._boundHandleMouseLeave); + this._subscriptions.add(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; + this._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 +153,28 @@ 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,39 +184,29 @@ 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; - _hostElement.style.top = - -_editor.getLineHeightInPixels() + _offset.y + 'px'; - _hostElement.style.left = - (lineLength - range.end.column) * charWidth + - LINE_END_MARGIN + - _offset.x + - 'px'; + const lineLength = _editor.getBuffer().getLines()[range.start.row].length; + _hostElement.style.top = -_editor.getLineHeightInPixels() + _offset.y + 'px'; + _hostElement.style.left = (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'; + _hostElement.style.bottom = _editor.getLineHeightInPixels() + _hostElement.clientHeight - _offset.y + 'px'; _hostElement.style.left = _offset.x + 'px'; break; default: - (_position: empty); + _position; throw new Error(`Unexpected PinnedDatatip position: ${this._position}`); } } - async render(): Promise { - const {_editor, _datatip, _hostElement, _isDragging, _isHovering} = this; + async render() { + const { _editor, _datatip, _hostElement, _isDragging, _isHovering } = this; let rangeClassname = 'datatip-highlight-region'; if (_isHovering) { @@ -260,8 +214,8 @@ export class PinnedDatatip { } if (this._marker == null) { - const marker: atom$Marker = _editor.markBufferRange(_datatip.range, { - invalidate: 'never', + const marker = _editor.markBufferRange(_datatip.range, { + invalidate: 'never' }); this._marker = marker; _editor.decorateMarker(marker, { @@ -269,12 +223,12 @@ export class PinnedDatatip { position: 'head', item: this._hostElement, // above-range datatips currently assume that the overlay is below. - avoidOverflow: this._position !== 'above-range', + avoidOverflow: this._position !== 'above-range' }); if (this._showRangeHighlight) { this._rangeDecoration = _editor.decorateMarker(marker, { type: 'highlight', - class: rangeClassname, + class: rangeClassname }); } await _editor.getElement().getNextUpdatePromise(); @@ -285,29 +239,23 @@ export class PinnedDatatip { } else if (this._rangeDecoration != null) { this._rangeDecoration.setProperties({ type: 'highlight', - class: rangeClassname, + class: rangeClassname }); } - ReactDOM.render( - , - _hostElement, - ); + _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 +265,9 @@ 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 09a76ffea2..bcc9459ad4 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,3 +1,17 @@ +'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. @@ -6,40 +20,35 @@ * LICENSE file in 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 strict-local + * strict-local * @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, + Meta: (_types || _load_types()).ModifierKeys.META, + Shift: (_types || _load_types()).ModifierKeys.SHIFT, + Alt: (_types || _load_types()).ModifierKeys.ALT, + Control: (_types || _load_types()).ModifierKeys.CTRL }; -export function getModifierKeysFromMouseEvent(e: MouseEvent): Set { - const keys: Set = new Set(); +function getModifierKeysFromMouseEvent(e) { + const keys = new Set(); if (e.metaKey) { - keys.add(ModifierKeys.META); + keys.add((_types || _load_types()).ModifierKeys.META); } if (e.shiftKey) { - keys.add(ModifierKeys.SHIFT); + keys.add((_types || _load_types()).ModifierKeys.SHIFT); } if (e.altKey) { - keys.add(ModifierKeys.ALT); + keys.add((_types || _load_types()).ModifierKeys.ALT); } if (e.ctrlKey) { - keys.add(ModifierKeys.CTRL); + keys.add((_types || _load_types()).ModifierKeys.CTRL); } return keys; } -export function getModifierKeyFromKeyboardEvent( - e: KeyboardEvent, -): ?ModifierKey { +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 2e3fcf0a66..adc72e097c 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,3 +1,9 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = isScrollable; /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,23 +12,17 @@ * LICENSE file in 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); +function isScrollable(element, wheelEvent) { + let node = wheelEvent.target; while (node != null && node !== element) { - if ( - node.scrollHeight > node.clientHeight || - node.scrollWidth > node.clientWidth - ) { + 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 1e4239c78f..04762d8fe0 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,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 strict-local - * @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(); } -} +} /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ -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-datatip/lib/types.js b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/types.js index aad7d4f8fc..8f8cebc6e1 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,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,7 +11,7 @@ * LICENSE file in 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 */ @@ -15,79 +20,11 @@ * 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({ +const ModifierKeys = exports.ModifierKeys = Object.freeze({ META: 'metaKey', SHIFT: 'shiftKey', ALT: 'altKey', - CTRL: 'ctrlKey', + CTRL: 'ctrlKey' }); -export type ModifierKey = 'metaKey' | 'shiftKey' | 'altKey' | '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 0ef07e5131..317302267e 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,137 +1,125 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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, - VsAdapterType, -} 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; -const _configurationProviders: Map< - VsAdapterType, - DebuggerConfigurationProvider, -> = new Map(); - -export function setConsoleService(createConsole: ConsoleService): IDisposable { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +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; +exports.resolveDebugConfiguration = resolveDebugConfiguration; + +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; +const _configurationProviders = new Map(); + +function setConsoleService(createConsole) { _createConsole = createConsole; - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { _createConsole = null; }); } -export function getConsoleService(): ?ConsoleService { +function getConsoleService() { return _createConsole; } -export function setConsoleRegisterExecutor( - registerExecutor: RegisterExecutorFunction, -): IDisposable { +function setConsoleRegisterExecutor(registerExecutor) { _registerExecutor = registerExecutor; - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { _registerExecutor = null; }); } -export function getConsoleRegisterExecutor(): ?RegisterExecutorFunction { +function getConsoleRegisterExecutor() { return _registerExecutor; } -export function setDatatipService(datatipService: DatatipService): IDisposable { +function setDatatipService(datatipService) { _datatipService = datatipService; - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { _datatipService = null; }); } -export function getDatatipService(): ?DatatipService { +function getDatatipService() { return _datatipService; } -export function setNotificationService( - raiseNativeNotification: raiseNativeNotificationFunc, -): void { +function setNotificationService(raiseNativeNotification) { _raiseNativeNotification = raiseNativeNotification; } -export function getNotificationService(): ?raiseNativeNotificationFunc { +function getNotificationService() { return _raiseNativeNotification; } -export function setTerminalService(terminalService: TerminalApi): IDisposable { +function setTerminalService(terminalService) { _terminalService = terminalService; - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { _terminalService = null; }); } -export function getTerminalService(): ?TerminalApi { +function getTerminalService() { return _terminalService; } -export function setRpcService(rpcService: nuclide$RpcService): IDisposable { +function setRpcService(rpcService) { _rpcService = rpcService; - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { _rpcService = null; }); } -export function isNuclideEnvironment(): boolean { +function isNuclideEnvironment() { return _rpcService != null; } -export function addDebugConfigurationProvider( - provider: DebuggerConfigurationProvider, -): IDisposable { +function addDebugConfigurationProvider(provider) { const existingProvider = _configurationProviders.get(provider.adapterType); if (existingProvider != null) { - throw new Error( - 'Debug Configuration Provider already exists for adapter type: ' + - provider.adapterType, - ); + throw new Error('Debug Configuration Provider already exists for adapter type: ' + provider.adapterType); } _configurationProviders.set(provider.adapterType, provider); - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { _configurationProviders.delete(provider.adapterType); }); } -export async function resolveDebugConfiguration( - configuration: IProcessConfig, -): Promise { - const existingProvider = _configurationProviders.get( - configuration.adapterType, - ); - return existingProvider != null - ? existingProvider.resolveConfiguration(configuration) - : configuration; -} +async function resolveDebugConfiguration(configuration) { + const existingProvider = _configurationProviders.get(configuration.adapterType); + return existingProvider != null ? existingProvider.resolveConfiguration(configuration) : configuration; +} \ 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 1cb9550e4f..b1275dde57 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,26 +1,64 @@ +'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 }; } + /** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 + * Handles displaying breakpoints and processing events for a single text + * editor. */ -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'; /** * A single delegate which handles events from the object. @@ -29,49 +67,30 @@ import featureConfig from 'nuclide-commons-atom/feature-config'; * 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. + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 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, - ) { + +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 = []; this._markerInfo = new Map(); this._lastShadowBreakpointMarker = null; this._boundGlobalMouseMoveHandler = this._handleGlobalMouseLeave.bind(this); - this._boundCreateContextMenuHandler = this._handleCreateContextMenu.bind( - this, - ); + this._boundCreateContextMenuHandler = this._handleCreateContextMenu.bind(this); this._debugging = this._isDebugging(); // Configure the gutter. @@ -79,49 +98,28 @@ 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(), - ); + this._disposables.add(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, - ), - ); + editorElement.addEventListener('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' - ) { + if (gutter.name !== 'line-number' && gutter.name !== 'debugger-breakpoint') { return; } const boundClickHandler = this._handleGutterClick.bind(this); @@ -133,31 +131,11 @@ export default class BreakpointDisplayController { gutterView.addEventListener('mousemove', boundMouseMoveHandler); gutterView.addEventListener('mouseenter', boundMouseEnterHandler); gutterView.addEventListener('mouseleave', boundMouseLeaveHandler); - gutterView.addEventListener( - '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.addEventListener('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)); } - _handleCreateContextMenu(event: MouseEvent): void { + _handleCreateContextMenu(event) { if (event.button !== 2 || !this._isDebugging()) { return; } @@ -166,12 +144,10 @@ export default class BreakpointDisplayController { event.stopPropagation(); const menuTemplate = atom.contextMenu.templateForEvent(event); - const debuggerGroupIndex = menuTemplate.findIndex( - item => item.label === 'Debugger', - ); + const debuggerGroupIndex = menuTemplate.findIndex(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 +158,7 @@ export default class BreakpointDisplayController { } } - getEditor(): atom$TextEditor { + getEditor() { return this._editor; } @@ -199,7 +175,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) { @@ -211,29 +187,22 @@ export default class BreakpointDisplayController { return true; } - if ( - info.enabled !== bp.enabled || - info.resolved !== bp.verified || - info.conditional !== (bp.condition != null) - ) { + if (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 - ); + return (bp.endLine != null && !Number.isNaN(bp.endLine) ? bp.endLine : bp.line) - 1; } /** * Update the display with the current set of breakpoints for this editor. */ - _update(): void { + _update() { const gutter = this._gutter; if (gutter == null) { return; @@ -247,9 +216,7 @@ 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]), - ); + const lineMap = new Map(breakpoints.map(bp => [this._getLineForBp(bp), bp])); // A mutable unhandled lines map. const unhandledLines = new Set(lineMap.keys()); @@ -259,11 +226,7 @@ export default class BreakpointDisplayController { this._markers.forEach(marker => { const line = marker.getStartBufferPosition().row; const bp = lineMap.get(line); - if ( - debugging === this._debugging && - unhandledLines.has(line) && - !this._needsUpdate(line, bp) - ) { + if (debugging === this._debugging && unhandledLines.has(line) && !this._needsUpdate(line, bp)) { markersToKeep.push(marker); unhandledLines.delete(line); } else { @@ -288,18 +251,15 @@ export default class BreakpointDisplayController { // This line has been handled. continue; } - const marker = this._createBreakpointMarkerAtLine( - line, - false, // isShadow - breakpoint, - ); + const marker = this._createBreakpointMarkerAtLine(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); @@ -312,32 +272,26 @@ export default class BreakpointDisplayController { /** * Handler for marker movements due to text being edited. */ - _handleMarkerChange( - breakpoint: IBreakpoint, - event: atom$MarkerChangeEvent, - ): void { + _handleMarkerChange(breakpoint, event) { const path = this._editor.getPath(); if (path == null || path.length === 0) { return; } if (!event.isValid) { this._service.removeBreakpoints(breakpoint.getId()); - } else if ( - event.oldHeadBufferPosition.row !== event.newHeadBufferPosition.row - ) { + } else if (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; } @@ -350,13 +304,7 @@ 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') - ) { + 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')) { return; } @@ -364,19 +312,13 @@ export default class BreakpointDisplayController { const curLine = this._getCurrentMouseEventLine(event); this._service.toggleSourceBreakpoint(path, curLine + 1); - if ( - this._service.getModel().getBreakpointAtLine(path, curLine + 1) != null - ) { + if (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')) { - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'debugger:show', - { - showOnlyIfHidden: true, - }, - ); + if ((_featureConfig || _load_featureConfig()).default.get('atom-ide-debugger.showDebuggerOnBpSet')) { + atom.commands.dispatch(atom.views.getView(atom.workspace), 'debugger:show', { + showOnlyIfHidden: true + }); } } } catch (e) { @@ -384,13 +326,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 +347,7 @@ export default class BreakpointDisplayController { } } - _handleGutterMouseEnter(event: Event): void { + _handleGutterMouseEnter(event) { window.addEventListener('mousemove', this._boundGlobalMouseMoveHandler); } @@ -413,90 +355,70 @@ 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 - ) { + if (event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom) { this._removeLastShadowBreakpoint(); - window.removeEventListener( - 'mousemove', - this._boundGlobalMouseMoveHandler, - ); + window.removeEventListener('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 - ); + return shadowBreakpointMarker != null && shadowBreakpointMarker.getStartBufferPosition().row === curLine; } - _removeLastShadowBreakpoint(): void { + _removeLastShadowBreakpoint() { if (this._lastShadowBreakpointMarker != null) { this._lastShadowBreakpointMarker.destroy(); this._lastShadowBreakpointMarker = null; } } - _createShadowBreakpointAtLine(editor: TextEditor, line: number): void { - const breakpointsAtLine = this._markers.filter( - marker => marker.getStartBufferPosition().row === line, - ); + _createShadowBreakpointAtLine(editor, line) { + const breakpointsAtLine = this._markers.filter(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, - ); + this._lastShadowBreakpointMarker = this._createBreakpointMarkerAtLine(line, true, // isShadow + null); } } - _createBreakpointMarkerAtLine( - line: number, - isShadow: boolean, - breakpoint: ?IBreakpoint, - ): atom$Marker { + _createBreakpointMarkerAtLine(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) { @@ -513,8 +435,12 @@ export default class BreakpointDisplayController { } } - invariant(this._gutter != null); - this._gutter.decorateMarker(marker, {item: elem}); + if (!(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 1bfa4089cd..f7ffea04c0 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,34 +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 strict-local - * @format - */ - -import type {IDebugService} from './types'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import BreakpointDisplayController from './BreakpointDisplayController'; - -export default class BreakpointManager { - _service: IDebugService; - _displayControllers: Map; - _disposables: UniversalDisposable; - - constructor(service: IDebugService) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../../nuclide-commons/UniversalDisposable')); +} + +var _BreakpointDisplayController; + +function _load_BreakpointDisplayController() { + return _BreakpointDisplayController = _interopRequireDefault(require('./BreakpointDisplayController')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class BreakpointManager { + + constructor(service) { this._service = service; this._displayControllers = new Map(); - this._disposables = new UniversalDisposable( - atom.workspace.observeTextEditors(this._handleTextEditor.bind(this)), - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(atom.workspace.observeTextEditors(this._handleTextEditor.bind(this))); } - dispose(): void { + dispose() { this._disposables.dispose(); this._displayControllers.forEach(controller => controller.dispose()); this._displayControllers.clear(); @@ -37,26 +35,33 @@ export default class BreakpointManager { /** * Used for testing. */ - getDisplayControllers(): Map { + getDisplayControllers() { return this._displayControllers; } /** * Delegate callback from BreakpointDisplayController. */ - handleTextEditorDestroyed(controller: 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; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ \ 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 0e7c634f83..464a02596f 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,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 strict-local - * @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) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.debuggerDatatip = debuggerDatatip; + +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 }; } + +async function debuggerDatatip(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 = getDefaultEvaluationExpression(editor, position); + const evaluationExpression = (0, (_evaluationExpression || _load_evaluationExpression()).getDefaultEvaluationExpression)(editor, position); if (evaluationExpression == null) { return null; } - const {expression, range} = evaluationExpression; - const {focusedProcess, focusedStackFrame} = service.viewModel; + 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( - service.createExpression(expression), - focusedProcess, - focusedStackFrame, - 'hover', - ).map(evaluationResult => ({ + const propStream = (0, (_utils || _load_utils()).expressionAsEvaluationResultStream)(service.createExpression(expression), focusedProcess, focusedStackFrame, 'hover').map(evaluationResult => ({ expression, - evaluationResult, + evaluationResult })); return { - component: bindObservableAsProps(propStream, DebuggerDatatipComponent), - range, + component: (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)(propStream, (_DebuggerDatatipComponent || _load_DebuggerDatatipComponent()).default), + range }; -} +} /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ \ 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 f2e34d6150..838741179b 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,26 +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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.WORKSPACE_VIEW_URI = undefined; -import type { - DebuggerLaunchAttachProvider, - NuclideDebuggerProvider, -} from 'nuclide-debugger-common'; -import type {IDebugService} from './types'; +var _UniversalDisposable; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Emitter} from 'atom'; -import nuclideUri from 'nuclide-commons/nuclideUri'; +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../../nuclide-commons/UniversalDisposable')); +} + +var _atom = require('atom'); -export const WORKSPACE_VIEW_URI = 'atom://nuclide/debugger'; +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. + * + * strict-local + * @format + */ const CONNECTIONS_UPDATED_EVENT = 'CONNECTIONS_UPDATED_EVENT'; const PROVIDERS_UPDATED_EVENT = 'PROVIDERS_UPDATED_EVENT'; @@ -28,27 +39,21 @@ const PROVIDERS_UPDATED_EVENT = 'PROVIDERS_UPDATED_EVENT'; /** * Atom ViewProvider compatible model object. */ -export default class DebuggerModel { - _disposables: UniversalDisposable; - _service: IDebugService; - _emitter: Emitter; +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(); }); @@ -58,7 +63,7 @@ export default class DebuggerModel { * Utility for getting refreshed connections. * TODO: refresh connections when new directories are removed/added in file-tree. */ - _updateConnections(): void { + _updateConnections() { const connections = this._getRemoteConnections(); // Always have one single local connection. connections.push('local'); @@ -69,47 +74,43 @@ export default class DebuggerModel { /** * Get remote connections without duplication. */ - _getRemoteConnections(): Array { + _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 { + 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; } @@ -117,9 +118,7 @@ export default class DebuggerModel { * Return available launch/attach provider for input connection. * Caller is responsible for disposing the results. */ - getLaunchAttachProvidersForConnection( - connection: string, - ): Array { + getLaunchAttachProvidersForConnection(connection) { const availableLaunchAttachProviders = []; for (const provider of this._debuggerProviders) { const launchAttachProvider = provider.getLaunchAttachProvider(connection); @@ -130,3 +129,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 60ae76b808..616fd38adf 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,3 +1,31 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _vscodeDebugprotocol; + +function _load_vscodeDebugprotocol() { + return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol')); +} + +var _constants; + +function _load_constants() { + return _constants = require('./constants'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../../nuclide-commons/UniversalDisposable')); +} + +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. @@ -6,105 +34,75 @@ * LICENSE file in 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, IProcess} 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'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -export default class RemoteControlService { - _service: IDebugService; - _disposables: UniversalDisposable; +class RemoteControlService { - constructor(service: IDebugService) { + constructor(service) { this._service = service; - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - dispose(): void { + dispose() { this._disposables.dispose(); } - onSessionEnd( - focusedProcess: IProcess, - disposables: UniversalDisposable, - ): void { - disposables.add( - this._service.viewModel.onDidFocusProcess(() => { - if ( - !this._service - .getModel() - .getProcesses() - .includes(focusedProcess) - ) { - disposables.dispose(); - } - }), - ); + onSessionEnd(focusedProcess, disposables) { + disposables.add(this._service.viewModel.onDidFocusProcess(() => { + if (!this._service.getModel().getProcesses().includes(focusedProcess)) { + disposables.dispose(); + } + })); } - async startDebugging(processInfo: VspProcessInfo): Promise { - const instance = await this.startVspDebugging( - processInfo.getProcessConfig(), - ); + async startDebugging(processInfo) { + const instance = await this.startVspDebugging(processInfo.getProcessConfig()); processInfo.setVspDebuggerInstance(instance); - const {focusedProcess} = this._service.viewModel; - invariant(focusedProcess != null); - const disposables = new UniversalDisposable(); + const { focusedProcess } = this._service.viewModel; + + if (!(focusedProcess != null)) { + throw new Error('Invariant violation: "focusedProcess != null"'); + } + + const disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); disposables.add(processInfo); this.onSessionEnd(focusedProcess, disposables); } - async startVspDebugging(config: IProcessConfig): Promise { + async startVspDebugging(config) { await this._service.startDebugging(config); - const {viewModel} = this._service; - const {focusedProcess} = viewModel; - invariant(focusedProcess != null); + const { viewModel } = this._service; + const { focusedProcess } = viewModel; + + if (!(focusedProcess != null)) { + throw new Error('Invariant violation: "focusedProcess != null"'); + } - const isFocusedProcess = (): boolean => { - return ( - this._service.getDebuggerMode() !== DebuggerMode.STOPPED && - viewModel.focusedProcess === focusedProcess - ); + const isFocusedProcess = () => { + return this._service.getDebuggerMode() !== (_constants || _load_constants()).DebuggerMode.STOPPED && viewModel.focusedProcess === focusedProcess; }; - const customRequest = async ( - request: string, - args: any, - ): Promise => { + const customRequest = async (request, args) => { if (!isFocusedProcess()) { - throw new Error( - 'Cannot send custom requests to a no longer active debug session!', - ); + throw new Error('Cannot send custom requests to a no longer active debug session!'); } return focusedProcess.session.custom(request, args); }; - const observeCustomEvents = (): Observable => { + const observeCustomEvents = () => { if (!isFocusedProcess()) { - throw new Error( - 'Cannot send custom requests to a no longer active debug session!', - ); + throw new Error('Cannot send custom requests to a no longer active debug session!'); } return focusedProcess.session.observeCustomEvents(); }; - const disposables = new UniversalDisposable(); - const addCustomDisposable = (disposable: IDisposable): void => { + const disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + const addCustomDisposable = disposable => { disposables.add(disposable); }; @@ -113,7 +111,8 @@ export default class RemoteControlService { return Object.freeze({ customRequest, observeCustomEvents, - addCustomDisposable, + addCustomDisposable }); } } +exports.default = RemoteControlService; \ 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 f20a214f9b..af8967a003 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,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. - * - * @flow strict-local - * @format - */ +'use strict'; -import type {DebuggerModeType} from './types'; - -export const AnalyticsEvents = Object.freeze({ +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 +29,38 @@ 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', -}); + 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. + * + * strict-local + * @format + */ -export const DebuggerMode = Object.freeze({ +const DebuggerMode = exports.DebuggerMode = Object.freeze({ STARTING: 'starting', RUNNING: 'running', PAUSED: 'paused', STOPPED: 'stopped', - STOPPING: 'stopping', + 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 27eb7605a9..fba2ea27ff 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,15 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict - * @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. +'use strict'; -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. -*/ +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getDefaultEvaluationExpression = getDefaultEvaluationExpression; -import {Range} from 'atom'; +var _atom = require('atom'); -export function getDefaultEvaluationExpression( - editor: atom$TextEditor, - position: atom$Point, -): ?{ - expression: string, - range: atom$Range, -} { +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 +18,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,22 +34,15 @@ export function getDefaultEvaluationExpression( if (matchingExpression != null) { const subExpression = /\w+/g; let subExpressionResult; - while ((subExpressionResult = subExpression.exec(matchingExpression))) { - const subEnd = - subExpressionResult.index + - 1 + - startOffset + - subExpressionResult[0].length; + while (subExpressionResult = subExpression.exec(matchingExpression)) { + const subEnd = subExpressionResult.index + 1 + startOffset + subExpressionResult[0].length; if (subEnd >= position.column + 1) { break; } } if (subExpressionResult) { - matchingExpression = matchingExpression.substring( - 0, - subExpression.lastIndex, - ); + matchingExpression = matchingExpression.substring(0, subExpression.lastIndex); } } @@ -98,9 +52,44 @@ 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. + * + * strict + * @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 fe1da99997..dba337c05f 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 strict - * @format - */ +'use strict'; -import {getLogger} from 'log4js'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -const DEBUGGER_LOGGER_CATEGORY = 'atom-debugger'; -export default getLogger(DEBUGGER_LOGGER_CATEGORY); +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. + * + * strict + * @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 71c4913f3b..f3616cce7d 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,433 +1,407 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 type {GatekeeperService} from 'nuclide-commons-atom/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'; +'use strict'; + +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 }; } + +const DATATIP_PACKAGE_NAME = 'debugger-datatip'; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 { - _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); + + 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', - ); + const insertIndex = atom.menu.template.findIndex(item => item.role === 'window' || item.role === 'help'); if (insertIndex !== -1) { - const deuggerIndex = atom.menu.template.findIndex( - item => item.label === 'Debugger', - ); + const deuggerIndex = atom.menu.template.findIndex(item => item.label === 'Debugger'); const menuItem = atom.menu.template.splice(deuggerIndex, 1)[0]; - const newIndex = - insertIndex > deuggerIndex ? insertIndex - 1 : insertIndex; + const newIndex = 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._connectionProviders.delete(key); + 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()); + + 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(); } - for (const connection of addedConnections) { - this._setProvidersForConnection(connection); + 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(); } - }), - this._uiModel.onProvidersUpdated(() => { - const connections = this._uiModel.getConnections(); - for (const connection of connections) { - this._setProvidersForConnection(connection); + }, { + 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; } - }), - // 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(); - } - } + }], + '.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. // TODO(ericblue): have providers register their file extensions and filter correctly here. return true; } else { - return Boolean( - focusedProcess.session.capabilities.supportsConditionalBreakpoints, - ); + return Boolean(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, - ); + return Boolean(focusedProcess.session.capabilities.supportsTerminateThreadsRequest); } } - _setProvidersForConnection(connection: NuclideUri): void { - const key = nuclideUri.isRemote(connection) - ? nuclideUri.getHostname(connection) - : 'local'; - const availableProviders = this._uiModel.getLaunchAttachProvidersForConnection( - connection, - ); + _setProvidersForConnection(connection) { + const key = (_nuclideUri || _load_nuclideUri()).default.isRemote(connection) ? (_nuclideUri || _load_nuclideUri()).default.getHostname(connection) : 'local'; + const availableProviders = this._uiModel.getLaunchAttachProvidersForConnection(connection); this._connectionProviders.set(key, availableProviders); } - async _getSuggestions( - request: atom$AutocompleteRequest, - ): Promise> { + async _getSuggestions(request) { let text = request.editor.getText(); const lines = text.split('\n'); - const {row} = request.bufferPosition; + 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; + const { focusedStackFrame, focusedProcess } = this._service.viewModel; if (focusedProcess == null || focusedStackFrame == null) { return []; - } else if ( - !Boolean(focusedProcess.session.capabilities.supportsCompletionsRequest) - ) { + } else if (!Boolean(focusedProcess.session.capabilities.supportsCompletionsRequest)) { const scopes = await focusedStackFrame.getScopes(); - return scopes.map(scope => ({text: scope.name, type: 'variable'})); + return scopes.map(scope => ({ text: scope.name, type: 'variable' })); } else { - const completions = await focusedProcess.completions( - focusedStackFrame.frameId, - text, - request.bufferPosition, - 0, - ); + const completions = await 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, + type: item.type })); } } - serialize(): SerializedState { + serialize() { const model = this._service.getModel(); const state = { sourceBreakpoints: model.getBreakpoints(), @@ -435,7 +409,7 @@ 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; } @@ -444,79 +418,55 @@ class Activation { this._disposables.dispose(); } - consumeGatekeeperService(service: GatekeeperService): IDisposable { + consumeGatekeeperService(service) { return this._layoutManager.consumeGatekeeperService(service); } - _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(); } } @@ -530,36 +480,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); @@ -569,8 +519,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) { @@ -590,26 +540,23 @@ 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()) { @@ -618,129 +565,113 @@ 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 { + _renderConfigDialog(panel, dialogMode, dialogCloser) { if (this._selectedDebugConnection == null) { // If no connection is selected yet, default to the local connection. this._selectedDebugConnection = 'local'; } - 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)); + if (!(this._selectedDebugConnection != null)) { + throw new Error('Invariant violation: "this._selectedDebugConnection != null"'); + } + + 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 { - if ( - this._visibleLaunchAttachDialogMode != null && - this._visibleLaunchAttachDialogMode !== dialogMode - ) { + _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) { // 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, - className: 'debugger-config-dialog', + className: 'debugger-config-dialog' }); - 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(); - } - }), - ); + disposables.add(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, + dialogMode }); - ReactDOM.unmountComponentAtNode(hostEl); + _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); @@ -751,12 +682,10 @@ class Activation { if (!editor) { return; } - const selectedText = editor.getTextInBufferRange( - trimRange(editor, editor.getSelectedBufferRange()), - ); - const expr = wordAtPosition(editor, editor.getCursorBufferPosition()); + const selectedText = editor.getTextInBufferRange((0, (_range || _load_range()).trimRange)(editor, editor.getSelectedBufferRange())); + const expr = (0, (_range || _load_range()).wordAtPosition)(editor, editor.getCursorBufferPosition()); - const watchExpression = selectedText || (expr && expr.wordMatch[0]); + const watchExpression = selectedText || expr && expr.wordMatch[0]; if (watchExpression != null && watchExpression.length > 0) { this._service.addWatchExpression(watchExpression); } @@ -768,40 +697,35 @@ 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); - callstackText += `${i}\t${item.name}\t${path}:${item.range.start.row}${ - os.EOL - }`; + const path = (_nuclideUri || _load_nuclideUri()).default.basename(item.source.uri); + callstackText += `${i}\t${item.name}\t${path}:${item.range.start.row}${_os.default.EOL}`; }); atom.clipboard.write(callstackText.trim()); } } - 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; @@ -809,121 +733,100 @@ class Activation { } }; const boundUpdateSelectedColumn = updateSelectedConnection.bind(this); - const disposable = cwdApi.observeCwd(directory => - boundUpdateSelectedColumn(directory), - ); + const disposable = cwdApi.observeCwd(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); + consumeRegisterExecutor(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); + consumeDebuggerConfigurationProvider(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(() => { + toolBar.addButton((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); return disposable; } - consumeNotifications( - raiseNativeNotification: ( - title: string, - body: string, - timeout: number, - raiseIfAtomHasFocus: boolean, - ) => ?IDisposable, - ): void { - setNotificationService(raiseNativeNotification); + consumeNotifications(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 - ) { + if (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; } @@ -931,4 +834,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 91e5ec5115..5396c5b522 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,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. - * - * @flow - * @format - */ +'use strict'; -/** - * 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 +var _vscodeDebugprotocol; -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; +function _load_vscodeDebugprotocol() { + return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol')); } -export type SerializedState = { - sourceBreakpoints: ?Array, - functionBreakpoints: ?Array, - exceptionBreakpoints: ?Array, - watchExpressions: ?Array, - showDebugger: boolean, - workspaceDocksVisibility: Array, -}; +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 1fcd25a9c7..bdc3b7881d 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,99 +1,115 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict-local - * @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 _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 _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 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(); - }), - ); + 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(); + })); } - 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(); - } - }), - ); + this._disposables.add(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(); + async _updateBreakpoint() { + const { breakpoint, service } = this.props; + const condition = (0, (_nullthrows || _load_nullthrows()).default)(this._condition).getText().trim(); if (condition === (breakpoint.condition || '')) { this.props.onDismiss(); return; @@ -101,82 +117,113 @@ export default class BreakpointConfigComponent extends React.Component< await service.removeBreakpoints(breakpoint.getId()); - const bp: IRawBreakpoint = { + const bp = { line: breakpoint.line, column: breakpoint.column, - enabled: breakpoint.enabled, + enabled: breakpoint.enabled }; if (condition !== '') { bp.condition = condition; } await service.addBreakpoints(breakpoint.uri, [bp]); - track(AnalyticsEvents.DEBUGGER_BREAKPOINT_UPDATE_CONDITION, { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_BREAKPOINT_UPDATE_CONDITION, { path: breakpoint.uri, line: breakpoint.line, condition, - fileExtension: nuclideUri.extname(breakpoint.uri), + fileExtension: (_nuclideUri || _load_nuclideUri()).default.extname(breakpoint.uri) }); this.props.onDismiss(); } - render(): React.Node { - return ( - -
-

Edit breakpoint

-
- -
-
- { - track(AnalyticsEvents.DEBUGGER_BREAKPOINT_TOGGLE_ENABLED, { - enabled: isChecked, - }); - this.props.service.enableOrDisableBreakpoints( - isChecked, - this.props.breakpoint, - ); - }} - checked={this.props.breakpoint.enabled} - label="Enable breakpoint" - /> -
-
- { - this._condition = input; - }} - autofocus={true} - /> -
- -
- - - - -
-
-
+ render() { + return _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' + }) + ), + _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 + }) + ), + _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. + * + * strict-local + * @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 3536ce248d..c69063e24b 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,311 +1,311 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict-local - * @format - */ - -import type {IBreakpoint, IDebugService, IExceptionBreakpoint} from '../types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -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'; -import {Section} from 'nuclide-commons-ui/Section'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {observeProjectPathsAll} from 'nuclide-commons-atom/projects'; - -type Props = {| - service: IDebugService, -|}; - -type State = { - supportsConditionalBreakpoints: boolean, - breakpoints: IBreakpoint[], - exceptionBreakpoints: IExceptionBreakpoint[], - exceptionBreakpointsCollapsed: boolean, - activeProjects: NuclideUri[], -}; - -export default class BreakpointListComponent extends React.Component< - Props, - State, -> { - _disposables: UniversalDisposable; - - constructor(props: Props) { +'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'); +} + +var _Section; + +function _load_Section() { + return _Section = require('../../../../../nuclide-commons-ui/Section'); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../../../nuclide-commons-atom/feature-config')); +} + +var _projects; + +function _load_projects() { + return _projects = require('../../../../../nuclide-commons-atom/projects'); +} + +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._setExceptionCollapsed = collapsed => { + (_featureConfig || _load_featureConfig()).default.set('debugger-exceptionBreakpointsCollapsed', collapsed); + this.setState({ exceptionBreakpointsCollapsed: collapsed }); + }; + this.state = this._computeState(); - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - _computeState(): State { - const {service} = this.props; - const {focusedProcess} = service.viewModel; + _computeState() { + const { service } = this.props; + const { focusedProcess } = service.viewModel; const model = service.getModel(); - const exceptionBreakpointsCollapsed = Boolean( - featureConfig.get('debugger-exceptionBreakpointsCollapsed'), - ); + const exceptionBreakpointsCollapsed = Boolean((_featureConfig || _load_featureConfig()).default.get('debugger-exceptionBreakpointsCollapsed')); let newActiveProjects = []; if (this.state != null) { - const {activeProjects} = this.state; + const { activeProjects } = this.state; if (activeProjects != null) { newActiveProjects = activeProjects; } } return { - supportsConditionalBreakpoints: - focusedProcess != null && - Boolean( - focusedProcess.session.capabilities.supportsConditionalBreakpoints, - ), + supportsConditionalBreakpoints: focusedProcess != null && Boolean(focusedProcess.session.capabilities.supportsConditionalBreakpoints), breakpoints: model.getBreakpoints(), exceptionBreakpoints: model.getExceptionBreakpoints(), exceptionBreakpointsCollapsed, - activeProjects: newActiveProjects, + activeProjects: newActiveProjects }; } - componentDidMount(): void { + componentDidMount() { const model = this.props.service.getModel(); - this._disposables.add( - model.onDidChangeBreakpoints(() => { - this.setState(this._computeState()); - }), - observeProjectPathsAll(projectPaths => - this.setState({activeProjects: projectPaths}), - ), - ); + this._disposables.add(model.onDidChangeBreakpoints(() => { + this.setState(this._computeState()); + }), (0, (_projects || _load_projects()).observeProjectPathsAll)(projectPaths => this.setState({ activeProjects: projectPaths }))); } - componentWillUnmount(): void { + componentWillUnmount() { 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); - }; - - _setExceptionCollapsed = (collapsed: boolean): void => { - featureConfig.set('debugger-exceptionBreakpointsCollapsed', collapsed); - this.setState({exceptionBreakpointsCollapsed: collapsed}); - }; - - render(): React.Node { + render() { const { exceptionBreakpoints, supportsConditionalBreakpoints, - activeProjects, + activeProjects } = this.state; - const breakpoints = this.state.breakpoints.filter(breakpoint => - activeProjects.some(projectPath => - breakpoint.uri.startsWith(projectPath), - ), - ); - 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( - 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} - - ); - }); - const separator = - breakpoints.length !== 0 && - !this.state.exceptionBreakpointsCollapsed && - exceptionBreakpoints.length !== 0 ? ( -
+ const breakpoints = this.state.breakpoints.filter(breakpoint => activeProjects.some(projectPath => breakpoint.uri.startsWith(projectPath))); + 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; - return ( -
-
- {exceptionBreakpoints.map(exceptionBreakpoint => { - return ( -
- - service.enableOrDisableBreakpoints( - enabled, - exceptionBreakpoint, - ) - } - checked={exceptionBreakpoint.enabled} - /> - {exceptionBreakpoint.label || - `${exceptionBreakpoint.filter} exceptions`} -
- ); - })} -
- {separator} - - {items} - -
+ + 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: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 && !this.state.exceptionBreakpointsCollapsed && exceptionBreakpoints.length !== 0 ? _react.createElement('hr', { className: 'nuclide-ui-hr debugger-breakpoint-separator' }) : null; + return _react.createElement( + 'div', + null, + _react.createElement( + (_Section || _load_Section()).Section, + { + className: 'debugger-breakpoint-section', + headline: 'Exception breakpoints', + collapsable: true, + onChange: this._setExceptionCollapsed, + collapsed: this.state.exceptionBreakpointsCollapsed }, + exceptionBreakpoints.map(exceptionBreakpoint => { + return _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. + * + * strict-local + * @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 4ff6fd0891..f363c585a1 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,3 +1,27 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _classnames; + +function _load_classnames() { + return _classnames = _interopRequireDefault(require('classnames')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _BreakpointListComponent; + +function _load_BreakpointListComponent() { + return _BreakpointListComponent = _interopRequireDefault(require('./BreakpointListComponent')); +} + +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. @@ -6,34 +30,24 @@ * LICENSE file in 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 strict-local + * strict-local * @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 ( -
-
- -
-
+class BreakpointsView extends _react.PureComponent { + render() { + const { service } = this.props; + + return _react.createElement( + 'div', + { + className: (0, (_classnames || _load_classnames()).default)('debugger-container-new', '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 7a6c918d91..461cc06192 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,3 +1,83 @@ +'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 _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; } } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,196 +86,145 @@ * LICENSE file in 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 {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 nuclide-internal/prefer-nuclide-uri -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) { +class DebuggerCallstackComponent extends _react.Component { + + constructor(props) { super(props); - this._disposables = new UniversalDisposable(); + + this._handleStackFrameClick = (clickedRow, callFrameIndex) => { + this.props.service.focusStackFrame(clickedRow.frame, null, null, true); + }; + + 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, + selectedCallFrameId: focusedStackFrame == null ? -1 : focusedStackFrame.frameId, + isFechingStackFrames: false }; } - componentDidMount(): void { - const {service} = this.props; + componentDidMount() { + const { service } = this.props; const model = service.getModel(); - 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())), - ); + const { viewModel } = service; + this._disposables.add(_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; - 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'; - } - - return cellData; - }); - - const columns = [ - { - title: '', - key: 'frameId', - width: 0.05, - }, - { - title: 'Address', - key: 'address', - width: 0.95, - }, - ]; - - const emptyComponent = () => ( -
callstack unavailable
+ 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'; + } + + return cellData; + }); + + const columns = [{ + title: '', + key: 'frameId', + width: 0.05 + }, { + title: 'Address', + key: 'address', + width: 0.95 + }]; + + 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()} - - + return _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; - const totalFrames = - idx(viewModel, _ => _.focusedThread.stoppedDetails.totalFrames) || 0; + _renderLoadMoreStackFrames() { + var _ref, _ref2, _ref3; + + const { viewModel } = this.props.service; + const { callstack, isFechingStackFrames } = this.state; + const totalFrames = ((_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 ( -
- - { - if (!isNaN(value)) { - this.setState({callStackLevels: parseInt(value, 10)}); - } - }} - /> - - {isFechingStackFrames ? ( - - ) : 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) }); + } + } + }), + _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; +// eslint-disable-next-line nuclide-internal/prefer-nuclide-uri \ 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 22cade4c4f..4629239de7 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,3 +1,39 @@ +'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. @@ -6,54 +42,44 @@ * LICENSE file in 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 strict-local + * strict-local * @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; +class DebuggerControllerView extends _react.Component { - constructor(props: Props) { + constructor(props) { super(props); - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } componentDidMount() { - const {service} = this.props; - this._disposables.add( - observableFromSubscribeFunction( - service.onDidChangeMode.bind(service), - ).subscribe(mode => this.forceUpdate()), - ); + const { service } = this.props; + this._disposables.add((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) { - return ( -
-
- Starting Debugger... - -
-
+ render() { + if (this.props.service.getDebuggerMode() === (_constants || _load_constants()).DebuggerMode.STARTING) { + return _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 63f089dea2..8000e30938 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,158 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict-local - * @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. + * + * strict-local + * @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; - 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, - }), - ), - ); + componentDidMount() { + const { service } = this.props; + this._disposables.add((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; - 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} -
-
-
- ); - - const debugeeRunningNotice = - mode !== DebuggerMode.RUNNING ? null : ( -
-
- The debug target is currently running. -
-
- ); - - return ( -
-
- -
-
- -
- {debugeeRunningNotice} - {debuggerStoppedNotice} -
+ render() { + const { service } = this.props; + const { mode } = this.state; + const debuggerStoppedNotice = 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 !== (_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 _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 acc853eec1..f43382ec12 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,3 +1,39 @@ +'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. @@ -6,42 +42,34 @@ * LICENSE file in 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; +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 e70f258921..6ec6d852c9 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,150 +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 - */ -/* global localStorage */ +'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 _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../../../nuclide-commons/nuclideUri')); +} + +var _Button; + +function _load_Button() { + return _Button = require('../../../../../nuclide-commons-ui/Button'); +} -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, -}; +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 _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; } } // TODO those should be managed by the debugger store state -function setLastUsedDebugger( - host: string, - action: DebuggerConfigAction, - debuggerDisplayName: string, -): void { +function setLastUsedDebugger(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: string, - action: DebuggerConfigAction, -): ?string { +function getLastUsedDebugger(host, action) { 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; +class DebuggerLaunchAttachUI extends _react.Component { - constructor(props: Props) { + constructor(props) { super(props); - this._disposables = new UniversalDisposable(); - this._disposables.add( - atom.commands.add('atom-workspace', { - 'core:confirm': () => { - if (this.state.configIsValid) { - this._rememberTab(); + this._setConfigValid = valid => { + this.setState({ + configIsValid: valid + }); + }; - // 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._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._disposables.add(atom.commands.add('atom-workspace', { + 'core:confirm': () => { + if (this.state.configIsValid) { this._rememberTab(); - this.props.dialogCloser(); - }, - }), - ); + + // 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: [], + enabledProviders: [] }; } - _rememberTab(): void { + _rememberTab() { // 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'; + 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 || '', - ); + setLastUsedDebugger(host, this.props.dialogMode, this.state.selectedProviderTab || ''); } } componentWillMount() { - const host = nuclideUri.isRemote(this.props.connection) - ? nuclideUri.getHostname(this.props.connection) - : 'local'; + 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), + selectedProviderTab: getLastUsedDebugger(host, this.props.dialogMode) }); } - componentWillReceiveProps(nextProps: Props) { - const host = nuclideUri.isRemote(nextProps.connection) - ? nuclideUri.getHostname(nextProps.connection) - : 'local'; + 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), + selectedProviderTab: getLastUsedDebugger(host, nextProps.dialogMode) }); } @@ -152,81 +143,53 @@ export default class DebuggerLaunchAttachUI extends React.Component< this._disposables.dispose(); } - async _getProviderIfEnabled( - provider: DebuggerLaunchAttachProvider, - ): Promise { - const enabled = await provider - .getCallbacksForAction(this.props.dialogMode) - .isEnabled(); + async _getProviderIfEnabled(provider) { + const enabled = await provider.getCallbacksForAction(this.props.dialogMode).isEnabled(); return enabled ? provider : null; } - _filterProviders(key: string): void { + _filterProviders(key) { this.setState({ - enabledProviders: [], + enabledProviders: [] }); - Observable.merge( - ...(this.props.providers.get(key) || []).map(provider => - Observable.fromPromise(this._getProviderIfEnabled(provider)), - ), - ) - .filter(provider => provider != null) - .map(provider => { - invariant(provider != null); - return provider - .getCallbacksForAction(this.props.dialogMode) - .getDebuggerTypeNames() - .map(debuggerName => { - return { - provider, - debuggerName, - }; - }); - }) - .scan((arr, provider) => arr.concat(provider), []) - .subscribe(enabledProviders => { - this.setState({enabledProviders}); + _rxjsBundlesRxMinJs.Observable.merge(...(this.props.providers.get(key) || []).map(provider => _rxjsBundlesRxMinJs.Observable.fromPromise(this._getProviderIfEnabled(provider)))).filter(provider => provider != null).map(provider => { + if (!(provider != null)) { + throw new Error('Invariant violation: "provider != null"'); + } + + return provider.getCallbacksForAction(this.props.dialogMode).getDebuggerTypeNames().map(debuggerName => { + return { + provider, + debuggerName + }; }); + }).scan((arr, provider) => arr.concat(provider), []).subscribe(enabledProviders => { + 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)); + _getTabsFromEnabledProviders(enabledProviders) { + const tabs = this.state.enabledProviders.map(debuggerType => ({ + name: debuggerType.debuggerName, + tabContent: _react.createElement( + 'span', + { + title: debuggerType.debuggerName, + className: 'debugger-provider-tab' }, + debuggerType.debuggerName + ) + })).sort((a, b) => a.name.localeCompare(b.name)); return tabs; } - setState( - partialState: $Shape | ((State, Props) => $Shape | void), - callback?: () => mixed, - ): void { + setState(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, - ); + const tabs = this._getTabsFromEnabledProviders(fullState.enabledProviders); if (tabs.length > 0) { const firstTab = tabs[0]; fullState.selectedProviderTab = firstTab.name; @@ -236,100 +199,97 @@ 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; - let provider = this.state.enabledProviders.find( - p => p.debuggerName === selectedTab, - ); + let selectedTab = this.state.selectedProviderTab != null ? this.state.selectedProviderTab : this.state.enabledProviders[0].debuggerName; + let provider = this.state.enabledProviders.find(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, + growable: true, + 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} -
- - - - -
-
+ return _react.createElement( + 'div', + { className: 'padded debugger-launch-attach-container' }, + (0, (_AtomServiceContainer || _load_AtomServiceContainer()).isNuclideEnvironment)() ? _react.createElement( + 'h1', + { className: 'debugger-launch-attach-header' }, + _react.createElement( + 'span', + { className: 'padded' }, + this.props.dialogMode === 'attach' ? 'Attach debugger to ' : 'Launch debugger on ' + ), + _react.createElement((_Dropdown || _load_Dropdown()).Dropdown, { + className: 'inline', + options: this.props.connectionOptions, + onChange: value => this.props.connectionChanged(value), + size: 'xs', + value: this.props.connection + }) + ) : null, + providerContent, + _react.createElement( + 'div', + { className: 'debugger-launch-attach-actions' }, + _react.createElement( + (_ButtonGroup || _load_ButtonGroup()).ButtonGroup, + null, + _react.createElement( + (_Button || _load_Button()).Button, + { + onClick: () => atom.commands.dispatch(atom.views.getView(atom.workspace), 'core:cancel') }, + 'Cancel' + ), + _react.createElement( + (_Button || _load_Button()).Button, + { + buttonType: (_Button || _load_Button()).ButtonTypes.PRIMARY, + disabled: !this.state.configIsValid, + onClick: () => atom.commands.dispatch(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 3d904d314b..d5f162d16c 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,3 +1,102 @@ +'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 _MultiTargettedDebuggerView; + +function _load_MultiTargettedDebuggerView() { + return _MultiTargettedDebuggerView = _interopRequireDefault(require('./MultiTargettedDebuggerView')); +} + +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; } } + +const CONSOLE_VIEW_URI = 'atom://nuclide/console'; + +// Debugger views /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,99 +105,25 @@ * LICENSE file in 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 type {GatekeeperService} from 'nuclide-commons-atom/types'; +const DEBUGGER_URI_BASE = 'atom://nuclide/debugger-'; -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'; +// Configuration that defines a debugger pane. This controls what gets added +// to the workspace when starting debugging. -// Debugger views -import DebuggerControlsView from './DebuggerControlsView'; -import ThreadsView from './ThreadsView'; -import MultiTargettedDebuggingView from './MultiTargettedDebuggerView'; -import DebuggerCallstackComponent from './DebuggerCallstackComponent'; -import BreakpointsView from './BreakpointsView'; -import ScopesView from './ScopesView'; -import WatchView from './WatchView'; -const CONSOLE_VIEW_URI = 'atom://nuclide/console'; -const DEBUGGER_URI_BASE = 'atom://nuclide/debugger-'; +let _gkService; -export type DebuggerPaneLocation = { - dock: string, - layoutIndex: number, - userHidden: boolean, - userCustomized?: boolean, -}; +class DebuggerLayoutManager { -// 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, - - // Previous default location, used to track if the saved location was not - // explicitly chosen by the user. - previousDefaultLocation?: string, - - // Optional callback to be invoked when the pane is being resized (flex scale changed). - onPaneResize?: (pane: atom$Pane, newFlexScale: number) => boolean, -}; - -let _gkService: ?GatekeeperService; - -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(); + 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; @@ -116,60 +141,41 @@ 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), - }), - ); - - 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; - }, - }, - ], - }, - ], - }), - ); + this._disposables.add(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; + } + }] + }] + })); }); } - _overridePaneInitialHeight( - dockPane: atom$Pane, - newFlexScale: number, - desiredHeight: number, - ): void { - invariant(dockPane.element != null); + _overridePaneInitialHeight(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. @@ -191,108 +197,82 @@ export default class DebuggerLayoutManager { } } - _initializeDebuggerPanes(): void { + _initializeDebuggerPanes() { const getFocusedProcess = () => this._service.viewModel.focusedProcess; // This configures the debugger panes. By default, they'll appear below the stepping // 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: DEBUGGER_URI_BASE + 'controls', - isLifetimeView: true, - title: () => 'Debugger', - defaultLocation: DEBUGGER_PANELS_DEFAULT_LOCATION, - isEnabled: () => true, - createView: () => , - onPaneResize: (dockPane, newFlexScale) => { - // If the debugger is stopped, let the controls pane keep its default - // layout to make room for the buttons and additional content. Otherwise, - // override the layout to shrink the pane and remove extra vertical whitespace. - const debuggerMode = this._service.getDebuggerMode(); - if (debuggerMode !== DebuggerMode.STOPPED) { - this._overridePaneInitialHeight(dockPane, newFlexScale, 100); - } + this._debuggerPanes = [{ + uri: DEBUGGER_URI_BASE + '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 the debugger is stopped, let the controls pane keep its default + // layout to make room for the buttons and additional content. Otherwise, + // override the layout to shrink the pane and remove extra vertical whitespace. + const debuggerMode = this._service.getDebuggerMode(); + if (debuggerMode !== (_constants || _load_constants()).DebuggerMode.STOPPED) { + this._overridePaneInitialHeight(dockPane, newFlexScale, 100); + } - // 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: DEBUGGER_URI_BASE + 'callstack', - isLifetimeView: false, - defaultLocation: DEBUGGER_PANELS_DEFAULT_LOCATION, - title: () => 'Call Stack', - isEnabled: () => true, - createView: () => ( - - ), - debuggerModeFilter: (mode: DebuggerModeType) => - mode !== DebuggerMode.STOPPED, - }, - { - uri: DEBUGGER_URI_BASE + 'breakpoints', - isLifetimeView: false, - defaultLocation: DEBUGGER_PANELS_DEFAULT_LOCATION, - title: () => 'Breakpoints', - isEnabled: () => true, - createView: () => , - }, - { - uri: DEBUGGER_URI_BASE + 'scopes', - isLifetimeView: false, - defaultLocation: DEBUGGER_PANELS_DEFAULT_LOCATION, - title: () => 'Scopes', - isEnabled: () => true, - createView: () => , - debuggerModeFilter: (mode: DebuggerModeType) => - mode !== DebuggerMode.STOPPED, - }, - { - uri: DEBUGGER_URI_BASE + 'watch-expressions', - isLifetimeView: false, - defaultLocation: 'bottom', - previousDefaultLocation: DEBUGGER_PANELS_DEFAULT_LOCATION, - title: () => 'Watch Expressions', - isEnabled: () => true, - createView: () => , - }, - { - uri: DEBUGGER_URI_BASE + '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, - }, - ]; + // 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: DEBUGGER_URI_BASE + '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: DEBUGGER_URI_BASE + '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: DEBUGGER_URI_BASE + '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: DEBUGGER_URI_BASE + 'watch-expressions', + isLifetimeView: false, + defaultLocation: 'bottom', + previousDefaultLocation: (_constants || _load_constants()).DEBUGGER_PANELS_DEFAULT_LOCATION, + title: () => 'Watch Expressions', + isEnabled: () => true, + createView: () => _react.createElement((_WatchView || _load_WatchView()).default, { service: this._service }) + }, { + uri: DEBUGGER_URI_BASE + '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 - ) { + if (dock.dock.isVisible != null && state.workspaceDocksVisibility != null && !state.workspaceDocksVisibility[index] && dock.dock.isVisible() && dock.dock.hide != null) { dock.dock.hide(); } }); @@ -303,22 +283,14 @@ export default class DebuggerLayoutManager { } } - _updateDebuggerVisibility(): void { + _updateDebuggerVisibility() { this._debuggerVisible = false; // See if any visible docks contain a pane that contains a debugger pane. this._getWorkspaceDocks().forEach(dock => { 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 - ) { + if (pane.getItems().find(item => item instanceof (_DebuggerPaneViewModel || _load_DebuggerPaneViewModel()).default || item instanceof (_DebuggerPaneContainerViewModel || _load_DebuggerPaneContainerViewModel()).default) != null) { this._debuggerVisible = true; } }); @@ -326,7 +298,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; @@ -335,56 +307,62 @@ 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, - }> { + _getWorkspaceDocks() { const docks = new Array(4); - invariant(atom.workspace.getLeftDock != null); + 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' }; - invariant(atom.workspace.getBottomDock != null); + if (!(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' }; - invariant(atom.workspace.getCenter != null); + if (!(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' }; - invariant(atom.workspace.getRightDock != null); + if (!(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; } - consumeGatekeeperService(service: GatekeeperService): IDisposable { + consumeGatekeeperService(service) { _gkService = service; if (_gkService != null) { _gkService.passesGK('nuclide_multitarget_debugging').then(passes => { @@ -392,10 +370,10 @@ export default class DebuggerLayoutManager { this._debuggerPanes.splice(1, 0, { uri: DEBUGGER_URI_BASE + 'multitargetteddebugging', isLifetimeView: false, - defaultLocation: DEBUGGER_PANELS_DEFAULT_LOCATION, + defaultLocation: (_constants || _load_constants()).DEBUGGER_PANELS_DEFAULT_LOCATION, title: () => 'Multi targetted debugging', isEnabled: () => true, - createView: () => , + createView: () => _react.createElement((_MultiTargettedDebuggerView || _load_MultiTargettedDebuggerView()).default, null) }); if (this._debuggerVisible) { this.showDebuggerViews(); @@ -403,29 +381,24 @@ export default class DebuggerLayoutManager { } }); } - return new UniversalDisposable(() => (_gkService = null)); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => _gkService = null); } - _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 // with no items is left open, Atom implicitly adds a single pane with no items // 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) - ); + return panes.length === 0 || panes.length === 1 && panes[0].getItems().length === 0; } - _appendItemToDock( - paneConfig: ?DebuggerPaneConfig, - dock: atom$AbstractPaneContainer, - item: Object, - debuggerItemsPerDock: Map, - ): void { + _appendItemToDock(paneConfig, dock, item, debuggerItemsPerDock) { const panes = dock.getPanes(); - invariant(panes.length >= 1); + + if (!(panes.length >= 1)) { + throw new Error('Invariant violation: "panes.length >= 1"'); + } const dockPane = panes[panes.length - 1]; if (this._isDockEmpty(dock)) { @@ -435,7 +408,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') { @@ -458,7 +431,7 @@ export default class DebuggerLayoutManager { dockPane.activateItem(item); } else { dockPane.splitDown({ - items: [item], + items: [item] }); } } @@ -481,21 +454,22 @@ 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(); - } - }), - ); + disposables.add(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); @@ -508,7 +482,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); } @@ -520,19 +494,14 @@ 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 - ) { + if (obj != null && obj.dock != null && obj.layoutIndex != null && obj.userHidden != null) { return obj; } } catch (e) {} @@ -540,41 +509,37 @@ 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), - ); + const savedItem = localStorage.getItem(this._getPaneStorageKey(debuggerPane.uri)); if (savedItem != null) { - debuggerPane.previousLocation = this._deserializeSavedLocation( - savedItem, - ); + debuggerPane.previousLocation = this._deserializeSavedLocation(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; @@ -602,14 +567,7 @@ export default class DebuggerLayoutManager { // If the location is the pane's default location, no need to store // it explicitly. This is also helpful if the default changes in the // future. - if ( - debuggerPane.previousLocation != null && - !debuggerPane.previousLocation.userHidden && - (debuggerPane.previousLocation.dock === debuggerPane.defaultLocation || - (debuggerPane.previousLocation.dock === - debuggerPane.previousDefaultLocation && - !debuggerPane.previousLocation.userCustomized)) - ) { + if (debuggerPane.previousLocation != null && !debuggerPane.previousLocation.userHidden && (debuggerPane.previousLocation.dock === debuggerPane.defaultLocation || debuggerPane.previousLocation.dock === debuggerPane.previousDefaultLocation && !debuggerPane.previousLocation.userCustomized)) { localStorage.removeItem(key); } else { if (debuggerPane.previousLocation != null) { @@ -621,13 +579,10 @@ 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) - ) { + if (config.debuggerModeFilter != null && !config.debuggerModeFilter(mode)) { item.setRemovedFromLayout(true); return true; } @@ -635,23 +590,18 @@ 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 - ) { + if (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), - ); + item.destroyWhere(innerItem => this._shouldDestroyPaneItem(mode, innerItem)); this._destroyContainerIfEmpty(item); return false; @@ -664,40 +614,24 @@ 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) { @@ -710,45 +644,42 @@ 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); + const defaultDock = this._getWorkspaceDocks().find(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); + + 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, - ); + this._leftPaneContainerModel = this._addPaneContainerToWorkspace(leftPaneContainer, leftDock.dock, addedItemsByDock, size); } const rightDock = this._getWorkspaceDocks().find(d => d.name === 'right'); - invariant(rightDock != null); + + 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, - ); + this._rightPaneContainerModel = this._addPaneContainerToWorkspace(rightPaneContainer, rightDock.dock, addedItemsByDock, size); } // Lay out the remaining debugger panes according to their configurations. @@ -756,96 +687,62 @@ 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; // Re-focus the console pane after layout so that it remains visible // even if we added debugger panes to the console's dock. // eslint-disable-next-line nuclide-internal/atom-apis - atom.workspace.open(CONSOLE_VIEW_URI, {searchAllPanes: true}); + atom.workspace.open(CONSOLE_VIEW_URI, { searchAllPanes: true }); } - _addPaneContainerToWorkspace( - container: atom$PaneContainer, - dock: atom$AbstractPaneContainer, - addedItemsByDock: Map, - dockSize: ?number, - ): DebuggerPaneContainerViewModel { - const containerModel = new DebuggerPaneContainerViewModel( - container, - dockSize, - ); + _addPaneContainerToWorkspace(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(); } @@ -857,23 +754,26 @@ 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); + + 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); + if (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 @@ -881,9 +781,7 @@ export default class DebuggerLayoutManager { if (!this._paneHiddenWarningShown) { this._paneHiddenWarningShown = true; - atom.notifications.addInfo( - `${config.title()} has been hidden. Right click any Debugger pane to bring it back.`, - ); + atom.notifications.addInfo(`${config.title()} has been hidden. Right click any Debugger pane to bring it back.`); } } } @@ -893,7 +791,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) { @@ -903,7 +801,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 @@ -914,10 +812,7 @@ export default class DebuggerLayoutManager { // Find and destroy all debugger items, and the panes that contained them. atom.workspace.getPanes().forEach(pane => { pane.getItems().forEach(item => { - if ( - item instanceof DebuggerPaneViewModel || - item instanceof DebuggerPaneContainerViewModel - ) { + if (item instanceof (_DebuggerPaneViewModel || _load_DebuggerPaneViewModel()).default || item instanceof (_DebuggerPaneContainerViewModel || _load_DebuggerPaneContainerViewModel()).default) { // Remove the view model. item.setRemovedFromLayout(true); pane.destroyItem(item); @@ -932,25 +827,31 @@ 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); + + 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); + + if (!(this._rightPaneContainerModel != null)) { + throw new Error('Invariant violation: "this._rightPaneContainerModel != null"'); + } + this._rightPaneContainerModel.dispose(); this._rightPaneContainerModel = null; } @@ -958,14 +859,15 @@ 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; \ 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 8ef730200d..d944807c76 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,3 +1,45 @@ +'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. @@ -6,32 +48,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 */ -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; +class DebuggerPaneContainerViewModel { - constructor(paneContainer: atom$PaneContainer, preferredWidth: ?number) { - this._disposables = new UniversalDisposable(); + constructor(paneContainer, preferredWidth) { + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._paneEvents = new Map(); this._removedFromLayout = false; this._container = paneContainer; @@ -42,70 +68,60 @@ export default class DebuggerPaneContainerViewModel { this._addManagedPane(pane); } - 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._disposables.add(() => { + this._forEachChildPaneItem(item => { + if (!(item instanceof (_DebuggerPaneViewModel || _load_DebuggerPaneViewModel()).default || item instanceof DebuggerPaneContainerViewModel)) { + throw new Error('Invariant violation: "item instanceof DebuggerPaneViewModel ||\\n item instanceof DebuggerPaneContainerViewModel"'); } - 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.setRemovedFromLayout(this._removedFromLayout); + item.destroy(); + }); + this._container.destroy(); + }, paneContainer.onDidAddPane(event => { + const pane = event.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); - } + 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); - }), - ); + disposables.add(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 +135,22 @@ 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(); - pendingAddTabDisposable.add( - pane.onDidAddItem(event => { - if (this._conditionallyAddTabBarToPane(pane)) { - this._disposables.remove(pendingAddTabDisposable); - pendingAddTabDisposable.dispose(); - } - }), - ); + _deferredAddTabBarToEmptyPane(pane) { + const pendingAddTabDisposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + pendingAddTabDisposable.add(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 +164,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) { @@ -159,10 +173,7 @@ export default class DebuggerPaneContainerViewModel { // the debugger layout. // TODO: Better solution here. process.nextTick(() => { - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'debugger:show', - ); + atom.commands.dispatch(atom.views.getView(atom.workspace), 'debugger:show'); }); } else { // This is another debugger pane container, which contains other debugger @@ -184,38 +195,45 @@ 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 { + _moveItemToParentPane(item, pane) { const parentPane = this.getParentPane(); - invariant(parentPane != null); + + 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); - pane.moveItemToPane( - item, - parentPane, - parentPane.getItems().indexOf(this) + 1, - ); + if (!(parentPane != null)) { + throw new Error('Invariant violation: "parentPane != null"'); + } + + pane.moveItemToPane(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); + 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,24 +244,22 @@ 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); // moveItemBetweenPanes conflicts with the parent tab's moveItemBetweenPanes. // Empty it out to get the correct behavior. tabBarView.moveItemBetweenPanes = () => {}; - tabBarView.element.classList.add( - 'nuclide-workspace-views-panel-location-tabs', - ); + tabBarView.element.classList.add('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 +269,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 +282,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 +290,42 @@ 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 { + _forEachChildPaneItem(callback) { for (const pane of this._container.getPanes()) { pane.getItems().forEach(item => { callback(item, pane); @@ -321,7 +333,7 @@ export default class DebuggerPaneContainerViewModel { } } - getAllItems(): Array { + getAllItems() { const items = []; this._forEachChildPaneItem(item => { items.push(item); @@ -330,11 +342,12 @@ 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 e40184efd9..a3a3aa5635 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,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 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; - - constructor( - config: DebuggerPaneConfig, - isLifetimeView: boolean, - paneDestroyed: (pane: DebuggerPaneConfig) => void, - preferredWidth: ?number, - ) { +class DebuggerPaneViewModel { + + constructor(config, isLifetimeView, paneDestroyed, preferredWidth) { this._config = config; this._isLifetimeView = isLifetimeView; this._paneDestroyed = paneDestroyed; @@ -42,57 +29,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 fb00826bfa..e4c35db009 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,158 +1,185 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 = ( - - - - + 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 = ( - - - - +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 = ( - - - - +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: { - onClick: () => mixed, - tooltip: atom$TooltipsAddOptions, - icon: React.Element, - disabled: boolean, -}): React.Element { - return ( - +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; +class DebuggerSteppingComponent extends _react.Component { - constructor(props: DebuggerSteppingComponentProps) { + constructor(props) { super(props); - this._disposables = new UniversalDisposable(); - const {service} = 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: [], + customControlButtons: [] }; } - componentDidMount(): void { - const {service} = this.props; + componentDidMount() { + 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); - } - }), - ); + 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(): void { + componentWillUnmount() { this._disposables.dispose(); } - _setWaitingForPause(waiting: boolean): void { + _setWaitingForPause(waiting) { this.setState({ - waitingForPause: waiting, + waitingForPause: waiting }); } - _getPausableThread(): ?IThread { - const {focusedThread, focusedProcess} = this.props.service.viewModel; + _getPausableThread() { + const { focusedThread, focusedProcess } = this.props.service.viewModel; if (focusedThread != null) { return focusedThread; } else if (focusedProcess != null) { @@ -162,77 +189,42 @@ export default class DebuggerSteppingComponent extends React.Component< } } - _togglePauseState = () => { - const pausableThread = this._getPausableThread(); - if (pausableThread == null) { - logger.error('No thread to pause/resume'); - return; - } + 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' + }); - 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 : _react.createElement((_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinner, { + className: 'debugger-stepping-playpause-button-loading', + size: (_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinnerSizes.EXTRA_SMALL + }); - const loadingIndicator = !isPausing ? null : ( - - ); + const restartDebuggerButton = debuggerMode !== (_constants || _load_constants()).DebuggerMode.STOPPED ? _react.createElement((_Button || _load_Button()).Button, { + icon: 'sync', + className: 'debugger-stepping-button-separated', + disabled: isStopped, + tooltip: Object.assign({}, defaultTooltipOptions, { + title: 'Restart the debugger using the same settings as the current debug session', + keyBindingCommand: 'debugger:restart-debugging' + }), + onClick: () => service.restartProcess() + }) : 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 => { - this._threadTable = table; - }} - /> - ); + return _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/MultiTargettedDebuggerView.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/MultiTargettedDebuggerView.js index ff204252bf..83cf0306dc 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/MultiTargettedDebuggerView.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/MultiTargettedDebuggerView.js @@ -1,23 +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 strict-local - * @format - */ +'use strict'; -import * as React from 'react'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -type Props = {}; +var _react = _interopRequireWildcard(require('react')); -export default class MultiTargettedDebuggingView extends React.PureComponent< - Props, -> { - render(): React.Node { +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 MultiTargettedDebuggingView extends _react.PureComponent { + render() { return 'Hello World'; } } +exports.default = MultiTargettedDebuggingView; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ \ 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 3b0de3b6c4..b3d97f37ad 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,174 +1,180 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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) -
-); +'use strict'; -const LOADING = ( -
- - - -
-); +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _bindObservableAsProps; + +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 + */ -type State = {| - scopes: Expected>, - expandedScopes: Set, -|}; +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' }) + ) +); -export default class ScopesComponent extends React.Component { - _disposables: UniversalDisposable; - _expansionStates: Map< - string /* expression */, - Object /* unique reference for expression */, - >; +class ScopesComponent extends _react.Component { - constructor(props: Props) { + 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: Expect.value([]), + scopes: (_expected || _load_expected()).Expect.value([]), // UX: Local scope names should be expanded by default. - expandedScopes: new Set(['Local', 'Locals']), + expandedScopes: new Set(['Local', 'Locals']) }; this._expansionStates = new Map(); - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - componentDidMount(): void { - const {viewModel} = this.props.service; - this._disposables.add( - Observable.merge( - observableFromSubscribeFunction( - viewModel.onDidFocusStackFrame.bind(viewModel), - ), - observableFromSubscribeFunction( - viewModel.onDidChangeExpressionContext.bind(viewModel), - ), - ) - .debounceTime(100) - .startWith(null) - .switchMap(() => this._getScopes()) - .subscribe(scopes => { - this.setState({scopes}); - }), - ); + 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).startWith(null).switchMap(() => this._getScopes()).subscribe(scopes => { + this.setState({ scopes }); + })); } - _getScopes(): Observable>> { - const {focusedStackFrame} = this.props.service.viewModel; + _getScopes() { + const { focusedStackFrame } = this.props.service.viewModel; if (focusedStackFrame == null) { - return Observable.of(Expect.value([])); + return _rxjsBundlesRxMinJs.Observable.of((_expected || _load_expected()).Expect.value([])); } else { - return Observable.of(Expect.pendingValue([])).concat( - Observable.fromPromise( - focusedStackFrame - .getScopes() - .then(scopes => Expect.value(scopes), error => Expect.error(error)), - ), - ); + 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(): void { + componentWillUnmount() { this._disposables.dispose(); } - _renderScopeSection(scope: IScope): ?React.Element { + _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; + 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, - ); + ScopeBodyComponent = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)(this._getScopeVariables(scope).map(variables => ({ + variables, + canSetVariables, + getExpansionStateIdForExpression: this._getExpansionStateIdForExpression + })), ScopeComponent); } - return ( -
this._setScopeExpanded(scope, !isCollapsed)} - headline={scope.name} - size="small"> - -
+ 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) ); } - _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), - ), - ), - ); + _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; } @@ -178,39 +184,69 @@ 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), - ); - return ( -
{scopeSections}
+ const scopeSections = scopes.value.map(scope => this._renderScopeSection(scope)); + return _react.createElement( + 'div', + { className: 'debugger-expression-value-list' }, + scopeSections ); } } -type ScopeProps = { - variables: Expected>, - canSetVariables: boolean, - getExpansionStateIdForExpression: (name: string) => Object, -}; +exports.default = ScopesComponent; + + +class ScopeComponent extends _react.Component { + constructor(...args) { + var _temp; + + return _temp = super(...args), this._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; + } + + if (!(newValue != null)) { + throw new Error('Invariant violation: "newValue != null"'); + } + + variable.setVariable(newValue).then(() => this.forceUpdate()); + }, _temp; + } -class ScopeComponent extends React.Component { render() { - const {variables} = this.props; + const { variables } = this.props; if (variables.isError) { - return ( -
Error fetching scope variables {variables.error.toString()}
+ return _react.createElement( + 'div', + null, + 'Error fetching scope variables ', + variables.error.toString() ); } else if (variables.isPending) { return LOADING; @@ -221,42 +257,24 @@ class ScopeComponent extends React.Component { } } - _setVariable = (expression: ?string, newValue: ?string): void => { - 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()); - }; - - _renderVariable(expression: IVariable): ?React.Element { - return ( -
-
- -
-
+ _renderVariable(expression) { + return _react.createElement( + 'div', + { + className: 'debugger-expression-value-row debugger-scope native-key-bindings', + 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 0bd45007cb..9629b34be9 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,88 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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; - this._disposables.add( - observableFromSubscribeFunction( - service.onDidChangeMode.bind(service), - ).subscribe(mode => this.setState({mode})), - ); + componentDidMount() { + const { service } = this.props; + this._disposables.add((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; - const disabledClass = - mode !== DebuggerMode.RUNNING ? '' : ' debugger-container-new-disabled'; - - return ( -
-
- -
-
+ render() { + const { service } = this.props; + const { mode } = this.state; + const disabledClass = 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 b934c5ba7e..72fb89dbd0 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,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 strict-local - * @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; - this._disposables.add( - observableFromSubscribeFunction( - service.onDidChangeMode.bind(service), - ).subscribe(mode => this.setState({mode})), - ); + componentDidMount() { + const { service } = this.props; + this._disposables.add((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; - const disabledClass = - mode !== DebuggerMode.RUNNING ? '' : ' debugger-container-new-disabled'; - - return ( -
-
- -
-
+ render() { + const { service } = this.props; + const { mode } = this.state; + const disabledClass = 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. + * + * strict-local + * @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 9de17530c4..9b2a0c9d48 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,65 +1,150 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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) { +'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 = (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, + rowBeingEdited: null }; } - _getExpansionStateIdForExpression(expression: string): Object { + _getExpansionStateIdForExpression(expression) { let expansionStateId = this._expansionStates.get(expression); if (expansionStateId == null) { expansionStateId = {}; @@ -68,143 +153,60 @@ export default class WatchExpressionComponent extends React.Component< return expansionStateId; } - removeExpression(id: string, event: MouseEvent): void { + removeExpression(id, event) { event.stopPropagation(); this.props.onRemoveWatchExpression(id); } - addExpression(expression: string): void { + addExpression(expression) { 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(); + _onConfirmExpressionEdit(id) { + const text = (0, (_nullthrows || _load_nullthrows()).default)(this._editExpressionEditor).getText(); this.props.onUpdateWatchExpression(id, text); this._resetExpressionEditState(); } - _setRowBeingEdited(id: string): void { + _setRowBeingEdited(id) { this.setState({ - rowBeingEdited: id, + rowBeingEdited: id }); if (this.coreCancelDisposable) { this.coreCancelDisposable.dispose(); } this.coreCancelDisposable = atom.commands.add('atom-workspace', { - 'core:cancel': () => this._resetExpressionEditState(), + '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( - watchExpression, - focusedProcess, - focusedStackFrame, - 'watch', - ); - } - const ValueComponent = bindObservableAsProps( - evalResult.map(evaluationResult => ({evaluationResult})), - LazyNestedValueComponent, - ); - return ( -
-
- -
-
- - -
-
- ); - }; - - render(): React.Node { + render() { const expressions = this.props.watchExpressions.map(this._renderExpression); - const addNewExpressionInput = ( - { - this._newExpressionEditor = input; - }} - size="sm" - placeholderText="Add new watch expression" - /> - ); - return ( -
- {expressions} - {addNewExpressionInput} -
+ 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 _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 c0c90fc2f5..b33b13ed43 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,3 +1,47 @@ +'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. @@ -6,81 +50,45 @@ * LICENSE file in 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; +class WatchView extends _react.PureComponent { - constructor(props: Props) { + 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; - - return ( -
-
- -
-
+ 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 0153524ff7..67ee950639 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,3 +1,34 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.openSourceLocation = openSourceLocation; +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. @@ -6,25 +37,11 @@ * LICENSE file in 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 { +function getGutterLineNumber(target) { const eventLine = parseInt(target.dataset.line, 10); if (eventLine != null && eventLine >= 0 && !isNaN(Number(eventLine))) { return eventLine; @@ -33,10 +50,7 @@ function getGutterLineNumber(target: HTMLElement): ?number { const SCREEN_ROW_ATTRIBUTE_NAME = 'data-screen-row'; -function getEditorLineNumber( - editor: atom$TextEditor, - target: HTMLElement, -): ?number { +function getEditorLineNumber(editor, target) { let node = target; while (node != null) { if (node.hasAttribute(SCREEN_ROW_ATTRIBUTE_NAME)) { @@ -51,14 +65,11 @@ function getEditorLineNumber( } } -export async function openSourceLocation( - path: string, - line: number, -): Promise { +async function openSourceLocation(path, line) { // eslint-disable-next-line nuclide-internal/atom-apis const editor = await atom.workspace.open(path, { searchAllPanes: true, - pending: true, + pending: true }); if (editor == null) { // Failed to open file. Return an empty text editor. @@ -69,49 +80,41 @@ export async function openSourceLocation( editor.setCursorBufferPosition([line, 0]); // Put the focus back in the console prompt. - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'atom-ide-console:focus-console-prompt', - ); + atom.commands.dispatch(atom.views.getView(atom.workspace), 'atom-ide-console:focus-console-prompt'); return editor; } function firstNonNull(...args) { - return nullthrows(args.find(arg => arg != null)); + return (0, (_nullthrows || _load_nullthrows()).default)(args.find(arg => arg != null)); } -export function getLineForEvent(editor: atom$TextEditor, event: any): number { +function getLineForEvent(editor, event) { const cursorLine = editor.getLastCursor().getBufferRow(); - const target = event ? (event.target: HTMLElement) : null; + 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, - ); + return firstNonNull(getGutterLineNumber(target), getEditorLineNumber(editor, target), + // fall back to the line the cursor is on. + cursorLine); } -export function isLocalScopeName(scopeName: string): boolean { +function isLocalScopeName(scopeName) { return ['Local', 'Locals'].indexOf(scopeName) !== -1; } -export function expressionAsEvaluationResult( - expression: IExpression, -): EvaluationResult { +function expressionAsEvaluationResult(expression) { const value = expression.getValue(); if (!expression.available) { - return {type: 'error', value}; + return { type: 'error', value }; } else if (!expression.hasChildren()) { return { type: typeForSimpleValue(value), - value, + value }; } else { return { @@ -119,25 +122,16 @@ export function expressionAsEvaluationResult( description: value, // Used a means to get children when requested later. // $FlowFixMe: that isn't an object ID, - objectId: expression, + 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 expressionAsEvaluationResultStream(expression, focusedProcess, focusedStackFrame, context) { + return _rxjsBundlesRxMinJs.Observable.fromPromise(expression.evaluate(focusedProcess, focusedStackFrame, context)).map(() => expressionAsEvaluationResult(expression)).startWith(null); } -function typeForSimpleValue(value: string): string { +function typeForSimpleValue(value) { if (value === 'undefined' || value === 'null') { return value; } else { @@ -145,41 +139,27 @@ function typeForSimpleValue(value: string): string { } } -export function fetchChildrenForLazyComponent( - expression: IExpression, -): Observable { - return Observable.fromPromise( - expression.getChildren().then( - children => - children.map(child => ({ - name: child.name, - value: expressionAsEvaluationResult(child), - })), - error => null, - ), - ); +function fetchChildrenForLazyComponent(expression) { + return _rxjsBundlesRxMinJs.Observable.fromPromise(expression.getChildren().then(children => children.map(child => ({ + name: child.name, + value: expressionAsEvaluationResult(child) + })), error => null)); } -export function onUnexpectedError(error: any) { +function onUnexpectedError(error) { 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, - }, - ); + (_logger || _load_logger()).default.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 { +function capitalize(str) { 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', - }, - ); -} +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 a37ce694ac..e27889ea95 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,14 +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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +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')); +} + +var _os = _interopRequireDefault(require('os')); + +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 CONSOLE_VIEW_URI = 'atom://nuclide/console'; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 @@ -39,88 +185,6 @@ 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} 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'; -import os from 'os'; - -const CONSOLE_VIEW_URI = 'atom://nuclide/console'; - const CUSTOM_DEBUG_EVENT = 'CUSTOM_DEBUG_EVENT'; const CHANGE_DEBUG_MODE = 'CHANGE_DEBUG_MODE'; @@ -131,64 +195,45 @@ 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; +class ViewModel { constructor() { this._focusedProcess = null; this._focusedThread = null; this._focusedStackFrame = null; - this._emitter = new Emitter(); + this._emitter = new _atom.Emitter(); } - get focusedProcess(): ?IProcess { + get focusedProcess() { return this._focusedProcess; } - get focusedThread(): ?IThread { - return this._focusedStackFrame != null - ? this._focusedStackFrame.thread - : this._focusedThread; + get focusedThread() { + return this._focusedStackFrame != null ? this._focusedStackFrame.thread : this._focusedThread; } - get focusedStackFrame(): ?IStackFrame { + get focusedStackFrame() { return this._focusedStackFrame; } - onDidFocusProcess(callback: (process: ?IProcess) => mixed): IDisposable { + onDidFocusProcess(callback) { return this._emitter.on(CHANGE_FOCUSED_PROCESS, callback); } - onDidFocusStackFrame( - callback: (data: {stackFrame: ?IStackFrame, explicit: boolean}) => mixed, - ): IDisposable { + onDidFocusStackFrame(callback) { return this._emitter.on(CHANGE_FOCUSED_STACKFRAME, callback); } - onDidChangeExpressionContext( - callback: (data: {stackFrame: ?IStackFrame, explicit: boolean}) => mixed, - ): IDisposable { + onDidChangeExpressionContext(callback) { return this._emitter.on(CHANGE_EXPRESSION_CONTEXT, callback); } - isMultiProcessView(): boolean { + isMultiProcessView() { return false; } - setFocus( - stackFrame: ?IStackFrame, - thread: ?IThread, - process: ?IProcess, - explicit: boolean, - ): void { - const shouldEmit = - this._focusedProcess !== process || - this._focusedThread !== thread || - this._focusedStackFrame !== stackFrame || - explicit; + 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); @@ -197,96 +242,157 @@ class ViewModel implements IViewModel { this._focusedStackFrame = stackFrame; if (shouldEmit) { - this._emitter.emit(CHANGE_FOCUSED_STACKFRAME, {stackFrame, explicit}); + 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}); + this._emitter.emit(CHANGE_EXPRESSION_CONTEXT, { stackFrame, explicit }); } } } -function getDebuggerName(adapterType: string): string { - return `${capitalize(adapterType)} Debugger`; +function getDebuggerName(adapterType) { + return `${(0, (_utils || _load_utils()).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; +class DebugService { + + constructor(state) { + this._runInTerminal = async 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 = 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(); + }); + }; + + 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 Model( - this._loadBreakpoints(state), - true, - this._loadFunctionBreakpoints(state), - this._loadExceptionBreakpoints(state), - this._loadWatchExpressions(state), - ); + 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(): IViewModel { + get viewModel() { return this._viewModel; } - getDebuggerMode(): DebuggerModeType { + getDebuggerMode() { 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', - ); - } + _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'); } - }), - ); + } + })); } - async _openSourceView(uri: string): Promise { - const query = (url.parse(uri).path || '').split('/'); + async _openSourceView(uri) { + const query = (_url.default.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; + 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, + sourceReference }); let content = ''; try { const response = await process.session.source({ sourceReference, - source: source.raw, + source: source.raw }); content = response.body.content; } catch (error) { @@ -297,26 +403,20 @@ export default class DebugService implements IDebugService { const editor = atom.workspace.buildTextEditor({ buffer: new DebugSourceTextBufffer(content, uri), autoHeight: false, - readOnly: true, + 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(), - ); + 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(() => disposable.dispose()), () => editor.destroy()); this._sessionEndDisposables.add(disposable); @@ -326,31 +426,21 @@ export default class DebugService implements IDebugService { /** * 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 - ) { + async stopProcess() { + if (this._debuggerMode === (_constants || _load_constants()).DebuggerMode.STOPPING || this._debuggerMode === (_constants || _load_constants()).DebuggerMode.STOPPED) { return; } this._onSessionEnd(); } - _tryToAutoFocusStackFrame(thread: IThread): void { + _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)) - ) { + 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, - ); + const stackFrameToFocus = callStack.find(sf => sf.source != null && sf.source.available); if (stackFrameToFocus == null) { return; } @@ -358,10 +448,10 @@ export default class DebugService implements IDebugService { this.focusStackFrame(stackFrameToFocus, null, null); } - _registerMarkers(): IDisposable { - let selectedFrameMarker: ?atom$Marker = null; - let threadChangeDatatip: ?IDisposable; - let lastFocusedThreadId: ?number; + _registerMarkers() { + let selectedFrameMarker = null; + let threadChangeDatatip; + let lastFocusedThreadId; const cleaupMarkers = () => { if (selectedFrameMarker != null) { @@ -375,581 +465,393 @@ export default class DebugService implements IDebugService { } }; - 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', - }); + return new (_UniversalDisposable || _load_UniversalDisposable()).default((0, (_event || _load_event()).observableFromSubscribeFunction)(this._viewModel.onDidFocusStackFrame.bind(this._viewModel)).concatMap(event => { + cleaupMarkers(); - const datatipService = getDatatipService(); - if (datatipService == null) { - return; - } + const { stackFrame, explicit } = event; - 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; - }), + 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' + }); - cleaupMarkers, - ); + 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: Process, session: VsDebugSession): void { - this._sessionEndDisposables = new UniversalDisposable(session); + _registerSessionListeners(process, session) { + this._sessionEndDisposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(session); this._sessionEndDisposables.add(this._registerMarkers()); const sessionId = session.getId(); - const threadFetcher = serializeAsyncCall(async () => { + const threadFetcher = (0, (_promise || _load_promise()).serializeAsyncCall)(async () => { const response = await session.threads(); if (response && response.body && response.body.threads) { response.body.threads.forEach(thread => { this._model.rawUpdate({ sessionId, - thread, + 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)), - ); + 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(async filePath => { - if (filePath == null || !this._breakpointsToSendOnSave.has(filePath)) { - return; + 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().then(_ => { + this._updateModeAndEmit((_constants || _load_constants()).DebuggerMode.RUNNING); + }).catch(e => { + // Disconnect the debug session on configuration done error #10596 + this._onSessionEnd(); + session.disconnect().catch((_utils || _load_utils()).onUnexpectedError); + atom.notifications.addError('Failed to configure debugger. This is often because either ' + 'the process you tried to attach to has already terminated, or ' + 'you do not have permissions (the process is running as root or ' + 'another user.)', { + detail: e.message + }); + }); } - 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() - .then(_ => { - this._updateModeAndEmit(DebuggerMode.RUNNING); - }) - .catch(e => { - // Disconnect the debug session on configuration done error #10596 - this._onSessionEnd(); - session.disconnect().catch(onUnexpectedError); - atom.notifications.addError( - 'Failed to configure debugger. This is often because either ' + - 'the process you tried to attach to has already terminated, or ' + - 'you do not have permissions (the process is running as root or ' + - 'another user.)', - { - 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); + try { + await this._sendAllBreakpoints().then(sendConfigurationDone, sendConfigurationDone); + await threadFetcher(); + } catch (error) { + (0, (_utils || _load_utils()).onUnexpectedError)(error); + } + })); + + 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(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, - }); + 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 => { - 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(); - } + if (threadId == null) { + return; + } + const thread = process.getThread(threadId); + if (thread != null) { + toFocusThreads.next(thread); + } + }), toFocusThreads.concatMap(thread => { + var _ref, _ref2; - // 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), - }); + 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(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(); + }); + } 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, + 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) + 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 !== BreakpointEventReasons.CHANGED && - reason !== BreakpointEventReasons.REMOVED - ) { - return Observable.of({ - reason, - breakpoint, - sourceBreakpoint: null, - functionBreakpoint: null, - }); + 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); + } + })); - // 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.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); - }), - ); + 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)); + 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(): void { - const raiseNativeNotification = getNotificationService(); + _scheduleNativeNotification() { + const raiseNativeNotification = (0, (_AtomServiceContainer || _load_AtomServiceContainer()).getNotificationService)(); if (raiseNativeNotification != null) { - const pendingNotification = raiseNativeNotification( - 'Debugger', - 'Paused at a breakpoint', - 3000, - false, - ); + const pendingNotification = raiseNativeNotification('Debugger', 'Paused at a breakpoint', 3000, false); if (pendingNotification != null) { this._sessionEndDisposables.add(pendingNotification); } } } - onDidCustomEvent( - callback: (event: DebugProtocol.DebugEvent) => mixed, - ): IDisposable { + onDidCustomEvent(callback) { return this._emitter.on(CUSTOM_DEBUG_EVENT, callback); } - onDidChangeMode(callback: (mode: DebuggerModeType) => mixed): IDisposable { + onDidChangeMode(callback) { return this._emitter.on(CHANGE_DEBUG_MODE, callback); } - _loadBreakpoints(state: ?SerializedState): Breakpoint[] { - let result: Breakpoint[] = []; + _loadBreakpoints(state) { + let result = []; 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, - ); + 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: ?SerializedState): FunctionBreakpoint[] { - let result: FunctionBreakpoint[] = []; + _loadFunctionBreakpoints(state) { + let result = []; if (state == null || state.functionBreakpoints == null) { return result; } try { result = state.functionBreakpoints.map(fb => { - return new FunctionBreakpoint(fb.name, fb.enabled, fb.hitCondition); + return new (_DebuggerModel || _load_DebuggerModel()).FunctionBreakpoint(fb.name, fb.enabled, fb.hitCondition); }); } catch (e) {} return result; } - _loadExceptionBreakpoints(state: ?SerializedState): ExceptionBreakpoint[] { - let result: ExceptionBreakpoint[] = []; + _loadExceptionBreakpoints(state) { + let result = []; if (state == null || state.exceptionBreakpoints == null) { return result; } try { result = state.exceptionBreakpoints.map(exBreakpoint => { - return new ExceptionBreakpoint( - exBreakpoint.filter, - exBreakpoint.label, - exBreakpoint.enabled, - ); + return new (_DebuggerModel || _load_DebuggerModel()).ExceptionBreakpoint(exBreakpoint.filter, exBreakpoint.label, exBreakpoint.enabled); }); } catch (e) {} return result; } - _loadWatchExpressions(state: ?SerializedState): Expression[] { - let result: Expression[] = []; + _loadWatchExpressions(state) { + let result = []; if (state == null || state.watchExpressions == null) { return result; } try { - result = state.watchExpressions.map(name => new Expression(name)); + result = state.watchExpressions.map(name => new (_DebuggerModel || _load_DebuggerModel()).Expression(name)); } catch (e) {} return result; } - _updateModeAndEmit(debugMode: DebuggerModeType): void { + _updateModeAndEmit(debugMode) { this._debuggerMode = debugMode; this._emitter.emit(CHANGE_DEBUG_MODE, debugMode); } - focusStackFrame( - stackFrame: ?IStackFrame, - thread: ?IThread, - process: ?IProcess, - explicit?: boolean = false, - ): void { + focusStackFrame(stackFrame, thread, process, explicit = false) { let focusProcess = process; if (focusProcess == null) { if (stackFrame != null) { @@ -960,7 +862,7 @@ export default class DebugService implements IDebugService { focusProcess = this._model.getProcesses()[0]; } } - let focusThread: ?IThread = thread; + let focusThread = thread; let focusStackFrame = stackFrame; if (focusThread == null && stackFrame != null) { @@ -973,43 +875,32 @@ export default class DebugService implements IDebugService { focusStackFrame = thread.getCallStack()[0]; } - this._viewModel.setFocus( - focusStackFrame, - focusThread, - focusProcess, - explicit, - ); + 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; + _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 DebuggerMode.STOPPED; - } else if (this._debuggerMode === DebuggerMode.STARTING) { - return DebuggerMode.STARTING; + return (_constants || _load_constants()).DebuggerMode.STOPPED; + } else if (this._debuggerMode === (_constants || _load_constants()).DebuggerMode.STARTING) { + return (_constants || _load_constants()).DebuggerMode.STARTING; } else { - return DebuggerMode.RUNNING; + return (_constants || _load_constants()).DebuggerMode.RUNNING; } } - enableOrDisableBreakpoints( - enable: boolean, - breakpoint?: IEnableable, - ): Promise { + enableOrDisableBreakpoints(enable, breakpoint) { if (breakpoint != null) { this._model.setEnablement(breakpoint, enable); - if (breakpoint instanceof Breakpoint) { + if (breakpoint instanceof (_DebuggerModel || _load_DebuggerModel()).Breakpoint) { return this._sendBreakpoints(breakpoint.uri); - } else if (breakpoint instanceof FunctionBreakpoint) { + } else if (breakpoint instanceof (_DebuggerModel || _load_DebuggerModel()).FunctionBreakpoint) { return this._sendFunctionBreakpoints(); } else { - track(AnalyticsEvents.DEBUGGER_TOGGLE_EXCEPTION_BREAKPOINT); + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_TOGGLE_EXCEPTION_BREAKPOINT); return this._sendExceptionBreakpoints(); } } @@ -1018,180 +909,153 @@ export default class DebugService implements IDebugService { return this._sendAllBreakpoints(); } - addBreakpoints(uri: string, rawBreakpoints: IRawBreakpoint[]): Promise { - track(AnalyticsEvents.DEBUGGER_BREAKPOINT_ADD); + 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: string, line: number): Promise { - track(AnalyticsEvents.DEBUGGER_BREAKPOINT_TOGGLE); + 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}]); + return this.addBreakpoints(uri, [{ line }]); } else { return this.removeBreakpoints(existing.getId(), true); } } - updateBreakpoints( - uri: string, - data: {[id: string]: DebugProtocol.Breakpoint}, - ) { + updateBreakpoints(uri, data) { 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); + async removeBreakpoints(id, skipAnalytics = false) { + const toRemove = this._model.getBreakpoints().filter(bp => id == null || bp.getId() === id); + const urisToClear = (0, (_collection || _load_collection()).distinct)(toRemove, bp => bp.uri).map(bp => bp.uri); this._model.removeBreakpoints(toRemove); if (id == null) { - track(AnalyticsEvents.DEBUGGER_BREAKPOINT_DELETE_ALL); + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_BREAKPOINT_DELETE_ALL); } else if (!skipAnalytics) { - track(AnalyticsEvents.DEBUGGER_BREAKPOINT_DELETE); + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_BREAKPOINT_DELETE); } await Promise.all(urisToClear.map(uri => this._sendBreakpoints(uri))); } - setBreakpointsActivated(activated: boolean): Promise { + setBreakpointsActivated(activated) { this._model.setBreakpointsActivated(activated); return this._sendAllBreakpoints(); } - addFunctionBreakpoint(): void { + addFunctionBreakpoint() { this._model.addFunctionBreakpoint(''); } - renameFunctionBreakpoint(id: string, newFunctionName: string): Promise { - this._model.updateFunctionBreakpoints({[id]: {name: newFunctionName}}); + renameFunctionBreakpoint(id, newFunctionName) { + this._model.updateFunctionBreakpoints({ [id]: { name: newFunctionName } }); return this._sendFunctionBreakpoints(); } - removeFunctionBreakpoints(id?: string): Promise { + removeFunctionBreakpoints(id) { this._model.removeFunctionBreakpoints(id); return this._sendFunctionBreakpoints(); } - async terminateThreads(threadIds: Array): Promise { - const {focusedProcess} = this.viewModel; + async terminateThreads(threadIds) { + const { focusedProcess } = this.viewModel; if (focusedProcess == null) { return; } const session = focusedProcess.session; - track(AnalyticsEvents.DEBUGGER_TERMINATE_THREAD); + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_TERMINATE_THREAD); if (Boolean(session.capabilities.supportsTerminateThreadsRequest)) { await session.custom('terminateThreads', { - threadIds, + threadIds }); } } - async runToLocation(uri: string, line: number): Promise { - const {focusedThread, focusedProcess} = this.viewModel; + async runToLocation(uri, line) { + const { focusedThread, focusedProcess } = this.viewModel; if (focusedThread == null || focusedProcess == null) { return; } const session = focusedProcess.session; - track(AnalyticsEvents.DEBUGGER_STEP_RUN_TO_LOCATION); + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_RUN_TO_LOCATION); if (Boolean(session.capabilities.supportsContinueToLocation)) { await session.custom('continueToLocation', { - source: focusedProcess.getSource({path: uri}).raw, + source: focusedProcess.getSource({ path: uri }).raw, line, - threadId: focusedThread.threadId, + 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); + await this.addBreakpoints(uri, [{ line }]); + const runToLocationBreakpoint = this._model.getBreakpointAtLine(uri, line); + + if (!(runToLocationBreakpoint != null)) { + throw new Error('Invariant violation: "runToLocationBreakpoint != null"'); + } const removeBreakpoint = () => { - this.removeBreakpoints( - runToLocationBreakpoint.getId(), - true /* skip analytics */, - ).catch(error => - onUnexpectedError( - `Failed to clear run-to-location breakpoint! - ${String(error)}`, - ), - ); + this.removeBreakpoints(runToLocationBreakpoint.getId(), true /* skip analytics */ + ).catch(error => (0, (_utils || _load_utils()).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), - ); + const removeBreakpointDisposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(session.observeStopEvents().take(1).subscribe(removeBreakpoint)); // Remove if the session has ended without hitting it. - this._sessionEndDisposables.add( - removeBreakpointDisposable, - removeBreakpoint, - ); + this._sessionEndDisposables.add(removeBreakpointDisposable, removeBreakpoint); } await focusedThread.continue(); } - addWatchExpression(name: string): void { - track(AnalyticsEvents.DEBUGGER_WATCH_ADD_EXPRESSION); + addWatchExpression(name) { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_WATCH_ADD_EXPRESSION); return this._model.addWatchExpression(name); } - renameWatchExpression(id: string, newName: string): void { - track(AnalyticsEvents.DEBUGGER_WATCH_UPDATE_EXPRESSION); + renameWatchExpression(id, newName) { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_WATCH_UPDATE_EXPRESSION); return this._model.renameWatchExpression(id, newName); } - removeWatchExpressions(id?: string): void { - track(AnalyticsEvents.DEBUGGER_WATCH_REMOVE_EXPRESSION); + removeWatchExpressions(id) { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_WATCH_REMOVE_EXPRESSION); this._model.removeWatchExpressions(id); } - createExpression(rawExpression: string): IEvaluatableExpression { - return new Expression(rawExpression); + createExpression(rawExpression) { + return new (_DebuggerModel || _load_DebuggerModel()).Expression(rawExpression); } - async _doCreateProcess( - rawConfiguration: IProcessConfig, - sessionId: string, - ): Promise { - let process: ?IProcess; - let session: ?VsDebugSession; - const errorHandler = (error: Error) => { + async _doCreateProcess(rawConfiguration, sessionId) { + let process; + let session; + const errorHandler = error => { if (this._timer != null) { this._timer.onError(error); this._timer = null; } - track(AnalyticsEvents.DEBUGGER_START_FAIL, {}); + (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}`, - ); + atom.notifications.addError(`Failed to start debugger process: ${errorMessage}`); this._consoleDisposables.dispose(); - this._updateModeAndEmit(DebuggerMode.STOPPED); + this._updateModeAndEmit((_constants || _load_constants()).DebuggerMode.STOPPED); if (session != null && !session.isDisconnected()) { this._onSessionEnd(); - session.disconnect().catch(onUnexpectedError); + session.disconnect().catch((_utils || _load_utils()).onUnexpectedError); } if (process != null) { this._model.removeProcess(process.getId()); @@ -1199,38 +1063,28 @@ export default class DebugService implements IDebugService { }; try { - const adapterExecutable = await this._resolveAdapterExecutable( - rawConfiguration, - ); - const configuration = await resolveDebugConfiguration({ - ...rawConfiguration, - adapterExecutable, - }); + const adapterExecutable = await this._resolveAdapterExecutable(rawConfiguration); + const configuration = await (0, (_AtomServiceContainer || _load_AtomServiceContainer()).resolveDebugConfiguration)(Object.assign({}, rawConfiguration, { + adapterExecutable + })); const { adapterType, onInitializeCallback, - customDisposable, + customDisposable } = configuration; - track(AnalyticsEvents.DEBUGGER_START, { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_START, { serviceName: configuration.adapterType, - clientType: 'VSP', + clientType: 'VSP' }); - const createInitializeSession = async (config: IProcessConfig) => { - const newSession = await this._createVsDebugSession( - config, - config.adapterExecutable || adapterExecutable, - sessionId, - ); + const createInitializeSession = async config => { + const newSession = await this._createVsDebugSession(config, config.adapterExecutable || adapterExecutable, sessionId); process = this._model.addProcess(config, newSession); this.focusStackFrame(null, null, process); this._registerSessionListeners(process, newSession); - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'debugger:show', - ); + atom.commands.dispatch(atom.views.getView(atom.workspace), 'debugger:show'); await newSession.initialize({ clientID: 'atom', adapterID: adapterType, @@ -1239,17 +1093,15 @@ export default class DebugService implements IDebugService { columnsStartAt1: true, supportsVariableType: true, supportsVariablePaging: false, - supportsRunInTerminalRequest: getTerminalService() != null, - locale: 'en-us', + supportsRunInTerminalRequest: (0, (_AtomServiceContainer || _load_AtomServiceContainer()).getTerminalService)() != null, + locale: 'en-us' }); if (onInitializeCallback != null) { await onInitializeCallback(newSession); } - this._model.setExceptionBreakpoints( - newSession.getCapabilities().exceptionBreakpointFilters || [], - ); + this._model.setExceptionBreakpoints(newSession.getCapabilities().exceptionBreakpointFilters || []); return newSession; }; @@ -1258,31 +1110,18 @@ export default class DebugService implements IDebugService { // 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(async error => { - if ( - configuration.debugMode === 'attach' && - configuration.adapterExecutable != null && - configuration.adapterExecutable.command !== 'sudo' && - // sudo is not supported on Windows, and currently remote projects - // are not supported on Windows, so a remote URI must be *nix. - (os.platform() !== 'win32' || - nuclideUri.isRemote(configuration.targetUri)) - ) { - configuration.adapterExecutable.args = [ - configuration.adapterExecutable.command, - ...configuration.adapterExecutable.args, - ]; + if (configuration.debugMode === 'attach' && configuration.adapterExecutable != null && configuration.adapterExecutable.command !== 'sudo' && ( + // sudo is not supported on Windows, and currently remote projects + // are not supported on Windows, so a remote URI must be *nix. + _os.default.platform() !== 'win32' || (_nuclideUri || _load_nuclideUri()).default.isRemote(configuration.targetUri))) { + configuration.adapterExecutable.args = [configuration.adapterExecutable.command, ...configuration.adapterExecutable.args]; configuration.adapterExecutable.command = 'sudo'; const errorMessage = error instanceof Error ? error.message : error; - atom.notifications.addWarning( - `The debugger was unable to attach to the target process: ${errorMessage}. ` + - 'Attempting to re-launch the debugger as root...', - ); + atom.notifications.addWarning(`The debugger was unable to attach to the target process: ${errorMessage}. ` + 'Attempting to re-launch the debugger as root...'); session = await createInitializeSession(configuration); - this._launchOrAttachTarget(session, configuration).catch( - errorHandler, - ); + this._launchOrAttachTarget(session, configuration).catch(errorHandler); } else { errorHandler(error); } @@ -1291,17 +1130,11 @@ export default class DebugService implements IDebugService { // make sure to add the configuration.customDisposable to dispose on // session end if (customDisposable != null) { - customDisposable.add( - this.viewModel.onDidFocusProcess(() => { - if ( - !this.getModel() - .getProcesses() - .includes(process) - ) { - customDisposable.dispose(); - } - }), - ); + customDisposable.add(this.viewModel.onDidFocusProcess(() => { + if (!this.getModel().getProcesses().includes(process)) { + customDisposable.dispose(); + } + })); } return process; @@ -1311,55 +1144,35 @@ export default class DebugService implements IDebugService { } } - async _resolveAdapterExecutable( - configuration: IProcessConfig, - ): Promise { + async _resolveAdapterExecutable(configuration) { if (configuration.adapterExecutable != null) { return configuration.adapterExecutable; } - return getVSCodeDebuggerAdapterServiceByNuclideUri( - configuration.targetUri, - ).getAdapterExecutableInfo(configuration.adapterType); + return (0, (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).getVSCodeDebuggerAdapterServiceByNuclideUri)(configuration.targetUri).getAdapterExecutableInfo(configuration.adapterType); } - async _createVsDebugSession( - configuration: IProcessConfig, - adapterExecutable: VSAdapterExecutableInfo, - sessionId: string, - ): Promise { - const {targetUri} = configuration; - const service = getVSCodeDebuggerAdapterServiceByNuclideUri(targetUri); + async _createVsDebugSession(configuration, adapterExecutable, sessionId) { + const { targetUri } = configuration; + const service = (0, (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).getVSCodeDebuggerAdapterServiceByNuclideUri)(targetUri); const spawner = await service.createVsRawAdapterSpawnerService(); - const clientPreprocessors: Array = []; - const adapterPreprocessors: Array = []; + const clientPreprocessors = []; + const adapterPreprocessors = []; if (configuration.clientPreprocessor != null) { clientPreprocessors.push(configuration.clientPreprocessor); } if (configuration.adapterPreprocessor != null) { adapterPreprocessors.push(configuration.adapterPreprocessor); } - const isRemote = nuclideUri.isRemote(targetUri); + const isRemote = (_nuclideUri || _load_nuclideUri()).default.isRemote(targetUri); if (isRemote) { - clientPreprocessors.push(remoteToLocalProcessor()); - adapterPreprocessors.push(localToRemoteProcessor(targetUri)); + clientPreprocessors.push((0, (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).remoteToLocalProcessor)()); + adapterPreprocessors.push((0, (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).localToRemoteProcessor)(targetUri)); } - return new VsDebugSession( - sessionId, - logger, - adapterExecutable, - {adapter: configuration.adapterType, host: 'debugService', isRemote}, - spawner, - clientPreprocessors, - adapterPreprocessors, - this._runInTerminal, - ); + return new (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsDebugSession(sessionId, (_logger || _load_logger()).default, adapterExecutable, { adapter: configuration.adapterType, host: 'debugService', isRemote }, spawner, clientPreprocessors, adapterPreprocessors, this._runInTerminal); } - async _launchOrAttachTarget( - session: VsDebugSession, - configuration: IProcessConfig, - ): Promise { + async _launchOrAttachTarget(session, configuration) { if (configuration.debugMode === 'attach') { await session.attach(configuration.config); } else { @@ -1368,78 +1181,11 @@ export default class DebugService implements IDebugService { } } - _sourceIsNotAvailable(uri: string): void { + _sourceIsNotAvailable(uri) { 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 { + async restartProcess() { const process = this._getCurrentProcess(); if (process == null) { return; @@ -1448,7 +1194,7 @@ export default class DebugService implements IDebugService { await process.session.custom('restart', null); } await process.session.disconnect(true); - await sleep(300); + await (0, (_promise || _load_promise()).sleep)(300); await this.startDebugging(process.configuration); } @@ -1457,94 +1203,45 @@ export default class DebugService implements IDebugService { * 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'); + async startDebugging(config) { + this._timer = (0, (_analytics || _load_analytics()).startTracking)('debugger-atom:startDebugging'); if (this._viewModel.focusedProcess != null) { // We currently support only running only one debug session at a time, // so stop the current debug session. this.stopProcess(); } - this._updateModeAndEmit(DebuggerMode.STARTING); + this._updateModeAndEmit((_constants || _load_constants()).DebuggerMode.STARTING); // Open the console window if it's not already opened. // eslint-disable-next-line nuclide-internal/atom-apis - atom.workspace.open(CONSOLE_VIEW_URI, {searchAllPanes: true}); + atom.workspace.open(CONSOLE_VIEW_URI, { searchAllPanes: true }); this._consoleDisposables = this._registerConsoleExecutor(); - await this._doCreateProcess(config, uuid.v4()); + await this._doCreateProcess(config, (_uuid || _load_uuid()).default.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 { + getModel() { return this._model; } - async _sendAllBreakpoints(): Promise { - await Promise.all( - distinct(this._model.getBreakpoints(), bp => bp.uri).map(bp => - this._sendBreakpoints(bp.uri, false), - ), - ); + async _sendAllBreakpoints() { + await Promise.all((0, (_collection || _load_collection()).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 { + async _sendBreakpoints(uri, sourceModified = false) { const process = this._getCurrentProcess(); const session = this._getCurrentSession(); - if ( - process == null || - session == null || - !session.isReadyForBreakpoints() - ) { + if (process == null || session == null || !session.isReadyForBreakpoints()) { return; } - const breakpointsToSend = this._model - .getBreakpoints() - .filter( - bp => - this._model.areBreakpointsActivated() && bp.enabled && bp.uri === uri, - ); + 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), + name: (_nuclideUri || _load_nuclideUri()).default.basename(uri) }).raw; if (breakpointsToSend.length && !rawSource.adapterData) { @@ -1553,21 +1250,21 @@ export default class DebugService implements IDebugService { // The UI is 0-based, while VSP is 1-based. const response = await session.setBreakpoints({ - source: (rawSource: any), + source: rawSource, lines: breakpointsToSend.map(bp => bp.line), breakpoints: breakpointsToSend.map(bp => ({ line: bp.line, column: bp.column, condition: bp.condition, - hitCondition: bp.hitCondition, + hitCondition: bp.hitCondition })), - sourceModified, + sourceModified }); if (response == null || response.body == null) { return; } - const data: {[id: string]: DebugProtocol.Breakpoint} = {}; + const data = {}; for (let i = 0; i < breakpointsToSend.length; i++) { data[breakpointsToSend[i].getId()] = response.body.breakpoints[i]; if (!breakpointsToSend[i].column) { @@ -1579,34 +1276,24 @@ export default class DebugService implements IDebugService { this._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 { + async _sendFunctionBreakpoints() { const session = this._getCurrentSession(); - if ( - session == null || - !session.isReadyForBreakpoints() || - !session.getCapabilities().supportsFunctionBreakpoints - ) { + if (session == null || !session.isReadyForBreakpoints() || !session.getCapabilities().supportsFunctionBreakpoints) { return; } - const breakpointsToSend: any = this._model - .getFunctionBreakpoints() - .filter(fbp => fbp.enabled && this._model.areBreakpointsActivated()); - const response: DebugProtocol.SetFunctionBreakpointsResponse = await session.setFunctionBreakpoints( - { - breakpoints: breakpointsToSend, - }, - ); + const breakpointsToSend = this._model.getFunctionBreakpoints().filter(fbp => fbp.enabled && this._model.areBreakpointsActivated()); + const response = await session.setFunctionBreakpoints({ + breakpoints: breakpointsToSend + }); if (response == null || response.body == null) { return; } @@ -1619,98 +1306,76 @@ export default class DebugService implements IDebugService { this._model.updateFunctionBreakpoints(data); } - async _sendExceptionBreakpoints(): Promise { + async _sendExceptionBreakpoints() { const session = this._getCurrentSession(); - if ( - session == null || - !session.isReadyForBreakpoints() || - this._model.getExceptionBreakpoints().length === 0 - ) { + if (session == null || !session.isReadyForBreakpoints() || this._model.getExceptionBreakpoints().length === 0) { return; } - const enabledExceptionBps = this._model - .getExceptionBreakpoints() - .filter(exb => exb.enabled); + const enabledExceptionBps = this._model.getExceptionBreakpoints().filter(exb => exb.enabled); await session.setExceptionBreakpoints({ - filters: enabledExceptionBps.map(exb => exb.filter), + 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), - }), - ); + disposables.add(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(); } } -class DebugSourceTextBufffer extends TextBuffer { - _uri: string; +exports.default = DebugService; +class DebugSourceTextBufffer extends _atom.TextBuffer { - constructor(contents: string, uri: string) { + constructor(contents, uri) { super(contents); this._uri = uri; } @@ -1726,4 +1391,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 62208d81c5..b7909d632c 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,3 +1,66 @@ +'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 _vscodeDebugprotocol; + +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 _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. @@ -6,7 +69,7 @@ * LICENSE file in 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 */ @@ -39,122 +102,59 @@ 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) { +class Source { + + constructor(raw, sessionId) { if (raw == null) { - this._raw = {name: UNKNOWN_SOURCE}; + this._raw = { name: (_constants || _load_constants()).UNKNOWN_SOURCE }; } else { this._raw = raw; } 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}`; + 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 || ''; } this.available = this.uri !== ''; } - get name(): ?string { + get name() { return this._raw.name; } - get origin(): ?string { + get origin() { return this._raw.origin; } - get presentationHint(): ?SourcePresentationHint { + get presentationHint() { return this._raw.presentationHint; } - get raw(): DebugProtocol.Source { + get raw() { return this._raw; } - get reference(): ?number { + 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 nuclide-internal/atom-apis return atom.workspace.open(this.uri, { searchAllPanes: true, - pending: true, + pending: true }); } } -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, - ) { +exports.Source = Source; +class ExpressionContainer { + + constructor(process, reference, id, namedVariables, indexedVariables, startOfVariables) { this.process = process; this._reference = reference; this._id = id; @@ -162,17 +162,19 @@ class ExpressionContainer implements IExpressionContainer { 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,7 +182,7 @@ class ExpressionContainer implements IExpressionContainer { return this._children; } - async _doGetChildren(): Promise { + async _doGetChildren() { if (!this.hasChildren()) { return []; } @@ -191,17 +193,14 @@ class ExpressionContainer implements IExpressionContainer { } // Check if object has named variables, fetch them independent from indexed variables #9670 - let childrenArray: Array = []; + let childrenArray = []; if (Boolean(this._namedVariables)) { childrenArray = await 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 - ) { + while (this._indexedVariables > chunkSize * ExpressionContainer.BASE_CHUNK_SIZE) { chunkSize *= ExpressionContainer.BASE_CHUNK_SIZE; } @@ -210,130 +209,71 @@ class ExpressionContainer implements IExpressionContainer { 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( - new Variable( - this.process, - this, - this.reference, - `[${start}..${start + count - 1}]`, - '', - '', - null, - count, - {kind: 'virtual'}, - null, - true, - start, - ), - ); + const count = Math.min(chunkSize, this._indexedVariables - i * chunkSize); + childrenArray.push(new Variable(this.process, this, this.reference, `[${start}..${start + count - 1}]`, '', '', null, count, { kind: 'virtual' }, null, true, start)); } return childrenArray; } - const variables = await this._fetchVariables( - this._startOfVariables, - this._indexedVariables, - 'indexed', - ); + const variables = await this._fetchVariables(this._startOfVariables, this._indexedVariables, 'indexed'); 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 { + async _fetchVariables(start, count, filter) { const process = this.process; - invariant(process); + + if (!process) { + throw new Error('Invariant violation: "process"'); + } + try { - const response: DebugProtocol.VariablesResponse = await process.session.variables( - { - variablesReference: this.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, - v.variablesReference, - v.name, - v.evaluateName, - v.value, - v.namedVariables, - v.indexedVariables, - v.presentationHint, - v.type, - ), - ); + const response = await process.session.variables({ + variablesReference: this.reference, + start, + count, + filter + }); + const variables = (0, (_collection || _load_collection()).distinct)(response.body.variables.filter(v => v != null && v.name), v => v.name); + return variables.map(v => new Variable(this.process, this, v.variablesReference, v.name, v.evaluateName, v.value, v.namedVariables, v.indexedVariables, v.presentationHint, v.type)); } catch (e) { - return [ - new Variable( - this.process, - this, - 0, - null, - e.message, - '', - 0, - 0, - {kind: 'virtual'}, - null, - false, - ), - ]; + return [new Variable(this.process, this, 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; } } -export class Expression extends ExpressionContainer - implements IEvaluatableExpression { - static DEFAULT_VALUE = 'not available'; - - available: boolean; - _type: ?string; - name: string; +ExpressionContainer.allValues = new Map(); +ExpressionContainer.BASE_CHUNK_SIZE = 100; +class Expression extends ExpressionContainer { - 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,20 +285,13 @@ 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; + async evaluate(process, stackFrame, context) { + 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; @@ -366,13 +299,11 @@ export class Expression extends ExpressionContainer this.process = process; try { - const response: DebugProtocol.EvaluateResponse = await process.session.evaluate( - { - expression: this.name, - frameId: stackFrame ? stackFrame.frameId : undefined, - context, - }, - ); + const response = await process.session.evaluate({ + expression: this.name, + frameId: stackFrame ? stackFrame.frameId : undefined, + context + }); this.available = response != null && response.body != null; if (response && response.body) { @@ -389,44 +320,19 @@ export class Expression extends ExpressionContainer } } - toString(): string { + toString() { return `${this.name}\n${this._value}`; } } -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, - ) { - super( - process, - reference, - // flowlint-next-line sketchy-null-string:off - `variable:${parent.getId()}:${name || 'no_name'}`, - namedVariables, - indexedVariables, - _startOfVariables, - ); +exports.Expression = Expression; +Expression.DEFAULT_VALUE = 'not available'; +class Variable extends ExpressionContainer { + + constructor(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); this.parent = parent; this.name = name == null ? 'no_name' : name; this.evaluateName = evaluateName; @@ -435,26 +341,27 @@ export class Variable extends ExpressionContainer implements IExpression { 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, + async setVariable(value) { + const process = (0, (_nullthrows || _load_nullthrows()).default)(this.process); + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_EDIT_VARIABLE, { + language: process.configuration.adapterType }); try { const response = await process.session.setVariable({ - name: nullthrows(this.name), + name: (0, (_nullthrows || _load_nullthrows()).default)(this.name), value, - variablesReference: this.parent.reference, + 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._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; @@ -464,58 +371,26 @@ export class Variable extends ExpressionContainer implements IExpression { } } - toString(): string { + toString() { return `${this.name}: ${this._value}`; } } -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, - ) { - super( - stackFrame.thread.process, - reference, - `scope:${stackFrame.getId()}:${name}:${index}`, - namedVariables, - indexedVariables, - ); +exports.Variable = Variable; +class Scope extends ExpressionContainer { + + constructor(stackFrame, index, name, reference, expensive, namedVariables, indexedVariables, range) { + super(stackFrame.thread.process, reference, `scope:${stackFrame.getId()}:${name}:${index}`, namedVariables, indexedVariables); this.name = name; this.expensive = expensive; this.range = range; } } -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, - ) { +exports.Scope = Scope; +class StackFrame { + + constructor(thread, frameId, source, name, presentationHint, range, index) { this.thread = thread; this.frameId = frameId; this.source = source; @@ -526,103 +401,67 @@ export class StackFrame implements IStackFrame { this.scopes = null; } - getId(): string { + getId() { return `stackframe:${this.thread.getId()}:${this.frameId}:${this.index}`; } - async getScopes(): Promise { + async getScopes() { if (this.scopes == null) { this.scopes = this._getScopesImpl(); } - return (this.scopes: any); + return this.scopes; } - async _getScopesImpl(): Promise { + async _getScopesImpl() { try { const { - body: {scopes}, + body: { scopes } } = await this.thread.process.session.scopes({ - frameId: this.frameId, + frameId: this.frameId }); - return scopes.map( - (rs, index) => - new Scope( - this, - 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, - ), - ); + return scopes.map((rs, index) => new Scope(this, index, rs.name, rs.variablesReference, rs.expensive, rs.namedVariables, rs.indexedVariables, 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, - ); + async getMostSpecificScopes(range) { + const scopes = (await this.getScopes()).filter(s => !s.expensive); const haveRangeInfo = scopes.some(s => 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); - // prettier-ignore - return (firstRange.end.row - firstRange.start.row) - - (secondRange.end.row - secondRange.end.row); - }); + const scopesContainingRange = scopes.filter(scope => scope.range != null && scope.range.containsRange(range)).sort((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 scopesContainingRange.length ? scopesContainingRange : scopes; } - async restart(): Promise { - await this.thread.process.session.restartFrame( - {frameId: this.frameId}, - this.thread.threadId, - ); + async restart() { + await this.thread.process.session.restartFrame({ frameId: this.frameId }, this.thread.threadId); } - toString(): string { - return `${this.name} (${ - this.source.inMemory ? nullthrows(this.source.name) : this.source.uri - }:${this.range.start.row})`; + toString() { + return `${this.name} (${this.source.inMemory ? (0, (_nullthrows || _load_nullthrows()).default)(this.source.name) : this.source.uri}:${this.range.start.row})`; } - async openInEditor(): Promise { + async openInEditor() { if (this.source.available) { - return openSourceLocation(this.source.uri, this.range.start.row); + return (0, (_utils || _load_utils()).openSourceLocation)(this.source.uri, this.range.start.row); } else { return null; } } } -export class Thread implements IThread { - _callStack: IStackFrame[]; - _staleCallStack: IStackFrame[]; - stoppedDetails: ?IRawStoppedDetails; - stopped: boolean; - +process: IProcess; - +threadId: number; - name: string; +exports.StackFrame = StackFrame; +class Thread { - constructor(process: IProcess, name: string, threadId: number) { + constructor(process, name, threadId) { this.process = process; this.name = name; this.threadId = threadId; @@ -632,22 +471,22 @@ 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; } @@ -658,7 +497,7 @@ export class Thread implements IThread { * 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 { + async fetchCallStack(levels = 20) { if (!this.stopped) { return; } @@ -672,18 +511,13 @@ export class Thread implements IThread { this._callStack = this._callStack.concat(callStack || []); } - async _getCallStackImpl( - startFrame: number, - levels: number, - ): Promise { + async _getCallStackImpl(startFrame, levels) { try { - const response: DebugProtocol.StackTraceResponse = await this.process.session.stackTrace( - { - threadId: this.threadId, - startFrame, - levels, - }, - ); + const response = await this.process.session.stackTrace({ + threadId: this.threadId, + startFrame, + levels + }); if (response == null || response.body == null) { return []; } @@ -694,22 +528,9 @@ export class Thread implements IThread { return response.body.stackFrames.map((rsf, index) => { const source = this.process.getSource(rsf.source); - 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, - ); + return new StackFrame(this, rsf.id, source, rsf.name, rsf.presentationHint, + // The UI is 0-based while VSP is 1-based. + 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]), startFrame + index); }); } catch (err) { if (this.stoppedDetails != null) { @@ -723,12 +544,9 @@ export class Thread implements IThread { /** * Returns exception info promise if the exception was thrown, otherwise null */ - async exceptionInfo(): Promise { + async exceptionInfo() { const session = this.process.session; - if ( - this.stoppedDetails == null || - this.stoppedDetails.reason !== 'exception' - ) { + if (this.stoppedDetails == null || this.stoppedDetails.reason !== 'exception') { return null; } const stoppedDetails = this.stoppedDetails; @@ -737,13 +555,11 @@ export class Thread implements IThread { id: null, details: null, description: stoppedDetails.description, - breakMode: null, + breakMode: null }; } - const exception: DebugProtocol.ExceptionInfoResponse = await session.exceptionInfo( - {threadId: this.threadId}, - ); + const exception = await session.exceptionInfo({ threadId: this.threadId }); if (exception == null) { return null; } @@ -752,74 +568,71 @@ export class Thread implements IThread { id: exception.body.exceptionId, description: exception.body.description, breakMode: exception.body.breakMode, - details: exception.body.details, + details: exception.body.details }; } - async next(): Promise { - track(AnalyticsEvents.DEBUGGER_STEP_OVER); - await this.process.session.next({threadId: this.threadId}); + async next() { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).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}); + async stepIn() { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_INTO); + await this.process.session.stepIn({ threadId: this.threadId }); } - async stepOut(): Promise { - track(AnalyticsEvents.DEBUGGER_STEP_OUT); - await this.process.session.stepOut({threadId: this.threadId}); + async stepOut() { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_OUT); + await this.process.session.stepOut({ threadId: this.threadId }); } - async stepBack(): Promise { - track(AnalyticsEvents.DEBUGGER_STEP_BACK); - await this.process.session.stepBack({threadId: this.threadId}); + async stepBack() { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_BACK); + await this.process.session.stepBack({ threadId: this.threadId }); } - async continue(): Promise { - track(AnalyticsEvents.DEBUGGER_STEP_CONTINUE); - await this.process.session.continue({threadId: this.threadId}); + async continue() { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_CONTINUE); + await this.process.session.continue({ threadId: this.threadId }); } - async pause(): Promise { - track(AnalyticsEvents.DEBUGGER_STEP_PAUSE); - await this.process.session.pause({threadId: this.threadId}); + async pause() { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_PAUSE); + await this.process.session.pause({ threadId: this.threadId }); } - async reverseContinue(): Promise { - await this.process.session.reverseContinue({threadId: this.threadId}); + async reverseContinue() { + await this.process.session.reverseContinue({ threadId: this.threadId }); } } -export class Process implements IProcess { - _sources: Map; - _threads: Map; - _session: ISession & ITreeElement; - _configuration: IProcessConfig; +exports.Thread = Thread; +class Process { - constructor(configuration: IProcessConfig, session: ISession & ITreeElement) { + 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 +640,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 @@ -852,35 +665,34 @@ export class Process implements IProcess { // whether the thread is stopped or not if (stoppedDetails.allThreadsStopped) { this._threads.forEach(thread => { - thread.stoppedDetails = - thread.threadId === threadId ? stoppedDetails : thread.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,12 +715,7 @@ export class Process implements IProcess { } } - async completions( - frameId: number, - text: string, - position: atom$Point, - overwriteBefore: number, - ): Promise> { + async completions(frameId, text, position, overwriteBefore) { if (!this._session.capabilities.supportsCompletionsRequest) { return []; } @@ -917,7 +724,7 @@ export class Process implements IProcess { frameId, text, column: position.column, - line: position.row, + line: position.row }); if (response && response.body && response.body.targets) { return response.body.targets; @@ -930,30 +737,10 @@ export class Process implements IProcess { } } -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; - - constructor( - uri: string, - line: number, - column: ?number, - enabled: ?boolean, - condition: ?string, - hitCondition: ?string, - adapterData?: any, - ) { +exports.Process = Process; +class Breakpoint { + + constructor(uri, line, column, enabled, condition, hitCondition, adapterData) { this.uri = uri; this.line = line; this.column = column == null ? 1 : column; @@ -962,79 +749,56 @@ 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; } } -export class FunctionBreakpoint implements IFunctionBreakpoint { - id: string; - verified: boolean; - idFromAdapter: ?number; - name: string; - enabled: boolean; - hitCondition: ?string; - condition: ?string; +exports.Breakpoint = Breakpoint; +class FunctionBreakpoint { - 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; } } -export class ExceptionBreakpoint implements IExceptionBreakpoint { - _id: string; - +filter: string; - +label: string; - enabled: boolean; +exports.FunctionBreakpoint = FunctionBreakpoint; +class ExceptionBreakpoint { - 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; - - constructor( - breakpoints: Breakpoint[], - breakpointsActivated: boolean, - functionBreakpoints: FunctionBreakpoint[], - exceptionBreakpoints: ExceptionBreakpoint[], - watchExpressions: Expression[], - ) { +class Model { + + constructor(breakpoints, breakpointsActivated, functionBreakpoints, exceptionBreakpoints, watchExpressions) { this._processes = []; this._schedulers = new Map(); this._breakpoints = breakpoints; @@ -1042,65 +806,56 @@ 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 { + addProcess(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 { + onDidChangeBreakpoints(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 { + onDidChangeWatchExpressions(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,27 +866,17 @@ export class Model implements IModel { } } - async fetchCallStack(threadI: IThread): Promise { - const thread: Thread = (threadI: any); + async fetchCallStack(threadI) { + const thread = threadI; if ( - // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - nullthrows(thread.process).session.capabilities - .supportsDelayedStackTraceLoading - ) { + // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) + (0, (_nullthrows || _load_nullthrows()).default)(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( - thread.getId(), - Observable.timer(500).subscribe(() => { - thread - .fetchCallStack(19) - .then( - () => this._emitter.emit(CALLSTACK_CHANGED), - onUnexpectedError, - ); - }), - ); + this._schedulers.set(thread.getId(), _rxjsBundlesRxMinJs.Observable.timer(500).subscribe(() => { + thread.fetchCallStack(19).then(() => this._emitter.emit(CALLSTACK_CHANGED), (_utils || _load_utils()).onUnexpectedError); + })); } } else { thread.clearCallStack(); @@ -1140,97 +885,69 @@ export class Model implements IModel { this._emitter.emit(CALLSTACK_CHANGED); } - getBreakpoints(): IBreakpoint[] { - return (this._breakpoints: any); + getBreakpoints() { + return this._breakpoints; } - getBreakpointAtLine(uri: string, line: number): ?IBreakpoint { + getBreakpointAtLine(uri, line) { // Since we show calibrated breakpoints at their end line, prefer an end line // match. If there is no such breakpoint, try a start line match. - let breakpoint = this._breakpoints.find( - bp => bp.uri === uri && bp.endLine === line, - ); + let breakpoint = this._breakpoints.find(bp => bp.uri === uri && bp.endLine === line); if (breakpoint == null) { - breakpoint = this._breakpoints.find( - bp => bp.uri === uri && bp.line === line, - ); + breakpoint = this._breakpoints.find(bp => bp.uri === uri && bp.line === line); } return breakpoint; } - 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 { + setExceptionBreakpoints(data) { this._exceptionBreakpoints = data.map(d => { - const ebp = this._exceptionBreakpoints - .filter(bp => bp.filter === d.filter) - .pop(); - return new ExceptionBreakpoint( - d.filter, - d.label, - ebp ? ebp.enabled : d.default, - ); + const ebp = this._exceptionBreakpoints.filter(bp => bp.filter === d.filter).pop(); + return new ExceptionBreakpoint(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[] { - const newBreakpoints = rawData.map( - rawBp => - new Breakpoint( - uri, - rawBp.line, - rawBp.column, - rawBp.enabled, - rawBp.condition, - rawBp.hitCondition, - ), - ); + addBreakpoints(uri, rawData, fireEvent = true) { + const newBreakpoints = rawData.map(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 { - this._breakpoints = this._breakpoints.filter( - bp => !toRemove.some(r => r.getId() === bp.getId()), - ); - this._emitter.emit(BREAKPOINTS_CHANGED, {removed: toRemove}); + removeBreakpoints(toRemove) { + this._breakpoints = this._breakpoints.filter(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) { @@ -1241,17 +958,15 @@ 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); @@ -1262,19 +977,12 @@ export class Model implements IModel { return first.line - second.line; }); - this._breakpoints = distinct( - this._breakpoints, - bp => - `${bp.uri}:${bp.endLine != null ? bp.endLine : bp.line}:${bp.column}`, - ); + this._breakpoints = (0, (_collection || _load_collection()).distinct)(this._breakpoints, bp => `${bp.uri}:${bp.endLine != null ? bp.endLine : bp.line}:${bp.column}`); } - setEnablement(element: IEnableable, enable: boolean): void { - const changed: Array = []; - if ( - element.enabled !== enable && - (element instanceof Breakpoint || element instanceof FunctionBreakpoint) - ) { + setEnablement(element, enable) { + const changed = []; + if (element.enabled !== enable && (element instanceof Breakpoint || element instanceof FunctionBreakpoint)) { changed.push(element); } @@ -1283,11 +991,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); @@ -1304,29 +1012,18 @@ export class Model implements IModel { fbp.enabled = enable; }); - this._emitter.emit(BREAKPOINTS_CHANGED, {changed}); + this._emitter.emit(BREAKPOINTS_CHANGED, { changed }); } - addFunctionBreakpoint(functionName: string): FunctionBreakpoint { - const newFunctionBreakpoint = new FunctionBreakpoint( - functionName, - true, - null, - ); + addFunctionBreakpoint(functionName) { + const newFunctionBreakpoint = new FunctionBreakpoint(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()]; @@ -1340,34 +1037,32 @@ 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, - ); + this._functionBreakpoints = this._functionBreakpoints.filter(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; @@ -1375,22 +1070,22 @@ export class Model implements IModel { } } - removeWatchExpressions(id: ?string): void { - this._watchExpressions = - id != null ? this._watchExpressions.filter(we => we.getId() !== id) : []; + removeWatchExpressions(id) { + this._watchExpressions = 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 1107537e8f..73ad7627e3 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,32 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +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,46 +35,26 @@ * LICENSE file in 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'; - -// 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(); + constructor() { + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + } dispose() { this._disposables.dispose(); } - getCached( - editor: atom$TextEditor, - position: atom$Point, - ): ?Promise { - if ( - this._cachedResultRange != null && - this._cachedResultEditor === editor && - isPositionInRange(position, this._cachedResultRange) - ) { + getCached(editor, position) { + if (this._cachedResultRange != null && this._cachedResultEditor === editor && (0, (_range2 || _load_range2()).isPositionInRange)(position, this._cachedResultRange)) { return this._cachedResultPromise; } } - async get( - editor: atom$TextEditor, - position: atom$Point, - getImpl: () => Promise, - ): Promise { + async get(editor, position, getImpl) { const cached = this.getCached(editor, position); if (cached != null) { return cached; @@ -62,13 +71,10 @@ class DefinitionCache { this._disposables.remove(editorDisposables); editorDisposables.dispose(); }; - const editorDisposables = new UniversalDisposable( - editor.getBuffer().onDidChangeText(invalidateAndStopListening), - editor.onDidDestroy(invalidateAndStopListening), - ); + const editorDisposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(editor.getBuffer().onDidChangeText(invalidateAndStopListening), editor.onDidDestroy(invalidateAndStopListening)); this._disposables.add(editorDisposables); - const wordGuess = wordAtPosition(editor, position); + const wordGuess = (0, (_range || _load_range()).wordAtPosition)(editor, position); this._cachedResultRange = wordGuess && wordGuess.range; this._cachedResultEditor = editor; const promise = getImpl().then(result => { @@ -85,4 +91,4 @@ class DefinitionCache { } } -export default DefinitionCache; +exports.default = 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 b8a9be9bb2..676159bdc7 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,29 +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 strict-local - * @format - */ +'use strict'; -import analytics from 'nuclide-commons/analytics'; -import {getDefinitionPreview as getLocalFileDefinitionPreview} from 'nuclide-commons/symbol-definition-preview'; +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _analytics; -import React from 'react'; -import type {Datatip} from '../../atom-ide-datatip/lib/types'; +function _load_analytics() { + return _analytics = _interopRequireDefault(require('../../../../nuclide-commons/analytics')); +} -import type {Definition, DefinitionPreviewProvider} from './types'; +var _symbolDefinitionPreview; + +function _load_symbolDefinitionPreview() { + return _symbolDefinitionPreview = require('../../../../nuclide-commons/symbol-definition-preview'); +} -export default (async function getPreviewDatatipFromDefinition( - range: atom$Range, - definitions: Array, - definitionPreviewProvider: ?DefinitionPreviewProvider, - grammar: atom$Grammar, -): Promise { +var _react = _interopRequireDefault(require('react')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = async function getPreviewDatatipFromDefinition(range, definitions, definitionPreviewProvider, grammar) { if (definitions.length === 1) { const definition = definitions[0]; // Some providers (e.g. Flow) return negative positions. @@ -31,10 +28,7 @@ export default (async function getPreviewDatatipFromDefinition( return null; } - const definitionPreview = await getPreview( - definition, - definitionPreviewProvider, - ); + const definitionPreview = await getPreview(definition, definitionPreviewProvider); if (definitionPreview == null) { return null; @@ -44,54 +38,49 @@ export default (async function getPreviewDatatipFromDefinition( // image contents, otherwise use markedStrings if (definitionPreview.mime.startsWith('image/')) { return { - component: () => ( - - ), - range, + component: () => _react.default.createElement('img', { + src: `data:${definitionPreview.mime};${definitionPreview.encoding},${definitionPreview.contents}` + }), + range }; } return { - markedStrings: [ - { - type: 'snippet', - value: definitionPreview.contents, - grammar, - }, - ], - range, + markedStrings: [{ + type: 'snippet', + value: definitionPreview.contents, + grammar + }], + range }; } return { - markedStrings: [ - { - type: 'markdown', - value: `${definitions.length} definitions found. Click to jump.`, - grammar, - }, - ], - range, + markedStrings: [{ + type: 'markdown', + value: `${definitions.length} definitions found. Click to jump.`, + grammar + }], + range }; -}); +}; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ -async function getPreview( - definition: Definition, - definitionPreviewProvider: ?DefinitionPreviewProvider, -) { +async function getPreview(definition, definitionPreviewProvider) { let getDefinitionPreviewFn; if (definitionPreviewProvider == null) { - getDefinitionPreviewFn = getLocalFileDefinitionPreview; + getDefinitionPreviewFn = (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview; } else { - getDefinitionPreviewFn = definitionPreviewProvider.getDefinitionPreview.bind( - definitionPreviewProvider, - ); + getDefinitionPreviewFn = definitionPreviewProvider.getDefinitionPreview.bind(definitionPreviewProvider); } - return analytics.trackTiming('hyperclickPreview.getDefinitionPreview', () => - getDefinitionPreviewFn(definition), - ); -} + return (_analytics || _load_analytics()).default.trackTiming('hyperclickPreview.getDefinitionPreview', () => getDefinitionPreviewFn(definition)); +} \ 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 9cc7465626..4543eaac3e 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,165 +1,180 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 _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 _performanceNow; + +function _load_performanceNow() { + return _performanceNow = _interopRequireDefault(require('../../../../nuclide-commons/performanceNow')); +} + +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 }; } + +const TRACK_TIMING_SAMPLE_RATIO = 0.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 + */ // This package provides Hyperclick results for any language which provides a // DefinitionProvider. -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 performanceNow from 'nuclide-commons/performanceNow'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {goToLocation} from 'nuclide-commons-atom/go-to-location'; - -import DefinitionCache from './DefinitionCache'; -import getPreviewDatatipFromDefinitionResult from './getPreviewDatatipFromDefinitionResult'; - -const TRACK_TIMING_SAMPLE_RATIO = 0.1; - class Activation { - _providers: ProviderRegistry; - _definitionPreviewProvider: ?DefinitionPreviewProvider; - _definitionCache: DefinitionCache; - _disposables: UniversalDisposable; - _triggerKeys: Set; constructor() { - this._providers = new ProviderRegistry(); - this._definitionCache = new DefinitionCache(); + this._providers = new (_ProviderRegistry || _load_ProviderRegistry()).default(); + this._definitionCache = new (_DefinitionCache || _load_DefinitionCache()).default(); 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); - }, - ), - ); + 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); + })); } dispose() { this._disposables.dispose(); } - async _getDefinition( - editor: atom$TextEditor, - position: atom$Point, - ): Promise { + async _getDefinition(editor, position) { 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, + const match = (0, (_range || _load_range()).wordAtPosition)(editor, position, { + includeNonWordCharacters: false }); - result.queryRange = [ - match != null ? match.range : new Range(position, position), - ]; + result.queryRange = [match != null ? match.range : new _atom.Range(position, position)]; } return result; } } catch (err) { - getLogger('atom-ide-definitions').error( - `Error getting definition for ${String(editor.getPath())}`, - err, - ); + (0, (_log4js || _load_log4js()).getLogger)('atom-ide-definitions').error(`Error getting definition for ${String(editor.getPath())}`, err); } } return null; } - _getDefinitionCached( - editor: atom$TextEditor, - position: atom$Point, - ): Promise { + _getDefinitionCached(editor, position) { return this._definitionCache.get(editor, position, () => { - return analytics.trackTimingSampled( - 'get-definition', - () => this._getDefinition(editor, position), - TRACK_TIMING_SAMPLE_RATIO, - {path: editor.getPath()}, - ); + return (_analytics || _load_analytics()).default.trackTimingSampled('get-definition', () => this._getDefinition(editor, position), TRACK_TIMING_SAMPLE_RATIO, { path: editor.getPath() }); }); } - async getSuggestion( - editor: atom$TextEditor, - position: atom$Point, - ): Promise { - const startTime = performanceNow(); + async getSuggestion(editor, position) { + const startTime = (0, (_performanceNow || _load_performanceNow()).default)(); const result = await this._getDefinitionCached(editor, position); - const duration = performanceNow() - startTime; + const duration = (0, (_performanceNow || _load_performanceNow()).default)() - startTime; if (result == null) { return null; } - const {queryRange, definitions} = result; - invariant(definitions.length > 0); + 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. - invariant(queryRange != null); + + + if (!(queryRange != null)) { + throw new Error('Invariant violation: "queryRange != null"'); + } function createCallback(definition) { return () => { - goToLocation(definition.path, { + (0, (_goToLocation || _load_goToLocation()).goToLocation)(definition.path, { line: definition.position.row, - column: definition.position.column, + column: definition.position.column }); - analytics.track('go-to-definition', { + (_analytics || _load_analytics()).default.track('go-to-definition', { path: definition.path, line: definition.position.row, column: definition.position.column, from: editor.getPath(), - duration, + duration }); }; } function createTitle(definition) { - const filePath = - definition.projectRoot == null - ? definition.path - : nuclideUri.relative(definition.projectRoot, definition.path); + 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}`; @@ -170,7 +185,7 @@ class Activation { if (definitions.length === 1) { return { range: queryRange, - callback: createCallback(definitions[0]), + callback: createCallback(definitions[0]) }; } else { return { @@ -178,23 +193,17 @@ class Activation { callback: definitions.map(definition => { return { title: createTitle(definition), - callback: createCallback(definition), + callback: createCallback(definition) }; - }), + }) }; } } - async getPreview( - editor: atom$TextEditor, - position: atom$Point, - heldKeys: Set, - ): Promise { - if ( - !this._triggerKeys || - // are the required keys held down? - !Array.from(this._triggerKeys).every(key => heldKeys.has(key)) - ) { + async getPreview(editor, position, heldKeys) { + if (!this._triggerKeys || + // are the required keys held down? + !Array.from(this._triggerKeys).every(key => heldKeys.has(key))) { return; } @@ -209,46 +218,40 @@ class Activation { 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); + + if (!(queryRange != null)) { + throw new Error('Invariant violation: "queryRange != null"'); + } const grammar = editor.getGrammar(); - const previewDatatip = getPreviewDatatipFromDefinitionResult( - queryRange[0], - result.definitions, - this._definitionPreviewProvider, - grammar, - ); + const previewDatatip = (0, (_getPreviewDatatipFromDefinitionResult || _load_getPreviewDatatipFromDefinitionResult()).default)(queryRange[0], result.definitions, this._definitionPreviewProvider, grammar); // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) if (previewDatatip != null && previewDatatip.markedStrings) { - analytics.track('hyperclick-preview-popup', { + (_analytics || _load_analytics()).default.track('hyperclick-preview-popup', { grammar: grammar.name, - definitionCount: result.definitions.length, + 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), + modifierDatatip: (editor, bufferPosition, heldKeys) => this.getPreview(editor, bufferPosition, heldKeys) }; const disposable = service.addModifierProvider(datatipProvider); @@ -256,11 +259,11 @@ class Activation { 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) }; } } @@ -274,4 +277,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 65134d8830..a726efc43f 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 deleted file mode 100644 index 17dc6cbcd1..0000000000 --- a/modules/atom-ide-ui/pkg/atom-ide-definitions/spec/DefinitionHyperclick-spec.js +++ /dev/null @@ -1,251 +0,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. - * - * @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); - let goToLocation; - let disposables; - - beforeEach(() => { - atom.packages.activatePackage('atom-ide-definitions'); - editor = new 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; - }), - ); - }); - - afterEach(() => { - disposables.dispose(); - }); - - 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); - 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); - - expect(result).toBe(null); - expect(spy).toHaveBeenCalledWith(editor, position); - }); - }); - - it('definition - single', () => { - waitsForPromise(async () => { - const definition = { - queryRange: [new Range(new Point(1, 1), new Point(1, 5))], - definitions: [ - { - path: 'path1', - position: new Point(1, 2), - range: null, - id: 'symbol-name', - name: null, - projectRoot: null, - }, - ], - }; - const spy = spyOn(definitionProvider, 'getDefinition').andReturn( - Promise.resolve(definition), - ); - - invariant(provider != null); - invariant(provider.getSuggestion != null); - const result = await provider.getSuggestion(editor, position); - - invariant(result != null); - expect(result.range).toEqual(definition.queryRange); - expect(spy).toHaveBeenCalledWith(editor, position); - expect(goToLocation).not.toHaveBeenCalled(); - - invariant(result != null); - invariant(result.callback != null); - invariant(typeof result.callback === 'function'); - result.callback(); - expect(goToLocation).toHaveBeenCalledWith('path1', {line: 1, column: 2}); - }); - }); - - it('definition - multiple', () => { - waitsForPromise(async () => { - const defs = { - queryRange: [new Range(new Point(1, 1), new 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', - }, - ], - }; - const spy = spyOn(definitionProvider, 'getDefinition').andReturn( - Promise.resolve(defs), - ); - - invariant(provider != null); - invariant(provider.getSuggestion != null); - const result: ?HyperclickSuggestion = await provider.getSuggestion( - editor, - position, - ); - - invariant(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); - - expect(callbacks.length).toBe(3); - expect(callbacks[0].title).toBe('d1 (b/path1)'); - expect(typeof callbacks[0].callback).toBe('function'); - expect(callbacks[1].title).toBe('d2 (b/path2)'); - expect(typeof callbacks[1].callback).toBe('function'); - expect(callbacks[2].title).toBe('b/path3:4'); - expect(typeof callbacks[2].callback).toBe('function'); - - callbacks[1].callback(); - expect(goToLocation).toHaveBeenCalledWith('/a/b/path2', { - line: 3, - column: 4, - }); - }); - }); - - it('falls back to lower-priority providers', () => { - waitsForPromise(async () => { - const def = { - queryRange: [new Range(new Point(1, 1), new Point(1, 5))], - definitions: [ - { - path: 'path1', - position: new 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); - expect(result.range).toEqual(def.queryRange); - }); - }); - - it('does not cache null values', () => { - waitsForPromise(async () => { - editor.setText('test'); - const def = { - queryRange: [new Range(new Point(1, 1), new Point(1, 5))], - definitions: [ - { - path: 'path1', - position: new 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); - expect(result).toBe(null); - - newProvider.getDefinition = () => Promise.resolve(def); - invariant(provider.getSuggestion != null); - result = await provider.getSuggestion(editor, position); - invariant(result != null); - expect(result.range).toEqual(def.queryRange); - }); - }); -}); 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 6b0a068632..853238c18d 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,3 +1,108 @@ +'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. @@ -6,136 +111,57 @@ * LICENSE file in 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, - }, -}; +const WORKSPACE_VIEW_URI = exports.WORKSPACE_VIEW_URI = 'atom://nuclide/diagnostics'; + +class DiagnosticsViewModel { + + constructor(globalStates) { + _initialiseProps.call(this); -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) { // 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, + 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'); - }), - ); + 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, - ) - ) { + if (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 +170,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(); } @@ -153,10 +179,7 @@ export class DiagnosticsViewModel { // Only hide the diagnostics if it's the only item in its pane. if (pane != null) { const items = pane.getItems(); - if ( - items.length === 1 && - items[0] instanceof DiagnosticsViewModel - ) { + if (items.length === 1 && items[0] instanceof DiagnosticsViewModel) { atom.workspace.hide(this); } } @@ -166,40 +189,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; } @@ -209,37 +232,11 @@ 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'); - }; - _filterDiagnostics( - diagnostics: Array, - pattern: ?RegExp, - hiddenGroups: Set, - filterByPath: ?string, - ): Array { + _filterDiagnostics(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) { @@ -248,45 +245,65 @@ export class DiagnosticsViewModel { if (pattern == null) { return true; } - return ( - (message.text != null && pattern.test(message.text)) || - (message.html != null && pattern.test(message.html)) || - pattern.test(message.providerName) || - pattern.test(message.filePath) - ); + return message.text != null && pattern.test(message.text) || message.html != null && pattern.test(message.html) || pattern.test(message.providerName) || pattern.test(message.filePath); }); } - _selectMessage = (message: DiagnosticMessage): void => { - this._model.setState({selectedMessage: message}); - }; } -function goToDiagnosticLocation( - message: DiagnosticMessage, - options: {|focusEditor: boolean|}, -): void { +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 }); + }; +}; + +function goToDiagnosticLocation(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; } @@ -296,10 +313,5 @@ function patternsAreEqual(a: ?RegExp, b: ?RegExp) { if (a == null || b == null) { return false; } - return ( - a.source === b.source && - a.global === b.global && - a.multiline === b.multiline && - a.ignoreCase === b.ignoreCase - ); -} + return a.source === b.source && a.global === b.global && a.multiline === b.multiline && 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 21b9dacffa..a270ad93d6 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,3 +1,12 @@ +'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. @@ -6,32 +15,24 @@ * LICENSE file in 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 strict-local + * strict-local * @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 = ['review', 'errors', 'warnings', 'info', 'action']; -const PRIORITIZED_GROUPS: Array = [ - 'review', - 'errors', - 'warnings', - 'info', - 'action', -]; - -export function getGroup(message: DiagnosticMessage): DiagnosticGroup { - const {kind} = message; +function getGroup(message) { + const { kind } = message; switch (kind) { case 'lint': case null: case undefined: - invariant(message.type !== 'Hint'); + 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'; @@ -40,7 +41,7 @@ export function getGroup(message: DiagnosticMessage): DiagnosticGroup { case 'Info': return 'info'; default: - (message.type: empty); + message.type; throw new Error(`Invalid message severity: ${message.type}`); } case 'review': @@ -48,12 +49,12 @@ export function getGroup(message: DiagnosticMessage): DiagnosticGroup { case 'action': return 'action'; default: - (kind: empty); + kind; throw new Error(`Invalid message kind: ${kind}`); } } -export function getDisplayName(group: DiagnosticGroup): string { +function getDisplayName(group) { switch (group) { case 'errors': return 'Errors'; @@ -66,12 +67,12 @@ export function getDisplayName(group: DiagnosticGroup): string { case 'action': return 'Actions'; default: - (group: empty); + group; throw new Error(`Invalid group: ${group}`); } } -export function getIcon(group: DiagnosticGroup): IconName { +function getIcon(group) { switch (group) { case 'errors': return 'nuclicon-error'; @@ -84,18 +85,16 @@ export function getIcon(group: DiagnosticGroup): IconName { case 'action': return 'nuclicon-lightbulb-filled'; default: - (group: empty); + group; throw new Error(`Invalid filter type: ${group}`); } } -export function getHighestPriorityGroup( - groups: Set, -): DiagnosticGroup { +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 e8a4f70435..ef49667925 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,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 strict-local - * @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(); - }, - ), - ); + this._subscriptions.add((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 +60,28 @@ 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 +97,12 @@ 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; + let candidateTrace = this._traceIndex == null ? traces.length - 1 : this._traceIndex - 1; while (candidateTrace >= 0) { if (this.trySetCurrentTrace(traces, candidateTrace)) { return; @@ -143,7 +113,7 @@ export default class KeyboardShortcuts { this.gotoCurrentIndex(); } - currentTraces(): ?Array { + currentTraces() { if (this._index == null) { return null; } @@ -152,23 +122,31 @@ export default class KeyboardShortcuts { } // TODO: Should filter out traces whose location matches the main diagnostic's location? - trySetCurrentTrace( - traces: Array, - traceIndex: number, - ): boolean { + trySetCurrentTrace(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. + * + * strict-local + * @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 0d47fc7205..93915cba5f 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,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 strict - * @format - */ +'use strict'; -import {Observable} from 'rxjs'; - -type Point = {x: number, y: number}; - -const VECTOR_DURATION = 100; - -const distance = (a: Point, b: Point): number => { +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. + * + * strict + * @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: MouseEvent): Point => ({ +const eventToPoint = e => ({ x: e.clientX, - y: e.clientY, + 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 areHovering(element) { + return _rxjsBundlesRxMinJs.Observable.merge(_rxjsBundlesRxMinJs.Observable.fromEvent(element, 'mouseenter').mapTo(true), _rxjsBundlesRxMinJs.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 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: HTMLElement, to: HTMLElement): Observable { +function areAiming(from, to) { const [topLeft, topRight, bottomLeft, bottomRight] = findCorners(to); - const toBelowFrom = - to.getBoundingClientRect().top >= from.getBoundingClientRect().bottom; + 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]; + 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(); + 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(); } -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(); -} +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 8aacca291b..359c1d687a 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,3 +1,37 @@ +'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 _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; } } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,49 +40,23 @@ * LICENSE file in 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 strict-local + * strict-local * @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 gotoLine = (file, line) => (0, (_goToLocation || _load_goToLocation()).goToLocation)(file, { line }); + +function makeDatatipComponent(messages, diagnosticUpdater) { const fixer = message => diagnosticUpdater.applyFix(message); - return bindObservableAsProps( - observableFromSubscribeFunction(cb => - diagnosticUpdater.observeCodeActionsForMessage(cb), - ).map(codeActionsForMessage => ({ - messages, - fixer, - goToLocation: gotoLine, - codeActionsForMessage, - })), - DiagnosticsPopup, - ); + 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); } -export default (async function getDiagnosticDatatip( - editor: TextEditor, - position: atom$Point, - messagesAtPosition: Array, - diagnosticUpdater: DiagnosticUpdater, -): Promise { +exports.default = async function getDiagnosticDatatip(editor, position, messagesAtPosition, diagnosticUpdater) { let range = null; for (const message of messagesAtPosition) { if (message.range != null) { @@ -56,10 +64,14 @@ export default (async function getDiagnosticDatatip( } } diagnosticUpdater.fetchCodeActions(editor, messagesAtPosition); - invariant(range != null); + + if (!(range != null)) { + throw new Error('Invariant violation: "range != null"'); + } + return { component: makeDatatipComponent(messagesAtPosition, diagnosticUpdater), pinnable: false, - range, + range }; -}); +}; \ 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 f632c78d8a..a56c4d6829 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,3 +1,82 @@ +'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. @@ -6,33 +85,10 @@ * LICENSE file in 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, @@ -51,7 +107,7 @@ const HIGHLIGHT_CSS_LEVELS = { Error: 'diagnostics-gutter-ui-highlight-error', Warning: 'diagnostics-gutter-ui-highlight-warning', Info: 'diagnostics-gutter-ui-highlight-info', - Hint: '', + Hint: '' }; const GUTTER_CSS_GROUPS = { @@ -60,17 +116,13 @@ const GUTTER_CSS_GROUPS = { warnings: 'diagnostics-gutter-ui-gutter-warning', info: 'diagnostics-gutter-ui-gutter-info', action: 'diagnostics-gutter-ui-gutter-action', - hidden: '', + hidden: '' }; -const editorToMarkers: WeakMap> = new WeakMap(); -const itemToEditor: WeakMap = new WeakMap(); +const editorToMarkers = new WeakMap(); +const itemToEditor = new WeakMap(); -export function applyUpdateToEditor( - editor: TextEditor, - update: DiagnosticMessages, - diagnosticUpdater: DiagnosticUpdater, -): void { +function applyUpdateToEditor(editor, update, diagnosticUpdater) { let gutter = editor.gutterWithName(GUTTER_ID); if (!gutter) { // TODO(jessicalin): Determine an appropriate priority so that the gutter: @@ -84,7 +136,7 @@ export function applyUpdateToEditor( name: GUTTER_ID, visible: false, // Priority is -200 by default and 0 is the line number - priority: -1000, + priority: -1000 }); } @@ -102,8 +154,8 @@ export function applyUpdateToEditor( 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 = []; @@ -113,16 +165,10 @@ export function applyUpdateToEditor( } for (const message of update.messages) { - const wordRange = - message.range != null && message.range.isEmpty() - ? wordAtPosition(editor, message.range.start) - : null; + const wordRange = 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) { @@ -141,9 +187,7 @@ export function applyUpdateToEditor( for (let line = range.start.row; line <= range.end.row; line++) { let start; let end; - const lineText = editor.getTextInBufferRange( - new Range([line, 0], [line + 1, 0]), - ); + const lineText = editor.getTextInBufferRange(new _atom.Range([line, 0], [line + 1, 0])); if (line === range.start.row) { start = range.start.column; @@ -160,12 +204,10 @@ export function applyUpdateToEditor( end = lineText.length; } - highlightMarker = editor.markBufferRange( - new Range([line, start], [line, end]), - ); + highlightMarker = editor.markBufferRange(new _atom.Range([line, start], [line, end])); editor.decorateMarker(highlightMarker, { type: 'highlight', - class: highlightCssClass, + class: highlightCssClass }); markers.add(highlightMarker); } @@ -177,14 +219,10 @@ 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 +233,15 @@ 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} { +function createGutterItem(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 +249,61 @@ 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, - ); + const popupElement = showPopupFor(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. */ -function showPopupFor( - messages: Array, - item: HTMLElement, - goToLocation: (filePath: NuclideUri, line: number) => mixed, - diagnosticUpdater: DiagnosticUpdater, - gutter: atom$Gutter, -): HTMLElement { +function showPopupFor(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 +312,53 @@ function showPopupFor( const { bottom: itemBottom, top: itemTop, - height: itemHeight, + 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); + + 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, + height: editorHeight } = editorElement.getBoundingClientRect(); const popupElement = hostElement.firstElementChild; - invariant(popupElement instanceof HTMLElement); + + 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 +368,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 7434ddf7ce..6d0b914832 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,3 +1,129 @@ +'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 _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 _textEditor; + +function _load_textEditor() { + return _textEditor = require('../../../../nuclide-commons-atom/text-editor'); +} + +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 }; } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,156 +132,90 @@ * LICENSE file in 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 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, -|}; +class Activation { -type DiagnosticsState = {| - ...ActivationState, - diagnosticUpdater: ?DiagnosticUpdater, -|}; + constructor(state) { + var _ref; -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({ - filterByActiveTextEditor: - idx(state, _ => _.filterByActiveTextEditor) === true, - diagnosticUpdater: null, + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(this.registerOpenerAndCommand(), this._registerActionsMenu(), (0, (_showAtomLinterWarning || _load_showAtomLinterWarning()).default)()); + this._model = new (_Model || _load_Model()).default({ + filterByActiveTextEditor: ((_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; + const messagesAtPosition = this._getMessagesAtPosition(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. - atom.workspace.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. + atom.workspace.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(); @@ -163,15 +223,15 @@ 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()); } /** @@ -180,203 +240,115 @@ class Activation { * 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 { + _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: Observable< - boolean, - > = (featureConfig.observeAsStream( - 'atom-ide-diagnostics-ui.autoVisibility', - ): any); + const autoVisibilityStream = (_featureConfig || _load_featureConfig()).default.observeAsStream('atom-ide-diagnostics-ui.autoVisibility'); 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 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, - }), - ); + 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 ? _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 { - 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, - ); + registerOpenerAndCommand() { + const commandDisposable = atom.commands.add('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 { - 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, - ); - }, - ); + _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; + } + (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 { + _getMessagesAtPosition(editor, position) { const messagesForFile = this._fileDiagnostics.get(editor); if (messagesForFile == null) { return []; } - return messagesForFile.filter( - message => message.range != null && message.range.containsPoint(position), - ); + return messagesForFile.filter(message => message.range != null && message.range.containsPoint(position)); } } -function gutterConsumeDiagnosticUpdates( - diagnosticUpdater: DiagnosticUpdater, -): IDisposable { - const subscriptions = new UniversalDisposable(); - subscriptions.add( - atom.workspace.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); - }), - ); +function gutterConsumeDiagnosticUpdates(diagnosticUpdater) { + const subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + subscriptions.add(atom.workspace.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) { @@ -386,52 +358,34 @@ 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(); +function getTopMostErrorLocationsByFilePath(messages) { + const errorLocations = new Map(); messages.forEach(message => { const filePath = message.filePath; - if (nuclideUri.endsWithSeparator(filePath)) { + if ((_nuclideUri || _load_nuclideUri()).default.endsWithSeparator(filePath)) { return; } @@ -450,58 +404,27 @@ 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() - ); + return (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)), - ); +function getEditorDiagnosticUpdates(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 32ec4abd8b..bf38aaf0e9 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,110 +1,107 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict-local - * @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); +'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. + * + * strict-local + * @format + */ + +if (!(remote != null)) { + throw new Error('Invariant violation: "remote != null"'); +} const CODE_ACTIONS_TIMEOUT = 2000; -export default function showActionsMenu( - editor: TextEditor, - position: atom$Point, - messagesAtPosition: Array, - diagnosticUpdater: DiagnosticUpdater, -): IDisposable { +function showActionsMenu(editor, position, messagesAtPosition, diagnosticUpdater) { 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 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({ - x: Math.round( - boundingRect.left + pixelPosition.left - editorView.getScrollLeft(), - ), - y: Math.round( - boundingRect.top + pixelPosition.top - editorView.getScrollTop(), - ), - positioningItem: 0, - async: true, - }); - }), - ); -} + 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 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({ + x: Math.round(boundingRect.left + pixelPosition.left - editorView.getScrollLeft()), + y: Math.round(boundingRect.top + pixelPosition.top - editorView.getScrollTop()), + positioningItem: 0, + async: true + }); + })); +} \ 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 38ec763ff0..b27c8903d7 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,3 +1,32 @@ +'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. @@ -6,85 +35,52 @@ * LICENSE file in 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 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(): void { +function disableLinter() { atom.packages.disablePackage(LINTER_PACKAGE); } -function disableDiagnostics(): void { - featureConfig.set('use.atom-ide-diagnostics-ui', false); +function disableDiagnostics() { + (_featureConfig || _load_featureConfig()).default.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(); +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(); } - 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(), - ); -} + }, { + 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 caed4a0d89..3f7734bfe2 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,3 +1,14 @@ +'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. @@ -6,35 +17,19 @@ * LICENSE file in 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 strict-local + * strict-local * @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'; +function sortDiagnostics(diagnostics, sortedColumnName, sortDescending) { + const compare = SORT_FUNCTIONS[sortedColumnName]; -import invariant from 'assert'; + if (!(compare != null)) { + throw new Error('Invariant violation: "compare != null"'); + } + // Don't sort in place. -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 // ordering of "equal" items with respect to eachother. @@ -42,53 +37,19 @@ export default function sortDiagnostics( } const SORT_FUNCTIONS = { - classification: compose( - compareClassification, - compareSource, - comparePath, - compareDescription, - ), - providerName: compose( - compareSource, - compareClassification, - compareDescription, - comparePath, - ), - description: compose( - compareDescription, - compareSource, - compareClassification, - comparePath, - ), - dir: compose( - comparePath, - compareSource, - compareClassification, - compareDescription, - ), - location: compose( - compareBasename, - comparePath, - compareClassification, - compareSource, - compareDescription, - ), - line: compose( - compareBasename, - comparePath, - compareClassification, - compareSource, - compareDescription, - ), + classification: compose(compareClassification, compareSource, comparePath, compareDescription), + providerName: compose(compareSource, compareClassification, compareDescription, comparePath), + description: compose(compareDescription, compareSource, compareClassification, comparePath), + dir: compose(comparePath, compareSource, compareClassification, compareDescription), + location: compose(compareBasename, comparePath, compareClassification, compareSource, compareDescription), + line: compose(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. */ -function compose( - ...comparisons: Array -): DiagnosticsComparison { +function compose(...comparisons) { return (a, b) => { for (const compare of comparisons) { const val = compare(a, b); @@ -100,28 +61,13 @@ function compose( }; } -function compareClassification( - a: Row, - b: Row, -): number { - return ( - compareClassificationKind( - a.data.classification.kind, - b.data.classification.kind, - ) || - compareClassificationSeverity( - a.data.classification.severity, - b.data.classification.severity, - ) - ); +function compareClassification(a, b) { + return compareClassificationKind(a.data.classification.kind, b.data.classification.kind) || compareClassificationSeverity(a.data.classification.severity, b.data.classification.severity); } const KIND_ORDER = ['review', 'lint']; -function compareClassificationKind( - a: ?DiagnosticMessageKind, - b: ?DiagnosticMessageKind, -): number { +function compareClassificationKind(a, b) { const aKind = a || 'lint'; const bKind = b || 'lint'; return KIND_ORDER.indexOf(aKind) - KIND_ORDER.indexOf(bKind); @@ -129,31 +75,19 @@ function compareClassificationKind( const SEVERITY_ORDER = ['Info', 'Warning', 'Error']; -function compareClassificationSeverity( - a: DiagnosticMessageType, - b: DiagnosticMessageType, -): number { +function compareClassificationSeverity(a, b) { return SEVERITY_ORDER.indexOf(a) - SEVERITY_ORDER.indexOf(b); } -function compareSource( - a: Row, - b: Row, -): number { +function compareSource(a, b) { return compareStrings(a.data.providerName, b.data.providerName); } -function compareDescription( - a: Row, - b: Row, -): number { +function compareDescription(a, b) { return compareStrings(a.data.description.text, b.data.description.text); } -function comparePath( - a: Row, - b: Row, -): number { +function comparePath(a, b) { const aLocation = a.data.location; const bLocation = b.data.location; if (aLocation == null && bLocation == null) { @@ -169,17 +103,12 @@ function comparePath( if (pathComparison !== 0) { return pathComparison; } - const aLine = - aLocation.locationInFile == null ? 0 : aLocation.locationInFile.line; - const bLine = - bLocation.locationInFile == null ? 0 : bLocation.locationInFile.line; + const aLine = aLocation.locationInFile == null ? 0 : aLocation.locationInFile.line; + const bLine = bLocation.locationInFile == null ? 0 : bLocation.locationInFile.line; return compareNumbers(aLine, bLine); } -function compareBasename( - a: Row, - b: Row, -): number { +function compareBasename(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) { @@ -191,16 +120,13 @@ function compareBasename( if (bLocationInFile == null) { return 1; } - return ( - compareStrings(aLocationInFile.basename, bLocationInFile.basename) || - compareNumbers(aLocationInFile.line, bLocationInFile.line) - ); + return compareStrings(aLocationInFile.basename, bLocationInFile.basename) || 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 3c7575bc04..a726efc43f 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 strict-local - * @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 4465e985d5..4784202cc4 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,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 - */ +'use strict'; -import type {CodeAction} from '../../../atom-ide-code-actions/lib/types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = DiagnosticsCodeActions; -import {TextEditor} from 'atom'; -import * as React from 'react'; -import {Button} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; +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; +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 + */ -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 ( - - - - ); - })} -
+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 bf534fed7c..d9c8cce6a6 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,3 +1,38 @@ +'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. @@ -6,37 +41,19 @@ * LICENSE file in 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 strict-local + * strict-local * @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 */ -}; - 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 +61,63 @@ 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} -
+ return _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) => ( - - ))} -
+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) => { - return ( -
- {diagnosticHeader(props)} -
- -
- {traceElements(props)} - {props.children} -
+const DiagnosticsMessage = exports.DiagnosticsMessage = props => { + return _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) => { - return ( -
- - {traceElements(props)} -
+const DiagnosticsMessageNoHeader = exports.DiagnosticsMessageNoHeader = props => { + return _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 affbe472d9..9f6a54fdb8 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,3 +1,25 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DiagnosticsMessageText = undefined; +exports.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. @@ -6,37 +28,14 @@ * LICENSE file in 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, - }; +const domPurify = (0, (_dompurify || _load_dompurify()).default)(); // Exported for testing. -export function separateUrls(message: string): Array { +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. @@ -45,29 +44,27 @@ export function separateUrls(message: string): Array { 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 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], - }, - ]; + const parts = [{ + isUrl: false, + text: nonUrls[0] + }]; for (let i = 1; i < nonUrls.length; i++) { - invariant(urls != null); + 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; @@ -75,57 +72,55 @@ export function separateUrls(message: string): Array { const LEADING_WHITESPACE_RE = /^\s+/; const NBSP = '\xa0'; -function renderRowWithLinks( - message: string, - rowIndex: number, - rows: Array, -): React.Element { - const messageWithWhitespace = message.replace( - LEADING_WHITESPACE_RE, - whitespace => NBSP.repeat(whitespace.length), - ); +function renderRowWithLinks(message, rowIndex, rows) { + const messageWithWhitespace = message.replace(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} - + return _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 ( - - ); + 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)}; + const rows = 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 1401c90dec..9ee72c99f4 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,95 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 _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 _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 + */ + +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} - -
+ return _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 { +function getCodeActions(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() {}, - }, - ]; - }), - ), - ); + codeActionMaps.push(new Map(message.actions.map(action => { + return [action.title, { + async getTitle() { + return action.title; + }, + async apply() { + action.apply(); + }, + dispose() {} + }]; + }))); } if (codeActionsForMessage) { const actions = codeActionsForMessage.get(message); @@ -91,32 +97,32 @@ 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 { + const _props = this.props, + { fixer, goToLocation, codeActionsForMessage, - messages, - ...rest - } = this.props; - return ( -
- {messages.map( - renderMessage.bind(null, fixer, goToLocation, codeActionsForMessage), - )} -
+ messages + } = _props, + rest = _objectWithoutProperties(_props, ['fixer', 'goToLocation', 'codeActionsForMessage', 'messages']); + return _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 1b893bd0b0..70c12228a2 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,127 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 _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 + */ -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; // 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, -}; +class DiagnosticsTable extends _react.PureComponent { -export default class DiagnosticsTable extends React.PureComponent< - Props, - State, -> { - _previousSelectedIndex: number = -1; - _table: ?Table; - - constructor(props: Props) { + 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,7 +143,7 @@ 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,7 +153,7 @@ 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 { @@ -193,57 +164,37 @@ 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, - ]; + 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]; } // 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|} { + + _getSortOptions(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 +202,72 @@ 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, - ); + let sortedRows = this._sortRows(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 ( -
-
{ - 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} - + '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 ); } - focus(): void { + focus() { if (this._table != null) { this._table.focus(); } } - _findSelectedIndex( - selectedMessage: ?DiagnosticMessage, - rows: Array>, - ): number { + _findSelectedIndex(selectedMessage, rows) { if (selectedMessage == null) { return -1; } @@ -331,8 +276,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; @@ -352,34 +297,30 @@ export default class DiagnosticsTable extends React.PureComponent< return bestRankedIndex; } - _getRows( - diagnostics: Array, - showTraces: boolean, - ): Array> { - const diagnosticsToRows = showTraces - ? DIAGNOSTICS_TO_ROWS_TRACES_MAP - : DIAGNOSTICS_TO_ROWS_NO_TRACES_MAP; + _getRows(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); + 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); } @@ -388,36 +329,74 @@ 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); + _sortRows(rows, sortedColumn, descending) { + return (0, (_sortDiagnostics || _load_sortDiagnostics()).default)(rows, sortedColumn, descending); } } -const EmptyComponent = () => ( -
No diagnostic messages
-); +exports.default = DiagnosticsTable; + +var _initialiseProps = function () { + this._previousSelectedIndex = -1; -type Classification = { - kind: DiagnosticMessageKind, - severity: DiagnosticMessageType, + 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 } + }); + }; }; -function TypeComponent(props: {data: Classification}): React.Element { +const EmptyComponent = () => _react.createElement( + 'div', + { className: 'diagnostics-ui-empty-component' }, + 'No diagnostic messages' +); + +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 +405,16 @@ function getIconName(classification: Classification): IconName { case 'Info': return 'info'; default: - (severity: empty); + severity; throw new Error(`Invalid severity: ${severity}`); } } -function getMessageContent( - diagnostic: DiagnosticMessage, - showTraces: boolean, -): {text: string, isPlainText: boolean} { +function getMessageContent(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,64 +426,79 @@ 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; - return ( - - {basename} - :{line} - + const { basename, line } = locationInFile; + return _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; +function getLocation(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 } + } }; } @@ -518,17 +506,12 @@ function getLocation( * 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 { +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 - ) { + if (aKind !== bKind || a.providerName !== b.providerName || a.type !== b.type || aFilePath !== bFilePath) { return null; } const aRange = a.range; @@ -549,4 +532,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 562bb2448f..59e37d0aa4 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,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 strict-local - * @format - */ +'use strict'; -import type {DiagnosticTrace} from '../../../atom-ide-diagnostics/lib/types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DiagnosticsTraceItem = undefined; -import * as React from 'react'; -import {DiagnosticsMessageText} from './DiagnosticsMessageText'; +var _react = _interopRequireWildcard(require('react')); -type DiagnosticsTraceItemProps = { - trace: DiagnosticTrace, - goToLocation: (path: string, line: number) => mixed, -}; +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 +28,36 @@ 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} -
+ return _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. + * + * strict-local + * @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 c3bd83c616..570a035830 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,3 +1,102 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _analytics; + +function _load_analytics() { + return _analytics = _interopRequireDefault(require('../../../../../nuclide-commons/analytics')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../../../nuclide-commons/UniversalDisposable')); +} + +var _DiagnosticsTable; + +function _load_DiagnosticsTable() { + return _DiagnosticsTable = _interopRequireDefault(require('./DiagnosticsTable')); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +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. + */ /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,91 +105,57 @@ * LICENSE file in 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 UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import DiagnosticsTable from './DiagnosticsTable'; -import nullthrows from 'nullthrows'; -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, -}; +class DiagnosticsView extends _react.Component { + constructor(...args) { + var _temp; -/** - * Dismissable panel that displays the diagnostics from nuclide-diagnostics-store. - */ -export default class DiagnosticsView extends React.Component { - _diagnosticsTableWrapperEl: ?HTMLDivElement; - _disposables: ?UniversalDisposable; - _filterComponent: ?RegExpFilter; - _table: ?DiagnosticsTable; + 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'); + }, this._handleFocus = event => { + if (this._table == null) { + return; + } + let el = event.target; + while (el != null) { + if (el.tagName === 'INPUT' || el.tagName === 'BUTTON') { + return; + } + el = el.parentElement; + } + this._table.focus(); + }, _temp; + } - shouldComponentUpdate(nextProps: Props): boolean { + shouldComponentUpdate(nextProps) { return nextProps.isVisible; } componentDidMount() { - this._disposables = new UniversalDisposable( - atom.commands.add( - nullthrows(this._diagnosticsTableWrapperEl), - 'atom-ide:filter', - () => this._focusFilter(), - ), - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(atom.commands.add((0, (_nullthrows || _load_nullthrows()).default)(this._diagnosticsTableWrapperEl), 'atom-ide:filter', () => this._focusFilter())); } componentWillUnmount() { - nullthrows(this._disposables).dispose(); + (0, (_nullthrows || _load_nullthrows()).default)(this._disposables).dispose(); } - render(): React.Element { - const {diagnostics, showDirectoryColumn, showTraces} = this.props; + render() { + const { diagnostics, showDirectoryColumn, showTraces } = this.props; const groups = ['errors', 'warnings', 'info']; if (this.props.supportedMessageKinds.has('review')) { @@ -100,136 +165,104 @@ export default class DiagnosticsView extends React.Component { groups.push('action'); } - const showFullDescriptionToggle = diagnostics.find( - diagnostic => - // flowlint-next-line sketchy-null-string:off - diagnostic.trace || (diagnostic.text && diagnostic.text.includes('\n')), - ); + 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); - }} - /> - ))} - - (this._filterComponent = component)} - value={this.props.textFilter} - onChange={this.props.onTextFilterChange} - /> - {/* TODO: This will probably change to a dropdown to also accommodate Head Changes */} - - - - {showFullDescriptionToggle ? ( - - ) : null} - -
+ 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, { + ref: component => this._filterComponent = component, + 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( + 'div', + { + className: 'atom-ide-filterable', + ref: el => this._diagnosticsTableWrapperEl = el, + style: { display: 'flex', flexDirection: 'column' } }, + _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 + }) + ) ); } - _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( - atom.views.getView(atom.workspace), - 'diagnostics:open-all-files-with-errors', - ); - }; - - _focusFilter(): void { + _focusFilter() { if (this._filterComponent != null) { this._filterComponent.focus(); } } - _handleFocus = (event: SyntheticMouseEvent<*>): void => { - if (this._table == null) { - return; - } - let el = event.target; - while (el != null) { - if (el.tagName === 'INPUT' || el.tagName === 'BUTTON') { - return; - } - el = (el: any).parentElement; - } - this._table.focus(); - }; } +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 a78857501f..26a588aaa5 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,3 +1,26 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = FilterButton; + +var _Button; + +function _load_Button() { + return _Button = require('../../../../../nuclide-commons-ui/Button'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _GroupUtils; + +function _load_GroupUtils() { + return _GroupUtils = _interopRequireWildcard(require('../GroupUtils')); +} + +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. @@ -6,33 +29,19 @@ * LICENSE file in 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); +function FilterButton(props) { + const { selected, group } = props; + const displayName = (_GroupUtils || _load_GroupUtils()).getDisplayName(group); const title = props.selected ? `Hide ${displayName}` : `Show ${displayName}`; - return ( -
- +var _Block; + +function _load_Block() { + return _Block = require('./Block'); +} + +var _Table; + +function _load_Table() { + return _Table = require('./Table'); +} + +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 Highlight42Component = props => _react.createElement( + 'div', + { style: props.data === 42 ? { fontWeight: 'bold' } : {} }, + props.data +); /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 TableExample = () => { + const columns = [{ + title: 'first column', + key: 'first' + }, { + title: 'second column', + key: 'second', + component: Highlight42Component + }, { + title: 'third column', + key: 'third' + }, { + title: 'fourth column', + key: 'fourth' + }, { + title: 'fifth column', + key: 'fifth' + }]; + const rows = [{ + data: { + first: 1, + second: 2, + third: 3, + fourth: 33, + fifth: 123 + } + }, { + className: 'this-is-an-optional-classname', + data: { + first: 4, + second: 42, + third: 6, + fourth: 66, + fifth: 123 + } + }, { + data: { + first: 7, + second: 42, + third: undefined, + fourth: 66, + fifth: 123 + } + }]; + return _react.createElement( + (_Block || _load_Block()).Block, + null, + _react.createElement((_Table || _load_Table()).Table, { columns: columns, rows: rows, selectable: true }) ); }; -class SortableTableExample extends React.Component< - mixed, - { - rows: Array, - sortDescending: boolean, - sortedColumn: ?string, - }, -> { - constructor(props: mixed) { +class SortableTableExample extends _react.Component { + constructor(props) { 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, - }, - }, - ]; + 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, + rows }; - (this: any)._handleSort = this._handleSort.bind(this); + 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 +127,71 @@ 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} - /> - + render() { + const columns = [{ + title: 'first', + key: 'first' + }, { + title: 'second', + key: 'second' + }, { + 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 = (): React.Element => { - const columns = [ - { - title: 'first column', - key: 'first', - }, - { - title: 'second column', - key: 'second', - }, - { - title: 'third column', - key: 'third', - }, - ]; +const EmptyTableExample = () => { + const columns = [{ + title: 'first column', + key: 'first' + }, { + title: 'second column', + key: 'second' + }, { + title: 'third column', + key: 'third' + }]; const rows = []; - return ( - -
- + 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, - }, - ], -}; + examples: [{ + 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 79c5ecfd97..823165acde 100644 --- a/modules/nuclide-commons-ui/Table.js +++ b/modules/nuclide-commons-ui/Table.js @@ -1,188 +1,88 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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'; -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
-); +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; -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}; +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. -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, -|}; + /** * Design concerns: @@ -211,134 +111,108 @@ type State = {| * 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) { +class Table extends _react.Component { + + constructor(props) { super(props); - this._resizeStarts = new Subject(); + this._resizeStarts = new _rxjsBundlesRxMinJs.Subject(); this.state = { preferredColumnWidths: getInitialPreferredColumnWidths(props.columns), resizeOffset: null, tableWidth: 0, - usingKeyboard: false, + usingKeyboard: false }; } - shouldComponentUpdate(nextProps: Props, nextState: State): boolean { + shouldComponentUpdate(nextProps, nextState) { // If the state changed, we need to re-render. - if (!shallowEqual(nextState, this.state)) { + if (!(0, (_shallowequal || _load_shallowequal()).default)(nextState, this.state)) { return true; } - if (!shallowEqual(nextProps, this.props, compareCheapProps)) { + if (!(0, (_shallowequal || _load_shallowequal()).default)(nextProps, this.props, compareCheapProps)) { return true; } - if (!arrayEqual(nextProps.columns, this.props.columns, shallowEqual)) { + if (!(0, (_collection || _load_collection()).arrayEqual)(nextProps.columns, this.props.columns, (_shallowequal || _load_shallowequal()).default)) { return true; } - if (!arrayEqual(nextProps.rows, this.props.rows)) { + if (!(0, (_collection || _load_collection()).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(); - } + 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(): void { + componentWillUnmount() { this._disposables.dispose(); } - componentDidUpdate(prevProps: Props, prevState: State): void { - if ( - this._tableBody != null && - this.props.selectedIndex != null && - this.props.selectedIndex !== prevProps.selectedIndex - ) { + 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) { - scrollIntoViewIfNeeded(selectedRow); + (0, (_scrollIntoView || _load_scrollIntoView()).scrollIntoViewIfNeeded)(selectedRow); } } if (this.state.usingKeyboard !== prevState.usingKeyboard) { @@ -346,18 +220,14 @@ export class Table extends React.Component, State> { this._mouseMoveDisposable.dispose(); } if (this.state.usingKeyboard) { - this._mouseMoveDisposable = new UniversalDisposable( - Observable.fromEvent(document, 'mousemove') - .take(1) - .subscribe(() => { - this.setState({usingKeyboard: false}); - }), - ); + this._mouseMoveDisposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(_rxjsBundlesRxMinJs.Observable.fromEvent(document, 'mousemove').take(1).subscribe(() => { + this.setState({ usingKeyboard: false }); + })); } } } - focus(): void { + focus() { if (this._tableBody == null) { return; } @@ -372,46 +242,34 @@ export class Table extends React.Component, State> { this._tableBody.focus(); } - componentWillReceiveProps(nextProps: Props): void { + 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. - !areSetsEqual( - new Set(currentColumns.map(column => column.key)), - new Set(nextColumns.map(column => column.key)), - ) - ) { + 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), + preferredColumnWidths: getInitialPreferredColumnWidths(nextColumns) }); } } - _moveSelection(offset: -1 | 1, event: SelectionEvent): void { - const {selectedIndex} = this.props; + _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), - ); + const nextSelectedIndex = Math.max(0, Math.min(this.props.rows.length - 1, selectedIndex + offset)); if (nextSelectedIndex === selectedIndex) { return; } - this._selectRow({index: nextSelectedIndex, event}); + 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; + _selectRow(options) { + const { index: selectedIndex, event, confirm } = options; + const { onSelect, onWillSelect, rows } = this.props; if (onSelect == null) { return; } @@ -428,45 +286,40 @@ export class Table extends React.Component, State> { } } - _handleSortByColumn(sortedBy: $Keys): void { - const {onSort, sortDescending, sortedColumn} = this.props; + _handleSortByColumn(sortedBy) { + const { onSort, sortDescending, sortedColumn } = this.props; if (onSort == null) { return; } - onSort( - sortedBy, - sortDescending == null || sortedBy !== sortedColumn - ? false - : !sortDescending, - ); + onSort(sortedBy, sortDescending == null || sortedBy !== sortedColumn ? false : !sortDescending); } // Just a bound version of the `_calculateColumnWidths` function for convenience. - _calculateColumnWidths(): PercentageWidthMap { + _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, + resizeOffset: this.state.resizeOffset }); } - _renderEmptyCellContent(): React.Element { - return
; + _renderEmptyCellContent() { + return _react.createElement('div', null); } - render(): React.Node { - return ( -
(this._rootNode = rootNode)}> - {this._renderContents()} -
+ render() { + return _react.createElement( + 'div', + { + className: this.props.className, + ref: rootNode => this._rootNode = rootNode }, + this._renderContents() ); } - _renderContents(): React.Node { + _renderContents() { if (this.state.tableWidth === 0) { // We don't have the table width yet so we can't render the columns. return null; @@ -483,85 +336,80 @@ export class Table extends React.Component, State> { selectedIndex, sortable, sortedColumn, - sortDescending, + 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 = ( - - - - ); - } + 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(); } - return ( -
- {title} - {sortIndicator} - {resizer} -
+ }); + } + 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 { className: rowClassName, data, rowAttributes } = row; const renderedRow = columns.map((column, j) => { const { key, cellClassName, component: Component, - shouldRightAlign, + shouldRightAlign } = column; let datum = data[key]; if (Component != null) { - datum = ; + datum = _react.createElement(Component, { data: datum }); } else if (datum == null) { datum = this._renderEmptyCellContent(); } @@ -570,127 +418,123 @@ export class Table extends React.Component, State> { if (width != null) { cellStyle.width = `${width * 100}%`; } - return ( -
- {datum} -
+ '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 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} -
+ '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 = ; + body = _react.createElement(EmptyComponent, null); } const scrollableBodyStyle = {}; if (maxBodyHeight != null) { scrollableBodyStyle.maxHeight = maxBodyHeight; scrollableBodyStyle.overflowY = 'auto'; } - const bodyClassNames = classnames( - 'nuclide-ui-table', - 'nuclide-ui-table-body', + 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', { - // 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}
-
, -
{ + key: 'body', + style: scrollableBodyStyle, + onFocus: event => { if (this.props.onBodyFocus != null) { this.props.onBodyFocus(event); } - }} - onBlur={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} -
-
, - ]; + }, + className: bodyClassNames, + tabIndex: '-1' }, + body + ) + )]; } } -/** - * Get the initial size of each column as a percentage of the total. - */ -function getInitialPreferredColumnWidths( - columns: Array>, -): PercentageWidthMap { +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; + const { key, width } = column; if (width != null) { columnWidthRatios[key] = width; assignedWidth += width; @@ -705,11 +549,10 @@ function getInitialPreferredColumnWidths( return columnWidthRatios; } -function getMinWidths(columns: Array>): PixelWidthMap { +function getMinWidths(columns) { const minWidths = {}; columns.forEach(column => { - minWidths[column.key] = - column.minWidth == null ? DEFAULT_MIN_COLUMN_WIDTH : column.minWidth; + minWidths[column.key] = column.minWidth == null ? DEFAULT_MIN_COLUMN_WIDTH : column.minWidth; }); return minWidths; } @@ -718,21 +561,15 @@ function getMinWidths(columns: Array>): PixelWidthMap { * 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 { +function _calculateColumnWidths(options) { const { preferredWidths, minWidths: minWidthsPx, tableWidth, columnOrder, - resizeOffset: resizeOffset_, + resizeOffset: resizeOffset_ } = options; - const resizeOffset = resizeOffset_ || {deltaPx: 0, resizerLocation: 0}; + const resizeOffset = resizeOffset_ || { deltaPx: 0, resizerLocation: 0 }; const widthsPx = {}; // Calculate the pixel widths of each column given its desired percentage width and minimum pixel @@ -742,16 +579,12 @@ export function _calculateColumnWidths(options: { 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]; - }), - ); + 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; @@ -782,14 +615,11 @@ export function _calculateColumnWidths(options: { { // Adjust the column widths according to the resized column. - const {deltaPx, resizerLocation} = resizeOffset; + 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 [shrinkingColumns, growingColumn] = deltaPx < 0 ? [leftColumns.reverse(), rightColumns[0]] : [rightColumns, leftColumns[leftColumns.length - 1]]; const targetChange = Math.abs(deltaPx); let cumulativeChange = 0; @@ -832,13 +662,9 @@ export function _calculateColumnWidths(options: { * 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); +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). @@ -850,7 +676,10 @@ export function _calculatePreferredColumnWidths(options: { 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'); + 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. @@ -882,7 +711,7 @@ export function _calculatePreferredColumnWidths(options: { * 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 { +function compareCheapProps(a, b, key) { switch (key) { case undefined: // This is a magic way of telling `shallowEqual()` to use the default comparison for the @@ -895,4 +724,4 @@ function compareCheapProps(a: mixed, b: mixed, key: ?string): ?boolean { 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 8d47ef8ebb..1dd0b2e876 100644 --- a/modules/nuclide-commons-ui/Tabs.example.js +++ b/modules/nuclide-commons-ui/Tabs.example.js @@ -1,84 +1,117 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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'; -import * as React from 'react'; -import {Block} from './Block'; -import Tabs from './Tabs'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.TabExamples = undefined; -const tabs = [ - { - name: 'one', - tabContent:
One
, - }, - { - name: 'two', - tabContent:
Two
, - }, - { - name: 'three', - tabContent:
Three
, - }, - { - name: 'four', - tabContent:
Four
, - }, - { - name: 'five', - tabContent:
Five
, - }, -]; +var _react = _interopRequireWildcard(require('react')); -class TabExample extends React.Component { - constructor(props: any) { +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: _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', + activeTabName: 'one' }; } - handleTabChange = (newTabName: { - name: string, - tabContent: React.Element, - }): void => { - this.setState({ - activeTabName: newTabName.name, - }); - }; - - render(): React.Node { - const {activeTabName} = this.state; - return ( - - -
- Showing content for tab "{activeTabName}". -
-
+ render() { + const { activeTabName } = this.state; + return _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, + '".' + ) ); } } -export const TabExamples = { +const TabExamples = exports.TabExamples = { sectionName: 'Tabs', description: '', - examples: [ - { - title: '', - component: TabExample, - }, - ], -}; + examples: [{ + 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 a8a736fdc9..4d6b021f7e 100644 --- a/modules/nuclide-commons-ui/Tabs.js +++ b/modules/nuclide-commons-ui/Tabs.js @@ -1,86 +1,97 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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'; -import type {IconName} from './Icon'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -import {Icon} from './Icon'; -import * as React from 'react'; -import classnames from 'classnames'; -import nullthrows from 'nullthrows'; +var _Icon; -export type Tab = { - name: string, - icon?: IconName, - tabContent: React.Element, -}; +function _load_Icon() { + return _Icon = require('./Icon'); +} -type Props = { - tabs: Array, - activeTabName: ?string, - closeable: boolean, - onActiveTabChange: (tab: Tab) => void, - onClose?: () => void, - triggeringEvent: string, - growable?: boolean, -}; +var _react = _interopRequireWildcard(require('react')); -export default class Tabs extends React.Component { - static defaultProps = { - closeable: false, - triggeringEvent: 'onClick', - growable: false, - }; +var _classnames; - _handleTabChange = (selectedTabName: string) => { - if (typeof this.props.onActiveTabChange === 'function') { - this.props.onActiveTabChange( - nullthrows(this.props.tabs.find(tab => tab.name === selectedTabName)), - ); - } - }; +function _load_classnames() { + return _classnames = _interopRequireDefault(require('classnames')); +} - _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( - this, - tab.name, - ); - return ( -
  • -
    - {icon} - {tab.tabContent} -
    - {closeButton} -
  • +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 _react.createElement( + 'li', + Object.assign({ + className: (0, (_classnames || _load_classnames()).default)({ + tab: true, + active: this.props.activeTabName === tab.name, + growable: this.props.growable + }), + key: tab.name, + title: tab.name + }, handler), + _react.createElement( + 'div', + { className: 'title' }, + icon, + tab.tabContent + ), + closeButton + ); + }); + return _react.createElement( + 'ul', + { className: 'tab-bar list-inline inset-panel' }, + tabs ); - }); - return
      {tabs}
    ; - }; + }, _temp; + } - render(): React.Node { - return
    {this._renderTabMenu()}
    ; + 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', + growable: false +}; \ No newline at end of file diff --git a/modules/nuclide-commons-ui/TextEditorBanner.js b/modules/nuclide-commons-ui/TextEditorBanner.js index 6386021afd..52127efef4 100644 --- a/modules/nuclide-commons-ui/TextEditorBanner.js +++ b/modules/nuclide-commons-ui/TextEditorBanner.js @@ -1,3 +1,30 @@ +'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. @@ -6,64 +33,68 @@ * LICENSE file in 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; +class TextEditorBanner { + + constructor(editor) { + this.render = reactElement => { + this.renderUnstyled(_react.createElement( + 'div', + { className: 'nuclide-ui-text-editor-banner-element' }, + reactElement + )); + }; + + this.renderUnstyled = reactElement => { + _reactDom.default.render(_react.createElement( + 'div', + { className: 'nuclide-ui-text-editor-banner' }, + reactElement, + _react.createElement('div', { + // eslint-disable-next-line nuclide-internal/jsx-simple-callback-refs + ref: ref => this._updateTextEditorElement(ref), + className: 'nuclide-ui-text-editor-banner-editor' + }) + ), this._element); + }; - constructor(editor: atom$TextEditor | AtomTextEditor) { this._editor = editor; const editorElement = editor.getElement().firstChild; this._element = document.createElement('div'); this._element.className = 'nuclide-ui-text-editor-banner-container'; - invariant( - editorElement instanceof HTMLElement && editorElement.parentNode != null, - ); + if (!(editorElement instanceof HTMLElement && editorElement.parentNode != null)) { + throw new Error('Invariant violation: "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,54 +110,30 @@ 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): void => { - this.renderUnstyled( -
    - {reactElement} -
    , - ); - }; - - renderUnstyled = (reactElement: React.Element): void => { - ReactDOM.render( -
    - {reactElement} -
    this._updateTextEditorElement(ref)} - className="nuclide-ui-text-editor-banner-editor" - /> -
    , - this._element, - ); - }; - hide() { this.dispose(); } } -type NoticeProps = { - messageType: MessageType, - children: React.Node, -}; - -export class Notice extends React.Component { +exports.TextEditorBanner = TextEditorBanner; +class Notice extends _react.Component { render() { - return ( -
    - -
    - {this.props.children} -
    -
    -
    + return _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 466153f3a3..600251c7ce 100644 --- a/modules/nuclide-commons-ui/TextInputs.example.js +++ b/modules/nuclide-commons-ui/TextInputs.example.js @@ -1,125 +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 - */ +'use strict'; -import {TextBuffer} from 'atom'; -import * as React from 'react'; -import {Block} from './Block'; -import {AtomInput} from './AtomInput'; -import {AtomTextEditor} from './AtomTextEditor'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.TextInputExamples = undefined; -const AtomInputExample = (): React.Element => ( -
    - - - - - - - - - - - - - - - - - - - - - -
    -); +var _atom = require('atom'); + +var _react = _interopRequireWildcard(require('react')); + +var _Block; + +function _load_Block() { + return _Block = require('./Block'); +} + +var _AtomInput; -const buffer1 = new TextBuffer({ - text: '/**\n * Hi!\n */\n\n// I am a TextBuffer.\nconst a = 42;', +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 TextBuffer({ - text: - '/**\n * Hi!\n */\n\n// I am a read-only, gutter-less 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)', + boxShadow: '0 0 20px 0 rgba(0, 0, 0, 0.3)' }; -const AtomTextEditorExample = (): React.Element => ( - -
    - -
    -
    - -
    -
    +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 + }) + ) ); -export const TextInputExamples = { +const TextInputExamples = exports.TextInputExamples = { sectionName: 'Text Inputs', description: '', - examples: [ - { - title: 'AtomInput', - component: AtomInputExample, - }, - { - title: 'AtomTextEditor', - component: AtomTextEditorExample, - }, - ], -}; + examples: [{ + 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 2a33a4cab7..dc8dae4cd8 100644 --- a/modules/nuclide-commons-ui/TextRenderer.js +++ b/modules/nuclide-commons-ui/TextRenderer.js @@ -1,35 +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 - */ +'use strict'; -import * as React from 'react'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.TextRenderer = TextRenderer; -/* Evaluation & values */ -export type EvaluationResult = { - type: string, - // Either: - value?: string, - // Or: - description?: string, - objectId?: string, - subtype?: string, -}; +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; } } -export function TextRenderer( - evaluationResult: EvaluationResult, -): ?React.Element { - const {type, value} = evaluationResult; +/* 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 c95516af94..a4d3bffa34 100644 --- a/modules/nuclide-commons-ui/Toggle.js +++ b/modules/nuclide-commons-ui/Toggle.js @@ -1,70 +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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Toggle = undefined; -import * as React from 'react'; -import classnames from 'classnames'; +var _react = _interopRequireWildcard(require('react')); -import ignoreTextSelectionEvents from './ignoreTextSelectionEvents'; +var _classnames; -type DefaultProps = { - disabled: boolean, - onClick: (event: SyntheticEvent<>) => mixed, -}; +function _load_classnames() { + return _classnames = _interopRequireDefault(require('classnames')); +} + +var _ignoreTextSelectionEvents; -type Props = { - className?: string, - toggled: boolean, - disabled: boolean, - label: ?string, - onChange: (isToggled: boolean) => mixed, - onClick: (event: SyntheticEvent<>) => mixed, -}; +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) {}, - }; +class Toggle extends _react.Component { + constructor(...args) { + var _temp; - _onChange = (event: SyntheticEvent<>) => { - const isToggled = ((event.target: any): HTMLInputElement).checked; - this.props.onChange.call(null, isToggled); - }; + return _temp = super(...args), this._onChange = event => { + const isToggled = event.target.checked; + this.props.onChange.call(null, isToggled); + }, _temp; + } - render(): React.Node { - const {className, disabled, label, onClick, toggled} = this.props; - const text = - label === '' ? null : ( - {label} - ); - return ( - + render() { + const { className, disabled, label, onClick, toggled } = this.props; + const text = 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 f809387407..e6f250576e 100644 --- a/modules/nuclide-commons-ui/Toolbar.example.js +++ b/modules/nuclide-commons-ui/Toolbar.example.js @@ -1,97 +1,187 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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. -
    -
    -
    -); +'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.Element => ( - - - -
    Example of {''}.
    -
    -
    -
    +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.Element => ( - - - -
    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.Element => ( - - - -
    You can combine
    -
    - -
    the various kinds
    -
    - -
    of aligners.
    -
    -
    -
    +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.' + ) + ) + ) ); -export const ToolbarExamples = { +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, - }, - ], -}; + examples: [{ + 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 8c1579c35f..72829c8865 100644 --- a/modules/nuclide-commons-ui/Toolbar.js +++ b/modules/nuclide-commons-ui/Toolbar.js @@ -1,37 +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 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 1b99e08af7..3561eabced 100644 --- a/modules/nuclide-commons-ui/ToolbarCenter.js +++ b/modules/nuclide-commons-ui/ToolbarCenter.js @@ -1,24 +1,31 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict - * @format - */ +"use strict"; -import * as React from 'react'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ToolbarCenter = undefined; -type Props = { - children?: mixed, -}; +var _react = _interopRequireWildcard(require("react")); -export const ToolbarCenter = (props: Props) => { +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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons-ui/ToolbarLeft.js b/modules/nuclide-commons-ui/ToolbarLeft.js index f85c106019..57e5ebbabd 100644 --- a/modules/nuclide-commons-ui/ToolbarLeft.js +++ b/modules/nuclide-commons-ui/ToolbarLeft.js @@ -1,24 +1,31 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict - * @format - */ +"use strict"; -import * as React from 'react'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ToolbarLeft = undefined; -type Props = { - children?: mixed, -}; +var _react = _interopRequireWildcard(require("react")); -export const ToolbarLeft = (props: Props) => { +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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons-ui/ToolbarRight.js b/modules/nuclide-commons-ui/ToolbarRight.js index 33f2c0c6f1..0e69ba0b10 100644 --- a/modules/nuclide-commons-ui/ToolbarRight.js +++ b/modules/nuclide-commons-ui/ToolbarRight.js @@ -1,24 +1,31 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict - * @format - */ +"use strict"; -import * as React from 'react'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ToolbarRight = undefined; -type Props = { - children?: mixed, -}; +var _react = _interopRequireWildcard(require("react")); -export const ToolbarRight = (props: Props) => { +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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons-ui/ToolbarUtils.js b/modules/nuclide-commons-ui/ToolbarUtils.js index 4cafe95f17..76bd28fe16 100644 --- a/modules/nuclide-commons-ui/ToolbarUtils.js +++ b/modules/nuclide-commons-ui/ToolbarUtils.js @@ -1,32 +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 strict - * @format - */ +'use strict'; -import humanizeKeystroke from 'nuclide-commons/humanizeKeystroke'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.makeToolbarButtonSpec = makeToolbarButtonSpec; -export function makeToolbarButtonSpec( - options: toolbar$ButtonSpec, -): toolbar$ButtonSpec { +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. + * + * strict + * @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 88a41a2647..c3dc8a50e7 100644 --- a/modules/nuclide-commons-ui/Tree.example.js +++ b/modules/nuclide-commons-ui/Tree.example.js @@ -1,3 +1,32 @@ +'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. @@ -6,88 +35,166 @@ * LICENSE file in 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 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.Element => ( - - - A Directory}> - Nested Directory}> - - File one - - - Collapsed Nested Directory}> - - File one - - - - File one - - - File three .selected! - - - - .icon-file-text - - - .icon-file-symlink-file - - - +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' + ) + ) + ) ); -export const TreeExamples = { +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, - }, - ], + examples: [{ + title: 'Basic Tree', + component: BasicTreeExample + }, { + title: 'Reproducing the Atom style guide example:', + component: AtomStyleguideTreeExample + }] }; function handleSelect() { @@ -98,4 +205,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 5db9e9db89..a0df2d5792 100644 --- a/modules/nuclide-commons-ui/Tree.js +++ b/modules/nuclide-commons-ui/Tree.js @@ -1,57 +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 - */ +'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 */ -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 ( -
      - ); +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)); } -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); +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 +71,56 @@ export class TreeItem extends React.Component { onMouseEnter, onMouseLeave, path, - name, + 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. + return _react.createElement( + 'li', + { + 'aria-selected': selected, + className: (0, (_classnames || _load_classnames()).default)(className, { + selected + }, '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 ); } } -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; - } - - invariant(e.target instanceof Element); - if (e.target.closest('.list-item') === itemNode) { - handleClick.call(this, e); - } - }; +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 +129,54 @@ export class NestedTreeItem extends React.Component { selected, collapsed, title, - children, + children } = this.props; - return ( -
    3. - {title == null ? null : ( -
      (this._itemNode = node)}> - {title} -
      - )} - {children} -
    4. + return _react.createElement( + 'li', + { + 'aria-selected': selected, + 'aria-expanded': !collapsed, + className: (0, (_classnames || _load_classnames()).default)(className, { + selected, + 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 + ) ); } } -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} -
      +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: SyntheticMouseEvent<>): void { - const {onSelect, onConfirm, onTripleClick} = this.props; +function handleClick(e) { + const { onSelect, onConfirm, onTripleClick } = this.props; const numberOfClicks = e.detail; switch (numberOfClicks) { @@ -205,4 +192,4 @@ function handleClick(e: SyntheticMouseEvent<>): void { default: break; } -} +} \ No newline at end of file diff --git a/modules/nuclide-commons-ui/TruncatedButton.js b/modules/nuclide-commons-ui/TruncatedButton.js index 3731eef2e3..df5890a02b 100644 --- a/modules/nuclide-commons-ui/TruncatedButton.js +++ b/modules/nuclide-commons-ui/TruncatedButton.js @@ -1,40 +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 strict-local - * @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; - return ( - +'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. + * + * strict-local + * @format + */ + +class TruncatedButton extends _react.Component { + render() { + const _props = this.props, + { children, className, label } = _props, + props = _objectWithoutProperties(_props, ['children', 'className', 'label']); + return _react.createElement( + (_Button || _load_Button()).Button, + Object.assign({ + className: (0, (_classnames || _load_classnames()).default)('btn-block', 'nuclide-ui-truncated-button', 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 ee10f216d8..edf263b066 100644 --- a/modules/nuclide-commons-ui/UnstyledButton.js +++ b/modules/nuclide-commons-ui/UnstyledButton.js @@ -1,37 +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 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(); +'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; } - _setRef = (node: ?HTMLButtonElement) => (this._node = node); + focus() { + (0, (_nullthrows || _load_nullthrows()).default)(this._node).focus(); + } - render(): React$Element { - const {className, ...props} = this.props; - const classes = classnames('nuclide-ui-unstyled-button', className); + 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 nuclide-internal/use-nuclide-ui-components - return ; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ModalExamples = undefined; + +var _react = _interopRequireWildcard(require('react')); + +var _Button; + +function _load_Button() { + return _Button = require('./Button'); } +var _showModal; + +function _load_showModal() { + return _showModal = _interopRequireDefault(require('./showModal')); +} + +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 ModalButton() { + 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. + * + * strict-local + * @format + */ + 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! -
      - -
      + (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' + ) ); }); } -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, - }, - ], -}; + examples: [{ + 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 26b42bd00f..28b602229c 100644 --- a/modules/nuclide-commons-ui/showModal.js +++ b/modules/nuclide-commons-ui/showModal.js @@ -1,3 +1,48 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = 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. @@ -6,161 +51,106 @@ * LICENSE file in 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'; - -/** - * 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 { +function showModal(contentFactory, options = defaults) { const hostElement = document.createElement('div'); const atomPanel = atom.workspace.addModalPanel({ item: hostElement, priority: options.priority, - className: options.className, + className: options.className }); - const shouldDismissOnClickOutsideModal = - options.shouldDismissOnClickOutsideModal || (() => true); - const shouldDismissOnPressEscape = - options.shouldDismissOnPressEscape || (() => true); + 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(); - } - }, - ); + 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(); + } + }); return disposable; } /** Flow makes {} an unsealed object (eyeroll) */ -const defaults: Options = Object.freeze({}); - -type Props = { - children?: any, -}; +const defaults = Object.freeze({}); /** * 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 { - return ( -
      - - {this.props.children} - -
      +class ModalContainer extends _react.Component { + render() { + return _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 // does not support the autofocus attribute. + + if (!node.contains(document.activeElement)) { node.focus(); } } -} +} \ No newline at end of file diff --git a/modules/nuclide-commons/AbortController.js b/modules/nuclide-commons/AbortController.js index 09437905a2..58e6f616aa 100644 --- a/modules/nuclide-commons/AbortController.js +++ b/modules/nuclide-commons/AbortController.js @@ -1,32 +1,24 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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'; -/** - * 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. - */ +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AbortSignal = undefined; -// 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'; +var _eventTargetShim; + +function _load_eventTargetShim() { + return _eventTargetShim = require('event-target-shim'); +} + +class AbortSignal extends (_eventTargetShim || _load_eventTargetShim()).EventTarget { + constructor(...args) { + var _temp; -export class AbortSignal extends (EventTargetShim: typeof EventTarget) { - aborted: boolean = false; + 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]() { @@ -34,10 +26,33 @@ export class AbortSignal extends (EventTargetShim: typeof EventTarget) { } } -defineEventAttribute(AbortSignal.prototype, 'abort'); +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'); -export default class AbortController { - signal = new AbortSignal(); +class AbortController { + constructor() { + this.signal = new AbortSignal(); + } abort() { // From whatwg spec, section 3.2: @@ -49,7 +64,7 @@ export default class AbortController { 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)); + this.signal.dispatchEvent({ type: 'abort' }); } // $FlowIssue: Computed properties are not supported @@ -57,3 +72,4 @@ export default class AbortController { 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 8840d433bf..789a1c3733 100644 --- a/modules/nuclide-commons/BatchProcessedQueue.js +++ b/modules/nuclide-commons/BatchProcessedQueue.js @@ -1,33 +1,22 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict - * @format - */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); -export type BatchHandler = (batch: Array) => void; // 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,7 +33,7 @@ export default class BatchProcessedQueue { this._handler(batch); } - dispose(): void { + dispose() { // eslint-disable-next-line eqeqeq if (this._timeoutId !== null) { clearTimeout(this._timeoutId); @@ -52,3 +41,14 @@ export default class BatchProcessedQueue { } } } +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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/ConfigCache.js b/modules/nuclide-commons/ConfigCache.js index cd3429eadb..0493603819 100644 --- a/modules/nuclide-commons/ConfigCache.js +++ b/modules/nuclide-commons/ConfigCache.js @@ -1,3 +1,36 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ConfigCache = undefined; + +var _lruCache; + +function _load_lruCache() { + return _lruCache = _interopRequireDefault(require('lru-cache')); +} + +var _collection; + +function _load_collection() { + return _collection = require('./collection'); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('./fsPromise')); +} + +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. @@ -6,38 +39,22 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type {LRUCache} from 'lru-cache'; -import type {NuclideUri} from './nuclideUri'; +class ConfigCache { -import LRU from 'lru-cache'; -import {findSubArrayIndex} from './collection'; -import fsPromise from './fsPromise'; -import nuclideUri from './nuclideUri'; - -export type SearchStrategy = 'nearest' | 'furthest' | 'priority' | 'pathMatch'; - -export class ConfigCache { - _configPatterns: Array; - _searchStrategy: SearchStrategy; - _configCache: LRUCache>; - - constructor( - configPatterns: Array, - searchStrategy?: SearchStrategy = 'nearest', - ) { + constructor(configPatterns, searchStrategy = 'nearest') { this._configPatterns = configPatterns; 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); @@ -46,16 +63,14 @@ export class ConfigCache { return result; } - async _findConfigDir(path: NuclideUri): Promise { - const configDirs = await Promise.all( - this._configPatterns.map(configFile => { - if (this._searchStrategy === 'furthest') { - return fsPromise.findFurthestFile(configFile, path); - } else { - return fsPromise.findNearestFile(configFile, path); - } - }), - ); + async _findConfigDir(path) { + const configDirs = await Promise.all(this._configPatterns.map(configFile => { + if (this._searchStrategy === 'furthest') { + return (_fsPromise || _load_fsPromise()).default.findFurthestFile(configFile, path); + } else { + return (_fsPromise || _load_fsPromise()).default.findNearestFile(configFile, path); + } + })); if (this._searchStrategy === 'nearest') { // Find the result with the greatest length (the closest match). @@ -74,25 +89,20 @@ export class ConfigCache { }, null); } else if (this._searchStrategy === 'pathMatch') { // Find the first occurrence of a config segment in the path. - const pathSplit = nuclideUri.split(path); - return this._configPatterns - .map(configPattern => { - const configSplit = nuclideUri.split(configPattern); - const foundIndex = findSubArrayIndex(pathSplit, configSplit); - return foundIndex !== -1 - ? nuclideUri.join( - ...pathSplit.slice(0, foundIndex + configSplit.length), - ) - : null; - }) - .find(Boolean); + const pathSplit = (_nuclideUri || _load_nuclideUri()).default.split(path); + return this._configPatterns.map(configPattern => { + const configSplit = (_nuclideUri || _load_nuclideUri()).default.split(configPattern); + const foundIndex = (0, (_collection || _load_collection()).findSubArrayIndex)(pathSplit, configSplit); + return foundIndex !== -1 ? (_nuclideUri || _load_nuclideUri()).default.join(...pathSplit.slice(0, foundIndex + configSplit.length)) : null; + }).find(Boolean); } 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 bc32d51727..ec91e96d4b 100644 --- a/modules/nuclide-commons/Hasher.js +++ b/modules/nuclide-commons/Hasher.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,7 +11,7 @@ * LICENSE file in 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 strict + * strict * @format */ @@ -29,34 +34,30 @@ * } * } */ -export default class Hasher { - _hashes: WeakMap; - _objectCount: number; +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': @@ -69,3 +70,4 @@ export default class Hasher { } } } +exports.default = Hasher; \ No newline at end of file diff --git a/modules/nuclide-commons/Model.js b/modules/nuclide-commons/Model.js index ff3a12e706..b4e13e1b75 100644 --- a/modules/nuclide-commons/Model.js +++ b/modules/nuclide-commons/Model.js @@ -1,19 +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'; -import type {Observable} from 'rxjs'; +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('./UniversalDisposable')); +} -import {BehaviorSubject} from 'rxjs'; -import UniversalDisposable from './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 @@ -52,27 +51,37 @@ import UniversalDisposable from './UniversalDisposable'; * 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; +class Model { - constructor(initialState: State) { - this._states = new BehaviorSubject(initialState); + 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 fa99ad202c..25cbd32e11 100644 --- a/modules/nuclide-commons/ObservablePool.js +++ b/modules/nuclide-commons/ObservablePool.js @@ -1,25 +1,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. - * - * @flow strict - * @format - */ +'use strict'; -import {Observable, Subject} from 'rxjs'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -type Executor = Observable | (() => rxjs$ObservableInput); - -type Request = {tag: mixed, executor: Executor}; - -type Response = { - observer: rxjs$Observer, - unsubscribed: Subject, -}; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); /** * ObservablePool allows you to execute Observables or functions that return @@ -52,23 +37,20 @@ type Response = { * 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; +class ObservablePool { - constructor(concurrency: number) { - this._requests = new Subject(); + 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(); @@ -80,53 +62,55 @@ export default class ObservablePool { * 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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/SafeStreamMessageReader.js b/modules/nuclide-commons/SafeStreamMessageReader.js index 0e5ba69ad7..5de4bba79a 100644 --- a/modules/nuclide-commons/SafeStreamMessageReader.js +++ b/modules/nuclide-commons/SafeStreamMessageReader.js @@ -1,16 +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 strict - * @format - */ +'use strict'; -import {StreamMessageReader} from 'vscode-jsonrpc'; +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! @@ -19,8 +17,8 @@ import {StreamMessageReader} from 'vscode-jsonrpc'; * * https://github.com/Microsoft/vscode-languageserver-node/issues/270 */ -export default class SafeStreamMessageReader extends StreamMessageReader { - onData(data: Buffer | string) { +class SafeStreamMessageReader extends (_vscodeJsonrpc || _load_vscodeJsonrpc()).StreamMessageReader { + onData(data) { try { super.onData(data); } catch (err) { @@ -32,3 +30,14 @@ export default class SafeStreamMessageReader extends StreamMessageReader { } } } +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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/SimpleCache.js b/modules/nuclide-commons/SimpleCache.js index a4bda05177..c2d49b1d5c 100644 --- a/modules/nuclide-commons/SimpleCache.js +++ b/modules/nuclide-commons/SimpleCache.js @@ -1,51 +1,24 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 - */ - -// TODO: Merge this class with nuclide-commons/cache.js because they probably do -// very similar things - -/** - * Tiny class that is useful to cache simple values. - * It's quite useful for promises with a SimpleCache> which allows reusing the same promise. - */ +"use strict"; -type DisposeCallback = (value: T) => void; -type KeyFactory = (args: KeyArgs) => mixed; +Object.defineProperty(exports, "__esModule", { + value: true +}); +class SimpleCache { -type CacheConfig = { - keyFactory?: KeyFactory, - dispose?: DisposeCallback, -}; + constructor(config = {}) { + this.store = new Map(); -export class SimpleCache { - store: Map = new Map(); - _dispose: ?DisposeCallback; - _keyFactory: KeyFactory; - - constructor(config: CacheConfig = {}) { if (config.dispose != null) { this._dispose = config.dispose; } - this._keyFactory = - config.keyFactory != null - ? config.keyFactory - : (keyArgs: KeyArgs) => keyArgs; + this._keyFactory = config.keyFactory != null ? config.keyFactory : keyArgs => keyArgs; } - _getUnsafe(key: mixed): T { - return ((this.store.get(key): any): T); + _getUnsafe(key) { + return this.store.get(key); } - getOrCreate(keyArgs: KeyArgs, factory: (KeyArgs, mixed) => T): T { + getOrCreate(keyArgs, factory) { const key = this._keyFactory(keyArgs); if (this.store.has(key)) { return this._getUnsafe(key); @@ -55,7 +28,7 @@ export class SimpleCache { return value; } - delete(keyArgs: KeyArgs): void { + delete(keyArgs) { const key = this._keyFactory(keyArgs); if (this._dispose != null) { this._ifHas(key, this._dispose); @@ -63,32 +36,51 @@ export class SimpleCache { this.store.delete(key); } - clear(): void { + clear() { if (this._dispose != null) { this.store.forEach(this._dispose); } this.store.clear(); } - get(keyArgs: KeyArgs): ?T { + get(keyArgs) { return this.store.get(this._keyFactory(keyArgs)); } - set(keyArgs: KeyArgs, value: T): void { + set(keyArgs, value) { this.store.set(this._keyFactory(keyArgs), value); } - ifHas(keyArgs: KeyArgs, callback: (value: T) => void) { + ifHas(keyArgs, callback) { this._ifHas(this._keyFactory(keyArgs), callback); } - _ifHas(key: mixed, callback: (value: T) => void) { + _ifHas(key, callback) { if (this.store.has(key)) { callback(this._getUnsafe(key)); } } - keyForArgs(keyArgs: KeyArgs): mixed { + keyForArgs(keyArgs) { return this._keyFactory(keyArgs); } } +exports.SimpleCache = SimpleCache; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 + */ + +// TODO: Merge this class with nuclide-commons/cache.js because they probably do +// very similar things + +/** + * Tiny class that is useful to cache simple values. + * It's quite useful for promises with a SimpleCache> which allows reusing the same promise. + */ \ No newline at end of file diff --git a/modules/nuclide-commons/UniversalDisposable.js b/modules/nuclide-commons/UniversalDisposable.js index 65836a5218..092bc56141 100644 --- a/modules/nuclide-commons/UniversalDisposable.js +++ b/modules/nuclide-commons/UniversalDisposable.js @@ -1,26 +1,17 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 +}); -export type AnyTeardown = (() => mixed) | rxjs$ISubscription | IDisposable; /** * 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; +class UniversalDisposable { - constructor(...teardowns: Array) { + constructor(...teardowns) { this.teardowns = new Set(); this.disposed = false; if (teardowns.length) { @@ -28,7 +19,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 +29,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 +47,36 @@ 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' - ) { +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', - ); -} + throw new TypeError('Arguments to UniversalDisposable.add must be disposable'); +} \ No newline at end of file diff --git a/modules/nuclide-commons/__mocks__/fixtures/symbol-definition-preview-sample.js b/modules/nuclide-commons/__mocks__/fixtures/symbol-definition-preview-sample.js index b2edab6824..5447b05d18 100644 --- a/modules/nuclide-commons/__mocks__/fixtures/symbol-definition-preview-sample.js +++ b/modules/nuclide-commons/__mocks__/fixtures/symbol-definition-preview-sample.js @@ -1,3 +1,11 @@ +"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. @@ -5,7 +13,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict */ // license header above without @format // eslint-disable-next-line @@ -19,33 +27,17 @@ const A_MULTILINE_CONST = ` lines `; -type Something = { - name: string, - age?: number, -}; - -export function aSingleLineFunctionSignature() { +function aSingleLineFunctionSignature() { return A_CONSTANT + SOME_OTHER_CONSTANT; } -export function aMultiLineFunctionSignature( - aReallyReallyLongArgumentNameThatWouldRequireThisToBreakAcrossMultipleLines: Something, -): number { +function aMultiLineFunctionSignature(aReallyReallyLongArgumentNameThatWouldRequireThisToBreakAcrossMultipleLines) { return 97; } - export function aPoorlyIndentedFunction( -aReallyReallyLongArgumentNameThatWouldRequireThisToBreakAcrossMultipleLines: Something, -): number { +function aPoorlyIndentedFunction(aReallyReallyLongArgumentNameThatWouldRequireThisToBreakAcrossMultipleLines) { return 97; } -type SomethingComplex = { - properties: { - name: string, - age?: number, - }, -}; - -const foo: ?SomethingComplex = null; -foo; +const foo = null; +foo; \ No newline at end of file diff --git a/modules/nuclide-commons/__mocks__/fixtures/throw.js b/modules/nuclide-commons/__mocks__/fixtures/throw.js index 23330ab5ae..f328e344aa 100644 --- a/modules/nuclide-commons/__mocks__/fixtures/throw.js +++ b/modules/nuclide-commons/__mocks__/fixtures/throw.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,8 +8,8 @@ * LICENSE file in 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 strict + * strict * @format */ -throw new Error('Errored!'); +throw new Error('Errored!'); \ No newline at end of file diff --git a/modules/nuclide-commons/__mocks__/fixtures/toBeMocked.js b/modules/nuclide-commons/__mocks__/fixtures/toBeMocked.js index 009f789986..0f7dcd664c 100644 --- a/modules/nuclide-commons/__mocks__/fixtures/toBeMocked.js +++ b/modules/nuclide-commons/__mocks__/fixtures/toBeMocked.js @@ -1,3 +1,9 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.importedFunction = importedFunction; /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,10 +12,10 @@ * LICENSE file in 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 { +function importedFunction(arg) { return 0; -} +} \ No newline at end of file diff --git a/modules/nuclide-commons/__mocks__/fixtures/toBeTested.js b/modules/nuclide-commons/__mocks__/fixtures/toBeTested.js index 8eda92952e..6ecdecadf3 100644 --- a/modules/nuclide-commons/__mocks__/fixtures/toBeTested.js +++ b/modules/nuclide-commons/__mocks__/fixtures/toBeTested.js @@ -1,17 +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 - */ +'use strict'; -import {importedFunction} from './toBeMocked'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.functionToTest = functionToTest; -export function functionToTest(): any { - return importedFunction(42); +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/__tests__/AbortController-test.js b/modules/nuclide-commons/__tests__/AbortController-test.js index 105bd527b6..f11c732f38 100644 --- a/modules/nuclide-commons/__tests__/AbortController-test.js +++ b/modules/nuclide-commons/__tests__/AbortController-test.js @@ -1,20 +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 strict-local - * @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 = jest.fn(); @@ -31,7 +27,7 @@ describe('AbortController', () => { }); it('dispatches abort() events via addEventListener', () => { - const controller = new AbortController(); + const controller = new (_AbortController || _load_AbortController()).default(); const spy = jest.fn(); controller.signal.addEventListener('abort', spy); @@ -40,4 +36,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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/BatchProcessedQueue-test.js b/modules/nuclide-commons/__tests__/BatchProcessedQueue-test.js index cbf6c70e63..2130ffeed7 100644 --- a/modules/nuclide-commons/__tests__/BatchProcessedQueue-test.js +++ b/modules/nuclide-commons/__tests__/BatchProcessedQueue-test.js @@ -1,23 +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 strict - * @format - */ - -import BatchProcessedQueue from '../BatchProcessedQueue'; - -jest.useFakeTimers(); +'use strict'; + +var _BatchProcessedQueue; + +function _load_BatchProcessedQueue() { + return _BatchProcessedQueue = _interopRequireDefault(require('../BatchProcessedQueue')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +jest.useFakeTimers(); /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict + * @format + */ 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); @@ -35,4 +41,4 @@ describe('analytics - BatchProcessedQueue', () => { jest.advanceTimersByTime(10000); expect(handler).toHaveBeenCalledWith([42]); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/ConfigCache-test.js b/modules/nuclide-commons/__tests__/ConfigCache-test.js index 37694e74b4..364995327e 100644 --- a/modules/nuclide-commons/__tests__/ConfigCache-test.js +++ b/modules/nuclide-commons/__tests__/ConfigCache-test.js @@ -1,3 +1,19 @@ +'use strict'; + +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. @@ -6,86 +22,62 @@ * LICENSE file in 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 strict-local + * strict-local * @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, '../__mocks__/fixtures'); - const rootFolder = nuclideUri.join( - __dirname, - '../__mocks__/fixtures/ConfigCache', - ); - const rootFile = nuclideUri.join( - __dirname, - '../__mocks__/fixtures/ConfigCache/file', - ); - const nestedFolder = nuclideUri.join( - __dirname, - '../__mocks__/fixtures/ConfigCache/testFolder', - ); - const nestedFolder2 = nuclideUri.join( - __dirname, - '../__mocks__/fixtures/ConfigCache/testFolder2', - ); + const noConfigFolder = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures'); + const rootFolder = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures/ConfigCache'); + const rootFile = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures/ConfigCache/file'); + const nestedFolder = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures/ConfigCache/testFolder'); + const nestedFolder2 = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures/ConfigCache/testFolder2'); it('finds the right config dir', async () => { - const cache = new ConfigCache([CONFIG_FILE_NAME]); + const cache = new (_ConfigCache || _load_ConfigCache()).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(noConfigFolder))).toBe(null); + expect((await cache.getConfigDir(rootFolder))).toBe(rootFolder); + expect((await cache.getConfigDir(rootFile))).toBe(rootFolder); }); it('prefers closer matches with multiple config files', async () => { await (async () => { - const cache = new ConfigCache([CONFIG_FILE_NAME, CONFIG_FILE_NAME_2]); + 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((await cache.getConfigDir(rootFolder))).toBe(rootFolder); + expect((await cache.getConfigDir(nestedFolder2))).toBe(nestedFolder2); })(); }); it('prefers further matches when the search strategy is "furthest"', async () => { await (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); + const cache = new (_ConfigCache || _load_ConfigCache()).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); })(); }); it('prefers priority matches when the search strategy is "priority"', async () => { await (async () => { - const cache = new ConfigCache( - [CONFIG_FILE_NAME, CONFIG_FILE_NAME_2], - 'priority', - ); + const cache = new (_ConfigCache || _load_ConfigCache()).ConfigCache([CONFIG_FILE_NAME, CONFIG_FILE_NAME_2], 'priority'); - expect(await cache.getConfigDir(rootFolder)).toBe(rootFolder); - expect(await cache.getConfigDir(nestedFolder2)).toBe(rootFolder); + expect((await cache.getConfigDir(rootFolder))).toBe(rootFolder); + expect((await cache.getConfigDir(nestedFolder2))).toBe(rootFolder); })(); }); it('matches first path segment when the search strategy is "pathMatch"', async () => { - const cache = new ConfigCache( - ['ConfigCache/testFolder', 'ConfigCache'], - 'pathMatch', - ); + const cache = new (_ConfigCache || _load_ConfigCache()).ConfigCache(['ConfigCache/testFolder', 'ConfigCache'], 'pathMatch'); // matches both patterns, tie-breaks with first one - expect(await cache.getConfigDir(nestedFolder)).toBe(nestedFolder); + expect((await cache.getConfigDir(nestedFolder))).toBe(nestedFolder); // matches second pattern - expect(await cache.getConfigDir(nestedFolder2)).toBe(rootFolder); + expect((await cache.getConfigDir(nestedFolder2))).toBe(rootFolder); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/Hasher-test.js b/modules/nuclide-commons/__tests__/Hasher-test.js index 1c242b19fc..62fd090ebb 100644 --- a/modules/nuclide-commons/__tests__/Hasher-test.js +++ b/modules/nuclide-commons/__tests__/Hasher-test.js @@ -1,46 +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 strict - * @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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/Model-test.js b/modules/nuclide-commons/__tests__/Model-test.js index 1027cac3b7..628d4c4763 100644 --- a/modules/nuclide-commons/__tests__/Model-test.js +++ b/modules/nuclide-commons/__tests__/Model-test.js @@ -1,43 +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 strict-local - * @format - */ +'use strict'; -import Model from '../Model'; +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', async () => { await (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}, - ]); + const model = new (_Model || _load_Model()).default({ 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 }]); })(); }); -}); +}); /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/ObservablePool-test.js b/modules/nuclide-commons/__tests__/ObservablePool-test.js index f85b6be8bd..908fd960a2 100644 --- a/modules/nuclide-commons/__tests__/ObservablePool-test.js +++ b/modules/nuclide-commons/__tests__/ObservablePool-test.js @@ -1,3 +1,21 @@ +'use strict'; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _ObservablePool; + +function _load_ObservablePool() { + return _ObservablePool = _interopRequireDefault(require('../ObservablePool')); +} + +var _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../../../jest/waits_for')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,30 +24,25 @@ * LICENSE file in 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'; -import waitsFor from '../../../jest/waits_for'; - 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 = jest.fn().mockReturnValue(subject1); const req1 = pool.schedule(spy1); - const subject2 = new Subject(); + const subject2 = new _rxjsBundlesRxMinJs.Subject(); const spy2 = jest.fn().mockReturnValue(subject2); const req2 = pool.schedule(spy2); - const subject3 = new Subject(); + const subject3 = new _rxjsBundlesRxMinJs.Subject(); const spy3 = jest.fn().mockReturnValue(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(); @@ -62,19 +75,15 @@ describe('ObservablePool', () => { }); it('waits for promises, even on unsubscribe', async () => { - const pool = new ObservablePool(1); - let resolve: ?Function; - let reject: ?Function; - const spy1 = jest.fn().mockReturnValue( - new Promise(r => { - resolve = r; - }), - ); - const spy2 = jest.fn().mockReturnValue( - new Promise((_, r) => { - reject = r; - }), - ); + const pool = new (_ObservablePool || _load_ObservablePool()).default(1); + let resolve; + let reject; + const spy1 = jest.fn().mockReturnValue(new Promise(r => { + resolve = r; + })); + const spy2 = jest.fn().mockReturnValue(new Promise((_, r) => { + reject = r; + })); const errorSpy = jest.fn(); const sub1 = pool.schedule(spy1).subscribe(); pool.schedule(spy2).subscribe(() => {}, errorSpy); @@ -82,10 +91,7 @@ describe('ObservablePool', () => { // Immediately subscribe & unsubscribe - // the request should never be scheduled. const spy3 = jest.fn().mockReturnValue(Promise.resolve()); - pool - .schedule(spy3) - .subscribe() - .unsubscribe(); + pool.schedule(spy3).subscribe().unsubscribe(); expect(spy1).toHaveBeenCalled(); expect(spy2).not.toHaveBeenCalled(); @@ -94,19 +100,23 @@ describe('ObservablePool', () => { // 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'); + + if (!(resolve != null)) { + throw new Error('spy1 should have been scheduled'); + } + resolve(); // Promise resolution is always async... - await waitsFor(() => spy2.mock.calls.length > 0, 'spy2 should be called'); + await (0, (_waits_for || _load_waits_for()).default)(() => spy2.mock.calls.length > 0, 'spy2 should be called'); + + if (!(reject != null)) { + throw new Error('spy2 was called'); + } - invariant(reject != null, 'spy2 was called'); reject('test'); - await waitsFor( - () => errorSpy.mock.calls.length > 0, - 'errorSpy should be called', - ); + await (0, (_waits_for || _load_waits_for()).default)(() => errorSpy.mock.calls.length > 0, 'errorSpy should be called'); expect(errorSpy).toHaveBeenCalledWith('test'); expect(pool._responseListeners.size).toBe(0); @@ -114,25 +124,23 @@ 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 = jest.fn(); - pool.schedule(() => Promise.resolve()).subscribe({error: errorSpy}); + pool.schedule(() => Promise.resolve()).subscribe({ error: errorSpy }); pool.dispose(); expect(errorSpy).toHaveBeenCalled(); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/SafeStreamMessageReader-test.js b/modules/nuclide-commons/__tests__/SafeStreamMessageReader-test.js index d8b2a08f62..d5d4aa9aaa 100644 --- a/modules/nuclide-commons/__tests__/SafeStreamMessageReader-test.js +++ b/modules/nuclide-commons/__tests__/SafeStreamMessageReader-test.js @@ -1,53 +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 strict-local - * @format - */ - -import Stream from 'stream'; -import SafeStreamMessageReader from '../SafeStreamMessageReader'; -import waitsFor from '../../../jest/waits_for'; +'use strict'; + +var _stream = _interopRequireDefault(require('stream')); + +var _SafeStreamMessageReader; + +function _load_SafeStreamMessageReader() { + return _SafeStreamMessageReader = _interopRequireDefault(require('../SafeStreamMessageReader')); +} + +var _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../../../jest/waits_for')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } describe('SafeStreamMessageReader', () => { it('reads valid messages', async () => { - const readable = new Stream.Readable({ + 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(readable); + const reader = new (_SafeStreamMessageReader || _load_SafeStreamMessageReader()).default(readable); const listenSpy = jest.fn(); reader.listen(listenSpy); - await waitsFor(() => listenSpy.mock.calls.length > 0); + await (0, (_waits_for || _load_waits_for()).default)(() => listenSpy.mock.calls.length > 0); - expect(listenSpy.mock.calls[0]).toEqual([{a: 1}]); + expect(listenSpy.mock.calls[0]).toEqual([{ a: 1 }]); }); it('emits an error for an invalid header', async () => { - 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 = jest.fn(); const errorSpy = jest.fn(); reader.listen(listenSpy); reader.onError(errorSpy); - await waitsFor(() => errorSpy.mock.calls.length > 0); + await (0, (_waits_for || _load_waits_for()).default)(() => errorSpy.mock.calls.length > 0); expect(errorSpy.mock.calls[0][0].name).toBe('Error'); expect(listenSpy).not.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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/UniversalDisposable-test.js b/modules/nuclide-commons/__tests__/UniversalDisposable-test.js index 830f01c836..2210bd00a0 100644 --- a/modules/nuclide-commons/__tests__/UniversalDisposable-test.js +++ b/modules/nuclide-commons/__tests__/UniversalDisposable-test.js @@ -1,21 +1,17 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 = jest.fn(); - const universal = new UniversalDisposable({dispose}); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default({ dispose }); expect(dispose.mock.calls.length > 0).toBe(false); universal.dispose(); @@ -23,7 +19,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 +28,7 @@ describe('UniversalDisposable', () => { it('calls function arguments', () => { const foo = jest.fn(); - const universal = new UniversalDisposable(foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(foo); expect(foo.mock.calls.length > 0).toBe(false); universal.dispose(); @@ -41,7 +37,7 @@ describe('UniversalDisposable', () => { it('calls unsubscribe arguments', () => { const unsubscribe = jest.fn(); - const universal = new UniversalDisposable(unsubscribe); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(unsubscribe); expect(unsubscribe.mock.calls.length > 0).toBe(false); universal.dispose(); @@ -52,7 +48,7 @@ describe('UniversalDisposable', () => { const dispose = jest.fn(); const unsubscribe = jest.fn(); const foo = jest.fn(); - const universal = new UniversalDisposable({dispose}, {unsubscribe}, foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default({ dispose }, { unsubscribe }, foo); expect(dispose.mock.calls.length > 0).toBe(false); expect(unsubscribe.mock.calls.length > 0).toBe(false); @@ -67,8 +63,8 @@ describe('UniversalDisposable', () => { const dispose = jest.fn(); const unsubscribe = jest.fn(); const foo = jest.fn(); - const universal = new UniversalDisposable(); - universal.add({dispose}, {unsubscribe}, foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + universal.add({ dispose }, { unsubscribe }, foo); expect(dispose.mock.calls.length > 0).toBe(false); expect(unsubscribe.mock.calls.length > 0).toBe(false); @@ -83,7 +79,7 @@ describe('UniversalDisposable', () => { const dispose = jest.fn(); const unsubscribe = jest.fn(); const foo = jest.fn(); - const universal = new UniversalDisposable({dispose}, {unsubscribe}, foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default({ dispose }, { unsubscribe }, foo); expect(dispose.mock.calls.length > 0).toBe(false); expect(unsubscribe.mock.calls.length > 0).toBe(false); @@ -98,7 +94,7 @@ describe('UniversalDisposable', () => { const dispose = jest.fn(); const unsubscribe = jest.fn(); const foo = jest.fn(); - const universal = new UniversalDisposable({dispose}, {unsubscribe}, foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default({ dispose }, { unsubscribe }, foo); expect(dispose.mock.calls.length > 0).toBe(false); expect(unsubscribe.mock.calls.length > 0).toBe(false); @@ -113,10 +109,10 @@ describe('UniversalDisposable', () => { }); it('supports removal of the teardowns', () => { - const dispose = {dispose: jest.fn()}; - const unsubscribe = {unsubscribe: jest.fn()}; + const dispose = { dispose: jest.fn() }; + const unsubscribe = { unsubscribe: jest.fn() }; const foo = jest.fn(); - 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 +126,10 @@ describe('UniversalDisposable', () => { }); it('can clear all of the teardowns', () => { - const dispose = {dispose: jest.fn()}; - const unsubscribe = {unsubscribe: jest.fn()}; + const dispose = { dispose: jest.fn() }; + const unsubscribe = { unsubscribe: jest.fn() }; const foo = jest.fn(); - const universal = new UniversalDisposable(dispose, unsubscribe, foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(dispose, unsubscribe, foo); universal.clear(); @@ -152,7 +148,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 +158,11 @@ describe('UniversalDisposable', () => { describe('teardown priority', () => { it('calls dispose()', () => { - const foo: Function = jest.fn(); + const foo = jest.fn(); foo.dispose = jest.fn(); foo.unsubscribe = jest.fn(); - const universal = new UniversalDisposable(foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(foo); universal.dispose(); expect(foo.dispose.mock.calls.length > 0).toBe(true); @@ -175,11 +171,11 @@ describe('UniversalDisposable', () => { }); it('calls unsubscribe()', () => { - const foo: Function = jest.fn(); + const foo = jest.fn(); foo.dispose = null; foo.unsubscribe = jest.fn(); - const universal = new UniversalDisposable(foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(foo); universal.dispose(); expect(foo.unsubscribe.mock.calls.length > 0).toBe(true); @@ -187,14 +183,24 @@ describe('UniversalDisposable', () => { }); it('calls the function', () => { - const foo: Function = jest.fn(); + const foo = jest.fn(); foo.dispose = null; foo.unsubscribe = null; - const universal = new UniversalDisposable(foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(foo); universal.dispose(); expect(foo.mock.calls.length > 0).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/__tests__/cache-test.js b/modules/nuclide-commons/__tests__/cache-test.js index 1e304b6c97..194cce21a0 100644 --- a/modules/nuclide-commons/__tests__/cache-test.js +++ b/modules/nuclide-commons/__tests__/cache-test.js @@ -1,16 +1,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. - * - * @flow strict-local - * @format - */ - -import {Cache} from '../cache'; +'use strict'; + +var _cache; + +function _load_cache() { + return _cache = require('../cache'); +} describe('Cache', () => { const key1 = 'key1'; @@ -24,7 +18,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 +34,7 @@ describe('Cache', () => { it('delete', () => { const factory = jest.fn().mockReturnValue(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 +46,7 @@ describe('Cache', () => { it('delete disposes values', () => { const factory = jest.fn().mockReturnValue(value); const dispose = jest.fn(); - const cache: Cache = new Cache(factory, dispose); + const cache = new (_cache || _load_cache()).Cache(factory, dispose); cache.get(key1); cache.delete(key1); @@ -62,7 +56,7 @@ describe('Cache', () => { it('clear disposes values', () => { const factory = jest.fn().mockReturnValue(value); const dispose = jest.fn(); - const cache: Cache = new Cache(factory, dispose); + const cache = new (_cache || _load_cache()).Cache(factory, dispose); cache.get(key1); cache.clear(); @@ -72,7 +66,7 @@ describe('Cache', () => { it('dispose disposes values', () => { const factory = jest.fn().mockReturnValue(value); const dispose = jest.fn(); - const cache: Cache = new Cache(factory, dispose); + const cache = new (_cache || _load_cache()).Cache(factory, dispose); cache.get(key1); cache.dispose(); @@ -82,32 +76,36 @@ describe('Cache', () => { it('observeValues sees existing and new values', async () => { await (async () => { const factory = jest.fn().mockImplementation(key => key); - const cache: Cache = new Cache(factory); + 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((await values)).toEqual([key1, key2]); })(); }); it('observeKeys sees existing and new keys', async () => { await (async () => { const factory = jest.fn().mockImplementation(key => value); - const cache: Cache = new Cache(factory); + 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((await 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/collection-test.js b/modules/nuclide-commons/__tests__/collection-test.js index c03158102f..4f43ba1864 100644 --- a/modules/nuclide-commons/__tests__/collection-test.js +++ b/modules/nuclide-commons/__tests__/collection-test.js @@ -1,68 +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 { - 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']); - }); -}); + 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: any; - let empty: any; - let single: any; + let a; + let empty; + let single; beforeEach(() => { a = ['a', 'b', 'c']; @@ -71,85 +40,78 @@ describe('arrayRemove', () => { }); 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( - arrayEqual([{x: 1}, {x: 2}], [{x: 1}, {x: 2}], (a, b) => a.x === b.x), - ).toBe(true); + expect((0, (_collection || _load_collection()).arrayEqual)([{}], [{}])).toBe(false); + expect((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 = jest.fn().mockReturnValue(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 +119,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 +131,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 +142,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 +174,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 +211,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 +222,17 @@ 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); + const 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 +244,7 @@ describe('collect', () => { describe('DefaultMap', () => { it('calls the factory each time you get a nonexistant key', () => { const spy = jest.fn().mockReturnValue('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 +253,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 +261,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 +276,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 +284,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 +315,7 @@ 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 +328,7 @@ 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 +347,7 @@ 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()); @@ -427,271 +370,191 @@ describe('MultiMap', () => { describe('objectValues', () => { it('returns the values of an object', () => { - expect( - objectValues({ - a: 1, - b: 2, - c: 4, - }), - ).toEqual([1, 2, 4]); + expect((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]); + expect(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); - expect( - 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); + expect((0, (_collection || _load_collection()).someOfIterable)(new Set([1, 2, 3, 4, 5]), element => element % 2 === 0)).toEqual(true); + expect((0, (_collection || _load_collection()).someOfIterable)(new Set([1, 2, 3, 4, 5]), element => element % 5 === 0)).toEqual(true); + expect((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); - expect( - 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); + expect((0, (_collection || _load_collection()).findInIterable)(new Set([1, 2, 3, 4, 5]), element => element % 2 === 0)).toEqual(2); + expect((0, (_collection || _load_collection()).findInIterable)(new Set([1, 2, 3, 4, 5]), element => element % 5 === 0)).toEqual(5); + expect((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]); - expect( - Array.from(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([]); + expect(Array.from((0, (_collection || _load_collection()).filterIterable)(new Set([1, 2, 3, 4, 5]), element => element % 2 === 0))).toEqual([2, 4]); + expect(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((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); + expect(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); + expect((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( - mapEqual( - new Map([[1, {x: 1}]]), - new Map([[1, {x: 1}]]), - (v1, v2) => v1.x === v2.x, - ), - ).toBe(true); + expect((0, (_collection || _load_collection()).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 }]]), (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( - mapIterable(new Set([1, 2, 3, 4, 5]), element => element * element), - ), - ).toEqual([1, 4, 9, 16, 25]); + expect(Array.from((0, (_collection || _load_collection()).mapIterable)(new Set(), element => true))).toEqual([]); + expect(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 +564,33 @@ 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); + expect((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( - distinct([{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 4}], o => String(o.x)), - ).toEqual([{x: 1}, {x: 2}, {x: 3}, {x: 4}]); + 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((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/__tests__/debounce-test.js b/modules/nuclide-commons/__tests__/debounce-test.js index 1bf40574bf..7562f99793 100644 --- a/modules/nuclide-commons/__tests__/debounce-test.js +++ b/modules/nuclide-commons/__tests__/debounce-test.js @@ -1,3 +1,13 @@ +'use strict'; + +var _debounce; + +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. @@ -6,20 +16,17 @@ * LICENSE file in 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'; - const sleep = n => new Promise(resolve => setTimeout(resolve, n)); describe('debounce()', () => { it('only calls function once after time advances', async () => { jest.useRealTimers(); - const timerCallback: any = jasmine.createSpy('timerCallback'); - const debouncedFunc = debounce(timerCallback, 10, false); + const timerCallback = jasmine.createSpy('timerCallback'); + const debouncedFunc = (0, (_debounce || _load_debounce()).default)(timerCallback, 10, false); debouncedFunc(); expect(timerCallback).not.toHaveBeenCalled(); @@ -30,8 +37,8 @@ describe('debounce()', () => { it('disposes', () => { jest.useFakeTimers(); - 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(); @@ -44,8 +51,8 @@ describe('debounce()', () => { it('does not swallow flow types', () => { jest.useFakeTimers(); - 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. @@ -53,10 +60,14 @@ 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(); @@ -66,4 +77,4 @@ describe('debounce()', () => { debounced.bar(); }).toThrow(); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/event-test.js b/modules/nuclide-commons/__tests__/event-test.js index 9a8d2eb214..b110b3030b 100644 --- a/modules/nuclide-commons/__tests__/event-test.js +++ b/modules/nuclide-commons/__tests__/event-test.js @@ -1,37 +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 strict-local - * @format - */ - -import invariant from 'assert'; -import EventEmitter from 'events'; -import {attachEvent, observableFromSubscribeFunction} from '../event'; +'use strict'; + +var _events = _interopRequireDefault(require('events')); + +var _event; + +function _load_event() { + return _event = require('../event'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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); + 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(); }); }); -}); +}); /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ 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,7 +46,7 @@ describe('observableFromSubscribeFunction', () => { disposable = { dispose() { callback = null; - }, + } }; jest.spyOn(disposable, 'dispose'); return disposable; @@ -52,7 +58,7 @@ 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(); @@ -60,23 +66,27 @@ describe('observableFromSubscribeFunction', () => { it('should send events to the observable stream', async () => { await (async () => { - const result = observableFromSubscribeFunction(subscribeFunction) - .take(2) - .toArray() - .toPromise(); - invariant(callback != null); + 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((await 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(); - invariant(disposable != null); + if (!(disposable != null)) { + throw new Error('Invariant violation: "disposable != null"'); + } + expect(disposable.dispose).not.toHaveBeenCalled(); subscription.unsubscribe(); expect(disposable.dispose).toHaveBeenCalled(); @@ -91,4 +101,4 @@ describe('observableFromSubscribeFunction', () => { subscription.unsubscribe(); expect(disposable.dispose).toHaveBeenCalled(); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/fsPromise-test.js b/modules/nuclide-commons/__tests__/fsPromise-test.js index 72186c5fd3..5a4e4aa0f5 100644 --- a/modules/nuclide-commons/__tests__/fsPromise-test.js +++ b/modules/nuclide-commons/__tests__/fsPromise-test.js @@ -1,3 +1,33 @@ +'use strict'; + +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 }; } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,116 +36,78 @@ * LICENSE file in 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(); +(_temp || _load_temp()).default.track(); describe('fsPromise test suite', () => { describe('findNearestFile()', () => { - let dirPath: string = (null: any); + let dirPath = null; beforeEach(async () => { await (async () => { - dirPath = await generateFixture( - 'nearest_test', - new Map([ - ['.some_file', 'just some file'], - ['nested_dir/.another_file', 'just another file'], - ]), - ); + dirPath = await (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', async () => { await (async () => { - const foundPath = await fsPromise.findNearestFile( - '.some_file', - dirPath, - ); + const foundPath = await (_fsPromise || _load_fsPromise()).default.findNearestFile('.some_file', dirPath); expect(foundPath).toBe(dirPath); })(); }); it('find the file if given a nested directory', async () => { await (async () => { - const foundPath = await fsPromise.findNearestFile( - '.some_file', - nuclideUri.join(dirPath, 'nested_dir'), - ); + const foundPath = await (_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', async () => { await (async () => { - const foundPath = await fsPromise.findNearestFile( - 'non-existent.txt', - nuclideUri.join(dirPath, 'nested_dir'), - ); + const foundPath = await (_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(async () => { await (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'], - ]), - ); + dirPath = await (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', async () => { await (async () => { - const expectedPath = nuclideUri.join(dirPath, '0'); - const foundPath = await fsPromise.findFurthestFile( - '.some_file', - expectedPath, - ); + const expectedPath = (_nuclideUri || _load_nuclideUri()).default.join(dirPath, '0'); + const foundPath = await (_fsPromise || _load_fsPromise()).default.findFurthestFile('.some_file', expectedPath); expect(foundPath).toBe(expectedPath); })(); }); it('finds the furthest file if given a nested directory', async () => { await (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, - ); + const expectedPath = (_nuclideUri || _load_nuclideUri()).default.join(dirPath, '0'); + const startPath = (_nuclideUri || _load_nuclideUri()).default.join(dirPath, '0/1/2/3/4'); + const foundPath = await (_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', async () => { await (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 */, + 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 = await (_fsPromise || _load_fsPromise()).default.findFurthestFile('.some_file', startPath, true /* stopOnMissing */ ); expect(foundPath).toBe(expectedPath); })(); @@ -123,11 +115,8 @@ describe('fsPromise test suite', () => { it('does not find the file if not existing', async () => { await (async () => { - const startPath = nuclideUri.join(dirPath, '0/1/2/3/4'); - const foundPath = await fsPromise.findFurthestFile( - 'non-existent.txt', - startPath, - ); + const startPath = (_nuclideUri || _load_nuclideUri()).default.join(dirPath, '0/1/2/3/4'); + const foundPath = await (_fsPromise || _load_fsPromise()).default.findFurthestFile('non-existent.txt', startPath); expect(foundPath).toBe(null); })(); }); @@ -135,60 +124,44 @@ describe('fsPromise test suite', () => { describe('getCommonAncestorDirectory', () => { it('gets the parent directory', () => { - expect( - fsPromise.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'); + expect((_fsPromise || _load_fsPromise()).default.getCommonAncestorDirectory(['/foo/bar.txt', '/foo/baz/lol.txt'])).toBe('/foo'); + expect((_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', async () => { await (async () => { - await fsPromise.writeFileAtomic( - pathToWriteFile, - "I'm a little teapot.\n", - ); - expect(fs.readFileSync(pathToWriteFile).toString()).toEqual( - "I'm a little teapot.\n", - ); + await (_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', async () => { await (async () => { - const subPath = nuclideUri.join(pathToWriteFile, 'test'); - await fsPromise.writeFileAtomic(subPath, 'test1234\n'); - expect(fs.readFileSync(subPath).toString()).toEqual('test1234\n'); + const subPath = (_nuclideUri || _load_nuclideUri()).default.join(pathToWriteFile, 'test'); + await (_fsPromise || _load_fsPromise()).default.writeFileAtomic(subPath, 'test1234\n'); + expect(_fs.default.readFileSync(subPath).toString()).toEqual('test1234\n'); })(); }); it('preserves permissions on files', async () => { - fs.writeFileSync(pathToWriteFile, 'test'); - fs.chmodSync(pathToWriteFile, 0o700); + _fs.default.writeFileSync(pathToWriteFile, 'test'); + _fs.default.chmodSync(pathToWriteFile, 0o700); await (async () => { - await fsPromise.writeFileAtomic(pathToWriteFile, 'test2'); - expect(fs.readFileSync(pathToWriteFile).toString()).toEqual('test2'); - const stat = fs.statSync(pathToWriteFile); + await (_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); })(); @@ -198,15 +171,15 @@ describe('fsPromise test suite', () => { await (async () => { let err; try { - await fsPromise.writeFileAtomic( - pathToWriteFile + '/that/is/missing/', - 'something', - ); + await (_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/__tests__/humanizeKeystroke-test.js b/modules/nuclide-commons/__tests__/humanizeKeystroke-test.js index bfcac4a4da..0ce53676d0 100644 --- a/modules/nuclide-commons/__tests__/humanizeKeystroke-test.js +++ b/modules/nuclide-commons/__tests__/humanizeKeystroke-test.js @@ -1,96 +1,88 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict - * @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(humanizeKeystroke('cmd-shift-up', 'darwin')).toEqual('⌘⇧↑'); - expect(humanizeKeystroke('cmd-shift-up', 'linux')).toEqual( - 'Cmd+Shift+Up', - ); + 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(humanizeKeystroke('cmd-option-down', 'darwin')).toEqual('⌘⌥↓'); - expect(humanizeKeystroke('cmd-option-down', 'linux')).toEqual( - 'Cmd+Alt+Down', - ); + 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-option-left', 'darwin')).toEqual('⌘⌥←'); - expect(humanizeKeystroke('cmd-option-left', 'linux')).toEqual( - 'Cmd+Alt+Left', - ); + 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-right', 'darwin')).toEqual('⌘⌥→'); - expect(humanizeKeystroke('cmd-option-right', 'linux')).toEqual( - 'Cmd+Alt+Right', - ); + 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-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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/matchIndexesToRanges-test.js b/modules/nuclide-commons/__tests__/matchIndexesToRanges-test.js index 30e3e2ac1a..6dec2f9569 100644 --- a/modules/nuclide-commons/__tests__/matchIndexesToRanges-test.js +++ b/modules/nuclide-commons/__tests__/matchIndexesToRanges-test.js @@ -1,31 +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 strict - * @format - */ +'use strict'; -import matchIndexesToRanges from '../matchIndexesToRanges'; +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]]); + expect((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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/memoizeUntilChanged-test.js b/modules/nuclide-commons/__tests__/memoizeUntilChanged-test.js index 56af101ef8..7a2d35f48f 100644 --- a/modules/nuclide-commons/__tests__/memoizeUntilChanged-test.js +++ b/modules/nuclide-commons/__tests__/memoizeUntilChanged-test.js @@ -1,23 +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 strict-local - * @format - */ +'use strict'; -import memoizeUntilChanged from '../memoizeUntilChanged'; +var _memoizeUntilChanged; -const sum = (a, b) => a + b; +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. + * + * strict-local + * @format + */ describe('memoizeUntilChanged', () => { it('memoizes', () => { const spy = jest.fn().mockImplementation(sum); - const f = memoizeUntilChanged(spy); + const f = (0, (_memoizeUntilChanged || _load_memoizeUntilChanged()).default)(spy); f(1, 2); const result = f(1, 2); expect(result).toBe(3); @@ -26,7 +32,7 @@ describe('memoizeUntilChanged', () => { it('resets when args change', () => { const spy = jest.fn().mockImplementation(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 +42,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 +51,7 @@ describe('memoizeUntilChanged', () => { it('uses all args when memoizing by default', () => { const spy = jest.fn().mockImplementation(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 +60,12 @@ describe('memoizeUntilChanged', () => { it('uses the key selector and comparator', () => { const spy = jest.fn().mockImplementation(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 +73,4 @@ describe('memoizeUntilChanged', () => { f(0, 4); expect(spy.mock.calls.length).toBe(2); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/nice-test.js b/modules/nuclide-commons/__tests__/nice-test.js index dba6099fb9..8e3e81ab34 100644 --- a/modules/nuclide-commons/__tests__/nice-test.js +++ b/modules/nuclide-commons/__tests__/nice-test.js @@ -1,61 +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 - */ +'use strict'; -import typeof {niceSafeSpawn as niceSafeSpawnType} from '../nice'; +var _testHelpers; -import {uncachedRequire} from '../test-helpers'; -import {Observable} from 'rxjs'; +function _load_testHelpers() { + return _testHelpers = require('../test-helpers'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); describe('nice', () => { - let niceSafeSpawn: niceSafeSpawnType = (null: any); + let niceSafeSpawn = null; - let whichSpy = (null: any); - let spawnSpy = (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(() => { jest.resetModules(); shouldFindNiceCommand = true; shouldFindIoniceCommand = true; - whichSpy = jest - .spyOn(require('../which'), 'default') - .mockImplementation(async command => { - if ( - (shouldFindNiceCommand && command === 'nice') || - (shouldFindIoniceCommand && command === 'ionice') - ) { - return command; - } else { - return null; - } - }); - spawnSpy = jest - .spyOn(require('../process'), 'spawn') - .mockReturnValue(Observable.of(fakeSafeSpawnReturn)); - ({niceSafeSpawn} = (uncachedRequire(require, '../nice'): any)); + whichSpy = jest.spyOn(require('../which'), 'default').mockImplementation(async command => { + if (shouldFindNiceCommand && command === 'nice' || shouldFindIoniceCommand && command === 'ionice') { + return command; + } else { + return null; + } + }); + spawnSpy = jest.spyOn(require('../process'), 'spawn').mockReturnValue(_rxjsBundlesRxMinJs.Observable.of(fakeSafeSpawnReturn)); + ({ niceSafeSpawn } = (0, (_testHelpers || _load_testHelpers()).uncachedRequire)(require, '../nice')); }); it('should spawn `nice` and return whatever spawn returns', async () => { const execOptions = {}; const result = await niceSafeSpawn('echo', ['hi'], execOptions); - expect(spawnSpy).toHaveBeenCalledWith( - 'ionice', - ['-n', '7', 'nice', 'echo', 'hi'], - execOptions, - ); + expect(spawnSpy).toHaveBeenCalledWith('ionice', ['-n', '7', 'nice', 'echo', 'hi'], execOptions); expect(result).toBe(fakeSafeSpawnReturn); }); @@ -81,11 +63,7 @@ describe('nice', () => { shouldFindNiceCommand = false; const execOptions = {}; const result = await niceSafeSpawn('echo', ['hi'], execOptions); - expect(spawnSpy).toHaveBeenCalledWith( - 'ionice', - ['-n', '7', 'echo', 'hi'], - execOptions, - ); + expect(spawnSpy).toHaveBeenCalledWith('ionice', ['-n', '7', 'echo', 'hi'], execOptions); expect(result).toBe(fakeSafeSpawnReturn); }); @@ -98,4 +76,14 @@ describe('nice', () => { expect(whichSpy.mock.calls.length).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/__tests__/nuclideUri-test.js b/modules/nuclide-commons/__tests__/nuclideUri-test.js index 1848f4b84c..5411725f7d 100644 --- a/modules/nuclide-commons/__tests__/nuclideUri-test.js +++ b/modules/nuclide-commons/__tests__/nuclideUri-test.js @@ -1,3 +1,21 @@ +'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. @@ -6,49 +24,39 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import nuclideUri, {__TEST__} from '../nuclideUri'; -// eslint-disable-next-line nuclide-internal/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 #', - ); + 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 +66,515 @@ 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.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); - 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(); + 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 || _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 || _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.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']); - 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']); - 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', - ]); + 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 || _load_nuclideUri()).default.collapse(['/a/b.zip', '/a/b.zip!c', '/a/b.zip!c/d'])).toEqual(['/a/b.zip']); + expect((_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 || _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 || _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.relative( - nuclideUri.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( - '..', - ); - expect( - nuclideUri.relative(nuclideUri.dirname(localArchiveUri), localArchiveUri), - ).toBe('a'); - expect( - nuclideUri.relative(localArchiveUri, nuclideUri.dirname(localArchiveUri)), - ).toBe('..'); - expect( - nuclideUri.relative( - nuclideUri.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(); + 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 || _load_nuclideUri()).default.relative((_nuclideUri || _load_nuclideUri()).default.dirname(remoteUriWithSpaces), remoteUriWithSpaces)).toBe('c d'); + expect((_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 || _load_nuclideUri()).default.relative((_nuclideUri || _load_nuclideUri()).default.dirname(localArchiveUri), localArchiveUri)).toBe('a'); + expect((_nuclideUri || _load_nuclideUri()).default.relative(localArchiveUri, (_nuclideUri || _load_nuclideUri()).default.dirname(localArchiveUri))).toBe('..'); + expect((_nuclideUri || _load_nuclideUri()).default.relative((_nuclideUri || _load_nuclideUri()).default.dirname(endsWithExclamationUri), endsWithExclamationUri)).toBe('!! WARNING !!'); + expect((_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.nuclideUriToDisplayString(archiveSuffixUri), - ).toThrow(); + 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 || _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('/file.zip!', () => - expect(() => nuclideUri.isRoot('/file.zip!')).toThrow()); - it('/file.zip!abc', () => - expect(nuclideUri.isRoot('/file.zip!abc')).toBe(false)); - it('remote root', () => - expect(nuclideUri.isRoot('nuclide://host/')).toBe(true)); - it('remote root with port', () => - expect(nuclideUri.isRoot('nuclide://host/')).toBe(true)); - it('remote non-root', () => - expect(nuclideUri.isRoot('nuclide://host/abc')).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 || _load_nuclideUri()).default.isRoot('/file.zip!')).toThrow()); + it('/file.zip!abc', () => expect((_nuclideUri || _load_nuclideUri()).default.isRoot('/file.zip!abc')).toBe(false)); + it('remote root', () => expect((_nuclideUri || _load_nuclideUri()).default.isRoot('nuclide://host/')).toBe(true)); + it('remote root with port', () => expect((_nuclideUri || _load_nuclideUri()).default.isRoot('nuclide://host/')).toBe(true)); + it('remote non-root', () => 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 double root', () => - expect(nuclideUri.isRoot('\\\\')).toBe(false)); - it('win diskless non-root', () => - expect(nuclideUri.isRoot('\\abc')).toBe(false)); - it('win diskful root', () => expect(nuclideUri.isRoot('C:\\')).toBe(true)); - it('win diskful double root', () => - expect(nuclideUri.isRoot('C:\\\\')).toBe(false)); - it('win diskful non-root', () => - expect(nuclideUri.isRoot('C:\\abc')).toBe(false)); - - it('win relative', () => expect(nuclideUri.isRoot('abc\\def')).toBe(false)); + it('win diskless root', () => expect((_nuclideUri || _load_nuclideUri()).default.isRoot('\\')).toBe(true)); + it('win diskless double root', () => expect((_nuclideUri || _load_nuclideUri()).default.isRoot('\\\\')).toBe(false)); + it('win diskless non-root', () => 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 || _load_nuclideUri()).default.isRoot('C:\\\\')).toBe(false)); + it('win diskful non-root', () => expect((_nuclideUri || _load_nuclideUri()).default.isRoot('C:\\abc')).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.ensureTrailingSeparator(archiveSuffixUri), - ).toThrow(); + 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 || _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.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', - ); + 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 || _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 || _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.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', - ); + expect((_nuclideUri || _load_nuclideUri()).default.nuclideUriToUri('/foo/bar/file.ext')).toEqual('file:///foo/bar/file.ext'); + expect((_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.ancestorOutsideArchive('nuclide://host/abc.zip!def'), - ).toBe('nuclide://host/abc.zip'); - expect( - nuclideUri.ancestorOutsideArchive('nuclide://host/abc.jar!def'), - ).toBe('nuclide://host/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 || _load_nuclideUri()).default.ancestorOutsideArchive('nuclide://host/abc.zip!def')).toBe('nuclide://host/abc.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.ancestorOutsideArchive('nuclide://host/abc.jar!def')).toBe('nuclide://host/abc.jar'); }); }); +// eslint-disable-next-line nuclide-internal/prefer-nuclide-uri \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/observable-test.js b/modules/nuclide-commons/__tests__/observable-test.js index 1404d81a2c..aff5d76781 100644 --- a/modules/nuclide-commons/__tests__/observable-test.js +++ b/modules/nuclide-commons/__tests__/observable-test.js @@ -1,3 +1,33 @@ +'use strict'; + +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. @@ -6,45 +36,14 @@ * LICENSE file in 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, - mergeUntilAnyComplete, - 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 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(); + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(); jest.spyOn(disposable, 'dispose'); return disposable; }; @@ -54,9 +53,7 @@ describe('nuclide-commons/observable', () => { it('splits streams', async () => { await (async () => { const input = ['foo\nbar', '\n', '\nba', 'z', '\nblar']; - const output = await splitStream(Observable.from(input)) - .toArray() - .toPromise(); + const output = await (0, (_observable || _load_observable()).splitStream)(_rxjsBundlesRxMinJs.Observable.from(input)).toArray().toPromise(); expect(output).toEqual(['foo\n', 'bar\n', '\n', 'baz\n', 'blar']); })(); }); @@ -64,9 +61,7 @@ describe('nuclide-commons/observable', () => { it('splits streams without the newline', async () => { await (async () => { const input = ['foo\nbar', '\n', '\nba', 'z', '\nblar']; - const output = await splitStream(Observable.from(input), false) - .toArray() - .toPromise(); + const output = await (0, (_observable || _load_observable()).splitStream)(_rxjsBundlesRxMinJs.Observable.from(input), false).toArray().toPromise(); expect(output).toEqual(['foo', 'bar', '', 'baz', 'blar']); })(); }); @@ -74,11 +69,11 @@ describe('nuclide-commons/observable', () => { 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 = jest.fn(); - const complete: () => mixed = jest.fn(); - result.subscribe({next, complete}); + const source = new _rxjsBundlesRxMinJs.Subject(); + const result = source.let((0, (_observable || _load_observable()).takeWhileInclusive)(x => x !== 2)); + const next = jest.fn(); + const complete = jest.fn(); + result.subscribe({ next, complete }); source.next(1); source.next(2); source.next(3); @@ -88,15 +83,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', () => { @@ -138,31 +133,23 @@ describe('nuclide-commons/observable', () => { describe('diffSets', () => { it('emits a diff for the first item', async () => { await (async () => { - const source = new Subject(); - const diffsPromise = source - .let(diffSets()) - .toArray() - .toPromise(); + 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; expect(diffs.length).toBe(1); - expect( - diffsAreEqual(diffs[0], { - added: new Set([1, 2, 3]), - removed: new Set(), - }), - ).toBe(true); + expect(diffsAreEqual(diffs[0], { + added: new Set([1, 2, 3]), + removed: new Set() + })).toBe(true); })(); }); it('correctly identifies removed items', async () => { await (async () => { - const source = new Subject(); - const diffsPromise = source - .let(diffSets()) - .toArray() - .toPromise(); + 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(); @@ -173,30 +160,22 @@ describe('nuclide-commons/observable', () => { it('correctly identifies removed items when a hash function is used', async () => { await (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}]; + const source = new _rxjsBundlesRxMinJs.Subject(); + const diffsPromise = source.let((0, (_observable || _load_observable()).diffSets)(x => 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; - expect(setsAreEqual(diffs[1].removed, new Set([firstItems[2]]))).toBe( - true, - ); + expect(setsAreEqual(diffs[1].removed, new Set([firstItems[2]]))).toBe(true); })(); }); it('correctly identifies added items', async () => { await (async () => { - const source = new Subject(); - const diffsPromise = source - .let(diffSets()) - .toArray() - .toPromise(); + 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(); @@ -207,30 +186,22 @@ describe('nuclide-commons/observable', () => { it('correctly identifies added items when a hash function is used', async () => { await (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}]; + const source = new _rxjsBundlesRxMinJs.Subject(); + const diffsPromise = source.let((0, (_observable || _load_observable()).diffSets)(x => 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; - expect(setsAreEqual(diffs[1].added, new Set([secondItems[2]]))).toBe( - true, - ); + expect(setsAreEqual(diffs[1].added, new Set([secondItems[2]]))).toBe(true); })(); }); it("doesn't emit a diff when nothing changes", async () => { await (async () => { - const source = new Subject(); - const diffsPromise = source - .let(diffSets()) - .toArray() - .toPromise(); + 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(); @@ -242,13 +213,10 @@ describe('nuclide-commons/observable', () => { it("doesn't emit a diff when nothing changes and a hash function is used", async () => { await (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}]; + const source = new _rxjsBundlesRxMinJs.Subject(); + const diffsPromise = source.let((0, (_observable || _load_observable()).diffSets)(x => 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(); @@ -261,47 +229,47 @@ describe('nuclide-commons/observable', () => { describe('reconcileSetDiffs', () => { it("calls the add action for each item that's added", () => { - const diffs = new Subject(); - const addAction = jest.fn().mockReturnValue(new UniversalDisposable()); - reconcileSetDiffs(diffs, addAction); + const diffs = new _rxjsBundlesRxMinJs.Subject(); + const addAction = jest.fn().mockReturnValue(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.mock.calls.map(call => call[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(); @@ -309,20 +277,20 @@ describe('nuclide-commons/observable', () => { }); 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(); @@ -330,22 +298,22 @@ describe('nuclide-commons/observable', () => { }); 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)); }); @@ -373,7 +341,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,22 +370,14 @@ describe('nuclide-commons/observable', () => { describe('concatLatest', () => { it('should work with empty input', async () => { await (async () => { - const output = await concatLatest() - .toArray() - .toPromise(); + const output = await (0, (_observable || _load_observable()).concatLatest)().toArray().toPromise(); expect(output).toEqual([]); })(); }); it('should work with several observables', async () => { await (async () => { - const output = await concatLatest( - Observable.of([], [1]), - Observable.of([2]), - Observable.of([3], [3, 4]), - ) - .toArray() - .toPromise(); + const output = await (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]]); })(); }); @@ -425,25 +385,25 @@ describe('nuclide-commons/observable', () => { 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 = jest.fn(); - 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 = jest.fn(); - source.let(throttle(notifier)).subscribe(spy); + source.let((0, (_observable || _load_observable()).throttle)(notifier)).subscribe(spy); expect(spy.mock.calls.length).toBe(1); }); it('throttles', () => { - const source = new Subject(); - const notifier = new Subject(); + const source = new _rxjsBundlesRxMinJs.Subject(); + const notifier = new _rxjsBundlesRxMinJs.Subject(); const spy = jest.fn(); - source.let(throttle(notifier)).subscribe(spy); + source.let((0, (_observable || _load_observable()).throttle)(notifier)).subscribe(spy); source.next(1); spy.mockClear(); source.next(2); @@ -462,8 +422,8 @@ describe('nuclide-commons/observable', () => { it('subscribes to the source once per subscription', () => { const spy = jest.fn(); - 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.mock.calls.length).toBe(1); }); }); @@ -484,13 +444,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,20 +460,14 @@ describe('nuclide-commons/observable', () => { describe('bufferUntil', () => { it('buffers based on the predicate', async () => { await (async () => { - const chunks = await Observable.of(1, 2, 3, 4) - .let(bufferUntil(x => x % 2 === 0)) - .toArray() - .toPromise(); + const chunks = await _rxjsBundlesRxMinJs.Observable.of(1, 2, 3, 4).let((0, (_observable || _load_observable()).bufferUntil)(x => x % 2 === 0)).toArray().toPromise(); expect(chunks).toEqual([[1, 2], [3, 4]]); })(); }); it('provides the current buffer', async () => { await (async () => { - const chunks = await Observable.of(1, 2, 3, 4) - .let(bufferUntil((x, buffer) => buffer.length === 2)) - .toArray() - .toPromise(); + const chunks = await _rxjsBundlesRxMinJs.Observable.of(1, 2, 3, 4).let((0, (_observable || _load_observable()).bufferUntil)((x, buffer) => buffer.length === 2)).toArray().toPromise(); expect(chunks).toEqual([[1, 2], [3, 4]]); })(); }); @@ -522,17 +476,9 @@ describe('nuclide-commons/observable', () => { describe('completingSwitchMap', () => { it('propagates completions to the inner observable', async () => { await (async () => { - const results = await Observable.of(1, 2) - .let( - completingSwitchMap(x => { - return Observable.concat( - Observable.of(x + 1), - Observable.never(), - ); - }), - ) - .toArray() - .toPromise(); + const results = await _rxjsBundlesRxMinJs.Observable.of(1, 2).let((0, (_observable || _load_observable()).completingSwitchMap)(x => { + return _rxjsBundlesRxMinJs.Observable.concat(_rxjsBundlesRxMinJs.Observable.of(x + 1), _rxjsBundlesRxMinJs.Observable.never()); + })).toArray().toPromise(); expect(results).toEqual([2, 3]); })(); }); @@ -542,17 +488,9 @@ describe('nuclide-commons/observable', () => { it('completes when the first inner observable completes', async () => { const aDone = jest.fn(); const bDone = jest.fn(); - const a = Observable.timer(0, 10) - .mapTo('A') - .take(100) - .finally(aDone); - const b = Observable.timer(5, 10) - .mapTo('B') - .take(3) - .finally(bDone); - const results = await mergeUntilAnyComplete(a, b) - .toArray() - .toPromise(); + const a = _rxjsBundlesRxMinJs.Observable.timer(0, 10).mapTo('A').take(100).finally(aDone); + const b = _rxjsBundlesRxMinJs.Observable.timer(5, 10).mapTo('B').take(3).finally(bDone); + const results = await (0, (_observable || _load_observable()).mergeUntilAnyComplete)(a, b).toArray().toPromise(); expect(results).toEqual(['A', 'B', 'A', 'B', 'A', 'B']); expect(aDone).toHaveBeenCalled(); expect(bDone).toHaveBeenCalled(); @@ -562,21 +500,18 @@ describe('nuclide-commons/observable', () => { describe('fastDebounce', () => { it('debounces events', async () => { let nextSpy; - const originalCreate = Observable.create.bind(Observable); + 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. - jest.spyOn(Observable, 'create').mockImplementation(callback => { + jest.spyOn(_rxjsBundlesRxMinJs.Observable, 'create').mockImplementation(callback => { return originalCreate(observer => { nextSpy = jest.spyOn(observer, 'next'); 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); @@ -592,19 +527,17 @@ describe('nuclide-commons/observable', () => { subject.complete(); await sleep(20); - expect(await promise).toEqual([2, 4]); - expect(nullthrows(nextSpy).mock.calls.length).toBe(2); + expect((await promise)).toEqual([2, 4]); + expect((0, (_nullthrows || _load_nullthrows()).default)(nextSpy).mock.calls.length).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); }); }); @@ -613,9 +546,9 @@ describe('nuclide-commons/observable', () => { it('is cancelable', async () => { await (async () => { const spy = jest.fn(); - 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(r => resolve = r); sub.unsubscribe(); process.nextTick(() => { expect(spy).not.toHaveBeenCalled(); @@ -629,7 +562,7 @@ describe('nuclide-commons/observable', () => { describe('macrotask', () => { it('is cancelable', () => { jest.spyOn(global, 'clearImmediate'); - const sub = macrotask.subscribe(() => {}); + const sub = (_observable || _load_observable()).macrotask.subscribe(() => {}); sub.unsubscribe(); expect(clearImmediate).toHaveBeenCalled(); }); @@ -638,12 +571,12 @@ describe('nuclide-commons/observable', () => { describe('fromAbortablePromise', () => { it('is able to cancel a promise after unsubscription', () => { const spy = jest.fn(); - 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(); }); @@ -651,11 +584,11 @@ describe('nuclide-commons/observable', () => { it('does not trigger an abort after normal completion', async () => { await (async () => { const spy = jest.fn(); - function f(signal: AbortSignal) { + function f(signal) { signal.onabort = spy; return Promise.resolve(1); } - const result = await fromAbortablePromise(f).toPromise(); + const result = await (0, (_observable || _load_observable()).fromAbortablePromise)(f).toPromise(); expect(result).toBe(1); expect(spy).not.toHaveBeenCalled(); })(); @@ -664,17 +597,14 @@ describe('nuclide-commons/observable', () => { describe('toAbortablePromise', () => { it('rejects with a DOMException on abort', async () => { - const controller = new AbortController(); + const controller = new (_AbortController || _load_AbortController()).default(); const spy = jest.fn(); - 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; expect(spy).toHaveBeenCalled(); - const exception: any = spy.mock.calls[0][0]; + const exception = spy.mock.calls[0][0]; expect(exception.constructor.name).toBe('DOMException'); expect(exception.name).toBe('AbortError'); expect(exception.message).toBe('Aborted'); @@ -682,12 +612,10 @@ describe('nuclide-commons/observable', () => { describe('takeUntilAbort', () => { it('completes on abort', () => { - const controller = new AbortController(); + const controller = new (_AbortController || _load_AbortController()).default(); const spy = jest.fn(); - 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(); @@ -695,13 +623,11 @@ describe('nuclide-commons/observable', () => { }); it('completes when already aborted', () => { - const controller = new AbortController(); + const controller = new (_AbortController || _load_AbortController()).default(); controller.abort(); const spy = jest.fn(); - 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(); }); @@ -709,18 +635,18 @@ describe('nuclide-commons/observable', () => { it('works with no signal', async () => { await (async () => { - const promise = toAbortablePromise(Observable.of(1)); - expect(await promise).toBe(1); + const promise = (0, (_observable || _load_observable()).toAbortablePromise)(_rxjsBundlesRxMinJs.Observable.of(1)); + expect((await 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); @@ -731,23 +657,23 @@ describe('nuclide-commons/observable', () => { it('completing task normally', async () => { await (async () => { - const executor = new SingletonExecutor(); - const source = new Subject(); + 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((await result)).toBe(42); expect(executor.isExecuting()).toBe(false); })(); }); it('completing task by error', async () => { await (async () => { - const executor = new SingletonExecutor(); - const source = new Subject(); + const executor = new (_observable || _load_observable()).SingletonExecutor(); + const source = new _rxjsBundlesRxMinJs.Subject(); const result = executor.execute(source); expect(executor.isExecuting()).toBe(true); @@ -767,13 +693,13 @@ describe('nuclide-commons/observable', () => { it('scheduling second task while first is in flight', async () => { await (async () => { - const executor = new SingletonExecutor(); + 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); @@ -790,7 +716,7 @@ describe('nuclide-commons/observable', () => { source2.next(42); source2.complete(); - expect(await result2).toBe(42); + expect((await result2)).toBe(42); expect(executor.isExecuting()).toBe(false); })(); }); @@ -800,28 +726,28 @@ describe('nuclide-commons/observable', () => { beforeEach(() => {}); it('subscribes to the observable synchronously', () => { - const source = Observable.never(); + const source = _rxjsBundlesRxMinJs.Observable.never(); const spy = jest.spyOn(source, 'subscribe'); - const sub = source.let(poll(10)).subscribe(); + const sub = source.let((0, (_observable || _load_observable()).poll)(10)).subscribe(); expect(spy.mock.calls.length).toBe(1); sub.unsubscribe(); }); it('resubscribes when complete', async () => { let mostRecentObserver; - const source = Observable.create(observer => { + const source = _rxjsBundlesRxMinJs.Observable.create(observer => { mostRecentObserver = observer; }); const spy = jest.spyOn(source, 'subscribe'); - const sub = source.let(poll(10)).subscribe(); + const sub = source.let((0, (_observable || _load_observable()).poll)(10)).subscribe(); expect(spy.mock.calls.length).toBe(1); - (mostRecentObserver: any).next(); + mostRecentObserver.next(); // Even though we're waiting longer than the delay, it hasn't completed yet so we shouldn't // resubscribe. await sleep(30); expect(spy.mock.calls.length).toBe(1); - (mostRecentObserver: any).complete(); + mostRecentObserver.complete(); expect(spy.mock.calls.length).toBe(1); // Now that the source has completed, we should subscribe again. @@ -831,12 +757,10 @@ describe('nuclide-commons/observable', () => { }); it("doesn't resubscribe to the source when you unsubscribe", async () => { - const source = new Subject(); + const source = new _rxjsBundlesRxMinJs.Subject(); const spy = jest.spyOn(source, 'subscribe'); - 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.mock.calls.length).toBe(1); source.next(); await sleep(30); @@ -845,18 +769,13 @@ describe('nuclide-commons/observable', () => { it('polls synchronously completing observables', async () => { await (async () => { - const result = await Observable.of('hi') - .let(poll(10)) - .take(2) - .toArray() - .toPromise(); + const result = await _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); - }); +const sleep = n => new Promise(resolve => { + setTimeout(resolve, n); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/process-test.js b/modules/nuclide-commons/__tests__/process-test.js index 3f6f079c86..84c7410eee 100644 --- a/modules/nuclide-commons/__tests__/process-test.js +++ b/modules/nuclide-commons/__tests__/process-test.js @@ -1,3 +1,37 @@ +'use strict'; + +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 _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../../../jest/waits_for')); +} + +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. @@ -6,38 +40,10 @@ * LICENSE file in 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 waitsFor from '../../../jest/waits_for'; - -import { - spawn, - getOutputStream, - killProcess, - killUnixProcessTree, - logStreamErrors, - observeProcess, - observeProcessRaw, - parsePsOutput, - preventStreamsFromThrowing, - ProcessSystemError, - runCommand, - runCommandDetailed, - scriptifyCommand, - exitEventToMessage, - LOG_CATEGORY, -} from '../process'; - jest.mock('../performanceNow'); beforeEach(() => { @@ -51,164 +57,119 @@ 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', async () => { await (async () => { const proc = { - kill: jasmine.createSpy(), + kill: jasmine.createSpy() }; jest.spyOn(console, 'log'); // suppress log printing - await killProcess((proc: any), false); + await (0, (_process || _load_process()).killProcess)(proc, false); expect(proc.kill).toHaveBeenCalled(); })(); }); it('should kill the process tree when `killTree` is true', async () => { // 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']); jest.spyOn(console, 'log'); // suppress log printing jest.spyOn(process, 'kill'); - await sleep(250); // Give some time for the processes to spawn. - await killUnixProcessTree(proc); + await (0, (_promise || _load_promise()).sleep)(250); // Give some time for the processes to spawn. + await (0, (_process || _load_process()).killUnixProcessTree)(proc); expect(process.kill.mock.calls.length).toBeGreaterThan(2); }); it('should kill the process tree on windows when `killTree` is true', async () => { await (async () => { const proc = { - pid: 123, + pid: 123 }; jest.spyOn(console, 'log'); // suppress log printing - Object.defineProperty(process, 'platform', {value: 'win32'}); - jest.spyOn(child_process, 'exec'); - await killProcess((proc: any), true); - expect(child_process.exec.mock.calls).toHaveLength(1); - expect(child_process.exec.mock.calls[0][0]).toBe( - `taskkill /pid ${proc.pid} /T /F`, - ); + Object.defineProperty(process, 'platform', { value: 'win32' }); + jest.spyOn(_child_process.default, 'exec'); + await (0, (_process || _load_process()).killProcess)(proc, true); + expect(_child_process.default.exec.mock.calls).toHaveLength(1); + expect(_child_process.default.exec.mock.calls[0][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); - 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', - }, - ]); + const 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' + }]); }); it('parse `ps` unix output with command arguments', () => { - const unixPsOut = - ' 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'; - - const processList = 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', - }, - ]); + const unixPsOut = ' 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'; + + 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' + }]); }); it('parse `ps` windows output', () => { - const windowsProcessOut = - 'ParentProcessId ProcessId Name\r\n' + - ' 0 4 System Process\r\n' + - ' 4 228 smss.exe'; - - const processList = 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', - }, - ]); + const windowsProcessOut = 'ParentProcessId ProcessId Name\r\n' + ' 0 4 System Process\r\n' + ' 4 228 smss.exe'; + + 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' + }]); }); }); describe('getOutputStream', () => { it('captures stdout, stderr and exitCode', async () => { await (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(); - expect(results).toEqual([ - {kind: 'stderr', data: 'stderr\n'}, - {kind: 'stdout', data: 'std out\n'}, - {kind: 'exit', exitCode: 0, signal: null}, - ]); + const child = _child_process.default.spawn(process.execPath, ['-e', 'console.error("stderr"); console.log("std out"); process.exit(0);']); + const results = await (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 }]); })(); }); it('errors on nonzero exit codes by default', async () => { await (async () => { - const child = child_process.spawn(process.execPath, [ - '-e', - 'console.error("stderr"); console.log("std out"); process.exit(42);', - ]); - const results = await getOutputStream(child) - .materialize() - .toArray() - .toPromise(); - expect(results.map(notification => notification.kind)).toEqual([ - 'N', - 'N', - 'E', - ]); - const {error} = results[2]; + const child = _child_process.default.spawn(process.execPath, ['-e', 'console.error("stderr"); console.log("std out"); process.exit(42);']); + const results = await (0, (_process || _load_process()).getOutputStream)(child).materialize().toArray().toPromise(); + expect(results.map(notification => 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'); @@ -218,22 +179,21 @@ describe('commons-node/process', () => { it('accumulates the first `exitErrorBufferSize` bytes of stderr for the exit error', async () => { await (async () => { 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, { + await (0, (_process || _load_process()).getOutputStream)(child, { exitErrorBufferSize: 2, - isExitError: () => true, - }) - .toArray() - .toPromise(); + isExitError: () => true + }).toArray().toPromise(); } catch (err) { error = err; } expect(error).toBeDefined(); - invariant(error != null); + + if (!(error != null)) { + throw new Error('Invariant violation: "error != null"'); + } + expect(error.stderr).toBe('st'); })(); }); @@ -242,8 +202,8 @@ describe('commons-node/process', () => { describe('spawn', () => { it('errors when the process does', async () => { jest.spyOn(console, 'log'); // suppress log printing - const processStream = spawn('fakeCommand', undefined, { - dontLogInNuclide: true, + const processStream = (0, (_process || _load_process()).spawn)('fakeCommand', undefined, { + dontLogInNuclide: true }); let error; try { @@ -252,7 +212,11 @@ describe('commons-node/process', () => { error = err; } expect(error).toBeDefined(); - invariant(error); + + if (!error) { + throw new Error('Invariant violation: "error"'); + } + expect(error.code).toBe('ENOENT'); expect(error.message).toBe('spawn fakeCommand ENOENT'); }); @@ -264,17 +228,14 @@ describe('commons-node/process', () => { it('errors before emitting the process', async () => { jest.spyOn(console, 'log'); // suppress log printing let proc; - await spawn('fakeCommand', undefined, {dontLogInNuclide: true}) - .do(p => { - proc = p; - }) - .catch(err => { - expect(proc).toBeUndefined(); - expect(err.code).toBe('ENOENT'); - expect(err.message).toBe('spawn fakeCommand ENOENT'); - return Observable.empty(); - }) - .toPromise(); + await (0, (_process || _load_process()).spawn)('fakeCommand', undefined, { dontLogInNuclide: true }).do(p => { + proc = p; + }).catch(err => { + expect(proc).toBeUndefined(); + expect(err.code).toBe('ENOENT'); + expect(err.message).toBe('spawn fakeCommand ENOENT'); + return _rxjsBundlesRxMinJs.Observable.empty(); + }).toPromise(); }); it('leaves an error handler when you unsubscribe', async () => { @@ -284,45 +245,40 @@ describe('commons-node/process', () => { const promise = new Promise(r => { resolve = r; }); - const sub = spawn('cat', undefined, {dontLogInNuclide: true}) - // 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(); - }); + const sub = (0, (_process || _load_process()).spawn)('cat', undefined, { dontLogInNuclide: true }) + // 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(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; })(); }); it('can be retried', async () => { jest.spyOn(console, 'log'); // suppress log printing - jest.spyOn(child_process, 'spawn'); + jest.spyOn(_child_process.default, 'spawn'); try { - await spawn('fakeCommand', undefined, {dontLogInNuclide: true}) - .retryWhen(errors => - errors.scan((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 - // this test if we only tried twice.) - if (errorCount === 2) { - throw err; - } - return errorCount + 1; - }, 0), - ) - .toPromise(); + await (0, (_process || _load_process()).spawn)('fakeCommand', undefined, { dontLogInNuclide: true }).retryWhen(errors => errors.scan((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 + // this test if we only tried twice.) + if (errorCount === 2) { + throw err; + } + return errorCount + 1; + }, 0)).toPromise(); } catch (err) {} - expect(child_process.spawn.mock.calls).toHaveLength(3); + expect(_child_process.default.spawn.mock.calls).toHaveLength(3); }); it('can be timed out', async () => { @@ -330,17 +286,22 @@ describe('commons-node/process', () => { let error; let proc; try { - await spawn('sleep', ['10000'], {timeout: 1}) - .do(p => { - proc = p; - jest.spyOn(proc, 'kill'); - }) - .toPromise(); + await (0, (_process || _load_process()).spawn)('sleep', ['10000'], { timeout: 1 }).do(p => { + proc = p; + jest.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(); })(); @@ -351,7 +312,7 @@ describe('commons-node/process', () => { it('errors when the process does', async () => { await (async () => { jest.spyOn(console, 'log'); // suppress log printing - const processStream = observeProcess('fakeCommand', []); + const processStream = (0, (_process || _load_process()).observeProcess)('fakeCommand', []); let error; try { await processStream.toPromise(); @@ -359,7 +320,11 @@ describe('commons-node/process', () => { error = err; } expect(error).toBeDefined(); - invariant(error); + + if (!error) { + throw new Error('Invariant violation: "error"'); + } + expect(error.code).toBe('ENOENT'); expect(error.message).toBe('spawn fakeCommand ENOENT'); })(); @@ -367,19 +332,9 @@ describe('commons-node/process', () => { it('errors on nonzero exit codes by default', async () => { await (async () => { - const results = await observeProcess(process.execPath, [ - '-e', - 'console.error("stderr"); console.log("std out"); process.exit(42);', - ]) - .materialize() - .toArray() - .toPromise(); - expect(results.map(notification => notification.kind)).toEqual([ - 'N', - 'N', - 'E', - ]); - const {error} = results[2]; + const results = await (0, (_process || _load_process()).observeProcess)(process.execPath, ['-e', 'console.error("stderr"); console.log("std out"); process.exit(42);']).materialize().toArray().toPromise(); + expect(results.map(notification => 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'); @@ -388,13 +343,7 @@ describe('commons-node/process', () => { it("doesn't get an exit message when there's an exit error", async () => { await (async () => { - const results = await observeProcess(process.execPath, [ - '-e', - 'process.exit(42);', - ]) - .materialize() - .toArray() - .toPromise(); + const results = await (0, (_process || _load_process()).observeProcess)(process.execPath, ['-e', 'process.exit(42);']).materialize().toArray().toPromise(); expect(results.length).toBe(1); expect(results[0].kind).toBe('E'); })(); @@ -404,18 +353,16 @@ describe('commons-node/process', () => { await (async () => { let error; try { - await observeProcess( - process.execPath, - ['-e', 'console.error("stderr"); process.exit(42);'], - {exitErrorBufferSize: 2, isExitError: () => true}, - ) - .toArray() - .toPromise(); + await (0, (_process || _load_process()).observeProcess)(process.execPath, ['-e', 'console.error("stderr"); process.exit(42);'], { exitErrorBufferSize: 2, isExitError: () => true }).toArray().toPromise(); } catch (err) { error = err; } expect(error).toBeDefined(); - invariant(error != null); + + if (!(error != null)) { + throw new Error('Invariant violation: "error != null"'); + } + expect(error.stderr).toBe('st'); })(); }); @@ -425,13 +372,12 @@ describe('commons-node/process', () => { it("doesn't split on line breaks", async () => { jest.spyOn(console, 'log'); // suppress log printing await (async () => { - const event = await observeProcessRaw(process.execPath, [ - '-e', - 'process.stdout.write("stdout1\\nstdout2\\n"); process.exit(1)', - ]) - .take(1) - .toPromise(); - invariant(event.kind === 'stdout'); + const event = await (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'); })(); }); @@ -448,38 +394,42 @@ describe('commons-node/process', () => { } it('sends the stdin to the process', async () => { - const output = await runCommand('cat', [], { - input: 'hello', + const output = await (0, (_process || _load_process()).runCommand)('cat', [], { + input: 'hello' }).toPromise(); expect(output).toBe('hello'); }); it('sends a stream of stdin to the process', async () => { - const input = new Subject(); - const outputPromise = runCommand('cat', [], { - input, + 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((await outputPromise)).toBe('hello world'); }); it('enforces maxBuffer', async () => { let error; try { - await runCommand('yes', [], {maxBuffer: 100}).toPromise(); + await (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', async () => { - const val = await runCommand('echo', ['-n', 'foo'], { - env: process.env, + const val = await (0, (_process || _load_process()).runCommand)('echo', ['-n', 'foo'], { + env: process.env }).toPromise(); expect(val).toEqual('foo'); }); @@ -487,17 +437,21 @@ describe('commons-node/process', () => { it("throws an error if the process can't be spawned", async () => { let error; try { - await runCommand('fakeCommand').toPromise(); + await (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.message).toBe('spawn fakeCommand ENOENT'); }); it('throws an error if the exit code !== 0', async () => { - const cmd = runCommand(process.execPath, ['-e', 'process.exit(1)']); + const cmd = (0, (_process || _load_process()).runCommand)(process.execPath, ['-e', 'process.exit(1)']); await expect(cmd.toPromise()).rejects.toThrow('failed with exit code 1'); }); @@ -505,14 +459,15 @@ describe('commons-node/process', () => { await (async () => { let error; try { - await runCommand(process.execPath, [ - '-e', - 'process.stderr.write("oopsy"); process.stdout.write("daisy"); process.exit(1)', - ]).toPromise(); + await (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'); @@ -523,14 +478,15 @@ describe('commons-node/process', () => { await (async () => { let error; try { - await runCommand(process.execPath, [ - '-e', - 'process.stderr.write("oopsy"); process.exit(1)', - ]).toPromise(); + await (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'); })(); }); @@ -539,12 +495,9 @@ describe('commons-node/process', () => { // mutated value. it("doesn't share a mutable seed (regression test)", async () => { await (async () => { - const observable = runCommand(process.execPath, [ - '-e', - 'process.stdout.write("hello"); process.exit(0)', - ]); + const observable = (0, (_process || _load_process()).runCommand)(process.execPath, ['-e', 'process.stdout.write("hello"); process.exit(0)']); await observable.toPromise(); - expect(await observable.toPromise()).toBe('hello'); + expect((await observable.toPromise())).toBe('hello'); })(); }); @@ -552,16 +505,14 @@ describe('commons-node/process', () => { if (origPlatform !== 'win32') { it('returns stdout of the running process', async () => { await (async () => { - const val = await runCommand('echo', ['-n', 'foo'], { - env: process.env, + const val = await (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', async () => { - await expect( - runCommand(process.execPath, ['-e', 'process.exit(1)']).toPromise(), - ).rejects.toThrow('failed with exit code 1'); + await expect((0, (_process || _load_process()).runCommand)(process.execPath, ['-e', 'process.exit(1)']).toPromise()).rejects.toThrow('failed with exit code 1'); }); } }); @@ -579,8 +530,8 @@ describe('commons-node/process', () => { it('sends the stdin to the process', async () => { await (async () => { - const output = await runCommandDetailed('cat', [], { - input: 'hello', + const output = await (0, (_process || _load_process()).runCommandDetailed)('cat', [], { + input: 'hello' }).toPromise(); expect(output.stdout).toBe('hello'); })(); @@ -590,33 +541,38 @@ describe('commons-node/process', () => { await (async () => { let error; try { - await runCommandDetailed('yes', [], {maxBuffer: 100}).toPromise(); + await (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', async () => { await (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}); + const val = await (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", async () => { let error; try { - await runCommandDetailed('fakeCommand').toPromise(); + await (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.message).toBe('spawn fakeCommand ENOENT'); }); @@ -624,14 +580,15 @@ describe('commons-node/process', () => { it('throws an error if the exit code !== 0', async () => { let error; try { - await runCommandDetailed(process.execPath, [ - '-e', - 'process.exit(1)', - ]).toPromise(); + await (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); }); @@ -640,14 +597,15 @@ describe('commons-node/process', () => { await (async () => { let error; try { - await runCommandDetailed(process.execPath, [ - '-e', - 'process.stderr.write("oopsy"); process.exit(1)', - ]).toPromise(); + await (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'); })(); }); @@ -655,24 +613,22 @@ describe('commons-node/process', () => { 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'); + expect((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() + }; jest.spyOn(proc.stdin, 'addListener'); jest.spyOn(proc.stdout, 'addListener'); jest.spyOn(proc.stderr, 'addListener'); @@ -682,48 +638,30 @@ describe('commons-node/process', () => { }); it('adds listeners', () => { - preventStreamsFromThrowing(proc); - expect(proc.stdin.addListener).toHaveBeenCalledWith( - 'error', - jasmine.any(Function), - ); - expect(proc.stdout.addListener).toHaveBeenCalledWith( - 'error', - jasmine.any(Function), - ); - expect(proc.stderr.addListener).toHaveBeenCalledWith( - 'error', - jasmine.any(Function), - ); + (0, (_process || _load_process()).preventStreamsFromThrowing)(proc); + expect(proc.stdin.addListener).toHaveBeenCalledWith('error', jasmine.any(Function)); + expect(proc.stdout.addListener).toHaveBeenCalledWith('error', jasmine.any(Function)); + expect(proc.stderr.addListener).toHaveBeenCalledWith('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), - ); - expect(proc.stdout.removeListener).toHaveBeenCalledWith( - 'error', - jasmine.any(Function), - ); - expect(proc.stderr.removeListener).toHaveBeenCalledWith( - 'error', - jasmine.any(Function), - ); + expect(proc.stdin.removeListener).toHaveBeenCalledWith('error', jasmine.any(Function)); + expect(proc.stdout.removeListener).toHaveBeenCalledWith('error', jasmine.any(Function)); + expect(proc.stderr.removeListener).toHaveBeenCalledWith('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', () => {}); @@ -732,13 +670,13 @@ describe('commons-node/process', () => { }); it('logs errors', () => { - logStreamErrors(proc, 'test', [], {}); + (0, (_process || _load_process()).logStreamErrors)(proc, 'test', [], {}); 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', [], {}); disposable.dispose(); proc.stderr.emit('error', new Error('Test error')); expect(logger.error).not.toHaveBeenCalled(); @@ -747,14 +685,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', + syscall: 'syscall value' }; - const err = new ProcessSystemError(originalError, proc); + 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'); @@ -767,25 +705,18 @@ describe('commons-node/process', () => { if (process.platform === 'linux') { it('escapes correctly on linux', async () => { await (async () => { - const output = await runCommand( - ...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', - ); + const output = await (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'); })(); }); } }); }); -function makeExitMessage(exitCode: number): ProcessExitMessage { +function makeExitMessage(exitCode) { return { kind: 'exit', exitCode, - signal: null, + signal: null }; -} +} \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/promise-test.js b/modules/nuclide-commons/__tests__/promise-test.js index 937da8b92d..cce48018df 100644 --- a/modules/nuclide-commons/__tests__/promise-test.js +++ b/modules/nuclide-commons/__tests__/promise-test.js @@ -1,36 +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 - */ +'use strict'; -/* eslint-disable prefer-promise-reject-errors */ +var _promise; + +function _load_promise() { + return _promise = require('../promise'); +} + +var _testHelpers; + +function _load_testHelpers() { + return _testHelpers = require('../test-helpers'); +} + +var _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../../../jest/waits_for')); +} -import { - asyncFind, - denodeify, - serializeAsyncCall, - asyncLimit, - asyncFilter, - asyncObjFilter, - asyncSome, - lastly, - retryLimit, - RequestSerializer, - TimedOutError, - timeoutPromise, -} from '../promise'; -import invariant from 'assert'; -import {expectAsyncFailure} from '../test-helpers'; -import waitsFor from '../../../jest/waits_for'; - -jest.useFakeTimers(); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +jest.useFakeTimers(); /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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()', () => { beforeEach(() => { @@ -48,17 +50,15 @@ describe('promises::asyncFind()', () => { throw new Error('Should not be called.'); }; - asyncFind(args, test) - .then(result => { - observedResult = result; - isResolved = true; - }) - .catch(error => { - observedError = error; - isRejected = true; - }); + (0, (_promise || _load_promise()).asyncFind)(args, test).then(result => { + observedResult = result; + isResolved = true; + }).catch(error => { + observedError = error; + isRejected = true; + }); - await waitsFor(() => isResolved || isRejected); + await (0, (_waits_for || _load_waits_for()).default)(() => isResolved || isRejected); expect(isResolved).toBe(true); expect(observedResult).toBe(null); @@ -83,17 +83,15 @@ describe('promises::asyncFind()', () => { } }; - asyncFind(args, test) - .then(result => { - observedResult = result; - isResolved = true; - }) - .catch(error => { - observedError = error; - isRejected = true; - }); + (0, (_promise || _load_promise()).asyncFind)(args, test).then(result => { + observedResult = result; + isResolved = true; + }).catch(error => { + observedError = error; + isRejected = true; + }); - await waitsFor(() => isResolved || isRejected); + await (0, (_waits_for || _load_waits_for()).default)(() => isResolved || isRejected); expect(isResolved).toBe(true); expect(observedResult).toBe('win'); @@ -115,7 +113,7 @@ describe('promises::denodeify()', () => { * rather than at the end. The type signature of this function cannot be * expressed in Flow. */ - function asyncProduct(...factors): void { + function asyncProduct(...factors) { const callback = factors.pop(); const product = factors.reduce((previousValue, currentValue) => { return previousValue * currentValue; @@ -129,7 +127,7 @@ describe('promises::denodeify()', () => { } it('resolves Promise when callback succeeds', async () => { - const denodeifiedAsyncProduct = denodeify(asyncProduct); + const denodeifiedAsyncProduct = (0, (_promise || _load_promise()).denodeify)(asyncProduct); await (async () => { const trivialProduct = await denodeifiedAsyncProduct(); expect(trivialProduct).toBe(1); @@ -140,14 +138,11 @@ describe('promises::denodeify()', () => { }); it('rejects Promise when callback fails', async () => { - const denodeifiedAsyncProduct = denodeify(asyncProduct); + const denodeifiedAsyncProduct = (0, (_promise || _load_promise()).denodeify)(asyncProduct); await (async () => { - await expectAsyncFailure( - denodeifiedAsyncProduct('a', 'b'), - (error: Error) => { - expect(error.message).toBe('product was NaN'); - }, - ); + await (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)(denodeifiedAsyncProduct('a', 'b'), error => { + expect(error.message).toBe('product was NaN'); + }); })(); }); @@ -160,22 +155,19 @@ describe('promises::denodeify()', () => { } it('result of denodeify propagates receiver as expected', async () => { - const denodeifiedChecksReceiver = denodeify(checksReceiver); + const denodeifiedChecksReceiver = (0, (_promise || _load_promise()).denodeify)(checksReceiver); await (async () => { - const receiver = {denodeifiedChecksReceiver}; + const receiver = { denodeifiedChecksReceiver }; const result = await receiver.denodeifiedChecksReceiver(receiver); expect(result).toBe('winner'); })(); await (async () => { - const receiver = {denodeifiedChecksReceiver}; - await expectAsyncFailure( - receiver.denodeifiedChecksReceiver(null), - (error: Error) => { - expect(error.message).toBe('unexpected receiver'); - }, - ); + const receiver = { denodeifiedChecksReceiver }; + await (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)(receiver.denodeifiedChecksReceiver(null), error => { + expect(error.message).toBe('unexpected receiver'); + }); })(); }); }); @@ -185,7 +177,7 @@ describe('promises::serializeAsyncCall()', () => { jest.useRealTimers(); let i = 0; const asyncFunSpy = jasmine.createSpy('async'); - const oneAsyncCallAtATime = serializeAsyncCall(() => { + const oneAsyncCallAtATime = (0, (_promise || _load_promise()).serializeAsyncCall)(() => { i++; const resultPromise = waitPromise(10, i); asyncFunSpy(); @@ -200,20 +192,16 @@ describe('promises::serializeAsyncCall()', () => { await waitPromise(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); + (0, (_waits_for || _load_waits_for()).default)(() => asyncFunSpy.callCount === 2); await waitPromise(11); - const results = await Promise.all([ - result1Promise, - result2Promise, - result3Promise, - ]); + 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', async () => { jest.useFakeTimers(); let i = 0; - const oneAsyncCallAtATime = serializeAsyncCall(() => { + const oneAsyncCallAtATime = (0, (_promise || _load_promise()).serializeAsyncCall)(() => { i++; if (i === 4) { return Promise.reject('ERROR'); @@ -234,7 +222,7 @@ describe('promises::serializeAsyncCall()', () => { const errorPromoise = oneAsyncCallAtATime(); jest.advanceTimersByTime(11); - await expectAsyncFailure(errorPromoise, error => { + await (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)(errorPromoise, error => { expect(error).toBe('ERROR'); }); @@ -251,24 +239,14 @@ describe('promises::asyncLimit()', () => { }); it('runs in series if limit is 1', async () => { - const {result, parallelismHistory} = await captureParallelismHistory( - asyncLimit, - [[1, 2, 3], 1, item => waitPromise(10, item + 1)], - ); + const { result, parallelismHistory } = await captureParallelismHistory((_promise || _load_promise()).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', async () => { await (async () => { - const {result, parallelismHistory} = await captureParallelismHistory( - asyncLimit, - [ - [1, 2, 3, 4, 5, 6, 7, 8, 9], - 3, - item => waitPromise(10 + item, item - 1), - ], - ); + const { result, parallelismHistory } = await captureParallelismHistory((_promise || _load_promise()).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]); })(); @@ -276,29 +254,24 @@ describe('promises::asyncLimit()', () => { it('works when the limit is bigger than the array length', async () => { await (async () => { - const result = await asyncLimit([1, 2, 3], 10, item => - waitPromise(10, item * 2), - ); + const result = await (0, (_promise || _load_promise()).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', async () => { await (async () => { - await expectAsyncFailure( - asyncLimit([1], 1, async item => { - throw new Error('rejected iterator promise'); - }), - (error: Error) => { - expect(error.message).toBe('rejected iterator promise'); - }, - ); + await (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)((0, (_promise || _load_promise()).asyncLimit)([1], 1, async item => { + throw new Error('rejected iterator promise'); + }), error => { + expect(error.message).toBe('rejected iterator promise'); + }); })(); }); it('works when the array is empty', async () => { await (async () => { - const result = await asyncLimit([], 1, () => Promise.resolve()); + const result = await (0, (_promise || _load_promise()).asyncLimit)([], 1, () => Promise.resolve()); expect(result).toEqual([]); })(); }); @@ -314,11 +287,8 @@ describe('promises::asyncFilter()', () => { await (async () => { const { result: filtered, - parallelismHistory, - } = await captureParallelismHistory(asyncFilter, [ - [1, 2, 3, 4, 5], - item => waitPromise(10 + item, item > 2), - ]); + parallelismHistory + } = await captureParallelismHistory((_promise || _load_promise()).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]); })(); @@ -328,12 +298,8 @@ describe('promises::asyncFilter()', () => { await (async () => { const { result: filtered, - parallelismHistory, - } = await captureParallelismHistory(asyncFilter, [ - [1, 2, 3, 4, 5], - item => waitPromise(10 + item, item > 2), - 3, - ]); + parallelismHistory + } = await captureParallelismHistory((_promise || _load_promise()).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]); @@ -351,12 +317,9 @@ describe('promises::asyncObjFilter()', () => { await (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}); + parallelismHistory + } = await captureParallelismHistory((_promise || _load_promise()).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]); })(); }); @@ -365,13 +328,9 @@ describe('promises::asyncObjFilter()', () => { await (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}); + parallelismHistory + } = await captureParallelismHistory((_promise || _load_promise()).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]); })(); @@ -386,10 +345,7 @@ describe('promises::asyncSome()', () => { // eslint-disable-next-line max-len it('some an array with an async iterator and maximum parallelization when no limit is specified', async () => { await (async () => { - const {result, parallelismHistory} = await captureParallelismHistory( - asyncSome, - [[1, 2, 3, 4, 5], item => waitPromise(10, item === 6)], - ); + const { result, parallelismHistory } = await captureParallelismHistory((_promise || _load_promise()).asyncSome, [[1, 2, 3, 4, 5], item => waitPromise(10, item === 6)]); expect(result).toEqual(false); expect(parallelismHistory).toEqual([1, 2, 3, 4, 5]); })(); @@ -397,10 +353,7 @@ describe('promises::asyncSome()', () => { it('some an array with a limit on parallelization', async () => { await (async () => { - const {result, parallelismHistory} = await captureParallelismHistory( - asyncSome, - [[1, 2, 3, 4, 5], item => waitPromise(10 + item, item === 5), 3], - ); + const { result, parallelismHistory } = await captureParallelismHistory((_promise || _load_promise()).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]); })(); @@ -411,7 +364,7 @@ describe('promises::lastly', () => { it('executes after a resolved promise', async () => { await (async () => { const spy = jasmine.createSpy('spy'); - const result = await lastly(Promise.resolve(1), spy); + const result = await (0, (_promise || _load_promise()).lastly)(Promise.resolve(1), spy); expect(result).toBe(1); expect(spy).toHaveBeenCalled(); })(); @@ -420,7 +373,7 @@ describe('promises::lastly', () => { it('executes after a rejected promise', async () => { await (async () => { const spy = jasmine.createSpy('spy'); - await expectAsyncFailure(lastly(Promise.reject(2), spy), err => { + await (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)((0, (_promise || _load_promise()).lastly)(Promise.reject(2), spy), err => { expect(err).toBe(2); }); expect(spy).toHaveBeenCalled(); @@ -430,7 +383,7 @@ describe('promises::lastly', () => { it('works for async functions', async () => { await (async () => { const spy = jasmine.createSpy('spy'); - const result = await lastly(Promise.resolve(1), async () => { + const result = await (0, (_promise || _load_promise()).lastly)(Promise.resolve(1), async () => { spy(); }); expect(result).toBe(1); @@ -449,23 +402,19 @@ describe('promises::retryLimit()', () => { 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, - ); + const retrialsResult = await (0, (_promise || _load_promise()).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'); @@ -476,18 +425,14 @@ describe('promises::retryLimit()', () => { await (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 => { + const failRetriesPromise = (0, (_promise || _load_promise()).retryLimit)(() => { + calls++; + return Promise.reject('ERROR'); + }, result => { + validationCalls++; + return result != null; + }, 2); + await (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)(failRetriesPromise, error => { expect(error).toBe('ERROR'); }); expect(calls).toBe(2); @@ -500,21 +445,17 @@ describe('promises::retryLimit()', () => { 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, - ); + const retryResult = await (0, (_promise || _load_promise()).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); @@ -523,16 +464,12 @@ describe('promises::retryLimit()', () => { it('no valid response is ever got', async () => { await (async () => { - const nonValidRetriesPromise = retryLimit( - () => { - return Promise.resolve('A'); - }, - result => { - return result === 'B'; - }, - 2, - ); - await expectAsyncFailure(nonValidRetriesPromise, error => { + const nonValidRetriesPromise = (0, (_promise || _load_promise()).retryLimit)(() => { + return Promise.resolve('A'); + }, result => { + return result === 'B'; + }, 2); + await (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)(nonValidRetriesPromise, error => { expect(error.message).toBe('No valid response found!'); }); })(); @@ -540,21 +477,25 @@ describe('promises::retryLimit()', () => { }); describe('promises::RequestSerializer()', () => { - let requestSerializer: RequestSerializer = (null: any); + let requestSerializer = null; beforeEach(() => { jest.useRealTimers(); - requestSerializer = new RequestSerializer(); + requestSerializer = new (_promise || _load_promise()).RequestSerializer(); }); it('gets outdated result for old promises resolving after newer calls', async () => { await (async () => { const oldPromise = requestSerializer.run(waitPromise(10, 'OLD')); const newPromise = requestSerializer.run(waitPromise(5, 'NEW')); - const {status: oldStatus} = await oldPromise; + const { status: oldStatus } = await oldPromise; expect(oldStatus).toBe('outdated'); const newResult = await newPromise; - invariant(newResult.status === 'success'); + + if (!(newResult.status === 'success')) { + throw new Error('Invariant violation: "newResult.status === \'success\'"'); + } + expect(newResult.result).toBe('NEW'); })(); }); @@ -591,58 +532,49 @@ describe('timeoutPromise', () => { it('should resolve normally if within the timeout', async () => { await (async () => { const inputPromise = new Promise(resolve => resolve('foo')); - const outputPromise = timeoutPromise(inputPromise, 1000); - expect(await outputPromise).toBe('foo'); + const outputPromise = (0, (_promise || _load_promise()).timeoutPromise)(inputPromise, 1000); + expect((await outputPromise)).toBe('foo'); })(); }); it('should reject if the given promise rejects', async () => { await (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'); + const outputPromise = (0, (_promise || _load_promise()).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', async () => { jest.useFakeTimers(); const inputPromise = new Promise(resolve => setTimeout(resolve, 2000)); - const outputPromise = timeoutPromise(inputPromise, 1000).catch( - value => value, - ); + const outputPromise = (0, (_promise || _load_promise()).timeoutPromise)(inputPromise, 1000).catch(value => value); jest.advanceTimersByTime(1500); - expect(await outputPromise).toEqual(new TimedOutError(1000)); + expect((await outputPromise)).toEqual(new (_promise || _load_promise()).TimedOutError(1000)); }); }); -async function captureParallelismHistory( - asyncFunction: (...args: Array) => Promise, - args: Array, -): Promise<{result: mixed, parallelismHistory: Array}> { +async function captureParallelismHistory(asyncFunction, args) { const parallelismHistory = []; let parralelism = 0; - const result = await asyncFunction( - ...args.map(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}; + const result = await asyncFunction(...args.map(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 { +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/__tests__/range-test.js b/modules/nuclide-commons/__tests__/range-test.js index 95e188a0ec..f45c4bd4e9 100644 --- a/modules/nuclide-commons/__tests__/range-test.js +++ b/modules/nuclide-commons/__tests__/range-test.js @@ -1,33 +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 strict - * @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); + 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(); - invariant(match != null); + + 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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/shell-quote-test.js b/modules/nuclide-commons/__tests__/shell-quote-test.js index f542088c3c..5bf8b5edf7 100644 --- a/modules/nuclide-commons/__tests__/shell-quote-test.js +++ b/modules/nuclide-commons/__tests__/shell-quote-test.js @@ -1,16 +1,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. - * - * @flow - * @format - */ +'use strict'; + +var _shellQuote; -import {parse, quote} from '../_shell-quote'; +function _load_shellQuote() { + return _shellQuote = require('../_shell-quote'); +} /** * The rest of shell-quote has been verified to work correctly. @@ -20,23 +14,28 @@ import {parse, quote} from '../_shell-quote'; 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/__tests__/stream-test.js b/modules/nuclide-commons/__tests__/stream-test.js index b85e6939e5..9f4fa124f8 100644 --- a/modules/nuclide-commons/__tests__/stream-test.js +++ b/modules/nuclide-commons/__tests__/stream-test.js @@ -1,29 +1,31 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict-local - * @format - */ +'use strict'; -import {observeStream, observeRawStream, writeToStream} from '../stream'; -import fsPromise from '../fsPromise'; -import Stream from 'stream'; -import fs from 'fs'; -import path from 'path'; +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')); + +var _path = _interopRequireDefault(require('path')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } describe('commons-node/stream', () => { it('observeStream', async () => { await (async () => { const input = ['foo\nbar', '\n', '\nba', 'z', '\nblar']; - const stream = new Stream.PassThrough(); - const promise = observeStream(stream) - .toArray() - .toPromise(); + const stream = new _stream2.default.PassThrough(); + const promise = (0, (_stream || _load_stream()).observeStream)(stream).toArray().toPromise(); input.forEach(value => { stream.write(value, 'utf8'); }); @@ -35,15 +37,11 @@ describe('commons-node/stream', () => { it('observeStream - error', async () => { await (async () => { - const stream = new Stream.PassThrough(); + 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), - () => {}, - ); + (0, (_stream || _load_stream()).observeStream)(stream).subscribe(v => output.push(v), e => resolve(e), () => {}); }); const error = new Error('Had an error'); @@ -60,22 +58,27 @@ describe('commons-node/stream', () => { it('writeToStream', async () => { await (async () => { - const tempPath = await fsPromise.tempfile(); - const fixturePath = path.resolve( - __dirname, - '../__mocks__/fixtures/lyrics', - ); - const stream = fs.createWriteStream(tempPath, {highWaterMark: 10}); + const tempPath = await (_fsPromise || _load_fsPromise()).default.tempfile(); + const fixturePath = _path.default.resolve(__dirname, '../__mocks__/fixtures/lyrics'); + 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(); + await (0, (_stream || _load_stream()).writeToStream)(observable, stream).toPromise(); - const writtenFile = await fsPromise.readFile(tempPath); - const fixtureFile = await fsPromise.readFile(fixturePath); + const writtenFile = await (_fsPromise || _load_fsPromise()).default.readFile(tempPath); + const fixtureFile = await (_fsPromise || _load_fsPromise()).default.readFile(fixturePath); expect(writtenFile).toEqual(fixtureFile); })(); }); -}); +}); /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/string-test.js b/modules/nuclide-commons/__tests__/string-test.js index 3ee5491140..f66a9e15bc 100644 --- a/modules/nuclide-commons/__tests__/string-test.js +++ b/modules/nuclide-commons/__tests__/string-test.js @@ -1,29 +1,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. - * - * @flow strict-local - * @format - */ +'use strict'; -import { - capitalize, - countOccurrences, - getMatchRanges, - indent, - maybeToString, - pluralize, - relativeDate, - removeCommonPrefix, - removeCommonSuffix, - shellParse, - shorten, - splitOnce, -} from '../string'; +var _string; + +function _load_string() { + return _string = require('../string'); +} describe('relativeDate', () => { it('works', () => { @@ -39,267 +20,207 @@ 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( - relativeDate(reference - 41 * SECOND, reference, /* short */ true), - ).toEqual('now'); - expect( - relativeDate(reference - 42 * SECOND, reference, /* short */ true), - ).toEqual('1m'); - expect( - relativeDate(reference - MINUTE, reference, /* short */ true), - ).toEqual('1m'); - expect( - relativeDate(reference - MINUTE * 1.5, reference, /* short */ true), - ).toEqual('2m'); - expect( - relativeDate(reference - MINUTE * 59, reference, /* short */ true), - ).toEqual('59m'); - expect(relativeDate(reference - HOUR, reference, /* short */ true)).toEqual( - '1h', - ); - expect( - relativeDate(reference - HOUR * 1.5, reference, /* short */ true), - ).toEqual('2h'); - expect( - relativeDate(reference - HOUR * 16, reference, /* short */ true), - ).toEqual('16h'); - expect( - relativeDate(reference - HOUR * 23, reference, /* short */ true), - ).toEqual('23h'); - expect( - relativeDate(reference - DAY * 1.8, reference, /* short */ true), - ).toEqual('1d'); - expect( - relativeDate(reference - DAY * 3, reference, /* short */ true), - ).toEqual('3d'); - expect( - relativeDate(reference - DAY * 6, reference, /* short */ true), - ).toEqual('6d'); - expect(relativeDate(reference - WEEK, reference, /* short */ true)).toEqual( - '1w', - ); - expect( - relativeDate(reference - WEEK * 2, reference, /* short */ true), - ).toEqual('2w'); - expect( - relativeDate(reference - WEEK * 4, reference, /* short */ true), - ).toEqual('4w'); - expect( - relativeDate(reference - MONTH * 1.2, reference, /* short */ true), - ).toEqual('1mo'); - expect( - relativeDate(reference - YEAR + HOUR, reference, /* short */ true), - ).toEqual('12mo'); - expect(relativeDate(reference - YEAR, reference, /* short */ true)).toEqual( - '1y', - ); - expect( - relativeDate(reference - YEAR * 2, reference, /* short */ true), - ).toEqual('2y'); - expect(relativeDate(0, reference, /* short */ true)).toEqual('5y'); - }); -}); + expect((0, (_string || _load_string()).relativeDate)(0, undefined, /* short */true)).toEqual(Math.round(now / YEAR) + 'y'); + expect((0, (_string || _load_string()).relativeDate)(reference * SECOND, reference, /* short */true)).toEqual('now'); + expect((0, (_string || _load_string()).relativeDate)(reference - 41 * SECOND, reference, /* short */true)).toEqual('now'); + expect((0, (_string || _load_string()).relativeDate)(reference - 42 * SECOND, reference, /* short */true)).toEqual('1m'); + expect((0, (_string || _load_string()).relativeDate)(reference - MINUTE, reference, /* short */true)).toEqual('1m'); + expect((0, (_string || _load_string()).relativeDate)(reference - MINUTE * 1.5, reference, /* short */true)).toEqual('2m'); + expect((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((0, (_string || _load_string()).relativeDate)(reference - HOUR * 1.5, reference, /* short */true)).toEqual('2h'); + expect((0, (_string || _load_string()).relativeDate)(reference - HOUR * 16, reference, /* short */true)).toEqual('16h'); + expect((0, (_string || _load_string()).relativeDate)(reference - HOUR * 23, reference, /* short */true)).toEqual('23h'); + expect((0, (_string || _load_string()).relativeDate)(reference - DAY * 1.8, reference, /* short */true)).toEqual('1d'); + expect((0, (_string || _load_string()).relativeDate)(reference - DAY * 3, reference, /* short */true)).toEqual('3d'); + expect((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((0, (_string || _load_string()).relativeDate)(reference - WEEK * 2, reference, /* short */true)).toEqual('2w'); + expect((0, (_string || _load_string()).relativeDate)(reference - WEEK * 4, reference, /* short */true)).toEqual('4w'); + expect((0, (_string || _load_string()).relativeDate)(reference - MONTH * 1.2, reference, /* short */true)).toEqual('1mo'); + expect((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'); + 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. + * + * strict-local + * @format + */ describe('maybeToString', () => { it("returns 'undefined'", () => { - expect(maybeToString(undefined)).toEqual('undefined'); + expect((0, (_string || _load_string()).maybeToString)(undefined)).toEqual('undefined'); }); it("returns 'null'", () => { - expect(maybeToString(null)).toEqual('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/__tests__/symbol-definition-preview-test.js b/modules/nuclide-commons/__tests__/symbol-definition-preview-test.js index 3a36230118..a4e275ebda 100644 --- a/modules/nuclide-commons/__tests__/symbol-definition-preview-test.js +++ b/modules/nuclide-commons/__tests__/symbol-definition-preview-test.js @@ -1,3 +1,31 @@ +'use strict'; + +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. @@ -6,39 +34,23 @@ * LICENSE file in 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) { +function javascriptFixtureDefinitionWithPoint(point) { return { - path: nuclideUri.join( - __dirname, - '../__mocks__', - 'fixtures', - 'symbol-definition-preview-sample.js', - ), + path: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__', 'fixtures', 'symbol-definition-preview-sample.js'), language: 'javascript', - position: point, + position: point }; } -function pythonFixtureDefinitionWithPoint(point: Point) { +function pythonFixtureDefinitionWithPoint(point) { return { - path: nuclideUri.join( - __dirname, - '../__mocks__', - 'fixtures', - 'symbol-definition-preview-sample.py', - ), + path: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__', 'fixtures', 'symbol-definition-preview-sample.py'), language: 'python', - position: point, + position: point }; } @@ -46,31 +58,33 @@ describe('getDefinitionPreview', () => { describe('Constant symbols', () => { it('returns the only line of a one-line symbol', async () => { await (async () => { - const preview = await getDefinitionPreview( - javascriptFixtureDefinitionWithPoint(new Point(11, 6)), - ); + const preview = await (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)(javascriptFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(11, 6))); expect(preview).not.toBeNull(); - invariant(preview != null); + + 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', async () => { await (async () => { - const preview = await getDefinitionPreview( - javascriptFixtureDefinitionWithPoint(new Point(15, 6)), - ); + const preview = await (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)(javascriptFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(15, 6))); expect(preview).not.toBeNull(); - invariant(preview != null); - expect(preview.contents).toEqual( - dedent`const A_MULTILINE_CONST = \` + + if (!(preview != null)) { + throw new Error('Invariant violation: "preview != null"'); + } + + expect(preview.contents).toEqual((_dedent || _load_dedent()).default`const A_MULTILINE_CONST = \` hey look I span multiple lines - \`;`, - ); + \`;`); })(); }); }); @@ -78,47 +92,49 @@ describe('getDefinitionPreview', () => { describe('Type symbols', () => { it('returns an entire multi-line type', async () => { await (async () => { - const preview = await getDefinitionPreview( - javascriptFixtureDefinitionWithPoint(new Point(21, 5)), - ); + const preview = await (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)(javascriptFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(21, 5))); expect(preview).not.toBeNull(); - invariant(preview != null); - expect(preview.contents).toEqual( - dedent`type Something = { + + if (!(preview != null)) { + throw new Error('Invariant violation: "preview != null"'); + } + + expect(preview.contents).toEqual((_dedent || _load_dedent()).default`type Something = { name: string, age?: number, - };`, - ); + };`); })(); }); it('returns only the property from within a type', async () => { await (async () => { - const preview = await getDefinitionPreview( - javascriptFixtureDefinitionWithPoint(new Point(44, 4)), - ); + const preview = await (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)(javascriptFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(44, 4))); expect(preview).not.toBeNull(); - invariant(preview != null); + + 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', async () => { await (async () => { - const preview = await getDefinitionPreview( - javascriptFixtureDefinitionWithPoint(new Point(43, 2)), - ); + const preview = await (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)(javascriptFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(43, 2))); expect(preview).not.toBeNull(); - invariant(preview != null); - expect(preview.contents).toEqual( - dedent`properties: { + + if (!(preview != null)) { + throw new Error('Invariant violation: "preview != null"'); + } + + expect(preview.contents).toEqual((_dedent || _load_dedent()).default`properties: { name: string, age?: number, - },`, - ); + },`); })(); }); }); @@ -126,80 +142,82 @@ describe('getDefinitionPreview', () => { describe('Function symbols', () => { it('returns just one line if parens are balanced on the first line', async () => { await (async () => { - const preview = await getDefinitionPreview( - javascriptFixtureDefinitionWithPoint(new Point(26, 16)), - ); + const preview = await (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)(javascriptFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(26, 16))); expect(preview).not.toBeNull(); - invariant(preview != null); - expect(preview.contents).toEqual( - 'export function aSingleLineFunctionSignature() {', - ); + + if (!(preview != null)) { + throw new Error('Invariant violation: "preview != null"'); + } + + expect(preview.contents).toEqual('export function aSingleLineFunctionSignature() {'); })(); }); it('works without parentheses as with python', async () => { await (async () => { - const preview = await getDefinitionPreview( - pythonFixtureDefinitionWithPoint(new Point(7, 4)), - ); + const preview = await (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)(pythonFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(7, 4))); expect(preview).not.toBeNull(); - invariant(preview != null); + + 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', async () => { await (async () => { - const preview = await getDefinitionPreview( - pythonFixtureDefinitionWithPoint(new Point(11, 4)), - ); + const preview = await (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)(pythonFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(11, 4))); expect(preview).not.toBeNull(); - invariant(preview != null); - expect(preview.contents).toEqual( - dedent`def baz(test={ + + if (!(preview != null)) { + throw new Error('Invariant violation: "preview != null"'); + } + + expect(preview.contents).toEqual((_dedent || _load_dedent()).default`def baz(test={ 'one': 'two' - }):`, - ); + }):`); })(); }); it("doesn't dedent beyond the current lines indentation level", async () => { await (async () => { - const preview = await getDefinitionPreview( - javascriptFixtureDefinitionWithPoint(new Point(36, 18)), - ); + const preview = await (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)(javascriptFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(36, 18))); expect(preview).not.toBeNull(); - invariant(preview != null); - expect(preview.contents).toEqual( - dedent` + + if (!(preview != null)) { + throw new Error('Invariant violation: "preview != null"'); + } + + expect(preview.contents).toEqual((_dedent || _load_dedent()).default` export function aPoorlyIndentedFunction( aReallyReallyLongArgumentNameThatWouldRequireThisToBreakAcrossMultipleLines: Something, ): number { - `, - ); + `); })(); }); it('reads until the indentation returns to initial and parens are balanced', async () => { await (async () => { - const preview = await getDefinitionPreview( - javascriptFixtureDefinitionWithPoint(new Point(30, 16)), - ); + const preview = await (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)(javascriptFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(30, 16))); expect(preview).not.toBeNull(); - invariant(preview != null); - expect(preview.contents).toEqual( - dedent` + + if (!(preview != null)) { + throw new Error('Invariant violation: "preview != null"'); + } + + expect(preview.contents).toEqual((_dedent || _load_dedent()).default` export function aMultiLineFunctionSignature( aReallyReallyLongArgumentNameThatWouldRequireThisToBreakAcrossMultipleLines: Something, ): number { - `, - ); + `); })(); }); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/test-helpers-test.js b/modules/nuclide-commons/__tests__/test-helpers-test.js index 016119c1a9..0f9356aec5 100644 --- a/modules/nuclide-commons/__tests__/test-helpers-test.js +++ b/modules/nuclide-commons/__tests__/test-helpers-test.js @@ -1,62 +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 typeof * as TestModuleType from '../__mocks__/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 _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); }); -}); +}); /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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', async () => { - const verify: any = jest.fn(); - await expect( - expectAsyncFailure(Promise.resolve('resolved, not rejected!'), verify), - ).rejects.toThrow(/but did not/); + const verify = jest.fn(); + await expect((0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)(Promise.resolve('resolved, not rejected!'), verify)).rejects.toThrow(/but did not/); expect(verify.mock.calls).toHaveLength(0); }); @@ -70,9 +77,7 @@ describe('expectAsyncFailure', () => { } } - await expect( - expectAsyncFailure(Promise.reject(Error('I failed.')), verify), - ).rejects.toThrow(/I failed/); + await expect((0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)(Promise.reject(Error('I failed.')), verify)).rejects.toThrow(/I failed/); expect(callCount).toBe(1); }); @@ -86,7 +91,7 @@ describe('expectAsyncFailure', () => { } } - await expectAsyncFailure(Promise.reject(Error('I failed badly.')), verify); + await (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)(Promise.reject(Error('I failed badly.')), verify); expect(callCount).toBe(1); }); }); @@ -94,58 +99,49 @@ describe('expectAsyncFailure', () => { describe('generateFixture', () => { it('should create the directory hierarchy', async () => { await (async () => { - const fixturePath = await generateFixture( - 'fixture-to-generate', - new Map([['foo.js', undefined], ['bar/baz.txt', 'some text']]), - ); + const fixturePath = await (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); + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute(fixturePath)).toBe(true); + expect(_fs.default.statSync(fixturePath).isDirectory()).toBe(true); - const fooPath = nuclideUri.join(fixturePath, 'foo.js'); - const bazPath = nuclideUri.join(fixturePath, 'bar/baz.txt'); + const fooPath = (_nuclideUri || _load_nuclideUri()).default.join(fixturePath, 'foo.js'); + const bazPath = (_nuclideUri || _load_nuclideUri()).default.join(fixturePath, 'bar/baz.txt'); - expect(fs.statSync(fooPath).isFile()).toBe(true); - expect(fs.statSync(bazPath).isFile()).toBe(true); + expect(_fs.default.statSync(fooPath).isFile()).toBe(true); + expect(_fs.default.statSync(bazPath).isFile()).toBe(true); - expect(fs.readFileSync(fooPath, 'utf8')).toBe(''); - expect(fs.readFileSync(bazPath, 'utf8')).toBe('some text'); + expect(_fs.default.readFileSync(fooPath, 'utf8')).toBe(''); + expect(_fs.default.readFileSync(bazPath, 'utf8')).toBe('some text'); })(); }); - it( - 'should work with lots of files', - async () => { - const files = new Map(); - for (let i = 0; i < 10; i++) { - for (let j = 0; j < 300; j++) { - files.set(`dir_${i}/file_${j}.txt`, `${i} + ${j} = ${i + j}`); - } + it('should work with lots of files', async () => { + const files = new Map(); + for (let i = 0; i < 10; i++) { + for (let j = 0; j < 300; 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'), - ); - expect(fixtureFiles.length).toBe(3000); - }, - 20000, - ); + } + const fixturePath = await (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(3000); + }, 20000); it('should work with no files', async () => { await (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([]); + const fixturePath = await (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', async () => { await (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([]); + const fixturePath = await (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([]); })(); }); }); @@ -154,18 +150,13 @@ describe('Mocking Imports test suite', () => { // Tests ToBeTested.functionToTest while mocking imported function toBeMocked. it('Mocking imported dependencies', () => { // 1 - First mock all functions imported by the module under test - const mock = jest - .spyOn(require('../__mocks__/fixtures/toBeMocked'), 'importedFunction') - .mockReturnValue(45); + const mock = jest.spyOn(require('../__mocks__/fixtures/toBeMocked'), 'importedFunction').mockReturnValue(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, - '../__mocks__/fixtures/toBeTested', - ): any); + const moduleToTest = (0, (_testHelpers || _load_testHelpers()).uncachedRequire)(require, '../__mocks__/fixtures/toBeTested'); // 3 - Perform your test const result = moduleToTest.functionToTest(); @@ -174,6 +165,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, '../__mocks__/fixtures/toBeTested'); + (0, (_testHelpers || _load_testHelpers()).clearRequireCache)(require, '../__mocks__/fixtures/toBeTested'); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/__tests__/which-test.js b/modules/nuclide-commons/__tests__/which-test.js index e51290da75..d2b96b09f3 100644 --- a/modules/nuclide-commons/__tests__/which-test.js +++ b/modules/nuclide-commons/__tests__/which-test.js @@ -1,3 +1,15 @@ +'use strict'; + +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. @@ -6,22 +18,17 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import which from '../which'; -import {Observable} from 'rxjs'; - describe('which', () => { let runCommand; let runCommandReturn = ''; beforeEach(() => { runCommandReturn = ''; - runCommand = jest - .spyOn(require('../process'), 'runCommand') - .mockImplementation(() => Observable.of(runCommandReturn)); + runCommand = jest.spyOn(require('../process'), 'runCommand').mockImplementation(() => _rxjsBundlesRxMinJs.Observable.of(runCommandReturn)); }); afterEach(() => { @@ -30,60 +37,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', async () => { await (async () => { runCommandReturn = 'hello' + os.EOL + 'hello.exe' + os.EOL; - const ret = await which('bla'); + const ret = await (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', async () => { await (async () => { runCommandReturn = 'hello' + os.EOL + '/bin/hello' + os.EOL; - const ret = await which('bla'); + const ret = await (0, (_which || _load_which()).default)('bla'); expect(ret).toEqual('hello'); })(); }); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/analytics.js b/modules/nuclide-commons/analytics.js index 253b7bfee0..765ba319ed 100644 --- a/modules/nuclide-commons/analytics.js +++ b/modules/nuclide-commons/analytics.js @@ -1,3 +1,40 @@ +'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.trackTimingSampled = trackTimingSampled; +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. @@ -6,38 +43,13 @@ * LICENSE file in 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}, +let rawAnalyticsService = { + track() {}, + isTrackSupported: () => false }; /** @@ -47,14 +59,11 @@ export type TrackEvent = { * @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 { +function track(eventName, values) { rawAnalyticsService.track(eventName, values || {}); } -export function isTrackSupported(): boolean { +function isTrackSupported() { return rawAnalyticsService.isTrackSupported(); } @@ -62,61 +71,44 @@ export function isTrackSupported(): boolean { * 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() - ); +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). */ -export function trackEvent(event: TrackingEvent): void { +function trackEvent(event) { 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)); +function trackEvents(events) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(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 { +function trackSampled(eventName, sampleRate, values) { if (Math.random() * sampleRate <= 1) { - rawAnalyticsService.track(eventName, { - ...values, - sample_rate: sampleRate, - }); + rawAnalyticsService.track(eventName, Object.assign({}, values, { + sample_rate: sampleRate + })); } } const PERFORMANCE_EVENT = 'performance'; const canMeasure = typeof performance !== 'undefined'; -export class TimingTracker { - static eventCount = 0; +class TimingTracker { - _eventName: string; - _startTime: number; - _startMark: string; - _values: {[key: string]: mixed}; - - constructor(eventName: string, values: {[key: string]: mixed}) { + constructor(eventName, values) { this._eventName = eventName; this._startMark = `${this._eventName}_${TimingTracker.eventCount++}_start`; - this._startTime = performanceNow(); + this._startTime = (0, (_performanceNow || _load_performanceNow()).default)(); this._values = values; if (canMeasure) { // eslint-disable-next-line no-undef @@ -124,15 +116,15 @@ export class TimingTracker { } } - onError(error: Error): void { + onError(error) { this._trackTimingEvent(error); } - onSuccess(): void { - this._trackTimingEvent(/* error */ null); + onSuccess() { + this._trackTimingEvent( /* error */null); } - _trackTimingEvent(exception: ?Error): void { + _trackTimingEvent(exception) { if (canMeasure) { /* eslint-disable no-undef */ // call measure to add this information to the devtools timeline in the @@ -145,20 +137,18 @@ export class TimingTracker { /* eslint-enable no-undef */ } - track(PERFORMANCE_EVENT, { - ...this._values, - duration: Math.round(performanceNow() - this._startTime).toString(), + 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() : '', - }); + exception: exception ? exception.toString() : '' + })); } } -export function startTracking( - eventName: string, - values?: {[key: string]: any} = {}, -): TimingTracker { +exports.TimingTracker = TimingTracker; +TimingTracker.eventCount = 0; +function startTracking(eventName, values = {}) { return new TimingTracker(eventName, values); } @@ -171,31 +161,24 @@ export function startTracking( * * Returns (or throws) the result of the operation. */ -export function trackTiming( - eventName: string, - operation: () => T, - values?: {[key: string]: any} = {}, -): T { +function trackTiming(eventName, operation, values = {}) { const tracker = startTracking(eventName, values); try { const result = operation(); - if (isPromise(result)) { + 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); - }, - ); + 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; @@ -209,33 +192,25 @@ export function trackTiming( /** * A sampled version of trackTiming that only tracks every 1/sampleRate calls. */ -export function trackTimingSampled( - eventName: string, - operation: () => T, - sampleRate: number, - values?: {[key: string]: any} = {}, -): T { +function trackTimingSampled(eventName, operation, sampleRate, values = {}) { if (Math.random() * sampleRate <= 1) { - return trackTiming(eventName, operation, { - ...values, - sample_rate: sampleRate, - }); + return trackTiming(eventName, operation, Object.assign({}, values, { + sample_rate: sampleRate + })); } return operation(); } -export function setRawAnalyticsService( - analyticsService: RawAnalyticsService, -): void { +function setRawAnalyticsService(analyticsService) { rawAnalyticsService = analyticsService; } -export default { +exports.default = { track, trackSampled, trackEvent, trackTiming, trackTimingSampled, startTracking, - TimingTracker, -}; + TimingTracker +}; \ No newline at end of file diff --git a/modules/nuclide-commons/cache.js b/modules/nuclide-commons/cache.js index 9a18206125..79d9b1841e 100644 --- a/modules/nuclide-commons/cache.js +++ b/modules/nuclide-commons/cache.js @@ -1,39 +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 - */ +'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]>; - - constructor( - factory: (key: KeyType) => ValueType, - disposeValue: (value: ValueType) => mixed = value => {}, - ) { +class Cache { + + constructor(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 +29,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 +48,31 @@ 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 +83,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 +92,25 @@ export class Cache { } } - dispose(): void { + dispose() { this.clear(); this._entriesSubject.complete(); } } -// Useful for optional second parameter to Cache constructor. -export const DISPOSE_VALUE = (value: IDisposable) => { +exports.Cache = Cache; // Useful for optional second parameter to Cache constructor. +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 8af526a67b..843ab8f79b 100644 --- a/modules/nuclide-commons/collection.js +++ b/modules/nuclide-commons/collection.js @@ -1,3 +1,52 @@ +'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.findSubArrayIndex = findSubArrayIndex; +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. @@ -6,33 +55,29 @@ * LICENSE file in 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 { +function ensureArray(x) { return Array.isArray(x) ? x : [x]; } -export function arrayRemove(array: Array, element: T): void { +function arrayRemove(array, element) { 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 { +function arrayEqual(array1, array2, equalComparator) { if (array1 === array2) { return true; } if (array1.length !== array2.length) { return false; } - const equalFunction = equalComparator || ((a: T, b: T) => a === b); + const equalFunction = equalComparator || ((a, b) => a === b); return array1.every((item1, i) => equalFunction(item1, array2[i])); } @@ -40,7 +85,7 @@ export function arrayEqual( * 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 { +function arrayCompact(array) { const result = []; for (const elem of array) { if (elem != null) { @@ -53,7 +98,7 @@ export function arrayCompact(array: Array): Array { /** * Flattens an Array> into just an Array */ -export function arrayFlatten(array: Array>): Array { +function arrayFlatten(array) { const result = []; for (const subArray of array) { result.push(...subArray); @@ -66,7 +111,7 @@ export function arrayFlatten(array: Array>): 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 { +function arrayUnique(array) { return Array.from(new Set(array)); } @@ -74,11 +119,7 @@ export function arrayUnique(array: Array): 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 { +function arrayFindLastIndex(array, predicate, thisArg) { for (let i = array.length - 1; i >= 0; i--) { if (predicate.call(thisArg, array[i], i, array)) { return i; @@ -91,20 +132,15 @@ export function arrayFindLastIndex( * Return the first index in array where subarray is equal to the next * subarray-sized slice of array. Return -1 if no match is found. */ -export function findSubArrayIndex( - array: Array, - subarr: Array, -): number { - return array.findIndex((_, offset) => - arrayEqual(array.slice(offset, offset + subarr.length), subarr), - ); +function findSubArrayIndex(array, subarr) { + return array.findIndex((_, offset) => arrayEqual(array.slice(offset, offset + subarr.length), subarr)); } /** * 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 { +function mapUnion(...maps) { const unionMap = new Map(); for (const map of maps) { for (const [key, value] of map) { @@ -114,7 +150,7 @@ export function mapUnion(...maps: Array>): Map { return unionMap; } -export function mapCompact(map: Map): Map { +function mapCompact(map) { const selected = new Map(); for (const [key, value] of map) { if (value != null) { @@ -124,10 +160,7 @@ export function mapCompact(map: Map): Map { return selected; } -export function mapFilter( - map: Map, - selector: (key: T, value: X) => boolean, -): Map { +function mapFilter(map, selector) { const selected = new Map(); for (const [key, value] of map) { if (selector(key, value)) { @@ -137,10 +170,7 @@ export function mapFilter( return selected; } -export function mapTransform( - src: Map, - transform: (value: V1, key: T) => V2, -): Map { +function mapTransform(src, transform) { const result = new Map(); for (const [key, value] of src) { result.set(key, transform(value, key)); @@ -148,47 +178,36 @@ export function mapTransform( return result; } -export function mapEqual( - map1: Map, - map2: Map, - equalComparator?: (val1: X, val2: X, key1?: T, key2?: T) => boolean, -) { +function mapEqual(map1, map2, equalComparator) { if (map1.size !== map2.size) { return false; } - const equalFunction = equalComparator || ((a: X, b: X) => a === b); + const equalFunction = equalComparator || ((a, b) => a === b); for (const [key1, value1] of map1) { - if (!map2.has(key1) || !equalFunction(value1, (map2.get(key1): any))) { + if (!map2.has(key1) || !equalFunction(value1, map2.get(key1))) { return false; } } return true; } -export function mapGetWithDefault( - map: Map, - key: K, - default_: V, -): V { +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); + return map.get(key); } else { return default_; } } -export function areSetsEqual(a: Set, b: Set): boolean { +function areSetsEqual(a, b) { 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 { +function every(values, predicate) { for (const element of values) { if (!predicate(element)) { return false; @@ -197,11 +216,11 @@ export function every( return true; } -export function setIntersect(a: Set, b: Set): Set { +function setIntersect(a, b) { return setFilter(a, e => b.has(e)); } -function setUnionTwo(a: Set, b: Set): Set { +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); @@ -211,23 +230,19 @@ function setUnionTwo(a: Set, b: Set): Set { return result; } -export function setUnion(...sets: Array>): Set { +function setUnion(...sets) { if (sets.length < 1) { return new Set(); } - const setReducer = (accumulator: Set, current: Set): Set => { + const setReducer = (accumulator, current) => { return setUnionTwo(accumulator, current); }; return sets.reduce(setReducer); } -export function setDifference( - a: Set, - b: Set, - hash_?: (v: T) => any, -): Set { +function setDifference(a, b, hash_) { if (a.size === 0) { return new Set(); } else if (b.size === 0) { @@ -244,10 +259,7 @@ export function setDifference( return result; } -export function setFilter( - set: Set, - predicate: (value: T) => boolean, -): Set { +function setFilter(set, predicate) { const out = new Set(); for (const item of set) { if (predicate(item)) { @@ -261,7 +273,7 @@ export function setFilter( /** * O(1)-check if a given object is empty (has no properties, inherited or not) */ -export function isEmpty(obj: Object): boolean { +function isEmpty(obj) { for (const key in obj) { return false; } @@ -274,7 +286,7 @@ export function isEmpty(obj: Object): boolean { * * Based off the equivalent function in www. */ -export function keyMirror(obj: T): $ObjMapi(k: K) => K> { +function keyMirror(obj) { const ret = {}; Object.keys(obj).forEach(key => { ret[key] = key; @@ -286,7 +298,7 @@ export function keyMirror(obj: T): $ObjMapi(k: K) => K> { * 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> { +function collect(pairs) { const result = new Map(); for (const pair of pairs) { const [k, v] = pair; @@ -300,9 +312,7 @@ export function collect(pairs: Array<[K, V]>): Map> { return result; } -export function objectFromPairs( - iterable: Iterable<[T, U]>, -): {[T]: U} { +function objectFromPairs(iterable) { const result = {}; for (const [key, value] of iterable) { result[key] = value; @@ -310,28 +320,16 @@ export function objectFromPairs( return result; } -export function objectMapValues( - object: {[T: string]: U}, - project: (value: U, key: T) => V, -): {[T]: V} { +function objectMapValues(object, project) { const result = {}; Object.keys(object).forEach(key => { - result[key] = project(object[key], ((key: any): T)); + result[key] = project(object[key], key); }); return result; } -export class MultiMap { +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 - // 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; @@ -341,7 +339,14 @@ export class MultiMap { * 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 { + + + // 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 */ + get(key) { const set = this._map.get(key); if (set == null) { return new Set(); @@ -353,7 +358,7 @@ export class MultiMap { * 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 { + add(key, value) { let set = this._map.get(key); if (set == null) { set = new Set(); @@ -369,7 +374,7 @@ export class MultiMap { /* * Mimics the Map.prototype.set interface. Replaces the previous binding with new values. */ - set(key: K, values: Iterable): void { + set(key, values) { this.deleteAll(key); const newSet = new Set(values); if (newSet.size !== 0) { @@ -381,7 +386,7 @@ export class MultiMap { /* * Deletes a single binding. Returns true iff the binding existed. */ - delete(key: K, value: V): boolean { + delete(key, value) { const set = this.get(key); const didRemove = set.delete(value); if (set.size === 0) { @@ -396,59 +401,55 @@ export class MultiMap { /* * Deletes all bindings associated with the given key. Returns true iff any bindings were deleted. */ - deleteAll(key: K): boolean { + deleteAll(key) { const set = this.get(key); this.size -= set.size; return this._map.delete(key); } - clear(): void { + clear() { this._map.clear(); this.size = 0; } - has(key: K, value: V): boolean { + has(key, value) { return this.get(key).has(value); } - hasAny(key: K): boolean { + hasAny(key) { return this._map.has(key); } - *values(): Iterable { + *values() { 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)), - ); + forEach(callback) { + this._map.forEach((values, key) => values.forEach(value => callback(value, key, this))); } } -export function objectValues(obj: {[key: string]: T}): Array { +exports.MultiMap = MultiMap; +function objectValues(obj) { return Object.keys(obj).map(key => obj[key]); } -export function objectEntries(obj: ?{[key: string]: T}): Array<[string, T]> { +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) - ) { + 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} { +function objectFromMap(map) { const obj = {}; map.forEach((v, k) => { obj[k] = v; @@ -456,9 +457,7 @@ export function objectFromMap(map: Map): {[key: string]: T} { return obj; } -export function* concatIterators( - ...iterators: Array> -): Iterator { +function* concatIterators(...iterators) { for (const iterator of iterators) { for (const element of iterator) { yield element; @@ -466,10 +465,7 @@ export function* concatIterators( } } -export function someOfIterable( - iterable: Iterable, - predicate: (element: T) => boolean, -): boolean { +function someOfIterable(iterable, predicate) { for (const element of iterable) { if (predicate(element)) { return true; @@ -478,10 +474,7 @@ export function someOfIterable( return false; } -export function findInIterable( - iterable: Iterable, - predicate: (element: T) => boolean, -): ?T { +function findInIterable(iterable, predicate) { for (const element of iterable) { if (predicate(element)) { return element; @@ -490,10 +483,7 @@ export function findInIterable( return null; } -export function* filterIterable( - iterable: Iterable, - predicate: (element: T) => boolean, -): Iterable { +function* filterIterable(iterable, predicate) { for (const element of iterable) { if (predicate(element)) { yield element; @@ -501,19 +491,13 @@ export function* filterIterable( } } -export function* mapIterable( - iterable: Iterable, - projectorFn: (element: T) => M, -): Iterable { +function* mapIterable(iterable, projectorFn) { for (const element of iterable) { yield projectorFn(element); } } -export function* takeIterable( - iterable: Iterable, - limit: number, -): Iterable { +function* takeIterable(iterable, limit) { let i = 0; for (const element of iterable) { if (++i > limit) { @@ -524,21 +508,17 @@ export function* takeIterable( } // Return an iterable of the numbers start (inclusive) through stop (exclusive) -export function* range( - start: number, - stop: number, - step?: number = 1, -): Iterable { +function* range(start, stop, step = 1) { for (let i = start; i < stop; i += step) { yield i; } } -export function firstOfIterable(iterable: Iterable): ?T { +function firstOfIterable(iterable) { return findInIterable(iterable, () => true); } -export function iterableIsEmpty(iterable: Iterable): boolean { +function iterableIsEmpty(iterable) { // eslint-disable-next-line no-unused-vars for (const element of iterable) { return false; @@ -546,13 +526,11 @@ export function iterableIsEmpty(iterable: Iterable): boolean { return true; } -export function iterableContains(iterable: Iterable, value: T): boolean { - return !iterableIsEmpty( - filterIterable(iterable, element => element === value), - ); +function iterableContains(iterable, value) { + return !iterableIsEmpty(filterIterable(iterable, element => element === value)); } -export function count(iterable: Iterable): number { +function count(iterable) { let size = 0; // eslint-disable-next-line no-unused-vars for (const element of iterable) { @@ -561,23 +539,17 @@ export function count(iterable: Iterable): number { return size; } -export function isIterable(obj: any): boolean { +function isIterable(obj) { 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]> { +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 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) { @@ -592,15 +564,15 @@ export function* insideOut( } } -export function mapFromObject(obj: {[key: string]: T}): Map { +function mapFromObject(obj) { return new Map(objectEntries(obj)); } -export function lastFromArray(arr: Array): T { +function lastFromArray(arr) { return arr[arr.length - 1]; } -export function distinct(array: T[], keyFn?: (t: T) => string): T[] { +function distinct(array, keyFn) { if (keyFn == null) { return Array.from(new Set(array)); } @@ -616,21 +588,21 @@ export function distinct(array: T[], keyFn?: (t: T) => string): T[] { }); } -export class DefaultMap extends Map { - _factory: () => V; +class DefaultMap extends Map { - constructor(factory: () => V, iterable: ?Iterable<[K, V]>) { + constructor(factory, iterable) { super(iterable); this._factory = factory; } - get(key: K): V { + 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): any); + 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 54c6172a6f..74f5bacc01 100644 --- a/modules/nuclide-commons/debounce.js +++ b/modules/nuclide-commons/debounce.js @@ -1,38 +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'; -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, -} { +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) { @@ -40,7 +20,10 @@ export default function debounce< } else { timeout = null; if (!immediate) { - invariant(args != null); + if (!(args != null)) { + throw new Error('Invariant violation: "args != null"'); + } + result = func.apply(context, args); if (!timeout) { context = args = null; @@ -49,7 +32,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 +56,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 085e103236..37326c15ed 100644 --- a/modules/nuclide-commons/event.js +++ b/modules/nuclide-commons/event.js @@ -1,3 +1,26 @@ +'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. @@ -6,39 +29,22 @@ * LICENSE file in 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 { +function attachEvent(emitter, eventName, callback) { emitter.addListener(eventName, callback); - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { emitter.removeListener(eventName, callback); }); } -type SubscribeCallback = (item: T) => any; -type SubscribeFunction = (callback: SubscribeCallback) => IDisposable; - -export function observableFromSubscribeFunction( - fn: SubscribeFunction, -): Observable { - return Observable.create(observer => { +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 dfd49af15b..6eaca76667 100644 --- a/modules/nuclide-commons/expected.js +++ b/modules/nuclide-commons/expected.js @@ -1,3 +1,8 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,7 +11,7 @@ * LICENSE file in 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 strict + * strict * @format */ @@ -16,63 +21,38 @@ * 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 { +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 3e7b91ec0c..596b83aba5 100644 --- a/modules/nuclide-commons/fsPromise.js +++ b/modules/nuclide-commons/fsPromise.js @@ -1,25 +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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +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')); +} -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'; +var _temp; -import nuclideUri from './nuclideUri'; -import {runCommand} from './process'; +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 @@ -27,9 +62,9 @@ import {runCommand} from './process'; * @param prefix optinal prefix for the temp directory name. * @return path to a temporary directory. */ -function tempdir(prefix: string = ''): Promise { +function tempdir(prefix = '') { return new Promise((resolve, reject) => { - temp.mkdir(prefix, (err, result) => { + (_temp || _load_temp()).default.mkdir(prefix, (err, result) => { if (err == null) { resolve(result); } else { @@ -43,13 +78,25 @@ function tempdir(prefix: string = ''): Promise { * @return path to a temporary file. The caller is responsible for cleaning up * the file. */ -function tempfile(options: any): Promise { +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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.open(options, (err, info) => { + (_temp || _load_temp()).default.open(options, (err, info) => { if (err) { reject(err); } else { - fs.close(info.fd, closeErr => { + _fs.default.close(info.fd, closeErr => { if (closeErr) { reject(closeErr); } else { @@ -69,43 +116,37 @@ function tempfile(options: any): Promise { * not a file. * @return directory that contains the nearest file or null. */ -async function findNearestFile( - fileName: string, - pathToDirectory: string, -): Promise { +async function findNearestFile(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.resolve(pathToDirectory); + let currentPath = (_nuclideUri || _load_nuclideUri()).default.resolve(pathToDirectory); for (;;) { - const fileToFind = nuclideUri.join(currentPath, fileName); + const fileToFind = (_nuclideUri || _load_nuclideUri()).default.join(currentPath, fileName); // eslint-disable-next-line no-await-in-loop const hasFile = await exists(fileToFind); if (hasFile) { return currentPath; } - if (nuclideUri.isRoot(currentPath)) { + if ((_nuclideUri || _load_nuclideUri()).default.isRoot(currentPath)) { return null; } - currentPath = nuclideUri.dirname(currentPath); + currentPath = (_nuclideUri || _load_nuclideUri()).default.dirname(currentPath); } } -async function findNearestAncestorNamed( - fileName: string, - pathToDirectory: string, -): Promise { +async function findNearestAncestorNamed(fileName, pathToDirectory) { const directory = await findNearestFile(fileName, pathToDirectory); if (directory != null) { - return nuclideUri.join(directory, fileName); + return (_nuclideUri || _load_nuclideUri()).default.join(directory, fileName); } else { return null; } } -function resolveRealPath(path: string): Promise { - return realpath(nuclideUri.expandHomeDir(path)); +function resolveRealPath(path) { + return realpath((_nuclideUri || _load_nuclideUri()).default.expandHomeDir(path)); } /** @@ -117,39 +158,33 @@ function resolveRealPath(path: string): Promise { * @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); +async function findFurthestFile(fileName, pathToDirectory, stopOnMissing = false) { + let currentPath = (_nuclideUri || _load_nuclideUri()).default.resolve(pathToDirectory); let result = null; for (;;) { - const fileToFind = nuclideUri.join(currentPath, fileName); + const fileToFind = (_nuclideUri || _load_nuclideUri()).default.join(currentPath, fileName); // eslint-disable-next-line no-await-in-loop const hasFile = await exists(fileToFind); - if ((!hasFile && stopOnMissing) || nuclideUri.isRoot(currentPath)) { + if (!hasFile && stopOnMissing || (_nuclideUri || _load_nuclideUri()).default.isRoot(currentPath)) { return result; } else if (hasFile) { result = currentPath; } - currentPath = nuclideUri.dirname(currentPath); + currentPath = (_nuclideUri || _load_nuclideUri()).default.dirname(currentPath); } } -function getCommonAncestorDirectory(filePaths: Array): string { - let commonDirectoryPath = nuclideUri.dirname(filePaths[0]); - while ( - filePaths.some(filePath => !filePath.startsWith(commonDirectoryPath)) - ) { - commonDirectoryPath = nuclideUri.dirname(commonDirectoryPath); +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: string): Promise { +function exists(filePath) { return new Promise((resolve, reject) => { - fs.exists(filePath, resolve); + _fs.default.exists(filePath, resolve); }); } @@ -160,13 +195,13 @@ function exists(filePath: string): Promise { * 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 { +async function mkdirp(filePath) { const isExistingDirectory = await exists(filePath); if (isExistingDirectory) { return false; } else { return new Promise((resolve, reject) => { - mkdirpLib(filePath, err => { + (0, (_mkdirp || _load_mkdirp()).default)(filePath, err => { if (err) { reject(err); } else { @@ -180,9 +215,9 @@ async function mkdirp(filePath: string): Promise { /** * Removes directories even if they are non-empty. Does not fail if the directory doesn't exist. */ -function rimrafWrapper(filePath: string): Promise { +function rimrafWrapper(filePath) { return new Promise((resolve, reject) => { - rimraf(filePath, (err, result) => { + (0, (_rimraf || _load_rimraf()).default)(filePath, (err, result) => { if (err == null) { resolve(result); } else { @@ -192,16 +227,10 @@ function rimrafWrapper(filePath: string): Promise { }); } -async function getFileSystemType(entityPath: string): Promise { +async function getFileSystemType(entityPath) { if (process.platform === 'linux' || process.platform === 'darwin') { try { - const stdout = await runCommand('stat', [ - '-f', - '-L', - '-c', - '%T', - entityPath, - ]).toPromise(); + const stdout = await (0, (_process || _load_process()).runCommand)('stat', ['-f', '-L', '-c', '%T', entityPath]).toPromise(); return stdout.trim(); } catch (err) { return null; @@ -213,20 +242,20 @@ async function getFileSystemType(entityPath: string): Promise { } /** @return true only if we are sure entityPath is on NFS. */ -async function isNfs(entityPath: string): Promise { +async function isNfs(entityPath) { 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 { +async function isFuse(entityPath) { return (await getFileSystemType(entityPath)) === 'fuseblk'; } -function glob(pattern: string, options?: Object): Promise> { +function glob(pattern, options) { return new Promise((resolve, reject) => { - globLib(pattern, options, (err, result) => { + (0, (_glob || _load_glob()).default)(pattern, options, (err, result) => { if (err == null) { resolve(result); } else { @@ -236,7 +265,7 @@ function glob(pattern: string, options?: Object): Promise> { }); } -async function isNonNfsDirectory(directoryPath: string): Promise { +async function isNonNfsDirectory(directoryPath) { try { const stats = await stat(directoryPath); if (stats.isDirectory()) { @@ -256,9 +285,9 @@ async function isNonNfsDirectory(directoryPath: string): Promise { * Promisified wrappers around fs-plus functions. */ -function copy(source: string, dest: string): Promise { +function copy(source, dest) { return new Promise((resolve, reject) => { - fsPlus.copy(source, dest, (err, result) => { + (_fsPlus || _load_fsPlus()).default.copy(source, dest, (err, result) => { if (err == null) { resolve(result); } else { @@ -268,26 +297,19 @@ function copy(source: string, dest: string): Promise { }); } -async function copyFilePermissions( - sourcePath: string, - destinationPath: string, -): Promise { +async function copyFilePermissions(sourcePath, destinationPath) { try { - const {mode, uid, gid} = await stat(sourcePath); + 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), - ]); + // 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 + await chmod(destinationPath, 0o666 & ~process.umask() // eslint-disable-line no-bitwise ); } } @@ -296,13 +318,9 @@ async function copyFilePermissions( * 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 { +function writeFile(filename, data, options) { return new Promise((resolve, reject) => { - fsPlus.writeFile(filename, data, options, (err, result) => { + (_fsPlus || _load_fsPlus()).default.writeFile(filename, data, options, (err, result) => { if (err == null) { resolve(result); } else { @@ -312,11 +330,7 @@ function writeFile( }); } -async function writeFileAtomic( - path: string, - data: Buffer | string, - options?: Object | string, -): Promise { +async function writeFileAtomic(path, data, options) { const tempFilePath = await tempfile('nuclide'); try { await writeFile(tempFilePath, data, options); @@ -325,11 +339,11 @@ async function writeFileAtomic( 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. - } + } 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 @@ -340,7 +354,7 @@ async function writeFileAtomic( // 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}); + await mv(tempFilePath, realPath, { mkdirp: true }); } catch (err) { await unlink(tempFilePath); throw err; @@ -351,9 +365,9 @@ async function writeFileAtomic( * Promisified wrappers around fs functions. */ -function chmod(path: string, mode: number | string): Promise { +function chmod(path, mode) { return new Promise((resolve, reject) => { - fs.chmod(path, mode, (err, result) => { + _fs.default.chmod(path, mode, (err, result) => { if (err == null) { resolve(result); } else { @@ -363,9 +377,9 @@ function chmod(path: string, mode: number | string): Promise { }); } -function chown(path: string, uid: number, gid: number): Promise { +function chown(path, uid, gid) { return new Promise((resolve, reject) => { - fs.chown(path, uid, gid, (err, result) => { + _fs.default.chown(path, uid, gid, (err, result) => { if (err == null) { resolve(result); } else { @@ -375,9 +389,9 @@ function chown(path: string, uid: number, gid: number): Promise { }); } -function close(fd: number): Promise { +function close(fd) { return new Promise((resolve, reject) => { - fs.close(fd, err => { + _fs.default.close(fd, err => { if (err == null) { resolve(); } else { @@ -387,9 +401,9 @@ function close(fd: number): Promise { }); } -function lstat(path: string): Promise { +function lstat(path) { return new Promise((resolve, reject) => { - fs.lstat(path, (err, result) => { + _fs.default.lstat(path, (err, result) => { if (err == null) { resolve(result); } else { @@ -399,9 +413,9 @@ function lstat(path: string): Promise { }); } -function mkdir(path: string, mode?: number): Promise { +function mkdir(path, mode) { return new Promise((resolve, reject) => { - fs.mkdir(path, mode, (err, result) => { + _fs.default.mkdir(path, mode, (err, result) => { if (err == null) { resolve(result); } else { @@ -411,26 +425,13 @@ function mkdir(path: string, mode?: number): Promise { }); } -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 { +function mv(sourcePath, destinationPath, options = {}) { return new Promise((resolve, reject) => { - mvLib(sourcePath, destinationPath, options, error => { + (0, (_mv || _load_mv()).default)(sourcePath, destinationPath, options, error => { if (error) { reject(error); } else { @@ -440,13 +441,9 @@ function mv( }); } -function open( - path: string | Buffer | URL, - flags: string | number, - mode: number = 0o666, -): Promise { +function open(path, flags, mode = 0o666) { return new Promise((resolve, reject) => { - fs.open(path, flags, mode, (err, fd) => { + _fs.default.open(path, flags, mode, (err, fd) => { if (err == null) { resolve(fd); } else { @@ -456,15 +453,9 @@ function open( }); } -function read( - fd: number, - buffer: Buffer, - offset: number, - length: number, - position: number | null, -): Promise { +function read(fd, buffer, offset, length, position) { return new Promise((resolve, reject) => { - fs.read(fd, buffer, offset, length, position, (err, bytesRead) => { + _fs.default.read(fd, buffer, offset, length, position, (err, bytesRead) => { if (err == null) { resolve(bytesRead); } else { @@ -476,17 +467,12 @@ function read( // `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) { + + +const readFile = function (...args) { return new Promise((resolve, reject) => { // $FlowIssue: spread operator doesn't preserve any-type - fs.readFile(...args, (err, result) => { + _fs.default.readFile(...args, (err, result) => { if (err == null) { resolve(result); } else { @@ -494,11 +480,11 @@ const readFile: ReadFileType = (function(...args: Array) { } }); }); -}: any); +}; -function readdir(path: string): Promise> { +function readdir(path) { return new Promise((resolve, reject) => { - fs.readdir(path, (err, result) => { + _fs.default.readdir(path, (err, result) => { if (err == null) { resolve(result); } else { @@ -508,9 +494,9 @@ function readdir(path: string): Promise> { }); } -function readlink(path: string): Promise { +function readlink(path) { return new Promise((resolve, reject) => { - fs.readlink(path, (err, result) => { + _fs.default.readlink(path, (err, result) => { if (err == null) { resolve(result); } else { @@ -520,9 +506,9 @@ function readlink(path: string): Promise { }); } -function realpath(path: string, cache?: Object): Promise { +function realpath(path, cache) { return new Promise((resolve, reject) => { - fs.realpath(path, cache, (err, result) => { + _fs.default.realpath(path, cache, (err, result) => { if (err == null) { resolve(result); } else { @@ -532,9 +518,9 @@ function realpath(path: string, cache?: Object): Promise { }); } -function access(path: string, mode: number): Promise { +function access(path, mode) { return new Promise((resolve, reject) => { - fs.access(path, mode, err => { + _fs.default.access(path, mode, err => { if (err == null) { resolve(true); } else { @@ -544,9 +530,9 @@ function access(path: string, mode: number): Promise { }); } -function stat(path: string): Promise { +function stat(path) { return new Promise((resolve, reject) => { - fs.stat(path, (err, result) => { + _fs.default.stat(path, (err, result) => { if (err == null) { resolve(result); } else { @@ -556,9 +542,9 @@ function stat(path: string): Promise { }); } -function symlink(source: string, dest: string, type?: string): Promise { +function symlink(source, dest, type) { return new Promise((resolve, reject) => { - fs.symlink(source, dest, type, (err, result) => { + _fs.default.symlink(source, dest, type, (err, result) => { if (err == null) { resolve(result); } else { @@ -572,23 +558,20 @@ function symlink(source: string, dest: string, type?: string): Promise { * 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 { +async function tailBytes(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} = await stat(file); + 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( - fd, - buffer, - 0, // buffer offset - maxBytes, // length to read - file_size - maxBytes, // file offset + const bytesRead = await read(fd, buffer, 0, // buffer offset + maxBytes, // length to read + file_size - maxBytes // file offset ); await close(fd); @@ -597,10 +580,7 @@ async function tailBytes(file: string, maxBytes: number): Promise { * 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`, - ); + throw new Error(`Failed to tail file. Intended to read ${maxBytes} bytes but ` + `only read ${bytesRead} bytes`); } return buffer; } else { @@ -608,9 +588,9 @@ async function tailBytes(file: string, maxBytes: number): Promise { } } -function unlink(path: string): Promise { +function unlink(path) { return new Promise((resolve, reject) => { - fs.unlink(path, (err, result) => { + _fs.default.unlink(path, (err, result) => { if (err == null) { resolve(result); } else { @@ -620,13 +600,9 @@ function unlink(path: string): Promise { }); } -function utimes( - path: string, - atime: number | Date, - mtime: number | Date, -): Promise { +function utimes(path, atime, mtime) { return new Promise((resolve, reject) => { - fs.utimes(path, atime, mtime, err => { + _fs.default.utimes(path, atime, mtime, err => { if (err == null) { resolve(); } else { @@ -636,9 +612,9 @@ function utimes( }); } -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 { @@ -648,7 +624,7 @@ function rmdir(path: string): Promise { }); } -export default { +exports.default = { tempdir, tempfile, findNearestFile, @@ -688,5 +664,5 @@ export default { access, findNearestAncestorNamed, - resolveRealPath, -}; + resolveRealPath +}; \ No newline at end of file diff --git a/modules/nuclide-commons/humanizeKeystroke.js b/modules/nuclide-commons/humanizeKeystroke.js index 05ab877eae..1bfaf9f05d 100644 --- a/modules/nuclide-commons/humanizeKeystroke.js +++ b/modules/nuclide-commons/humanizeKeystroke.js @@ -1,3 +1,9 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = humanizeKeystroke; /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,7 +12,7 @@ * LICENSE file in 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 strict + * strict * @format */ @@ -24,7 +30,7 @@ const MAC_MODIFIER_KEYMAP = { option: '\u2325', right: '\u2192', shift: '\u21e7', - up: '\u2191', + up: '\u2191' }; const NON_MAC_MODIFIER_KEYMAP = { @@ -37,7 +43,7 @@ const NON_MAC_MODIFIER_KEYMAP = { option: 'Alt', right: 'Right', shift: 'Shift', - up: 'Up', + up: 'Up' }; // Human key combos should always explicitly state the shift key. This map is a disambiguator. @@ -53,13 +59,13 @@ const SHIFT_KEYMAP = { '<': ',', '>': '.', '|': '\\', - '~': '`', + '~': '`' }; const FN_KEY_RE = /f[0-9]{1,2}/; // $FlowIssue -function flatten(arr: Array>): Array { +function flatten(arr) { let flattened = []; for (const el of arr) { if (Array.isArray(el)) { @@ -71,18 +77,17 @@ function flatten(arr: Array>): Array { return flattened; } -function capitalize(word: string): string { +function capitalize(word) { const first = word[0] || ''; const rest = word.slice(1); return first.toUpperCase() + rest; } -function humanizeKey(key: string, platform: ?string): string | Array { +function humanizeKey(key, platform) { if (!key) { return key; } - const modifierKeyMap = - platform === 'darwin' ? MAC_MODIFIER_KEYMAP : NON_MAC_MODIFIER_KEYMAP; + const modifierKeyMap = platform === 'darwin' ? MAC_MODIFIER_KEYMAP : NON_MAC_MODIFIER_KEYMAP; if (modifierKeyMap[key]) { return modifierKeyMap[key]; } @@ -111,10 +116,7 @@ function humanizeKey(key: string, platform: ?string): string | Array { * @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 { +function humanizeKeystroke(keystroke, platform_) { let platform = platform_; if (!keystroke) { return keystroke; @@ -144,4 +146,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 7e1bec7bca..b77ebc7528 100644 --- a/modules/nuclide-commons/matchIndexesToRanges.js +++ b/modules/nuclide-commons/matchIndexesToRanges.js @@ -1,20 +1,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. - * - * @flow strict - * @format - */ +"use strict"; -type MatchRange = [/* start */ number, /* end */ number]; - -export default function matchIndexesToRanges( - matchIndexes: Array, -): Array { +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = matchIndexesToRanges; +function matchIndexesToRanges(matchIndexes) { let streakOngoing = false; let start = 0; const ranges = []; @@ -38,4 +28,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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/memoizeUntilChanged.js b/modules/nuclide-commons/memoizeUntilChanged.js index 93088431ec..81501f0430 100644 --- a/modules/nuclide-commons/memoizeUntilChanged.js +++ b/modules/nuclide-commons/memoizeUntilChanged.js @@ -1,44 +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'; -import invariant from 'assert'; -import {arrayEqual} from './collection'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -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); +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 @@ -77,25 +47,40 @@ type memoizeUntilChanged = (( * } * } */ -export default ((func, keySelector_?, compareKeys_?) => { - invariant( - !(keySelector_ == null && compareKeys_ != null), - "You can't provide a compare function without also providing a key selector.", - ); +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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_ || arrayEqual; - return function(...args) { - const key = (keySelector: Function)(...args); - invariant(key != null, 'Key cannot be null'); + 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 61115d1a37..65bb55668f 100644 --- a/modules/nuclide-commons/nice.js +++ b/modules/nuclide-commons/nice.js @@ -1,3 +1,33 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.niceSafeSpawn = niceSafeSpawn; +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. @@ -6,29 +36,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 */ -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 { +async function niceSafeSpawn(command, args, execOptions) { const nicified = await nicifyCommand(command, args, execOptions); - const processStream = spawn(...nicified).publish(); + const processStream = (0, (_process || _load_process()).spawn)(...nicified).publish(); const processPromise = processStream.take(1).toPromise(); processStream.connect(); return processPromise; @@ -46,11 +63,7 @@ export async function niceSafeSpawn( * * See also `scriptifyCommand()` which does a similar thing but for `script`. */ -async function nicifyCommand( - command: string, - args?: Array, - options: T, -): Promise<[string, Array, T]> { +async function nicifyCommand(command, args, options) { const fullArgs = [command, ...(args || [])]; if (await hasNiceCommand()) { fullArgs.unshift(NICE_COMMAND); @@ -71,37 +84,31 @@ async function nicifyCommand( return [fullArgs[0], fullArgs.slice(1), options]; } -const commandAvailabilityCache: LRUCache> = LRU({ +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 + maxAge: 1000 * 60 * 5 // 5 minutes }); -function hasNiceCommand(): Promise { +function hasNiceCommand() { return hasCommand(NICE_COMMAND); } -function hasIoniceCommand(): Promise { +function hasIoniceCommand() { return hasCommand(IONICE_COMMAND); } -function hasCommand(command: string): Promise { - let result: ?Promise = commandAvailabilityCache.get(command); +function hasCommand(command) { + let result = commandAvailabilityCache.get(command); if (result == null) { - result = which(command).then(x => x != null); + result = (0, (_which || _load_which()).default)(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)); -} +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 78b3e9bc8c..c03e1cad4e 100644 --- a/modules/nuclide-commons/nuclideUri.js +++ b/modules/nuclide-commons/nuclideUri.js @@ -1,3 +1,28 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.__TEST__ = undefined; + +var _vscodeUri; + +function _load_vscodeUri() { + return _vscodeUri = _interopRequireDefault(require('vscode-uri')); +} + +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. @@ -6,7 +31,7 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ @@ -15,36 +40,9 @@ // // This package creates, queries and decomposes NuclideUris. -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'; +const ARCHIVE_SEPARATOR = '!'; // eslint-disable-next-line nuclide-internal/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://'; @@ -52,40 +50,36 @@ const REMOTE_PATH_URI_PREFIX = 'nuclide://'; // [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 { +function isRemote(uri) { return uri.startsWith(REMOTE_PATH_URI_PREFIX); } // 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) - ) { + for (let i = uri.indexOf(ARCHIVE_SEPARATOR); i >= 0; i = uri.indexOf(ARCHIVE_SEPARATOR, i + 1)) { if (_isArchiveSeparator(uri, i)) { return true; } @@ -93,12 +87,8 @@ function isInArchive(uri: NuclideUri): boolean { return false; } -function ancestorOutsideArchive(uri: NuclideUri): NuclideUri { - for ( - let i = uri.indexOf(ARCHIVE_SEPARATOR); - i >= 0; - i = uri.indexOf(ARCHIVE_SEPARATOR, i + 1) - ) { +function ancestorOutsideArchive(uri) { + for (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,67 +105,68 @@ function ancestorOutsideArchive(uri: NuclideUri): NuclideUri { * 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 { +function parse(uri) { if (uri.startsWith(REMOTE_PATH_URI_PREFIX)) { const hostAndPath = uri.substr(REMOTE_PATH_URI_PREFIX.length); const hostSep = hostAndPath.indexOf('/'); - invariant( - hostSep !== -1, - `Remote URIs must contain a hostname and a path. Failed to parse ${uri}`, - ); + if (!(hostSep !== -1)) { + throw new Error(`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}`, - ); + + if (!(hostname !== '')) { + throw new Error(`Remote URIs must contain a hostname. 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}; + + if (!!_endsWithArchiveSeparator(uri)) { + throw new Error(`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}; + 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}'`, - ); + + 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; } @@ -183,28 +174,22 @@ 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)), - ); + return _archiveDecode(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), - ); + return _archiveDecode(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}`); @@ -212,98 +197,63 @@ 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 normal = _archiveDecode( - uriPathModule, - uriPathModule.normalize(_archiveEncode(uriPathModule, path)), - ); + const { hostname, path } = parseRemoteUri(uri); + const normal = _archiveDecode(uriPathModule, uriPathModule.normalize(_archiveEncode(uriPathModule, path))); return createRemoteUri(hostname, normal); } else { - return _archiveDecode( - uriPathModule, - uriPathModule.normalize(_archiveEncode(uriPathModule, uri)), - ); + return _archiveDecode(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)) - ) { - throw new Error( - `Cannot relative urls on different hosts: ${uri} and ${other}`, - ); + if (remote !== isRemote(other) || remote && getHostname(uri) !== getHostname(other)) { + throw new Error(`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, - ); - return _archiveDecode( - uriPathModule, - uriPathModule.relative( - _matchTrailingArchive(uriEncode, otherEncode), - _matchTrailingArchive(otherEncode, uriEncode), - ), - ); -} - -function basename(uri: NuclideUri, ext: string = ''): string { + const otherEncode = _archiveEncode(uriPathModule, remote ? getPath(other) : other); + return _archiveDecode(uriPathModule, uriPathModule.relative(_matchTrailingArchive(uriEncode, otherEncode), _matchTrailingArchive(otherEncode, uriEncode))); +} + +function basename(uri, ext = '') { _testForIllegalUri(uri); const uriPathModule = _pathModuleFor(uri); - return _archiveDecode( - uriPathModule, - uriPathModule.basename(_archiveEncode(uriPathModule, getPath(uri)), ext), - ); + return _archiveDecode(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); - return createRemoteUri( - hostname, - _archiveDecode( - uriPathModule, - uriPathModule.dirname(_archiveEncode(uriPathModule, path)), - ), - ); + const { hostname, path } = parseRemoteUri(uri); + return createRemoteUri(hostname, _archiveDecode(uriPathModule, uriPathModule.dirname(_archiveEncode(uriPathModule, path)))); } else { - return _archiveDecode( - uriPathModule, - uriPathModule.dirname(_archiveEncode(uriPathModule, uri)), - ); + return _archiveDecode(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))), - ); + return _archiveDecode(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) { @@ -313,11 +263,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; @@ -333,7 +283,7 @@ function _getWindowsPathFromWindowsFileUri(uri: string): ?string { * * Returns null if not a valid file: URI. */ -function uriToNuclideUri(uri: string): ?string { +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". @@ -347,7 +297,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. @@ -362,19 +312,19 @@ function uriToNuclideUri(uri: string): ?string { /** * Converts local paths to file: URI's. Leaves remote URI's alone. */ -function nuclideUriToUri(uri: NuclideUri): string { +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 { +function contains(parent, child) { _testForIllegalUri(parent); _testForIllegalUri(child); @@ -401,10 +351,7 @@ function contains(parent: NuclideUri, child: NuclideUri): boolean { return false; } - return ( - parent.startsWith(child) && - (endsWithSeparator(parent) || _isArchiveSeparator(child, parent.length)) - ); + return parent.startsWith(child) && (endsWithSeparator(parent) || _isArchiveSeparator(child, parent.length)); } if (!child.startsWith(parent)) { @@ -417,17 +364,14 @@ function contains(parent: NuclideUri, child: NuclideUri): boolean { const uriPathModule = _pathModuleFor(child); - return ( - _isArchiveSeparator(child, parent.length) || - child.slice(parent.length).startsWith(uriPathModule.sep) - ); + return _isArchiveSeparator(child, parent.length) || 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 { +function collapse(paths) { return paths.filter(p => !paths.some(fp => contains(fp, p) && fp !== p)); } @@ -435,10 +379,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: () => { @@ -446,7 +390,7 @@ function registerHostnameFormatter(formatter: HostnameFormatter): IDisposable { if (index >= 0) { hostFormatters.splice(index, 1); } - }, + } }; } @@ -454,7 +398,7 @@ function registerHostnameFormatter(formatter: HostnameFormatter): IDisposable { * NuclideUris should never be shown to humans. * This function returns a human usable string. */ -function nuclideUriToDisplayString(uri: NuclideUri): string { +function nuclideUriToDisplayString(uri) { _testForIllegalUri(uri); if (isRemote(uri)) { let hostname = getHostname(uri); @@ -472,7 +416,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)) { @@ -482,7 +426,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; @@ -494,13 +438,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; @@ -510,28 +454,22 @@ 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)), - ); + return createRemoteUri(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), - ); + return _archiveDecode(uriPathModule, uriPathModule.resolve.apply(null, paths)); } } -function expandHomeDir(uri: NuclideUri): NuclideUri { +function expandHomeDir(uri) { _testForIllegalUri(uri); // Do not expand non home relative uris @@ -542,11 +480,14 @@ 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 isWindows = !isRemote(uri) && _os.default.platform() === 'win32'; const homePath = isWindows ? UserProfile : HOME; - invariant(homePath != null); + + if (!(homePath != null)) { + throw new Error('Invariant violation: "homePath != null"'); + } if (uri === '~') { return homePath; @@ -557,7 +498,7 @@ function expandHomeDir(uri: NuclideUri): NuclideUri { return uri; } - return pathModule.resolve(homePath, uri.replace('~', '.')); + return _path.default.resolve(homePath, uri.replace('~', '.')); } /** @@ -566,11 +507,11 @@ function expandHomeDir(uri: NuclideUri): NuclideUri { * * 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', - ); +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); @@ -582,15 +523,14 @@ function splitPathList(paths: string): Array { * * Since remote URI might contain the delimiter, only local paths are allowed. */ -function joinPathList(paths: Array): string { +function joinPathList(paths) { if (paths.length === 0) { return ''; } - invariant( - paths.every(path => !isRemote(path)), - 'Joining of remote URIs is not supported', - ); + if (!paths.every(path => !isRemote(path))) { + throw new Error('Joining of remote URIs is not supported'); + } const uriPathModule = _pathModuleFor(paths[0]); return paths.join(uriPathModule.delimiter); @@ -600,15 +540,17 @@ function joinPathList(paths: Array): string { * This function prepends the given relative path with a "current-folder" prefix * which is `./` on *nix and .\ on Windows */ -function ensureLocalPrefix(uri: NuclideUri): NuclideUri { +function ensureLocalPrefix(uri) { _testForIllegalUri(uri); const uriPathModule = _pathModuleFor(uri); - 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', - ); + 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'); + } const localPrefix = `.${uriPathModule.sep}`; if (uri.startsWith(localPrefix)) { @@ -618,35 +560,33 @@ 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)), - ); + const parsed = uriPathModule.parse(_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); @@ -665,82 +605,54 @@ 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; + if (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))); +function _archiveEncodeArrayInPlace(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 { +function _archiveEncode(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, - ); + return KNOWN_ARCHIVE_EXTENSIONS.reduce((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 { +function _archiveDecode(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, - ), - ); + return _trimArchiveSuffix(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 @@ -754,19 +666,15 @@ 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 { - if ( - uri.length < other.length && - other.startsWith(uri) && - _isArchiveSeparator(other, uri.length) - ) { +function _matchTrailingArchive(uri, other) { + if (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 { @@ -774,27 +682,21 @@ 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 { - 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 _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}`, - ); + throw new Error(`Path operation invoked on URI ending with ${ARCHIVE_SEPARATOR}: ${uri}`); } } } @@ -803,42 +705,44 @@ 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'); + + if (!(mustBeRemote !== false)) { + throw new Error('Expected remote NuclideUri'); + } } else { - invariant(uri !== '', 'NuclideUri must contain a non-empty path'); - invariant(mustBeRemote !== true, 'Expected local NuclideUri'); + if (!(uri !== '')) { + throw new Error('NuclideUri must contain a non-empty path'); + } + + if (!(mustBeRemote !== true)) { + throw new Error('Expected local NuclideUri'); + } } } -const IMAGE_EXTENSIONS = new Set([ - '.bmp', - '.gif', - '.ico', - '.jpeg', - '.jpg', - '.png', - '.webp', -]); +const IMAGE_EXTENSIONS = new Set(['.bmp', '.gif', '.ico', '.jpeg', '.jpg', '.png', '.webp']); /** * Returns true if this filename looks like an image that Nuclide can open; otherwise false. */ -function looksLikeImageUri(uri: NuclideUri): boolean { +function looksLikeImageUri(uri) { const ext = extname(uri).toLowerCase(); return IMAGE_EXTENSIONS.has(ext); } -export default { +exports.default = { basename, dirname, extname, @@ -883,9 +787,8 @@ export default { hasKnownArchiveExtension, ARCHIVE_SEPARATOR, KNOWN_ARCHIVE_EXTENSIONS, - NUCLIDE_URI_TYPE_NAME, -}; - -export const __TEST__ = { - _pathModuleFor, + NUCLIDE_URI_TYPE_NAME }; +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 f0cecd3ab3..a74475b354 100644 --- a/modules/nuclide-commons/observable.js +++ b/modules/nuclide-commons/observable.js @@ -1,39 +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 - */ +'use strict'; -/* global requestAnimationFrame, cancelAnimationFrame */ +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SingletonExecutor = exports.nextAnimationFrame = exports.macrotask = exports.microtask = undefined; +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.mergeUntilAnyComplete = mergeUntilAnyComplete; +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')); +} -// 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): -// -// const makeExciting = (excitementLevel: number = 1) => -// (source: Observable) => -// source.map(x => x + '!'.repeat(excitementLevel)); -// -// Observable.of('hey', 'everybody') -// .let(makeExciting()) -// .subscribe(x => console.log(x)); +var _domexception; + +function _load_domexception() { + return _domexception = _interopRequireDefault(require('domexception')); +} -import type {AbortSignal} from './AbortController'; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); -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'; +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. @@ -41,12 +63,9 @@ import debounce from './debounce'; * 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 splitStream(input, includeNewlines = true) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { + let current = ''; function onEnd() { if (current !== '') { @@ -55,26 +74,22 @@ export function splitStream( } } - 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(); - }, - ); + 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(); + }); }); } @@ -87,38 +102,59 @@ export function splitStream( * (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(); - }, - ); + +// Note: DOMException is usable in Chrome but not in Node. +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 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): +// +// const makeExciting = (excitementLevel: number = 1) => +// (source: Observable) => +// source.map(x => x + '!'.repeat(excitementLevel)); +// +// Observable.of('hey', 'everybody') +// .let(makeExciting()) +// .subscribe(x => console.log(x)); + +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(); }); + }); } /** @@ -129,49 +165,36 @@ export function bufferUntil( * 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(); +function cacheWhileSubscribed(input) { + return input.multicast(() => new _rxjsBundlesRxMinJs.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); +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. */ -export function reconcileSetDiffs( - diffs: Observable>, - addAction: (addedItem: T) => IDisposable, - hash_?: (v: T) => any, -): IDisposable { +function reconcileSetDiffs(diffs, addAction, hash_) { const hash = hash_ || (x => x); const itemsToDisposables = new Map(); const disposeItem = item => { const disposable = itemsToDisposables.get(hash(item)); - invariant(disposable != null); + + if (!(disposable != null)) { + throw new Error('Invariant violation: "disposable != null"'); + } + disposable.dispose(); itemsToDisposables.delete(item); }; @@ -182,18 +205,15 @@ export function reconcileSetDiffs( 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)); - }); + 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, - ); + // "Undo" the add action for each item that got removed. + diff.removed.forEach(disposeItem); + }), disposeAll); } /** @@ -224,88 +244,52 @@ export function reconcileSetDiffs( * 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 { +function reconcileSets(sets, addAction, hash) { 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())); +function toggle(toggler) { + return source => toggler.distinctUntilChanged().switchMap(enabled => enabled ? source : _rxjsBundlesRxMinJs.Observable.empty()); } -export function compact(source: Observable): Observable { +function compact(source) { // Flow does not understand the semantics of `filter` - return (source.filter(x => x != null): any); + return source.filter(x => x != null); } /** * 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(); - }, - ), - ); +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> { +function concatLatest(...observables) { // 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)); + 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)); } -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) => { +function throttle(duration, options_) { + return source => { const options = options_ || {}; const leading = options.leading !== false; let audit; @@ -324,16 +308,10 @@ export function throttle( return audit(source); } - return Observable.create(observer => { + return _rxjsBundlesRxMinJs.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(), - ); + const throttled = _rxjsBundlesRxMinJs.Observable.merge(connectableSource.take(1), audit(connectableSource.skip(1))); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(throttled.subscribe(observer), connectableSource.connect()); }); }; } @@ -351,34 +329,24 @@ export function throttle( * 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 { +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); - }); + return observable => _rxjsBundlesRxMinJs.Observable.concat(observable, _rxjsBundlesRxMinJs.Observable.of(completedSymbol)).switchMap((input, index) => { + if (input === completedSymbol) { + return _rxjsBundlesRxMinJs.Observable.empty(); + } + return project(input, index); + }); } /** * Returns a new observable consisting of the merged values from the passed * observables and completes when the first inner observable completes. */ -export function mergeUntilAnyComplete( - ...observables: Array> -): Observable { - const notifications = Observable.merge( - ...observables.map(o => o.materialize()), - ); +function mergeUntilAnyComplete(...observables) { + const notifications = _rxjsBundlesRxMinJs.Observable.merge(...observables.map(o => o.materialize())); // $FlowFixMe add dematerialize to rxjs Flow types return notifications.dematerialize(); } @@ -395,29 +363,22 @@ export function mergeUntilAnyComplete( * * [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); - }); +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); + }); } -export const microtask = Observable.create(observer => { +const microtask = exports.microtask = _rxjsBundlesRxMinJs.Observable.create(observer => { process.nextTick(() => { observer.next(); observer.complete(); }); }); -export const macrotask = Observable.create(observer => { +const macrotask = exports.macrotask = _rxjsBundlesRxMinJs.Observable.create(observer => { const timerId = setImmediate(() => { observer.next(); observer.complete(); @@ -427,7 +388,7 @@ export const macrotask = Observable.create(observer => { }; }); -export const nextAnimationFrame = Observable.create(observer => { +const nextAnimationFrame = exports.nextAnimationFrame = _rxjsBundlesRxMinJs.Observable.create(observer => { if (typeof requestAnimationFrame === 'undefined') { throw new Error('This util can only be used in Atom'); } @@ -451,23 +412,18 @@ export const nextAnimationFrame = Observable.create(observer => { * 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 => { +function fromAbortablePromise(func) { + return _rxjsBundlesRxMinJs.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); - }, - ); + 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(); @@ -498,23 +454,16 @@ export function fromAbortablePromise( * 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 { +function toAbortablePromise(observable, signal) { if (signal == null) { return observable.toPromise(); } if (signal.aborted) { - return Promise.reject(DOMException('Aborted', 'AbortError')); + return Promise.reject((0, (_domexception || _load_domexception()).default)('Aborted', 'AbortError')); } - return observable - .race( - Observable.fromEvent(signal, 'abort').map(() => { - throw new DOMException('Aborted', 'AbortError'); - }), - ) - .toPromise(); + return observable.race(_rxjsBundlesRxMinJs.Observable.fromEvent(signal, 'abort').map(() => { + throw new (_domexception || _load_domexception()).default('Aborted', 'AbortError'); + })).toPromise(); } /** @@ -525,34 +474,33 @@ export function toAbortablePromise( * myObservable * .let(obs => takeUntilAbort(obs, signal)) */ -export function takeUntilAbort( - observable: Observable, - signal: AbortSignal, -): Observable { - return Observable.defer(() => { +function takeUntilAbort(observable, signal) { + return _rxjsBundlesRxMinJs.Observable.defer(() => { if (signal.aborted) { - return Observable.empty(); + return _rxjsBundlesRxMinJs.Observable.empty(); } - return observable.takeUntil(Observable.fromEvent(signal, 'abort')); + 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; +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 { + async execute(createTask) { // Kill any previously running processes this.cancel(); // Start a new process - const controller = new AbortController(); + const controller = new (_AbortController || _load_AbortController()).default(); this._abortController = controller; // Wait for the process to complete or be canceled ... @@ -566,12 +514,12 @@ export class SingletonExecutor { } } - isExecuting(): boolean { + isExecuting() { return this._abortController != null; } // Cancels any currently executing tasks. - cancel(): void { + cancel() { if (this._abortController != null) { this._abortController.abort(); this._abortController = null; @@ -579,40 +527,37 @@ export class 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!!") - * }); - * - */ -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)); - }, - }); - }); +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 9e5e007a68..6dbba7067f 100644 --- a/modules/nuclide-commons/package.js +++ b/modules/nuclide-commons/package.js @@ -1,29 +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 strict - * @format - */ - -import fs from 'fs'; -import invariant from 'assert'; +'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.-]+))?$/; +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. + * + * strict + * @format + */ -export function getPackageMinorVersion(packageJsonPath: string): string { - const pkgJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); +function getPackageMinorVersion(packageJsonPath) { + const pkgJson = JSON.parse(_fs.default.readFileSync(packageJsonPath, 'utf8')); const match = SEMVERISH_RE.exec(pkgJson.version); - invariant(match); + + 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; -} +} \ No newline at end of file diff --git a/modules/nuclide-commons/path-uri.js b/modules/nuclide-commons/path-uri.js index afdf9eff71..eae4b58db1 100644 --- a/modules/nuclide-commons/path-uri.js +++ b/modules/nuclide-commons/path-uri.js @@ -1,18 +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 strict - * @format - */ +'use strict'; -import url from 'url'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.pathToUri = pathToUri; +exports.uriToPath = uriToPath; -export function pathToUri(path: string): string { +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. @@ -20,16 +18,26 @@ export function pathToUri(path: string): string { // fails to work with UNC-style paths "\\server\path", // and fails to escape. 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. + * + * strict + * @format + */ -export function uriToPath(uri: string): string { +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); + 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 bbcd3c1bff..421d3def8c 100644 --- a/modules/nuclide-commons/performanceNow.js +++ b/modules/nuclide-commons/performanceNow.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,7 +11,7 @@ * LICENSE file in 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 strict + * strict * @format */ @@ -22,9 +27,7 @@ * const timeItTookInMilliseconds = performanceNow() - now; */ -export default (typeof performance !== 'undefined' - ? (): number => performance.now() - : (): number => { - const [seconds, nanoseconds] = process.hrtime(); - return seconds * 1000 + nanoseconds / 1000000; - }); +exports.default = 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 60b5d50e85..ea9e9a147c 100644 --- a/modules/nuclide-commons/process.js +++ b/modules/nuclide-commons/process.js @@ -1,14 +1,109 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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.loggedCalls = exports.ProcessLoggingEvent = exports.ProcessTimeoutError = exports.MaxBufferExceededError = exports.ProcessSystemError = exports.ProcessExitError = exports.LOG_CATEGORY = undefined; +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.getOriginalEnvironment = getOriginalEnvironment; +exports.exitEventToMessage = exitEventToMessage; +exports.getChildrenOfProcess = getChildrenOfProcess; +exports.psTree = psTree; +exports.parsePsOutput = parsePsOutput; +exports.memoryUsagePerPid = memoryUsagePerPid; +exports.preventStreamsFromThrowing = preventStreamsFromThrowing; +exports.logStreamErrors = logStreamErrors; +exports.getAbsoluteBinaryPathForPid = getAbsoluteBinaryPathForPid; +exports.killUnixProcessTree = killUnixProcessTree; + +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 + */ // // __ __ __ __ ___ __ __ __ @@ -48,27 +143,9 @@ // // [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 NUCLIDE_DO_NOT_LOG = global.NUCLIDE_DO_NOT_LOG; -const logger = getLogger(LOG_CATEGORY); +const logger = (0, (_log4js || _load_log4js()).getLogger)(LOG_CATEGORY); /** * Run a command, accumulate the output. Errors are surfaced as stream errors and unsubscribing will @@ -123,12 +200,7 @@ const logger = getLogger(LOG_CATEGORY); * [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 { +function runCommand(command, args = [], options = {}, rest) { return runCommandDetailed(command, args, options).map(event => event.stdout); } @@ -158,22 +230,10 @@ export function runCommand( * }); * ``` */ -export function observeProcess( - command: string, - args?: Array, - options?: ObserveProcessOptions, -): Observable { - return spawn(command, args, options).flatMap(proc => - getOutputStream(proc, options), - ); +function observeProcess(command, args, options) { + 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 @@ -182,59 +242,39 @@ export type DetailedProcessResult = { * 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}, - ); +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. */ -export function observeProcessRaw( - command: string, - args?: Array, - options?: ObserveProcessOptions, -): Observable { - return spawn(command, args, options).flatMap(proc => - getOutputStream(proc, {...options, splitByLines: false}), - ); +function observeProcessRaw(command, args, options) { + return spawn(command, args, options).flatMap(proc => getOutputStream(proc, Object.assign({}, options, { splitByLines: false }))); } // @@ -270,22 +310,14 @@ export function observeProcessRaw( * }); * ``` */ -export function spawn( - command: string, - args?: Array, - options?: SpawnProcessOptions, -): Observable { +function spawn(command, args, options) { 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 { +function fork(modulePath, args, options) { return createProcessStream('fork', modulePath, args, options); } @@ -300,76 +332,41 @@ export function fork( * 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(); +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)); + 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 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 Observable.merge(stdoutEvents, stderrEvents) - .concat(closeEvents) - .let( - takeWhileInclusive( - event => event.kind !== 'error' && event.kind !== 'exit', - ), - ) - .finally(() => { - exitSub.unsubscribe(); - }); + return _rxjsBundlesRxMinJs.Observable.merge(stdoutEvents, stderrEvents).concat(closeEvents).let((0, (_observable || _load_observable()).takeWhileInclusive)(event => event.kind !== 'error' && event.kind !== 'exit')).finally(() => { + exitSub.unsubscribe(); + }); }); } @@ -392,51 +389,38 @@ 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] { +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]); + 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. - {...opts, env: {...env, SHELL: '/bin/bash'}}, - ]; + 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. */ -export function killProcess( - proc: child_process$ChildProcess, - killTree: boolean, -): void { - _killProcess(proc, killTree).then( - () => {}, - error => { - logger.error(`Killing process ${proc.pid} failed`, error); - }, - ); +function killProcess(proc, killTree) { + _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 { +function killPid(pid) { try { process.kill(pid); } catch (err) { @@ -449,7 +433,7 @@ export function killPid(pid: number): void { // 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 { +async function getOriginalEnvironment() { await new Promise(resolve => { whenShellEnvironmentLoaded(resolve); }); @@ -457,7 +441,7 @@ export async function getOriginalEnvironment(): Promise { return cachedOriginalEnvironment; } - const {NUCLIDE_ORIGINAL_ENV} = process.env; + 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 = {}; @@ -465,9 +449,7 @@ export async function getOriginalEnvironment(): Promise { // envVar should look like A=value_of_A const equalIndex = envVar.indexOf('='); if (equalIndex !== -1) { - cachedOriginalEnvironment[ - envVar.substring(0, equalIndex) - ] = envVar.substring(equalIndex + 1); + cachedOriginalEnvironment[envVar.substring(0, equalIndex)] = envVar.substring(equalIndex + 1); } } // Guard against invalid original environments. @@ -483,21 +465,19 @@ export async function getOriginalEnvironment(): Promise { /** * Returns a string suitable for including in displayed error messages. */ -export function exitEventToMessage(event: { - exitCode: ?number, - signal: ?string, -}): string { +function exitEventToMessage(event) { if (event.exitCode != null) { return `exit code ${event.exitCode}`; } else { - invariant(event.signal != null); + if (!(event.signal != null)) { + throw new Error('Invariant violation: "event.signal != null"'); + } + return `signal ${event.signal}`; } } -export async function getChildrenOfProcess( - processId: number, -): Promise> { +async function getChildrenOfProcess(processId) { const processes = await psTree(); return processes.filter(processInfo => processInfo.parentPid === processId); @@ -506,12 +486,10 @@ export async function getChildrenOfProcess( /** * Get a list of descendants, sorted by increasing depth (including the one with the provided pid). */ -async function getDescendantsOfProcess( - pid: number, -): Promise> { +async function getDescendantsOfProcess(pid) { const processes = await psTree(); let rootProcessInfo; - const pidToChildren = new MultiMap(); + const pidToChildren = new (_collection || _load_collection()).MultiMap(); processes.forEach(info => { if (info.pid === pid) { rootProcessInfo = info; @@ -529,51 +507,32 @@ async function getDescendantsOfProcess( return descendants; } -export async function psTree(): Promise> { +async function psTree() { 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(), - ]); + 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(); +async function psTreeWindows() { + const stdout = await runCommand('wmic.exe', ['PROCESS', 'GET', 'ParentProcessId,ProcessId,Name']).toPromise(); return parsePsOutput(stdout); } -export function parsePsOutput( - psOutput: string, - argsOutput: ?string, -): Array { +function parsePsOutput(psOutput, argsOutput) { // Remove the first header line. - const lines = psOutput - .trim() - .split(/\n|\r\n/) - .slice(1); + 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]; - }), - ); + 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 => { @@ -587,26 +546,17 @@ export function parsePsOutput( command, parentPid: parseInt(parentPid, 10), pid, - commandWithArgs: commandWithArgs == null ? command : commandWithArgs, + 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> { +async function memoryUsagePerPid(pids) { const usage = new Map(); if (pids.length >= 1) { try { - const stdout = await runCommand('ps', [ - '-p', - pids.join(','), - '-o', - 'pid=', - '-o', - 'rss=', - ]).toPromise(); + 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) { @@ -624,36 +574,18 @@ export async function memoryUsagePerPid( /** * 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()); +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()`. */ -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(), - ); +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()); } // @@ -662,91 +594,11 @@ export function logStreamErrors( // 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 @@ -761,33 +613,17 @@ export type ProcessError = ProcessSystemError | ProcessExitError; * `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, - ) { +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 { 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(' ')}`, - ); + super(`"${command}" failed with ${exitEventToMessage({ + exitCode, + signal + })}\n\n${stderr}\n\n${argsAndCommand.join(' ')}`); this.name = 'ProcessExitError'; this.exitCode = exitCode; this.signal = signal; @@ -799,18 +635,14 @@ export class ProcessExitError extends Error { } } -/** - * 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) { +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; @@ -821,81 +653,79 @@ export class ProcessSystemError extends Error { } } -export class MaxBufferExceededError extends Error { - constructor(streamName: string) { +exports.ProcessSystemError = ProcessSystemError; +class MaxBufferExceededError extends Error { + constructor(streamName) { super(`${streamName} maxBuffer exceeded`); this.name = 'MaxBufferExceededError'; } } -export class ProcessTimeoutError extends Error { - constructor(timeout: number, proc: child_process$ChildProcess) { +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]; + 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; - }; +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; +class ProcessLoggingEvent { - constructor(command: string, duration: number) { + 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] = () => { + this[_util.default.inspect.custom] = () => { return `${this.duration}ms: ${this.command}`; }; } } -export const loggedCalls = []; -function logCall(duration: number, command: string, args: Array) { +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(), + time: new Date() }); } - const fullCommand = shellQuote([command, ...args]); + const fullCommand = (0, (_string || _load_string()).shellQuote)([command, ...args]); loggedCalls.push({ command: fullCommand, duration, - time: new Date(), + time: new Date() }); logger.info(new ProcessLoggingEvent(fullCommand, duration)); } @@ -910,9 +740,7 @@ function logCall(duration: number, command: string, args: Array) { * an open FD to the executable. This can fail for various reasons (mostly * not having permissions to execute lsof on the pid.) */ -export async function getAbsoluteBinaryPathForPid( - pid: number, -): Promise { +async function getAbsoluteBinaryPathForPid(pid) { if (process.platform === 'linux') { return _getLinuxBinaryPathForPid(pid); } @@ -924,31 +752,16 @@ export async function getAbsoluteBinaryPathForPid( return null; } -async function _getLinuxBinaryPathForPid(pid: number): Promise { +async function _getLinuxBinaryPathForPid(pid) { const exeLink = `/proc/${pid}/exe`; // /proc/xxx/exe is a symlink to the real binary in the file system. - return runCommand('/bin/realpath', ['-q', '-e', exeLink]) - .catch(_ => Observable.of(null)) - .toPromise(); + return runCommand('/bin/realpath', ['-q', '-e', exeLink]).catch(_ => _rxjsBundlesRxMinJs.Observable.of(null)).toPromise(); } -async function _getDarwinBinaryPathForPid(pid: number): Promise { - return runCommand('/usr/sbin/lsof', ['-p', `${pid}`]) - .catch(_ => { - return Observable.of(null); - }) - .map( - stdout => - stdout == null - ? null - : stdout - .split('\n') - .map(line => line.trim().split(/\s+/)) - .filter(line => line[3] === 'txt') - .map(line => line[8])[0], - ) - .take(1) - .toPromise(); +async function _getDarwinBinaryPathForPid(pid) { + return runCommand('/usr/sbin/lsof', ['-p', `${pid}`]).catch(_ => { + return _rxjsBundlesRxMinJs.Observable.of(null); + }).map(stdout => stdout == null ? null : stdout.split('\n').map(line => line.trim().split(/\s+/)).filter(line => line[3] === 'txt').map(line => line[8])[0]).take(1).toPromise(); } /** @@ -963,154 +776,101 @@ async function _getDarwinBinaryPathForPid(pid: number): Promise { * * 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 { +function createProcessStream(type = 'spawn', commandOrModulePath, args = [], options = {}) { const inputOption = options.input; let input; if (inputOption != null) { - input = - typeof inputOption === 'string' - ? Observable.of(inputOption) - : inputOption; + input = typeof inputOption === 'string' ? _rxjsBundlesRxMinJs.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 && NUCLIDE_DO_NOT_LOG !== 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(); - } + 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 && NUCLIDE_DO_NOT_LOG !== 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( - 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(() => { - // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - if (!proc.wasKilled && !finished) { - killProcess(proc, Boolean(killTreeWhenDone)); - } - }); + 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(() => { + // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) + if (!proc.wasKilled && !finished) { + killProcess(proc, Boolean(killTreeWhenDone)); + } }); + }); } -function isRealExit(event: {exitCode: ?number, signal: ?string}): boolean { +function isRealExit(event) { // 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 { +async function _killProcess(proc, killTree) { proc.wasKilled = true; if (!killTree) { proc.kill(); @@ -1123,9 +883,9 @@ async function _killProcess( } } -function killWindowsProcessTree(pid: number): Promise { +function killWindowsProcessTree(pid) { return new Promise((resolve, reject) => { - child_process.exec(`taskkill /pid ${pid} /T /F`, error => { + _child_process.default.exec(`taskkill /pid ${pid} /T /F`, error => { if (error == null) { reject(error); } else { @@ -1135,9 +895,7 @@ function killWindowsProcessTree(pid: number): Promise { }); } -export async function killUnixProcessTree( - proc: child_process$ChildProcess, -): Promise { +async function killUnixProcessTree(proc) { const descendants = await getDescendantsOfProcess(proc.pid); // Kill the processes, starting with those of greatest depth. for (const info of descendants.reverse()) { @@ -1145,23 +903,20 @@ export async function killUnixProcessTree( } } -function isExitErrorDefault(exit: ProcessExitMessage): boolean { +function isExitErrorDefault(exit) { return exit.exitCode !== 0; } -function isWindowsPlatform(): boolean { - return /^win/.test(process.platform); +function isWindowsPlatform() { + return (/^win/.test(process.platform) + ); } -function limitBufferSize( - stream: Observable, - maxBuffer: ?number, - streamName: string, -): Observable { +function limitBufferSize(stream, maxBuffer, streamName) { if (maxBuffer == null) { return stream; } - return Observable.defer(() => { + return _rxjsBundlesRxMinJs.Observable.defer(() => { let totalSize = 0; return stream.do(data => { totalSize += data.length; @@ -1176,20 +931,7 @@ function limitBufferSize( * 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]), - ), - ); -} +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 264e63ce53..744ecf4907 100644 --- a/modules/nuclide-commons/promise.js +++ b/modules/nuclide-commons/promise.js @@ -1,25 +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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.sleep = sleep; +exports.nextTick = nextTick; +exports.triggerAfterWait = triggerAfterWait; +exports.timeoutPromise = timeoutPromise; +exports.createDeadline = createDeadline; +exports.timeoutAfterDeadline = timeoutAfterDeadline; +exports.retryLimit = retryLimit; +exports.serializeAsyncCall = serializeAsyncCall; +exports.asyncFind = asyncFind; +exports.denodeify = denodeify; +exports.asyncLimit = asyncLimit; +exports.asyncFilter = asyncFilter; +exports.asyncObjFilter = asyncObjFilter; +exports.asyncSome = asyncSome; +exports.isPromise = isPromise; +exports.lastly = lastly; +exports.delayTime = delayTime; -import invariant from 'assert'; - -type RunReturn = - | { - status: 'success', - result: T, - } - | { - status: 'outdated', - }; /** * Allows a caller to ensure that the results it receives from consecutive @@ -46,11 +47,7 @@ type RunReturn = * 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; +class RequestSerializer { constructor() { this._lastDispatchedOp = 0; @@ -60,7 +57,7 @@ export class RequestSerializer { }); } - async run(promise: Promise): Promise> { + async run(promise) { const thisOp = this._lastDispatchedOp + 1; this._lastDispatchedOp = thisOp; this._latestPromise = promise; @@ -70,11 +67,11 @@ export class RequestSerializer { this._lastFinishedOp = thisOp; return { status: 'success', - result, + result }; } else { return { - status: 'outdated', + status: 'outdated' }; } } @@ -83,9 +80,9 @@ export class RequestSerializer { * Returns a Promise that resolves to the last result of `run`, * as soon as there are no more outstanding `run` calls. */ - async waitForLatestResult(): Promise { + async waitForLatestResult() { let lastPromise = null; - let result: any = null; + let result = null; while (lastPromise !== this._latestPromise) { lastPromise = this._latestPromise; // Wait for the current last know promise to resolve, or a next run have started. @@ -95,26 +92,38 @@ export class RequestSerializer { this._latestPromise.then(resolve); }); } - return (result: T); + return result; } - isRunInProgress(): boolean { + isRunInProgress() { 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. +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. + */ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 function sleep(milliSeconds: number): Promise { + +function sleep(milliSeconds) { return new Promise(resolve => { setTimeout(resolve, milliSeconds); }); } -export function nextTick(): Promise { +function nextTick() { return new Promise(resolve => { process.nextTick(resolve); }); @@ -131,12 +140,7 @@ export function nextTick(): Promise { * `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 { +async function triggerAfterWait(promise, milliSeconds, timeoutFn, cleanupFn) { const timeout = setTimeout(timeoutFn, milliSeconds); try { return await promise; @@ -151,22 +155,19 @@ export async function triggerAfterWait( /** * Thrown by `timeoutPromise` if the timer fires before the promise resolves/rejects. */ -export class TimedOutError extends Error { - timeout: number; - constructor(milliseconds: number) { +class TimedOutError extends Error { + constructor(milliseconds) { 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 { +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; @@ -175,19 +176,17 @@ export function timeoutPromise( // 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); - }); + promise.then(value => { + if (timeout != null) { + clearTimeout(timeout); + } + resolve(value); + }).catch(value => { + if (timeout != null) { + clearTimeout(timeout); + } + reject(value); + }); }); } @@ -207,16 +206,11 @@ export function timeoutPromise( // "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 { +function createDeadline(delay) { return Date.now() + delay; } -export function timeoutAfterDeadline( - deadline: DeadlineRequest, - promise: Promise, -): Promise { +function timeoutAfterDeadline(deadline, promise) { const delay = deadline - Date.now(); return timeoutPromise(promise, delay < 0 ? 0 : delay); } @@ -235,12 +229,7 @@ export function timeoutAfterDeadline( * 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 { +async function retryLimit(retryFunction, validationFunction, maximumTries, retryIntervalMs = 0) { let result = null; let tries = 0; let lastError = null; @@ -267,7 +256,7 @@ export async function retryLimit( } else if (tries === maximumTries) { throw new Error('No valid response found!'); } else { - return ((result: any): T); + return result; } } @@ -291,17 +280,12 @@ export async function retryLimit( * const result3Promise = oneExecAtATime(); // Reuse scheduled promise and resolve to 2 in 400 ms. * ``` */ -export function serializeAsyncCall( - asyncFun: () => Promise, -): () => Promise { +function serializeAsyncCall(asyncFun) { let scheduledCall = null; let pendingCall = null; const startAsyncCall = () => { const resultPromise = asyncFun(); - pendingCall = resultPromise.then( - () => (pendingCall = null), - () => (pendingCall = null), - ); + pendingCall = resultPromise.then(() => pendingCall = null, () => pendingCall = null); return resultPromise; }; const callNext = () => { @@ -310,7 +294,10 @@ export function serializeAsyncCall( }; const scheduleNextCall = () => { if (scheduledCall == null) { - invariant(pendingCall, 'pendingCall must not be null!'); + if (!pendingCall) { + throw new Error('pendingCall must not be null!'); + } + scheduledCall = pendingCall.then(callNext, callNext); } return scheduledCall; @@ -331,10 +318,7 @@ export function serializeAsyncCall( * 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; +class Deferred { constructor() { this.promise = new Promise((resolve, reject) => { @@ -344,29 +328,26 @@ export class 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. - */ -export function asyncFind( - items_: Array, - test: (t: T) => ?Promise, - thisArg?: mixed, -): Promise { +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 @@ -374,7 +355,7 @@ export function asyncFind( items = items.slice(); const numItems = items.length; - const next = async function(index) { + const next = async function (index) { if (index === numItems) { resolve(null); return; @@ -393,10 +374,8 @@ export function asyncFind( }); } -export function denodeify( - f: (...args: Array) => any, -): (...args: Array) => Promise { - return function(...args: Array) { +function denodeify(f) { + return function (...args) { return new Promise((resolve, reject) => { function callback(error, result) { if (error) { @@ -426,12 +405,8 @@ export function denodeify( * @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); +function asyncLimit(array, limit, mappingFunction) { + const result = new Array(array.length); let parallelPromises = 0; let index = 0; @@ -483,14 +458,10 @@ export function asyncLimit( * boolean. * @param limit the configurable number of parallel async operations. */ -export async function asyncFilter( - array: Array, - filterFunction: (item: T) => Promise, - limit?: number, -): Promise> { +async function asyncFilter(array, filterFunction, limit) { const filteredList = []; // flowlint-next-line sketchy-null-number:off - await asyncLimit(array, limit || array.length, async (item: T) => { + await asyncLimit(array, limit || array.length, async item => { if (await filterFunction(item)) { filteredList.push(item); } @@ -498,15 +469,11 @@ export async function asyncFilter( return filteredList; } -export async function asyncObjFilter( - obj: {[key: string]: T}, - filterFunction: (item: T, key: string) => Promise, - limit?: number, -): Promise<{[key: string]: T}> { +async function asyncObjFilter(obj, filterFunction, limit) { const keys = Object.keys(obj); const filteredObj = {}; // flowlint-next-line sketchy-null-number:off - await asyncLimit(keys, limit || keys.length, async (key: string) => { + await asyncLimit(keys, limit || keys.length, async key => { const item = obj[key]; if (await filterFunction(item, key)) { filteredObj[key] = item; @@ -536,14 +503,10 @@ export async function asyncObjFilter( * boolean. * @param limit the configurable number of parallel async operations. */ -export async function asyncSome( - array: Array, - someFunction: (item: T) => Promise, - limit?: number, -): Promise { +async function asyncSome(array, someFunction, limit) { let resolved = false; // flowlint-next-line sketchy-null-number:off - await asyncLimit(array, limit || array.length, async (item: T) => { + await asyncLimit(array, limit || array.length, async item => { if (resolved) { // We don't need to call the someFunction anymore or wait any longer. return; @@ -558,30 +521,20 @@ export async function asyncSome( /** * 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' - ); +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. */ -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)); - }, - ); +function lastly(promise, fn) { + return promise.then(ret => { + return Promise.resolve(fn()).then(() => ret); + }, err => { + return Promise.resolve(fn()).then(() => Promise.reject(err)); + }); } /** @@ -589,40 +542,31 @@ export function lastly( * 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; - }, - ); +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(): Promise { + getPromise() { return this._promise; } - getState(): PromiseState { + getState() { return this._state; } } -export function delayTime(ms: number): Promise { +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 c166286ffb..d526b8999b 100644 --- a/modules/nuclide-commons/range.js +++ b/modules/nuclide-commons/range.js @@ -1,3 +1,11 @@ +"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. @@ -6,25 +14,18 @@ * LICENSE file in 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 strict + * strict * @format */ -export function wordAtPositionFromBuffer( - buffer: atom$TextBuffer | simpleTextBuffer$TextBuffer, - position: atom$PointObject, - wordRegex: RegExp, -): ?{wordMatch: Array, range: atom$Range} { - const {row, column} = position; +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) - ) { + const { range } = data; + if (range.start.isLessThanOrEqual(position) && range.end.isGreaterThan(position)) { matchData = data; } // Stop the scan if the scanner has passed our position. @@ -35,7 +36,7 @@ export function wordAtPositionFromBuffer( if (matchData) { return { wordMatch: matchData.match, - range: matchData.range, + range: matchData.range }; } else { return null; @@ -45,21 +46,12 @@ export function wordAtPositionFromBuffer( // 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 { +function matchRegexEndingAt(buffer, endPosition, regex) { 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 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 0d3211667e..385493ce26 100644 --- a/modules/nuclide-commons/redux-observable.js +++ b/modules/nuclide-commons/redux-observable.js @@ -1,14 +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 - */ +'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: @@ -35,46 +55,15 @@ // 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(); +function createEpicMiddleware(rootEpic) { + const actions = new _rxjsBundlesRxMinJs.Subject(); const actionsObs = new ActionsObservable(actions); - return (store: Store) => (next: Next) => { + return store => next => { if (rootEpic != null) { rootEpic(actionsObs, store).subscribe(store.dispatch); } - return (action: T) => { + return action => { const result = next(action); actions.next(action); return result; @@ -82,22 +71,21 @@ export function createEpicMiddleware( }; } -export class ActionsObservable extends Observable { - operator: any; +class ActionsObservable extends _rxjsBundlesRxMinJs.Observable { - constructor(actionsSubject: Observable) { + constructor(actionsSubject) { super(); this.source = actionsSubject; } - lift(operator: any): Observable { + lift(operator) { const observable = new ActionsObservable(this); observable.operator = operator; return observable; } - ofType(...keys: Array): ActionsObservable { - const result = this.filter(({type}) => { + ofType(...keys) { + const result = this.filter(({ type }) => { const len = keys.length; if (len === 1) { return type === keys[0]; @@ -110,6 +98,7 @@ 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/serverPort.js b/modules/nuclide-commons/serverPort.js index 2f056ccc52..9841a17c35 100644 --- a/modules/nuclide-commons/serverPort.js +++ b/modules/nuclide-commons/serverPort.js @@ -1,27 +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 strict - * @format - */ +'use strict'; -import net from 'net'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getAvailableServerPort = getAvailableServerPort; -export async function getAvailableServerPort(): Promise { +var _net = _interopRequireDefault(require('net')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +async function getAvailableServerPort() { return new Promise((resolve, reject) => { - const server = net.createServer(); + const server = _net.default.createServer(); server.unref(); server.on('error', reject); - server.listen({port: 0}, () => { + server.listen({ port: 0 }, () => { const port = server.address().port; server.close(() => { resolve(port); }); }); }); -} +} /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/spec/fixtures/ConfigCache/testFolder/.test_nuclide_config_file b/modules/nuclide-commons/spec/fixtures/ConfigCache/testFolder/.test_nuclide_config_file deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/modules/nuclide-commons/stream.js b/modules/nuclide-commons/stream.js index 984a021d8e..efc929a988 100644 --- a/modules/nuclide-commons/stream.js +++ b/modules/nuclide-commons/stream.js @@ -1,3 +1,33 @@ +'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. @@ -6,69 +36,47 @@ * LICENSE file in 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 strict-local + * strict-local * @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 { +function observeStream(stream) { 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')); +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. */ -export function writeToStream( - source: Observable, - destStream: stream$Writable, -): Observable { - return Observable.create(observer => { +function writeToStream(source, destStream) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { let byteCount = 0; - const byteCounterStream = new Stream.Transform({ + 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( - attachEvent(destStream, 'error', err => { - observer.error(err); - }), - attachEvent(destStream, 'close', () => { - observer.complete(); - }), - source.subscribe( - buffer => { - byteCounterStream.write(buffer); - }, - err => { - observer.error(err); - }, - () => { - byteCounterStream.end(); - }, - ), - ); + 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 dd6afd7346..6797b6cfe4 100644 --- a/modules/nuclide-commons/string.js +++ b/modules/nuclide-commons/string.js @@ -1,3 +1,31 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ZERO_WIDTH_SPACE = 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. @@ -6,22 +34,17 @@ * LICENSE file in 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 - }.`; +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 { +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. @@ -40,43 +63,11 @@ 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 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], -]; +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 { +function relativeDate(input_, reference_, useShortVariant = false) { let input = input_; let reference = reference_; if (input instanceof Date) { @@ -95,11 +86,7 @@ export function relativeDate( for (const [limit, relativeFormat, remainder] of formats) { if (delta < limit) { if (typeof remainder === 'number') { - return ( - Math.round(delta / remainder) + - (useShortVariant ? '' : ' ') + - relativeFormat - ); + return Math.round(delta / remainder) + (useShortVariant ? '' : ' ') + relativeFormat; } else { return relativeFormat; } @@ -113,8 +100,10 @@ export function relativeDate( * 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'); +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); @@ -130,18 +119,14 @@ export function countOccurrences(haystack: string, char: string) { * 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); +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`, - ); + throw new Error(`Unexpected operator "${result[i].op}" provided to shellParse`); } else { - throw new Error( - `Unexpected comment "${result[i].comment}" provided to shellParse`, - ); + throw new Error(`Unexpected comment "${result[i].comment}" provided to shellParse`); } } } @@ -152,11 +137,11 @@ export function shellParse(str: string, env?: Object): Array { * 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); +function shellQuote(args) { + return (0, (_shellQuote || _load_shellQuote()).quote)(args); } -export function removeCommonPrefix(a: string, b: string): [string, string] { +function removeCommonPrefix(a, b) { let i = 0; while (a[i] === b[i] && i < a.length && i < b.length) { i++; @@ -164,73 +149,47 @@ export function removeCommonPrefix(a: string, b: string): [string, string] { return [a.substring(i), b.substring(i)]; } -export function removeCommonSuffix(a: string, b: string): [string, string] { +function removeCommonSuffix(a, b) { let i = 0; - while ( - a[a.length - 1 - i] === b[b.length - 1 - i] && - i < a.length && - i < b.length - ) { + 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 || ''); +function shorten(str, maxLength, suffix) { + 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] { +function splitOnce(str, separator) { const index = str.indexOf(separator); - return index === -1 - ? [str, null] - : [str.slice(0, index), str.slice(index + separator.length)]; + 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 { +function indent(str, level = 2, char = ' ') { return str.replace(/^([^\n])/gm, char.repeat(level) + '$1'); } -export function pluralize(noun: string, count: number) { +function pluralize(noun, count) { 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)); +function capitalize(str) { + 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 { +function getMatchRanges(haystack, needle) { if (needle === '') { // Not really a valid use. return []; @@ -250,7 +209,7 @@ export function getMatchRanges( return ranges; } -export function escapeMarkdown(markdown: string): string { +function escapeMarkdown(markdown) { // _ * # () [] need to be slash escaped. const slashEscaped = markdown.replace(/[_*#/()[\]]/g, '\\$&'); // And HTML tags need to be < > escaped. @@ -264,7 +223,7 @@ export function escapeMarkdown(markdown: string): string { // 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@:%+.~#?&/=!]*)/; +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@:%+.~#?&/=!]*)/; -export const ELLIPSIS_CHAR = '\u2026'; -export const ZERO_WIDTH_SPACE = '\u200B'; +const ELLIPSIS_CHAR = exports.ELLIPSIS_CHAR = '\u2026'; +const ZERO_WIDTH_SPACE = exports.ZERO_WIDTH_SPACE = '\u200B'; \ 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 9371c3cf47..197b23a5d3 100644 --- a/modules/nuclide-commons/symbol-definition-preview.js +++ b/modules/nuclide-commons/symbol-definition-preview.js @@ -1,53 +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 - */ - -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; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getDefinitionPreview = getDefinitionPreview; + +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: string) { +function getIndentLevel(line) { return WHITESPACE_REGEX.exec(line)[0].length; } -export async function getDefinitionPreview( - definition: Definition, -): Promise { +async function getDefinitionPreview(definition) { // ensure filesize not too big before reading in whole file - const stats = await fsPromise.stat(definition.path); + const stats = await (_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 = await fsPromise.readFile(definition.path); + const fileBuffer = await (_fsPromise || _load_fsPromise()).default.readFile(definition.path); - const mime = - mimeTypes.contentType(nuclideUri.extname(definition.path)) || 'text/plain'; + 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'}; + return { mime, contents: fileBuffer.toString('base64'), encoding: 'base64' }; } const contents = fileBuffer.toString('utf8'); @@ -57,21 +71,13 @@ export async function getDefinitionPreview( const initialIndentLevel = getIndentLevel(lines[start]); const buffer = []; - for ( - let i = start, - openParenCount = 0, - closedParenCount = 0, - openCurlyCount = 0, - closedCurlyCount = 0; - i < start + MAX_PREVIEW_LINES && i < lines.length; - i++ - ) { + for (let i = start, 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, '}'); + 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 @@ -85,17 +91,16 @@ export async function getDefinitionPreview( // 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 - ) { + // 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; } } } - return {mime, contents: buffer.join('\n'), encoding: 'utf8'}; -} + return { mime, contents: buffer.join('\n'), encoding: 'utf8' }; +} \ No newline at end of file diff --git a/modules/nuclide-commons/test-helpers.js b/modules/nuclide-commons/test-helpers.js index 6136555d1e..f2798ffd4b 100644 --- a/modules/nuclide-commons/test-helpers.js +++ b/modules/nuclide-commons/test-helpers.js @@ -1,3 +1,51 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.expectAsyncFailure = expectAsyncFailure; +exports.clearRequireCache = clearRequireCache; +exports.uncachedRequire = uncachedRequire; +exports.spyOnGetterValue = spyOnGetterValue; +exports.arePropertiesEqual = arePropertiesEqual; +exports.expectObservableToStartWith = expectObservableToStartWith; +exports.generateFixture = generateFixture; +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. @@ -6,25 +54,13 @@ * LICENSE file in 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', -); +if (!(typeof atom !== 'undefined' && atom.inSpecMode() || process.env.NODE_ENV === 'test')) { + throw new Error('Test helpers should only be used in spec mode'); +} /** * Verifies that a Promise fails with an Error with specific expectations. When @@ -39,15 +75,12 @@ invariant( * 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 { + + +async function expectAsyncFailure(promise, verify) { try { await promise; - return Promise.reject( - new Error('Promise should have failed, but did not.'), - ); + return Promise.reject(new Error('Promise should have failed, but did not.')); } catch (e) { verify(e); } @@ -62,11 +95,11 @@ export async function expectAsyncFailure( * 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 { +function clearRequireCache(require, module) { delete require.cache[require.resolve(module)]; } -export function uncachedRequire(require: Object, module: string): mixed { +function uncachedRequire(require, module) { clearRequireCache(require, module); // $FlowIgnore return require(module); @@ -83,7 +116,7 @@ export function uncachedRequire(require: Object, module: string): mixed { * - The getter returns a function (otherwise, it doesn't make sense to spy on * it) */ -export function spyOnGetterValue(object: Object, f: string): JasmineSpy { +function spyOnGetterValue(object, f) { const value = object[f]; delete object[f]; object[f] = value; @@ -94,7 +127,7 @@ export function spyOnGetterValue(object: Object, f: string): JasmineSpy { * 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 { +function arePropertiesEqual(obj1, obj2) { const allProps = new Set(); function addAllProps(obj) { for (const prop of Object.keys(obj)) { @@ -114,14 +147,8 @@ export function arePropertiesEqual(obj1: Object, obj2: Object): boolean { * 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(); +async function expectObservableToStartWith(source, expected) { + const actual = await source.take(expected.length).toArray().toPromise(); expect(actual).toEqual(expected); } @@ -139,14 +166,11 @@ export async function expectObservableToStartWith( * /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(); +async function generateFixture(fixtureName, files) { + (_temp || _load_temp()).default.track(); const MAX_CONCURRENT_FILE_OPS = 100; - const tempDir = await fsPromise.tempdir(fixtureName); + const tempDir = await (_fsPromise || _load_fsPromise()).default.tempdir(fixtureName); if (files == null) { return tempDir; @@ -155,51 +179,40 @@ export async function generateFixture( // 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]); + 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); - - await asyncLimit(dirsToMake, MAX_CONCURRENT_FILE_OPS, dirname => - fsPromise.mkdirp(dirname), - ); - - await asyncLimit( - fileTuples, - MAX_CONCURRENT_FILE_OPS, - ([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 => { - if (err) { - reject(err); - } else { - resolve(); - } - }); + const dirsToMake = fileTuples.map(([filename]) => (_nuclideUri || _load_nuclideUri()).default.dirname(filename)).filter((dirname, i, arr) => arr.indexOf(dirname) === i); + + await (0, (_promise || _load_promise()).asyncLimit)(dirsToMake, MAX_CONCURRENT_FILE_OPS, dirname => (_fsPromise || _load_fsPromise()).default.mkdirp(dirname)); + + await (0, (_promise || _load_promise()).asyncLimit)(fileTuples, MAX_CONCURRENT_FILE_OPS, ([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.default.writeFile(filename, contents || '', err => { + if (err) { + reject(err); + } else { + resolve(); + } }); - }, - ); + }); + }); return tempDir; } -export function writeCoverage(): void { - const {COVERAGE_DIR} = process.env; +function writeCoverage() { + 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), - ); + _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 b4c2c54b11..e2cd69acf4 100644 --- a/modules/nuclide-commons/tokenized-text.js +++ b/modules/nuclide-commons/tokenized-text.js @@ -1,69 +1,63 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict - * @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 { +'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); -} - -export function className(value: string): TextToken { +} /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict + * @format + */ + +function className(value) { return _buildToken('class-name', value); } -export function constructor(value: string): TextToken { +function constructor(value) { return _buildToken('constructor', value); } -export function method(value: string): TextToken { +function method(value) { return _buildToken('method', value); } -export function param(value: string): TextToken { +function param(value) { return _buildToken('param', value); } -export function string(value: string): TextToken { +function string(value) { return _buildToken('string', value); } -export function whitespace(value: string): TextToken { +function whitespace(value) { return _buildToken('whitespace', value); } -export function plain(value: string): TextToken { +function plain(value) { return _buildToken('plain', value); } -export function type(value: string): TextToken { +function type(value) { return _buildToken('type', value); } -function _buildToken(kind: TokenKind, value: string): TextToken { - return {kind, 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 ece177dd7d..55e0ea7d32 100644 --- a/modules/nuclide-commons/which.js +++ b/modules/nuclide-commons/which.js @@ -1,19 +1,24 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _os = _interopRequireDefault(require('os')); -import os from 'os'; -import nuclideUri from './nuclideUri'; +var _nuclideUri; -import {runCommand} from './process'; +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. @@ -22,23 +27,33 @@ import {runCommand} from './process'; * remember) so we can use this for now. */ -function sanitizePathForWindows(path: string): string { - if (nuclideUri.basename(path) === path) { +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)}`; + 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. + * + * strict-local + * @format + */ -export default (async function which(path: string): Promise { +exports.default = async function which(path) { 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]; + const result = await (0, (_process || _load_process()).runCommand)(whichCommand, [searchPath]).toPromise(); + return result.split(_os.default.EOL)[0]; } catch (e) { return null; } -}); +}; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/BackTraceCommand.js b/modules/nuclide-debugger-cli/lib/BackTraceCommand.js index b477eb87c1..bb59a360f6 100644 --- a/modules/nuclide-debugger-cli/lib/BackTraceCommand.js +++ b/modules/nuclide-debugger-cli/lib/BackTraceCommand.js @@ -1,28 +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 strict-local - * @format - */ - -import * as DebugProtocol from 'vscode-debugprotocol'; -import type {Command} from './Command'; -import type {ConsoleIO} from './ConsoleIO'; -import type {DebuggerInterface} from './DebuggerInterface'; - -import idx from 'idx'; -import Thread from './Thread'; - -export default class BackTraceCommand implements Command { - name = 'backtrace'; - helpText = - '[frame] Displays the call stack of the active thread. With optional frame index, sets the current frame for variable display.'; - detailedHelpText = ` +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _vscodeDebugprotocol; + +function _load_vscodeDebugprotocol() { + return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol')); +} + +var _idx; + +function _load_idx() { + return _idx = _interopRequireDefault(require('idx')); +} + +var _Thread; + +function _load_Thread() { + return _Thread = _interopRequireDefault(require('./Thread')); +} + +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 BackTraceCommand { + + constructor(con, debug) { + this.name = 'backtrace'; + this.helpText = '[frame] Displays the call stack of the active thread. With optional frame index, sets the current frame for variable display.'; + this.detailedHelpText = ` backtrace [frame] With no arguments, displays the call stack, showing the most recent stack frame @@ -42,23 +51,15 @@ which query program state will use the selected frame for context; for example: in scope in the selected frame. `; - _console: ConsoleIO; - _debugger: DebuggerInterface; - - static _defaultFrames: number = 100; - - constructor(con: ConsoleIO, debug: DebuggerInterface) { this._console = con; this._debugger = debug; } - async execute(args: string[]): Promise { + async execute(args) { const activeThread = this._debugger.getActiveThread(); if (args.length > 1) { - throw new Error( - "'backtrace' takes at most one argument -- the index of the frame to select", - ); + throw new Error("'backtrace' takes at most one argument -- the index of the frame to select"); } const frameArg = args[0]; @@ -67,17 +68,11 @@ which query program state will use the selected frame for context; for example: return; } - const frames = await this._debugger.getStackTrace( - activeThread.id(), - BackTraceCommand._defaultFrames, - ); + const frames = await this._debugger.getStackTrace(activeThread.id(), BackTraceCommand._defaultFrames); this._printFrames(frames, activeThread.selectedStackFrame()); } - async _setSelectedStackFrame( - thread: Thread, - frameArg: string, - ): Promise { + async _setSelectedStackFrame(thread, frameArg) { if (frameArg.match(/^\d+$/) == null) { throw new Error('Argument must be a numeric frame index.'); } @@ -86,17 +81,27 @@ which query program state will use the selected frame for context; for example: await this._debugger.setSelectedStackFrame(thread, newSelectedFrame); } - _printFrames( - frames: DebugProtocol.StackFrame[], - selectedFrame: number, - ): void { + _printFrames(frames, selectedFrame) { frames.forEach((frame, index) => { + var _ref, _ref2; + const selectedMarker = index === selectedFrame ? '*' : ' '; - const path = idx(frame, _ => _.source.path) || null; + const path = ((_ref = frame) != null ? (_ref2 = _ref.source) != null ? _ref2.path : _ref2 : _ref) || null; const location = path != null ? `${path}:${frame.line}` : '[no source]'; - this._console.outputLine( - `${selectedMarker} #${index} ${frame.name} ${location}`, - ); + this._console.outputLine(`${selectedMarker} #${index} ${frame.name} ${location}`); }); } } +exports.default = BackTraceCommand; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ + +BackTraceCommand._defaultFrames = 100; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/Breakpoint.js b/modules/nuclide-debugger-cli/lib/Breakpoint.js index 0e09f6f2e2..1490017557 100644 --- a/modules/nuclide-debugger-cli/lib/Breakpoint.js +++ b/modules/nuclide-debugger-cli/lib/Breakpoint.js @@ -1,102 +1,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. - * - * @flow - * @format - */ - -import nullthrows from 'nullthrows'; - -export default class Breakpoint { - // index is the name of the breakpoint we show externally in the UI - _index: number; +'use strict'; - // id is the attached breakpoint in the adapter (if the adapter supports it) - _id: ?number; +Object.defineProperty(exports, "__esModule", { + value: true +}); - // verified tracks if the breakpoint was successfully set by the adapter. - // it may not be if the referenced code was not yet loaded - _verified: boolean; +var _nullthrows; - // enabled tracks if the breakpoint has been enabled or disabled by the user. - _enabled: boolean; +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} - // The source file of the breakpoint (which may be undefined if we have an - // unresolved function breakpoint.) - _path: ?string; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Breakpoint { // The line number of the breakpoint (which may be undefined if we have an // unresolved function breakpoint.) - _line: ?number; - // The function name of the breakpoint (only defined if the breakpoint is - // a function breakpoint.) - _func: ?string; - constructor(index: number) { + // enabled tracks if the breakpoint has been enabled or disabled by the user. + + + // id is the attached breakpoint in the adapter (if the adapter supports it) + constructor(index) { this._index = index; this._verified = false; this._enabled = true; } - get index(): number { + // The function name of the breakpoint (only defined if the breakpoint is + // a function breakpoint.) + + + // The source file of the breakpoint (which may be undefined if we have an + // unresolved function breakpoint.) + + + // verified tracks if the breakpoint was successfully set by the adapter. + // it may not be if the referenced code was not yet loaded + + // index is the name of the breakpoint we show externally in the UI + + + get index() { return this._index; } - get id(): ?number { + get id() { return this._id; } - setId(id: number): void { + setId(id) { this._id = id; } - setVerified(verified: boolean): void { + setVerified(verified) { this._verified = verified; } - get verified(): boolean { + get verified() { return this._verified; } - setEnabled(enabled: boolean): void { + setEnabled(enabled) { this._enabled = enabled; } - get enabled(): boolean { + get enabled() { return this._enabled; } - setPath(path: string) { + setPath(path) { this._path = path; } - get path(): ?string { + get path() { return this._path; } - setLine(line: number) { + setLine(line) { this._line = line; } - get line(): ?number { + get line() { return this._line; } - setFunc(func: string) { + setFunc(func) { this._func = func; } - get func(): ?string { + get func() { return this._func; } - toString(): string { + toString() { const func = this._func; if (func != null) { @@ -106,6 +104,17 @@ export default class Breakpoint { return `${func}() [${this._path}:${this._line}]`; } - return `${nullthrows(this._path)}:${nullthrows(this._line)}`; + return `${(0, (_nullthrows || _load_nullthrows()).default)(this._path)}:${(0, (_nullthrows || _load_nullthrows()).default)(this._line)}`; } } +exports.default = Breakpoint; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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-cli/lib/BreakpointCollection.js b/modules/nuclide-debugger-cli/lib/BreakpointCollection.js index 2d887958ee..6e2dbfbc4b 100644 --- a/modules/nuclide-debugger-cli/lib/BreakpointCollection.js +++ b/modules/nuclide-debugger-cli/lib/BreakpointCollection.js @@ -1,44 +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 strict-local - * @format - */ - -import {arrayCompact} from 'nuclide-commons/collection'; - -import Breakpoint from './Breakpoint'; -import nullthrows from 'nullthrows'; - -export type SourceBreakpoint = { - index: number, - id: ?number, - verified: boolean, - enabled: boolean, - path: string, - line: number, -}; - -export type FunctionBreakpoint = { - index: number, - id: ?number, - verified: boolean, - enabled: boolean, - path: ?string, - line: ?number, - func: string, -}; - -export default class BreakpointCollection { - _breakpoints: Map = new Map(); - _nextIndex: number = 1; - - addSourceBreakpoint(path: string, line: number): number { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _collection; + +function _load_collection() { + return _collection = require('../../nuclide-commons/collection'); +} + +var _Breakpoint; + +function _load_Breakpoint() { + return _Breakpoint = _interopRequireDefault(require('./Breakpoint')); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class BreakpointCollection { + constructor() { + this._breakpoints = new Map(); + this._nextIndex = 1; + } + + addSourceBreakpoint(path, line) { this._breakpoints.forEach((breakpoint, index) => { if (breakpoint.path === path && breakpoint.line === line) { throw new Error(`There is already a breakpoint (#${index}) here.`); @@ -46,7 +38,7 @@ export default class BreakpointCollection { }); const index = this._allocateIndex(); - const breakpoint = new Breakpoint(index); + const breakpoint = new (_Breakpoint || _load_Breakpoint()).default(index); breakpoint.setPath(path); breakpoint.setLine(line); @@ -54,7 +46,7 @@ export default class BreakpointCollection { return index; } - addFunctionBreakpoint(func: string): number { + addFunctionBreakpoint(func) { this._breakpoints.forEach((breakpoint, index) => { if (breakpoint.func === func) { throw new Error(`There is already a breakpoint (#${index}) here.`); @@ -62,54 +54,41 @@ export default class BreakpointCollection { }); const index = this._allocateIndex(); - const breakpoint = new Breakpoint(index); + const breakpoint = new (_Breakpoint || _load_Breakpoint()).default(index); breakpoint.setFunc(func); this._breakpoints.set(index, breakpoint); return index; } - getAllEnabledBreakpointsForSource(path: string): Array { - return Array.from(this._breakpoints.values()) - .filter( - x => x.path === path && x.line != null && x.func == null && x.enabled, - ) - .map(_ => ({ - index: _.index, - id: _.id, - verified: _.verified, - enabled: _.enabled, - path: nullthrows(_.path), - line: nullthrows(_.line), - })); + getAllEnabledBreakpointsForSource(path) { + return Array.from(this._breakpoints.values()).filter(x => x.path === path && x.line != null && x.func == null && x.enabled).map(_ => ({ + index: _.index, + id: _.id, + verified: _.verified, + enabled: _.enabled, + path: (0, (_nullthrows || _load_nullthrows()).default)(_.path), + line: (0, (_nullthrows || _load_nullthrows()).default)(_.line) + })); } - getAllEnabledBreakpointsByPath(): Map> { - const sources = new Set( - arrayCompact(Array.from(this._breakpoints.values()).map(_ => _.path)), - ); - return new Map( - Array.from(sources).map(src => [ - src, - this.getAllEnabledBreakpointsForSource(src), - ]), - ); + getAllEnabledBreakpointsByPath() { + const sources = new Set((0, (_collection || _load_collection()).arrayCompact)(Array.from(this._breakpoints.values()).map(_ => _.path))); + return new Map(Array.from(sources).map(src => [src, this.getAllEnabledBreakpointsForSource(src)])); } - getAllEnabledFunctionBreakpoints(): Array { - return Array.from(this._breakpoints.values()) - .filter(x => x.func != null && x.enabled) - .map(x => ({ - index: x.index, - id: x.id, - verified: x.verified, - enabled: x.enabled, - path: x.path, - line: x.line, - func: nullthrows(x.func), - })); + getAllEnabledFunctionBreakpoints() { + return Array.from(this._breakpoints.values()).filter(x => x.func != null && x.enabled).map(x => ({ + index: x.index, + id: x.id, + verified: x.verified, + enabled: x.enabled, + path: x.path, + line: x.line, + func: (0, (_nullthrows || _load_nullthrows()).default)(x.func) + })); } - getBreakpointByIndex(index: number): Breakpoint { + getBreakpointByIndex(index) { const breakpoint = this._breakpoints.get(index); if (breakpoint == null) { @@ -119,10 +98,8 @@ export default class BreakpointCollection { return breakpoint; } - getBreakpointById(id: number): Breakpoint { - const breakpoint: ?Breakpoint = Array.from(this._breakpoints.values()).find( - _ => _.id === id, - ); + getBreakpointById(id) { + const breakpoint = Array.from(this._breakpoints.values()).find(_ => _.id === id); if (breakpoint == null) { throw new Error(`There is no breakpoint with id ${id}`); @@ -131,29 +108,29 @@ export default class BreakpointCollection { return breakpoint; } - getAllBreakpoints(): Breakpoint[] { + getAllBreakpoints() { return Array.from(this._breakpoints.values()); } - deleteBreakpoint(index: number): void { + deleteBreakpoint(index) { this._breakpoints.delete(index); } - setBreakpointId(index: number, id: number): void { + setBreakpointId(index, id) { const bpt = this._breakpoints.get(index); if (bpt != null) { bpt.setId(id); } } - setBreakpointVerified(index: number, verified: boolean): void { + setBreakpointVerified(index, verified) { const bpt = this._breakpoints.get(index); if (bpt != null) { bpt.setVerified(verified); } } - setPathAndFile(index: number, path: string, line: number): void { + setPathAndFile(index, path, line) { const bpt = this._breakpoints.get(index); if (bpt != null) { bpt.setPath(path); @@ -161,7 +138,18 @@ export default class BreakpointCollection { } } - _allocateIndex(): number { + _allocateIndex() { return this._nextIndex++; } } +exports.default = BreakpointCollection; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/BreakpointCommand.js b/modules/nuclide-debugger-cli/lib/BreakpointCommand.js index 18fdccfa26..1a726d4ea1 100644 --- a/modules/nuclide-debugger-cli/lib/BreakpointCommand.js +++ b/modules/nuclide-debugger-cli/lib/BreakpointCommand.js @@ -1,34 +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 strict-local - * @format - */ - -import type {Command} from './Command'; -import type {DebuggerInterface, BreakpointSetResult} from './DebuggerInterface'; -import type {ConsoleIO} from './ConsoleIO'; - -import BreakpointDeleteCommand from './BreakpointDeleteCommand'; -import BreakpointDisableCommand from './BreakpointDisableCommand'; -import BreakpointEnableCommand from './BreakpointEnableCommand'; -import BreakpointListCommand from './BreakpointListCommand'; -import CommandDispatcher from './CommandDispatcher'; -import HelpCommand from './HelpCommand'; - -export default class BreakpointCommand implements Command { - name = 'breakpoint'; +'use strict'; - // $TODO this will need more thorough help which will require extending the - // help system to support subcommands - helpText = 'Sets a breakpoint on the target.'; +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _BreakpointDeleteCommand; + +function _load_BreakpointDeleteCommand() { + return _BreakpointDeleteCommand = _interopRequireDefault(require('./BreakpointDeleteCommand')); +} + +var _BreakpointDisableCommand; + +function _load_BreakpointDisableCommand() { + return _BreakpointDisableCommand = _interopRequireDefault(require('./BreakpointDisableCommand')); +} + +var _BreakpointEnableCommand; + +function _load_BreakpointEnableCommand() { + return _BreakpointEnableCommand = _interopRequireDefault(require('./BreakpointEnableCommand')); +} + +var _BreakpointListCommand; + +function _load_BreakpointListCommand() { + return _BreakpointListCommand = _interopRequireDefault(require('./BreakpointListCommand')); +} - detailedHelpText = ` +var _CommandDispatcher; + +function _load_CommandDispatcher() { + return _CommandDispatcher = _interopRequireDefault(require('./CommandDispatcher')); +} + +var _HelpCommand; + +function _load_HelpCommand() { + return _HelpCommand = _interopRequireDefault(require('./HelpCommand')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class BreakpointCommand { + + constructor(con, debug) { + this.name = 'breakpoint'; + this.helpText = 'Sets a breakpoint on the target.'; + this.detailedHelpText = ` breakpoint [subcommand | [source-file:]line] | function-name() Sets a breakpoint, or operates on existing breakpoints. @@ -61,23 +80,22 @@ The breakpoint command has several subcommands: * 'list' will list all existing breakpoints `; - _debugger: DebuggerInterface; - _console: ConsoleIO; - _dispatcher: CommandDispatcher; - - constructor(con: ConsoleIO, debug: DebuggerInterface) { this._console = con; this._debugger = debug; - this._dispatcher = new CommandDispatcher(new Map()); + this._dispatcher = new (_CommandDispatcher || _load_CommandDispatcher()).default(new Map()); - this._dispatcher.registerCommand(new BreakpointDeleteCommand(debug)); - this._dispatcher.registerCommand(new BreakpointDisableCommand(debug)); - this._dispatcher.registerCommand(new BreakpointEnableCommand(debug)); - this._dispatcher.registerCommand(new BreakpointListCommand(con, debug)); - this._dispatcher.registerCommand(new HelpCommand(con, this._dispatcher)); + this._dispatcher.registerCommand(new (_BreakpointDeleteCommand || _load_BreakpointDeleteCommand()).default(debug)); + this._dispatcher.registerCommand(new (_BreakpointDisableCommand || _load_BreakpointDisableCommand()).default(debug)); + this._dispatcher.registerCommand(new (_BreakpointEnableCommand || _load_BreakpointEnableCommand()).default(debug)); + this._dispatcher.registerCommand(new (_BreakpointListCommand || _load_BreakpointListCommand()).default(con, debug)); + this._dispatcher.registerCommand(new (_HelpCommand || _load_HelpCommand()).default(con, this._dispatcher)); } - async execute(args: string[]): Promise { + // $TODO this will need more thorough help which will require extending the + // help system to support subcommands + + + async execute(args) { const result = await this._trySettingBreakpoint(args); if (result != null) { this._displayBreakpointResult(result); @@ -87,9 +105,7 @@ The breakpoint command has several subcommands: await this._dispatcher.executeTokenizedLine(args); } - async _trySettingBreakpoint( - args: Array, - ): Promise { + async _trySettingBreakpoint(args) { const breakpointSpec = args[0]; if (breakpointSpec == null) { return this._setBreakpointHere(); @@ -117,29 +133,35 @@ The breakpoint command has several subcommands: return null; } - _displayBreakpointResult(result: BreakpointSetResult): void { + _displayBreakpointResult(result) { this._console.outputLine(`Breakpoint ${result.index} set.`); if (result.message != null) { this._console.outputLine(result.message); } } - async _setBreakpointHere(line: ?number): Promise { + async _setBreakpointHere(line) { const frame = await this._debugger.getCurrentStackFrame(); if (frame == null) { throw new Error('Cannot set breakpoint here, no current stack frame.'); } if (frame.source == null || frame.source.path == null) { - throw new Error( - 'Cannot set breakpoint here, current stack frame has no source.', - ); + throw new Error('Cannot set breakpoint here, current stack frame has no source.'); } - const result = await this._debugger.setSourceBreakpoint( - frame.source.path, - line == null ? frame.line : line, - ); + const result = await this._debugger.setSourceBreakpoint(frame.source.path, line == null ? frame.line : line); return result; } } +exports.default = BreakpointCommand; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/BreakpointDeleteCommand.js b/modules/nuclide-debugger-cli/lib/BreakpointDeleteCommand.js index 1b70ece176..f5b9d23764 100644 --- a/modules/nuclide-debugger-cli/lib/BreakpointDeleteCommand.js +++ b/modules/nuclide-debugger-cli/lib/BreakpointDeleteCommand.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,30 +11,27 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type {Command} from './Command'; -import type {DebuggerInterface} from './DebuggerInterface'; - -export default class BreakpointDeleteCommand implements Command { - name = 'delete'; - helpText = '[index]: permanently deletes a breakpoint.'; +class BreakpointDeleteCommand { - _debugger: DebuggerInterface; + constructor(debug) { + this.name = 'delete'; + this.helpText = '[index]: permanently deletes a breakpoint.'; - constructor(debug: DebuggerInterface) { this._debugger = debug; } - async execute(args: string[]): Promise { + async execute(args) { let index = -1; - if (args.length !== 1 || isNaN((index = parseInt(args[0], 10)))) { + if (args.length !== 1 || isNaN(index = parseInt(args[0], 10))) { throw new Error("Format is 'breakpoint delete index'"); } await this._debugger.deleteBreakpoint(index); } } +exports.default = BreakpointDeleteCommand; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/BreakpointDisableCommand.js b/modules/nuclide-debugger-cli/lib/BreakpointDisableCommand.js index 7e8ea7ba67..9cb8f035fc 100644 --- a/modules/nuclide-debugger-cli/lib/BreakpointDisableCommand.js +++ b/modules/nuclide-debugger-cli/lib/BreakpointDisableCommand.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,30 +11,27 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type {Command} from './Command'; -import type {DebuggerInterface} from './DebuggerInterface'; - -export default class BreakpointDisableCommand implements Command { - name = 'disable'; - helpText = '[index]: temporarily disables a breakpoint.'; +class BreakpointDisableCommand { - _debugger: DebuggerInterface; + constructor(debug) { + this.name = 'disable'; + this.helpText = '[index]: temporarily disables a breakpoint.'; - constructor(debug: DebuggerInterface) { this._debugger = debug; } - async execute(args: string[]): Promise { + async execute(args) { let index = -1; - if (args.length !== 1 || isNaN((index = parseInt(args[0], 10)))) { + if (args.length !== 1 || isNaN(index = parseInt(args[0], 10))) { throw new Error("Format is 'breakpoint disable index'"); } await this._debugger.setBreakpointEnabled(index, false); } } +exports.default = BreakpointDisableCommand; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/BreakpointEnableCommand.js b/modules/nuclide-debugger-cli/lib/BreakpointEnableCommand.js index b5d18b7f94..db5461323d 100644 --- a/modules/nuclide-debugger-cli/lib/BreakpointEnableCommand.js +++ b/modules/nuclide-debugger-cli/lib/BreakpointEnableCommand.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,30 +11,27 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type {Command} from './Command'; -import type {DebuggerInterface} from './DebuggerInterface'; - -export default class BreakpointEnableCommand implements Command { - name = 'enable'; - helpText = '[index]: enables a breakpoint.'; +class BreakpointEnableCommand { - _debugger: DebuggerInterface; + constructor(debug) { + this.name = 'enable'; + this.helpText = '[index]: enables a breakpoint.'; - constructor(debug: DebuggerInterface) { this._debugger = debug; } - async execute(args: string[]): Promise { + async execute(args) { let index = -1; - if (args.length !== 1 || isNaN((index = parseInt(args[0], 10)))) { + if (args.length !== 1 || isNaN(index = parseInt(args[0], 10))) { throw new Error("Format is 'breakpoint enable index'"); } await this._debugger.setBreakpointEnabled(index, true); } } +exports.default = BreakpointEnableCommand; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/BreakpointListCommand.js b/modules/nuclide-debugger-cli/lib/BreakpointListCommand.js index 9fceb70eb1..36636151f4 100644 --- a/modules/nuclide-debugger-cli/lib/BreakpointListCommand.js +++ b/modules/nuclide-debugger-cli/lib/BreakpointListCommand.js @@ -1,3 +1,17 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _Format; + +function _load_Format() { + return _Format = _interopRequireDefault(require('./Format')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,32 +20,22 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type {Command} from './Command'; -import type {DebuggerInterface} from './DebuggerInterface'; -import type {ConsoleIO} from './ConsoleIO'; - -import leftPad from './Format'; - -export default class BreakpointListCommand implements Command { - name = 'list'; - helpText = 'Lists all breakpoints.'; +class BreakpointListCommand { - _console: ConsoleIO; - _debugger: DebuggerInterface; + constructor(con, debug) { + this.name = 'list'; + this.helpText = 'Lists all breakpoints.'; - constructor(con: ConsoleIO, debug: DebuggerInterface) { this._console = con; this._debugger = debug; } - async execute(args: string[]): Promise { - const breakpoints = this._debugger - .getAllBreakpoints() - .sort((left, right) => left.index - right.index); + async execute(args) { + const breakpoints = this._debugger.getAllBreakpoints().sort((left, right) => left.index - right.index); if (breakpoints.length === 0) { return; @@ -49,9 +53,10 @@ export default class BreakpointListCommand implements Command { attributes.push('disabled'); } - const index = leftPad(`#${bpt.index}`, indexSize); + const index = (0, (_Format || _load_Format()).default)(`#${bpt.index}`, indexSize); const attrs = attributes.length === 0 ? '' : `(${attributes.join(',')})`; this._console.outputLine(`${index} ${bpt.toString()} ${attrs}`); }); } } +exports.default = BreakpointListCommand; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/Command.js b/modules/nuclide-debugger-cli/lib/Command.js index a68222dddf..9a390c31f7 100644 --- a/modules/nuclide-debugger-cli/lib/Command.js +++ b/modules/nuclide-debugger-cli/lib/Command.js @@ -1,18 +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 strict - * @format - */ - -export interface Command { - +name: string; - +helpText: string; - +detailedHelpText?: string; - execute(args: string[]): Promise; -} +"use strict"; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/CommandDispatcher.js b/modules/nuclide-debugger-cli/lib/CommandDispatcher.js index 615657615d..82aa32ffd1 100644 --- a/modules/nuclide-debugger-cli/lib/CommandDispatcher.js +++ b/modules/nuclide-debugger-cli/lib/CommandDispatcher.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,48 +11,45 @@ * LICENSE file in 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 strict + * strict * @format */ -import type {Command} from './Command'; -import type {DispatcherInterface} from './DispatcherInterface'; +class CommandDispatcher { -export default class CommandDispatcher implements DispatcherInterface { - _commands: Command[] = []; - _aliases: Map; + constructor(aliases) { + this._commands = []; - constructor(aliases: Map) { this._aliases = aliases; } - registerCommand(command: Command): void { + registerCommand(command) { this._commands.push(command); } - getCommands(): Command[] { + getCommands() { return this._commands; } - getCommandsMatching(prefix: string): Command[] { + getCommandsMatching(prefix) { const re = new RegExp(`^${prefix}`); return this._commands.filter(x => x.name.match(re)); } - commandListToString(commands: Command[]): string { + commandListToString(commands) { const names = commands.map(_ => _.name); return `"${names.join('", "')}"`; } - async execute(line: string): Promise { + async execute(line) { let tail = line; - const tokens: string[] = []; + const tokens = []; // Here we're looking for quoted arguments. // \1 is the contents of a single-quoted arg that may contain spaces // \2 is a space-delimited arg if there are no quotes // \3 is the rest of the command line - const tokenizer: RegExp = /^\s*(?:('([^']*)')|(\S+))\s*(.*)$/; + const tokenizer = /^\s*(?:('([^']*)')|(\S+))\s*(.*)$/; while (tail.length > 0) { const match = tail.match(tokenizer); @@ -55,7 +57,7 @@ export default class CommandDispatcher implements DispatcherInterface { break; } - const [, , quoted, unquoted, rest] = match; + const [,, quoted, unquoted, rest] = match; tokens.push(quoted != null ? quoted : unquoted); tail = rest; } @@ -63,7 +65,7 @@ export default class CommandDispatcher implements DispatcherInterface { return this.executeTokenizedLine(tokens); } - async executeTokenizedLine(tokens: string[]): Promise { + async executeTokenizedLine(tokens) { if (tokens.length === 0 || !tokens[0]) { return; } @@ -89,13 +91,11 @@ export default class CommandDispatcher implements DispatcherInterface { } return new Promise((resolve, reject) => { - matches[0] - .execute(tokens.slice(1)) - .then(_ => resolve(null), _ => resolve(_)); + matches[0].execute(tokens.slice(1)).then(_ => resolve(null), _ => resolve(_)); }); } - resolveAlias(tokens: string[]): ?string { + resolveAlias(tokens) { const alias = this._aliases.get(tokens[0]); if (alias != null) { return `${alias} ${tokens.splice(1).join(' ')}`; @@ -113,3 +113,4 @@ export default class CommandDispatcher implements DispatcherInterface { return null; } } +exports.default = CommandDispatcher; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/CommandLine.js b/modules/nuclide-debugger-cli/lib/CommandLine.js index 6f08f4e650..5e0681296a 100644 --- a/modules/nuclide-debugger-cli/lib/CommandLine.js +++ b/modules/nuclide-debugger-cli/lib/CommandLine.js @@ -1,3 +1,21 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _readline = _interopRequireDefault(require('readline')); + +var _CommandDispatcher; + +function _load_CommandDispatcher() { + return _CommandDispatcher = _interopRequireDefault(require('./CommandDispatcher')); +} + +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. @@ -6,70 +24,48 @@ * LICENSE file in 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 strict + * strict * @format */ -import type {ConsoleIO} from './ConsoleIO'; - -import readline from 'readline'; -import CommandDispatcher from './CommandDispatcher'; -import {Observable, Subject} from 'rxjs'; - const PROMPT = 'fbdbg> '; -export default class CommandLine implements ConsoleIO { - _dispatcher: CommandDispatcher; - _cli: readline$Interface; - _inputStopped = false; - _shouldPrompt = false; - _lastLine = ''; - _overridePrompt: ?string = null; +class CommandLine { - _interrupts: Subject; - _lines: Subject; - - _subscriptions: Array = []; + constructor(dispatcher) { + this._inputStopped = false; + this._shouldPrompt = false; + this._lastLine = ''; + this._overridePrompt = null; + this._subscriptions = []; - constructor(dispatcher: CommandDispatcher) { this._dispatcher = dispatcher; - this._cli = readline.createInterface({ + this._cli = _readline.default.createInterface({ input: process.stdin, - output: process.stdout, + output: process.stdout }); this.setPrompt(); - this._interrupts = new Subject(); - this._subscriptions.push( - Observable.fromEvent(this._cli, 'SIGINT').subscribe(this._interrupts), - ); - - this._lines = new Subject(); - this._subscriptions.push( - Observable.fromEvent(this._cli, 'line') - .takeUntil(Observable.fromEvent(this._cli, 'close')) - .subscribe(this._lines), - ); - - this._subscriptions.push( - this._lines - .filter(_ => !this._inputStopped) - .switchMap(_ => { - this._lastLine = _.trim() === '' ? this._lastLine : _.trim(); - return this._dispatcher.execute(this._lastLine); - }) - .subscribe(_ => { - if (_ != null) { - this.outputLine(_.message); - } - if (!this._inputStopped) { - this._cli.prompt(); - } else { - this._shouldPrompt = true; - } - }), - ); + this._interrupts = new _rxjsBundlesRxMinJs.Subject(); + this._subscriptions.push(_rxjsBundlesRxMinJs.Observable.fromEvent(this._cli, 'SIGINT').subscribe(this._interrupts)); + + this._lines = new _rxjsBundlesRxMinJs.Subject(); + this._subscriptions.push(_rxjsBundlesRxMinJs.Observable.fromEvent(this._cli, 'line').takeUntil(_rxjsBundlesRxMinJs.Observable.fromEvent(this._cli, 'close')).subscribe(this._lines)); + + this._subscriptions.push(this._lines.filter(_ => !this._inputStopped).switchMap(_ => { + this._lastLine = _.trim() === '' ? this._lastLine : _.trim(); + return this._dispatcher.execute(this._lastLine); + }).subscribe(_ => { + if (_ != null) { + this.outputLine(_.message); + } + if (!this._inputStopped) { + this._cli.prompt(); + } else { + this._shouldPrompt = true; + } + })); this._shouldPrompt = true; } @@ -78,31 +74,29 @@ export default class CommandLine implements ConsoleIO { this._subscriptions.forEach(_ => _.unsubscribe()); } - observeInterrupts(): Observable { + observeInterrupts() { return this._interrupts; } - observeLines(): Observable { + observeLines() { return this._lines; } - setPrompt(prompt: ?string): void { + setPrompt(prompt) { this._overridePrompt = prompt; this._updatePrompt(); } - _updatePrompt(): void { + _updatePrompt() { if (this._inputStopped) { this._cli.setPrompt(''); } else { - this._cli.setPrompt( - this._overridePrompt != null ? this._overridePrompt : PROMPT, - ); + this._cli.setPrompt(this._overridePrompt != null ? this._overridePrompt : PROMPT); } } // $TODO handle paging long output (more) if termcap allows us to know the screen height - output(text: string): void { + output(text) { if (!this._inputStopped) { if (!text.startsWith('\n')) { process.stdout.write('\n'); @@ -114,20 +108,20 @@ export default class CommandLine implements ConsoleIO { process.stdout.write(text); } - outputLine(line?: string = ''): void { + outputLine(line = '') { process.stdout.write(`${line}\n`); } - prompt(): void { + prompt() { this._cli.prompt(); } - stopInput(): void { + stopInput() { this._inputStopped = true; this._updatePrompt(); } - startInput(): void { + startInput() { this._inputStopped = false; this._updatePrompt(); if (this._shouldPrompt) { @@ -136,7 +130,8 @@ export default class CommandLine implements ConsoleIO { } } - close(): void { + close() { this._cli.close(); } } +exports.default = CommandLine; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/ConfigFile.js b/modules/nuclide-debugger-cli/lib/ConfigFile.js index bece897119..3f74126fe5 100644 --- a/modules/nuclide-debugger-cli/lib/ConfigFile.js +++ b/modules/nuclide-debugger-cli/lib/ConfigFile.js @@ -1,65 +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 fs from 'fs'; -import os from 'os'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import yargs from 'yargs'; -import {mapFromObject} from 'nuclide-commons/collection'; - -export type Preset = { - description: string, - args: Array, - aliases: {[string]: string}, -}; - -type PresetSummary = { - name: string, - description: string, -}; - -type ConfigFileContents = { - aliases?: {[string]: string}, - presets: { - [string]: Preset, - }, -}; - -export default class ConfigFile { - _config: ConfigFileContents; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _fs = _interopRequireDefault(require('fs')); + +var _os = _interopRequireDefault(require('os')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../nuclide-commons/nuclideUri')); +} + +var _yargs; + +function _load_yargs() { + return _yargs = _interopRequireDefault(require('yargs')); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../nuclide-commons/collection'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class ConfigFile { constructor() { - const configFiles = [ - '/usr/local/share/fbdbg/config.json', - nuclideUri.join(os.homedir(), '.fbdbg', 'config.json'), - ]; + const configFiles = ['/usr/local/share/fbdbg/config.json', (_nuclideUri || _load_nuclideUri()).default.join(_os.default.homedir(), '.fbdbg', 'config.json')]; // $FlowFixMe Flow doesn't understand Object.assign - this._config = configFiles - .filter(fname => fs.existsSync(fname)) - .reduce((agg, fname) => { - try { - const contents = fs.readFileSync(fname, 'utf8'); - const presets = JSON.parse(contents); - const combined = {presets: {}}; - Object.assign(combined, agg, presets); - return combined; - } catch (_) { - throw new Error(`Invalid JSON in config file ${fname}.`); - } - }, {}); + this._config = configFiles.filter(fname => _fs.default.existsSync(fname)).reduce((agg, fname) => { + try { + const contents = _fs.default.readFileSync(fname, 'utf8'); + const presets = JSON.parse(contents); + const combined = { presets: {} }; + Object.assign(combined, agg, presets); + return combined; + } catch (_) { + throw new Error(`Invalid JSON in config file ${fname}.`); + } + }, {}); } - getPresetFromArguments(): ?Preset { - const name = yargs.argv.preset; + getPresetFromArguments() { + const name = (_yargs || _load_yargs()).default.argv.preset; if (name != null) { const preset = this._config.presets[name]; if (preset == null) { @@ -72,31 +60,42 @@ export default class ConfigFile { return null; } - applyPresetToArguments(preset: Preset): Array { + applyPresetToArguments(preset) { // we want to put the args from the preset first, so the user can override // them on the command line. // for now, only replace $USER instead of doing a global environment check // - const user = os.userInfo().username; + const user = _os.default.userInfo().username; const args = preset.args.map(arg => arg.replace(/\$USER/g, user)); return args.concat(process.argv.splice(2)); } - resolveAliasesForPreset(preset: ?Preset): Map { + resolveAliasesForPreset(preset) { const aliases = this._config.aliases || {}; - const presetAliases = (preset && preset.aliases) || {}; + const presetAliases = preset && preset.aliases || {}; const resolved = Object.assign(aliases, aliases, presetAliases); - return mapFromObject(resolved); + return (0, (_collection || _load_collection()).mapFromObject)(resolved); } - presets(): Array { + presets() { const keys = Object.keys(this._config.presets); keys.sort(); return keys.map(name => ({ name, - description: this._config.presets[name].description, + description: this._config.presets[name].description })); } } +exports.default = ConfigFile; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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-cli/lib/ConsoleIO.js b/modules/nuclide-debugger-cli/lib/ConsoleIO.js index 5e991195fe..2ce867e78c 100644 --- a/modules/nuclide-debugger-cli/lib/ConsoleIO.js +++ b/modules/nuclide-debugger-cli/lib/ConsoleIO.js @@ -1,25 +1,3 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict - * @format - */ +'use strict'; -import {Observable} from 'rxjs'; - -export interface ConsoleIO { - // output does not add a newline. outputLine does. - output(text: string): void; - outputLine(line?: string): void; - setPrompt(prompt: ?string): void; - prompt(): void; - stopInput(): void; - startInput(): void; - observeInterrupts(): Observable; - observeLines(): Observable; -} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/ContinueCommand.js b/modules/nuclide-debugger-cli/lib/ContinueCommand.js index 334fd356b5..090e0483c6 100644 --- a/modules/nuclide-debugger-cli/lib/ContinueCommand.js +++ b/modules/nuclide-debugger-cli/lib/ContinueCommand.js @@ -1,3 +1,15 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _DebuggerInterface; + +function _load_DebuggerInterface() { + return _DebuggerInterface = require('./DebuggerInterface'); +} + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,24 +18,21 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type {Command} from './Command'; -import {DebuggerInterface} from './DebuggerInterface'; - -export default class ContinueCommand implements Command { - name = 'continue'; - helpText = 'Continue execution of the target.'; +class ContinueCommand { - _debugger: DebuggerInterface; + constructor(debug) { + this.name = 'continue'; + this.helpText = 'Continue execution of the target.'; - constructor(debug: DebuggerInterface) { this._debugger = debug; } - async execute(): Promise { + async execute() { await this._debugger.continue(); } } +exports.default = ContinueCommand; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/DebugAdapter.js b/modules/nuclide-debugger-cli/lib/DebugAdapter.js index 02469aa03e..a726efc43f 100644 --- a/modules/nuclide-debugger-cli/lib/DebugAdapter.js +++ b/modules/nuclide-debugger-cli/lib/DebugAdapter.js @@ -1,34 +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 { - LaunchRequestArguments, - AttachRequestArguments, -} from 'vscode-debugprotocol'; -import type {Arguments} from './DebuggerAdapterFactory'; -import type {CustomArgumentType} from './VSPOptionsParser'; -import type {VsAdapterType} from 'nuclide-debugger-common'; - -export interface DebugAdapter { - +key: VsAdapterType; - +type: string; - +excludedOptions: Set; - +extensions: Set; - +customArguments: Map; - transformLaunchArguments( - args: ?LaunchRequestArguments, - ): LaunchRequestArguments; - transformAttachArguments( - args: ?AttachRequestArguments, - ): AttachRequestArguments; - parseArguments(args: Arguments): Map; -} +'use strict'; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/Debugger.js b/modules/nuclide-debugger-cli/lib/Debugger.js index 9f4899037d..818f8271d1 100644 --- a/modules/nuclide-debugger-cli/lib/Debugger.js +++ b/modules/nuclide-debugger-cli/lib/Debugger.js @@ -1,3 +1,153 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _vscodeDebugprotocol; + +function _load_vscodeDebugprotocol() { + return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol')); +} + +var _BackTraceCommand; + +function _load_BackTraceCommand() { + return _BackTraceCommand = _interopRequireDefault(require('./BackTraceCommand')); +} + +var _Breakpoint; + +function _load_Breakpoint() { + return _Breakpoint = _interopRequireDefault(require('./Breakpoint')); +} + +var _BreakpointCollection; + +function _load_BreakpointCollection() { + return _BreakpointCollection = _interopRequireDefault(require('./BreakpointCollection')); +} + +var _BreakpointCommand; + +function _load_BreakpointCommand() { + return _BreakpointCommand = _interopRequireDefault(require('./BreakpointCommand')); +} + +var _CommandDispatcher; + +function _load_CommandDispatcher() { + return _CommandDispatcher = _interopRequireDefault(require('./CommandDispatcher')); +} + +var _ContinueCommand; + +function _load_ContinueCommand() { + return _ContinueCommand = _interopRequireDefault(require('./ContinueCommand')); +} + +var _EnterCodeCommand; + +function _load_EnterCodeCommand() { + return _EnterCodeCommand = _interopRequireDefault(require('./EnterCodeCommand')); +} + +var _SourceFileCache; + +function _load_SourceFileCache() { + return _SourceFileCache = _interopRequireDefault(require('./SourceFileCache')); +} + +var _idx; + +function _load_idx() { + return _idx = _interopRequireDefault(require('idx')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../nuclide-commons/nuclideUri')); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _StepCommand; + +function _load_StepCommand() { + return _StepCommand = _interopRequireDefault(require('./StepCommand')); +} + +var _NextCommand; + +function _load_NextCommand() { + return _NextCommand = _interopRequireDefault(require('./NextCommand')); +} + +var _Thread; + +function _load_Thread() { + return _Thread = _interopRequireDefault(require('./Thread')); +} + +var _ThreadsCommand; + +function _load_ThreadsCommand() { + return _ThreadsCommand = _interopRequireDefault(require('./ThreadsCommand')); +} + +var _VariablesCommand; + +function _load_VariablesCommand() { + return _VariablesCommand = _interopRequireDefault(require('./VariablesCommand')); +} + +var _ListCommand; + +function _load_ListCommand() { + return _ListCommand = _interopRequireDefault(require('./ListCommand')); +} + +var _RestartCommand; + +function _load_RestartCommand() { + return _RestartCommand = _interopRequireDefault(require('./RestartCommand')); +} + +var _PrintCommand; + +function _load_PrintCommand() { + return _PrintCommand = _interopRequireDefault(require('./PrintCommand')); +} + +var _RunCommand; + +function _load_RunCommand() { + return _RunCommand = _interopRequireDefault(require('./RunCommand')); +} + +var _ThreadCollection; + +function _load_ThreadCollection() { + return _ThreadCollection = _interopRequireDefault(require('./ThreadCollection')); +} + +var _VsDebugSession; + +function _load_VsDebugSession() { + return _VsDebugSession = _interopRequireDefault(require('../../nuclide-debugger-common/VsDebugSession')); +} + +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; } } + +// program is gone and not coming back + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,113 +156,53 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type {ConsoleIO} from './ConsoleIO'; -import type {ParsedVSAdapter} from './DebuggerAdapterFactory'; -import type { - DebuggerInterface, - VariablesInScope, - BreakpointSetResult, -} from './DebuggerInterface'; -import * as DebugProtocol from 'vscode-debugprotocol'; -import type {AdapterExitedEvent} from 'nuclide-debugger-common/VsDebugSession'; -import type { - SourceBreakpoint, - FunctionBreakpoint, -} from './BreakpointCollection'; -import type {Preset} from './ConfigFile'; - -import BackTraceCommand from './BackTraceCommand'; -import Breakpoint from './Breakpoint'; -import BreakpointCollection from './BreakpointCollection'; -import BreakpointCommand from './BreakpointCommand'; -import CommandDispatcher from './CommandDispatcher'; -import ContinueCommand from './ContinueCommand'; -import EnterCodeCommand from './EnterCodeCommand'; -import SourceFileCache from './SourceFileCache'; -import idx from 'idx'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import nullthrows from 'nullthrows'; -import StepCommand from './StepCommand'; -import NextCommand from './NextCommand'; -import Thread from './Thread'; -import ThreadsCommand from './ThreadsCommand'; -import VariablesCommand from './VariablesCommand'; -import ListCommand from './ListCommand'; -import RestartCommand from './RestartCommand'; -import PrintCommand from './PrintCommand'; -import RunCommand from './RunCommand'; -import ThreadCollection from './ThreadCollection'; - -import invariant from 'assert'; -import VsDebugSession from 'nuclide-debugger-common/VsDebugSession'; - -type Capabilities = { - ...DebugProtocol.Capabilities, - supportsReadyForEvaluationsEvent?: ?boolean, -}; - -type SessionState = - | 'INITIALIZING' // waiting for initialized event from adapter - | 'CONFIGURING' // waiting for user to issue 'run' command after setting initial breakpoints - | 'RUNNING' // program is running - | 'STOPPED' // program has hit a breakpoint - | 'TERMINATED'; // program is gone and not coming back - -export default class Debugger implements DebuggerInterface { - _capabilities: Capabilities = {}; - _console: ConsoleIO; - _debugSession: ?VsDebugSession; - _logger: log4js$Logger; - _activeThread: ?number; - _threads: ThreadCollection = new ThreadCollection(); - _sourceFiles: SourceFileCache; - _state: SessionState = 'INITIALIZING'; - _breakpoints: BreakpointCollection = new BreakpointCollection(); - _adapter: ?ParsedVSAdapter; - _attachMode: boolean = false; - _preset: ?Preset; - _readyForEvaluations: boolean = false; - - constructor(logger: log4js$Logger, con: ConsoleIO, preset: ?Preset) { +class Debugger { + + constructor(logger, con, preset) { + this._capabilities = {}; + this._threads = new (_ThreadCollection || _load_ThreadCollection()).default(); + this._state = 'INITIALIZING'; + this._breakpoints = new (_BreakpointCollection || _load_BreakpointCollection()).default(); + this._attachMode = false; + this._readyForEvaluations = false; + this._logger = logger; this._console = con; - this._sourceFiles = new SourceFileCache( - this._getSourceByReference.bind(this), - ); + this._sourceFiles = new (_SourceFileCache || _load_SourceFileCache()).default(this._getSourceByReference.bind(this)); this._preset = preset; } - registerCommands(dispatcher: CommandDispatcher): void { - dispatcher.registerCommand(new BackTraceCommand(this._console, this)); - dispatcher.registerCommand(new ThreadsCommand(this._console, this)); - dispatcher.registerCommand(new StepCommand(this)); - dispatcher.registerCommand(new NextCommand(this)); - dispatcher.registerCommand(new VariablesCommand(this._console, this)); - dispatcher.registerCommand(new BreakpointCommand(this._console, this)); - dispatcher.registerCommand(new ContinueCommand(this)); - dispatcher.registerCommand(new ListCommand(this._console, this)); - dispatcher.registerCommand(new RestartCommand(this)); - dispatcher.registerCommand(new PrintCommand(this._console, this)); - dispatcher.registerCommand(new RunCommand(this)); - dispatcher.registerCommand(new EnterCodeCommand(this._console, this)); + registerCommands(dispatcher) { + dispatcher.registerCommand(new (_BackTraceCommand || _load_BackTraceCommand()).default(this._console, this)); + dispatcher.registerCommand(new (_ThreadsCommand || _load_ThreadsCommand()).default(this._console, this)); + dispatcher.registerCommand(new (_StepCommand || _load_StepCommand()).default(this)); + dispatcher.registerCommand(new (_NextCommand || _load_NextCommand()).default(this)); + dispatcher.registerCommand(new (_VariablesCommand || _load_VariablesCommand()).default(this._console, this)); + dispatcher.registerCommand(new (_BreakpointCommand || _load_BreakpointCommand()).default(this._console, this)); + dispatcher.registerCommand(new (_ContinueCommand || _load_ContinueCommand()).default(this)); + dispatcher.registerCommand(new (_ListCommand || _load_ListCommand()).default(this._console, this)); + dispatcher.registerCommand(new (_RestartCommand || _load_RestartCommand()).default(this)); + dispatcher.registerCommand(new (_PrintCommand || _load_PrintCommand()).default(this._console, this)); + dispatcher.registerCommand(new (_RunCommand || _load_RunCommand()).default(this)); + dispatcher.registerCommand(new (_EnterCodeCommand || _load_EnterCodeCommand()).default(this._console, this)); } // launch is for launching a process from scratch when we need a new // session - launch(adapter: ParsedVSAdapter): Promise { + launch(adapter) { this._adapter = adapter; - this._breakpoints = new BreakpointCollection(); + this._breakpoints = new (_BreakpointCollection || _load_BreakpointCollection()).default(); return this.relaunch(); } // relaunch is for when we want to restart the current process // without tearing down the session. some adapters can do this // automatically - async relaunch(): Promise { + async relaunch() { const adapter = this._adapter; if (adapter == null) { throw new Error('There is nothing to relaunch.'); @@ -122,42 +212,40 @@ export default class Debugger implements DebuggerInterface { await this.closeSession(); await this.createSession(adapter); - invariant(adapter.action === 'attach' || adapter.action === 'launch'); + if (!(adapter.action === 'attach' || adapter.action === 'launch')) { + throw new Error('Invariant violation: "adapter.action === \'attach\' || adapter.action === \'launch\'"'); + } + this._attachMode = adapter.action === 'attach'; const session = this._ensureDebugSession(true); if (this._attachMode) { - await session.attach( - nullthrows(this._adapter).adapter.transformAttachArguments( - adapter.attachArgs, - ), - ); + await session.attach((0, (_nullthrows || _load_nullthrows()).default)(this._adapter).adapter.transformAttachArguments(adapter.attachArgs)); } else { - await session.launch( - nullthrows(this._adapter).adapter.transformLaunchArguments( - adapter.launchArgs, - ), - ); + await session.launch((0, (_nullthrows || _load_nullthrows()).default)(this._adapter).adapter.transformLaunchArguments(adapter.launchArgs)); } } - async _onInitialized(): Promise { + async _onInitialized() { const adapter = this._adapter; - invariant(adapter != null); + + if (!(adapter != null)) { + throw new Error('Invariant violation: "adapter != null"'); + } this._state = 'CONFIGURING'; this._startConfigurationInput(); } - async _configurationDone(): Promise { + async _configurationDone() { const session = this._ensureDebugSession(true); this._state = 'RUNNING'; await this._resetAllBreakpoints(); // this needs to be sent last for adapters that don't support configurationDone - await session.setExceptionBreakpoints({filters: []}); + await session.setExceptionBreakpoints({ filters: [] }); if (this._capabilities.supportsConfigurationDoneRequest) { await session.configurationDone(); @@ -167,7 +255,7 @@ export default class Debugger implements DebuggerInterface { this._console.stopInput(); } - async run(): Promise { + async run() { if (this._attachMode) { throw new Error('Cannot run an attached process; already attached.'); } @@ -179,57 +267,46 @@ export default class Debugger implements DebuggerInterface { return this._configurationDone(); } - breakInto(): void { + breakInto() { // if there is a focus thread from before, stop that one, else just // pick the first. - const thread = - this._threads.focusThread != null - ? this._threads.focusThread - : this._threads.allThreads[0]; + const thread = this._threads.focusThread != null ? this._threads.focusThread : this._threads.allThreads[0]; if (thread == null) { return; } - this._ensureDebugSession().pause({threadId: thread.id()}); + this._ensureDebugSession().pause({ threadId: thread.id() }); } - getThreads(): ThreadCollection { + getThreads() { this._ensureDebugSession(); return this._threads; } - getActiveThread(): Thread { + getActiveThread() { this._ensureDebugSession(); - return nullthrows(this._threads.focusThread); + return (0, (_nullthrows || _load_nullthrows()).default)(this._threads.focusThread); } - async getStackTrace( - thread: number, - levels: number, - ): Promise { + async getStackTrace(thread, levels) { const { - body: {stackFrames}, + body: { stackFrames } } = await this._ensureDebugSession().stackTrace({ threadId: thread, - levels, + levels }); return stackFrames; } - async setSelectedStackFrame( - thread: Thread, - frameIndex: number, - ): Promise { + async setSelectedStackFrame(thread, frameIndex) { const frames = await this.getStackTrace(thread.id(), frameIndex + 1); if (frames[frameIndex] == null) { - throw new Error( - `There are only ${frames.length} frames in the thread's stack trace.`, - ); + throw new Error(`There are only ${frames.length} frames in the thread's stack trace.`); } thread.setSelectedStackFrame(frameIndex); } - async getCurrentStackFrame(): Promise { + async getCurrentStackFrame() { this._ensureDebugSession(); const thread = this.getActiveThread(); const selectedFrame = thread.selectedStackFrame(); @@ -238,19 +315,19 @@ export default class Debugger implements DebuggerInterface { return frames[selectedFrame]; } - async stepIn(): Promise { + async stepIn() { await this._ensureDebugSession().stepIn({ - threadId: this.getActiveThread().id(), + threadId: this.getActiveThread().id() }); } - async stepOver(): Promise { + async stepOver() { await this._ensureDebugSession().next({ - threadId: this.getActiveThread().id(), + threadId: this.getActiveThread().id() }); } - async continue(): Promise { + async continue() { const session = this._ensureDebugSession(true); // if we are attaching and still in configuration, this is where we'll @@ -264,7 +341,7 @@ export default class Debugger implements DebuggerInterface { if (this._state === 'STOPPED') { await session.continue({ - threadId: this.getActiveThread().id(), + threadId: this.getActiveThread().id() }); return; @@ -277,34 +354,26 @@ export default class Debugger implements DebuggerInterface { throw new Error(`Continue called from unexpected state ${this._state}`); } - async getVariables(selectedScope: ?string): Promise { + async getVariables(selectedScope) { const session = this._ensureDebugSession(); const activeThread = this.getActiveThread(); - const stack = await this.getStackTrace( - activeThread.id(), - activeThread.selectedStackFrame() + 1, - ); - const frameId = this._stackFrameId( - stack, - activeThread.selectedStackFrame(), - ); + const stack = await this.getStackTrace(activeThread.id(), activeThread.selectedStackFrame() + 1); + const frameId = this._stackFrameId(stack, activeThread.selectedStackFrame()); if (frameId == null) { return []; } const { - body: {scopes}, - } = await session.scopes({frameId}); + body: { scopes } + } = await session.scopes({ frameId }); - let queries: DebugProtocol.Scope[]; + let queries; if (selectedScope != null) { queries = scopes.filter(scope => scope.name === selectedScope); if (queries.length === 0) { - throw new Error( - `There is no scope named '${selectedScope}' in the current context.`, - ); + throw new Error(`There is no scope named '${selectedScope}' in the current context.`); } } else { queries = scopes.filter(scope => !scope.expensive); @@ -312,9 +381,9 @@ export default class Debugger implements DebuggerInterface { const executers = queries.map(async scope => { const { - body: {variables}, + body: { variables } } = await session.variables({ - variablesReference: scope.variablesReference, + variablesReference: scope.variablesReference }); return [scope.variablesReference, variables]; }); @@ -326,15 +395,12 @@ export default class Debugger implements DebuggerInterface { return { expensive: scope.expensive, scopeName: scope.name, - variables: resultsByVarRef.get(scope.variablesReference), + variables: resultsByVarRef.get(scope.variablesReference) }; }); } - async setSourceBreakpoint( - path: string, - line: number, - ): Promise { + async setSourceBreakpoint(path, line) { // NB this call is allowed before the program is launched const session = this._ensureDebugSession(true); const index = this._breakpoints.addSourceBreakpoint(path, line); @@ -342,33 +408,23 @@ export default class Debugger implements DebuggerInterface { let message = 'Breakpoint pending until program starts.'; if (this._state !== 'CONFIGURING') { - const breakpoint = await this._setSourceBreakpointsForPath( - session, - path, - index, - ); + const breakpoint = await this._setSourceBreakpointsForPath(session, path, index); message = breakpoint == null ? null : breakpoint.message; } - return {index, message}; + return { index, message }; } - async _setSourceBreakpointsForPath( - session: VsDebugSession, - path: string, - indexOfInterest: ?number, - ): Promise { - const localBreakpoints = this._breakpoints.getAllEnabledBreakpointsForSource( - path, - ); + async _setSourceBreakpointsForPath(session, path, indexOfInterest) { + const localBreakpoints = this._breakpoints.getAllEnabledBreakpointsForSource(path); const request = { - source: {path}, - breakpoints: localBreakpoints.map(x => ({line: x.line})), + source: { path }, + breakpoints: localBreakpoints.map(x => ({ line: x.line })) }; const { - body: {breakpoints: adapterBreakpoints}, + body: { breakpoints: adapterBreakpoints } } = await session.setBreakpoints(request); const paired = localBreakpoints.map((_, i) => [_, adapterBreakpoints[i]]); @@ -381,13 +437,9 @@ export default class Debugger implements DebuggerInterface { return breakpoint == null ? null : breakpoint[1]; } - async setFunctionBreakpoint(func: string): Promise { + async setFunctionBreakpoint(func) { if (!this._capabilities.supportsFunctionBreakpoints) { - throw new Error( - `The ${ - nullthrows(this._adapter).type - } debugger does not support function breakpoints.`, - ); + throw new Error(`The ${(0, (_nullthrows || _load_nullthrows()).default)(this._adapter).type} debugger does not support function breakpoints.`); } // NB this call is allowed before the program is launched @@ -401,25 +453,22 @@ export default class Debugger implements DebuggerInterface { message = breakpoint == null ? null : breakpoint.message; } - return {index, message}; + return { index, message }; } - async _setFunctionBreakpoints( - session: VsDebugSession, - indexOfInterest: number, - ): Promise { + async _setFunctionBreakpoints(session, indexOfInterest) { const funcBreakpoints = this._breakpoints.getAllEnabledFunctionBreakpoints(); const request = { breakpoints: funcBreakpoints.map(bpt => ({ - name: bpt.func, - })), + name: bpt.func + })) }; const response = await session.setFunctionBreakpoints(request); const { - body: {breakpoints: adapterBreakpoints}, + body: { breakpoints: adapterBreakpoints } } = response; const paired = funcBreakpoints.map((_, i) => [_, adapterBreakpoints[i]]); @@ -432,26 +481,21 @@ export default class Debugger implements DebuggerInterface { return breakpoint == null ? null : breakpoint[1]; } - _stackFrameId(stack: DebugProtocol.StackFrame[], depth: number): ?number { - return idx(stack, _ => _[depth].id); + _stackFrameId(stack, depth) { + var _ref, _ref2; + + return (_ref = stack) != null ? (_ref2 = _ref[depth]) != null ? _ref2.id : _ref2 : _ref; } - async getSourceLines( - source: DebugProtocol.Source, - start: number, - length: number, - ): Promise { + async getSourceLines(source, start, length) { // If `source' contains a non-zero sourceReference, then the adapter // supports returning source data; otherwise, we use the given // path as a local file system path. - // - let lines: string[] = []; + let lines = []; const sourceReference = source.sourceReference; if (sourceReference != null && sourceReference !== 0) { - lines = await this._sourceFiles.getFileDataBySourceReference( - sourceReference, - ); + lines = await this._sourceFiles.getFileDataBySourceReference(sourceReference); } else if (source.path != null) { lines = await this._sourceFiles.getFileDataByPath(source.path); } @@ -464,15 +508,15 @@ export default class Debugger implements DebuggerInterface { return lines.slice(start - 1, end); } - getAllBreakpoints(): Breakpoint[] { + getAllBreakpoints() { return this._breakpoints.getAllBreakpoints(); } - getBreakpointByIndex(index: number): Breakpoint { + getBreakpointByIndex(index) { return this._breakpoints.getBreakpointByIndex(index); } - async setBreakpointEnabled(index: number, enabled: boolean): Promise { + async setBreakpointEnabled(index, enabled) { const session = this._ensureDebugSession(); const breakpoint = this._breakpoints.getBreakpointByIndex(index); const path = breakpoint.path; @@ -495,7 +539,7 @@ export default class Debugger implements DebuggerInterface { // $TODO function breakpoints } - async deleteBreakpoint(index: number): Promise { + async deleteBreakpoint(index) { const session = this._ensureDebugSession(); const breakpoint = this._breakpoints.getBreakpointByIndex(index); const path = breakpoint.path; @@ -503,123 +547,108 @@ export default class Debugger implements DebuggerInterface { this._breakpoints.deleteBreakpoint(index); if (path != null) { - const pathBreakpoints = this._breakpoints.getAllEnabledBreakpointsForSource( - path, - ); + const pathBreakpoints = this._breakpoints.getAllEnabledBreakpointsForSource(path); await session.setBreakpoints({ - source: {path}, + source: { path }, breakpoints: pathBreakpoints.map(x => { - return {line: x.line}; - }), + return { line: x.line }; + }) }); } } - async evaluateExpression( - expression: string, - ): Promise { + async evaluateExpression(expression) { const session = this._ensureDebugSession(true); - let args = {expression, context: 'repl'}; + let args = { expression, context: 'repl' }; if (this._state === 'RUNNING') { const frame = await this.getCurrentStackFrame(); if (frame != null) { - args = {...args, frameId: frame.id}; + args = Object.assign({}, args, { frameId: frame.id }); } } return session.evaluate(args); } - async createSession(adapter: ParsedVSAdapter): Promise { + async createSession(adapter) { this._console.stopInput(); - this._threads = new ThreadCollection(); + this._threads = new (_ThreadCollection || _load_ThreadCollection()).default(); - this._debugSession = new VsDebugSession( - process.pid.toString(), - this._logger, - adapter.adapterInfo, - {host: 'cli', adapter: adapter.type, isRemote: false}, - ); + this._debugSession = new (_VsDebugSession || _load_VsDebugSession()).default(process.pid.toString(), this._logger, adapter.adapterInfo, { host: 'cli', adapter: adapter.type, isRemote: false }); this._initializeObservers(); - invariant(this._debugSession != null); - const {body} = await this._debugSession.initialize({ + if (!(this._debugSession != null)) { + throw new Error('Invariant violation: "this._debugSession != null"'); + } + + const { body } = await this._debugSession.initialize({ adapterID: 'fbdbg', pathFormat: 'path', linesStartAt1: true, columnsStartAt1: true, - clientID: 'nuclide-cli', + clientID: 'nuclide-cli' }); this._capabilities = {}; if (body != null) { // $FlowFixMe should be able to just assign here - this._capabilities = ((body: any): Capabilities); + this._capabilities = body; } this._readyForEvaluations = true; // $FlowFixMe - const extraBody: any = body; + const extraBody = body; if (extraBody.supportsReadyForEvaluationsEvent === true) { this._readyForEvaluations = false; } } - async _resetAllBreakpoints(): Promise { + async _resetAllBreakpoints() { const session = this._ensureDebugSession(); const sourceBreakpoints = this._breakpoints.getAllEnabledBreakpointsByPath(); - const sourceBreakpointSets = Array.from(sourceBreakpoints).map( - async ([path, breakpointLines]) => { - const lines: DebugProtocol.SourceBreakpoint[] = breakpointLines.map( - _ => ({line: _.line}), - ); + const sourceBreakpointSets = Array.from(sourceBreakpoints).map(async ([path, breakpointLines]) => { + const lines = breakpointLines.map(_ => ({ line: _.line })); - const source: DebugProtocol.Source = { - path, - }; + const source = { + path + }; - const { - body: {breakpoints: breakpointsOut}, - } = await session.setBreakpoints({ - source, - breakpoints: lines, - }); + const { + body: { breakpoints: breakpointsOut } + } = await session.setBreakpoints({ + source, + breakpoints: lines + }); - breakpointLines.forEach((local, i) => { - this._updateBreakpoint(local, breakpointsOut[i]); - }); - }, - ); + breakpointLines.forEach((local, i) => { + this._updateBreakpoint(local, breakpointsOut[i]); + }); + }); - await Promise.all( - sourceBreakpointSets.concat(this._resetAllFunctionBreakpoints()), - ); + await Promise.all(sourceBreakpointSets.concat(this._resetAllFunctionBreakpoints())); } - async _resetAllFunctionBreakpoints(): Promise { + async _resetAllFunctionBreakpoints() { const session = this._ensureDebugSession(); const funcBreakpoints = this._breakpoints.getAllEnabledFunctionBreakpoints(); - if ( - !this._capabilities.supportsFunctionBreakpoints || - funcBreakpoints.length === 0 - ) { + if (!this._capabilities.supportsFunctionBreakpoints || funcBreakpoints.length === 0) { return; } const { - body: {breakpoints: funcBreakpointsOut}, + body: { breakpoints: funcBreakpointsOut } } = await session.setFunctionBreakpoints({ breakpoints: funcBreakpoints.map(bpt => ({ - name: bpt.func, - })), + name: bpt.func + })) }); funcBreakpoints.forEach((local, i) => { @@ -627,10 +656,7 @@ export default class Debugger implements DebuggerInterface { }); } - _updateBreakpoint( - local: SourceBreakpoint | FunctionBreakpoint, - remote: DebugProtocol.Breakpoint, - ) { + _updateBreakpoint(local, remote) { const index = local.index; const id = remote.id; @@ -662,12 +688,11 @@ export default class Debugger implements DebuggerInterface { // If we failed to set the breakpoint, and we didn't get a message why, // concot one. if (!remote.verified && (remote.message == null || remote.message === '')) { - remote.message = - 'Could not set this breakpoint. The module may not have been loaded yet.'; + remote.message = 'Could not set this breakpoint. The module may not have been loaded yet.'; } } - _initializeObservers(): void { + _initializeObservers() { const session = this._ensureDebugSession(true); session.observeInitializeEvents().subscribe(() => { @@ -680,12 +705,7 @@ export default class Debugger implements DebuggerInterface { } }); - session - .observeOutputEvents() - .filter( - x => x.body.category !== 'stderr' && x.body.category !== 'telemetry', - ) - .subscribe(this._onOutput.bind(this)); + session.observeOutputEvents().filter(x => x.body.category !== 'stderr' && x.body.category !== 'telemetry').subscribe(this._onOutput.bind(this)); session.observeContinuedEvents().subscribe(this._onContinued.bind(this)); @@ -693,21 +713,13 @@ export default class Debugger implements DebuggerInterface { session.observeThreadEvents().subscribe(this._onThread.bind(this)); - session - .observeExitedDebugeeEvents() - .subscribe(this._onExitedDebugee.bind(this)); + session.observeExitedDebugeeEvents().subscribe(this._onExitedDebugee.bind(this)); - session - .observeTerminateDebugeeEvents() - .subscribe(this._onTerminatedDebugee.bind(this)); + session.observeTerminateDebugeeEvents().subscribe(this._onTerminatedDebugee.bind(this)); - session - .observeAdapterExitedEvents() - .subscribe(this._onAdapterExited.bind(this)); + session.observeAdapterExitedEvents().subscribe(this._onAdapterExited.bind(this)); - session - .observeBreakpointEvents() - .subscribe(this._onBreakpointEvent.bind(this)); + session.observeBreakpointEvents().subscribe(this._onBreakpointEvent.bind(this)); session.observeCustomEvents().subscribe(e => { if (e.event === 'readyForEvaluations') { @@ -716,13 +728,13 @@ export default class Debugger implements DebuggerInterface { }); } - async closeSession(): Promise { + async closeSession() { if (this._debugSession == null) { return; } await this._debugSession.disconnect(); - this._threads = new ThreadCollection(); + this._threads = new (_ThreadCollection || _load_ThreadCollection()).default(); this._debugSession = null; this._activeThread = null; @@ -732,14 +744,16 @@ export default class Debugger implements DebuggerInterface { this._sourceFiles.flush(); } - _onOutput(event: DebugProtocol.OutputEvent): void { - const text = idx(event, _ => _.body.output) || ''; + _onOutput(event) { + var _ref3, _ref4; + + const text = ((_ref3 = event) != null ? (_ref4 = _ref3.body) != null ? _ref4.output : _ref4 : _ref3) || ''; this._console.output(text); } - _onContinued(event: DebugProtocol.ContinuedEvent) { + _onContinued(event) { const { - body: {threadId, allThreadsContinued}, + body: { threadId, allThreadsContinued } } = event; if (allThreadsContinued === true) { @@ -754,9 +768,9 @@ export default class Debugger implements DebuggerInterface { } } - async _onStopped(event: DebugProtocol.StoppedEvent) { + async _onStopped(event) { const { - body: {description, threadId, allThreadsStopped}, + body: { description, threadId, allThreadsStopped } } = event; if (description != null) { @@ -770,9 +784,7 @@ export default class Debugger implements DebuggerInterface { this._threads.allThreads.map(_ => _.clearSelectedStackFrame()); } else if (threadId != null) { this._threads.markThreadStopped(threadId); - nullthrows( - this._threads.getThreadById(threadId), - ).clearSelectedStackFrame(); + (0, (_nullthrows || _load_nullthrows()).default)(this._threads.getThreadById(threadId)).clearSelectedStackFrame(); } else { // the call didn't actually contain information about anything stopping. this._console.outputLine('stop event with no thread information.'); @@ -784,18 +796,18 @@ export default class Debugger implements DebuggerInterface { this._threads.setFocusThread(threadId); } else { const firstStopped = this._threads.firstStoppedThread(); - invariant(firstStopped != null); + + if (!(firstStopped != null)) { + throw new Error('Invariant violation: "firstStopped != null"'); + } + this._threads.setFocusThread(firstStopped); } - const topOfStack = await this._getTopOfStackSourceInfo( - nullthrows(this._threads.focusThreadId), - ); + const topOfStack = await this._getTopOfStackSourceInfo((0, (_nullthrows || _load_nullthrows()).default)(this._threads.focusThreadId)); if (topOfStack != null) { - this._console.outputLine( - `${topOfStack.name}:${topOfStack.frame.line} ${topOfStack.line}`, - ); + this._console.outputLine(`${topOfStack.name}:${topOfStack.frame.line} ${topOfStack.line}`); } this._state = 'STOPPED'; @@ -803,15 +815,15 @@ export default class Debugger implements DebuggerInterface { } } - _onThread(event: DebugProtocol.ThreadEvent) { + _onThread(event) { const { - body: {reason, threadId}, + body: { reason, threadId } } = event; if (reason === 'started') { // to avoid a race, create a thread immediately. then call _cacheThreads, // which will query gdb and update the description - this._threads.addThread(new Thread(threadId, `thread ${threadId}`)); + this._threads.addThread(new (_Thread || _load_Thread()).default(threadId, `thread ${threadId}`)); this._cacheThreads(); return; } @@ -821,26 +833,27 @@ export default class Debugger implements DebuggerInterface { } } - _onReadyForEvaluations(): void { + _onReadyForEvaluations() { this._readyForEvaluations = true; this._startConfigurationInput(); } - _startConfigurationInput(): void { + _startConfigurationInput() { if (this._readyForEvaluations && this._state === 'CONFIGURING') { this._console.startInput(); } } - _onExitedDebugee(event: DebugProtocol.ExitedEvent) { + _onExitedDebugee(event) { this._state = 'TERMINATED'; - this._console.outputLine( - `Target exited with status ${event.body.exitCode}`, - ); + this._console.outputLine(`Target exited with status ${event.body.exitCode}`); const adapter = this._adapter; - invariant(adapter != null); + + if (!(adapter != null)) { + throw new Error('Invariant violation: "adapter != null"'); + } if (!this._attachMode) { this._console.startInput(); @@ -851,7 +864,7 @@ export default class Debugger implements DebuggerInterface { process.exit(0); } - _onTerminatedDebugee(event: DebugProtocol.TerminatedEvent) { + _onTerminatedDebugee(event) { // Some adapters will send multiple terminated events. if (this._state !== 'RUNNING') { return; @@ -862,7 +875,10 @@ export default class Debugger implements DebuggerInterface { this._console.outputLine('The target has exited.'); const adapter = this._adapter; - invariant(adapter != null); + + if (!(adapter != null)) { + throw new Error('Invariant violation: "adapter != null"'); + } if (!this._attachMode) { this._console.startInput(); @@ -873,12 +889,15 @@ export default class Debugger implements DebuggerInterface { process.exit(0); } - _onAdapterExited(event: AdapterExitedEvent) { + _onAdapterExited(event) { this._state = 'TERMINATED'; this._console.outputLine('The debug adapter has exited.'); const adapter = this._adapter; - invariant(adapter != null); + + if (!(adapter != null)) { + throw new Error('Invariant violation: "adapter != null"'); + } if (!this._attachMode) { this._console.startInput(); @@ -889,26 +908,23 @@ export default class Debugger implements DebuggerInterface { process.exit(0); } - async _cacheThreads(): Promise { - invariant( - this._debugSession != null, - '_cacheThreads called without session', - ); + async _cacheThreads() { + if (!(this._debugSession != null)) { + throw new Error('_cacheThreads called without session'); + } - const {body} = await this._debugSession.threads(); - const threads = (body.threads != null ? body.threads : []).map( - _ => new Thread(_.id, _.name), - ); + const { body } = await this._debugSession.threads(); + const threads = (body.threads != null ? body.threads : []).map(_ => new (_Thread || _load_Thread()).default(_.id, _.name)); this._threads.updateThreads(threads); } - _onBreakpointEvent(event: DebugProtocol.BreakpointEvent): void { + _onBreakpointEvent(event) { const { body: { reason, - breakpoint: {id, verified}, - }, + breakpoint: { id, verified } + } } = event; if (id != null && (reason === 'new' || reason === 'changed')) { @@ -921,13 +937,7 @@ export default class Debugger implements DebuggerInterface { } } - async _getTopOfStackSourceInfo( - threadId: number, - ): Promise { + async _getTopOfStackSourceInfo(threadId) { // $TODO paths relative to project root? const frames = await this.getStackTrace(threadId, 1); const source = Debugger._sourceFromTopFrame(frames); @@ -938,11 +948,11 @@ export default class Debugger implements DebuggerInterface { const frame = frames[0]; const lines = await this.getSourceLines(source, frames[0].line, 1); - let name: string; + let name; if (source.path != null) { - const path = nuclideUri.resolve(source.path); - name = nuclideUri.split(path).pop(); + const path = (_nuclideUri || _load_nuclideUri()).default.resolve(source.path); + name = (_nuclideUri || _load_nuclideUri()).default.split(path).pop(); } else if (source.name != null) { name = source.name; } else { @@ -954,40 +964,36 @@ export default class Debugger implements DebuggerInterface { return { line: lines.length > 0 ? lines[0] : '', name, - frame, + frame }; } - static _sourceFromTopFrame( - frames: DebugProtocol.StackFrame[], - ): ?DebugProtocol.Source { - return idx(frames, _ => _[0].source) || null; + static _sourceFromTopFrame(frames) { + var _ref5, _ref6; + + return ((_ref5 = frames) != null ? (_ref6 = _ref5[0]) != null ? _ref6.source : _ref6 : _ref5) || null; } - async _getSourceByReference(sourceReference: number): Promise { + async _getSourceByReference(sourceReference) { const { - body: {content}, + body: { content } } = await this._ensureDebugSession().source({ - sourceReference, + sourceReference }); return content; } - _ensureDebugSession(allowBeforeLaunch: boolean = false): VsDebugSession { + _ensureDebugSession(allowBeforeLaunch = false) { if (this._debugSession == null) { throw new Error('There is no active debugging session.'); } - if ( - (this._state === 'INITIALIZING' || this._state === 'CONFIGURING') && - !allowBeforeLaunch - ) { - const err = new Error( - "The program is not yet running (use 'run' to start it).", - ); + if ((this._state === 'INITIALIZING' || this._state === 'CONFIGURING') && !allowBeforeLaunch) { + const err = new Error("The program is not yet running (use 'run' to start it)."); throw err; } return this._debugSession; } } +exports.default = Debugger; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/DebuggerAdapterFactory.js b/modules/nuclide-debugger-cli/lib/DebuggerAdapterFactory.js index 1bd1bfd703..5ddaecaec5 100644 --- a/modules/nuclide-debugger-cli/lib/DebuggerAdapterFactory.js +++ b/modules/nuclide-debugger-cli/lib/DebuggerAdapterFactory.js @@ -1,3 +1,65 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../nuclide-commons/nuclideUri')); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../nuclide-commons/collection'); +} + +var _debuggerRegistry; + +function _load_debuggerRegistry() { + return _debuggerRegistry = require('../../nuclide-debugger-common/debugger-registry'); +} + +var _VSPOptionsParser; + +function _load_VSPOptionsParser() { + return _VSPOptionsParser = _interopRequireDefault(require('./VSPOptionsParser')); +} + +var _HHVMDebugAdapter; + +function _load_HHVMDebugAdapter() { + return _HHVMDebugAdapter = _interopRequireDefault(require('./adapters/HHVMDebugAdapter')); +} + +var _NativeGdbDebugAdapter; + +function _load_NativeGdbDebugAdapter() { + return _NativeGdbDebugAdapter = _interopRequireDefault(require('./adapters/NativeGdbDebugAdapter')); +} + +var _NodeDebugAdapter; + +function _load_NodeDebugAdapter() { + return _NodeDebugAdapter = _interopRequireDefault(require('./adapters/NodeDebugAdapter')); +} + +var _OCamlDebugAdapter; + +function _load_OCamlDebugAdapter() { + return _OCamlDebugAdapter = _interopRequireDefault(require('./adapters/OCamlDebugAdapter')); +} + +var _PythonDebugAdapter; + +function _load_PythonDebugAdapter() { + return _PythonDebugAdapter = _interopRequireDefault(require('./adapters/PythonDebugAdapter')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,60 +68,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 strict-local + * strict-local * @format */ -import type {DebugAdapter} from './DebugAdapter'; -import type { - LaunchRequestArguments, - AttachRequestArguments, -} from 'vscode-debugprotocol'; -import type { - DebuggerConfigAction, - VSAdapterExecutableInfo, - VsAdapterType, -} from 'nuclide-debugger-common'; - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {objectFromMap} from 'nuclide-commons/collection'; -import { - getAdapterExecutable, - getAdapterPackageRoot, -} from 'nuclide-debugger-common/debugger-registry'; -import VSPOptionsParser from './VSPOptionsParser'; - -import HHVMDebugAdapter from './adapters/HHVMDebugAdapter'; -import NativeGdbDebugAdapter from './adapters/NativeGdbDebugAdapter'; -import NodeDebugAdapter from './adapters/NodeDebugAdapter'; -import OCamlDebugAdapter from './adapters/OCamlDebugAdapter'; -import PythonDebugAdapter from './adapters/PythonDebugAdapter'; - -export type ParsedVSAdapter = { - action: DebuggerConfigAction, - type: VsAdapterType, - adapterInfo: VSAdapterExecutableInfo, - launchArgs?: LaunchRequestArguments, - attachArgs?: AttachRequestArguments, - adapter: DebugAdapter, -}; - -export type Arguments = { - _: string[], - type?: string, - attach: boolean, -}; - -export default class DebuggerAdapterFactory { - _debugAdapters: Array = [ - new HHVMDebugAdapter(), - new NativeGdbDebugAdapter(), - new NodeDebugAdapter(), - new OCamlDebugAdapter(), - new PythonDebugAdapter(), - ]; - - adapterFromArguments(args: Arguments): ?ParsedVSAdapter { +class DebuggerAdapterFactory { + constructor() { + this._debugAdapters = [new (_HHVMDebugAdapter || _load_HHVMDebugAdapter()).default(), new (_NativeGdbDebugAdapter || _load_NativeGdbDebugAdapter()).default(), new (_NodeDebugAdapter || _load_NodeDebugAdapter()).default(), new (_OCamlDebugAdapter || _load_OCamlDebugAdapter()).default(), new (_PythonDebugAdapter || _load_PythonDebugAdapter()).default()]; + } + + adapterFromArguments(args) { let adapter; if (args.attach) { @@ -71,31 +89,24 @@ export default class DebuggerAdapterFactory { return adapter; } - contextSensitiveHelp(args: Arguments): Array { + contextSensitiveHelp(args) { const adapter = this._adapterFromCommandLine(args); if (adapter == null) { return []; } - const root = getAdapterPackageRoot(adapter.key); - const optionsParser = new VSPOptionsParser(root); - const action: DebuggerConfigAction = args.attach ? 'attach' : 'launch'; + const root = (0, (_debuggerRegistry || _load_debuggerRegistry()).getAdapterPackageRoot)(adapter.key); + const optionsParser = new (_VSPOptionsParser || _load_VSPOptionsParser()).default(root); + const action = args.attach ? 'attach' : 'launch'; - return optionsParser.commandLineHelp( - adapter.type, - action, - adapter.excludedOptions, - adapter.customArguments, - ); + return optionsParser.commandLineHelp(adapter.type, action, adapter.excludedOptions, adapter.customArguments); } - _parseAttachArguments(args: Arguments): ?ParsedVSAdapter { + _parseAttachArguments(args) { const adapter = this._adapterFromCommandLine(args); if (adapter == null) { - throw new Error( - 'Debugger type not specified; please use "--type" to specify it.', - ); + throw new Error('Debugger type not specified; please use "--type" to specify it.'); } const commandLineArgs = adapter.parseArguments(args); @@ -103,30 +114,24 @@ export default class DebuggerAdapterFactory { return { action: 'attach', type: adapter.key, - adapterInfo: getAdapterExecutable(adapter.key), - attachArgs: objectFromMap(commandLineArgs), - adapter, + adapterInfo: (0, (_debuggerRegistry || _load_debuggerRegistry()).getAdapterExecutable)(adapter.key), + attachArgs: (0, (_collection || _load_collection()).objectFromMap)(commandLineArgs), + adapter }; } - _parseLaunchArguments(args: Arguments): ?ParsedVSAdapter { + _parseLaunchArguments(args) { const launchArgs = args._; const program = launchArgs[0]; if (program == null) { - throw new Error( - '--attach not specified and no program to debug specified on the command line.', - ); + throw new Error('--attach not specified and no program to debug specified on the command line.'); } - const adapter = - this._adapterFromCommandLine(args) || - this._adapterFromProgramName(program); + const adapter = this._adapterFromCommandLine(args) || this._adapterFromProgramName(program); if (adapter == null) { - throw new Error( - 'Could not determine the type of program being debugged. Please specifiy with the "--type" option.', - ); + throw new Error('Could not determine the type of program being debugged. Please specifiy with the "--type" option.'); } const commandLineArgs = adapter.parseArguments(args); @@ -134,22 +139,20 @@ export default class DebuggerAdapterFactory { return { action: 'launch', type: adapter.key, - adapterInfo: getAdapterExecutable(adapter.key), - launchArgs: objectFromMap(commandLineArgs), - adapter, + adapterInfo: (0, (_debuggerRegistry || _load_debuggerRegistry()).getAdapterExecutable)(adapter.key), + launchArgs: (0, (_collection || _load_collection()).objectFromMap)(commandLineArgs), + adapter }; } - _adapterFromCommandLine(args: Arguments): ?DebugAdapter { + _adapterFromCommandLine(args) { const type = args.type; if (type != null) { const adapter = this._debugAdapters.find(a => a.key === type); if (adapter == null) { const validAdapters = this._debugAdapters.map(a => a.key).join('", "'); - throw new Error( - `Invalid target type "${type}"; valid types are "${validAdapters}".`, - ); + throw new Error(`Invalid target type "${type}"; valid types are "${validAdapters}".`); } return adapter; @@ -158,18 +161,17 @@ export default class DebuggerAdapterFactory { return null; } - _adapterFromProgramName(program: string): DebugAdapter { - const programUri = nuclideUri.parsePath(program); + _adapterFromProgramName(program) { + const programUri = (_nuclideUri || _load_nuclideUri()).default.parsePath(program); const ext = programUri.ext; const adapters = this._debugAdapters.filter(a => a.extensions.has(ext)); if (adapters.length > 1) { - throw new Error( - `Multiple debuggers can debug programs with extension ${ext}. Please explicitly specify one with '--type'`, - ); + throw new Error(`Multiple debuggers can debug programs with extension ${ext}. Please explicitly specify one with '--type'`); } return adapters[0]; } } +exports.default = DebuggerAdapterFactory; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/DebuggerInterface.js b/modules/nuclide-debugger-cli/lib/DebuggerInterface.js index d5a8b58d46..742ade00ab 100644 --- a/modules/nuclide-debugger-cli/lib/DebuggerInterface.js +++ b/modules/nuclide-debugger-cli/lib/DebuggerInterface.js @@ -1,60 +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 strict-local - * @format - */ - -import * as DebugProtocol from 'vscode-debugprotocol'; - -import Breakpoint from './Breakpoint'; -import Thread from './Thread'; -import ThreadCollection from './ThreadCollection'; - -export type VariablesInScope = { - expensive: boolean, - scopeName: string, - variables?: DebugProtocol.Variable[], -}; - -export type BreakpointSetResult = { - index: number, - message: ?string, -}; - -export interface DebuggerInterface { - run(): Promise; - getThreads(): ThreadCollection; - getActiveThread(): Thread; - stepIn(): Promise; - stepOver(): Promise; - continue(): Promise; - getStackTrace( - thread: number, - levels: number, - ): Promise; - setSelectedStackFrame(thread: Thread, frameIndex: number): Promise; - getCurrentStackFrame(): Promise; - getVariables(): Promise; - getVariables(selectedfScope: ?string): Promise; - setSourceBreakpoint(path: string, line: number): Promise; - setFunctionBreakpoint(func: string): Promise; - getAllBreakpoints(): Breakpoint[]; - getBreakpointByIndex(index: number): Breakpoint; - setBreakpointEnabled(index: number, enabled: boolean): Promise; - deleteBreakpoint(index: number): Promise; - getSourceLines( - source: DebugProtocol.Source, - start: number, - length: number, - ): Promise; - relaunch(): Promise; - evaluateExpression( - expression: string, - ): Promise; +'use strict'; + +var _vscodeDebugprotocol; + +function _load_vscodeDebugprotocol() { + return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol')); } + +var _Breakpoint; + +function _load_Breakpoint() { + return _Breakpoint = _interopRequireDefault(require('./Breakpoint')); +} + +var _Thread; + +function _load_Thread() { + return _Thread = _interopRequireDefault(require('./Thread')); +} + +var _ThreadCollection; + +function _load_ThreadCollection() { + return _ThreadCollection = _interopRequireDefault(require('./ThreadCollection')); +} + +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; } } \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/DispatcherInterface.js b/modules/nuclide-debugger-cli/lib/DispatcherInterface.js index daa3f1de8a..a726efc43f 100644 --- a/modules/nuclide-debugger-cli/lib/DispatcherInterface.js +++ b/modules/nuclide-debugger-cli/lib/DispatcherInterface.js @@ -1,19 +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 strict - * @format - */ - -import type {Command} from './Command'; - -export interface DispatcherInterface { - getCommands(): Command[]; - getCommandsMatching(prefix: string): Command[]; - commandListToString(commands: Command[]): string; -} +'use strict'; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/EnterCodeCommand.js b/modules/nuclide-debugger-cli/lib/EnterCodeCommand.js index c50bee4c15..ea1f0a3e7a 100644 --- a/modules/nuclide-debugger-cli/lib/EnterCodeCommand.js +++ b/modules/nuclide-debugger-cli/lib/EnterCodeCommand.js @@ -1,94 +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 - */ +'use strict'; -import type {Command} from './Command'; -import type {ConsoleIO} from './ConsoleIO'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -import {DebuggerInterface} from './DebuggerInterface'; -import {Observable} from 'rxjs'; -import nullthrows from 'nullthrows'; +var _DebuggerInterface; -type InterruptEvent = { - type: 'interrupt', -}; +function _load_DebuggerInterface() { + return _DebuggerInterface = require('./DebuggerInterface'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nullthrows; -type LineEvent = { - type: 'line', - line: string, -}; +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} -type Event = InterruptEvent | LineEvent; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -export default class EnterCode implements Command { - name = 'code'; - helpText = 'Enter a multi-line code fragment for evaluation.'; +class EnterCode { - _debugger: DebuggerInterface; - _console: ConsoleIO; - _pendingText: string = ''; - _subscription: ?rxjs$ISubscription = null; + constructor(console, debug) { + this.name = 'code'; + this.helpText = 'Enter a multi-line code fragment for evaluation.'; + this._pendingText = ''; + this._subscription = null; - constructor(console: ConsoleIO, debug: DebuggerInterface) { this._debugger = debug; this._console = console; } - async execute(): Promise { - this._console.output( - "Enter code, end with a single dot '.'. Use ctrl+c to abort.\n", - ); + async execute() { + this._console.output("Enter code, end with a single dot '.'. Use ctrl+c to abort.\n"); this._pendingText = ''; this._console.stopInput(); this._console.setPrompt('... '); this._console.prompt(); - this._subscription = Observable.merge( - this._console - .observeInterrupts() - .switchMap(_ => Observable.from([{type: 'interrupt'}])), - this._console - .observeLines() - .switchMap(line => Observable.from([{type: 'line', line}])), - ) - .switchMap((event: Event) => { - switch (event.type) { - case 'interrupt': - this._console.outputLine('Code entry aborted.'); - this._closeNestedInput(); - break; + this._subscription = _rxjsBundlesRxMinJs.Observable.merge(this._console.observeInterrupts().switchMap(_ => _rxjsBundlesRxMinJs.Observable.from([{ type: 'interrupt' }])), this._console.observeLines().switchMap(line => _rxjsBundlesRxMinJs.Observable.from([{ type: 'line', line }]))).switchMap(event => { + switch (event.type) { + case 'interrupt': + this._console.outputLine('Code entry aborted.'); + this._closeNestedInput(); + break; - case 'line': - if (event.line === '.') { - return this._eval(); - } - this._pendingText = `${this._pendingText}\n${event.line}`; - this._console.prompt(); - } - return Observable.empty(); - }) - .subscribe(_ => this._closeNestedInput(), _ => this._closeNestedInput()); + case 'line': + if (event.line === '.') { + return this._eval(); + } + this._pendingText = `${this._pendingText}\n${event.line}`; + this._console.prompt(); + } + return _rxjsBundlesRxMinJs.Observable.empty(); + }).subscribe(_ => this._closeNestedInput(), _ => this._closeNestedInput()); } _closeNestedInput() { - nullthrows(this._subscription).unsubscribe(); + (0, (_nullthrows || _load_nullthrows()).default)(this._subscription).unsubscribe(); this._subscription = null; this._console.setPrompt(); this._console.startInput(); } - async _eval(): Promise { + async _eval() { try { const { - body: {result}, + body: { result } } = await this._debugger.evaluateExpression(this._pendingText); this._console.outputLine(result); } catch (err) { @@ -96,3 +75,14 @@ export default class EnterCode implements Command { } } } +exports.default = EnterCode; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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-cli/lib/Format.js b/modules/nuclide-debugger-cli/lib/Format.js index 61c7aaab18..c14fde7ecb 100644 --- a/modules/nuclide-debugger-cli/lib/Format.js +++ b/modules/nuclide-debugger-cli/lib/Format.js @@ -1,3 +1,9 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = leftPad; /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,19 +12,15 @@ * LICENSE file in 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 strict + * strict * @format */ -export default function leftPad( - s: string, - size: number, - pad: string = ' ', -): string { +function leftPad(s, size, pad = ' ') { if (s.length >= size) { return s; } const padded = pad.repeat(size) + s; return padded.substr(padded.length - size); -} +} \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/HelpCommand.js b/modules/nuclide-debugger-cli/lib/HelpCommand.js index abbd28d696..739b798839 100644 --- a/modules/nuclide-debugger-cli/lib/HelpCommand.js +++ b/modules/nuclide-debugger-cli/lib/HelpCommand.js @@ -1,31 +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 strict - * @format - */ +'use strict'; -import type {Command} from './Command'; -import type {ConsoleIO} from './ConsoleIO'; -import type {DispatcherInterface} from './DispatcherInterface'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +class HelpCommand { -export default class HelpCommand implements Command { - name = 'help'; - helpText = 'Give help about the debugger command set.'; - _console: ConsoleIO; - _dispatcher: DispatcherInterface; + constructor(con, dispatcher) { + this.name = 'help'; + this.helpText = 'Give help about the debugger command set.'; - constructor(con: ConsoleIO, dispatcher: DispatcherInterface) { this._console = con; this._dispatcher = dispatcher; } - async execute(args: string[]): Promise { + async execute(args) { const [command] = args; if (command != null) { @@ -36,10 +24,10 @@ export default class HelpCommand implements Command { this._displayHelp(); } - _displayHelp(): void { + _displayHelp() { const commands = this._dispatcher.getCommands(); const commandDict = {}; - commands.forEach(x => (commandDict[x.name] = x)); + commands.forEach(x => commandDict[x.name] = x); const commandNames = commands.map(x => x.name).sort(); @@ -48,7 +36,7 @@ export default class HelpCommand implements Command { }); } - _displayDetailedHelp(cmd: string): void { + _displayDetailedHelp(cmd) { const commands = this._dispatcher.getCommandsMatching(cmd); if (commands.length === 0) { throw new Error(`There is no command "${cmd}"`); @@ -69,3 +57,14 @@ export default class HelpCommand implements Command { this._console.outputLine(command.helpText); } } +exports.default = HelpCommand; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/ListCommand.js b/modules/nuclide-debugger-cli/lib/ListCommand.js index f0509120d4..154c76bf93 100644 --- a/modules/nuclide-debugger-cli/lib/ListCommand.js +++ b/modules/nuclide-debugger-cli/lib/ListCommand.js @@ -1,33 +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 strict-local - * @format - */ - -import * as DebugProtocol from 'vscode-debugprotocol'; -import type {ConsoleIO} from './ConsoleIO'; -import type {Command} from './Command'; - -import {DebuggerInterface} from './DebuggerInterface'; -import leftPad from './Format'; - -type SourceReference = { - source: DebugProtocol.Source, - line: number, -}; - -export default class ListCommand implements Command { - name = 'list'; - helpText = - "[line | source[:line] | @[:line]]: list source file contents. '@' may be used to refer to the source at the current stack frame."; - - detailedHelpText = ` +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _vscodeDebugprotocol; + +function _load_vscodeDebugprotocol() { + return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol')); +} + +var _DebuggerInterface; + +function _load_DebuggerInterface() { + return _DebuggerInterface = require('./DebuggerInterface'); +} + +var _Format; + +function _load_Format() { + return _Format = _interopRequireDefault(require('./Format')); +} + +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 ListCommand { + + constructor(con, debug) { + this.name = 'list'; + this.helpText = "[line | source[:line] | @[:line]]: list source file contents. '@' may be used to refer to the source at the current stack frame."; + this.detailedHelpText = ` list [line | source[:line] | @[:line]] Lists source files. @@ -47,25 +51,17 @@ If a line number is also given, then the listing will start at that line. selected stack frame. With no line number, the listing will attempt to center the current location in the ouput. Otherwise, listing will begin at the given line number. `; + this._source = {}; + this._nextLine = 1; + this._sourceIsStackFrame = false; + this._stackFrameLine = 0; - static _formatError = "Format is 'list [source[:line]]'."; - static _linesToPrint = 25; - - _console: ConsoleIO; - _debugger: DebuggerInterface; - - _source: DebugProtocol.Source = {}; - _nextLine: number = 1; - _sourceIsStackFrame: boolean = false; - _stackFrameLine: number = 0; - - constructor(con: ConsoleIO, debug: DebuggerInterface) { this._console = con; this._debugger = debug; } - async execute(args: string[]): Promise { - let ref: SourceReference; + async execute(args) { + let ref; switch (args.length) { case 0: @@ -74,7 +70,7 @@ current location in the ouput. Otherwise, listing will begin at the given line n } else { ref = { source: this._previousSource(), - line: this._nextLine, + line: this._nextLine }; } break; @@ -90,7 +86,7 @@ current location in the ouput. Otherwise, listing will begin at the given line n await this._printSourceLines(ref); } - _previousSource(): DebugProtocol.Source { + _previousSource() { if (this._sourceIsEmpty()) { throw new Error('There is no current source file to list.'); } @@ -98,33 +94,31 @@ current location in the ouput. Otherwise, listing will begin at the given line n return this._source; } - async _parseSourcePath(sourceRef: string): Promise { + async _parseSourcePath(sourceRef) { // just line on current source let match = sourceRef.match(/^(\d+)$/); if (match != null) { const [, line] = match; return { source: this._previousSource(), - line: parseInt(line, 10), + line: parseInt(line, 10) }; } // source:line (where source may be '@' meaning current stack frame source) match = sourceRef.match(/^([^:]+)(:(\d+))?$/); if (match != null) { - const [, sourcePath, , lineStr] = match; + const [, sourcePath,, lineStr] = match; let line = lineStr != null ? parseInt(lineStr, 10) : 1; - let source = {path: sourcePath}; + let source = { path: sourcePath }; this._sourceIsStackFrame = sourcePath === '@'; if (this._sourceIsStackFrame) { const stackFrame = await this._debugger.getCurrentStackFrame(); if (stackFrame == null || stackFrame.source == null) { - throw new Error( - 'Source is not available for the current stack frame.', - ); + throw new Error('Source is not available for the current stack frame.'); } source = stackFrame.source; @@ -133,31 +127,24 @@ current location in the ouput. Otherwise, listing will begin at the given line n if (lineStr == null) { // If no line was specified, center around current line in // stack frame - line = Math.max( - 1, - this._stackFrameLine - Math.floor(ListCommand._linesToPrint / 2), - ); + line = Math.max(1, this._stackFrameLine - Math.floor(ListCommand._linesToPrint / 2)); } } return { source, - line, + line }; } throw new Error(ListCommand._formatError); } - async _printSourceLines(ref: SourceReference): Promise { - let sourceLines: string[]; + async _printSourceLines(ref) { + let sourceLines; try { - sourceLines = await this._debugger.getSourceLines( - ref.source, - ref.line, - ListCommand._linesToPrint, - ); + sourceLines = await this._debugger.getSourceLines(ref.source, ref.line, ListCommand._linesToPrint); } catch (error) { if (error.code === 'ENOENT') { this._console.outputLine('Source file does not exist.'); @@ -185,9 +172,7 @@ current location in the ouput. Otherwise, listing will begin at the given line n if (this._sourceIsStackFrame && lineNumber === this._stackFrameLine) { sep = '=>'; } - this._console.outputLine( - `${leftPad(String(lineNumber), maxLength)}${sep} ${sourceLine}`, - ); + this._console.outputLine(`${(0, (_Format || _load_Format()).default)(String(lineNumber), maxLength)}${sep} ${sourceLine}`); lineNumber++; } @@ -195,11 +180,21 @@ current location in the ouput. Otherwise, listing will begin at the given line n this._nextLine = ref.line + sourceLines.length; } - _sourceIsEmpty(): boolean { - return ( - this._source.path == null && - (this._source.sourceReference == null || - this._source.sourceReference === 0) - ); + _sourceIsEmpty() { + return this._source.path == null && (this._source.sourceReference == null || this._source.sourceReference === 0); } } +exports.default = ListCommand; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ + +ListCommand._formatError = "Format is 'list [source[:line]]'."; +ListCommand._linesToPrint = 25; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/NextCommand.js b/modules/nuclide-debugger-cli/lib/NextCommand.js index 5390627991..e1f05eed5d 100644 --- a/modules/nuclide-debugger-cli/lib/NextCommand.js +++ b/modules/nuclide-debugger-cli/lib/NextCommand.js @@ -1,3 +1,15 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _DebuggerInterface; + +function _load_DebuggerInterface() { + return _DebuggerInterface = require('./DebuggerInterface'); +} + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,24 +18,21 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type {Command} from './Command'; -import {DebuggerInterface} from './DebuggerInterface'; - -export default class NextCommand implements Command { - name = 'next'; - helpText = 'Step over the current line of code.'; +class NextCommand { - _debugger: DebuggerInterface; + constructor(debug) { + this.name = 'next'; + this.helpText = 'Step over the current line of code.'; - constructor(debug: DebuggerInterface) { this._debugger = debug; } - async execute(): Promise { + async execute() { await this._debugger.stepOver(); } } +exports.default = NextCommand; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/PrintCommand.js b/modules/nuclide-debugger-cli/lib/PrintCommand.js index 591f326c7e..160679c9fb 100644 --- a/modules/nuclide-debugger-cli/lib/PrintCommand.js +++ b/modules/nuclide-debugger-cli/lib/PrintCommand.js @@ -1,25 +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 strict-local - * @format - */ - -import type {Command} from './Command'; -import type {ConsoleIO} from './ConsoleIO'; - -import {DebuggerInterface} from './DebuggerInterface'; - -export default class PrintCommand implements Command { - name = 'print'; - helpText = - 'expr: Prints the result of an expression in the context of the current stack frame.'; - detailedHelpText = ` +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _DebuggerInterface; + +function _load_DebuggerInterface() { + return _DebuggerInterface = require('./DebuggerInterface'); +} + +class PrintCommand { + + constructor(con, debug) { + this.name = 'print'; + this.helpText = 'expr: Prints the result of an expression in the context of the current stack frame.'; + this.detailedHelpText = ` print expression Displays the value of an expression. The expression will be evaluated in the syntax @@ -38,19 +34,15 @@ an expression, any in-scope function may be called, which may modify program sta in complex ways. `; - _console: ConsoleIO; - _debugger: DebuggerInterface; - - constructor(con: ConsoleIO, debug: DebuggerInterface) { this._console = con; this._debugger = debug; } - async execute(args: string[]): Promise { - const expr: string = args.join(' '); + async execute(args) { + const expr = args.join(' '); try { const { - body: {result}, + body: { result } } = await this._debugger.evaluateExpression(expr); this._console.outputLine(result); } catch (err) { @@ -58,3 +50,14 @@ in complex ways. } } } +exports.default = PrintCommand; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/QuitCommand.js b/modules/nuclide-debugger-cli/lib/QuitCommand.js index f0822359b8..17a045c6aa 100644 --- a/modules/nuclide-debugger-cli/lib/QuitCommand.js +++ b/modules/nuclide-debugger-cli/lib/QuitCommand.js @@ -1,27 +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 strict - * @format - */ +'use strict'; -import type {Command} from './Command'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +class QuitCommand { -export default class QuitCommand implements Command { - name = 'quit'; - helpText = 'Exit the debugger.'; - quit: () => void; + constructor(quit) { + this.name = 'quit'; + this.helpText = 'Exit the debugger.'; - constructor(quit: () => void) { this.quit = quit; } - async execute(): Promise { + async execute() { this.quit(); } } +exports.default = QuitCommand; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/RestartCommand.js b/modules/nuclide-debugger-cli/lib/RestartCommand.js index 7a64afcd75..bc9d2b3bdb 100644 --- a/modules/nuclide-debugger-cli/lib/RestartCommand.js +++ b/modules/nuclide-debugger-cli/lib/RestartCommand.js @@ -1,3 +1,15 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _DebuggerInterface; + +function _load_DebuggerInterface() { + return _DebuggerInterface = require('./DebuggerInterface'); +} + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,25 +18,21 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type {Command} from './Command'; - -import {DebuggerInterface} from './DebuggerInterface'; - -export default class RestartCommand implements Command { - name = 'restart'; - helpText = 'Restart the current target.'; +class RestartCommand { - _debugger: DebuggerInterface; + constructor(debug) { + this.name = 'restart'; + this.helpText = 'Restart the current target.'; - constructor(debug: DebuggerInterface) { this._debugger = debug; } - async execute(): Promise { + async execute() { return this._debugger.relaunch(); } } +exports.default = RestartCommand; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/RunCommand.js b/modules/nuclide-debugger-cli/lib/RunCommand.js index fb7237039e..946b353bc2 100644 --- a/modules/nuclide-debugger-cli/lib/RunCommand.js +++ b/modules/nuclide-debugger-cli/lib/RunCommand.js @@ -1,3 +1,15 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _DebuggerInterface; + +function _load_DebuggerInterface() { + return _DebuggerInterface = require('./DebuggerInterface'); +} + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,25 +18,21 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type {Command} from './Command'; - -import {DebuggerInterface} from './DebuggerInterface'; - -export default class RunCommand implements Command { - name = 'run'; - helpText = 'Start execution of the target.'; +class RunCommand { - _debugger: DebuggerInterface; + constructor(debug) { + this.name = 'run'; + this.helpText = 'Start execution of the target.'; - constructor(debug: DebuggerInterface) { this._debugger = debug; } - async execute(): Promise { + async execute() { return this._debugger.run(); } } +exports.default = RunCommand; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/SourceFileCache.js b/modules/nuclide-debugger-cli/lib/SourceFileCache.js index 4210eff3b3..77dacedf1b 100644 --- a/modules/nuclide-debugger-cli/lib/SourceFileCache.js +++ b/modules/nuclide-debugger-cli/lib/SourceFileCache.js @@ -1,30 +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 LineByLineReader from 'line-by-line'; - -export default class SourceFileCache { - _files: Map = new Map(); - _getSourceByReference: (sourceReference: number) => Promise; - - constructor( - getSourceByReference: (sourceReference: number) => Promise, - ) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _lineByLine; + +function _load_lineByLine() { + return _lineByLine = _interopRequireDefault(require('line-by-line')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class SourceFileCache { + + constructor(getSourceByReference) { + this._files = new Map(); + this._getSourceByReference = getSourceByReference; } - async getFileDataBySourceReference( - sourceReference: number, - ): Promise { + async getFileDataBySourceReference(sourceReference) { const path = `sourceref://${sourceReference}`; let data = this._files.get(path); @@ -36,7 +32,7 @@ export default class SourceFileCache { return data; } - async getFileDataByPath(path: string): Promise { + async getFileDataByPath(path) { let data = this._files.get(path); if (data == null) { @@ -47,27 +43,33 @@ export default class SourceFileCache { return data; } - flush(): void { + flush() { this._files = new Map(); } - async _fillCacheFromLocalFileSystem(path: string): Promise { + async _fillCacheFromLocalFileSystem(path) { return new Promise((resolve, reject) => { - const lines: string[] = []; + const lines = []; // LineByLineReader splits the file on the fly so we don't // have to read into memory first - new LineByLineReader(path) - .on('line', line => lines.push(line)) - .on('end', () => resolve(lines)) - .on('error', e => reject(e)); + new (_lineByLine || _load_lineByLine()).default(path).on('line', line => lines.push(line)).on('end', () => resolve(lines)).on('error', e => reject(e)); }); } - async _fillCacheWithSourceReference( - sourceReference: number, - ): Promise { + async _fillCacheWithSourceReference(sourceReference) { const data = await this._getSourceByReference(sourceReference); return data.split(/\n|\r\n|\r/); } } +exports.default = SourceFileCache; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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-cli/lib/StepCommand.js b/modules/nuclide-debugger-cli/lib/StepCommand.js index 7d2bfa2a1e..b5606037c0 100644 --- a/modules/nuclide-debugger-cli/lib/StepCommand.js +++ b/modules/nuclide-debugger-cli/lib/StepCommand.js @@ -1,3 +1,15 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _DebuggerInterface; + +function _load_DebuggerInterface() { + return _DebuggerInterface = require('./DebuggerInterface'); +} + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,24 +18,21 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type {Command} from './Command'; -import {DebuggerInterface} from './DebuggerInterface'; - -export default class StepCommand implements Command { - name = 'step'; - helpText = 'Step into the current line of code.'; +class StepCommand { - _debugger: DebuggerInterface; + constructor(debug) { + this.name = 'step'; + this.helpText = 'Step into the current line of code.'; - constructor(debug: DebuggerInterface) { this._debugger = debug; } - async execute(): Promise { + async execute() { this._debugger.stepIn(); } } +exports.default = StepCommand; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/Thread.js b/modules/nuclide-debugger-cli/lib/Thread.js index 22fe7aa6e9..cdc9f64552 100644 --- a/modules/nuclide-debugger-cli/lib/Thread.js +++ b/modules/nuclide-debugger-cli/lib/Thread.js @@ -1,3 +1,8 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,56 +11,53 @@ * LICENSE file in 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 class Thread { - _id: number; - _name: string; - _selectedStackFrame: number; - _stopped: boolean; +class Thread { - constructor(id: number, name: string) { + constructor(id, name) { this._id = id; this._name = name; this._stopped = false; this.clearSelectedStackFrame(); } - id(): number { + id() { return this._id; } - name(): string { + name() { return this._name; } - setName(name: string): void { + setName(name) { this._name = name; } - get isStopped(): boolean { + get isStopped() { return this._stopped; } - clearSelectedStackFrame(): void { + clearSelectedStackFrame() { this._selectedStackFrame = 0; } - selectedStackFrame(): number { + selectedStackFrame() { return this._selectedStackFrame; } - setSelectedStackFrame(frame: number): void { + setSelectedStackFrame(frame) { this._selectedStackFrame = frame; } - setRunning(): void { + setRunning() { this._stopped = false; } - setStopped(): void { + setStopped() { this._stopped = true; } } +exports.default = Thread; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/ThreadCollection.js b/modules/nuclide-debugger-cli/lib/ThreadCollection.js index 4a16d636b3..c902bad56b 100644 --- a/modules/nuclide-debugger-cli/lib/ThreadCollection.js +++ b/modules/nuclide-debugger-cli/lib/ThreadCollection.js @@ -1,32 +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 Thread from './Thread'; - -export default class ThreadCollection { - _threads: Map; - _focusThread: ?number; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _Thread; + +function _load_Thread() { + return _Thread = _interopRequireDefault(require('./Thread')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class ThreadCollection { constructor() { this._threads = new Map(); } - updateThreads(threads: Array): void { + updateThreads(threads) { const newIds = new Set(threads.map(_ => _.id())); const existingIds = [...this._threads.keys()]; - existingIds - .filter(_ => !newIds.has(_)) - .forEach(_ => this._threads.delete(_)); + existingIds.filter(_ => !newIds.has(_)).forEach(_ => this._threads.delete(_)); threads.forEach(_ => { const thread = this._threads.get(_.id()); @@ -37,34 +33,31 @@ export default class ThreadCollection { this._threads.set(_.id(), _); }); - if ( - this._focusThread != null && - this.getThreadById(this._focusThread) == null - ) { + if (this._focusThread != null && this.getThreadById(this._focusThread) == null) { this._focusThread = null; } } - addThread(thread: Thread): void { + addThread(thread) { this._threads.set(thread.id(), thread); } - removeThread(id: number): void { + removeThread(id) { this._threads.delete(id); if (this._focusThread === id) { this._focusThread = null; } } - get allThreads(): Array { + get allThreads() { return [...this._threads.values()]; } - getThreadById(id: number): ?Thread { + getThreadById(id) { return this._threads.get(id); } - markThreadStopped(id: number): void { + markThreadStopped(id) { const thread = this.getThreadById(id); if (thread == null) { throw new Error(`Attempt to mark unknown thread ${id} as stopped.`); @@ -72,7 +65,7 @@ export default class ThreadCollection { thread.setStopped(); } - markThreadRunning(id: number): void { + markThreadRunning(id) { const thread = this.getThreadById(id); if (thread == null) { throw new Error(`Attempt to mark unknown thread ${id} as running.`); @@ -80,29 +73,24 @@ export default class ThreadCollection { thread.setRunning(); } - markAllThreadsStopped(): void { + markAllThreadsStopped() { [...this._threads.values()].forEach(thread => thread.setStopped()); } - markAllThreadsRunning(): void { + markAllThreadsRunning() { [...this._threads.values()].forEach(thread => thread.setRunning()); } - allThreadsStopped(): boolean { + allThreadsStopped() { return [...this._threads.values()].reduce((x, y) => x && y.isStopped, true); } - allThreadsRunning(): boolean { - return [...this._threads.values()].reduce( - (x, y) => x && !y.isStopped, - true, - ); + allThreadsRunning() { + return [...this._threads.values()].reduce((x, y) => x && !y.isStopped, true); } - firstStoppedThread(): ?number { - const stopped = [...this._threads.values()] - .sort((a, b) => a.id() - b.id()) - .find(_ => _.isStopped); + firstStoppedThread() { + const stopped = [...this._threads.values()].sort((a, b) => a.id() - b.id()).find(_ => _.isStopped); if (stopped == null) { return null; @@ -111,21 +99,32 @@ export default class ThreadCollection { return stopped.id(); } - setFocusThread(id: number): void { + setFocusThread(id) { if (this.getThreadById(id) == null) { throw new Error(`Attempt to focus unknown thread ${id}`); } this._focusThread = id; } - get focusThreadId(): ?number { + get focusThreadId() { return this._focusThread; } - get focusThread(): ?Thread { + get focusThread() { if (this._focusThread == null) { return null; } return this._threads.get(this._focusThread); } } +exports.default = ThreadCollection; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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-cli/lib/ThreadsCommand.js b/modules/nuclide-debugger-cli/lib/ThreadsCommand.js index b4b0ec1237..7504aa18f0 100644 --- a/modules/nuclide-debugger-cli/lib/ThreadsCommand.js +++ b/modules/nuclide-debugger-cli/lib/ThreadsCommand.js @@ -1,42 +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 strict-local - * @format - */ +'use strict'; -import type {Command} from './Command'; -import type {DebuggerInterface} from './DebuggerInterface'; -import type {ConsoleIO} from './ConsoleIO'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +class ThreadsCommand { -export default class ThreadsCommand implements Command { - name = 'threads'; - helpText = "List all of the target's threads."; + constructor(con, debug) { + this.name = 'threads'; + this.helpText = "List all of the target's threads."; - _debugger: DebuggerInterface; - _console: ConsoleIO; - - constructor(con: ConsoleIO, debug: DebuggerInterface) { this._console = con; this._debugger = debug; } - async execute(): Promise { + async execute() { const threads = this._debugger.getThreads(); const focusThread = threads.focusThreadId; - threads.allThreads - .sort((left, right) => left.id() - right.id()) - .forEach(thread => { - const activeMarker = thread.id() === focusThread ? '*' : ' '; - this._console.outputLine( - `${activeMarker} ${thread.id()} ${thread.name() || ''}`, - ); - }); + threads.allThreads.sort((left, right) => left.id() - right.id()).forEach(thread => { + const activeMarker = thread.id() === focusThread ? '*' : ' '; + this._console.outputLine(`${activeMarker} ${thread.id()} ${thread.name() || ''}`); + }); } } +exports.default = ThreadsCommand; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/VSPOptionsData.js b/modules/nuclide-debugger-cli/lib/VSPOptionsData.js index f63f249725..861bdd08c6 100644 --- a/modules/nuclide-debugger-cli/lib/VSPOptionsData.js +++ b/modules/nuclide-debugger-cli/lib/VSPOptionsData.js @@ -1,114 +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 {DebuggerConfigAction} from 'nuclide-debugger-common'; - -import idx from 'idx'; -import fs from 'fs'; -import {mapFromObject} from 'nuclide-commons/collection'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - -export type AdapterPropertyType = - | 'string' - | 'number' - | 'array' - | 'boolean' - | 'object'; - -export type AdapterProperty = { - // type may be missing for enumerated properties - type?: string | string[], - description?: string, - default?: any, - enum?: (string | boolean)[], - // items contains the type for array elements; however, it isn't always - // there even for array types. - items?: { - type: AdapterPropertyType, - }, -}; - -export type AdapterPropertyObject = { - [string]: AdapterProperty, -}; - -export type AdapterPropertyMap = Map; - -export type AdapterActionSection = { - required?: [string], - properties: AdapterPropertyObject, -}; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _idx; + +function _load_idx() { + return _idx = _interopRequireDefault(require('idx')); +} + +var _fs = _interopRequireDefault(require('fs')); + +var _collection; + +function _load_collection() { + return _collection = require('../../nuclide-commons/collection'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // The parts of a VSP adapter's package.json that we need in order to parse // command line options. -export type AdapterConfiguration = { - contributes: { - debuggers: [ - { - type: string, - configurationAttributes: { - [DebuggerConfigAction]: AdapterActionSection, - }, - }, - ], - }, -}; - -export default class VSPOptionsData { - _packagePath: string; - _adapterConfiguration: AdapterConfiguration; - _strings: ?Map; - - constructor(packagePath: string) { +class VSPOptionsData { + + constructor(packagePath) { this._packagePath = packagePath; - const path = nuclideUri.join(this._packagePath, 'package.json'); + const path = (_nuclideUri || _load_nuclideUri()).default.join(this._packagePath, 'package.json'); try { - this._adapterConfiguration = JSON.parse(fs.readFileSync(path, 'utf8')); + this._adapterConfiguration = JSON.parse(_fs.default.readFileSync(path, 'utf8')); } catch (error) { - throw new Error( - `Adapter package.json for '${this._packagePath}' is corrupt.`, - ); + throw new Error(`Adapter package.json for '${this._packagePath}' is corrupt.`); } if (this._adapterConfiguration == null) { - throw new Error( - `Adapter package.json for '${this._packagePath}' is corrupt.`, - ); + throw new Error(`Adapter package.json for '${this._packagePath}' is corrupt.`); } // $TODO enumerate languages // Note that not all adapters will have this file; some have the // strings directly embedded in package.json - const nlsPath = nuclideUri.join(this._packagePath, 'package.nls.json'); + const nlsPath = (_nuclideUri || _load_nuclideUri()).default.join(this._packagePath, 'package.nls.json'); try { - const packageStrings: {[string]: string} = JSON.parse( - fs.readFileSync(nlsPath, 'utf8'), - ); + const packageStrings = JSON.parse(_fs.default.readFileSync(nlsPath, 'utf8')); if (packageStrings != null) { - this._strings = mapFromObject(packageStrings); + this._strings = (0, (_collection || _load_collection()).mapFromObject)(packageStrings); } } catch (error) {} } - adapterPropertiesForAction( - type: string, - action: DebuggerConfigAction, - ): Map { - const propertyMap = this._propertiesFromConfig( - this._adapterConfiguration, - action, - type, - ); + adapterPropertiesForAction(type, action) { + const propertyMap = this._propertiesFromConfig(this._adapterConfiguration, action, type); for (const prop of propertyMap.values()) { const desc = this._translateDescription(prop.description); @@ -120,29 +70,24 @@ export default class VSPOptionsData { return propertyMap; } - _propertiesFromConfig( - config: AdapterConfiguration, - action: DebuggerConfigAction, - type: string, - ): AdapterPropertyMap { - const debuggers = idx(config, _ => _.contributes.debuggers) || null; + _propertiesFromConfig(config, action, type) { + var _ref, _ref2, _ref3, _ref4, _ref5; + + const debuggers = ((_ref = config) != null ? (_ref2 = _ref.contributes) != null ? _ref2.debuggers : _ref2 : _ref) || null; if (debuggers == null) { throw new Error('Adapter package.json is missing.'); } const theDebugger = debuggers.find(_ => _.type === type); - const properties = idx( - theDebugger, - _ => _.configurationAttributes[action].properties, - ); + const properties = (_ref3 = theDebugger) != null ? (_ref4 = _ref3.configurationAttributes) != null ? (_ref5 = _ref4[action]) != null ? _ref5.properties : _ref5 : _ref4 : _ref3; if (properties != null) { - return mapFromObject(properties); + return (0, (_collection || _load_collection()).mapFromObject)(properties); } throw new Error('Adapter configuration is missing.'); } - _translateDescription(description: ?string): ?string { + _translateDescription(description) { if (description == null || this._strings == null) { return description; } @@ -159,3 +104,14 @@ export default class VSPOptionsData { return strings.get(match[1]) || description; } } +exports.default = VSPOptionsData; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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-cli/lib/VSPOptionsParser.js b/modules/nuclide-debugger-cli/lib/VSPOptionsParser.js index a6a4df9ec7..032fd5015b 100644 --- a/modules/nuclide-debugger-cli/lib/VSPOptionsParser.js +++ b/modules/nuclide-debugger-cli/lib/VSPOptionsParser.js @@ -1,3 +1,35 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _idx; + +function _load_idx() { + return _idx = _interopRequireDefault(require('idx')); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../nuclide-commons/collection'); +} + +var _VSPOptionsData; + +function _load_VSPOptionsData() { + return _VSPOptionsData = _interopRequireDefault(require('./VSPOptionsData')); +} + +var _yargs; + +function _load_yargs() { + return _yargs = _interopRequireDefault(require('yargs')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,60 +38,27 @@ * LICENSE file in 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 { - AdapterProperty, - AdapterPropertyMap, - AdapterPropertyType, -} from './VSPOptionsData'; - -import type {DebuggerConfigAction} from 'nuclide-debugger-common'; - -import idx from 'idx'; -import invariant from 'assert'; -import {mapFilter, mapTransform} from 'nuclide-commons/collection'; -import VSPOptionsData from './VSPOptionsData'; -import yargs from 'yargs'; - -export type CustomArgumentType = { - typeDescription: string, - parseType: AdapterPropertyType, - parser: any => any, -}; +class VSPOptionsParser { -export type CustomArgumentMap = Map; - -export default class VSPOptionsParser { - _optionsData: VSPOptionsData; - - constructor(packagePath: string) { - this._optionsData = new VSPOptionsData(packagePath); + constructor(packagePath) { + this._optionsData = new (_VSPOptionsData || _load_VSPOptionsData()).default(packagePath); } - get optionsData(): VSPOptionsData { + get optionsData() { return this._optionsData; } - commandLineHelp( - type: string, - action: DebuggerConfigAction, - exclude: Set, - customArguments: CustomArgumentMap, - ): Array { + commandLineHelp(type, action, exclude, customArguments) { let help = []; const custom = customArguments == null ? new Map() : customArguments; - const properties: Map< - string, - AdapterProperty, - > = this._optionsData.adapterPropertiesForAction(type, action); + const properties = this._optionsData.adapterPropertiesForAction(type, action); - const optionKeys = Array.from(properties.keys()) - .filter(_ => !exclude.has(_)) - .sort(); + const optionKeys = Array.from(properties.keys()).filter(_ => !exclude.has(_)).sort(); for (const optionKey of optionKeys) { const property = properties.get(optionKey); @@ -71,11 +70,7 @@ export default class VSPOptionsParser { return help; } - _helpFor( - optionKey: string, - property: AdapterProperty, - customArguments: CustomArgumentMap, - ): Array { + _helpFor(optionKey, property, customArguments) { const help = []; const description = property.description; @@ -90,10 +85,12 @@ export default class VSPOptionsParser { } else if (custom != null) { spec = custom.typeDescription; } else if (type != null) { + var _ref, _ref2; + if (!Array.isArray(type)) { type = [type]; } - const itemType = idx(property, _ => _.items.type) || null; + const itemType = ((_ref = property) != null ? (_ref2 = _ref.items) != null ? _ref2.type : _ref2 : _ref) || null; spec = type.map(_ => this._typeToDisplay(_, itemType)).join('|'); } @@ -124,7 +121,7 @@ export default class VSPOptionsParser { return help; } - _typeToDisplay(type: string, itemType: ?string): string { + _typeToDisplay(type, itemType) { switch (type) { case 'boolean': return "'true'|'false'"; @@ -138,42 +135,22 @@ export default class VSPOptionsParser { return type; } - parseCommandLine( - type: string, - action: DebuggerConfigAction, - exclude: Set, - includeDefaults: Set, - customArguments: CustomArgumentMap, - ): Map { - const propertyMap = this._optionsData.adapterPropertiesForAction( - type, - action, - ); - - let args = mapFilter( - propertyMap, - (name, prop) => prop.default != null && name in includeDefaults, - ); - args = mapTransform(args, (prop, name) => [name, prop.default]); + parseCommandLine(type, action, exclude, includeDefaults, customArguments) { + const propertyMap = this._optionsData.adapterPropertiesForAction(type, action); + + let args = (0, (_collection || _load_collection()).mapFilter)(propertyMap, (name, prop) => prop.default != null && name in includeDefaults); + args = (0, (_collection || _load_collection()).mapTransform)(args, (prop, name) => [name, prop.default]); const parser = this._yargsFromPropertyMap(propertyMap, customArguments); - this._applyCommandLineToArgs( - args, - parser.argv, - propertyMap, - customArguments, - ); + this._applyCommandLineToArgs(args, parser.argv, propertyMap, customArguments); return args; } // $TODO better flow typing for yargs - _yargsFromPropertyMap( - propertyMap: AdapterPropertyMap, - customArguments: CustomArgumentMap, - ): Object { - let parser = yargs; + _yargsFromPropertyMap(propertyMap, customArguments) { + let parser = (_yargs || _load_yargs()).default; for (const [name, prop] of propertyMap) { // If an enum is specified, it gives a list of valid choices, so don't @@ -214,12 +191,7 @@ export default class VSPOptionsParser { return parser; } - _applyCommandLineToArgs( - args: Map, - commandLine: {[string]: any}, - propertyMap: AdapterPropertyMap, - customArguments: CustomArgumentMap, - ) { + _applyCommandLineToArgs(args, commandLine, propertyMap, customArguments) { for (const [name, prop] of propertyMap) { const value = commandLine[name]; if (value == null) { @@ -241,7 +213,10 @@ export default class VSPOptionsParser { } const type = prop.type; - invariant(type != null); + + if (!(type != null)) { + throw new Error('Invariant violation: "type != null"'); + } switch (type) { case 'number': @@ -273,3 +248,4 @@ export default class VSPOptionsParser { } } } +exports.default = VSPOptionsParser; \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/VariablesCommand.js b/modules/nuclide-debugger-cli/lib/VariablesCommand.js index d9d8f1346c..2723e655c6 100644 --- a/modules/nuclide-debugger-cli/lib/VariablesCommand.js +++ b/modules/nuclide-debugger-cli/lib/VariablesCommand.js @@ -1,24 +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 strict-local - * @format - */ +'use strict'; -import type {Command} from './Command'; -import type {ConsoleIO} from './ConsoleIO'; -import {DebuggerInterface} from './DebuggerInterface'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -export default class VariablesCommand implements Command { - name = 'variables'; - helpText = - '[scope] Display variables of the current stack frame, optionally for a single scope.'; - detailedHelpText = ` +var _DebuggerInterface; + +function _load_DebuggerInterface() { + return _DebuggerInterface = require('./DebuggerInterface'); +} + +class VariablesCommand { + + constructor(con, debug) { + this.name = 'variables'; + this.helpText = '[scope] Display variables of the current stack frame, optionally for a single scope.'; + this.detailedHelpText = ` variables [scope] Each stack frame in a program may have its own local variables, and there there @@ -36,15 +33,11 @@ You can use the 'backtrace' command to set the selected stack frame. By default, when the program stops the most recent frame will be selected. `; - _console: ConsoleIO; - _debugger: DebuggerInterface; - - constructor(con: ConsoleIO, debug: DebuggerInterface) { this._console = con; this._debugger = debug; } - async execute(args: string[]): Promise { + async execute(args) { if (args.length > 1) { throw new Error("'variables' takes at most one scope parameter"); } @@ -54,15 +47,9 @@ when the program stops the most recent frame will be selected. const vars = scope.variables; if (scope.expensive && vars == null) { this._console.outputLine(); - this._console.outputLine( - `Variables in scope '${ - scope.scopeName - }' have been elided as they are expensive`, - ); + this._console.outputLine(`Variables in scope '${scope.scopeName}' have been elided as they are expensive`); - this._console.outputLine( - `to evaluate. Use 'variables ${scope.scopeName}' to see them.`, - ); + this._console.outputLine(`to evaluate. Use 'variables ${scope.scopeName}' to see them.`); return; } @@ -74,3 +61,14 @@ when the program stops the most recent frame will be selected. } } } +exports.default = VariablesCommand; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/adapters/HHVMDebugAdapter.js b/modules/nuclide-debugger-cli/lib/adapters/HHVMDebugAdapter.js index 0ac9a35f52..8a5f618a79 100644 --- a/modules/nuclide-debugger-cli/lib/adapters/HHVMDebugAdapter.js +++ b/modules/nuclide-debugger-cli/lib/adapters/HHVMDebugAdapter.js @@ -1,96 +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 - */ - -import type { - LaunchRequestArguments, - AttachRequestArguments, -} from 'vscode-debugprotocol'; -import type {Arguments} from '../DebuggerAdapterFactory'; -import type {CustomArgumentType} from '../VSPOptionsParser'; -import type {DebugAdapter} from '../DebugAdapter'; -import type {VsAdapterType} from 'nuclide-debugger-common'; - -import {getAdapterPackageRoot} from 'nuclide-debugger-common/debugger-registry'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {VsAdapterTypes} from 'nuclide-debugger-common/constants'; -import VSPOptionsParser from '../VSPOptionsParser'; - -export default class HHVMDebugAdapter implements DebugAdapter { - key: VsAdapterType = VsAdapterTypes.HHVM; - type: string = 'hhvm'; - excludedOptions: Set = new Set([ - 'targetUri', - 'scriptArgs', - 'noDebug', - 'launchScriptPath', - 'startupDocumentPath', - ]); - - extensions: Set = new Set(['.php']); - customArguments: Map = new Map(); - - _includedOptions: Set = new Set(); - - parseArguments(args: Arguments): Map { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _debuggerRegistry; + +function _load_debuggerRegistry() { + return _debuggerRegistry = require('../../../nuclide-debugger-common/debugger-registry'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../nuclide-commons/nuclideUri')); +} + +var _constants; + +function _load_constants() { + return _constants = require('../../../nuclide-debugger-common/constants'); +} + +var _VSPOptionsParser; + +function _load_VSPOptionsParser() { + return _VSPOptionsParser = _interopRequireDefault(require('../VSPOptionsParser')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class HHVMDebugAdapter { + constructor() { + this.key = (_constants || _load_constants()).VsAdapterTypes.HHVM; + this.type = 'hhvm'; + this.excludedOptions = new Set(['targetUri', 'scriptArgs', 'noDebug', 'launchScriptPath', 'startupDocumentPath']); + this.extensions = new Set(['.php']); + this.customArguments = new Map(); + this._includedOptions = new Set(); + } + + parseArguments(args) { const action = args.attach ? 'attach' : 'launch'; - const root = getAdapterPackageRoot(this.key); - const parser = new VSPOptionsParser(root); - const commandLineArgs = parser.parseCommandLine( - this.type, - action, - this.excludedOptions, - this._includedOptions, - this.customArguments, - ); + const root = (0, (_debuggerRegistry || _load_debuggerRegistry()).getAdapterPackageRoot)(this.key); + const parser = new (_VSPOptionsParser || _load_VSPOptionsParser()).default(root); + const commandLineArgs = parser.parseCommandLine(this.type, action, this.excludedOptions, this._includedOptions, this.customArguments); if (action === 'launch') { const launchArgs = args._; - const program = nuclideUri.resolve(launchArgs[0]); + const program = (_nuclideUri || _load_nuclideUri()).default.resolve(launchArgs[0]); commandLineArgs.set('scriptArgs', launchArgs.splice(1)); commandLineArgs.set('launchScriptPath', program); commandLineArgs.set('targetUri', program); commandLineArgs.set('noDebug', false); - commandLineArgs.set('cwd', nuclideUri.resolve('.')); + commandLineArgs.set('cwd', (_nuclideUri || _load_nuclideUri()).default.resolve('.')); } else { if (!commandLineArgs.has('targetUri')) { - commandLineArgs.set('targetUri', nuclideUri.resolve('.')); + commandLineArgs.set('targetUri', (_nuclideUri || _load_nuclideUri()).default.resolve('.')); } } commandLineArgs.set('action', action); - commandLineArgs.set( - 'hhvmRuntimeArgs', - commandLineArgs.get('hhvmRuntimeArgs') || [], - ); + commandLineArgs.set('hhvmRuntimeArgs', commandLineArgs.get('hhvmRuntimeArgs') || []); return commandLineArgs; } - transformLaunchArguments( - args: ?LaunchRequestArguments, - ): LaunchRequestArguments { - return { - ...(args || {}), - showDummyOnAsyncPause: true, - }; + transformLaunchArguments(args) { + return Object.assign({}, args || {}, { + showDummyOnAsyncPause: true + }); } - transformAttachArguments( - args: ?AttachRequestArguments, - ): AttachRequestArguments { - return { - ...(args || {}), - showDummyOnAsyncPause: true, - }; + transformAttachArguments(args) { + return Object.assign({}, args || {}, { + showDummyOnAsyncPause: true + }); } } +exports.default = HHVMDebugAdapter; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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-cli/lib/adapters/NativeGdbDebugAdapter.js b/modules/nuclide-debugger-cli/lib/adapters/NativeGdbDebugAdapter.js index 80b3d07741..07385f0a2f 100644 --- a/modules/nuclide-debugger-cli/lib/adapters/NativeGdbDebugAdapter.js +++ b/modules/nuclide-debugger-cli/lib/adapters/NativeGdbDebugAdapter.js @@ -1,80 +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 { - LaunchRequestArguments, - AttachRequestArguments, -} from 'vscode-debugprotocol'; - -import type {Arguments} from '../DebuggerAdapterFactory'; -import type {CustomArgumentType} from '../VSPOptionsParser'; -import type {DebugAdapter} from '../DebugAdapter'; -import type {VsAdapterType} from 'nuclide-debugger-common'; - -import {getAdapterPackageRoot} from 'nuclide-debugger-common/debugger-registry'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {VsAdapterTypes} from 'nuclide-debugger-common/constants'; -import VSPOptionsParser from '../VSPOptionsParser'; - -export default class NativeGdbDebugAdapter implements DebugAdapter { - key: VsAdapterType = VsAdapterTypes.NATIVE_GDB; - type: string = 'mi'; - excludedOptions: Set = new Set([ - 'arguments', - 'debuggerRoot', - 'diagnosticLogging', - 'stopOnAttach', - 'program', - ]); - - extensions: Set = new Set(); - customArguments: Map = new Map(); - - _includedOptions: Set = new Set(); - - parseArguments(args: Arguments): Map { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _debuggerRegistry; + +function _load_debuggerRegistry() { + return _debuggerRegistry = require('../../../nuclide-debugger-common/debugger-registry'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../nuclide-commons/nuclideUri')); +} + +var _constants; + +function _load_constants() { + return _constants = require('../../../nuclide-debugger-common/constants'); +} + +var _VSPOptionsParser; + +function _load_VSPOptionsParser() { + return _VSPOptionsParser = _interopRequireDefault(require('../VSPOptionsParser')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class NativeGdbDebugAdapter { + constructor() { + this.key = (_constants || _load_constants()).VsAdapterTypes.NATIVE_GDB; + this.type = 'mi'; + this.excludedOptions = new Set(['arguments', 'debuggerRoot', 'diagnosticLogging', 'stopOnAttach', 'program']); + this.extensions = new Set(); + this.customArguments = new Map(); + this._includedOptions = new Set(); + } + + parseArguments(args) { const action = args.attach ? 'attach' : 'launch'; - const root = getAdapterPackageRoot(this.key); - const parser = new VSPOptionsParser(root); - const commandLineArgs = parser.parseCommandLine( - this.type, - action, - this.excludedOptions, - this._includedOptions, - this.customArguments, - ); + const root = (0, (_debuggerRegistry || _load_debuggerRegistry()).getAdapterPackageRoot)(this.key); + const parser = new (_VSPOptionsParser || _load_VSPOptionsParser()).default(root); + const commandLineArgs = parser.parseCommandLine(this.type, action, this.excludedOptions, this._includedOptions, this.customArguments); if (action === 'launch') { const launchArgs = args._; const program = launchArgs[0]; commandLineArgs.set('arguments', launchArgs.splice(1)); - commandLineArgs.set('program', nuclideUri.resolve(program)); - commandLineArgs.set('cwd', nuclideUri.resolve('.')); + commandLineArgs.set('program', (_nuclideUri || _load_nuclideUri()).default.resolve(program)); + commandLineArgs.set('cwd', (_nuclideUri || _load_nuclideUri()).default.resolve('.')); commandLineArgs.set('stopOnAttach', false); } return commandLineArgs; } - transformLaunchArguments( - args: ?LaunchRequestArguments, - ): LaunchRequestArguments { + transformLaunchArguments(args) { return args || {}; } - transformAttachArguments( - args: ?AttachRequestArguments, - ): AttachRequestArguments { + transformAttachArguments(args) { return args || {}; } } +exports.default = NativeGdbDebugAdapter; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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-cli/lib/adapters/NodeDebugAdapter.js b/modules/nuclide-debugger-cli/lib/adapters/NodeDebugAdapter.js index 077bcfaf17..566829cfe5 100644 --- a/modules/nuclide-debugger-cli/lib/adapters/NodeDebugAdapter.js +++ b/modules/nuclide-debugger-cli/lib/adapters/NodeDebugAdapter.js @@ -1,102 +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 - */ - -import type { - LaunchRequestArguments, - AttachRequestArguments, -} from 'vscode-debugprotocol'; -import type {Arguments} from '../DebuggerAdapterFactory'; -import type {CustomArgumentType} from '../VSPOptionsParser'; -import type {DebugAdapter} from '../DebugAdapter'; -import type {VsAdapterType} from 'nuclide-debugger-common'; - -import {getAdapterPackageRoot} from 'nuclide-debugger-common/debugger-registry'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {VsAdapterTypes} from 'nuclide-debugger-common/constants'; -import VSPOptionsParser from '../VSPOptionsParser'; - -export default class NodeDebugAdapter implements DebugAdapter { - key: VsAdapterType = VsAdapterTypes.NODE; - type: string = 'node2'; - excludedOptions: Set = new Set([ - 'args', - 'console', - 'diagnosticLogging', - 'externalConsole', - 'noDebug', - 'outputCapture', - 'program', - 'restart', - 'trace', - 'verboseDiagnosticLogging', - ]); - - extensions: Set = new Set(['.js']); - customArguments: Map = new Map([ - [ - 'sourceMapPathOverrides', - { - typeDescription: 'source-pattern replace-pattern ...', - parseType: 'array', - parser: _parseSourceMapPathOverrides, - }, - ], - ]); - - _includedOptions: Set = new Set(['address', 'port']); - - parseArguments(args: Arguments): Map { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _debuggerRegistry; + +function _load_debuggerRegistry() { + return _debuggerRegistry = require('../../../nuclide-debugger-common/debugger-registry'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../nuclide-commons/nuclideUri')); +} + +var _constants; + +function _load_constants() { + return _constants = require('../../../nuclide-debugger-common/constants'); +} + +var _VSPOptionsParser; + +function _load_VSPOptionsParser() { + return _VSPOptionsParser = _interopRequireDefault(require('../VSPOptionsParser')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class NodeDebugAdapter { + constructor() { + this.key = (_constants || _load_constants()).VsAdapterTypes.NODE; + this.type = 'node2'; + this.excludedOptions = new Set(['args', 'console', 'diagnosticLogging', 'externalConsole', 'noDebug', 'outputCapture', 'program', 'restart', 'trace', 'verboseDiagnosticLogging']); + this.extensions = new Set(['.js']); + this.customArguments = new Map([['sourceMapPathOverrides', { + typeDescription: 'source-pattern replace-pattern ...', + parseType: 'array', + parser: _parseSourceMapPathOverrides + }]]); + this._includedOptions = new Set(['address', 'port']); + } + + parseArguments(args) { const action = args.attach ? 'attach' : 'launch'; - const root = getAdapterPackageRoot(this.key); - const parser = new VSPOptionsParser(root); - const commandLineArgs = parser.parseCommandLine( - this.type, - action, - this.excludedOptions, - this._includedOptions, - this.customArguments, - ); + const root = (0, (_debuggerRegistry || _load_debuggerRegistry()).getAdapterPackageRoot)(this.key); + const parser = new (_VSPOptionsParser || _load_VSPOptionsParser()).default(root); + const commandLineArgs = parser.parseCommandLine(this.type, action, this.excludedOptions, this._includedOptions, this.customArguments); if (action === 'launch') { const launchArgs = args._; const program = launchArgs[0]; commandLineArgs.set('args', launchArgs.splice(1)); - commandLineArgs.set('program', nuclideUri.resolve(program)); + commandLineArgs.set('program', (_nuclideUri || _load_nuclideUri()).default.resolve(program)); commandLineArgs.set('noDebug', false); - commandLineArgs.set('cwd', nuclideUri.resolve('.')); + commandLineArgs.set('cwd', (_nuclideUri || _load_nuclideUri()).default.resolve('.')); } return commandLineArgs; } - transformLaunchArguments( - args: ?LaunchRequestArguments, - ): LaunchRequestArguments { + transformLaunchArguments(args) { return args || {}; } - transformAttachArguments( - args: ?AttachRequestArguments, - ): AttachRequestArguments { + transformAttachArguments(args) { return args || {}; } } -function _parseSourceMapPathOverrides(entries: string[]): {[string]: string} { +exports.default = NodeDebugAdapter; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 _parseSourceMapPathOverrides(entries) { if (entries.length % 2 !== 0) { - throw new Error( - 'Source map path overrides must be a list of pattern pairs.', - ); + throw new Error('Source map path overrides must be a list of pattern pairs.'); } const result = {}; @@ -107,4 +97,4 @@ function _parseSourceMapPathOverrides(entries: string[]): {[string]: string} { } return result; -} +} \ No newline at end of file diff --git a/modules/nuclide-debugger-cli/lib/adapters/OCamlDebugAdapter.js b/modules/nuclide-debugger-cli/lib/adapters/OCamlDebugAdapter.js index ec05ad5901..b867015abc 100644 --- a/modules/nuclide-debugger-cli/lib/adapters/OCamlDebugAdapter.js +++ b/modules/nuclide-debugger-cli/lib/adapters/OCamlDebugAdapter.js @@ -1,73 +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 { - LaunchRequestArguments, - AttachRequestArguments, -} from 'vscode-debugprotocol'; -import type {Arguments} from '../DebuggerAdapterFactory'; -import type {CustomArgumentType} from '../VSPOptionsParser'; -import type {DebugAdapter} from '../DebugAdapter'; -import type {VsAdapterType} from 'nuclide-debugger-common'; - -import {getAdapterPackageRoot} from 'nuclide-debugger-common/debugger-registry'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {VsAdapterTypes} from 'nuclide-debugger-common/constants'; -import VSPOptionsParser from '../VSPOptionsParser'; - -export default class OCamlDebugAdapter implements DebugAdapter { - key: VsAdapterType = VsAdapterTypes.OCAML; - type: string = 'ocaml'; - excludedOptions: Set = new Set([]); - - extensions: Set = new Set(); - customArguments: Map = new Map(); - - _includedOptions: Set = new Set(); - - parseArguments(args: Arguments): Map { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _debuggerRegistry; + +function _load_debuggerRegistry() { + return _debuggerRegistry = require('../../../nuclide-debugger-common/debugger-registry'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../nuclide-commons/nuclideUri')); +} + +var _constants; + +function _load_constants() { + return _constants = require('../../../nuclide-debugger-common/constants'); +} + +var _VSPOptionsParser; + +function _load_VSPOptionsParser() { + return _VSPOptionsParser = _interopRequireDefault(require('../VSPOptionsParser')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class OCamlDebugAdapter { + constructor() { + this.key = (_constants || _load_constants()).VsAdapterTypes.OCAML; + this.type = 'ocaml'; + this.excludedOptions = new Set([]); + this.extensions = new Set(); + this.customArguments = new Map(); + this._includedOptions = new Set(); + } + + parseArguments(args) { const action = args.attach ? 'attach' : 'launch'; - const root = getAdapterPackageRoot(this.key); - const parser = new VSPOptionsParser(root); - const commandLineArgs = parser.parseCommandLine( - this.type, - action, - this.excludedOptions, - this._includedOptions, - this.customArguments, - ); + const root = (0, (_debuggerRegistry || _load_debuggerRegistry()).getAdapterPackageRoot)(this.key); + const parser = new (_VSPOptionsParser || _load_VSPOptionsParser()).default(root); + const commandLineArgs = parser.parseCommandLine(this.type, action, this.excludedOptions, this._includedOptions, this.customArguments); if (action === 'launch') { const launchArgs = args._; const program = launchArgs[0]; commandLineArgs.set('args', launchArgs.splice(1)); - commandLineArgs.set('program', nuclideUri.resolve(program)); + commandLineArgs.set('program', (_nuclideUri || _load_nuclideUri()).default.resolve(program)); commandLineArgs.set('noDebug', false); - commandLineArgs.set('cwd', nuclideUri.resolve('.')); + commandLineArgs.set('cwd', (_nuclideUri || _load_nuclideUri()).default.resolve('.')); } return commandLineArgs; } - transformLaunchArguments( - args: ?LaunchRequestArguments, - ): LaunchRequestArguments { + transformLaunchArguments(args) { return args || {}; } - transformAttachArguments( - args: ?AttachRequestArguments, - ): AttachRequestArguments { + transformAttachArguments(args) { return args || {}; } } +exports.default = OCamlDebugAdapter; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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-cli/lib/adapters/PythonDebugAdapter.js b/modules/nuclide-debugger-cli/lib/adapters/PythonDebugAdapter.js index 6108b1ec53..08605fc595 100644 --- a/modules/nuclide-debugger-cli/lib/adapters/PythonDebugAdapter.js +++ b/modules/nuclide-debugger-cli/lib/adapters/PythonDebugAdapter.js @@ -1,84 +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 { - LaunchRequestArguments, - AttachRequestArguments, -} from 'vscode-debugprotocol'; -import type {Arguments} from '../DebuggerAdapterFactory'; -import type {CustomArgumentType} from '../VSPOptionsParser'; -import type {DebugAdapter} from '../DebugAdapter'; -import type {VsAdapterType} from 'nuclide-debugger-common'; - -import {getAdapterPackageRoot} from 'nuclide-debugger-common/debugger-registry'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {VsAdapterTypes} from 'nuclide-debugger-common/constants'; -import VSPOptionsParser from '../VSPOptionsParser'; - -export default class PythonDebugAdapter implements DebugAdapter { - key: VsAdapterType = VsAdapterTypes.PYTHON; - type: string = 'python'; - excludedOptions: Set = new Set([ - 'args', - 'console', - 'diagnosticLogging', - 'externalConsole', - 'noDebug', - 'outputCapture', - 'program', - 'restart', - 'trace', - 'verboseDiagnosticLogging', - ]); - - extensions: Set = new Set(['.py']); - customArguments: Map = new Map(); - - _includedOptions: Set = new Set(['address', 'port']); - - parseArguments(args: Arguments): Map { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _debuggerRegistry; + +function _load_debuggerRegistry() { + return _debuggerRegistry = require('../../../nuclide-debugger-common/debugger-registry'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../nuclide-commons/nuclideUri')); +} + +var _constants; + +function _load_constants() { + return _constants = require('../../../nuclide-debugger-common/constants'); +} + +var _VSPOptionsParser; + +function _load_VSPOptionsParser() { + return _VSPOptionsParser = _interopRequireDefault(require('../VSPOptionsParser')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class PythonDebugAdapter { + constructor() { + this.key = (_constants || _load_constants()).VsAdapterTypes.PYTHON; + this.type = 'python'; + this.excludedOptions = new Set(['args', 'console', 'diagnosticLogging', 'externalConsole', 'noDebug', 'outputCapture', 'program', 'restart', 'trace', 'verboseDiagnosticLogging']); + this.extensions = new Set(['.py']); + this.customArguments = new Map(); + this._includedOptions = new Set(['address', 'port']); + } + + parseArguments(args) { const action = args.attach ? 'attach' : 'launch'; - const root = getAdapterPackageRoot(this.key); - const parser = new VSPOptionsParser(root); - const commandLineArgs = parser.parseCommandLine( - this.type, - action, - this.excludedOptions, - this._includedOptions, - this.customArguments, - ); + const root = (0, (_debuggerRegistry || _load_debuggerRegistry()).getAdapterPackageRoot)(this.key); + const parser = new (_VSPOptionsParser || _load_VSPOptionsParser()).default(root); + const commandLineArgs = parser.parseCommandLine(this.type, action, this.excludedOptions, this._includedOptions, this.customArguments); if (action === 'launch') { const launchArgs = args._; const program = launchArgs[0]; commandLineArgs.set('args', launchArgs.splice(1)); - commandLineArgs.set('program', nuclideUri.resolve(program)); + commandLineArgs.set('program', (_nuclideUri || _load_nuclideUri()).default.resolve(program)); commandLineArgs.set('noDebug', false); - commandLineArgs.set('cwd', nuclideUri.resolve('.')); + commandLineArgs.set('cwd', (_nuclideUri || _load_nuclideUri()).default.resolve('.')); } return commandLineArgs; } - transformLaunchArguments( - args: ?LaunchRequestArguments, - ): LaunchRequestArguments { + transformLaunchArguments(args) { return args || {}; } - transformAttachArguments( - args: ?AttachRequestArguments, - ): AttachRequestArguments { + transformAttachArguments(args) { return args || {}; } } +exports.default = PythonDebugAdapter; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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-cli/lib/main.js b/modules/nuclide-debugger-cli/lib/main.js index cd4eac0326..b9fcf54c68 100755 --- a/modules/nuclide-debugger-cli/lib/main.js +++ b/modules/nuclide-debugger-cli/lib/main.js @@ -1,36 +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 CommandLine from './CommandLine'; -import CommandDispatcher from './CommandDispatcher'; -import ConfigFile from './ConfigFile'; -import Debugger from './Debugger'; -import DebuggerAdapterFactory from './DebuggerAdapterFactory'; -import HelpCommand from './HelpCommand'; -import log4js from 'log4js'; -import QuitCommand from './QuitCommand'; -import yargs from 'yargs'; - -function buildLogger(): log4js$Logger { - const args = yargs.argv; +'use strict'; + +var _CommandLine; + +function _load_CommandLine() { + return _CommandLine = _interopRequireDefault(require('./CommandLine')); +} + +var _CommandDispatcher; + +function _load_CommandDispatcher() { + return _CommandDispatcher = _interopRequireDefault(require('./CommandDispatcher')); +} + +var _ConfigFile; + +function _load_ConfigFile() { + return _ConfigFile = _interopRequireDefault(require('./ConfigFile')); +} + +var _Debugger; + +function _load_Debugger() { + return _Debugger = _interopRequireDefault(require('./Debugger')); +} + +var _DebuggerAdapterFactory; + +function _load_DebuggerAdapterFactory() { + return _DebuggerAdapterFactory = _interopRequireDefault(require('./DebuggerAdapterFactory')); +} + +var _HelpCommand; + +function _load_HelpCommand() { + return _HelpCommand = _interopRequireDefault(require('./HelpCommand')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = _interopRequireDefault(require('log4js')); +} + +var _QuitCommand; + +function _load_QuitCommand() { + return _QuitCommand = _interopRequireDefault(require('./QuitCommand')); +} + +var _yargs; + +function _load_yargs() { + return _yargs = _interopRequireDefault(require('yargs')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function buildLogger() { + const args = (_yargs || _load_yargs()).default.argv; const level = (args.loglevel || 'FATAL').toUpperCase(); - const validLevels = new Set([ - 'TRACE', - 'DEBUG', - 'INFO', - 'WARN', - 'ERROR', - 'FATAL', - ]); + const validLevels = new Set(['TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL']); if (!validLevels.has(level)) { throw new Error(`${level} is not a valid loglevel.`); @@ -39,59 +68,43 @@ function buildLogger(): log4js$Logger { // Send debug level logging to a file. Send a configurable (by default FATAL) // level to the console. const config = { - appenders: [ - { - type: 'file', - filename: '/tmp/nuclide-cli.log', - maxLogSize: 50 * 1024, - category: '[all]', - }, - { - type: 'logLevelFilter', - level, - maxLevel: 'FATAL', - appender: { - type: 'stdout', - category: '[all]', - }, - }, - ], + appenders: [{ + type: 'file', + filename: '/tmp/nuclide-cli.log', + maxLogSize: 50 * 1024, + category: '[all]' + }, { + type: 'logLevelFilter', + level, + maxLevel: 'FATAL', + appender: { + type: 'stdout', + category: '[all]' + } + }], levels: { - '[all]': 'DEBUG', - }, + '[all]': 'DEBUG' + } }; - log4js.configure(config); + (_log4js || _load_log4js()).default.configure(config); - return log4js.getLogger('default'); -} + return (_log4js || _load_log4js()).default.getLogger('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 + */ -const _help: string[] = [ - 'fbdbg [options] [program [program-arguments]]', - ' The debugger may be launched in either "launch" or "attach" mode. "launch"', - ' starts a local program; "attach" attaches to an already running program', - ' which may be remote. There are options which are specific to the mode and', - ' type of program being debugged; to see them, specify the --type and mode', - ' options along with --help.', - '', - '--help:', - ' Show this help.', - '--attach:', - ' Attach the debugger to a running process.', - '--preset:', - ' Load default arguments for a session type preset', - '--type python|node:', - ' Specify the type of program to debug. Required with --attach', - '', - '[program]: If not attaching, the program to launch. Normally the type of', - ' program can be inferred from the file extension.', - '', -]; - -function showHelp( - configFile: ConfigFile, - contextSensitiveHelp: Array, -): void { +const _help = ['fbdbg [options] [program [program-arguments]]', ' The debugger may be launched in either "launch" or "attach" mode. "launch"', ' starts a local program; "attach" attaches to an already running program', ' which may be remote. There are options which are specific to the mode and', ' type of program being debugged; to see them, specify the --type and mode', ' options along with --help.', '', '--help:', ' Show this help.', '--attach:', ' Attach the debugger to a running process.', '--preset:', ' Load default arguments for a session type preset', '--type python|node:', ' Specify the type of program to debug. Required with --attach', '', '[program]: If not attaching, the program to launch. Normally the type of', ' program can be inferred from the file extension.', '']; + +function showHelp(configFile, contextSensitiveHelp) { process.stdout.write(_help.join('\n') + '\n'); if (contextSensitiveHelp.length !== 0) { @@ -108,20 +121,15 @@ function showHelp( } } -async function main(): Promise { +async function main() { try { // see if there's session information on the command line - const debuggerAdapterFactory = new DebuggerAdapterFactory(); - const configFile = new ConfigFile(); + const debuggerAdapterFactory = new (_DebuggerAdapterFactory || _load_DebuggerAdapterFactory()).default(); + const configFile = new (_ConfigFile || _load_ConfigFile()).default(); const preset = configFile.getPresetFromArguments(); - const cmdLine = - preset == null - ? process.argv.splice(2) - : configFile.applyPresetToArguments(preset); - const args = yargs(cmdLine) - .boolean('attach') - .boolean('help').argv; + const cmdLine = preset == null ? process.argv.splice(2) : configFile.applyPresetToArguments(preset); + const args = (0, (_yargs || _load_yargs()).default)(cmdLine).boolean('attach').boolean('help').argv; if (args.help) { showHelp(configFile, debuggerAdapterFactory.contextSensitiveHelp(args)); @@ -129,11 +137,11 @@ async function main(): Promise { } const aliases = configFile.resolveAliasesForPreset(preset); - const dispatcher = new CommandDispatcher(aliases); - const cli = new CommandLine(dispatcher); + const dispatcher = new (_CommandDispatcher || _load_CommandDispatcher()).default(aliases); + const cli = new (_CommandLine || _load_CommandLine()).default(dispatcher); - dispatcher.registerCommand(new HelpCommand(cli, dispatcher)); - dispatcher.registerCommand(new QuitCommand(() => cli.close())); + dispatcher.registerCommand(new (_HelpCommand || _load_HelpCommand()).default(cli, dispatcher)); + dispatcher.registerCommand(new (_QuitCommand || _load_QuitCommand()).default(() => cli.close())); let adapter; @@ -147,7 +155,7 @@ async function main(): Promise { } const logger = buildLogger(); - const debuggerInstance = new Debugger(logger, cli, preset); + const debuggerInstance = new (_Debugger || _load_Debugger()).default(logger, cli, preset); if (adapter != null) { await debuggerInstance.launch(adapter); @@ -159,20 +167,16 @@ async function main(): Promise { debuggerInstance.breakInto(); }); - cli.observeLines().subscribe( - _ => {}, - _ => {}, - _ => { - debuggerInstance.closeSession().then(x => { - cli.outputLine(); - process.exit(0); - }); - }, - ); + cli.observeLines().subscribe(_ => {}, _ => {}, _ => { + debuggerInstance.closeSession().then(x => { + cli.outputLine(); + process.exit(0); + }); + }); } catch (x) { process.stderr.write(`${x.message}\n`); process.exit(1); } } -main(); +main(); \ No newline at end of file diff --git a/modules/nuclide-debugger-common/AdbDeviceSelector.js b/modules/nuclide-debugger-common/AdbDeviceSelector.js index 2ba3708437..87d2b15bc7 100644 --- a/modules/nuclide-debugger-common/AdbDeviceSelector.js +++ b/modules/nuclide-debugger-common/AdbDeviceSelector.js @@ -1,3 +1,58 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AdbDeviceSelector = undefined; + +var _AdbDevicePoller; + +function _load_AdbDevicePoller() { + return _AdbDevicePoller = require('../nuclide-adb/lib/AdbDevicePoller'); +} + +var _DebugBridge; + +function _load_DebugBridge() { + return _DebugBridge = require('../nuclide-adb/lib/common/DebugBridge'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _Dropdown; + +function _load_Dropdown() { + return _Dropdown = require('../nuclide-commons-ui/Dropdown'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../nuclide-commons/UniversalDisposable')); +} + +var _expected; + +function _load_expected() { + return _expected = require('../nuclide-commons/expected'); +} + +var _LoadingSpinner; + +function _load_LoadingSpinner() { + return _LoadingSpinner = require('../nuclide-commons-ui/LoadingSpinner'); +} + +var _collection; + +function _load_collection() { + return _collection = require('../nuclide-commons/collection'); +} + +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. @@ -6,155 +61,107 @@ * LICENSE file in 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 {Device} from 'nuclide-debugger-common/types'; -import type {Expected} from 'nuclide-commons/expected'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {MenuItem} from 'nuclide-commons-ui/Dropdown'; - -import {observeAndroidDevicesX} from 'nuclide-adb/lib/AdbDevicePoller'; -import {DEFAULT_ADB_PORT} from 'nuclide-adb/lib/common/DebugBridge'; -import * as React from 'react'; -import {Dropdown} from 'nuclide-commons-ui/Dropdown'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Expect} from 'nuclide-commons/expected'; -import {LoadingSpinner} from 'nuclide-commons-ui/LoadingSpinner'; -import {arrayEqual} from 'nuclide-commons/collection'; -import invariant from 'assert'; - const NO_DEVICES_MSG = 'No adb devices attached!'; -type Props = { - targetUri: NuclideUri, - onChange: (value: ?Device) => void, -}; +class AdbDeviceSelector extends _react.Component { -type State = { - deviceList: Expected, - selectedDevice: ?Device, -}; - -export class AdbDeviceSelector extends React.Component { - props: Props; - state: State; - _disposables: UniversalDisposable; - - constructor(props: Props) { + constructor(props) { super(props); - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); - (this: any)._handleDeviceListChange = this._handleDeviceListChange.bind( - this, - ); - (this: any)._handleDeviceDropdownChange = this._handleDeviceDropdownChange.bind( - this, - ); + this._handleDeviceListChange = this._handleDeviceListChange.bind(this); + this._handleDeviceDropdownChange = this._handleDeviceDropdownChange.bind(this); this.state = { - deviceList: Expect.pendingValue([]), - selectedDevice: null, + deviceList: (_expected || _load_expected()).Expect.pendingValue([]), + selectedDevice: null }; } - componentDidMount(): void { - this._disposables.add( - observeAndroidDevicesX(this.props.targetUri) - .startWith(Expect.pendingValue([])) - .distinctUntilChanged((a, b) => { - if (a.isPending || b.isPending) { - return a.isPending === b.isPending; - } - - if (a.isError || b.isError) { - return a.isError === b.isError; - } - - invariant(!a.isPending && !b.isPending && !a.isError && !b.isError); - return arrayEqual( - a.value != null ? a.value : [], - b.value != null ? b.value : [], - (x, y) => { - return x.name === y.name && x.port === y.port; - }, - ); - }) - .subscribe(deviceList => this._handleDeviceListChange(deviceList)), - ); + componentDidMount() { + this._disposables.add((0, (_AdbDevicePoller || _load_AdbDevicePoller()).observeAndroidDevicesX)(this.props.targetUri).startWith((_expected || _load_expected()).Expect.pendingValue([])).distinctUntilChanged((a, b) => { + if (a.isPending || b.isPending) { + return a.isPending === b.isPending; + } + + if (a.isError || b.isError) { + return a.isError === b.isError; + } + + if (!(!a.isPending && !b.isPending && !a.isError && !b.isError)) { + throw new Error('Invariant violation: "!a.isPending && !b.isPending && !a.isError && !b.isError"'); + } + + return (0, (_collection || _load_collection()).arrayEqual)(a.value != null ? a.value : [], b.value != null ? b.value : [], (x, y) => { + return x.name === y.name && x.port === y.port; + }); + }).subscribe(deviceList => this._handleDeviceListChange(deviceList))); } componentWillUnmount() { this._disposables.dispose(); } - _handleDeviceListChange(deviceList: Expected): void { + _handleDeviceListChange(deviceList) { const previousDevice = this.state.selectedDevice; - let selectedDevice = - deviceList.isError || deviceList.isPending || previousDevice == null - ? null - : deviceList.value.find(device => device.name === previousDevice.name); - - if ( - selectedDevice == null && - !deviceList.isError && - !deviceList.isPending - ) { + let selectedDevice = deviceList.isError || deviceList.isPending || previousDevice == null ? null : deviceList.value.find(device => device.name === previousDevice.name); + + if (selectedDevice == null && !deviceList.isError && !deviceList.isPending) { selectedDevice = deviceList.value[0]; } this.setState({ deviceList, - selectedDevice, + selectedDevice }); this.props.onChange(selectedDevice); } - _getDeviceItems(): Array { - invariant( - !this.state.deviceList.isError && !this.state.deviceList.isPending, - ); + _getDeviceItems() { + if (!(!this.state.deviceList.isError && !this.state.deviceList.isPending)) { + throw new Error('Invariant violation: "!this.state.deviceList.isError && !this.state.deviceList.isPending"'); + } + if (this.state.deviceList.value.length === 0) { - return [{value: null, label: NO_DEVICES_MSG}]; + return [{ value: null, label: NO_DEVICES_MSG }]; } return this.state.deviceList.value.map(device => ({ value: device, - label: - device.port === DEFAULT_ADB_PORT - ? device.displayName - : `${device.displayName} on ADB port ${device.port}`, + label: device.port === (_DebugBridge || _load_DebugBridge()).DEFAULT_ADB_PORT ? device.displayName : `${device.displayName} on ADB port ${device.port}` })); } - render(): React.Node { + render() { if (this.state.deviceList.isPending) { - return ; + return _react.createElement((_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinner, { size: 'EXTRA_SMALL' }); } if (this.state.deviceList.isError) { - return ( -
      - {this.state.deviceList.error.toString()} -
      + return _react.createElement( + 'div', + { className: 'nuclide-ui-message-error' }, + this.state.deviceList.error.toString() ); } const deviceItems = this._getDeviceItems(); - return ( - - ); + return _react.createElement((_Dropdown || _load_Dropdown()).Dropdown, { + options: deviceItems, + onChange: this._handleDeviceDropdownChange, + value: this.state.selectedDevice + }); } - _handleDeviceDropdownChange(selectedDevice: ?Device): void { + _handleDeviceDropdownChange(selectedDevice) { this.setState({ - selectedDevice, + selectedDevice }); this.props.onChange(selectedDevice); } } +exports.AdbDeviceSelector = AdbDeviceSelector; \ No newline at end of file diff --git a/modules/nuclide-debugger-common/AutoGenLaunchAttachProvider.js b/modules/nuclide-debugger-common/AutoGenLaunchAttachProvider.js index 6cae51d379..75aa7660d4 100644 --- a/modules/nuclide-debugger-common/AutoGenLaunchAttachProvider.js +++ b/modules/nuclide-debugger-common/AutoGenLaunchAttachProvider.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 strict-local - * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -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'; - -const LaunchAttachProviderDefaultIsEnabled = ( - action: DebuggerConfigAction, - config: AutoGenConfig, -) => { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AutoGenLaunchAttachProvider = undefined; + +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, config) => { return Promise.resolve(config[action] != null); -}; - -export 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. + * + * strict-local + * @format + */ + +class AutoGenLaunchAttachProvider extends (_DebuggerLaunchAttachProvider || _load_DebuggerLaunchAttachProvider()).default { + + constructor(debuggingTypeName, targetUri, config, isEnabled = LaunchAttachProviderDefaultIsEnabled) { super(debuggingTypeName, targetUri); this._config = config; this._isEnabled = isEnabled; } - async _resolvePath(project: NuclideUri, filePath: string): Promise { - let rpcService: ?nuclide$RpcService = null; + async _resolvePath(project, filePath) { + 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) { - const fsService = rpcService.getServiceByNuclideUri( - 'FileSystemService', - project, - ); + const fsService = rpcService.getServiceByNuclideUri('FileSystemService', project); if (fsService != null) { try { return fsService.expandHomeDir(filePath); @@ -64,42 +63,41 @@ export class AutoGenLaunchAttachProvider extends DebuggerLaunchAttachProvider { return Promise.resolve(filePath); } - getCallbacksForAction(action: DebuggerConfigAction) { + getCallbacksForAction(action) { return { /** * Whether this provider is enabled or not. */ - isEnabled: async (): Promise => { + isEnabled: async () => { return this._isEnabled(action, this._config); }, /** * Returns a list of supported debugger types + environments for the specified action. */ - getDebuggerTypeNames: super.getCallbacksForAction(action) - .getDebuggerTypeNames, + getDebuggerTypeNames: super.getCallbacksForAction(action).getDebuggerTypeNames, /** * Returns the UI component for configuring the specified debugger type and action. */ - getComponent: ( - debuggerTypeName: string, - configIsValidChanged: (valid: boolean) => void, - ) => { + getComponent: (debuggerTypeName, configIsValidChanged) => { const launchOrAttachConfig = this._config[action]; - invariant(launchOrAttachConfig != null); - return ( - - ); - }, + + 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, + pathResolver: this._resolvePath + }); + } }; } - dispose(): void {} + dispose() {} } +exports.AutoGenLaunchAttachProvider = AutoGenLaunchAttachProvider; \ No newline at end of file diff --git a/modules/nuclide-debugger-common/AutoGenLaunchAttachUiComponent.js b/modules/nuclide-debugger-common/AutoGenLaunchAttachUiComponent.js index dfb5c68623..e7dd2a63fc 100644 --- a/modules/nuclide-debugger-common/AutoGenLaunchAttachUiComponent.js +++ b/modules/nuclide-debugger-common/AutoGenLaunchAttachUiComponent.js @@ -1,3 +1,100 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +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 _DeviceAndPackage; + +function _load_DeviceAndPackage() { + return _DeviceAndPackage = require('./DeviceAndPackage'); +} + +var _DeviceAndProcess; + +function _load_DeviceAndProcess() { + return _DeviceAndProcess = require('./DeviceAndProcess'); +} + +var _SelectableFilterableProcessTable; + +function _load_SelectableFilterableProcessTable() { + return _SelectableFilterableProcessTable = _interopRequireDefault(require('./SelectableFilterableProcessTable')); +} + +var _SourceSelector; + +function _load_SourceSelector() { + return _SourceSelector = require('./SourceSelector'); +} + +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; } } + +// extension must be a string starting with a '.' like '.js' or '.py' /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,94 +103,134 @@ * LICENSE file in 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 {AndroidJavaProcess} from 'nuclide-adb/lib/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - AutoGenProperty, - AutoGenLaunchOrAttachConfig, - AutoGenPropertyType, - AutoGenPropertyPrimitiveType, - Device, -} 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 {DeviceAndPackage} from './DeviceAndPackage'; -import {DeviceAndProcess} from './DeviceAndProcess'; -import SelectableFilterableProcessTable from './SelectableFilterableProcessTable'; -import {SourceSelector} from './SourceSelector'; - -type StringPair = [string, string]; - -type Props = {| - +targetUri: NuclideUri, - +configIsValidChanged: (valid: boolean) => void, - +config: AutoGenLaunchOrAttachConfig, - +debuggerTypeName: string, - +pathResolver: (project: NuclideUri, filePath: string) => Promise, -|}; - -type DeviceAndPackageType = {| - +device: ?Device, - +selectedPackage: string, -|}; - -type DeviceAndProcessType = {| - +device: ?Device, - +selectedProcess: ?AndroidJavaProcess, -|}; - -type State = { - enumValues: Map, - booleanValues: Map, - atomInputValues: Map, - processTableValues: Map, - deviceAndPackageValues: Map, - deviceAndProcessValues: Map, - selectSourcesValues: 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) - ) { +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; +class AutoGenLaunchAttachUiComponent extends _react.Component { - constructor(props: Props) { + constructor(props) { super(props); - this._disposables = new UniversalDisposable(); + + this._handleDebugButtonClick = async () => { + const { targetUri, config } = this.props; + const { + atomInputValues, + booleanValues, + enumValues, + processTableValues, + deviceAndPackageValues, + deviceAndProcessValues, + selectSourcesValues + } = 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(); + await Promise.all(Array.from(this._getConfigurationProperties().filter(property => property.visible && atomInputValues.has(property.name)).map(async property => { + var _ref3; + + const { name, type } = property; + const itemType = (_ref3 = property) != null ? _ref3.itemType : _ref3; + const value = atomInputValues.get(name) || ''; + if (type === 'path') { + try { + const resolvedPath = this.props.pathResolver == null ? value : await this.props.pathResolver(targetUri, value); + stringValues.set(name, resolvedPath); + } catch (_) { + stringValues.set(name, value); + } + } else if (type === 'string') { + stringValues.set(name, value); + } else if (type === 'array' && itemType === 'string') { + stringArrayValues.set(name, (0, (_string || _load_string()).shellParse)(value)); + } else if (type === 'object') { + const objectValue = {}; + (0, (_string || _load_string()).shellParse)(value).forEach(variable => { + const [lhs, rhs] = variable.split('='); + objectValue[lhs] = rhs; + }); + objectValues.set(name, objectValue); + } else if (type === 'number') { + numberValues.set(name, Number(value)); + } else if (type === 'json') { + jsonValues.set(name, JSON.parse(value)); + } + + return value; + }))); + + const packageValues = new Map(); + this._getConfigurationProperties().filter(property => property.visible && deviceAndPackageValues.has(property.name)).forEach(property => { + const deviceAndPackage = deviceAndPackageValues.get(property.name); + if (deviceAndPackage != null) { + packageValues.set(property.name, deviceAndPackage.selectedPackage); + } + }); + + const processValues = new Map(); + this._getConfigurationProperties().filter(property => property.visible && deviceAndProcessValues.has(property.name)).forEach(property => { + var _ref4, _ref5; + + const deviceAndProcess = deviceAndProcessValues.get(property.name); + const processName = (_ref4 = deviceAndProcess) != null ? (_ref5 = _ref4.selectedProcess) != null ? _ref5.name : _ref5 : _ref4; + if (deviceAndProcess != null && processName != null) { + processValues.set(property.name, processName); + } + }); + + const values = {}; + [booleanValues, enumValues, stringValues, stringArrayValues, objectValues, numberValues, processTableValues, jsonValues, deviceAndPackageValues, deviceAndProcessValues, selectSourcesValues].forEach(map => { + map.forEach((value, key) => { + values[key] = value; + }); + }); + + this._getConfigurationProperties().filter(property => !property.visible && !atomInputValues.has(property.name)).forEach(property => { + var _ref6; + + const { name } = property; + values[name] = (_ref6 = property) != null ? _ref6.defaultValue : _ref6; + }); + + const debuggerService = await (0, (_debugger || _load_debugger()).getDebuggerService)(); + debuggerService.startVspDebugging({ + targetUri, + debugMode: launch ? 'launch' : 'attach', + adapterType: vsAdapterType, + adapterExecutable: null, + config: values, + capabilities: { threads }, + properties: { + customControlButtons: [], + threadsComponentTitle: 'Threads' + }, + customDisposable: new (_UniversalDisposable || _load_UniversalDisposable()).default() + }); + + (0, (_DebuggerConfigSerializer || _load_DebuggerConfigSerializer()).serializeDebuggerConfig)(...this._getSerializationArgs(this.props), { + atomInputValues: Array.from(atomInputValues), + booleanValues: Array.from(booleanValues), + enumValues: Array.from(enumValues), + packageValues: Array.from(packageValues), + processValues: Array.from(processValues), + selectSourcesValues: Array.from(selectSourcesValues) + }); + }; + + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this.state = { atomInputValues: new Map(), booleanValues: new Map(), @@ -101,183 +238,128 @@ export default class AutoGenLaunchAttachUiComponent extends React.Component< processTableValues: new Map(), deviceAndPackageValues: new Map(), deviceAndProcessValues: new Map(), - selectSourcesValues: new Map(), + selectSourcesValues: new Map() }; } - _atomInputType( - type: AutoGenPropertyType, - itemType: ?AutoGenPropertyPrimitiveType, - ): boolean { - return ( - type === 'string' || - type === 'path' || - (type === 'array' && itemType === 'string') || - type === 'object' || - type === 'number' || - type === 'json' - ); + _atomInputType(type, itemType) { + return type === 'string' || type === 'path' || type === 'array' && itemType === 'string' || type === 'object' || type === 'number' || type === 'json'; } - _getConfigurationProperties(): AutoGenProperty[] { - const {config} = this.props; + _getConfigurationProperties() { + const { config } = this.props; return config.properties; } - _populateDefaultValues( - config: AutoGenLaunchOrAttachConfig, - atomInputValues: Map, - booleanValues: Map, - enumValues: Map, - ): void { + _populateDefaultValues(config, atomInputValues, booleanValues, enumValues) { config.properties.filter(property => property.visible).map(property => { - const {name, type} = property; - const itemType = idx(property, _ => _.itemType); + 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' - ) { + 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) - : ''; + 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' - ) { + 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' - ) { + 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, - ]; + _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: 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); - } + _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); - } + } + 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 these values: - const processTableValues = new Map(); - const deviceAndPackageValues = new Map(); - const deviceAndProcessValues = new Map(); - - this.setState({ - atomInputValues, - booleanValues, - enumValues, - processTableValues, - deviceAndPackageValues, - deviceAndProcessValues, - }); - }, - ); + } + const booleanValues = new Map(savedSettings.booleanValues || []); + const enumValues = new Map(savedSettings.enumValues || []); + this._populateDefaultValues(config, atomInputValues, booleanValues, enumValues); + // do not serialize and deserialize these values: + const processTableValues = new Map(); + const deviceAndPackageValues = new Map(); + const deviceAndProcessValues = new Map(); + + this.setState({ + atomInputValues, + booleanValues, + enumValues, + processTableValues, + deviceAndPackageValues, + deviceAndProcessValues + }); + }); } - setState(newState: Object): void { - super.setState(newState, () => - this.props.configIsValidChanged(this._debugButtonShouldEnable()), - ); + setState(newState) { + super.setState(newState, () => this.props.configIsValidChanged(this._debugButtonShouldEnable())); } - componentWillReceiveProps(nextProps: Props) { + componentWillReceiveProps(nextProps) { if (nextProps.debuggerTypeName !== this.props.debuggerTypeName) { this._deserializeDebuggerConfig(nextProps); } } - componentWillMount(): void { + componentWillMount() { this._deserializeDebuggerConfig(this.props); } - componentDidMount(): void { - this._disposables.add( - atom.commands.add('atom-workspace', { - 'core:confirm': async () => { - if (this._debugButtonShouldEnable()) { - await this._handleDebugButtonClick(); - } - }, - }), - ); + componentDidMount() { + this._disposables.add(atom.commands.add('atom-workspace', { + 'core:confirm': async () => { + if (this._debugButtonShouldEnable()) { + await this._handleDebugButtonClick(); + } + } + })); } - componentWillUnmount(): void { + componentWillUnmount() { this._disposables.dispose(); } - _valueExists(property: AutoGenProperty): boolean { - const {name, type} = property; + _valueExists(property) { + const { name, type } = property; if (type === 'string' || type === 'path') { const value = this.state.atomInputValues.get(name); return value != null && value !== ''; @@ -295,18 +377,10 @@ export default class AutoGenLaunchAttachUiComponent extends React.Component< return value != null; } else if (type === 'deviceAndPackage') { const deviceAndPackageValue = this.state.deviceAndPackageValues.get(name); - return ( - deviceAndPackageValue != null && - deviceAndPackageValue.device != null && - deviceAndPackageValue.selectedPackage != null - ); + return deviceAndPackageValue != null && deviceAndPackageValue.device != null && deviceAndPackageValue.selectedPackage != null; } else if (type === 'deviceAndProcess') { const deviceAndProcessValue = this.state.deviceAndProcessValues.get(name); - return ( - deviceAndProcessValue != null && - deviceAndProcessValue.device != null && - deviceAndProcessValue.selectedProcess != null - ); + return deviceAndProcessValue != null && deviceAndProcessValue.device != null && deviceAndProcessValue.selectedProcess != null; } else if (type === 'selectSources') { const selectSourcesValue = this.state.selectSourcesValues.get(name); return selectSourcesValue != null; @@ -314,322 +388,179 @@ export default class AutoGenLaunchAttachUiComponent extends React.Component< return false; } - _debugButtonShouldEnable(): boolean { - return this._getConfigurationProperties() - .filter(p => p.required) - .every(p => this._valueExists(p)); + _debugButtonShouldEnable() { + 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); + _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 ( -
      - {nameLabel} - { - this.state.atomInputValues.set(name, newValue); - this.props.configIsValidChanged(this._debugButtonShouldEnable()); - }} - /> -
      + 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 ( -
      -
      {nameLabel}
      - { - this.state.booleanValues.set(name, newValue); - this.props.configIsValidChanged(this._debugButtonShouldEnable()); - }} - /> -
      + 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 ( -
      - {nameLabel} - ( - - ))} - onSelectedChange={index => { - this.state.enumValues.set(name, enums[index]); - this.props.configIsValidChanged(this._debugButtonShouldEnable()); - }} - /> -
      + 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 ( -
      - {nameLabel} - { - if (selectedProcess != null) { - this.state.processTableValues.set(name, selectedProcess.pid); - } else { - this.state.processTableValues.delete(name); - } - this.props.configIsValidChanged(this._debugButtonShouldEnable()); - }} - /> -
      - ); - } else if (type === 'deviceAndPackage') { - return ( - { - let packageValuesArray: Array = []; - deserializeDebuggerConfig( - ...this._getSerializationArgs(this.props), - (transientSettings, savedSettings) => { - packageValuesArray = - (savedSettings.packageValues: Array) || []; - }, - ); - const packageValues = new Map(packageValuesArray); - return packageValues.get(name) || null; - }} - onSelect={(device, javaPackage) => { - this.state.deviceAndPackageValues.set(name, { - device, - selectedPackage: javaPackage, - }); + 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()); - }} - /> + } + }) ); + } else if (type === 'deviceAndPackage') { + return _react.createElement((_DeviceAndPackage || _load_DeviceAndPackage()).DeviceAndPackage, { + targetUri: this.props.targetUri, + deserialize: () => { + let packageValuesArray = []; + (0, (_DebuggerConfigSerializer || _load_DebuggerConfigSerializer()).deserializeDebuggerConfig)(...this._getSerializationArgs(this.props), (transientSettings, savedSettings) => { + packageValuesArray = savedSettings.packageValues || []; + }); + const packageValues = new Map(packageValuesArray); + return packageValues.get(name) || null; + }, + onSelect: (device, javaPackage) => { + this.state.deviceAndPackageValues.set(name, { + device, + selectedPackage: javaPackage + }); + this.props.configIsValidChanged(this._debugButtonShouldEnable()); + } + }); } else if (type === 'deviceAndProcess') { - return ( - { - let processValuesArray: Array = []; - deserializeDebuggerConfig( - ...this._getSerializationArgs(this.props), - (transientSettings, savedSettings) => { - processValuesArray = - (savedSettings.processValues: Array) || []; - }, - ); - const processValues = new Map(processValuesArray); - return processValues.get(name) || null; - }} - onSelect={(device, javaProcess) => { - this.state.deviceAndProcessValues.set(name, { - device, - selectedProcess: javaProcess, + return _react.createElement((_DeviceAndProcess || _load_DeviceAndProcess()).DeviceAndProcess, { + targetUri: this.props.targetUri, + deserialize: () => { + let processValuesArray = []; + (0, (_DebuggerConfigSerializer || _load_DebuggerConfigSerializer()).deserializeDebuggerConfig)(...this._getSerializationArgs(this.props), (transientSettings, savedSettings) => { + processValuesArray = savedSettings.processValues || []; + }); + const processValues = new Map(processValuesArray); + return processValues.get(name) || null; + }, + onSelect: (device, javaProcess) => { + this.state.deviceAndProcessValues.set(name, { + device, + selectedProcess: javaProcess + }); + this.props.configIsValidChanged(this._debugButtonShouldEnable()); + } + }); + } else if (type === 'selectSources') { + return _react.createElement( + 'div', + null, + nameLabel, + _react.createElement((_SourceSelector || _load_SourceSelector()).SourceSelector, { + deserialize: () => { + let selectSourcesValuesArray = []; + (0, (_DebuggerConfigSerializer || _load_DebuggerConfigSerializer()).deserializeDebuggerConfig)(...this._getSerializationArgs(this.props), (transientSettings, savedSettings) => { + selectSourcesValuesArray = savedSettings.selectSourcesValues || []; }); + const selectSourcesValues = new Map(selectSourcesValuesArray); + return selectSourcesValues.get(name) || null; + }, + onSelect: selectedSource => { + this.state.selectSourcesValues.set(name, selectedSource); this.props.configIsValidChanged(this._debugButtonShouldEnable()); - }} - /> - ); - } else if (type === 'selectSources') { - return ( -
      - {nameLabel} - { - let selectSourcesValuesArray: Array = []; - deserializeDebuggerConfig( - ...this._getSerializationArgs(this.props), - (transientSettings, savedSettings) => { - selectSourcesValuesArray = - (savedSettings.selectSourcesValues: Array) || - []; - }, - ); - const selectSourcesValues = new Map(selectSourcesValuesArray); - return selectSourcesValues.get(name) || null; - }} - onSelect={selectedSource => { - this.state.selectSourcesValues.set(name, selectedSource); - this.props.configIsValidChanged(this._debugButtonShouldEnable()); - }} - /> -
      + } + }) ); } - return ( -
      - -
      -
      + return _react.createElement( + 'div', + null, + _react.createElement( + 'label', + null, + 'NO TRANSLATION YET FOR: ', + (0, (_string || _load_string()).capitalize)(name) + ), + _react.createElement('hr', null) ); } - render(): React.Node { - const {debuggerTypeName, config} = this.props; - return ( -
      - {config.header} - {this._getConfigurationProperties() - .filter(property => property.visible) - .map(property => ( -
      - {this._getComponentForProperty(property)} -
      - ))} -
      + 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) + )) ); } - _handleDebugButtonClick = async (): Promise => { - const {targetUri, config} = this.props; - const { - atomInputValues, - booleanValues, - enumValues, - processTableValues, - deviceAndPackageValues, - deviceAndProcessValues, - selectSourcesValues, - } = 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(); - await Promise.all( - Array.from( - this._getConfigurationProperties() - .filter( - property => property.visible && atomInputValues.has(property.name), - ) - .map(async property => { - const {name, type} = property; - const itemType = idx(property, _ => _.itemType); - const value = atomInputValues.get(name) || ''; - if (type === 'path') { - try { - const resolvedPath = - this.props.pathResolver == null - ? value - : await this.props.pathResolver(targetUri, value); - stringValues.set(name, resolvedPath); - } catch (_) { - stringValues.set(name, value); - } - } else if (type === 'string') { - stringValues.set(name, value); - } else if (type === 'array' && itemType === 'string') { - stringArrayValues.set(name, shellParse(value)); - } else if (type === 'object') { - const objectValue = {}; - shellParse(value).forEach(variable => { - const [lhs, rhs] = variable.split('='); - objectValue[lhs] = rhs; - }); - objectValues.set(name, objectValue); - } else if (type === 'number') { - numberValues.set(name, Number(value)); - } else if (type === 'json') { - jsonValues.set(name, JSON.parse(value)); - } - - return value; - }), - ), - ); - - const packageValues = new Map(); - this._getConfigurationProperties() - .filter( - property => - property.visible && deviceAndPackageValues.has(property.name), - ) - .forEach(property => { - const deviceAndPackage = deviceAndPackageValues.get(property.name); - if (deviceAndPackage != null) { - packageValues.set(property.name, deviceAndPackage.selectedPackage); - } - }); - - const processValues = new Map(); - this._getConfigurationProperties() - .filter( - property => - property.visible && deviceAndProcessValues.has(property.name), - ) - .forEach(property => { - const deviceAndProcess = deviceAndProcessValues.get(property.name); - const processName = idx(deviceAndProcess, _ => _.selectedProcess.name); - if (deviceAndProcess != null && processName != null) { - processValues.set(property.name, processName); - } - }); - - const values = {}; - [ - booleanValues, - enumValues, - stringValues, - stringArrayValues, - objectValues, - numberValues, - processTableValues, - jsonValues, - deviceAndPackageValues, - deviceAndProcessValues, - selectSourcesValues, - ].forEach(map => { - map.forEach((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); - }); - - const debuggerService = await getDebuggerService(); - debuggerService.startVspDebugging({ - targetUri, - debugMode: launch ? 'launch' : 'attach', - adapterType: vsAdapterType, - adapterExecutable: null, - config: values, - capabilities: {threads}, - properties: { - customControlButtons: [], - threadsComponentTitle: 'Threads', - }, - customDisposable: new UniversalDisposable(), - }); - - serializeDebuggerConfig(...this._getSerializationArgs(this.props), { - atomInputValues: Array.from(atomInputValues), - booleanValues: Array.from(booleanValues), - enumValues: Array.from(enumValues), - packageValues: Array.from(packageValues), - processValues: Array.from(processValues), - selectSourcesValues: Array.from(selectSourcesValues), - }); - }; } +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 954c186b68..e1738a3280 100644 --- a/modules/nuclide-debugger-common/DebuggerConfigSerializer.js +++ b/modules/nuclide-debugger-common/DebuggerConfigSerializer.js @@ -1,38 +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 - */ -/* global localStorage */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.serializeDebuggerConfig = serializeDebuggerConfig; +exports.deserializeDebuggerConfig = deserializeDebuggerConfig; -import type {DebuggerConfigAction} from './types'; // 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 = {}; +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: string, - action: DebuggerConfigAction, - debuggerName: string, -) { +function _getStorageKey(host, action, debuggerName) { return 'NUCLIDE_DEBUGGER_CONFIG_' + host + '_' + action + '_' + debuggerName; } -export function serializeDebuggerConfig( - host: string, - action: DebuggerConfigAction, - debuggerName: string, - persistent: Object, - transient?: Object, -): void { +function serializeDebuggerConfig(host, action, debuggerName, persistent, transient) { if (global.localStorage == null) { throw new Error('localStorage is not available in this runtime'); } @@ -46,19 +41,14 @@ export function serializeDebuggerConfig( } } -export function deserializeDebuggerConfig( - host: string, - action: DebuggerConfigAction, - debuggerName: string, - callback: (transientSettings: Object, persistentSettings: Object) => void, -): void { +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): any) : {}; + 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 dcf632d006..1bc34e2fef 100644 --- a/modules/nuclide-debugger-common/DebuggerLaunchAttachProvider.js +++ b/modules/nuclide-debugger-common/DebuggerLaunchAttachProvider.js @@ -1,46 +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 - */ +'use strict'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {DebuggerConfigAction} from './types'; -import * as React from 'react'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -let uniqueKeySeed = 0; +var _react = _interopRequireWildcard(require('react')); -export type callbacksForAction = { - isEnabled: () => Promise, - getDebuggerTypeNames: () => Array, - getComponent: ( - debuggerTypeName: string, - configIsValidChanged: (valid: boolean) => void, - ) => ?React.Element, -}; +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; +class DebuggerLaunchAttachProvider { - constructor(debuggingTypeName: string, targetUri: NuclideUri) { + 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. @@ -59,33 +51,31 @@ export default class DebuggerLaunchAttachProvider { /** * Returns the UI component for configuring the specified debugger type and action. */ - getComponent: ( - debuggerTypeName: string, - configIsValidChanged: (valid: boolean) => void, - ) => { + getComponent: (debuggerTypeName, configIsValidChanged) => { throw new Error('abstract method'); - }, + } }; } /** * Returns a unique key which can be associated with the component. */ - getUniqueKey(): number { + getUniqueKey() { return this._uniqueKey; } /** * Returns target uri for this provider. */ - getTargetUri(): NuclideUri { + getTargetUri() { return this._targetUri; } /** * Dispose any resource held by this provider. */ - dispose(): void { + dispose() { throw new Error('abstract method'); } } +exports.default = DebuggerLaunchAttachProvider; \ No newline at end of file diff --git a/modules/nuclide-debugger-common/DeviceAndPackage.js b/modules/nuclide-debugger-common/DeviceAndPackage.js index 7bec553e48..20a3074c74 100644 --- a/modules/nuclide-debugger-common/DeviceAndPackage.js +++ b/modules/nuclide-debugger-common/DeviceAndPackage.js @@ -1,3 +1,64 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DeviceAndPackage = undefined; + +var _nuclideAdb; + +function _load_nuclideAdb() { + return _nuclideAdb = require('../nuclide-adb'); +} + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../nuclide-commons-ui/AtomInput'); +} + +var _Dropdown; + +function _load_Dropdown() { + return _Dropdown = require('../nuclide-commons-ui/Dropdown'); +} + +var _LoadingSpinner; + +function _load_LoadingSpinner() { + return _LoadingSpinner = require('../nuclide-commons-ui/LoadingSpinner'); +} + +var _debounce; + +function _load_debounce() { + return _debounce = _interopRequireDefault(require('../nuclide-commons/debounce')); +} + +var _expected; + +function _load_expected() { + return _expected = require('../nuclide-commons/expected'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _AdbDeviceSelector; + +function _load_AdbDeviceSelector() { + return _AdbDeviceSelector = require('./AdbDeviceSelector'); +} + +var _EmulatorUtils; + +function _load_EmulatorUtils() { + return _EmulatorUtils = require('./EmulatorUtils'); +} + +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. @@ -6,146 +67,108 @@ * LICENSE file in 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 {Expected} from 'nuclide-commons/expected'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {Device} from './types'; - -import {getAdbServiceByNuclideUri} from 'nuclide-adb'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {Dropdown} from 'nuclide-commons-ui/Dropdown'; -import {LoadingSpinner} from 'nuclide-commons-ui/LoadingSpinner'; -import debounce from 'nuclide-commons/debounce'; -import {Expect} from 'nuclide-commons/expected'; -import * as React from 'react'; -import {AdbDeviceSelector} from './AdbDeviceSelector'; -import {getAdbPath, setAdbPath, addAdbPorts} from './EmulatorUtils'; - -type Props = {| - +targetUri: NuclideUri, - +onSelect: (device: ?Device, javaPackage: string) => void, - +deserialize: () => ?string, -|}; - -type State = { - selectedDevice: ?Device, - launchPackage: string, - packages: Expected>, - adbPorts: string, -}; - -export class DeviceAndPackage extends React.Component { - constructor(props: Props) { +class DeviceAndPackage extends _react.Component { + constructor(props) { super(props); - (this: any)._setAdbPorts = debounce(this._setAdbPorts.bind(this), 1000); + + this._handleDeviceChange = device => { + const state = { + selectedDevice: device, + packages: device == null ? (_expected || _load_expected()).Expect.value([]) : (_expected || _load_expected()).Expect.pendingValue([]) + }; + const value = this.props.deserialize(); + if (device != null && (this.state.selectedDevice == null || device.name !== this.state.selectedDevice.name) && value != null) { + state.launchPackage = value; + } + + this.setState(state, () => { + this._refreshPackageList(device); + }); + }; + + this._setAdbPorts = (0, (_debounce || _load_debounce()).default)(this._setAdbPorts.bind(this), 1000); this.state = { selectedDevice: null, launchPackage: '', - packages: Expect.value([]), - adbPorts: '', + packages: (_expected || _load_expected()).Expect.value([]), + adbPorts: '' }; } - async _setAdbPorts(value: string): Promise { - setAdbPath(this.props.targetUri, await getAdbPath()); + async _setAdbPorts(value) { + (0, (_EmulatorUtils || _load_EmulatorUtils()).setAdbPath)(this.props.targetUri, (await (0, (_EmulatorUtils || _load_EmulatorUtils()).getAdbPath)())); - const parsedPorts = value - .split(/,\s*/) - .map(port => parseInt(port.trim(), 10)) - .filter(port => !Number.isNaN(port)); + const parsedPorts = value.split(/,\s*/).map(port => parseInt(port.trim(), 10)).filter(port => !Number.isNaN(port)); - addAdbPorts(this.props.targetUri, parsedPorts); - this.setState({adbPorts: value, selectedDevice: null}); + (0, (_EmulatorUtils || _load_EmulatorUtils()).addAdbPorts)(this.props.targetUri, parsedPorts); + this.setState({ adbPorts: value, selectedDevice: null }); } - async _refreshPackageList(device: ?Device) { + async _refreshPackageList(device) { if (device != null) { - const packages = Expect.value( - (await getAdbServiceByNuclideUri( - this.props.targetUri, - ).getInstalledPackages(device)).sort(), - ); + const packages = (_expected || _load_expected()).Expect.value((await (0, (_nuclideAdb || _load_nuclideAdb()).getAdbServiceByNuclideUri)(this.props.targetUri).getInstalledPackages(device)).sort()); this.setState({ - packages, + packages }); } else { this.setState({ - packages: Expect.value([]), + packages: (_expected || _load_expected()).Expect.value([]) }); } } - setState(partialState: Object, callback?: () => mixed): void { - const fullState: State = { - ...this.state, - ...partialState, - }; + setState(partialState, callback) { + const fullState = Object.assign({}, this.state, partialState); super.setState(fullState, () => { this.props.onSelect(fullState.selectedDevice, fullState.launchPackage); callback && callback(); }); } - _handleDeviceChange = (device: ?Device): void => { - const state: $Shape = { - selectedDevice: device, - packages: device == null ? Expect.value([]) : Expect.pendingValue([]), - }; - const value = this.props.deserialize(); - if ( - device != null && - (this.state.selectedDevice == null || - device.name !== this.state.selectedDevice.name) && - value != null - ) { - state.launchPackage = value; - } - - this.setState(state, () => { - this._refreshPackageList(device); - }); - }; - - render(): React.Node { - const devicesLabel = - this.state.adbPorts === '' - ? '' - : '(ADB port ' + this.state.adbPorts + ')'; - return ( -
      - - this._setAdbPorts(value)} - /> - - - - {this.state.packages.isPending ? ( - - ) : ( - { - return {value: packageName, label: packageName}; - }) - } - onChange={value => this.setState({launchPackage: value})} - value={this.state.launchPackage} - /> - )} -
      + render() { + const devicesLabel = this.state.adbPorts === '' ? '' : '(ADB port ' + this.state.adbPorts + ')'; + return _react.createElement( + 'div', + { className: 'block' }, + _react.createElement( + 'label', + null, + 'ADB Server Port: ' + ), + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + placeholderText: 'Optional. (For One World devices, specify ANDROID_ADB_SERVER_PORT from one_world_adb)', + title: 'Optional. (For One World devices, specify ANDROID_ADB_SERVER_PORT from one_world_adb)', + value: this.state.adbPorts, + onDidChange: value => this._setAdbPorts(value) + }), + _react.createElement( + 'label', + null, + 'Device: ', + devicesLabel + ), + _react.createElement((_AdbDeviceSelector || _load_AdbDeviceSelector()).AdbDeviceSelector, { + onChange: this._handleDeviceChange, + targetUri: this.props.targetUri + }), + _react.createElement( + 'label', + null, + 'Package: ' + ), + this.state.packages.isPending ? _react.createElement((_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinner, { size: 'EXTRA_SMALL' }) : _react.createElement((_Dropdown || _load_Dropdown()).Dropdown, { + disabled: this.state.selectedDevice == null, + options: this.state.packages.isPending || this.state.packages.isError ? [] : this.state.packages.value.map(packageName => { + return { value: packageName, label: packageName }; + }), + onChange: value => this.setState({ launchPackage: value }), + value: this.state.launchPackage + }) ); } } +exports.DeviceAndPackage = DeviceAndPackage; \ No newline at end of file diff --git a/modules/nuclide-debugger-common/DeviceAndProcess.js b/modules/nuclide-debugger-common/DeviceAndProcess.js index 6c2ec86fbf..b7c383d1cf 100644 --- a/modules/nuclide-debugger-common/DeviceAndProcess.js +++ b/modules/nuclide-debugger-common/DeviceAndProcess.js @@ -1,78 +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 {AndroidJavaProcess} from 'nuclide-adb/lib/types'; -import type {Column, Row} from 'nuclide-commons-ui/Table'; -import type {Expected} from 'nuclide-commons/expected'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {Subscription} from 'rxjs'; -import type {Device} from './types'; - -import idx from 'idx'; -import {getAdbServiceByNuclideUri} from 'nuclide-adb'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {LoadingSpinner} from 'nuclide-commons-ui/LoadingSpinner'; -import {Table} from 'nuclide-commons-ui/Table'; -import {arrayEqual} from 'nuclide-commons/collection'; -import debounce from 'nuclide-commons/debounce'; -import {Expect} from 'nuclide-commons/expected'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import * as React from 'react'; -import {Observable} from 'rxjs'; -import {AdbDeviceSelector} from './AdbDeviceSelector'; -import {getAdbPath, setAdbPath, addAdbPorts} from './EmulatorUtils'; - -type ColumnName = 'pid' | 'user' | 'name'; - -type Props = {| - +targetUri: NuclideUri, - +onSelect: (device: ?Device, javaProcess: ?AndroidJavaProcess) => void, - +deserialize: () => ?string, -|}; - -type State = { - selectedDevice: ?Device, - javaProcesses: Expected>, - selectedProcess: ?AndroidJavaProcess, - selectedProcessName: ?string, - sortedColumn: ?ColumnName, - sortDescending: boolean, - adbPorts: string, -}; - -export class DeviceAndProcess extends React.Component { - _disposables: UniversalDisposable; - _javaProcessSubscription: ?Subscription; - - constructor(props: Props) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DeviceAndProcess = undefined; + +var _idx; + +function _load_idx() { + return _idx = _interopRequireDefault(require('idx')); +} + +var _nuclideAdb; + +function _load_nuclideAdb() { + return _nuclideAdb = require('../nuclide-adb'); +} + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../nuclide-commons-ui/AtomInput'); +} + +var _LoadingSpinner; + +function _load_LoadingSpinner() { + return _LoadingSpinner = require('../nuclide-commons-ui/LoadingSpinner'); +} + +var _Table; + +function _load_Table() { + return _Table = require('../nuclide-commons-ui/Table'); +} + +var _collection; + +function _load_collection() { + return _collection = require('../nuclide-commons/collection'); +} + +var _debounce; + +function _load_debounce() { + return _debounce = _interopRequireDefault(require('../nuclide-commons/debounce')); +} + +var _expected; + +function _load_expected() { + return _expected = require('../nuclide-commons/expected'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../nuclide-commons/UniversalDisposable')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _AdbDeviceSelector; + +function _load_AdbDeviceSelector() { + return _AdbDeviceSelector = require('./AdbDeviceSelector'); +} + +var _EmulatorUtils; + +function _load_EmulatorUtils() { + return _EmulatorUtils = require('./EmulatorUtils'); +} + +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 DeviceAndProcess extends _react.Component { + + constructor(props) { super(props); - this._disposables = new UniversalDisposable(); + this._handleDeviceChange = device => { + const oldDevice = this.state.selectedDevice; + if (oldDevice != null && device != null && oldDevice.name === device.name && oldDevice.port === device.port) { + // Same device selected. + return; + } + + if (this._javaProcessSubscription != null) { + this._javaProcessSubscription.unsubscribe(); + this._javaProcessSubscription = null; + } + + this.setState({ + selectedDevice: device, + javaProcesses: device == null ? (_expected || _load_expected()).Expect.value([]) : (_expected || _load_expected()).Expect.pendingValue([]), + selectedProcess: null, + selectedProcessName: this.props.deserialize() + }); + + if (device != null) { + // If a device is selected, observe the Java processes on the device. + const adbService = (0, (_nuclideAdb || _load_nuclideAdb()).getAdbServiceByNuclideUri)(this.props.targetUri); + this._javaProcessSubscription = _rxjsBundlesRxMinJs.Observable.interval(2000).startWith(0).switchMap(() => adbService.getJavaProcesses(device).refCount()).distinctUntilChanged((a, b) => (0, (_collection || _load_collection()).arrayEqual)(a, b, (x, y) => { + return x.user === y.user && x.pid === y.pid && x.name === y.name; + })).subscribe(javaProcesses => { + this._javaProcessListChanged((_expected || _load_expected()).Expect.value(javaProcesses)); + }); + } + }; + + this._handleSort = (sortedColumn, sortDescending) => { + this.setState({ sortedColumn, sortDescending }); + }; + + this._sortRows = (processes, sortedColumnName, sortDescending) => { + if (sortedColumnName == null) { + return processes; + } + + // Use a numerical comparison for the pid column, string compare for all the others. + const compare = sortedColumnName === 'pid' ? (a, b, isAsc) => { + const cmp = (a || 0) - (b || 0); + return isAsc ? cmp : -cmp; + } : (a, b, isAsc) => { + const cmp = String(a).toLowerCase().localeCompare(String(b).toLowerCase()); + return isAsc ? cmp : -cmp; + }; + + const getter = row => row.data[sortedColumnName]; + return [...processes].sort((a, b) => { + return compare(getter(a), getter(b), !sortDescending); + }); + }; + + this._handleSelectTableRow = (item, selectedIndex) => { + var _ref; + + this.setState({ + selectedProcess: item, + selectedProcessName: (_ref = item) != null ? _ref.name : _ref + }); + }; + + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._javaProcessSubscription = null; this._disposables.add(() => { if (this._javaProcessSubscription != null) { this._javaProcessSubscription.unsubscribe(); } }); - (this: any)._setAdbPorts = debounce(this._setAdbPorts.bind(this), 1000); + this._setAdbPorts = (0, (_debounce || _load_debounce()).default)(this._setAdbPorts.bind(this), 1000); this.state = { selectedDevice: null, - javaProcesses: Expect.value([]), + javaProcesses: (_expected || _load_expected()).Expect.value([]), selectedProcess: null, selectedProcessName: null, sortedColumn: 'name', sortDescending: false, - adbPorts: '', + adbPorts: '' }; } @@ -80,241 +171,132 @@ export class DeviceAndProcess extends React.Component { this._disposables.dispose(); } - async _setAdbPorts(value: string): Promise { - setAdbPath(this.props.targetUri, await getAdbPath()); + async _setAdbPorts(value) { + (0, (_EmulatorUtils || _load_EmulatorUtils()).setAdbPath)(this.props.targetUri, (await (0, (_EmulatorUtils || _load_EmulatorUtils()).getAdbPath)())); - const parsedPorts = value - .split(/,\s*/) - .map(port => parseInt(port.trim(), 10)) - .filter(port => !Number.isNaN(port)); + const parsedPorts = value.split(/,\s*/).map(port => parseInt(port.trim(), 10)).filter(port => !Number.isNaN(port)); - addAdbPorts(this.props.targetUri, parsedPorts); - this.setState({adbPorts: value, selectedDevice: null}); + (0, (_EmulatorUtils || _load_EmulatorUtils()).addAdbPorts)(this.props.targetUri, parsedPorts); + this.setState({ adbPorts: value, selectedDevice: null }); } - setState(partialState: Object, callback?: () => mixed): void { - const fullState: State = { - ...this.state, - ...partialState, - }; + setState(partialState, callback) { + const fullState = Object.assign({}, this.state, partialState); super.setState(fullState, () => { this.props.onSelect(fullState.selectedDevice, fullState.selectedProcess); callback && callback(); }); } - _handleDeviceChange = (device: ?Device): void => { - const oldDevice = this.state.selectedDevice; - if ( - oldDevice != null && - device != null && - oldDevice.name === device.name && - oldDevice.port === device.port - ) { - // Same device selected. - return; - } - - if (this._javaProcessSubscription != null) { - this._javaProcessSubscription.unsubscribe(); - this._javaProcessSubscription = null; - } - - this.setState({ - selectedDevice: device, - javaProcesses: - device == null ? Expect.value([]) : Expect.pendingValue([]), - selectedProcess: null, - selectedProcessName: this.props.deserialize(), - }); - - if (device != null) { - // If a device is selected, observe the Java processes on the device. - const adbService = getAdbServiceByNuclideUri(this.props.targetUri); - this._javaProcessSubscription = Observable.interval(2000) - .startWith(0) - .switchMap(() => adbService.getJavaProcesses(device).refCount()) - .distinctUntilChanged((a, b) => - arrayEqual(a, b, (x, y) => { - return x.user === y.user && x.pid === y.pid && x.name === y.name; - }), - ) - .subscribe(javaProcesses => { - this._javaProcessListChanged(Expect.value(javaProcesses)); - }); - } - }; - - _javaProcessListChanged(javaProcesses: Expected>) { - const selectedPid = - this.state.selectedProcess == null - ? null - : this.state.selectedProcess.pid; - let selectedProcess = - javaProcesses.isPending || javaProcesses.isError - ? null - : javaProcesses.value.find(process => process.pid === selectedPid); + _javaProcessListChanged(javaProcesses) { + const selectedPid = this.state.selectedProcess == null ? null : this.state.selectedProcess.pid; + let selectedProcess = javaProcesses.isPending || javaProcesses.isError ? null : javaProcesses.value.find(process => process.pid === selectedPid); if (this.state.selectedProcessName != null) { - selectedProcess = - javaProcesses.isPending || javaProcesses.isError - ? null - : javaProcesses.value.find( - process => process.name === this.state.selectedProcessName, - ); + selectedProcess = javaProcesses.isPending || javaProcesses.isError ? null : javaProcesses.value.find(process => process.name === this.state.selectedProcessName); } this.setState({ javaProcesses, selectedProcess, - selectedProcessName: - selectedProcess == null ? null : selectedProcess.name, + selectedProcessName: selectedProcess == null ? null : selectedProcess.name }); } - _getColumns(): Array> { - return [ - { - key: 'pid', - title: 'PID', - width: 0.1, - }, - { - key: 'user', - title: 'User', - width: 0.1, - }, - { - key: 'name', - title: 'Name', - width: 0.8, - }, - ]; + _getColumns() { + return [{ + key: 'pid', + title: 'PID', + width: 0.1 + }, { + key: 'user', + title: 'User', + width: 0.1 + }, { + key: 'name', + title: 'Name', + width: 0.8 + }]; } - _handleSort = (sortedColumn: ?ColumnName, sortDescending: boolean): void => { - this.setState({sortedColumn, sortDescending}); - }; - - _sortRows = ( - processes: Array>, - sortedColumnName: ?ColumnName, - sortDescending: boolean, - ): Array> => { - if (sortedColumnName == null) { - return processes; - } + render() { + const devicesLabel = this.state.adbPorts === '' ? '' : '(ADB port ' + this.state.adbPorts + ')'; - // Use a numerical comparison for the pid column, string compare for all the others. - const compare: any = - sortedColumnName === 'pid' - ? (a: ?number, b: ?number, isAsc: boolean): number => { - const cmp = (a || 0) - (b || 0); - return isAsc ? cmp : -cmp; - } - : (a: ?string, b: ?string, isAsc: boolean): number => { - const cmp = String(a) - .toLowerCase() - .localeCompare(String(b).toLowerCase()); - return isAsc ? cmp : -cmp; - }; - - const getter = row => row.data[sortedColumnName]; - return [...processes].sort((a, b) => { - return compare(getter(a), getter(b), !sortDescending); - }); - }; - - _handleSelectTableRow = ( - item: ?AndroidJavaProcess, - selectedIndex: number, - ): void => { - this.setState({ - selectedProcess: item, - selectedProcessName: idx(item, _ => _.name), - }); - }; - - render(): React.Node { - const devicesLabel = - this.state.adbPorts === '' - ? '' - : '(ADB port ' + this.state.adbPorts + ')'; - - const emptyMessage: string = - this.state.selectedDevice == null - ? 'No device selected' - : 'No debuggable Java processes found!'; - const emptyComponent = () => ( -
      - {this.state.javaProcesses.isPending ? ( - - ) : ( - emptyMessage - )} -
      + const emptyMessage = this.state.selectedDevice == null ? 'No device selected' : 'No debuggable Java processes found!'; + const emptyComponent = () => _react.createElement( + 'div', + null, + this.state.javaProcesses.isPending ? _react.createElement((_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinner, { size: 'EXTRA_SMALL' }) : emptyMessage ); - const processListRows = - !this.state.javaProcesses.isPending && !this.state.javaProcesses.isError - ? this._sortRows( - this.state.javaProcesses.value.map(processRow => { - const data = { - pid: processRow.pid, - user: processRow.user, - name: processRow.name, - }; - return {data}; - }), - this.state.sortedColumn, - this.state.sortDescending, - ) - : []; - - const selectedRows = - this.state.selectedProcess == null - ? [] - : processListRows.filter( - row => - this.state.selectedProcess == null || - (row.data.pid === this.state.selectedProcess.pid && - row.data.name === this.state.selectedProcess.name), - ); - const selectedRowIndex = - selectedRows.length === 1 ? processListRows.indexOf(selectedRows[0]) : -1; - - return ( -
      - - this._setAdbPorts(value)} - /> - - - -
    - + const processListRows = !this.state.javaProcesses.isPending && !this.state.javaProcesses.isError ? this._sortRows(this.state.javaProcesses.value.map(processRow => { + const data = { + pid: processRow.pid, + user: processRow.user, + name: processRow.name + }; + return { data }; + }), this.state.sortedColumn, this.state.sortDescending) : []; + + const selectedRows = this.state.selectedProcess == null ? [] : processListRows.filter(row => this.state.selectedProcess == null || row.data.pid === this.state.selectedProcess.pid && row.data.name === this.state.selectedProcess.name); + const selectedRowIndex = selectedRows.length === 1 ? processListRows.indexOf(selectedRows[0]) : -1; + + return _react.createElement( + 'div', + { className: 'block' }, + _react.createElement( + 'label', + null, + 'ADB Server Port: ' + ), + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + placeholderText: 'Optional. (For One World devices, specify ANDROID_ADB_SERVER_PORT from one_world_adb)', + title: 'Optional. (For One World devices, specify ANDROID_ADB_SERVER_PORT from one_world_adb)', + value: this.state.adbPorts, + onDidChange: value => this._setAdbPorts(value) + }), + _react.createElement( + 'label', + null, + 'Device: ', + devicesLabel + ), + _react.createElement((_AdbDeviceSelector || _load_AdbDeviceSelector()).AdbDeviceSelector, { + onChange: this._handleDeviceChange, + targetUri: this.props.targetUri + }), + _react.createElement( + 'label', + null, + 'Debuggable Java processes: ' + ), + _react.createElement((_Table || _load_Table()).Table, { + tabIndex: '12', + collapsable: false, + columns: this._getColumns(), + emptyComponent: emptyComponent, + fixedHeader: true, + maxBodyHeight: '99999px', + rows: processListRows, + sortable: true, + onSort: this._handleSort, + sortedColumn: this.state.sortedColumn, + sortDescending: this.state.sortDescending, + selectable: true, + selectedIndex: selectedRowIndex, + onSelect: this._handleSelectTableRow + }) ); } } +exports.DeviceAndProcess = DeviceAndProcess; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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/EmulatorUtils.js b/modules/nuclide-debugger-common/EmulatorUtils.js index 19674d6aca..44e2fba0fa 100644 --- a/modules/nuclide-debugger-common/EmulatorUtils.js +++ b/modules/nuclide-debugger-common/EmulatorUtils.js @@ -1,72 +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 strict-local - * @format - */ +'use strict'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.NUCLIDE_ONE_WORLD_ADB_PATH_NAME = undefined; +exports.getAdbPath = getAdbPath; +exports.getAdbPorts = getAdbPorts; +exports.addAdbPorts = addAdbPorts; +exports.setAdbPath = setAdbPath; -import {DEFAULT_ADB_PORT} from 'nuclide-adb/lib/common/DebugBridge'; -import {getAdbServiceByNuclideUri} from 'nuclide-adb'; -import invariant from 'assert'; +var _DebugBridge; -export const NUCLIDE_ONE_WORLD_ADB_PATH_NAME = 'NUCLIDE_ONE_WORLD_ADB_PATH'; +function _load_DebugBridge() { + return _DebugBridge = require('../nuclide-adb/lib/common/DebugBridge'); +} + +var _nuclideAdb; + +function _load_nuclideAdb() { + return _nuclideAdb = require('../nuclide-adb'); +} -export function getAdbPath(): string { - const atomConfigAdbPathName = atom.config.get( - NUCLIDE_ONE_WORLD_ADB_PATH_NAME, - ); - if ( - atomConfigAdbPathName != null && - typeof atomConfigAdbPathName === 'string' - ) { +const NUCLIDE_ONE_WORLD_ADB_PATH_NAME = exports.NUCLIDE_ONE_WORLD_ADB_PATH_NAME = 'NUCLIDE_ONE_WORLD_ADB_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. + * + * strict-local + * @format + */ + +function getAdbPath() { + const atomConfigAdbPathName = atom.config.get(NUCLIDE_ONE_WORLD_ADB_PATH_NAME); + if (atomConfigAdbPathName != null && typeof atomConfigAdbPathName === 'string') { return atomConfigAdbPathName; } return 'adb'; } -export async function getAdbPorts( - targetUri: NuclideUri, -): Promise> { - const adbService = getAdbServiceByNuclideUri(targetUri); +async function getAdbPorts(targetUri) { + const adbService = (0, (_nuclideAdb || _load_nuclideAdb()).getAdbServiceByNuclideUri)(targetUri); const ports = await adbService.getAdbPorts(); // Don't show the user the default adb port. This should always be included. - return ports.filter(port => port !== DEFAULT_ADB_PORT); + return ports.filter(port => port !== (_DebugBridge || _load_DebugBridge()).DEFAULT_ADB_PORT); } -export async function addAdbPorts( - targetUri: NuclideUri, - ports: Array, -): Promise { - const adbService = getAdbServiceByNuclideUri(targetUri); +async function addAdbPorts(targetUri, ports) { + const adbService = (0, (_nuclideAdb || _load_nuclideAdb()).getAdbServiceByNuclideUri)(targetUri); const existingPorts = await adbService.getAdbPorts(); // Remove any ports that are no longer in the list, but never remove // the default adb server port. // NOTE: the list of ports is expected to be very short here (like 5 items or less) for (const oldPort of existingPorts) { - if (oldPort !== DEFAULT_ADB_PORT && !ports.includes(oldPort)) { + if (oldPort !== (_DebugBridge || _load_DebugBridge()).DEFAULT_ADB_PORT && !ports.includes(oldPort)) { adbService.removeAdbPort(oldPort); } } for (const newPort of ports) { - invariant(newPort != null); + if (!(newPort != null)) { + throw new Error('Invariant violation: "newPort != null"'); + } + if (!existingPorts.includes(newPort)) { adbService.addAdbPort(newPort); } } } -export function setAdbPath(targetUri: NuclideUri, adbPath: string) { - const adbService = getAdbServiceByNuclideUri(targetUri); +function setAdbPath(targetUri, adbPath) { + const adbService = (0, (_nuclideAdb || _load_nuclideAdb()).getAdbServiceByNuclideUri)(targetUri); if (adbPath != null) { adbService.registerCustomPath(adbPath); } else { @@ -74,4 +82,4 @@ export function setAdbPath(targetUri: NuclideUri, adbPath: string) { // to fallback to its default configuration. adbService.registerCustomPath(null); } -} +} \ No newline at end of file diff --git a/modules/nuclide-debugger-common/SelectableFilterableProcessTable.js b/modules/nuclide-debugger-common/SelectableFilterableProcessTable.js index 5e2b59351c..4640d5156e 100644 --- a/modules/nuclide-debugger-common/SelectableFilterableProcessTable.js +++ b/modules/nuclide-debugger-common/SelectableFilterableProcessTable.js @@ -1,3 +1,47 @@ +'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. @@ -6,80 +50,39 @@ * LICENSE file in 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, -}; - -function getCompareFunction( - sortedColumn: ?ColumnName, - sortDescending: boolean, -): (a: ProcessRow, b: ProcessRow) => number { +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, 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()); @@ -90,7 +93,7 @@ function getCompareFunction( return () => 0; } -function filterProcesses(processes: Array, filterText: string) { +function filterProcesses(processes, filterText) { // Show all results if invalid regex let filterRegex; try { @@ -98,111 +101,95 @@ function filterProcesses(processes: Array, filterText: string) { } catch (e) { return processes; } - return processes.filter( - item => - filterRegex.test(item.process) || - filterRegex.test(item.pid.toString()) || - filterRegex.test(item.command), - ); + return processes.filter(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; +class SelectableFilterableProcessTable extends _react.Component { - constructor(props: Props) { + constructor(props) { super(props); - this._disposables = new UniversalDisposable(); + + 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); + }; + + const processList = processes.map(process => { + return { + process: commandName(process.command, process.commandWithArgs), + pid: process.pid, + command: process.commandWithArgs + }; + }); + + this.setState({ processList }); + }; + + this._handleFilterTextChange = filterText => { + // 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) { + // 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 + }); + }; + + this._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: '', + filterText: '' }; } - componentDidMount(): void { - this._disposables.add( - Observable.interval(PROCESS_UPDATES_INTERVAL_MS) - .startWith(0) - .flatMap(_ => - getVSCodeDebuggerAdapterServiceByNuclideUri( - this.props.targetUri, - ).getProcessTree(), - ) - .subscribe(this._updateList), - ); + 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(); } - _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, - }; - }); - - this.setState({processList}); - }; - - _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) { - // 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 : _ => {}; + 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; + changedSelectedProcess = newState.selectedProcess.pid !== this.state.selectedProcess.pid; } else { changedSelectedProcess = true; } @@ -218,70 +205,59 @@ export default class SelectableFilterableProcessTable extends React.Component< }); } - _handleSelectTableRow = ( - selectedProcess: ProcessRow, - selectedIndex: number, - ): void => { - this.setState({selectedProcess}); - }; - - _handleSort = (sortedColumn: ColumnName, sortDescending: boolean): void => { - this.setState({ - sortedColumn, - sortDescending, - }); - }; - - render(): React.Node { + render() { const { processList, sortedColumn, sortDescending, selectedProcess, - filterText, + 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; - } + if (selectedProcess != null && selectedProcess.pid === process.pid) { + selectedIndex = index; + } - return row; - }); + return row; + }); - return ( -
    -

    Attach to a running native process

    - -
    - + return _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/SourceSelector.js b/modules/nuclide-debugger-common/SourceSelector.js index 7756e902e2..f8412dad2a 100644 --- a/modules/nuclide-debugger-common/SourceSelector.js +++ b/modules/nuclide-debugger-common/SourceSelector.js @@ -1,3 +1,46 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SourceSelector = undefined; + +var _idx; + +function _load_idx() { + return _idx = _interopRequireDefault(require('idx')); +} + +var _Dropdown; + +function _load_Dropdown() { + return _Dropdown = require('../nuclide-commons-ui/Dropdown'); +} + +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 _react = _interopRequireWildcard(require('react')); + +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 }; } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,136 +49,96 @@ * LICENSE file in 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 {SuggestedProjectPath} from 'atom-ide-debugger-java/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; +class SourceSelector extends _react.Component { -import idx from 'idx'; -import {Dropdown} from 'nuclide-commons-ui/Dropdown'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import * as React from 'react'; -import {observeProjectPathsAllFromSourcePathsService} from './utils'; - -type Props = {| - +onSelect: (selectedSource: ?NuclideUri) => void, - +deserialize: () => ?string, -|}; - -type State = { - selectableSources: Array, - selectedSource: ?SuggestedProjectPath, -}; + constructor(props) { + super(props); -export class SourceSelector extends React.Component { - _disposables: UniversalDisposable; + this._sourceToOption = source => { + const label = this._getLabelFromSource(source); + return { + value: source, + label, + selectedLabel: label + }; + }; - constructor(props: Props) { - super(props); - this._disposables = new UniversalDisposable(); - this.state = {selectableSources: [], selectedSource: null}; + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this.state = { selectableSources: [], selectedSource: null }; } - _getNewlySelectedSource( - selectedSource: ?SuggestedProjectPath, - projectPaths: Array, - deserializedProjectPath: ?string, - ): ?SuggestedProjectPath { + _getNewlySelectedSource(selectedSource, projectPaths, deserializedProjectPath) { let newSelectedSource = null; if (selectedSource != null) { - newSelectedSource = projectPaths.includes(selectedSource) - ? selectedSource - : null; + newSelectedSource = projectPaths.includes(selectedSource) ? selectedSource : null; } if (newSelectedSource == null && projectPaths.length > 0) { - const matches = projectPaths.filter( - projectPath => projectPath.projectPath === deserializedProjectPath, - ); + const matches = projectPaths.filter(projectPath => projectPath.projectPath === deserializedProjectPath); newSelectedSource = matches.length > 0 ? matches[0] : projectPaths[0]; } return newSelectedSource; } componentDidMount() { - this._disposables.add( - observeProjectPathsAllFromSourcePathsService( - (projectPaths: Array) => { - const newSelectedSource = this._getNewlySelectedSource( - this.state.selectedSource, - projectPaths, - this.props.deserialize(), - ); - this.setState({ - selectableSources: projectPaths, - selectedSource: newSelectedSource, - }); - }, - ), - ); + this._disposables.add((0, (_utils || _load_utils()).observeProjectPathsAllFromSourcePathsService)(projectPaths => { + const newSelectedSource = this._getNewlySelectedSource(this.state.selectedSource, projectPaths, this.props.deserialize()); + this.setState({ + selectableSources: projectPaths, + selectedSource: newSelectedSource + }); + })); } componentWillUnmount() { this._disposables.dispose(); } - _getLabelFromSource(source: SuggestedProjectPath) { - const {projectPath, hostLabel} = source; - const basename = nuclideUri.basename(projectPath); + _getLabelFromSource(source) { + const { projectPath, hostLabel } = source; + const basename = (_nuclideUri || _load_nuclideUri()).default.basename(projectPath); return hostLabel + ' - ' + basename; } - _sourceToOption = (source: SuggestedProjectPath) => { - const label = this._getLabelFromSource(source); - return { - value: source, - label, - selectedLabel: label, - }; - }; - - setState(partialState: Object, callback?: () => mixed): void { - const fullState: State = { - ...this.state, - ...partialState, - }; + setState(partialState, callback) { + const fullState = Object.assign({}, this.state, partialState); super.setState(fullState, () => { - this.props.onSelect(idx(fullState, _ => _.selectedSource.projectPath)); + var _ref, _ref2; + + this.props.onSelect((_ref = fullState) != null ? (_ref2 = _ref.selectedSource) != null ? _ref2.projectPath : _ref2 : _ref); callback && callback(); }); } - render(): React.Node { - const {selectableSources, selectedSource} = this.state; + render() { + const { selectableSources, selectedSource } = this.state; const options = selectableSources.map(this._sourceToOption); if (options.length === 0) { - return ( -
    - No Projects Found. Please add a project to your file tree so the - debugger can find sources. -
    + return _react.createElement( + 'div', + null, + 'No Projects Found. Please add a project to your file tree so the debugger can find sources.' ); } - const potentiallyWrongSourceLabel = - selectedSource != null && !selectedSource.suggested ? ( - - ) : null; - return ( -
    - this.setState({selectedSource: option})} - placeholder={'Select a source'} - value={selectedSource} - /> - {potentiallyWrongSourceLabel} -
    + const potentiallyWrongSourceLabel = selectedSource != null && !selectedSource.suggested ? _react.createElement( + 'label', + null, + 'Nuclide is not sure that you have selected a project which contains sources the debugger can use. Please double check that your selected source is correct.' + ) : null; + return _react.createElement( + 'div', + null, + _react.createElement((_Dropdown || _load_Dropdown()).Dropdown, { + options: options, + onChange: option => this.setState({ selectedSource: option }), + placeholder: 'Select a source', + value: selectedSource + }), + potentiallyWrongSourceLabel ); } } +exports.SourceSelector = SourceSelector; \ No newline at end of file diff --git a/modules/nuclide-debugger-common/V8Protocol.js b/modules/nuclide-debugger-common/V8Protocol.js index 4cfd95adb0..1293d3437d 100644 --- a/modules/nuclide-debugger-common/V8Protocol.js +++ b/modules/nuclide-debugger-common/V8Protocol.js @@ -1,3 +1,17 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +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; } } + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,35 +20,18 @@ * LICENSE file in 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[]; - - constructor( - id: string, - logger: log4js$Logger, - sendPreprocessors: MessageProcessor[], - receivePreprocessors: MessageProcessor[], - ) { +class V8Protocol { + + constructor(id, logger, sendPreprocessors, receivePreprocessors) { this._id = id; this._logger = logger; this._sendPreprocessors = sendPreprocessors; @@ -45,30 +42,27 @@ 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 { + async dispatchRequest(request, response) { 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,25 +74,17 @@ 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 - }`, - ); + this._logger.error(`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, + _doSend(command, args, clb) { + const request = { + command }; if (args && Object.keys(args).length > 0) { request.arguments = args; @@ -112,11 +98,8 @@ export default class V8Protocol { } } - _sendMessage( - typ: 'request' | 'response' | 'event', - message: DebugProtocol.ProtocolMessage, - ): void { - message.type = (typ: any); + _sendMessage(typ, message) { + message.type = typ; message.seq = this._sequence++; this._sendPreprocessors.forEach(processor => processor(message)); @@ -126,16 +109,12 @@ 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, - ); + const message = this._rawData.toString('utf8', 0, this._contentLength); this._rawData = this._rawData.slice(this._contentLength); this._contentLength = -1; if (message.length > 0) { @@ -159,17 +138,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,13 +156,13 @@ 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; @@ -193,3 +172,4 @@ export default class V8Protocol { } } } +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 f95b2b1d07..38c6efc0e5 100644 --- a/modules/nuclide-debugger-common/VSCodeDebuggerAdapterService.js +++ b/modules/nuclide-debugger-common/VSCodeDebuggerAdapterService.js @@ -1,62 +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 strict-local - * @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'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import fsPromise from 'nuclide-commons/fsPromise'; -import {getAbsoluteBinaryPathForPid} from 'nuclide-commons/process'; - -export class VsRawAdapterSpawnerService extends VsAdapterSpawner { - spawnAdapter( - adapter: VSAdapterExecutableInfo, - ): ConnectableObservable { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.VsRawAdapterSpawnerService = undefined; +exports.createVsRawAdapterSpawnerService = createVsRawAdapterSpawnerService; +exports.getProcessTree = getProcessTree; +exports.getBuckRootFromUri = getBuckRootFromUri; +exports.getBuckRootFromPid = getBuckRootFromPid; +exports.realpath = realpath; +exports.getAdapterExecutableInfo = getAdapterExecutableInfo; + +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'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../nuclide-commons/nuclideUri')); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../nuclide-commons/fsPromise')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class VsRawAdapterSpawnerService extends (_VsAdapterSpawner || _load_VsAdapterSpawner()).default { + spawnAdapter(adapter) { return super.spawnAdapter(adapter); } - write(input: string): Promise { + write(input) { return super.write(input); } - dispose(): Promise { + dispose() { return super.dispose(); } } -export async function createVsRawAdapterSpawnerService(): Promise< - VsRawAdapterSpawnerService, -> { +exports.VsRawAdapterSpawnerService = VsRawAdapterSpawnerService; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ + +async function createVsRawAdapterSpawnerService() { return new VsRawAdapterSpawnerService(); } -export async function getProcessTree(): Promise> { - return psTree(); +async function getProcessTree() { + return (0, (_process || _load_process()).psTree)(); } -export async function getBuckRootFromUri(uri: string): Promise { +async function getBuckRootFromUri(uri) { let path = uri; while (true) { - const rootTest = nuclideUri.join(path, '.buckconfig'); + const rootTest = (_nuclideUri || _load_nuclideUri()).default.join(path, '.buckconfig'); // eslint-disable-next-line no-await-in-loop - if (await fsPromise.exists(rootTest)) { + if (await (_fsPromise || _load_fsPromise()).default.exists(rootTest)) { return path; } - const newPath = nuclideUri.getParent(path); + const newPath = (_nuclideUri || _load_nuclideUri()).default.getParent(path); if (newPath === path) { break; } @@ -67,8 +97,8 @@ export async function getBuckRootFromUri(uri: string): Promise { return null; } -export async function getBuckRootFromPid(pid: number): Promise { - const path = await getAbsoluteBinaryPathForPid(pid); +async function getBuckRootFromPid(pid) { + const path = await (0, (_process || _load_process()).getAbsoluteBinaryPathForPid)(pid); if (path == null) { return null; } @@ -76,12 +106,10 @@ export async function getBuckRootFromPid(pid: number): Promise { return getBuckRootFromUri(path); } -export async function realpath(path: string): Promise { - return fsPromise.realpath(path); +async function realpath(path) { + return (_fsPromise || _load_fsPromise()).default.realpath(path); } -export async function getAdapterExecutableInfo( - adapterType: VsAdapterType, -): Promise { - return getAdapterExecutable(adapterType); -} +async function getAdapterExecutableInfo(adapterType) { + return (0, (_debuggerRegistry || _load_debuggerRegistry()).getAdapterExecutable)(adapterType); +} \ No newline at end of file diff --git a/modules/nuclide-debugger-common/VSCodeDebuggerAdapterServiceProxy.js b/modules/nuclide-debugger-common/VSCodeDebuggerAdapterServiceProxy.js new file mode 100644 index 0000000000..47963dc218 --- /dev/null +++ b/modules/nuclide-debugger-common/VSCodeDebuggerAdapterServiceProxy.js @@ -0,0 +1,672 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + remoteModule.VsRawAdapterSpawnerService = class { + constructor() { + throw Error("constructors are not supported for remote objects"); + } + + spawnAdapter(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 24 + }, + name: "VsRawAdapterSpawnerService" + }), "spawnAdapter", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "adapter", + type: { + kind: "named", + name: "VSAdapterExecutableInfo" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "ProcessMessage" + }); + }).publish(); + } + + write(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 24 + }, + name: "VsRawAdapterSpawnerService" + }), "write", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "input", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + } + + dispose() { + return _client.disposeRemoteObject(this); + } + + }; + + remoteModule.createVsRawAdapterSpawnerService = function () { + return _client.callRemoteFunction("VSCodeDebuggerAdapterService/createVsRawAdapterSpawnerService", "promise", _client.marshalArguments(Array.from(arguments), [])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "VsRawAdapterSpawnerService" + }); + }); + }; + + remoteModule.getProcessTree = function () { + return _client.callRemoteFunction("VSCodeDebuggerAdapterService/getProcessTree", "promise", _client.marshalArguments(Array.from(arguments), [])).then(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "ProcessInfo" + } + }); + }); + }; + + remoteModule.getBuckRootFromUri = function (arg0) { + return _client.callRemoteFunction("VSCodeDebuggerAdapterService/getBuckRootFromUri", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "uri", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "string" + } + }); + }); + }; + + remoteModule.getBuckRootFromPid = function (arg0) { + return _client.callRemoteFunction("VSCodeDebuggerAdapterService/getBuckRootFromPid", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "pid", + type: { + kind: "number" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "string" + } + }); + }); + }; + + remoteModule.realpath = function (arg0) { + return _client.callRemoteFunction("VSCodeDebuggerAdapterService/realpath", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }); + }; + + remoteModule.getAdapterExecutableInfo = function (arg0) { + return _client.callRemoteFunction("VSCodeDebuggerAdapterService/getAdapterExecutableInfo", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "adapterType", + type: { + kind: "named", + name: "VsAdapterType" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "VSAdapterExecutableInfo" + }); + }); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + ProcessExitMessage: { + kind: "alias", + location: { + type: "source", + fileName: "process.js", + line: 665 + }, + name: "ProcessExitMessage", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "exit" + }, + optional: false + }, { + name: "exitCode", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }, { + name: "signal", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }] + } + }, + ProcessMessage: { + kind: "alias", + location: { + type: "source", + fileName: "process.js", + line: 671 + }, + name: "ProcessMessage", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "stdout" + }, + optional: false + }, { + name: "data", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "stderr" + }, + optional: false + }, { + name: "data", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "exit" + }, + optional: false + }, { + name: "exitCode", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }, { + name: "signal", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }] + }], + discriminantField: "kind" + } + }, + VSAdapterExecutableInfo: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 38 + }, + name: "VSAdapterExecutableInfo", + definition: { + kind: "object", + fields: [{ + name: "command", + type: { + kind: "string" + }, + optional: false + }, { + name: "args", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: false + }] + } + }, + VsRawAdapterSpawnerService: { + kind: "interface", + name: "VsRawAdapterSpawnerService", + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 24 + }, + staticMethods: {}, + instanceMethods: { + spawnAdapter: { + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 25 + }, + kind: "function", + argumentTypes: [{ + name: "adapter", + type: { + kind: "named", + name: "VSAdapterExecutableInfo" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "ProcessMessage" + } + } + }, + write: { + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 31 + }, + kind: "function", + argumentTypes: [{ + name: "input", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + }, + dispose: { + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 35 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + } + }, + createVsRawAdapterSpawnerService: { + kind: "function", + name: "createVsRawAdapterSpawnerService", + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 40 + }, + type: { + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 40 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "VsRawAdapterSpawnerService" + } + } + } + }, + ProcessInfo: { + kind: "alias", + location: { + type: "source", + fileName: "process.js", + line: 688 + }, + name: "ProcessInfo", + definition: { + kind: "object", + fields: [{ + name: "parentPid", + type: { + kind: "number" + }, + optional: false + }, { + name: "pid", + type: { + kind: "number" + }, + optional: false + }, { + name: "command", + type: { + kind: "string" + }, + optional: false + }, { + name: "commandWithArgs", + type: { + kind: "string" + }, + optional: false + }] + } + }, + getProcessTree: { + kind: "function", + name: "getProcessTree", + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 46 + }, + type: { + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 46 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "array", + type: { + kind: "named", + name: "ProcessInfo" + } + } + } + } + }, + getBuckRootFromUri: { + kind: "function", + name: "getBuckRootFromUri", + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 50 + }, + type: { + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 50 + }, + kind: "function", + argumentTypes: [{ + name: "uri", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + } + } + }, + getBuckRootFromPid: { + kind: "function", + name: "getBuckRootFromPid", + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 70 + }, + type: { + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 70 + }, + kind: "function", + argumentTypes: [{ + name: "pid", + type: { + kind: "number" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + } + } + }, + realpath: { + kind: "function", + name: "realpath", + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 79 + }, + type: { + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 79 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "string" + } + } + } + }, + VsAdapterType: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 45 + }, + name: "VsAdapterType", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "hhvm" + }, { + kind: "string-literal", + value: "python" + }, { + kind: "string-literal", + value: "node" + }, { + kind: "string-literal", + value: "java" + }, { + kind: "string-literal", + value: "java_android" + }, { + kind: "string-literal", + value: "react-native" + }, { + kind: "string-literal", + value: "prepack" + }, { + kind: "string-literal", + value: "ocaml" + }, { + kind: "string-literal", + value: "mobilejs" + }, { + kind: "string-literal", + value: "native_lldb" + }, { + kind: "string-literal", + value: "native_gdb" + }] + } + }, + getAdapterExecutableInfo: { + kind: "function", + name: "getAdapterExecutableInfo", + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 83 + }, + type: { + location: { + type: "source", + fileName: "VSCodeDebuggerAdapterService.js", + line: 83 + }, + kind: "function", + argumentTypes: [{ + name: "adapterType", + type: { + kind: "named", + name: "VsAdapterType" + } + }], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "VSAdapterExecutableInfo" + } + } + } + } + } +}); \ No newline at end of file diff --git a/modules/nuclide-debugger-common/VsAdapterSpawner.js b/modules/nuclide-debugger-common/VsAdapterSpawner.js index a7f6a38347..84d5d0d0b8 100644 --- a/modules/nuclide-debugger-common/VsAdapterSpawner.js +++ b/modules/nuclide-debugger-common/VsAdapterSpawner.js @@ -1,61 +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 strict-local - * @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 _process; + +function _load_process() { + return _process = require('../nuclide-commons/process'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +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(); + spawnAdapter(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'], + 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 write(input: string): Promise { + async write(input) { this._stdin.next(input); } - async dispose(): Promise { + async dispose() { this._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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-debugger-common/VsDebugSession.js b/modules/nuclide-debugger-common/VsDebugSession.js index 6e0c701933..35793d3de8 100644 --- a/modules/nuclide-debugger-common/VsDebugSession.js +++ b/modules/nuclide-debugger-common/VsDebugSession.js @@ -1,178 +1,157 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 _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; + +function _load_analytics() { + return _analytics = require('../nuclide-commons/analytics'); +} + +var _uuid; -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 {track, trackTiming} from 'nuclide-commons/analytics'; -import uuid from 'uuid'; - -export interface AdapterExitedEvent extends DebugProtocol.DebugEvent { - event: 'adapter-exited'; - body: {exitCode: number}; +function _load_uuid() { + return _uuid = _interopRequireDefault(require('uuid')); } -export type AdapterAnalyticsExtras = { - adapter: string, - host: string, - isRemote: boolean, -}; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function raiseAdapterExitedEvent(exitCode: number): AdapterExitedEvent { +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 raiseAdapterExitedEvent(exitCode) { return { seq: 0, type: 'event', event: 'adapter-exited', - body: {exitCode}, + body: { exitCode } }; -} - -type RunInTerminalHandler = ( - arguments: DebugProtocol.RunInTerminalRequestArguments, -) => Promise; +} /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 + */ /** * 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; - - constructor( - id: string, - logger: log4js$Logger, - adapterExecutable: VSAdapterExecutableInfo, - adapterAnalyticsExtras: ?AdapterAnalyticsExtras, - spawner?: IVsAdapterSpawner, - sendPreprocessors?: MessageProcessor[] = [], - receivePreprocessors?: MessageProcessor[] = [], - runInTerminalHandler?: RunInTerminalHandler, - ) { +class VsDebugSession extends (_V8Protocol || _load_V8Protocol()).default { + + constructor(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._spawner = spawner == null ? new (_VsAdapterSpawner || _load_VsAdapterSpawner()).default() : spawner; + this._adapterAnalyticsExtras = Object.assign({}, adapterAnalyticsExtras, { // $FlowFixMe flow doesn't consider uuid callable, but it is - debuggerSessionId: uuid(), - }; + debuggerSessionId: (0, (_uuid || _load_uuid()).default)() + }); - 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._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; } @@ -181,86 +160,65 @@ 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: DebugProtocol.Response) => { - const sanitizedResponse = this._sanitizeResponse(response); - this._logger.info('Received response:', sanitizedResponse); - track('vs-debug-session:transaction', { - ...this._adapterAnalyticsExtras, - request: {command, arguments: args}, - response: sanitizedResponse, - }); - 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(', '); - } - track('vs-debug-session:transaction', { - ...this._adapterAnalyticsExtras, - request: {command, arguments: args}, - response: errorResponse, - }); - throw new Error(formattedError); - }, - ); + return super.send(command, args).then(response => { + const sanitizedResponse = this._sanitizeResponse(response); + this._logger.info('Received response:', sanitizedResponse); + (0, (_analytics || _load_analytics()).track)('vs-debug-session:transaction', Object.assign({}, this._adapterAnalyticsExtras, { + request: { command, arguments: args }, + response: sanitizedResponse + })); + 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(', '); + } + (0, (_analytics || _load_analytics()).track)('vs-debug-session:transaction', Object.assign({}, this._adapterAnalyticsExtras, { + request: { command, arguments: args }, + response: errorResponse + })); + 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); } - _sanitizeResponse( - response: DebugProtocol.base$Response, - ): DebugProtocol.base$Response { + _sanitizeResponse(response) { try { if (response.command === 'variables') { - const varResponse = ((response: any): DebugProtocol.VariablesResponse); - const sanResponse = { - ...varResponse, - body: { - ...varResponse.body, - variables: varResponse.body.variables.map(v => ({ - ...v, - value: '', - })), - }, - }; + const varResponse = response; + const sanResponse = Object.assign({}, varResponse, { + body: Object.assign({}, varResponse.body, { + variables: varResponse.body.variables.map(v => Object.assign({}, v, { + value: '' + })) + }) + }); // $FlowFixMe flow isn't recognizing that ...varResponse is filling in needed members return sanResponse; } if (response.command === 'evaluate') { - const evalResponse = ((response: any): DebugProtocol.EvaluateResponse); - const sanResponse = { - ...evalResponse, - body: { - ...evalResponse.body, - result: '', - }, - }; + const evalResponse = response; + const sanResponse = Object.assign({}, evalResponse, { + body: Object.assign({}, evalResponse.body, { + result: '' + }) + }); // $FlowFixMe flow isn't recognizing that ...evalResponse is filling in needed members return sanResponse; } @@ -275,24 +233,23 @@ export default class VsDebugSession extends V8Protocol { success: false, command: response.command, error: 'Error sanitizing response.', - message: e.message, + message: e.message }; } } - 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() }; } - track('vs-debug-session:transaction', { - ...this._adapterAnalyticsExtras, - event, - }); + (0, (_analytics || _load_analytics()).track)('vs-debug-session:transaction', Object.assign({}, this._adapterAnalyticsExtras, { + event + })); this._onDidEvent.next(event); @@ -338,97 +295,70 @@ export default class VsDebugSession extends V8Protocol { } } - getCapabilities(): DebugProtocol.Capabilities { + getCapabilities() { return this.capabilities; } - async initialize( - args: DebugProtocol.InitializeRequestArguments, - ): Promise { + async initialize(args) { const response = await 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 { + async launch(args) { const response = await this.send('launch', args); return this._readCapabilities(response); } - async attach( - args: DebugProtocol.AttachRequestArguments, - ): Promise { + async attach(args) { const response = await this.send('attach', args); return this._readCapabilities(response); } - next(args: DebugProtocol.NextArguments): Promise { + next(args) { this._fireFakeContinued(args.threadId); return this.send('next', args); } - stepIn( - args: DebugProtocol.StepInArguments, - ): Promise { + stepIn(args) { this._fireFakeContinued(args.threadId); return this.send('stepIn', args); } - stepOut( - args: DebugProtocol.StepOutArguments, - ): Promise { + stepOut(args) { this._fireFakeContinued(args.threadId); return this.send('stepOut', args); } - continue( - args: DebugProtocol.ContinueArguments, - ): Promise { + continue(args) { this._fireFakeContinued(args.threadId); return this.send('continue', args); } - pause( - args: DebugProtocol.PauseArguments, - ): Promise { + pause(args) { return this.send('pause', args); } - setVariable( - args: DebugProtocol.SetVariableArguments, - ): Promise { + setVariable(args) { return this.send('setVariable', args); } - restartFrame( - args: DebugProtocol.RestartFrameArguments, - threadId: number, - ): Promise { + restartFrame(args, threadId) { this._fireFakeContinued(threadId); return this.send('restartFrame', args); } - completions( - args: DebugProtocol.CompletionsArguments, - ): Promise { + completions(args) { return this.send('completions', args); } - async disconnect( - restart?: boolean = false, - force?: boolean = false, - ): Promise { + async disconnect(restart = false, force = false) { if (this._disconnected && force) { this._stopServer(); return; @@ -437,112 +367,82 @@ export default class VsDebugSession extends V8Protocol { 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}); + await this.send('disconnect', { restart }); this._stopServer(); } } - setBreakpoints( - args: DebugProtocol.SetBreakpointsArguments, - ): Promise { + setBreakpoints(args) { return this.send('setBreakpoints', args); } - setFunctionBreakpoints( - args: DebugProtocol.SetFunctionBreakpointsArguments, - ): Promise { + setFunctionBreakpoints(args) { return this.send('setFunctionBreakpoints', args); } - setExceptionBreakpoints( - args: DebugProtocol.SetExceptionBreakpointsArguments, - ): Promise { + setExceptionBreakpoints(args) { return this.send('setExceptionBreakpoints', args); } - configurationDone(): Promise { + configurationDone() { return this.send('configurationDone', null); } - stackTrace( - args: DebugProtocol.StackTraceArguments, - ): Promise { + stackTrace(args) { return this.send('stackTrace', args); } - exceptionInfo( - args: DebugProtocol.ExceptionInfoArguments, - ): Promise { + exceptionInfo(args) { return this.send('exceptionInfo', args); } - scopes( - args: DebugProtocol.ScopesArguments, - ): Promise { + scopes(args) { return this.send('scopes', args); } - variables( - args: DebugProtocol.VariablesArguments, - ): Promise { + variables(args) { return this.send('variables', args); } - source( - args: DebugProtocol.SourceArguments, - ): Promise { + source(args) { return this.send('source', args); } - threads(): Promise { + threads() { return this.send('threads', null); } - evaluate( - args: DebugProtocol.EvaluateArguments, - ): Promise { + evaluate(args) { return this.send('evaluate', args); } - stepBack( - args: DebugProtocol.StepBackArguments, - ): Promise { + stepBack(args) { this._fireFakeContinued(args.threadId); return this.send('stepBack', args); } - reverseContinue( - args: DebugProtocol.ReverseContinueArguments, - ): Promise { + reverseContinue(args) { this._fireFakeContinued(args.threadId); return this.send('reverseContinue', args); } - nuclide_continueToLocation( - args: DebugProtocol.nuclide_ContinueToLocationArguments, - ): Promise { + nuclide_continueToLocation(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 { + async dispatchRequest(request, response) { if (request.command === 'runInTerminal') { const runInTerminalHandler = this._runInTerminalHandler; if (runInTerminalHandler == null) { - this._logger.error( - "'runInTerminal' isn't supported for this debug session", - request, - ); + this._logger.error("'runInTerminal' isn't supported for this debug session", request); return; } try { - await runInTerminalHandler((request.arguments: any)); + await runInTerminalHandler(request.arguments); } catch (error) { response.success = false; response.message = error.message; @@ -557,59 +457,53 @@ export default class VsDebugSession extends V8Protocol { } } - _fireFakeContinued( - threadId: number, - allThreadsContinued?: boolean = false, - ): void { - const event: DebugProtocol.ContinuedEvent = { + _fireFakeContinued(threadId, allThreadsContinued = false) { + const event = { type: 'event', event: 'continued', body: { threadId, // $FlowFixMe - allThreadsContinued, + allThreadsContinued }, - seq: 0, + 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; @@ -620,7 +514,7 @@ export default class VsDebugSession extends V8Protocol { this._endHandlers(); } - _endHandlers(): void { + _endHandlers() { this._onDidInitialize.complete(); this._onDidStop.complete(); this._onDidContinued.complete(); @@ -636,33 +530,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}`, - ); + this._logger.error(`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 2f2b6cc2bc..d62ca4eb3f 100644 --- a/modules/nuclide-debugger-common/VspProcessInfo.js +++ b/modules/nuclide-debugger-common/VspProcessInfo.js @@ -1,68 +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 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; - - constructor( - targetUri: NuclideUri, - debugMode: DebuggerConfigAction, - adapterType: VsAdapterType, - adapterExecutable: ?VSAdapterExecutableInfo, - config: Object, - customCapabilities?: ?CustomDebuggerCapabilities, - customProperties?: ?CustomDebuggerProperties, - preprocessors?: ?MessagePreprocessors, - ) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +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 _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 VspProcessInfo { + + constructor(targetUri, debugMode, adapterType, adapterExecutable, config, customCapabilities, customProperties, preprocessors) { this._targetUri = targetUri; this._debugMode = debugMode; this._adapterType = adapterType; @@ -71,36 +33,31 @@ 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 { + async customRequest(request, args) { if (this._vspInstance != null) { return this._vspInstance.customRequest(request, args); } else { @@ -108,26 +65,24 @@ export default class VspProcessInfo { } } - 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, @@ -136,18 +91,23 @@ export default class VspProcessInfo { capabilities: this._getDebuggerCapabilities(), properties: this._getDebuggerProps(), config: this._config, - clientPreprocessor: - this._preprocessors == null - ? null - : this._preprocessors.vspClientPreprocessor, - adapterPreprocessor: - this._preprocessors == null - ? null - : this._preprocessors.vspAdapterPreprocessor, + clientPreprocessor: this._preprocessors == null ? null : this._preprocessors.vspClientPreprocessor, + adapterPreprocessor: 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 3ed69b100b..4f24aecc1a 100644 --- a/modules/nuclide-debugger-common/autogen-utils.js +++ b/modules/nuclide-debugger-common/autogen-utils.js @@ -1,3 +1,21 @@ +'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. @@ -6,80 +24,58 @@ * LICENSE file in 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; - }); +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; } -export function getNativeAutoGenConfig( - vsAdapterType: NativeVsAdapterType, -): AutoGenConfig { +function getNativeAutoGenConfig(vsAdapterType) { const program = { name: 'program', type: 'path', description: 'Input the program/executable you want to launch', required: true, - visible: true, + visible: true }; const cwd = { name: 'cwd', type: 'path', description: 'Working directory for the launched executable', required: true, - visible: true, + visible: true }; const args = { name: 'args', @@ -88,17 +84,16 @@ export function getNativeAutoGenConfig( description: '(Optional) Arguments to the executable', required: false, defaultValue: '', - visible: true, + visible: true }; const env = { name: 'env', type: 'array', itemType: 'string', - description: - '(Optional) Environment variables (e.g. SHELL=/bin/bash PATH=/bin)', + description: '(Optional) Environment variables (e.g. SHELL=/bin/bash PATH=/bin)', required: false, defaultValue: '', - visible: true, + visible: true }; const sourcePath = { name: 'sourcePath', @@ -106,14 +101,12 @@ export function getNativeAutoGenConfig( description: '(Optional) base path for sources', required: false, defaultValue: '', - visible: true, + visible: true }; - const debugTypeMessage = `using ${ - vsAdapterType === VsAdapterTypes.NATIVE_GDB ? 'gdb' : 'lldb' - }`; + const debugTypeMessage = `using ${vsAdapterType === (_constants || _load_constants()).VsAdapterTypes.NATIVE_GDB ? 'gdb' : 'lldb'}`; - const autoGenLaunchConfig: AutoGenLaunchConfig = { + const autoGenLaunchConfig = { launch: true, vsAdapterType, threads: true, @@ -121,7 +114,13 @@ 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 = { @@ -129,17 +128,22 @@ export function getNativeAutoGenConfig( type: 'process', description: '', required: true, - visible: true, + visible: true }; - const autoGenAttachConfig: AutoGenAttachConfig = { + 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 5a371246c3..89430fbee8 100644 --- a/modules/nuclide-debugger-common/constants.js +++ b/modules/nuclide-debugger-common/constants.js @@ -1,18 +1,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. - * - * @flow strict-local - * @format - */ - -import type {VsAdapterType} from './types'; +'use strict'; -export const VsAdapterTypes = Object.freeze({ +Object.defineProperty(exports, "__esModule", { + value: true +}); +const VsAdapterTypes = exports.VsAdapterTypes = Object.freeze({ HHVM: 'hhvm', PYTHON: 'python', REACT_NATIVE: 'react-native', @@ -23,8 +14,20 @@ 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. + * + * strict-local + * @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 d9a86d09d0..1d90dd7746 100644 --- a/modules/nuclide-debugger-common/debug-adapter-service.js +++ b/modules/nuclide-debugger-common/debug-adapter-service.js @@ -1,36 +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 strict-local - * @format - */ +'use strict'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import typeof * as VSCodeDebuggerAdapterService from './VSCodeDebuggerAdapterService'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getVSCodeDebuggerAdapterServiceByNuclideUri = getVSCodeDebuggerAdapterServiceByNuclideUri; -import * as VSCodeDebuggerAdapterServiceLocal from './VSCodeDebuggerAdapterService'; +var _VSCodeDebuggerAdapterService; -export function getVSCodeDebuggerAdapterServiceByNuclideUri( - uri: NuclideUri, -): VSCodeDebuggerAdapterService { - let rpcService: ?nuclide$RpcService = null; +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, - ); + return rpcService.getServiceByNuclideUri('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. + * + * strict-local + * @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 e4a3bbe004..efb5f634a7 100644 --- a/modules/nuclide-debugger-common/debugger-registry.js +++ b/modules/nuclide-debugger-common/debugger-registry.js @@ -1,3 +1,21 @@ +'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. @@ -6,203 +24,94 @@ * LICENSE file in 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 strict-local + * strict-local * @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 || _load_nuclideUri()).default.dirname(__dirname); -const modulesPath = nuclideUri.dirname(__dirname); - -function resolvePackagePath(packageName: string): string { - const bundledPath = nuclideUri.join(modulesPath, packageName); - if (fs.existsSync(bundledPath)) { +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.join(pkg.path, 'node_modules', packageName); + return (_nuclideUri || _load_nuclideUri()).default.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: nuclideUri.join( - resolvePackagePath('atom-ide-debugger-node'), - 'VendorLib/vscode-node-debug2', - ), - }, - ], - [ - 'python', - { - executable: { - command: 'node', - args: [ - nuclideUri.join( - resolvePackagePath('atom-ide-debugger-python'), - 'VendorLib/vs-py-debugger/out/client/debugger/Main.js', - ), - ], - }, - root: nuclideUri.join( - resolvePackagePath('atom-ide-debugger-python'), - 'VendorLib/vs-py-debugger', - ), - }, - ], - [ - 'react-native', - { - executable: { - command: 'node', - args: [ - nuclideUri.join( - resolvePackagePath('atom-ide-debugger-react-native'), - 'VendorLib/vscode-react-native/out/debugger/reactNativeDebugEntryPoint.js', - ), - ], - }, - root: nuclideUri.join( - resolvePackagePath('atom-ide-debugger-react-native'), - 'VendorLib/vscode-react-native', - ), - }, - ], - [ - 'prepack', - { - executable: { - command: 'node', - args: [ - nuclideUri.join( - __dirname, - '../nuclide-debugger-vsps/VendorLib/vscode-prepack/adapter/DebugAdapter.js', - ), - ], - }, - root: nuclideUri.join( - __dirname, - '../nuclide-debugger-vsps/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'), - }, - ], - [ - 'java', - { - executable: { - command: 'java', - args: [], - }, - root: resolvePackagePath('atom-ide-debugger-java'), - }, - ], - [ - 'java_android', - { - executable: { - command: 'java', - args: [], - }, - root: resolvePackagePath('atom-ide-debugger-java-android'), - }, - ], - [ - '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'), - }, - ], -]); +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: (_nuclideUri || _load_nuclideUri()).default.join(resolvePackagePath('atom-ide-debugger-node'), 'VendorLib/vscode-node-debug2') +}], ['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: (_nuclideUri || _load_nuclideUri()).default.join(resolvePackagePath('atom-ide-debugger-python'), 'VendorLib/vs-py-debugger') +}], ['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: (_nuclideUri || _load_nuclideUri()).default.join(resolvePackagePath('atom-ide-debugger-react-native'), 'VendorLib/vscode-react-native') +}], ['prepack', { + executable: { + command: 'node', + args: [(_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../nuclide-debugger-vsps/VendorLib/vscode-prepack/adapter/DebugAdapter.js')] + }, + root: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../nuclide-debugger-vsps/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') +}], ['java', { + executable: { + command: 'java', + args: [] + }, + root: resolvePackagePath('atom-ide-debugger-java') +}], ['java_android', { + executable: { + command: 'java', + args: [] + }, + root: resolvePackagePath('atom-ide-debugger-java-android') +}], ['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') +}]]); -export function getAdapterExecutable( - adapter: VsAdapterType, -): VSAdapterExecutableInfo { +function getAdapterExecutable(adapter) { const adapterInfo = _adapters.get(adapter); if (adapterInfo == null) { throw new Error(`Cannot find VSP for given adapter type ${adapter}`); @@ -210,10 +119,10 @@ export function getAdapterExecutable( return adapterInfo.executable; } -export function getAdapterPackageRoot(adapter: VsAdapterType): string { +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 4c8deb8616..a13f9abd9a 100644 --- a/modules/nuclide-debugger-common/main.js +++ b/modules/nuclide-debugger-common/main.js @@ -1,55 +1,129 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict-local - * @format - */ - -export type { - AtomNotificationType, - ControlButtonSpecification, - DebuggerCapabilities, - DebuggerConfigAction, - DebuggerConfigurationProvider, - DebuggerProperties, - Device, - DevicePanelServiceApi, - 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 e19643d331..b05a7218df 100644 --- a/modules/nuclide-debugger-common/processors.js +++ b/modules/nuclide-debugger-common/processors.js @@ -1,34 +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 - */ +'use strict'; -import type {MessageProcessor} from './types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.remoteToLocalProcessor = remoteToLocalProcessor; +exports.localToRemoteProcessor = localToRemoteProcessor; +exports.pathProcessor = pathProcessor; -import nuclideUri from 'nuclide-commons/nuclideUri'; +var _nuclideUri; -type PathMapper = (path: string) => string; - -export function remoteToLocalProcessor(): MessageProcessor { - return pathProcessor(path => nuclideUri.getPath(path)); +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../nuclide-commons/nuclideUri')); } -export function localToRemoteProcessor( - targetUri: NuclideUri, -): MessageProcessor { - const hostname = nuclideUri.getHostname(targetUri); - return pathProcessor(path => nuclideUri.createRemoteUri(hostname, path)); +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)); } -export function pathProcessor(pathMapper: PathMapper): MessageProcessor { +function pathProcessor(pathMapper) { return message => { processRequestsUris(message, pathMapper); processResponseUris(message, pathMapper); @@ -36,7 +42,7 @@ export function pathProcessor(pathMapper: PathMapper): MessageProcessor { }; } -function processRequestsUris(message: Object, pathMapper: PathMapper): void { +function processRequestsUris(message, pathMapper) { if (message.type !== 'request') { return; } @@ -48,36 +54,28 @@ function processRequestsUris(message: Object, pathMapper: PathMapper): void { } } -function processResponseUris(message: Object, pathMapper: PathMapper): void { +function processResponseUris(message, pathMapper) { if (message.type !== 'response') { return; } switch (message.command) { case 'setBreakpoints': case 'setFunctionBreakpoints': - message.body.breakpoints.forEach(bp => - translateField(bp, 'source.path', pathMapper), - ); + message.body.breakpoints.forEach(bp => translateField(bp, 'source.path', pathMapper)); break; case 'stackTrace': - message.body.stackFrames.forEach(frame => - translateField(frame, 'source.path', pathMapper), - ); + message.body.stackFrames.forEach(frame => translateField(frame, 'source.path', pathMapper)); break; case 'modules': - message.body.modules.forEach(module => - translateField(module, 'path', pathMapper), - ); + message.body.modules.forEach(module => translateField(module, 'path', pathMapper)); break; case 'loadedSources': - message.body.sources.forEach(source => - translateField(source, 'path', pathMapper), - ); + message.body.sources.forEach(source => translateField(source, 'path', pathMapper)); break; } } -function processEventsUris(message: Object, pathMapper: PathMapper): void { +function processEventsUris(message, pathMapper) { if (message.type !== 'event') { return; } @@ -98,11 +96,7 @@ function processEventsUris(message: Object, pathMapper: PathMapper): void { // 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 { +function translateField(object, fieldDescriptor, pathMapper) { const fields = fieldDescriptor.split('.'); let lastObj = {}; const value = fields.reduce((child, field) => { @@ -115,6 +109,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 9bd0bd40db..87572cd416 100644 --- a/modules/nuclide-debugger-common/types.js +++ b/modules/nuclide-debugger-common/types.js @@ -1,342 +1,11 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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'; -import type {ISession} from 'atom-ide-ui/pkg/atom-ide-debugger/lib/types'; -import type UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import type {TaskEvent, ProcessMessage} from 'nuclide-commons/process'; -import type {Expected} from 'nuclide-commons/expected'; -import type {Device as DeviceIdType} from './types'; -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 * as DebugProtocol from 'vscode-debugprotocol'; -import * as React from 'react'; +var _vscodeDebugprotocol; -export interface IVspInstance { - customRequest( - request: string, - args: any, - ): Promise; - observeCustomEvents(): Observable; - addCustomDisposable(disposable: IDisposable): void; +function _load_vscodeDebugprotocol() { + return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol')); } -export type AtomNotificationType = 'info' | 'warning' | 'error' | 'fatalError'; +var _react = _interopRequireWildcard(require('react')); -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' - | 'java_android' - | 'react-native' - | 'prepack' - | 'ocaml' - | 'mobilejs' - | 'native_lldb' - | 'native_gdb'; - -export type NuclideDebuggerProvider = { - type: VsAdapterType, - 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, - +customDisposable?: UniversalDisposable, - +onInitializeCallback?: (session: ISession) => Promise, -|}; - -export interface IVsAdapterSpawner { - spawnAdapter( - adapter: VSAdapterExecutableInfo, - ): ConnectableObservable; - write(input: string): Promise; -} - -export type MessageProcessor = (message: Object) => void; - -export type AutoGenPropertyPrimitiveType = - | 'string' - | 'number' - | 'boolean' - | 'path'; - -export type AutoGenPropertyType = - | AutoGenPropertyPrimitiveType - | 'array' - | 'enum' - | 'object' - | 'json' - | 'deviceAndPackage' - | 'deviceAndProcess' - | 'selectSources' - | '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; - adapterType: VsAdapterType; -} - -export interface DebuggerPathResolverProvider { - resolvePath(project: string, filePath: string): Promise; -} - -// -// Device Panel Types -// - -// -// DeviceTask interface -// - -export interface IDeviceTask { - getName(): string; - getTaskEvents(): Observable; - start(): void; - cancel(): void; -} - -// -// Api -// - -export type DevicePanelServiceApi = { - registerListProvider: (provider: DeviceListProvider) => IDisposable, - registerInfoProvider: (provider: DeviceInfoProvider) => IDisposable, - registerProcessesProvider: (provider: DeviceProcessesProvider) => IDisposable, - registerTaskProvider: (provider: DeviceTaskProvider) => IDisposable, - registerProcessTaskProvider: ( - provider: DeviceProcessTaskProvider, - ) => IDisposable, - registerDeviceTypeTaskProvider: ( - provider: DeviceTypeTaskProvider, - ) => IDisposable, - registerDeviceActionProvider: (provider: DeviceActionProvider) => IDisposable, - registerAppInfoProvider: (provider: DeviceAppInfoProvider) => IDisposable, - registerDeviceTypeComponentProvider: ( - provider: DeviceTypeComponentProvider, - ) => IDisposable, -}; - -export interface DeviceListProvider { - observe(host: NuclideUri): Observable>; - getType(): string; -} - -export interface DeviceInfoProvider { - fetch( - host: NuclideUri, - device: DeviceIdType, - ): Observable>; - getType(): string; - getTitle(): string; - getPriority(): number; - isSupported(host: NuclideUri): Observable; -} - -export interface DeviceProcessesProvider { - observe(host: NuclideUri, device: DeviceIdType): Observable; - getType(): string; -} - -export interface DeviceTaskProvider { - getTask(host: NuclideUri, device: DeviceIdType): Observable; - getName(): string; - getType(): string; - isSupported(host: NuclideUri): Observable; -} - -export interface DeviceTypeTaskProvider { - getTask(host: NuclideUri): Observable; - getName(): string; - getType(): string; -} - -export interface DeviceProcessTaskProvider { - run(host: NuclideUri, device: DeviceIdType, proc: Process): Promise; - getTaskType(): ProcessTaskType; - getType(): string; - getSupportedPIDs( - host: NuclideUri, - device: DeviceIdType, - procs: Process[], - ): Observable>; - getName(): string; -} - -export interface DeviceAppInfoProvider { - observe(host: NuclideUri, device: DeviceIdType): Observable; - getName(): string; - getType(): string; - getProcessName(): string; - getAppName(): string; - canUpdate(): boolean; - update(value: string): Promise; -} - -export type DeviceAction = { - name: string, - callback: (device: Device) => void, -}; - -export interface DeviceActionProvider { - getActionsForDevice(device: Device): Array; -} - -export type ComponentPosition = 'host_selector' | 'above_table' | 'below_table'; - -export type DeviceTypeComponent = { - position: ComponentPosition, - type: React$ComponentType, - key: string, -}; - -export interface DeviceTypeComponentProvider { - getType(): string; - observe( - host: NuclideUri, - callback: (?DeviceTypeComponent) => void, - ): IDisposable; -} - -// -// Basic objects -// - -export type DeviceArchitecture = 'x86' | 'x86_64' | 'arm' | 'arm64' | ''; - -export type Device = {| - name: string, - port: number, - displayName: string, - architecture: DeviceArchitecture, - rawArchitecture: string, - ignoresSelection?: boolean, -|}; - -export type Process = { - user: string, - pid: number, - name: string, - cpuUsage: ?number, - memUsage: ?number, - isJava: boolean, -}; - -export type ProcessTaskType = 'KILL' | 'DEBUG'; - -export type ProcessTask = { - type: ProcessTaskType, - run: (proc: Process) => Promise, - isSupported: (proc: Process) => boolean, - name: string, -}; - -export type AppInfoRow = { - appName: string, - name: string, - value: string, - isError?: boolean, -}; +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-debugger-common/utils.js b/modules/nuclide-debugger-common/utils.js index f58f613c54..9ce5a3c541 100644 --- a/modules/nuclide-debugger-common/utils.js +++ b/modules/nuclide-debugger-common/utils.js @@ -1,3 +1,16 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.observeProjectPathsAllFromSourcePathsService = observeProjectPathsAllFromSourcePathsService; + +var _projects; + +function _load_projects() { + return _projects = require('../nuclide-commons-atom/projects'); +} + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,37 +19,22 @@ * LICENSE file in 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 strict-local + * strict-local * @format */ -import type { - SuggestedProjectPath, - DebuggerSourcePathsService, -} from 'atom-ide-debugger-java/types'; - -import {observeProjectPathsAll} from 'nuclide-commons-atom/projects'; - -export function observeProjectPathsAllFromSourcePathsService( - callback: (Array) => void, -) { - let _sourcePathsService: ?DebuggerSourcePathsService; - atom.packages.serviceHub - .consume('debugger.sourcePaths', '0.0.0', provider => { - _sourcePathsService = provider; - }) - .dispose(); - return _sourcePathsService != null - ? _sourcePathsService.observeSuggestedAndroidProjectPaths(callback) - : observeProjectPathsAll(projectPaths => { - callback( - projectPaths.map(projectPath => { - return { - projectPath, - suggested: true, - hostLabel: projectPath, - }; - }), - ); - }); -} +function observeProjectPathsAllFromSourcePathsService(callback) { + let _sourcePathsService; + atom.packages.serviceHub.consume('debugger.sourcePaths', '0.0.0', provider => { + _sourcePathsService = provider; + }).dispose(); + return _sourcePathsService != null ? _sourcePathsService.observeSuggestedAndroidProjectPaths(callback) : (0, (_projects || _load_projects()).observeProjectPathsAll)(projectPaths => { + callback(projectPaths.map(projectPath => { + return { + projectPath, + suggested: true, + hostLabel: projectPath + }; + })); + }); +} \ No newline at end of file diff --git a/modules/nuclide-jasmine/lib/faketimer.js b/modules/nuclide-jasmine/lib/faketimer.js index 400d4093da..d1b35b3977 100644 --- a/modules/nuclide-jasmine/lib/faketimer.js +++ b/modules/nuclide-jasmine/lib/faketimer.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,7 +8,7 @@ * LICENSE file in 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 */ @@ -23,7 +25,7 @@ let intervalCount = 0; let timeouts = []; let intervalTimeouts = {}; -function resetTimeouts(): void { +function resetTimeouts() { now = 0; timeoutCount = 0; intervalCount = 0; @@ -31,20 +33,18 @@ 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, - ); + timeouts.sort(([, 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) { @@ -73,7 +73,7 @@ function advanceClock(deltaMs: number): void { /** * Allows tests to use the non-fake setTimeout and clearTimeout functions. */ -function useRealClock(): void { +function useRealClock() { jasmine.unspy(global, 'setTimeout'); jasmine.unspy(global, 'clearTimeout'); jasmine.unspy(Date, 'now'); @@ -83,7 +83,7 @@ function useRealClock(): void { * Atom does this half-way mock. * https://github.com/atom/atom/blob/v1.12.7/spec/spec-helper.coffee#L169-L174 */ -function useMockClock(): void { +function useMockClock() { spyOn(global, 'setInterval').andCallFake(fakeSetInterval); spyOn(global, 'clearInterval').andCallFake(fakeClearInterval); } @@ -98,7 +98,7 @@ 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 @@ -110,4 +110,4 @@ beforeEach(() => { 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 19a89cc4ab..b1e02783f6 100644 --- a/modules/nuclide-jasmine/lib/focused.js +++ b/modules/nuclide-jasmine/lib/focused.js @@ -1,3 +1,10 @@ +'use strict'; + +// eslint-disable-next-line nuclide-internal/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,7 +13,7 @@ * LICENSE file in 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 */ @@ -15,26 +22,7 @@ * https://github.com/atom/jasmine-focused/blob/c922330/src/jasmine-focused.coffee */ -import invariant from 'assert'; - -// eslint-disable-next-line nuclide-internal/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; +const jasmine = global.jasmine; function setGlobalFocusPriority(priority) { const env = jasmine.getEnv(); @@ -51,7 +39,11 @@ function fdescribe(description, specDefinitions, priority_) { const priority = priority_ != null ? priority_ : 1; setGlobalFocusPriority(priority); const suite = describe(description, specDefinitions); - invariant(suite != null); + + if (!(suite != null)) { + throw new Error('Invariant violation: "suite != null"'); + } + suite.focusPriority = priority; return suite; } @@ -71,7 +63,11 @@ function fit(description, definition, priority_) { const priority = priority_ != null ? priority_ : 1; setGlobalFocusPriority(priority); const spec = it(description, definition); - invariant(spec != null); + + if (!(spec != null)) { + throw new Error('Invariant violation: "spec != null"'); + } + spec.focusPriority = priority; return spec; } @@ -87,7 +83,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; @@ -99,7 +95,10 @@ jasmine.getEnv().specFilter = function(spec) { } else if (!parent) { return false; } else { - invariant(typeof env.specFilter === 'function'); + if (!(typeof env.specFilter === 'function')) { + throw new Error('Invariant violation: "typeof env.specFilter === \'function\'"'); + } + return env.specFilter(parent); } }; @@ -111,4 +110,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 11ad1c895a..6a03c561c4 100644 --- a/modules/nuclide-jasmine/lib/unspy.js +++ b/modules/nuclide-jasmine/lib/unspy.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,7 +8,7 @@ * LICENSE file in 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 */ @@ -17,9 +19,9 @@ 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) { +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 c6dd0b7d5e..614a50b944 100644 --- a/modules/nuclide-jasmine/lib/waitsForPromise.js +++ b/modules/nuclide-jasmine/lib/waitsForPromise.js @@ -1,25 +1,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. - * - * @flow - * @format - */ +'use strict'; -import invariant from 'assert'; - -type WaitsForPromiseOptions = { - shouldReject?: boolean, - timeout?: number, -}; - -export default function waitsForPromise( - ...args: Array Promise)> -): void { +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = waitsForPromise; +function waitsForPromise(...args) { let shouldReject; let timeout; if (args.length > 1) { @@ -34,45 +19,41 @@ export default function waitsForPromise( runs(() => { const fn = args[args.length - 1]; - invariant(typeof fn === 'function'); + + 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 deleted file mode 100644 index ff49da18ae..0000000000 --- a/modules/nuclide-jasmine/spec/faketimer-spec.js +++ /dev/null @@ -1,155 +0,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. - * - * @flow strict - * @format - */ - -describe('Fake timer test suite', () => { - it('test setTimeout and clearTimeout', () => { - let firstExecuted = false; - - setTimeout(() => { - firstExecuted = true; - }, 10); - - advanceClock(9); - - expect(firstExecuted).toBe(false); - advanceClock(1); - expect(firstExecuted).toBe(true); - - let secondExecuted = false; - let thirdExecuted = false; - - const secondId = setTimeout(() => { - secondExecuted = true; - }, 20); - setTimeout(() => { - thirdExecuted = true; - }, 30); - - advanceClock(19); - clearTimeout(secondId); - - expect(secondExecuted).toBe(false); - expect(thirdExecuted).toBe(false); - - advanceClock(20); - - expect(secondExecuted).toBe(false); - expect(thirdExecuted).toBe(true); - }); - - it('test setInterval and clearInterval', () => { - jasmine.useMockClock(); - - let firstExecuted = false; - - setInterval(() => { - firstExecuted = true; - }, 10); - - advanceClock(9); - - expect(firstExecuted).toBe(false); - advanceClock(1); - expect(firstExecuted).toBe(true); - - let secondExecuted = false; - let thirdExecuted = false; - - const secondId = setInterval(() => { - secondExecuted = true; - }, 20); - setInterval(() => { - thirdExecuted = true; - }, 30); - - advanceClock(19); - clearInterval(secondId); - - expect(secondExecuted).toBe(false); - expect(thirdExecuted).toBe(false); - - advanceClock(20); - - expect(secondExecuted).toBe(false); - expect(thirdExecuted).toBe(true); - }); - - it('test fakeSetTimeout triggered in expected order', () => { - let firstExecuted = false; - let secondExecuted = false; - - setTimeout(() => { - firstExecuted = true; - expect(secondExecuted).toBe(false); - }, 10); - - setTimeout(() => { - secondExecuted = true; - expect(firstExecuted).toBe(true); - }, 20); - - advanceClock(20); - - expect(firstExecuted).toBe(true); - expect(secondExecuted).toBe(true); - }); - - it('test fakeSetInterval and fakeClearInterval', () => { - let firstExecutedCount = 0; - let secondExecutedCount = 0; - - global.fakeSetInterval(() => firstExecutedCount++, 10); - advanceClock(5); - const secondId = global.fakeSetInterval(() => secondExecutedCount++, 10); - - advanceClock(15); - - expect(firstExecutedCount).toBe(2); - expect(secondExecutedCount).toBe(1); - - global.fakeClearInterval(secondId); - - advanceClock(20); - - expect(firstExecutedCount).toBe(4); - expect(secondExecutedCount).toBe(1); - }); - - // Atom's implementation will fail at this test case. (https://github.com/atom/atom/issues/6627) - it('test fakeSetInterval triggered in expected order', () => { - let firstExecutedCount = 0; - let secondExecutedCount = 0; - - global.fakeSetInterval(() => { - firstExecutedCount++; - expect(secondExecutedCount < firstExecutedCount).toBe(true); - }, 10); - - advanceClock(5); - - global.fakeSetInterval(() => secondExecutedCount++, 10); - - advanceClock(40); - - expect(firstExecutedCount).toBe(4); - expect(secondExecutedCount).toBe(4); - }); - - it('test Date.now and global.now', () => { - const now1 = Date.now(); - expect(now1).toEqual(global.now); - advanceClock(100); - const now2 = Date.now(); - expect(now2 - now1).toEqual(100); - expect(now2).toEqual(global.now); - }); -}); diff --git a/modules/nuclide-jasmine/spec/run-jasmine-tests-spec.js b/modules/nuclide-jasmine/spec/run-jasmine-tests-spec.js deleted file mode 100644 index 936480bc9c..0000000000 --- a/modules/nuclide-jasmine/spec/run-jasmine-tests-spec.js +++ /dev/null @@ -1,58 +0,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. - * - * @flow strict-local - * @format - */ - -import waitsForPromise from '../lib/waitsForPromise'; - -function testFlowtypedFunction(arg: number): number { - return arg; -} - -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'); - }); -}); - -describe('Jasmine waitsForPromise test suite', () => { - beforeEach(() => jasmine.useRealClock()); - - it('test waitsForPromise worked as expected on a resolved promise', () => { - waitsForPromise(async () => { - const promise = Promise.resolve('test'); - const result = await promise; - expect(result).toEqual('test'); - }); - }); - - it('test waitsForPromise worked as expected on a rejected promise', () => { - waitsForPromise({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}, () => { - return new Promise((resolve, reject) => { - setTimeout(resolve, 6 * 1000); - }); - }); - }); -}); diff --git a/modules/nuclide-jest/atom-reporter.js b/modules/nuclide-jest/atom-reporter.js index da98540aa7..108d1c81db 100644 --- a/modules/nuclide-jest/atom-reporter.js +++ b/modules/nuclide-jest/atom-reporter.js @@ -1,62 +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 - */ +'use strict'; -import type {TestResult, AggregatedResults} from './types'; +var _UniversalDisposable; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import React from 'react'; -import ReactDOM from 'react-dom'; -import nullthrows from 'nullthrows'; +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../nuclide-commons/UniversalDisposable')); +} -import Model from 'nuclide-commons/Model'; -import Jest from './frontend/Jest'; +var _react = _interopRequireDefault(require('react')); -const div = document.createElement('div'); -nullthrows(document.body).appendChild(div); +var _reactDom = _interopRequireDefault(require('react-dom')); -type GlobalConfig = Object; +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 nuclide-internal/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}); + onTestResult(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 0d2152ef47..d81adeef8a 100644 --- a/modules/nuclide-jest/emptyObject.js +++ b/modules/nuclide-jest/emptyObject.js @@ -1,3 +1,5 @@ +"use strict"; + /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,9 +8,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 strict + * strict * @format */ // eslint-disable-next-line nuclide-internal/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 e378d39563..0f822ba7db 100644 --- a/modules/nuclide-jest/frontend/Jest.js +++ b/modules/nuclide-jest/frontend/Jest.js @@ -1,167 +1,197 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in 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 strict-local - * @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; + +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. + * + * strict-local + * @format + */ -export default class Jest extends React.Component { +class Jest extends _react.default.Component { render() { - const {results} = this.props; + 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)}
    -
    -
    - + return _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' + ) + ), + _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) + ) + ) + ) ); } } -type ResultProps = { - result: TestResult, -}; -function ResultItem(props: ResultProps) { - const {result} = props; - return ( -
  • - {result.testFilePath} - {result.failureMessage == null ? null : ( -
    {result.failureMessage}
    - )} -
    - - {result.testResults.map(test => ( - - ))} - -
    -
  • +exports.default = Jest; + +function ResultItem(props) { + const { result } = props; + return _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; - return ( -
  • - - {test.title} - {test.failureMessages.length > 0 ? ( - - {test.failureMessages.map(message => { - return ( -
  • -
    {message}
    -
  • - ); - })} - - ) : null} - +function SingleTestItem(props) { + const { test } = props; + return _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 ( -
    - ); + return _react.default.createElement('div', Object.assign({ + style: { + display: 'flex', + flexDirection: 'column', + height: '100vh' + } + }, props)); } function Header(props) { - const {success, ...restProps} = props; - return ( -
    - ); + const { success } = props, + restProps = _objectWithoutProperties(props, ['success']); + return _react.default.createElement('header', Object.assign({ + style: { + alignItems: 'center', + display: 'flex', + height: 48, + backgroundColor: success ? 'green' : 'red', + color: 'white', + flex: '0 0 48', + 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) { - return ( -
    - ); +const Main = function (props) { + return _react.default.createElement('div', Object.assign({ + style: { + flex: 1, + overflow: 'auto', + padding: '40px 0' + } + }, props)); }; -const List = function(props) { - return ( -
      - ); +const List = function (props) { + return _react.default.createElement('ol', Object.assign({ + style: { + listStyle: 'none', + 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 83813c3340..a726efc43f 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/NodeTranspiler-spec.js b/modules/nuclide-node-transpiler/spec/NodeTranspiler-spec.js deleted file mode 100644 index ac41a896ab..0000000000 --- a/modules/nuclide-node-transpiler/spec/NodeTranspiler-spec.js +++ /dev/null @@ -1,160 +0,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. - * - * @noflow - */ -'use strict'; - -/* eslint - comma-dangle: [1, always-multiline], - prefer-object-spread/prefer-object-spread: 0, - nuclide-internal/no-commonjs: 0, - */ - -const fs = require('fs'); -const vm = require('vm'); -const dedent = require('dedent'); - -const NodeTranspiler = require('../lib/NodeTranspiler'); - -describe('NodeTranspiler', () => { - describe('NodeTranspiler.shouldCompile', () => { - it('matches @flow', () => { - [ - '/** @flow */\n', - dedent` - /** - * @flow - */ - `, - dedent` - /** - * @foo - * @flow - */ - `, - ].forEach(src => { - expect(NodeTranspiler.shouldCompile(src)).toBe(true); - expect(NodeTranspiler.shouldCompile(new Buffer(src))).toBe(true); - }); - }); - - it('ignores everything else', () => { - [ - "'use strict';\n", - '/** @fflow */\n', - '/** flow */\n', - dedent` - 'use strict'; - /** - * @flow - */ - `, - dedent` - 'use strict'; - /** - * @flow - */ - `, - // You have to strip your own shebang before the docblock is parsed! - dedent` - #!/usr/bin/env node - /** - * @flow - */ - `, - ].forEach(src => { - expect(NodeTranspiler.shouldCompile(src)).toBe(false); - expect(NodeTranspiler.shouldCompile(new Buffer(src))).toBe(false); - }); - }); - }); - - describe('NodeTranspiler#getConfigDigest', () => { - it('works with real babel', () => { - const realBabel = require('babel-core'); - const nodeTranspilerReal = new NodeTranspiler(); - - const fakeBabel = { - version: realBabel.version, - transform() { throw new Error('This should not have been called.'); }, - }; - const nodeTranspilerFake = - new NodeTranspiler(fakeBabel.version, () => fakeBabel); - - expect(nodeTranspilerReal.getConfigDigest()) - .toBe(nodeTranspilerFake.getConfigDigest()); - }); - }); - - describe('NodeTranspiler#transform', () => { - it('works on buffers', () => { - const filename = require.resolve('./fixtures/modern-syntax'); - const nodeTranspiler = new NodeTranspiler(); - - const bufferSrc = fs.readFileSync(filename); - expect(Buffer.isBuffer(bufferSrc)).toBe(true); - - const out1 = nodeTranspiler.transform(bufferSrc, filename); - expect(typeof out1).toBe('string'); - - const c1 = {exports: {}}; - vm.runInNewContext(out1, c1); - expect(c1.exports.Foo.bar).toBe('qux'); - }); - - it('works on strings', () => { - const filename = require.resolve('./fixtures/modern-syntax'); - const nodeTranspiler = new NodeTranspiler(); - - const stringSrc = fs.readFileSync(filename, 'utf8'); - expect(typeof stringSrc).toBe('string'); - - const out2 = nodeTranspiler.transform(stringSrc, filename); - expect(typeof out2).toBe('string'); - - const c2 = {exports: {}}; - vm.runInNewContext(out2, c2); - expect(c2.exports.Foo.bar).toBe('qux'); - }); - }); - - describe('NodeTranspiler#_getCacheFilename', () => { - it('works', () => { - const filename = require.resolve('./fixtures/modern-syntax'); - const nodeTranspiler = new NodeTranspiler(); - - const bufferSrc = fs.readFileSync(filename); - expect(Buffer.isBuffer(bufferSrc)).toBe(true); - - const cacheFilename1 = - nodeTranspiler._getCacheFilename(bufferSrc, filename); - const cacheFilename2 = - nodeTranspiler._getCacheFilename(bufferSrc.toString(), filename); - - expect(cacheFilename1).toEqual(cacheFilename2); - }); - }); - - describe('NodeTranspiler#transformWithCache', () => { - it('reads from the cache', () => { - const filename = require.resolve('./fixtures/modern-syntax'); - const nodeTranspiler = new NodeTranspiler(); - - nodeTranspiler._getCacheFilename = src => { - expect(src).toBe('abc'); - return filename; - }; - - const out = nodeTranspiler.transformWithCache('abc', filename); - const expected = fs.readFileSync(filename, 'utf8'); - - expect(out).toBe(expected); - }); - }); -}); diff --git a/modules/nuclide-node-transpiler/spec/README.md b/modules/nuclide-node-transpiler/spec/README.md deleted file mode 100644 index 601fdd79be..0000000000 --- a/modules/nuclide-node-transpiler/spec/README.md +++ /dev/null @@ -1,3 +0,0 @@ -`nuclide-node-transpiler` is a dependency of `nuclide-jasmine`, so it cannot use `nuclide-jasmine` as a test runner. - -Since some of the tests need a clean environment and some tests install the require hook, each test is run in a new node process. diff --git a/modules/nuclide-node-transpiler/spec/bin-transpile-spec.js b/modules/nuclide-node-transpiler/spec/bin-transpile-spec.js deleted file mode 100644 index 0a4f76ba0b..0000000000 --- a/modules/nuclide-node-transpiler/spec/bin-transpile-spec.js +++ /dev/null @@ -1,47 +0,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. - * - * @noflow - */ -'use strict'; - -/* eslint - comma-dangle: [1, always-multiline], - prefer-object-spread/prefer-object-spread: 0, - nuclide-internal/no-commonjs: 0, - */ - -const child_process = require('child_process'); -const vm = require('vm'); - -describe('bin-transpile', () => { - it('transpiles one file', () => { - const ps = child_process.spawn( - require.resolve('../bin/transpile.js'), - [require.resolve('./fixtures/modern-syntax')] - ); - - let out = ''; - let err = ''; - ps.stdout.on('data', buf => { out += buf; }); - ps.stderr.on('data', buf => { err += buf; }); - - let ran = false; - ps.on('close', () => { - expect(err).toBe(''); - - const c = {exports: {}}; - vm.runInNewContext(out, c); - expect(c.exports.Foo.bar).toBe('qux'); - - ran = true; - }); - - waitsFor(() => ran); - }); -}); diff --git a/modules/nuclide-node-transpiler/spec/env-spec.js b/modules/nuclide-node-transpiler/spec/env-spec.js deleted file mode 100644 index 0300de13d1..0000000000 --- a/modules/nuclide-node-transpiler/spec/env-spec.js +++ /dev/null @@ -1,28 +0,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. - * - * @noflow - */ -'use strict'; - -/* eslint - comma-dangle: [1, always-multiline], - prefer-object-spread/prefer-object-spread: 0, - nuclide-internal/no-commonjs: 0, - */ - -const fs = require('fs'); -const path = require('path'); - -describe('env', () => { - it('has correct __DEV__', () => { - // This should exist if we're running a test. - expect(fs.existsSync(path.join(__dirname, '../../../DEVELOPMENT'))).toBe(true); - expect(require('../lib/env').__DEV__).toBe(true); - }); -}); diff --git a/modules/nuclide-node-transpiler/spec/fixtures/modern-syntax.js b/modules/nuclide-node-transpiler/spec/fixtures/modern-syntax.js deleted file mode 100644 index cf76237719..0000000000 --- a/modules/nuclide-node-transpiler/spec/fixtures/modern-syntax.js +++ /dev/null @@ -1,15 +0,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. - * - * @flow strict - * @format - */ - -export class Foo { - static bar = 'qux'; -} diff --git a/modules/nuclide-node-transpiler/spec/fixtures/require-hook-test.js b/modules/nuclide-node-transpiler/spec/fixtures/require-hook-test.js deleted file mode 100644 index ab5b2c2e5a..0000000000 --- a/modules/nuclide-node-transpiler/spec/fixtures/require-hook-test.js +++ /dev/null @@ -1,49 +0,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. - * - * @noflow - */ -'use strict'; - -/* eslint - comma-dangle: [1, always-multiline], - prefer-object-spread/prefer-object-spread: 0, - nuclide-internal/no-commonjs: 0, - */ -/* eslint-disable no-console */ - -require('../..'); - -const assert = require('assert'); - -assert.doesNotThrow(() => { - require('./modern-syntax'); -}); - -const ModernSyntax = require('./modern-syntax'); -assert.equal(typeof ModernSyntax.Foo, 'function'); -assert.equal(ModernSyntax.Foo.bar, 'qux'); - -const VanillaSyntax = require('./vanilla-syntax'); -assert.equal(typeof VanillaSyntax.Foo, 'function'); -assert.equal(typeof VanillaSyntax.Foo.bar, 'function'); -assert.equal(VanillaSyntax.Foo.bar(), 'qux'); - -// This may not always be true forever. If the v8 output changes, then remove -// this test. -assert.equal( - VanillaSyntax.Foo.toString(), - "class Foo {\n static bar() {\n return 'qux';\n }\n}" -); -// The transpiled version of "Foo" would've looked like this: -assert.notEqual( - VanillaSyntax.Foo.toString(), - 'function Foo() {\n _classCallCheck(this, Foo);\n }' -); - -console.log('OK'); diff --git a/modules/nuclide-node-transpiler/spec/fixtures/vanilla-syntax.js b/modules/nuclide-node-transpiler/spec/fixtures/vanilla-syntax.js deleted file mode 100644 index 218413208b..0000000000 --- a/modules/nuclide-node-transpiler/spec/fixtures/vanilla-syntax.js +++ /dev/null @@ -1,25 +0,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. - * - * @noflow - */ -'use strict'; - -/* eslint - comma-dangle: [1, always-multiline], - prefer-object-spread/prefer-object-spread: 0, - nuclide-internal/no-commonjs: 0, - */ - -class Foo { - static bar() { - return 'qux'; - } -} - -module.exports.Foo = Foo; diff --git a/modules/nuclide-node-transpiler/spec/inline-invariant-spec.js b/modules/nuclide-node-transpiler/spec/inline-invariant-spec.js deleted file mode 100644 index 6df44fb7ea..0000000000 --- a/modules/nuclide-node-transpiler/spec/inline-invariant-spec.js +++ /dev/null @@ -1,176 +0,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. - * - * @noflow - */ -'use strict'; - -/* eslint - comma-dangle: [1, always-multiline], - prefer-object-spread/prefer-object-spread: 0, - nuclide-internal/no-commonjs: 0, - */ - -const babel = require('babel-core'); -const dedent = require('dedent'); - -function transform(source) { - return babel.transform(source, { - plugins: [ - require('babel-plugin-syntax-flow'), - require('../lib/inline-invariant-tr'), - ], - }).code; -} - -describe('inline-invariant transform', () => { - it('works 1', () => { - expect(transform(dedent` - import invariant from ''; - invariant(false); - `)).toEqual(dedent` - if (!false) { - throw new Error('Invariant violation: "false"'); - } - `); - }); - - it('works 2', () => { - expect(transform(dedent` - import invariant from ''; - invariant(false != true); - `)).toEqual(dedent` - if (!(false != true)) { - throw new Error('Invariant violation: "false != true"'); - } - `); - }); - - it('works 3', () => { - expect(transform(dedent` - import invariant from ''; - invariant(foo() ? !!bar : baz.qux()); - `)).toEqual(dedent` - if (!(foo() ? !!bar : baz.qux())) { - throw new Error('Invariant violation: "foo() ? !!bar : baz.qux()"'); - } - `); - }); - - it('works 4', () => { - expect(transform(dedent` - import invariant from ''; - invariant(true, 'it is true'); - `)).toEqual(dedent` - if (!true) { - throw new Error('it is true'); - } - `); - }); - - it('works 5', () => { - expect(transform(dedent` - import {invariant} from ''; - invariant(true, 'it is true'); - `)).toEqual(dedent` - if (!true) { - throw new Error('it is true'); - } - `); - }); - - it('works 6', () => { - expect(transform(dedent` - import invariant from ''; - invariant(true, 'it is true'); - invariant.ok(); - `)).toEqual(dedent` - import invariant from ''; - - if (!true) { - throw new Error('it is true'); - } - - invariant.ok(); - `); - }); - - it('works 7', () => { - expect(transform(dedent` - export { invariant } from '' - `)).toEqual(dedent` - export { invariant } from ''; - `); - }); - - it('works 8', () => { - expect(transform(dedent` - import {default as invariant} from '' - invariant(true); - `)).toEqual(dedent` - if (!true) { - throw new Error('Invariant violation: "true"'); - } - `); - }); - - it('works 9', () => { - expect(transform(dedent` - invariant; - `)).toEqual(dedent` - invariant; - `); - }); - - it('works 10', () => { - expect(transform(dedent` - var invariant = require('invariant'); - `)).toEqual(dedent` - var invariant = require('invariant'); - `); - }); - - it('works 11', () => { - expect(transform(dedent` - var invariant = require('invariant'); - invariant(true); - `)).toEqual(dedent` - var invariant = require('invariant'); - invariant(true); - `); - }); - - it('works 12', () => { - expect(transform(dedent` - import invariant from 'invariant'; - foo; - `)).toEqual('\nfoo;'); - }); - - it('works 13', () => { - expect(() => { - transform(dedent` - import invariant from 'invariant'; - if (invariant(true)) {} - `); - }).toThrow( - new SyntaxError('unknown: `invariant()` must be used as an expression statement.') - ); - }); - - it('works 14', () => { - expect(() => { - transform(dedent` - import invariant from 'invariant'; - invariant(); - `); - }).toThrow( - new SyntaxError('unknown: `invariant()` must at least one argument.') - ); - }); -}); diff --git a/modules/nuclide-node-transpiler/spec/main-spec.js b/modules/nuclide-node-transpiler/spec/main-spec.js deleted file mode 100644 index 0725453ebf..0000000000 --- a/modules/nuclide-node-transpiler/spec/main-spec.js +++ /dev/null @@ -1,32 +0,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. - * - * @noflow - */ -'use strict'; - -/* eslint - comma-dangle: [1, always-multiline], - prefer-object-spread/prefer-object-spread: 0, - nuclide-internal/no-commonjs: 0, - */ - -const child_process = require('child_process'); - -describe('require-hook', () => { - it('works', () => { - // This test runs in a new process because it monkey-patches `require` and - // we don't want to pollute the test environment. - const ret = child_process.spawnSync(process.execPath, [ - require.resolve('./fixtures/require-hook-test'), - ]); - expect(ret.status).toBe(0); - expect(String(ret.stdout).trim()).toBe('OK'); - expect(String(ret.stderr).trim()).toBe(''); - }); -}); diff --git a/modules/nuclide-node-transpiler/spec/path-rules-spec.js b/modules/nuclide-node-transpiler/spec/path-rules-spec.js deleted file mode 100644 index b1dda7e4ec..0000000000 --- a/modules/nuclide-node-transpiler/spec/path-rules-spec.js +++ /dev/null @@ -1,52 +0,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. - * - * @noflow - */ -'use strict'; - -/* eslint - comma-dangle: [1, always-multiline], - prefer-object-spread/prefer-object-spread: 0, - nuclide-internal/no-commonjs: 0, - */ - -const path = require('path'); -const glob = require('glob'); - -const pathRules = require('../lib/path-rules'); - -describe('path-rules', () => { - describe('pathRules.getIncludedFiles', () => { - it('works', () => { - const includedFiles = pathRules.getIncludedFiles(); - - expect(includedFiles.includes(__filename)).toBe(true); - - const pathToNodeModulesFile = require.resolve('babel-core'); - expect(!includedFiles.includes(pathToNodeModulesFile)).toBe(true); - }); - }); - - describe('pathRules.isIncluded', () => { - it('matches what getIncludedFiles finds', () => { - const expectedFiles = pathRules.getIncludedFiles().sort(); - const allFiles = glob.sync(path.join(__dirname, '../../../**/*.js')).sort(); - - expect(expectedFiles).not.toEqual(allFiles); - - for (let i = allFiles.length - 1; i >= 0; i--) { - if (!pathRules.isIncluded(allFiles[i])) { - allFiles.splice(i, 1); - } - } - - expect(expectedFiles).toEqual(allFiles); - }); - }); -}); diff --git a/modules/nuclide-watchman-helpers/lib/WatchmanClient.js b/modules/nuclide-watchman-helpers/lib/WatchmanClient.js index 9f8d8b381e..fb42a1af04 100644 --- a/modules/nuclide-watchman-helpers/lib/WatchmanClient.js +++ b/modules/nuclide-watchman-helpers/lib/WatchmanClient.js @@ -1,68 +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 nuclideUri from 'nuclide-commons/nuclideUri'; -import watchman from 'fb-watchman'; -import {serializeAsyncCall, sleep} from 'nuclide-commons/promise'; -import {maybeToString} from 'nuclide-commons/string'; -import {getWatchmanBinaryPath} from './path'; -import WatchmanSubscription from './WatchmanSubscription'; -import {getLogger} from 'log4js'; - -const logger = getLogger('nuclide-watchman-helpers'); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../nuclide-commons/nuclideUri')); +} + +var _fbWatchman; + +function _load_fbWatchman() { + return _fbWatchman = _interopRequireDefault(require('fb-watchman')); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../nuclide-commons/promise'); +} + +var _string; + +function _load_string() { + return _string = require('../../nuclide-commons/string'); +} + +var _path; + +function _load_path() { + return _path = require('./path'); +} + +var _WatchmanSubscription; + +function _load_WatchmanSubscription() { + return _WatchmanSubscription = _interopRequireDefault(require('./WatchmanSubscription')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-watchman-helpers'); /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in 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 WATCHMAN_SETTLE_TIME_MS = 2500; -import type {WatchmanSubscriptionOptions} from './WatchmanSubscription'; - -type WatchmanSubscriptionResponse = { - root: string, - subscription: string, - files?: Array, - 'state-enter'?: string, - 'state-leave'?: string, - metadata?: Object, - canceled?: boolean, -}; - -export type FileChange = { - name: string, - new: boolean, - exists: boolean, - mode: number, -}; - -export default class WatchmanClient { - _subscriptions: Map; - _clientPromise: Promise; - _serializedReconnect: () => Promise; +class WatchmanClient { constructor() { this._initWatchmanClient(); - this._serializedReconnect = serializeAsyncCall(() => { + this._serializedReconnect = (0, (_promise || _load_promise()).serializeAsyncCall)(() => { logger.info('Calling _reconnectClient from _serializedReconnect.'); - return this._reconnectClient().catch(error => - logger.error('_reconnectClient failed', error), - ); + return this._reconnectClient().catch(error => logger.error('_reconnectClient failed', error)); }); this._subscriptions = new Map(); } - async dispose(): Promise { + async dispose() { const client = await this._clientPromise; client.removeAllListeners(); // disable reconnection client.end(); } - async _initWatchmanClient(): Promise { + async _initWatchmanClient() { this._clientPromise = this._createClientPromise(); const client = await this._clientPromise; @@ -87,13 +104,13 @@ export default class WatchmanClient { client.on('subscription', this._onSubscriptionResult.bind(this)); } - async _createClientPromise(): Promise { - return new watchman.Client({ - watchmanBinaryPath: await getWatchmanBinaryPath(), + async _createClientPromise() { + return new (_fbWatchman || _load_fbWatchman()).default.Client({ + watchmanBinaryPath: await (0, (_path || _load_path()).getWatchmanBinaryPath)() }); } - async _reconnectClient(): Promise { + async _reconnectClient() { logger.error('Watchman client disconnected, reconnecting a new client!'); await this._initWatchmanClient(); logger.info('Watchman client re-initialized, restoring subscriptions'); @@ -102,56 +119,43 @@ export default class WatchmanClient { // TODO(mbolin): What happens if someone calls watchDirectoryRecursive() while // this method is executing? - async _restoreSubscriptions(): Promise { + async _restoreSubscriptions() { const watchSubscriptions = Array.from(this._subscriptions.values()); const numSubscriptions = watchSubscriptions.length; - logger.info( - `Attempting to restore ${numSubscriptions} Watchman subscriptions.`, - ); + logger.info(`Attempting to restore ${numSubscriptions} Watchman subscriptions.`); let numRestored = 0; - await Promise.all( - watchSubscriptions.map( - async (subscription: WatchmanSubscription, index: number) => { - // Note that this call to `watchman watch-project` could fail if the - // subscription.path has been unmounted/deleted. - await this._watchProject(subscription.path); - - // We have already missed the change events from the disconnect time, - // watchman could have died, so the last clock result is not valid. - await sleep(WATCHMAN_SETTLE_TIME_MS); - - // Register the subscriptions after the filesystem settles. - const {name, options, root} = subscription; - subscription.options.since = await this._clock(root); - logger.info( - `Subscribing to ${name}: (${index + 1}/${numSubscriptions})`, - ); - await this._subscribe(root, name, options); - ++numRestored; - logger.info( - `Subscribed to ${name}: (${numRestored}/${numSubscriptions}) complete.`, - ); - }, - ), - ); + await Promise.all(watchSubscriptions.map(async (subscription, index) => { + // Note that this call to `watchman watch-project` could fail if the + // subscription.path has been unmounted/deleted. + await this._watchProject(subscription.path); + + // We have already missed the change events from the disconnect time, + // watchman could have died, so the last clock result is not valid. + await (0, (_promise || _load_promise()).sleep)(WATCHMAN_SETTLE_TIME_MS); + + // Register the subscriptions after the filesystem settles. + const { name, options, root } = subscription; + subscription.options.since = await this._clock(root); + logger.info(`Subscribing to ${name}: (${index + 1}/${numSubscriptions})`); + await this._subscribe(root, name, options); + ++numRestored; + logger.info(`Subscribed to ${name}: (${numRestored}/${numSubscriptions}) complete.`); + })); } - _getSubscription(entryPath: string): ?WatchmanSubscription { - return this._subscriptions.get(nuclideUri.normalize(entryPath)); + _getSubscription(entryPath) { + return this._subscriptions.get((_nuclideUri || _load_nuclideUri()).default.normalize(entryPath)); } - _setSubscription( - entryPath: string, - subscription: WatchmanSubscription, - ): void { - this._subscriptions.set(nuclideUri.normalize(entryPath), subscription); + _setSubscription(entryPath, subscription) { + this._subscriptions.set((_nuclideUri || _load_nuclideUri()).default.normalize(entryPath), subscription); } - _deleteSubscription(entryPath: string): void { - this._subscriptions.delete(nuclideUri.normalize(entryPath)); + _deleteSubscription(entryPath) { + this._subscriptions.delete((_nuclideUri || _load_nuclideUri()).default.normalize(entryPath)); } - _onSubscriptionResult(response: WatchmanSubscriptionResponse): void { + _onSubscriptionResult(response) { const subscription = this._getSubscription(response.subscription); if (subscription == null) { logger.error('Subscription not found for response:!', response); @@ -161,28 +165,19 @@ export default class WatchmanClient { if (Array.isArray(response.files)) { subscription.emit('change', response.files); } else if (response.canceled === true) { - logger.info( - `Watch for ${response.root} was deleted: triggering a reconnect.`, - ); + logger.info(`Watch for ${response.root} was deleted: triggering a reconnect.`); // Ending the client will trigger a reconnect. this._clientPromise.then(client => client.end()); } else { // TODO(most): use state messages to decide on when to send updates. const stateEnter = response['state-enter']; const stateLeave = response['state-leave']; - const stateMessage = - stateEnter != null - ? `Entering ${stateEnter}` - : `Leaving ${maybeToString(stateLeave)}`; + const stateMessage = stateEnter != null ? `Entering ${stateEnter}` : `Leaving ${(0, (_string || _load_string()).maybeToString)(stateLeave)}`; logger.info(`Subscription state: ${stateMessage}`); } } - async watchDirectoryRecursive( - localDirectoryPath: string, - subscriptionName?: string = localDirectoryPath, - subscriptionOptions?: WatchmanSubscriptionOptions, - ): Promise { + async watchDirectoryRecursive(localDirectoryPath, subscriptionName = localDirectoryPath, subscriptionOptions) { const existingSubscription = this._getSubscription(subscriptionName); if (existingSubscription) { existingSubscription.subscriptionCount++; @@ -190,14 +185,13 @@ export default class WatchmanClient { } else { const { watch: watchRoot, - relative_path: relativePath, + relative_path: relativePath } = await this._watchProject(localDirectoryPath); const clock = await this._clock(watchRoot); - const options: WatchmanSubscriptionOptions = { - ...subscriptionOptions, + const options = Object.assign({}, subscriptionOptions, { fields: ['name', 'new', 'exists', 'mode'], - since: clock, - }; + since: clock + }); if (relativePath) { options.relative_root = relativePath; } @@ -206,25 +200,24 @@ export default class WatchmanClient { options.empty_on_fresh_instance = true; // relativePath is undefined if watchRoot is the same as directoryPath. - const subscription = new WatchmanSubscription( - /* subscriptionRoot */ watchRoot, - /* pathFromSubscriptionRootToSubscriptionPath */ relativePath, - /* subscriptionPath */ localDirectoryPath, - /* subscriptionName */ subscriptionName, - /* subscriptionCount */ 1, - /* subscriptionOptions */ options, - ); + const subscription = new (_WatchmanSubscription || _load_WatchmanSubscription()).default( + /* subscriptionRoot */watchRoot, + /* pathFromSubscriptionRootToSubscriptionPath */relativePath, + /* subscriptionPath */localDirectoryPath, + /* subscriptionName */subscriptionName, + /* subscriptionCount */1, + /* subscriptionOptions */options); this._setSubscription(subscriptionName, subscription); await this._subscribe(watchRoot, subscriptionName, options); return subscription; } } - hasSubscription(entryPath: string): boolean { + hasSubscription(entryPath) { return Boolean(this._getSubscription(entryPath)); } - async unwatch(entryPath: string): Promise { + async unwatch(entryPath) { const subscription = this._getSubscription(entryPath); if (subscription == null) { @@ -242,49 +235,39 @@ export default class WatchmanClient { * List all (watched) files in the given directory. * Paths will be relative. */ - async listFiles( - entryPath: string, - options?: {[name: string]: any} = {}, - ): Promise> { - const {watch, relative_path} = await this._watchProject(entryPath); - const result = await this._command('query', watch, { - expression: [ - 'allof', - ['type', 'f'], // all files - ['exists'], - ], + async listFiles(entryPath, options = {}) { + const { watch, relative_path } = await this._watchProject(entryPath); + const result = await this._command('query', watch, Object.assign({ + expression: ['allof', ['type', 'f'], // all files + ['exists']], // Providing `path` will let watchman use path generator, and will perform // a tree walk with respect to the relative_root and path provided. // Path generator will do less work unless the root path of the repository // is passed in as an entry path. path: [''], fields: ['name'], // names only - relative_root: relative_path, - ...options, - }); + relative_root: relative_path + }, options)); return result.files; } - async _watchList(): Promise> { - const {roots} = await this._command('watch-list'); + async _watchList() { + const { roots } = await this._command('watch-list'); return roots; } - _unsubscribe( - subscriptionPath: string, - subscriptionName: string, - ): Promise { + _unsubscribe(subscriptionPath, subscriptionName) { return this._command('unsubscribe', subscriptionPath, subscriptionName); } - async _watch(directoryPath: string): Promise { + async _watch(directoryPath) { const response = await this._command('watch', directoryPath); if (response.warning) { logger.error('watchman warning: ', response.warning); } } - async _watchProject(directoryPath: string): Promise { + async _watchProject(directoryPath) { const response = await this._command('watch-project', directoryPath); if (response.warning) { logger.error('watchman warning: ', response.warning); @@ -292,38 +275,25 @@ export default class WatchmanClient { return response; } - async _clock(directoryPath: string): Promise { - const {clock} = await this._command('clock', directoryPath); + async _clock(directoryPath) { + const { clock } = await this._command('clock', directoryPath); return clock; } - _subscribe( - watchRoot: string, - subscriptionName: ?string, - options: WatchmanSubscriptionOptions, - ): Promise { - logger.info( - `Creating Watchman subscription ${String( - subscriptionName, - )} under ${watchRoot}`, - JSON.stringify(options), - ); + _subscribe(watchRoot, subscriptionName, options) { + logger.info(`Creating Watchman subscription ${String(subscriptionName)} under ${watchRoot}`, JSON.stringify(options)); return this._command('subscribe', watchRoot, subscriptionName, options); } /* * Promisify calls to watchman client. */ - _command(...args: Array): Promise { + _command(...args) { return new Promise((resolve, reject) => { - this._clientPromise - .then(client => { - client.command( - args, - (error, response) => (error ? reject(error) : resolve(response)), - ); - }) - .catch(reject); + this._clientPromise.then(client => { + client.command(args, (error, response) => error ? reject(error) : resolve(response)); + }).catch(reject); }); } } +exports.default = WatchmanClient; \ No newline at end of file diff --git a/modules/nuclide-watchman-helpers/lib/WatchmanSubscription.js b/modules/nuclide-watchman-helpers/lib/WatchmanSubscription.js index eeb2d5e0ff..0d6ec2f0f6 100644 --- a/modules/nuclide-watchman-helpers/lib/WatchmanSubscription.js +++ b/modules/nuclide-watchman-helpers/lib/WatchmanSubscription.js @@ -1,38 +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 strict - * @format - */ +'use strict'; -import {Emitter} from 'event-kit'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -export type WatchmanSubscriptionOptions = { - expression: ?Array, // e.g. ['match', '*.js'], - fields?: Array, // e.g. ['name', 'size', 'exists', 'mode'] - expression?: Array, // e.g. ['dirname', relativePath] - since?: string, // e.g. "c:1439492655:58601:1:14195" - defer_vcs?: boolean, +var _eventKit; - /** - * For performance reasons, prefer: - * - * "relative_root": "relative/path" - * - * over: - * - * "expression": ["dirname", "relative/path"] - */ - relative_root?: string, - - /** If true, no files will be returned for fresh instances. */ - empty_on_fresh_instance?: boolean, -}; +function _load_eventKit() { + return _eventKit = require('event-kit'); +} /** * @param pathFromSubscriptionRootToSubscriptionPath The relative path from @@ -41,21 +17,8 @@ export type WatchmanSubscriptionOptions = { * Notably, this value should be undefined if subscriptionRoot is the same as * subscriptionPath. */ -export default class WatchmanSubscription extends Emitter { - subscriptionCount: number; - root: string; - path: string; - pathFromSubscriptionRootToSubscriptionPath: ?string; - name: string; - options: WatchmanSubscriptionOptions; - constructor( - subscriptionRoot: string, - pathFromSubscriptionRootToSubscriptionPath: ?string, - subscriptionPath: string, - subscriptionName: string, - subscriptionCount: number, - subscriptionOptions: WatchmanSubscriptionOptions, - ) { +class WatchmanSubscription extends (_eventKit || _load_eventKit()).Emitter { + constructor(subscriptionRoot, pathFromSubscriptionRootToSubscriptionPath, subscriptionPath, subscriptionName, subscriptionCount, subscriptionOptions) { super(); this.root = subscriptionRoot; this.pathFromSubscriptionRootToSubscriptionPath = pathFromSubscriptionRootToSubscriptionPath; @@ -65,3 +28,14 @@ export default class WatchmanSubscription extends Emitter { this.options = subscriptionOptions; } } +exports.default = WatchmanSubscription; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-watchman-helpers/lib/main.js b/modules/nuclide-watchman-helpers/lib/main.js index ad97049631..500a38ef12 100644 --- a/modules/nuclide-watchman-helpers/lib/main.js +++ b/modules/nuclide-watchman-helpers/lib/main.js @@ -1,18 +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 strict-local - * @format - */ +'use strict'; -import type {FileChange} from './WatchmanClient'; -import WatchmanClient from './WatchmanClient'; -import WatchmanSubscription from './WatchmanSubscription'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.WatchmanSubscription = exports.WatchmanClient = undefined; -export type {FileChange}; -export {WatchmanClient, WatchmanSubscription}; +var _WatchmanClient; + +function _load_WatchmanClient() { + return _WatchmanClient = _interopRequireDefault(require('./WatchmanClient')); +} + +var _WatchmanSubscription; + +function _load_WatchmanSubscription() { + return _WatchmanSubscription = _interopRequireDefault(require('./WatchmanSubscription')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.WatchmanClient = (_WatchmanClient || _load_WatchmanClient()).default; +exports.WatchmanSubscription = (_WatchmanSubscription || _load_WatchmanSubscription()).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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-watchman-helpers/lib/path.js b/modules/nuclide-watchman-helpers/lib/path.js index 35a2b20f42..7f95a67206 100644 --- a/modules/nuclide-watchman-helpers/lib/path.js +++ b/modules/nuclide-watchman-helpers/lib/path.js @@ -1,30 +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 strict-local - * @format - */ +'use strict'; -import fsPromise from 'nuclide-commons/fsPromise'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getWatchmanBinaryPath = getWatchmanBinaryPath; -const WATCHMAN_DEFAULT_PATH = '/usr/local/bin/watchman'; +var _fsPromise; -export async function getWatchmanBinaryPath(): Promise { +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../nuclide-commons/fsPromise')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const WATCHMAN_DEFAULT_PATH = '/usr/local/bin/watchman'; /** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * strict-local + * @format + */ + +async function getWatchmanBinaryPath() { try { - const stats = await fsPromise.stat(WATCHMAN_DEFAULT_PATH); + const stats = await (_fsPromise || _load_fsPromise()).default.stat(WATCHMAN_DEFAULT_PATH); // `stats` contains a `mode` property, a number which can be used to determine // whether this file is executable. However, the number is platform-dependent. if (stats && stats.isFile()) { return WATCHMAN_DEFAULT_PATH; } - } catch (e) { - // Suppress the error. - } + } catch (e) {} + // Suppress the error. + // Let the watchman Client find the watchman binary via the default env PATH. return 'watchman'; -} +} \ No newline at end of file diff --git a/modules/nuclide-watchman-helpers/spec/WatchmanClient-spec.js b/modules/nuclide-watchman-helpers/spec/WatchmanClient-spec.js deleted file mode 100644 index d957b82109..0000000000 --- a/modules/nuclide-watchman-helpers/spec/WatchmanClient-spec.js +++ /dev/null @@ -1,176 +0,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. - * - * @flow - * @format - */ - -import fs from 'fs'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import watchman from 'fb-watchman'; -import WatchmanClient from '../lib/WatchmanClient'; -import {generateFixture} from 'nuclide-commons/test-helpers'; - -const FILE_MODE = 33188; - -describe('WatchmanClient test suite', () => { - let dirPath: string = ''; - let client: WatchmanClient = (null: any); - - beforeEach(() => { - jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; - client = new WatchmanClient(); - - waitsForPromise(async () => { - dirPath = await generateFixture( - 'watchman_helpers_test', - new Map([ - // Many people use restrict_root_files so watchman only will watch folders - // that have those listed files in them. watchmanconfig is always a root - // file. - ['.watchmanconfig', '{}'], - ['test.txt', 'abc'], - ['non-used-file.txt', 'def'], - ['nested/nested-test.txt', 'ghi'], - ]), - ); - // TODO(hansonw): This is a big change in Watchman behavior- figure out what - // this means for Nuclide's use. - dirPath = fs.realpathSync(dirPath); - waits(1010); - }); - }); - - afterEach(() => { - client.dispose(); - }); - - describe('restore subscriptions', () => { - function testRestoreSubscriptions( - onRestoreChange: (watchmanClient: watchman.Client) => void, - ) { - // First watchman init can be slow and flaky. - waitsForPromise({timeout: 15000}, async () => { - const filePath = nuclideUri.join(dirPath, 'test.txt'); - const watcher = await client - .watchDirectoryRecursive(dirPath) - // Give it two retries. - .catch(() => client.watchDirectoryRecursive(dirPath)) - .catch(() => client.watchDirectoryRecursive(dirPath)); - const changeHandler = jasmine.createSpy(); - watcher.on('change', changeHandler); - waits(1010); - runs(() => fs.writeFileSync(filePath, 'def')); - waitsFor(() => changeHandler.callCount > 0); - runs(async () => { - expect(changeHandler.callCount).toBe(1); - expect(changeHandler.argsForCall[0][0]).toEqual([ - { - name: 'test.txt', - mode: FILE_MODE, - new: false, - exists: true, - }, - ]); - const internalClient = await client._clientPromise; - onRestoreChange(internalClient); - internalClient.end(); - }); - waits(1000); // Wait for watchman to watch the directory. - runs(() => advanceClock(3000)); // Pass the settle filesystem time. - waits(1000); // Wait for the client to restore subscriptions. - runs(() => fs.unlinkSync(filePath)); - waitsFor(() => changeHandler.callCount > 1); - runs(() => { - expect(changeHandler.callCount).toBe(2); - expect(changeHandler.argsForCall[1][0]).toEqual([ - { - name: 'test.txt', - mode: FILE_MODE, - new: false, - exists: false, - }, - ]); - }); - }); - // Cleanup watch resources. - waitsForPromise(() => client.unwatch(dirPath)); - } - - it('restores subscriptions on client end', () => { - testRestoreSubscriptions(watchmanClient => { - // End the socket client to watchman to trigger restore subscriptions. - watchmanClient.end(); - }); - }); - - it('restores subscriptions on client error', () => { - testRestoreSubscriptions(watchmanClient => { - // End the socket client to watchman to trigger restore subscriptions. - watchmanClient.emit('error', new Error('fake error')); - }); - }); - - /** - * This simulates the case where: - * 1. watchman fails, and then - * 2. the reconnection fails on startup - * 3. subsequent reconnections can still succeed. - * - * We need to make sure we don't end up in a deadlock where the first reconnection - * attempt blocks subsequent ones. - */ - it('restores subscriptions on client startup failure', () => { - testRestoreSubscriptions(watchmanClient => { - let counter = 0; - const oldConnect = watchman.Client.prototype.connect; - spyOn(watchman.Client.prototype, 'connect').andCallFake(function() { - if (counter++ === 0) { - this.emit('error', new Error('startup error')); - } else { - oldConnect.apply(this); - } - }); - watchmanClient.emit('error', new Error('fake error')); - }); - }); - }); - - describe('cleanup watchers after unwatch', () => { - it('unwatch cleans up watchman subscriptions resources', () => { - waitsForPromise(async () => { - const dirRealPath = fs.realpathSync(dirPath); - await client.watchDirectoryRecursive(dirPath); - const watchList = await client._watchList(); - expect(watchList.indexOf(dirRealPath)).not.toBe(-1); - // $FlowIssue - client.dispose = () => {}; - await client.unwatch(dirPath); - expect(client.hasSubscription(dirPath)).toBeFalsy(); - // Didn't remove it from the watched directories. - const noWatchListCleanup = await client._watchList(); - expect(noWatchListCleanup.indexOf(dirRealPath)).not.toBe(-1); - }); - }); - }); - - describe('watchProject()', () => { - it('should be able to watch nested project folders, but cleanup watchRoot', () => { - waitsForPromise(async () => { - const dirRealPath = fs.realpathSync(dirPath); - const nestedDirPath = nuclideUri.join(dirPath, 'nested'); - const { - watch: watchRoot, - relative_path: relativePath, - } = await client._watchProject(nestedDirPath); - expect(watchRoot).toBe(dirRealPath); - expect(relativePath).toBe('nested'); - }); - }); - }); -}); diff --git a/package.json b/package.json index 3745794b38..bd92375104 100644 --- a/package.json +++ b/package.json @@ -196,7 +196,6 @@ "atom": ">=1.27.0", "node": ">=7.9.0" }, - "private": true, "atomTestRunner": "./lib/test-runner-entry.js", "package-deps": [ "file-icons:2.1.21", diff --git a/pkg/commons-atom/AutocompleteCacher.js b/pkg/commons-atom/AutocompleteCacher.js index f17dc89614..9761a23001 100644 --- a/pkg/commons-atom/AutocompleteCacher.js +++ b/pkg/commons-atom/AutocompleteCacher.js @@ -1,3 +1,23 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _passesGK; + +function _load_passesGK() { + return _passesGK = _interopRequireDefault(require('../commons-node/passesGK')); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../modules/nuclide-commons/promise'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,92 +25,39 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import passesGK from '../commons-node/passesGK'; -import {PromiseWithState} from 'nuclide-commons/promise'; - -export type AutocompleteCacherConfig = {| - // This function filters+sorts the firstResult that came back from `getSuggestions`. - // Return null here to if firstResult isn't appropriate and we should go back - // to the language service. - // This function is also responsible for updating any cached TextEdit ranges. - updateResults: ( - originalRequest: atom$AutocompleteRequest, - currentRequest: atom$AutocompleteRequest, - firstResult: T, - ) => ?T, - // If we had to go to `getSuggestions` for whatever reason, we can still configure - // a filter+sort function to be used in that case too. - updateFirstResults?: (request: atom$AutocompleteRequest, firstResult: T) => T, - // If this is provided, we will ask it whether we can filter on the given request after first - // verifying that the cursor has only moved by one column since the last request. - shouldFilter?: ( - lastRequest: atom$AutocompleteRequest, - currentRequest: atom$AutocompleteRequest, - // autocomplete-plus does some debouncing so if the user types quickly enough we may not see a - // request for every character. This indicates how many columns the cursor has moved since the - // last request. Typically, within an autocomplete session this will be 1, but it may be greater - // if the user typed quickly. It is also possible that the cursor moved for another reason, so - // take care to avoid returning `true` when we are in fact not in the same autocomplete session. - charsSinceLastRequest: number, - ) => boolean, - gatekeeper?: string, -|}; - -type TrackedResponse = {request: atom$AutocompleteRequest, response: T}; - -function track( - request: atom$AutocompleteRequest, - responsePromise: Promise, -): Promise> { - return responsePromise.then( - response => (response == null ? null : {request, response}), - ); +function track(request, responsePromise) { + return responsePromise.then(response => response == null ? null : { request, response }); } -type AutocompleteSession = { - firstResultPromise: PromiseWithState>, - lastRequest: atom$AutocompleteRequest, -}; - -export default class AutocompleteCacher { - _getSuggestions: (request: atom$AutocompleteRequest) => Promise; - _config: AutocompleteCacherConfig; - - _enabled: boolean; - _session: ?AutocompleteSession; +class AutocompleteCacher { constructor( - // If getSuggestions returns null or undefined, it means that we should not filter that result - // to serve later queries, even if shouldFilter returns true. If there are truly no results, it - // is recommended that getSuggestions return an empty Array. - getSuggestions: (request: atom$AutocompleteRequest) => Promise, - config: AutocompleteCacherConfig, - ) { - this._getSuggestions = async (request: atom$AutocompleteRequest) => { + // If getSuggestions returns null or undefined, it means that we should not filter that result + // to serve later queries, even if shouldFilter returns true. If there are truly no results, it + getSuggestions, config) { + this._getSuggestions = async request => { const results = await getSuggestions(request); - return config.updateFirstResults == null || results == null - ? results - : config.updateFirstResults(request, results); + return config.updateFirstResults == null || results == null ? results : config.updateFirstResults(request, results); }; this._config = config; this._setEnabled(); } - async _setEnabled(): Promise { + async _setEnabled() { const gk = this._config.gatekeeper; if (gk == null) { this._enabled = true; } else { this._enabled = false; - this._enabled = await passesGK(gk); + this._enabled = await (0, (_passesGK || _load_passesGK()).default)(gk); } } - getSuggestions(request: atom$AutocompleteRequest): Promise { + getSuggestions(request) { if (!this._enabled) { return this._getSuggestions(request); } @@ -101,13 +68,9 @@ export default class AutocompleteCacher { // Maybe an earlier request had already resolved to not-null so we can use // it right now, synchronously? const firstResult = state.value; - const result = this._config.updateResults( - firstResult.request, - request, - firstResult.response, - ); + const result = this._config.updateResults(firstResult.request, request, firstResult.response); if (result != null) { - this._session = {...this._session, lastRequest: request}; + this._session = Object.assign({}, this._session, { lastRequest: request }); return Promise.resolve(result); } } @@ -119,44 +82,27 @@ export default class AutocompleteCacher { // decision about whether to use the existing response or // the speculative one. const resultFromLanguageService = this._getSuggestions(request); - const result = this._filterSuggestionsIfPossible( - request, - session, - resultFromLanguageService, - ); + const result = this._filterSuggestionsIfPossible(request, session, resultFromLanguageService); this._session = { - firstResultPromise: new PromiseWithState( - getNewFirstResult( - session.firstResultPromise.getPromise(), - track(request, resultFromLanguageService), - ), - ), - lastRequest: request, + firstResultPromise: new (_promise || _load_promise()).PromiseWithState(getNewFirstResult(session.firstResultPromise.getPromise(), track(request, resultFromLanguageService))), + lastRequest: request }; return result; } else { const result = this._getSuggestions(request); this._session = { - firstResultPromise: new PromiseWithState(track(request, result)), + firstResultPromise: new (_promise || _load_promise()).PromiseWithState(track(request, result)), originalRequest: request, - lastRequest: request, + lastRequest: request }; return result; } } - async _filterSuggestionsIfPossible( - request: atom$AutocompleteRequest, - session: AutocompleteSession, - resultFromLanguageService: Promise, - ): Promise { + async _filterSuggestionsIfPossible(request, session, resultFromLanguageService) { const firstResult = await session.firstResultPromise.getPromise(); if (firstResult != null) { - const updated = this._config.updateResults( - firstResult.request, - request, - firstResult.response, - ); + const updated = this._config.updateResults(firstResult.request, request, firstResult.response); if (updated != null) { return updated; } @@ -166,29 +112,16 @@ export default class AutocompleteCacher { // This doesn't guarantee we can filter results -- if the previous result turns out to be null, we // may still have to use the results from the language service. - _canMaybeFilterResults( - session: AutocompleteSession, - currentRequest: atom$AutocompleteRequest, - ): boolean { - const {lastRequest} = session; - const shouldFilter = - this._config.shouldFilter != null - ? this._config.shouldFilter - : defaultShouldFilter; - const charsSinceLastRequest = - currentRequest.bufferPosition.column - lastRequest.bufferPosition.column; - return ( - lastRequest.bufferPosition.row === currentRequest.bufferPosition.row && - charsSinceLastRequest > 0 && - shouldFilter(lastRequest, currentRequest, charsSinceLastRequest) - ); + _canMaybeFilterResults(session, currentRequest) { + const { lastRequest } = session; + const shouldFilter = this._config.shouldFilter != null ? this._config.shouldFilter : defaultShouldFilter; + const charsSinceLastRequest = currentRequest.bufferPosition.column - lastRequest.bufferPosition.column; + return lastRequest.bufferPosition.row === currentRequest.bufferPosition.row && charsSinceLastRequest > 0 && shouldFilter(lastRequest, currentRequest, charsSinceLastRequest); } } -async function getNewFirstResult( - firstResultPromise: Promise>, - resultFromLanguageService: Promise>, -): Promise> { +exports.default = AutocompleteCacher; +async function getNewFirstResult(firstResultPromise, resultFromLanguageService) { const firstResult = await firstResultPromise; if (firstResult != null) { return firstResult; @@ -199,11 +132,7 @@ async function getNewFirstResult( const IDENTIFIER_REGEX = /^[a-zA-Z_]+$/; -function defaultShouldFilter( - lastRequest: atom$AutocompleteRequest, - currentRequest: atom$AutocompleteRequest, - charsSinceLastRequest: number, -) { +function defaultShouldFilter(lastRequest, currentRequest, charsSinceLastRequest) { // This function's goal is to check whether the currentRequest represents // additional typing to do further filtering, or whether it represents an // entirely new autocomplete request. @@ -224,10 +153,5 @@ function defaultShouldFilter( // (e.g. always failing to cache for identifiers that have numerals or // hyphens), the only bad effect is more autocomplete requests to the // language server than is strictly necessary. - return ( - currentRequest.prefix.startsWith(lastRequest.prefix) && - currentRequest.prefix.length === - lastRequest.prefix.length + charsSinceLastRequest && - IDENTIFIER_REGEX.test(currentRequest.prefix) - ); -} + return currentRequest.prefix.startsWith(lastRequest.prefix) && currentRequest.prefix.length === lastRequest.prefix.length + charsSinceLastRequest && IDENTIFIER_REGEX.test(currentRequest.prefix); +} \ No newline at end of file diff --git a/pkg/commons-atom/DashProviderUtils.js b/pkg/commons-atom/DashProviderUtils.js index d731aee5dc..c5ede9cd57 100644 --- a/pkg/commons-atom/DashProviderUtils.js +++ b/pkg/commons-atom/DashProviderUtils.js @@ -1,23 +1,36 @@ -/** - * 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 - */ - -import fuzzldrin from 'fuzzaldrin-plus'; - -const noSpaceNeededPrefixes = new Set(' !@#$%^&*();[]-_?/\'".,<>{}:'); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.prefixRequiresSpace = prefixRequiresSpace; +exports.fuzzyRelevance = fuzzyRelevance; + +var _fuzzaldrinPlus; + +function _load_fuzzaldrinPlus() { + return _fuzzaldrinPlus = _interopRequireDefault(require('fuzzaldrin-plus')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const noSpaceNeededPrefixes = new Set(' !@#$%^&*();[]-_?/\'".,<>{}:'); /** + * 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. + * + * + * @format + */ + noSpaceNeededPrefixes.add(''); // empty prefix (omnisearch) also doesn't require a space -export function prefixRequiresSpace(prefix: string): boolean { +function prefixRequiresSpace(prefix) { return prefix.length > 1 || !noSpaceNeededPrefixes.has(prefix); } -export function fuzzyRelevance(string: string, query: string) { - return fuzzldrin.score(string, query) / fuzzldrin.score(string, string); -} +function fuzzyRelevance(string, query) { + return (_fuzzaldrinPlus || _load_fuzzaldrinPlus()).default.score(string, query) / (_fuzzaldrinPlus || _load_fuzzaldrinPlus()).default.score(string, string); +} \ No newline at end of file diff --git a/pkg/commons-atom/DiffViewEditor.js b/pkg/commons-atom/DiffViewEditor.js index 87738676a6..afd079a430 100644 --- a/pkg/commons-atom/DiffViewEditor.js +++ b/pkg/commons-atom/DiffViewEditor.js @@ -1,3 +1,31 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _atom = require('atom'); + +var _react = _interopRequireWildcard(require('react')); + +var _reactDom = _interopRequireDefault(require('react-dom')); + +var _collection; + +function _load_collection() { + return _collection = require('../../modules/nuclide-commons/collection'); +} + +var _blockDecorations; + +function _load_blockDecorations() { + return _blockDecorations = require('./block-decorations'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,45 +33,30 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {LineMapper, OffsetMap} from '../commons-node/computeDiff'; - -import {Range} from 'atom'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import {concatIterators} from 'nuclide-commons/collection'; -import {syncBlockDecorations} from './block-decorations'; - -export type EditorElementsMap = Map>; - -function renderLineOffset( - lineCount: number, - lineHeight: number, -): React.Element { - return ( -
      - ); +function renderLineOffset(lineCount, lineHeight) { + return _react.createElement('div', { + className: 'nuclide-diff-view-block-offset', + style: { minHeight: lineCount * lineHeight } + }); } -function renderInlineOffset( - offsetElement: React.Element, -): React.Element { - return ( -
      -
      -
      - {offsetElement} -
      -
      +function renderInlineOffset(offsetElement) { + return _react.createElement( + 'div', + { style: { position: 'relative', width: '100%' } }, + _react.createElement('div', { + className: 'nuclide-diff-view-block-offset', + style: { position: 'absolute', left: 0, right: 0, top: 0, bottom: 0 } + }), + _react.createElement( + 'div', + { style: { visibility: 'hidden', pointerEvents: 'none' } }, + offsetElement + ) ); } @@ -51,15 +64,9 @@ function renderInlineOffset( * The DiffViewEditor manages the lifecycle of the two editors used in the diff view, * and controls its rendering of highlights and offsets. */ -export default class DiffViewEditor { - _editor: atom$TextEditor; - _editorElement: atom$TextEditorElement; - _highlightMarkers: Array; - _offsetMarkers: Array; - _uiElementsMarkers: Array; - _offsetUiElementsMarkers: Array; - - constructor(editorElement: atom$TextEditorElement) { +class DiffViewEditor { + + constructor(editorElement) { this._editorElement = editorElement; this._editor = editorElement.getModel(); this._highlightMarkers = []; @@ -72,67 +79,45 @@ export default class DiffViewEditor { // This is now to work around Atom 1.12.x not clearing removed block decorations. // TODO(most): Remove this when upgrading to Atom 1.13.x. - _cleanupInvisibleDecorations(): void { + _cleanupInvisibleDecorations() { if (this._editor.isDestroyed()) { return; } - const removedElements = Array.from( - this._editorElement.getElementsByClassName( - 'atom--invisible-block-decoration', - ), - ); + const removedElements = Array.from(this._editorElement.getElementsByClassName('atom--invisible-block-decoration')); for (const element of removedElements) { - ReactDOM.unmountComponentAtNode(element); + _reactDom.default.unmountComponentAtNode(element); } } - setUiElements(elements: EditorElementsMap): void { + setUiElements(elements) { const diffBlockType = 'inline'; - this._uiElementsMarkers = syncBlockDecorations( - this._editorElement, - diffBlockType, - elements, - (element, customProps) => customProps.element !== element, - element => ({ - element, - customProps: {diffBlockType, element}, - }), - /* syncWidth */ true, - ); + this._uiElementsMarkers = (0, (_blockDecorations || _load_blockDecorations()).syncBlockDecorations)(this._editorElement, diffBlockType, elements, (element, customProps) => customProps.element !== element, element => ({ + element, + customProps: { diffBlockType, element } + }), + /* syncWidth */true); } - setOffsetUiElements( - offsetElements: EditorElementsMap, - lineMapper: LineMapper, - ): void { + setOffsetUiElements(offsetElements, lineMapper) { const mappedOffsetElements = new Map(); for (const [bufferRow, offsetElement] of offsetElements) { mappedOffsetElements.set(lineMapper[bufferRow], offsetElement); } const diffBlockType = 'inline-offset'; - this._offsetUiElementsMarkers = syncBlockDecorations( - this._editorElement, - diffBlockType, - mappedOffsetElements, - (offsetElement, customProps) => - customProps.offsetElement !== offsetElement, - offsetElement => ({ - element: renderInlineOffset(offsetElement), - customProps: {diffBlockType, offsetElement}, - }), - ); + this._offsetUiElementsMarkers = (0, (_blockDecorations || _load_blockDecorations()).syncBlockDecorations)(this._editorElement, diffBlockType, mappedOffsetElements, (offsetElement, customProps) => customProps.offsetElement !== offsetElement, offsetElement => ({ + element: renderInlineOffset(offsetElement), + customProps: { diffBlockType, offsetElement } + })); } - scrollToScreenLine(screenLine: number): void { + scrollToScreenLine(screenLine) { this._editor.scrollToScreenPosition( - // Markers are ordered in ascending order by line number. - [screenLine, 0], - {center: true}, - ); + // Markers are ordered in ascending order by line number. + [screenLine, 0], { center: true }); } - setFileContents(filePath: string, contents: string): void { + setFileContents(filePath, contents) { const buffer = this._editor.getBuffer(); if (buffer.getText() !== contents) { // Applies only to the compared read only text buffer. @@ -143,11 +128,11 @@ export default class DiffViewEditor { atom.grammars.assignLanguageMode(buffer, grammar.scopeName); } - getModel(): Object { + getModel() { return this._editor; } - getText(): string { + getText() { return this._editor.getText(); } @@ -155,20 +140,11 @@ export default class DiffViewEditor { * @param addedLines An array of buffer line numbers that should be highlighted as added. * @param removedLines An array of buffer line numbers that should be highlighted as removed. */ - setHighlightedLines( - addedLines: Array = [], - removedLines: Array = [], - ) { + setHighlightedLines(addedLines = [], removedLines = []) { for (const marker of this._highlightMarkers) { marker.destroy(); } - this._highlightMarkers = addedLines - .map(lineNumber => this._createLineMarker(lineNumber, 'insert')) - .concat( - removedLines.map(lineNumber => - this._createLineMarker(lineNumber, 'delete'), - ), - ); + this._highlightMarkers = addedLines.map(lineNumber => this._createLineMarker(lineNumber, 'insert')).concat(removedLines.map(lineNumber => this._createLineMarker(lineNumber, 'delete'))); } /** @@ -176,38 +152,27 @@ export default class DiffViewEditor { * @param type The type of highlight to be applied to the line. * Could be a value of: ['insert', 'delete']. */ - _createLineMarker(lineNumber: number, type: string): atom$Marker { - const range = new Range([lineNumber, 0], [lineNumber + 1, 0]); - const marker = this._editor.markBufferRange(range, {invalidate: 'never'}); + _createLineMarker(lineNumber, type) { + const range = new _atom.Range([lineNumber, 0], [lineNumber + 1, 0]); + const marker = this._editor.markBufferRange(range, { invalidate: 'never' }); this._editor.decorateMarker(marker, { type: 'highlight', - class: `diff-view-${type}`, + class: `diff-view-${type}` }); return marker; } - setOffsets(lineOffsets: OffsetMap): void { + setOffsets(lineOffsets) { const lineHeight = this._editor.getLineHeightInPixels(); const diffBlockType = 'line-offset'; - this._offsetMarkers = syncBlockDecorations( - this._editorElement, - diffBlockType, - lineOffsets, - (lineCount, customProps) => customProps.lineCount !== lineCount, - lineCount => ({ - element: renderLineOffset(lineCount, lineHeight), - customProps: {lineCount, diffBlockType}, - }), - ); + this._offsetMarkers = (0, (_blockDecorations || _load_blockDecorations()).syncBlockDecorations)(this._editorElement, diffBlockType, lineOffsets, (lineCount, customProps) => customProps.lineCount !== lineCount, lineCount => ({ + element: renderLineOffset(lineCount, lineHeight), + customProps: { lineCount, diffBlockType } + })); } - destroyMarkers(): void { - const allMarkers = concatIterators( - this._highlightMarkers, - this._offsetMarkers, - this._uiElementsMarkers, - this._offsetUiElementsMarkers, - ); + destroyMarkers() { + const allMarkers = (0, (_collection || _load_collection()).concatIterators)(this._highlightMarkers, this._offsetMarkers, this._uiElementsMarkers, this._offsetUiElementsMarkers); for (const marker of allMarkers) { marker.destroy(); } @@ -218,16 +183,17 @@ export default class DiffViewEditor { this._cleanupInvisibleDecorations(); } - destroy(): void { + destroy() { this.destroyMarkers(); this._editor.destroy(); } - getEditor(): atom$TextEditor { + getEditor() { return this._editor; } - getEditorDomElement(): atom$TextEditorElement { + getEditorDomElement() { return this._editorElement; } } +exports.default = DiffViewEditor; \ No newline at end of file diff --git a/pkg/commons-atom/LocalStorageJsonTable.js b/pkg/commons-atom/LocalStorageJsonTable.js index 4f97529219..f0d6661745 100644 --- a/pkg/commons-atom/LocalStorageJsonTable.js +++ b/pkg/commons-atom/LocalStorageJsonTable.js @@ -1,32 +1,24 @@ -/** - * 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 - */ +'use strict'; -/* global localStorage */ +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LocalStorageJsonTable = undefined; -import {nextAnimationFrame} from 'nuclide-commons/observable'; +var _observable; -type Entry = {key: string, value: T}; +function _load_observable() { + return _observable = require('../../modules/nuclide-commons/observable'); +} -export class LocalStorageJsonTable { - _localStorageKey: string; - _db: ?Array>; - _clearCacheSubscription: ?rxjs$Subscription; - _cacheSize: number; +class LocalStorageJsonTable { - constructor(localStorageKey: string, cacheSize: number = 100) { + constructor(localStorageKey, cacheSize = 100) { this._localStorageKey = localStorageKey; this._cacheSize = cacheSize; } - _open(): Array> { + _open() { if (this._db == null) { const json = localStorage.getItem(this._localStorageKey); let db; @@ -39,7 +31,7 @@ export class LocalStorageJsonTable { // Clear the cache after this frame. We have to do this because other windows might be // interacting with the database too. if (this._clearCacheSubscription == null) { - this._clearCacheSubscription = nextAnimationFrame.subscribe(() => { + this._clearCacheSubscription = (_observable || _load_observable()).nextAnimationFrame.subscribe(() => { this._db = null; this._clearCacheSubscription = null; }); @@ -48,15 +40,15 @@ export class LocalStorageJsonTable { return this._db; } - dispose(): void { + dispose() { if (this._clearCacheSubscription != null) { this._clearCacheSubscription.unsubscribe(); } } - setItem(key: string, value: T): void { + setItem(key, value) { let db = this._open(); - const matchIndex = db.findIndex(({key: k}) => k === key); + const matchIndex = db.findIndex(({ key: k }) => k === key); if (matchIndex !== -1) { const previousValue = db[matchIndex].value; // No reason to drop and re-push the most recent value @@ -65,18 +57,30 @@ export class LocalStorageJsonTable { } db.splice(matchIndex, 1); } - db.push({key, value}); + db.push({ key, value }); db = db.slice(-this._cacheSize); localStorage.setItem(this._localStorageKey, JSON.stringify(db)); } - getItem(key: string): ?T { + getItem(key) { const db = this._open(); - const entry = db.find(({key: k}) => key === k); + const entry = db.find(({ key: k }) => key === k); return entry == null ? null : entry.value; } - getEntries(): Array> { + getEntries() { return this._open().slice(); } } +exports.LocalStorageJsonTable = LocalStorageJsonTable; /** + * 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. + * + * + * @format + */ + +/* global localStorage */ \ No newline at end of file diff --git a/pkg/commons-atom/OutlineTreeUtils.js b/pkg/commons-atom/OutlineTreeUtils.js index e3d2536022..0973f7f6e5 100644 --- a/pkg/commons-atom/OutlineTreeUtils.js +++ b/pkg/commons-atom/OutlineTreeUtils.js @@ -1,3 +1,10 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.iconForOutlineKind = iconForOutlineKind; +exports.iconForOutlineTree = iconForOutlineTree; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,17 +12,11 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {IconName} from 'nuclide-commons-ui/Icon'; -import type { - OutlineTree, - OutlineTreeKind, -} from 'atom-ide-ui/pkg/atom-ide-outline-view/lib/types'; - -const OUTLINE_KIND_TO_ICON: {[OutlineTreeKind]: IconName} = { +const OUTLINE_KIND_TO_ICON = { array: 'type-array', boolean: 'type-boolean', class: 'type-class', @@ -33,20 +34,20 @@ const OUTLINE_KIND_TO_ICON: {[OutlineTreeKind]: IconName} = { package: 'type-package', property: 'type-property', string: 'type-string', - variable: 'type-variable', + variable: 'type-variable' }; -export function iconForOutlineKind(kind: OutlineTreeKind): IconName { +function iconForOutlineKind(kind) { return OUTLINE_KIND_TO_ICON[kind]; } -export function iconForOutlineTree(outlineTree: OutlineTree): IconName { - const {kind} = outlineTree; +function iconForOutlineTree(outlineTree) { + const { kind } = outlineTree; // $FlowFixMe these come from the RPC and are untyped. - const icon: ?IconName = outlineTree.icon; + const icon = outlineTree.icon; const iconName = icon != null ? icon : kind && iconForOutlineKind(kind); if (iconName == null) { return 'code'; } return iconName; -} +} \ No newline at end of file diff --git a/pkg/commons-atom/block-decorations.js b/pkg/commons-atom/block-decorations.js index 46a25a7d0f..dad6a067a8 100644 --- a/pkg/commons-atom/block-decorations.js +++ b/pkg/commons-atom/block-decorations.js @@ -1,21 +1,17 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.syncBlockDecorations = syncBlockDecorations; + +var _react = _interopRequireWildcard(require('react')); + +var _reactDom = _interopRequireDefault(require('react-dom')); -import * as React from 'react'; -import ReactDOM from 'react-dom'; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -type BlockElementWithProps = { - element: React.Element, - customProps: Object, -}; +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; } } /** * Instead of destroying all the decorations and re-rendering them on each edit, @@ -30,18 +26,22 @@ type BlockElementWithProps = { * * @return an array of markers to be destroyed when the decorations are no longer needed. */ -export function syncBlockDecorations( - editorElement: atom$TextEditorElement, - diffBlockType: string, - source: Map, - shouldUpdate: (value: Value, properties: Object) => boolean, - getElementWithProps: (value: Value) => BlockElementWithProps, - syncWidth?: boolean = false, -): Array { +/** + * 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. + * + * + * @format + */ + +function syncBlockDecorations(editorElement, diffBlockType, source, shouldUpdate, getElementWithProps, syncWidth = false) { const editor = editorElement.getModel(); - const decorations = editor.getDecorations({diffBlockType}); + const decorations = editor.getDecorations({ diffBlockType }); const renderedLineNumbers = new Set(); - const {component} = editorElement; + const { component } = editorElement; const markers = []; @@ -50,7 +50,7 @@ export function syncBlockDecorations( const lineNumber = marker.getBufferRange().start.row; const value = source.get(lineNumber); const properties = decoration.getProperties(); - const item: HTMLElement = properties.item; + const item = properties.item; // If the decoration should no longer exist or it has already been rendered, // it needs to be destroyed. @@ -60,8 +60,8 @@ export function syncBlockDecorations( } if (shouldUpdate(value, properties)) { - const {element, customProps} = getElementWithProps(value); - ReactDOM.render(element, item); + const { element, customProps } = getElementWithProps(value); + _reactDom.default.render(element, item); Object.assign(properties, customProps); @@ -81,28 +81,26 @@ export function syncBlockDecorations( continue; } - const {element, customProps} = getElementWithProps(value); + const { element, customProps } = getElementWithProps(value); const marker = editor.markBufferPosition([lineNumber, 0], { - invalidate: 'never', + invalidate: 'never' }); // The position should be `after` if the element is at the end of the file. - const position = - lineNumber >= editor.getLineCount() - 1 ? 'after' : 'before'; + const position = lineNumber >= editor.getLineCount() - 1 ? 'after' : 'before'; const item = document.createElement('div'); - ReactDOM.render(element, item); + _reactDom.default.render(element, item); marker.onDidDestroy(() => { - ReactDOM.unmountComponentAtNode(item); + _reactDom.default.unmountComponentAtNode(item); }); - editor.decorateMarker(marker, { - ...customProps, + editor.decorateMarker(marker, Object.assign({}, customProps, { type: 'block', item, - position, - }); + position + })); markers.push(marker); } return markers; -} +} \ No newline at end of file diff --git a/pkg/commons-atom/browser-cookies.js b/pkg/commons-atom/browser-cookies.js index 8a0efe605c..aefe66fd2e 100644 --- a/pkg/commons-atom/browser-cookies.js +++ b/pkg/commons-atom/browser-cookies.js @@ -1,3 +1,13 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _electron = _interopRequireDefault(require('electron')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,62 +15,51 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -import invariant from 'assert'; -import electron from 'electron'; +const { remote } = _electron.default; -const {remote} = electron; -invariant(remote != null); +if (!(remote != null)) { + throw new Error('Invariant violation: "remote != null"'); +} -export default { - getCookies(domain: string): Promise<{[key: string]: string}> { +exports.default = { + getCookies(domain) { return new Promise((resolve, reject) => { // $FlowFixMe: Add types for electron$WebContents - remote.getCurrentWindow().webContents.session.cookies.get( - { - domain, - }, - (error, cookies) => { - if (error) { - reject(error); - } else { - const cookieMap = {}; - cookies.forEach(cookie => { - cookieMap[cookie.name] = cookie.value; - }); - resolve(cookieMap); - } - }, - ); + remote.getCurrentWindow().webContents.session.cookies.get({ + domain + }, (error, cookies) => { + if (error) { + reject(error); + } else { + const cookieMap = {}; + cookies.forEach(cookie => { + cookieMap[cookie.name] = cookie.value; + }); + resolve(cookieMap); + } + }); }); }, - setCookie( - url: string, - domain: string, - name: string, - value: string, - ): Promise { + setCookie(url, domain, name, value) { return new Promise((resolve, reject) => { // $FlowFixMe: Add types for electron$WebContents - remote.getCurrentWindow().webContents.session.cookies.set( - { - url, - domain, - name, - value, - }, - error => { - if (error) { - reject(error); - } else { - resolve(); - } - }, - ); + remote.getCurrentWindow().webContents.session.cookies.set({ + url, + domain, + name, + value + }, error => { + if (error) { + reject(error); + } else { + resolve(); + } + }); }); - }, -}; + } +}; \ No newline at end of file diff --git a/pkg/commons-atom/deep-link.js b/pkg/commons-atom/deep-link.js index ef2967978e..d80d0f8459 100644 --- a/pkg/commons-atom/deep-link.js +++ b/pkg/commons-atom/deep-link.js @@ -1,50 +1,54 @@ -/** - * 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 - */ - -import invariant from 'assert'; -import electron from 'electron'; -import {Observable} from 'rxjs'; - -const {ipcRenderer, remote} = electron; -invariant(ipcRenderer != null, 'must be in renderer process'); -invariant(remote != null); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.observeDeepLinks = observeDeepLinks; +exports.sendDeepLink = sendDeepLink; +exports.getHasSentDeepLink = getHasSentDeepLink; + +var _electron = _interopRequireDefault(require('electron')); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const { ipcRenderer, remote } = _electron.default; /** + * 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. + * + * + * @format + */ + +if (!(ipcRenderer != null)) { + throw new Error('must be in renderer process'); +} + +if (!(remote != null)) { + throw new Error('Invariant violation: "remote != null"'); +} const CHANNEL = 'nuclide-url-open'; let hasSentDeepLink = false; -export type DeepLinkMessage = { - message: string, - params: DeepLinkParams, -}; - -export type DeepLinkParams = {[key: string]: string | Array}; - -export function observeDeepLinks(): Observable { - return Observable.fromEvent(ipcRenderer, CHANNEL, (event, data) => data); +function observeDeepLinks() { + return _rxjsBundlesRxMinJs.Observable.fromEvent(ipcRenderer, CHANNEL, (event, data) => data); } -export function sendDeepLink( - browserWindow: electron$BrowserWindow, - path: string, - params: Object, -): void { +function sendDeepLink(browserWindow, path, params) { if (browserWindow === remote.getCurrentWindow()) { hasSentDeepLink = true; } - browserWindow.webContents.send(CHANNEL, {message: path, params}); + browserWindow.webContents.send(CHANNEL, { message: path, params }); browserWindow.focus(); } -export function getHasSentDeepLink(): boolean { +function getHasSentDeepLink() { return hasSentDeepLink; -} +} \ No newline at end of file diff --git a/pkg/commons-atom/destroy-pane-item.js b/pkg/commons-atom/destroy-pane-item.js index c2a2558480..2762004d73 100644 --- a/pkg/commons-atom/destroy-pane-item.js +++ b/pkg/commons-atom/destroy-pane-item.js @@ -1,3 +1,9 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = destroyPaneItemWithTitle; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,11 +11,11 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -export default function destroyPaneItemWithTitle(title: string) { +function destroyPaneItemWithTitle(title) { for (const item of atom.workspace.getPaneItems()) { if (item.getTitle() === title) { const pane = atom.workspace.paneForItem(item); @@ -19,4 +25,4 @@ export default function destroyPaneItemWithTitle(title: string) { } } } -} +} \ No newline at end of file diff --git a/pkg/commons-atom/disablePackage.js b/pkg/commons-atom/disablePackage.js index 5230bf5d63..73985d8306 100644 --- a/pkg/commons-atom/disablePackage.js +++ b/pkg/commons-atom/disablePackage.js @@ -1,40 +1,57 @@ -/** - * 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 - */ - -import idx from 'idx'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -export const DisabledReason = Object.freeze({ - INCOMPATIBLE: 'incompatible', - REIMPLEMENTED: 'reimplemented', +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true }); -type DisabledReasonType = $Values; +exports.DisabledReason = undefined; +exports.default = disablePackage; + +var _idx; + +function _load_idx() { + return _idx = _interopRequireDefault(require('idx')); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../modules/nuclide-commons-atom/feature-config')); +} -function deactivateAndUnloadPackage( - name: string, - options: {|warn: boolean, reason: DisabledReasonType|}, -): void { +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../modules/nuclide-commons/UniversalDisposable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const DisabledReason = exports.DisabledReason = Object.freeze({ + INCOMPATIBLE: 'incompatible', + REIMPLEMENTED: 'reimplemented' +}); /** + * 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. + * + * + * @format + */ + +function deactivateAndUnloadPackage(name, options) { if (atom.packages.initialPackagesActivated === true) { if (options.warn) { - const packageName = featureConfig.getPackageName(); + const packageName = (_featureConfig || _load_featureConfig()).default.getPackageName(); atom.notifications.addWarning(`Incompatible Package: ${name}`, { description: getWarningMessage(name, packageName, options.reason), - dismissable: true, + dismissable: true }); } } - const deactivationPromise = - atom.packages.deactivatePackage(name) || Promise.resolve(); + const deactivationPromise = atom.packages.deactivatePackage(name) || Promise.resolve(); deactivationPromise.then(() => { atom.packages.disablePackage(name); atom.packages.unloadPackage(name); @@ -46,24 +63,23 @@ function deactivateAndUnloadPackage( delete atom.packages.preloadedPackages[name]; } -export default function disablePackage( - name: string, - options?: {|reason?: DisabledReasonType|}, -): IDisposable { +function disablePackage(name, options) { + var _ref; + const initiallyDisabled = atom.packages.isPackageDisabled(name); - const reason = idx(options, _ => _.reason) || DisabledReason.INCOMPATIBLE; + const reason = ((_ref = options) != null ? _ref.reason : _ref) || DisabledReason.INCOMPATIBLE; if (!initiallyDisabled) { // If it wasn't activated yet, maybe we can prevent the activation altogether atom.packages.disablePackage(name); } if (atom.packages.isPackageActive(name)) { - deactivateAndUnloadPackage(name, {warn: false, reason}); + deactivateAndUnloadPackage(name, { warn: false, reason }); } const activationMonitor = atom.packages.onDidActivatePackage(pack => { if (pack.name === name) { - deactivateAndUnloadPackage(name, {warn: true, reason}); + deactivateAndUnloadPackage(name, { warn: true, reason }); } }); @@ -75,28 +91,17 @@ export default function disablePackage( } }; - return new UniversalDisposable(activationMonitor, stateRestorer); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(activationMonitor, stateRestorer); } -function getWarningMessage( - disabledFeature: string, - packageName: string, - reason: DisabledReasonType, -): string { +function getWarningMessage(disabledFeature, packageName, reason) { switch (reason) { case 'incompatible': - return ( - `${disabledFeature} can't be enabled because it's incompatible with ${packageName}.` + - ` If you need to use this package, you must first disable ${packageName}.` - ); + return `${disabledFeature} can't be enabled because it's incompatible with ${packageName}.` + ` If you need to use this package, you must first disable ${packageName}.`; case 'reimplemented': - return ( - `${disabledFeature} can't be enabled because it's incompatible with ${packageName},` + - ` however ${packageName} provides similar functionality. If you need to use` + - ` ${disabledFeature} anyway, you must first disable ${packageName}.` - ); + return `${disabledFeature} can't be enabled because it's incompatible with ${packageName},` + ` however ${packageName} provides similar functionality. If you need to use` + ` ${disabledFeature} anyway, you must first disable ${packageName}.`; default: - (reason: empty); + reason; throw new Error(`Invalid reason: ${reason}`); } -} +} \ No newline at end of file diff --git a/pkg/commons-atom/format-enoent-notification.js b/pkg/commons-atom/format-enoent-notification.js index a2d6b91d74..43292d2ab1 100644 --- a/pkg/commons-atom/format-enoent-notification.js +++ b/pkg/commons-atom/format-enoent-notification.js @@ -1,3 +1,24 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = formatEnoentNotification; + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../modules/nuclide-commons-atom/feature-config')); +} + +var _string; + +function _load_string() { + return _string = require('../../modules/nuclide-commons/string'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,32 +26,18 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {maybeToString} from 'nuclide-commons/string'; - -type Options = { - feature: string, - toolName: string, - pathSetting: string, -}; - -type Result = { - message: string, - meta: atom$NotificationOptions, -}; - const capitalize = str => str[0].toUpperCase() + str.substr(1); -export default function formatEnoentNotification(options: Options): Result { - const {feature, toolName, pathSetting} = options; - const schema = featureConfig.getSchema(pathSetting); +function formatEnoentNotification(options) { + const { feature, toolName, pathSetting } = options; + const schema = (_featureConfig || _load_featureConfig()).default.getSchema(pathSetting); const settingTitle = schema.title; const categoryTitle = capitalize(pathSetting.split('.').shift()); - const command: string = (featureConfig.get(pathSetting): any); + const command = (_featureConfig || _load_featureConfig()).default.get(pathSetting); const capitalizedFeature = capitalize(feature); const description = `${capitalizedFeature} needs *${toolName}* but Nuclide couldn't find it at \`${command}\`. @@ -41,16 +48,14 @@ export default function formatEnoentNotification(options: Options): Result { 3. Atom doesn't know about PATH modifications made in your shell config (".bash_profile", ".zshrc", etc.). If *${toolName}* is installed and you can run it successfully from your terminal using the command \`${command}\`, Nuclide may just not be looking in the right place. Update the command by - changing the **${maybeToString( - settingTitle, - )}** setting (under **${categoryTitle}**) on the + changing the **${(0, (_string || _load_string()).maybeToString)(settingTitle)}** setting (under **${categoryTitle}**) on the Nuclide settings page.`; return { message: `Nuclide couldn't find *${toolName}*!`, meta: { dismissable: true, - description, - }, + description + } }; -} +} \ No newline at end of file diff --git a/pkg/commons-atom/loading-notification.js b/pkg/commons-atom/loading-notification.js index 633806ffc2..b853346d7c 100644 --- a/pkg/commons-atom/loading-notification.js +++ b/pkg/commons-atom/loading-notification.js @@ -1,37 +1,40 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = loadingNotification; -import {triggerAfterWait} from 'nuclide-commons/promise'; +var _promise; + +function _load_promise() { + return _promise = require('../../modules/nuclide-commons/promise'); +} /** * Displays a loading notification while waiting for a promise. * Waits delayMs before actually showing the notification (to prevent flicker). */ -export default function loadingNotification( - promise: Promise, - message: string, - delayMs: number = 100, - options: Object = {}, -): Promise { +function loadingNotification(promise, message, delayMs = 100, options = {}) { let notif = null; const timeoutFn = () => { - notif = atom.notifications.addInfo(message, { - dismissable: true, - ...options, - }); + notif = atom.notifications.addInfo(message, Object.assign({ + dismissable: true + }, options)); }; const cleanupFn = () => { if (notif) { notif.dismiss(); } }; - return triggerAfterWait(promise, delayMs, timeoutFn, cleanupFn); -} + return (0, (_promise || _load_promise()).triggerAfterWait)(promise, delayMs, timeoutFn, cleanupFn); +} /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/commons-atom/observe-grammar-for-text-editors.js b/pkg/commons-atom/observe-grammar-for-text-editors.js index 2a5d4305f9..2aed50d63e 100644 --- a/pkg/commons-atom/observe-grammar-for-text-editors.js +++ b/pkg/commons-atom/observe-grammar-for-text-editors.js @@ -1,3 +1,20 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = observeGrammarForTextEditors; + +var _atom = require('atom'); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../modules/nuclide-commons/UniversalDisposable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,43 +22,33 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import {Emitter} from 'atom'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - const GRAMMAR_CHANGE_EVENT = 'grammar-change'; /** * A singleton that listens to grammar changes in all text editors. */ class GrammarForTextEditorsListener { - _emitter: Emitter; - _subscriptions: UniversalDisposable; constructor() { - this._emitter = new Emitter(); - this._subscriptions = new UniversalDisposable(); - this._subscriptions.add( - this._emitter, - atom.workspace.observeTextEditors(textEditor => { - const grammarSubscription = textEditor.observeGrammar(grammar => { - this._emitter.emit(GRAMMAR_CHANGE_EVENT, textEditor); - }); - const destroySubscription = textEditor.onDidDestroy(() => { - grammarSubscription.dispose(); - destroySubscription.dispose(); - }); - this._subscriptions.add(grammarSubscription, destroySubscription); - }), - ); + this._emitter = new _atom.Emitter(); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._subscriptions.add(this._emitter, atom.workspace.observeTextEditors(textEditor => { + const grammarSubscription = textEditor.observeGrammar(grammar => { + this._emitter.emit(GRAMMAR_CHANGE_EVENT, textEditor); + }); + const destroySubscription = textEditor.onDidDestroy(() => { + grammarSubscription.dispose(); + destroySubscription.dispose(); + }); + this._subscriptions.add(grammarSubscription, destroySubscription); + })); } - observeGrammarForTextEditors( - fn: (textEditor: TextEditor, grammar: atom$Grammar) => void, - ): IDisposable { + observeGrammarForTextEditors(fn) { function fnWithGrammar(textEditor) { fn(textEditor, textEditor.getGrammar()); } @@ -52,12 +59,12 @@ class GrammarForTextEditorsListener { return this._emitter.on(GRAMMAR_CHANGE_EVENT, fnWithGrammar); } - dispose(): void { + dispose() { this._subscriptions.dispose(); } } -let grammarForTextEditorsListener: ?GrammarForTextEditorsListener; +let grammarForTextEditorsListener; /** * Use this to perform an action on every text editor with its latest grammar. @@ -65,9 +72,7 @@ let grammarForTextEditorsListener: ?GrammarForTextEditorsListener; * @param fn This is called once for every text editor, and then again every * time it changes to a grammar. */ -export default function observeGrammarForTextEditors( - fn: (textEditor: TextEditor, grammar: atom$Grammar) => void, -): IDisposable { +function observeGrammarForTextEditors(fn) { if (!grammarForTextEditorsListener) { grammarForTextEditorsListener = new GrammarForTextEditorsListener(); } @@ -75,10 +80,10 @@ export default function observeGrammarForTextEditors( } if (atom.inSpecMode()) { - observeGrammarForTextEditors.__reset__ = function() { + observeGrammarForTextEditors.__reset__ = function () { if (grammarForTextEditorsListener) { grammarForTextEditorsListener.dispose(); grammarForTextEditorsListener = null; } }; -} +} \ No newline at end of file diff --git a/pkg/commons-atom/observe-language-text-editors.js b/pkg/commons-atom/observe-language-text-editors.js index efd0acfc09..29c5672862 100644 --- a/pkg/commons-atom/observe-language-text-editors.js +++ b/pkg/commons-atom/observe-language-text-editors.js @@ -1,19 +1,37 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = observeLanguageTextEditors; + +var _atom = require('atom'); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../modules/nuclide-commons/UniversalDisposable')); +} + +var _observeGrammarForTextEditors; + +function _load_observeGrammarForTextEditors() { + return _observeGrammarForTextEditors = _interopRequireDefault(require('./observe-grammar-for-text-editors')); +} -import {Emitter} from 'atom'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import observeGrammarForTextEditors from './observe-grammar-for-text-editors'; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const START_OBSERVING_TEXT_EDITOR_EVENT = 'start-observing-text-editor'; /** + * 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. + * + * + * @format + */ -const START_OBSERVING_TEXT_EDITOR_EVENT = 'start-observing-text-editor'; const STOP_OBSERVING_TEXT_EDITOR_EVENT = 'stop-observing-text-editor'; /** @@ -23,76 +41,55 @@ const STOP_OBSERVING_TEXT_EDITOR_EVENT = 'stop-observing-text-editor'; * multiple callers observe on text editors with the same grammar scopes. */ class LanguageTextEditorsListener { - _grammarScopes: Set; - _emitter: Emitter; - _observedTextEditors: Set; - _destroySubscriptionsMap: Map; - _grammarSubscription: IDisposable; - constructor(grammarScopes: Set) { + constructor(grammarScopes) { this._grammarScopes = grammarScopes; - this._emitter = new Emitter(); + this._emitter = new _atom.Emitter(); this._observedTextEditors = new Set(); this._destroySubscriptionsMap = new Map(); - this._grammarSubscription = observeGrammarForTextEditors( - (textEditor, grammar) => { - const textEditorHasTheRightGrammar = this._grammarScopes.has( - grammar.scopeName, - ); - const isTextEditorObserved = this._observedTextEditors.has(textEditor); - if (textEditorHasTheRightGrammar && !isTextEditorObserved) { - this._emitter.emit(START_OBSERVING_TEXT_EDITOR_EVENT, textEditor); - this._observedTextEditors.add(textEditor); - } else if (!textEditorHasTheRightGrammar && isTextEditorObserved) { + this._grammarSubscription = (0, (_observeGrammarForTextEditors || _load_observeGrammarForTextEditors()).default)((textEditor, grammar) => { + const textEditorHasTheRightGrammar = this._grammarScopes.has(grammar.scopeName); + const isTextEditorObserved = this._observedTextEditors.has(textEditor); + if (textEditorHasTheRightGrammar && !isTextEditorObserved) { + this._emitter.emit(START_OBSERVING_TEXT_EDITOR_EVENT, textEditor); + this._observedTextEditors.add(textEditor); + } else if (!textEditorHasTheRightGrammar && isTextEditorObserved) { + this._emitter.emit(STOP_OBSERVING_TEXT_EDITOR_EVENT, textEditor); + this._observedTextEditors.delete(textEditor); + } + + const destroySubscription = textEditor.onDidDestroy(() => { + // When a text editor that we were observing is destroyed, we need to + // do clean-up even if its grammar hasn't changed. + if (this._observedTextEditors.has(textEditor)) { this._emitter.emit(STOP_OBSERVING_TEXT_EDITOR_EVENT, textEditor); this._observedTextEditors.delete(textEditor); } - const destroySubscription = textEditor.onDidDestroy(() => { - // When a text editor that we were observing is destroyed, we need to - // do clean-up even if its grammar hasn't changed. - if (this._observedTextEditors.has(textEditor)) { - this._emitter.emit(STOP_OBSERVING_TEXT_EDITOR_EVENT, textEditor); - this._observedTextEditors.delete(textEditor); - } - - destroySubscription.dispose(); - this._destroySubscriptionsMap.delete(textEditor); - }); - this._destroySubscriptionsMap.set(textEditor, destroySubscription); - }, - ); + destroySubscription.dispose(); + this._destroySubscriptionsMap.delete(textEditor); + }); + this._destroySubscriptionsMap.set(textEditor, destroySubscription); + }); } - observeLanguageTextEditors( - fn: (textEditor: TextEditor) => void, - cleanupFn: (textEditor: TextEditor) => void, - ): IDisposable { + observeLanguageTextEditors(fn, cleanupFn) { // The event was already handled before `fn` was added to the emitter, so // we need to call it on all the existing editors. - atom.workspace - .getTextEditors() - .filter(textEditor => - this._grammarScopes.has(textEditor.getGrammar().scopeName), - ) - // We wrap `fn` instead of passing it directly to `.forEach` so it only - // gets called with one arg (i.e. it matches the Flow annotation). - .forEach(textEditor => fn(textEditor)); - - return new UniversalDisposable( - this._emitter.on(START_OBSERVING_TEXT_EDITOR_EVENT, fn), - this._emitter.on(STOP_OBSERVING_TEXT_EDITOR_EVENT, cleanupFn), - ); + atom.workspace.getTextEditors().filter(textEditor => this._grammarScopes.has(textEditor.getGrammar().scopeName)) + // We wrap `fn` instead of passing it directly to `.forEach` so it only + // gets called with one arg (i.e. it matches the Flow annotation). + .forEach(textEditor => fn(textEditor)); + + return new (_UniversalDisposable || _load_UniversalDisposable()).default(this._emitter.on(START_OBSERVING_TEXT_EDITOR_EVENT, fn), this._emitter.on(STOP_OBSERVING_TEXT_EDITOR_EVENT, cleanupFn)); } - dispose(): void { + dispose() { this._emitter.dispose(); this._observedTextEditors.clear(); - this._destroySubscriptionsMap.forEach(subscription => - subscription.dispose(), - ); + this._destroySubscriptionsMap.forEach(subscription => subscription.dispose()); this._destroySubscriptionsMap.clear(); this._grammarSubscription.dispose(); } @@ -106,16 +103,10 @@ class LanguageTextEditorsListener { * @param cleanupFn This is called when a text editor no longer matches the * grammars or is destroyed. */ -export default function observeLanguageTextEditors( - grammarScopes: Array, - fn: (textEditor: TextEditor) => void, - cleanupFn?: (textEditor: TextEditor) => void, -): IDisposable { - const subscriptions = new UniversalDisposable(); +function observeLanguageTextEditors(grammarScopes, fn, cleanupFn) { + const subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); const listener = new LanguageTextEditorsListener(new Set(grammarScopes)); subscriptions.add(listener); - subscriptions.add( - listener.observeLanguageTextEditors(fn, cleanupFn || (() => {})), - ); + subscriptions.add(listener.observeLanguageTextEditors(fn, cleanupFn || (() => {}))); return subscriptions; -} +} \ No newline at end of file diff --git a/pkg/commons-atom/observeStalls.js b/pkg/commons-atom/observeStalls.js index 8c92f7b8d5..692982e2bf 100644 --- a/pkg/commons-atom/observeStalls.js +++ b/pkg/commons-atom/observeStalls.js @@ -1,30 +1,55 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -/* eslint-env browser */ +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _electron = require('electron'); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _observableDom; + +function _load_observableDom() { + return _observableDom = require('../../modules/nuclide-commons-ui/observable-dom'); +} + +var _UniversalDisposable; -import invariant from 'assert'; -import nullthrows from 'nullthrows'; -import {remote} from 'electron'; -import {Observable} from 'rxjs'; -import {PerformanceObservable} from 'nuclide-commons-ui/observable-dom'; +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../modules/nuclide-commons/UniversalDisposable')); +} -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import once from '../commons-node/once'; +var _once; -invariant(remote != null); +function _load_once() { + return _once = _interopRequireDefault(require('../commons-node/once')); +} -const CHROME_VERSION = Number( - nullthrows(process.versions.chrome).split('.')[0], -); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +if (!(_electron.remote != null)) { + throw new Error('Invariant violation: "remote != null"'); +} /** + * 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. + * + * strict-local + * @format + */ + +/* eslint-env browser */ + +const CHROME_VERSION = Number((0, (_nullthrows || _load_nullthrows()).default)(process.versions.chrome).split('.')[0]); // The startup period naturally causes many event loop blockages. // Don't start checking blockages until some time has passed. @@ -39,80 +64,50 @@ const BLOCKED_MAX = 600000; const BLOCKED_RANGE_PADDING = 15; // Share + cache the observable. -const observeStalls = once( - (): Observable => { - const browserWindow = remote.getCurrentWindow(); - - let intentionalBlockTime = 0; - const onIntentionalBlock = () => { - intentionalBlockTime = performance.now(); - }; - - const blockedEvents = new PerformanceObservable({entryTypes: ['longtask']}) - .flattenEntries() - // only count if the window is focused when the task ran long - .filter(() => document.hasFocus()) - // discard early longtasks as the app is booting - .filter(() => process.uptime() > BLOCKED_GRACE_PERIOD) - // early versions of chromium report times in *microseconds* instead of - // milliseconds! - .map( - entry => - CHROME_VERSION <= 56 - ? { - duration: entry.duration / 1000, - startTime: entry.startTime / 1000, - } - : entry, - ) - // discard durations that are unrealistically long, or those that aren't - // meaningful enough - .filter( - entry => entry.duration > BLOCKED_MIN && entry.duration < BLOCKED_MAX, - ) - // discard events that result from user interaction actually blocking the - // thread when there is no other option (e.g. context menus) - .filter( - entry => - // did the intentionalblocktime occur between the start and end, - // accounting for some extra padding? - !( - intentionalBlockTime > entry.startTime - BLOCKED_RANGE_PADDING && - intentionalBlockTime < - entry.startTime + entry.duration + BLOCKED_RANGE_PADDING - ), - ); - - return Observable.using( - () => - new UniversalDisposable( - // Confirmation dialogs also block the event loop. - // This typically happens when you're about to close an unsaved file. - atom.workspace.onWillDestroyPaneItem(onIntentionalBlock), - // Electron context menus block the event loop. - Observable.fromEvent(browserWindow, 'context-menu') - // There appears to be an race with browser window shutdown where - // the 'context-menu' event fires after window destruction. - // Try to prevent this by removing the event on close. - // https://github.com/facebook/nuclide/issues/1246 - .takeUntil(Observable.fromEvent(browserWindow, 'close')) - .subscribe(onIntentionalBlock), - ), - () => { - return Observable.merge( - // kick off subscription with a one-time query on start - Observable.of(document.hasFocus()), - Observable.fromEvent(browserWindow, 'focus').mapTo(true), - Observable.fromEvent(browserWindow, 'blur').mapTo(false), - ) - .distinctUntilChanged() - .switchMap( - isFocused => (isFocused ? blockedEvents : Observable.empty()), - ) - .map(entry => entry.duration); - }, - ).share(); - }, -); - -export default observeStalls; +const observeStalls = (0, (_once || _load_once()).default)(() => { + const browserWindow = _electron.remote.getCurrentWindow(); + + let intentionalBlockTime = 0; + const onIntentionalBlock = () => { + intentionalBlockTime = performance.now(); + }; + + const blockedEvents = new (_observableDom || _load_observableDom()).PerformanceObservable({ entryTypes: ['longtask'] }).flattenEntries() + // only count if the window is focused when the task ran long + .filter(() => document.hasFocus()) + // discard early longtasks as the app is booting + .filter(() => process.uptime() > BLOCKED_GRACE_PERIOD) + // early versions of chromium report times in *microseconds* instead of + // milliseconds! + .map(entry => CHROME_VERSION <= 56 ? { + duration: entry.duration / 1000, + startTime: entry.startTime / 1000 + } : entry) + // discard durations that are unrealistically long, or those that aren't + // meaningful enough + .filter(entry => entry.duration > BLOCKED_MIN && entry.duration < BLOCKED_MAX) + // discard events that result from user interaction actually blocking the + // thread when there is no other option (e.g. context menus) + .filter(entry => + // did the intentionalblocktime occur between the start and end, + // accounting for some extra padding? + !(intentionalBlockTime > entry.startTime - BLOCKED_RANGE_PADDING && intentionalBlockTime < entry.startTime + entry.duration + BLOCKED_RANGE_PADDING)); + + return _rxjsBundlesRxMinJs.Observable.using(() => new (_UniversalDisposable || _load_UniversalDisposable()).default( + // Confirmation dialogs also block the event loop. + // This typically happens when you're about to close an unsaved file. + atom.workspace.onWillDestroyPaneItem(onIntentionalBlock), + // Electron context menus block the event loop. + _rxjsBundlesRxMinJs.Observable.fromEvent(browserWindow, 'context-menu') + // There appears to be an race with browser window shutdown where + // the 'context-menu' event fires after window destruction. + // Try to prevent this by removing the event on close. + // https://github.com/facebook/nuclide/issues/1246 + .takeUntil(_rxjsBundlesRxMinJs.Observable.fromEvent(browserWindow, 'close')).subscribe(onIntentionalBlock)), () => { + return _rxjsBundlesRxMinJs.Observable.merge( + // kick off subscription with a one-time query on start + _rxjsBundlesRxMinJs.Observable.of(document.hasFocus()), _rxjsBundlesRxMinJs.Observable.fromEvent(browserWindow, 'focus').mapTo(true), _rxjsBundlesRxMinJs.Observable.fromEvent(browserWindow, 'blur').mapTo(false)).distinctUntilChanged().switchMap(isFocused => isFocused ? blockedEvents : _rxjsBundlesRxMinJs.Observable.empty()).map(entry => entry.duration); + }).share(); +}); + +exports.default = observeStalls; \ No newline at end of file diff --git a/pkg/commons-atom/open-in-diff-view.js b/pkg/commons-atom/open-in-diff-view.js index 1cd4feeb05..a23fb09537 100644 --- a/pkg/commons-atom/open-in-diff-view.js +++ b/pkg/commons-atom/open-in-diff-view.js @@ -1,3 +1,14 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.openFileInDiffView = openFileInDiffView; + +var _url = _interopRequireDefault(require('url')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,26 +16,22 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import url from 'url'; - -export function openFileInDiffView(filePath: NuclideUri): void { - const diffOpenUrl = url.format({ +function openFileInDiffView(filePath) { + const diffOpenUrl = _url.default.format({ protocol: 'atom', host: 'nuclide', pathname: 'diff-view', slashes: true, query: { file: filePath, - onlyDiff: true, - }, + onlyDiff: true + } }); // This is not a file URI // eslint-disable-next-line nuclide-internal/atom-apis atom.workspace.open(diffOpenUrl); -} +} \ No newline at end of file diff --git a/pkg/commons-atom/register-grammar.js b/pkg/commons-atom/register-grammar.js index 195bb48c5c..811966737a 100644 --- a/pkg/commons-atom/register-grammar.js +++ b/pkg/commons-atom/register-grammar.js @@ -1,3 +1,9 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = registerGrammar; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +11,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ @@ -24,10 +30,7 @@ * the grammar is available. * @return whether the extension was registered or not. */ -export default function registerGrammar( - scopeName: string, - extensions: Array, -): boolean { +function registerGrammar(scopeName, extensions) { let customFileTypes = atom.config.get('core.customFileTypes'); if (customFileTypes == null || typeof customFileTypes !== 'object') { customFileTypes = {}; @@ -53,4 +56,4 @@ export default function registerGrammar( } return false; -} +} \ No newline at end of file diff --git a/pkg/commons-atom/removeProjectPath.js b/pkg/commons-atom/removeProjectPath.js index 460be2da89..4f0cc2025c 100644 --- a/pkg/commons-atom/removeProjectPath.js +++ b/pkg/commons-atom/removeProjectPath.js @@ -1,24 +1,35 @@ -/** - * 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 - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {getLogger} from 'log4js'; - -const logger = getLogger('commons-atom'); - -export default (async function removeProjectPath( - projectPath: NuclideUri, -): Promise { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../modules/nuclide-commons/nuclideUri')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const logger = (0, (_log4js || _load_log4js()).getLogger)('commons-atom'); /** + * 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. + * + * + * @format + */ + +exports.default = async function removeProjectPath(projectPath) { logger.info(`Removing project path ${projectPath}`); // close all the files associated with the project before closing @@ -28,19 +39,9 @@ export default (async function removeProjectPath( // if the path of the editor is not null AND // is part of the root that would be removed AND // is not part of any other open root, then close the file. - if ( - path != null && - path.startsWith(nuclideUri.ensureTrailingSeparator(projectPath)) && - atom.project - .getPaths() - .filter(root => - path.startsWith(nuclideUri.ensureTrailingSeparator(root)), - ).length === 1 - ) { + if (path != null && path.startsWith((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator(projectPath)) && atom.project.getPaths().filter(root => path.startsWith((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator(root))).length === 1) { // eslint-disable-next-line no-await-in-loop - const didDestroy = await atom.workspace - .paneForURI(path) - .destroyItem(editor); + const didDestroy = await atom.workspace.paneForURI(path).destroyItem(editor); // Atom has a bug where, in some cases, destroyItem returns nonsense. // Luckily, in the case we care about, it returns a literal `false`, @@ -53,5 +54,5 @@ export default (async function removeProjectPath( } // actually close the project - atom.project.removePath(nuclideUri.trimTrailingSeparator(projectPath)); -}); + atom.project.removePath((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator(projectPath)); +}; \ No newline at end of file diff --git a/pkg/commons-atom/spec/AutocompleteCacher-spec.js b/pkg/commons-atom/spec/AutocompleteCacher-spec.js deleted file mode 100644 index 5dda9c6ed4..0000000000 --- a/pkg/commons-atom/spec/AutocompleteCacher-spec.js +++ /dev/null @@ -1,290 +0,0 @@ -/** - * 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 - */ - -import {Point} from 'atom'; - -import {Deferred} from 'nuclide-commons/promise'; - -import AutocompleteCacher from '../AutocompleteCacher'; - -describe('AutocompleteCacher', () => { - let getSuggestions: JasmineSpy = (null: any); - let updateResults: JasmineSpy = (null: any); - let shouldFilter: JasmineSpy | void = undefined; - let mockedSuggestions: Promise> = (null: any); - let mockedUpdateResults: ?Array = null; - // returned from the second call - let secondMockedUpdateResults: Array = (null: any); - - let autocompleteCacher: AutocompleteCacher> = (null: any); - - let mockedRequest: atom$AutocompleteRequest = (null: any); - let mockedRequest2: atom$AutocompleteRequest = (null: any); - let mockedRequest3: atom$AutocompleteRequest = (null: any); - - // Denotes a new autocomplete session. Previous results cannot be re-used. - let separateMockedRequest: atom$AutocompleteRequest = (null: any); - - function initializeAutocompleteCacher() { - autocompleteCacher = new AutocompleteCacher(getSuggestions, { - updateResults, - shouldFilter, - }); - } - - beforeEach(() => { - waitsForPromise(async () => { - mockedSuggestions = Promise.resolve([]); - mockedUpdateResults = ['first']; - secondMockedUpdateResults = ['second']; - - mockedRequest = { - editor: await atom.workspace.open(), - bufferPosition: new Point(0, 0), - scopeDescriptor: ('foo': any), - prefix: '', - activatedManually: false, - }; - - mockedRequest2 = { - ...mockedRequest, - bufferPosition: new Point(0, 1), - prefix: 'b', - }; - - mockedRequest3 = { - ...mockedRequest, - bufferPosition: new Point(0, 2), - prefix: 'ba', - }; - - separateMockedRequest = { - ...mockedRequest, - bufferPosition: new Point(1, 0), - prefix: '', - }; - - getSuggestions = jasmine.createSpy('getSuggestions').andCallFake(() => { - return mockedSuggestions; - }); - let updateResultsCallCount = 0; - updateResults = jasmine.createSpy('updateResults').andCallFake(() => { - let result; - if (updateResultsCallCount > 0) { - result = secondMockedUpdateResults; - } else { - result = mockedUpdateResults; - } - updateResultsCallCount++; - return result; - }); - - initializeAutocompleteCacher(); - }); - }); - - it('should call through on first request', () => { - waitsForPromise(async () => { - const results = await autocompleteCacher.getSuggestions(mockedRequest); - expect(results).toBe(await mockedSuggestions); - expect(getSuggestions).toHaveBeenCalledWith(mockedRequest); - expect(updateResults).not.toHaveBeenCalled(); - }); - }); - - it('should just filter original results on the second request', () => { - waitsForPromise(async () => { - await autocompleteCacher.getSuggestions(mockedRequest); - const secondResults = await autocompleteCacher.getSuggestions( - mockedRequest2, - ); - - expect(getSuggestions.callCount).toBe(1); - expect(getSuggestions).toHaveBeenCalledWith(mockedRequest); - - expect(updateResults.callCount).toBe(1); - expect(updateResults).toHaveBeenCalledWith( - mockedRequest, - mockedRequest2, - await mockedSuggestions, - ); - - expect(secondResults).toBe(mockedUpdateResults); - }); - }); - - it('should satisfy a second query even if the original has not yet resolved', () => { - waitsForPromise(async () => { - const originalSuggestionDeferred = new Deferred(); - mockedSuggestions = originalSuggestionDeferred.promise; - - // on purpose don't await here. the promise is not resolved until later - const firstResultPromise = autocompleteCacher.getSuggestions( - mockedRequest, - ); - - const secondResultPromise = autocompleteCacher.getSuggestions( - mockedRequest2, - ); - - expect(getSuggestions.callCount).toBe(2); - expect(getSuggestions).toHaveBeenCalledWith(mockedRequest); - expect(updateResults).not.toHaveBeenCalled(); - - originalSuggestionDeferred.resolve([]); - expect(await firstResultPromise).toBe( - await originalSuggestionDeferred.promise, - ); - - expect(updateResults.callCount).toBe(1); - expect(updateResults).toHaveBeenCalledWith( - mockedRequest, - mockedRequest2, - await firstResultPromise, - ); - - expect(await secondResultPromise).toBe(mockedUpdateResults); - expect(getSuggestions.callCount).toBe(2); - }); - }); - - it('should satisfy a third query even if the original has not yet resolved', () => { - waitsForPromise(async () => { - const originalSuggestionDeferred = new Deferred(); - mockedSuggestions = originalSuggestionDeferred.promise; - - // on purpose don't await here. the promise is not resolved until later - autocompleteCacher.getSuggestions(mockedRequest); - const secondResult = autocompleteCacher.getSuggestions(mockedRequest2); - const finalResult = autocompleteCacher.getSuggestions(mockedRequest3); - - expect(getSuggestions.callCount).toBe(3); - expect(getSuggestions).toHaveBeenCalledWith(mockedRequest); - expect(updateResults).not.toHaveBeenCalled(); - - originalSuggestionDeferred.resolve([]); - - expect(await secondResult).toBe(mockedUpdateResults); - expect(await finalResult).toBe(secondMockedUpdateResults); - - expect(updateResults.callCount).toBe(2); - - // We expect mockedRequest to always be the original request for these - // calls, since it completed with a non-null value. - expect(updateResults.calls.map(call => call.args)).toEqual([ - [mockedRequest, mockedRequest2, await mockedSuggestions], - [mockedRequest, mockedRequest3, await mockedSuggestions], - ]); - - expect(getSuggestions.callCount).toBe(3); - }); - }); - - it('should pass a new request through if it cannot filter', () => { - waitsForPromise(async () => { - await autocompleteCacher.getSuggestions(mockedRequest); - const secondResults = await autocompleteCacher.getSuggestions( - separateMockedRequest, - ); - - expect(getSuggestions.callCount).toBe(2); - expect(getSuggestions.calls.map(call => call.args)).toEqual([ - [mockedRequest], - [separateMockedRequest], - ]); - - expect(updateResults).not.toHaveBeenCalled(); - - expect(secondResults).toBe(await mockedSuggestions); - }); - }); - - it('should pass a new request through if the first returned null', () => { - waitsForPromise(async () => { - mockedSuggestions = Promise.resolve(null); - await autocompleteCacher.getSuggestions(mockedRequest); - - const secondMockedSuggestion = []; - mockedSuggestions = Promise.resolve(secondMockedSuggestion); - const secondResults = await autocompleteCacher.getSuggestions( - mockedRequest2, - ); - - expect(getSuggestions.calls.map(call => call.args)).toEqual([ - [mockedRequest], - [mockedRequest2], - ]); - - expect(updateResults).not.toHaveBeenCalled(); - - expect(secondResults).toBe(secondMockedSuggestion); - }); - }); - - describe('with a custom shouldFilter function', () => { - let shouldFilterResult = false; - beforeEach(() => { - shouldFilter = jasmine - .createSpy('shouldFilter') - .andCallFake(() => shouldFilterResult); - initializeAutocompleteCacher(); - }); - - it('should not filter if not allowed', () => { - waitsForPromise(async () => { - await autocompleteCacher.getSuggestions(mockedRequest); - await autocompleteCacher.getSuggestions(mockedRequest2); - - expect(getSuggestions.callCount).toBe(2); - expect(shouldFilter).toHaveBeenCalledWith( - mockedRequest, - mockedRequest2, - 1, - ); - - expect(updateResults).not.toHaveBeenCalled(); - }); - }); - - it('should filter if allowed', () => { - waitsForPromise(async () => { - shouldFilterResult = true; - await autocompleteCacher.getSuggestions(mockedRequest); - const secondResults = await autocompleteCacher.getSuggestions( - mockedRequest2, - ); - - expect(getSuggestions.callCount).toBe(1); - expect(getSuggestions).toHaveBeenCalledWith(mockedRequest); - - expect(updateResults.callCount).toBe(1); - expect(updateResults).toHaveBeenCalledWith( - mockedRequest, - mockedRequest2, - await mockedSuggestions, - ); - - expect(secondResults).toBe(mockedUpdateResults); - }); - }); - - it('should check the cursor positions of requests before calling shouldFilter', () => { - waitsForPromise(async () => { - await autocompleteCacher.getSuggestions(mockedRequest); - await autocompleteCacher.getSuggestions(separateMockedRequest); - - expect(getSuggestions.callCount).toBe(2); - expect(shouldFilter).not.toHaveBeenCalled(); - expect(updateResults).not.toHaveBeenCalled(); - }); - }); - }); -}); diff --git a/pkg/commons-atom/spec/LocalStorageJsonTable-spec.js b/pkg/commons-atom/spec/LocalStorageJsonTable-spec.js deleted file mode 100644 index 8d9316ea1a..0000000000 --- a/pkg/commons-atom/spec/LocalStorageJsonTable-spec.js +++ /dev/null @@ -1,74 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -/* global localStorage */ - -import {LocalStorageJsonTable} from '../LocalStorageJsonTable'; - -describe('LocalStorageJsonTable', () => { - it('writes values to localStorage', () => { - spyOn(localStorage, 'setItem'); - const storage = new LocalStorageJsonTable('test'); - storage.setItem('a', true); - expect(localStorage.setItem.calls[0].args).toEqual([ - 'test', - JSON.stringify([{key: 'a', value: true}]), - ]); - }); - - it('writes multiple values to localStorage', () => { - spyOn(localStorage, 'setItem'); - const storage = new LocalStorageJsonTable('test'); - storage.setItem('a', 1); - storage.setItem('b', 2); - expect(localStorage.setItem.mostRecentCall.args).toEqual([ - 'test', - JSON.stringify([{key: 'a', value: 1}, {key: 'b', value: 2}]), - ]); - }); - - it('retrieves values from localStorage', () => { - spyOn(localStorage, 'getItem').andReturn( - JSON.stringify([{key: 'a', value: true}]), - ); - const storage = new LocalStorageJsonTable('test'); - expect(storage.getItem('a')).toBe(true); - }); - - it('retrieves entries from localStorage', () => { - spyOn(localStorage, 'getItem').andReturn( - JSON.stringify([{key: 'a', value: true}]), - ); - const storage = new LocalStorageJsonTable('test'); - expect(storage.getEntries()).toEqual([{key: 'a', value: true}]); - }); - - it('has the correct order when the same key is reused', () => { - spyOn(localStorage, 'setItem'); - const storage = new LocalStorageJsonTable('test'); - storage.setItem('a', 1); - storage.setItem('b', 2); - storage.setItem('a', 1); - expect(localStorage.setItem.mostRecentCall.args).toEqual([ - 'test', - JSON.stringify([{key: 'b', value: 2}, {key: 'a', value: 1}]), - ]); - }); - - it("doesn't call setItem when not necessary", () => { - spyOn(localStorage, 'setItem'); - const storage = new LocalStorageJsonTable('test'); - storage.setItem('a', 1); - storage.setItem('b', 2); - storage.setItem('b', 2); - expect(localStorage.setItem.callCount).toBe(2); - }); -}); diff --git a/pkg/commons-atom/spec/browser-cookies.js b/pkg/commons-atom/spec/browser-cookies.js deleted file mode 100644 index 90e068e480..0000000000 --- a/pkg/commons-atom/spec/browser-cookies.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * 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 strict - * @format - */ - -import browserCookies from '../browser-cookies'; - -describe('browser', () => { - describe('getCookies', () => { - it('gets cookies for a domain', () => - waitsForPromise(async () => { - const cookies = await browserCookies.getCookies('example.com'); - expect(typeof cookies).toBe('object'); - })); - }); - - describe('setCookies', () => { - it('can set cookies for a domain/URL', () => - waitsForPromise(async () => { - const now = Date.now().toString(); - const cookiesBefore = await browserCookies.getCookies('example.com'); - expect(cookiesBefore.now).not.toBe(now); - await browserCookies.setCookie( - 'http://example.com', - 'example.com', - 'now', - now, - ); - const cookiesAfter = await browserCookies.getCookies('example.com'); - expect(cookiesAfter.now).toBe(now); - })); - }); -}); diff --git a/pkg/commons-atom/spec/format-enoent-notification-spec.js b/pkg/commons-atom/spec/format-enoent-notification-spec.js deleted file mode 100644 index 2b9654e83d..0000000000 --- a/pkg/commons-atom/spec/format-enoent-notification-spec.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import formatEnoentNotification from '../format-enoent-notification'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import invariant from 'assert'; - -describe('formatEnoentNotification', () => { - let formatted; - - beforeEach(() => { - spyOn(featureConfig, 'getSchema').andReturn({ - title: 'Path to Node Executable', - type: 'string', - default: 'node', - description: 'Absolute path to the node executable on your system.', - }); - spyOn(featureConfig, 'get').andReturn('/path/to/node'); - formatted = formatEnoentNotification({ - feature: 'awesome stuff creation', - toolName: 'node', - pathSetting: 'my-special-package.pathToNode', - }); - }); - - it('formats the message', () => { - invariant(formatted != null); - expect(formatted.message).toBe("Nuclide couldn't find *node*!"); - }); - - it('has a useful intro line', () => { - invariant(formatted != null); - const expected = - "Awesome stuff creation needs *node* but Nuclide couldn't find it at `/path/to/node`"; - invariant(formatted.meta.description != null); - expect(formatted.meta.description.startsWith(expected)).toBe(true); - }); - - it('mentions the setting title in the description', () => { - invariant(formatted != null); - invariant(formatted.meta.description != null); - expect(/Path to Node/.test(formatted.meta.description)).toBe(true); - }); - - it('mentions the setting category in the description', () => { - invariant(formatted != null); - invariant(formatted.meta.description != null); - expect(/My-special-package/.test(formatted.meta.description)).toBe(true); - }); -}); diff --git a/pkg/commons-atom/spec/grammars/java.cson b/pkg/commons-atom/spec/grammars/java.cson deleted file mode 100644 index 0cd2a4fab3..0000000000 --- a/pkg/commons-atom/spec/grammars/java.cson +++ /dev/null @@ -1,8 +0,0 @@ -# From https://github.com/atom/language-java/blob/27154ef235a0dc5a17e23e69d29d88a20eced330/grammars/java.cson -'scopeName': 'source.java' -'name': 'Java' -'fileTypes': [ - 'java' - 'bsh' -] -'patterns': [] diff --git a/pkg/commons-atom/spec/grammars/javascript.cson b/pkg/commons-atom/spec/grammars/javascript.cson deleted file mode 100644 index 5717f1f127..0000000000 --- a/pkg/commons-atom/spec/grammars/javascript.cson +++ /dev/null @@ -1,15 +0,0 @@ -# From https://github.com/atom/language-javascript/blob/861c53f200d5faf2d0bf06c6d405d8d683a2aca0/grammars/javascript.cson -'scopeName': 'source.js' -'fileTypes': [ - 'js' - 'htc' - '_js' - 'es' - 'es6' - 'pjs' - 'xsjs' - 'xsjslib' -] -'firstLineMatch': '^#!.*\\b(node|iojs|JavaScript)' -'name': 'JavaScript' -'patterns': [] diff --git a/pkg/commons-atom/spec/grammars/objective-c.cson b/pkg/commons-atom/spec/grammars/objective-c.cson deleted file mode 100644 index 507f979e58..0000000000 --- a/pkg/commons-atom/spec/grammars/objective-c.cson +++ /dev/null @@ -1,12 +0,0 @@ -# From https://github.com/atom/language-objective-c/blob/a0159d115d89698dec7116793163c86233e38a3a/grammars/objective-c.cson -'scopeName': 'source.objc' -'fileTypes': [ - 'm' - 'h' - 'pch' - 'x' - 'xm' - 'xmi' -] -'name': 'Objective-C' -'patterns': [] diff --git a/pkg/commons-atom/spec/loading-notification-spec.js b/pkg/commons-atom/spec/loading-notification-spec.js deleted file mode 100644 index 97e92cd39e..0000000000 --- a/pkg/commons-atom/spec/loading-notification-spec.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import invariant from 'assert'; -import loadingNotification from '../loading-notification'; - -describe('loadingNotification', () => { - let mockNotif; - beforeEach(() => { - mockNotif = { - dismiss: jasmine.createSpy('dismiss'), - }; - spyOn(atom.notifications, 'addInfo').andReturn(mockNotif); - }); - - it('displays and closes a loading notification', () => { - waitsForPromise(async () => { - const testValue = 1; - const promise = new Promise((resolve, reject) => { - setTimeout(() => resolve(testValue), 10); - }); - const resultPromise = loadingNotification( - promise, - 'test message', - /* delayMs */ 0, - ); - advanceClock(10); - expect(await resultPromise).toEqual(testValue); - expect(atom.notifications.addInfo).toHaveBeenCalled(); - invariant(mockNotif); - expect(mockNotif.dismiss).toHaveBeenCalled(); - }); - }); - - it('displays and closes a loading notification for errors', () => { - waitsForPromise(async () => { - const promise = new Promise((resolve, reject) => { - setTimeout(() => reject(new Error()), 10); - }); - try { - const resultPromise = loadingNotification( - promise, - 'test message', - /* delayMs */ 0, - ); - advanceClock(10); - await resultPromise; - } catch (e) {} - expect(atom.notifications.addInfo).toHaveBeenCalled(); - invariant(mockNotif); - expect(mockNotif.dismiss).toHaveBeenCalled(); - }); - }); - - it('does nothing for fast promises', () => { - waitsForPromise(async () => { - const testValue = 1; - const promise = new Promise((resolve, reject) => { - setTimeout(() => resolve(testValue), 1); - }); - const resultPromise = loadingNotification( - promise, - 'test message', - /* delayMs */ 10, - ); - advanceClock(1); - expect(await resultPromise).toEqual(testValue); - expect(atom.notifications.addInfo.calls.length).toEqual(0); - invariant(mockNotif); - expect(mockNotif.dismiss.calls.length).toEqual(0); - }); - }); -}); diff --git a/pkg/commons-atom/spec/observe-grammar-for-text-editors-spec.js b/pkg/commons-atom/spec/observe-grammar-for-text-editors-spec.js deleted file mode 100644 index 4d81e45c44..0000000000 --- a/pkg/commons-atom/spec/observe-grammar-for-text-editors-spec.js +++ /dev/null @@ -1,122 +0,0 @@ -/** - * 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 - */ - -import fsPromise from 'nuclide-commons/fsPromise'; -import nullthrows from 'nullthrows'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import observeGrammarForTextEditors from '../observe-grammar-for-text-editors'; - -describe('observeGrammarForTextEditors', () => { - let objcGrammar: atom$Grammar = (null: any); - let jsGrammar: atom$Grammar = (null: any); - let tempFilename: string = (null: any); - - beforeEach(() => { - observeGrammarForTextEditors.__reset__(); - // The grammar registry is cleared automatically after Atom 1.3.0+ - atom.grammars.clear(); - atom.grammars.loadGrammarSync( - nuclideUri.join(__dirname, 'grammars/objective-c.cson'), - ); - objcGrammar = nullthrows(atom.grammars.grammarForScopeName('source.objc')); - atom.grammars.loadGrammarSync( - nuclideUri.join(__dirname, 'grammars/javascript.cson'), - ); - jsGrammar = nullthrows(atom.grammars.grammarForScopeName('source.js')); - waitsForPromise(async () => { - tempFilename = `${await fsPromise.tempfile()}.m`; - }); - }); - - it('calls for existing text editors', () => { - waitsForPromise(async () => { - const textEditor = await atom.workspace.open(tempFilename); - - const fn: any = jasmine.createSpy('fn'); - const subscription = observeGrammarForTextEditors(fn); - expect(fn).toHaveBeenCalledWith(textEditor, objcGrammar); - expect(fn.callCount).toBe(1); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('calls for new text editors', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeGrammarForTextEditors(fn); - const textEditor = await atom.workspace.open(tempFilename); - - expect(fn).toHaveBeenCalledWith(textEditor, objcGrammar); - expect(fn.callCount).toBe(1); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('calls when a text editor changes grammars', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeGrammarForTextEditors(fn); - const textEditor = await atom.workspace.open(tempFilename); - textEditor.setGrammar(jsGrammar); - - expect(fn).toHaveBeenCalledWith(textEditor, objcGrammar); - expect(fn).toHaveBeenCalledWith(textEditor, jsGrammar); - expect(fn.callCount).toBe(2); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('does not call after the return value is disposed', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeGrammarForTextEditors(fn); - const textEditor = await atom.workspace.open(tempFilename); - - subscription.dispose(); - textEditor.setGrammar(jsGrammar); - - expect(fn).toHaveBeenCalledWith(textEditor, objcGrammar); - expect(fn.callCount).toBe(1); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('calls for other clients after another listener is disposed', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeGrammarForTextEditors(fn); - const fn2: any = jasmine.createSpy('fn2'); - const subscription2 = observeGrammarForTextEditors(fn2); - const textEditor = await atom.workspace.open(tempFilename); - - subscription.dispose(); - - textEditor.setGrammar(jsGrammar); - - expect(fn).toHaveBeenCalledWith(textEditor, objcGrammar); - expect(fn.callCount).toBe(1); - expect(fn2).toHaveBeenCalledWith(textEditor, objcGrammar); - expect(fn2).toHaveBeenCalledWith(textEditor, jsGrammar); - expect(fn2.callCount).toBe(2); - - subscription2.dispose(); - textEditor.destroy(); - }); - }); -}); diff --git a/pkg/commons-atom/spec/observe-language-text-editors-spec.js b/pkg/commons-atom/spec/observe-language-text-editors-spec.js deleted file mode 100644 index 42660aa241..0000000000 --- a/pkg/commons-atom/spec/observe-language-text-editors-spec.js +++ /dev/null @@ -1,246 +0,0 @@ -/** - * 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 - */ - -import fsPromise from 'nuclide-commons/fsPromise'; -import nullthrows from 'nullthrows'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import observeGrammarForTextEditors from '../observe-grammar-for-text-editors'; -import observeLanguageTextEditors from '../observe-language-text-editors'; - -describe('observeLanguageTextEditors', () => { - let objcGrammar: atom$Grammar = (null: any); - let javaGrammar: atom$Grammar = (null: any); - let jsGrammar: atom$Grammar = (null: any); - let nullGrammar: atom$Grammar = (null: any); - let grammarScopes: Array = (null: any); - let tempFilenameJS: string = (null: any); - let tempFilenameObjC: string = (null: any); - - beforeEach(() => { - observeGrammarForTextEditors.__reset__(); - atom.grammars.loadGrammarSync( - nuclideUri.join(__dirname, 'grammars/objective-c.cson'), - ); - objcGrammar = nullthrows(atom.grammars.grammarForScopeName('source.objc')); - - atom.grammars.loadGrammarSync( - nuclideUri.join(__dirname, 'grammars/java.cson'), - ); - javaGrammar = nullthrows(atom.grammars.grammarForScopeName('source.java')); - - atom.grammars.loadGrammarSync( - nuclideUri.join(__dirname, 'grammars/javascript.cson'), - ); - jsGrammar = nullthrows(atom.grammars.grammarForScopeName('source.js')); - nullGrammar = nullthrows( - atom.grammars.grammarForScopeName('text.plain.null-grammar'), - ); - - grammarScopes = [objcGrammar.scopeName, javaGrammar.scopeName]; - - waitsForPromise(async () => { - tempFilenameJS = `${await fsPromise.tempfile()}.js`; - tempFilenameObjC = `${await fsPromise.tempfile()}.m`; - }); - }); - - describe('without cleanup function', () => { - it('calls for existing text editors that match the grammars', () => { - waitsForPromise(async () => { - const textEditor = await atom.workspace.open(tempFilenameObjC); - - const fn: any = jasmine.createSpy('fn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn); - - expect(fn).toHaveBeenCalledWith(textEditor); - expect(fn.callCount).toBe(1); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('calls for new text editors that already match the grammars', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn); - - const textEditor = await atom.workspace.open(tempFilenameObjC); - - expect(fn).toHaveBeenCalledWith(textEditor); - expect(fn.callCount).toBe(1); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('calls for new text editors that change to match the grammars', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn); - - const textEditor = await atom.workspace.open(); - textEditor.setGrammar(objcGrammar); - - expect(fn).toHaveBeenCalledWith(textEditor); - expect(fn.callCount).toBe(1); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it("does not call for new text editors that change and still don't match the grammars", () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn); - - const textEditor = await atom.workspace.open(); - textEditor.setGrammar(jsGrammar); - - expect(fn.callCount).toBe(0); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('does not call for text editors whose matching grammar changes but still matches', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn); - - const textEditor = await atom.workspace.open(tempFilenameObjC); - textEditor.setGrammar(javaGrammar); - - expect(fn).toHaveBeenCalledWith(textEditor); - expect(fn.callCount).toBe(1); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('stops listening to grammar changes on text editors that are destroyed', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn); - - const textEditor = await atom.workspace.open(tempFilenameObjC); - textEditor.destroy(); - - subscription.dispose(); - }); - }); - }); - - describe('with cleanup function', () => { - it('does not call for existing text editors that do not match the grammars', () => { - waitsForPromise(async () => { - const textEditor = await atom.workspace.open(); - - const fn: any = jasmine.createSpy('fn'); - const cleanupFn: any = jasmine.createSpy('cleanupFn'); - const subscription = observeLanguageTextEditors( - grammarScopes, - fn, - cleanupFn, - ); - - expect(cleanupFn.callCount).toBe(0); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('does not call for new text editors that never matched the grammars', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const cleanupFn: any = jasmine.createSpy('cleanupFn'); - const subscription = observeLanguageTextEditors( - grammarScopes, - fn, - cleanupFn, - ); - - const textEditor = await atom.workspace.open(tempFilenameJS); - textEditor.setGrammar(nullGrammar); - - expect(cleanupFn.callCount).toBe(0); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('calls for new text editors that stop matching the grammars', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const cleanupFn: any = jasmine.createSpy('cleanupFn'); - const subscription = observeLanguageTextEditors( - grammarScopes, - fn, - cleanupFn, - ); - - const textEditor = await atom.workspace.open(tempFilenameObjC); - textEditor.setGrammar(nullGrammar); - - expect(cleanupFn).toHaveBeenCalledWith(textEditor); - expect(cleanupFn.callCount).toBe(1); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('does not call when new text editors that do not match the grammars are destroyed', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const cleanupFn: any = jasmine.createSpy('cleanupFn'); - const subscription = observeLanguageTextEditors( - grammarScopes, - fn, - cleanupFn, - ); - - const textEditor = await atom.workspace.open(tempFilenameJS); - textEditor.destroy(); - - expect(cleanupFn.callCount).toBe(0); - - subscription.dispose(); - }); - }); - - it('calls when new text editors matching the grammars are destroyed', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const cleanupFn: any = jasmine.createSpy('cleanupFn'); - const subscription = observeLanguageTextEditors( - grammarScopes, - fn, - cleanupFn, - ); - - const textEditor = await atom.workspace.open(tempFilenameObjC); - textEditor.destroy(); - - expect(cleanupFn).toHaveBeenCalledWith(textEditor); - expect(cleanupFn.callCount).toBe(1); - - subscription.dispose(); - }); - }); - }); -}); diff --git a/pkg/commons-atom/spec/register-grammar-spec.js b/pkg/commons-atom/spec/register-grammar-spec.js deleted file mode 100644 index 83d6515a63..0000000000 --- a/pkg/commons-atom/spec/register-grammar-spec.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * 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 - */ - -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import registerGrammar from '../register-grammar'; - -describe('registerGrammar', () => { - it('works', () => { - waitsForPromise(async () => { - atom.grammars.loadGrammarSync( - nuclideUri.join(__dirname, 'grammars/javascript.cson'), - ); - registerGrammar('source.js', ['cats']); - const textEditor = await atom.workspace.open( - `${await fsPromise.tempfile()}.cats`, - ); - expect(textEditor.getGrammar().scopeName).toBe('source.js'); - textEditor.destroy(); - }); - }); -}); diff --git a/pkg/commons-atom/spec/repositoryContainsPath-spec.js b/pkg/commons-atom/spec/repositoryContainsPath-spec.js deleted file mode 100644 index 7c371cacba..0000000000 --- a/pkg/commons-atom/spec/repositoryContainsPath-spec.js +++ /dev/null @@ -1,89 +0,0 @@ -/** - * 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 - */ - -import typeof * as HgServiceType from '../../nuclide-hg-rpc/lib/HgService'; - -import {Directory, GitRepository} from 'atom'; -import {repositoryContainsPath} from '../../nuclide-vcs-base'; -import {runCommand} from 'nuclide-commons/process'; -import MockHgService from '../../nuclide-hg-rpc/__mocks__/MockHgService'; -import {HgRepositoryClient} from '../../nuclide-hg-repository-client'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {generateFixture} from 'nuclide-commons/test-helpers'; - -describe('repositoryContainsPath', () => { - let tempFolder: string = (null: any); - let repoRoot: string = (null: any); - - beforeEach(() => { - // Create a temporary Hg repository. - waitsForPromise(async () => { - tempFolder = await generateFixture( - 'hg-git-bridge', - new Map([['repoRoot/file.txt', 'hello world']]), - ); - repoRoot = nuclideUri.join(tempFolder, 'repoRoot'); - }); - }); - - it('is accurate for GitRepository.', () => { - waitsForPromise(async () => { - // Create a temporary Git repository. - await runCommand('git', ['init'], {cwd: repoRoot}).toPromise(); - - const gitRepository = new GitRepository(repoRoot); - // For some reason, the path returned in tests from - // GitRepository.getWorkingDirectory is prepended with '/private', - // which makes the Directory::contains method inaccurate in - // `repositoryContainsPath`. We mock out the method here to get the - // expected behavior. - spyOn(gitRepository, 'getWorkingDirectory').andCallFake(() => { - return repoRoot; - }); - - expect(repositoryContainsPath(gitRepository, repoRoot)).toBe(true); - const subdir = nuclideUri.join(repoRoot, 'subdir'); - expect(repositoryContainsPath(gitRepository, subdir)).toBe(true); - const parentDir = nuclideUri.resolve(tempFolder, '..'); - expect(repositoryContainsPath(gitRepository, parentDir)).toBe(false); - }); - }); - - it('is accurate for HgRepositoryClient.', () => { - waitsForPromise(async () => { - // Create temporary Hg repository. - await runCommand('hg', ['init'], {cwd: repoRoot}).toPromise(); - - const mockService = new MockHgService(); - const mockHgService: HgServiceType = (mockService: any); - const hgRepositoryClient = new HgRepositoryClient( - /* repoPath */ - nuclideUri.join(repoRoot, '.hg'), - /* hgService */ - mockHgService, - /* options */ - { - originURL: 'testURL', - workingDirectory: new Directory(repoRoot), - projectRootDirectory: new Directory(repoRoot), - }, - ); - - const hgRepository: atom$Repository = (hgRepositoryClient: any); - - expect(repositoryContainsPath(hgRepository, repoRoot)).toBe(true); - const subdir = nuclideUri.join(repoRoot, 'subdir'); - expect(repositoryContainsPath(hgRepository, subdir)).toBe(true); - const parentDir = nuclideUri.resolve(tempFolder, '..'); - expect(repositoryContainsPath(hgRepository, parentDir)).toBe(false); - }); - }); -}); diff --git a/pkg/commons-atom/spec/testHelpers-spec.js b/pkg/commons-atom/spec/testHelpers-spec.js deleted file mode 100644 index 263b4fb1d3..0000000000 --- a/pkg/commons-atom/spec/testHelpers-spec.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * 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 - */ - -import {Range} from 'atom'; -import fsPromise from 'nuclide-commons/fsPromise'; -import {dispatchKeyboardEvent, rangeMatchers} from '../testHelpers'; - -describe('dispatchKeyboardEvent', () => { - it('sends copy and paste', () => { - waitsForPromise(async () => { - const editor = await atom.workspace.open(await fsPromise.tempfile()); - jasmine.attachToDOM(atom.views.getView(atom.workspace)); - editor.insertText('text'); - const events = []; - atom.keymaps.onDidMatchBinding(event => events.push(event)); - - // Copy line. - dispatchKeyboardEvent('c', document.activeElement, {cmd: true}); - // Paste copied line. - dispatchKeyboardEvent('v', document.activeElement, {cmd: true}); - - expect(events.length).toBe(2); - expect(events[0].keystrokes).toBe('cmd-c'); - expect(events[1].keystrokes).toBe('cmd-v'); - expect(editor.getText()).toBe('texttext'); - }); - }); - - it('sends escape', () => { - waitsForPromise(async () => { - await atom.workspace.open(await fsPromise.tempfile()); - jasmine.attachToDOM(atom.views.getView(atom.workspace)); - const events = []; - atom.keymaps.onDidMatchBinding(event => events.push(event)); - - // Hit escape key. - dispatchKeyboardEvent('escape', document.activeElement); - - expect(events.length).toBe(1); - expect(events[0].keystrokes).toBe('escape'); - }); - }); -}); - -describe('rangeMatchers', () => { - beforeEach(function() { - this.addMatchers(rangeMatchers); - }); - - describe('toEqualAtomRange', () => { - it('determines when two Ranges are equal.', () => { - expect(new Range([0, 0], [0, 0])).toEqualAtomRange( - new Range([0, 0], [0, 0]), - ); - expect(new Range([0, 0], [0, 0])).not.toEqualAtomRange( - new Range([1, 0], [0, 0]), - ); - }); - }); - - describe('toEqualAtomRanges', () => { - it('determines when two arrays of Ranges are equal.', () => { - const ranges = [new Range([0, 0], [0, 0]), new Range([1, 1], [1, 1])]; - const sameRanges = [new Range([0, 0], [0, 0]), new Range([1, 1], [1, 1])]; - const differentRanges = [ - new Range([0, 0], [0, 0]), - new Range([2, 2], [2, 2]), - ]; - expect(ranges).toEqualAtomRanges(sameRanges); - expect(ranges).not.toEqualAtomRanges(differentRanges); - }); - }); -}); diff --git a/pkg/commons-atom/sync-atom-commands.js b/pkg/commons-atom/sync-atom-commands.js index 611c132aac..1ab691f95e 100644 --- a/pkg/commons-atom/sync-atom-commands.js +++ b/pkg/commons-atom/sync-atom-commands.js @@ -1,25 +1,25 @@ -/** - * 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 - */ +'use strict'; -export type AtomCommands = { - [target: string]: { - [commandName: string]: atom$CommandListener, - }, -}; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = syncAtomCommands; -import {reconcileSets} from 'nuclide-commons/observable'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Observable} from 'rxjs'; +var _observable; + +function _load_observable() { + return _observable = require('../../modules/nuclide-commons/observable'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../modules/nuclide-commons/UniversalDisposable')); +} -type Projector = (item: T) => AtomCommands; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A utility that adds and removes commands to the Atom command registry based on their presence in @@ -27,26 +27,25 @@ type Projector = (item: T) => AtomCommands; * result (commands), we diff the input (sets) since it's easier and less likely to contain * functions (which are unlikely to be able to be safely compared using `===`). */ -export default function syncAtomCommands( - source: Observable>, - project: Projector, - hash?: (v: T) => any, -): IDisposable { +/** + * 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. + * + * + * @format + */ + +function syncAtomCommands(source, project, hash) { // Add empty sets before completing and erroring to make sure that we remove remaining commands // in both cases. - const sets = source - .concat(Observable.of(new Set())) - .catch(err => Observable.of(new Set()).concat(Observable.throw(err))); - - return reconcileSets( - sets, - item => { - const commands = project(item); - const disposables = Object.keys(commands).map(target => - atom.commands.add(target, commands[target]), - ); - return new UniversalDisposable(...disposables); - }, - hash, - ); -} + const sets = source.concat(_rxjsBundlesRxMinJs.Observable.of(new Set())).catch(err => _rxjsBundlesRxMinJs.Observable.of(new Set()).concat(_rxjsBundlesRxMinJs.Observable.throw(err))); + + return (0, (_observable || _load_observable()).reconcileSets)(sets, item => { + const commands = project(item); + const disposables = Object.keys(commands).map(target => atom.commands.add(target, commands[target])); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(...disposables); + }, hash); +} \ No newline at end of file diff --git a/pkg/commons-atom/testHelpers.js b/pkg/commons-atom/testHelpers.js index 83040018b9..f2e36f01d2 100644 --- a/pkg/commons-atom/testHelpers.js +++ b/pkg/commons-atom/testHelpers.js @@ -1,18 +1,28 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.rangeMatchers = undefined; +exports.dispatchKeyboardEvent = dispatchKeyboardEvent; +exports.setLocalProject = setLocalProject; +exports.waitsForFile = waitsForFile; +exports.waitsForFilePosition = waitsForFilePosition; +exports.getMountedReactRootNames = getMountedReactRootNames; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../modules/nuclide-commons/nuclideUri')); +} + +var _react = _interopRequireWildcard(require('react')); -import invariant from 'assert'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; +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 }; } /** * Use this function to simulate keyboard shortcuts or special keys, e.g. cmd-v, @@ -25,26 +35,35 @@ import ReactDOM from 'react-dom'; * @param metaKeys An object denoting which meta keys are pressed for this * keyboard event. */ -export function dispatchKeyboardEvent( - key: string, - target: ?HTMLElement, - metaKeys: { - alt?: boolean, - cmd?: boolean, - ctrl?: boolean, - shift?: boolean, - } = {}, -): void { - const {alt, cmd, ctrl, shift} = metaKeys; +/** + * 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. + * + * + * @format + */ + +function dispatchKeyboardEvent(key, target, metaKeys = {}) { + const { alt, cmd, ctrl, shift } = metaKeys; // Atom requires `key` to be uppercase when `shift` is specified. - invariant(shift !== true || key.toUpperCase() === key); - invariant(target != null); + + if (!(shift !== true || key.toUpperCase() === key)) { + throw new Error('Invariant violation: "shift !== true || key.toUpperCase() === key"'); + } + + if (!(target != null)) { + throw new Error('Invariant violation: "target != null"'); + } + const event = atom.keymaps.constructor.buildKeydownEvent(key, { target, alt: Boolean(alt), cmd: Boolean(cmd), ctrl: Boolean(ctrl), - shift: Boolean(shift), + shift: Boolean(shift) }); atom.keymaps.handleKeyboardEvent(event); } @@ -53,7 +72,7 @@ export function dispatchKeyboardEvent( * Custom matchers for jasmine testing, as described in: * http://jasmine.github.io/1.3/introduction.html#section-Writing_a_custom_matcher. */ -export const rangeMatchers = { +const rangeMatchers = exports.rangeMatchers = { /** * Determines if two Ranges are equal. This function should not be called * directly, but rather added as a Jasmine custom matcher. @@ -61,7 +80,7 @@ export const rangeMatchers = { * @this A JasmineMatcher object. * @returns True if the Ranges are equal. */ - toEqualAtomRange(expected: ?atom$Range): boolean { + toEqualAtomRange(expected) { return Boolean(this.actual && expected && this.actual.isEqual(expected)); }, @@ -72,13 +91,17 @@ export const rangeMatchers = { * @this A JasmineMatcher object. * @returns True if the array of Ranges are equal. */ - toEqualAtomRanges(expected: ?Array): boolean { + toEqualAtomRanges(expected) { let allEqual = true; if (!this.actual || !expected) { return false; } this.actual.some((range, index) => { - invariant(expected); // Tell Flow this is definitely non-null now. + if (!expected) { + throw new Error('Invariant violation: "expected"'); + } // Tell Flow this is definitely non-null now. + + if (range.isEqual(expected[index])) { return false; } else { @@ -87,14 +110,14 @@ export const rangeMatchers = { } }); return allEqual; - }, + } }; /** * Set the project. If there are one or more projects set previously, this * replaces them all with the one(s) provided as the argument `projectPath`. */ -export function setLocalProject(projectPath: string | Array): void { +function setLocalProject(projectPath) { if (Array.isArray(projectPath)) { atom.project.setPaths(projectPath); } else { @@ -106,10 +129,7 @@ export function setLocalProject(projectPath: string | Array): void { * Waits for the specified file to become the active text editor. * Can only be used in a Jasmine context. */ -export function waitsForFile( - filename: string, - timeoutMs: number = 10000, -): void { +function waitsForFile(filename, timeoutMs = 10000) { waitsFor(`${filename} to become active`, timeoutMs, () => { const editor = atom.workspace.getActiveTextEditor(); if (editor == null) { @@ -119,36 +139,23 @@ export function waitsForFile( if (editorPath == null) { return false; } - return nuclideUri.basename(editorPath) === filename; + return (_nuclideUri || _load_nuclideUri()).default.basename(editorPath) === filename; }); } -export function waitsForFilePosition( - filename: string, - row: number, - column: number, - timeoutMs: number = 10000, -): void { - waitsFor( - `${filename} to become active at ${row}:${column}`, - timeoutMs, - () => { - const editor = atom.workspace.getActiveTextEditor(); - if (editor == null) { - return false; - } - const editorPath = editor.getPath(); - if (editorPath == null) { - return false; - } - const pos = editor.getCursorBufferPosition(); - return ( - nuclideUri.basename(editorPath) === filename && - pos.row === row && - pos.column === column - ); - }, - ); +function waitsForFilePosition(filename, row, column, timeoutMs = 10000) { + waitsFor(`${filename} to become active at ${row}:${column}`, timeoutMs, () => { + const editor = atom.workspace.getActiveTextEditor(); + if (editor == null) { + return false; + } + const editorPath = editor.getPath(); + if (editorPath == null) { + return false; + } + const pos = editor.getCursorBufferPosition(); + return (_nuclideUri || _load_nuclideUri()).default.basename(editorPath) === filename && pos.row === row && pos.column === column; + }); } /** @@ -156,40 +163,30 @@ export function waitsForFilePosition( * unmounted. Having mounted React components after the creator has been * disposed is a sign that there are problems in the cleanup logic. */ -const mountedRootComponents: Map = new Map(); - -const oldReactRender = ReactDOM.render.bind(ReactDOM); -ReactDOM.render = function render( - element: React$Element, - container: Element, - callback?: () => void, -): React$ElementRef { +const mountedRootComponents = new Map(); + +const oldReactRender = _reactDom.default.render.bind(_reactDom.default); +_reactDom.default.render = function render(element, container, callback) { mountedRootComponents.set(container, element); return oldReactRender(element, container, callback); }; -const oldReactUnmountComponentAtNode = ReactDOM.unmountComponentAtNode.bind( - ReactDOM, -); -ReactDOM.unmountComponentAtNode = function unmountComponentAtNode( - container: Element, -): boolean { +const oldReactUnmountComponentAtNode = _reactDom.default.unmountComponentAtNode.bind(_reactDom.default); +_reactDom.default.unmountComponentAtNode = function unmountComponentAtNode(container) { mountedRootComponents.delete(container); return oldReactUnmountComponentAtNode(container); }; -export function getMountedReactRootNames(): Array { - return Array.from(mountedRootComponents) - .map(([element, container]) => element) - .map(element => { - const constructor = element.constructor; - // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - if (typeof constructor.displayName === 'string') { - return constructor.displayName; - } else if (typeof constructor.name === 'string') { - return constructor.name; - } else { - return 'Unknown'; - } - }); -} +function getMountedReactRootNames() { + return Array.from(mountedRootComponents).map(([element, container]) => element).map(element => { + const constructor = element.constructor; + // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) + if (typeof constructor.displayName === 'string') { + return constructor.displayName; + } else if (typeof constructor.name === 'string') { + return constructor.name; + } else { + return 'Unknown'; + } + }); +} \ No newline at end of file diff --git a/pkg/commons-atom/text-buffer.js b/pkg/commons-atom/text-buffer.js index d86e4e31e0..1c5f651c37 100644 --- a/pkg/commons-atom/text-buffer.js +++ b/pkg/commons-atom/text-buffer.js @@ -1,58 +1,47 @@ -/** - * 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 - */ +'use strict'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.observeBufferOpen = observeBufferOpen; +exports.observeBufferCloseOrRename = observeBufferCloseOrRename; -import {Observable} from 'rxjs'; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; +var _event; + +function _load_event() { + return _event = require('../../modules/nuclide-commons/event'); +} // Observes all buffer opens. // Buffer renames are sent as an open of the new name. -export function observeBufferOpen(): Observable { - return observableFromSubscribeFunction(cb => - atom.project.observeBuffers(cb), - ).mergeMap(buffer => { - const end = observableFromSubscribeFunction( - buffer.onDidDestroy.bind(buffer), - ); - const rename = observableFromSubscribeFunction( - buffer.onDidChangePath.bind(buffer), - ) - .map(() => buffer) - .takeUntil(end); - return Observable.of(buffer).concat(rename); +function observeBufferOpen() { + return (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => atom.project.observeBuffers(cb)).mergeMap(buffer => { + const end = (0, (_event || _load_event()).observableFromSubscribeFunction)(buffer.onDidDestroy.bind(buffer)); + const rename = (0, (_event || _load_event()).observableFromSubscribeFunction)(buffer.onDidChangePath.bind(buffer)).map(() => buffer).takeUntil(end); + return _rxjsBundlesRxMinJs.Observable.of(buffer).concat(rename); }); } // Note that on a rename, the openedPath will be the path of the buffer when the open was sent, // which may not match the current name of the buffer. -export type CloseBufferEvent = { - kind: 'close', - openedPath: ?NuclideUri, - buffer: atom$TextBuffer, -}; +/** + * 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. + * + * + * @format + */ // Fires a single event when the buffer is destroyed or renamed. // Note that on a rename the buffer path will not be the same as the openedPath. -export function observeBufferCloseOrRename( - buffer: atom$TextBuffer, -): Observable { - const openedPath: ?NuclideUri = buffer.getPath(); - const end = observableFromSubscribeFunction(buffer.onDidDestroy.bind(buffer)); - const rename = observableFromSubscribeFunction( - buffer.onDidChangePath.bind(buffer), - ); - return end - .merge(rename) - .take(1) - .map(() => ({kind: 'close', buffer, openedPath})); -} +function observeBufferCloseOrRename(buffer) { + const openedPath = buffer.getPath(); + const end = (0, (_event || _load_event()).observableFromSubscribeFunction)(buffer.onDidDestroy.bind(buffer)); + const rename = (0, (_event || _load_event()).observableFromSubscribeFunction)(buffer.onDidChangePath.bind(buffer)); + return end.merge(rename).take(1).map(() => ({ kind: 'close', buffer, openedPath })); +} \ No newline at end of file diff --git a/pkg/commons-atom/ui-tree-path.js b/pkg/commons-atom/ui-tree-path.js index aff30c498e..12c4de7830 100644 --- a/pkg/commons-atom/ui-tree-path.js +++ b/pkg/commons-atom/ui-tree-path.js @@ -1,3 +1,9 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = uiTreePath; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,28 +11,25 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ const TREE_API_DATA_PATH = 'data-path'; -import invariant from 'assert'; - /** * This shouldn't be used for the `file-tree` as it's replaced by * the `FileTreeContextMenu` API. * This can only be useful for other `ui/tree` usages, like the `DiffViewTree`. */ -export default function uiTreePath( - event: Event | {currentTarget: EventTarget}, -): ?string { +function uiTreePath(event) { // Event target isn't necessarily an HTMLElement, - // but that's guaranteed in the usages here. - const target: HTMLElement = (event.currentTarget: any); - const nameElement = target.hasAttribute(TREE_API_DATA_PATH) - ? target - : target.querySelector(`[${TREE_API_DATA_PATH}]`); - invariant(nameElement != null); + const target = event.currentTarget; + const nameElement = target.hasAttribute(TREE_API_DATA_PATH) ? target : target.querySelector(`[${TREE_API_DATA_PATH}]`); + + if (!(nameElement != null)) { + throw new Error('Invariant violation: "nameElement != null"'); + } + return nameElement.getAttribute(TREE_API_DATA_PATH); -} +} \ No newline at end of file diff --git a/pkg/commons-atom/viewableFromReactElement.js b/pkg/commons-atom/viewableFromReactElement.js index a5a93fece0..7199d4d4e4 100644 --- a/pkg/commons-atom/viewableFromReactElement.js +++ b/pkg/commons-atom/viewableFromReactElement.js @@ -1,17 +1,23 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.viewableFromReactElement = viewableFromReactElement; + +var _react = _interopRequireWildcard(require('react')); -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import ReactMountRootElement from 'nuclide-commons-ui/ReactMountRootElement'; +var _reactDom = _interopRequireDefault(require('react-dom')); + +var _ReactMountRootElement; + +function _load_ReactMountRootElement() { + return _ReactMountRootElement = _interopRequireDefault(require('../../modules/nuclide-commons-ui/ReactMountRootElement')); +} + +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; } } /** * Create an object that can be used as an Atom model from a React element. Example: @@ -33,31 +39,34 @@ import ReactMountRootElement from 'nuclide-commons-ui/ReactMountRootElement'; * const item = viewableFromReactElement(); * atom.workspace.getPanes()[0].addItem(item); // Or anywhere else Atom uses model "items." */ -export function viewableFromReactElement( - reactElement: React.Element, -): Object { - const container = new ReactMountRootElement(); - const item = ReactDOM.render(reactElement, container); +function viewableFromReactElement(reactElement) { + const container = new (_ReactMountRootElement || _load_ReactMountRootElement()).default(); + const item = _reactDom.default.render(reactElement, container); // Add the a reference to the container to the item. This will allow Atom's view registry to // associate the item with the HTML element. if (item.element != null) { - throw new Error( - "Component cannot have an `element` property. That's added by viewableFromReactElement", - ); + throw new Error("Component cannot have an `element` property. That's added by viewableFromReactElement"); } - (item: any).element = container; + item.element = container; // Add a destroy method to the item that will unmount the component. There's no need for users to // implement this themselves because they have `componentWillUnmount()`. if (item.destroy != null) { - throw new Error( - "Component cannot implement `destroy()`. That's added by `viewableFromReactElement`", - ); + throw new Error("Component cannot implement `destroy()`. That's added by `viewableFromReactElement`"); } - (item: any).destroy = () => { - ReactDOM.unmountComponentAtNode(container); + item.destroy = () => { + _reactDom.default.unmountComponentAtNode(container); }; return item; -} +} /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/commons-node/DiskCache.js b/pkg/commons-node/DiskCache.js index ac2307e4b1..9d82013c59 100644 --- a/pkg/commons-node/DiskCache.js +++ b/pkg/commons-node/DiskCache.js @@ -1,29 +1,25 @@ -/** - * 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 - */ +'use strict'; -import fsPromise from 'nuclide-commons/fsPromise'; +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../modules/nuclide-commons/fsPromise')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A simple cache that has the ability to persist itself from/to disk. * Values must be JSON-serializable. */ -export default class DiskCache { +class DiskCache { // Use a plain object for faster loading/saving. // We'll be careful to use an Object without a prototype below. - _cache: {[key: string]: V}; - _cacheKeyFunc: K => string; - _cachePath: string; - _byteSize: number; - - constructor(cachePath: string, cacheKeyFunc: K => string) { + constructor(cachePath, cacheKeyFunc) { // Flow (rightfully) does not consider Object.create(null) as a real Object. // Fortunately we don't need to make use of any Object.prototype methods here. // $FlowIgnore @@ -33,14 +29,14 @@ export default class DiskCache { this._byteSize = 0; } - getPath(): string { + getPath() { return this._cachePath; } /** * Returns the size, in bytes, of the most recently serialized value. */ - getByteSize(): number { + getByteSize() { return this._byteSize; } @@ -48,9 +44,9 @@ export default class DiskCache { * Attempts to load the cache from disk. * Returns false if the cache no longer exists, or is corrupt. */ - async load(): Promise { + async load() { try { - const data = await fsPromise.readFile(this._cachePath, 'utf8'); + const data = await (_fsPromise || _load_fsPromise()).default.readFile(this._cachePath, 'utf8'); this._byteSize = data.length; // Make sure we don't pick up any Object prototype methods. this._cache = Object.assign(Object.create(null), JSON.parse(data)); @@ -60,22 +56,32 @@ export default class DiskCache { } } - async save(): Promise { + async save() { try { const data = JSON.stringify(this._cache); this._byteSize = data.length; - await fsPromise.writeFileAtomic(this._cachePath, data); + await (_fsPromise || _load_fsPromise()).default.writeFileAtomic(this._cachePath, data); return true; } catch (err) { return false; } } - get(key: K): ?V { + get(key) { return this._cache[this._cacheKeyFunc(key)]; } - set(key: K, value: V): void { + set(key, value) { this._cache[this._cacheKeyFunc(key)] = value; } } +exports.default = DiskCache; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/commons-node/Dispatcher.js b/pkg/commons-node/Dispatcher.js index 7f0f836138..10b7ba8d7e 100644 --- a/pkg/commons-node/Dispatcher.js +++ b/pkg/commons-node/Dispatcher.js @@ -1,21 +1,9 @@ -/** - * 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 strict - * @format - */ +'use strict'; -/** - * Originally from https://github.com/facebook/flux/blob/55480fb/src/Dispatcher.js - */ - -import invariant from 'assert'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -export type DispatchToken = string; const _prefix = 'ID_'; @@ -106,13 +94,22 @@ const _prefix = 'ID_'; * registered callbacks in order: `CountryStore`, `CityStore`, then * `FlightPriceStore`. */ -export default class Dispatcher { - _callbacks: {[key: DispatchToken]: (payload: TPayload) => void}; - _isDispatching: boolean; - _isHandled: {[key: DispatchToken]: boolean}; - _isPending: {[key: DispatchToken]: boolean}; - _lastID: number; - _pendingPayload: TPayload; +/** + * 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. + * + * strict + * @format + */ + +/** + * Originally from https://github.com/facebook/flux/blob/55480fb/src/Dispatcher.js + */ + +class Dispatcher { constructor() { this._callbacks = {}; @@ -126,11 +123,11 @@ export default class Dispatcher { * Registers a callback to be invoked with every dispatched payload. Returns * a token that can be used with `waitFor()`. */ - register(callback: (payload: TPayload) => void): DispatchToken { - invariant( - !this._isDispatching, - 'Dispatcher.register(...): Cannot register in the middle of a dispatch.', - ); + register(callback) { + if (!!this._isDispatching) { + throw new Error('Dispatcher.register(...): Cannot register in the middle of a dispatch.'); + } + const id = _prefix + this._lastID++; this._callbacks[id] = callback; return id; @@ -139,16 +136,15 @@ export default class Dispatcher { /** * Removes a callback based on its token. */ - unregister(id: DispatchToken): void { - invariant( - !this._isDispatching, - 'Dispatcher.unregister(...): Cannot unregister in the middle of a dispatch.', - ); - invariant( - this._callbacks[id], - 'Dispatcher.unregister(...): `%s` does not map to a registered callback.', - id, - ); + unregister(id) { + if (!!this._isDispatching) { + throw new Error('Dispatcher.unregister(...): Cannot unregister in the middle of a dispatch.'); + } + + if (!this._callbacks[id]) { + throw new Error('Dispatcher.unregister(...): `%s` does not map to a registered callback.'); + } + delete this._callbacks[id]; } @@ -157,27 +153,25 @@ export default class Dispatcher { * of the current callback. This method should only be used by a callback in * response to a dispatched payload. */ - waitFor(ids: Array): void { - invariant( - this._isDispatching, - 'Dispatcher.waitFor(...): Must be invoked while dispatching.', - ); + waitFor(ids) { + if (!this._isDispatching) { + throw new Error('Dispatcher.waitFor(...): Must be invoked while dispatching.'); + } + for (let ii = 0; ii < ids.length; ii++) { const id = ids[ii]; if (this._isPending[id]) { - invariant( - this._isHandled[id], - 'Dispatcher.waitFor(...): Circular dependency detected while ' + - 'waiting for `%s`.', - id, - ); + if (!this._isHandled[id]) { + throw new Error('Dispatcher.waitFor(...): Circular dependency detected while ' + 'waiting for `%s`.'); + } + continue; } - invariant( - this._callbacks[id], - 'Dispatcher.waitFor(...): `%s` does not map to a registered callback.', - id, - ); + + if (!this._callbacks[id]) { + throw new Error('Dispatcher.waitFor(...): `%s` does not map to a registered callback.'); + } + this._invokeCallback(id); } } @@ -185,11 +179,11 @@ export default class Dispatcher { /** * Dispatches a payload to all registered callbacks. */ - dispatch(payload: TPayload): void { - invariant( - !this._isDispatching, - 'Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.', - ); + dispatch(payload) { + if (!!this._isDispatching) { + throw new Error('Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.'); + } + this._startDispatching(payload); try { for (const id in this._callbacks) { @@ -206,7 +200,7 @@ export default class Dispatcher { /** * Is this Dispatcher currently dispatching. */ - isDispatching(): boolean { + isDispatching() { return this._isDispatching; } @@ -216,7 +210,7 @@ export default class Dispatcher { * * @internal */ - _invokeCallback(id: DispatchToken): void { + _invokeCallback(id) { this._isPending[id] = true; this._callbacks[id](this._pendingPayload); this._isHandled[id] = true; @@ -227,7 +221,7 @@ export default class Dispatcher { * * @internal */ - _startDispatching(payload: TPayload): void { + _startDispatching(payload) { for (const id in this._callbacks) { this._isPending[id] = false; this._isHandled[id] = false; @@ -241,8 +235,9 @@ export default class Dispatcher { * * @internal */ - _stopDispatching(): void { + _stopDispatching() { delete this._pendingPayload; this._isDispatching = false; } } +exports.default = Dispatcher; \ No newline at end of file diff --git a/pkg/commons-node/ScribeProcess.js b/pkg/commons-node/ScribeProcess.js index b06d1ee473..70acbf0f84 100644 --- a/pkg/commons-node/ScribeProcess.js +++ b/pkg/commons-node/ScribeProcess.js @@ -1,3 +1,44 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.__test__ = undefined; + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _performanceNow; + +function _load_performanceNow() { + return _performanceNow = _interopRequireDefault(require('../../modules/nuclide-commons/performanceNow')); +} + +var _os = _interopRequireDefault(require('os')); + +var _process; + +function _load_process() { + return _process = require('../../modules/nuclide-commons/process'); +} + +var _which; + +function _load_which() { + return _which = _interopRequireDefault(require('../../modules/nuclide-commons/which')); +} + +var _once; + +function _load_once() { + return _once = _interopRequireDefault(require('./once')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,17 +46,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import {getLogger} from 'log4js'; -import performanceNow from 'nuclide-commons/performanceNow'; -import os from 'os'; -import {spawn} from 'nuclide-commons/process'; -import which from 'nuclide-commons/which'; -import once from './once'; - const DEFAULT_JOIN_TIMEOUT = 5000; let SCRIBE_CAT_COMMAND = 'scribe_cat'; @@ -35,19 +69,9 @@ const SPAWN_TOO_LONG_MS = 2000; * call `scribeProcess.write($object)` to save an JSON schemaed Object into scribe category. * It will also recover from `scribe_cat` failure automatically. */ -export default class ScribeProcess { - static _enabled: boolean = true; - - _scribeCategory: string; - _childPromise: ?Promise; - _subscription: ?rxjs$ISubscription; - _joinTimer: ?TimeoutID; - _joinInterval: ?number; - - constructor( - scribeCategory: string, - joinInterval: ?number = DEFAULT_JOIN_INTERVAL, - ) { +class ScribeProcess { + + constructor(scribeCategory, joinInterval = DEFAULT_JOIN_INTERVAL) { this._scribeCategory = scribeCategory; this._joinInterval = joinInterval; this._getChildProcess(); @@ -56,11 +80,9 @@ export default class ScribeProcess { /** * Check if `scribe_cat` exists in PATH. */ - static isScribeCatOnPath: () => Promise = once(() => - which(SCRIBE_CAT_COMMAND).then(cmd => cmd != null), - ); - static isEnabled(): boolean { + + static isEnabled() { return ScribeProcess._enabled; } @@ -69,7 +91,7 @@ export default class ScribeProcess { * Ensure newlines are properly escaped. * Returns false if something is wrong with the Scribe process (use a fallback instead.) */ - async write(message: string): Promise { + async write(message) { if (!ScribeProcess._enabled) { return false; } @@ -80,14 +102,11 @@ export default class ScribeProcess { ScribeProcess._enabled = false; // Note: Logging errors is potentially recursive, since they go through Scribe! // It's important that we set _enabled before logging errors in this file. - getLogger('ScribeProcess').error( - 'Disabling ScribeProcess due to spawn error:', - err, - ); + (0, (_log4js || _load_log4js()).getLogger)('ScribeProcess').error('Disabling ScribeProcess due to spawn error:', err); return false; } await new Promise(resolve => { - child.stdin.write(`${message}${os.EOL}`, resolve); + child.stdin.write(`${message}${_os.default.EOL}`, resolve); }); return true; } @@ -97,8 +116,8 @@ export default class ScribeProcess { * process has exited. This method is called when the server shuts down in order to guarantee we * capture logging during shutdown. */ - async join(timeout: number = DEFAULT_JOIN_TIMEOUT): Promise { - const {_childPromise, _subscription} = this; + async join(timeout = DEFAULT_JOIN_TIMEOUT) { + const { _childPromise, _subscription } = this; if (_childPromise == null || _subscription == null) { return; } @@ -109,7 +128,7 @@ export default class ScribeProcess { this._clear(); const child = await _childPromise; - const {stdin} = child; + const { stdin } = child; const waitForExit = new Promise(resolve => { child.on('exit', () => { resolve(); @@ -120,7 +139,7 @@ export default class ScribeProcess { }, timeout); }); // Make sure stdin has drained before ending it. - if (!stdin.write(os.EOL)) { + if (!stdin.write(_os.default.EOL)) { stdin.once('drain', () => stdin.end()); } else { stdin.end(); @@ -128,41 +147,34 @@ export default class ScribeProcess { return waitForExit; } - _getChildProcess(): Promise { + _getChildProcess() { if (this._childPromise) { return this._childPromise; } // Obtain a promise to get the child process, but don't start it yet. // this._subscription will have control over starting / stopping the process. - const startTime = performanceNow(); - const processStream = spawn(SCRIBE_CAT_COMMAND, [this._scribeCategory], { - dontLogInNuclide: true, - }) - .do(child => { - const duration = performanceNow() - startTime; - if (duration > SPAWN_TOO_LONG_MS) { - ScribeProcess._enabled = false; - getLogger('ScribeProcess').error( - `Disabling ScribeProcess because spawn took too long (${duration}ms)`, - ); - // Don't raise any errors and allow the current write to complete. - // However, the next write will fail due to the _enabled check. - this.join(); - } - child.stdin.setDefaultEncoding('utf8'); - }) - .finally(() => { - // We may have already started a new process in the meantime. - if (this._childPromise === childPromise) { - this._clear(); - } - }) - .publish(); - - const childPromise = (this._childPromise = processStream - .first() - .toPromise()); + const startTime = (0, (_performanceNow || _load_performanceNow()).default)(); + const processStream = (0, (_process || _load_process()).spawn)(SCRIBE_CAT_COMMAND, [this._scribeCategory], { + dontLogInNuclide: true + }).do(child => { + const duration = (0, (_performanceNow || _load_performanceNow()).default)() - startTime; + if (duration > SPAWN_TOO_LONG_MS) { + ScribeProcess._enabled = false; + (0, (_log4js || _load_log4js()).getLogger)('ScribeProcess').error(`Disabling ScribeProcess because spawn took too long (${duration}ms)`); + // Don't raise any errors and allow the current write to complete. + // However, the next write will fail due to the _enabled check. + this.join(); + } + child.stdin.setDefaultEncoding('utf8'); + }).finally(() => { + // We may have already started a new process in the meantime. + if (this._childPromise === childPromise) { + this._clear(); + } + }).publish(); + + const childPromise = this._childPromise = processStream.first().toPromise(); this._subscription = processStream.connect(); if (this._joinInterval != null) { @@ -185,10 +197,13 @@ export default class ScribeProcess { } } -export const __test__ = { - setScribeCatCommand(newCommand: string): string { +exports.default = ScribeProcess; +ScribeProcess._enabled = true; +ScribeProcess.isScribeCatOnPath = (0, (_once || _load_once()).default)(() => (0, (_which || _load_which()).default)(SCRIBE_CAT_COMMAND).then(cmd => cmd != null)); +const __test__ = exports.__test__ = { + setScribeCatCommand(newCommand) { const originalCommand = SCRIBE_CAT_COMMAND; SCRIBE_CAT_COMMAND = newCommand; return originalCommand; - }, -}; + } +}; \ No newline at end of file diff --git a/pkg/commons-node/SharedObservableCache.js b/pkg/commons-node/SharedObservableCache.js index 460beb8498..c5c71e4379 100644 --- a/pkg/commons-node/SharedObservableCache.js +++ b/pkg/commons-node/SharedObservableCache.js @@ -1,15 +1,10 @@ -/** - * 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 strict - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); -import {Observable} from 'rxjs'; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); /** * This class creates and caches observables by key. @@ -19,28 +14,20 @@ import {Observable} from 'rxjs'; * * Once all subscribers to a key have unsubscribed, the cached observable is cleared. */ -export default class SharedObservableCache { - _factory: (key: Tk) => Observable; - _cache: Map< - Tk, - { - refCount: number, - observable: Observable, - }, - >; +class SharedObservableCache { - constructor(factory: (key: Tk) => Observable) { + constructor(factory) { this._factory = factory; this._cache = new Map(); } - get(key: Tk): Observable { - return Observable.create(observer => { + get(key) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { let cached = this._cache.get(key); if (cached == null) { cached = { refCount: 1, - observable: this._factory(key), + observable: this._factory(key) }; } else { cached.refCount++; @@ -58,3 +45,13 @@ export default class SharedObservableCache { }); } } +exports.default = SharedObservableCache; /** + * 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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/pkg/commons-node/compareVersions.js b/pkg/commons-node/compareVersions.js index 304051289e..4c6ae85ed0 100644 --- a/pkg/commons-node/compareVersions.js +++ b/pkg/commons-node/compareVersions.js @@ -1,3 +1,9 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = compareVersions; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +11,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ @@ -13,7 +19,7 @@ * Compare two version strings. This is much more lax than semver and allows, for example, versions * like "9". */ -export default function compareVersions(a: string, b: string): number { +function compareVersions(a, b) { const aParts = a.split('.').map(x => parseInt(x, 10)); const bParts = b.split('.').map(x => parseInt(x, 10)); for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) { @@ -27,4 +33,4 @@ export default function compareVersions(a: string, b: string): number { } } return 0; -} +} \ No newline at end of file diff --git a/pkg/commons-node/computeDiff.js b/pkg/commons-node/computeDiff.js index 2983638710..312eada09d 100644 --- a/pkg/commons-node/computeDiff.js +++ b/pkg/commons-node/computeDiff.js @@ -1,53 +1,20 @@ -/** - * 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 - */ - -import {diffLines} from 'diff'; - -export type LineMapper = Array; - -export type LineMapping = { - newToOld: LineMapper, - oldToNew: LineMapper, -}; - -export type TextDiff = LineMapping & { - addedLines: Array, - removedLines: Array, - oldLineOffsets: Array<[number, number]>, - newLineOffsets: Array<[number, number]>, -}; - -type ChunkPiece = { - added: number, - removed: number, - value: string, - count: number, - offset: number, -}; - -type DiffChunk = { - addedLines: Array, - removedLines: Array, - chunks: Array, -}; - -export type OffsetMap = Map; - -export function computeDiff(oldText: string, newText: string): TextDiff { - const {addedLines, removedLines, chunks} = _computeDiffChunks( - oldText, - newText, - ); - const {oldLineOffsets, newLineOffsets} = _computeOffsets(chunks); - const {oldToNew, newToOld} = _computeLineDiffMapping(chunks); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.computeDiff = computeDiff; + +var _diff; + +function _load_diff() { + return _diff = require('diff'); +} + +function computeDiff(oldText, newText) { + const { addedLines, removedLines, chunks } = _computeDiffChunks(oldText, newText); + const { oldLineOffsets, newLineOffsets } = _computeOffsets(chunks); + const { oldToNew, newToOld } = _computeLineDiffMapping(chunks); return { addedLines, @@ -55,25 +22,31 @@ export function computeDiff(oldText: string, newText: string): TextDiff { oldLineOffsets: Array.from(oldLineOffsets), // serialize for JSON. newLineOffsets: Array.from(newLineOffsets), // serialize for JSON. oldToNew, - newToOld, + newToOld }; -} - -function _computeDiffChunks(oldText_: string, newText_: string): DiffChunk { +} /** + * 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. + * + * + * @format + */ + +function _computeDiffChunks(oldText_, newText_) { let oldText = oldText_; let newText = newText_; // If the last line has changes, JsDiff doesn't return that. // Generally, content with new line ending are easier to calculate offsets for. - if ( - oldText[oldText.length - 1] !== '\n' || - newText[newText.length - 1] !== '\n' - ) { + if (oldText[oldText.length - 1] !== '\n' || newText[newText.length - 1] !== '\n') { oldText += '\n'; newText += '\n'; } - const lineDiff = diffLines(oldText, newText); + const lineDiff = (0, (_diff || _load_diff()).diffLines)(oldText, newText); const chunks = []; let addedCount = 0; @@ -84,7 +57,7 @@ function _computeDiffChunks(oldText_: string, newText_: string): DiffChunk { const addedLines = []; const removedLines = []; lineDiff.forEach(part => { - const {added, removed, value} = part; + const { added, removed, value } = part; const count = value.split('\n').length - 1; if (!added && !removed) { addedCount += count; @@ -104,7 +77,7 @@ function _computeDiffChunks(oldText_: string, newText_: string): DiffChunk { removedCount += count; nextOffset -= count; } - chunks.push({added, removed, value, count, offset}); + chunks.push({ added, removed, value, count, offset }); offset = 0; }); if (nextOffset !== 0) { @@ -114,15 +87,13 @@ function _computeDiffChunks(oldText_: string, newText_: string): DiffChunk { removed: 0, value: '', count: 0, - offset: nextOffset, + offset: nextOffset }); } - return {addedLines, removedLines, chunks}; + return { addedLines, removedLines, chunks }; } -function _computeOffsets( - diffChunks: Array, -): {oldLineOffsets: OffsetMap, newLineOffsets: OffsetMap} { +function _computeOffsets(diffChunks) { const newLineOffsets = new Map(); const oldLineOffsets = new Map(); @@ -130,7 +101,7 @@ function _computeOffsets( let newLineCount = 0; for (const chunk of diffChunks) { - const {added, removed, offset, count} = chunk; + const { added, removed, offset, count } = chunk; if (added) { newLineCount += count; } else if (removed) { @@ -153,11 +124,11 @@ function _computeOffsets( return { oldLineOffsets, - newLineOffsets, + newLineOffsets }; } -function _computeLineDiffMapping(diffChunks: Array): LineMapping { +function _computeLineDiffMapping(diffChunks) { const newToOld = []; const oldToNew = []; @@ -169,7 +140,7 @@ function _computeLineDiffMapping(diffChunks: Array): LineMapping { let removedCount = 0; for (const chunk of diffChunks) { - const {added, removed, offset, count} = chunk; + const { added, removed, offset, count } = chunk; if (added) { addedCount = count; } else if (removed) { @@ -214,6 +185,6 @@ function _computeLineDiffMapping(diffChunks: Array): LineMapping { return { newToOld, - oldToNew, + oldToNew }; -} +} \ No newline at end of file diff --git a/pkg/commons-node/definition.js b/pkg/commons-node/definition.js index 4133d39537..768285e08f 100644 --- a/pkg/commons-node/definition.js +++ b/pkg/commons-node/definition.js @@ -1,15 +1,10 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.definitionsAreEqual = definitionsAreEqual; -import type {Definition} from 'atom-ide-ui'; /** * Returns true if the 2 definitions are considered equal. They are considered equal if: @@ -22,7 +17,7 @@ import type {Definition} from 'atom-ide-ui'; * - language * - project root */ -export function definitionsAreEqual(x: ?Definition, y: ?Definition): boolean { +function definitionsAreEqual(x, y) { if (x == null || y == null) { return x === y; } @@ -32,10 +27,7 @@ export function definitionsAreEqual(x: ?Definition, y: ?Definition): boolean { if (x.path !== y.path) { return false; } - if ( - x.position.row !== y.position.row || - x.position.column !== y.position.column - ) { + if (x.position.row !== y.position.row || x.position.column !== y.position.column) { return false; } if (x.language !== y.language) { @@ -45,4 +37,13 @@ export function definitionsAreEqual(x: ?Definition, y: ?Definition): boolean { return false; } return true; -} +} /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/commons-node/humanizeEventName.js b/pkg/commons-node/humanizeEventName.js index 4184f64417..a9b6041f88 100644 --- a/pkg/commons-node/humanizeEventName.js +++ b/pkg/commons-node/humanizeEventName.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,30 +7,25 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ // Adapted from https://github.com/atom/underscore-plus/blob/master/src/underscore-plus.coffee // TODO: Consider combining with the similar function in `./humanizeKeystoke.js` -function capitalize(word: string): string { +function capitalize(word) { if (!word) { return ''; } return word[0].toUpperCase() + word.slice(1); } -function undasherize(string: string): string { - return string - ? string - .split('-') - .map(capitalize) - .join(' ') - : ''; +function undasherize(string) { + return string ? string.split('-').map(capitalize).join(' ') : ''; } -function humanizeEventName(eventName: string): string { +function humanizeEventName(eventName) { const [namespace, event] = eventName.split(':'); if (!event) { return undasherize(namespace); @@ -40,4 +37,4 @@ function humanizeEventName(eventName: string): string { } // eslint-disable-next-line nuclide-internal/no-commonjs -module.exports = humanizeEventName; +module.exports = humanizeEventName; \ No newline at end of file diff --git a/pkg/commons-node/immutable-snapshot.js b/pkg/commons-node/immutable-snapshot.js index 3f7dcddb32..9811be7f6c 100644 --- a/pkg/commons-node/immutable-snapshot.js +++ b/pkg/commons-node/immutable-snapshot.js @@ -1,122 +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 - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ImmutableSnapshotReader = exports.Map = exports.ImmutableSnapshotter = undefined; +exports.List = List; +exports.OrderedMap = OrderedMap; +exports.Record = Record; -import type {RecordFactory, RecordOf} from 'immutable'; +var _immutable; + +function _load_immutable() { + return _immutable = _interopRequireDefault(require('immutable')); +} -import invariant from 'assert'; -import Immutable from 'immutable'; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // A snapshot of the Immutable.JS object represented by the ID "root". // "root" may be represented as a 'delta' based on previously snapshotted objects, // so this includes all of the objects that it depends on. // Snapshots are intended to be JSON-serializable. -export type DeltaSnapshot = {| - root: number, - snapshotObjects: {[id: number]: DeltaSnapshotImmutableObject}, -|}; + // A snapshotted version of an individual immutable object. // Every object is tagged with a unique ID. -type DeltaSnapshotImmutableObject = - // "ref" means that the object has already been snapshotted - - // either elsewhere in the current snapshot or in the previous snapshot. - | {| - type: 'ref', - id: number, - |} - // "delta" means that the object should be derived from the value of `parentID` - // after applying the mutations in `mutations`. - | {| - type: 'delta', - id: number, - parentID: number, - mutations: Array, - |} - // If not 'ref' or 'delta', the entire object state is serialized. - // Immutable.List - | {| - type: 'list', - id: number, - value: Array, - |} - // Immutable.Map - | {| - type: 'map', - id: number, - // (key, value) pairs - value: Array<[DeltaSnapshotObject, DeltaSnapshotObject]>, - |} - // Immutable.OrderedMap - | {| - type: 'orderedmap', - id: number, - // (key, value) pairs - value: Array<[DeltaSnapshotObject, DeltaSnapshotObject]>, - |} - // Immutable.RecordOf - | {| - type: 'record', - id: number, - value: Array<[string, DeltaSnapshotObject]>, - |}; + // A more general representation of an object that can be either immutable or non-immutable. -type DeltaSnapshotObject = - // To save space, primitives are serialized as is. (These never have typeof "object"). - | string - | number - | boolean - | null - | void - // Regular JS objects need to be wrapped to differentiate from DeltaSnapshotImmutableObject. - // NOTE: JSON-serializability of the snapshot depends on the serializability of these. - // Nesting immutables in objects in immutables is not supported. - | {|_: Object|} - | DeltaSnapshotImmutableObject; + // Snapshotted mutation (note that the args may be other immutable objects.) -type DeltaSnapshotMutation = {| - method: string, - args: Array, -|}; - -const UNWRAPPED_METHODS = new Set([ - 'constructor', - // Methods that are guaranteed not to cause a mutation. - 'get', - 'getIn', - 'first', - 'last', - 'reduce', - 'reduceRight', - 'find', - 'findLast', - 'findEntry', - 'findLastEntry', - 'max', - 'maxBy', - 'min', - 'minBy', - // Covered by overriding __ensureOwner. - 'asMutable', - 'asImmutable', - 'withMutations', -]); +const UNWRAPPED_METHODS = new Set(['constructor', +// Methods that are guaranteed not to cause a mutation. +'get', 'getIn', 'first', 'last', 'reduce', 'reduceRight', 'find', 'findLast', 'findEntry', 'findLastEntry', 'max', 'maxBy', 'min', 'minBy', +// Covered by overriding __ensureOwner. +'asMutable', 'asImmutable', 'withMutations']); // A union of all Immutable collections that are currently supported. -export type DeltaSnapshotCollection = - | Immutable.List - | Immutable.Map - | Immutable.OrderedMap - | RecordOf; +/** + * 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. + * + * + * @format + */ /** * immutable-snapshot exports custom versions of Immutable collections that can record @@ -153,64 +83,56 @@ export type DeltaSnapshotCollection = * IMPORTANT: It's assumed that any non-Immutable object anywhere in the snapshot * is JSON-serializable. (Otherwise, the result will not be JSON-serializable). */ -export class ImmutableSnapshotter { - // Track the contents of the previous snapshot so that we know what we can reuse. - // Note that we could also store a complete history of snapshots on both sides, - // but in practice patterns like Redux ensure that only the most recent state is really needed. - _previousSnapshotObjects: ?{[id: number]: DeltaSnapshotImmutableObject}; +class ImmutableSnapshotter { - createDeltaSnapshot(object: DeltaSnapshotCollection): DeltaSnapshot { + createDeltaSnapshot(object) { const snapshotObjects = {}; - const result = _snapshotImpl( - object, - snapshotObjects, - this._previousSnapshotObjects || {}, - ); - invariant( - result != null && typeof result.id === 'number', - 'Expected an immutable object as input', - ); + const result = _snapshotImpl(object, snapshotObjects, this._previousSnapshotObjects || {}); + + if (!(result != null && typeof result.id === 'number')) { + throw new Error('Expected an immutable object as input'); + } + this._previousSnapshotObjects = snapshotObjects; return { root: result.id, - snapshotObjects, + snapshotObjects }; } + // Track the contents of the previous snapshot so that we know what we can reuse. + // Note that we could also store a complete history of snapshots on both sides, + // but in practice patterns like Redux ensure that only the most recent state is really needed. } -export function List(value?: Iterable): Immutable.List { +exports.ImmutableSnapshotter = ImmutableSnapshotter; +function List(value) { // Use a custom prototype to override methods for tracking purposes. - return _wrap(Immutable.List(value), List); + return _wrap((_immutable || _load_immutable()).default.List(value), List); } -List.prototype = Object.create(Immutable.List.prototype); +List.prototype = Object.create((_immutable || _load_immutable()).default.List.prototype); List.of = (...args) => List(args); -_overrideMethods(List, Immutable.List); +_overrideMethods(List, (_immutable || _load_immutable()).default.List); -function SnapshotMap( - value?: Iterable<[K, V]> | {[key: K]: V}, -): Immutable.Map { - return _wrap(Immutable.Map(value), SnapshotMap); +function SnapshotMap(value) { + return _wrap((_immutable || _load_immutable()).default.Map(value), SnapshotMap); } -SnapshotMap.prototype = Object.create(Immutable.Map.prototype); +SnapshotMap.prototype = Object.create((_immutable || _load_immutable()).default.Map.prototype); // $FlowIssue: Map.of is missing -SnapshotMap.of = (...args) => SnapshotMap(Immutable.Map.of(...args)); -_overrideMethods(SnapshotMap, Immutable.Map); -export {SnapshotMap as Map}; - -export function OrderedMap( - value?: Iterable<[K, V]> | {[key: K]: V}, -): Immutable.OrderedMap { - return _wrap(Immutable.OrderedMap(value), OrderedMap); +SnapshotMap.of = (...args) => SnapshotMap((_immutable || _load_immutable()).default.Map.of(...args)); +_overrideMethods(SnapshotMap, (_immutable || _load_immutable()).default.Map); +exports.Map = SnapshotMap; +function OrderedMap(value) { + return _wrap((_immutable || _load_immutable()).default.OrderedMap(value), OrderedMap); } -OrderedMap.prototype = Object.create(Immutable.OrderedMap.prototype); -_overrideMethods(OrderedMap, Immutable.OrderedMap); +OrderedMap.prototype = Object.create((_immutable || _load_immutable()).default.OrderedMap.prototype); +_overrideMethods(OrderedMap, (_immutable || _load_immutable()).default.OrderedMap); // Immutable.Record actually returns a RecordFactory which then produces RecordInstances. -export function Record(value: T): RecordFactory { - const OriginalRecord = Immutable.Record(value); +function Record(value) { + const OriginalRecord = (_immutable || _load_immutable()).default.Record(value); class DiffableRecord extends OriginalRecord {} _overrideMethods(DiffableRecord, OriginalRecord); return DiffableRecord; @@ -218,7 +140,7 @@ export function Record(value: T): RecordFactory { // Immutable.JS does not correctly support inheritance :( // We often need to manually re-wrap the objects. -function _wrap(object: Object, constructor: Function) { +function _wrap(object, constructor) { if (object.size === 0) { // Immutable.JS shares empty objects, so we can't mutate these. // TODO: implement our own shared empty objects. @@ -233,73 +155,50 @@ function _wrap(object: Object, constructor: Function) { // (This is much faster than using a WeakMap.) const MetadataKey = Symbol('Metadata'); -type Metadata = {| - // A guaranteed unique ID for the object. - id: number, - // Records the source of each immutable object, along with the mutations applied. - parent?: DeltaSnapshotCollection, - mutations?: Array<{ - method: string, - args: Array, - }>, - // We track all objects ever snapshotted for an optimization: - // There's no point in tracking mutations to newly-created objects not in the snapshot. - // For new objects, the serialized list of mutations almost certainly takes more space - // than its raw JSON representation. - // Ideally this would be tied to a particular ImmutableSnapshotter for accuracy, - // but we make a tradeoff here to keep the actual collections global. - // (In practice objects not in the previous snapshot are unlikely to be used again.) - snapshotted?: boolean, -|}; - // Generates a unique auto-incrementing ID for any object. -let _objectCount: number = 0; +let _objectCount = 0; -function _getMetadata(object: Object): Metadata { +function _getMetadata(object) { let metadata = object[MetadataKey]; if (metadata == null) { - metadata = {id: ++_objectCount}; + metadata = { id: ++_objectCount }; object[MetadataKey] = metadata; } return metadata; } -function _snapshotImpl( - object: Object, - snapshotObjects: {[id: number]: DeltaSnapshotImmutableObject}, - previousSnapshotObjects: {[id: number]: DeltaSnapshotImmutableObject}, -): DeltaSnapshotObject { +function _snapshotImpl(object, snapshotObjects, previousSnapshotObjects) { // Primitives if (typeof object !== 'object') { return object; } // Regular JS objects - if (!Immutable.isImmutable(object)) { - return {_: object}; + if (!(_immutable || _load_immutable()).default.isImmutable(object)) { + return { _: object }; } const metadata = _getMetadata(object); - const {id, parent, mutations} = metadata; + const { id, parent, mutations } = metadata; // If this was already snapshotted last time (or earlier in the current snapshot), // assume the deserializer still knows about it. if (previousSnapshotObjects[id] != null || snapshotObjects[id] != null) { - return (snapshotObjects[id] = {type: 'ref', id}); + return snapshotObjects[id] = { type: 'ref', id }; } metadata.snapshotted = true; if (parent != null) { - invariant(mutations != null); - const parentSnapshot = _snapshotImpl( - parent, - snapshotObjects, - previousSnapshotObjects, - ); - invariant( - parentSnapshot != null && typeof parentSnapshot.id === 'number', - 'Parent must be immutable', - ); - return (snapshotObjects[id] = { + if (!(mutations != null)) { + throw new Error('Invariant violation: "mutations != null"'); + } + + const parentSnapshot = _snapshotImpl(parent, snapshotObjects, previousSnapshotObjects); + + if (!(parentSnapshot != null && typeof parentSnapshot.id === 'number')) { + throw new Error('Parent must be immutable'); + } + + return snapshotObjects[id] = { type: 'delta', id, parentID: parentSnapshot.id, @@ -307,52 +206,38 @@ function _snapshotImpl( return { method: mutation.method, // Mutation arguments may be other immutable objects, so snapshot those too. - args: mutation.args.map(arg => - _snapshotImpl(arg, snapshotObjects, previousSnapshotObjects), - ), + args: mutation.args.map(arg => _snapshotImpl(arg, snapshotObjects, previousSnapshotObjects)) }; - }), - }); - } else if (object instanceof Immutable.List) { - return (snapshotObjects[id] = { + }) + }; + } else if (object instanceof (_immutable || _load_immutable()).default.List) { + return snapshotObjects[id] = { type: 'list', id, value: object.toJSON().map(x => - // Nested immutable objects are well-supported. - _snapshotImpl(x, snapshotObjects, previousSnapshotObjects), - ), - }); - } else if (object instanceof Immutable.OrderedMap) { + // Nested immutable objects are well-supported. + _snapshotImpl(x, snapshotObjects, previousSnapshotObjects)) + }; + } else if (object instanceof (_immutable || _load_immutable()).default.OrderedMap) { const value = []; for (const [k, v] of object.entries()) { - value.push([ - _snapshotImpl(k, snapshotObjects, previousSnapshotObjects), - _snapshotImpl(v, snapshotObjects, previousSnapshotObjects), - ]); + value.push([_snapshotImpl(k, snapshotObjects, previousSnapshotObjects), _snapshotImpl(v, snapshotObjects, previousSnapshotObjects)]); } - return (snapshotObjects[id] = {type: 'orderedmap', id, value}); - } else if (object instanceof Immutable.Map) { + return snapshotObjects[id] = { type: 'orderedmap', id, value }; + } else if (object instanceof (_immutable || _load_immutable()).default.Map) { const value = []; for (const [k, v] of object.entries()) { - value.push([ - _snapshotImpl(k, snapshotObjects, previousSnapshotObjects), - _snapshotImpl(v, snapshotObjects, previousSnapshotObjects), - ]); + value.push([_snapshotImpl(k, snapshotObjects, previousSnapshotObjects), _snapshotImpl(v, snapshotObjects, previousSnapshotObjects)]); } - return (snapshotObjects[id] = {type: 'map', id, value}); - } else if (object instanceof Immutable.Record) { + return snapshotObjects[id] = { type: 'map', id, value }; + } else if (object instanceof (_immutable || _load_immutable()).default.Record) { const value = []; for (const [k, v] of object.entries()) { - value.push([ - k, - _snapshotImpl(v, snapshotObjects, previousSnapshotObjects), - ]); + value.push([k, _snapshotImpl(v, snapshotObjects, previousSnapshotObjects)]); } - return (snapshotObjects[id] = {type: 'record', id, value}); + return snapshotObjects[id] = { type: 'record', id, value }; } else { - throw new Error( - `Serialization for ${object.constructor.name} is not implemented yet.`, - ); + throw new Error(`Serialization for ${object.constructor.name} is not implemented yet.`); } } @@ -362,14 +247,14 @@ function _snapshotImpl( * the new object descended from the initial object and also record the mutation. * These can then be replayed in ImmutableSnapshotReader. */ -function _overrideMethods(wrapped: Function, original: Function): void { +function _overrideMethods(wrapped, original) { const originalPrototype = original.prototype; // Storing the call depth allows us to discard mutations triggered within mutations // (e.g. List.push uses List.set underneath.) let depth = 0; - function wrapIfNeeded(object: Object): Object { + function wrapIfNeeded(object) { if (object == null || typeof object !== 'object') { return object; } @@ -379,7 +264,7 @@ function _overrideMethods(wrapped: Function, original: Function): void { if (proto === originalPrototype) { return _wrap(object, wrapped); // $FlowIssue: OrderedMap.prototype should exist - } else if (proto === Immutable.OrderedMap.prototype) { + } else if (proto === (_immutable || _load_immutable()).default.OrderedMap.prototype) { // Immutable.Map.sort returns an OrderedMap. // This won't be recorded as a mutation, but continue wrapping it. return _wrap(object, OrderedMap); @@ -388,16 +273,11 @@ function _overrideMethods(wrapped: Function, original: Function): void { } for (const method in originalPrototype) { - if ( - method.startsWith('__') || - method.startsWith('to') || - method.startsWith('@@') || - UNWRAPPED_METHODS.has(method) - ) { + if (method.startsWith('__') || method.startsWith('to') || method.startsWith('@@') || UNWRAPPED_METHODS.has(method)) { continue; } const oldMethod = wrapped.prototype[method]; - wrapped.prototype[method] = function(...args) { + wrapped.prototype[method] = function (...args) { // Don't record nested mutations. if (depth) { return wrapIfNeeded(oldMethod.apply(this, args)); @@ -408,28 +288,25 @@ function _overrideMethods(wrapped: Function, original: Function): void { if (newObject !== this) { newObject = wrapIfNeeded(newObject); // Only record a mutation if wrapping was successful. - if ( - newObject instanceof wrapped && - _isSerializable(args) && - _shouldRecordMutations(this) - ) { + if (newObject instanceof wrapped && _isSerializable(args) && _shouldRecordMutations(this)) { const metadata = _getMetadata(newObject); - invariant( - metadata.parent == null, - 'An object cannot have two parents', - ); + + if (!(metadata.parent == null)) { + throw new Error('An object cannot have two parents'); + } + metadata.parent = this; - metadata.mutations = [{method, args}]; + metadata.mutations = [{ method, args }]; } } else if (this.__ownerID) { // this.__ownerID indicates that the object is currently mutable. // We'll push these mutations onto the existing parent record. // (generated from the __ensureOwner override below). - const {mutations} = _getMetadata(newObject); + const { mutations } = _getMetadata(newObject); if (mutations != null) { // Note: withMutations only supports certain mutations. // All of them should be serializable (e.g. set, push, pop) - mutations.push({method, args}); + mutations.push({ method, args }); } } return newObject; @@ -438,8 +315,8 @@ function _overrideMethods(wrapped: Function, original: Function): void { // __ensureOwner is what Immutable.JS uses to implement asMutable(). // It creates a copy of the object, so we need to record the parent. - const {__ensureOwner} = wrapped.prototype; - wrapped.prototype.__ensureOwner = function(ownerID) { + const { __ensureOwner } = wrapped.prototype; + wrapped.prototype.__ensureOwner = function (ownerID) { let newObject = __ensureOwner.call(this, ownerID); // Some methods use `withMutation` in their implementation. Ignore it. if (depth) { @@ -451,7 +328,11 @@ function _overrideMethods(wrapped: Function, original: Function): void { } if (_shouldRecordMutations(this)) { const metadata = _getMetadata(newObject); - invariant(metadata.parent == null, 'An object cannot have two parents'); + + if (!(metadata.parent == null)) { + throw new Error('An object cannot have two parents'); + } + metadata.parent = this; metadata.mutations = []; } @@ -460,17 +341,17 @@ function _overrideMethods(wrapped: Function, original: Function): void { }; } -function _isSerializable(args: Array): boolean { +function _isSerializable(args) { // Mutations with functions as arguments are not serializable. return args.every(x => typeof x !== 'function'); } -function _shouldRecordMutations(object: DeltaSnapshotCollection): boolean { +function _shouldRecordMutations(object) { // It's not worth recording mutations to empty collections. if (object.size === 0) { return false; } - const {parent, snapshotted} = _getMetadata(object); + const { parent, snapshotted } = _getMetadata(object); return parent != null || snapshotted != null; } @@ -479,34 +360,26 @@ function _shouldRecordMutations(object: DeltaSnapshotCollection): boolean { * Note that any values used in snapshots before that will be discarded - so it's important that * ImmutableSnapshotReader and its corresponding ImmutableSnapshotter stay in sync. */ -export class ImmutableSnapshotReader { +class ImmutableSnapshotReader { + constructor() { + this._previousDeserializedObjects = new Map(); + } // Since ImmutableSnapshotter uses the previous snapshot to create deltas, // we must also keep the deserialized version of the last snapshot around. - _previousDeserializedObjects: Map< - number, - DeltaSnapshotCollection, - > = new Map(); + readSnapshot({ root, - snapshotObjects, - }: DeltaSnapshot): DeltaSnapshotCollection { + snapshotObjects + }) { const deserializedObjects = new Map(); - const result = this._deserializeImmutable( - root, - snapshotObjects, - deserializedObjects, - ); + const result = this._deserializeImmutable(root, snapshotObjects, deserializedObjects); // Keep the last snapshot around for the next snapshot to use. this._previousDeserializedObjects = deserializedObjects; return result; } - _deserializeObject( - object: DeltaSnapshotObject, - snapshotObjects: {[id: number]: DeltaSnapshotImmutableObject}, - deserializedObjects: Map, - ): mixed { + _deserializeObject(object, snapshotObjects, deserializedObjects) { if (object == null || typeof object !== 'object') { return object; } @@ -514,118 +387,76 @@ export class ImmutableSnapshotReader { // $FlowIssue: this is guaranteed to exist return object._; } - return this._deserializeImmutable( - object.id, - snapshotObjects, - deserializedObjects, - ); + return this._deserializeImmutable(object.id, snapshotObjects, deserializedObjects); } - _deserializeImmutable( - id: number, - snapshotObjects: {[id: number]: DeltaSnapshotImmutableObject}, - deserializedObjects: Map, - ): DeltaSnapshotCollection { + _deserializeImmutable(id, snapshotObjects, deserializedObjects) { const object = snapshotObjects[id]; - invariant(object != null, `Missing record for id ${id}`); + + if (!(object != null)) { + throw new Error(`Missing record for id ${id}`); + } + switch (object.type) { case 'ref': - const stored = - this._previousDeserializedObjects.get(object.id) || - deserializedObjects.get(object.id); - invariant( - stored != null, - `Expected ${object.id} to be previously snapshotted`, - ); + const stored = this._previousDeserializedObjects.get(object.id) || deserializedObjects.get(object.id); + + if (!(stored != null)) { + throw new Error(`Expected ${object.id} to be previously snapshotted`); + } + deserializedObjects.set(object.id, stored); return stored; case 'delta': - const parent = this._deserializeImmutable( - object.parentID, - snapshotObjects, - deserializedObjects, - ); - invariant( - Immutable.isImmutable(parent), - 'Expected parent to be an immutable object', - ); + const parent = this._deserializeImmutable(object.parentID, snapshotObjects, deserializedObjects); + + if (!(_immutable || _load_immutable()).default.isImmutable(parent)) { + throw new Error('Expected parent to be an immutable object'); + } + let value; // withMutations doesn't support all mutations, so we must handle the singular case. if (object.mutations.length === 1) { - value = this._applyMutation( - parent, - object.mutations[0], - snapshotObjects, - deserializedObjects, - ); + value = this._applyMutation(parent, object.mutations[0], snapshotObjects, deserializedObjects); } else { value = parent.withMutations(p => { object.mutations.forEach(mutation => { - this._applyMutation( - p, - mutation, - snapshotObjects, - deserializedObjects, - ); + this._applyMutation(p, mutation, snapshotObjects, deserializedObjects); }); }); } deserializedObjects.set(object.id, value); return value; case 'list': - const list = Immutable.List( - object.value.map(elem => - this._deserializeObject(elem, snapshotObjects, deserializedObjects), - ), - ); + const list = (_immutable || _load_immutable()).default.List(object.value.map(elem => this._deserializeObject(elem, snapshotObjects, deserializedObjects))); deserializedObjects.set(object.id, list); return list; case 'map': - const map = Immutable.Map( - object.value.map(([k, v]) => [ - this._deserializeObject(k, snapshotObjects, deserializedObjects), - this._deserializeObject(v, snapshotObjects, deserializedObjects), - ]), - ); + const map = (_immutable || _load_immutable()).default.Map(object.value.map(([k, v]) => [this._deserializeObject(k, snapshotObjects, deserializedObjects), this._deserializeObject(v, snapshotObjects, deserializedObjects)])); deserializedObjects.set(object.id, map); return map; case 'orderedmap': - const orderedMap = Immutable.OrderedMap( - object.value.map(([k, v]) => [ - this._deserializeObject(k, snapshotObjects, deserializedObjects), - this._deserializeObject(v, snapshotObjects, deserializedObjects), - ]), - ); + const orderedMap = (_immutable || _load_immutable()).default.OrderedMap(object.value.map(([k, v]) => [this._deserializeObject(k, snapshotObjects, deserializedObjects), this._deserializeObject(v, snapshotObjects, deserializedObjects)])); deserializedObjects.set(object.id, orderedMap); return orderedMap; case 'record': const record = {}; object.value.forEach(([k, v]) => { - record[k] = this._deserializeObject( - v, - snapshotObjects, - deserializedObjects, - ); + record[k] = this._deserializeObject(v, snapshotObjects, deserializedObjects); }); - class _Record extends Immutable.Record(record) {} + class _Record extends (_immutable || _load_immutable()).default.Record(record) {} const rec = new _Record(record); deserializedObjects.set(object.id, rec); return rec; default: - (object.type: empty); + object.type; throw new Error(`Unexpected type ${object.type}`); } } - _applyMutation( - object: Object, - mutation: DeltaSnapshotMutation, - snapshotObjects: {[id: number]: DeltaSnapshotImmutableObject}, - deserializedObjects: Map, - ): DeltaSnapshotCollection { - const args = mutation.args.map(arg => - this._deserializeObject(arg, snapshotObjects, deserializedObjects), - ); + _applyMutation(object, mutation, snapshotObjects, deserializedObjects) { + const args = mutation.args.map(arg => this._deserializeObject(arg, snapshotObjects, deserializedObjects)); return object[mutation.method](...args); } } +exports.ImmutableSnapshotReader = ImmutableSnapshotReader; \ No newline at end of file diff --git a/pkg/commons-node/keytarWrapper.js b/pkg/commons-node/keytarWrapper.js index d0203da55b..362f2717fe 100644 --- a/pkg/commons-node/keytarWrapper.js +++ b/pkg/commons-node/keytarWrapper.js @@ -1,3 +1,38 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.__TEST__ = undefined; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../modules/nuclide-commons/nuclideUri')); +} + +var _process; + +function _load_process() { + return _process = require('../../modules/nuclide-commons/process'); +} + +var _passesGK; + +function _load_passesGK() { + return _passesGK = _interopRequireDefault(require('./passesGK')); +} + +var _keytar; + +function _load_keytar() { + return _keytar = _interopRequireWildcard(require('nuclide-prebuilt-libs/keytar')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,25 +40,21 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {runCommand, ProcessExitError} from 'nuclide-commons/process'; -import passesGK from './passesGK'; +async function shouldUseApmNode() { + return !(await (0, (_passesGK || _load_passesGK()).default)('nuclide_prebuilt_keytar')); +} + +// KeyTar>=4.x APM>=1.18 + /** * If we're running outside of Atom, attempt to use the prebuilt keytar libs. * (May throw if prebuilt libs aren't available for the current platform!) */ -import * as keytar from 'nuclide-prebuilt-libs/keytar'; - -async function shouldUseApmNode(): Promise { - return !(await passesGK('nuclide_prebuilt_keytar')); -} - -// KeyTar>=4.x APM>=1.18 const getPasswordScriptAsync = ` var readline = require('readline'); var keytar = require('keytar'); @@ -73,93 +104,71 @@ const deletePasswordScriptAsync = ` }); `; -function getApmNodePath(): string { - const apmDir = nuclideUri.dirname(atom.packages.getApmPath()); - return nuclideUri.normalize(nuclideUri.join(apmDir, 'node')); +function getApmNodePath() { + const apmDir = (_nuclideUri || _load_nuclideUri()).default.dirname(atom.packages.getApmPath()); + return (_nuclideUri || _load_nuclideUri()).default.normalize((_nuclideUri || _load_nuclideUri()).default.join(apmDir, 'node')); } -function getApmNodeModulesPath(): string { - const apmDir = nuclideUri.dirname(atom.packages.getApmPath()); - return nuclideUri.normalize(nuclideUri.join(apmDir, '..', 'node_modules')); +function getApmNodeModulesPath() { + const apmDir = (_nuclideUri || _load_nuclideUri()).default.dirname(atom.packages.getApmPath()); + return (_nuclideUri || _load_nuclideUri()).default.normalize((_nuclideUri || _load_nuclideUri()).default.join(apmDir, '..', 'node_modules')); } -function runScriptInApmNode( - script: string, - service: string, - account: string, - password?: string, -): Promise { +function runScriptInApmNode(script, service, account, password) { const args = ['-e', script]; const options = { // The newline is important so we can use readline's line event. - input: JSON.stringify({service, account, password}) + '\n', - env: { - ...process.env, - NODE_PATH: getApmNodeModulesPath(), - }, + input: JSON.stringify({ service, account, password }) + '\n', + env: Object.assign({}, process.env, { + NODE_PATH: getApmNodeModulesPath() + }) }; - return runCommand(getApmNodePath(), args, options) - .toPromise() - .catch(err => { - if (err instanceof ProcessExitError) { - // Unwrap underlying error from stderr (as it already has a stack!) - throw new Error(err.stderr); - } - throw err; - }); + return (0, (_process || _load_process()).runCommand)(getApmNodePath(), args, options).toPromise().catch(err => { + if (err instanceof (_process || _load_process()).ProcessExitError) { + // Unwrap underlying error from stderr (as it already has a stack!) + throw new Error(err.stderr); + } + throw err; + }); } -export default { +exports.default = { /** * Returns the password (or null if it doesn't exist). * Rejects on keychain access failure. */ - async getPassword(service: string, account: string): Promise { + async getPassword(service, account) { if (typeof atom === 'object' && (await shouldUseApmNode())) { - return JSON.parse( - await runScriptInApmNode(getPasswordScriptAsync, service, account), - ); + return JSON.parse((await runScriptInApmNode(getPasswordScriptAsync, service, account))); } - return keytar.getPassword(service, account); + return (_keytar || _load_keytar()).getPassword(service, account); }, /** * Returns nothing. * Rejects on keychain access failure. */ - async replacePassword( - service: string, - account: string, - password: string, - ): Promise { + async replacePassword(service, account, password) { if (typeof atom === 'object' && (await shouldUseApmNode())) { - await runScriptInApmNode( - replacePasswordScriptAsync, - service, - account, - password, - ); + await runScriptInApmNode(replacePasswordScriptAsync, service, account, password); return; } - return keytar.setPassword(service, account, password); + return (_keytar || _load_keytar()).setPassword(service, account, password); }, /** * Returns true if a password was deleted, or false if it didn't exist. * Rejects on keychain access failure. */ - async deletePassword(service: string, account: string): Promise { + async deletePassword(service, account) { if (typeof atom === 'object' && (await shouldUseApmNode())) { - return JSON.parse( - await runScriptInApmNode(deletePasswordScriptAsync, service, account), - ); + return JSON.parse((await runScriptInApmNode(deletePasswordScriptAsync, service, account))); } - return keytar.deletePassword(service, account); - }, + return (_keytar || _load_keytar()).deletePassword(service, account); + } }; - -export const __TEST__ = { +const __TEST__ = exports.__TEST__ = { getApmNodeModulesPath, getApmNodePath, - runScriptInApmNode, -}; + runScriptInApmNode +}; \ No newline at end of file diff --git a/pkg/commons-node/memoizeWithDisk.js b/pkg/commons-node/memoizeWithDisk.js index 049855ffdc..222e26b03d 100644 --- a/pkg/commons-node/memoizeWithDisk.js +++ b/pkg/commons-node/memoizeWithDisk.js @@ -1,31 +1,47 @@ -/** - * 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 - */ +'use strict'; -import crypto from 'crypto'; -import fs from 'fs'; -import fsPlus from 'fs-plus'; -import os from 'os'; -import nuclideUri from 'nuclide-commons/nuclideUri'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = memoizeWithDisk; -const CACHE_DIR = 'nuclide-cache'; +var _crypto = _interopRequireDefault(require('crypto')); + +var _fs = _interopRequireDefault(require('fs')); + +var _fsPlus; + +function _load_fsPlus() { + return _fsPlus = _interopRequireDefault(require('fs-plus')); +} -function getCachePath(key: string, cacheDir?: string) { - const sha1 = crypto - .createHash('sha1') - .update(key) - .digest('hex'); +var _os = _interopRequireDefault(require('os')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../modules/nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const CACHE_DIR = 'nuclide-cache'; /** + * 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. + * + * + * @format + */ + +function getCachePath(key, cacheDir) { + const sha1 = _crypto.default.createHash('sha1').update(key).digest('hex'); if (cacheDir != null) { - return nuclideUri.join(cacheDir, sha1 + '.json'); + return (_nuclideUri || _load_nuclideUri()).default.join(cacheDir, sha1 + '.json'); } - return nuclideUri.join(os.tmpdir(), CACHE_DIR, sha1 + '.json'); + return (_nuclideUri || _load_nuclideUri()).default.join(_os.default.tmpdir(), CACHE_DIR, sha1 + '.json'); } /** @@ -40,29 +56,25 @@ function getCachePath(key: string, cacheDir?: string) { * Unlike lodash.memoize, this uses the result of JSON.stringify(args) if no * keySelector is provided. */ -export default function memoizeWithDisk, T>( - func: (...args: ArgsType) => T, - keySelector?: (...args: ArgsType) => mixed, - cacheDir?: string, -): (...args: ArgsType) => T { +function memoizeWithDisk(func, keySelector, cacheDir) { return (...args) => { const key = keySelector != null ? keySelector(...args) : args; // Include the function string as well to prevent collisions from multiple functions. const fullKey = JSON.stringify([func.toString(), key]); const cachePath = getCachePath(fullKey, cacheDir); try { - const cacheContents = fs.readFileSync(cachePath, 'utf8'); + const cacheContents = _fs.default.readFileSync(cachePath, 'utf8'); return JSON.parse(cacheContents); } catch (err) { // An error implies that the cached value does not exist. const result = func(...args); try { // fsPlus.writeFileSync creates the directory if necessary. - fsPlus.writeFileSync(cachePath, JSON.stringify(result), 'utf8'); + (_fsPlus || _load_fsPlus()).default.writeFileSync(cachePath, JSON.stringify(result), 'utf8'); } catch (_) { // Ignore errors here. } return result; } }; -} +} \ No newline at end of file diff --git a/pkg/commons-node/memoryLogger.js b/pkg/commons-node/memoryLogger.js index 2be5acb0fd..65493d9120 100644 --- a/pkg/commons-node/memoryLogger.js +++ b/pkg/commons-node/memoryLogger.js @@ -1,3 +1,21 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SnapshotLogger = exports.MemoryLogger = undefined; + +var _doubleEndedQueue; + +function _load_doubleEndedQueue() { + return _doubleEndedQueue = _interopRequireDefault(require('double-ended-queue')); +} + +var _util = _interopRequireDefault(require('util')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Retain past five minutes /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,63 +23,48 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import {default as Deque} from 'double-ended-queue'; -import util from 'util'; -import invariant from 'assert'; - -type LogEntry = {|time: number, level: string, text: string|}; - -// Retain past five minutes const DEFAULT_RETENTION_PERIOD_MS = 5 * 60 * 1000; // ...but only if it is less than 10 MB const DEFAULT_RETENTION_SIZE_LIMIT = 10 * 1000 * 1000; -export class MemoryLogger { - _underlyingLogger: ?log4js$Logger; - _logs: Deque = new Deque(); - _retentionPeriod: number; - _sizeLimit: number; - _size: number; - - constructor( - underlyingLogger: ?log4js$Logger, - retentionPeriod: number = DEFAULT_RETENTION_PERIOD_MS, - sizeLimit: number = DEFAULT_RETENTION_SIZE_LIMIT, - ) { +class MemoryLogger { + + constructor(underlyingLogger, retentionPeriod = DEFAULT_RETENTION_PERIOD_MS, sizeLimit = DEFAULT_RETENTION_SIZE_LIMIT) { + this._logs = new (_doubleEndedQueue || _load_doubleEndedQueue()).default(); + this._underlyingLogger = underlyingLogger; this._retentionPeriod = retentionPeriod; this._sizeLimit = sizeLimit; this._size = 0; } - dispose(): void { + dispose() { this._logs.isEmpty(); } - dump(count?: number): string { + dump(count) { let logs = this._logs.toArray(); if (count != null && count < this._logs.length) { - invariant(count > 0, 'Must provide a positive count'); + if (!(count > 0)) { + throw new Error('Must provide a positive count'); + } + logs = logs.slice(logs.length - count); } - return logs - .map( - entry => `${formatTime(entry.time)} ${entry.level} - ${entry.text}\n`, - ) - .join(''); + return logs.map(entry => `${formatTime(entry.time)} ${entry.level} - ${entry.text}\n`).join(''); } - getUnderlyingLogger(): ?log4js$Logger { + getUnderlyingLogger() { return this._underlyingLogger; } - debug(format: string, ...values: Array): void { - const message = util.format(format, ...values); + debug(format, ...values) { + const message = _util.default.format(format, ...values); const underlying = this._underlyingLogger; if (underlying != null) { underlying.debug(message.substring(0, 400)); @@ -69,8 +72,8 @@ export class MemoryLogger { this._appendAndExpunge('DEBUG', message); } - trace(format: string, ...values: Array): void { - const message = util.format(format, ...values); + trace(format, ...values) { + const message = _util.default.format(format, ...values); const underlying = this._underlyingLogger; if (underlying != null) { underlying.trace(message.substring(0, 400)); @@ -78,8 +81,8 @@ export class MemoryLogger { this._appendAndExpunge('TRACE', message); } - info(format: string, ...values: Array): void { - const message = util.format(format, ...values); + info(format, ...values) { + const message = _util.default.format(format, ...values); const underlying = this._underlyingLogger; if (underlying != null) { underlying.info(message.substring(0, 400)); @@ -87,8 +90,8 @@ export class MemoryLogger { this._appendAndExpunge('INFO', message); } - warn(format: string, ...values: Array): void { - const message = util.format(format, ...values); + warn(format, ...values) { + const message = _util.default.format(format, ...values); const underlying = this._underlyingLogger; if (underlying != null) { underlying.warn(message); @@ -96,8 +99,8 @@ export class MemoryLogger { this._appendAndExpunge('WARN', message); } - error(format: string, ...values: Array): void { - const message = util.format(format, ...values); + error(format, ...values) { + const message = _util.default.format(format, ...values); const underlying = this._underlyingLogger; if (underlying != null) { underlying.error(message); @@ -105,7 +108,7 @@ export class MemoryLogger { this._appendAndExpunge('ERROR', message); } - _appendAndExpunge(level: string, message: string): void { + _appendAndExpunge(level, message) { if (this._retentionPeriod === 0) { return; } @@ -113,7 +116,7 @@ export class MemoryLogger { // this._logs will keep the past five minute's worth of logs const time = Date.now(); // push the new entry - const newLog: LogEntry = {time, level, text: message}; + const newLog = { time, level, text: message }; this._logs.push(newLog); // the format is HH:MM:SS level - text (level + text + 12 chars) this._size += newLog.level.length + newLog.text.length + 12; @@ -123,10 +126,7 @@ export class MemoryLogger { if (front == null) { break; } - if ( - time <= front.time + this._retentionPeriod && - this._size <= this._sizeLimit - ) { + if (time <= front.time + this._retentionPeriod && this._size <= this._sizeLimit) { break; } this._logs.shift(); @@ -135,46 +135,36 @@ export class MemoryLogger { } } -export class SnapshotLogger { - _retentionPeriod: number; - _snapshotInterval: number; - _files: Map< - string, - Array<{|time: number, text: string, version: number|}>, - > = new Map(); - - constructor( - retentionPeriod: number = 5 * 60 * 1000, // retain past five minutes - snapshotInterval: number = 30 * 1000, // snapshot no more than every 30s - ) { +exports.MemoryLogger = MemoryLogger; +class SnapshotLogger { + + constructor(retentionPeriod = 5 * 60 * 1000, // retain past five minutes + snapshotInterval = 30 * 1000) // snapshot no more than every 30s + { + this._files = new Map(); + this._retentionPeriod = retentionPeriod; this._snapshotInterval = snapshotInterval; } - dispose(): void { + dispose() { this._files.clear(); } - dump(): Array<{|title: string, text: string|}> { + dump() { const results = []; for (const [filepath, snapshots] of this._files) { for (const snapshot of snapshots) { results.push({ - title: `${filepath} ${formatTime(snapshot.time)},v${ - snapshot.version - }`, - text: snapshot.text, + title: `${filepath} ${formatTime(snapshot.time)},v${snapshot.version}`, + text: snapshot.text }); } } return results; } - snapshot( - filepath: string, - version: number, - buffer: simpleTextBuffer$TextBuffer, - ): void { + snapshot(filepath, version, buffer) { if (this._retentionPeriod === 0) { return; } @@ -186,10 +176,7 @@ export class SnapshotLogger { let snapshots = this._files.get(filepath); if (snapshots != null && snapshots.length > 0) { const mostRecent = snapshots[snapshots.length - 1]; - if ( - mostRecent.time + this._snapshotInterval > time || - mostRecent.version === version - ) { + if (mostRecent.time + this._snapshotInterval > time || mostRecent.version === version) { return; } } @@ -198,25 +185,24 @@ export class SnapshotLogger { this._files.set(filepath, snapshots); } // Remove any old snapshots at the start of the array - const firstRemainingSnapshot = snapshots.findIndex( - snapshot => snapshot.time + this._retentionPeriod > time, - ); + const firstRemainingSnapshot = snapshots.findIndex(snapshot => snapshot.time + this._retentionPeriod > time); if (firstRemainingSnapshot > 0) { snapshots.splice(0, firstRemainingSnapshot); } // Add a new snashot at the end - snapshots.push({time, text: buffer.getText(), version}); + snapshots.push({ time, text: buffer.getText(), version }); } - close(filepath: string): void { + close(filepath) { this._files.delete(filepath); } } -/** - * Formats a UNIX timestamp in 24-hour US format. - * e.g. 16:01:19 - */ -function formatTime(time: number): string { - return new Date(time).toLocaleTimeString('en-US', {hour12: false}); -} +exports.SnapshotLogger = SnapshotLogger; /** + * Formats a UNIX timestamp in 24-hour US format. + * e.g. 16:01:19 + */ + +function formatTime(time) { + return new Date(time).toLocaleTimeString('en-US', { hour12: false }); +} \ No newline at end of file diff --git a/pkg/commons-node/node-info.js b/pkg/commons-node/node-info.js index cf1849f959..f2e9a9bca9 100644 --- a/pkg/commons-node/node-info.js +++ b/pkg/commons-node/node-info.js @@ -1,21 +1,23 @@ -/** - * 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 - */ +'use strict'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -export async function getNodeBinaryPath(path: NuclideUri): Promise { +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getNodeBinaryPath = getNodeBinaryPath; +async function getNodeBinaryPath(path) { try { // $FlowFB return require('./fb-node-info').getNodeBinaryPath(path); } catch (error) { return 'node'; } -} +} /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/commons-node/once.js b/pkg/commons-node/once.js index d8b1133911..de8b144771 100644 --- a/pkg/commons-node/once.js +++ b/pkg/commons-node/once.js @@ -1,3 +1,9 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = once; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,27 +11,22 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -export default function once< - T, - TArgs: Array, - TReturn, - TFunc: (...TArgs) => TReturn, // eslint-disable-line space-before-function-paren ->(fn: TFunc): (...TArgs) => TReturn { - let fnMaybe: ?TFunc = fn; - let ret: ?TReturn; - return function(...args: TArgs): TReturn { +function once(fn) { + let fnMaybe = fn; + let ret; + return function (...args) { // The type gymnastics here are so `fn` can be // garbage collected once we've used it. if (!fnMaybe) { - return (ret: any); + return ret; } else { ret = fnMaybe.apply(this, args); fnMaybe = null; return ret; } }; -} +} \ No newline at end of file diff --git a/pkg/commons-node/passesGK.js b/pkg/commons-node/passesGK.js index 525cd0f414..12a31b8fe7 100644 --- a/pkg/commons-node/passesGK.js +++ b/pkg/commons-node/passesGK.js @@ -1,3 +1,31 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.isGkEnabled = isGkEnabled; +exports.onceGkInitialized = onceGkInitialized; +exports.onceGkInitializedAsync = onceGkInitializedAsync; +exports.getCacheEntries = getCacheEntries; + +var _once; + +function _load_once() { + return _once = _interopRequireDefault(require('./once')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../modules/nuclide-commons/UniversalDisposable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Get the actual Gatekeeper constructor or stub the relevant methods for OSS + * friendliness. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,45 +33,38 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import once from './once'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -/** - * Get the actual Gatekeeper constructor or stub the relevant methods for OSS - * friendliness. - */ -const getGatekeeper = once(() => { +const getGatekeeper = (0, (_once || _load_once()).default)(() => { let Gatekeeper; try { // $FlowFB Gatekeeper = require('./fb-gatekeeper').Gatekeeper; } catch (e) { Gatekeeper = class { - isGkEnabled(name: string): ?boolean { + isGkEnabled(name) { return null; } - asyncIsGkEnabled(name: string, timeout?: number): Promise { + asyncIsGkEnabled(name, timeout) { return Promise.resolve(); } - onceGkInitialized(callback: () => mixed): IDisposable { + onceGkInitialized(callback) { let canceled = false; process.nextTick(() => { if (!canceled) { callback(); } }); - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { canceled = true; }); } - getCacheEntries(): Iterable<[string, boolean]> { + getCacheEntries() { return []; } }; @@ -54,36 +75,37 @@ const getGatekeeper = once(() => { /** * Check a GK. Silently return false on error. */ -export default (async function passesGK( - name: string, - // timeout in ms - timeout?: number, -): Promise { + +exports.default = async function passesGK(name, +// timeout in ms +timeout) { try { return (await getGatekeeper().asyncIsGkEnabled(name, timeout)) === true; } catch (e) { return false; } -}); +}; /** * Synchronous GK check. There is no guarantee that GKs have loaded. This * should be used inside a `onceGkInitialized`. */ -export function isGkEnabled(name: string): ?boolean { + + +function isGkEnabled(name) { return getGatekeeper().isGkEnabled(name); } -export function onceGkInitialized(callback: () => mixed): IDisposable { +function onceGkInitialized(callback) { return getGatekeeper().onceGkInitialized(callback); } -export function onceGkInitializedAsync(): Promise { +function onceGkInitializedAsync() { return new Promise(resolve => { getGatekeeper().onceGkInitialized(() => resolve()); }); } -export function getCacheEntries(): Iterable<[string, boolean]> { +function getCacheEntries() { return getGatekeeper().getCacheEntries(); -} +} \ No newline at end of file diff --git a/pkg/commons-node/promise-executors.js b/pkg/commons-node/promise-executors.js index 570efc630f..3d46322027 100644 --- a/pkg/commons-node/promise-executors.js +++ b/pkg/commons-node/promise-executors.js @@ -1,18 +1,19 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PromiseQueue = exports.PromisePool = undefined; -import {default as Deque} from 'double-ended-queue'; -import EventEmitter from 'events'; +var _doubleEndedQueue; + +function _load_doubleEndedQueue() { + return _doubleEndedQueue = _interopRequireDefault(require('double-ended-queue')); +} -type Executor = () => Promise; +var _events = _interopRequireDefault(require('events')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A pool that executes Promise executors in parallel given the poolSize, in order. @@ -22,16 +23,22 @@ type Executor = () => Promise; * a sequence of async operations that need to be run in parallel and you also want * control the number of concurrent executions. */ -export class PromisePool { - _fifo: Deque<{id: string, executor: Executor}>; - _emitter: EventEmitter; - _numPromisesRunning: number; - _poolSize: number; - _nextRequestId: number; - - constructor(poolSize: number) { - this._fifo = new Deque(); - this._emitter = new EventEmitter(); +/** + * 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. + * + * + * @format + */ + +class PromisePool { + + constructor(poolSize) { + this._fifo = new (_doubleEndedQueue || _load_doubleEndedQueue()).default(); + this._emitter = new _events.default(); this._numPromisesRunning = 0; this._poolSize = poolSize; this._nextRequestId = 1; @@ -43,12 +50,12 @@ export class PromisePool { * @return A Promise that will be resolved/rejected in response to the * execution of the executor. */ - submit(executor: Executor): Promise { + submit(executor) { const id = this._getNextRequestId(); - this._fifo.push({id, executor}); + this._fifo.push({ id, executor }); const promise = new Promise((resolve, reject) => { this._emitter.once(id, result => { - const {isSuccess, value} = result; + const { isSuccess, value } = result; (isSuccess ? resolve : reject)(value); }); }); @@ -66,37 +73,34 @@ export class PromisePool { return; } - const {id, executor} = first; + const { id, executor } = first; this._numPromisesRunning++; - executor().then( - result => { - this._emitter.emit(id, {isSuccess: true, value: result}); - this._numPromisesRunning--; - this._run(); - }, - error => { - this._emitter.emit(id, {isSuccess: false, value: error}); - this._numPromisesRunning--; - this._run(); - }, - ); + executor().then(result => { + this._emitter.emit(id, { isSuccess: true, value: result }); + this._numPromisesRunning--; + this._run(); + }, error => { + this._emitter.emit(id, { isSuccess: false, value: error }); + this._numPromisesRunning--; + this._run(); + }); } - _getNextRequestId(): string { + _getNextRequestId() { return (this._nextRequestId++).toString(16); } } -/** - * FIFO queue that executes Promise executors one at a time, in order. - * - * The executor function passed to the constructor of a Promise is evaluated - * immediately. This may not always be desirable. Use a PromiseQueue if you have - * a sequence of async operations that need to use a shared resource serially. - */ -export class PromiseQueue { - _promisePool: PromisePool; +exports.PromisePool = PromisePool; /** + * FIFO queue that executes Promise executors one at a time, in order. + * + * The executor function passed to the constructor of a Promise is evaluated + * immediately. This may not always be desirable. Use a PromiseQueue if you have + * a sequence of async operations that need to use a shared resource serially. + */ + +class PromiseQueue { constructor() { this._promisePool = new PromisePool(1); @@ -108,7 +112,8 @@ export class PromiseQueue { * @return A Promise that will be resolved/rejected in response to the * execution of the executor. */ - submit(executor: Executor): Promise { + submit(executor) { return this._promisePool.submit(executor); } } +exports.PromiseQueue = PromiseQueue; \ No newline at end of file diff --git a/pkg/commons-node/rectContainsPoint.js b/pkg/commons-node/rectContainsPoint.js index 9c6b4f0f58..59106fbb7e 100644 --- a/pkg/commons-node/rectContainsPoint.js +++ b/pkg/commons-node/rectContainsPoint.js @@ -1,3 +1,9 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = rectContainsPoint; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,27 +11,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -type Rect = { - left: number, - right: number, - top: number, - bottom: number, -}; - -type Point = { - x: number, - y: number, -}; - -export default function rectContainsPoint(rect: Rect, point: Point): boolean { - return ( - point.x >= rect.left && - point.y >= rect.top && - point.x <= rect.right && - point.y <= rect.bottom - ); -} +function rectContainsPoint(rect, point) { + return point.x >= rect.left && point.y >= rect.top && point.x <= rect.right && point.y <= rect.bottom; +} \ No newline at end of file diff --git a/pkg/commons-node/runtime-info.js b/pkg/commons-node/runtime-info.js index cee1f0d274..0c7ae6f569 100644 --- a/pkg/commons-node/runtime-info.js +++ b/pkg/commons-node/runtime-info.js @@ -1,3 +1,33 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.__DEV__ = undefined; +exports.getRuntimeInformation = getRuntimeInformation; + +var _systemInfo; + +function _load_systemInfo() { + return _systemInfo = require('./system-info'); +} + +var _os = _interopRequireDefault(require('os')); + +var _uuid; + +function _load_uuid() { + return _uuid = _interopRequireDefault(require('uuid')); +} + +var _env; + +function _load_env() { + return _env = require('../../modules/nuclide-node-transpiler/lib/env'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,67 +35,42 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import { - getOsType, - getAtomVersion, - getNuclideVersion, - isRunningInServer, -} from './system-info'; -import os from 'os'; -import uuid from 'uuid'; -import {__DEV__} from 'nuclide-node-transpiler/lib/env'; - -export type RuntimeInformation = { - sessionId: string, - user: string, - osType: string, - timestamp: number, - isClient: boolean, - isDevelopment: boolean, - atomVersion: string, - nuclideVersion: string, - installerPackageVersion: number, - serverVersion: number, - uptime: number, -}; - let cachedInformation = null; -function getCacheableRuntimeInformation(): RuntimeInformation { +function getCacheableRuntimeInformation() { // eslint-disable-next-line eqeqeq if (cachedInformation !== null) { return cachedInformation; } cachedInformation = { - sessionId: uuid.v4(), - user: os.userInfo().username, - osType: getOsType(), + sessionId: (_uuid || _load_uuid()).default.v4(), + user: _os.default.userInfo().username, + osType: (0, (_systemInfo || _load_systemInfo()).getOsType)(), timestamp: 0, - isClient: !isRunningInServer(), - isDevelopment: __DEV__, - atomVersion: typeof atom === 'object' ? getAtomVersion() : '', - nuclideVersion: getNuclideVersion(), + isClient: !(0, (_systemInfo || _load_systemInfo()).isRunningInServer)(), + isDevelopment: (_env || _load_env()).__DEV__, + atomVersion: typeof atom === 'object' ? (0, (_systemInfo || _load_systemInfo()).getAtomVersion)() : '', + nuclideVersion: (0, (_systemInfo || _load_systemInfo()).getNuclideVersion)(), installerPackageVersion: 0, uptime: 0, // TODO (chenshen) fill following information. - serverVersion: 0, + serverVersion: 0 }; return cachedInformation; } -export function getRuntimeInformation(): RuntimeInformation { - const runtimeInformation = { - ...getCacheableRuntimeInformation(), +function getRuntimeInformation() { + const runtimeInformation = Object.assign({}, getCacheableRuntimeInformation(), { timestamp: Date.now(), - uptime: Math.floor(process.uptime() * 1000), - }; + uptime: Math.floor(process.uptime() * 1000) + }); return runtimeInformation; } -export {__DEV__}; +exports.__DEV__ = (_env || _load_env()).__DEV__; \ No newline at end of file diff --git a/pkg/commons-node/scheduleIdleCallback.js b/pkg/commons-node/scheduleIdleCallback.js index 827df753ae..5d458f9f8b 100644 --- a/pkg/commons-node/scheduleIdleCallback.js +++ b/pkg/commons-node/scheduleIdleCallback.js @@ -1,13 +1,58 @@ -/** - * 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 strict - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = typeof requestIdleCallback !== 'undefined' ? // Using Browser API +// Is guaranteed to resolve after `timeout` milliseconds. +function scheduleIdleCallback(callback_, options = {}) { + const afterRemainingTime = options.afterRemainingTime || 49; + // flowlint-next-line sketchy-null-number:off + const timeout = options.timeout || 500; + let callback = callback_; + let id; + const startTime = Date.now(); + function fn(deadline) { + if (deadline.timeRemaining() >= afterRemainingTime || Date.now() - startTime >= timeout) { + if (!(callback != null)) { + throw new Error('Invariant violation: "callback != null"'); + } + + callback(); + id = callback = null; + } else { + id = requestIdleCallback(fn, { + timeout: timeout - (Date.now() - startTime) + }); + } + } + id = requestIdleCallback(fn, { timeout }); + return { + dispose() { + if (id != null) { + cancelIdleCallback(id); + id = callback = null; + } + } + }; +} : // Using Node API +function scheduleIdleCallback(callback, options) { + const id = setImmediate(callback); + return { + dispose() { + clearImmediate(id); + } + }; +}; /** + * 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. + * + * strict + * @format + */ /* global requestIdleCallback, cancelIdleCallback */ @@ -21,62 +66,4 @@ * `afterRemainingTime`, you're saying: "only invoke the callback when there * are 49ms available for me to do work". It was can take multiple loops around * `requestIdleCallback` for so much time to become available. - */ - -import invariant from 'assert'; - -type CallbackT = () => void; -type OptionsT = { - afterRemainingTime?: 30 | 40 | 49, - timeout?: number, -}; - -export default (typeof requestIdleCallback !== 'undefined' - ? // Using Browser API - // Is guaranteed to resolve after `timeout` milliseconds. - function scheduleIdleCallback( - callback_: CallbackT, - options?: OptionsT = {}, - ): IDisposable { - const afterRemainingTime = options.afterRemainingTime || 49; - // flowlint-next-line sketchy-null-number:off - const timeout = options.timeout || 500; - let callback = callback_; - let id; - const startTime = Date.now(); - function fn(deadline) { - if ( - deadline.timeRemaining() >= afterRemainingTime || - Date.now() - startTime >= timeout - ) { - invariant(callback != null); - callback(); - id = callback = null; - } else { - id = requestIdleCallback(fn, { - timeout: timeout - (Date.now() - startTime), - }); - } - } - id = requestIdleCallback(fn, {timeout}); - return { - dispose() { - if (id != null) { - cancelIdleCallback(id); - id = callback = null; - } - }, - }; - } - : // Using Node API - function scheduleIdleCallback( - callback: CallbackT, - options?: OptionsT, - ): IDisposable { - const id = setImmediate(callback); - return { - dispose() { - clearImmediate(id); - }, - }; - }); + */ \ No newline at end of file diff --git a/pkg/commons-node/singleton.js b/pkg/commons-node/singleton.js index efd764e16e..601bd1d56f 100644 --- a/pkg/commons-node/singleton.js +++ b/pkg/commons-node/singleton.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,13 +10,13 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ const GLOBAL_MAP_NAME = '__NUCLIDE_SINGLETONS__'; -function getMap(): Map { +function getMap() { let map = global[GLOBAL_MAP_NAME]; if (!map) { map = global[GLOBAL_MAP_NAME] = new Map(); @@ -24,7 +29,7 @@ function getMap(): Map { * constructor will be called exactly once, future invocations will * return the result of the constructor call. */ -function get(field: string, constructor: () => T): T { +function get(field, constructor) { const map = getMap(); if (!map.has(field)) { map.set(field, constructor()); @@ -33,20 +38,20 @@ function get(field: string, constructor: () => T): T { // because we have just checked it above. However, we cannot just call `get` and then check it // against null because T may be a nullable type, in which case this would break subtly. So, we // circumvent the type system here to maintain the desired runtime behavior. - return (map.get(field): any); + return map.get(field); } -function clear(field: string): void { +function clear(field) { getMap().delete(field); } -function reset(field: string, constructor: () => T): T { +function reset(field, constructor) { clear(field); return get(field, constructor); } -export default { +exports.default = { get, clear, - reset, -}; + reset +}; \ No newline at end of file diff --git a/pkg/commons-node/spec/DiskCache-spec.js b/pkg/commons-node/spec/DiskCache-spec.js deleted file mode 100644 index e6eddf7047..0000000000 --- a/pkg/commons-node/spec/DiskCache-spec.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 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 - */ - -import temp from 'temp'; -import DiskCache from '../DiskCache'; - -temp.track(); - -describe('DiskCache', () => { - let tempFile; - beforeEach(() => { - tempFile = temp.openSync(); - }); - - it('is able to save and load values from disk', () => { - waitsForPromise(async () => { - const cache: DiskCache = new DiskCache( - tempFile.path, - key => `k${key}`, - ); - expect(await cache.load()).toBe(false); - expect(cache.getPath()).toBe(tempFile.path); - expect(cache.getByteSize()).toBe(0); - expect(cache.get(1)).toBe(undefined); - cache.set(1, 2); - cache.set(3, 4); - expect(cache.get(1)).toBe(2); - expect(cache.get(3)).toBe(4); - expect(await cache.save()).toBe(true); - expect(cache.getByteSize()).toBe(15); - - const restore = new DiskCache(tempFile.path, key => `k${key}`); - expect(await restore.load()).toBe(true); - expect(restore.getByteSize()).toBe(15); - expect(restore.get(1)).toBe(2); - expect(restore.get(3)).toBe(4); - }); - }); - - it('does not leak Object methods', () => { - waitsForPromise(async () => { - const cache = new DiskCache(tempFile.path, x => x); - expect(cache.get('hasOwnProperty')).toBe(undefined); - expect(await cache.save()).toBe(true); - expect(await cache.load()).toBe(true); - expect(cache.get('hasOwnProperty')).toBe(undefined); - }); - }); -}); diff --git a/pkg/commons-node/spec/Dispatcher-spec.js b/pkg/commons-node/spec/Dispatcher-spec.js deleted file mode 100644 index 5e0c3a52a5..0000000000 --- a/pkg/commons-node/spec/Dispatcher-spec.js +++ /dev/null @@ -1,215 +0,0 @@ -/** - * 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 strict - * @format - */ - -/** - * Originally from https://github.com/facebook/flux/blob/55480fb/src/Dispatcher.js - */ - -import Dispatcher from '../Dispatcher'; - -describe('Dispatcher', () => { - let dispatcher; - let callbackA; - let callbackB; - - beforeEach(() => { - dispatcher = new Dispatcher(); - callbackA = jasmine.createSpy('callbackA'); - callbackB = jasmine.createSpy('callbackB'); - }); - - it('should execute all subscriber callbacks', () => { - dispatcher.register(callbackA); - dispatcher.register(callbackB); - - const payload = {}; - dispatcher.dispatch(payload); - - expect(callbackA.calls.length).toBe(1); - expect(callbackA.calls[0].args[0]).toBe(payload); - - expect(callbackB.calls.length).toBe(1); - expect(callbackB.calls[0].args[0]).toBe(payload); - - dispatcher.dispatch(payload); - - expect(callbackA.calls.length).toBe(2); - expect(callbackA.calls[1].args[0]).toBe(payload); - - expect(callbackB.calls.length).toBe(2); - expect(callbackB.calls[1].args[0]).toBe(payload); - }); - - it('should wait for callbacks registered earlier', () => { - const tokenA = dispatcher.register(callbackA); - - dispatcher.register(payload => { - dispatcher.waitFor([tokenA]); - expect(callbackA.calls.length).toBe(1); - expect(callbackA.calls[0].args[0]).toBe(payload); - callbackB(payload); - }); - - const payload = {}; - dispatcher.dispatch(payload); - - expect(callbackA.calls.length).toBe(1); - expect(callbackA.calls[0].args[0]).toBe(payload); - - expect(callbackB.calls.length).toBe(1); - expect(callbackB.calls[0].args[0]).toBe(payload); - }); - - it('should wait for callbacks registered later', () => { - dispatcher.register(payload => { - dispatcher.waitFor([tokenB]); - expect(callbackB.calls.length).toBe(1); - expect(callbackB.calls[0].args[0]).toBe(payload); - callbackA(payload); - }); - - const tokenB = dispatcher.register(callbackB); - - const payload = {}; - dispatcher.dispatch(payload); - - expect(callbackA.calls.length).toBe(1); - expect(callbackA.calls[0].args[0]).toBe(payload); - - expect(callbackB.calls.length).toBe(1); - expect(callbackB.calls[0].args[0]).toBe(payload); - }); - - it('should throw if dispatch() while dispatching', () => { - dispatcher.register(payload => { - dispatcher.dispatch(payload); - callbackA(); - }); - - const payload = {}; - expect(() => dispatcher.dispatch(payload)).toThrow(); - expect(callbackA.calls.length).toBe(0); - }); - - it('should throw if waitFor() while not dispatching', () => { - const tokenA = dispatcher.register(callbackA); - - expect(() => dispatcher.waitFor([tokenA])).toThrow(); - expect(callbackA.calls.length).toBe(0); - }); - - it('should throw if waitFor() with invalid token', () => { - const invalidToken = 1337; - - dispatcher.register(() => { - // $FlowIgnore: Purposefully invalid token. - dispatcher.waitFor([invalidToken]); - }); - - const payload = {}; - expect(() => dispatcher.dispatch(payload)).toThrow(); - }); - - it('should throw on self-circular dependencies', () => { - const tokenA = dispatcher.register(payload => { - dispatcher.waitFor([tokenA]); - callbackA(payload); - }); - - const payload = {}; - expect(() => dispatcher.dispatch(payload)).toThrow(); - expect(callbackA.calls.length).toBe(0); - }); - - it('should throw on multi-circular dependencies', () => { - const tokenA = dispatcher.register(payload => { - dispatcher.waitFor([tokenB]); - callbackA(payload); - }); - - const tokenB = dispatcher.register(payload => { - dispatcher.waitFor([tokenA]); - callbackB(payload); - }); - - expect(() => dispatcher.dispatch({})).toThrow(); - expect(callbackA.calls.length).toBe(0); - expect(callbackB.calls.length).toBe(0); - }); - - it('should remain in a consistent state after a failed dispatch', () => { - dispatcher.register(callbackA); - dispatcher.register(payload => { - if (payload.shouldThrow) { - throw new Error(); - } - callbackB(); - }); - - expect(() => dispatcher.dispatch({shouldThrow: true})).toThrow(); - - // Cannot make assumptions about a failed dispatch. - const callbackACount = callbackA.calls.length; - - dispatcher.dispatch({shouldThrow: false}); - - expect(callbackA.calls.length).toBe(callbackACount + 1); - expect(callbackB.calls.length).toBe(1); - }); - - it('should properly unregister callbacks', () => { - dispatcher.register(callbackA); - - const tokenB = dispatcher.register(callbackB); - - const payload = {}; - dispatcher.dispatch(payload); - - expect(callbackA.calls.length).toBe(1); - expect(callbackA.calls[0].args[0]).toBe(payload); - - expect(callbackB.calls.length).toBe(1); - expect(callbackB.calls[0].args[0]).toBe(payload); - - dispatcher.unregister(tokenB); - - dispatcher.dispatch(payload); - - expect(callbackA.calls.length).toBe(2); - expect(callbackA.calls[1].args[0]).toBe(payload); - - expect(callbackB.calls.length).toBe(1); - }); - - it('should throw if register() while dispatching', () => { - dispatcher.register(payload => { - dispatcher.register(callbackB); - callbackA(); - }); - - const payload = {}; - expect(() => dispatcher.dispatch(payload)).toThrow(); - expect(callbackA.calls.length).toBe(0); - }); - - it('should throw if unregister() while dispatching', () => { - const tokenA = dispatcher.register(callbackA); - dispatcher.register(payload => { - dispatcher.unregister(tokenA); - callbackB(); - }); - - const payload = {}; - expect(() => dispatcher.dispatch(payload)).toThrow(); - expect(callbackA.calls.length).toBe(1); - expect(callbackB.calls.length).toBe(0); - }); -}); diff --git a/pkg/commons-node/spec/ScribeProcess-spec.js b/pkg/commons-node/spec/ScribeProcess-spec.js deleted file mode 100644 index 94829ba602..0000000000 --- a/pkg/commons-node/spec/ScribeProcess-spec.js +++ /dev/null @@ -1,137 +0,0 @@ -/** - * 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 - */ - -import fs from 'fs'; -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import ScribeProcess, {__test__} from '../ScribeProcess'; - -describe('scribe_cat test suites', () => { - let tempDir = ''; - let originalCommand = ''; - - function getContentOfScribeCategory(category: string): Array { - try { - const categoryFilePath = nuclideUri.join(tempDir, category); - const content = fs.readFileSync(categoryFilePath, 'utf8'); - const result = content.split('\n').filter(item => item.length > 0); - return result; - } catch (err) { - return []; - } - } - - beforeEach(() => { - jasmine.useRealClock(); - // Simulated scribe_cat script which saves data into: - // ${process.env['SCRIBE_MOCK_PATH'] + category_name} - // It terminates once we cut off the stdin stream. - const scribeCatMockCommandPath = nuclideUri.join( - nuclideUri.dirname(__filename), - 'scripts', - 'scribe_cat_mock', - ); - waitsForPromise(async () => { - tempDir = await fsPromise.tempdir(); - originalCommand = __test__.setScribeCatCommand(scribeCatMockCommandPath); - process.env.SCRIBE_MOCK_PATH = tempDir; - }); - }); - - afterEach(() => { - waitsForPromise(async () => { - __test__.setScribeCatCommand(originalCommand); - }); - }); - - it('Saves data to scribe category', () => { - const localScribeProcess = new ScribeProcess('test'); - - const messages = [ - 'A', - 'nuclide', - 'is', - 'an', - 'atomic', - 'species', - 'characterized', - 'by', - 'the', - 'specific', - 'constitution', - 'of', - 'its', - 'nucleus.', - ]; - waitsForPromise(async () => { - messages.map(message => localScribeProcess.write(message)); - // Wait for `scribe_cat_mock` to flush data into disk. - await localScribeProcess.join(); - expect(messages).toEqual(getContentOfScribeCategory('test')); - }); - }); - - it('Saves data to scribe category and resume from error', () => { - const localScribeProcess = new ScribeProcess('test'); - - const firstPart = 'A nuclide is an atomic species'.split(' '); - const secondPart = 'characterized by the specific constitution of its nucleus.'.split( - ' ', - ); - - waitsForPromise(async () => { - firstPart.map(message => localScribeProcess.write(message)); - // Kill the existing process. - await localScribeProcess.join(); - secondPart.map(message => localScribeProcess.write(message)); - // Wait for `scribe_cat_mock` to flush data into disk. - await localScribeProcess.join(); - expect(firstPart.concat(secondPart)).toEqual( - getContentOfScribeCategory('test'), - ); - }); - }); - - it('Can automatically join', () => { - const localScribeProcess = new ScribeProcess('test', 100); - runs(() => { - localScribeProcess.write('test1'); - }); - - waitsFor(() => getContentOfScribeCategory('test').includes('test1')); - - runs(() => { - localScribeProcess.write('test2'); - localScribeProcess.write('test3'); - expect(getContentOfScribeCategory('test')).toEqual(['test1']); - }); - - waitsFor(() => getContentOfScribeCategory('test').includes('test3')); - - runs(() => { - expect(getContentOfScribeCategory('test')).toEqual([ - 'test1', - 'test2', - 'test3', - ]); - }); - }); - - it('disables itself when spawning fails', () => { - waitsForPromise(async () => { - __test__.setScribeCatCommand('not a valid command'); - const scribeProcess = new ScribeProcess('test', 100); - expect(await scribeProcess.write('hi')).toBe(false); - expect(ScribeProcess.isEnabled()).toBe(false); - expect(await scribeProcess.write('hi')).toBe(false); - }); - }); -}); diff --git a/pkg/commons-node/spec/SharedObservableCache-spec.js b/pkg/commons-node/spec/SharedObservableCache-spec.js deleted file mode 100644 index 12480d8889..0000000000 --- a/pkg/commons-node/spec/SharedObservableCache-spec.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * 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 strict - * @format - */ - -import {Subject} from 'rxjs'; -import SharedObservableCache from '../SharedObservableCache'; - -describe('SharedObservableCache', () => { - it('creates and deletes observables on demand', () => { - const mockObservable = new Subject(); - const mockFactory = jasmine.createSpy('factory').andReturn(mockObservable); - - const map = new SharedObservableCache(mockFactory); - const stream1 = map.get('key'); - const stream2 = map.get('key'); - - // The factory doesn't get called until the first subscription. - expect(mockFactory).not.toHaveBeenCalled(); - - const spy1 = jasmine.createSpy('spy1'); - const spy2 = jasmine.createSpy('spy2'); - - // The first subscription triggers observable creation. - const sub1 = stream1.subscribe(spy1); - expect(mockFactory.callCount).toBe(1); - - // The second subscription shouldn't. - const sub2 = stream2.subscribe(spy2); - expect(mockFactory.callCount).toBe(1); - - mockObservable.next('test'); - expect(spy1).toHaveBeenCalledWith('test'); - expect(spy2).toHaveBeenCalledWith('test'); - - sub1.unsubscribe(); - sub2.unsubscribe(); - - // Cache should be clear now. - expect(map._cache.size).toBe(0); - - const sub3 = stream1.subscribe(() => {}); - expect(mockFactory.callCount).toBe(2); - sub3.unsubscribe(); - }); -}); diff --git a/pkg/commons-node/spec/compareVersions-spec.js b/pkg/commons-node/spec/compareVersions-spec.js deleted file mode 100644 index 61a178c85b..0000000000 --- a/pkg/commons-node/spec/compareVersions-spec.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * 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 strict - * @format - */ - -import compareVersions from '../compareVersions'; - -describe('compareVersions', () => { - it('compares two versions', () => { - expect(compareVersions('9.2', '10.0')).toBe(-1); - }); - - it('compares versions with an unequal number of parts', () => { - expect(compareVersions('9', '8.9')).toBe(1); - expect(compareVersions('9', '9.1')).toBe(-1); - expect(compareVersions('9', '9.0')).toBe(0); - }); - - it('compares numbers using version numbers and not decimal values', () => { - expect(compareVersions('9.2', '9.10')).toBe(-1); - }); -}); diff --git a/pkg/commons-node/spec/diff-utils-spec.js b/pkg/commons-node/spec/diff-utils-spec.js deleted file mode 100644 index 9e711bf73b..0000000000 --- a/pkg/commons-node/spec/diff-utils-spec.js +++ /dev/null @@ -1,114 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import {computeDiff} from '../computeDiff'; - -describe('diff-utils', () => { - describe('computeDiff()', () => { - it('diffs two empty texts', () => { - const { - addedLines, - removedLines, - oldLineOffsets, - newLineOffsets, - newToOld, - oldToNew, - } = computeDiff('', ''); - expect(addedLines).toEqual([]); - expect(removedLines).toEqual([]); - expect(oldLineOffsets.length).toBe(0); - expect(newLineOffsets.length).toBe(0); - expect(newToOld).toEqual([0, 1, 2]); - expect(oldToNew).toEqual([0, 1, 2]); - }); - - it('diffs simple text with one line changes', () => { - const { - addedLines, - removedLines, - oldLineOffsets, - newLineOffsets, - newToOld, - oldToNew, - } = computeDiff( - `simple text -on multiline -same end line`, - `on multiline -added text -same end line`, - ); - - expect(addedLines).toEqual([1]); // the second line is newly added. - expect(removedLines).toEqual([0]); // the first line was removed. - expect(oldLineOffsets).toEqual([[2, 1]]); // offset 1 for the new added line. - expect(newLineOffsets).toEqual([[0, 1]]); // offset 1 for the first removed line. - expect(newToOld).toEqual([1, 2, 2, 3, 4]); - expect(oldToNew).toEqual([0, 0, 2, 3, 4]); - }); - - it('diffs multi-line text changes', () => { - const { - addedLines, - removedLines, - oldLineOffsets, - newLineOffsets, - newToOld, - oldToNew, - } = computeDiff( - `This text is intended for testing. -If we test at too low a level, -testing for matching tags -with pattern matching, -our tests will be BAD. -The slightest change in layout, -could break a large number of tests. -`, - `This text is intended for testing. -with pattern matching, -adding different two lines -replacing the two lines removed above! -our tests will be BAD. -The slightest change in layout, -could break a large number of tests. -adding a non-new-line line`, - ); - - expect(addedLines).toEqual([2, 3, 7]); // 2 lines were added in the middle and one at the end. - // 2 lines were removed in the middle and last new-line replaced. - expect(removedLines).toEqual([1, 2, 7]); - expect(oldLineOffsets).toEqual([[4, 2]]); // offset 2 for the 2 lines added. - expect(newLineOffsets).toEqual([[1, 2]]); // offset 2 for the 2 lines removed. - expect(newToOld).toEqual([0, 3, 4, 4, 4, 5, 6, 7, 8]); - expect(oldToNew).toEqual([0, 1, 1, 1, 4, 5, 6, 7, 8]); - }); - - it('diffs new text longer than the other', () => { - const { - addedLines, - removedLines, - oldLineOffsets, - newLineOffsets, - newToOld, - oldToNew, - } = computeDiff( - 'first line text\n', - 'first line text\nsecond line text\n', - ); - expect(addedLines).toEqual([1]); - expect(removedLines).toEqual([]); - expect(oldLineOffsets).toEqual([[1, 1]]); // offset for the last added line. - expect(newLineOffsets.length).toBe(0); - expect(newToOld).toEqual([0, 1, 1, 2]); - expect(oldToNew).toEqual([0, 2, 3]); - }); - }); -}); diff --git a/pkg/commons-node/spec/humanizeEventName-spec.js b/pkg/commons-node/spec/humanizeEventName-spec.js deleted file mode 100644 index 14acffe769..0000000000 --- a/pkg/commons-node/spec/humanizeEventName-spec.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - * 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 strict - * @format - */ - -import humanizeEventName from '../humanizeEventName'; - -describe('humanizeEventName(eventName)', () => { - describe('when no namespace exists', () => { - it('undasherizes and capitalizes the event name', () => { - expect(humanizeEventName('nonamespace')).toBe('Nonamespace'); - expect(humanizeEventName('no-name-space')).toBe('No Name Space'); - }); - }); - - describe('when a namespace exists', () => { - it('space separates the undasherized/capitalized versions of the namespace and event name', () => { - expect(humanizeEventName('space:final-frontier')).toBe( - 'Space: Final Frontier', - ); - expect(humanizeEventName('star-trek:the-next-generation')).toBe( - 'Star Trek: The Next Generation', - ); - }); - }); -}); diff --git a/pkg/commons-node/spec/immutable-snapshot-compat-spec.js b/pkg/commons-node/spec/immutable-snapshot-compat-spec.js deleted file mode 100644 index 4523e8818e..0000000000 --- a/pkg/commons-node/spec/immutable-snapshot-compat-spec.js +++ /dev/null @@ -1,1382 +0,0 @@ -/** - * 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-console */ - -import {List, ImmutableSnapshotter, Map, Record} from '../immutable-snapshot'; -import Immutable from 'immutable'; -import performanceNow from 'nuclide-commons/performanceNow'; - -const ITER = 1000; - -describe('Benchmark', () => { - it('checks List performance', () => { - const LIST_SIZE = 1000; - console.log(`Benchmark: List.push * ${LIST_SIZE} * ${ITER}`); - - let startTime = performanceNow(); - for (let i = 0; i < ITER; i++) { - let list = Immutable.List(); - for (let j = 0; j < LIST_SIZE; j++) { - list = list.push(j); - } - } - console.log('Immutable.List:', performanceNow() - startTime); - - startTime = performanceNow(); - for (let i = 0; i < ITER; i++) { - let list = List(); - for (let j = 0; j < LIST_SIZE; j++) { - list = list.push(j); - } - } - console.log('ImmutableSnapshot.List:', performanceNow() - startTime); - - // Snapshot testList so mutations start becoming tracked. - const testList = List([0]); - const snapshotter = new ImmutableSnapshotter(); - snapshotter.createDeltaSnapshot(testList); - - startTime = performanceNow(); - for (let i = 0; i < ITER; i++) { - let list = testList; - for (let j = 0; j < LIST_SIZE; j++) { - list = list.push(j); - } - } - console.log( - 'ImmutableSnapshot.List (with deltas):', - performanceNow() - startTime, - ); - }); -}); - -// The tests below are adapted from: -// https://github.com/facebook/immutable-js/blob/master/__tests__/List.ts - -function arrayOfSize(s) { - const a = new Array(s); - for (let ii = 0; ii < s; ii++) { - a[ii] = ii; - } - return a; -} - -describe('compatibility with Immutable.List', () => { - it('determines assignment of unspecified value types', () => { - const t = { - list: List(), - }; - - expect(t.list.size).toBe(0); - }); - - it('of provides initial values', () => { - const v = List.of('a', 'b', 'c'); - expect(v.get(0)).toBe('a'); - expect(v.get(1)).toBe('b'); - expect(v.get(2)).toBe('c'); - }); - - it('toArray provides a JS array', () => { - const v = List.of('a', 'b', 'c'); - expect(v.toArray()).toEqual(['a', 'b', 'c']); - }); - - it('does not accept a scalar', () => { - expect(() => { - List((3: any)); - }).toThrow('Expected Array or collection object of values: 3'); - }); - - it('accepts an array', () => { - const v = List(['a', 'b', 'c']); - expect(v.get(1)).toBe('b'); - expect(v.toArray()).toEqual(['a', 'b', 'c']); - }); - - it('accepts an array-like', () => { - const v = List(({length: 3, '1': 'b'}: any)); - expect(v.get(1)).toBe('b'); - expect(v.toArray()).toEqual([undefined, 'b', undefined]); - }); - - it('accepts any array-like collection, including strings', () => { - const v = List('abc'); - expect(v.get(1)).toBe('b'); - expect(v.toArray()).toEqual(['a', 'b', 'c']); - }); - - it('accepts an indexed Immutable.Seq', () => { - const seq = Immutable.Seq(['a', 'b', 'c']); - const v = List(seq); - expect(v.toArray()).toEqual(['a', 'b', 'c']); - }); - - it('accepts a keyed Immutable.Seq as a list of entries', () => { - const seq = Immutable.Seq({a: null, b: null, c: null}).flip(); - const v = List(seq); - expect(v.toArray()).toEqual([[null, 'a'], [null, 'b'], [null, 'c']]); - // Explicitly getting the values sequence - const v2 = List(seq.valueSeq()); - expect(v2.toArray()).toEqual(['a', 'b', 'c']); - // toList() does this for you. - const v3 = seq.toList(); - expect(v3.toArray()).toEqual(['a', 'b', 'c']); - }); - - it('can set and get a value', () => { - let v = List(); - expect(v.get(0)).toBe(undefined); - v = v.set(0, 'value'); - expect(v.get(0)).toBe('value'); - }); - - it('can setIn and getIn a deep value', () => { - let v = List([ - Map({ - aKey: List(['bad', 'good']), - }), - ]); - expect(v.getIn([0, 'aKey', 1])).toBe('good'); - v = v.setIn([0, 'aKey', 1], 'great'); - expect(v.getIn([0, 'aKey', 1])).toBe('great'); - }); - - it('can update a value', () => { - const l = List.of(5); - expect(l.update(0, v => v * v).toArray()).toEqual([25]); - }); - - it('can updateIn a deep value', () => { - let l = List([ - Map({ - aKey: List(['bad', 'good']), - }), - ]); - l = l.updateIn([0, 'aKey', 1], v => v + v); - expect(l.toJS()).toEqual([ - { - aKey: ['bad', 'goodgood'], - }, - ]); - }); - - it('returns undefined when getting a null value', () => { - const v = List([1, 2, 3]); - // $FlowIgnore - expect(v.get(null)).toBe(undefined); - - const o = List([{a: 1}, {b: 2}, {c: 3}]); - // $FlowIgnore - expect(o.get(null)).toBe(undefined); - }); - - it('counts from the end of the list on negative index', () => { - const i = List.of(1, 2, 3, 4, 5, 6, 7); - expect(i.get(-1)).toBe(7); - expect(i.get(-5)).toBe(3); - expect(i.get(-9)).toBe(undefined); - expect(i.get(-999, 1000)).toBe(1000); - }); - - it('coerces numeric-string keys', () => { - // Of course, TypeScript protects us from this, so cast to "any" to test. - const i: any = List.of(1, 2, 3, 4, 5, 6); - expect(i.get('1')).toBe(2); - expect(i.set('3', 10).get('3')).toBe(10); - // Like array, string negative numbers do not qualify - expect(i.get('-1')).toBe(undefined); - // Like array, string floating point numbers do not qualify - expect(i.get('1.0')).toBe(undefined); - }); - - it('uses not set value for string index', () => { - const list: any = List(); - expect(list.get('stringKey', 'NOT-SET')).toBe('NOT-SET'); - }); - - it('uses not set value for index {}', () => { - const list: any = List.of(1, 2, 3, 4, 5); - expect(list.get({}, 'NOT-SET')).toBe('NOT-SET'); - }); - - it('uses not set value for index void 0', () => { - const list: any = List.of(1, 2, 3, 4, 5); - expect(list.get(undefined, 'NOT-SET')).toBe('NOT-SET'); - }); - - it('uses not set value for index undefined', () => { - const list: any = List.of(1, 2, 3, 4, 5); - expect(list.get(undefined, 'NOT-SET')).toBe('NOT-SET'); - }); - - it('doesnt coerce empty strings to index 0', () => { - const list: any = List.of(1, 2, 3); - expect(list.has('')).toBe(false); - }); - - it('doesnt contain elements at non-empty string keys', () => { - const list: any = List.of(1, 2, 3, 4, 5); - expect(list.has('str')).toBe(false); - }); - - it('hasIn doesnt contain elements at non-empty string keys', () => { - const list: any = List.of(1, 2, 3, 4, 5); - expect(list.hasIn(['str'])).toBe(false); - }); - - it('hasIn doesnt throw for bad key-path', () => { - const list = List.of(1, 2, 3, 4, 5); - expect(list.hasIn([1, 2, 3])).toBe(false); - - const list2 = List([{}]); - expect(list2.hasIn([0, 'bad'])).toBe(false); - }); - - it('setting creates a new instance', () => { - const v0 = List.of('a'); - const v1 = v0.set(0, 'A'); - expect(v0.get(0)).toBe('a'); - expect(v1.get(0)).toBe('A'); - }); - - it('size includes the highest index', () => { - const v0 = List(); - const v1 = v0.set(0, 'a'); - const v2 = v1.set(1, 'b'); - const v3 = v2.set(2, 'c'); - expect(v0.size).toBe(0); - expect(v1.size).toBe(1); - expect(v2.size).toBe(2); - expect(v3.size).toBe(3); - }); - - it('get helpers make for easier to read code', () => { - const v = List.of('a', 'b', 'c'); - expect(v.first()).toBe('a'); - expect(v.get(1)).toBe('b'); - expect(v.last()).toBe('c'); - }); - - it('slice helpers make for easier to read code', () => { - const v0 = List.of('a', 'b', 'c'); - const v1 = List.of('a', 'b'); - const v2 = List.of('a'); - const v3 = List(); - - expect(v0.rest().toArray()).toEqual(['b', 'c']); - expect(v0.butLast().toArray()).toEqual(['a', 'b']); - - expect(v1.rest().toArray()).toEqual(['b']); - expect(v1.butLast().toArray()).toEqual(['a']); - - expect(v2.rest().toArray()).toEqual([]); - expect(v2.butLast().toArray()).toEqual([]); - - expect(v3.rest().toArray()).toEqual([]); - expect(v3.butLast().toArray()).toEqual([]); - }); - - it('can set at arbitrary indices', () => { - const v0 = List.of('a', 'b', 'c'); - const v1 = v0.set(1, 'B'); // within existing tail - const v2 = v1.set(3, 'd'); // at last position - const v3 = v2.set(31, 'e'); // (testing internal guts) - const v4 = v3.set(32, 'f'); // (testing internal guts) - const v5 = v4.set(1023, 'g'); // (testing internal guts) - const v6 = v5.set(1024, 'h'); // (testing internal guts) - const v7 = v6.set(32, 'F'); // set within existing tree - expect(v7.size).toBe(1025); - const expectedArray = ['a', 'B', 'c', 'd']; - expectedArray[31] = 'e'; - expectedArray[32] = 'F'; - expectedArray[1023] = 'g'; - expectedArray[1024] = 'h'; - expect(v7.toArray()).toEqual(expectedArray); - }); - - it('can contain a large number of indices', () => { - const r = Immutable.Range(0, 20000).toList(); - let iterations = 0; - r.forEach(v => { - expect(v).toBe(iterations); - iterations++; - }); - }); - - it('describes a dense list', () => { - const v = List.of('a', 'b', 'c') - .push('d') - .set(14, 'o') - .set(6, undefined) - .remove(1); - expect(v.size).toBe(14); - // eslint-disable-next-line no-sparse-arrays - expect(v.toJS()).toEqual(['a', 'c', 'd', , , , , , , , , , , 'o']); - }); - - it('iterates a dense list', () => { - const v = List() - .setSize(11) - .set(1, 1) - .set(3, 3) - .set(5, 5) - .set(7, 7) - .set(9, 9); - expect(v.size).toBe(11); - - const forEachResults: Array = []; - v.forEach((val, i) => forEachResults.push([i, val])); - expect(forEachResults).toEqual([ - [0, undefined], - [1, 1], - [2, undefined], - [3, 3], - [4, undefined], - [5, 5], - [6, undefined], - [7, 7], - [8, undefined], - [9, 9], - [10, undefined], - ]); - - const arrayResults = v.toArray(); - expect(arrayResults).toEqual([ - undefined, - 1, - undefined, - 3, - undefined, - 5, - undefined, - 7, - undefined, - 9, - undefined, - ]); - - const iteratorResults: Array = []; - const iterator = v.entries(); - let step; - while (!(step = iterator.next()).done) { - iteratorResults.push(step.value); - } - expect(iteratorResults).toEqual([ - [0, undefined], - [1, 1], - [2, undefined], - [3, 3], - [4, undefined], - [5, 5], - [6, undefined], - [7, 7], - [8, undefined], - [9, 9], - [10, undefined], - ]); - }); - - it('push inserts at highest index', () => { - const v0 = List.of('a', 'b', 'c'); - const v1 = v0.push('d', 'e', 'f'); - expect(v0.size).toBe(3); - expect(v1.size).toBe(6); - expect(v1.toArray()).toEqual(['a', 'b', 'c', 'd', 'e', 'f']); - }); - - it('pushes multiple values to the end', () => { - const s1 = 100; - const s2 = 100; - const a1 = arrayOfSize(s1); - const a2 = arrayOfSize(s2); - - const v1 = List(a1); - const v3 = v1.push(...a2); - - const a3 = a1.slice(); - a3.push(...a2); - - expect(v3.size).toEqual(a3.length); - expect(v3.toArray()).toEqual(a3); - }); - - it('pop removes the highest index, decrementing size', () => { - let v = List.of('a', 'b', 'c').pop(); - expect(v.last()).toBe('b'); - expect(v.toArray()).toEqual(['a', 'b']); - v = v.set(1230, 'x'); - expect(v.size).toBe(1231); - expect(v.last()).toBe('x'); - v = v.pop(); - expect(v.size).toBe(1230); - expect(v.last()).toBe(undefined); - v = v.push('X'); - expect(v.size).toBe(1231); - expect(v.last()).toBe('X'); - }); - - it('pop removes the highest index, just like array', () => { - const len = 200; - const a = arrayOfSize(len); - let v = List(a); - - while (a.length) { - expect(v.size).toBe(a.length); - expect(v.toArray()).toEqual(a); - v = v.pop(); - a.pop(); - } - expect(v.size).toBe(a.length); - expect(v.toArray()).toEqual(a); - }); - - it('push adds the next highest index, just like array', () => { - const len = 200; - const a: Array = []; - let v = List(); - - for (let ii = 0; ii < len; ii++) { - expect(v.size).toBe(a.length); - expect(v.toArray()).toEqual(a); - v = v.push(ii); - a.push(ii); - } - expect(v.size).toBe(a.length); - expect(v.toArray()).toEqual(a); - }); - - it('allows popping an empty list', () => { - let v = List.of('a').pop(); - expect(v.size).toBe(0); - expect(v.toArray()).toEqual([]); - v = v - .pop() - .pop() - .pop() - .pop() - .pop(); - expect(v.size).toBe(0); - expect(v.toArray()).toEqual([]); - }); - - it('remove removes any index', () => { - let v = List.of('a', 'b', 'c') - .remove(2) - .remove(0); - expect(v.size).toBe(1); - expect(v.get(0)).toBe('b'); - expect(v.get(1)).toBe(undefined); - expect(v.get(2)).toBe(undefined); - expect(v.toArray()).toEqual(['b']); - v = v.push('d'); - expect(v.size).toBe(2); - expect(v.get(1)).toBe('d'); - expect(v.toArray()).toEqual(['b', 'd']); - }); - - it('shifts values from the front', () => { - const v = List.of('a', 'b', 'c').shift(); - expect(v.first()).toBe('b'); - expect(v.size).toBe(2); - }); - - it('unshifts values to the front', () => { - const v = List.of('a', 'b', 'c').unshift('x', 'y', 'z'); - expect(v.first()).toBe('x'); - expect(v.size).toBe(6); - expect(v.toArray()).toEqual(['x', 'y', 'z', 'a', 'b', 'c']); - }); - - it('unshifts multiple values to the front', () => { - const s1 = 100; - const s2 = 100; - const a1 = arrayOfSize(s1); - const a2 = arrayOfSize(s2); - - const v1 = List(a1); - const v3 = v1.unshift(...a2); - - const a3 = a1.slice(); - a3.unshift(...a2); - - expect(v3.size).toEqual(a3.length); - expect(v3.toArray()).toEqual(a3); - }); - - it('finds values using indexOf', () => { - const v = List.of('a', 'b', 'c', 'b', 'a'); - expect(v.indexOf('b')).toBe(1); - expect(v.indexOf('c')).toBe(2); - expect(v.indexOf('d')).toBe(-1); - }); - - it('finds values using lastIndexOf', () => { - const v = List.of('a', 'b', 'c', 'b', 'a'); - expect(v.lastIndexOf('b')).toBe(3); - expect(v.lastIndexOf('c')).toBe(2); - expect(v.lastIndexOf('d')).toBe(-1); - }); - - it('finds values using findIndex', () => { - const v = List.of('a', 'b', 'c', 'B', 'a'); - expect(v.findIndex(value => value.toUpperCase() === value)).toBe(3); - expect(v.findIndex(value => value.length > 1)).toBe(-1); - }); - - it('finds values using findEntry', () => { - const v = List.of('a', 'b', 'c', 'B', 'a'); - expect(v.findEntry(value => value.toUpperCase() === value)).toEqual([ - 3, - 'B', - ]); - expect(v.findEntry(value => value.length > 1)).toBe(undefined); - }); - - it('maps values', () => { - const v = List.of('a', 'b', 'c'); - const r = v.map(value => value.toUpperCase()); - expect(r.toArray()).toEqual(['A', 'B', 'C']); - }); - - it('filters values', () => { - const v = List.of('a', 'b', 'c', 'd', 'e', 'f'); - const r = v.filter((value, index) => index % 2 === 1); - expect(r.toArray()).toEqual(['b', 'd', 'f']); - }); - - it('filters values based on type', () => { - class A {} - class B extends A { - b(): void { - return; - } - } - class C extends A { - c(): void { - return; - } - } - const l1 = List([new B(), new C(), new B(), new C()]); - // tslint:disable-next-line:arrow-parens - const l2 = l1.filter(v => v instanceof C); - expect(l2.size).toEqual(2); - expect(l2.every(v => v instanceof C)).toBe(true); - }); - - it('reduces values', () => { - const v = List.of(1, 10, 100); - const r = v.reduce((reduction, value) => reduction + value); - expect(r).toEqual(111); - const r2 = v.reduce((reduction, value) => reduction + value, 1000); - expect(r2).toEqual(1111); - }); - - it('reduces from the right', () => { - const v = List.of('a', 'b', 'c'); - const r = v.reduceRight((reduction, value) => reduction + value); - expect(r).toEqual('cba'); - const r2 = v.reduceRight((reduction, value) => reduction + value, 'x'); - expect(r2).toEqual('xcba'); - }); - - it('takes maximum number', () => { - const v = List.of('a', 'b', 'c'); - const r = v.take(Number.MAX_SAFE_INTEGER); - expect(r).toBe(v); - }); - - it('takes and skips values', () => { - const v = List.of('a', 'b', 'c', 'd', 'e', 'f'); - const r = v.skip(2).take(2); - expect(r.toArray()).toEqual(['c', 'd']); - }); - - it('takes and skips no-ops return same reference', () => { - const v = List.of('a', 'b', 'c', 'd', 'e', 'f'); - const r = v.skip(0).take(6); - expect(r).toBe(v); - }); - - it('takeLast and skipLast values', () => { - const v = List.of('a', 'b', 'c', 'd', 'e', 'f'); - const r = v.skipLast(1).takeLast(2); - expect(r.toArray()).toEqual(['d', 'e']); - }); - - it('takeLast and skipLast no-ops return same reference', () => { - const v = List.of('a', 'b', 'c', 'd', 'e', 'f'); - const r = v.skipLast(0).takeLast(6); - expect(r).toBe(v); - }); - - it('efficiently chains array methods', () => { - const v = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14); - - const r = v - .filter(x => x % 2 === 0) - .skip(2) - .map(x => x * x) - .take(3) - .reduce((a: number, b: number) => a + b, 0); - - expect(r).toEqual(200); - }); - - it('can convert to a map', () => { - const v = List.of('a', 'b', 'c'); - const m = v.toMap(); - expect(m.size).toBe(3); - expect(m.get(1)).toBe('b'); - }); - - it('reverses', () => { - const v = List.of('a', 'b', 'c'); - expect(v.reverse().toArray()).toEqual(['c', 'b', 'a']); - }); - - it('ensures equality', () => { - // Make a sufficiently long list. - const a = Array(100) - .join('abcdefghijklmnopqrstuvwxyz') - .split(''); - const v1 = List(a); - const v2 = List(a); - // eslint-disable-next-line eqeqeq - expect(v1 == v2).not.toBe(true); - expect(v1 === v2).not.toBe(true); - expect(v1.equals(v2)).toBe(true); - }); - - it('works with insert', () => { - const v = List.of('a', 'b', 'c'); - const m = v.insert(1, 'd'); - expect(m.size).toBe(4); - expect(m.get(1)).toBe('d'); - - // Works when index is greater than size of array. - const n = v.insert(10, 'e'); - expect(n.size).toBe(4); - expect(n.get(3)).toBe('e'); - - // Works when index is negative. - const o = v.insert(-4, 'f'); - expect(o.size).toBe(4); - expect(o.get(0)).toBe('f'); - }); - - // TODO: assert that findIndex only calls the function as much as it needs to. - it('forEach iterates in the correct order', () => { - let n = 0; - const a: Array = []; - const v = List.of(0, 1, 2, 3, 4); - v.forEach(x => { - a.push(x); - n++; - }); - expect(n).toBe(5); - expect(a.length).toBe(5); - expect(a).toEqual([0, 1, 2, 3, 4]); - }); - - it('forEach iteration terminates when callback returns false', () => { - const a: Array = []; - function count(x) { - if (x > 2) { - return false; - } - a.push(x); - } - const v = List.of(0, 1, 2, 3, 4); - v.forEach(count); - expect(a).toEqual([0, 1, 2]); - }); - - it('concat works like Array.prototype.concat', () => { - const v1 = List([1, 2, 3]); - const v2 = v1.concat( - 4, - List([5, 6]), - [7, 8], - Immutable.Seq([9, 10]), - List.of(11, 12), - null, - ); - expect(v1.toArray()).toEqual([1, 2, 3]); - expect(v2.toArray()).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, null]); - }); - - it('concat returns self when no changes', () => { - const v1 = List([1, 2, 3]); - expect(v1.concat([])).toBe(v1); - }); - - it('concat returns arg when concat to empty', () => { - const v1 = List([1, 2, 3]); - expect(List().concat(v1)).toBe(v1); - }); - - it('concats a single value', () => { - const v1 = Immutable.List([1, 2, 3]); - expect(v1.concat(4).toJS()).toEqual([1, 2, 3, 4]); - }); - - it('concat returns List-coerced arg when concat to empty', () => { - expect(List().concat([1, 2, 3])).toEqual(List([1, 2, 3])); - }); - - it('concat does not spread in string characters', () => { - const v1 = List([1, 2, 3]); - expect(v1.concat('abcdef').toJS()).toEqual([1, 2, 3, 'abcdef']); - }); - - it('allows chained mutations', () => { - const v1 = List(); - const v2 = v1.push(1); - const v3 = v2.withMutations(v => - v - .push(2) - .push(3) - .push(4), - ); - const v4 = v3.push(5); - - expect(v1.toArray()).toEqual([]); - expect(v2.toArray()).toEqual([1]); - expect(v3.toArray()).toEqual([1, 2, 3, 4]); - expect(v4.toArray()).toEqual([1, 2, 3, 4, 5]); - }); - - it('allows chained mutations using alternative API', () => { - const v1 = List(); - const v2 = v1.push(1); - const v3 = v2 - .asMutable() - .push(2) - .push(3) - .push(4) - .asImmutable(); - const v4 = v3.push(5); - - expect(v1.toArray()).toEqual([]); - expect(v2.toArray()).toEqual([1]); - expect(v3.toArray()).toEqual([1, 2, 3, 4]); - expect(v4.toArray()).toEqual([1, 2, 3, 4, 5]); - }); - - // Sharing empty instances is a TODO. - // eslint-disable-next-line - xit('chained mutations does not result in new empty list instance', () => { - const v1 = List(['x']); - const v2 = v1.withMutations(v => - v - .push('y') - .pop() - .pop(), - ); - expect(v2).toBe(List()); - }); - - it('allows size to be set', () => { - const v1 = Immutable.Range(0, 2000).toList(); - const v2 = v1.setSize(1000); - const v3 = v2.setSize(1500); - expect(v1.size).toBe(2000); - expect(v2.size).toBe(1000); - expect(v3.size).toBe(1500); - expect(v1.get(900)).toBe(900); - expect(v1.get(1300)).toBe(1300); - expect(v1.get(1800)).toBe(1800); - expect(v2.get(900)).toBe(900); - expect(v2.get(1300)).toBe(undefined); - expect(v2.get(1800)).toBe(undefined); - expect(v3.get(900)).toBe(900); - expect(v3.get(1300)).toBe(undefined); - expect(v3.get(1800)).toBe(undefined); - }); - - it('discards truncated elements when using slice', () => { - const list = [1, 2, 3, 4, 5, 6]; - const v1 = List(list); - const v2 = v1.slice(0, 3); - const v3 = v2.setSize(6); - - expect(v2.toArray()).toEqual(list.slice(0, 3)); - expect(v3.toArray()).toEqual( - list.slice(0, 3).concat([undefined, undefined, undefined]), - ); - }); - - it('discards truncated elements when using setSize', () => { - const list = [1, 2, 3, 4, 5, 6]; - const v1 = List(list); - const v2 = v1.setSize(3); - const v3 = v2.setSize(6); - - expect(v2.toArray()).toEqual(list.slice(0, 3)); - expect(v3.toArray()).toEqual( - list.slice(0, 3).concat([undefined, undefined, undefined]), - ); - }); - - it('can be efficiently sliced', () => { - const v1 = Immutable.Range(0, 2000).toList(); - const v2 = v1.slice(100, -100).toList(); - const v3 = v2.slice(0, Infinity); - expect(v1.size).toBe(2000); - expect(v2.size).toBe(1800); - expect(v3.size).toBe(1800); - expect(v2.first()).toBe(100); - expect(v2.rest().size).toBe(1799); - expect(v2.last()).toBe(1899); - expect(v2.butLast().size).toBe(1799); - }); - - [NaN, Infinity, -Infinity].forEach(zeroishValue => { - it(`treats ${zeroishValue} like zero when setting size`, () => { - const v1 = List.of('a', 'b', 'c'); - const v2 = v1.setSize(zeroishValue); - expect(v2.size).toBe(0); - }); - }); - - it('Does not infinite loop when sliced with NaN #459', () => { - const list = List([1, 2, 3, 4, 5]); - const newList = list.slice(0, NaN); - expect(newList.toJS()).toEqual([]); - }); - - it('Accepts NaN for slice and concat #602', () => { - const list = List() - .slice(0, NaN) - .concat(NaN); - // toEqual([ NaN ]) - expect(list.size).toBe(1); - expect(isNaNValue(list.get(0))).toBe(true); - }); - - // Note: NaN is the only value not equal to itself. The isNaN() built-in - // function returns true for any non-numeric value, not just the NaN value. - function isNaNValue(value) { - // eslint-disable-next-line no-self-compare - return value !== value; - } - - describe('when slicing', () => { - [NaN, -Infinity].forEach(zeroishValue => { - it(`considers a ${zeroishValue} begin argument to be zero`, () => { - const v1 = List.of('a', 'b', 'c'); - const v2 = v1.slice(zeroishValue, 3); - expect(v2.size).toBe(3); - }); - it(`considers a ${zeroishValue} end argument to be zero`, () => { - const v1 = List.of('a', 'b', 'c'); - const v2 = v1.slice(0, zeroishValue); - expect(v2.size).toBe(0); - }); - it(`considers ${zeroishValue} begin and end arguments to be zero`, () => { - const v1 = List.of('a', 'b', 'c'); - const v2 = v1.slice(zeroishValue, zeroishValue); - expect(v2.size).toBe(0); - }); - }); - }); - - describe('Iterator', () => { - it('iterates through List', () => { - const start = 10; - const len = 100; - const l1 = Immutable.Range(0, start + len).toList(); - const l2: Immutable.List = l1.slice(start, start + len); - expect(l2.size).toBe(len); - const valueIter = l2.values(); - const keyIter = l2.keys(); - const entryIter = l2.entries(); - for (let ii = 0; ii < len; ii++) { - expect(valueIter.next().value).toBe(start + ii); - expect(keyIter.next().value).toBe(ii); - expect(entryIter.next().value).toEqual([ii, start + ii]); - } - }); - - it('iterates through List in reverse', () => { - const start = 10; - const len = 100; - const l1 = Immutable.Range(0, start + len).toList(); - const l2: Immutable.List = l1.slice(start, start + len); - const s = l2.toSeq().reverse(); // impl calls List.__iterator(REVERSE) - expect(s.size).toBe(len); - const valueIter = s.values(); - const keyIter = s.keys(); - const entryIter = s.entries(); - for (let ii = 0; ii < len; ii++) { - expect(valueIter.next().value).toBe(start + len - 1 - ii); - expect(keyIter.next().value).toBe(ii); - expect(entryIter.next().value).toEqual([ii, start + len - 1 - ii]); - } - }); - }); -}); - -// The tests below are adapted from: -// https://github.com/facebook/immutable-js/blob/master/__tests__/Map.ts - -describe('compatibility with Immutable.Map', () => { - it('converts from object', () => { - const m = Map({a: 'A', b: 'B', c: 'C'}); - expect(m.size).toBe(3); - expect(m.get('a')).toBe('A'); - expect(m.get('b')).toBe('B'); - expect(m.get('c')).toBe('C'); - }); - - it('constructor provides initial values', () => { - const m = Map({a: 'A', b: 'B', c: 'C'}); - expect(m.size).toBe(3); - expect(m.get('a')).toBe('A'); - expect(m.get('b')).toBe('B'); - expect(m.get('c')).toBe('C'); - }); - - it('constructor provides initial values as array of entries', () => { - const m = Map([['a', 'A'], ['b', 'B'], ['c', 'C']]); - expect(m.size).toBe(3); - expect(m.get('a')).toBe('A'); - expect(m.get('b')).toBe('B'); - expect(m.get('c')).toBe('C'); - }); - - it('constructor provides initial values as sequence', () => { - const s = Immutable.Seq({a: 'A', b: 'B', c: 'C'}); - const m = Map(s); - expect(m.size).toBe(3); - expect(m.get('a')).toBe('A'); - expect(m.get('b')).toBe('B'); - expect(m.get('c')).toBe('C'); - }); - - it('constructor provides initial values as list of lists', () => { - const l = List([List(['a', 'A']), List(['b', 'B']), List(['c', 'C'])]); - const m = Map(l); - expect(m.size).toBe(3); - expect(m.get('a')).toBe('A'); - expect(m.get('b')).toBe('B'); - expect(m.get('c')).toBe('C'); - }); - - it('constructor is identity when provided map', () => { - const m1 = Map({a: 'A', b: 'B', c: 'C'}); - const m2 = Map(m1); - expect(m2).toBe(m1); - }); - - it('does not accept a scalar', () => { - expect(() => { - Map((3: any)); - }).toThrow( - 'Expected Array or collection object of [k, v] entries, or keyed object: 3', - ); - }); - - it('does not accept strings (collection, but scalar)', () => { - expect(() => { - Map(('abc': any)); - }).toThrow(); - }); - - it('does not accept non-entries array', () => { - expect(() => { - Map(([1, 2, 3]: any)); - }).toThrow('Expected [K, V] tuple: 1'); - }); - - it('accepts non-collection array-like objects as keyed collections', () => { - const m = Map({length: 3, '1': 'one'}); - expect(m.get('length')).toBe(3); - expect(m.get('1')).toBe('one'); - expect(m.toJS()).toEqual({length: 3, '1': 'one'}); - }); - - it('accepts flattened pairs via of()', () => { - const m: Immutable.Map = Map.of(1, 'a', 2, 'b', 3, 'c'); - expect(m.size).toBe(3); - expect(m.get(1)).toBe('a'); - expect(m.get(2)).toBe('b'); - expect(m.get(3)).toBe('c'); - }); - - it('does not accept mismatched flattened pairs via of()', () => { - expect(() => { - Map.of(1, 2, 3); - }).toThrow('Missing value for key: 3'); - }); - - it('converts back to JS object', () => { - const m = Map({a: 'A', b: 'B', c: 'C'}); - expect(m.toObject()).toEqual({a: 'A', b: 'B', c: 'C'}); - }); - - it('iterates values', () => { - const m = Map({a: 'A', b: 'B', c: 'C'}); - const iterator = jasmine.createSpy(); - m.forEach(iterator); - expect(iterator.calls.map(x => x.args)).toEqual([ - ['A', 'a', m], - ['B', 'b', m], - ['C', 'c', m], - ]); - }); - - it('merges two maps', () => { - const m1 = Map({a: 'A', b: 'B', c: 'C'}); - const m2 = Map({wow: 'OO', d: 'DD', b: 'BB'}); - expect(m2.toObject()).toEqual({wow: 'OO', d: 'DD', b: 'BB'}); - const m3 = m1.merge(m2); - expect(m3.toObject()).toEqual({ - a: 'A', - b: 'BB', - c: 'C', - wow: 'OO', - d: 'DD', - }); - }); - - it('accepts null as a key', () => { - const m1 = Map(); - const m2 = m1.set(null, 'null'); - const m3 = m2.remove(null); - expect(m1.size).toBe(0); - expect(m2.size).toBe(1); - expect(m3.size).toBe(0); - expect(m2.get(null)).toBe('null'); - }); - - it('is persistent to sets', () => { - const m1 = Map(); - const m2 = m1.set('a', 'Aardvark'); - const m3 = m2.set('b', 'Baboon'); - const m4 = m3.set('c', 'Canary'); - const m5 = m4.set('b', 'Bonobo'); - expect(m1.size).toBe(0); - expect(m2.size).toBe(1); - expect(m3.size).toBe(2); - expect(m4.size).toBe(3); - expect(m5.size).toBe(3); - expect(m3.get('b')).toBe('Baboon'); - expect(m5.get('b')).toBe('Bonobo'); - }); - - it('is persistent to deletes', () => { - const m1 = Map(); - const m2 = m1.set('a', 'Aardvark'); - const m3 = m2.set('b', 'Baboon'); - const m4 = m3.set('c', 'Canary'); - const m5 = m4.remove('b'); - expect(m1.size).toBe(0); - expect(m2.size).toBe(1); - expect(m3.size).toBe(2); - expect(m4.size).toBe(3); - expect(m5.size).toBe(2); - expect(m3.has('b')).toBe(true); - expect(m3.get('b')).toBe('Baboon'); - expect(m5.has('b')).toBe(false); - expect(m5.get('b')).toBe(undefined); - expect(m5.get('c')).toBe('Canary'); - }); - - it('deletes down to empty map', () => { - const size = 20; - let m = Immutable.Range(0, size).toMap(); - expect(m.size).toBe(size); - for (let ii = size - 1; ii >= 0; ii--) { - m = m.remove(ii); - expect(m.size).toBe(ii); - } - expect(Immutable.is(m, Map())).toBe(true); - }); - - it('can map many items', () => { - let m = Map(); - for (let ii = 0; ii < 2000; ii++) { - m = m.set('thing:' + ii, ii); - } - expect(m.size).toBe(2000); - expect(m.get('thing:1234')).toBe(1234); - }); - - it('can use weird keys', () => { - const symbol = Symbol('A'); - const m: Immutable.Map = Map() - .set(NaN, 1) - .set(Infinity, 2) - .set(symbol, 'A') - .set(-Infinity, 3); - - expect(m.get(symbol)).toBe('A'); - expect(m.get(NaN)).toBe(1); - expect(m.get(Infinity)).toBe(2); - expect(m.get(-Infinity)).toBe(3); - }); - - it('can map items known to hash collide', () => { - // make a big map, so it hashmaps - let m: Immutable.Map = Immutable.Range(0, 32).toMap(); - m = m.set('AAA', 'letters').set(64545, 'numbers'); - expect(m.size).toBe(34); - expect(m.get('AAA')).toEqual('letters'); - expect(m.get(64545)).toEqual('numbers'); - }); - - it('can progressively add items known to collide', () => { - // make a big map, so it hashmaps - let map: Immutable.Map = Immutable.Range(0, 32).toMap(); - map = map.set('@', '@'); - map = map.set(64, 64); - map = map.set(96, 96); - expect(map.size).toBe(35); - expect(map.get('@')).toBe('@'); - expect(map.get(64)).toBe(64); - expect(map.get(96)).toBe(96); - }); - - it('maps values', () => { - const m = Map({a: 'a', b: 'b', c: 'c'}); - const r = m.map(value => value.toUpperCase()); - expect(r.toObject()).toEqual({a: 'A', b: 'B', c: 'C'}); - }); - - it('maps keys', () => { - const m = Map({a: 'a', b: 'b', c: 'c'}); - const r = m.mapKeys(key => key.toUpperCase()); - expect(r.toObject()).toEqual({A: 'a', B: 'b', C: 'c'}); - }); - - it('filters values', () => { - const m = Map({a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}); - const r = m.filter(value => value % 2 === 1); - expect(r.toObject()).toEqual({a: 1, c: 3, e: 5}); - }); - - it('filterNots values', () => { - const m = Map({a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}); - const r = m.filterNot(value => value % 2 === 1); - expect(r.toObject()).toEqual({b: 2, d: 4, f: 6}); - }); - - it('derives keys', () => { - const v = Map({a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}); - expect(v.keySeq().toArray()).toEqual(['a', 'b', 'c', 'd', 'e', 'f']); - }); - - it('flips keys and values', () => { - const v = Map({a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}); - expect(v.flip().toObject()).toEqual({ - '1': 'a', - '2': 'b', - '3': 'c', - '4': 'd', - '5': 'e', - '6': 'f', - }); - }); - - it('can convert to a list', () => { - const m = Map({a: 1, b: 2, c: 3}); - const v = m.toList(); - const k = m.keySeq().toList(); - expect(v.size).toBe(3); - expect(k.size).toBe(3); - // Note: Map has undefined ordering, this List may not be the same - // order as the order you set into the Map. - expect(v.get(1)).toBe(2); - expect(k.get(1)).toBe('b'); - }); - - it('works like an object', () => { - const obj = {a: 1, b: 2, c: 3}; - let map = Map(obj); - Object.keys(obj).forEach(key => { - expect(map.get(key)).toBe(obj[key]); - expect(map.has(key)).toBe(true); - }); - Object.keys(obj).forEach(key => { - expect(map.get(key)).toBe(obj[key]); - expect(map.has(key)).toBe(true); - map = map.remove(key); - expect(map.get(key)).toBe(undefined); - expect(map.has(key)).toBe(false); - }); - }); - - it('sets', () => { - const len = 20; - let map = Map(); - for (let ii = 0; ii < len; ii++) { - expect(map.size).toBe(ii); - map = map.set(String(ii), ii); - } - expect(map.size).toBe(len); - expect(Immutable.is(map.toSet(), Immutable.Range(0, len).toSet())).toBe( - true, - ); - }); - - it('has and get', () => { - const len = 20; - const map = Immutable.Range(0, len) - .toKeyedSeq() - .mapKeys(x => String(x)) - .toMap(); - for (let ii = 0; ii < len; ii++) { - expect(map.get(String(ii))).toBe(ii); - expect(map.has(String(ii))).toBe(true); - } - }); - - it('deletes', () => { - const len = 20; - let map = Immutable.Range(0, len).toMap(); - for (let ii = 0; ii < len; ii++) { - expect(map.size).toBe(len - ii); - map = map.remove(ii); - } - expect(map.size).toBe(0); - expect(map.toObject()).toEqual({}); - }); - - it('deletes from transient', () => { - const len = 20; - const map = Immutable.Range(0, len) - .toMap() - .asMutable(); - for (let ii = 0; ii < len; ii++) { - expect(map.size).toBe(len - ii); - map.remove(ii); - } - expect(map.size).toBe(0); - expect(map.toObject()).toEqual({}); - }); - - it('iterates through all entries', () => { - const len = 20; - const v = Immutable.Range(0, len).toMap(); - const a = v.toArray(); - const iter = v.entries(); - for (let ii = 0; ii < len; ii++) { - // $FlowIgnore - delete a[iter.next().value[0]]; - } - expect(a).toEqual(new Array(len)); - }); - - it('allows chained mutations', () => { - const m1 = Map(); - const m2 = m1.set('a', 1); - const m3 = m2.withMutations(m => m.set('b', 2).set('c', 3)); - const m4 = m3.set('d', 4); - - expect(m1.toObject()).toEqual({}); - expect(m2.toObject()).toEqual({a: 1}); - expect(m3.toObject()).toEqual({a: 1, b: 2, c: 3}); - expect(m4.toObject()).toEqual({a: 1, b: 2, c: 3, d: 4}); - }); - - // Shared empty collections are an explicit TODO. - // eslint-disable-next-line - xit('chained mutations does not result in new empty map instance', () => { - const v1 = Map({x: 1}); - const v2 = v1.withMutations(v => - v - .set('y', 2) - .delete('x') - .delete('y'), - ); - expect(v2).toBe(Map()); - }); - - it('expresses value equality with unordered sequences', () => { - const m1 = Map({A: 1, B: 2, C: 3}); - const m2 = Map({C: 3, B: 2, A: 1}); - expect(Immutable.is(m1, m2)).toBe(true); - }); - - it('deletes all the provided keys', () => { - const NOT_SET = undefined; - const m1 = Map({A: 1, B: 2, C: 3}); - const m2 = m1.deleteAll(['A', 'B']); - expect(m2.get('A')).toBe(NOT_SET); - expect(m2.get('B')).toBe(NOT_SET); - expect(m2.get('C')).toBe(3); - expect(m2.size).toBe(1); - }); - - it('remains unchanged when no keys are provided', () => { - const m1 = Map({A: 1, B: 2, C: 3}); - const m2 = m1.deleteAll([]); - expect(m1).toBe(m2); - }); - - it('uses toString on keys and values', () => { - class A extends Record({x: (null: ?number)}) { - toString() { - // $FlowIgnore - return this.x; - } - } - - const r = new A({x: 2}); - const map = Map([[r, r]]); - expect(map.toString()).toEqual('Map { 2: 2 }'); - }); - - it('supports Symbols as tuple keys', () => { - const a = Symbol('a'); - const b = Symbol('b'); - const c = Symbol('c'); - const m = Map([[a, 'a'], [b, 'b'], [c, 'c']]); - expect(m.size).toBe(3); - expect(m.get(a)).toBe('a'); - expect(m.get(b)).toBe('b'); - expect(m.get(c)).toBe('c'); - }); - - it('Symbol keys are unique', () => { - const a = Symbol('FooBar'); - const b = Symbol('FooBar'); - const m = Map([[a, 'FizBuz'], [b, 'FooBar']]); - expect(m.size).toBe(2); - expect(m.get(a)).toBe('FizBuz'); - expect(m.get(b)).toBe('FooBar'); - }); - - it('mergeDeep with tuple Symbol keys', () => { - const a = Symbol('a'); - const b = Symbol('b'); - const c = Symbol('c'); - const d = Symbol('d'); - const e = Symbol('e'); - const f = Symbol('f'); - const g = Symbol('g'); - - // Note the use of nested Map constructors, Map() does not do a - // deep conversion! - const m1 = Map([[a, Map([[b, Map([[c, 1], [d, 2]])]])]]); - const m2 = Map([ - [a, Map([[b, Map([[c, 10], [e, 20], [f, 30], [g, 40]])]])], - ]); - const merged = m1.mergeDeep(m2); - - expect(merged).toEqual( - Map([[a, Map([[b, Map([[c, 10], [d, 2], [e, 20], [f, 30], [g, 40]])]])]]), - ); - }); -}); diff --git a/pkg/commons-node/spec/immutable-snapshot-spec.js b/pkg/commons-node/spec/immutable-snapshot-spec.js deleted file mode 100644 index 4664f9ccdd..0000000000 --- a/pkg/commons-node/spec/immutable-snapshot-spec.js +++ /dev/null @@ -1,166 +0,0 @@ -/** - * 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 - */ - -import invariant from 'assert'; -import { - List, - Map, - OrderedMap, - Record, - ImmutableSnapshotter, - ImmutableSnapshotReader, -} from '../immutable-snapshot'; - -describe('immutable-snapshot', () => { - let snapshotter: ImmutableSnapshotter; - let reader: ImmutableSnapshotReader; - beforeEach(() => { - snapshotter = new ImmutableSnapshotter(); - reader = new ImmutableSnapshotReader(); - }); - - function verify(object, expected) { - const isDeltaSnapshot = snapshotter._previousSnapshotObjects != null; - const snapshot = snapshotter.createDeltaSnapshot(object); - const stringified = JSON.stringify(snapshot, null, 2); - expect(JSON.parse(stringified)).toEqual(snapshot); - expect(reader.readSnapshot(snapshot).toJS()).toEqual(expected); - if (isDeltaSnapshot) { - const {root, snapshotObjects} = snapshot; - const serialized = snapshotObjects[root]; - expect(serialized.type).toBe('delta'); - } - } - - describe('List', () => { - it('records basic mutations', () => { - let list = List([1, 2, 3]); - verify(list, [1, 2, 3]); - list = list.push(4); - list = list.push(5); - list = list.shift(); - list = list.delete(1); - verify(list, [2, 4, 5]); - }); - - it('does not store mutations to an empty object', () => { - let list = List([]); - verify(list, []); - list = list.push(1); - const {root, snapshotObjects} = snapshotter.createDeltaSnapshot(list); - expect(snapshotObjects[root].type).toBe('list'); - }); - - it('works with JS objects', () => { - let list = List([1]); - verify(list, [1]); - list = list.push([1, 2, 3]).push({a: {b: 1}}); - verify(list, [1, [1, 2, 3], {a: {b: 1}}]); - }); - - it('works with withMutations', () => { - let list = List([1, 2, 3]); - verify(list, [1, 2, 3]); - list = list.withMutations(mutableList => { - mutableList.clear(); - mutableList.push(4); - mutableList.push(5); - }); - verify(list, [4, 5]); - }); - - it('continues to wrap things after an unserializable mutation', () => { - let list = List([1, 2, 3]).sort((x, y) => y - x); - verify(list, [3, 2, 1]); - list = list.unshift(4); - verify(list, [4, 3, 2, 1]); - }); - }); - - describe('Map', () => { - it('records basic mutations', () => { - let map = Map([['a', 1]]); - verify(map, {a: 1}); - map = map.set('b', 2); - map = map.set('a', 3); - verify(map, {a: 3, b: 2}); - }); - - it('serializes mutations correctly', () => { - const a = Map([['a', 1]]); - snapshotter.createDeltaSnapshot(a); - const b = a.set('b', 2); - const {root, snapshotObjects} = snapshotter.createDeltaSnapshot(b); - const serialized = snapshotObjects[root]; - expect(serialized.type).toBe('delta'); - invariant(serialized.type === 'delta'); - expect(serialized.mutations).toEqual([{method: 'set', args: ['b', 2]}]); - }); - - it('works with withMutations', () => { - let map = Map([['a', 1]]); - verify(map, {a: 1}); - map = map.withMutations(mutableMap => { - mutableMap.clear(); - mutableMap.set('a', 3); - mutableMap.set('b', 2); - mutableMap.delete('a'); - }); - verify(map, {b: 2}); - }); - - it('works with nested maps', () => { - let map = Map(); - let map2 = Map(); - map = map.set('x', map2); - verify(map, {x: {}}); - map2 = map2.set('a', 1); - map2 = map2.set('b', 2); - map = map.set('x', map2); - verify(map, {x: {a: 1, b: 2}}); - }); - - it('works with duplicated values', () => { - let map = Map(); - const list = List([1, 2, 3]); - map = map.set('x', list); - map = map.set('y', list); - const {root, snapshotObjects} = snapshotter.createDeltaSnapshot(map); - const serialized = snapshotObjects[root]; - expect(serialized.type).toBe('map'); - invariant(serialized.type === 'map'); - // The value for 'y' should just be an ID. - const y = serialized.value[1][1]; - invariant(y != null && typeof y.type === 'string'); - expect(y.type).toBe('ref'); - }); - - it('returns an OrderedMap from sort', () => { - let map = Map({b: 1, a: 1}); - map = map.sort(); - expect(map instanceof OrderedMap).toBe(true); - verify(map, {a: 1, b: 1}); - map = map.set('c', 2); - verify(map, {a: 1, b: 1, c: 2}); - }); - }); - - describe('Record', () => { - it('records basic mutations', () => { - const TestRecord = Record({a: 0, b: 0}); - let record = new TestRecord({a: 1, b: 0}); - verify(record, {a: 1, b: 0}); - record = record.set('b', 2); - record = record.set('a', 3); - verify(record, {a: 3, b: 2}); - }); - }); -}); diff --git a/pkg/commons-node/spec/memoizeWithDisk-spec.js b/pkg/commons-node/spec/memoizeWithDisk-spec.js deleted file mode 100644 index dcb0b9ea68..0000000000 --- a/pkg/commons-node/spec/memoizeWithDisk-spec.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * 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 - */ - -import temp from 'temp'; -import memoizeWithDisk from '../memoizeWithDisk'; - -temp.track(); - -describe('memoizeWithDisk', () => { - it('memoizes the result of a function', () => { - const tempdir = temp.mkdirSync(); - - const func1 = jasmine - .createSpy() - .andCallFake((map: Map) => { - return map.get('x'); - }); - - const func2 = jasmine - .createSpy() - .andCallFake((map: Map) => { - return map.get('y'); - }); - - // Spies are a bit special because they're a wrapper function. - // Mock out .toString() to make the stringable values different. - spyOn(func2, 'toString').andReturn('different'); - - const memoized = memoizeWithDisk(func1, map => Array.from(map), tempdir); - const memoized2 = memoizeWithDisk(func2, map => Array.from(map), tempdir); - - const map1 = new Map(); - map1.set('x', 1); - map1.set('y', 3); - expect(memoized(map1)).toBe(1); - expect(func1.callCount).toBe(1); - - // Make sure this isn't called again. - expect(memoized(map1)).toBe(1); - expect(func1.callCount).toBe(1); - - // Make sure the two functions don't collide. - expect(memoized2(map1)).toBe(3); - expect(func2.callCount).toBe(1); - - map1.set('x', 2); - expect(memoized(map1)).toBe(2); - expect(func1.callCount).toBe(2); - }); -}); diff --git a/pkg/commons-node/spec/memoryLogger-spec.js b/pkg/commons-node/spec/memoryLogger-spec.js deleted file mode 100644 index d7c52c4784..0000000000 --- a/pkg/commons-node/spec/memoryLogger-spec.js +++ /dev/null @@ -1,136 +0,0 @@ -/** - * 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 - */ - -import log4js from 'log4js'; -import {MemoryLogger} from '../memoryLogger'; - -describe('memoryLogger', () => { - let time = 0; - let logger: MemoryLogger = ((null: any): MemoryLogger); - const underlyingLogger = log4js.getLogger('test'); - underlyingLogger.setLevel('OFF'); - - beforeEach(() => { - time = 0; - const time0 = new Date(0).getTimezoneOffset() * 60 * 1000; // midnight - jasmine.unspy(Date, 'now'); - spyOn(Date, 'now').andCallFake(() => time0 + time); - logger = new MemoryLogger(underlyingLogger, 5 * 60 * 1000); - }); - - it('logs and formats correctly', () => { - time = 1000; - logger.info('msg1'); - time = 2000; - logger.warn('%s%d', 'msg', 2); - expect(logger.dump()).toBe('00:00:01 INFO - msg1\n00:00:02 WARN - msg2\n'); - }); - - it('expunges old messages', () => { - time = 1 * 60 * 1000; - logger.info('1min'); - time = 2 * 60 * 1000; - logger.info('2min'); - time = 3 * 60 * 1000; - logger.info('3min'); - time = 4 * 60 * 1000; - logger.info('4min'); - time = 5 * 60 * 1000; - logger.info('5min'); - expect(logger.dump()).toBe( - '00:01:00 INFO - 1min\n00:02:00 INFO - 2min\n00:03:00 INFO - 3min\n00:04:00 INFO - 4min\n00:05:00 INFO - 5min\n', - ); - time = 6 * 60 * 1000 + 1; - logger.info('6min'); - expect(logger.dump()).toBe( - '00:02:00 INFO - 2min\n00:03:00 INFO - 3min\n00:04:00 INFO - 4min\n00:05:00 INFO - 5min\n00:06:00 INFO - 6min\n', - ); - }); - - it('declines to store anything given zero retention period', () => { - logger = new MemoryLogger(underlyingLogger, 0); - time = 1000; - logger.info('msg1'); - expect(logger.dump()).toBe(''); - }); - - it('limits storage size', () => { - time = 0; - logger = new MemoryLogger(null, 1000, '00:00:00 INFO - '.length + 10); - logger.info('123456789'); - logger.info('11'); - expect(logger.dump()).toBe('00:00:00 INFO - 11\n'); - }); - - it('dumps correctly when count is less than the number of logs', () => { - const nextToLastLog = 'next to last log'; - const lastLog = 'last log'; - - time = 0; - logger.info('123456789'); - logger.info('11'); - logger.info('hello'); - logger.info('world'); - logger.info(nextToLastLog); - logger.info(lastLog); - - const tail = logger - .dump(2) - .split('\n') - .filter(line => line !== ''); - - expect(tail.length).toBe(2); - expect(tail[0].indexOf(nextToLastLog)).toBeGreaterThan(-1); - expect(tail[1].indexOf(lastLog)).toBeGreaterThan(-1); - }); - - it('dumps correctly when count is greater than the number of logs, and around boundaries', () => { - const lastLog = 'last log'; - - time = 0; - logger.info('123456789'); - logger.info('11'); - logger.info('hello'); - logger.info('world'); - logger.info('next to last log'); - logger.info(lastLog); - - let tail = logger - .dump(10) - .split('\n') - .filter(line => line !== ''); - - expect(tail.length).toBe(6); - - tail = logger - .dump(6) - .split('\n') - .filter(line => line !== ''); - - expect(tail.length).toBe(6); - - tail = logger - .dump(1) - .split('\n') - .filter(line => line !== ''); - - expect(tail.length).toBe(1); - expect(tail[0].indexOf(lastLog)).toBeGreaterThan(-1); - - expect(() => { - logger.dump(-1); - }).toThrow(); - - expect(() => { - logger.dump(0); - }).toThrow(); - }); -}); diff --git a/pkg/commons-node/spec/once-spec.js b/pkg/commons-node/spec/once-spec.js deleted file mode 100644 index b3aa0aedfe..0000000000 --- a/pkg/commons-node/spec/once-spec.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import once from '../once'; - -describe('once', () => { - it('correctly calls only once', () => { - let num = 1; - const onceFn = once(n => (num += n)); - expect(onceFn(2)).toEqual(3); - expect(onceFn(2)).toEqual(3); - }); - - it('does not swallow flow types', () => { - const func = (a: string): number => 1; - const onceFn = once(func); - const ret = onceFn('bar'); - - (ret: number); - // $FlowIgnore: func's first param should be a string. - onceFn(1); - }); -}); diff --git a/pkg/commons-node/spec/promise-executors-spec.js b/pkg/commons-node/spec/promise-executors-spec.js deleted file mode 100644 index a7e7129e65..0000000000 --- a/pkg/commons-node/spec/promise-executors-spec.js +++ /dev/null @@ -1,107 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import {PromisePool, PromiseQueue} from '../promise-executors'; - -describe('PromiseQueue', () => { - // Workarounds to enable setTimeout, as suggested by: - // https://discuss.atom.io/t/solved-settimeout-not-working-firing-in-specs-tests/11427/17 - beforeEach(() => { - jasmine.useRealClock(); - }); - - it('Run three async operations serially and make sure they do not overlap.', () => { - const queue = new PromiseQueue(); - let res1Start = 0; - let res1End = 0; - let res2Start = 0; - let res2End = 0; - let res3Start = 0; - let res3End = 0; - - runs(() => { - queue.submit(async () => { - res1Start = Date.now(); - await new Promise(resolve => { - setTimeout(() => { - resolve((res1End = Date.now())); - }, 100); - }); - }); - queue.submit(async () => { - res2Start = Date.now(); - await new Promise(resolve => { - setTimeout(() => { - resolve((res2End = Date.now())); - }, 200); - }); - }); - queue.submit(async () => { - res3Start = Date.now(); - await new Promise(resolve => { - setTimeout(() => { - resolve((res3End = Date.now())); - }, 300); - }); - }); - }); - - waitsFor(() => res1End && res2End && res3End, 700); - - runs(() => { - // Make sure that none of the executors overlapped. - expect(res1Start).not.toBeGreaterThan(res1End); - expect(res1End).not.toBeGreaterThan(res2Start); - expect(res2Start).not.toBeGreaterThan(res2End); - expect(res2End).not.toBeGreaterThan(res3Start); - expect(res3Start).not.toBeGreaterThan(res3End); - }); - }); -}); - -describe('PromisePool', () => { - beforeEach(() => { - jasmine.useRealClock(); - }); - - it('Run async operations in parallel and do not exceed pool size.', () => { - const poolSize = 3; - const numDelayedExecutors = 30; - const delayMs = 10; - let numRunning = 0; - - const executors = []; - for (let i = 0; i < numDelayedExecutors; i++) { - executors.push(async () => { - numRunning++; - expect(numRunning <= poolSize).toBe(true); - await new Promise(resolve => { - setTimeout(() => { - expect(numRunning <= poolSize).toBe(true); - numRunning--; - resolve(); - }, delayMs); - }); - }); - } - - const queue = new PromisePool(poolSize); - - waitsForPromise(async () => { - const start = Date.now(); - await Promise.all(executors.map(executor => queue.submit(executor))); - const end = Date.now(); - expect(end - start).toBeLessThan( - (numDelayedExecutors * delayMs) / (poolSize - 1), - ); - }); - }); -}); diff --git a/pkg/commons-node/spec/scheduleIdleCallback-spec.js b/pkg/commons-node/spec/scheduleIdleCallback-spec.js deleted file mode 100644 index c89cced1f0..0000000000 --- a/pkg/commons-node/spec/scheduleIdleCallback-spec.js +++ /dev/null @@ -1,144 +0,0 @@ -/** - * 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 strict - * @format - */ - -describe('scheduleIdleCallback using node API', () => { - let oldSetImmediate; - let oldClearImmediate; - let setImmediateCalls; - let clearImmediateCalls; - let scheduleIdleCallback; - let oldRequestIdleCallback; - - beforeEach(() => { - oldRequestIdleCallback = global.requestIdleCallback; - delete global.requestIdleCallback; - - oldSetImmediate = global.setImmediate; - setImmediateCalls = []; - global.setImmediate = (...args) => { - setImmediateCalls.push(args); - return 1; - }; - - oldClearImmediate = global.clearImmediate; - clearImmediateCalls = []; - global.clearImmediate = (...args) => { - clearImmediateCalls.push(args); - }; - - delete require.cache[require.resolve('../scheduleIdleCallback')]; - scheduleIdleCallback = require('../scheduleIdleCallback').default; - }); - - afterEach(() => { - global.clearImmediate = oldClearImmediate; - global.setImmediate = oldSetImmediate; - global.requestIdleCallback = oldRequestIdleCallback; - delete require.cache[require.resolve('../scheduleIdleCallback')]; - }); - - it('works', () => { - const fnCalls = []; - const fn = () => { - fnCalls.push([]); - }; - const disposable = scheduleIdleCallback(fn); - expect(setImmediateCalls.length).toBe(1); - expect(setImmediateCalls[0][0]).toBe(fn); - expect(clearImmediateCalls.length).toBe(0); - - disposable.dispose(); - expect(clearImmediateCalls.length).toBe(1); - }); -}); - -describe('scheduleIdleCallback using browser API', () => { - let oldRequestIdleCallback; - let oldCancelIdleCallback; - let requestIdleCallbackCalls; - let cancelIdleCallbackCalls; - let scheduleIdleCallback; - - beforeEach(() => { - oldRequestIdleCallback = global.requestIdleCallback; - requestIdleCallbackCalls = []; - let count = 1; - global.requestIdleCallback = (...args) => { - requestIdleCallbackCalls.push(args); - return count++; - }; - - oldCancelIdleCallback = global.cancelIdleCallback; - cancelIdleCallbackCalls = []; - global.cancelIdleCallback = (...args) => { - cancelIdleCallbackCalls.push(args); - }; - - delete require.cache[require.resolve('../scheduleIdleCallback')]; - scheduleIdleCallback = require('../scheduleIdleCallback').default; - }); - - afterEach(() => { - global.cancelIdleCallback = oldCancelIdleCallback; - global.requestIdleCallback = oldRequestIdleCallback; - delete require.cache[require.resolve('../scheduleIdleCallback')]; - }); - - it('works', () => { - const fnCalls = []; - const fn = () => { - fnCalls.push([]); - }; - const disposable = scheduleIdleCallback(fn); - expect(requestIdleCallbackCalls.length).toBe(1); - requestIdleCallbackCalls[0][0]({timeRemaining: () => 48}); - expect(fnCalls.length).toBe(0); - expect(requestIdleCallbackCalls.length).toBe(2); - requestIdleCallbackCalls[1][0]({timeRemaining: () => 49}); - expect(fnCalls.length).toBe(1); - expect(cancelIdleCallbackCalls.length).toBe(0); - - disposable.dispose(); - expect(cancelIdleCallbackCalls.length).toBe(0); - }); - - it('cancels', () => { - const disposable = scheduleIdleCallback(() => {}); - requestIdleCallbackCalls[0][0]({timeRemaining: () => 48}); - disposable.dispose(); - expect(cancelIdleCallbackCalls.length).toBe(1); - disposable.dispose(); - expect(cancelIdleCallbackCalls.length).toBe(1); - }); - - it('expires after a timeout', () => { - let curDate = 0; - jasmine.unspy(Date, 'now'); - spyOn(Date, 'now').andCallFake(() => curDate); - const fn = jasmine.createSpy('callback'); - const disposable = scheduleIdleCallback(fn, { - afterRemainingTime: 100, - timeout: 100, - }); - - requestIdleCallbackCalls[0][0]({timeRemaining: () => 48}); - expect(fn).not.toHaveBeenCalled(); - curDate = 50; - requestIdleCallbackCalls[0][0]({timeRemaining: () => 48}); - expect(fn).not.toHaveBeenCalled(); - curDate = 100; - requestIdleCallbackCalls[0][0]({timeRemaining: () => 48}); - expect(fn).toHaveBeenCalled(); - - disposable.dispose(); - expect(cancelIdleCallbackCalls.length).toBe(0); - }); -}); diff --git a/pkg/commons-node/spec/scripts/scribe_cat_mock b/pkg/commons-node/spec/scripts/scribe_cat_mock deleted file mode 100755 index 8ac2562c41..0000000000 --- a/pkg/commons-node/spec/scripts/scribe_cat_mock +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python - -# 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. - -'''A script simulate scribe_cat and save the stdin into os.environ[SCRIBE_MOCK_PATH]/$category_name file. - To simulate the crash, if the input line is "abort" (quote included), it crash itself with exit code 1.''' - -import optparse -import os -import sys - -parser = optparse.OptionParser(usage='usage: %prog [category_name]', - description='Save stdin into $SCRIBE_MOCK_PATH/$categor_name') -options, args = parser.parse_args(sys.argv[1:]) -category_name = args[0]; - -with open(os.path.join(os.environ['SCRIBE_MOCK_PATH'], category_name), 'a') as f: - while True: - line = sys.stdin.readline() - if line == '': - sys.exit(1) - f.write(line) - f.flush(); diff --git a/pkg/commons-node/spec/singleton-spec.js b/pkg/commons-node/spec/singleton-spec.js deleted file mode 100644 index aed8e7c2a9..0000000000 --- a/pkg/commons-node/spec/singleton-spec.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import singleton from '../singleton'; - -describe('singleton', () => { - let count = 0; - const field = 'singleton-test-field'; - - function get() { - return singleton.get(field, () => { - return count++; - }); - } - - function clear() { - singleton.clear(field); - } - - function reset() { - return singleton.reset(field, () => { - return count++; - }); - } - - it('get', () => { - const id1 = get(); - const id2 = get(); - expect(id1).toEqual(id2); - }); - - it('clear', () => { - const id1 = get(); - - clear(); - - const id2 = get(); - expect(id2 !== id1).toBe(true); - }); - - it('reset', () => { - const id1 = get(); - - const id2 = reset(); - expect(id2).not.toEqual(id1); - - const id3 = get(); - expect(id3).toEqual(id2); - }); -}); diff --git a/pkg/commons-node/spec/tasks-spec.js b/pkg/commons-node/spec/tasks-spec.js deleted file mode 100644 index 448efdc939..0000000000 --- a/pkg/commons-node/spec/tasks-spec.js +++ /dev/null @@ -1,263 +0,0 @@ -/** - * 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 - */ - -import type {Message} from 'nuclide-commons/process'; - -import {taskFromObservable, observableFromTask} from '../tasks'; -import invariant from 'assert'; -import {Emitter} from 'event-kit'; -import {Observable, Subject, Subscription} from 'rxjs'; - -describe('commons-node/tasks', () => { - describe('observableFromTask', () => { - it('calls start when subscribed', () => { - const task = createMockTask(); - const observable = observableFromTask(task); - expect(task.start).not.toHaveBeenCalled(); - observable.subscribe(); - expect(task.start).toHaveBeenCalled(); - }); - - it('calls cancel when unsubscribed early', () => { - const task = createMockTask(); - const observable = observableFromTask(task); - const sub = observable.subscribe(); - expect(task.cancel).not.toHaveBeenCalled(); - sub.unsubscribe(); - expect(task.cancel).toHaveBeenCalled(); - }); - - it('completes when the task does', () => { - const task = createMockTask(); - const observable = observableFromTask(task); - const completed = jasmine.createSpy(); - observable.subscribe({complete: completed}); - expect(completed).not.toHaveBeenCalled(); - task._complete(); - expect(completed).toHaveBeenCalled(); - }); - - it('errors when the task does', () => { - const task = createMockTask(); - const observable = observableFromTask(task); - const errored = jasmine.createSpy(); - observable.subscribe({error: errored}); - expect(errored).not.toHaveBeenCalled(); - task._error(new Error()); - expect(errored).toHaveBeenCalled(); - }); - - it("doesn't call cancel when unsubscribed after completion", () => { - const task = createMockTask(); - const observable = observableFromTask(task); - const sub = observable.subscribe(); - task._complete(); - sub.unsubscribe(); - expect(task.cancel).not.toHaveBeenCalled(); - }); - - it("doesn't call cancel when unsubscribed after an error", () => { - const task = createMockTask(); - const observable = observableFromTask(task); - const sub = observable.catch(() => Observable.empty()).subscribe(); - task._error(new Error()); - sub.unsubscribe(); - expect(task.cancel).not.toHaveBeenCalled(); - }); - - it('includes emitted message events', () => { - const task = createMockTask(); - const observable = observableFromTask(task); - const handler = jasmine.createSpy(); - observable.subscribe(handler); - task._message({text: 'hello', level: 'warning'}); - expect(handler).toHaveBeenCalledWith({ - type: 'message', - message: {text: 'hello', level: 'warning'}, - }); - }); - - it('includes emitted progress events', () => { - const task = createMockTask(); - const observable = observableFromTask(task); - const handler = jasmine.createSpy(); - observable.subscribe(handler); - task._progress(0.5); - expect(handler).toHaveBeenCalledWith({type: 'progress', progress: 0.5}); - }); - - it('includes emitted result events', () => { - const task = createMockTask(); - const observable = observableFromTask(task); - const handler = jasmine.createSpy(); - observable.subscribe(handler); - task._result(42); - expect(handler).toHaveBeenCalledWith({type: 'result', result: 42}); - }); - - it('includes emitted status events', () => { - const task = createMockTask(); - const observable = observableFromTask(task); - const handler = jasmine.createSpy(); - observable.subscribe(handler); - task._status('fine and dandy'); - expect(handler).toHaveBeenCalledWith({ - type: 'status', - status: 'fine and dandy', - }); - }); - }); - - describe('taskFromObservable', () => { - it('subscribes when started', () => { - const observable = new Subject(); - spyOn(observable, 'subscribe').andCallThrough(); - const task = taskFromObservable(observable); - expect(observable.subscribe).not.toHaveBeenCalled(); - task.start(); - expect(observable.subscribe).toHaveBeenCalled(); - }); - - it('unsubscribes when canceled', () => { - const sub = new Subscription(); - spyOn(sub, 'unsubscribe'); - const observable = new Subject(); - spyOn(observable, 'subscribe').andReturn(sub); - const task = taskFromObservable(observable); - task.start(); - expect(sub.unsubscribe).not.toHaveBeenCalled(); - task.cancel(); - expect(sub.unsubscribe).toHaveBeenCalled(); - }); - - it('calls onDidComplete callbacks when it completes', () => { - const sub = new Subscription(); - spyOn(sub, 'unsubscribe'); - const observable = new Subject(); - const task = taskFromObservable(observable); - const completed = jasmine.createSpy(); - task.onDidComplete(completed); - task.start(); - expect(completed).not.toHaveBeenCalled(); - observable.complete(); - expect(completed).toHaveBeenCalled(); - }); - - it('calls onDidError callbacks when it errors', () => { - const observable = new Subject(); - const task = taskFromObservable(observable); - const errored = jasmine.createSpy(); - task.onDidError(errored); - task.start(); - expect(errored).not.toHaveBeenCalled(); - observable.error(); - expect(errored).toHaveBeenCalled(); - }); - - it('calls onMessage callbacks for message events', () => { - const observable = new Subject(); - const task = taskFromObservable(observable); - const handler = jasmine.createSpy(); - invariant(task.onMessage != null); - task.onMessage(handler); - task.start(); - expect(handler).not.toHaveBeenCalled(); - observable.next({ - type: 'message', - message: {text: 'hello', level: 'warning'}, - }); - expect(handler).toHaveBeenCalledWith({text: 'hello', level: 'warning'}); - }); - - it('calls onProgress callbacks for progress events', () => { - const observable = new Subject(); - const task = taskFromObservable(observable); - const handler = jasmine.createSpy(); - invariant(task.onProgress != null); - task.onProgress(handler); - task.start(); - expect(handler).not.toHaveBeenCalled(); - observable.next({type: 'progress', progress: 0.5}); - expect(handler).toHaveBeenCalledWith(0.5); - }); - - it('calls onResult callbacks for result events', () => { - const observable = new Subject(); - const task = taskFromObservable(observable); - const handler = jasmine.createSpy(); - invariant(task.onResult != null); - task.onResult(handler); - task.start(); - expect(handler).not.toHaveBeenCalled(); - observable.next({type: 'result', result: 42}); - expect(handler).toHaveBeenCalledWith(42); - }); - - it('calls onStatusChange callbacks for status events', () => { - const observable = new Subject(); - const task = taskFromObservable(observable); - const handler = jasmine.createSpy(); - invariant(task.onStatusChange != null); - task.onStatusChange(handler); - task.start(); - expect(handler).not.toHaveBeenCalled(); - observable.next({type: 'status', status: 'fine and dandy'}); - expect(handler).toHaveBeenCalledWith('fine and dandy'); - }); - }); -}); - -function createMockTask() { - const emitter = new Emitter(); - const task = { - start: () => {}, - cancel: () => {}, - onDidComplete: (callback: () => mixed): IDisposable => { - return emitter.on('complete', callback); - }, - onDidError: (callback: (err: Error) => mixed): IDisposable => { - return emitter.on('error', callback); - }, - onMessage: (callback: (message: Message) => mixed): IDisposable => { - return emitter.on('message', callback); - }, - onProgress: (callback: (progress: ?number) => mixed): IDisposable => { - return emitter.on('progress', callback); - }, - onResult: (callback: (result: mixed) => mixed): IDisposable => { - return emitter.on('result', callback); - }, - onStatusChange: (callback: (status: string) => mixed): IDisposable => { - return emitter.on('status', callback); - }, - _complete: (): void => { - emitter.emit('complete'); - }, - _error: (err: Error): void => { - emitter.emit('error', err); - }, - _message: (message: Message): void => { - emitter.emit('message', message); - }, - _progress: (progress: ?number): void => { - emitter.emit('progress', progress); - }, - _result: (result: number): void => { - emitter.emit('result', result); - }, - _status: (status: string): void => { - emitter.emit('status', status); - }, - }; - spyOn(task, 'start'); - spyOn(task, 'cancel'); - return task; -} diff --git a/pkg/commons-node/spec/xfetch-spec.js b/pkg/commons-node/spec/xfetch-spec.js deleted file mode 100644 index 3c86d7eebd..0000000000 --- a/pkg/commons-node/spec/xfetch-spec.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * 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 - */ - -import invariant from 'assert'; -import fs from 'fs'; -import fsPromise from 'nuclide-commons/fsPromise'; -import http from 'http'; -import xfetch from '../xfetch'; - -describe('xfetch', () => { - beforeEach(() => { - // Normally we get a stubbed version during tests. - spyOn(require('../system-info'), 'isRunningInTest').andReturn(false); - }); - - it('is the correct module', () => { - if (typeof atom === 'undefined') { - expect(xfetch).toBe(require('node-fetch')); - } else { - expect(xfetch).toBe(global.fetch); - } - }); - - it('rejects a connection error', () => { - waitsForPromise(async () => { - let errorThrown; - try { - await xfetch('http://0.0.0.0:62222'); - } catch (err) { - errorThrown = err; - } - if (typeof atom === 'undefined') { - expect(errorThrown).toMatch(/FetchError/); - } else { - expect(errorThrown).toMatch(/Failed to fetch/); - } - }); - }); - - describe('with a connection', () => { - let server: ?http.Server; - let port; - - beforeEach(() => { - server = http - .createServer((req, res) => { - fs.readFile(req.url, 'utf8', (err, contents) => { - if (err) { - res.statusCode = 404; - res.end('Not found', 'utf8'); - } else { - res.setHeader('Content-Type', 'text/plain;charset=utf8'); - res.end(contents, 'utf8'); - } - }); - }) - .listen(0); - port = server.address().port; - }); - - afterEach(() => { - invariant(server); - server.close(); - }); - - it('can do a 2xx GET request', () => { - waitsForPromise(async () => { - const realFilename = __filename; - const response = await xfetch(`http://0.0.0.0:${port}${realFilename}`); - expect(response.ok).toBe(true); - - const text = await response.text(); - const contents = await fsPromise.readFile(realFilename, 'utf8'); - expect(text).toEqual(contents); - }); - }); - - it('can do a 404 GET request', () => { - waitsForPromise(async () => { - // eslint-disable-next-line no-path-concat - const nonexistingFilename = __filename + 'XXX'; - const response = await xfetch( - `http://0.0.0.0:${port}${nonexistingFilename}`, - ); - expect(response.ok).toBe(false); - expect(response.status).toBe(404); - expect(response.statusText).toBe('Not Found'); - }); - }); - }); -}); diff --git a/pkg/commons-node/system-info.js b/pkg/commons-node/system-info.js index 0ab74179a7..c3fca14cad 100644 --- a/pkg/commons-node/system-info.js +++ b/pkg/commons-node/system-info.js @@ -1,3 +1,37 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.isRunningInTest = exports.OS_TYPE = undefined; +exports.isRunningInServer = isRunningInServer; +exports.getAtomNuclideDir = getAtomNuclideDir; +exports.getAtomVersion = getAtomVersion; +exports.getNuclideVersion = getNuclideVersion; +exports.getNuclideRealDir = getNuclideRealDir; +exports.getOsType = getOsType; +exports.isRunningInWindows = isRunningInWindows; +exports.getOsVersion = getOsVersion; +exports.getRuntimePath = getRuntimePath; + +var _fs = _interopRequireDefault(require('fs')); + +var _once; + +function _load_once() { + return _once = _interopRequireDefault(require('./once')); +} + +var _os = _interopRequireDefault(require('os')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../modules/nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,26 +39,20 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import fs from 'fs'; -import invariant from 'assert'; -import once from './once'; -import os from 'os'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - const NUCLIDE_PACKAGE_JSON_PATH = require.resolve('../../package.json'); -const NUCLIDE_BASEDIR = nuclideUri.dirname(NUCLIDE_PACKAGE_JSON_PATH); +const NUCLIDE_BASEDIR = (_nuclideUri || _load_nuclideUri()).default.dirname(NUCLIDE_PACKAGE_JSON_PATH); -const pkgJson = JSON.parse(fs.readFileSync(NUCLIDE_PACKAGE_JSON_PATH, 'utf8')); +const pkgJson = JSON.parse(_fs.default.readFileSync(NUCLIDE_PACKAGE_JSON_PATH, 'utf8')); -export const OS_TYPE = { +const OS_TYPE = exports.OS_TYPE = { WIN32: 'win32', WIN64: 'win64', LINUX: 'linux', - OSX: 'darwin', + OSX: 'darwin' }; // Prior to Atom v1.7.0, `atom.inSpecMode` had a chance of performing an IPC call that could be @@ -35,15 +63,13 @@ export const OS_TYPE = { // ensures happens only once. // // [1]: https://github.com/atom/atom/blob/v1.6.2/src/window-load-settings-helpers.coffee#L10-L14 -export const isRunningInTest = once( - (): boolean => { - if (typeof atom === 'object') { - return atom.inSpecMode(); - } else { - return process.env.NODE_ENV === 'test'; - } - }, -); +const isRunningInTest = exports.isRunningInTest = (0, (_once || _load_once()).default)(() => { + if (typeof atom === 'object') { + return atom.inSpecMode(); + } else { + return process.env.NODE_ENV === 'test'; + } +}); // Nuclide code can run in one of three situations: // @@ -52,50 +78,52 @@ export const isRunningInTest = once( // 3) Inside of the Nuclide server, or another plain Node script // // It's hard to explicitly check 3) so this checks for the absence of 1/2. -export function isRunningInServer(): boolean { - return ( - typeof atom === 'undefined' && process.env.ELECTRON_RUN_AS_NODE !== '1' - ); +function isRunningInServer() { + return typeof atom === 'undefined' && process.env.ELECTRON_RUN_AS_NODE !== '1'; } // This path may be a symlink. -export function getAtomNuclideDir(): string { +function getAtomNuclideDir() { if (typeof atom !== 'object') { throw new Error('Not running in Atom.'); } const nuclidePackageModule = atom.packages.getLoadedPackage('nuclide'); - invariant(nuclidePackageModule); + + if (!nuclidePackageModule) { + throw new Error('Invariant violation: "nuclidePackageModule"'); + } + return nuclidePackageModule.path; } -export function getAtomVersion(): string { +function getAtomVersion() { if (typeof atom !== 'object') { throw new Error('Not running in Atom.'); } return atom.getVersion(); } -export function getNuclideVersion(): string { +function getNuclideVersion() { return pkgJson.version; } -export function getNuclideRealDir(): string { +function getNuclideRealDir() { return NUCLIDE_BASEDIR; } -export function getOsType(): string { - return os.platform(); +function getOsType() { + return _os.default.platform(); } -export function isRunningInWindows(): boolean { +function isRunningInWindows() { return getOsType() === OS_TYPE.WIN32 || getOsType() === OS_TYPE.WIN64; } -export function getOsVersion(): string { - return os.release(); +function getOsVersion() { + return _os.default.release(); } -export function getRuntimePath(): string { +function getRuntimePath() { // "resourcesPath" only exists in Atom. It's as close as you can get to // Atom's path. In the general case, it looks like this: // Mac: "/Applications/Atom.app/Contents/Resources" @@ -105,9 +133,9 @@ export function getRuntimePath(): string { // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) if (global.atom && typeof process.resourcesPath === 'string') { const resourcesPath = process.resourcesPath; - if (os.platform() === 'darwin') { + if (_os.default.platform() === 'darwin') { return resourcesPath.replace(/\/Contents\/Resources$/, ''); - } else if (os.platform() === 'linux') { + } else if (_os.default.platform() === 'linux') { return resourcesPath.replace(/\/resources$/, ''); } else { return resourcesPath.replace(/[\\]+resources$/, ''); @@ -115,4 +143,4 @@ export function getRuntimePath(): string { } else { return process.execPath; } -} +} \ No newline at end of file diff --git a/pkg/commons-node/tasks.js b/pkg/commons-node/tasks.js index e18a0dcb12..1095f214a9 100644 --- a/pkg/commons-node/tasks.js +++ b/pkg/commons-node/tasks.js @@ -1,3 +1,40 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.taskFromObservable = taskFromObservable; +exports.observableFromTask = observableFromTask; +exports.createMessage = createMessage; +exports.createResult = createResult; +exports.createStatus = createStatus; +exports.createStep = createStep; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../modules/nuclide-commons/UniversalDisposable')); +} + +var _event; + +function _load_event() { + return _event = require('../../modules/nuclide-commons/event'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Subscribe to an observable and transform it into the Task interface. The Task interface allows us + * to interop nicely with Atom and Atom packages without forcing them to use Rx, but internally, + * Observables are probably how we'll always build the functionality. + */ + + +// FIXME: This should really be an interface, but we're currently transpiling with Babel 5, which +// doesn't support that. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +42,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ @@ -13,98 +50,63 @@ // interface](https://atom.io/docs/api/latest/Task). These are utilities for converting between the // two. -import type {TaskEvent, Message, Level} from 'nuclide-commons/process'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import invariant from 'assert'; -import {Observable, Subscription} from 'rxjs'; - -// FIXME: This should really be an interface, but we're currently transpiling with Babel 5, which -// doesn't support that. -export type Task = { - start: () => void, - cancel: () => void, - onDidComplete: (callback: () => mixed) => IDisposable, - onDidError: (callback: (err: Error) => mixed) => IDisposable, - +onMessage?: (callback: (message: Message) => mixed) => IDisposable, - +onProgress?: (callback: (progress: ?number) => mixed) => IDisposable, - +onResult?: (callback: (result: mixed) => mixed) => IDisposable, - +onStatusChange?: (callback: (status: ?string) => mixed) => IDisposable, -}; - -/** - * Subscribe to an observable and transform it into the Task interface. The Task interface allows us - * to interop nicely with Atom and Atom packages without forcing them to use Rx, but internally, - * Observables are probably how we'll always build the functionality. - */ -export function taskFromObservable(observable: Observable): Task { +function taskFromObservable(observable) { const events = observable.share().publish(); let subscription; const task = { - start(): void { + start() { if (subscription == null) { subscription = events.connect(); } }, - cancel(): void { + cancel() { if (subscription != null) { subscription.unsubscribe(); } }, - onDidComplete(callback: () => mixed): IDisposable { - return new UniversalDisposable( - events.subscribe({complete: callback, error: () => {}}), - ); + onDidComplete(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(events.subscribe({ complete: callback, error: () => {} })); }, - onDidError(callback: (err: Error) => mixed): IDisposable { - return new UniversalDisposable(events.subscribe({error: callback})); + onDidError(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(events.subscribe({ error: callback })); }, - onMessage(callback: (message: Message) => mixed): IDisposable { - return new UniversalDisposable( - events - .filter(event => event.type === 'message') - .map(event => { - invariant(event.type === 'message'); - return event.message; - }) - .subscribe({next: callback, error: () => {}}), - ); + onMessage(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(events.filter(event => event.type === 'message').map(event => { + if (!(event.type === 'message')) { + throw new Error('Invariant violation: "event.type === \'message\'"'); + } + + return event.message; + }).subscribe({ next: callback, error: () => {} })); }, - onProgress(callback: (progress: ?number) => mixed): IDisposable { - return new UniversalDisposable( - events - .filter(event => event.type === 'progress') - .map(event => { - invariant(event.type === 'progress'); - return event.progress; - }) - .subscribe({next: callback, error: () => {}}), - ); + onProgress(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(events.filter(event => event.type === 'progress').map(event => { + if (!(event.type === 'progress')) { + throw new Error('Invariant violation: "event.type === \'progress\'"'); + } + + return event.progress; + }).subscribe({ next: callback, error: () => {} })); }, - onResult(callback: (result: mixed) => mixed): IDisposable { - return new UniversalDisposable( - events - .filter(event => event.type === 'result') - .map(event => { - invariant(event.type === 'result'); - return event.result; - }) - .subscribe({next: callback, error: () => {}}), - ); - }, - onStatusChange(callback: (status: ?string) => mixed): IDisposable { - return new UniversalDisposable( - events - .filter(event => event.type === 'status') - .map(event => { - invariant(event.type === 'status'); - return event.status; - }) - .subscribe({next: callback, error: () => {}}), - ); + onResult(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(events.filter(event => event.type === 'result').map(event => { + if (!(event.type === 'result')) { + throw new Error('Invariant violation: "event.type === \'result\'"'); + } + + return event.result; + }).subscribe({ next: callback, error: () => {} })); }, + onStatusChange(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(events.filter(event => event.type === 'status').map(event => { + if (!(event.type === 'status')) { + throw new Error('Invariant violation: "event.type === \'status\'"'); + } + + return event.status; + }).subscribe({ next: callback, error: () => {} })); + } }; return task; } @@ -112,43 +114,19 @@ export function taskFromObservable(observable: Observable): Task { /** * Convert a task to an observable of events. */ -export function observableFromTask(task: Task): Observable { - return Observable.create(observer => { +function observableFromTask(task) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { let finished = false; - const messages = - typeof task.onMessage === 'function' - ? observableFromSubscribeFunction(task.onMessage.bind(task)).map( - message => ({type: 'message', message}), - ) - : Observable.never(); - const progresses = - typeof task.onProgress === 'function' - ? observableFromSubscribeFunction(task.onProgress.bind(task)).map( - progress => ({type: 'progress', progress}), - ) - : Observable.never(); - const results = - typeof task.onResult === 'function' - ? observableFromSubscribeFunction(task.onResult.bind(task)).map( - result => ({type: 'result', result}), - ) - : Observable.never(); - const statuses = - typeof task.onStatusChange === 'function' - ? observableFromSubscribeFunction(task.onStatusChange.bind(task)).map( - status => ({type: 'status', status}), - ) - : Observable.never(); - - const completeEvents = observableFromSubscribeFunction( - task.onDidComplete.bind(task), - ); - const errors = observableFromSubscribeFunction( - task.onDidError.bind(task), - ).switchMap(Observable.throw); - - const subscription = new Subscription(); + const messages = typeof task.onMessage === 'function' ? (0, (_event || _load_event()).observableFromSubscribeFunction)(task.onMessage.bind(task)).map(message => ({ type: 'message', message })) : _rxjsBundlesRxMinJs.Observable.never(); + const progresses = typeof task.onProgress === 'function' ? (0, (_event || _load_event()).observableFromSubscribeFunction)(task.onProgress.bind(task)).map(progress => ({ type: 'progress', progress })) : _rxjsBundlesRxMinJs.Observable.never(); + const results = typeof task.onResult === 'function' ? (0, (_event || _load_event()).observableFromSubscribeFunction)(task.onResult.bind(task)).map(result => ({ type: 'result', result })) : _rxjsBundlesRxMinJs.Observable.never(); + const statuses = typeof task.onStatusChange === 'function' ? (0, (_event || _load_event()).observableFromSubscribeFunction)(task.onStatusChange.bind(task)).map(status => ({ type: 'status', status })) : _rxjsBundlesRxMinJs.Observable.never(); + + const completeEvents = (0, (_event || _load_event()).observableFromSubscribeFunction)(task.onDidComplete.bind(task)); + const errors = (0, (_event || _load_event()).observableFromSubscribeFunction)(task.onDidError.bind(task)).switchMap(_rxjsBundlesRxMinJs.Observable.throw); + + const subscription = new _rxjsBundlesRxMinJs.Subscription(); subscription.add(() => { if (!finished) { @@ -156,19 +134,14 @@ export function observableFromTask(task: Task): Observable { } }); - subscription.add( - Observable.merge(messages, progresses, results, statuses, errors) - .takeUntil(completeEvents) - .do({ - complete: () => { - finished = true; - }, - error: () => { - finished = true; - }, - }) - .subscribe(observer), - ); + subscription.add(_rxjsBundlesRxMinJs.Observable.merge(messages, progresses, results, statuses, errors).takeUntil(completeEvents).do({ + complete: () => { + finished = true; + }, + error: () => { + finished = true; + } + }).subscribe(observer)); task.start(); @@ -176,37 +149,26 @@ export function observableFromTask(task: Task): Observable { }); } -export function createMessage( - text: string, - level: Level, -): Observable { - return Observable.of({ +function createMessage(text, level) { + return _rxjsBundlesRxMinJs.Observable.of({ type: 'message', - message: {text, level}, + message: { text, level } }); } -export function createResult(result: mixed): Observable { - return Observable.of({ +function createResult(result) { + return _rxjsBundlesRxMinJs.Observable.of({ type: 'result', - result, + result }); } -export function createStatus(status: string): Observable { - return Observable.of({type: 'status', status}); +function createStatus(status) { + return _rxjsBundlesRxMinJs.Observable.of({ type: 'status', status }); } -export function createStep( - stepName: ?string, - action: () => Observable, -): Observable { - return Observable.concat( - Observable.of({type: 'progress', progress: null}), - // flowlint-next-line sketchy-null-string:off - stepName - ? Observable.of({type: 'status', status: stepName}) - : Observable.empty(), - Observable.defer(action), - ); -} +function createStep(stepName, action) { + return _rxjsBundlesRxMinJs.Observable.concat(_rxjsBundlesRxMinJs.Observable.of({ type: 'progress', progress: null }), + // flowlint-next-line sketchy-null-string:off + stepName ? _rxjsBundlesRxMinJs.Observable.of({ type: 'status', status: stepName }) : _rxjsBundlesRxMinJs.Observable.empty(), _rxjsBundlesRxMinJs.Observable.defer(action)); +} \ No newline at end of file diff --git a/pkg/commons-node/xfetch.js b/pkg/commons-node/xfetch.js index f8735292d3..f67fe15184 100644 --- a/pkg/commons-node/xfetch.js +++ b/pkg/commons-node/xfetch.js @@ -1,3 +1,23 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _systemInfo; + +function _load_systemInfo() { + return _systemInfo = require('./system-info'); +} + +var _nodeFetch; + +function _load_nodeFetch() { + return _nodeFetch = _interopRequireDefault(require('node-fetch')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +25,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ @@ -40,20 +60,14 @@ // The export is typed with `typeof fetch` so flow treats the polyfill as the // real `fetch`. -import {isRunningInTest} from './system-info'; -import nodeFetch from 'node-fetch'; - -const fetchImpl = - typeof global.fetch === 'function' ? global.fetch : (nodeFetch: typeof fetch); +const fetchImpl = typeof global.fetch === 'function' ? global.fetch : (_nodeFetch || _load_nodeFetch()).default; // Stub out `fetch` in all tests so we don't inadvertently rely on external URLs. -const testFetch: typeof fetch = function testFetch(url) { +const testFetch = function testFetch(url) { if (typeof url === 'string' && url.startsWith('http://localhost')) { return fetchImpl(url); } - return Promise.reject( - Error('fetch is stubbed out for testing. Use a spy instead.'), - ); + return Promise.reject(Error('fetch is stubbed out for testing. Use a spy instead.')); }; -export default (isRunningInTest() ? testFetch : fetchImpl); +exports.default = (0, (_systemInfo || _load_systemInfo()).isRunningInTest)() ? testFetch : fetchImpl; \ No newline at end of file diff --git a/pkg/dev-nuclide-contributors/lib/NuclidePackageReloadDashProvider.js b/pkg/dev-nuclide-contributors/lib/NuclidePackageReloadDashProvider.js deleted file mode 100644 index 4dc0d82c17..0000000000 --- a/pkg/dev-nuclide-contributors/lib/NuclidePackageReloadDashProvider.js +++ /dev/null @@ -1,79 +0,0 @@ -/** - * 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 - */ - -import type { - GenericResult, - DashProvider, - QueryContext, - // $FlowFB -} from '../../fb-dash/lib/types'; -import fuzzAldrinPlus from 'fuzzaldrin-plus'; - -import highlightText from 'nuclide-commons-ui/highlightText'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -const ELLIPSES = '\u2026'; - -export default class NuclidePackageReloadDashProvider - implements DashProvider { - _reloader: string => Promise; - - debounceDelay = 0; - display = { - title: 'Nuclide: Reload package', - prompt: { - verb: 'Reload', - object: 'Nuclide packages', - }, - action: 'nuclide-reload-package-dash-provider:toggle-provider', - }; - - includeAsFallback = true; - prefix = 'npr'; - priority = 10; - - constructor(reloader: string => Promise) { - this._reloader = reloader; - } - - executeQuery( - query: string, - queryContext: QueryContext, - callback: (items: Array) => mixed, - ): IDisposable { - let results; - if (query === '') { - results = [ - { - type: 'generic', - relevance: 1, - primaryText: `Nuclide: Reload package ${ELLIPSES}`, - }, - ]; - } else { - results = atom.packages.getLoadedPackages().map(pkg => { - return { - type: 'generic', - primaryText: highlightText`Reload ${pkg.name}`, - secondaryText: pkg.metadata.description, - relevance: fuzzAldrinPlus.score(pkg.name, query), - - callback: () => { - this._reloader(pkg.name); - }, - }; - }); - } - - callback(results); - return new UniversalDisposable(); - } -} diff --git a/pkg/dev-nuclide-contributors/lib/main.js b/pkg/dev-nuclide-contributors/lib/main.js deleted file mode 100644 index c10d8edc0a..0000000000 --- a/pkg/dev-nuclide-contributors/lib/main.js +++ /dev/null @@ -1,147 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -// $FlowFB -import type {RegisterProvider} from '../../fb-dash/lib/types'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import invariant from 'assert'; -import Module from 'module'; -import path from 'path'; // eslint-disable-line nuclide-internal/prefer-nuclide-uri - -import NuclidePackageReloadDashProvider from './NuclidePackageReloadDashProvider'; - -class Activation { - _disposables: UniversalDisposable; - _reloader: string => Promise; - - constructor() { - this._disposables = new UniversalDisposable( - /** - * Open any file in the "Run Package Specs" window. - */ - atom.commands.add( - 'atom-workspace', - 'nuclide-contributors:run-current-spec', - { - tags: ['test'], - didDispatch: () => { - const activePaneItem = atom.workspace.getActivePaneItem(); - if (activePaneItem == null) { - atom.notifications.addError('No active editor!'); - return; - } - const activePath = activePaneItem.getPath(); - const ipcRenderer = require('electron').ipcRenderer; // Atom 1.7+ - invariant(ipcRenderer != null); - ipcRenderer.send('run-package-specs', activePath); - }, - }, - ), - /** - * Force saving Atom state (for debugging). - */ - atom.commands.add( - 'atom-workspace', - 'nuclide-contributors:save-atom-state', - async () => { - let state; - try { - // $FlowIgnore - await atom.saveState(); - state = await atom.loadState(); - } catch (err) { - console.log(err); // eslint-disable-line no-console - atom.notifications.addError(`Failed to save state: ${err.message}`); - return; - } - - console.log(state); // eslint-disable-line no-console - atom.notifications.addInfo('State saved!'); - }, - ), - /** - * Allows running `require('nuclide-commons/promise');`. - * Useful for debugging from the devtools console. - */ - atom.commands.add( - 'atom-workspace', - 'nuclide-contributors:add-nuclide-modules-to-global-paths', - () => { - const nuclidePack = atom.packages.getLoadedPackage('nuclide'); - if (!nuclidePack) { - atom.notifications.addError('Nuclide is not loaded.'); - return; - } - [ - path.join(nuclidePack.path, 'node_modules'), - path.join(nuclidePack.path, 'pkg'), - ].filter(nuclidePath => { - // $FlowIgnore - const {globalPaths} = Module; - if (globalPaths.indexOf(nuclidePath) === -1) { - globalPaths.push(nuclidePath); - // eslint-disable-next-line no-console - console.log('Added "%s" to Module.globalPaths', nuclidePath); - } - }); - }, - ), - ); - } - - _reloader = async name => { - const pack = atom.packages.getLoadedPackage(name); - if (pack == null) { - atom.notifications.addWarning(`${name} package is not loaded`); - return; - } - - await atom.packages.deactivatePackage(name); - atom.packages.unloadPackage(name); - - // remove cache - Object.keys(require.cache) - .filter(p => p.indexOf(pack.path + path.sep) === 0) - .forEach(p => { - delete require.cache[p]; - }); - - // For Atom 1.17+ - if (global.snapshotResult && global.snapshotResult.customRequire) { - Object.keys(global.snapshotResult.customRequire.cache) - .filter(p => p.indexOf(pack.path + path.sep) !== -1) - .forEach(p => { - delete global.snapshotResult.customRequire.cache[p]; - }); - } - - const pkg = atom.packages.loadPackage(pack.path); - invariant(pkg != null); - pkg.activateResources(); - pkg.activateNow(); - }; - - consumeDash(registerProvider: RegisterProvider): IDisposable { - const disposable = new UniversalDisposable( - registerProvider(new NuclidePackageReloadDashProvider(this._reloader)), - ); - this._disposables.add(disposable); - return disposable; - } - - dispose(): void { - this._disposables.dispose(); - } -} - -createPackage(module.exports, Activation); diff --git a/pkg/dev-nuclide-contributors/menus/nuclide-contributors.json b/pkg/dev-nuclide-contributors/menus/nuclide-contributors.json deleted file mode 100644 index 348a690fd9..0000000000 --- a/pkg/dev-nuclide-contributors/menus/nuclide-contributors.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "menu": [ - { - "label": "Nuclide", - "submenu": [ - { - "label": "Nuclide Contributors", - "submenu": [ - { - "label": "Run Current Spec", - "command": "nuclide-contributors:run-current-spec" - }, - { - "label": "Save Atom State", - "command": "nuclide-contributors:save-atom-state" - }, - { - "label": "Add Nuclide Modules to Global Paths", - "command": "nuclide-contributors:add-nuclide-modules-to-global-paths" - } - ] - } - ] - } - ] -} diff --git a/pkg/dev-nuclide-contributors/package.json b/pkg/dev-nuclide-contributors/package.json deleted file mode 100644 index 90bdf4027d..0000000000 --- a/pkg/dev-nuclide-contributors/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "dev-nuclide-contributors", - "main": "./lib/main.js", - "version": "0.0.0", - "description": "Utilities useful for hacking on Nuclide", - "author": "NEEDS OWNER", - "atomTestRunner": "../../lib/test-runner-entry.js", - "nuclide": { - "packageType": "Atom", - "testRunner": "apm" - }, - "consumedServices": { - "nuclide-dash-register-provider": { - "versions": { - "0.0.0": "consumeDash" - } - } - } -} diff --git a/pkg/dev-nuclide-ui-playground/lib/Playground.js b/pkg/dev-nuclide-ui-playground/lib/Playground.js deleted file mode 100644 index 852e2ae862..0000000000 --- a/pkg/dev-nuclide-ui-playground/lib/Playground.js +++ /dev/null @@ -1,192 +0,0 @@ -/** - * 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 - */ - -import classnames from 'classnames'; -import * as React from 'react'; - -import {Button} from 'nuclide-commons-ui/Button'; -import {ButtonExamples} from 'nuclide-commons-ui/Button.example'; -import {ProgressIndicatorExamples} from 'nuclide-commons-ui/ProgressIndicators.example'; -import {CheckboxExamples} from 'nuclide-commons-ui/Checkbox.example'; -import {ModalExamples} from 'nuclide-commons-ui/showModal.example'; -import {DropdownExamples} from 'nuclide-commons-ui/Dropdown.example'; -import {FullWidthProgressBarExamples} from '../../nuclide-ui/FullWidthProgressBar.example'; -import {TabbableContainerExamples} from 'nuclide-commons-ui/TabbableContainer.example'; -import {TabExamples} from 'nuclide-commons-ui/Tabs.example'; -import {RadioGroupExamples} from 'nuclide-commons-ui/RadioGroup.example'; -import {TextInputExamples} from 'nuclide-commons-ui/TextInputs.example'; -import {ToolbarExamples} from 'nuclide-commons-ui/Toolbar.example'; -import {BadgeExamples} from '../../nuclide-ui/Badge.example'; -import {HighlightExamples} from 'nuclide-commons-ui/Highlight.example'; -import {IconExamples} from 'nuclide-commons-ui/Icon.example'; -import {TreeExamples} from 'nuclide-commons-ui/Tree.example'; -import {ListviewExamples} from 'nuclide-commons-ui/ListView.example'; -import {TableExamples} from 'nuclide-commons-ui/Table.example'; -import {RelativeDateExamples} from '../../nuclide-ui/RelativeDate.example'; -import {MultiRootChangedFilesViewExample} from '../../nuclide-ui/MultiRootChangedFilesView.example'; -import {ToggleExamples} from '../../nuclide-ui/Toggle.example'; -import {ResizableFlexContainerExamples} from '../../nuclide-ui/ResizableFlexContainer.example'; -import {MessageExamples} from 'nuclide-commons-ui/Message.example'; -import {PathWithFileIconExamples} from '../../nuclide-ui/PathWithFileIcon.example'; -import {AnimatedEllipsisExamples} from '../../nuclide-ui/AnimatedEllipsis.example'; -import RegExpFilterExamples from 'nuclide-commons-ui/RegExpFilter.example'; -import {FileChangesExamples} from '../../nuclide-ui/FileChanges.example'; -import {HighlightedCodeExamples} from 'nuclide-commons-ui/HighlightedCode.example'; - -const playgroundComponents = [ - ButtonExamples, - DropdownExamples, - ModalExamples, - ProgressIndicatorExamples, - FullWidthProgressBarExamples, - CheckboxExamples, - ToggleExamples, - TabExamples, - ResizableFlexContainerExamples, - RadioGroupExamples, - TextInputExamples, - TabbableContainerExamples, - RegExpFilterExamples, - ToolbarExamples, - BadgeExamples, - HighlightExamples, - IconExamples, - TreeExamples, - ListviewExamples, - TableExamples, - RelativeDateExamples, - MessageExamples, - MultiRootChangedFilesViewExample, - PathWithFileIconExamples, - AnimatedEllipsisExamples, - FileChangesExamples, - HighlightedCodeExamples, -]; - -type ComponentSpec = { - sectionName: string, - description: string, - examples: Array<{ - title: string, - component: React.ComponentType | (() => React.Element), - }>, -}; - -type State = { - collapsedSections: Set, -}; - -export const WORKSPACE_VIEW_URI = 'atom://nuclide/ui-playground'; - -export class Playground extends React.Component { - constructor(props: any) { - super(props); - this.state = { - collapsedSections: new Set(), - }; - } - - getTitle(): string { - return 'Nuclide UI Playground'; - } - - getIconName(): string { - return 'puzzle'; - } - - getURI(): string { - return WORKSPACE_VIEW_URI; - } - - getDefaultLocation(): string { - return 'center'; - } - - serialize(): mixed { - return { - deserializer: 'nuclide.SampleUiPlayground', - }; - } - - _collapseAllSections = (): void => { - this.setState({ - collapsedSections: new Set( - playgroundComponents.map(spec => spec.sectionName), - ), - }); - }; - - _toggleSection(sectionName: string): void { - const {collapsedSections} = this.state; - if (collapsedSections.has(sectionName)) { - collapsedSections.delete(sectionName); - } else { - collapsedSections.add(sectionName); - } - this.forceUpdate(); - } - - renderExampleForComponent = ( - spec: ComponentSpec, - index: number, - ): React.Element => { - const {sectionName, description, examples} = spec; - let renderedDescription; - let flattenedExample; - const isCollapsed = this.state.collapsedSections.has(sectionName); - if (!isCollapsed) { - flattenedExample = [].concat( - ...examples.map((example, i) => { - const {title, component: Component} = example; - return [ -

      {title}

      , -
      - -
      , - ]; - }), - ); - renderedDescription =

      {description}

      ; - } - const h1ClassName = classnames({ - 'nuclide-ui-playground-section-headline-collapsed': isCollapsed, - }); - return ( -
      -

      - {sectionName} -

      - {renderedDescription} - {flattenedExample} -
      - ); - }; - - render(): React.Node { - const renderedExamples = playgroundComponents.map( - this.renderExampleForComponent, - ); - return ( -
      -
      - -
      - {renderedExamples} -
      - ); - } -} diff --git a/pkg/dev-nuclide-ui-playground/lib/main.js b/pkg/dev-nuclide-ui-playground/lib/main.js deleted file mode 100644 index 8eac57d852..0000000000 --- a/pkg/dev-nuclide-ui-playground/lib/main.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import {destroyItemWhere} from 'nuclide-commons-atom/destroyItemWhere'; -import {viewableFromReactElement} from '../../commons-atom/viewableFromReactElement'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Playground, WORKSPACE_VIEW_URI} from './Playground'; -import invariant from 'assert'; -import * as React from 'react'; - -let disposables: ?UniversalDisposable = null; - -export function activate(): void { - disposables = registerCommandAndOpener(); -} - -export function deactivate(): void { - invariant(disposables != null); - disposables.dispose(); - disposables = null; -} - -function registerCommandAndOpener(): UniversalDisposable { - return new UniversalDisposable( - atom.workspace.addOpener(uri => { - if (uri === WORKSPACE_VIEW_URI) { - return viewableFromReactElement(); - } - }), - () => destroyItemWhere(item => item instanceof Playground), - // eslint-disable-next-line nuclide-internal/atom-apis - atom.commands.add('atom-workspace', 'nuclide-ui-playground:toggle', () => { - atom.workspace.toggle(WORKSPACE_VIEW_URI); - }), - ); -} - -export function deserializeSampleUiPlayground(): atom$PaneItem { - return viewableFromReactElement(); -} diff --git a/pkg/dev-nuclide-ui-playground/package.json b/pkg/dev-nuclide-ui-playground/package.json deleted file mode 100644 index a53e4f300c..0000000000 --- a/pkg/dev-nuclide-ui-playground/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "dev-nuclide-ui-playground", - "main": "./lib/main.js", - "version": "0.0.0", - "description": "Various examples of how to use generic UI components.", - "author": "Nuclide : Core UI", - "atomTestRunner": "../../lib/test-runner-entry.js", - "deserializers": { - "nuclide.SampleUiPlayground": "deserializeSampleUiPlayground" - }, - "nuclide": { - "packageType": "Atom", - "testRunner": "apm" - } -} diff --git a/pkg/dev-nuclide-ui-playground/styles/nuclide-ui-playground.less b/pkg/dev-nuclide-ui-playground/styles/nuclide-ui-playground.less deleted file mode 100644 index 23a9acc0d1..0000000000 --- a/pkg/dev-nuclide-ui-playground/styles/nuclide-ui-playground.less +++ /dev/null @@ -1,56 +0,0 @@ -@import "ui-variables"; -@import "syntax-variables"; - -@nuclide-ui-playground-background: lighten(@tool-panel-background-color, 2%); - -.nuclide-ui-playground { - background-color: @nuclide-ui-playground-background; - overflow: auto; - padding: 20px 0; - width: 100%; - - h1 { - color: @text-color-highlight; - cursor: pointer; - font-size: 1.6em; - font-weight: bold; - margin: 0; - - &.nuclide-ui-playground-section-headline-collapsed { - color: @text-color; - } - - &:hover { - color: @text-color-highlight; - } - } - - h2 { - margin: 1.75em 0 0 0; - color: @text-color-highlight; - } - - p { - font-size: 1.2em; - margin: 0.5em 0; - } -} - -.nuclide-ui-playground-header { - padding: @component-padding; - text-align: right; -} - -section.nuclide-ui-playground-section { - padding: @component-padding * 2; -} - -.nuclide-ui-playground-example { - background-color: @nuclide-ui-playground-background; - border-radius: @component-border-radius; - border: 1px solid @tool-panel-border-color; - margin: @component-padding 0; - overflow: hidden; - padding: @component-padding; - position: relative; -} diff --git a/pkg/nuclide-adb-logcat/lib/Activation.js b/pkg/nuclide-adb-logcat/lib/Activation.js index 5ac9659eb3..92cb140df1 100644 --- a/pkg/nuclide-adb-logcat/lib/Activation.js +++ b/pkg/nuclide-adb-logcat/lib/Activation.js @@ -1,91 +1,98 @@ -/** - * 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 - */ - -import type {OutputService} from 'atom-ide-ui'; - -import formatEnoentNotification from '../../commons-atom/format-enoent-notification'; -import {createProcessStream} from './createProcessStream'; -import createMessageStream from './createMessageStream'; -import {LogTailer} from '../../nuclide-console-base/lib/LogTailer'; -import {Observable} from 'rxjs'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -export default class Activation { - _disposables: UniversalDisposable; - _logTailer: LogTailer; - - constructor(state: ?Object) { - const message$ = Observable.defer(() => - createMessageStream( - createProcessStream() - // Retry 3 times (unless we get a ENOENT) - .retryWhen(errors => - errors.scan((errCount, err) => { - if (isNoEntError(err) || errCount >= 2) { - throw err; - } - return errCount + 1; - }, 0), - ), - ), - ); - - this._logTailer = new LogTailer({ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _formatEnoentNotification; + +function _load_formatEnoentNotification() { + return _formatEnoentNotification = _interopRequireDefault(require('../../commons-atom/format-enoent-notification')); +} + +var _createProcessStream; + +function _load_createProcessStream() { + return _createProcessStream = require('./createProcessStream'); +} + +var _createMessageStream; + +function _load_createMessageStream() { + return _createMessageStream = _interopRequireDefault(require('./createMessageStream')); +} + +var _LogTailer; + +function _load_LogTailer() { + return _LogTailer = require('../../nuclide-console-base/lib/LogTailer'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Activation { + + constructor(state) { + const message$ = _rxjsBundlesRxMinJs.Observable.defer(() => (0, (_createMessageStream || _load_createMessageStream()).default)((0, (_createProcessStream || _load_createProcessStream()).createProcessStream)() + // Retry 3 times (unless we get a ENOENT) + .retryWhen(errors => errors.scan((errCount, err) => { + if (isNoEntError(err) || errCount >= 2) { + throw err; + } + return errCount + 1; + }, 0)))); + + this._logTailer = new (_LogTailer || _load_LogTailer()).LogTailer({ name: 'adb Logcat', messages: message$, trackingEvents: { start: 'adb-logcat:start', stop: 'adb-logcat:stop', - restart: 'adb-logcat:restart', + restart: 'adb-logcat:restart' }, handleError(err) { if (isNoEntError(err)) { - const {message, meta} = formatEnoentNotification({ + const { message, meta } = (0, (_formatEnoentNotification || _load_formatEnoentNotification()).default)({ feature: 'Tailing Android (adb) logs', toolName: 'adb', - pathSetting: 'nuclide-adb-logcat.pathToAdb', + pathSetting: 'nuclide-adb-logcat.pathToAdb' }); atom.notifications.addError(message, meta); return; } throw err; - }, + } }); - this._disposables = new UniversalDisposable( - () => { - this._logTailer.stop(); - }, - atom.commands.add('atom-workspace', { - 'nuclide-adb-logcat:start': () => this._logTailer.start(), - 'nuclide-adb-logcat:stop': () => this._logTailer.stop(), - 'nuclide-adb-logcat:restart': () => this._logTailer.restart(), - }), - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { + this._logTailer.stop(); + }, atom.commands.add('atom-workspace', { + 'nuclide-adb-logcat:start': () => this._logTailer.start(), + 'nuclide-adb-logcat:stop': () => this._logTailer.stop(), + 'nuclide-adb-logcat:restart': () => this._logTailer.restart() + })); } - consumeOutputService(api: OutputService): void { - this._disposables.add( - api.registerOutputProvider({ - id: 'adb logcat', - messages: this._logTailer.getMessages(), - observeStatus: cb => this._logTailer.observeStatus(cb), - start: () => { - this._logTailer.start(); - }, - stop: () => { - this._logTailer.stop(); - }, - }), - ); + consumeOutputService(api) { + this._disposables.add(api.registerOutputProvider({ + id: 'adb logcat', + messages: this._logTailer.getMessages(), + observeStatus: cb => this._logTailer.observeStatus(cb), + start: () => { + this._logTailer.start(); + }, + stop: () => { + this._logTailer.stop(); + } + })); } dispose() { @@ -93,4 +100,15 @@ export default class Activation { } } -const isNoEntError = err => (err: any).code === 'ENOENT'; +exports.default = Activation; /** + * 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. + * + * + * @format + */ + +const isNoEntError = err => err.code === 'ENOENT'; \ No newline at end of file diff --git a/pkg/nuclide-adb-logcat/lib/createMessage.js b/pkg/nuclide-adb-logcat/lib/createMessage.js index cd418be927..ac47320f79 100644 --- a/pkg/nuclide-adb-logcat/lib/createMessage.js +++ b/pkg/nuclide-adb-logcat/lib/createMessage.js @@ -1,3 +1,14 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = createMessage; + + +/** + * Convert a structured logcat entry into the format that nuclide-console wants. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,42 +16,41 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {ConsoleLevel, ConsoleMessage} from 'atom-ide-ui'; -import type {LogcatEntry, Priority} from './types'; - -/** - * Convert a structured logcat entry into the format that nuclide-console wants. - */ -export default function createMessage(entry: LogcatEntry): ConsoleMessage { - const priority = (entry.metadata && entry.metadata.priority) || 'I'; - const tag = (entry.metadata && entry.metadata.tag) || null; +function createMessage(entry) { + const priority = entry.metadata && entry.metadata.priority || 'I'; + const tag = entry.metadata && entry.metadata.tag || null; return { text: entry.message, level: priorityToLevel(priority), - tags: tag ? [tag] : null, + tags: tag ? [tag] : null }; } -function priorityToLevel(priority: Priority): ConsoleLevel { +function priorityToLevel(priority) { switch (priority) { - case 'W': // warn + case 'W': + // warn return 'warning'; case 'E': // error - case 'F': // fatal + case 'F': + // fatal return 'error'; - case 'S': // silent + case 'S': + // silent throw new Error('Silent messages should be filtered'); - case 'D': // debug + case 'D': + // debug return 'debug'; - case 'I': // info + case 'I': + // info // Even though the console has an "info" level, this is the default for adb, so we use "log." return 'log'; case 'V': // verbose default: return 'info'; } -} +} \ No newline at end of file diff --git a/pkg/nuclide-adb-logcat/lib/createMessageStream.js b/pkg/nuclide-adb-logcat/lib/createMessageStream.js index d194b1d28e..fe03cf92d5 100644 --- a/pkg/nuclide-adb-logcat/lib/createMessageStream.js +++ b/pkg/nuclide-adb-logcat/lib/createMessageStream.js @@ -1,28 +1,47 @@ -/** - * 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 - */ - -import type {ConsoleMessage} from 'atom-ide-ui'; - -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {fastDebounce} from 'nuclide-commons/observable'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import createMessage from './createMessage'; -import parseLogcatMetadata from './parseLogcatMetadata'; -import {Observable} from 'rxjs'; - -export default function createMessageStream( - line$: Observable, -): Observable { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = createMessageStream; + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _observable; + +function _load_observable() { + return _observable = require('../../../modules/nuclide-commons/observable'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _createMessage; + +function _load_createMessage() { + return _createMessage = _interopRequireDefault(require('./createMessage')); +} + +var _parseLogcatMetadata; + +function _load_parseLogcatMetadata() { + return _parseLogcatMetadata = _interopRequireDefault(require('./parseLogcatMetadata')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function createMessageStream(line$) { // Separate the lines into groups, beginning with metadata lines. - const messages = Observable.create(observer => { + const messages = _rxjsBundlesRxMinJs.Observable.create(observer => { let buffer = []; let prevMetadata = null; const prevLineIsBlank = () => buffer[buffer.length - 1] === ''; @@ -39,7 +58,7 @@ export default function createMessageStream( observer.next({ metadata: prevMetadata, - message: buffer.join('\n'), + message: buffer.join('\n') }); buffer = []; prevMetadata = null; @@ -47,70 +66,68 @@ export default function createMessageStream( const sharedLine$ = line$.share(); - return new UniversalDisposable( - // Buffer incoming lines. - sharedLine$.subscribe( - // onNext - line => { - let metadata; - const hasPreviousLines = buffer.length > 0; - - if (!hasPreviousLines || prevLineIsBlank()) { - metadata = parseLogcatMetadata(line); - } - - if (metadata) { - // We've reached a new message so the other one must be done. - flush(); - prevMetadata = metadata; - } else { - buffer.push(line); - } - }, - // onError - error => { - flush(); - observer.error(error); - }, - // onCompleted - () => { - flush(); - observer.complete(); - }, - ), - // We know *for certain* that we have a complete entry once we see the metadata for the next - // one. But what if the next one takes a long time to happen? After a certain point, we need - // to just assume we have the complete entry and move on. - sharedLine$.let(fastDebounce(200)).subscribe(flush), - ); - }).map(createMessage); + return new (_UniversalDisposable || _load_UniversalDisposable()).default( + // Buffer incoming lines. + sharedLine$.subscribe( + // onNext + line => { + let metadata; + const hasPreviousLines = buffer.length > 0; + + if (!hasPreviousLines || prevLineIsBlank()) { + metadata = (0, (_parseLogcatMetadata || _load_parseLogcatMetadata()).default)(line); + } + + if (metadata) { + // We've reached a new message so the other one must be done. + flush(); + prevMetadata = metadata; + } else { + buffer.push(line); + } + }, + // onError + error => { + flush(); + observer.error(error); + }, + // onCompleted + () => { + flush(); + observer.complete(); + }), + // We know *for certain* that we have a complete entry once we see the metadata for the next + // one. But what if the next one takes a long time to happen? After a certain point, we need + // to just assume we have the complete entry and move on. + sharedLine$.let((0, (_observable || _load_observable()).fastDebounce)(200)).subscribe(flush)); + }).map((_createMessage || _load_createMessage()).default); return filter(messages).share(); -} +} /** + * 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. + * + * + * @format + */ -function filter( - messages: Observable, -): Observable { - const patterns = (featureConfig.observeAsStream( - 'nuclide-adb-logcat.whitelistedTags', - ): Observable).map(source => { +function filter(messages) { + const patterns = (_featureConfig || _load_featureConfig()).default.observeAsStream('nuclide-adb-logcat.whitelistedTags').map(source => { try { return new RegExp(source); } catch (err) { - atom.notifications.addError( - 'The nuclide-adb-logcat.whitelistedTags setting contains an invalid regular expression' + - ' string. Fix it in your Atom settings.', + atom.notifications.addError('The nuclide-adb-logcat.whitelistedTags setting contains an invalid regular expression' + ' string. Fix it in your Atom settings.'); + return (/.*/ ); - return /.*/; } }); - return messages - .withLatestFrom(patterns) - .filter(([message, pattern]) => { - // Add an empty tag to untagged messages so they cfeaturean be matched by `.*` etc. - const tags = message.tags == null ? [''] : message.tags; - return tags.some(tag => pattern.test(tag)); - }) - .map(([message, pattern]) => message); -} + return messages.withLatestFrom(patterns).filter(([message, pattern]) => { + // Add an empty tag to untagged messages so they cfeaturean be matched by `.*` etc. + const tags = message.tags == null ? [''] : message.tags; + return tags.some(tag => pattern.test(tag)); + }).map(([message, pattern]) => message); +} \ No newline at end of file diff --git a/pkg/nuclide-adb-logcat/lib/createProcessStream.js b/pkg/nuclide-adb-logcat/lib/createProcessStream.js index b6843ecafc..4f149fc1c7 100644 --- a/pkg/nuclide-adb-logcat/lib/createProcessStream.js +++ b/pkg/nuclide-adb-logcat/lib/createProcessStream.js @@ -1,3 +1,32 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.createProcessStream = createProcessStream; + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _observable; + +function _load_observable() { + return _observable = require('../../../modules/nuclide-commons/observable'); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,72 +34,51 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import {observeProcess} from 'nuclide-commons/process'; -import {compact} from 'nuclide-commons/observable'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {Observable} from 'rxjs'; - -export function createProcessStream(): Observable { - const processEvents = observeProcess( - ((featureConfig.get('nuclide-adb-logcat.pathToAdb'): any): string), - ['logcat', '-v', 'long'], - {/* TODO(T17353599) */ isExitError: () => false}, - ) - .catch(error => Observable.of({kind: 'error', error})) // TODO(T17463635) - .share(); - const stdoutEvents = processEvents - .filter(event => event.kind === 'stdout') - // Not all versions of adb have a way to skip historical logs so we just ignore the first - // second. - .skipUntil(Observable.interval(1000).take(1)); +function createProcessStream() { + const processEvents = (0, (_process || _load_process()).observeProcess)((_featureConfig || _load_featureConfig()).default.get('nuclide-adb-logcat.pathToAdb'), ['logcat', '-v', 'long'], { /* TODO(T17353599) */isExitError: () => false }).catch(error => _rxjsBundlesRxMinJs.Observable.of({ kind: 'error', error })) // TODO(T17463635) + .share(); + const stdoutEvents = processEvents.filter(event => event.kind === 'stdout') + // Not all versions of adb have a way to skip historical logs so we just ignore the first + // second. + .skipUntil(_rxjsBundlesRxMinJs.Observable.interval(1000).take(1)); const otherEvents = processEvents.filter(event => event.kind !== 'stdout'); - return ( - compact( - Observable.merge(stdoutEvents, otherEvents) - // Forward the event, but add the last line of std err too. We can use this later if the - // process exits to provide more information. - .scan( - (acc, event) => { - switch (event.kind) { - case 'error': - throw event.error; - case 'exit': - throw new Error(acc.lastError || ''); - case 'stdout': - // Keep track of the last error so that we can show it to users if the process dies - // badly. If we get a non-error message, then the last error we saw wasn't the one - // that killed the process, so throw it away. Why is this not on stderr? I don't know. - return { - event, - lastError: parseError(event.data) || acc.lastError, - }; - case 'stderr': - return { - ...acc, - lastError: event.data || acc.lastError, - event, - }; - default: - // This should never happen. - throw new Error(`Invalid event kind: ${event.kind}`); - } - }, - {event: null, lastError: null}, - ) - .map(acc => acc.event), - ) - // Only get the text from stdout. - .filter(event => event.kind === 'stdout') - .map(event => event.data && event.data.replace(/\r*\n$/, '')) - ); + return (0, (_observable || _load_observable()).compact)(_rxjsBundlesRxMinJs.Observable.merge(stdoutEvents, otherEvents) + // Forward the event, but add the last line of std err too. We can use this later if the + // process exits to provide more information. + .scan((acc, event) => { + switch (event.kind) { + case 'error': + throw event.error; + case 'exit': + throw new Error(acc.lastError || ''); + case 'stdout': + // Keep track of the last error so that we can show it to users if the process dies + // badly. If we get a non-error message, then the last error we saw wasn't the one + // that killed the process, so throw it away. Why is this not on stderr? I don't know. + return { + event, + lastError: parseError(event.data) || acc.lastError + }; + case 'stderr': + return Object.assign({}, acc, { + lastError: event.data || acc.lastError, + event + }); + default: + // This should never happen. + throw new Error(`Invalid event kind: ${event.kind}`); + } + }, { event: null, lastError: null }).map(acc => acc.event)) + // Only get the text from stdout. + .filter(event => event.kind === 'stdout').map(event => event.data && event.data.replace(/\r*\n$/, '')); } -function parseError(line: string): ?string { +function parseError(line) { const match = line.match(/^ERROR:\s*(.*)/); return match == null ? null : match[1].trim(); -} +} \ No newline at end of file diff --git a/pkg/nuclide-adb-logcat/lib/main.js b/pkg/nuclide-adb-logcat/lib/main.js index 4c7781457e..025e08aaec 100644 --- a/pkg/nuclide-adb-logcat/lib/main.js +++ b/pkg/nuclide-adb-logcat/lib/main.js @@ -1,32 +1,48 @@ -/** - * 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 - */ - -import type {OutputService} from 'atom-ide-ui'; - -import invariant from 'assert'; -import Activation from './Activation'; - -let activation: ?Activation = null; - -export function activate(state: ?Object) { - activation = new Activation(state); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.activate = activate; +exports.deactivate = deactivate; +exports.consumeOutputService = consumeOutputService; + +var _Activation; + +function _load_Activation() { + return _Activation = _interopRequireDefault(require('./Activation')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +let activation = null; /** + * 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. + * + * + * @format + */ + +function activate(state) { + activation = new (_Activation || _load_Activation()).default(state); } -export function deactivate() { - invariant(activation != null); +function deactivate() { + if (!(activation != null)) { + throw new Error('Invariant violation: "activation != null"'); + } + activation.dispose(); activation = null; } -export function consumeOutputService(api: OutputService): void { - invariant(activation); +function consumeOutputService(api) { + if (!activation) { + throw new Error('Invariant violation: "activation"'); + } + activation.consumeOutputService(api); -} +} \ No newline at end of file diff --git a/pkg/nuclide-adb-logcat/lib/parseLogcatMetadata.js b/pkg/nuclide-adb-logcat/lib/parseLogcatMetadata.js index a9ba81b8c1..610cf5f544 100644 --- a/pkg/nuclide-adb-logcat/lib/parseLogcatMetadata.js +++ b/pkg/nuclide-adb-logcat/lib/parseLogcatMetadata.js @@ -1,21 +1,25 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = parseLogcatMetadata; -import type {Metadata, Priority} from './types'; // Example: [ 01-14 17:14:44.285 640: 656 E/KernelUidCpuTimeReader ] // eslint-disable-next-line max-len -const METADATA_REGEX = /^\[ (\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3})\s+(\d+):(?:(0x[a-f0-9]+)|\s*(\d+))\s+(V|D|I|W|E|F|S)\/(.+) ]$/; +const METADATA_REGEX = /^\[ (\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3})\s+(\d+):(?:(0x[a-f0-9]+)|\s*(\d+))\s+(V|D|I|W|E|F|S)\/(.+) ]$/; /** + * 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. + * + * + * @format + */ -export default function parseLogcatMetadata(line: string): ?Metadata { +function parseLogcatMetadata(line) { const match = line.match(METADATA_REGEX); if (match == null) { @@ -28,7 +32,7 @@ export default function parseLogcatMetadata(line: string): ?Metadata { time, pid: parseInt(pid, 10), tid: hexTid == null ? parseInt(decTid, 10) : parseInt(hexTid, 16), - priority: ((priority: any): Priority), - tag, + priority: priority, + tag }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-adb-logcat/lib/types.js b/pkg/nuclide-adb-logcat/lib/types.js index 62e44b6e32..a726efc43f 100644 --- a/pkg/nuclide-adb-logcat/lib/types.js +++ b/pkg/nuclide-adb-logcat/lib/types.js @@ -1,25 +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 strict - * @format - */ - -export type Priority = 'V' | 'D' | 'I' | 'W' | 'E' | 'F' | 'S'; - -export type LogcatEntry = { - message: string, - metadata: ?Metadata, -}; - -export type Metadata = { - time: string, - pid: number, - tid: number, - priority: Priority, - tag: string, -}; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-adb-logcat/spec/createMessageStream-spec.js b/pkg/nuclide-adb-logcat/spec/createMessageStream-spec.js deleted file mode 100644 index c8506dfd3f..0000000000 --- a/pkg/nuclide-adb-logcat/spec/createMessageStream-spec.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import featureConfig from 'nuclide-commons-atom/feature-config'; -import createMessageStream from '../lib/createMessageStream'; -import {Observable} from 'rxjs'; - -describe('createMessageStream', () => { - it('splits the output by message', () => { - const original = featureConfig.observeAsStream.bind(featureConfig); - spyOn(featureConfig, 'observeAsStream').andCallFake( - name => - name === 'nuclide-adb-logcat.whitelistedTags' - ? Observable.of('.*') - : original(name), - ); - - waitsForPromise(async () => { - const output = Observable.from([ - '[ 01-14 17:15:01.003 640: 654 I/ProcessStatsService ]', - 'Prepared write state in 0ms', - '', - '[ 01-14 17:15:01.003 640: 654 I/ProcessStatsService ]', - 'Prepared write state in 0ms', - '', - ]); - - const messages = await createMessageStream(output) - .map(message => message.text) - .toArray() - .toPromise(); - - expect(messages.length).toBe(2); - messages.forEach(message => { - expect(message).toBe('Prepared write state in 0ms'); - }); - }); - }); - - it('only includes messages with whitelisted tags', () => { - const original = featureConfig.observeAsStream.bind(featureConfig); - spyOn(featureConfig, 'observeAsStream').andCallFake( - name => - name === 'nuclide-adb-logcat.whitelistedTags' - ? Observable.of('ExampleTag') - : original(name), - ); - - waitsForPromise(async () => { - const output = Observable.from([ - '[ 01-14 17:15:01.003 640: 654 I/ProcessStatsService ]', - 'Bad', - '', - '[ 01-14 17:15:01.003 640: 654 I/ExampleTag ]', - 'Good', - '', - ]); - - const messages = await createMessageStream(output) - .map(message => message.text) - .toArray() - .toPromise(); - - expect(messages).toEqual(['Good']); - }); - }); - - it('shows an error (once) if the regular expression is invalid', () => { - spyOn(atom.notifications, 'addError'); - const original = featureConfig.observeAsStream.bind(featureConfig); - spyOn(featureConfig, 'observeAsStream').andCallFake( - name => - name === 'nuclide-adb-logcat.whitelistedTags' - ? Observable.of('(') - : original(name), - ); - - waitsForPromise(async () => { - const output = Observable.from([ - '[ 01-14 17:15:01.003 640: 654 I/ProcessStatsService ]', - 'Bad', - '', - '[ 01-14 17:15:01.003 640: 654 I/ExampleTag ]', - 'Good', - '', - ]); - await createMessageStream(output).toPromise(); - expect(atom.notifications.addError.callCount).toBe(1); - }); - }); -}); diff --git a/pkg/nuclide-adb-logcat/spec/parseLogcatMetadata-spec.js b/pkg/nuclide-adb-logcat/spec/parseLogcatMetadata-spec.js deleted file mode 100644 index 4f9080b463..0000000000 --- a/pkg/nuclide-adb-logcat/spec/parseLogcatMetadata-spec.js +++ /dev/null @@ -1,64 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import invariant from 'assert'; -import parseLogcatMetadata from '../lib/parseLogcatMetadata'; - -describe('parseLogcatMetadata', () => { - const formats = [ - '[ 01-14 17:15:01.003 640: 654 I/ProcessStatsService ]', - // Older versions use hex for the tid. - '[ 01-14 17:15:01.003 640:0x28e I/ProcessStatsService ]', - ]; - - formats.forEach(raw => { - describe(raw, () => { - const parsed = parseLogcatMetadata(raw); - invariant(parsed != null); - - it('parses the date and time', () => { - expect(parsed.time).toBe('01-14 17:15:01.003'); - }); - - it('parses the pid', () => { - expect(parsed.pid).toBe(640); - }); - - it('parses the tid', () => { - expect(parsed.tid).toBe(654); - }); - - it('parses the priority', () => { - expect(parsed.priority).toBe('I'); - }); - - it('parses the tag', () => { - expect(parsed.tag).toBe('ProcessStatsService'); - }); - }); - }); - - it('parses weird tags', () => { - const parsed = parseLogcatMetadata( - '[ 05-10 17:49:43.925 5846: 5993 D/fb4a(:):PeriodicForegroundScheduler ]', - ); - invariant(parsed != null); - expect(parsed.tag).toBe('fb4a(:):PeriodicForegroundScheduler'); - }); - - it('parses the 5-digit tid', () => { - const parsed = parseLogcatMetadata( - '[ 01-28 14:59:27.633 3211:15223 I/ReactNativeJS ]', - ); - invariant(parsed != null); - expect(parsed.tid).toBe(15223); - }); -}); diff --git a/pkg/nuclide-adb-sdb-base/lib/SdbDevicePoller.js b/pkg/nuclide-adb-sdb-base/lib/SdbDevicePoller.js index 1f851a1b27..9b17265383 100644 --- a/pkg/nuclide-adb-sdb-base/lib/SdbDevicePoller.js +++ b/pkg/nuclide-adb-sdb-base/lib/SdbDevicePoller.js @@ -1,36 +1,43 @@ -/** - * 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 strict-local - * @format - */ - -import type {DBPlatform} from 'nuclide-adb'; -import type {Expected} from 'nuclide-commons/expected'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {Observable} from 'rxjs'; -import type {Device} from 'nuclide-debugger-common/types'; - -import {DevicePoller} from 'nuclide-adb'; -import {getSdbServiceByNuclideUri} from '../../nuclide-remote-connection'; - -const SDB_PLATFORM: DBPlatform = { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.observeTizenDevices = observeTizenDevices; +exports.observeTizenDevicesX = observeTizenDevicesX; + +var _nuclideAdb; + +function _load_nuclideAdb() { + return _nuclideAdb = require('../../../modules/nuclide-adb'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +const SDB_PLATFORM = { name: 'Tizen', type: 'sdb', command: 'sdb', - getService: getSdbServiceByNuclideUri, -}; + getService: (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getSdbServiceByNuclideUri +}; /** + * 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. + * + * strict-local + * @format + */ -export function observeTizenDevices(host: NuclideUri): Observable { +function observeTizenDevices(host) { return observeTizenDevicesX(host).map(devices => devices.getOrDefault([])); } -export function observeTizenDevicesX( - host: NuclideUri, -): Observable> { - return DevicePoller.observeDevices(SDB_PLATFORM, host); -} +function observeTizenDevicesX(host) { + return (_nuclideAdb || _load_nuclideAdb()).DevicePoller.observeDevices(SDB_PLATFORM, host); +} \ No newline at end of file diff --git a/pkg/nuclide-adb-sdb-base/lib/Tunneling.js b/pkg/nuclide-adb-sdb-base/lib/Tunneling.js index 144992fe33..8fb6bdaf94 100644 --- a/pkg/nuclide-adb-sdb-base/lib/Tunneling.js +++ b/pkg/nuclide-adb-sdb-base/lib/Tunneling.js @@ -1,188 +1,179 @@ -/** - * 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 - */ - -import type {SshTunnelService} from 'nuclide-adb/lib/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {Subscription} from 'rxjs'; - -import invariant from 'assert'; -import {getLogger} from 'log4js'; -import {SimpleCache} from 'nuclide-commons/SimpleCache'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Observable, Subject} from 'rxjs'; -import consumeFirstProvider from 'nuclide-commons-atom/consumeFirstProvider'; -import {getAdbServiceByNuclideUri} from 'nuclide-adb'; -import {track} from '../../nuclide-analytics'; - -export type AdbTunnelingOptions = { - adbMismatchErrorMessage?: string, -}; - -export function startTunnelingAdb( - uri: NuclideUri, - options?: AdbTunnelingOptions = {}, -): Observable<'ready'> { - if (!nuclideUri.isRemote(uri)) { - return Observable.of('ready').concat(Observable.never()); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.startTunnelingAdb = startTunnelingAdb; +exports.stopTunnelingAdb = stopTunnelingAdb; +exports.isAdbTunneled = isAdbTunneled; + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _SimpleCache; + +function _load_SimpleCache() { + return _SimpleCache = require('../../../modules/nuclide-commons/SimpleCache'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _consumeFirstProvider; + +function _load_consumeFirstProvider() { + return _consumeFirstProvider = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/consumeFirstProvider')); +} + +var _nuclideAdb; + +function _load_nuclideAdb() { + return _nuclideAdb = require('../../../modules/nuclide-adb'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function startTunnelingAdb(uri, options = {}) { + if (!(_nuclideUri || _load_nuclideUri()).default.isRemote(uri)) { + return _rxjsBundlesRxMinJs.Observable.of('ready').concat(_rxjsBundlesRxMinJs.Observable.never()); } - const {tunnels} = activeTunnels.getOrCreate(uri, (_, serviceUri) => { - invariant(typeof serviceUri === 'string'); - const adbService = getAdbServiceByNuclideUri(serviceUri); - const localAdbService = getAdbServiceByNuclideUri(''); - - const observable = Observable.defer(async () => { - const [adbVersion, localAdbVersion] = await Promise.all([ - adbService.getVersion(), - localAdbService.getVersion(), - ]); + const { tunnels } = activeTunnels.getOrCreate(uri, (_, serviceUri) => { + if (!(typeof serviceUri === 'string')) { + throw new Error('Invariant violation: "typeof serviceUri === \'string\'"'); + } + + const adbService = (0, (_nuclideAdb || _load_nuclideAdb()).getAdbServiceByNuclideUri)(serviceUri); + const localAdbService = (0, (_nuclideAdb || _load_nuclideAdb()).getAdbServiceByNuclideUri)(''); + + const observable = _rxjsBundlesRxMinJs.Observable.defer(async () => { + const [adbVersion, localAdbVersion] = await Promise.all([adbService.getVersion(), localAdbService.getVersion()]); if (adbVersion !== localAdbVersion) { - throw new Error( - `Your remote adb version differs from the local one: ${adbVersion} (remote) != ${localAdbVersion} (local).\n\n${options.adbMismatchErrorMessage || - ''}`, - ); + throw new Error(`Your remote adb version differs from the local one: ${adbVersion} (remote) != ${localAdbVersion} (local).\n\n${options.adbMismatchErrorMessage || ''}`); } return adbService.checkMuxStatus(); - }) - .switchMap( - useAdbmux => - useAdbmux - ? checkInToAdbmux(serviceUri) - : openTunnelsManually(serviceUri), - ) - .catch(e => { - getLogger('nuclide-adb-sdb-base').error(e); - track('nuclide-adb-sdb-base:tunneling:error', {host: uri, error: e}); - return Observable.empty(); - }) - .publishReplay(1); + }).switchMap(useAdbmux => useAdbmux ? checkInToAdbmux(serviceUri) : openTunnelsManually(serviceUri)).catch(e => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-adb-sdb-base').error(e); + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('nuclide-adb-sdb-base:tunneling:error', { host: uri, error: e }); + return _rxjsBundlesRxMinJs.Observable.empty(); + }).publishReplay(1); let adbmuxPort; - const subscription = observable - .subscribe(port => (adbmuxPort = port)) - .add(() => { - if (adbmuxPort != null) { - adbService.checkOutMuxPort(adbmuxPort); - adbmuxPort = null; - } - stopTunnelingAdb(uri); - }) - // Start everything! - .add(observable.connect()); + const subscription = observable.subscribe(port => adbmuxPort = port).add(() => { + if (adbmuxPort != null) { + adbService.checkOutMuxPort(adbmuxPort); + adbmuxPort = null; + } + stopTunnelingAdb(uri); + }) + // Start everything! + .add(observable.connect()); return { subscription, - tunnels: observable, + tunnels: observable }; }); changes.next(); return tunnels.mapTo('ready'); -} +} /** + * 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. + * + * + * @format + */ -export function stopTunnelingAdb(uri: NuclideUri) { +function stopTunnelingAdb(uri) { activeTunnels.delete(uri); changes.next(); } -export function isAdbTunneled(uri: NuclideUri): Observable { - return changes - .startWith(undefined) - .map(() => activeTunnels.get(uri) != null) - .distinctUntilChanged(); +function isAdbTunneled(uri) { + return changes.startWith(undefined).map(() => activeTunnels.get(uri) != null).distinctUntilChanged(); } -const activeTunnels: SimpleCache< - NuclideUri, - {tunnels: Observable, subscription: Subscription}, -> = new SimpleCache({ - keyFactory: uri => - nuclideUri.createRemoteUri(nuclideUri.getHostname(uri), '/'), - dispose: value => value.subscription.unsubscribe(), +const activeTunnels = new (_SimpleCache || _load_SimpleCache()).SimpleCache({ + keyFactory: uri => (_nuclideUri || _load_nuclideUri()).default.createRemoteUri((_nuclideUri || _load_nuclideUri()).default.getHostname(uri), '/'), + dispose: value => value.subscription.unsubscribe() }); -const changes: Subject = new Subject(); - -function checkInToAdbmux(host: NuclideUri): Observable { - return Observable.defer(async () => { - const service: SshTunnelService = await consumeFirstProvider( - 'nuclide.ssh-tunnel', - ); - invariant(service); +const changes = new _rxjsBundlesRxMinJs.Subject(); + +function checkInToAdbmux(host) { + return _rxjsBundlesRxMinJs.Observable.defer(async () => { + const service = await (0, (_consumeFirstProvider || _load_consumeFirstProvider()).default)('nuclide.ssh-tunnel'); + + if (!service) { + throw new Error('Invariant violation: "service"'); + } + const port = await service.getAvailableServerPort(host); - return {service, port}; - }) - .switchMap(({service, port}) => - service - .openTunnels([ - { - description: 'adbmux', - from: {host, port, family: 4}, - to: {host: 'localhost', port: 5037, family: 4}, - }, - { - description: 'exopackage', - from: {host, port: 2829, family: 4}, - to: {host: 'localhost', port: 2829, family: 4}, - }, - ]) - .mapTo(port), - ) - .switchMap(async port => { - const service = getAdbServiceByNuclideUri(host); - await service.checkInMuxPort(port); - return port; - }); + return { service, port }; + }).switchMap(({ service, port }) => service.openTunnels([{ + description: 'adbmux', + from: { host, port, family: 4 }, + to: { host: 'localhost', port: 5037, family: 4 } + }, { + description: 'exopackage', + from: { host, port: 2829, family: 4 }, + to: { host: 'localhost', port: 2829, family: 4 } + }]).mapTo(port)).switchMap(async port => { + const service = (0, (_nuclideAdb || _load_nuclideAdb()).getAdbServiceByNuclideUri)(host); + await service.checkInMuxPort(port); + return port; + }); } -function openTunnelsManually(host: NuclideUri): Observable { +function openTunnelsManually(host) { let retries = 3; - return Observable.defer(async () => { - await getAdbServiceByNuclideUri(host).killServer(); + return _rxjsBundlesRxMinJs.Observable.defer(async () => { + await (0, (_nuclideAdb || _load_nuclideAdb()).getAdbServiceByNuclideUri)(host).killServer(); + + const service = await (0, (_consumeFirstProvider || _load_consumeFirstProvider()).default)('nuclide.ssh-tunnel'); + + if (!service) { + throw new Error('Invariant violation: "service"'); + } - const service: SshTunnelService = await consumeFirstProvider( - 'nuclide.ssh-tunnel', - ); - invariant(service); return service; - }) - .timeout(5000) - .switchMap(service => - service.openTunnels([ - { - description: 'adb', - from: {host, port: 5037, family: 4}, - to: {host: 'localhost', port: 5037, family: 4}, - }, - { - description: 'emulator console', - from: {host, port: 5554, family: 4}, - to: {host: 'localhost', port: 5554, family: 4}, - }, - { - description: 'emulator adb', - from: {host, port: 5555, family: 4}, - to: {host: 'localhost', port: 5555, family: 4}, - }, - { - description: 'exopackage', - from: {host, port: 2829, family: 4}, - to: {host: 'localhost', port: 2829, family: 4}, - }, - ]), - ) - .retryWhen(errors => { - return errors.do(error => { - if (retries-- <= 0) { - throw error; - } - }); - }) - .mapTo(null); -} + }).timeout(5000).switchMap(service => service.openTunnels([{ + description: 'adb', + from: { host, port: 5037, family: 4 }, + to: { host: 'localhost', port: 5037, family: 4 } + }, { + description: 'emulator console', + from: { host, port: 5554, family: 4 }, + to: { host: 'localhost', port: 5554, family: 4 } + }, { + description: 'emulator adb', + from: { host, port: 5555, family: 4 }, + to: { host: 'localhost', port: 5555, family: 4 } + }, { + description: 'exopackage', + from: { host, port: 2829, family: 4 }, + to: { host: 'localhost', port: 2829, family: 4 } + }])).retryWhen(errors => { + return errors.do(error => { + if (retries-- <= 0) { + throw error; + } + }); + }).mapTo(null); +} \ No newline at end of file diff --git a/pkg/nuclide-adb-sdb-base/lib/main.js b/pkg/nuclide-adb-sdb-base/lib/main.js index 87028d74ea..73551b66e6 100644 --- a/pkg/nuclide-adb-sdb-base/lib/main.js +++ b/pkg/nuclide-adb-sdb-base/lib/main.js @@ -1,3 +1,5 @@ +"use strict"; + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,11 +7,11 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ // eslint-disable-next-line nuclide-internal/no-commonjs module.exports = { // TODO(wallace): Add export code here. -}; +}; \ No newline at end of file diff --git a/pkg/nuclide-adb-sdb-rpc/lib/SdbService.js b/pkg/nuclide-adb-sdb-rpc/lib/SdbService.js index a8fa9c4ceb..4083922aa8 100644 --- a/pkg/nuclide-adb-sdb-rpc/lib/SdbService.js +++ b/pkg/nuclide-adb-sdb-rpc/lib/SdbService.js @@ -1,3 +1,47 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.registerSdbPath = registerSdbPath; +exports.getFullConfig = getFullConfig; +exports.registerCustomPath = registerCustomPath; +exports.getDeviceInfo = getDeviceInfo; +exports.getDeviceList = getDeviceList; +exports.getPidFromPackageName = getPidFromPackageName; +exports.getFileContentsAtPath = getFileContentsAtPath; +exports.installPackage = installPackage; +exports.launchApp = launchApp; +exports.stopProcess = stopProcess; +exports.uninstallPackage = uninstallPackage; +exports.getProcesses = getProcesses; + +var _Store; + +function _load_Store() { + return _Store = require('../../../modules/nuclide-adb/lib/common/Store'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _Sdb; + +function _load_Sdb() { + return _Sdb = require('./bridges/Sdb'); +} + +var _Processes; + +function _load_Processes() { + return _Processes = require('../../../modules/nuclide-adb/lib/common/Processes'); +} + +var _Devices; + +function _load_Devices() { + return _Devices = require('../../../modules/nuclide-adb/lib/common/Devices'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,103 +49,58 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {LegacyProcessMessage} from 'nuclide-commons/process'; -import type { - DeviceDescription, - DebugBridgeFullConfig, - DeviceId, - Process, -} from 'nuclide-adb/lib/types'; - -import {getStore} from 'nuclide-adb/lib/common/Store'; -import {ConnectableObservable} from 'rxjs'; -import {Sdb} from './bridges/Sdb'; -import {Processes} from 'nuclide-adb/lib/common/Processes'; -import {Devices} from 'nuclide-adb/lib/common/Devices'; - const SDB = 'sdb'; -export async function registerSdbPath( - id: string, - path: NuclideUri, - priority: number = -1, -): Promise { - getStore(SDB).registerPath(id, {path, priority}); +async function registerSdbPath(id, path, priority = -1) { + (0, (_Store || _load_Store()).getStore)(SDB).registerPath(id, { path, priority }); } -export async function getFullConfig(): Promise { - return getStore(SDB).getFullConfig(); +async function getFullConfig() { + return (0, (_Store || _load_Store()).getStore)(SDB).getFullConfig(); } -export async function registerCustomPath(path: ?string): Promise { - getStore(SDB).registerCustomPath(path); +async function registerCustomPath(path) { + (0, (_Store || _load_Store()).getStore)(SDB).registerCustomPath(path); } -export function getDeviceInfo( - device: DeviceId, -): ConnectableObservable> { - return new Sdb(device).getDeviceInfo().publish(); +function getDeviceInfo(device) { + return new (_Sdb || _load_Sdb()).Sdb(device).getDeviceInfo().publish(); } -export function getDeviceList(): ConnectableObservable< - Array, -> { - return new Devices(Sdb).getDeviceList().publish(); +function getDeviceList() { + return new (_Devices || _load_Devices()).Devices((_Sdb || _load_Sdb()).Sdb).getDeviceList().publish(); } -export async function getPidFromPackageName( - device: DeviceId, - packageName: string, -): Promise { - return new Processes(new Sdb(device)).getPidFromPackageName(packageName); +async function getPidFromPackageName(device, packageName) { + return new (_Processes || _load_Processes()).Processes(new (_Sdb || _load_Sdb()).Sdb(device)).getPidFromPackageName(packageName); } -export async function getFileContentsAtPath( - device: DeviceId, - path: string, -): Promise { - return new Sdb(device).getFileContentsAtPath(path); +async function getFileContentsAtPath(device, path) { + return new (_Sdb || _load_Sdb()).Sdb(device).getFileContentsAtPath(path); } -export function installPackage( - device: DeviceId, - packagePath: NuclideUri, -): ConnectableObservable { +function installPackage(device, packagePath) { // TODO(T17463635) - return new Sdb(device).installPackage(packagePath).publish(); + return new (_Sdb || _load_Sdb()).Sdb(device).installPackage(packagePath).publish(); } -export async function launchApp( - device: DeviceId, - identifier: string, -): Promise { - return new Sdb(device).launchApp(identifier); +async function launchApp(device, identifier) { + return new (_Sdb || _load_Sdb()).Sdb(device).launchApp(identifier); } -export async function stopProcess( - device: DeviceId, - packageName: string, - pid: number, -): Promise { - return new Sdb(device).stopProcess(packageName, pid); +async function stopProcess(device, packageName, pid) { + return new (_Sdb || _load_Sdb()).Sdb(device).stopProcess(packageName, pid); } -export function uninstallPackage( - device: DeviceId, - packageName: string, -): ConnectableObservable { +function uninstallPackage(device, packageName) { // TODO(T17463635) - return new Sdb(device).uninstallPackage(packageName).publish(); + return new (_Sdb || _load_Sdb()).Sdb(device).uninstallPackage(packageName).publish(); } -export function getProcesses( - device: DeviceId, - timeout: number, -): ConnectableObservable> { - return new Processes(new Sdb(device)).fetch(timeout).publish(); -} +function getProcesses(device, timeout) { + return new (_Processes || _load_Processes()).Processes(new (_Sdb || _load_Sdb()).Sdb(device)).fetch(timeout).publish(); +} \ No newline at end of file diff --git a/pkg/nuclide-adb-sdb-rpc/lib/SdbServiceProxy.js b/pkg/nuclide-adb-sdb-rpc/lib/SdbServiceProxy.js new file mode 100644 index 0000000000..d0ea0254f5 --- /dev/null +++ b/pkg/nuclide-adb-sdb-rpc/lib/SdbServiceProxy.js @@ -0,0 +1,1084 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + + remoteModule.registerSdbPath = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("SdbService/registerSdbPath", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "id", + type: { + kind: "string" + } + }, { + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "priority", + type: { + kind: "nullable", + type: { + kind: "number" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.getFullConfig = function () { + return _client.callRemoteFunction("SdbService/getFullConfig", "promise", _client.marshalArguments(Array.from(arguments), [])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "DebugBridgeFullConfig" + }); + }); + }; + + remoteModule.registerCustomPath = function (arg0) { + return _client.callRemoteFunction("SdbService/registerCustomPath", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.getDeviceInfo = function (arg0) { + return _client.callRemoteFunction("SdbService/getDeviceInfo", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "device", + type: { + kind: "named", + name: "DeviceId" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "map", + keyType: { + kind: "string" + }, + valueType: { + kind: "string" + } + }); + }).publish(); + }; + + remoteModule.getDeviceList = function () { + return _client.callRemoteFunction("SdbService/getDeviceList", "observable", _client.marshalArguments(Array.from(arguments), [])).map(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "DeviceDescription" + } + }); + }).publish(); + }; + + remoteModule.getPidFromPackageName = function (arg0, arg1) { + return _client.callRemoteFunction("SdbService/getPidFromPackageName", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "device", + type: { + kind: "named", + name: "DeviceId" + } + }, { + name: "packageName", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "number" + }); + }); + }; + + remoteModule.getFileContentsAtPath = function (arg0, arg1) { + return _client.callRemoteFunction("SdbService/getFileContentsAtPath", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "device", + type: { + kind: "named", + name: "DeviceId" + } + }, { + name: "path", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }); + }; + + remoteModule.installPackage = function (arg0, arg1) { + return _client.callRemoteFunction("SdbService/installPackage", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "device", + type: { + kind: "named", + name: "DeviceId" + } + }, { + name: "packagePath", + type: { + kind: "named", + name: "NuclideUri" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.launchApp = function (arg0, arg1) { + return _client.callRemoteFunction("SdbService/launchApp", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "device", + type: { + kind: "named", + name: "DeviceId" + } + }, { + name: "identifier", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }); + }; + + remoteModule.stopProcess = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("SdbService/stopProcess", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "device", + type: { + kind: "named", + name: "DeviceId" + } + }, { + name: "packageName", + type: { + kind: "string" + } + }, { + name: "pid", + type: { + kind: "number" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.uninstallPackage = function (arg0, arg1) { + return _client.callRemoteFunction("SdbService/uninstallPackage", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "device", + type: { + kind: "named", + name: "DeviceId" + } + }, { + name: "packageName", + type: { + kind: "string" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.getProcesses = function (arg0, arg1) { + return _client.callRemoteFunction("SdbService/getProcesses", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "device", + type: { + kind: "named", + name: "DeviceId" + } + }, { + name: "timeout", + type: { + kind: "number" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "Process" + } + }); + }).publish(); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + registerSdbPath: { + kind: "function", + name: "registerSdbPath", + location: { + type: "source", + fileName: "SdbService.js", + line: 29 + }, + type: { + location: { + type: "source", + fileName: "SdbService.js", + line: 29 + }, + kind: "function", + argumentTypes: [{ + name: "id", + type: { + kind: "string" + } + }, { + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "priority", + type: { + kind: "nullable", + type: { + kind: "number" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + DebugBridgeFullConfig: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 47 + }, + name: "DebugBridgeFullConfig", + definition: { + kind: "object", + fields: [{ + name: "active", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "all", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "ports", + type: { + kind: "array", + type: { + kind: "number" + } + }, + optional: false + }] + } + }, + getFullConfig: { + kind: "function", + name: "getFullConfig", + location: { + type: "source", + fileName: "SdbService.js", + line: 37 + }, + type: { + location: { + type: "source", + fileName: "SdbService.js", + line: 37 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "DebugBridgeFullConfig" + } + } + } + }, + registerCustomPath: { + kind: "function", + name: "registerCustomPath", + location: { + type: "source", + fileName: "SdbService.js", + line: 41 + }, + type: { + location: { + type: "source", + fileName: "SdbService.js", + line: 41 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + DeviceId: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 26 + }, + name: "DeviceId", + definition: { + kind: "object", + fields: [{ + name: "name", + type: { + kind: "string" + }, + optional: false + }, { + name: "port", + type: { + kind: "number" + }, + optional: false + }] + } + }, + getDeviceInfo: { + kind: "function", + name: "getDeviceInfo", + location: { + type: "source", + fileName: "SdbService.js", + line: 45 + }, + type: { + location: { + type: "source", + fileName: "SdbService.js", + line: 45 + }, + kind: "function", + argumentTypes: [{ + name: "device", + type: { + kind: "named", + name: "DeviceId" + } + }], + returnType: { + kind: "observable", + type: { + kind: "map", + keyType: { + kind: "string" + }, + valueType: { + kind: "string" + } + } + } + } + }, + DeviceDescription: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 28 + }, + name: "DeviceDescription", + definition: { + kind: "object", + fields: [{ + name: "name", + type: { + kind: "string" + }, + optional: false + }, { + name: "port", + type: { + kind: "number" + }, + optional: false + }, { + name: "architecture", + type: { + kind: "string" + }, + optional: false + }, { + name: "apiVersion", + type: { + kind: "string" + }, + optional: false + }, { + name: "model", + type: { + kind: "string" + }, + optional: false + }] + } + }, + getDeviceList: { + kind: "function", + name: "getDeviceList", + location: { + type: "source", + fileName: "SdbService.js", + line: 51 + }, + type: { + location: { + type: "source", + fileName: "SdbService.js", + line: 51 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "observable", + type: { + kind: "array", + type: { + kind: "named", + name: "DeviceDescription" + } + } + } + } + }, + getPidFromPackageName: { + kind: "function", + name: "getPidFromPackageName", + location: { + type: "source", + fileName: "SdbService.js", + line: 57 + }, + type: { + location: { + type: "source", + fileName: "SdbService.js", + line: 57 + }, + kind: "function", + argumentTypes: [{ + name: "device", + type: { + kind: "named", + name: "DeviceId" + } + }, { + name: "packageName", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "number" + } + } + } + }, + getFileContentsAtPath: { + kind: "function", + name: "getFileContentsAtPath", + location: { + type: "source", + fileName: "SdbService.js", + line: 64 + }, + type: { + location: { + type: "source", + fileName: "SdbService.js", + line: 64 + }, + kind: "function", + argumentTypes: [{ + name: "device", + type: { + kind: "named", + name: "DeviceId" + } + }, { + name: "path", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "string" + } + } + } + }, + ProcessExitMessage: { + kind: "alias", + location: { + type: "source", + fileName: "process.js", + line: 665 + }, + name: "ProcessExitMessage", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "exit" + }, + optional: false + }, { + name: "exitCode", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }, { + name: "signal", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }] + } + }, + ProcessMessage: { + kind: "alias", + location: { + type: "source", + fileName: "process.js", + line: 671 + }, + name: "ProcessMessage", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "stdout" + }, + optional: false + }, { + name: "data", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "stderr" + }, + optional: false + }, { + name: "data", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "exit" + }, + optional: false + }, { + name: "exitCode", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }, { + name: "signal", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }] + }], + discriminantField: "kind" + } + }, + LegacyProcessMessage: { + kind: "alias", + location: { + type: "source", + fileName: "process.js", + line: 684 + }, + name: "LegacyProcessMessage", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "stdout" + }, + optional: false + }, { + name: "data", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "stderr" + }, + optional: false + }, { + name: "data", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "exit" + }, + optional: false + }, { + name: "exitCode", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }, { + name: "signal", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "error" + }, + optional: false + }, { + name: "error", + type: { + kind: "named", + name: "Object" + }, + optional: false + }] + }], + discriminantField: "kind" + } + }, + installPackage: { + kind: "function", + name: "installPackage", + location: { + type: "source", + fileName: "SdbService.js", + line: 71 + }, + type: { + location: { + type: "source", + fileName: "SdbService.js", + line: 71 + }, + kind: "function", + argumentTypes: [{ + name: "device", + type: { + kind: "named", + name: "DeviceId" + } + }, { + name: "packagePath", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + launchApp: { + kind: "function", + name: "launchApp", + location: { + type: "source", + fileName: "SdbService.js", + line: 79 + }, + type: { + location: { + type: "source", + fileName: "SdbService.js", + line: 79 + }, + kind: "function", + argumentTypes: [{ + name: "device", + type: { + kind: "named", + name: "DeviceId" + } + }, { + name: "identifier", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "string" + } + } + } + }, + stopProcess: { + kind: "function", + name: "stopProcess", + location: { + type: "source", + fileName: "SdbService.js", + line: 86 + }, + type: { + location: { + type: "source", + fileName: "SdbService.js", + line: 86 + }, + kind: "function", + argumentTypes: [{ + name: "device", + type: { + kind: "named", + name: "DeviceId" + } + }, { + name: "packageName", + type: { + kind: "string" + } + }, { + name: "pid", + type: { + kind: "number" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + uninstallPackage: { + kind: "function", + name: "uninstallPackage", + location: { + type: "source", + fileName: "SdbService.js", + line: 94 + }, + type: { + location: { + type: "source", + fileName: "SdbService.js", + line: 94 + }, + kind: "function", + argumentTypes: [{ + name: "device", + type: { + kind: "named", + name: "DeviceId" + } + }, { + name: "packageName", + type: { + kind: "string" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + Process: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 36 + }, + name: "Process", + definition: { + kind: "object", + fields: [{ + name: "user", + type: { + kind: "string" + }, + optional: false + }, { + name: "pid", + type: { + kind: "number" + }, + optional: false + }, { + name: "name", + type: { + kind: "string" + }, + optional: false + }, { + name: "cpuUsage", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }, { + name: "memUsage", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }, { + name: "isJava", + type: { + kind: "boolean" + }, + optional: false + }] + } + }, + getProcesses: { + kind: "function", + name: "getProcesses", + location: { + type: "source", + fileName: "SdbService.js", + line: 102 + }, + type: { + location: { + type: "source", + fileName: "SdbService.js", + line: 102 + }, + kind: "function", + argumentTypes: [{ + name: "device", + type: { + kind: "named", + name: "DeviceId" + } + }, { + name: "timeout", + type: { + kind: "number" + } + }], + returnType: { + kind: "observable", + type: { + kind: "array", + type: { + kind: "named", + name: "Process" + } + } + } + } + } + } +}); \ No newline at end of file diff --git a/pkg/nuclide-adb-sdb-rpc/lib/bridges/Sdb.js b/pkg/nuclide-adb-sdb-rpc/lib/bridges/Sdb.js index 4f839d952f..a1f446cd96 100644 --- a/pkg/nuclide-adb-sdb-rpc/lib/bridges/Sdb.js +++ b/pkg/nuclide-adb-sdb-rpc/lib/bridges/Sdb.js @@ -1,3 +1,32 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Sdb = undefined; + +var _DebugBridge; + +function _load_DebugBridge() { + return _DebugBridge = require('../../../../modules/nuclide-adb/lib/common/DebugBridge'); +} + +var _Store; + +function _load_Store() { + return _Store = require('../../../../modules/nuclide-adb/lib/common/Store'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../../modules/nuclide-commons/nuclideUri')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,109 +34,80 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {SimpleProcess} from 'nuclide-adb/lib/types'; -import type {LegacyProcessMessage} from 'nuclide-commons/process'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; +class Sdb extends (_DebugBridge || _load_DebugBridge()).DebugBridge { -import invariant from 'assert'; -import {DebugBridge} from 'nuclide-adb/lib/common/DebugBridge'; -import {createConfigObs} from 'nuclide-adb/lib/common/Store'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Observable} from 'rxjs'; - -export class Sdb extends DebugBridge { - static configObs = createConfigObs('sdb'); - - async getFileContentsAtPath(path: string): Promise { + async getFileContentsAtPath(path) { return this.runShortCommand('shell', 'cat', path).toPromise(); } - getDeviceInfo(): Observable> { - const unknownCB = () => Observable.of(''); - return Observable.forkJoin( - this.getDeviceArchitecture().catch(unknownCB), - this.getAPIVersion().catch(unknownCB), - this.getDeviceModel().catch(unknownCB), - ).map(([architecture, apiVersion, model]) => { - return new Map([ - ['name', this._device.name], - ['sdb_port', String(this._device.port)], - ['architecture', architecture], - ['api_version', apiVersion], - ['model', model], - ]); + getDeviceInfo() { + const unknownCB = () => _rxjsBundlesRxMinJs.Observable.of(''); + return _rxjsBundlesRxMinJs.Observable.forkJoin(this.getDeviceArchitecture().catch(unknownCB), this.getAPIVersion().catch(unknownCB), this.getDeviceModel().catch(unknownCB)).map(([architecture, apiVersion, model]) => { + return new Map([['name', this._device.name], ['sdb_port', String(this._device.port)], ['architecture', architecture], ['api_version', apiVersion], ['model', model]]); }); } - getTizenModelConfigKey(key: string): Observable { + getTizenModelConfigKey(key) { const modelConfigPath = '/etc/config/model-config.xml'; - return this.runShortCommand('shell', 'cat', modelConfigPath) - .map(stdout => stdout.split(/\n+/g).filter(s => s.indexOf(key) !== -1)[0]) - .map(s => { - const regex = /.*<.*>(.*)<.*>/g; - return regex.exec(s)[1]; - }); + return this.runShortCommand('shell', 'cat', modelConfigPath).map(stdout => stdout.split(/\n+/g).filter(s => s.indexOf(key) !== -1)[0]).map(s => { + const regex = /.*<.*>(.*)<.*>/g; + return regex.exec(s)[1]; + }); } - async stopProcess(packageName: string, pid: number): Promise { + async stopProcess(packageName, pid) { await this.runShortCommand('shell', 'kill', '-9', `${pid}`).toPromise(); } - getDeviceArchitecture(): Observable { + getDeviceArchitecture() { return this.runShortCommand('shell', 'uname', '-m').map(s => s.trim()); } - getDeviceModel(): Observable { + getDeviceModel() { return this.getTizenModelConfigKey('tizen.org/system/model_name'); } - getDebuggableProcesses(): Observable> { - return Observable.of([]); + getDebuggableProcesses() { + return _rxjsBundlesRxMinJs.Observable.of([]); } - getAPIVersion(): Observable { - return this.getTizenModelConfigKey( - 'tizen.org/feature/platform.core.api.version', - ).catch(() => - this.getTizenModelConfigKey( - 'tizen.org/feature/platform.native.api.version', - ), - ); + getAPIVersion() { + return this.getTizenModelConfigKey('tizen.org/feature/platform.core.api.version').catch(() => this.getTizenModelConfigKey('tizen.org/feature/platform.native.api.version')); } - installPackage(packagePath: NuclideUri): Observable { + installPackage(packagePath) { // TODO(T17463635) - invariant(!nuclideUri.isRemote(packagePath)); + if (!!(_nuclideUri || _load_nuclideUri()).default.isRemote(packagePath)) { + throw new Error('Invariant violation: "!nuclideUri.isRemote(packagePath)"'); + } + return this.runLongCommand('install', packagePath); } - launchApp(identifier: string): Promise { + launchApp(identifier) { return this.runShortCommand('shell', 'launch_app', identifier).toPromise(); } - uninstallPackage(packageName: string): Observable { + uninstallPackage(packageName) { // TODO(T17463635) return this.runLongCommand('uninstall', packageName); } - getDeviceArgs(): Array { + getDeviceArgs() { return this._device.name !== '' ? ['-s', this._device.name] : []; } - getProcesses(): Observable> { - return this.runShortCommand( - 'shell', - 'for file in /proc/[0-9]*/stat; do cat "$file" 2>/dev/null || true; done', - ).map(stdout => - stdout.split(/\n/).map(line => { - const info = line.trim().split(/\s+/); - return {user: 'n/a', pid: info[0], name: info[1]}; - }), - ); + getProcesses() { + return this.runShortCommand('shell', 'for file in /proc/[0-9]*/stat; do cat "$file" 2>/dev/null || true; done').map(stdout => stdout.split(/\n/).map(line => { + const info = line.trim().split(/\s+/); + return { user: 'n/a', pid: info[0], name: info[1] }; + })); } } +exports.Sdb = Sdb; +Sdb.configObs = (0, (_Store || _load_Store()).createConfigObs)('sdb'); \ No newline at end of file diff --git a/pkg/nuclide-adb-sdb/lib/ConfigurePathTaskProvider.js b/pkg/nuclide-adb-sdb/lib/ConfigurePathTaskProvider.js index 808296dd9c..6b2721084f 100644 --- a/pkg/nuclide-adb-sdb/lib/ConfigurePathTaskProvider.js +++ b/pkg/nuclide-adb-sdb/lib/ConfigurePathTaskProvider.js @@ -1,3 +1,30 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ConfigurePathTaskProvider = undefined; + +var _showModal; + +function _load_showModal() { + return _showModal = _interopRequireDefault(require('../../../modules/nuclide-commons-ui/showModal')); +} + +var _CustomPathModal; + +function _load_CustomPathModal() { + return _CustomPathModal = require('./CustomPathModal'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,63 +32,44 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {DeviceTypeTaskProvider} from 'nuclide-debugger-common/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {TaskEvent} from 'nuclide-commons/process'; -import type {Bridge} from './types'; - -import showModal from 'nuclide-commons-ui/showModal'; -import {CustomPathModal} from './CustomPathModal'; -import {Observable} from 'rxjs'; -import * as React from 'react'; - -export class ConfigurePathTaskProvider implements DeviceTypeTaskProvider { - _bridge: Bridge; +class ConfigurePathTaskProvider { - constructor(bridge: Bridge) { + constructor(bridge) { this._bridge = bridge; } - getType(): string { + getType() { return this._bridge.name; } - getName(): string { + getName() { return `Configure ${this._bridge.debugBridge}`; } - getTask(host: NuclideUri): Observable { - return Observable.defer(() => this._bridge.getFullConfig(host)).switchMap( - fullConfig => { - return Observable.create(observer => { - const disposable = showModal( - ({dismiss}) => ( - - this._bridge.setCustomDebugBridgePath(host, customPath) - } - type={this._bridge.debugBridge} - /> - ), - { - className: 'nuclide-adb-sdb-custom-path-modal', - onDismiss: () => { - disposable.dispose(); - observer.complete(); - }, - shouldDismissOnClickOutsideModal: () => false, - }, - ); + getTask(host) { + return _rxjsBundlesRxMinJs.Observable.defer(() => this._bridge.getFullConfig(host)).switchMap(fullConfig => { + return _rxjsBundlesRxMinJs.Observable.create(observer => { + const disposable = (0, (_showModal || _load_showModal()).default)(({ dismiss }) => _react.createElement((_CustomPathModal || _load_CustomPathModal()).CustomPathModal, { + dismiss: dismiss, + activePath: fullConfig.active, + currentCustomPath: this._bridge.getCustomDebugBridgePath(host), + registeredPaths: fullConfig.all, + setCustomPath: customPath => this._bridge.setCustomDebugBridgePath(host, customPath), + type: this._bridge.debugBridge + }), { + className: 'nuclide-adb-sdb-custom-path-modal', + onDismiss: () => { + disposable.dispose(); + observer.complete(); + }, + shouldDismissOnClickOutsideModal: () => false }); - }, - ); + }); + }); } } +exports.ConfigurePathTaskProvider = ConfigurePathTaskProvider; \ No newline at end of file diff --git a/pkg/nuclide-adb-sdb/lib/CustomPathModal.js b/pkg/nuclide-adb-sdb/lib/CustomPathModal.js index 940b127d52..0406c0c4c3 100644 --- a/pkg/nuclide-adb-sdb/lib/CustomPathModal.js +++ b/pkg/nuclide-adb-sdb/lib/CustomPathModal.js @@ -1,141 +1,199 @@ -/** - * 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 - */ - -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {Dropdown} from 'nuclide-commons-ui/Dropdown'; -import {Button} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; -import * as React from 'react'; - -type Props = {| - type: 'adb' | 'sdb', - setCustomPath: (path: ?string) => void, - dismiss: () => mixed, - activePath: ?string, - currentCustomPath: ?string, - registeredPaths: string[], -|}; - -type State = {| - customPath: ?string, -|}; - -export class CustomPathModal extends React.Component { - constructor(props: Props) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.CustomPathModal = undefined; + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../../../modules/nuclide-commons-ui/AtomInput'); +} + +var _Dropdown; + +function _load_Dropdown() { + return _Dropdown = require('../../../modules/nuclide-commons-ui/Dropdown'); +} + +var _Button; + +function _load_Button() { + return _Button = require('../../../modules/nuclide-commons-ui/Button'); +} + +var _ButtonGroup; + +function _load_ButtonGroup() { + return _ButtonGroup = require('../../../modules/nuclide-commons-ui/ButtonGroup'); +} + +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 CustomPathModal extends _react.Component { + constructor(props) { super(props); - this.state = {customPath: this.props.currentCustomPath}; + + this._handleConfirm = () => { + this.props.setCustomPath(this.state.customPath); + this.props.dismiss(); + }; + + this._handleCancel = () => { + this.props.dismiss(); + }; + + this._handleCustomPathChange = customPath => { + this.setState({ customPath: customPath.length === 0 ? null : customPath }); + }; + + this._handleCopyToClipboard = () => { + if (this.props.activePath != null) { + atom.clipboard.write(this.props.activePath); + } + }; + + this.state = { customPath: this.props.currentCustomPath }; } - _handleConfirm = (): void => { - this.props.setCustomPath(this.state.customPath); - this.props.dismiss(); - }; - - _handleCancel = (): void => { - this.props.dismiss(); - }; - - _handleCustomPathChange = (customPath: string): void => { - this.setState({customPath: customPath.length === 0 ? null : customPath}); - }; - - _handleCopyToClipboard = (): void => { - if (this.props.activePath != null) { - atom.clipboard.write(this.props.activePath); - } - }; - - _getActiveConfig(): React.Element { - return ( -
      - - {this.props.activePath == null ? null : ( - - )} -
      + _getActiveConfig() { + return _react.createElement( + 'div', + { className: 'nuclide-adb-sdb-path' }, + _react.createElement( + 'label', + null, + 'Active ', + this.props.type, + ' path:', + ' ', + _react.createElement( + 'i', + null, + _react.createElement( + 'strong', + null, + this.props.activePath + ) + ) + ), + this.props.activePath == null ? null : _react.createElement( + (_Button || _load_Button()).Button, + { + onClick: this._handleCopyToClipboard, + size: 'SMALL', + className: 'nuclide-adb-sdb-copy-path-btn' }, + 'Copy path to clipboard' + ) ); } - _getPathSelector(): React.Element { - return ( -
      - ({ - label: path, - value: path, - }))} - onChange={this._handleCustomPathChange} - placeholder={`Set a fixed ${this.props.type} from a registered path`} - value={null} - /> -
      - -
      -
      + _getPathSelector() { + return _react.createElement( + 'div', + null, + _react.createElement((_Dropdown || _load_Dropdown()).Dropdown, { + options: this.props.registeredPaths.map(path => ({ + label: path, + value: path + })), + onChange: this._handleCustomPathChange, + placeholder: `Set a fixed ${this.props.type} from a registered path`, + value: null + }), + _react.createElement( + 'div', + { className: 'nuclide-adb-sdb-custom-path-input' }, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + size: 'sm', + value: this.state.customPath || '', + placeholderText: '... or from a custom path', + onDidChange: this._handleCustomPathChange + }) + ) ); } - _getFooter(): React.Element { - return ( -
      - - - - -
      + _getFooter() { + return _react.createElement( + 'div', + { className: 'nuclide-adb-sdb-custom-path-footer' }, + _react.createElement( + (_ButtonGroup || _load_ButtonGroup()).ButtonGroup, + null, + _react.createElement( + (_Button || _load_Button()).Button, + { onClick: this._handleConfirm, buttonType: 'PRIMARY' }, + 'Confirm' + ), + _react.createElement( + (_Button || _load_Button()).Button, + { onClick: this._handleCancel }, + 'Cancel' + ) + ) ); } - _getInfoBox(): React.Element { - return ( -

      - - A custom {this.props.type} path takes priority over any other path - that nuclide knows. This is specially useful if you also use{' '} - {this.props.type} from the command line along with nuclide. -
      - Keep in mind that using two different versions of { - this.props.type - }{' '} - simultaneously might break both tools. -
      -

      + _getInfoBox() { + return _react.createElement( + 'p', + null, + _react.createElement( + 'small', + null, + 'A custom ', + this.props.type, + ' path takes priority over any other path that nuclide knows. This is specially useful if you also use', + ' ', + this.props.type, + ' from the command line along with nuclide.', + _react.createElement('br', null), + 'Keep in mind that using two different versions of ', + this.props.type, + ' ', + 'simultaneously might break both tools.' + ) ); } - render(): React.Node { - return ( -
      -
      {this._getActiveConfig()}
      -
      {this._getPathSelector()}
      -
      {this._getInfoBox()}
      -
      {this._getFooter()}
      -
      + render() { + return _react.createElement( + 'div', + null, + _react.createElement( + 'div', + { className: 'block' }, + this._getActiveConfig() + ), + _react.createElement( + 'div', + { className: 'block' }, + this._getPathSelector() + ), + _react.createElement( + 'div', + { className: 'block' }, + this._getInfoBox() + ), + _react.createElement( + 'div', + { className: 'block' }, + this._getFooter() + ) ); } } +exports.CustomPathModal = CustomPathModal; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-adb-sdb/lib/bridges/AndroidBridge.js b/pkg/nuclide-adb-sdb/lib/bridges/AndroidBridge.js index 71f69063df..c89875df57 100644 --- a/pkg/nuclide-adb-sdb/lib/bridges/AndroidBridge.js +++ b/pkg/nuclide-adb-sdb/lib/bridges/AndroidBridge.js @@ -1,3 +1,32 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AndroidBridge = undefined; + +var _AdbDevicePoller; + +function _load_AdbDevicePoller() { + return _AdbDevicePoller = require('../../../../modules/nuclide-adb/lib/AdbDevicePoller'); +} + +var _Actions; + +function _load_Actions() { + return _Actions = _interopRequireWildcard(require('../redux/Actions')); +} + +var _utils; + +function _load_utils() { + return _utils = require('../../../../modules/nuclide-adb/lib/utils'); +} + +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; } } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,50 +34,37 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {DebugBridgeFullConfig} from 'nuclide-adb/lib/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import {observeAndroidDevicesX} from 'nuclide-adb/lib/AdbDevicePoller'; -import typeof * as AdbService from 'nuclide-adb/lib/AdbService'; -import type {Store} from '../types'; -import type {Expected} from 'nuclide-commons/expected'; -import type {Device} from 'nuclide-debugger-common/types'; -import type {DeviceTypeAndroid} from '../types'; - -import * as Actions from '../redux/Actions'; -import {getAdbServiceByNuclideUri} from 'nuclide-adb/lib/utils'; -import {Observable} from 'rxjs'; - -export class AndroidBridge { - debugBridge: 'adb' = 'adb'; - name: DeviceTypeAndroid = 'Android'; +class AndroidBridge { - _store: Store; + constructor(store) { + this.debugBridge = 'adb'; + this.name = 'Android'; - constructor(store: Store) { this._store = store; } - getService(host: NuclideUri): AdbService { - return getAdbServiceByNuclideUri(host); + getService(host) { + return (0, (_utils || _load_utils()).getAdbServiceByNuclideUri)(host); } - getCustomDebugBridgePath(host: NuclideUri): ?string { + getCustomDebugBridgePath(host) { return this._store.getState().customAdbPaths.get(host); } - setCustomDebugBridgePath(host: NuclideUri, path: ?string): void { - this._store.dispatch(Actions.setCustomAdbPath(host, path)); + setCustomDebugBridgePath(host, path) { + this._store.dispatch((_Actions || _load_Actions()).setCustomAdbPath(host, path)); } - getFullConfig(host: NuclideUri): Promise { + getFullConfig(host) { return this.getService(host).getFullConfig(); } - observeDevicesX(host: NuclideUri): Observable> { - return observeAndroidDevicesX(host); + observeDevicesX(host) { + return (0, (_AdbDevicePoller || _load_AdbDevicePoller()).observeAndroidDevicesX)(host); } } +exports.AndroidBridge = AndroidBridge; \ No newline at end of file diff --git a/pkg/nuclide-adb-sdb/lib/bridges/TizenBridge.js b/pkg/nuclide-adb-sdb/lib/bridges/TizenBridge.js index 34c4f0a3fb..ec36c568e9 100644 --- a/pkg/nuclide-adb-sdb/lib/bridges/TizenBridge.js +++ b/pkg/nuclide-adb-sdb/lib/bridges/TizenBridge.js @@ -1,54 +1,68 @@ -/** - * 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 strict-local - * @format - */ - -import type {DebugBridgeFullConfig} from 'nuclide-adb/lib/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import typeof * as SdbService from '../../../nuclide-adb-sdb-rpc/lib/SdbService'; -import type {Store} from '../types'; -import type {Expected} from 'nuclide-commons/expected'; -import type {Device} from 'nuclide-debugger-common/types'; -import type {DeviceTypeTizen} from '../types'; - -import * as Actions from '../redux/Actions'; -import {getSdbServiceByNuclideUri} from '../../../nuclide-remote-connection'; -import {observeTizenDevicesX} from '../../../nuclide-adb-sdb-base/lib/SdbDevicePoller'; -import {Observable} from 'rxjs'; - -export class TizenBridge { - debugBridge: 'sdb' = 'sdb'; - name: DeviceTypeTizen = 'Tizen'; - - _store: Store; - - constructor(store: Store) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.TizenBridge = undefined; + +var _Actions; + +function _load_Actions() { + return _Actions = _interopRequireWildcard(require('../redux/Actions')); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../../nuclide-remote-connection'); +} + +var _SdbDevicePoller; + +function _load_SdbDevicePoller() { + return _SdbDevicePoller = require('../../../nuclide-adb-sdb-base/lib/SdbDevicePoller'); +} + +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; } } + +class TizenBridge { + + constructor(store) { + this.debugBridge = 'sdb'; + this.name = 'Tizen'; + this._store = store; } - getService(host: NuclideUri): SdbService { - return getSdbServiceByNuclideUri(host); + getService(host) { + return (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getSdbServiceByNuclideUri)(host); } - getCustomDebugBridgePath(host: NuclideUri): ?string { + getCustomDebugBridgePath(host) { return this._store.getState().customSdbPaths.get(host); } - setCustomDebugBridgePath(host: NuclideUri, path: ?string): void { - this._store.dispatch(Actions.setCustomSdbPath(host, path)); + setCustomDebugBridgePath(host, path) { + this._store.dispatch((_Actions || _load_Actions()).setCustomSdbPath(host, path)); } - getFullConfig(host: NuclideUri): Promise { + getFullConfig(host) { return this.getService(host).getFullConfig(); } - observeDevicesX(host: NuclideUri): Observable> { - return observeTizenDevicesX(host); + observeDevicesX(host) { + return (0, (_SdbDevicePoller || _load_SdbDevicePoller()).observeTizenDevicesX)(host); } } +exports.TizenBridge = TizenBridge; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-adb-sdb/lib/main.js b/pkg/nuclide-adb-sdb/lib/main.js index 09260d6816..daedb3deb1 100644 --- a/pkg/nuclide-adb-sdb/lib/main.js +++ b/pkg/nuclide-adb-sdb/lib/main.js @@ -1,114 +1,151 @@ -/** - * 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 - */ - -import type {DevicePanelServiceApi} from 'nuclide-debugger-common/types'; -import type {Store} from './types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import * as AdbTunnelService from '../../nuclide-adb-sdb-base/lib/Tunneling'; -import {ServerConnection} from '../../nuclide-remote-connection/lib/ServerConnection'; -import {getAdbServiceByNuclideUri} from 'nuclide-adb'; -import {getSdbServiceByNuclideUri} from '../../nuclide-remote-connection'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {ConfigurePathTaskProvider} from './ConfigurePathTaskProvider'; -import {createEmptyAppState, deserialize, serialize} from './redux/AppState'; -import * as Reducers from './redux/Reducers'; -import * as Epics from './redux/Epics'; -import {applyMiddleware, createStore} from 'redux'; -import { - combineEpics, - createEpicMiddleware, -} from 'nuclide-commons/redux-observable'; -import {AndroidBridge} from './bridges/AndroidBridge'; -import {TizenBridge} from './bridges/TizenBridge'; - -let fbStartTunnelingAdb; +'use strict'; + +var _Tunneling; + +function _load_Tunneling() { + return _Tunneling = _interopRequireWildcard(require('../../nuclide-adb-sdb-base/lib/Tunneling')); +} + +var _ServerConnection; + +function _load_ServerConnection() { + return _ServerConnection = require('../../nuclide-remote-connection/lib/ServerConnection'); +} + +var _nuclideAdb; + +function _load_nuclideAdb() { + return _nuclideAdb = require('../../../modules/nuclide-adb'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _ConfigurePathTaskProvider; + +function _load_ConfigurePathTaskProvider() { + return _ConfigurePathTaskProvider = require('./ConfigurePathTaskProvider'); +} + +var _AppState; + +function _load_AppState() { + return _AppState = require('./redux/AppState'); +} + +var _Reducers; + +function _load_Reducers() { + return _Reducers = _interopRequireWildcard(require('./redux/Reducers')); +} + +var _Epics; + +function _load_Epics() { + return _Epics = _interopRequireWildcard(require('./redux/Epics')); +} + +var _reduxMin; + +function _load_reduxMin() { + return _reduxMin = require('redux/dist/redux.min.js'); +} + +var _reduxObservable; + +function _load_reduxObservable() { + return _reduxObservable = require('../../../modules/nuclide-commons/redux-observable'); +} + +var _AndroidBridge; + +function _load_AndroidBridge() { + return _AndroidBridge = require('./bridges/AndroidBridge'); +} + +var _TizenBridge; + +function _load_TizenBridge() { + return _TizenBridge = require('./bridges/TizenBridge'); +} + +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; } } + +let fbStartTunnelingAdb; /** + * 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. + * + * + * @format + */ + try { // $eslint-disable-next-line $FlowFB fbStartTunnelingAdb = require('../../nuclide-adb-sdb-base/lib/fb-Tunneling'); } catch (e) {} class Activation { - _disposables: UniversalDisposable; - _store: Store; - constructor(rawState: ?Object) { - const initialState = { - ...createEmptyAppState(), - ...deserialize(rawState), - }; + constructor(rawState) { + const initialState = Object.assign({}, (0, (_AppState || _load_AppState()).createEmptyAppState)(), (0, (_AppState || _load_AppState()).deserialize)(rawState)); - const epics = Object.keys(Epics) - .map(k => Epics[k]) - .filter(epic => typeof epic === 'function'); + const epics = Object.keys(_Epics || _load_Epics()).map(k => (_Epics || _load_Epics())[k]).filter(epic => typeof epic === 'function'); - this._store = createStore( - Reducers.app, - initialState, - applyMiddleware(createEpicMiddleware(combineEpics(...epics))), - ); + this._store = (0, (_reduxMin || _load_reduxMin()).createStore)((_Reducers || _load_Reducers()).app, initialState, (0, (_reduxMin || _load_reduxMin()).applyMiddleware)((0, (_reduxObservable || _load_reduxObservable()).createEpicMiddleware)((0, (_reduxObservable || _load_reduxObservable()).combineEpics)(...epics)))); this._registerCustomDBPaths('local'); - this._disposables = new UniversalDisposable( - ServerConnection.observeRemoteConnections().subscribe(conns => - conns.map(conn => { - this._registerCustomDBPaths(conn.getUriOfRemotePath('/')); - }), - ), - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default((_ServerConnection || _load_ServerConnection()).ServerConnection.observeRemoteConnections().subscribe(conns => conns.map(conn => { + this._registerCustomDBPaths(conn.getUriOfRemotePath('/')); + }))); } - _registerCustomDBPaths(host: NuclideUri): void { + _registerCustomDBPaths(host) { const state = this._store.getState(); if (state.customAdbPaths.has(host)) { - getAdbServiceByNuclideUri(host).registerCustomPath( - state.customAdbPaths.get(host), - ); + (0, (_nuclideAdb || _load_nuclideAdb()).getAdbServiceByNuclideUri)(host).registerCustomPath(state.customAdbPaths.get(host)); } if (state.customSdbPaths.has(host)) { - getSdbServiceByNuclideUri(host).registerCustomPath( - state.customSdbPaths.get(host), - ); + (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getSdbServiceByNuclideUri)(host).registerCustomPath(state.customSdbPaths.get(host)); } } - serialize(): Object { - return serialize(this._store.getState()); + serialize() { + return (0, (_AppState || _load_AppState()).serialize)(this._store.getState()); } - dispose(): void { + dispose() { this._disposables.dispose(); } - consumeDevicePanelServiceApi(api: DevicePanelServiceApi): void { - this._disposables.add( - api.registerDeviceTypeTaskProvider( - new ConfigurePathTaskProvider(new AndroidBridge(this._store)), - ), - api.registerDeviceTypeTaskProvider( - new ConfigurePathTaskProvider(new TizenBridge(this._store)), - ), - ); + consumeDevicePanelServiceApi(api) { + this._disposables.add(api.registerDeviceTypeTaskProvider(new (_ConfigurePathTaskProvider || _load_ConfigurePathTaskProvider()).ConfigurePathTaskProvider(new (_AndroidBridge || _load_AndroidBridge()).AndroidBridge(this._store))), api.registerDeviceTypeTaskProvider(new (_ConfigurePathTaskProvider || _load_ConfigurePathTaskProvider()).ConfigurePathTaskProvider(new (_TizenBridge || _load_TizenBridge()).TizenBridge(this._store)))); } provideAdbTunnelService() { - return { - ...AdbTunnelService, - startTunnelingAdb: - fbStartTunnelingAdb != null - ? fbStartTunnelingAdb - : AdbTunnelService.startTunnelingAdb, - }; + return Object.assign({}, _Tunneling || _load_Tunneling(), { + startTunnelingAdb: fbStartTunnelingAdb != null ? fbStartTunnelingAdb : (_Tunneling || _load_Tunneling()).startTunnelingAdb + }); } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-adb-sdb/lib/redux/Actions.js b/pkg/nuclide-adb-sdb/lib/redux/Actions.js index 01d2034a05..41090cba36 100644 --- a/pkg/nuclide-adb-sdb/lib/redux/Actions.js +++ b/pkg/nuclide-adb-sdb/lib/redux/Actions.js @@ -1,3 +1,11 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.setCustomAdbPath = setCustomAdbPath; +exports.setAdbPort = setAdbPort; +exports.setCustomSdbPath = setCustomSdbPath; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,44 +13,31 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - SetCustomAdbPathAction, - SetCustomSdbPathAction, - SetAdbPortAction, -} from '../types'; - -export const SET_CUSTOM_ADB_PATH = 'SET_CUSTOM_ADB_PATH'; -export const SET_CUSTOM_SDB_PATH = 'SET_CUSTOM_SDB_PATH'; -export const SET_ADB_PORT = 'SET_ADB_PORT'; +const SET_CUSTOM_ADB_PATH = exports.SET_CUSTOM_ADB_PATH = 'SET_CUSTOM_ADB_PATH'; +const SET_CUSTOM_SDB_PATH = exports.SET_CUSTOM_SDB_PATH = 'SET_CUSTOM_SDB_PATH'; +const SET_ADB_PORT = exports.SET_ADB_PORT = 'SET_ADB_PORT'; -export function setCustomAdbPath( - host: NuclideUri, - path: ?string, -): SetCustomAdbPathAction { +function setCustomAdbPath(host, path) { return { type: SET_CUSTOM_ADB_PATH, - payload: {host, path}, + payload: { host, path } }; } -export function setAdbPort(host: NuclideUri, port: ?string): SetAdbPortAction { +function setAdbPort(host, port) { return { type: SET_ADB_PORT, - payload: {host, port}, + payload: { host, port } }; } -export function setCustomSdbPath( - host: NuclideUri, - path: ?string, -): SetCustomSdbPathAction { +function setCustomSdbPath(host, path) { return { type: SET_CUSTOM_SDB_PATH, - payload: {host, path}, + payload: { host, path } }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-adb-sdb/lib/redux/AppState.js b/pkg/nuclide-adb-sdb/lib/redux/AppState.js index 38606265e6..6e6e5730c6 100644 --- a/pkg/nuclide-adb-sdb/lib/redux/AppState.js +++ b/pkg/nuclide-adb-sdb/lib/redux/AppState.js @@ -1,3 +1,18 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.createEmptyAppState = createEmptyAppState; +exports.serialize = serialize; +exports.deserialize = deserialize; + +var _collection; + +function _load_collection() { + return _collection = require('../../../../modules/nuclide-commons/collection'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,39 +20,33 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {AppState} from '../types'; - -import {objectEntries, objectFromMap} from 'nuclide-commons/collection'; - -export function createEmptyAppState(): AppState { +function createEmptyAppState() { return { customAdbPaths: new Map(), customSdbPaths: new Map(), - adbPorts: new Map(), + adbPorts: new Map() }; } -export function serialize(state: AppState): Object { +function serialize(state) { return { - customAdbPaths: objectFromMap(state.customAdbPaths), - customSdbPaths: objectFromMap(state.customSdbPaths), - adbPorts: objectFromMap(state.adbPorts), + customAdbPaths: (0, (_collection || _load_collection()).objectFromMap)(state.customAdbPaths), + customSdbPaths: (0, (_collection || _load_collection()).objectFromMap)(state.customSdbPaths), + adbPorts: (0, (_collection || _load_collection()).objectFromMap)(state.adbPorts) }; } -export function deserialize(rawState: ?Object): ?Object { +function deserialize(rawState) { if (rawState != null) { ['customAdbPaths', 'customSdbPaths', 'adbPorts'].forEach(objectProp => { if (rawState.hasOwnProperty(objectProp)) { - rawState[objectProp] = new Map( - objectEntries(rawState[objectProp] || {}), - ); + rawState[objectProp] = new Map((0, (_collection || _load_collection()).objectEntries)(rawState[objectProp] || {})); } }); } return rawState; -} +} \ No newline at end of file diff --git a/pkg/nuclide-adb-sdb/lib/redux/Epics.js b/pkg/nuclide-adb-sdb/lib/redux/Epics.js index a466472f8c..cfa1d232f8 100644 --- a/pkg/nuclide-adb-sdb/lib/redux/Epics.js +++ b/pkg/nuclide-adb-sdb/lib/redux/Epics.js @@ -1,3 +1,34 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.setCustomAdbPathEpic = setCustomAdbPathEpic; +exports.setCustomSdbPathEpic = setCustomSdbPathEpic; +exports.setAdbPortEpic = setAdbPortEpic; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _Actions; + +function _load_Actions() { + return _Actions = _interopRequireWildcard(require('./Actions')); +} + +var _utils; + +function _load_utils() { + return _utils = require('../../../../modules/nuclide-adb/lib/utils'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../../nuclide-remote-connection'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,60 +36,36 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {ActionsObservable} from 'nuclide-commons/redux-observable'; -import type {Action, Store} from '../types'; - -import {Observable} from 'rxjs'; -import * as Actions from './Actions'; -import invariant from 'assert'; -import {getAdbServiceByNuclideUri} from 'nuclide-adb/lib/utils'; -import {getSdbServiceByNuclideUri} from '../../../nuclide-remote-connection'; - -export function setCustomAdbPathEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions - .ofType(Actions.SET_CUSTOM_ADB_PATH) - .map(action => { - invariant(action.type === Actions.SET_CUSTOM_ADB_PATH); - getAdbServiceByNuclideUri(action.payload.host).registerCustomPath( - action.payload.path, - ); - }) - .ignoreElements(); -} +function setCustomAdbPathEpic(actions, store) { + return actions.ofType((_Actions || _load_Actions()).SET_CUSTOM_ADB_PATH).map(action => { + if (!(action.type === (_Actions || _load_Actions()).SET_CUSTOM_ADB_PATH)) { + throw new Error('Invariant violation: "action.type === Actions.SET_CUSTOM_ADB_PATH"'); + } -export function setCustomSdbPathEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions - .ofType(Actions.SET_CUSTOM_SDB_PATH) - .map(action => { - invariant(action.type === Actions.SET_CUSTOM_SDB_PATH); - getSdbServiceByNuclideUri(action.payload.host).registerCustomPath( - action.payload.path, - ); - }) - .ignoreElements(); + (0, (_utils || _load_utils()).getAdbServiceByNuclideUri)(action.payload.host).registerCustomPath(action.payload.path); + }).ignoreElements(); } -export function setAdbPortEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions - .ofType(Actions.SET_ADB_PORT) - .map(action => { - invariant(action.type === Actions.SET_ADB_PORT); - getAdbServiceByNuclideUri(action.payload.host).addAdbPort( - action.payload.port, - ); - }) - .ignoreElements(); +function setCustomSdbPathEpic(actions, store) { + return actions.ofType((_Actions || _load_Actions()).SET_CUSTOM_SDB_PATH).map(action => { + if (!(action.type === (_Actions || _load_Actions()).SET_CUSTOM_SDB_PATH)) { + throw new Error('Invariant violation: "action.type === Actions.SET_CUSTOM_SDB_PATH"'); + } + + (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getSdbServiceByNuclideUri)(action.payload.host).registerCustomPath(action.payload.path); + }).ignoreElements(); } + +function setAdbPortEpic(actions, store) { + return actions.ofType((_Actions || _load_Actions()).SET_ADB_PORT).map(action => { + if (!(action.type === (_Actions || _load_Actions()).SET_ADB_PORT)) { + throw new Error('Invariant violation: "action.type === Actions.SET_ADB_PORT"'); + } + + (0, (_utils || _load_utils()).getAdbServiceByNuclideUri)(action.payload.host).addAdbPort(action.payload.port); + }).ignoreElements(); +} \ No newline at end of file diff --git a/pkg/nuclide-adb-sdb/lib/redux/Reducers.js b/pkg/nuclide-adb-sdb/lib/redux/Reducers.js index 1d1b091394..017d7372fd 100644 --- a/pkg/nuclide-adb-sdb/lib/redux/Reducers.js +++ b/pkg/nuclide-adb-sdb/lib/redux/Reducers.js @@ -1,3 +1,18 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.app = app; + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,40 +20,33 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {Action, AppState} from '../types'; - -import * as Actions from './Actions'; - -export function app(state: AppState, action: Action): AppState { +function app(state, action) { switch (action.type) { - case Actions.SET_CUSTOM_ADB_PATH: + case (_Actions || _load_Actions()).SET_CUSTOM_ADB_PATH: const customAdbPaths = new Map(state.customAdbPaths); customAdbPaths.set(action.payload.host, action.payload.path); - return { - ...state, - customAdbPaths, - }; + return Object.assign({}, state, { + customAdbPaths + }); - case Actions.SET_CUSTOM_SDB_PATH: + case (_Actions || _load_Actions()).SET_CUSTOM_SDB_PATH: const customSdbPaths = new Map(state.customSdbPaths); customSdbPaths.set(action.payload.host, action.payload.path); - return { - ...state, - customSdbPaths, - }; + return Object.assign({}, state, { + customSdbPaths + }); - case Actions.SET_ADB_PORT: + case (_Actions || _load_Actions()).SET_ADB_PORT: const adbPorts = new Map(state.adbPorts); adbPorts.set(action.payload.host, action.payload.port); - return { - ...state, - adbPorts, - }; + return Object.assign({}, state, { + adbPorts + }); default: return state; } -} +} \ No newline at end of file diff --git a/pkg/nuclide-adb-sdb/lib/types.js b/pkg/nuclide-adb-sdb/lib/types.js index 3f41d8f67c..793c7674b8 100644 --- a/pkg/nuclide-adb-sdb/lib/types.js +++ b/pkg/nuclide-adb-sdb/lib/types.js @@ -1,56 +1,13 @@ -/** - * 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 - */ +'use strict'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import {AndroidBridge} from './bridges/AndroidBridge'; -import {TizenBridge} from './bridges/TizenBridge'; +var _AndroidBridge; -export type DeviceTypeAndroid = 'Android'; -export type DeviceTypeTizen = 'Tizen'; +function _load_AndroidBridge() { + return _AndroidBridge = require('./bridges/AndroidBridge'); +} -export type Bridge = AndroidBridge | TizenBridge; +var _TizenBridge; -export type AppState = { - customAdbPaths: Map, - customSdbPaths: Map, - adbPorts: Map, -}; - -export type Store = { - getState(): AppState, - dispatch(action: Action): void, -}; - -export type SetCustomAdbPathAction = { - type: 'SET_CUSTOM_ADB_PATH', - payload: { - host: NuclideUri, - path: ?string, - }, -}; - -export type SetCustomSdbPathAction = { - type: 'SET_CUSTOM_SDB_PATH', - payload: { - host: NuclideUri, - path: ?string, - }, -}; - -export type SetAdbPortAction = { - type: 'SET_ADB_PORT', - payload: { - host: NuclideUri, - port: ?string, - }, -}; - -export type Action = SetCustomSdbPathAction | SetCustomAdbPathAction; +function _load_TizenBridge() { + return _TizenBridge = require('./bridges/TizenBridge'); +} \ No newline at end of file diff --git a/pkg/nuclide-analytics/__atom_tests__/track-test.js b/pkg/nuclide-analytics/__atom_tests__/track-test.js index 6274fbb9ae..4d7368e855 100644 --- a/pkg/nuclide-analytics/__atom_tests__/track-test.js +++ b/pkg/nuclide-analytics/__atom_tests__/track-test.js @@ -1,20 +1,35 @@ -/** - * 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 - */ - -import {setRawAnalyticsService} from 'nuclide-commons/analytics'; -import {startTracking, trackImmediate} from '..'; -import * as track from '../lib/track'; -import invariant from 'assert'; - -const sleep = n => new Promise(r => setTimeout(r, n)); +'use strict'; + +var _analytics; + +function _load_analytics() { + return _analytics = require('../../../modules/nuclide-commons/analytics'); +} + +var _; + +function _load_() { + return _ = require('..'); +} + +var _track; + +function _load_track() { + return _track = _interopRequireWildcard(require('../lib/track')); +} + +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 sleep = n => new Promise(r => setTimeout(r, n)); /** + * 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. + * + * + * @format + */ describe('startTracking', () => { let trackKey; @@ -22,7 +37,7 @@ describe('startTracking', () => { let startTime; beforeEach(() => { - setRawAnalyticsService(track); + (0, (_analytics || _load_analytics()).setRawAnalyticsService)(_track || _load_track()); jest.spyOn(process, 'hrtime').mockImplementation(() => { if (startTime == null) { startTime = Date.now(); @@ -37,7 +52,7 @@ describe('startTracking', () => { trackKey = null; trackValues = null; - jest.spyOn(track, 'track').mockImplementation((key, values) => { + jest.spyOn(_track || _load_track(), 'track').mockImplementation((key, values) => { trackKey = key; trackValues = values; return Promise.resolve(); @@ -45,12 +60,16 @@ describe('startTracking', () => { }); it('startTracking - success', async () => { - const timer = startTracking('st-success'); + const timer = (0, (_ || _load_()).startTracking)('st-success'); await sleep(10); timer.onSuccess(); - expect(track.track).toHaveBeenCalled(); + expect((_track || _load_track()).track).toHaveBeenCalled(); expect(trackKey).toBe('performance'); - invariant(trackValues != null); + + if (!(trackValues != null)) { + throw new Error('Invariant violation: "trackValues != null"'); + } + expect(Number(trackValues.duration)).toBeGreaterThanOrEqual(10); expect(trackValues.eventName).toBe('st-success'); expect(trackValues.error).toBe('0'); @@ -58,12 +77,16 @@ describe('startTracking', () => { }); it('startTracking - success with values', async () => { - const timer = startTracking('st-success', {newValue: 'value'}); + const timer = (0, (_ || _load_()).startTracking)('st-success', { newValue: 'value' }); await sleep(10); timer.onSuccess(); - expect(track.track).toHaveBeenCalled(); + expect((_track || _load_track()).track).toHaveBeenCalled(); expect(trackKey).toBe('performance'); - invariant(trackValues != null); + + if (!(trackValues != null)) { + throw new Error('Invariant violation: "trackValues != null"'); + } + expect(Number(trackValues.duration)).toBeGreaterThanOrEqual(10); expect(trackValues.eventName).toBe('st-success'); expect(trackValues.error).toBe('0'); @@ -72,12 +95,16 @@ describe('startTracking', () => { }); it('startTracking - error', async () => { - const timer = startTracking('st-error'); + const timer = (0, (_ || _load_()).startTracking)('st-error'); await sleep(11); timer.onError(new Error()); - expect(track.track).toHaveBeenCalled(); + expect((_track || _load_track()).track).toHaveBeenCalled(); expect(trackKey).toBe('performance'); - invariant(trackValues != null); + + if (!(trackValues != null)) { + throw new Error('Invariant violation: "trackValues != null"'); + } + expect(Number(trackValues.duration)).toBeGreaterThanOrEqual(11); expect(trackValues.eventName).toBe('st-error'); expect(trackValues.error).toBe('1'); @@ -85,12 +112,16 @@ describe('startTracking', () => { }); it('startTracking - error with values', async () => { - const timer = startTracking('st-error', {newValue: 'value'}); + const timer = (0, (_ || _load_()).startTracking)('st-error', { newValue: 'value' }); await sleep(11); timer.onError(new Error()); - expect(track.track).toHaveBeenCalled(); + expect((_track || _load_track()).track).toHaveBeenCalled(); expect(trackKey).toBe('performance'); - invariant(trackValues != null); + + if (!(trackValues != null)) { + throw new Error('Invariant violation: "trackValues != null"'); + } + expect(Number(trackValues.duration)).toBeGreaterThanOrEqual(11); expect(trackValues.eventName).toBe('st-error'); expect(trackValues.error).toBe('1'); @@ -102,16 +133,16 @@ describe('startTracking', () => { describe('trackImmediate', () => { let spy; beforeEach(() => { - spy = jest.spyOn(track, 'track').mockImplementation((key, values) => { + spy = jest.spyOn(_track || _load_track(), 'track').mockImplementation((key, values) => { return Promise.resolve(1); }); }); it('should call track with immediate = true', async () => { await (async () => { - const result = await trackImmediate('test', {}); + const result = await (0, (_ || _load_()).trackImmediate)('test', {}); expect(result).toBe(1); expect(spy).toHaveBeenCalledWith('test', {}, true); })(); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-analytics/__tests__/HistogramTracker-test.js b/pkg/nuclide-analytics/__tests__/HistogramTracker-test.js index 4e6159b1e3..dac8c92a53 100644 --- a/pkg/nuclide-analytics/__tests__/HistogramTracker-test.js +++ b/pkg/nuclide-analytics/__tests__/HistogramTracker-test.js @@ -1,15 +1,10 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import {HistogramTracker} from '../lib/HistogramTracker'; +var _HistogramTracker; + +function _load_HistogramTracker() { + return _HistogramTracker = require('../lib/HistogramTracker'); +} describe('HistogramTracker', () => { let trackSpy; @@ -19,7 +14,7 @@ describe('HistogramTracker', () => { jest.useFakeTimers(); const trackModule = require('../lib/track'); trackSpy = jest.spyOn(trackModule, 'track'); - tracker = new HistogramTracker('test', 100, 10, 5); + tracker = new (_HistogramTracker || _load_HistogramTracker()).HistogramTracker('test', 100, 10, 5); }); afterEach(() => { @@ -48,11 +43,7 @@ describe('HistogramTracker', () => { tracker.track(42); tracker.saveAnalytics(); - expect(trackSpy.mock.calls.map(x => x)).toEqual([ - ['performance-histogram', {average: 2, samples: 1, eventName: 'test'}], - ['performance-histogram', {average: 15, samples: 1, eventName: 'test'}], - ['performance-histogram', {average: 42, samples: 1, eventName: 'test'}], - ]); + expect(trackSpy.mock.calls.map(x => x)).toEqual([['performance-histogram', { average: 2, samples: 1, eventName: 'test' }], ['performance-histogram', { average: 15, samples: 1, eventName: 'test' }], ['performance-histogram', { average: 42, samples: 1, eventName: 'test' }]]); }); it('can be cleared', () => { @@ -66,30 +57,33 @@ describe('HistogramTracker', () => { tracker.track(2); jest.advanceTimersByTime(5 * 1000); expect(trackSpy.mock.calls.length).toBe(1); - expect(trackSpy.mock.calls[0]).toEqual([ - 'performance-histogram', - {average: 2, samples: 1, eventName: 'test'}, - ]); + expect(trackSpy.mock.calls[0]).toEqual(['performance-histogram', { average: 2, samples: 1, eventName: 'test' }]); tracker.track(42); jest.advanceTimersByTime(5 * 1000); expect(trackSpy.mock.calls.length).toBe(2); - expect(trackSpy.mock.calls[1]).toEqual([ - 'performance-histogram', - {average: 42, samples: 1, eventName: 'test'}, - ]); + expect(trackSpy.mock.calls[1]).toEqual(['performance-histogram', { average: 42, samples: 1, eventName: 'test' }]); }); -}); +}); /** + * 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. + * + * strict-local + * @format + */ describe('Histogram.dispose', () => { it('stops after dispose', () => { jest.restoreAllMocks(); const trackModule = require('../lib/track'); const trackSpy = jest.spyOn(trackModule, 'track'); - const tracker = new HistogramTracker('test', 100, 10, 5); + const tracker = new (_HistogramTracker || _load_HistogramTracker()).HistogramTracker('test', 100, 10, 5); tracker.track(1); tracker.dispose(); jest.advanceTimersByTime(5 * 1000); expect(trackSpy.mock.calls.length).toBe(0); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-analytics/lib/HistogramTracker.js b/pkg/nuclide-analytics/lib/HistogramTracker.js index 92e6882c2a..689f927807 100644 --- a/pkg/nuclide-analytics/lib/HistogramTracker.js +++ b/pkg/nuclide-analytics/lib/HistogramTracker.js @@ -1,59 +1,56 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import {track} from './track'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.HistogramTracker = undefined; -const HISTOGRAM_TRACKER_KEY = 'performance-histogram'; +var _track; + +function _load_track() { + return _track = require('./track'); +} + +const HISTOGRAM_TRACKER_KEY = 'performance-histogram'; /** + * 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. + * + * strict-local + * @format + */ class Bucket { - _count: number; - _sum: number; constructor() { this._count = 0; this._sum = 0; } - addValue(value: number): void { + addValue(value) { this._sum += value; this._count++; } - getCount(): number { + getCount() { return this._count; } - getAverage(): number { + getAverage() { return this._count > 0 ? this._sum / this._count : 0; } - clear(): void { + clear() { this._count = 0; this._sum = 0; } } -export class HistogramTracker { - _eventName: string; - _maxValue: number; - _bucketSize: number; - _buckets: Array; - _intervalId: IntervalID; - - constructor( - eventName: string, - maxValue: number, - numBuckets: number, - intervalSeconds: number = 60, - ) { +class HistogramTracker { + + constructor(eventName, maxValue, numBuckets, intervalSeconds = 60) { this._eventName = eventName; this._maxValue = maxValue; this._bucketSize = maxValue / numBuckets; @@ -72,32 +69,30 @@ export class HistogramTracker { clearInterval(this._intervalId); } - track(value: number): HistogramTracker { - const bucket = Math.min( - this._buckets.length - 1, - Math.floor(value / this._bucketSize), - ); + track(value) { + const bucket = Math.min(this._buckets.length - 1, Math.floor(value / this._bucketSize)); this._buckets[bucket].addValue(value); return this; } - saveAnalytics(): void { + saveAnalytics() { for (let i = 0; i < this._buckets.length; i++) { const bucket = this._buckets[i]; - if (bucket.getCount() > 0 && track != null) { - track(HISTOGRAM_TRACKER_KEY, { + if (bucket.getCount() > 0 && (_track || _load_track()).track != null) { + (0, (_track || _load_track()).track)(HISTOGRAM_TRACKER_KEY, { eventName: this._eventName, average: bucket.getAverage(), - samples: bucket.getCount(), + samples: bucket.getCount() }); } } this.clear(); } - clear(): void { + clear() { for (let i = 0; i < this._buckets.length; i++) { this._buckets[i].clear(); } } } +exports.HistogramTracker = HistogramTracker; \ No newline at end of file diff --git a/pkg/nuclide-analytics/lib/analytics.js b/pkg/nuclide-analytics/lib/analytics.js index 6ea40b056e..902d8db351 100644 --- a/pkg/nuclide-analytics/lib/analytics.js +++ b/pkg/nuclide-analytics/lib/analytics.js @@ -1,3 +1,10 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.track = track; +exports.isTrackSupported = isTrackSupported; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,19 +12,15 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ // This is a stubbed implementation that other packages use to record analytics data & performance. -export function track( - eventName: string, - values?: {[key: string]: mixed}, - immediate?: boolean, -): ?Promise {} +function track(eventName, values, immediate) {} // Other packages can check this to avoid doing work that will be ignored // anyway by the stubbed track implementation. -export function isTrackSupported(): boolean { +function isTrackSupported() { return false; -} +} \ No newline at end of file diff --git a/pkg/nuclide-analytics/lib/main.js b/pkg/nuclide-analytics/lib/main.js index 9e5cca4612..7acfdcc4e7 100644 --- a/pkg/nuclide-analytics/lib/main.js +++ b/pkg/nuclide-analytics/lib/main.js @@ -1,26 +1,85 @@ -/** - * 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 - */ +'use strict'; -export {HistogramTracker} from './HistogramTracker'; -export type {TrackingEvent} from 'nuclide-commons/analytics'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -export { - startTracking, - TimingTracker, - track, - trackEvent, - trackEvents, - trackImmediate, - trackSampled, - trackTiming, - trackTimingSampled, - isTrackSupported, -} from 'nuclide-commons/analytics'; +var _HistogramTracker; + +function _load_HistogramTracker() { + return _HistogramTracker = require('./HistogramTracker'); +} + +Object.defineProperty(exports, 'HistogramTracker', { + enumerable: true, + get: function () { + return (_HistogramTracker || _load_HistogramTracker()).HistogramTracker; + } +}); + +var _analytics; + +function _load_analytics() { + return _analytics = require('../../../modules/nuclide-commons/analytics'); +} + +Object.defineProperty(exports, 'startTracking', { + enumerable: true, + get: function () { + return (_analytics || _load_analytics()).startTracking; + } +}); +Object.defineProperty(exports, 'TimingTracker', { + enumerable: true, + get: function () { + return (_analytics || _load_analytics()).TimingTracker; + } +}); +Object.defineProperty(exports, 'track', { + enumerable: true, + get: function () { + return (_analytics || _load_analytics()).track; + } +}); +Object.defineProperty(exports, 'trackEvent', { + enumerable: true, + get: function () { + return (_analytics || _load_analytics()).trackEvent; + } +}); +Object.defineProperty(exports, 'trackEvents', { + enumerable: true, + get: function () { + return (_analytics || _load_analytics()).trackEvents; + } +}); +Object.defineProperty(exports, 'trackImmediate', { + enumerable: true, + get: function () { + return (_analytics || _load_analytics()).trackImmediate; + } +}); +Object.defineProperty(exports, 'trackSampled', { + enumerable: true, + get: function () { + return (_analytics || _load_analytics()).trackSampled; + } +}); +Object.defineProperty(exports, 'trackTiming', { + enumerable: true, + get: function () { + return (_analytics || _load_analytics()).trackTiming; + } +}); +Object.defineProperty(exports, 'trackTimingSampled', { + enumerable: true, + get: function () { + return (_analytics || _load_analytics()).trackTimingSampled; + } +}); +Object.defineProperty(exports, 'isTrackSupported', { + enumerable: true, + get: function () { + return (_analytics || _load_analytics()).isTrackSupported; + } +}); \ No newline at end of file diff --git a/pkg/nuclide-analytics/lib/track.js b/pkg/nuclide-analytics/lib/track.js index 259ba6a653..38156cc2f8 100644 --- a/pkg/nuclide-analytics/lib/track.js +++ b/pkg/nuclide-analytics/lib/track.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +7,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ @@ -17,4 +19,4 @@ try { module.exports = require('../fb/analytics'); } catch (e) { module.exports = require('./analytics'); -} +} \ No newline at end of file diff --git a/pkg/nuclide-artillery/lib/main.js b/pkg/nuclide-artillery/lib/main.js index 374bc4c29a..5a5d658d9b 100644 --- a/pkg/nuclide-artillery/lib/main.js +++ b/pkg/nuclide-artillery/lib/main.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +7,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ @@ -16,4 +18,4 @@ try { module.exports = require('../fb/trace'); } catch (e) { module.exports = require('./trace'); -} +} \ No newline at end of file diff --git a/pkg/nuclide-artillery/lib/trace.js b/pkg/nuclide-artillery/lib/trace.js index ee7cded828..de35dae2fe 100644 --- a/pkg/nuclide-artillery/lib/trace.js +++ b/pkg/nuclide-artillery/lib/trace.js @@ -1,3 +1,8 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,14 +10,15 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -export class NuclideArtilleryTrace { - static begin(categoryName: string, eventName: string): NuclideArtilleryTrace { +class NuclideArtilleryTrace { + static begin(categoryName, eventName) { return new NuclideArtilleryTrace(); } - end(): void {} + end() {} } +exports.NuclideArtilleryTrace = NuclideArtilleryTrace; \ No newline at end of file diff --git a/pkg/nuclide-atom-notifications/lib/main.js b/pkg/nuclide-atom-notifications/lib/main.js index a2da0894ac..23bff001c6 100644 --- a/pkg/nuclide-atom-notifications/lib/main.js +++ b/pkg/nuclide-atom-notifications/lib/main.js @@ -1,43 +1,59 @@ -/** - * 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 - */ +'use strict'; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _marked; + +function _load_marked() { + return _marked = _interopRequireDefault(require('marked')); +} + +var _createPackage; -import type {ConsoleLevel, ConsoleService} from 'atom-ide-ui'; +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import marked from 'marked'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import createDOMPurify from 'dompurify'; +var _dompurify; -const domPurify = createDOMPurify(); +function _load_dompurify() { + return _dompurify = _interopRequireDefault(require('dompurify')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const domPurify = (0, (_dompurify || _load_dompurify()).default)(); /** + * 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. + * + * + * @format + */ class Activation { - _disposables: UniversalDisposable; constructor() { - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - consumeConsoleService(createConsole: ConsoleService): IDisposable { + consumeConsoleService(createConsole) { const consoleApi = createConsole({ id: 'Atom', - name: 'Atom', + name: 'Atom' + }); + const notificationDisposable = atom.notifications.onDidAddNotification(notification => { + consoleApi.append({ + text: stripFormatting(notification.getMessage()), + level: getLevel(notification.getType()) + }); }); - const notificationDisposable = atom.notifications.onDidAddNotification( - notification => { - consoleApi.append({ - text: stripFormatting(notification.getMessage()), - level: getLevel(notification.getType()), - }); - }, - ); this._disposables.add(consoleApi, notificationDisposable); return notificationDisposable; } @@ -47,7 +63,7 @@ class Activation { } } -function getLevel(atomNotificationType: string): ConsoleLevel { +function getLevel(atomNotificationType) { switch (atomNotificationType) { case 'error': case 'fatal': @@ -66,8 +82,8 @@ function getLevel(atomNotificationType: string): ConsoleLevel { /** * Markdown and HTML can be used with Atom notifications, but not in the console. */ -function stripFormatting(raw: string): string { - return domPurify.sanitize(marked(raw), {ALLOWED_TAGS: []}); +function stripFormatting(raw) { + return domPurify.sanitize((0, (_marked || _load_marked()).default)(raw), { ALLOWED_TAGS: [] }); } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-atom-script/lib/test-runner.js b/pkg/nuclide-atom-script/lib/test-runner.js index f6fceade98..27e3851a89 100644 --- a/pkg/nuclide-atom-script/lib/test-runner.js +++ b/pkg/nuclide-atom-script/lib/test-runner.js @@ -1,13 +1,36 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _string; + +function _load_string() { + return _string = require('../../../modules/nuclide-commons/string'); +} + +var _console = require('console'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Redirect `console` to output through to stdout/stderr. +const outputConsole = new _console.Console(process.stdout, process.stderr); /** + * 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. + * + * + * @format + */ // PRO-TIP: To debug this file, open it in Atom, and from the console, run: // @@ -20,40 +43,33 @@ // process will have production options set - not test options like // `--user-data-dir`. -import type {ExitCode, TestRunnerParams} from './types'; - -import invariant from 'assert'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {shellParse} from 'nuclide-commons/string'; -import {Console} from 'console'; - -// Redirect `console` to output through to stdout/stderr. -const outputConsole = new Console(process.stdout, process.stderr); - -export default (async function runTest( - params: TestRunnerParams, -): Promise { +exports.default = async function runTest(params) { let exitCode = 0; try { const atomGlobal = params.buildAtomEnvironment({ applicationDelegate: params.buildDefaultApplicationDelegate(), document, - window, + window }); // This is the spec runner but Nuclide code shouldn't think this is a spec. // (This ensures that `atom.inSpecMode()` returns false.) - (atomGlobal: any).specMode = false; + atomGlobal.specMode = false; atomGlobal.atomScriptMode = true; - invariant(typeof process.env.FILE_ATOM_SCRIPT === 'string'); + if (!(typeof process.env.FILE_ATOM_SCRIPT === 'string')) { + throw new Error('Invariant violation: "typeof process.env.FILE_ATOM_SCRIPT === \'string\'"'); + } + const fileAtomScript = process.env.FILE_ATOM_SCRIPT; - invariant(typeof process.env.ARGS_ATOM_SCRIPT === 'string'); + if (!(typeof process.env.ARGS_ATOM_SCRIPT === 'string')) { + throw new Error('Invariant violation: "typeof process.env.ARGS_ATOM_SCRIPT === \'string\'"'); + } + const argsAtomScript = process.env.ARGS_ATOM_SCRIPT; - const scriptPath = nuclideUri.resolve(fileAtomScript); - const scriptArgs = - argsAtomScript === "''" ? [] : shellParse(argsAtomScript); + const scriptPath = (_nuclideUri || _load_nuclideUri()).default.resolve(fileAtomScript); + const scriptArgs = argsAtomScript === "''" ? [] : (0, (_string || _load_string()).shellParse)(argsAtomScript); // Unfortunately we have to pollute our environment if we want to take // advantage of Atom's v8 cache. Ideally, we'd run the script file using @@ -87,4 +103,4 @@ export default (async function runTest( }); return exitCode; -}); +}; \ No newline at end of file diff --git a/pkg/nuclide-atom-script/lib/types.js b/pkg/nuclide-atom-script/lib/types.js index b3e4358388..9a390c31f7 100644 --- a/pkg/nuclide-atom-script/lib/types.js +++ b/pkg/nuclide-atom-script/lib/types.js @@ -1,35 +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 - */ - -export type TestRunnerParams = { - /** Absolute paths to tests to run. Could be paths to files or directories. */ - testPaths: Array, - /** A boolean indicating whether or not the tests are running headless. */ - headless: boolean, - /** Creates the `atom` global object. */ - buildAtomEnvironment: (params: BuildAtomEnvironmentParams) => AtomGlobal, - /** Currently undocumented, but seemingly necessary to use buildAtomEnvironment(). */ - buildDefaultApplicationDelegate: () => Object, - /** An optional path to a log file to which test output should be logged. */ - logFile: ?string, - /** Unclear what the contract of this is, but we will not be using it. */ - legacyTestRunner: () => void, -}; - -export type BuildAtomEnvironmentParams = { - applicationDelegate: Object, - window: Object, - document: Object, - configDirPath?: string, - enablePersistence?: boolean, -}; - -export type ExitCode = number; +"use strict"; \ No newline at end of file diff --git a/pkg/nuclide-atom-script/samples/echo.js b/pkg/nuclide-atom-script/samples/echo.js index a4c41fa3d5..3317e7b876 100644 --- a/pkg/nuclide-atom-script/samples/echo.js +++ b/pkg/nuclide-atom-script/samples/echo.js @@ -1,13 +1,23 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = async function runCommand(args) { + const message = args.length === 0 ? 'Please pass me an arg!' : args.join(' '); + console.log(message); + return 0; +}; /** + * 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. + * + * strict-local + * @format + */ /* * This is a simple way to see nuclide-atom-scripting in action: @@ -26,14 +36,4 @@ * you must set the USE_DEV environment variable when running bootstrap. */ -/* eslint-disable no-console */ - -import type {ExitCode} from '../lib/types'; - -export default (async function runCommand( - args: Array, -): Promise { - const message = args.length === 0 ? 'Please pass me an arg!' : args.join(' '); - console.log(message); - return 0; -}); +/* eslint-disable no-console */ \ No newline at end of file diff --git a/pkg/nuclide-atom-script/samples/keybindings.js b/pkg/nuclide-atom-script/samples/keybindings.js index 5f8fcadeea..bc6c60106e 100644 --- a/pkg/nuclide-atom-script/samples/keybindings.js +++ b/pkg/nuclide-atom-script/samples/keybindings.js @@ -1,21 +1,10 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -/* eslint-disable no-console */ - -import type {ExitCode} from '../lib/types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -export default (async function runCommand( - args: Array, -): Promise { +exports.default = async function runCommand(args) { const commands = []; for (const keybinding of atom.keymaps.getKeyBindings()) { commands.push(keybinding.command); @@ -24,4 +13,15 @@ export default (async function runCommand( commands.sort(); commands.forEach(command => console.log(command)); return 0; -}); +}; /** + * 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. + * + * strict-local + * @format + */ + +/* eslint-disable no-console */ \ No newline at end of file diff --git a/pkg/nuclide-atom-script/samples/markdown.js b/pkg/nuclide-atom-script/samples/markdown.js index 47021d2bb4..be3be1a6af 100644 --- a/pkg/nuclide-atom-script/samples/markdown.js +++ b/pkg/nuclide-atom-script/samples/markdown.js @@ -1,3 +1,25 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _fs = _interopRequireDefault(require('fs')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _yargs; + +function _load_yargs() { + return _yargs = _interopRequireDefault(require('yargs')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,41 +27,21 @@ * 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-console */ -import type {ExitCode} from '../lib/types'; - -import fs from 'fs'; -import invariant from 'assert'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import yargs from 'yargs'; - -export default (async function runCommand( - args: Array, -): Promise { +exports.default = async function runCommand(args) { const argv = await new Promise((resolve, reject) => { - resolve( - yargs - .usage( - `Usage: atom-script ${__dirname}/markdown.js -o `, - ) - .help('h') - .alias('h', 'help') - .option('out', { - alias: 'o', - demand: false, - describe: 'Must specify a path to an output file.', - type: 'string', - }) - .demand(1, 'Must specify a path to a Markdown file.') - .exitProcess(false) - .fail(reject) // This will bubble up and cause runCommand() to reject. - .parse(args), - ); + resolve((_yargs || _load_yargs()).default.usage(`Usage: atom-script ${__dirname}/markdown.js -o `).help('h').alias('h', 'help').option('out', { + alias: 'o', + demand: false, + describe: 'Must specify a path to an output file.', + type: 'string' + }).demand(1, 'Must specify a path to a Markdown file.').exitProcess(false).fail(reject) // This will bubble up and cause runCommand() to reject. + .parse(args)); }); // When this happens, the help text has already been printed to stdout. @@ -55,11 +57,14 @@ export default (async function runCommand( await atom.packages.activatePackage('markdown-preview'); // Use markdown-preview to generate the HTML. - const markdownPreviewPackage = atom.packages.getActivePackage( - 'markdown-preview', - ); - invariant(markdownPreviewPackage); + const markdownPreviewPackage = atom.packages.getActivePackage('markdown-preview'); + + if (!markdownPreviewPackage) { + throw new Error('Invariant violation: "markdownPreviewPackage"'); + } // Apparently copyHTML() is exposed as an export of markdown-preview. + + markdownPreviewPackage.mainModule.copyHTML(); // Note it should be possible to get the HTML via MarkdownPreviewView.getHTML(), // but that was causing this script to lock up, for some reason. @@ -70,13 +75,10 @@ export default (async function runCommand( // We create a MarkdownPreviewView to call its getMarkdownPreviewCSS() method. // $FlowIssue: Need to dynamically load a path. - const MarkdownPreviewView = require(nuclideUri.join( - markdownPreviewPackage.path, - 'lib/markdown-preview-view.js', - )); + const MarkdownPreviewView = require((_nuclideUri || _load_nuclideUri()).default.join(markdownPreviewPackage.path, 'lib/markdown-preview-view.js')); const view = new MarkdownPreviewView({ editorId: textEditor.id, - filePath: markdownFile, + filePath: markdownFile }); const styles = view.getMarkdownPreviewCSS(); @@ -103,20 +105,26 @@ export default (async function runCommand( console.log(html); } else { const outputFile = resolvePath(argv.out); - fs.writeFileSync(outputFile, html); + _fs.default.writeFileSync(outputFile, html); } return 0; -}); +}; // TODO(mbolin): Consider using fs-plus to ensure this handles ~ in fileName correctly. -function resolvePath(fileName): string { - if (!nuclideUri.isAbsolute(fileName)) { + + +function resolvePath(fileName) { + if (!(_nuclideUri || _load_nuclideUri()).default.isAbsolute(fileName)) { const pwd = process.env.PWD; // flowlint-next-line sketchy-null-string:off - invariant(pwd); - return nuclideUri.join(pwd, fileName); + + if (!pwd) { + throw new Error('Invariant violation: "pwd"'); + } + + return (_nuclideUri || _load_nuclideUri()).default.join(pwd, fileName); } else { return fileName; } -} +} \ No newline at end of file diff --git a/pkg/nuclide-atom-script/samples/run-package-specs.js b/pkg/nuclide-atom-script/samples/run-package-specs.js index 7d03c9befd..6176e39f9e 100644 --- a/pkg/nuclide-atom-script/samples/run-package-specs.js +++ b/pkg/nuclide-atom-script/samples/run-package-specs.js @@ -1,30 +1,40 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -/* eslint-disable no-console */ +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _electron = _interopRequireDefault(require('electron')); + +var _path = _interopRequireDefault(require('path')); + +var _promise; -import type {ExitCode} from '../lib/types'; +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -import invariant from 'assert'; -import electron from 'electron'; // eslint-disable-next-line nuclide-internal/prefer-nuclide-uri -import path from 'path'; -import {sleep} from 'nuclide-commons/promise'; +const { ipcRenderer, remote } = _electron.default; /** + * 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. + * + * strict-local + * @format + */ + +/* eslint-disable no-console */ -const {ipcRenderer, remote} = electron; -invariant(ipcRenderer != null && remote != null); +if (!(ipcRenderer != null && remote != null)) { + throw new Error('Invariant violation: "ipcRenderer != null && remote != null"'); +} -export default (async function runCommand( - args: Array, -): Promise { +exports.default = async function runCommand(args) { if (typeof args[0] !== 'string') { console.error(`Usage: atom-script ${__filename} `); return 1; @@ -32,17 +42,15 @@ export default (async function runCommand( const initialWindows = remote.BrowserWindow.getAllWindows(); - const packageSpecPath = path.resolve(args[0]); + const packageSpecPath = _path.default.resolve(args[0]); ipcRenderer.send('run-package-specs', packageSpecPath); // Wait for the window to load - await sleep(1000); + await (0, (_promise || _load_promise()).sleep)(1000); - const testWindow = remote.BrowserWindow.getAllWindows().find( - browserWindow => { - return !initialWindows.includes(browserWindow); - }, - ); + const testWindow = remote.BrowserWindow.getAllWindows().find(browserWindow => { + return !initialWindows.includes(browserWindow); + }); if (testWindow == null) { console.error('Could not find spec browser window.'); @@ -58,4 +66,4 @@ export default (async function runCommand( }); return 0; -}); +}; \ No newline at end of file diff --git a/pkg/nuclide-atom-script/samples/versions.js b/pkg/nuclide-atom-script/samples/versions.js index f6725b5717..c81e76c7f3 100644 --- a/pkg/nuclide-atom-script/samples/versions.js +++ b/pkg/nuclide-atom-script/samples/versions.js @@ -1,28 +1,31 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -/* eslint-disable no-console */ +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _chalk; -import chalk from 'chalk'; +function _load_chalk() { + return _chalk = _interopRequireDefault(require('chalk')); +} -import type {ExitCode} from '../lib/types'; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -export default (async function runCommand(): Promise { - const ctx = new chalk.constructor({enabled: true}); - const out = Object.keys(process.versions) - .map(key => [key, process.versions[key]]) - .concat([['atom', atom.getVersion()]]) - .map(([name, version]) => `${ctx.yellow(name)}=${ctx.green(version)}`) - .sort() - .join('\n'); +exports.default = async function runCommand() { + const ctx = new (_chalk || _load_chalk()).default.constructor({ enabled: true }); + const out = Object.keys(process.versions).map(key => [key, process.versions[key]]).concat([['atom', atom.getVersion()]]).map(([name, version]) => `${ctx.yellow(name)}=${ctx.green(version)}`).sort().join('\n'); console.log(out); return 0; -}); +}; /** + * 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. + * + * strict-local + * @format + */ + +/* eslint-disable no-console */ \ No newline at end of file diff --git a/pkg/nuclide-autocomplete/__atom_tests__/createAutocompleteProvider-test.js b/pkg/nuclide-autocomplete/__atom_tests__/createAutocompleteProvider-test.js index 0cb6ab8917..9cf817b206 100644 --- a/pkg/nuclide-autocomplete/__atom_tests__/createAutocompleteProvider-test.js +++ b/pkg/nuclide-autocomplete/__atom_tests__/createAutocompleteProvider-test.js @@ -1,35 +1,32 @@ -/** - * 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 - */ +'use strict'; -import createAutocompleteProvider from '../lib/createAutocompleteProvider'; +var _createAutocompleteProvider; + +function _load_createAutocompleteProvider() { + return _createAutocompleteProvider = _interopRequireDefault(require('../lib/createAutocompleteProvider')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } describe('getSuggestions', () => { - const fakeRequest: any = { + const fakeRequest = { bufferPosition: {}, editor: { - getPath: () => '', - }, + getPath: () => '' + } }; - const autocompleteProviderThatThrowsExecption = createAutocompleteProvider({ + const autocompleteProviderThatThrowsExecption = (0, (_createAutocompleteProvider || _load_createAutocompleteProvider()).default)({ selector: '', getSuggestions() { throw new Error(); }, analytics: { eventName: 'test', - shouldLogInsertedSuggestion: false, - }, + shouldLogInsertedSuggestion: false + } }); - const autocompleteProviderThatTimeOut = createAutocompleteProvider({ + const autocompleteProviderThatTimeOut = (0, (_createAutocompleteProvider || _load_createAutocompleteProvider()).default)({ selector: '', getSuggestions() { return new Promise((resolve, reject) => { @@ -38,28 +35,20 @@ describe('getSuggestions', () => { }, analytics: { eventName: 'test', - shouldLogInsertedSuggestion: false, - }, + shouldLogInsertedSuggestion: false + } }); let trackSpy; beforeEach(() => { jest.restoreAllMocks(); - trackSpy = jest.spyOn(require('nuclide-commons/analytics'), 'track'); + trackSpy = jest.spyOn(require('../../../modules/nuclide-commons/analytics'), 'track'); }); it('returns null when it throws an exception', async () => { await (async () => { - expect( - await autocompleteProviderThatThrowsExecption.getSuggestions( - ({...fakeRequest, activatedManually: false}: any), - ), - ).toBe(null); - expect( - await autocompleteProviderThatThrowsExecption.getSuggestions( - ({...fakeRequest, activatedManually: true}: any), - ), - ).toBe(null); + expect((await autocompleteProviderThatThrowsExecption.getSuggestions(Object.assign({}, fakeRequest, { activatedManually: false })))).toBe(null); + expect((await autocompleteProviderThatThrowsExecption.getSuggestions(Object.assign({}, fakeRequest, { activatedManually: true })))).toBe(null); })(); }); @@ -67,21 +56,24 @@ describe('getSuggestions', () => { await (async () => { await autocompleteProviderThatThrowsExecption.getSuggestions(fakeRequest); expect(trackSpy.mock.calls).toHaveLength(1); - expect(trackSpy.mock.calls[0][0]).toBe( - 'test:autocomplete:error-on-get-suggestions', - ); + expect(trackSpy.mock.calls[0][0]).toBe('test:autocomplete:error-on-get-suggestions'); })(); }); it('tracks when it times out', async () => { await (async () => { - expect( - await autocompleteProviderThatTimeOut.getSuggestions(fakeRequest), - ).toBe(null); + expect((await autocompleteProviderThatTimeOut.getSuggestions(fakeRequest))).toBe(null); expect(trackSpy.mock.calls.length).toBe(1); - expect(trackSpy.mock.calls[0][0]).toBe( - 'test:autocomplete:timeout-on-get-suggestions', - ); + expect(trackSpy.mock.calls[0][0]).toBe('test:autocomplete:timeout-on-get-suggestions'); })(); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-autocomplete/lib/__flowtests__/types-flowtest.js b/pkg/nuclide-autocomplete/lib/__flowtests__/types-flowtest.js index 86401099e1..bf662c3c68 100644 --- a/pkg/nuclide-autocomplete/lib/__flowtests__/types-flowtest.js +++ b/pkg/nuclide-autocomplete/lib/__flowtests__/types-flowtest.js @@ -1,18 +1,14 @@ -/** - * 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 - */ - -import type {AutocompleteProvider} from '../types'; +'use strict'; // Make sure that AutocompleteProvider is a super type of // atom$AutocompleteProvider -(((null: any): AutocompleteProvider< - atom$AutocompleteSuggestion, ->): atom$AutocompleteProvider); +null; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-autocomplete/lib/createAutocompleteProvider.js b/pkg/nuclide-autocomplete/lib/createAutocompleteProvider.js index 7ddccbee22..c1df1a49bc 100644 --- a/pkg/nuclide-autocomplete/lib/createAutocompleteProvider.js +++ b/pkg/nuclide-autocomplete/lib/createAutocompleteProvider.js @@ -1,28 +1,29 @@ -/** - * 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 - */ +'use strict'; -import type { - AutocompleteProvider, - AutocompleteAnalyticEventNames, - AtomSuggestionInsertedRequest, -} from './types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = createAutocompleteProvider; + +var _performanceNow; + +function _load_performanceNow() { + return _performanceNow = _interopRequireDefault(require('../../../modules/nuclide-commons/performanceNow')); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} -import performanceNow from 'nuclide-commons/performanceNow'; -import {sleep, TimedOutError} from 'nuclide-commons/promise'; -import { - track, - trackSampled, - trackTiming, - trackTimingSampled, -} from '../../nuclide-analytics'; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Autocomplete is extremely critical to the user experience! @@ -33,6 +34,17 @@ import { * autocomplete check happens right after you open the file and providers don't * have enough time to initialize. */ +/** + * 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. + * + * + * @format + */ + const AUTOCOMPLETE_TIMEOUT = atom.inSpecMode() ? 3000 : 500; const E2E_SAMPLE_RATE = 10; const ON_GET_SUGGESTIONS_SAMPLE_RATE = 10; @@ -43,9 +55,7 @@ const durationBySuggestion = new WeakMap(); * Receives a provider and returns a proxy provider that applies time limit to * `getSuggestions` calls and stop unhandled exceptions on to cascade. */ -export default function createAutocompleteProvider< - Suggestion: atom$AutocompleteSuggestion, ->(provider: AutocompleteProvider): atom$AutocompleteProvider { +function createAutocompleteProvider(provider) { // The `eventNames` could be computed in deep functions, but we don't want // to change the logger if a provider decides to changes its name. const eventNames = getAnalytics(provider); @@ -65,194 +75,139 @@ export default function createAutocompleteProvider< default: return Reflect.get(target, prop, receiver); } - }, + } }); // It is safe to cast it to any since AutocompleteProvider is a super type of // atom$AutocompleteProvider - return (proxy: any); + return proxy; } -type RequestTracker = {| - // Share a single "timeout" promise among all fetches for the same request. - // The timeout doubles as the trigger to log the slowest provider time. - timeoutPromise: Promise, - slowestProvider: AutocompleteProvider, - slowestProviderTime: number, - pendingProviders: number, -|}; -const requestTrackers: WeakMap = new WeakMap(); +const requestTrackers = new WeakMap(); -function _getRequestTracker( - request: atom$AutocompleteRequest, - provider: AutocompleteProvider, -): RequestTracker { +function _getRequestTracker(request, provider) { // Kind of hacky.. but the bufferPosition is a unique object per request. const key = request.bufferPosition; const tracker = requestTrackers.get(key); if (tracker != null) { return tracker; } - const startTime = performanceNow(); + const startTime = (0, (_performanceNow || _load_performanceNow()).default)(); const newTracker = { - timeoutPromise: sleep(AUTOCOMPLETE_TIMEOUT).then(() => { + timeoutPromise: (0, (_promise || _load_promise()).sleep)(AUTOCOMPLETE_TIMEOUT).then(() => { if (newTracker.pendingProviders) { - trackSampled('e2e-autocomplete', E2E_SAMPLE_RATE, { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackSampled)('e2e-autocomplete', E2E_SAMPLE_RATE, { path: request.editor.getPath(), duration: AUTOCOMPLETE_TIMEOUT, slowestProvider: 'timeout', - pendingProviders: newTracker.pendingProviders, + pendingProviders: newTracker.pendingProviders }); - throw new TimedOutError(AUTOCOMPLETE_TIMEOUT); + throw new (_promise || _load_promise()).TimedOutError(AUTOCOMPLETE_TIMEOUT); } - const {slowestProvider, slowestProviderTime} = newTracker; - trackSampled('e2e-autocomplete', E2E_SAMPLE_RATE, { + const { slowestProvider, slowestProviderTime } = newTracker; + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackSampled)('e2e-autocomplete', E2E_SAMPLE_RATE, { path: request.editor.getPath(), duration: Math.round(slowestProviderTime - startTime), - slowestProvider: slowestProvider.analytics.eventName, + slowestProvider: slowestProvider.analytics.eventName }); }), slowestProvider: provider, slowestProviderTime: startTime, - pendingProviders: 0, + pendingProviders: 0 }; requestTrackers.set(key, newTracker); return newTracker; } -function getSuggestions( - provider: AutocompleteProvider, - eventNames: AutocompleteAnalyticEventNames, - request: atom$AutocompleteRequest, -): Promise> | ?Array<*> { +function getSuggestions(provider, eventNames, request) { const logObject = {}; const requestTracker = _getRequestTracker(request, provider); requestTracker.pendingProviders++; - return trackTimingSampled( - eventNames.onGetSuggestions, - async () => { - let result = null; - const startTime = performanceNow(); - if (request.activatedManually) { - try { - result = await provider.getSuggestions(request); - } catch (e) { - track(eventNames.errorOnGetSuggestions); - } - } else { - try { - result = await Promise.race([ - Promise.resolve(provider.getSuggestions(request)), - requestTracker.timeoutPromise, - ]); - } catch (e) { - if (e instanceof TimedOutError) { - track(eventNames.timeoutOnGetSuggestions); - } else { - track(eventNames.errorOnGetSuggestions); - } - } + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTimingSampled)(eventNames.onGetSuggestions, async () => { + let result = null; + const startTime = (0, (_performanceNow || _load_performanceNow()).default)(); + if (request.activatedManually) { + try { + result = await provider.getSuggestions(request); + } catch (e) { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)(eventNames.errorOnGetSuggestions); } - logObject.isEmpty = result == null || result.length === 0; - const endTime = performanceNow(); - requestTracker.slowestProvider = provider; - requestTracker.slowestProviderTime = endTime; - requestTracker.pendingProviders--; - if (result) { - result.forEach(suggestion => - durationBySuggestion.set(suggestion, endTime - startTime), - ); + } else { + try { + result = await Promise.race([Promise.resolve(provider.getSuggestions(request)), requestTracker.timeoutPromise]); + } catch (e) { + if (e instanceof (_promise || _load_promise()).TimedOutError) { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)(eventNames.timeoutOnGetSuggestions); + } else { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)(eventNames.errorOnGetSuggestions); + } } - return result; - }, - ON_GET_SUGGESTIONS_SAMPLE_RATE, - logObject, - ); + } + logObject.isEmpty = result == null || result.length === 0; + const endTime = (0, (_performanceNow || _load_performanceNow()).default)(); + requestTracker.slowestProvider = provider; + requestTracker.slowestProviderTime = endTime; + requestTracker.pendingProviders--; + if (result) { + result.forEach(suggestion => durationBySuggestion.set(suggestion, endTime - startTime)); + } + return result; + }, ON_GET_SUGGESTIONS_SAMPLE_RATE, logObject); } -function getSuggestionDetailsOnSelect( - provider: AutocompleteProvider, - eventNames: AutocompleteAnalyticEventNames, - suggestion: Suggestion, -): Promise { +function getSuggestionDetailsOnSelect(provider, eventNames, suggestion) { const logObject = {}; - return trackTiming( - eventNames.onGetSuggestionDetailsOnSelect, - async () => { - let result = null; - if (provider.getSuggestionDetailsOnSelect != null) { - try { - result = await provider.getSuggestionDetailsOnSelect(suggestion); - } catch (e) { - track(eventNames.errorOnGetSuggestionDetailsOnSelect); - } + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(eventNames.onGetSuggestionDetailsOnSelect, async () => { + let result = null; + if (provider.getSuggestionDetailsOnSelect != null) { + try { + result = await provider.getSuggestionDetailsOnSelect(suggestion); + } catch (e) { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)(eventNames.errorOnGetSuggestionDetailsOnSelect); } - logObject.isEmpty = result == null; + } + logObject.isEmpty = result == null; - return result; - }, - logObject, - ); + return result; + }, logObject); } -function onDidInsertSuggestion( - provider: AutocompleteProvider, - eventNames: AutocompleteAnalyticEventNames, - insertedSuggestionArgument: AtomSuggestionInsertedRequest, -): void { - trackOnDidInsertSuggestion( - eventNames.onDidInsertSuggestion, - provider.analytics.shouldLogInsertedSuggestion, - insertedSuggestionArgument, - ); +function onDidInsertSuggestion(provider, eventNames, insertedSuggestionArgument) { + trackOnDidInsertSuggestion(eventNames.onDidInsertSuggestion, provider.analytics.shouldLogInsertedSuggestion, insertedSuggestionArgument); if (provider.onDidInsertSuggestion) { provider.onDidInsertSuggestion(insertedSuggestionArgument); } } -function trackOnDidInsertSuggestion( - eventName: string, - shouldLogInsertedSuggestion: boolean, - insertedSuggestionArgument: AtomSuggestionInsertedRequest, -) { - const duration = durationBySuggestion.get( - insertedSuggestionArgument.suggestion, - ); +function trackOnDidInsertSuggestion(eventName, shouldLogInsertedSuggestion, insertedSuggestionArgument) { + const duration = durationBySuggestion.get(insertedSuggestionArgument.suggestion); if (!shouldLogInsertedSuggestion) { - track(eventName, { - duration, + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)(eventName, { + duration }); return; } - const {suggestion} = insertedSuggestionArgument; - const suggestionText = - suggestion.text != null ? suggestion.text : suggestion.snippet; - track(eventName, { + const { suggestion } = insertedSuggestionArgument; + const suggestionText = suggestion.text != null ? suggestion.text : suggestion.snippet; + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)(eventName, { duration, replacementPrefix: suggestion.replacementPrefix, - suggestionText, + suggestionText }); } -function getAnalytics( - provider: AutocompleteProvider, -): AutocompleteAnalyticEventNames { - const eventNameFor = eventType => - `${provider.analytics.eventName}:autocomplete:${eventType}`; +function getAnalytics(provider) { + const eventNameFor = eventType => `${provider.analytics.eventName}:autocomplete:${eventType}`; return { errorOnGetSuggestions: eventNameFor('error-on-get-suggestions'), onDidInsertSuggestion: eventNameFor('on-did-insert-suggestion'), onGetSuggestions: eventNameFor('on-get-suggestions'), timeoutOnGetSuggestions: eventNameFor('timeout-on-get-suggestions'), - errorOnGetSuggestionDetailsOnSelect: eventNameFor( - 'error-on-get-suggestion-details-on-select', - ), - onGetSuggestionDetailsOnSelect: eventNameFor( - 'on-get-suggestion-details-on-select', - ), + errorOnGetSuggestionDetailsOnSelect: eventNameFor('error-on-get-suggestion-details-on-select'), + onGetSuggestionDetailsOnSelect: eventNameFor('on-get-suggestion-details-on-select') }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-autocomplete/lib/main.js b/pkg/nuclide-autocomplete/lib/main.js index ed817cc328..21b1d0a536 100644 --- a/pkg/nuclide-autocomplete/lib/main.js +++ b/pkg/nuclide-autocomplete/lib/main.js @@ -1,31 +1,35 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {AutocompleteProvider} from './types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.consumeProvider = consumeProvider; -import createAutocompleteProvider from './createAutocompleteProvider'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; +var _createAutocompleteProvider; -export function consumeProvider( - _provider: - | AutocompleteProvider - | Array>, -): IDisposable { - const providers = Array.isArray(_provider) ? _provider : [_provider]; - const disposables = providers.map(provider => - atom.packages.serviceHub.provide( - 'autocomplete.provider', - '2.0.0', - createAutocompleteProvider(provider), - ), - ); - return new UniversalDisposable(...disposables); +function _load_createAutocompleteProvider() { + return _createAutocompleteProvider = _interopRequireDefault(require('./createAutocompleteProvider')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function consumeProvider(_provider) { + const providers = Array.isArray(_provider) ? _provider : [_provider]; + const disposables = providers.map(provider => atom.packages.serviceHub.provide('autocomplete.provider', '2.0.0', (0, (_createAutocompleteProvider || _load_createAutocompleteProvider()).default)(provider))); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(...disposables); +} /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-autocomplete/lib/types.js b/pkg/nuclide-autocomplete/lib/types.js index 34af40eada..9a390c31f7 100644 --- a/pkg/nuclide-autocomplete/lib/types.js +++ b/pkg/nuclide-autocomplete/lib/types.js @@ -1,61 +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 strict - * @format - */ - -export type AtomAutocompleteProvider = AutocompleteProvider< - atom$AutocompleteSuggestion, ->; - -export type AutocompleteProvider< - Suggestion: atom$AutocompleteSuggestion, -> = AutocompleteProviderBase & { - analytics: AutocompleteAnalytics, -}; - -type AutocompleteProviderBase = { - +selector: string, - +getSuggestions: ( - request: atom$AutocompleteRequest, - ) => Promise> | ?Array, - +getSuggestionDetailsOnSelect?: ( - suggestion: Suggestion, - ) => Promise, - +disableForSelector?: string, - +inclusionPriority?: number, - +excludeLowerPriority?: boolean, - +suggestionPriority?: number, - +filterSuggestions?: boolean, - +disposable?: () => void, - +onDidInsertSuggestion?: ( - insertedSuggestion: AtomSuggestionInsertedRequest, - ) => void, -}; - -export type AtomSuggestionInsertedRequest< - Suggestion: atom$AutocompleteSuggestion, -> = { - +editor: atom$TextEditor, - +triggerPosition: atom$Point, - +suggestion: Suggestion, -}; - -export type AutocompleteAnalytics = {| - +eventName: string, - +shouldLogInsertedSuggestion: boolean, -|}; - -export type AutocompleteAnalyticEventNames = {| - +errorOnGetSuggestions: string, - +onDidInsertSuggestion: string, - +onGetSuggestions: string, - +errorOnGetSuggestionDetailsOnSelect: string, - +onGetSuggestionDetailsOnSelect: string, - +timeoutOnGetSuggestions: string, -|}; +"use strict"; \ No newline at end of file diff --git a/pkg/nuclide-blame-provider-hg/lib/HgBlameProvider.js b/pkg/nuclide-blame-provider-hg/lib/HgBlameProvider.js index 554393cfaf..c4a2c99adf 100644 --- a/pkg/nuclide-blame-provider-hg/lib/HgBlameProvider.js +++ b/pkg/nuclide-blame-provider-hg/lib/HgBlameProvider.js @@ -1,3 +1,27 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _common; + +function _load_common() { + return _common = require('./common'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,38 +29,28 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {BlameForEditor} from '../../nuclide-blame/lib/types'; - -import {hgRepositoryForEditor} from './common'; -import {trackTiming} from '../../nuclide-analytics'; -import {getLogger} from 'log4js'; - -const logger = getLogger('nuclide-blame-provider-hg'); +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-blame-provider-hg'); -function canProvideBlameForEditor(editor: atom$TextEditor): boolean { - return Boolean(hgRepositoryForEditor(editor)); +function canProvideBlameForEditor(editor) { + return Boolean((0, (_common || _load_common()).hgRepositoryForEditor)(editor)); } -function getBlameForEditor(editor: atom$TextEditor): Promise { - return trackTiming('blame-provider-hg:getBlameForEditor', () => - doGetBlameForEditor(editor), - ); +function getBlameForEditor(editor) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)('blame-provider-hg:getBlameForEditor', () => doGetBlameForEditor(editor)); } -async function doGetBlameForEditor( - editor: atom$TextEditor, -): Promise { +async function doGetBlameForEditor(editor) { const path = editor.getPath(); // flowlint-next-line sketchy-null-string:off if (!path) { return Promise.resolve([]); } - const repo = hgRepositoryForEditor(editor); + const repo = (0, (_common || _load_common()).hgRepositoryForEditor)(editor); if (!repo) { const message = `HgBlameProvider could not fetch blame for ${path}: no Hg repo found.`; logger.error(message); @@ -49,14 +63,14 @@ async function doGetBlameForEditor( let getUrlForRevision; try { // $FlowFB - const {getPhabricatorUrlForRevision} = require('./fb/FbHgBlameProvider'); + const { getPhabricatorUrlForRevision } = require('./fb/FbHgBlameProvider'); getUrlForRevision = getPhabricatorUrlForRevision; } catch (e) { // Ignore case where FbHgBlameProvider is unavailable. } -export default { +exports.default = { canProvideBlameForEditor, getBlameForEditor, - getUrlForRevision, -}; + getUrlForRevision +}; \ No newline at end of file diff --git a/pkg/nuclide-blame-provider-hg/lib/common.js b/pkg/nuclide-blame-provider-hg/lib/common.js index 947da7a094..aa4c01f418 100644 --- a/pkg/nuclide-blame-provider-hg/lib/common.js +++ b/pkg/nuclide-blame-provider-hg/lib/common.js @@ -1,3 +1,16 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.hgRepositoryForEditor = hgRepositoryForEditor; + +var _nuclideVcsBase; + +function _load_nuclideVcsBase() { + return _nuclideVcsBase = require('../../nuclide-vcs-base'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,18 +18,14 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {HgRepositoryClient} from '../../nuclide-hg-repository-client'; - -import {repositoryForPath} from '../../nuclide-vcs-base'; - -export function hgRepositoryForEditor(editor: TextEditor): ?HgRepositoryClient { - const repo = repositoryForPath(editor.getPath() || ''); +function hgRepositoryForEditor(editor) { + const repo = (0, (_nuclideVcsBase || _load_nuclideVcsBase()).repositoryForPath)(editor.getPath() || ''); if (!repo || repo.getType() !== 'hg') { return null; } - return ((repo: any): HgRepositoryClient); -} + return repo; +} \ No newline at end of file diff --git a/pkg/nuclide-blame-provider-hg/lib/main.js b/pkg/nuclide-blame-provider-hg/lib/main.js index e69f8d6df5..62adbdc35a 100644 --- a/pkg/nuclide-blame-provider-hg/lib/main.js +++ b/pkg/nuclide-blame-provider-hg/lib/main.js @@ -1,3 +1,18 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.provideHgBlameProvider = provideHgBlameProvider; + +var _HgBlameProvider; + +function _load_HgBlameProvider() { + return _HgBlameProvider = _interopRequireDefault(require('./HgBlameProvider')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,14 +20,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {BlameProvider} from '../../nuclide-blame/lib/types'; - -import HgBlameProvider from './HgBlameProvider'; - -export function provideHgBlameProvider(): BlameProvider { - return HgBlameProvider; -} +function provideHgBlameProvider() { + return (_HgBlameProvider || _load_HgBlameProvider()).default; +} \ No newline at end of file diff --git a/pkg/nuclide-blame/lib/BlameGutter.js b/pkg/nuclide-blame/lib/BlameGutter.js index cb41f8da13..b9edc5448e 100644 --- a/pkg/nuclide-blame/lib/BlameGutter.js +++ b/pkg/nuclide-blame/lib/BlameGutter.js @@ -1,3 +1,62 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _addTooltip; + +function _load_addTooltip() { + return _addTooltip = _interopRequireDefault(require('../../../modules/nuclide-commons-ui/addTooltip')); +} + +var _hideAllTooltips; + +function _load_hideAllTooltips() { + return _hideAllTooltips = _interopRequireDefault(require('../../nuclide-ui/hide-all-tooltips')); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _electron = require('electron'); + +var _escapeHtml; + +function _load_escapeHtml() { + return _escapeHtml = _interopRequireDefault(require('escape-html')); +} + +var _nuclideVcsLog; + +function _load_nuclideVcsLog() { + return _nuclideVcsLog = require('../../nuclide-vcs-log'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _reactDom = _interopRequireDefault(require('react-dom')); + +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 }; } + +// eslint-disable-next-line nuclide-internal/no-cross-atom-imports /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,25 +64,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {RevisionInfo} from '../../nuclide-hg-rpc/lib/HgService'; -import type {BlameForEditor, BlameProvider} from './types'; - -import addTooltip from 'nuclide-commons-ui/addTooltip'; -import hideAllTooltips from '../../nuclide-ui/hide-all-tooltips'; -import {track, trackTiming} from '../../nuclide-analytics'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {shell} from 'electron'; -import escapeHTML from 'escape-html'; -// eslint-disable-next-line nuclide-internal/no-cross-atom-imports -import {shortNameForAuthor} from '../../nuclide-vcs-log'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import classnames from 'classnames'; - const BLAME_DECORATION_CLASS = 'blame-decoration'; let Avatar; @@ -34,22 +78,14 @@ try { Avatar = null; } -function getHash(revision: ?RevisionInfo): ?string { +function getHash(revision) { if (revision == null) { return null; } return revision.hash; } -export default class BlameGutter { - _editor: atom$TextEditor; - _blameProvider: BlameProvider; - _bufferLineToDecoration: Map; - _gutter: atom$Gutter; - _loadingSpinnerDiv: ?HTMLElement; - _isDestroyed: boolean; - _isEditorDestroyed: boolean; - _subscriptions: UniversalDisposable; +class BlameGutter { /** * @param gutterName A name for this gutter. Must not be used by any another @@ -58,60 +94,49 @@ export default class BlameGutter { * @param blameProvider The BlameProvider that provides the appropriate blame * information for this BlameGutter. */ - constructor( - gutterName: string, - editor: atom$TextEditor, - blameProvider: BlameProvider, - ) { + constructor(gutterName, editor, blameProvider) { this._isDestroyed = false; this._isEditorDestroyed = false; - this._subscriptions = new UniversalDisposable(); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._editor = editor; this._blameProvider = blameProvider; this._bufferLineToDecoration = new Map(); // Priority is -200 by default and 0 is the line number - this._gutter = editor.addGutter({name: gutterName, priority: -1200}); + this._gutter = editor.addGutter({ name: gutterName, priority: -1200 }); - this._subscriptions.add( - editor.onDidDestroy(() => { - this._isEditorDestroyed = true; - }), - ); + this._subscriptions.add(editor.onDidDestroy(() => { + this._isEditorDestroyed = true; + })); const editorView = atom.views.getView(editor); - this._subscriptions.add( - editorView.onDidChangeScrollTop(() => { - hideAllTooltips(); - }), - ); + this._subscriptions.add(editorView.onDidChangeScrollTop(() => { + (0, (_hideAllTooltips || _load_hideAllTooltips()).default)(); + })); this._fetchAndDisplayBlame(); } - async _onClick(revision: RevisionInfo): Promise { + async _onClick(revision) { const blameProvider = this._blameProvider; if (typeof blameProvider.getUrlForRevision !== 'function') { return; } - const url = await blameProvider.getUrlForRevision( - this._editor, - revision.hash, - ); + const url = await blameProvider.getUrlForRevision(this._editor, revision.hash); // flowlint-next-line sketchy-null-string:off if (url) { // Note that 'shell' is not the public 'shell' package on npm but an Atom built-in. - shell.openExternal(url); + _electron.shell.openExternal(url); } else { atom.notifications.addWarning(`No URL found for ${revision.hash}.`); } - track('blame-gutter-click-revision', { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('blame-gutter-click-revision', { editorPath: this._editor.getPath() || '', - url: url || '', + url: url || '' }); } - async _fetchAndDisplayBlame(): Promise { + async _fetchAndDisplayBlame() { // Add a loading spinner while we fetch the blame. this._addLoadingSpinner(); @@ -119,15 +144,8 @@ export default class BlameGutter { try { newBlame = await this._blameProvider.getBlameForEditor(this._editor); } catch (error) { - atom.notifications.addError( - 'Failed to fetch blame to display. ' + - 'The file is empty or untracked or the repository cannot be reached.', - {detail: error}, - ); - atom.commands.dispatch( - atom.views.getView(this._editor), - 'nuclide-blame:hide-blame', - ); + atom.notifications.addError('Failed to fetch blame to display. ' + 'The file is empty or untracked or the repository cannot be reached.', { detail: error }); + atom.commands.dispatch(atom.views.getView(this._editor), 'nuclide-blame:hide-blame'); return; } // The BlameGutter could have been destroyed while blame was being fetched. @@ -141,7 +159,7 @@ export default class BlameGutter { this._updateBlame(newBlame); } - _addLoadingSpinner(): void { + _addLoadingSpinner() { if (this._loadingSpinnerDiv) { return; } @@ -152,7 +170,7 @@ export default class BlameGutter { gutterView.classList.add('nuclide-blame-loading'); } - _cleanUpLoadingSpinner(): void { + _cleanUpLoadingSpinner() { if (this._loadingSpinnerDiv) { this._loadingSpinnerDiv.remove(); this._loadingSpinnerDiv = null; @@ -161,7 +179,7 @@ export default class BlameGutter { } } - destroy(): void { + destroy() { this._isDestroyed = true; this._cleanUpLoadingSpinner(); if (!this._isEditorDestroyed) { @@ -175,19 +193,15 @@ export default class BlameGutter { } } - _updateBlame(blameForEditor: BlameForEditor): void { - return trackTiming('blame-ui.blame-gutter.updateBlame', () => - this.__updateBlame(blameForEditor), - ); + _updateBlame(blameForEditor) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)('blame-ui.blame-gutter.updateBlame', () => this.__updateBlame(blameForEditor)); } // The BlameForEditor completely replaces any previous blame information. - __updateBlame(blameForEditor: BlameForEditor): void { + __updateBlame(blameForEditor) { if (blameForEditor.length === 0) { - atom.notifications.addInfo( - `Found no blame to display. Is this file empty or untracked? - If not, check for errors in the Nuclide logs local to your repo.`, - ); + atom.notifications.addInfo(`Found no blame to display. Is this file empty or untracked? + If not, check for errors in the Nuclide logs local to your repo.`); } const allPreviousBlamedLines = new Set(this._bufferLineToDecoration.keys()); @@ -214,14 +228,7 @@ export default class BlameGutter { const blameInfo = blameForEditor[bufferLine]; if (blameInfo) { - this._setBlameLine( - bufferLine, - blameInfo, - isFirstLine, - isLastLine, - oldest, - newest, - ); + this._setBlameLine(bufferLine, blameInfo, isFirstLine, isLastLine, oldest, newest); } allPreviousBlamedLines.delete(bufferLine); } @@ -232,139 +239,102 @@ export default class BlameGutter { } } - _setBlameLine( - bufferLine: number, - revision: RevisionInfo, - isFirstLine: boolean, - isLastLine: boolean, - oldest: number, - newest: number, - ): void { - const item = this._createGutterItem( - revision, - isFirstLine, - isLastLine, - oldest, - newest, - ); + _setBlameLine(bufferLine, revision, isFirstLine, isLastLine, oldest, newest) { + const item = this._createGutterItem(revision, isFirstLine, isLastLine, oldest, newest); const decorationProperties = { type: 'gutter', gutterName: this._gutter.name, class: BLAME_DECORATION_CLASS, - item, + item }; let decoration = this._bufferLineToDecoration.get(bufferLine); if (!decoration) { - const marker = this._editor.markBufferRange( - [[bufferLine, 0], [bufferLine, 100000]], - {invalidate: 'touch'}, - ); + const marker = this._editor.markBufferRange([[bufferLine, 0], [bufferLine, 100000]], { invalidate: 'touch' }); decoration = this._editor.decorateMarker(marker, decorationProperties); this._bufferLineToDecoration.set(bufferLine, decoration); } else { - ReactDOM.unmountComponentAtNode(decoration.getProperties().item); + _reactDom.default.unmountComponentAtNode(decoration.getProperties().item); decoration.setProperties(decorationProperties); } } - _removeBlameLine(bufferLine: number): void { + _removeBlameLine(bufferLine) { const blameDecoration = this._bufferLineToDecoration.get(bufferLine); if (!blameDecoration) { return; } - ReactDOM.unmountComponentAtNode(blameDecoration.getProperties().item); + _reactDom.default.unmountComponentAtNode(blameDecoration.getProperties().item); // The recommended way of destroying a decoration is by destroying its marker. blameDecoration.getMarker().destroy(); this._bufferLineToDecoration.delete(bufferLine); } - _createGutterItem( - blameInfo: RevisionInfo, - isFirstLine: boolean, - isLastLine: boolean, - oldest: number, - newest: number, - ): HTMLElement { + _createGutterItem(blameInfo, isFirstLine, isLastLine, oldest, newest) { const item = document.createElement('div'); item.addEventListener('click', () => { this._onClick(blameInfo); }); - ReactDOM.render( - , - item, - ); + _reactDom.default.render(_react.createElement(GutterElement, { + revision: blameInfo, + isFirstLine: isFirstLine, + isLastLine: isLastLine, + oldest: oldest, + newest: newest + }), item); return item; } } -type Props = { - revision: RevisionInfo, - isFirstLine: boolean, - isLastLine: boolean, - oldest: number, - newest: number, -}; - -class GutterElement extends React.Component { - render(): React.Node { - const {oldest, newest, revision, isLastLine, isFirstLine} = this.props; +exports.default = BlameGutter; + + +class GutterElement extends _react.Component { + render() { + const { oldest, newest, revision, isLastLine, isFirstLine } = this.props; const date = Number(revision.date); const alpha = 1 - (date - newest) / (oldest - newest); const opacity = 0.2 + 0.8 * alpha; if (isFirstLine) { - const unixname = shortNameForAuthor(revision.author); + const unixname = (0, (_nuclideVcsLog || _load_nuclideVcsLog()).shortNameForAuthor)(revision.author); const tooltip = { - title: - escapeHTML(revision.title) + - '
      ' + - escapeHTML(unixname) + - ' · ' + - escapeHTML(revision.date.toDateString()), + title: (0, (_escapeHtml || _load_escapeHtml()).default)(revision.title) + '
      ' + (0, (_escapeHtml || _load_escapeHtml()).default)(unixname) + ' · ' + (0, (_escapeHtml || _load_escapeHtml()).default)(revision.date.toDateString()), delay: 0, - placement: 'right', + placement: 'right' }; - return ( -
      - {!isLastLine ? ( -
      - ) : null} - {Avatar ? ( - - ) : ( - unixname + ': ' - )} - {revision.title} -
      -
      + , ref: (0, (_addTooltip || _load_addTooltip()).default)(tooltip) }, + !isLastLine ? _react.createElement('div', { className: 'nuclide-blame-vertical-bar nuclide-blame-vertical-bar-first' }) : null, + Avatar ? _react.createElement(Avatar, { size: 16, employeeIdentifier: unixname }) : unixname + ': ', + _react.createElement( + 'span', + null, + revision.title + ), + _react.createElement('div', { style: { opacity }, className: 'nuclide-blame-border-age' }) ); } - return ( -
      -
      -
      -
      + return _react.createElement( + 'div', + { className: 'nuclide-blame-row' }, + _react.createElement('div', { + className: (0, (_classnames || _load_classnames()).default)('nuclide-blame-vertical-bar', { + 'nuclide-blame-vertical-bar-last': isLastLine, + 'nuclide-blame-vertical-bar-middle': !isLastLine + }) + }), + _react.createElement('div', { style: { opacity }, className: 'nuclide-blame-border-age' }) ); } -} +} \ No newline at end of file diff --git a/pkg/nuclide-blame/lib/BlameToggle.js b/pkg/nuclide-blame/lib/BlameToggle.js index cb45864830..82f30955f0 100644 --- a/pkg/nuclide-blame/lib/BlameToggle.js +++ b/pkg/nuclide-blame/lib/BlameToggle.js @@ -1,3 +1,37 @@ +'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('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _passesGK; + +function _load_passesGK() { + return _passesGK = _interopRequireDefault(require('../../commons-node/passesGK')); +} + +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 GATEKEEPER_NAME = 'nuclide_blame_toggle_button'; + +/** + * Shows a 'toggle blame' button to the bottom right of an editor, if the + * contents of the editor support it. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,130 +39,99 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Observable} from 'rxjs'; -import passesGK from '../../commons-node/passesGK'; - -const GATEKEEPER_NAME = 'nuclide_blame_toggle_button'; - -/** - * Shows a 'toggle blame' button to the bottom right of an editor, if the - * contents of the editor support it. - */ -export default class BlameToggle { - _container: HTMLDivElement; +class BlameToggle { /** * @param editor The atom TextEditor object. * @param canBlame A function returning a boolean value indicating whether * the editor can show blame for its contents. */ - constructor(editor: atom$TextEditor, canBlame: atom$TextEditor => boolean) { + constructor(editor, canBlame) { this._container = document.createElement('div'); editor.getElement().appendChild(this._container); - ReactDOM.render( - , - this._container, - ); + _reactDom.default.render(_react.createElement(BlameToggleContainer, { editor: editor, canBlame: canBlame }), this._container); } /** * Cleans up and removes the toggle button. */ - destroy(): void { - ReactDOM.unmountComponentAtNode(this._container); + destroy() { + _reactDom.default.unmountComponentAtNode(this._container); } } -type ContainerState = { - visible: boolean, -}; +exports.default = BlameToggle; -type ContainerProps = { - editor: atom$TextEditor, - canBlame: atom$TextEditor => boolean, -}; /** * Wraps event-handling, subscription and visibility logic for a blame toggle * button. */ -class BlameToggleContainer extends React.Component< - ContainerProps, - ContainerState, -> { - _subscriptions: UniversalDisposable; +class BlameToggleContainer extends _react.Component { constructor(props) { super(props); - this.state = {visible: false}; - this._subscriptions = new UniversalDisposable(); + + this._setVisible = () => { + this._subscriptions.add(_rxjsBundlesRxMinJs.Observable.fromPromise((0, (_passesGK || _load_passesGK()).default)(GATEKEEPER_NAME)).subscribe(passed => { + // The blame toggle button is visible if: + // - the use is in the Gatekeeper + // - the editor is not modiified + // - the editor is blamable (there is a blame provider for it) + this.setState({ + visible: passed && !this.props.editor.isModified() && this.props.canBlame(this.props.editor) + }); + })); + }; + + this.state = { visible: false }; + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } componentDidMount() { this._setVisible(); this._subscriptions.add( - // update visibility on editor changed (may now be modified, non-blamable) - this.props.editor.onDidStopChanging(this._setVisible), - // update visibility on editor saved (may no longer be modiified) - this.props.editor.onDidSave(this._setVisible), - // update visibility on initial package load, this might have been - // created before a BlameProvider was available. - atom.packages.onDidActivateInitialPackages(this._setVisible), - ); + // update visibility on editor changed (may now be modified, non-blamable) + this.props.editor.onDidStopChanging(this._setVisible), + // update visibility on editor saved (may no longer be modiified) + this.props.editor.onDidSave(this._setVisible), + // update visibility on initial package load, this might have been + // created before a BlameProvider was available. + atom.packages.onDidActivateInitialPackages(this._setVisible)); } componentWillUnmount() { this._subscriptions.dispose(); } - render(): React.Node { - return
      {this.state.visible && }
      ; + render() { + return _react.createElement( + 'div', + null, + this.state.visible && _react.createElement(BlameToggleComponent, null) + ); } - _setVisible = () => { - this._subscriptions.add( - Observable.fromPromise(passesGK(GATEKEEPER_NAME)).subscribe(passed => { - // The blame toggle button is visible if: - // - the use is in the Gatekeeper - // - the editor is not modiified - // - the editor is blamable (there is a blame provider for it) - this.setState({ - visible: - passed && - !this.props.editor.isModified() && - this.props.canBlame(this.props.editor), - }); - }), - ); - }; } -type ComponentProps = {}; - /** * Renders a 'toggle blame' button in an editor. */ -class BlameToggleComponent extends React.Component { - _onClick(): void { - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'nuclide-blame:toggle-blame', - ); +class BlameToggleComponent extends _react.Component { + _onClick() { + atom.commands.dispatch(atom.views.getView(atom.workspace), 'nuclide-blame:toggle-blame'); } - render(): React.Node { - return ( -
      - toggle blame -
      + render() { + return _react.createElement( + 'div', + { className: 'nuclide-blame-button', onClick: this._onClick }, + 'toggle blame' ); } -} +} \ No newline at end of file diff --git a/pkg/nuclide-blame/lib/main.js b/pkg/nuclide-blame/lib/main.js index bc69812b48..8ffdb3e4c4 100644 --- a/pkg/nuclide-blame/lib/main.js +++ b/pkg/nuclide-blame/lib/main.js @@ -1,3 +1,63 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.activate = activate; +exports.deactivate = deactivate; +exports.consumeBlameProvider = consumeBlameProvider; +exports.addItemsToFileTreeContextMenu = addItemsToFileTreeContextMenu; + +var _BlameGutter; + +function _load_BlameGutter() { + return _BlameGutter = _interopRequireDefault(require('./BlameGutter')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _goToLocation; + +function _load_goToLocation() { + return _goToLocation = require('../../../modules/nuclide-commons-atom/go-to-location'); +} + +var _nuclideVcsBase; + +function _load_nuclideVcsBase() { + return _nuclideVcsBase = require('../../nuclide-vcs-base'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _textEditor; + +function _load_textEditor() { + return _textEditor = require('../../../modules/nuclide-commons-atom/text-editor'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _BlameToggle; + +function _load_BlameToggle() { + return _BlameToggle = _interopRequireDefault(require('./BlameToggle')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,98 +65,61 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {BlameProvider} from './types'; -import type FileTreeContextMenu from '../../nuclide-file-tree/lib/FileTreeContextMenu'; -import type {FileTreeNode} from '../../nuclide-file-tree/lib/FileTreeNode'; - -import invariant from 'assert'; -import BlameGutter from './BlameGutter'; -import {getLogger} from 'log4js'; -import {goToLocation} from 'nuclide-commons-atom/go-to-location'; -import {repositoryForPath} from '../../nuclide-vcs-base'; -import {track, trackTiming} from '../../nuclide-analytics'; -import {isValidTextEditor} from 'nuclide-commons-atom/text-editor'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import BlameToggle from './BlameToggle'; - -const PACKAGES_MISSING_MESSAGE = - 'Could not open blame. Missing at least one blame provider.'; +const PACKAGES_MISSING_MESSAGE = 'Could not open blame. Missing at least one blame provider.'; const TOGGLE_BLAME_FILE_TREE_CONTEXT_MENU_PRIORITY = 2000; class Activation { - _packageDisposables: UniversalDisposable; - _registeredProviders: Set; - // Map of a TextEditor to its BlameToggle, if it exists. - _textEditorToBlameToggle: Map; // Map of a TextEditor to its BlameGutter, if it exists. - _textEditorToBlameGutter: Map; - // Map of a TextEditor to the subscription on its ::onDidDestroy. - _textEditorToDestroySubscription: Map; - constructor() { this._registeredProviders = new Set(); this._textEditorToBlameGutter = new Map(); this._textEditorToBlameToggle = new Map(); this._textEditorToDestroySubscription = new Map(); - this._packageDisposables = new UniversalDisposable(); - this._packageDisposables.add( - atom.contextMenu.add({ - 'atom-text-editor': [ - { - label: 'Source Control', - submenu: [ - { - label: 'Toggle Blame', - command: 'nuclide-blame:toggle-blame', - shouldDisplay: (event: MouseEvent) => - this._canShowBlame(true /* fromContextMenu */) || - this._canHideBlame(true /* fromContextMenu */), - }, - ], - }, - ], - }), - ); - this._packageDisposables.add( - atom.commands.add('atom-workspace', 'nuclide-blame:toggle-blame', () => { - if (this._canShowBlame()) { - this._showBlame(); - } else if (this._canHideBlame()) { - this._hideBlame(); - } - }), - // eslint-disable-next-line - atom.commands.add('atom-workspace', 'nuclide-blame:hide-blame', () => { - if (this._canHideBlame()) { - this._hideBlame(); - } - }), - ); - - this._packageDisposables.add( - atom.workspace.observeTextEditors(editor => { - const button = new BlameToggle( - editor, - this._hasProviderForEditor.bind(this), - ); - const disposeButton = () => button.destroy(); - this._packageDisposables.add(disposeButton); - - this._textEditorToBlameToggle.set(editor, button); - this._textEditorToDestroySubscription.set( - editor, - editor.onDidDestroy(() => { - this._packageDisposables.remove(disposeButton); - this._editorWasDestroyed(editor); - }), - ); - }), - ); + this._packageDisposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._packageDisposables.add(atom.contextMenu.add({ + 'atom-text-editor': [{ + label: 'Source Control', + submenu: [{ + label: 'Toggle Blame', + command: 'nuclide-blame:toggle-blame', + shouldDisplay: event => this._canShowBlame(true /* fromContextMenu */) || this._canHideBlame(true /* fromContextMenu */) + }] + }] + })); + this._packageDisposables.add(atom.commands.add('atom-workspace', 'nuclide-blame:toggle-blame', () => { + if (this._canShowBlame()) { + this._showBlame(); + } else if (this._canHideBlame()) { + this._hideBlame(); + } + }), + // eslint-disable-next-line + atom.commands.add('atom-workspace', 'nuclide-blame:hide-blame', () => { + if (this._canHideBlame()) { + this._hideBlame(); + } + })); + + this._packageDisposables.add(atom.workspace.observeTextEditors(editor => { + const button = new (_BlameToggle || _load_BlameToggle()).default(editor, this._hasProviderForEditor.bind(this)); + const disposeButton = () => button.destroy(); + this._packageDisposables.add(disposeButton); + + this._textEditorToBlameToggle.set(editor, button); + this._textEditorToDestroySubscription.set(editor, editor.onDidDestroy(() => { + this._packageDisposables.remove(disposeButton); + this._editorWasDestroyed(editor); + })); + })); } + // Map of a TextEditor to the subscription on its ::onDidDestroy. + + // Map of a TextEditor to its BlameToggle, if it exists. + dispose() { this._packageDisposables.dispose(); @@ -113,7 +136,7 @@ class Activation { * Section: Managing Gutters */ - _removeBlameGutterForEditor(editor: atom$TextEditor): void { + _removeBlameGutterForEditor(editor) { const blameGutter = this._textEditorToBlameGutter.get(editor); if (blameGutter != null) { blameGutter.destroy(); @@ -121,7 +144,7 @@ class Activation { } } - _showBlameGutterForEditor(editor: atom$TextEditor): void { + _showBlameGutterForEditor(editor) { if (this._registeredProviders.size === 0) { atom.notifications.addInfo(PACKAGES_MISSING_MESSAGE); return; @@ -132,35 +155,23 @@ class Activation { const providerForEditor = this._getProviderForEditor(editor); if (editor.isModified()) { - atom.notifications.addInfo( - 'There is blame information for this file, but only for saved changes. ' + - 'Save, then try again.', - ); + atom.notifications.addInfo('There is blame information for this file, but only for saved changes. ' + 'Save, then try again.'); } else if (providerForEditor) { - blameGutter = new BlameGutter( - 'nuclide-blame', - editor, - providerForEditor, - ); + blameGutter = new (_BlameGutter || _load_BlameGutter()).default('nuclide-blame', editor, providerForEditor); this._textEditorToBlameGutter.set(editor, blameGutter); - track('blame-open', { - editorPath: editor.getPath() || '', + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('blame-open', { + editorPath: editor.getPath() || '' }); } else { - atom.notifications.addInfo( - 'Could not open blame: no blame information currently available for this file.', - ); - - getLogger('nuclide-blame').info( - 'nuclide-blame: Could not open blame: no blame provider currently available for this ' + - `file: ${String(editor.getPath())}`, - ); + atom.notifications.addInfo('Could not open blame: no blame information currently available for this file.'); + + (0, (_log4js || _load_log4js()).getLogger)('nuclide-blame').info('nuclide-blame: Could not open blame: no blame provider currently available for this ' + `file: ${String(editor.getPath())}`); } } } - _editorWasDestroyed(editor: atom$TextEditor): void { + _editorWasDestroyed(editor) { const blameGutter = this._textEditorToBlameGutter.get(editor); if (blameGutter) { blameGutter.destroy(); @@ -184,8 +195,8 @@ class Activation { * Section: Managing Context Menus */ - _showBlame(event): void { - return trackTiming('blame.showBlame', () => { + _showBlame(event) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)('blame.showBlame', () => { const editor = getMostRelevantEditor(); if (editor != null) { this._showBlameGutterForEditor(editor); @@ -193,8 +204,8 @@ class Activation { }); } - _hideBlame(event): void { - return trackTiming('blame.hideBlame', () => { + _hideBlame(event) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)('blame.hideBlame', () => { const editor = getMostRelevantEditor(); if (editor != null) { this._removeBlameGutterForEditor(editor); @@ -202,12 +213,12 @@ class Activation { }); } - _canShowBlame(fromContextMenu: boolean = false): boolean { + _canShowBlame(fromContextMenu = false) { const editor = getMostRelevantEditor(fromContextMenu); return editor != null && !this._textEditorToBlameGutter.has(editor); } - _canHideBlame(fromContextMenu: boolean = false): boolean { + _canHideBlame(fromContextMenu = false) { const editor = getMostRelevantEditor(fromContextMenu); return editor != null && this._textEditorToBlameGutter.has(editor); } @@ -216,7 +227,7 @@ class Activation { * Section: Consuming Services */ - _getProviderForEditor(editor: atom$TextEditor): ?BlameProvider { + _getProviderForEditor(editor) { for (const blameProvider of this._registeredProviders) { if (blameProvider.canProvideBlameForEditor(editor)) { return blameProvider; @@ -226,61 +237,51 @@ class Activation { return null; } - _hasProviderForEditor(editor: atom$TextEditor): boolean { + _hasProviderForEditor(editor) { return Boolean(this._getProviderForEditor(editor) != null); } - consumeBlameProvider(provider: BlameProvider): IDisposable { + consumeBlameProvider(provider) { this._registeredProviders.add(provider); - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { if (this._registeredProviders) { this._registeredProviders.delete(provider); } }); } - addItemsToFileTreeContextMenu(contextMenu: FileTreeContextMenu): IDisposable { - const contextDisposable = contextMenu.addItemToSourceControlMenu( - { - label: 'Toggle Blame', - callback() { - findBlameableNodes(contextMenu).forEach(async node => { - const editor = await goToLocation(node.uri); - atom.commands.dispatch( - atom.views.getView(editor), - 'nuclide-blame:toggle-blame', - ); - }); - }, - shouldDisplay() { - return findBlameableNodes(contextMenu).length > 0; - }, + addItemsToFileTreeContextMenu(contextMenu) { + const contextDisposable = contextMenu.addItemToSourceControlMenu({ + label: 'Toggle Blame', + callback() { + findBlameableNodes(contextMenu).forEach(async node => { + const editor = await (0, (_goToLocation || _load_goToLocation()).goToLocation)(node.uri); + atom.commands.dispatch(atom.views.getView(editor), 'nuclide-blame:toggle-blame'); + }); }, - TOGGLE_BLAME_FILE_TREE_CONTEXT_MENU_PRIORITY, - ); + shouldDisplay() { + return findBlameableNodes(contextMenu).length > 0; + } + }, TOGGLE_BLAME_FILE_TREE_CONTEXT_MENU_PRIORITY); this._packageDisposables.add(contextDisposable); // We don't need to dispose of the contextDisposable when the provider is disabled - // it needs to be handled by the provider itself. We only should remove it from the list // of the disposables we maintain. - return new UniversalDisposable(() => - this._packageDisposables.remove(contextDisposable), - ); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => this._packageDisposables.remove(contextDisposable)); } } /** * @return list of nodes against which "Toggle Blame" is an appropriate action. */ -function findBlameableNodes( - contextMenu: FileTreeContextMenu, -): Array { +function findBlameableNodes(contextMenu) { const nodes = []; for (const node of contextMenu.getSelectedNodes()) { if (node == null || !node.uri) { continue; } - const repo = repositoryForPath(node.uri); + const repo = (0, (_nuclideVcsBase || _load_nuclideVcsBase()).repositoryForPath)(node.uri); if (!node.isContainer && repo != null && repo.getType() === 'hg') { nodes.push(node); } @@ -288,43 +289,42 @@ function findBlameableNodes( return nodes; } -let activation: ?Activation; +let activation; -export function activate(state: ?Object): void { +function activate(state) { if (!activation) { activation = new Activation(); } } -export function deactivate() { +function deactivate() { if (activation) { activation.dispose(); activation = null; } } -export function consumeBlameProvider(provider: BlameProvider): IDisposable { - invariant(activation); +function consumeBlameProvider(provider) { + if (!activation) { + throw new Error('Invariant violation: "activation"'); + } + return activation.consumeBlameProvider(provider); } -export function addItemsToFileTreeContextMenu( - contextMenu: FileTreeContextMenu, -): IDisposable { - invariant(activation); +function addItemsToFileTreeContextMenu(contextMenu) { + if (!activation) { + throw new Error('Invariant violation: "activation"'); + } + return activation.addItemsToFileTreeContextMenu(contextMenu); } -function getMostRelevantEditor( - fromContextMenu: boolean = false, -): ?atom$TextEditor { +function getMostRelevantEditor(fromContextMenu = false) { const editor = atom.workspace.getActiveTextEditor(); if (fromContextMenu || editor != null) { return editor; } - const item = atom.workspace - .getCenter() - .getActivePane() - .getActiveItem(); - return isValidTextEditor(item) ? item : null; -} + const item = atom.workspace.getCenter().getActivePane().getActiveItem(); + return (0, (_textEditor || _load_textEditor()).isValidTextEditor)(item) ? item : null; +} \ No newline at end of file diff --git a/pkg/nuclide-blame/lib/types.js b/pkg/nuclide-blame/lib/types.js index b377db169f..a726efc43f 100644 --- a/pkg/nuclide-blame/lib/types.js +++ b/pkg/nuclide-blame/lib/types.js @@ -1,32 +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 strict-local - * @format - */ - -import type {RevisionInfo} from '../../nuclide-hg-rpc/lib/HgService'; - -export type BlameForEditor = Array; - -export type BlameProvider = { - canProvideBlameForEditor: (editor: atom$TextEditor) => boolean, - getBlameForEditor: (editor: atom$TextEditor) => Promise, - - /** - * Tries to find a URL that contains more information about the revision. If no such URL exists, - * returns null. - * - * Note that this method is optional. Prefer to not define the method than to provide a dummy - * implementation that returns `Promise.resolve(null)`. The absence of this method indicates to - * clients that they should not expose UI that depends on this functionality. - */ - getUrlForRevision?: ( - editor: atom$TextEditor, - revision: string, - ) => Promise, -}; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-bookshelf/__mocks__/dummy1.js b/pkg/nuclide-bookshelf/__mocks__/dummy1.js index a75e814c61..71af805276 100644 --- a/pkg/nuclide-bookshelf/__mocks__/dummy1.js +++ b/pkg/nuclide-bookshelf/__mocks__/dummy1.js @@ -1,3 +1,20 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ACTIVE_SHOTHEAD_1 = exports.SHOTHEAD_1_2 = exports.SHOTHEAD_1_1 = exports.REPO_PATH_1 = undefined; +exports.getDummyRepositoryState = getDummyRepositoryState; +exports.getDummyBookShelfState = getDummyBookShelfState; + +var _immutable; + +function _load_immutable() { + return _immutable = _interopRequireWildcard(require('immutable')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,34 +22,25 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {BookShelfRepositoryState, BookShelfState} from '../lib/types'; - -import * as Immutable from 'immutable'; +const REPO_PATH_1 = exports.REPO_PATH_1 = '/fake/path_1'; +const SHOTHEAD_1_1 = exports.SHOTHEAD_1_1 = 'foo'; +const SHOTHEAD_1_2 = exports.SHOTHEAD_1_2 = 'bar'; +const ACTIVE_SHOTHEAD_1 = exports.ACTIVE_SHOTHEAD_1 = 'bar'; -export const REPO_PATH_1 = '/fake/path_1'; -export const SHOTHEAD_1_1 = 'foo'; -export const SHOTHEAD_1_2 = 'bar'; -export const ACTIVE_SHOTHEAD_1 = 'bar'; - -export function getDummyRepositoryState(): BookShelfRepositoryState { +function getDummyRepositoryState() { return { activeShortHead: ACTIVE_SHOTHEAD_1, isRestoring: false, - shortHeadsToFileList: Immutable.Map([ - [SHOTHEAD_1_1, ['c.txt', 'd.txt']], - [SHOTHEAD_1_2, ['e.txt']], - ]), + shortHeadsToFileList: (_immutable || _load_immutable()).Map([[SHOTHEAD_1_1, ['c.txt', 'd.txt']], [SHOTHEAD_1_2, ['e.txt']]]) }; } -export function getDummyBookShelfState(): BookShelfState { +function getDummyBookShelfState() { return Object.freeze({ - repositoryPathToState: Immutable.Map([ - [REPO_PATH_1, getDummyRepositoryState()], - ]), + repositoryPathToState: (_immutable || _load_immutable()).Map([[REPO_PATH_1, getDummyRepositoryState()]]) }); -} +} \ No newline at end of file diff --git a/pkg/nuclide-bookshelf/__tests__/accumulateState-test.js b/pkg/nuclide-bookshelf/__tests__/accumulateState-test.js index a4a9086b9c..5c0ed2007c 100644 --- a/pkg/nuclide-bookshelf/__tests__/accumulateState-test.js +++ b/pkg/nuclide-bookshelf/__tests__/accumulateState-test.js @@ -1,32 +1,41 @@ -/** - * 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 - */ - -import type { - AddProjectRepositoryAction, - BookShelfRepositoryState, - BookShelfState, - RemoveProjectRepositoryAction, - UpdatePaneItemStateAction, - UpdateRepositoryBookmarksAction, -} from '../lib/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import {accumulateState} from '../lib/accumulateState'; -import {ActionType, EMPTY_SHORTHEAD} from '../lib/constants'; -import {getEmptBookShelfState} from '../lib/utils'; -import nullthrows from 'nullthrows'; -import * as Immutable from 'immutable'; +'use strict'; + +var _accumulateState; + +function _load_accumulateState() { + return _accumulateState = require('../lib/accumulateState'); +} + +var _constants; + +function _load_constants() { + return _constants = require('../lib/constants'); +} + +var _utils; + +function _load_utils() { + return _utils = require('../lib/utils'); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _immutable; + +function _load_immutable() { + return _immutable = _interopRequireWildcard(require('immutable')); +} + +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('BookShelf accumulateState', () => { - let fakeRepository: atom$Repository = (null: any); + let fakeRepository = null; const REPO_PATH_1 = '/fake/path_1'; const SHOTHEAD_1_1 = 'foo'; const SHOTHEAD_1_2 = 'bar'; @@ -34,172 +43,146 @@ describe('BookShelf accumulateState', () => { const REPO_STATE_1 = { activeShortHead: ACTIVE_SHOTHEAD_1, isRestoring: false, - shortHeadsToFileList: Immutable.Map([ - [SHOTHEAD_1_1, ['c.txt', 'd.txt']], - [SHOTHEAD_1_2, ['e.txt']], - ]), + shortHeadsToFileList: (_immutable || _load_immutable()).Map([[SHOTHEAD_1_1, ['c.txt', 'd.txt']], [SHOTHEAD_1_2, ['e.txt']]]) }; - let emptyState: BookShelfState = (null: any); - let oneRepoState: BookShelfState = (null: any); + let emptyState = null; + let oneRepoState = null; beforeEach(() => { - fakeRepository = ({ - getWorkingDirectory: jest.fn().mockReturnValue(REPO_PATH_1), - }: any); + fakeRepository = { + getWorkingDirectory: jest.fn().mockReturnValue(REPO_PATH_1) + }; // a deepFreeze utility would have been better here. - emptyState = Object.freeze(getEmptBookShelfState()); + emptyState = Object.freeze((0, (_utils || _load_utils()).getEmptBookShelfState)()); oneRepoState = Object.freeze({ - repositoryPathToState: Immutable.Map([[REPO_PATH_1, REPO_STATE_1]]), + repositoryPathToState: (_immutable || _load_immutable()).Map([[REPO_PATH_1, REPO_STATE_1]]) }); }); describe('ADD_PROJECT_REPOSITORY', () => { it('adds an empty repository to the bookshelf state', () => { - const addRepositoryAction: AddProjectRepositoryAction = { + const addRepositoryAction = { payload: { - repository: fakeRepository, + repository: fakeRepository }, - type: ActionType.ADD_PROJECT_REPOSITORY, + type: (_constants || _load_constants()).ActionType.ADD_PROJECT_REPOSITORY }; - const newState = accumulateState(emptyState, addRepositoryAction); + const newState = (0, (_accumulateState || _load_accumulateState()).accumulateState)(emptyState, addRepositoryAction); expect(fakeRepository.getWorkingDirectory).toHaveBeenCalled(); expect(emptyState.repositoryPathToState.size).toBe(0); expect(newState.repositoryPathToState.size).toBe(1); - const addedRepoState: BookShelfRepositoryState = nullthrows( - newState.repositoryPathToState.get(REPO_PATH_1), - ); + const addedRepoState = (0, (_nullthrows || _load_nullthrows()).default)(newState.repositoryPathToState.get(REPO_PATH_1)); expect(addedRepoState).toBeDefined(); - expect(addedRepoState.activeShortHead).toBe(EMPTY_SHORTHEAD); + expect(addedRepoState.activeShortHead).toBe((_constants || _load_constants()).EMPTY_SHORTHEAD); expect(addedRepoState.isRestoring).toBeFalsy(); expect(addedRepoState.shortHeadsToFileList.size).toBe(0); }); it("keeps the existing state when it's there", () => { expect(oneRepoState.repositoryPathToState.size).toBe(1); - const addRepositoryAction: AddProjectRepositoryAction = { + const addRepositoryAction = { payload: { - repository: fakeRepository, + repository: fakeRepository }, - type: ActionType.ADD_PROJECT_REPOSITORY, + type: (_constants || _load_constants()).ActionType.ADD_PROJECT_REPOSITORY }; - const newState = accumulateState(oneRepoState, addRepositoryAction); + const newState = (0, (_accumulateState || _load_accumulateState()).accumulateState)(oneRepoState, addRepositoryAction); expect(fakeRepository.getWorkingDirectory).toHaveBeenCalled(); expect(newState.repositoryPathToState.size).toBe(1); - const keptRepoState: BookShelfRepositoryState = nullthrows( - newState.repositoryPathToState.get(REPO_PATH_1), - ); + const keptRepoState = (0, (_nullthrows || _load_nullthrows()).default)(newState.repositoryPathToState.get(REPO_PATH_1)); expect(keptRepoState).toBeDefined(); expect(keptRepoState.activeShortHead).toBe(ACTIVE_SHOTHEAD_1); expect(keptRepoState.isRestoring).toBeFalsy(); expect(keptRepoState.shortHeadsToFileList.size).toBe(2); - expect(keptRepoState.shortHeadsToFileList.get(SHOTHEAD_1_1)).toEqual([ - 'c.txt', - 'd.txt', - ]); - expect(keptRepoState.shortHeadsToFileList.get(SHOTHEAD_1_2)).toEqual([ - 'e.txt', - ]); + expect(keptRepoState.shortHeadsToFileList.get(SHOTHEAD_1_1)).toEqual(['c.txt', 'd.txt']); + expect(keptRepoState.shortHeadsToFileList.get(SHOTHEAD_1_2)).toEqual(['e.txt']); }); }); describe('REMOVE_PROJECT_REPOSITORY', () => { it('removes the managed state of the repository', () => { expect(oneRepoState.repositoryPathToState.size).toBe(1); - const removeRepositoryAction: RemoveProjectRepositoryAction = { + const removeRepositoryAction = { payload: { - repository: fakeRepository, + repository: fakeRepository }, - type: ActionType.REMOVE_PROJECT_REPOSITORY, + type: (_constants || _load_constants()).ActionType.REMOVE_PROJECT_REPOSITORY }; - const newState = accumulateState(emptyState, removeRepositoryAction); + const newState = (0, (_accumulateState || _load_accumulateState()).accumulateState)(emptyState, removeRepositoryAction); expect(fakeRepository.getWorkingDirectory).toHaveBeenCalled(); expect(oneRepoState.repositoryPathToState.size).toBe(1); expect(newState.repositoryPathToState.size).toBe(0); }); it('no-op when no existing tracked state', () => { - const removeRepositoryAction: RemoveProjectRepositoryAction = { + const removeRepositoryAction = { payload: { - repository: fakeRepository, + repository: fakeRepository }, - type: ActionType.REMOVE_PROJECT_REPOSITORY, + type: (_constants || _load_constants()).ActionType.REMOVE_PROJECT_REPOSITORY }; - const newState = accumulateState(emptyState, removeRepositoryAction); + const newState = (0, (_accumulateState || _load_accumulateState()).accumulateState)(emptyState, removeRepositoryAction); expect(fakeRepository.getWorkingDirectory).toHaveBeenCalled(); - expect(newState.repositoryPathToState).toBe( - emptyState.repositoryPathToState, - ); + expect(newState.repositoryPathToState).toBe(emptyState.repositoryPathToState); }); }); describe('UPDATE_REPOSITORY_BOOKMARKS', () => { it('creates a repository with bookmark state, if no one exists', () => { - const updateBookmarksAction: UpdateRepositoryBookmarksAction = { + const updateBookmarksAction = { payload: { repository: fakeRepository, bookmarkNames: new Set(['a', 'b', 'c']), - activeShortHead: 'a', + activeShortHead: 'a' }, - type: ActionType.UPDATE_REPOSITORY_BOOKMARKS, + type: (_constants || _load_constants()).ActionType.UPDATE_REPOSITORY_BOOKMARKS }; - const newState = accumulateState(emptyState, updateBookmarksAction); + const newState = (0, (_accumulateState || _load_accumulateState()).accumulateState)(emptyState, updateBookmarksAction); expect(emptyState.repositoryPathToState.size).toBe(0); expect(newState.repositoryPathToState.size).toBe(1); - const newRepositoryState: BookShelfRepositoryState = nullthrows( - newState.repositoryPathToState.get(REPO_PATH_1), - ); + const newRepositoryState = (0, (_nullthrows || _load_nullthrows()).default)(newState.repositoryPathToState.get(REPO_PATH_1)); expect(newRepositoryState.activeShortHead).toBe('a'); expect(newRepositoryState.isRestoring).toBe(false); expect(newRepositoryState.shortHeadsToFileList.size).toBe(0); }); it('removes old cached short head data when its bookmarks are gone', () => { - const updateBookmarksAction: UpdateRepositoryBookmarksAction = { + const updateBookmarksAction = { payload: { repository: fakeRepository, bookmarkNames: new Set([SHOTHEAD_1_2]), - activeShortHead: SHOTHEAD_1_2, + activeShortHead: SHOTHEAD_1_2 }, - type: ActionType.UPDATE_REPOSITORY_BOOKMARKS, + type: (_constants || _load_constants()).ActionType.UPDATE_REPOSITORY_BOOKMARKS }; - const oldRpositoryState = oneRepoState.repositoryPathToState.get( - REPO_PATH_1, - ); - expect(nullthrows(oldRpositoryState).shortHeadsToFileList.size).toBe(2); - expect( - nullthrows(oldRpositoryState).shortHeadsToFileList.has(SHOTHEAD_1_1), - ).toBeTruthy(); - - const newState = accumulateState(oneRepoState, updateBookmarksAction); + const oldRpositoryState = oneRepoState.repositoryPathToState.get(REPO_PATH_1); + expect((0, (_nullthrows || _load_nullthrows()).default)(oldRpositoryState).shortHeadsToFileList.size).toBe(2); + expect((0, (_nullthrows || _load_nullthrows()).default)(oldRpositoryState).shortHeadsToFileList.has(SHOTHEAD_1_1)).toBeTruthy(); + + const newState = (0, (_accumulateState || _load_accumulateState()).accumulateState)(oneRepoState, updateBookmarksAction); expect(newState.repositoryPathToState.size).toBe(1); - const newRepositoryState: BookShelfRepositoryState = nullthrows( - newState.repositoryPathToState.get(REPO_PATH_1), - ); + const newRepositoryState = (0, (_nullthrows || _load_nullthrows()).default)(newState.repositoryPathToState.get(REPO_PATH_1)); expect(newRepositoryState.activeShortHead).toBe(SHOTHEAD_1_2); expect(newRepositoryState.isRestoring).toBe(false); expect(newRepositoryState.shortHeadsToFileList.size).toBe(1); - expect( - newRepositoryState.shortHeadsToFileList.has(SHOTHEAD_1_1), - ).toBeFalsy(); - expect(newRepositoryState.shortHeadsToFileList.get(SHOTHEAD_1_2)).toEqual( - nullthrows(oldRpositoryState).shortHeadsToFileList.get(SHOTHEAD_1_2), - ); + expect(newRepositoryState.shortHeadsToFileList.has(SHOTHEAD_1_1)).toBeFalsy(); + expect(newRepositoryState.shortHeadsToFileList.get(SHOTHEAD_1_2)).toEqual((0, (_nullthrows || _load_nullthrows()).default)(oldRpositoryState).shortHeadsToFileList.get(SHOTHEAD_1_2)); }); }); describe('UDATE_PANE_ITEM_STATE', () => { const OTHER_REPO_PARH = '/another/repo/path'; - let fakeEditor1: atom$TextEditor = (null: any); - let fakeEditor2: atom$TextEditor = (null: any); - let fakeEditor3: atom$TextEditor = (null: any); + let fakeEditor1 = null; + let fakeEditor2 = null; + let fakeEditor3 = null; - function createFakeEditor(editorPath: NuclideUri): atom$TextEditor { + function createFakeEditor(editorPath) { // $FlowFixMe return { - getPath: jest.fn().mockReturnValue(editorPath), + getPath: jest.fn().mockReturnValue(editorPath) }; } @@ -210,38 +193,34 @@ describe('BookShelf accumulateState', () => { }); it('updates the tracked repos states with the new pane item state', () => { - const updatePaneItemAction: UpdatePaneItemStateAction = { + const updatePaneItemAction = { payload: { - repositoryPathToEditors: new Map([ - [REPO_PATH_1, [fakeEditor1, fakeEditor2]], - [OTHER_REPO_PARH, [fakeEditor3]], - ]), + repositoryPathToEditors: new Map([[REPO_PATH_1, [fakeEditor1, fakeEditor2]], [OTHER_REPO_PARH, [fakeEditor3]]]) }, - type: ActionType.UPDATE_PANE_ITEM_STATE, + type: (_constants || _load_constants()).ActionType.UPDATE_PANE_ITEM_STATE }; - const newState = accumulateState(oneRepoState, updatePaneItemAction); + const newState = (0, (_accumulateState || _load_accumulateState()).accumulateState)(oneRepoState, updatePaneItemAction); - const oldShortHeadsToFileList = nullthrows( - oneRepoState.repositoryPathToState.get(REPO_PATH_1), - ).shortHeadsToFileList; + const oldShortHeadsToFileList = (0, (_nullthrows || _load_nullthrows()).default)(oneRepoState.repositoryPathToState.get(REPO_PATH_1)).shortHeadsToFileList; expect(oldShortHeadsToFileList.size).toBe(2); - expect(oldShortHeadsToFileList.get(SHOTHEAD_1_1)).toEqual([ - 'c.txt', - 'd.txt', - ]); + expect(oldShortHeadsToFileList.get(SHOTHEAD_1_1)).toEqual(['c.txt', 'd.txt']); // Doesn't add untracked repos. expect(newState.repositoryPathToState.size).toBe(1); - const newShortHeadsToFileList = nullthrows( - newState.repositoryPathToState.get(REPO_PATH_1), - ).shortHeadsToFileList; + const newShortHeadsToFileList = (0, (_nullthrows || _load_nullthrows()).default)(newState.repositoryPathToState.get(REPO_PATH_1)).shortHeadsToFileList; expect(newShortHeadsToFileList.size).toBe(2); - expect(newShortHeadsToFileList.get(SHOTHEAD_1_1)).toEqual([ - 'file1.txt', - 'file2.txt', - ]); + expect(newShortHeadsToFileList.get(SHOTHEAD_1_1)).toEqual(['file1.txt', 'file2.txt']); expect(newShortHeadsToFileList.get(SHOTHEAD_1_2)).toEqual(['e.txt']); }); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-bookshelf/__tests__/utils-test.js b/pkg/nuclide-bookshelf/__tests__/utils-test.js index ff92fcb300..64857370b5 100644 --- a/pkg/nuclide-bookshelf/__tests__/utils-test.js +++ b/pkg/nuclide-bookshelf/__tests__/utils-test.js @@ -1,34 +1,40 @@ -/** - * 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 - */ - -import type { - RepositoryShortHeadChange, - SerializedBookShelfState, -} from '../lib/types'; - -import waitsFor from '../../../jest/waits_for'; -import invariant from 'assert'; -import { - getDummyBookShelfState, - REPO_PATH_1 as DUMMY_REPO_PATH_1, -} from '../__mocks__/dummy1'; -import { - deserializeBookShelfState, - getEmptBookShelfState, - getShortHeadChangesFromStateStream, - serializeBookShelfState, -} from '../lib/utils'; -import * as Immutable from 'immutable'; -import nullthrows from 'nullthrows'; -import {Subject} from 'rxjs'; +'use strict'; + +var _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../../../jest/waits_for')); +} + +var _dummy; + +function _load_dummy() { + return _dummy = require('../__mocks__/dummy1'); +} + +var _utils; + +function _load_utils() { + return _utils = require('../lib/utils'); +} + +var _immutable; + +function _load_immutable() { + return _immutable = _interopRequireWildcard(require('immutable')); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +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 }; } describe('BookShelf Utils', () => { describe('serialize/deserialize', () => { @@ -38,7 +44,7 @@ describe('BookShelf Utils', () => { const REPO_STATE_1 = { activeShortHead: ACTIVE_SHOTHEAD_1, isRestoring: false, - shortHeadsToFileList: Immutable.Map([[SHOTHEAD_1_1, ['a.txt', 'b.txt']]]), + shortHeadsToFileList: (_immutable || _load_immutable()).Map([[SHOTHEAD_1_1, ['a.txt', 'b.txt']]]) }; const REPO_PATH_2 = '/fake/path_2'; @@ -48,38 +54,28 @@ describe('BookShelf Utils', () => { const REPO_STATE_2 = { activeShortHead: ACTIVE_SHOTHEAD_2, isRestoring: false, - shortHeadsToFileList: Immutable.Map([ - [SHOTHEAD_2_1, ['c.txt', 'd.txt']], - [SHOTHEAD_2_2, ['e.txt']], - ]), + shortHeadsToFileList: (_immutable || _load_immutable()).Map([[SHOTHEAD_2_1, ['c.txt', 'd.txt']], [SHOTHEAD_2_2, ['e.txt']]]) }; describe('serializeBookShelfState', () => { it('serializes an empty state', () => { - const serialized = serializeBookShelfState(getEmptBookShelfState()); + const serialized = (0, (_utils || _load_utils()).serializeBookShelfState)((0, (_utils || _load_utils()).getEmptBookShelfState)()); expect(serialized.repositoryPathToState.length).toBe(0); }); it('serializes bookshelf state maps to entries pais', () => { - const serialized = serializeBookShelfState({ - repositoryPathToState: Immutable.Map([ - [REPO_PATH_1, REPO_STATE_1], - [REPO_PATH_2, REPO_STATE_2], - ]), + const serialized = (0, (_utils || _load_utils()).serializeBookShelfState)({ + repositoryPathToState: (_immutable || _load_immutable()).Map([[REPO_PATH_1, REPO_STATE_1], [REPO_PATH_2, REPO_STATE_2]]) }); expect(serialized.repositoryPathToState.length).toBe(2); const serializedRepoState1 = serialized.repositoryPathToState[0]; expect(serializedRepoState1.length).toBe(2); expect(serializedRepoState1[0]).toBe(REPO_PATH_1); expect(serializedRepoState1[1].activeShortHead).toBe(ACTIVE_SHOTHEAD_1); - expect((serializedRepoState1[1]: any).isRestoring).toBeUndefined(); + expect(serializedRepoState1[1].isRestoring).toBeUndefined(); expect(serializedRepoState1[1].shortHeadsToFileList.length).toBe(1); - expect(serializedRepoState1[1].shortHeadsToFileList[0][0]).toBe( - SHOTHEAD_1_1, - ); - expect( - serializedRepoState1[1].shortHeadsToFileList[0][1].join(','), - ).toBe(['a.txt', 'b.txt'].join(',')); + expect(serializedRepoState1[1].shortHeadsToFileList[0][0]).toBe(SHOTHEAD_1_1); + expect(serializedRepoState1[1].shortHeadsToFileList[0][1].join(',')).toBe(['a.txt', 'b.txt'].join(',')); const serializedRepoState2 = serialized.repositoryPathToState[1]; expect(serializedRepoState2.length).toBe(2); @@ -88,137 +84,109 @@ describe('BookShelf Utils', () => { }); it('serializing an invalid bookshelf state throws', () => { - expect(() => serializeBookShelfState(({}: any))).toThrow(); + expect(() => (0, (_utils || _load_utils()).serializeBookShelfState)({})).toThrow(); }); }); describe('deserializeBookShelfState', () => { it('dserializes null to an empty state', () => { - const deserialized = deserializeBookShelfState(null); + const deserialized = (0, (_utils || _load_utils()).deserializeBookShelfState)(null); expect(deserialized.repositoryPathToState.size).toBe(0); }); it('dserializes one repository state', () => { - const serializedState: SerializedBookShelfState = ({ - repositoryPathToState: [ - [ - REPO_PATH_1, - { - ...REPO_STATE_1, - shortHeadsToFileList: Array.from( - REPO_STATE_1.shortHeadsToFileList.entries(), - ), - }, - ], - ], - }: any); - const deserialized = deserializeBookShelfState(serializedState); + const serializedState = { + repositoryPathToState: [[REPO_PATH_1, Object.assign({}, REPO_STATE_1, { + shortHeadsToFileList: Array.from(REPO_STATE_1.shortHeadsToFileList.entries()) + })]] + }; + const deserialized = (0, (_utils || _load_utils()).deserializeBookShelfState)(serializedState); expect(deserialized.repositoryPathToState.size).toBe(1); - const deserializedRepoState = deserialized.repositoryPathToState.get( - REPO_PATH_1, - ); + const deserializedRepoState = deserialized.repositoryPathToState.get(REPO_PATH_1); expect(deserializedRepoState).not.toBeNull(); - invariant(deserializedRepoState != null); + + if (!(deserializedRepoState != null)) { + throw new Error('Invariant violation: "deserializedRepoState != null"'); + } + expect(deserializedRepoState.activeShortHead).toBe(ACTIVE_SHOTHEAD_1); expect(deserializedRepoState.isRestoring).toBe(false); expect(deserializedRepoState.shortHeadsToFileList.size).toBe(1); - expect( - nullthrows( - deserializedRepoState.shortHeadsToFileList.get(SHOTHEAD_1_1), - ).join(','), - ).toBe(['a.txt', 'b.txt'].join(',')); + expect((0, (_nullthrows || _load_nullthrows()).default)(deserializedRepoState.shortHeadsToFileList.get(SHOTHEAD_1_1)).join(',')).toBe(['a.txt', 'b.txt'].join(',')); }); it('dserializes two repository states', () => { - const serializedState: SerializedBookShelfState = ({ - repositoryPathToState: [ - [ - REPO_PATH_1, - { - ...REPO_STATE_1, - shortHeadsToFileList: Array.from( - REPO_STATE_1.shortHeadsToFileList.entries(), - ), - }, - ], - [ - REPO_PATH_2, - { - ...REPO_STATE_2, - shortHeadsToFileList: Array.from( - REPO_STATE_2.shortHeadsToFileList.entries(), - ), - }, - ], - ], - }: any); - const deserialized = deserializeBookShelfState(serializedState); + const serializedState = { + repositoryPathToState: [[REPO_PATH_1, Object.assign({}, REPO_STATE_1, { + shortHeadsToFileList: Array.from(REPO_STATE_1.shortHeadsToFileList.entries()) + })], [REPO_PATH_2, Object.assign({}, REPO_STATE_2, { + shortHeadsToFileList: Array.from(REPO_STATE_2.shortHeadsToFileList.entries()) + })]] + }; + const deserialized = (0, (_utils || _load_utils()).deserializeBookShelfState)(serializedState); expect(deserialized.repositoryPathToState.size).toBe(2); - const deserializedRepoState1 = nullthrows( - deserialized.repositoryPathToState.get(REPO_PATH_1), - ); + const deserializedRepoState1 = (0, (_nullthrows || _load_nullthrows()).default)(deserialized.repositoryPathToState.get(REPO_PATH_1)); expect(deserializedRepoState1).not.toBeNull(); - invariant(deserializedRepoState1 != null); + + if (!(deserializedRepoState1 != null)) { + throw new Error('Invariant violation: "deserializedRepoState1 != null"'); + } + expect(deserializedRepoState1.activeShortHead).toBe(ACTIVE_SHOTHEAD_1); expect(deserializedRepoState1.isRestoring).toBe(false); expect(deserializedRepoState1.shortHeadsToFileList.size).toBe(1); - expect( - nullthrows( - deserializedRepoState1.shortHeadsToFileList.get(SHOTHEAD_1_1), - ).join(','), - ).toBe(['a.txt', 'b.txt'].join(',')); - - const deserializedRepoState2 = nullthrows( - deserialized.repositoryPathToState.get(REPO_PATH_2), - ); + expect((0, (_nullthrows || _load_nullthrows()).default)(deserializedRepoState1.shortHeadsToFileList.get(SHOTHEAD_1_1)).join(',')).toBe(['a.txt', 'b.txt'].join(',')); + + const deserializedRepoState2 = (0, (_nullthrows || _load_nullthrows()).default)(deserialized.repositoryPathToState.get(REPO_PATH_2)); expect(deserializedRepoState2).not.toBeNull(); - invariant(deserializedRepoState2 != null); + + if (!(deserializedRepoState2 != null)) { + throw new Error('Invariant violation: "deserializedRepoState2 != null"'); + } + expect(deserializedRepoState2.activeShortHead).toBe(ACTIVE_SHOTHEAD_2); expect(deserializedRepoState2.isRestoring).toBe(false); expect(deserializedRepoState2.shortHeadsToFileList.size).toBe(2); - expect( - nullthrows( - deserializedRepoState2.shortHeadsToFileList.get(SHOTHEAD_2_1), - ).join(','), - ).toBe(['c.txt', 'd.txt'].join(',')); - expect( - nullthrows( - deserializedRepoState2.shortHeadsToFileList.get(SHOTHEAD_2_2), - ).join(','), - ).toBe('e.txt'); + expect((0, (_nullthrows || _load_nullthrows()).default)(deserializedRepoState2.shortHeadsToFileList.get(SHOTHEAD_2_1)).join(',')).toBe(['c.txt', 'd.txt'].join(',')); + expect((0, (_nullthrows || _load_nullthrows()).default)(deserializedRepoState2.shortHeadsToFileList.get(SHOTHEAD_2_2)).join(',')).toBe('e.txt'); }); it('deserializing an invalid state throws an exception', () => { - expect(() => - deserializeBookShelfState(({repositoryPathToState: 123}: any)), - ).toThrow(); + expect(() => (0, (_utils || _load_utils()).deserializeBookShelfState)({ repositoryPathToState: 123 })).toThrow(); }); }); }); test('getShortHeadChangesFromStateStream', async () => { - const states = new Subject(); - const shortHeadChangesStream = getShortHeadChangesFromStateStream(states); + const states = new _rxjsBundlesRxMinJs.Subject(); + const shortHeadChangesStream = (0, (_utils || _load_utils()).getShortHeadChangesFromStateStream)(states); - const shortHeadChanges: Array = []; + const shortHeadChanges = []; shortHeadChangesStream.subscribe(change => shortHeadChanges.push(change)); - states.next(getDummyBookShelfState()); + states.next((0, (_dummy || _load_dummy()).getDummyBookShelfState)()); const newActiveShortHead = 'foo_bar'; - const newStateWithShortHeadChange = getDummyBookShelfState(); - const newRepositoryState = newStateWithShortHeadChange.repositoryPathToState.get( - DUMMY_REPO_PATH_1, - ); - nullthrows(newRepositoryState).activeShortHead = newActiveShortHead; + const newStateWithShortHeadChange = (0, (_dummy || _load_dummy()).getDummyBookShelfState)(); + const newRepositoryState = newStateWithShortHeadChange.repositoryPathToState.get((_dummy || _load_dummy()).REPO_PATH_1); + (0, (_nullthrows || _load_nullthrows()).default)(newRepositoryState).activeShortHead = newActiveShortHead; states.next(newStateWithShortHeadChange); states.complete(); - await waitsFor(() => shortHeadChanges.length === 1); + await (0, (_waits_for || _load_waits_for()).default)(() => shortHeadChanges.length === 1); - const {repositoryPath, activeShortHead} = shortHeadChanges[0]; - expect(repositoryPath).toBe(DUMMY_REPO_PATH_1); + const { repositoryPath, activeShortHead } = shortHeadChanges[0]; + expect(repositoryPath).toBe((_dummy || _load_dummy()).REPO_PATH_1); expect(activeShortHead).toBe(newActiveShortHead); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-bookshelf/lib/Commands.js b/pkg/nuclide-bookshelf/lib/Commands.js index 25e1646415..8d2816c4de 100644 --- a/pkg/nuclide-bookshelf/lib/Commands.js +++ b/pkg/nuclide-bookshelf/lib/Commands.js @@ -1,3 +1,28 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Commands = undefined; + +var _constants; + +function _load_constants() { + return _constants = require('./constants'); +} + +var _utils; + +function _load_utils() { + return _utils = require('./utils'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,57 +30,45 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {Action, BookShelfState} from './types'; +class Commands { + + constructor(dispatch, getState) { + this.addProjectRepository = repository => { + this._dispatch({ + payload: { + repository + }, + type: (_constants || _load_constants()).ActionType.ADD_PROJECT_REPOSITORY + }); + }; -import {ActionType} from './constants'; -import {getRepoPathToEditors} from './utils'; -import {track} from '../../nuclide-analytics'; + this.updatePaneItemState = () => { + this._dispatch({ + type: (_constants || _load_constants()).ActionType.UPDATE_PANE_ITEM_STATE, + payload: { + repositoryPathToEditors: (0, (_utils || _load_utils()).getRepoPathToEditors)() + } + }); + }; -export class Commands { - _dispatch: (action: Action) => void; - _getState: () => BookShelfState; + this.restorePaneItemState = (repository, newShortHead) => { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('bookshelf-restore-files'); + this._dispatch({ + payload: { + repository, + shortHead: newShortHead + }, + type: (_constants || _load_constants()).ActionType.RESTORE_PANE_ITEM_STATE + }); + }; - constructor( - dispatch: (action: Action) => void, - getState: () => BookShelfState, - ) { this._dispatch = dispatch; this._getState = getState; } - addProjectRepository = (repository: atom$Repository): void => { - this._dispatch({ - payload: { - repository, - }, - type: ActionType.ADD_PROJECT_REPOSITORY, - }); - }; - - updatePaneItemState = (): void => { - this._dispatch({ - type: ActionType.UPDATE_PANE_ITEM_STATE, - payload: { - repositoryPathToEditors: getRepoPathToEditors(), - }, - }); - }; - - restorePaneItemState = ( - repository: atom$Repository, - newShortHead: string, - ): void => { - track('bookshelf-restore-files'); - this._dispatch({ - payload: { - repository, - shortHead: newShortHead, - }, - type: ActionType.RESTORE_PANE_ITEM_STATE, - }); - }; } +exports.Commands = Commands; \ No newline at end of file diff --git a/pkg/nuclide-bookshelf/lib/accumulateState.js b/pkg/nuclide-bookshelf/lib/accumulateState.js index 2b6ee6b479..669642496a 100644 --- a/pkg/nuclide-bookshelf/lib/accumulateState.js +++ b/pkg/nuclide-bookshelf/lib/accumulateState.js @@ -1,3 +1,24 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.accumulateState = accumulateState; + +var _constants; + +function _load_constants() { + return _constants = require('./constants'); +} + +var _immutable; + +function _load_immutable() { + return _immutable = _interopRequireWildcard(require('immutable')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,52 +26,32 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type { - Action, - AddProjectRepositoryAction, - BookShelfRepositoryState, - BookShelfState, - CompleteRestoringRepositoryStateAction, - RemoveProjectRepositoryAction, - StartRestoringRepositoryStateAction, - UpdatePaneItemStateAction, - UpdateRepositoryBookmarksAction, -} from './types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import {ActionType, EMPTY_SHORTHEAD} from './constants'; -import * as Immutable from 'immutable'; -import invariant from 'assert'; - -function getEmptyRepositoryState(): BookShelfRepositoryState { +function getEmptyRepositoryState() { return { - activeShortHead: EMPTY_SHORTHEAD, + activeShortHead: (_constants || _load_constants()).EMPTY_SHORTHEAD, isRestoring: false, - shortHeadsToFileList: Immutable.Map(), + shortHeadsToFileList: (_immutable || _load_immutable()).Map() }; } -export function accumulateState( - state: BookShelfState, - action: Action, -): BookShelfState { +function accumulateState(state, action) { switch (action.type) { - case ActionType.ADD_PROJECT_REPOSITORY: + case (_constants || _load_constants()).ActionType.ADD_PROJECT_REPOSITORY: return accumulateAddProjectRepository(state, action); - case ActionType.REMOVE_PROJECT_REPOSITORY: + case (_constants || _load_constants()).ActionType.REMOVE_PROJECT_REPOSITORY: return accumulateRemoveProjectRepository(state, action); - case ActionType.UPDATE_PANE_ITEM_STATE: + case (_constants || _load_constants()).ActionType.UPDATE_PANE_ITEM_STATE: return accumulateUpdatePaneItemState(state, action); - case ActionType.UPDATE_REPOSITORY_BOOKMARKS: - case ActionType.START_RESTORING_REPOSITORY_STATE: - case ActionType.COMPLETE_RESTORING_REPOSITORY_STATE: + case (_constants || _load_constants()).ActionType.UPDATE_REPOSITORY_BOOKMARKS: + case (_constants || _load_constants()).ActionType.START_RESTORING_REPOSITORY_STATE: + case (_constants || _load_constants()).ActionType.COMPLETE_RESTORING_REPOSITORY_STATE: return accumulateRepositoryStateAction(state, action); default: @@ -58,96 +59,62 @@ export function accumulateState( } } -function accumulateAddProjectRepository( - state: BookShelfState, - action: AddProjectRepositoryAction, -): BookShelfState { +function accumulateAddProjectRepository(state, action) { const repositoryPath = action.payload.repository.getWorkingDirectory(); - const newRepositoryState = - state.repositoryPathToState.get(repositoryPath) || - getEmptyRepositoryState(); - return { - ...state, - repositoryPathToState: state.repositoryPathToState.set( - repositoryPath, - newRepositoryState, - ), - }; + const newRepositoryState = state.repositoryPathToState.get(repositoryPath) || getEmptyRepositoryState(); + return Object.assign({}, state, { + repositoryPathToState: state.repositoryPathToState.set(repositoryPath, newRepositoryState) + }); } -function accumulateRemoveProjectRepository( - state: BookShelfState, - action: RemoveProjectRepositoryAction, -): BookShelfState { +function accumulateRemoveProjectRepository(state, action) { const repositoryPath = action.payload.repository.getWorkingDirectory(); - return { - ...state, - repositoryPathToState: state.repositoryPathToState.delete(repositoryPath), - }; + return Object.assign({}, state, { + repositoryPathToState: state.repositoryPathToState.delete(repositoryPath) + }); } -function accumulateRepositoryStateAction( - state: BookShelfState, - action: - | UpdateRepositoryBookmarksAction - | StartRestoringRepositoryStateAction - | CompleteRestoringRepositoryStateAction, -): BookShelfState { +function accumulateRepositoryStateAction(state, action) { const repositoryPath = action.payload.repository.getWorkingDirectory(); - const newRepositoryState = accumulateRepositoryState( - state.repositoryPathToState.get(repositoryPath), - action, - ); - return { - ...state, - repositoryPathToState: state.repositoryPathToState.set( - repositoryPath, - newRepositoryState, - ), - }; + const newRepositoryState = accumulateRepositoryState(state.repositoryPathToState.get(repositoryPath), action); + return Object.assign({}, state, { + repositoryPathToState: state.repositoryPathToState.set(repositoryPath, newRepositoryState) + }); } -function accumulateRepositoryState( - repositoryState: ?BookShelfRepositoryState, - action: Action, -): BookShelfRepositoryState { +function accumulateRepositoryState(repositoryState, action) { switch (action.type) { - case ActionType.UPDATE_REPOSITORY_BOOKMARKS: + case (_constants || _load_constants()).ActionType.UPDATE_REPOSITORY_BOOKMARKS: return accumulateRepositoryStateUpdateBookmarks(repositoryState, action); - case ActionType.START_RESTORING_REPOSITORY_STATE: - invariant( - repositoryState, - 'repository state not found when starting to restore!', - ); - return { - ...repositoryState, - isRestoring: true, - }; - case ActionType.COMPLETE_RESTORING_REPOSITORY_STATE: - invariant( - repositoryState, - 'repository state not found when starting to restore!', - ); - return { - ...repositoryState, - isRestoring: false, - }; + case (_constants || _load_constants()).ActionType.START_RESTORING_REPOSITORY_STATE: + if (!repositoryState) { + throw new Error('repository state not found when starting to restore!'); + } + + return Object.assign({}, repositoryState, { + isRestoring: true + }); + case (_constants || _load_constants()).ActionType.COMPLETE_RESTORING_REPOSITORY_STATE: + if (!repositoryState) { + throw new Error('repository state not found when starting to restore!'); + } + + return Object.assign({}, repositoryState, { + isRestoring: false + }); default: return repositoryState || getEmptyRepositoryState(); } } -function accumulateRepositoryStateUpdateBookmarks( - repositoryState_: ?BookShelfRepositoryState, - action: UpdateRepositoryBookmarksAction, -): BookShelfRepositoryState { +function accumulateRepositoryStateUpdateBookmarks(repositoryState_, action) { let repositoryState = repositoryState_; repositoryState = repositoryState || getEmptyRepositoryState(); - const {bookmarkNames, activeShortHead} = action.payload; + const { bookmarkNames, activeShortHead } = action.payload; - let {shortHeadsToFileList} = repositoryState; + let { shortHeadsToFileList } = repositoryState; // Invalidate removed bookmarks data. for (const shortHead of repositoryState.shortHeadsToFileList.keys()) { if (!bookmarkNames.has(shortHead)) { @@ -155,51 +122,27 @@ function accumulateRepositoryStateUpdateBookmarks( } } - return { - ...repositoryState, + return Object.assign({}, repositoryState, { activeShortHead, - shortHeadsToFileList, - }; + shortHeadsToFileList + }); } -function accumulateUpdatePaneItemState( - state: BookShelfState, - action: UpdatePaneItemStateAction, -): BookShelfState { - const {repositoryPathToEditors} = action.payload; - return { - ...state, - repositoryPathToState: Immutable.Map( - Array.from(state.repositoryPathToState.entries()).map( - ([repositoryPath, repositoryState]) => { - const fileList = ( - repositoryPathToEditors.get(repositoryPath) || [] - ).map(textEditor => textEditor.getPath() || ''); - return [ - repositoryPath, - accumulateRepositoryStateUpdatePaneItemState( - repositoryState, - fileList, - ), - ]; - }, - ), - ), - }; +function accumulateUpdatePaneItemState(state, action) { + const { repositoryPathToEditors } = action.payload; + return Object.assign({}, state, { + repositoryPathToState: (_immutable || _load_immutable()).Map(Array.from(state.repositoryPathToState.entries()).map(([repositoryPath, repositoryState]) => { + const fileList = (repositoryPathToEditors.get(repositoryPath) || []).map(textEditor => textEditor.getPath() || ''); + return [repositoryPath, accumulateRepositoryStateUpdatePaneItemState(repositoryState, fileList)]; + })) + }); } -function accumulateRepositoryStateUpdatePaneItemState( - repositoryState: BookShelfRepositoryState, - fileList: Array, -): BookShelfRepositoryState { +function accumulateRepositoryStateUpdatePaneItemState(repositoryState, fileList) { if (repositoryState.isRestoring) { return repositoryState; } - return { - ...repositoryState, - shortHeadsToFileList: repositoryState.shortHeadsToFileList.set( - repositoryState.activeShortHead, - fileList, - ), - }; -} + return Object.assign({}, repositoryState, { + shortHeadsToFileList: repositoryState.shortHeadsToFileList.set(repositoryState.activeShortHead, fileList) + }); +} \ No newline at end of file diff --git a/pkg/nuclide-bookshelf/lib/applyActionMiddleware.js b/pkg/nuclide-bookshelf/lib/applyActionMiddleware.js index 93c8404e84..a67880f6dc 100644 --- a/pkg/nuclide-bookshelf/lib/applyActionMiddleware.js +++ b/pkg/nuclide-bookshelf/lib/applyActionMiddleware.js @@ -1,3 +1,42 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.applyActionMiddleware = applyActionMiddleware; + +var _constants; + +function _load_constants() { + return _constants = require('./constants'); +} + +var _utils; + +function _load_utils() { + return _utils = require('./utils'); +} + +var _event; + +function _load_event() { + return _event = require('../../../modules/nuclide-commons/event'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _goToLocation; + +function _load_goToLocation() { + return _goToLocation = require('../../../modules/nuclide-commons-atom/go-to-location'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,199 +44,120 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type { - Action, - ActionTypeValue, - AddProjectRepositoryAction, - BookShelfState, - RestorePaneItemStateAction, -} from './types'; -import type {HgRepositoryClient} from '../../nuclide-hg-repository-client'; - -import {ActionType, EMPTY_SHORTHEAD} from './constants'; -import {getRepoPathToEditors} from './utils'; -import invariant from 'assert'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import {getLogger} from 'log4js'; -import {goToLocation} from 'nuclide-commons-atom/go-to-location'; -import {Observable} from 'rxjs'; - -const HANDLED_ACTION_TYPES = [ - ActionType.ADD_PROJECT_REPOSITORY, - ActionType.RESTORE_PANE_ITEM_STATE, -]; - -function getActionsOfType( - actions: Observable, - type: ActionTypeValue, -): Observable { +const HANDLED_ACTION_TYPES = [(_constants || _load_constants()).ActionType.ADD_PROJECT_REPOSITORY, (_constants || _load_constants()).ActionType.RESTORE_PANE_ITEM_STATE]; + +function getActionsOfType(actions, type) { return actions.filter(action => action.type === type); } -export function applyActionMiddleware( - actions: Observable, - getState: () => BookShelfState, -): Observable { - const output = Observable.merge( - // Let the unhandled ActionTypes pass through. - actions.filter(action => HANDLED_ACTION_TYPES.indexOf(action.type) === -1), - getActionsOfType(actions, ActionType.ADD_PROJECT_REPOSITORY).flatMap( - action => { - invariant(action.type === ActionType.ADD_PROJECT_REPOSITORY); - return watchProjectRepository(action, getState); - }, - ), - getActionsOfType(actions, ActionType.RESTORE_PANE_ITEM_STATE).switchMap( - action => { - invariant(action.type === ActionType.RESTORE_PANE_ITEM_STATE); - return restorePaneItemState(action, getState); - }, - ), - ); +function applyActionMiddleware(actions, getState) { + const output = _rxjsBundlesRxMinJs.Observable.merge( + // Let the unhandled ActionTypes pass through. + actions.filter(action => HANDLED_ACTION_TYPES.indexOf(action.type) === -1), getActionsOfType(actions, (_constants || _load_constants()).ActionType.ADD_PROJECT_REPOSITORY).flatMap(action => { + if (!(action.type === (_constants || _load_constants()).ActionType.ADD_PROJECT_REPOSITORY)) { + throw new Error('Invariant violation: "action.type === ActionType.ADD_PROJECT_REPOSITORY"'); + } + + return watchProjectRepository(action, getState); + }), getActionsOfType(actions, (_constants || _load_constants()).ActionType.RESTORE_PANE_ITEM_STATE).switchMap(action => { + if (!(action.type === (_constants || _load_constants()).ActionType.RESTORE_PANE_ITEM_STATE)) { + throw new Error('Invariant violation: "action.type === ActionType.RESTORE_PANE_ITEM_STATE"'); + } + + return restorePaneItemState(action, getState); + })); return output.share(); } -function watchProjectRepository( - action: AddProjectRepositoryAction, - getState: () => BookShelfState, -): Observable { - const {repository} = action.payload; - const hgRepository: HgRepositoryClient = (repository: any); +function watchProjectRepository(action, getState) { + const { repository } = action.payload; + const hgRepository = repository; // Type was checked with `getType`. Downcast to safely access members with Flow. - return hgRepository - .observeBookmarks() - .map(bookmarks => { - const bookmarkNames = new Set( - bookmarks.map(bookmark => bookmark.bookmark).concat([EMPTY_SHORTHEAD]), - ); - - const activeBookmark = bookmarks.filter(bookmark => bookmark.active)[0]; - const activeShortHead = - activeBookmark == null ? EMPTY_SHORTHEAD : activeBookmark.bookmark; - - return { - payload: { - activeShortHead, - bookmarkNames, - repository, - }, - type: ActionType.UPDATE_REPOSITORY_BOOKMARKS, - }; - }) - .takeUntil( - observableFromSubscribeFunction(repository.onDidDestroy.bind(repository)), - ) - .concat( - Observable.of({ - payload: { - repository, - }, - type: ActionType.REMOVE_PROJECT_REPOSITORY, - }), - ); + return hgRepository.observeBookmarks().map(bookmarks => { + const bookmarkNames = new Set(bookmarks.map(bookmark => bookmark.bookmark).concat([(_constants || _load_constants()).EMPTY_SHORTHEAD])); + + const activeBookmark = bookmarks.filter(bookmark => bookmark.active)[0]; + const activeShortHead = activeBookmark == null ? (_constants || _load_constants()).EMPTY_SHORTHEAD : activeBookmark.bookmark; + + return { + payload: { + activeShortHead, + bookmarkNames, + repository + }, + type: (_constants || _load_constants()).ActionType.UPDATE_REPOSITORY_BOOKMARKS + }; + }).takeUntil((0, (_event || _load_event()).observableFromSubscribeFunction)(repository.onDidDestroy.bind(repository))).concat(_rxjsBundlesRxMinJs.Observable.of({ + payload: { + repository + }, + type: (_constants || _load_constants()).ActionType.REMOVE_PROJECT_REPOSITORY + })); } -function restorePaneItemState( - action: RestorePaneItemStateAction, - getState: () => BookShelfState, -): Observable { - const {repository, shortHead} = action.payload; +function restorePaneItemState(action, getState) { + const { repository, shortHead } = action.payload; - const repositoryState = getState().repositoryPathToState.get( - repository.getWorkingDirectory(), - ); + const repositoryState = getState().repositoryPathToState.get(repository.getWorkingDirectory()); if (repositoryState == null) { - return Observable.empty(); + return _rxjsBundlesRxMinJs.Observable.empty(); } // TODO(most): refactor to a `Set` all the way. - const fileUris = new Set( - repositoryState.shortHeadsToFileList.get(shortHead) || [], - ); - - const oldOpenEditors = - getRepoPathToEditors().get(repository.getWorkingDirectory()) || []; - const oldOpenUris = oldOpenEditors.map( - textEditor => textEditor.getPath() || '', - ); - - const editorsToReload = oldOpenEditors.filter(textEditor => - fileUris.has(textEditor.getPath() || ''), - ); - const editorsToClose = oldOpenEditors.filter( - textEditor => !fileUris.has(textEditor.getPath() || ''), - ); - const urisToOpen = Array.from(fileUris).filter( - fileUri => oldOpenUris.indexOf(fileUri) === -1, - ); - - return Observable.concat( - Observable.of({ - payload: { - repository, - }, - type: ActionType.START_RESTORING_REPOSITORY_STATE, - }), - Observable.from(editorsToClose) - // Close the open files from the old short head. - .map(textEditor => { - const editorPane = atom.workspace.paneForItem(textEditor); - if (editorPane != null) { - editorPane.destroyItem(textEditor); - } else { - textEditor.destroy(); - } - }) - .catch(error => { - getLogger('nuclide-bookshelf').error( - 'bookshelf failed to close some editors', - error, - ); - return Observable.empty(); - }) - .ignoreElements(), - // Note: the reloading step can be omitted if the file watchers are proven to be robust. - // But that's not the case; hence, a reload on bookmark switch/restore doesn't hurt. - Observable.from(editorsToReload) - .flatMap(textEditor => { - // Reload the open files that also exist to be in the current. - if (textEditor.isModified()) { - // If the filesystem version has changed while it's edited, - // the user will be prompted to resolve the conflict: `file-watcher`. - return Observable.empty(); - } else { - return Observable.fromPromise(textEditor.getBuffer().load()); - } - }) - .catch(error => { - getLogger('nuclide-bookshelf').error( - 'bookshelf failed to reload some editors', - error, - ); - return Observable.empty(); - }) - .ignoreElements(), - Observable.from(urisToOpen) - .flatMap(fileUri => { - return Observable.fromPromise(goToLocation(fileUri)); - }) - .catch(error => { - getLogger('nuclide-bookshelf').error( - 'bookshelf failed to open some editors', - error, - ); - return Observable.empty(); - }) - .ignoreElements(), - Observable.of({ - payload: { - repository, - }, - type: ActionType.COMPLETE_RESTORING_REPOSITORY_STATE, - }), - ); -} + const fileUris = new Set(repositoryState.shortHeadsToFileList.get(shortHead) || []); + + const oldOpenEditors = (0, (_utils || _load_utils()).getRepoPathToEditors)().get(repository.getWorkingDirectory()) || []; + const oldOpenUris = oldOpenEditors.map(textEditor => textEditor.getPath() || ''); + + const editorsToReload = oldOpenEditors.filter(textEditor => fileUris.has(textEditor.getPath() || '')); + const editorsToClose = oldOpenEditors.filter(textEditor => !fileUris.has(textEditor.getPath() || '')); + const urisToOpen = Array.from(fileUris).filter(fileUri => oldOpenUris.indexOf(fileUri) === -1); + + return _rxjsBundlesRxMinJs.Observable.concat(_rxjsBundlesRxMinJs.Observable.of({ + payload: { + repository + }, + type: (_constants || _load_constants()).ActionType.START_RESTORING_REPOSITORY_STATE + }), _rxjsBundlesRxMinJs.Observable.from(editorsToClose) + // Close the open files from the old short head. + .map(textEditor => { + const editorPane = atom.workspace.paneForItem(textEditor); + if (editorPane != null) { + editorPane.destroyItem(textEditor); + } else { + textEditor.destroy(); + } + }).catch(error => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-bookshelf').error('bookshelf failed to close some editors', error); + return _rxjsBundlesRxMinJs.Observable.empty(); + }).ignoreElements(), + // Note: the reloading step can be omitted if the file watchers are proven to be robust. + // But that's not the case; hence, a reload on bookmark switch/restore doesn't hurt. + _rxjsBundlesRxMinJs.Observable.from(editorsToReload).flatMap(textEditor => { + // Reload the open files that also exist to be in the current. + if (textEditor.isModified()) { + // If the filesystem version has changed while it's edited, + // the user will be prompted to resolve the conflict: `file-watcher`. + return _rxjsBundlesRxMinJs.Observable.empty(); + } else { + return _rxjsBundlesRxMinJs.Observable.fromPromise(textEditor.getBuffer().load()); + } + }).catch(error => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-bookshelf').error('bookshelf failed to reload some editors', error); + return _rxjsBundlesRxMinJs.Observable.empty(); + }).ignoreElements(), _rxjsBundlesRxMinJs.Observable.from(urisToOpen).flatMap(fileUri => { + return _rxjsBundlesRxMinJs.Observable.fromPromise((0, (_goToLocation || _load_goToLocation()).goToLocation)(fileUri)); + }).catch(error => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-bookshelf').error('bookshelf failed to open some editors', error); + return _rxjsBundlesRxMinJs.Observable.empty(); + }).ignoreElements(), _rxjsBundlesRxMinJs.Observable.of({ + payload: { + repository + }, + type: (_constants || _load_constants()).ActionType.COMPLETE_RESTORING_REPOSITORY_STATE + })); +} \ No newline at end of file diff --git a/pkg/nuclide-bookshelf/lib/constants.js b/pkg/nuclide-bookshelf/lib/constants.js index 2f064ed59f..d76ea520b1 100644 --- a/pkg/nuclide-bookshelf/lib/constants.js +++ b/pkg/nuclide-bookshelf/lib/constants.js @@ -1,43 +1,40 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type { - ActionTypeValue, - ActiveShortHeadChangeBehaviorValue, -} from './types'; - -export const ActionType = Object.freeze({ +Object.defineProperty(exports, "__esModule", { + value: true +}); +const ActionType = exports.ActionType = Object.freeze({ ADD_PROJECT_REPOSITORY: 'add-project-repository', COMPLETE_RESTORING_REPOSITORY_STATE: 'complete-restoring-repository-state', REMOVE_PROJECT_REPOSITORY: 'remove-project-repository', RESTORE_PANE_ITEM_STATE: 'restore-pane-item-state', START_RESTORING_REPOSITORY_STATE: 'start-restoring-repository-state', UPDATE_PANE_ITEM_STATE: 'update-pane-item-state', - UPDATE_REPOSITORY_BOOKMARKS: 'update-repository-bookmarks', + UPDATE_REPOSITORY_BOOKMARKS: 'update-repository-bookmarks' }); // This is to work around flow's missing support of enums. -(ActionType: {[key: string]: ActionTypeValue}); +/** + * 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. + * + * strict-local + * @format + */ -export const ActiveShortHeadChangeBehavior = Object.freeze({ +ActionType; + +const ActiveShortHeadChangeBehavior = exports.ActiveShortHeadChangeBehavior = Object.freeze({ ALWAYS_IGNORE: 'Always Ignore', ALWAYS_RESTORE: 'Always Restore', - PROMPT_TO_RESTORE: 'Prompt to Restore', + PROMPT_TO_RESTORE: 'Prompt to Restore' }); -(ActiveShortHeadChangeBehavior: { - [key: string]: ActiveShortHeadChangeBehaviorValue, -}); +ActiveShortHeadChangeBehavior; -export const ACTIVE_SHORTHEAD_CHANGE_BEHAVIOR_CONFIG = - 'nuclide-bookshelf.changeActiveBookmarkBehavior'; +const ACTIVE_SHORTHEAD_CHANGE_BEHAVIOR_CONFIG = exports.ACTIVE_SHORTHEAD_CHANGE_BEHAVIOR_CONFIG = 'nuclide-bookshelf.changeActiveBookmarkBehavior'; -export const EMPTY_SHORTHEAD = ''; +const EMPTY_SHORTHEAD = exports.EMPTY_SHORTHEAD = ''; \ No newline at end of file diff --git a/pkg/nuclide-bookshelf/lib/main.js b/pkg/nuclide-bookshelf/lib/main.js index 84ffc7f3fb..7cb073090a 100644 --- a/pkg/nuclide-bookshelf/lib/main.js +++ b/pkg/nuclide-bookshelf/lib/main.js @@ -1,170 +1,172 @@ -/** - * 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 strict-local - * @format - */ - -import type {Action, BookShelfState, SerializedBookShelfState} from './types'; - -import {accumulateState} from './accumulateState'; -import { - ActiveShortHeadChangeBehavior, - ACTIVE_SHORTHEAD_CHANGE_BEHAVIOR_CONFIG, -} from './constants'; -import {applyActionMiddleware} from './applyActionMiddleware'; -import {BehaviorSubject, Observable, Subject} from 'rxjs'; -import {Commands} from './Commands'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import { - deserializeBookShelfState, - getEmptBookShelfState, - serializeBookShelfState, -} from './utils'; -import {getHgRepositoryStream} from '../../nuclide-vcs-base'; -import {getLogger} from 'log4js'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import invariant from 'assert'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import { - shortHeadChangedNotification, - getShortHeadChangesFromStateStream, -} from './utils'; -import {track} from '../../nuclide-analytics'; - -function createStateStream( - actions: Observable, - initialState: BookShelfState, -): BehaviorSubject { - const states = new BehaviorSubject(initialState); - actions - .scan(accumulateState, initialState) - .catch(error => { - getLogger('nuclide-bookshelf').fatal( - 'bookshelf middleware got broken', - error, - ); - atom.notifications.addError( - 'Nuclide bookshelf broke, please report a bug to help us fix it!', - ); - return Observable.empty(); - }) - .subscribe(states); - return states; +'use strict'; + +var _accumulateState; + +function _load_accumulateState() { + return _accumulateState = require('./accumulateState'); +} + +var _constants; + +function _load_constants() { + return _constants = require('./constants'); +} + +var _applyActionMiddleware; + +function _load_applyActionMiddleware() { + return _applyActionMiddleware = require('./applyActionMiddleware'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _Commands; + +function _load_Commands() { + return _Commands = require('./Commands'); +} + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _utils; + +function _load_utils() { + return _utils = require('./utils'); +} + +var _nuclideVcsBase; + +function _load_nuclideVcsBase() { + return _nuclideVcsBase = require('../../nuclide-vcs-base'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _event; + +function _load_event() { + return _event = require('../../../modules/nuclide-commons/event'); } +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function createStateStream(actions, initialState) { + const states = new _rxjsBundlesRxMinJs.BehaviorSubject(initialState); + actions.scan((_accumulateState || _load_accumulateState()).accumulateState, initialState).catch(error => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-bookshelf').fatal('bookshelf middleware got broken', error); + atom.notifications.addError('Nuclide bookshelf broke, please report a bug to help us fix it!'); + return _rxjsBundlesRxMinJs.Observable.empty(); + }).subscribe(states); + return states; +} /** + * 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. + * + * strict-local + * @format + */ + class Activation { - _disposables: UniversalDisposable; - _states: BehaviorSubject; - _commands: Commands; - constructor(state: ?SerializedBookShelfState) { + constructor(state) { let initialState; try { - initialState = deserializeBookShelfState(state); + initialState = (0, (_utils || _load_utils()).deserializeBookShelfState)(state); } catch (error) { - getLogger('nuclide-bookshelf').error( - 'failed to deserialize nuclide-bookshelf state', - state, - error, - ); - initialState = getEmptBookShelfState(); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-bookshelf').error('failed to deserialize nuclide-bookshelf state', state, error); + initialState = (0, (_utils || _load_utils()).getEmptBookShelfState)(); } - const actions = new Subject(); - const states = (this._states = createStateStream( - applyActionMiddleware(actions, () => this._states.getValue()), - initialState, - )); + const actions = new _rxjsBundlesRxMinJs.Subject(); + const states = this._states = createStateStream((0, (_applyActionMiddleware || _load_applyActionMiddleware()).applyActionMiddleware)(actions, () => this._states.getValue()), initialState); const dispatch = action => { actions.next(action); }; - const commands = new Commands(dispatch, () => states.getValue()); - - const addedRepoSubscription = getHgRepositoryStream().subscribe( - repository => { - // $FlowFixMe wrong repository type - commands.addProjectRepository(repository); - }, - ); - - const paneStateChangeSubscription = Observable.merge( - observableFromSubscribeFunction( - atom.workspace.onDidAddPaneItem.bind(atom.workspace), - ), - observableFromSubscribeFunction( - atom.workspace.onDidDestroyPaneItem.bind(atom.workspace), - ), - ).subscribe(() => { + const commands = new (_Commands || _load_Commands()).Commands(dispatch, () => states.getValue()); + + const addedRepoSubscription = (0, (_nuclideVcsBase || _load_nuclideVcsBase()).getHgRepositoryStream)().subscribe(repository => { + // $FlowFixMe wrong repository type + commands.addProjectRepository(repository); + }); + + const paneStateChangeSubscription = _rxjsBundlesRxMinJs.Observable.merge((0, (_event || _load_event()).observableFromSubscribeFunction)(atom.workspace.onDidAddPaneItem.bind(atom.workspace)), (0, (_event || _load_event()).observableFromSubscribeFunction)(atom.workspace.onDidDestroyPaneItem.bind(atom.workspace))).subscribe(() => { commands.updatePaneItemState(); }); - const shortHeadChangeSubscription = getShortHeadChangesFromStateStream( - states, - ) - .switchMap(({repositoryPath, activeShortHead}) => { - const repository = atom.project.getRepositories().filter(repo => { - return repo != null && repo.getWorkingDirectory() === repositoryPath; - })[0]; - invariant( - repository != null, - 'shortHead changed on a non-existing repository!', - ); - - switch (featureConfig.get(ACTIVE_SHORTHEAD_CHANGE_BEHAVIOR_CONFIG)) { - case ActiveShortHeadChangeBehavior.ALWAYS_IGNORE: - track('bookshelf-always-ignore'); - return Observable.empty(); - case ActiveShortHeadChangeBehavior.ALWAYS_RESTORE: - track('bookshelf-always-restore'); - // The restore needs to wait for the change shorthead state update to complete - // before triggering a cascaded state update when handling the restore action. - // TODO(most): move away from `nextTick`. - process.nextTick(() => { - commands.restorePaneItemState(repository, activeShortHead); - }); - return Observable.empty(); - default: - // Including ActiveShortHeadChangeBehavior.PROMPT_TO_RESTORE - track('bookshelf-prompt-restore'); - return shortHeadChangedNotification( - repository, - activeShortHead, - commands.restorePaneItemState, - ); - } - }) - .subscribe(); - - this._disposables = new UniversalDisposable( - actions.complete.bind(actions), - addedRepoSubscription, - paneStateChangeSubscription, - shortHeadChangeSubscription, - ); + const shortHeadChangeSubscription = (0, (_utils || _load_utils()).getShortHeadChangesFromStateStream)(states).switchMap(({ repositoryPath, activeShortHead }) => { + const repository = atom.project.getRepositories().filter(repo => { + return repo != null && repo.getWorkingDirectory() === repositoryPath; + })[0]; + + if (!(repository != null)) { + throw new Error('shortHead changed on a non-existing repository!'); + } + + switch ((_featureConfig || _load_featureConfig()).default.get((_constants || _load_constants()).ACTIVE_SHORTHEAD_CHANGE_BEHAVIOR_CONFIG)) { + case (_constants || _load_constants()).ActiveShortHeadChangeBehavior.ALWAYS_IGNORE: + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('bookshelf-always-ignore'); + return _rxjsBundlesRxMinJs.Observable.empty(); + case (_constants || _load_constants()).ActiveShortHeadChangeBehavior.ALWAYS_RESTORE: + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('bookshelf-always-restore'); + // The restore needs to wait for the change shorthead state update to complete + // before triggering a cascaded state update when handling the restore action. + // TODO(most): move away from `nextTick`. + process.nextTick(() => { + commands.restorePaneItemState(repository, activeShortHead); + }); + return _rxjsBundlesRxMinJs.Observable.empty(); + default: + // Including ActiveShortHeadChangeBehavior.PROMPT_TO_RESTORE + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('bookshelf-prompt-restore'); + return (0, (_utils || _load_utils()).shortHeadChangedNotification)(repository, activeShortHead, commands.restorePaneItemState); + } + }).subscribe(); + + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(actions.complete.bind(actions), addedRepoSubscription, paneStateChangeSubscription, shortHeadChangeSubscription); } dispose() { this._disposables.dispose(); } - serialize(): ?SerializedBookShelfState { + serialize() { try { - return serializeBookShelfState(this._states.getValue()); + return (0, (_utils || _load_utils()).serializeBookShelfState)(this._states.getValue()); } catch (error) { - getLogger('nuclide-bookshelf').error( - 'failed to serialize nuclide-bookshelf state', - error, - ); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-bookshelf').error('failed to serialize nuclide-bookshelf state', error); return null; } } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-bookshelf/lib/types.js b/pkg/nuclide-bookshelf/lib/types.js index dcad58cb23..a726efc43f 100644 --- a/pkg/nuclide-bookshelf/lib/types.js +++ b/pkg/nuclide-bookshelf/lib/types.js @@ -1,113 +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 - */ - -import type Immutable from 'immutable'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -export type BookShelfState = { - repositoryPathToState: Immutable.Map, -}; - -export type SerializedBookShelfState = { - repositoryPathToState: Array<[string, SerializedBookShelfRepositoryState]>, -}; - -export type BookShelfRepositoryState = { - activeShortHead: string, - isRestoring: boolean, - shortHeadsToFileList: Immutable.Map>, -}; - -export type SerializedBookShelfRepositoryState = { - activeShortHead: string, - shortHeadsToFileList: Array<[string, Array]>, -}; - -export type RepositoryShortHeadChange = { - repositoryPath: NuclideUri, - activeShortHead: string, -}; - -export type ActiveShortHeadChangeBehaviorValue = - | 'Always Ignore' - | 'Always Restore' - | 'Prompt to Restore'; - -export type ActionTypeValue = - | 'add-project-repository' - | 'complete-restoring-repository-state' - | 'remove-project-repository' - | 'restore-pane-item-state' - | 'start-restoring-repository-state' - | 'update-pane-item-state' - | 'update-repository-bookmarks'; - -export type AddProjectRepositoryAction = { - payload: { - repository: atom$Repository, - }, - type: 'add-project-repository', -}; - -export type UpdatePaneItemStateAction = { - payload: { - repositoryPathToEditors: Map>, - }, - type: 'update-pane-item-state', -}; - -export type RemoveProjectRepositoryAction = { - payload: { - repository: atom$Repository, - }, - type: 'remove-project-repository', -}; - -export type StartRestoringRepositoryStateAction = { - payload: { - repository: atom$Repository, - }, - type: 'start-restoring-repository-state', -}; - -export type CompleteRestoringRepositoryStateAction = { - payload: { - repository: atom$Repository, - }, - type: 'complete-restoring-repository-state', -}; - -export type RestorePaneItemStateAction = { - payload: { - repository: atom$Repository, - shortHead: string, - }, - type: 'restore-pane-item-state', -}; - -export type UpdateRepositoryBookmarksAction = { - payload: { - activeShortHead: string, - bookmarkNames: Set, - repository: atom$Repository, - }, - type: 'update-repository-bookmarks', -}; - -// Flow Issue: sorting alphabetically has a flow union issue. -export type Action = - | UpdatePaneItemStateAction - | RestorePaneItemStateAction - | UpdateRepositoryBookmarksAction - | StartRestoringRepositoryStateAction - | CompleteRestoringRepositoryStateAction - | AddProjectRepositoryAction - | RemoveProjectRepositoryAction; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-bookshelf/lib/utils.js b/pkg/nuclide-bookshelf/lib/utils.js index c38d082391..7fea4298f3 100644 --- a/pkg/nuclide-bookshelf/lib/utils.js +++ b/pkg/nuclide-bookshelf/lib/utils.js @@ -1,3 +1,57 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getEmptBookShelfState = getEmptBookShelfState; +exports.serializeBookShelfState = serializeBookShelfState; +exports.deserializeBookShelfState = deserializeBookShelfState; +exports.getRepoPathToEditors = getRepoPathToEditors; +exports.shortHeadChangedNotification = shortHeadChangedNotification; +exports.getShortHeadChangesFromStateStream = getShortHeadChangesFromStateStream; + +var _constants; + +function _load_constants() { + return _constants = require('./constants'); +} + +var _immutable; + +function _load_immutable() { + return _immutable = _interopRequireWildcard(require('immutable')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _nuclideVcsBase; + +function _load_nuclideVcsBase() { + return _nuclideVcsBase = require('../../nuclide-vcs-base'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-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; } } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,162 +59,90 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type { - BookShelfState, - RepositoryShortHeadChange, - SerializedBookShelfState, -} from './types'; - -import { - ActiveShortHeadChangeBehavior, - ACTIVE_SHORTHEAD_CHANGE_BEHAVIOR_CONFIG, -} from './constants'; - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import * as Immutable from 'immutable'; -import invariant from 'assert'; -import {Observable} from 'rxjs'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {repositoryForPath} from '../../nuclide-vcs-base'; -import {track} from '../../nuclide-analytics'; - -export function getEmptBookShelfState(): BookShelfState { +function getEmptBookShelfState() { return { - repositoryPathToState: Immutable.Map(), + repositoryPathToState: (_immutable || _load_immutable()).Map() }; } // Maps are serialized as key/value pairs array to match Map `enries` format. -export function serializeBookShelfState( - bookShelfState: BookShelfState, -): SerializedBookShelfState { - const {repositoryPathToState} = bookShelfState; - const serializedRepositoryPathToState = Array.from( - repositoryPathToState.entries(), - ).map(([repositoryPath, repositoryState]) => { +function serializeBookShelfState(bookShelfState) { + const { repositoryPathToState } = bookShelfState; + const serializedRepositoryPathToState = Array.from(repositoryPathToState.entries()).map(([repositoryPath, repositoryState]) => { const serializedShortHeadToFileList = { activeShortHead: repositoryState.activeShortHead, - shortHeadsToFileList: Array.from( - repositoryState.shortHeadsToFileList.entries(), - ), + shortHeadsToFileList: Array.from(repositoryState.shortHeadsToFileList.entries()) }; return [repositoryPath, serializedShortHeadToFileList]; }); return { - repositoryPathToState: serializedRepositoryPathToState, + repositoryPathToState: serializedRepositoryPathToState }; } -export function deserializeBookShelfState( - serializedBookShelfState: ?SerializedBookShelfState, -): BookShelfState { - if ( - serializedBookShelfState == null || - serializedBookShelfState.repositoryPathToState == null - ) { +function deserializeBookShelfState(serializedBookShelfState) { + if (serializedBookShelfState == null || serializedBookShelfState.repositoryPathToState == null) { return getEmptBookShelfState(); } - const repositoryPathToState = Immutable.Map( - serializedBookShelfState.repositoryPathToState.map( - ([repositoryPath, repositoryState]) => { - return [ - repositoryPath, - { - activeShortHead: repositoryState.activeShortHead, - isRestoring: false, - shortHeadsToFileList: Immutable.Map( - repositoryState.shortHeadsToFileList, - ), - }, - ]; - }, - ), - ); + const repositoryPathToState = (_immutable || _load_immutable()).Map(serializedBookShelfState.repositoryPathToState.map(([repositoryPath, repositoryState]) => { + return [repositoryPath, { + activeShortHead: repositoryState.activeShortHead, + isRestoring: false, + shortHeadsToFileList: (_immutable || _load_immutable()).Map(repositoryState.shortHeadsToFileList) + }]; + })); return { - repositoryPathToState, + repositoryPathToState }; } -export function getRepoPathToEditors(): Map< - NuclideUri, - Array, -> { +function getRepoPathToEditors() { const reposToEditors = new Map(); - atom.workspace - .getTextEditors() - .filter( - textEditor => textEditor.getPath() != null && textEditor.getPath() !== '', - ) - .map(textEditor => ({ - textEditor, - repository: repositoryForPath(textEditor.getPath() || ''), - })) - .filter(({repository}) => repository != null) - .forEach(({repository, textEditor}) => { - invariant(repository); - const repositoryPath = repository.getWorkingDirectory(); - reposToEditors.set( - repositoryPath, - (reposToEditors.get(repositoryPath) || []).concat([textEditor]), - ); - }); + atom.workspace.getTextEditors().filter(textEditor => textEditor.getPath() != null && textEditor.getPath() !== '').map(textEditor => ({ + textEditor, + repository: (0, (_nuclideVcsBase || _load_nuclideVcsBase()).repositoryForPath)(textEditor.getPath() || '') + })).filter(({ repository }) => repository != null).forEach(({ repository, textEditor }) => { + if (!repository) { + throw new Error('Invariant violation: "repository"'); + } + + const repositoryPath = repository.getWorkingDirectory(); + reposToEditors.set(repositoryPath, (reposToEditors.get(repositoryPath) || []).concat([textEditor])); + }); return reposToEditors; } -export function shortHeadChangedNotification( - repository: atom$Repository, - newShortHead: string, - restorePaneItemState: ( - repository: atom$Repository, - newShortHead: string, - ) => mixed, -): Observable { - return Observable.create(observer => { - const workingDirectoryName = nuclideUri.basename( - repository.getWorkingDirectory(), - ); +function shortHeadChangedNotification(repository, newShortHead, restorePaneItemState) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { + const workingDirectoryName = (_nuclideUri || _load_nuclideUri()).default.basename(repository.getWorkingDirectory()); // TODO(most): Should we handle empty bookmark switches differently? - const newShortHeadDisplayText = - newShortHead.length > 0 ? `to \`${newShortHead}\`` : ''; - - const shortHeadChangeNotification = atom.notifications.addInfo( - `\`${workingDirectoryName}\`'s active bookmark has changed ${newShortHeadDisplayText}`, - { - detail: - 'Would you like to open the files you had active then?\n \n' + - "ProTip: Change the default behavior from 'Nuclide Settings>Nuclide-bookshelf'", - dismissable: true, - buttons: [ - { - onDidClick: () => { - restorePaneItemState(repository, newShortHead); - observer.complete(); - }, - text: 'Open files', - }, - { - onDidClick: () => { - featureConfig.set( - ACTIVE_SHORTHEAD_CHANGE_BEHAVIOR_CONFIG, - ActiveShortHeadChangeBehavior.ALWAYS_IGNORE, - ); - observer.complete(); - }, - text: 'Always ignore', - }, - ], - }, - ); + const newShortHeadDisplayText = newShortHead.length > 0 ? `to \`${newShortHead}\`` : ''; + + const shortHeadChangeNotification = atom.notifications.addInfo(`\`${workingDirectoryName}\`'s active bookmark has changed ${newShortHeadDisplayText}`, { + detail: 'Would you like to open the files you had active then?\n \n' + "ProTip: Change the default behavior from 'Nuclide Settings>Nuclide-bookshelf'", + dismissable: true, + buttons: [{ + onDidClick: () => { + restorePaneItemState(repository, newShortHead); + observer.complete(); + }, + text: 'Open files' + }, { + onDidClick: () => { + (_featureConfig || _load_featureConfig()).default.set((_constants || _load_constants()).ACTIVE_SHORTHEAD_CHANGE_BEHAVIOR_CONFIG, (_constants || _load_constants()).ActiveShortHeadChangeBehavior.ALWAYS_IGNORE); + observer.complete(); + }, + text: 'Always ignore' + }] + }); const dismissSubscription = shortHeadChangeNotification.onDidDismiss(() => { - track('bookshelf-dismiss-restore-prompt'); + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('bookshelf-dismiss-restore-prompt'); observer.complete(); }); @@ -171,40 +153,21 @@ export function shortHeadChangedNotification( }); } -export function getShortHeadChangesFromStateStream( - states: Observable, -): Observable { - return states - .pairwise() - .flatMap( - ([oldBookShelfState, newBookShelfState]: [ - BookShelfState, - BookShelfState, - ]) => { - const { - repositoryPathToState: oldRepositoryPathToState, - } = oldBookShelfState; - - return Observable.from( - Array.from(newBookShelfState.repositoryPathToState.entries()) - .filter(([repositoryPath, newRepositoryState]) => { - const oldRepositoryState = oldRepositoryPathToState.get( - repositoryPath, - ); - return ( - oldRepositoryState != null && - oldRepositoryState.activeShortHead !== - newRepositoryState.activeShortHead - ); - }) - .map(([repositoryPath, newRepositoryState]) => { - const {activeShortHead} = newRepositoryState; - return { - repositoryPath, - activeShortHead, - }; - }), - ); - }, - ); -} +function getShortHeadChangesFromStateStream(states) { + return states.pairwise().flatMap(([oldBookShelfState, newBookShelfState]) => { + const { + repositoryPathToState: oldRepositoryPathToState + } = oldBookShelfState; + + return _rxjsBundlesRxMinJs.Observable.from(Array.from(newBookShelfState.repositoryPathToState.entries()).filter(([repositoryPath, newRepositoryState]) => { + const oldRepositoryState = oldRepositoryPathToState.get(repositoryPath); + return oldRepositoryState != null && oldRepositoryState.activeShortHead !== newRepositoryState.activeShortHead; + }).map(([repositoryPath, newRepositoryState]) => { + const { activeShortHead } = newRepositoryState; + return { + repositoryPath, + activeShortHead + }; + })); + }); +} \ No newline at end of file diff --git a/pkg/nuclide-buck-base/lib/main.js b/pkg/nuclide-buck-base/lib/main.js index c9ddea89b9..a668a20794 100644 --- a/pkg/nuclide-buck-base/lib/main.js +++ b/pkg/nuclide-buck-base/lib/main.js @@ -1,36 +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 strict-local - * @format - */ +'use strict'; -import typeof * as BuckService from '../../nuclide-buck-rpc'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.isBuckFile = isBuckFile; +exports.getBuckService = getBuckService; +exports.getBuckProjectRoot = getBuckProjectRoot; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {getServiceByNuclideUri} from '../../nuclide-remote-connection'; +var _nuclideUri; -const buckProjectDirectoryByPath: Map = new Map(); +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} -export function isBuckFile(filePath: string): boolean { +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const buckProjectDirectoryByPath = new Map(); /** + * 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. + * + * strict-local + * @format + */ + +function isBuckFile(filePath) { // TODO(mbolin): Buck does have an option where the user can customize the // name of the build file: https://github.com/facebook/buck/issues/238. // This function will not work for those who use that option. - return nuclideUri.basename(filePath) === 'BUCK'; + return (_nuclideUri || _load_nuclideUri()).default.basename(filePath) === 'BUCK'; } -export function getBuckService(filePath: string): ?BuckService { - return getServiceByNuclideUri('BuckService', filePath); +function getBuckService(filePath) { + return (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getServiceByNuclideUri)('BuckService', filePath); } /** * Cached, service-aware version of BuckProject.getRootForPath. */ -export async function getBuckProjectRoot(filePath: string): Promise { +async function getBuckProjectRoot(filePath) { let directory = buckProjectDirectoryByPath.get(filePath); // flowlint-next-line sketchy-null-string:off if (!directory) { @@ -46,4 +62,4 @@ export async function getBuckProjectRoot(filePath: string): Promise { } } return directory; -} +} \ No newline at end of file diff --git a/pkg/nuclide-buck-ios/lib/Platforms.js b/pkg/nuclide-buck-ios/lib/Platforms.js index 4968a28d23..8134e4ea85 100644 --- a/pkg/nuclide-buck-ios/lib/Platforms.js +++ b/pkg/nuclide-buck-ios/lib/Platforms.js @@ -1,3 +1,27 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getSimulatorPlatform = getSimulatorPlatform; +exports.getDevicePlatform = getDevicePlatform; + +var _Tasks; + +function _load_Tasks() { + return _Tasks = require('./Tasks'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideFbsimctl; + +function _load_nuclideFbsimctl() { + return _nuclideFbsimctl = _interopRequireWildcard(require('../../nuclide-fbsimctl')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,29 +29,12 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {Platform} from '../../nuclide-buck/lib/types'; -import type {LegacyProcessMessage} from 'nuclide-commons/process'; -import type {BuckEvent} from '../../nuclide-buck/lib/BuckEventStream'; -import type {Device} from '../../nuclide-fbsimctl-rpc/lib/types'; - -import {getTasks, runTask} from './Tasks'; - -import {Observable} from 'rxjs'; -import * as fbsimctl from '../../nuclide-fbsimctl'; - -export function getSimulatorPlatform( - buckRoot: NuclideUri, - ruleType: string, - debuggerCallback: ?( - Observable, - ) => Observable, -): Observable { - return fbsimctl.getDevices().map(devices => { +function getSimulatorPlatform(buckRoot, ruleType, debuggerCallback) { + return (_nuclideFbsimctl || _load_nuclideFbsimctl()).getDevices().map(devices => { let simulators; if (devices instanceof Error) { // TODO: Come up with a way to surface the error in UI @@ -39,67 +46,44 @@ export function getSimulatorPlatform( if (simulators.length === 0) { deviceGroups = BUILD_ONLY_SIMULATOR_GROUPS; } else { - deviceGroups = Array.from(groupByOs(simulators).entries()).map( - ([os, simsForOs]) => ({ - name: os, - devices: simsForOs.map(simulator => ({ - name: simulator.name, - udid: simulator.udid, - arch: simulator.arch, - type: 'simulator', - })), - }), - ); + deviceGroups = Array.from(groupByOs(simulators).entries()).map(([os, simsForOs]) => ({ + name: os, + devices: simsForOs.map(simulator => ({ + name: simulator.name, + udid: simulator.udid, + arch: simulator.arch, + type: 'simulator' + })) + })); } return { isMobile: true, name: 'Simulator', - tasksForDevice: device => - getTasks(buckRoot, ruleType, device, debuggerCallback != null), - runTask: (builder, taskType, target, settings, device) => - runTask( - builder, - taskType, - ruleType, - target, - settings, - device, - buckRoot, - debuggerCallback, - ), - deviceGroups, + tasksForDevice: device => (0, (_Tasks || _load_Tasks()).getTasks)(buckRoot, ruleType, device, debuggerCallback != null), + runTask: (builder, taskType, target, settings, device) => (0, (_Tasks || _load_Tasks()).runTask)(builder, taskType, ruleType, target, settings, device, buckRoot, debuggerCallback), + deviceGroups }; }); } -export function getDevicePlatform( - buckRoot: NuclideUri, - ruleType: string, - debuggerCallback: ?( - Observable, - ) => Observable, -): Observable { - return fbsimctl.getDevices().map(devices => { +function getDevicePlatform(buckRoot, ruleType, debuggerCallback) { + return (_nuclideFbsimctl || _load_nuclideFbsimctl()).getDevices().map(devices => { let deviceGroups = []; if (devices instanceof Array) { - const physicalDevices = devices.filter( - device => device.type === 'physical_device', - ); + const physicalDevices = devices.filter(device => device.type === 'physical_device'); if (physicalDevices.length > 0) { - deviceGroups = Array.from(groupByOs(physicalDevices).entries()).map( - ([os, devicesForOs]) => ({ - name: os, - devices: devicesForOs.map(device => ({ - name: device.name, - udid: device.udid, - arch: device.arch, - type: 'device', - })), - }), - ); + deviceGroups = Array.from(groupByOs(physicalDevices).entries()).map(([os, devicesForOs]) => ({ + name: os, + devices: devicesForOs.map(device => ({ + name: device.name, + udid: device.udid, + arch: device.arch, + type: 'device' + })) + })); } } @@ -108,25 +92,14 @@ export function getDevicePlatform( return { isMobile: true, name: 'Device', - tasksForDevice: device => - getTasks(buckRoot, ruleType, device, debuggerCallback != null), - runTask: (builder, taskType, target, settings, device) => - runTask( - builder, - taskType, - ruleType, - target, - settings, - device, - buckRoot, - debuggerCallback, - ), - deviceGroups, + tasksForDevice: device => (0, (_Tasks || _load_Tasks()).getTasks)(buckRoot, ruleType, device, debuggerCallback != null), + runTask: (builder, taskType, target, settings, device) => (0, (_Tasks || _load_Tasks()).runTask)(builder, taskType, ruleType, target, settings, device, buckRoot, debuggerCallback), + deviceGroups }; }); } -function groupByOs(devices: Array): Map> { +function groupByOs(devices) { const devicesByOs = devices.reduce((memo, device) => { let devicesForOs = memo.get(device.os); if (devicesForOs == null) { @@ -146,44 +119,36 @@ function groupByOs(devices: Array): Map> { return devicesByOs; } -const BUILD_ONLY_SIMULATOR_GROUPS = [ - { - name: 'Generic', - devices: [ - { - name: '64-bit', - udid: '', - arch: 'x86_64', - type: 'simulator', - buildOnly: true, - }, - { - name: '32-bit', - udid: '', - arch: 'i386', - type: 'simulator', - buildOnly: true, - }, - ], - }, -]; +const BUILD_ONLY_SIMULATOR_GROUPS = [{ + name: 'Generic', + devices: [{ + name: '64-bit', + udid: '', + arch: 'x86_64', + type: 'simulator', + buildOnly: true + }, { + name: '32-bit', + udid: '', + arch: 'i386', + type: 'simulator', + buildOnly: true + }] +}]; const BUILD_ONLY_DEVICES_GROUP = { name: 'Generic', - devices: [ - { - name: '64-bit', - udid: '', - arch: 'arm64', - type: 'device', - buildOnly: true, - }, - { - name: '32-bit', - udid: '', - arch: 'armv7', - type: 'device', - buildOnly: true, - }, - ], -}; + devices: [{ + name: '64-bit', + udid: '', + arch: 'arm64', + type: 'device', + buildOnly: true + }, { + name: '32-bit', + udid: '', + arch: 'armv7', + type: 'device', + buildOnly: true + }] +}; \ No newline at end of file diff --git a/pkg/nuclide-buck-ios/lib/Tasks.js b/pkg/nuclide-buck-ios/lib/Tasks.js index eacf113cc1..3b1e02ed3e 100644 --- a/pkg/nuclide-buck-ios/lib/Tasks.js +++ b/pkg/nuclide-buck-ios/lib/Tasks.js @@ -1,3 +1,34 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getTasks = getTasks; +exports.runTask = runTask; + +var _BuckTaskRunner; + +function _load_BuckTaskRunner() { + return _BuckTaskRunner = require('../../nuclide-buck/lib/BuckTaskRunner'); +} + +var _types; + +function _load_types() { + return _types = require('./types'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// eslint-disable-next-line nuclide-internal/no-cross-atom-imports /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,46 +36,19 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {BuckBuildSystem} from '../../nuclide-buck/lib/BuckBuildSystem'; -import type { - Device, - TaskSettings, - TaskType, -} from '../../nuclide-buck/lib/types'; -import type {TaskEvent} from 'nuclide-commons/process'; -import type {ResolvedBuildTarget} from '../../nuclide-buck-rpc/lib/types'; -import type {LegacyProcessMessage} from 'nuclide-commons/process'; -import type {BuckEvent} from '../../nuclide-buck/lib/BuckEventStream'; -import type {IosDeployable} from './types'; - -// eslint-disable-next-line nuclide-internal/no-cross-atom-imports -import { - isDebugTask, - getBuckSubcommandForTaskType, -} from '../../nuclide-buck/lib/BuckTaskRunner'; -import {RUNNABLE_RULE_TYPES} from './types'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Observable} from 'rxjs'; - -export function getTasks( - buckRoot: NuclideUri, - ruleType: string, - device: ?Device, - debuggerAvailable: boolean, -): Set { +function getTasks(buckRoot, ruleType, device, debuggerAvailable) { // $FlowIgnore typecast - const iosDeployable: IosDeployable = device; + const iosDeployable = device; const tasks = new Set(['build']); if (iosDeployable.buildOnly !== true) { - if (RUNNABLE_RULE_TYPES.has(ruleType)) { + if ((_types || _load_types()).RUNNABLE_RULE_TYPES.has(ruleType)) { tasks.add('run'); } - if (!nuclideUri.isRemote(buckRoot)) { + if (!(_nuclideUri || _load_nuclideUri()).default.isRemote(buckRoot)) { tasks.add('test'); if (debuggerAvailable) { tasks.add('debug'); @@ -54,50 +58,27 @@ export function getTasks( return tasks; } -export function runTask( - builder: BuckBuildSystem, - taskType: TaskType, - ruleType: string, - buildTarget: ResolvedBuildTarget, - settings: TaskSettings, - device: ?Device, - buckRoot: NuclideUri, - debuggerCallback: ?( - processStream: Observable, - ) => Observable, -): Observable { +function runTask(builder, taskType, ruleType, buildTarget, settings, device, buckRoot, debuggerCallback) { // $FlowIgnore typecast - const iosDeployable: IosDeployable = device; - const {arch, udid, type} = iosDeployable; + const iosDeployable = device; + const { arch, udid, type } = iosDeployable; const iosPlatform = type === 'simulator' ? 'iphonesimulator' : 'iphoneos'; const flavor = `${iosPlatform}-${arch}`; - const newTarget = { - ...buildTarget, - flavors: buildTarget.flavors.concat([flavor]), - }; + const newTarget = Object.assign({}, buildTarget, { + flavors: buildTarget.flavors.concat([flavor]) + }); - if (nuclideUri.isRemote(buckRoot)) { + if ((_nuclideUri || _load_nuclideUri()).default.isRemote(buckRoot)) { let runRemoteTask; try { // $FlowFB const remoteWorkflow = require('./fb-RemoteWorkflow'); runRemoteTask = () => { - return remoteWorkflow.runRemoteTask( - buckRoot, - builder, - taskType, - ruleType, - buildTarget, - settings, - iosDeployable, - flavor, - ); + return remoteWorkflow.runRemoteTask(buckRoot, builder, taskType, ruleType, buildTarget, settings, iosDeployable, flavor); }; } catch (_) { runRemoteTask = () => { - throw new Error( - 'Remote workflow currently unsupported for this target.', - ); + throw new Error('Remote workflow currently unsupported for this target.'); }; } @@ -110,20 +91,12 @@ export function runTask( const debug = taskType === 'debug'; - return builder.runSubcommand( - buckRoot, - subcommand, - newTarget, - settings, - debug, - udid, - debug ? debuggerCallback : null, - ); + return builder.runSubcommand(buckRoot, subcommand, newTarget, settings, debug, udid, debug ? debuggerCallback : null); } } -function _getLocalSubcommand(taskType: TaskType, ruleType: string) { - if (taskType === 'run' || isDebugTask(taskType)) { +function _getLocalSubcommand(taskType, ruleType) { + if (taskType === 'run' || (0, (_BuckTaskRunner || _load_BuckTaskRunner()).isDebugTask)(taskType)) { switch (ruleType) { case 'apple_bundle': return 'install'; @@ -134,17 +107,14 @@ function _getLocalSubcommand(taskType: TaskType, ruleType: string) { } } - return getBuckSubcommandForTaskType(taskType); + return (0, (_BuckTaskRunner || _load_BuckTaskRunner()).getBuckSubcommandForTaskType)(taskType); } -function startLogger(iosDeployable: IosDeployable): Observable { - return Observable.create(observer => { +function startLogger(iosDeployable) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { if (iosDeployable.type === 'simulator') { - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'nuclide-ios-simulator-logs:start', - ); + atom.commands.dispatch(atom.views.getView(atom.workspace), 'nuclide-ios-simulator-logs:start'); } observer.complete(); }); -} +} \ No newline at end of file diff --git a/pkg/nuclide-buck-ios/lib/main.js b/pkg/nuclide-buck-ios/lib/main.js index 730378a269..e014d2874c 100644 --- a/pkg/nuclide-buck-ios/lib/main.js +++ b/pkg/nuclide-buck-ios/lib/main.js @@ -1,90 +1,99 @@ -/** - * 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 strict-local - * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {PlatformGroup} from '../../nuclide-buck/lib/types'; -import type {PlatformService} from '../../nuclide-buck/lib/PlatformService'; -import type {LegacyProcessMessage} from 'nuclide-commons/process'; -import type {BuckEvent} from '../../nuclide-buck/lib/BuckEventStream'; - -import {SUPPORTED_RULE_TYPES} from './types'; -import {getDevicePlatform, getSimulatorPlatform} from './Platforms'; -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Observable} from 'rxjs'; -import consumeFirstProvider from 'nuclide-commons-atom/consumeFirstProvider'; - -let disposable: ?IDisposable = null; - -export function deactivate(): void { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.deactivate = deactivate; +exports.consumePlatformService = consumePlatformService; + +var _types; + +function _load_types() { + return _types = require('./types'); +} + +var _Platforms; + +function _load_Platforms() { + return _Platforms = require('./Platforms'); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _consumeFirstProvider; + +function _load_consumeFirstProvider() { + return _consumeFirstProvider = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/consumeFirstProvider')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +let disposable = null; /** + * 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. + * + * strict-local + * @format + */ + +function deactivate() { if (disposable != null) { disposable.dispose(); disposable = null; } } -export function consumePlatformService(service: PlatformService): void { +function consumePlatformService(service) { disposable = service.register(provideIosPlatformGroup); } -function provideIosPlatformGroup( - buckRoot: NuclideUri, - ruleType: string, - buildTarget: string, -): Observable { - if (!SUPPORTED_RULE_TYPES.has(ruleType)) { - return Observable.of(null); +function provideIosPlatformGroup(buckRoot, ruleType, buildTarget) { + if (!(_types || _load_types()).SUPPORTED_RULE_TYPES.has(ruleType)) { + return _rxjsBundlesRxMinJs.Observable.of(null); } if (ruleType === 'apple_binary' && buildTarget.endsWith('AppleMac')) { - return Observable.of(null); + return _rxjsBundlesRxMinJs.Observable.of(null); } - return Observable.fromPromise( - fsPromise.exists(nuclideUri.join(buckRoot, 'mode', 'oculus-mobile')), - ).switchMap(result => { + return _rxjsBundlesRxMinJs.Observable.fromPromise((_fsPromise || _load_fsPromise()).default.exists((_nuclideUri || _load_nuclideUri()).default.join(buckRoot, 'mode', 'oculus-mobile'))).switchMap(result => { if (result) { - return Observable.of(null); + return _rxjsBundlesRxMinJs.Observable.of(null); } else { - return Observable.fromPromise(_getDebuggerCallback(buckRoot)).switchMap( - debuggerCallback => { - return Observable.combineLatest( - getSimulatorPlatform(buckRoot, ruleType, debuggerCallback), - getDevicePlatform(buckRoot, ruleType, debuggerCallback), - ).map(([simulatorPlatform, devicePlatform]) => { - return { - name: 'iOS', - platforms: [simulatorPlatform, devicePlatform], - }; - }); - }, - ); + return _rxjsBundlesRxMinJs.Observable.fromPromise(_getDebuggerCallback(buckRoot)).switchMap(debuggerCallback => { + return _rxjsBundlesRxMinJs.Observable.combineLatest((0, (_Platforms || _load_Platforms()).getSimulatorPlatform)(buckRoot, ruleType, debuggerCallback), (0, (_Platforms || _load_Platforms()).getDevicePlatform)(buckRoot, ruleType, debuggerCallback)).map(([simulatorPlatform, devicePlatform]) => { + return { + name: 'iOS', + platforms: [simulatorPlatform, devicePlatform] + }; + }); + }); } }); } -async function _getDebuggerCallback( - buckRoot: NuclideUri, -): Promise) => Observable> { - const nativeDebuggerService = await consumeFirstProvider( - 'debugger.native-debugger-service', - ); +async function _getDebuggerCallback(buckRoot) { + const nativeDebuggerService = await (0, (_consumeFirstProvider || _load_consumeFirstProvider()).default)('debugger.native-debugger-service'); if (nativeDebuggerService == null) { return null; } - return (processStream: Observable) => { - return nativeDebuggerService.debugTargetFromBuckOutput( - buckRoot, - processStream, - ); + return processStream => { + return nativeDebuggerService.debugTargetFromBuckOutput(buckRoot, processStream); }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-buck-ios/lib/types.js b/pkg/nuclide-buck-ios/lib/types.js index a7679f8222..19fbf6afa9 100644 --- a/pkg/nuclide-buck-ios/lib/types.js +++ b/pkg/nuclide-buck-ios/lib/types.js @@ -1,25 +1,17 @@ -/** - * 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 strict - * @format - */ +'use strict'; -export type IosDeployable = { - name: string, - udid: string, - arch: string, - type: 'simulator' | 'device', - buildOnly?: boolean, -}; +Object.defineProperty(exports, "__esModule", { + value: true +}); +const RUNNABLE_RULE_TYPES = exports.RUNNABLE_RULE_TYPES = new Set(['apple_bundle']); /** + * 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. + * + * strict + * @format + */ -export const RUNNABLE_RULE_TYPES: Set = new Set(['apple_bundle']); -export const SUPPORTED_RULE_TYPES: Set = new Set([ - ...RUNNABLE_RULE_TYPES, - 'apple_library', - 'apple_test', -]); +const SUPPORTED_RULE_TYPES = exports.SUPPORTED_RULE_TYPES = new Set([...RUNNABLE_RULE_TYPES, 'apple_library', 'apple_test']); \ No newline at end of file diff --git a/pkg/nuclide-buck-rpc/lib/BuckClangCompilationDatabase.js b/pkg/nuclide-buck-rpc/lib/BuckClangCompilationDatabase.js index 69f245105b..6bae287962 100644 --- a/pkg/nuclide-buck-rpc/lib/BuckClangCompilationDatabase.js +++ b/pkg/nuclide-buck-rpc/lib/BuckClangCompilationDatabase.js @@ -1,3 +1,50 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getCompilationDatabaseHandler = getCompilationDatabaseHandler; + +var _SimpleCache; + +function _load_SimpleCache() { + return _SimpleCache = require('../../../modules/nuclide-commons/SimpleCache'); +} + +var _nuclideClangRpc; + +function _load_nuclideClangRpc() { + return _nuclideClangRpc = _interopRequireWildcard(require('../../nuclide-clang-rpc')); +} + +var _BuckServiceImpl; + +function _load_BuckServiceImpl() { + return _BuckServiceImpl = _interopRequireWildcard(require('./BuckServiceImpl')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _utils; + +function _load_utils() { + return _utils = require('../../nuclide-clang-rpc/lib/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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,30 +52,13 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {CompilationDatabaseParams} from '../../nuclide-buck/lib/types'; -import type {BuckClangCompilationDatabase} from './types'; - -import {SimpleCache} from 'nuclide-commons/SimpleCache'; -import * as ClangService from '../../nuclide-clang-rpc'; -import * as BuckService from './BuckServiceImpl'; -import {getLogger} from 'log4js'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {guessBuildFile, isHeaderFile} from '../../nuclide-clang-rpc/lib/utils'; - -const logger = getLogger('nuclide-buck'); +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-buck'); const BUCK_TIMEOUT = 10 * 60 * 1000; -const TARGET_KIND_REGEX = [ - 'apple_binary', - 'apple_library', - 'apple_test', - 'cxx_binary', - 'cxx_library', - 'cxx_test', -].join('|'); +const TARGET_KIND_REGEX = ['apple_binary', 'apple_library', 'apple_test', 'cxx_binary', 'cxx_library', 'cxx_test'].join('|'); /** * Facebook puts all headers in a :__default_headers__ build target by default. @@ -37,17 +67,16 @@ const TARGET_KIND_REGEX = [ const DEFAULT_HEADERS_TARGET = '__default_headers__'; class BuckClangCompilationDatabaseHandler { - _targetCache = new SimpleCache(); - _sourceCache = new SimpleCache(); // Ensure that we can clear targetCache for a given file. - _sourceToTargetKey = new Map(); - _params: CompilationDatabaseParams; + constructor(params) { + this._targetCache = new (_SimpleCache || _load_SimpleCache()).SimpleCache(); + this._sourceCache = new (_SimpleCache || _load_SimpleCache()).SimpleCache(); + this._sourceToTargetKey = new Map(); - constructor(params: CompilationDatabaseParams) { this._params = params; } - resetForSource(src: string): void { + resetForSource(src) { this._sourceCache.delete(src); const targetKey = this._sourceToTargetKey.get(src); if (targetKey != null) { @@ -56,32 +85,26 @@ class BuckClangCompilationDatabaseHandler { } } - reset(): void { + reset() { this._sourceCache.clear(); this._targetCache.clear(); this._sourceToTargetKey.clear(); } - getCompilationDatabase(file: string): Promise { + getCompilationDatabase(file) { return this._sourceCache.getOrCreate(file, async () => { - if (isHeaderFile(file)) { - const source = await ClangService.getRelatedSourceOrHeader(file); + if ((0, (_utils || _load_utils()).isHeaderFile)(file)) { + const source = await (_nuclideClangRpc || _load_nuclideClangRpc()).getRelatedSourceOrHeader(file); if (source != null) { - logger.info( - `${file} is a header, thus using ${source} for getting the compilation flags.`, - ); + logger.info(`${file} is a header, thus using ${source} for getting the compilation flags.`); return this.getCompilationDatabase(source); } else { - logger.error( - `Couldn't find a corresponding source file for ${file}, thus there are no compilation flags available.`, - ); + logger.error(`Couldn't find a corresponding source file for ${file}, thus there are no compilation flags available.`); return { file: null, - flagsFile: await guessBuildFile(file), + flagsFile: await (0, (_utils || _load_utils()).guessBuildFile)(file), libclangPath: null, - warnings: [ - `I could not find a corresponding source file for ${file}.`, - ], + warnings: [`I could not find a corresponding source file for ${file}.`] }; } } else { @@ -90,39 +113,27 @@ class BuckClangCompilationDatabaseHandler { }); } - async _getCompilationDatabase( - file: string, - ): Promise { - const buckRoot = await BuckService.getRootForPath(file); - return this._loadCompilationDatabaseFromBuck(file, buckRoot) - .catch(err => { - logger.error('Error getting flags from Buck for file ', file, err); - throw err; - }) - .then(db => { - if (db != null) { - this._cacheFilesToCompilationDB(db); - } - return db; - }); + async _getCompilationDatabase(file) { + const buckRoot = await (_BuckServiceImpl || _load_BuckServiceImpl()).getRootForPath(file); + return this._loadCompilationDatabaseFromBuck(file, buckRoot).catch(err => { + logger.error('Error getting flags from Buck for file ', file, err); + throw err; + }).then(db => { + if (db != null) { + this._cacheFilesToCompilationDB(db); + } + return db; + }); } - async _loadCompilationDatabaseFromBuck( - src: string, - buckRoot: ?string, - ): Promise { + async _loadCompilationDatabaseFromBuck(src, buckRoot) { if (buckRoot == null) { return null; } let queryTarget = null; try { - const owners = (await BuckService.getOwners( - buckRoot, - src, - [], - TARGET_KIND_REGEX, - )).filter(x => x.indexOf(DEFAULT_HEADERS_TARGET) === -1); + const owners = (await (_BuckServiceImpl || _load_BuckServiceImpl()).getOwners(buckRoot, src, [], TARGET_KIND_REGEX)).filter(x => x.indexOf(DEFAULT_HEADERS_TARGET) === -1); // Deprioritize Android-related targets because they build with gcc and // require gcc intrinsics that cause libclang to throw bad diagnostics. owners.sort((a, b) => { @@ -143,72 +154,40 @@ class BuckClangCompilationDatabaseHandler { if (queryTarget == null) { // Even if we can't get flags, return a flagsFile to watch - const buildFile = await guessBuildFile(src); + const buildFile = await (0, (_utils || _load_utils()).guessBuildFile)(src); if (buildFile != null) { return { flagsFile: buildFile, file: null, libclangPath: null, - warnings: [ - `I could not find owner target of ${src}`, - `Is there an error in ${buildFile}?`, - ], + warnings: [`I could not find owner target of ${src}`, `Is there an error in ${buildFile}?`] }; } return null; } const target = queryTarget; - this._sourceToTargetKey.set( - src, - this._targetCache.keyForArgs([buckRoot, target]), - ); + this._sourceToTargetKey.set(src, this._targetCache.keyForArgs([buckRoot, target])); - return this._targetCache.getOrCreate([buckRoot, target], () => - this._loadCompilationDatabaseForBuckTarget(buckRoot, target), - ); + return this._targetCache.getOrCreate([buckRoot, target], () => this._loadCompilationDatabaseForBuckTarget(buckRoot, target)); } - async _loadCompilationDatabaseForBuckTarget( - buckProjectRoot: string, - target: string, - ): Promise { - const allFlavors = [ - 'compilation-database', - ...this._params.flavorsForTarget, - ]; + async _loadCompilationDatabaseForBuckTarget(buckProjectRoot, target) { + const allFlavors = ['compilation-database', ...this._params.flavorsForTarget]; if (this._params.useDefaultPlatform) { - const platform = await BuckService.getDefaultPlatform( - buckProjectRoot, - target, - ); + const platform = await (_BuckServiceImpl || _load_BuckServiceImpl()).getDefaultPlatform(buckProjectRoot, target); if (platform != null) { allFlavors.push(platform); } } - const allArgs = - this._params.args.length === 0 - ? await BuckService._getFbRepoSpecificArgs(buckProjectRoot) - : this._params.args; + const allArgs = this._params.args.length === 0 ? await (_BuckServiceImpl || _load_BuckServiceImpl())._getFbRepoSpecificArgs(buckProjectRoot) : this._params.args; const buildTarget = target + '#' + allFlavors.join(','); - const buildReport = await BuckService.build( - buckProjectRoot, - [ - // Small builds, like those used for a compilation database, can degrade overall - // `buck build` performance by unnecessarily invalidating the Action Graph cache. - // See https://buckbuild.com/concept/buckconfig.html#client.skip-action-graph-cache - // for details on the importance of using skip-action-graph-cache=true. - '--config', - 'client.skip-action-graph-cache=true', - - buildTarget, - ...allArgs, - // TODO(hansonw): Any alternative to doing this? - // '-L', - // String(os.cpus().length / 2), - ], - {commandOptions: {timeout: BUCK_TIMEOUT}}, - ); + const buildReport = await (_BuckServiceImpl || _load_BuckServiceImpl()).build(buckProjectRoot, [ + // Small builds, like those used for a compilation database, can degrade overall + // `buck build` performance by unnecessarily invalidating the Action Graph cache. + // See https://buckbuild.com/concept/buckconfig.html#client.skip-action-graph-cache + // for details on the importance of using skip-action-graph-cache=true. + '--config', 'client.skip-action-graph-cache=true', buildTarget, ...allArgs], { commandOptions: { timeout: BUCK_TIMEOUT } }); if (!buildReport.success) { const error = new Error(`Failed to build ${buildTarget}`); logger.error(error); @@ -216,65 +195,44 @@ class BuckClangCompilationDatabaseHandler { } const firstResult = Object.keys(buildReport.results)[0]; let pathToCompilationDatabase = buildReport.results[firstResult].output; - pathToCompilationDatabase = nuclideUri.join( - buckProjectRoot, - pathToCompilationDatabase, - ); + pathToCompilationDatabase = (_nuclideUri || _load_nuclideUri()).default.join(buckProjectRoot, pathToCompilationDatabase); - const buildFile = await BuckService.getBuildFile(buckProjectRoot, target); + const buildFile = await (_BuckServiceImpl || _load_BuckServiceImpl()).getBuildFile(buckProjectRoot, target); const compilationDB = { file: pathToCompilationDatabase, flagsFile: buildFile, libclangPath: null, - warnings: [], + warnings: [] }; return this._processCompilationDb(compilationDB, buckProjectRoot, allArgs); } - async _processCompilationDb( - db: BuckClangCompilationDatabase, - buckRoot: string, - args: string[], - ): Promise { + async _processCompilationDb(db, buckRoot, args) { try { // $FlowFB - const {createOmCompilationDb} = require('./fb/omCompilationDb'); + const { createOmCompilationDb } = require('./fb/omCompilationDb'); return await createOmCompilationDb(db, buckRoot, args); } catch (e) {} return db; } - async _cacheFilesToCompilationDB( - db: BuckClangCompilationDatabase, - ): Promise { - const {file} = db; + async _cacheFilesToCompilationDB(db) { + const { file } = db; if (file == null) { return; } return new Promise((resolve, reject) => { - ClangService.loadFilesFromCompilationDatabaseAndCacheThem( - file, - db.flagsFile, - ) - .refCount() - .subscribe( - path => this._sourceCache.set(path, Promise.resolve(db)), - reject, // on error - resolve, // on complete - ); + (_nuclideClangRpc || _load_nuclideClangRpc()).loadFilesFromCompilationDatabaseAndCacheThem(file, db.flagsFile).refCount().subscribe(path => this._sourceCache.set(path, Promise.resolve(db)), reject, // on error + resolve // on complete + ); }); } } -const compilationDatabaseHandlerCache = new SimpleCache({ - keyFactory: (params: CompilationDatabaseParams) => JSON.stringify(params), +const compilationDatabaseHandlerCache = new (_SimpleCache || _load_SimpleCache()).SimpleCache({ + keyFactory: params => JSON.stringify(params) }); -export function getCompilationDatabaseHandler( - params: CompilationDatabaseParams, -): BuckClangCompilationDatabaseHandler { - return compilationDatabaseHandlerCache.getOrCreate( - params, - () => new BuckClangCompilationDatabaseHandler(params), - ); -} +function getCompilationDatabaseHandler(params) { + return compilationDatabaseHandlerCache.getOrCreate(params, () => new BuckClangCompilationDatabaseHandler(params)); +} \ No newline at end of file diff --git a/pkg/nuclide-buck-rpc/lib/BuckService.js b/pkg/nuclide-buck-rpc/lib/BuckService.js index d8e7bfa6c6..47b9f1bdc9 100644 --- a/pkg/nuclide-buck-rpc/lib/BuckService.js +++ b/pkg/nuclide-buck-rpc/lib/BuckService.js @@ -1,3 +1,89 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.MULTIPLE_TARGET_RULE_TYPE = undefined; +exports.getRootForPath = getRootForPath; +exports.getBuildFile = getBuildFile; +exports.getOwners = getOwners; +exports.getBuckConfig = getBuckConfig; +exports.build = build; +exports.install = install; +exports.buildWithOutput = buildWithOutput; +exports.testWithOutput = testWithOutput; +exports.installWithOutput = installWithOutput; +exports.runWithOutput = runWithOutput; +exports.listAliases = listAliases; +exports.listFlavors = listFlavors; +exports.showOutput = showOutput; +exports.buildRuleTypeFor = buildRuleTypeFor; +exports.clean = clean; +exports.kill = kill; +exports._buildRuleTypeFor = _buildRuleTypeFor; +exports.getHTTPServerPort = getHTTPServerPort; +exports.query = query; +exports.queryWithArgs = queryWithArgs; +exports.queryWithAttributes = queryWithAttributes; +exports.getWebSocketStream = getWebSocketStream; +exports.resetCompilationDatabaseForSource = resetCompilationDatabaseForSource; +exports.resetCompilationDatabase = resetCompilationDatabase; +exports.getCompilationDatabase = getCompilationDatabase; + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _createBuckWebSocket; + +function _load_createBuckWebSocket() { + return _createBuckWebSocket = _interopRequireDefault(require('./createBuckWebSocket')); +} + +var _ini; + +function _load_ini() { + return _ini = _interopRequireDefault(require('ini')); +} + +var _BuckClangCompilationDatabase; + +function _load_BuckClangCompilationDatabase() { + return _BuckClangCompilationDatabase = require('./BuckClangCompilationDatabase'); +} + +var _BuckServiceImpl; + +function _load_BuckServiceImpl() { + return _BuckServiceImpl = _interopRequireWildcard(require('./BuckServiceImpl')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,134 +91,25 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {LegacyProcessMessage} from 'nuclide-commons/process'; -import type {ConnectableObservable} from 'rxjs'; -import type { - BaseBuckBuildOptions, - ResolvedRuleType, - BuckClangCompilationDatabase, -} from './types'; -import type {CompilationDatabaseParams} from '../../nuclide-buck/lib/types'; - -import {getLogger} from 'log4js'; -import {Observable} from 'rxjs'; -import {observeProcess} from 'nuclide-commons/process'; -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import createBuckWebSocket from './createBuckWebSocket'; -import ini from 'ini'; -import {getCompilationDatabaseHandler} from './BuckClangCompilationDatabase'; -import * as BuckServiceImpl from './BuckServiceImpl'; - -export const MULTIPLE_TARGET_RULE_TYPE = 'multiple_targets'; - -export type BuckWebSocketMessage = - | { - // Not actually from Buck - this is to let the receiver know that the socket is connected. - type: 'SocketConnected', - } - | { - type: 'BuildProgressUpdated', - progressValue: number, - } - | { - type: 'BuildFinished', - exitCode: number, - } - | { - type: 'BuildStarted', - } - | { - type: 'ConsoleEvent', - message: string, - level: { - name: - | 'OFF' - | 'SEVERE' - | 'WARNING' - | 'INFO' - | 'CONFIG' - | 'FINE' - | 'FINER' - | 'FINEST' - | 'ALL', - }, - } - | { - type: 'ParseStarted', - } - | { - type: 'ParseFinished', - } - | { - type: 'InstallFinished', - success: boolean, - pid?: number, - } - | { - type: 'RunStarted', - } - | { - type: 'RunComplete', - } - | { - type: 'ResultsAvailable', - results: { - buildTarget: { - shortName: string, - baseName: string, - }, - success: boolean, - failureCount: number, - totalNumberOfTests: number, - testCases: Array<{ - success: boolean, - failureCount: number, - skippedCount: number, - testCaseName: string, - testResults: Array<{ - testCaseName: string, - testName: string, - type: string, - time: number, - message: string, - stacktrace: ?string, - stdOut: string, - stdErr: string, - }>, - }>, - }, - } - | { - type: 'CompilerErrorEvent', - error: string, - suggestions: Array, // TODO: use this? - compilerType: string, - }; - -type BuckConfig = Object; +const MULTIPLE_TARGET_RULE_TYPE = exports.MULTIPLE_TARGET_RULE_TYPE = 'multiple_targets'; /** * Given a file path, returns path to the Buck project root i.e. the directory containing * '.buckconfig' file. */ -export function getRootForPath(file: NuclideUri): Promise { - return BuckServiceImpl.getRootForPath(file); +function getRootForPath(file) { + return (_BuckServiceImpl || _load_BuckServiceImpl()).getRootForPath(file); } /** * Gets the build file for the specified target. */ -export function getBuildFile( - rootPath: NuclideUri, - targetName: string, -): Promise { - return BuckServiceImpl.getBuildFile(rootPath, targetName); +function getBuildFile(rootPath, targetName) { + return (_BuckServiceImpl || _load_BuckServiceImpl()).getBuildFile(rootPath, targetName); } /** @@ -147,18 +124,8 @@ export function getBuildFile( * @param extraArguments passed on the command line to buck query * @return Promise that resolves to an array of build targets. */ -export function getOwners( - rootPath: NuclideUri, - filePath: NuclideUri, - extraArguments: Array, - kindFilter?: string, -): Promise> { - return BuckServiceImpl.getOwners( - rootPath, - filePath, - extraArguments, - kindFilter, - ); +function getOwners(rootPath, filePath, extraArguments, kindFilter) { + return (_BuckServiceImpl || _load_BuckServiceImpl()).getOwners(rootPath, filePath, extraArguments, kindFilter); } /** @@ -169,11 +136,7 @@ export function getOwners( * * @return Promise that resolves to the value, if it is set, else `null`. */ -export async function getBuckConfig( - rootPath: NuclideUri, - section: string, - property: string, -): Promise { +async function getBuckConfig(rootPath, section, property) { const buckConfig = await _loadBuckConfig(rootPath); if (!buckConfig.hasOwnProperty(section)) { return null; @@ -189,13 +152,10 @@ export async function getBuckConfig( * TODO(natthu): Also load .buckconfig.local. Consider loading .buckconfig from the home directory * and ~/.buckconfig.d/ directory. */ -async function _loadBuckConfig(rootPath: string): Promise { +async function _loadBuckConfig(rootPath) { const header = 'scope = global\n'; - const buckConfigContent = await fsPromise.readFile( - nuclideUri.join(rootPath, '.buckconfig'), - 'utf8', - ); - return ini.parse(header + buckConfigContent); + const buckConfigContent = await (_fsPromise || _load_fsPromise()).default.readFile((_nuclideUri || _load_nuclideUri()).default.join(rootPath, '.buckconfig'), 'utf8'); + return (_ini || _load_ini()).default.parse(header + buckConfigContent); } /** @@ -207,12 +167,8 @@ async function _loadBuckConfig(rootPath: string): Promise { * An error should be thrown only if the specified targets are invalid. * @return Promise that resolves to a build report. */ -export function build( - rootPath: NuclideUri, - buildTargets: Array, - options?: BaseBuckBuildOptions, -): Promise { - return BuckServiceImpl.build(rootPath, buildTargets, options); +function build(rootPath, buildTargets, options) { + return (_BuckServiceImpl || _load_BuckServiceImpl()).build(rootPath, buildTargets, options); } /** @@ -226,18 +182,12 @@ export function build( * @param simulator The UDID of the simulator to install the binary on. * @return Promise that resolves to a build report. */ -export function install( - rootPath: NuclideUri, - buildTargets: Array, - simulator: ?string, - run: boolean, - debug: boolean, -): Promise { - return BuckServiceImpl._build(rootPath, buildTargets, { +function install(rootPath, buildTargets, simulator, run, debug) { + return (_BuckServiceImpl || _load_BuckServiceImpl())._build(rootPath, buildTargets, { install: true, simulator, run, - debug, + debug }); } @@ -252,13 +202,9 @@ export function install( * from stderr. * onCompleted: Only called if the build completes successfully. */ -export function buildWithOutput( - rootPath: NuclideUri, - buildTargets: Array, - extraArguments: Array, -): ConnectableObservable { +function buildWithOutput(rootPath, buildTargets, extraArguments) { // TODO(T17463635) - return _buildWithOutput(rootPath, buildTargets, {extraArguments}).publish(); + return _buildWithOutput(rootPath, buildTargets, { extraArguments }).publish(); } /** @@ -272,17 +218,12 @@ export function buildWithOutput( * from stderr. * onCompleted: Only called if the build completes successfully. */ -export function testWithOutput( - rootPath: NuclideUri, - buildTargets: Array, - extraArguments: Array, - debug: boolean, -): ConnectableObservable { +function testWithOutput(rootPath, buildTargets, extraArguments, debug) { // TODO(T17463635) return _buildWithOutput(rootPath, buildTargets, { test: true, extraArguments, - debug, + debug }).publish(); } @@ -297,35 +238,23 @@ export function testWithOutput( * from stderr. * onCompleted: Only called if the install completes successfully. */ -export function installWithOutput( - rootPath: NuclideUri, - buildTargets: Array, - extraArguments: Array, - simulator: ?string, - run: boolean, - debug: boolean, -): ConnectableObservable { +function installWithOutput(rootPath, buildTargets, extraArguments, simulator, run, debug) { // TODO(T17463635) return _buildWithOutput(rootPath, buildTargets, { install: true, simulator, run, debug, - extraArguments, + extraArguments }).publish(); } -export function runWithOutput( - rootPath: NuclideUri, - buildTargets: Array, - extraArguments: Array, - simulator: ?string, -): ConnectableObservable { +function runWithOutput(rootPath, buildTargets, extraArguments, simulator) { // TODO(T17463635) return _buildWithOutput(rootPath, buildTargets, { run: true, simulator, - extraArguments, + extraArguments }).publish(); } @@ -334,63 +263,37 @@ export function runWithOutput( * @return An Observable that returns output from buck, as described by the * docblocks for `buildWithOutput` and `installWithOutput`. */ -function _buildWithOutput( - rootPath: NuclideUri, - buildTargets: Array, - options: BaseBuckBuildOptions, -): Observable { +function _buildWithOutput(rootPath, buildTargets, options) { // TODO(T17463635) - const args = BuckServiceImpl._translateOptionsToBuckBuildArgs({ - baseOptions: {...options}, - buildTargets, + const args = (_BuckServiceImpl || _load_BuckServiceImpl())._translateOptionsToBuckBuildArgs({ + baseOptions: Object.assign({}, options), + buildTargets }); - return Observable.fromPromise( - BuckServiceImpl._getBuckCommandAndOptions(rootPath), - ).switchMap(({pathToBuck, buckCommandOptions}) => - observeProcess(pathToBuck, args, { - ...buckCommandOptions, - /* TODO(T17353599) */ isExitError: () => false, - }) - .catch(error => Observable.of({kind: 'error', error})) // TODO(T17463635) - .startWith({ - kind: 'stdout', - data: `Starting "${pathToBuck} ${_getArgsStringSkipClientId(args)}"`, - }), - ); -} - -function _getArgsStringSkipClientId(args: Array): string { + return _rxjsBundlesRxMinJs.Observable.fromPromise((_BuckServiceImpl || _load_BuckServiceImpl())._getBuckCommandAndOptions(rootPath)).switchMap(({ pathToBuck, buckCommandOptions }) => (0, (_process || _load_process()).observeProcess)(pathToBuck, args, Object.assign({}, buckCommandOptions, { + /* TODO(T17353599) */isExitError: () => false + })).catch(error => _rxjsBundlesRxMinJs.Observable.of({ kind: 'error', error })) // TODO(T17463635) + .startWith({ + kind: 'stdout', + data: `Starting "${pathToBuck} ${_getArgsStringSkipClientId(args)}"` + })); +} + +function _getArgsStringSkipClientId(args) { const skipped = args.findIndex(arg => arg === 'client.id=nuclide'); - return args - .filter((arg, index) => index !== skipped && index !== skipped - 1) - .join(' '); + return args.filter((arg, index) => index !== skipped && index !== skipped - 1).join(' '); } -export async function listAliases( - rootPath: NuclideUri, -): Promise> { +async function listAliases(rootPath) { const args = ['audit', 'alias', '--list']; - const result = await BuckServiceImpl.runBuckCommandFromProjectRoot( - rootPath, - args, - ); + const result = await (_BuckServiceImpl || _load_BuckServiceImpl()).runBuckCommandFromProjectRoot(rootPath, args); const stdout = result.trim(); return stdout ? stdout.split('\n') : []; } -export async function listFlavors( - rootPath: NuclideUri, - targets: Array, - additionalArgs: Array = [], -): Promise { - const args = ['audit', 'flavors', '--json'] - .concat(targets) - .concat(additionalArgs); +async function listFlavors(rootPath, targets, additionalArgs = []) { + const args = ['audit', 'flavors', '--json'].concat(targets).concat(additionalArgs); try { - const result = await BuckServiceImpl.runBuckCommandFromProjectRoot( - rootPath, - args, - ); + const result = await (_BuckServiceImpl || _load_BuckServiceImpl()).runBuckCommandFromProjectRoot(rootPath, args); return JSON.parse(result); } catch (e) { return null; @@ -404,31 +307,14 @@ export async function listFlavors( * * The build output path is typically contained in the 'buck.outputPath' key. */ -export async function showOutput( - rootPath: NuclideUri, - aliasOrTarget: string, - extraArguments: Array = [], -): Promise> { - const args = ['targets', '--json', '--show-output', aliasOrTarget].concat( - extraArguments, - ); - const result = await BuckServiceImpl.runBuckCommandFromProjectRoot( - rootPath, - args, - ); +async function showOutput(rootPath, aliasOrTarget, extraArguments = []) { + const args = ['targets', '--json', '--show-output', aliasOrTarget].concat(extraArguments); + const result = await (_BuckServiceImpl || _load_BuckServiceImpl()).runBuckCommandFromProjectRoot(rootPath, args); return JSON.parse(result.trim()); } -export async function buildRuleTypeFor( - rootPath: NuclideUri, - aliasesOrTargets: string, -): Promise { - const resolvedRuleTypes = await Promise.all( - aliasesOrTargets - .trim() - .split(/\s+/) - .map(target => _buildRuleTypeFor(rootPath, target)), - ); +async function buildRuleTypeFor(rootPath, aliasesOrTargets) { + const resolvedRuleTypes = await Promise.all(aliasesOrTargets.trim().split(/\s+/).map(target => _buildRuleTypeFor(rootPath, target))); if (resolvedRuleTypes.length === 1) { return resolvedRuleTypes[0]; @@ -436,30 +322,22 @@ export async function buildRuleTypeFor( return { buildTarget: { qualifiedName: aliasesOrTargets, - flavors: [], + flavors: [] }, - type: MULTIPLE_TARGET_RULE_TYPE, + type: MULTIPLE_TARGET_RULE_TYPE }; } } -export async function clean(rootPath: NuclideUri): Promise { - await BuckServiceImpl.runBuckCommandFromProjectRoot(rootPath, ['clean']); +async function clean(rootPath) { + await (_BuckServiceImpl || _load_BuckServiceImpl()).runBuckCommandFromProjectRoot(rootPath, ['clean']); } -export async function kill(rootPath: NuclideUri): Promise { - await BuckServiceImpl.runBuckCommandFromProjectRoot( - rootPath, - ['kill'], - {}, - false, - ); +async function kill(rootPath) { + await (_BuckServiceImpl || _load_BuckServiceImpl()).runBuckCommandFromProjectRoot(rootPath, ['kill'], {}, false); } -export async function _buildRuleTypeFor( - rootPath: NuclideUri, - aliasOrTarget: string, -): Promise { +async function _buildRuleTypeFor(rootPath, aliasOrTarget) { let flavors; if (aliasOrTarget.includes('#')) { const nameComponents = aliasOrTarget.split('#'); @@ -469,14 +347,11 @@ export async function _buildRuleTypeFor( } const canonicalName = _normalizeNameForBuckQuery(aliasOrTarget); - let result: {[target: string]: Object}; + let result; try { - result = await BuckServiceImpl.query(rootPath, canonicalName, [ - '--output-attributes', - 'buck.type', - ]); + result = await (_BuckServiceImpl || _load_BuckServiceImpl()).query(rootPath, canonicalName, ['--output-attributes', 'buck.type']); } catch (error) { - getLogger('nuclide-buck-rpc').error(error.message); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-buck-rpc').error(error.message); return null; } // If aliasOrTarget is an alias, targets[0] will be the fully qualified build target. @@ -498,20 +373,17 @@ export async function _buildRuleTypeFor( return { buildTarget: { qualifiedName, - flavors, + flavors }, - type, + type }; } // Buck query doesn't allow omitting // or adding # for flavors, this needs to be fixed in buck. -function _normalizeNameForBuckQuery(aliasOrTarget: string): string { +function _normalizeNameForBuckQuery(aliasOrTarget) { let canonicalName = aliasOrTarget; // Don't prepend // for aliases (aliases will not have colons or .) - if ( - (canonicalName.indexOf(':') !== -1 || canonicalName.indexOf('.') !== -1) && - canonicalName.indexOf('//') === -1 - ) { + if ((canonicalName.indexOf(':') !== -1 || canonicalName.indexOf('.') !== -1) && canonicalName.indexOf('//') === -1) { canonicalName = '//' + canonicalName; } // Strip flavor string @@ -524,7 +396,7 @@ function _normalizeNameForBuckQuery(aliasOrTarget: string): string { const _cachedPorts = new Map(); -export async function getHTTPServerPort(rootPath: NuclideUri): Promise { +async function getHTTPServerPort(rootPath) { let port = _cachedPorts.get(rootPath); if (port != null) { if (port === -1) { @@ -532,37 +404,24 @@ export async function getHTTPServerPort(rootPath: NuclideUri): Promise { } // If there are other builds on the promise queue, wait them out. // This ensures that we don't return the port for another build. - await BuckServiceImpl.getPool(rootPath, false).submit(() => - Promise.resolve(), - ); - const msg = await getWebSocketStream(rootPath, port) - .refCount() - .take(1) - .toPromise() - .catch(() => null); + await (_BuckServiceImpl || _load_BuckServiceImpl()).getPool(rootPath, false).submit(() => Promise.resolve()); + const msg = await getWebSocketStream(rootPath, port).refCount().take(1).toPromise().catch(() => null); if (msg != null && msg.type === 'SocketConnected') { return port; } } const args = ['server', 'status', '--json', '--http-port']; - const result = await BuckServiceImpl.runBuckCommandFromProjectRoot( - rootPath, - args, - ); - const json: Object = JSON.parse(result); + const result = await (_BuckServiceImpl || _load_BuckServiceImpl()).runBuckCommandFromProjectRoot(rootPath, args); + const json = JSON.parse(result); port = json['http.port']; _cachedPorts.set(rootPath, port); return port; } /** Runs `buck query --json` with the specified query. */ -export function query( - rootPath: NuclideUri, - queryString: string, - extraArguments: Array, -): Promise> { - return BuckServiceImpl.query(rootPath, queryString, extraArguments); +function query(rootPath, queryString, extraArguments) { + return (_BuckServiceImpl || _load_BuckServiceImpl()).query(rootPath, queryString, extraArguments); } /** @@ -574,17 +433,10 @@ export function query( * @return object where each arg in args will be a key. Its corresponding value will be the list * of matching build targets in its results. */ -export async function queryWithArgs( - rootPath: NuclideUri, - queryString: string, - args: Array, -): Promise<{[aliasOrTarget: string]: Array}> { +async function queryWithArgs(rootPath, queryString, args) { const completeArgs = ['query', '--json', queryString].concat(args); - const result = await BuckServiceImpl.runBuckCommandFromProjectRoot( - rootPath, - completeArgs, - ); - const json: {[aliasOrTarget: string]: Array} = JSON.parse(result); + const result = await (_BuckServiceImpl || _load_BuckServiceImpl()).runBuckCommandFromProjectRoot(rootPath, completeArgs); + const json = JSON.parse(result); // `buck query` does not include entries in the JSON for params that did not match anything. We // massage the output to ensure that every argument has an entry in the output. @@ -607,52 +459,26 @@ export async function queryWithArgs( * } * } */ -export async function queryWithAttributes( - rootPath: NuclideUri, - queryString: string, - attributes: Array, -): Promise<{[aliasOrTarget: string]: {[attribute: string]: mixed}}> { - const completeArgs = [ - 'query', - '--json', - queryString, - '--output-attributes', - ...attributes, - ]; - const result = await BuckServiceImpl.runBuckCommandFromProjectRoot( - rootPath, - completeArgs, - ); +async function queryWithAttributes(rootPath, queryString, attributes) { + const completeArgs = ['query', '--json', queryString, '--output-attributes', ...attributes]; + const result = await (_BuckServiceImpl || _load_BuckServiceImpl()).runBuckCommandFromProjectRoot(rootPath, completeArgs); return JSON.parse(result); } // TODO: Nuclide's RPC framework won't allow BuckWebSocketMessage here unless we cover // all possible message types. For now, we'll manually typecast at the callsite. -export function getWebSocketStream( - rootPath: NuclideUri, - httpPort: number, -): ConnectableObservable { - return createBuckWebSocket(httpPort).publish(); +function getWebSocketStream(rootPath, httpPort) { + return (0, (_createBuckWebSocket || _load_createBuckWebSocket()).default)(httpPort).publish(); } -export async function resetCompilationDatabaseForSource( - src: NuclideUri, - params: CompilationDatabaseParams, -): Promise { - getCompilationDatabaseHandler(params).resetForSource(src); +async function resetCompilationDatabaseForSource(src, params) { + (0, (_BuckClangCompilationDatabase || _load_BuckClangCompilationDatabase()).getCompilationDatabaseHandler)(params).resetForSource(src); } -export async function resetCompilationDatabase( - params: CompilationDatabaseParams, -): Promise { - getCompilationDatabaseHandler(params).reset(); +async function resetCompilationDatabase(params) { + (0, (_BuckClangCompilationDatabase || _load_BuckClangCompilationDatabase()).getCompilationDatabaseHandler)(params).reset(); } -export function getCompilationDatabase( - src: NuclideUri, - params: CompilationDatabaseParams, -): ConnectableObservable { - return Observable.fromPromise( - getCompilationDatabaseHandler(params).getCompilationDatabase(src), - ).publish(); -} +function getCompilationDatabase(src, params) { + return _rxjsBundlesRxMinJs.Observable.fromPromise((0, (_BuckClangCompilationDatabase || _load_BuckClangCompilationDatabase()).getCompilationDatabaseHandler)(params).getCompilationDatabase(src)).publish(); +} \ No newline at end of file diff --git a/pkg/nuclide-buck-rpc/lib/BuckServiceImpl.js b/pkg/nuclide-buck-rpc/lib/BuckServiceImpl.js index 374fc7e075..3ab1691b49 100644 --- a/pkg/nuclide-buck-rpc/lib/BuckServiceImpl.js +++ b/pkg/nuclide-buck-rpc/lib/BuckServiceImpl.js @@ -1,3 +1,69 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getPool = getPool; +exports._getBuckCommandAndOptions = _getBuckCommandAndOptions; +exports._translateOptionsToBuckBuildArgs = _translateOptionsToBuckBuildArgs; +exports._build = _build; +exports.build = build; +exports.getDefaultPlatform = getDefaultPlatform; +exports.getOwners = getOwners; +exports.getRootForPath = getRootForPath; +exports.runBuckCommandFromProjectRoot = runBuckCommandFromProjectRoot; +exports.query = query; +exports._getFbRepoSpecificArgs = _getFbRepoSpecificArgs; +exports.getBuildFile = getBuildFile; + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _promiseExecutors; + +function _load_promiseExecutors() { + return _promiseExecutors = require('../../commons-node/promise-executors'); +} + +var _os = _interopRequireWildcard(require('os')); + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _string; + +function _load_string() { + return _string = require('../../../modules/nuclide-commons/string'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-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; } } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,40 +71,15 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {BaseBuckBuildOptions} from './types'; -import type {ObserveProcessOptions} from 'nuclide-commons/process'; - -import {runCommand} from 'nuclide-commons/process'; -import {PromisePool} from '../../commons-node/promise-executors'; -import {getOriginalEnvironment} from 'nuclide-commons/process'; -import * as os from 'os'; -import fsPromise from 'nuclide-commons/fsPromise'; -import {shellQuote} from 'nuclide-commons/string'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {getLogger} from 'log4js'; -import {trackTiming} from '../../nuclide-analytics'; - -const logger = getLogger('nuclide-buck-rpc'); +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-buck-rpc'); // Tag these Buck calls as coming from Nuclide for analytics purposes. const CLIENT_ID_ARGS = ['--config', 'client.id=nuclide']; -type FullBuckBuildOptions = { - baseOptions: BaseBuckBuildOptions, - pathToBuildReport?: string, - buildTargets: Array, -}; - -type BuckCommandAndOptions = { - pathToBuck: string, - buckCommandOptions: ObserveProcessOptions, -}; - /** * As defined in com.facebook.buck.cli.Command, some of Buck's subcommands are * read-only. The read-only commands can be executed in parallel, but the rest @@ -52,13 +93,13 @@ type BuckCommandAndOptions = { const MAX_CONCURRENT_READ_ONLY = 1; // Math.max(1, os.cpus() ? os.cpus().length - 1 : 1); const pools = new Map(); -export function getPool(path: string, readOnly: boolean): PromisePool { +function getPool(path, readOnly) { const key = (readOnly ? 'ro:' : '') + path; let pool = pools.get(key); if (pool != null) { return pool; } - pool = new PromisePool(readOnly ? MAX_CONCURRENT_READ_ONLY : 1); + pool = new (_promiseExecutors || _load_promiseExecutors()).PromisePool(readOnly ? MAX_CONCURRENT_READ_ONLY : 1); pools.set(key, pool); return pool; } @@ -66,35 +107,28 @@ export function getPool(path: string, readOnly: boolean): PromisePool { /** * @return The path to buck and set of options to be used to run a `buck` command. */ -export async function _getBuckCommandAndOptions( - rootPath: string, - commandOptions?: ObserveProcessOptions = {}, -): Promise { +async function _getBuckCommandAndOptions(rootPath, commandOptions = {}) { // $UPFixMe: This should use nuclide-features-config - let pathToBuck = - (global.atom && - global.atom.config.get('nuclide.nuclide-buck.pathToBuck')) || - 'buck'; - if (pathToBuck === 'buck' && os.platform() === 'win32') { + let pathToBuck = global.atom && global.atom.config.get('nuclide.nuclide-buck.pathToBuck') || 'buck'; + if (pathToBuck === 'buck' && _os.platform() === 'win32') { pathToBuck = 'buck.exe'; } - let env = await getOriginalEnvironment(); + let env = await (0, (_process || _load_process()).getOriginalEnvironment)(); try { // $FlowFB - const {getRealUsername} = require('./fb/realUsername'); + const { getRealUsername } = require('./fb/realUsername'); const username = await getRealUsername(env.USER); if (username != null) { - env = {...env, USER: username}; + env = Object.assign({}, env, { USER: username }); } } catch (_) {} - const buckCommandOptions = { + const buckCommandOptions = Object.assign({ cwd: rootPath, // Buck restarts itself if the environment changes, so try to preserve // the original environment that Nuclide was started in. - env, - ...commandOptions, - }; - return {pathToBuck, buckCommandOptions}; + env + }, commandOptions); + return { pathToBuck, buckCommandOptions }; } /** @@ -102,17 +136,15 @@ export async function _getBuckCommandAndOptions( * @return An array of strings that can be passed as `args` to spawn a * process to run the `buck` command. */ -export function _translateOptionsToBuckBuildArgs( - options: FullBuckBuildOptions, -): Array { - const {baseOptions, pathToBuildReport, buildTargets} = options; +function _translateOptionsToBuckBuildArgs(options) { + const { baseOptions, pathToBuildReport, buildTargets } = options; const { install: doInstall, run, simulator, test, debug, - extraArguments, + extraArguments } = baseOptions; let args = [test ? 'test' : doInstall ? 'install' : run ? 'run' : 'build']; @@ -149,162 +181,110 @@ export function _translateOptionsToBuckBuildArgs( return args; } -export async function _build( - rootPath: NuclideUri, - buildTargets: Array, - options: BaseBuckBuildOptions, -): Promise { - const report = await fsPromise.tempfile({suffix: '.json'}); +async function _build(rootPath, buildTargets, options) { + const report = await (_fsPromise || _load_fsPromise()).default.tempfile({ suffix: '.json' }); const args = _translateOptionsToBuckBuildArgs({ - baseOptions: {...options}, + baseOptions: Object.assign({}, options), pathToBuildReport: report, - buildTargets, + buildTargets }); try { - await runBuckCommandFromProjectRoot( - rootPath, - args, - options.commandOptions, - false, // Do not add the client ID, since we already do it in the build args. - true, // Build commands are blocking. + await runBuckCommandFromProjectRoot(rootPath, args, options.commandOptions, false, // Do not add the client ID, since we already do it in the build args. + true // Build commands are blocking. ); } catch (e) { // The build failed. However, because --keep-going was specified, the // build report should have still been written unless any of the target // args were invalid. We check the contents of the report file to be sure. - const stat = await fsPromise.stat(report).catch(() => null); + const stat = await (_fsPromise || _load_fsPromise()).default.stat(report).catch(() => null); if (stat == null || stat.size === 0) { throw e; } } try { - const json: string = await fsPromise.readFile(report, {encoding: 'UTF-8'}); + const json = await (_fsPromise || _load_fsPromise()).default.readFile(report, { encoding: 'UTF-8' }); try { return JSON.parse(json); } catch (e) { throw new Error(`Failed to parse:\n${json}`); } } finally { - fsPromise.unlink(report); + (_fsPromise || _load_fsPromise()).default.unlink(report); } } -export function build( - rootPath: NuclideUri, - buildTargets: Array, - options?: BaseBuckBuildOptions, -): Promise { +function build(rootPath, buildTargets, options) { return _build(rootPath, buildTargets, options || {}); } -export async function getDefaultPlatform( - rootPath: NuclideUri, - target: string, -): Promise { - const result = await query(rootPath, target, [ - '--output-attributes', - 'defaults', - ]); - if ( - result[target] != null && - result[target].defaults != null && - result[target].defaults.platform != null - ) { +async function getDefaultPlatform(rootPath, target) { + const result = await query(rootPath, target, ['--output-attributes', 'defaults']); + if (result[target] != null && result[target].defaults != null && result[target].defaults.platform != null) { return result[target].defaults.platform; } return null; } -export async function getOwners( - rootPath: NuclideUri, - filePath: NuclideUri, - extraArguments: Array, - kindFilter?: string, -): Promise> { - let queryString = `owner("${shellQuote([filePath])}")`; +async function getOwners(rootPath, filePath, extraArguments, kindFilter) { + let queryString = `owner("${(0, (_string || _load_string()).shellQuote)([filePath])}")`; if (kindFilter != null) { queryString = `kind(${JSON.stringify(kindFilter)}, ${queryString})`; } return query(rootPath, queryString, extraArguments); } -export function getRootForPath(file: NuclideUri): Promise { - return fsPromise.findNearestFile('.buckconfig', file); +function getRootForPath(file) { + return (_fsPromise || _load_fsPromise()).default.findNearestFile('.buckconfig', file); } /** * @param args Do not include 'buck' as the first argument: it will be added * automatically. */ -export async function runBuckCommandFromProjectRoot( - rootPath: string, - args: Array, - commandOptions?: ObserveProcessOptions, - addClientId?: boolean = true, - readOnly?: boolean = true, -): Promise { +async function runBuckCommandFromProjectRoot(rootPath, args, commandOptions, addClientId = true, readOnly = true) { const { pathToBuck, - buckCommandOptions: options, + buckCommandOptions: options } = await _getBuckCommandAndOptions(rootPath, commandOptions); // Create an event name from the first arg, e.g. 'buck.query' or 'buck.build'. const analyticsEvent = `buck.${args.length > 0 ? args[0] : ''}`; const newArgs = addClientId ? args.concat(CLIENT_ID_ARGS) : args; return getPool(rootPath, readOnly).submit(() => { - logger.debug(`Running \`${pathToBuck} ${shellQuote(args)}\``); - return trackTiming( - analyticsEvent, - () => runCommand(pathToBuck, newArgs, options).toPromise(), - {args}, - ); + logger.debug(`Running \`${pathToBuck} ${(0, (_string || _load_string()).shellQuote)(args)}\``); + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(analyticsEvent, () => (0, (_process || _load_process()).runCommand)(pathToBuck, newArgs, options).toPromise(), { args }); }); } /** Runs `buck query --json` with the specified query. */ -export async function query( - rootPath: NuclideUri, - queryString: string, - extraArguments: Array, -): Promise { +async function query(rootPath, queryString, extraArguments) { const fbRepoSpecificArgs = await _getFbRepoSpecificArgs(rootPath); - const args = [ - 'query', - ...extraArguments, - '--json', - queryString, - ...fbRepoSpecificArgs, - ]; + const args = ['query', ...extraArguments, '--json', queryString, ...fbRepoSpecificArgs]; const result = await runBuckCommandFromProjectRoot(rootPath, args); return JSON.parse(result); } -export async function _getFbRepoSpecificArgs( - buckRoot: NuclideUri, -): Promise> { +async function _getFbRepoSpecificArgs(buckRoot) { try { // $FlowFB - const {getFbRepoSpecificArgs} = require('./fb/repoSpecificArgs'); + const { getFbRepoSpecificArgs } = require('./fb/repoSpecificArgs'); return await getFbRepoSpecificArgs(buckRoot); } catch (e) { return []; } } -export async function getBuildFile( - rootPath: NuclideUri, - targetName: string, -): Promise { +async function getBuildFile(rootPath, targetName) { try { const result = await query(rootPath, `buildfile(${targetName})`, []); if (result.length === 0) { return null; } - return nuclideUri.join(rootPath, result[0]); + return (_nuclideUri || _load_nuclideUri()).default.join(rootPath, result[0]); } catch (e) { logger.error(`No build file for target "${targetName}" ${e}`); return null; } -} +} \ No newline at end of file diff --git a/pkg/nuclide-buck-rpc/lib/BuckServiceProxy.js b/pkg/nuclide-buck-rpc/lib/BuckServiceProxy.js new file mode 100644 index 0000000000..3b26a6b826 --- /dev/null +++ b/pkg/nuclide-buck-rpc/lib/BuckServiceProxy.js @@ -0,0 +1,2520 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + + remoteModule.getRootForPath = function (arg0) { + return _client.callRemoteFunction("BuckService/getRootForPath", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "file", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "NuclideUri" + } + }); + }); + }; + + remoteModule.getBuildFile = function (arg0, arg1) { + return _client.callRemoteFunction("BuckService/getBuildFile", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "targetName", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "string" + } + }); + }); + }; + + remoteModule.getOwners = function (arg0, arg1, arg2, arg3) { + return _client.callRemoteFunction("BuckService/getOwners", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "extraArguments", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "kindFilter", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "string" + } + }); + }); + }; + + remoteModule.getBuckConfig = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("BuckService/getBuckConfig", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "section", + type: { + kind: "string" + } + }, { + name: "property", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "string" + } + }); + }); + }; + + remoteModule.build = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("BuckService/build", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "buildTargets", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "options", + type: { + kind: "nullable", + type: { + kind: "named", + name: "BaseBuckBuildOptions" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "any" + }); + }); + }; + + remoteModule.install = function (arg0, arg1, arg2, arg3, arg4) { + return _client.callRemoteFunction("BuckService/install", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "buildTargets", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "simulator", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }, { + name: "run", + type: { + kind: "boolean" + } + }, { + name: "debug", + type: { + kind: "boolean" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "any" + }); + }); + }; + + remoteModule.buildWithOutput = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("BuckService/buildWithOutput", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "buildTargets", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "extraArguments", + type: { + kind: "array", + type: { + kind: "string" + } + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.testWithOutput = function (arg0, arg1, arg2, arg3) { + return _client.callRemoteFunction("BuckService/testWithOutput", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "buildTargets", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "extraArguments", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "debug", + type: { + kind: "boolean" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.installWithOutput = function (arg0, arg1, arg2, arg3, arg4, arg5) { + return _client.callRemoteFunction("BuckService/installWithOutput", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "buildTargets", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "extraArguments", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "simulator", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }, { + name: "run", + type: { + kind: "boolean" + } + }, { + name: "debug", + type: { + kind: "boolean" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.runWithOutput = function (arg0, arg1, arg2, arg3) { + return _client.callRemoteFunction("BuckService/runWithOutput", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "buildTargets", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "extraArguments", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "simulator", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.listAliases = function (arg0) { + return _client.callRemoteFunction("BuckService/listAliases", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "string" + } + }); + }); + }; + + remoteModule.listFlavors = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("BuckService/listFlavors", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "targets", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "additionalArgs", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "string" + } + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "Object" + } + }); + }); + }; + + remoteModule.showOutput = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("BuckService/showOutput", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "aliasOrTarget", + type: { + kind: "string" + } + }, { + name: "extraArguments", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "string" + } + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "Object" + } + }); + }); + }; + + remoteModule.buildRuleTypeFor = function (arg0, arg1) { + return _client.callRemoteFunction("BuckService/buildRuleTypeFor", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "aliasesOrTargets", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "ResolvedRuleType" + } + }); + }); + }; + + remoteModule.clean = function (arg0) { + return _client.callRemoteFunction("BuckService/clean", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.kill = function (arg0) { + return _client.callRemoteFunction("BuckService/kill", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.getHTTPServerPort = function (arg0) { + return _client.callRemoteFunction("BuckService/getHTTPServerPort", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "number" + }); + }); + }; + + remoteModule.query = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("BuckService/query", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "queryString", + type: { + kind: "string" + } + }, { + name: "extraArguments", + type: { + kind: "array", + type: { + kind: "string" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "string" + } + }); + }); + }; + + remoteModule.queryWithArgs = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("BuckService/queryWithArgs", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "queryString", + type: { + kind: "string" + } + }, { + name: "args", + type: { + kind: "array", + type: { + kind: "string" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "object", + fields: [] + }); + }); + }; + + remoteModule.queryWithAttributes = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("BuckService/queryWithAttributes", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "queryString", + type: { + kind: "string" + } + }, { + name: "attributes", + type: { + kind: "array", + type: { + kind: "string" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "object", + fields: [] + }); + }); + }; + + remoteModule.getWebSocketStream = function (arg0, arg1) { + return _client.callRemoteFunction("BuckService/getWebSocketStream", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "httpPort", + type: { + kind: "number" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "Object" + }); + }).publish(); + }; + + remoteModule.resetCompilationDatabaseForSource = function (arg0, arg1) { + return _client.callRemoteFunction("BuckService/resetCompilationDatabaseForSource", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "params", + type: { + kind: "named", + name: "CompilationDatabaseParams" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.resetCompilationDatabase = function (arg0) { + return _client.callRemoteFunction("BuckService/resetCompilationDatabase", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "params", + type: { + kind: "named", + name: "CompilationDatabaseParams" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.getCompilationDatabase = function (arg0, arg1) { + return _client.callRemoteFunction("BuckService/getCompilationDatabase", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "params", + type: { + kind: "named", + name: "CompilationDatabaseParams" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "BuckClangCompilationDatabase" + } + }); + }).publish(); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + BuckWebSocketMessage: { + kind: "alias", + location: { + type: "source", + fileName: "BuckService.js", + line: 34 + }, + name: "BuckWebSocketMessage", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "SocketConnected" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "BuildProgressUpdated" + }, + optional: false + }, { + name: "progressValue", + type: { + kind: "number" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "BuildFinished" + }, + optional: false + }, { + name: "exitCode", + type: { + kind: "number" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "BuildStarted" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "ConsoleEvent" + }, + optional: false + }, { + name: "message", + type: { + kind: "string" + }, + optional: false + }, { + name: "level", + type: { + kind: "object", + fields: [{ + name: "name", + type: { + kind: "union", + types: [{ + kind: "string-literal", + value: "OFF" + }, { + kind: "string-literal", + value: "SEVERE" + }, { + kind: "string-literal", + value: "WARNING" + }, { + kind: "string-literal", + value: "INFO" + }, { + kind: "string-literal", + value: "CONFIG" + }, { + kind: "string-literal", + value: "FINE" + }, { + kind: "string-literal", + value: "FINER" + }, { + kind: "string-literal", + value: "FINEST" + }, { + kind: "string-literal", + value: "ALL" + }] + }, + optional: false + }] + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "ParseStarted" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "ParseFinished" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "InstallFinished" + }, + optional: false + }, { + name: "success", + type: { + kind: "boolean" + }, + optional: false + }, { + name: "pid", + type: { + kind: "number" + }, + optional: true + }] + }, { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "RunStarted" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "RunComplete" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "ResultsAvailable" + }, + optional: false + }, { + name: "results", + type: { + kind: "object", + fields: [{ + name: "buildTarget", + type: { + kind: "object", + fields: [{ + name: "shortName", + type: { + kind: "string" + }, + optional: false + }, { + name: "baseName", + type: { + kind: "string" + }, + optional: false + }] + }, + optional: false + }, { + name: "success", + type: { + kind: "boolean" + }, + optional: false + }, { + name: "failureCount", + type: { + kind: "number" + }, + optional: false + }, { + name: "totalNumberOfTests", + type: { + kind: "number" + }, + optional: false + }, { + name: "testCases", + type: { + kind: "array", + type: { + kind: "object", + fields: [{ + name: "success", + type: { + kind: "boolean" + }, + optional: false + }, { + name: "failureCount", + type: { + kind: "number" + }, + optional: false + }, { + name: "skippedCount", + type: { + kind: "number" + }, + optional: false + }, { + name: "testCaseName", + type: { + kind: "string" + }, + optional: false + }, { + name: "testResults", + type: { + kind: "array", + type: { + kind: "object", + fields: [{ + name: "testCaseName", + type: { + kind: "string" + }, + optional: false + }, { + name: "testName", + type: { + kind: "string" + }, + optional: false + }, { + name: "type", + type: { + kind: "string" + }, + optional: false + }, { + name: "time", + type: { + kind: "number" + }, + optional: false + }, { + name: "message", + type: { + kind: "string" + }, + optional: false + }, { + name: "stacktrace", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "stdOut", + type: { + kind: "string" + }, + optional: false + }, { + name: "stdErr", + type: { + kind: "string" + }, + optional: false + }] + } + }, + optional: false + }] + } + }, + optional: false + }] + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "CompilerErrorEvent" + }, + optional: false + }, { + name: "error", + type: { + kind: "string" + }, + optional: false + }, { + name: "suggestions", + type: { + kind: "array", + type: { + kind: "mixed" + } + }, + optional: false + }, { + name: "compilerType", + type: { + kind: "string" + }, + optional: false + }] + }], + discriminantField: "type" + } + }, + getRootForPath: { + kind: "function", + name: "getRootForPath", + location: { + type: "source", + fileName: "BuckService.js", + line: 124 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 124 + }, + kind: "function", + argumentTypes: [{ + name: "file", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "NuclideUri" + } + } + } + } + }, + getBuildFile: { + kind: "function", + name: "getBuildFile", + location: { + type: "source", + fileName: "BuckService.js", + line: 131 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 131 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "targetName", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + } + } + }, + getOwners: { + kind: "function", + name: "getOwners", + location: { + type: "source", + fileName: "BuckService.js", + line: 150 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 150 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "extraArguments", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "kindFilter", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "array", + type: { + kind: "string" + } + } + } + } + }, + getBuckConfig: { + kind: "function", + name: "getBuckConfig", + location: { + type: "source", + fileName: "BuckService.js", + line: 172 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 172 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "section", + type: { + kind: "string" + } + }, { + name: "property", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + } + } + }, + BaseBuckBuildOptions: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 14 + }, + name: "BaseBuckBuildOptions", + definition: { + kind: "object", + fields: [{ + name: "install", + type: { + kind: "boolean" + }, + optional: true + }, { + name: "run", + type: { + kind: "boolean" + }, + optional: true + }, { + name: "test", + type: { + kind: "boolean" + }, + optional: true + }, { + name: "debug", + type: { + kind: "boolean" + }, + optional: true + }, { + name: "simulator", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: true + }, { + name: "commandOptions", + type: { + kind: "named", + name: "Object" + }, + optional: true + }, { + name: "extraArguments", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: true + }] + } + }, + build: { + kind: "function", + name: "build", + location: { + type: "source", + fileName: "BuckService.js", + line: 210 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 210 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "buildTargets", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "options", + type: { + kind: "nullable", + type: { + kind: "named", + name: "BaseBuckBuildOptions" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "any" + } + } + } + }, + install: { + kind: "function", + name: "install", + location: { + type: "source", + fileName: "BuckService.js", + line: 229 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 229 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "buildTargets", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "simulator", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }, { + name: "run", + type: { + kind: "boolean" + } + }, { + name: "debug", + type: { + kind: "boolean" + } + }], + returnType: { + kind: "promise", + type: { + kind: "any" + } + } + } + }, + ProcessExitMessage: { + kind: "alias", + location: { + type: "source", + fileName: "process.js", + line: 665 + }, + name: "ProcessExitMessage", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "exit" + }, + optional: false + }, { + name: "exitCode", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }, { + name: "signal", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }] + } + }, + ProcessMessage: { + kind: "alias", + location: { + type: "source", + fileName: "process.js", + line: 671 + }, + name: "ProcessMessage", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "stdout" + }, + optional: false + }, { + name: "data", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "stderr" + }, + optional: false + }, { + name: "data", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "exit" + }, + optional: false + }, { + name: "exitCode", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }, { + name: "signal", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }] + }], + discriminantField: "kind" + } + }, + LegacyProcessMessage: { + kind: "alias", + location: { + type: "source", + fileName: "process.js", + line: 684 + }, + name: "LegacyProcessMessage", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "stdout" + }, + optional: false + }, { + name: "data", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "stderr" + }, + optional: false + }, { + name: "data", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "exit" + }, + optional: false + }, { + name: "exitCode", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }, { + name: "signal", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "error" + }, + optional: false + }, { + name: "error", + type: { + kind: "named", + name: "Object" + }, + optional: false + }] + }], + discriminantField: "kind" + } + }, + buildWithOutput: { + kind: "function", + name: "buildWithOutput", + location: { + type: "source", + fileName: "BuckService.js", + line: 255 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 255 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "buildTargets", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "extraArguments", + type: { + kind: "array", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + testWithOutput: { + kind: "function", + name: "testWithOutput", + location: { + type: "source", + fileName: "BuckService.js", + line: 275 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 275 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "buildTargets", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "extraArguments", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "debug", + type: { + kind: "boolean" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + installWithOutput: { + kind: "function", + name: "installWithOutput", + location: { + type: "source", + fileName: "BuckService.js", + line: 300 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 300 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "buildTargets", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "extraArguments", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "simulator", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }, { + name: "run", + type: { + kind: "boolean" + } + }, { + name: "debug", + type: { + kind: "boolean" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + runWithOutput: { + kind: "function", + name: "runWithOutput", + location: { + type: "source", + fileName: "BuckService.js", + line: 318 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 318 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "buildTargets", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "extraArguments", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "simulator", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + listAliases: { + kind: "function", + name: "listAliases", + location: { + type: "source", + fileName: "BuckService.js", + line: 369 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 369 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "array", + type: { + kind: "string" + } + } + } + } + }, + listFlavors: { + kind: "function", + name: "listFlavors", + location: { + type: "source", + fileName: "BuckService.js", + line: 381 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 381 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "targets", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "additionalArgs", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "string" + } + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "Object" + } + } + } + } + }, + showOutput: { + kind: "function", + name: "showOutput", + location: { + type: "source", + fileName: "BuckService.js", + line: 407 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 407 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "aliasOrTarget", + type: { + kind: "string" + } + }, { + name: "extraArguments", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "string" + } + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "array", + type: { + kind: "named", + name: "Object" + } + } + } + } + }, + ResolvedBuildTarget: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 25 + }, + name: "ResolvedBuildTarget", + definition: { + kind: "object", + fields: [{ + name: "qualifiedName", + type: { + kind: "string" + }, + optional: false + }, { + name: "flavors", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: false + }] + } + }, + ResolvedRuleType: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 30 + }, + name: "ResolvedRuleType", + definition: { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string" + }, + optional: false + }, { + name: "buildTarget", + type: { + kind: "named", + name: "ResolvedBuildTarget" + }, + optional: false + }] + } + }, + buildRuleTypeFor: { + kind: "function", + name: "buildRuleTypeFor", + location: { + type: "source", + fileName: "BuckService.js", + line: 422 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 422 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "aliasesOrTargets", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "ResolvedRuleType" + } + } + } + } + }, + clean: { + kind: "function", + name: "clean", + location: { + type: "source", + fileName: "BuckService.js", + line: 446 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 446 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + kill: { + kind: "function", + name: "kill", + location: { + type: "source", + fileName: "BuckService.js", + line: 450 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 450 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + getHTTPServerPort: { + kind: "function", + name: "getHTTPServerPort", + location: { + type: "source", + fileName: "BuckService.js", + line: 527 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 527 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "number" + } + } + } + }, + query: { + kind: "function", + name: "query", + location: { + type: "source", + fileName: "BuckService.js", + line: 560 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 560 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "queryString", + type: { + kind: "string" + } + }, { + name: "extraArguments", + type: { + kind: "array", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "array", + type: { + kind: "string" + } + } + } + } + }, + queryWithArgs: { + kind: "function", + name: "queryWithArgs", + location: { + type: "source", + fileName: "BuckService.js", + line: 577 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 577 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "queryString", + type: { + kind: "string" + } + }, { + name: "args", + type: { + kind: "array", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "object", + fields: [] + } + } + } + }, + queryWithAttributes: { + kind: "function", + name: "queryWithAttributes", + location: { + type: "source", + fileName: "BuckService.js", + line: 610 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 610 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "queryString", + type: { + kind: "string" + } + }, { + name: "attributes", + type: { + kind: "array", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "object", + fields: [] + } + } + } + }, + getWebSocketStream: { + kind: "function", + name: "getWebSocketStream", + location: { + type: "source", + fileName: "BuckService.js", + line: 631 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 631 + }, + kind: "function", + argumentTypes: [{ + name: "rootPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "httpPort", + type: { + kind: "number" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "Object" + } + } + } + }, + CompilationDatabaseParams: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 122 + }, + name: "CompilationDatabaseParams", + definition: { + kind: "object", + fields: [{ + name: "flavorsForTarget", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "args", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "useDefaultPlatform", + type: { + kind: "boolean" + }, + optional: true + }] + } + }, + resetCompilationDatabaseForSource: { + kind: "function", + name: "resetCompilationDatabaseForSource", + location: { + type: "source", + fileName: "BuckService.js", + line: 638 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 638 + }, + kind: "function", + argumentTypes: [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "params", + type: { + kind: "named", + name: "CompilationDatabaseParams" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + resetCompilationDatabase: { + kind: "function", + name: "resetCompilationDatabase", + location: { + type: "source", + fileName: "BuckService.js", + line: 645 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 645 + }, + kind: "function", + argumentTypes: [{ + name: "params", + type: { + kind: "named", + name: "CompilationDatabaseParams" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + BuckClangCompilationDatabase: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 35 + }, + name: "BuckClangCompilationDatabase", + definition: { + kind: "object", + fields: [{ + name: "file", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "flagsFile", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "libclangPath", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "warnings", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: false + }] + } + }, + getCompilationDatabase: { + kind: "function", + name: "getCompilationDatabase", + location: { + type: "source", + fileName: "BuckService.js", + line: 651 + }, + type: { + location: { + type: "source", + fileName: "BuckService.js", + line: 651 + }, + kind: "function", + argumentTypes: [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "params", + type: { + kind: "named", + name: "CompilationDatabaseParams" + } + }], + returnType: { + kind: "observable", + type: { + kind: "nullable", + type: { + kind: "named", + name: "BuckClangCompilationDatabase" + } + } + } + } + } + } +}); \ No newline at end of file diff --git a/pkg/nuclide-buck-rpc/lib/createBuckWebSocket.js b/pkg/nuclide-buck-rpc/lib/createBuckWebSocket.js index f638a17dc9..eacb42f68b 100644 --- a/pkg/nuclide-buck-rpc/lib/createBuckWebSocket.js +++ b/pkg/nuclide-buck-rpc/lib/createBuckWebSocket.js @@ -1,3 +1,26 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = createBuckWebSocket; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _ws; + +function _load_ws() { + return _ws = _interopRequireDefault(require('ws')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,27 +28,19 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {BuckWebSocketMessage} from './BuckService'; - -import {Observable} from 'rxjs'; -import {getLogger} from 'log4js'; -import WS from 'ws'; - -export default function createBuckWebSocket( - httpPort: number, -): Observable { - return Observable.create(observer => { +function createBuckWebSocket(httpPort) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { const uri = `ws://localhost:${httpPort}/ws/build`; - const socket = new WS(uri); - let buildId: ?string = null; + const socket = new (_ws || _load_ws()).default(uri); + let buildId = null; socket.on('open', () => { // Emit a message so the client knows the socket is ready for Buck events. - observer.next({type: 'SocketConnected'}); + observer.next({ type: 'SocketConnected' }); }); socket.on('message', data => { @@ -33,10 +48,7 @@ export default function createBuckWebSocket( try { message = JSON.parse(data); } catch (err) { - getLogger('nuclide-buck-rpc').error( - 'Error parsing Buck websocket message', - err, - ); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-buck-rpc').error('Error parsing Buck websocket message', err); return; } @@ -70,4 +82,4 @@ export default function createBuckWebSocket( socket.close(); }; }); -} +} \ No newline at end of file diff --git a/pkg/nuclide-buck-rpc/lib/types.js b/pkg/nuclide-buck-rpc/lib/types.js index c10a9baf20..d176aa4a91 100644 --- a/pkg/nuclide-buck-rpc/lib/types.js +++ b/pkg/nuclide-buck-rpc/lib/types.js @@ -1,51 +1,25 @@ -/** - * 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 - */ +'use strict'; -import type {ClangCompilationDatabase} from '../../nuclide-clang-rpc/lib/rpc-types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.convertBuckClangCompilationDatabase = convertBuckClangCompilationDatabase; -export type BaseBuckBuildOptions = { - install?: boolean, - run?: boolean, - test?: boolean, - debug?: boolean, - simulator?: ?string, - // The service framework doesn't support imported types - commandOptions?: Object /* ObserveProcessOptions */, - extraArguments?: Array, -}; - -export type ResolvedBuildTarget = { - qualifiedName: string, - flavors: Array, -}; - -export type ResolvedRuleType = { - type: string, - buildTarget: ResolvedBuildTarget, -}; - -export type BuckClangCompilationDatabase = {| - file: ?string, - flagsFile: ?string, - libclangPath: ?string, - warnings: Array, -|}; // Remove the warnings field from the buck value. -export function convertBuckClangCompilationDatabase( - buckDb: ?BuckClangCompilationDatabase, -): ?ClangCompilationDatabase { +function convertBuckClangCompilationDatabase(buckDb) { if (buckDb != null) { - const {file, flagsFile, libclangPath} = buckDb; - return {file, flagsFile, libclangPath}; + const { file, flagsFile, libclangPath } = buckDb; + return { file, flagsFile, libclangPath }; } return null; -} +} /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-buck-rpc/spec/BuckService-spec.js b/pkg/nuclide-buck-rpc/spec/BuckService-spec.js deleted file mode 100644 index 916741447d..0000000000 --- a/pkg/nuclide-buck-rpc/spec/BuckService-spec.js +++ /dev/null @@ -1,335 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import invariant from 'assert'; -import {Observable} from 'rxjs'; -import {getLogger} from 'log4js'; -import * as BuckService from '../lib/BuckService'; -import {copyBuildFixture} from '../../nuclide-test-helpers'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import * as processJs from 'nuclide-commons/process'; - -// flowlint-next-line sketchy-null-string:off -if (!process.env.SANDCASTLE) { - // Disable buckd so it doesn't linger around after the test. - process.env.NO_BUCKD = '1'; -} else { - // Enable this on Sandcastle for faster tests. - process.env.NO_BUCKD = ''; -} - -beforeEach(() => { - // This timeout covers the average case. Blocks that need more time specify it - // themselves. - jasmine.getEnv().defaultTimeoutInterval = 10000; -}); - -describe('BuckService (test-project-with-failing-targets)', () => { - let buckRoot: string; - - beforeEach(() => { - waitsForPromise(async () => { - if (buckRoot == null) { - buckRoot = await copyBuildFixture( - 'test-project-with-failing-targets', - __dirname, - ); - } - }); - }); - - describe('.build(targets)', () => { - it('generates report even if there are failing targets', () => { - // First expensive buck operation gets a large timeout. - waitsForPromise({timeout: 30000}, async () => { - const targets = ['//:good_rule', '//:bad_rule']; - const report = await BuckService.build(buckRoot, targets); - const expectedReport = { - success: false, - results: { - '//:good_rule': { - success: true, - type: 'BUILT_LOCALLY', - output: 'buck-out/gen/good_rule/good.txt', - }, - '//:bad_rule': { - success: false, - }, - }, - failures: { - '//:bad_rule': jasmine.any(String), - }, - }; - expect(report).toEqual(expectedReport); - expect(report.failures.hasOwnProperty('//:bad_rule')).toBe(true); - }); - }); - - it('respects extra options', () => { - // Should immediately timeout. - jasmine.useRealClock(); - waitsForPromise(async () => { - try { - await BuckService.build(buckRoot, ['//:good_rule'], { - commandOptions: {timeout: 1}, - }); - } catch (e) { - expect(e.name).toBe('ProcessTimeoutError'); - return; - } - throw new Error('promise should have been rejected'); - }); - }); - - it('respects extra arguments', () => { - waitsForPromise(async () => { - try { - await BuckService.build(buckRoot, ['//:good_rule'], { - extraArguments: ['--help'], - }); - } catch (e) { - return; - } - throw new Error('promise should have been rejected'); - }); - }); - }); - - describe('.showOutput(aliasOrTarget)', () => { - it('returns the output data for a genrule()', () => { - waitsForPromise(async () => { - const output = await BuckService.showOutput(buckRoot, 'good'); - expect(output.length).toBe(1); - expect(output[0]['buck.outputPath']).toBe( - 'buck-out/gen/good_rule/good.txt', - ); - }); - }); - }); - - describe('.buildRuleTypeFor(aliasesOrTargets)', () => { - it('returns the type of a build rule specified by alias', () => { - waitsForPromise(async () => { - const resolved = await BuckService.buildRuleTypeFor(buckRoot, 'good'); - invariant(resolved != null); - expect(resolved.type).toBe('genrule'); - expect(resolved.buildTarget.qualifiedName).toBe('//:good_rule'); - expect(resolved.buildTarget.flavors.length).toBe(0); - }); - }); - - it('returns the type of a build rule by full path', () => { - waitsForPromise(async () => { - const resolved = await BuckService.buildRuleTypeFor( - buckRoot, - '//:good_rule', - ); - invariant(resolved != null); - expect(resolved.type).toBe('genrule'); - expect(resolved.buildTarget.qualifiedName).toBe('//:good_rule'); - expect(resolved.buildTarget.flavors.length).toBe(0); - }); - }); - - it('does some parsing on rule names', () => { - // To speed up this test, mock out the actual Buck process calls. - spyOn(processJs, 'runCommand').andReturn( - Observable.of( - JSON.stringify({ - '//:good_rule': { - 'buck.type': 'genrule', - }, - }), - ), - ); - - waitsForPromise(async () => { - // Omitting the // is fine too. - const resolved = await BuckService.buildRuleTypeFor( - buckRoot, - ':good_rule', - ); - invariant(resolved != null); - expect(resolved.type).toBe('genrule'); - expect(resolved.buildTarget.qualifiedName).toBe('//:good_rule'); - expect(resolved.buildTarget.flavors.length).toBe(0); - }); - - waitsForPromise(async () => { - // Strip out flavors. - const resolved = await BuckService.buildRuleTypeFor( - buckRoot, - '//:good_rule#', - ); - invariant(resolved != null); - expect(resolved.type).toBe('genrule'); - expect(resolved.buildTarget.qualifiedName).toBe('//:good_rule'); - expect(resolved.buildTarget.flavors[0]).toBe(''); - }); - - waitsForPromise(async () => { - // Strip out flavors. - const resolved = await BuckService.buildRuleTypeFor( - buckRoot, - '//:good_rule#foo', - ); - invariant(resolved != null); - expect(resolved.type).toBe('genrule'); - expect(resolved.buildTarget.qualifiedName).toBe('//:good_rule'); - expect(resolved.buildTarget.flavors[0]).toBe('foo'); - }); - }); - - it('works for multi-target rules', () => { - waitsForPromise(async () => { - const resolved = await BuckService.buildRuleTypeFor(buckRoot, '//:'); - invariant(resolved != null); - expect(resolved.type).toBe(BuckService.MULTIPLE_TARGET_RULE_TYPE); - expect(resolved.buildTarget.qualifiedName).toBe('//:'); - expect(resolved.buildTarget.flavors.length).toBe(0); - }); - - waitsForPromise(async () => { - const resolved = await BuckService.buildRuleTypeFor(buckRoot, '//...'); - invariant(resolved != null); - expect(resolved.type).toBe(BuckService.MULTIPLE_TARGET_RULE_TYPE); - expect(resolved.buildTarget.qualifiedName).toBe('//...'); - expect(resolved.buildTarget.flavors.length).toBe(0); - }); - }); - - it('fails when passed an invalid target', () => { - waitsForPromise(async () => { - const resolved = await BuckService.buildRuleTypeFor( - buckRoot, - '//not:athing', - ); - expect(resolved).toBeNull(); - }); - }); - - it('returns the type of a build rule specified by two aliases', () => { - waitsForPromise({timeout: 30000}, async () => { - const resolved = await BuckService.buildRuleTypeFor( - buckRoot, - 'good good2', - ); - invariant(resolved != null); - expect(resolved.type).toBe(BuckService.MULTIPLE_TARGET_RULE_TYPE); - expect(resolved.buildTarget.qualifiedName).toBe('good good2'); - expect(resolved.buildTarget.flavors.length).toBe(0); - }); - }); - }); -}); - -describe('BuckService (buck-query-project)', () => { - let buckRoot: string; - - beforeEach(() => { - waitsForPromise(async () => { - if (buckRoot == null) { - buckRoot = await copyBuildFixture('buck-query-project', __dirname); - } - }); - }); - - describe('getOwner()', () => { - it('gets the owner', () => { - // First expensive buck operation gets a large timeout. - waitsForPromise({timeout: 15000}, async () => { - let owners = await BuckService.getOwners( - buckRoot, - 'examples/one.java', - [], - ); - expect(owners.sort()).toEqual([ - '//examples:one', - '//examples:two-tests', - ]); - - owners = await BuckService.getOwners( - buckRoot, - 'examples/one.java', - [], - '.*_library', - ); - expect(owners).toEqual(['//examples:one']); - }); - }); - }); - - describe('getBuildFile()', () => { - it('gets the build file', () => { - waitsForPromise(async () => { - const file = await BuckService.getBuildFile(buckRoot, '//examples:one'); - expect(file).toBe(nuclideUri.join(buckRoot, 'examples', 'BUCK')); - }); - }); - - it('errors with non-existent rule', () => { - waitsForPromise(async () => { - const logger = getLogger('nuclide-buck-rpc'); - spyOn(logger, 'error'); - const file = await BuckService.getBuildFile(buckRoot, '//nonexistent:'); - expect(file).toBe(null); - // eslint-disable-next-line no-console - expect(logger.error.argsForCall[0]).toMatch( - /No build file for target "\/\/nonexistent:"/, - ); - }); - }); - }); -}); - -describe('BuckService (buckconfig-project)', () => { - let buckRoot: string; - - beforeEach(() => { - waitsForPromise(async () => { - if (buckRoot == null) { - buckRoot = await copyBuildFixture('buckconfig-project', __dirname); - } - }); - }); - - describe('getBuckConfig()', () => { - it('returns the correct value if present', () => { - // First expensive buck operation gets a large timeout. - waitsForPromise({timeout: 15000}, async () => { - const value = await BuckService.getBuckConfig(buckRoot, 'cache', 'dir'); - expect(value).toBe('buck-cache'); - }); - }); - - it('returns null if property is not set', () => { - waitsForPromise(async () => { - const value = await BuckService.getBuckConfig( - buckRoot, - 'cache', - 'http_timeout', - ); - expect(value).toBe(null); - }); - }); - - it('returns null if section is not present', () => { - waitsForPromise(async () => { - const value = await BuckService.getBuckConfig( - buckRoot, - 'android', - 'target', - ); - expect(value).toBe(null); - }); - }); - }); -}); diff --git a/pkg/nuclide-buck-rpc/spec/fixtures/buck-query-project/.buckconfig b/pkg/nuclide-buck-rpc/spec/fixtures/buck-query-project/.buckconfig deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/pkg/nuclide-buck-rpc/spec/fixtures/buck-query-project/examples/BUCK-rename b/pkg/nuclide-buck-rpc/spec/fixtures/buck-query-project/examples/BUCK-rename deleted file mode 100644 index bc6d8b2e97..0000000000 --- a/pkg/nuclide-buck-rpc/spec/fixtures/buck-query-project/examples/BUCK-rename +++ /dev/null @@ -1,45 +0,0 @@ -java_library( - name = 'one', - srcs = ['one.java'], - deps = [ - ':three', - ':two', - ], -) - -java_library( - name = 'two', - deps = [ - ':four', - ], -) - -java_library( - name = 'three', - deps = [ - ':five', - ':four', - ], -) - -java_library( - name = 'four', - deps = [ - ':five', - ] -) - -java_library( - name = 'five', -) - -java_test( - name = 'two-tests', - srcs = [ 'one.java' ], - deps = [ ':two' ], -) - -java_test( - name = 'three-tests', - deps = [ ':three' ], -) diff --git a/pkg/nuclide-buck-rpc/spec/fixtures/buck-query-project/examples/one.java b/pkg/nuclide-buck-rpc/spec/fixtures/buck-query-project/examples/one.java deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/pkg/nuclide-buck-rpc/spec/fixtures/buckconfig-project/.buckconfig b/pkg/nuclide-buck-rpc/spec/fixtures/buckconfig-project/.buckconfig deleted file mode 100644 index 767253e850..0000000000 --- a/pkg/nuclide-buck-rpc/spec/fixtures/buckconfig-project/.buckconfig +++ /dev/null @@ -1,2 +0,0 @@ -[cache] - dir = buck-cache diff --git a/pkg/nuclide-buck-rpc/spec/fixtures/test-project-with-failing-targets/.buckconfig b/pkg/nuclide-buck-rpc/spec/fixtures/test-project-with-failing-targets/.buckconfig deleted file mode 100644 index f9275fa472..0000000000 --- a/pkg/nuclide-buck-rpc/spec/fixtures/test-project-with-failing-targets/.buckconfig +++ /dev/null @@ -1,3 +0,0 @@ -[alias] - good = //:good_rule - good2 = //:good_rule_two diff --git a/pkg/nuclide-buck-rpc/spec/fixtures/test-project-with-failing-targets/BUCK-rename b/pkg/nuclide-buck-rpc/spec/fixtures/test-project-with-failing-targets/BUCK-rename deleted file mode 100644 index 6872ee844c..0000000000 --- a/pkg/nuclide-buck-rpc/spec/fixtures/test-project-with-failing-targets/BUCK-rename +++ /dev/null @@ -1,17 +0,0 @@ -genrule( - name = 'good_rule', - bash = 'echo good > $OUT', - out = 'good.txt', -) - -genrule( - name = 'good_rule_two', - bash = 'echo good > $OUT', - out = 'good.txt', -) - -genrule( - name = 'bad_rule', - bash = 'exit 1 && echo bad > $OUT', - out = 'bad.txt', -) diff --git a/pkg/nuclide-buck-rpc/spec/fixtures/test-project-with-failing-targets/README.md b/pkg/nuclide-buck-rpc/spec/fixtures/test-project-with-failing-targets/README.md deleted file mode 100644 index 6d15c2243d..0000000000 --- a/pkg/nuclide-buck-rpc/spec/fixtures/test-project-with-failing-targets/README.md +++ /dev/null @@ -1,4 +0,0 @@ -This project includes build targets that will fail to build. - -This is used to verify that `buck build --keep-going --build-report` will still -produce a build report when there are failing targets. diff --git a/pkg/nuclide-buck/__atom_tests__/DiagnosticsParser-test.js b/pkg/nuclide-buck/__atom_tests__/DiagnosticsParser-test.js index ea722591c1..9051fe223c 100644 --- a/pkg/nuclide-buck/__atom_tests__/DiagnosticsParser-test.js +++ b/pkg/nuclide-buck/__atom_tests__/DiagnosticsParser-test.js @@ -1,583 +1,370 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import {Range} from 'atom'; -import * as nuclideRemoteConnection from '../../nuclide-remote-connection'; -import { - INDEFINITE_END_COLUMN, - default as DiagnosticsParser, -} from '../lib/DiagnosticsParser'; +var _atom = require('atom'); + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = _interopRequireWildcard(require('../../nuclide-remote-connection')); +} + +var _DiagnosticsParser; + +function _load_DiagnosticsParser() { + return _DiagnosticsParser = require('../lib/DiagnosticsParser'); +} + +var _DiagnosticsParser2; + +function _load_DiagnosticsParser2() { + return _DiagnosticsParser2 = _interopRequireDefault(require('../lib/DiagnosticsParser')); +} + +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; } } describe('DiagnosticsProvider', () => { let diagnosticsParser; beforeEach(() => { - diagnosticsParser = new DiagnosticsParser(); - jest - .spyOn(nuclideRemoteConnection, 'getFileSystemServiceByNuclideUri') - .mockReturnValue({ - exists(filename) { - return Promise.resolve(filename.indexOf('good') !== -1); - }, - }); + diagnosticsParser = new (_DiagnosticsParser2 || _load_DiagnosticsParser2()).default(); + jest.spyOn(_nuclideRemoteConnection || _load_nuclideRemoteConnection(), 'getFileSystemServiceByNuclideUri').mockReturnValue({ + exists(filename) { + return Promise.resolve(filename.indexOf('good') !== -1); + } + }); }); it('matches all lines that look like errors', async () => { await (async () => { - const message = - 'good_file.cpp:1:2: test error\n' + - 'good_file.cpp:1:3: note: trace\n' + - 'good_file.cpp:1:4: note: trace2\n' + - 'good_file.cpp:1:2 bad line\n' + - 'good_file.cpp:12: bad line2\n' + - ':12:2: bad line3\n' + - 'good_file2.cpp:2:3: test error2\n' + - 'good_file2.cpp:2:4: note: trace\n'; + const message = 'good_file.cpp:1:2: test error\n' + 'good_file.cpp:1:3: note: trace\n' + 'good_file.cpp:1:4: note: trace2\n' + 'good_file.cpp:1:2 bad line\n' + 'good_file.cpp:12: bad line2\n' + ':12:2: bad line3\n' + 'good_file2.cpp:2:3: test error2\n' + 'good_file2.cpp:2:4: note: trace\n'; - expect( - await diagnosticsParser.getDiagnostics(message, 'error', '/'), - ).toEqual([ - { - providerName: 'Buck', - type: 'Error', + expect((await diagnosticsParser.getDiagnostics(message, 'error', '/'))).toEqual([{ + providerName: 'Buck', + type: 'Error', + filePath: '/good_file.cpp', + text: 'test error', + range: new _atom.Range([0, 1], [0, 1]), + trace: [{ + type: 'Trace', + text: 'note: trace', + filePath: '/good_file.cpp', + range: new _atom.Range([0, 2], [0, 2]) + }, { + type: 'Trace', + text: 'note: trace2', filePath: '/good_file.cpp', - text: 'test error', - range: new Range([0, 1], [0, 1]), - trace: [ - { - type: 'Trace', - text: 'note: trace', - filePath: '/good_file.cpp', - range: new Range([0, 2], [0, 2]), - }, - { - type: 'Trace', - text: 'note: trace2', - filePath: '/good_file.cpp', - range: new Range([0, 3], [0, 3]), - }, - ], - }, - { - providerName: 'Buck', - type: 'Error', + range: new _atom.Range([0, 3], [0, 3]) + }] + }, { + providerName: 'Buck', + type: 'Error', + filePath: '/good_file2.cpp', + text: 'test error2', + range: new _atom.Range([1, 2], [1, 2]), + trace: [{ + type: 'Trace', + text: 'note: trace', filePath: '/good_file2.cpp', - text: 'test error2', - range: new Range([1, 2], [1, 2]), - trace: [ - { - type: 'Trace', - text: 'note: trace', - filePath: '/good_file2.cpp', - range: new Range([1, 3], [1, 3]), - }, - ], - }, - ]); + range: new _atom.Range([1, 3], [1, 3]) + }] + }]); })(); }); it('resolves absolute paths', async () => { await (async () => { const message = '/a/good_file.cpp:1:2: test error'; - expect( - await diagnosticsParser.getDiagnostics(message, 'error', '/root'), - ).toEqual([ - { - providerName: 'Buck', - type: 'Error', - filePath: '/a/good_file.cpp', - text: 'test error', - range: new Range([0, 1], [0, 1]), - }, - ]); + expect((await diagnosticsParser.getDiagnostics(message, 'error', '/root'))).toEqual([{ + providerName: 'Buck', + type: 'Error', + filePath: '/a/good_file.cpp', + text: 'test error', + range: new _atom.Range([0, 1], [0, 1]) + }]); })(); }); it('ignores non-existent files', async () => { await (async () => { const message = 'bad_file.cpp:1:2: test error'; - expect( - await diagnosticsParser.getDiagnostics(message, 'error', '/'), - ).toEqual([]); + expect((await diagnosticsParser.getDiagnostics(message, 'error', '/'))).toEqual([]); })(); }); it('matches a line that looks like a test failure', async () => { await (async () => { - const diagnostics = Promise.all([ - diagnosticsParser.getDiagnostics( - 'PASS <100ms 6 Passed 0 Skipped 0 Failed FooTests', - 'error', - '/', - ), - diagnosticsParser.getDiagnostics( - 'FAIL <100ms 4 Passed 0 Skipped 1 Failed BarTests', - 'error', - '/', - ), - diagnosticsParser.getDiagnostics( - 'FAILURE BarTests -[BarTests testBaz]: good/path/to/BarTests.m:42: failure description', - 'error', - '/', - ), - diagnosticsParser.getDiagnostics( - 'PASS <100ms 3 Passed 0 Skipped 0 Failed BazTests', - 'error', - '/', - ), - ]); - expect(await diagnostics).toEqual([ - [], - [], - [ - { - providerName: 'Buck', - type: 'Error', - filePath: '/good/path/to/BarTests.m', - text: 'failure description', - range: { - start: { - row: 41, - column: 0, - }, - end: { - row: 41, - column: INDEFINITE_END_COLUMN, - }, - }, + const diagnostics = Promise.all([diagnosticsParser.getDiagnostics('PASS <100ms 6 Passed 0 Skipped 0 Failed FooTests', 'error', '/'), diagnosticsParser.getDiagnostics('FAIL <100ms 4 Passed 0 Skipped 1 Failed BarTests', 'error', '/'), diagnosticsParser.getDiagnostics('FAILURE BarTests -[BarTests testBaz]: good/path/to/BarTests.m:42: failure description', 'error', '/'), diagnosticsParser.getDiagnostics('PASS <100ms 3 Passed 0 Skipped 0 Failed BazTests', 'error', '/')]); + expect((await diagnostics)).toEqual([[], [], [{ + providerName: 'Buck', + type: 'Error', + filePath: '/good/path/to/BarTests.m', + text: 'failure description', + range: { + start: { + row: 41, + column: 0 }, - ], - [], - ]); + end: { + row: 41, + column: (_DiagnosticsParser || _load_DiagnosticsParser()).INDEFINITE_END_COLUMN + } + } + }], []]); })(); }); it('matches multiple test failures from the same test', async () => { await (async () => { - const diagnostics = Promise.all([ - diagnosticsParser.getDiagnostics( - 'PASS <100ms 6 Passed 0 Skipped 0 Failed FooTests', - 'error', - '/', - ), - diagnosticsParser.getDiagnostics( - 'FAIL <100ms 4 Passed 0 Skipped 1 Failed BarTests', - 'error', - '/', - ), - diagnosticsParser.getDiagnostics( - 'FAILURE BarTests -[BarTests testBaz]: good/path/to/BarTests.m:91: failure one', - 'error', - '/', - ), - diagnosticsParser.getDiagnostics( - 'good/path/to/BarTests.m:92: failure two', - 'error', - '/', - ), - diagnosticsParser.getDiagnostics( - 'good/path/to/BarTests.m:98: failure three', - 'error', - '/', - ), - diagnosticsParser.getDiagnostics( - 'PASS <100ms 3 Passed 0 Skipped 0 Failed BazTests', - 'error', - '/', - ), - ]); + const diagnostics = Promise.all([diagnosticsParser.getDiagnostics('PASS <100ms 6 Passed 0 Skipped 0 Failed FooTests', 'error', '/'), diagnosticsParser.getDiagnostics('FAIL <100ms 4 Passed 0 Skipped 1 Failed BarTests', 'error', '/'), diagnosticsParser.getDiagnostics('FAILURE BarTests -[BarTests testBaz]: good/path/to/BarTests.m:91: failure one', 'error', '/'), diagnosticsParser.getDiagnostics('good/path/to/BarTests.m:92: failure two', 'error', '/'), diagnosticsParser.getDiagnostics('good/path/to/BarTests.m:98: failure three', 'error', '/'), diagnosticsParser.getDiagnostics('PASS <100ms 3 Passed 0 Skipped 0 Failed BazTests', 'error', '/')]); - expect(await diagnostics).toEqual([ - [], - [], - [ - { - providerName: 'Buck', - type: 'Error', - filePath: '/good/path/to/BarTests.m', - text: 'failure one', - range: { - start: { - row: 90, - column: 0, - }, - end: { - row: 90, - column: INDEFINITE_END_COLUMN, - }, - }, + expect((await diagnostics)).toEqual([[], [], [{ + providerName: 'Buck', + type: 'Error', + filePath: '/good/path/to/BarTests.m', + text: 'failure one', + range: { + start: { + row: 90, + column: 0 }, - ], - [ - { - providerName: 'Buck', - type: 'Error', - filePath: '/good/path/to/BarTests.m', - text: 'failure two', - range: { - start: { - row: 91, - column: 0, - }, - end: { - row: 91, - column: INDEFINITE_END_COLUMN, - }, - }, + end: { + row: 90, + column: (_DiagnosticsParser || _load_DiagnosticsParser()).INDEFINITE_END_COLUMN + } + } + }], [{ + providerName: 'Buck', + type: 'Error', + filePath: '/good/path/to/BarTests.m', + text: 'failure two', + range: { + start: { + row: 91, + column: 0 }, - ], - [ - { - providerName: 'Buck', - type: 'Error', - filePath: '/good/path/to/BarTests.m', - text: 'failure three', - range: { - start: { - row: 97, - column: 0, - }, - end: { - row: 97, - column: INDEFINITE_END_COLUMN, - }, - }, + end: { + row: 91, + column: (_DiagnosticsParser || _load_DiagnosticsParser()).INDEFINITE_END_COLUMN + } + } + }], [{ + providerName: 'Buck', + type: 'Error', + filePath: '/good/path/to/BarTests.m', + text: 'failure three', + range: { + start: { + row: 97, + column: 0 }, - ], - [], - ]); + end: { + row: 97, + column: (_DiagnosticsParser || _load_DiagnosticsParser()).INDEFINITE_END_COLUMN + } + } + }], []]); })(); }); it('matches multiple test failures', async () => { await (async () => { - const diagnostics = Promise.all([ - diagnosticsParser.getDiagnostics( - 'PASS <100ms 6 Passed 0 Skipped 0 Failed FooTests', - 'error', - '/', - ), - diagnosticsParser.getDiagnostics( - 'FAIL <100ms 4 Passed 0 Skipped 1 Failed BarTests', - 'error', - '/', - ), - diagnosticsParser.getDiagnostics( - 'FAILURE BarTests -[BarTests testBaz]: good/path/to/BarTests.m:91: failure one', - 'error', - '/', - ), - diagnosticsParser.getDiagnostics( - 'PASS <100ms 3 Passed 0 Skipped 0 Failed BazTests', - 'error', - '/', - ), - diagnosticsParser.getDiagnostics( - 'FAIL <100ms 1 Passed 0 Skipped 1 Failed QuxTests', - 'error', - '/', - ), - diagnosticsParser.getDiagnostics( - 'FAILURE QuxTests -[QuxTests testNoz]: good/path/to/QuxTests.m:3: failure one', - 'error', - '/', - ), - diagnosticsParser.getDiagnostics( - 'good/path/to/QuxTests.m:25: failure two', - 'error', - '/', - ), - ]); + const diagnostics = Promise.all([diagnosticsParser.getDiagnostics('PASS <100ms 6 Passed 0 Skipped 0 Failed FooTests', 'error', '/'), diagnosticsParser.getDiagnostics('FAIL <100ms 4 Passed 0 Skipped 1 Failed BarTests', 'error', '/'), diagnosticsParser.getDiagnostics('FAILURE BarTests -[BarTests testBaz]: good/path/to/BarTests.m:91: failure one', 'error', '/'), diagnosticsParser.getDiagnostics('PASS <100ms 3 Passed 0 Skipped 0 Failed BazTests', 'error', '/'), diagnosticsParser.getDiagnostics('FAIL <100ms 1 Passed 0 Skipped 1 Failed QuxTests', 'error', '/'), diagnosticsParser.getDiagnostics('FAILURE QuxTests -[QuxTests testNoz]: good/path/to/QuxTests.m:3: failure one', 'error', '/'), diagnosticsParser.getDiagnostics('good/path/to/QuxTests.m:25: failure two', 'error', '/')]); - expect(await diagnostics).toEqual([ - [], - [], - [ - { - providerName: 'Buck', - type: 'Error', - filePath: '/good/path/to/BarTests.m', - text: 'failure one', - range: { - start: { - row: 90, - column: 0, - }, - end: { - row: 90, - column: INDEFINITE_END_COLUMN, - }, - }, + expect((await diagnostics)).toEqual([[], [], [{ + providerName: 'Buck', + type: 'Error', + filePath: '/good/path/to/BarTests.m', + text: 'failure one', + range: { + start: { + row: 90, + column: 0 }, - ], - [], - [], - [ - { - providerName: 'Buck', - type: 'Error', - filePath: '/good/path/to/QuxTests.m', - text: 'failure one', - range: { - start: { - row: 2, - column: 0, - }, - end: { - row: 2, - column: INDEFINITE_END_COLUMN, - }, - }, + end: { + row: 90, + column: (_DiagnosticsParser || _load_DiagnosticsParser()).INDEFINITE_END_COLUMN + } + } + }], [], [], [{ + providerName: 'Buck', + type: 'Error', + filePath: '/good/path/to/QuxTests.m', + text: 'failure one', + range: { + start: { + row: 2, + column: 0 }, - ], - [ - { - providerName: 'Buck', - type: 'Error', - filePath: '/good/path/to/QuxTests.m', - text: 'failure two', - range: { - start: { - row: 24, - column: 0, - }, - end: { - row: 24, - column: INDEFINITE_END_COLUMN, - }, - }, + end: { + row: 2, + column: (_DiagnosticsParser || _load_DiagnosticsParser()).INDEFINITE_END_COLUMN + } + } + }], [{ + providerName: 'Buck', + type: 'Error', + filePath: '/good/path/to/QuxTests.m', + text: 'failure two', + range: { + start: { + row: 24, + column: 0 }, - ], - ]); + end: { + row: 24, + column: (_DiagnosticsParser || _load_DiagnosticsParser()).INDEFINITE_END_COLUMN + } + } + }]]); })(); }); it('matches multiple test failures, even when they appear in an order not found in Buck', async () => { await (async () => { - const diagnostics = Promise.all([ - diagnosticsParser.getDiagnostics( - 'FAILURE BarTests -[FooTests testBar]: good/path/to/FooTests.m:1: failure one', - 'error', - '/', - ), - // Normally Buck would output a line beginning with "FAIL" here, but - // this test verifies what happens if it doesn't for some reason. - diagnosticsParser.getDiagnostics( - 'FAILURE BazTests -[BazTests testQux]: good/path/to/BazTests.m:2: failure two', - 'error', - '/', - ), - ]); + const diagnostics = Promise.all([diagnosticsParser.getDiagnostics('FAILURE BarTests -[FooTests testBar]: good/path/to/FooTests.m:1: failure one', 'error', '/'), + // Normally Buck would output a line beginning with "FAIL" here, but + // this test verifies what happens if it doesn't for some reason. + diagnosticsParser.getDiagnostics('FAILURE BazTests -[BazTests testQux]: good/path/to/BazTests.m:2: failure two', 'error', '/')]); - expect(await diagnostics).toEqual([ - [ - { - providerName: 'Buck', - type: 'Error', - filePath: '/good/path/to/FooTests.m', - text: 'failure one', - range: { - start: { - row: 0, - column: 0, - }, - end: { - row: 0, - column: INDEFINITE_END_COLUMN, - }, - }, + expect((await diagnostics)).toEqual([[{ + providerName: 'Buck', + type: 'Error', + filePath: '/good/path/to/FooTests.m', + text: 'failure one', + range: { + start: { + row: 0, + column: 0 }, - ], - [ - { - providerName: 'Buck', - type: 'Error', - filePath: '/good/path/to/BazTests.m', - text: 'failure two', - range: { - start: { - row: 1, - column: 0, - }, - end: { - row: 1, - column: INDEFINITE_END_COLUMN, - }, - }, + end: { + row: 0, + column: (_DiagnosticsParser || _load_DiagnosticsParser()).INDEFINITE_END_COLUMN + } + } + }], [{ + providerName: 'Buck', + type: 'Error', + filePath: '/good/path/to/BazTests.m', + text: 'failure two', + range: { + start: { + row: 1, + column: 0 }, - ], - ]); + end: { + row: 1, + column: (_DiagnosticsParser || _load_DiagnosticsParser()).INDEFINITE_END_COLUMN + } + } + }]]); })(); }); it('matches ocaml errors in Buck', async () => { await (async () => { - const diagnostics = Promise.all([ - diagnosticsParser.getDiagnostics( - 'File "/a/good_file.ml", line 2, characters 10-12:\n' + - 'Error: Unbound value a\n' + - 'Hint: Did you mean b?', - 'error', - '/', - ), - diagnosticsParser.getDiagnostics( - 'File "/a/good_file2.ml", line 10, characters 15-17:\n' + - 'Error: whatever error', - 'error', - '/', - ), - ]); + const diagnostics = Promise.all([diagnosticsParser.getDiagnostics('File "/a/good_file.ml", line 2, characters 10-12:\n' + 'Error: Unbound value a\n' + 'Hint: Did you mean b?', 'error', '/'), diagnosticsParser.getDiagnostics('File "/a/good_file2.ml", line 10, characters 15-17:\n' + 'Error: whatever error', 'error', '/')]); - expect(await diagnostics).toEqual([ - [ - { - providerName: 'Buck', - type: 'Error', - filePath: '/a/good_file.ml', - text: 'Error: Unbound value a, Hint: Did you mean b?', - range: { - start: { - row: 1, - column: 9, - }, - end: { - row: 1, - column: 9, - }, - }, + expect((await diagnostics)).toEqual([[{ + providerName: 'Buck', + type: 'Error', + filePath: '/a/good_file.ml', + text: 'Error: Unbound value a, Hint: Did you mean b?', + range: { + start: { + row: 1, + column: 9 }, - ], - [ - { - providerName: 'Buck', - type: 'Error', - filePath: '/a/good_file2.ml', - text: 'Error: whatever error', - range: { - start: { - row: 9, - column: 14, - }, - end: { - row: 9, - column: 14, - }, - }, + end: { + row: 1, + column: 9 + } + } + }], [{ + providerName: 'Buck', + type: 'Error', + filePath: '/a/good_file2.ml', + text: 'Error: whatever error', + range: { + start: { + row: 9, + column: 14 }, - ], - ]); + end: { + row: 9, + column: 14 + } + } + }]]); })(); }); it('matches ocaml warnings', async () => { await (async () => { - const message = - 'File "/a/good_file.ml", line 2, characters 10-12:\n' + - 'Warning: Unbound value a'; + const message = 'File "/a/good_file.ml", line 2, characters 10-12:\n' + 'Warning: Unbound value a'; - expect( - await diagnosticsParser.getDiagnostics(message, 'warning', '/'), - ).toEqual([ - { - providerName: 'Buck', - type: 'Warning', - filePath: '/a/good_file.ml', - text: 'Warning: Unbound value a', - range: new Range([1, 9], [1, 9]), - }, - ]); + expect((await diagnosticsParser.getDiagnostics(message, 'warning', '/'))).toEqual([{ + providerName: 'Buck', + type: 'Warning', + filePath: '/a/good_file.ml', + text: 'Warning: Unbound value a', + range: new _atom.Range([1, 9], [1, 9]) + }]); })(); }); it('matches rustc errors in Buck', async () => { await (async () => { - const diagnostics = Promise.all([ - diagnosticsParser.getDiagnostics( - 'error: expected one of `.`, `;`, `?`, `}`, or an operator, found `breakage`\n' + - ' --> buck-out/foo/bar#some-container/good/path/to/hello.rs:11:5\n' + - ' |\n' + - '9 | println!("Rust says \'Hello World!\'")\n' + - ' | - expected one of `.`, `;`, `?`, `}`, or an operator here\n' + - '10 | \n' + - '11 | breakage\n' + - ' | ^^^^^^^^ unexpected token\n' + - '\n' + - 'error: aborting due to previous error', - 'error', - '/ROOT/PATH', - ), - ]); + const diagnostics = Promise.all([diagnosticsParser.getDiagnostics('error: expected one of `.`, `;`, `?`, `}`, or an operator, found `breakage`\n' + ' --> buck-out/foo/bar#some-container/good/path/to/hello.rs:11:5\n' + ' |\n' + '9 | println!("Rust says \'Hello World!\'")\n' + ' | - expected one of `.`, `;`, `?`, `}`, or an operator here\n' + '10 | \n' + '11 | breakage\n' + ' | ^^^^^^^^ unexpected token\n' + '\n' + 'error: aborting due to previous error', 'error', '/ROOT/PATH')]); - expect(await diagnostics).toEqual([ - [ - { - providerName: 'Buck', - type: 'Error', - filePath: - '/ROOT/PATH/buck-out/foo/bar#some-container/good/path/to/hello.rs', - text: - 'error: expected one of `.`, `;`, `?`, `}`, or an operator, found `breakage`', - range: { - start: { - row: 10, - column: 4, - }, - end: { - row: 10, - column: 4, - }, - }, + expect((await diagnostics)).toEqual([[{ + providerName: 'Buck', + type: 'Error', + filePath: '/ROOT/PATH/buck-out/foo/bar#some-container/good/path/to/hello.rs', + text: 'error: expected one of `.`, `;`, `?`, `}`, or an operator, found `breakage`', + range: { + start: { + row: 10, + column: 4 }, - ], - ]); + end: { + row: 10, + column: 4 + } + } + }]]); })(); }); it('matches rustc warnings in Buck', async () => { await (async () => { - const diagnostics = Promise.all([ - diagnosticsParser.getDiagnostics( - 'warning: unused variable: `unused`\n' + - ' --> some-container/good/path/to/hello.rs:10:9\n' + - ' |\n' + - '10 | let unused = 44;\n' + - ' | ^^^^^^\n' + - ' |\n' + - ' = note: #[warn(unused_variables)] on by default' + - 'error: aborting due to previous error', - 'error', - '/ROOT/PATH', - ), - ]); + const diagnostics = Promise.all([diagnosticsParser.getDiagnostics('warning: unused variable: `unused`\n' + ' --> some-container/good/path/to/hello.rs:10:9\n' + ' |\n' + '10 | let unused = 44;\n' + ' | ^^^^^^\n' + ' |\n' + ' = note: #[warn(unused_variables)] on by default' + 'error: aborting due to previous error', 'error', '/ROOT/PATH')]); - expect(await diagnostics).toEqual([ - [ - { - providerName: 'Buck', - type: 'Warning', - filePath: '/ROOT/PATH/some-container/good/path/to/hello.rs', - text: 'warning: unused variable: `unused`', - range: { - start: { - row: 9, - column: 8, - }, - end: { - row: 9, - column: 8, - }, - }, + expect((await diagnostics)).toEqual([[{ + providerName: 'Buck', + type: 'Warning', + filePath: '/ROOT/PATH/some-container/good/path/to/hello.rs', + text: 'warning: unused variable: `unused`', + range: { + start: { + row: 9, + column: 8 }, - ], - ]); + end: { + row: 9, + column: 8 + } + } + }]]); })(); }); -}); +}); /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-buck/__atom_tests__/HyperclickProvider-test.js b/pkg/nuclide-buck/__atom_tests__/HyperclickProvider-test.js index 669668c2d5..bbc196be33 100644 --- a/pkg/nuclide-buck/__atom_tests__/HyperclickProvider-test.js +++ b/pkg/nuclide-buck/__atom_tests__/HyperclickProvider-test.js @@ -1,3 +1,19 @@ +'use strict'; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _HyperclickProvider; + +function _load_HyperclickProvider() { + return _HyperclickProvider = require('../lib/HyperclickProvider'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,61 +21,36 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import nuclideUri from 'nuclide-commons/nuclideUri'; - -import { - findTargetLocation, - parseTarget, - resolveLoadTargetPath, -} from '../lib/HyperclickProvider'; - describe('HyperclickProvider', () => { - let projectPath: string = (null: any); + let projectPath = null; beforeEach(() => { - projectPath = - nuclideUri.join(__dirname, '../__mocks__/fixtures/test-project') + '/'; + projectPath = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures/test-project') + '/'; atom.project.setPaths([projectPath]); }); describe('parseTarget', () => { it('searches //Apps/TestApp/BUCK-rename', async () => { - let target = await parseTarget( - ([':target1', null, 'target1']: Array), - null, - projectPath, - ); + let target = await (0, (_HyperclickProvider || _load_HyperclickProvider()).parseTarget)([':target1', null, 'target1'], null, projectPath); expect(target).toBe(null); - target = await parseTarget( - ([':target1', null, 'target1']: Array), - projectPath + 'test/BUCK', - projectPath, - ); + target = await (0, (_HyperclickProvider || _load_HyperclickProvider()).parseTarget)([':target1', null, 'target1'], projectPath + 'test/BUCK', projectPath); expect(target).toEqual({ path: projectPath + 'test/BUCK', - name: 'target1', + name: 'target1' }); - target = await parseTarget( - (['//Apps/TestApp:w3ird', '//Apps/TestApp', 'w3ird']: Array), - null, - projectPath, - ); + target = await (0, (_HyperclickProvider || _load_HyperclickProvider()).parseTarget)(['//Apps/TestApp:w3ird', '//Apps/TestApp', 'w3ird'], null, projectPath); expect(target).toEqual(null); - target = await parseTarget( - (['//Apps/TestApp:w3ird', '//Apps/TestApp', 'w3ird']: Array), - '//test/BUCK', - projectPath, - ); + target = await (0, (_HyperclickProvider || _load_HyperclickProvider()).parseTarget)(['//Apps/TestApp:w3ird', '//Apps/TestApp', 'w3ird'], '//test/BUCK', projectPath); expect(target).toEqual({ path: projectPath + 'Apps/TestApp/BUCK', - name: 'w3ird', + name: 'w3ird' }); }); }); @@ -67,12 +58,7 @@ describe('HyperclickProvider', () => { describe('parseLoadTarget', () => { it('resolves a path for //pkg/subpkg:ext.bzl', async () => { await (async () => { - const target = await resolveLoadTargetPath( - (['//pkg/subpkg:ext.bzl', '', '//pkg/subpkg', 'ext.bzl']: Array< - string, - >), - projectPath, - ); + const target = await (0, (_HyperclickProvider || _load_HyperclickProvider()).resolveLoadTargetPath)(['//pkg/subpkg:ext.bzl', '', '//pkg/subpkg', 'ext.bzl'], projectPath); expect(target).toEqual(projectPath + 'pkg/subpkg/ext.bzl'); })(); }); @@ -85,10 +71,10 @@ describe('HyperclickProvider', () => { 'w3ird_target-name': 7, Target2: 13, TestsTarget: 27, - 'non-existing-target': -1, + 'non-existing-target': -1 }, 'Apps/BUCK-rename': { - test_target123: 1, + test_target123: 1 }, 'Libraries/TestLib1/BUCK-rename': { target_with_no_trailling_comma: 1, @@ -98,36 +84,36 @@ describe('HyperclickProvider', () => { lib_target: -1, TestsTarget: 23, PUBLIC: -1, - '[]': -1, + '[]': -1 }, 'Libraries/TestLib1/test-ios-sdk/sdk-v.1.2.3/BUCK-rename': { 'target-v.1': 1, target: 7, targett: -1, - arget: -1, - }, + arget: -1 + } }; for (const file in targetsByFile) { for (const targetName in targetsByFile[file]) { it('asks for a location of the target', async () => { await (() => { - return findTargetLocation({ + return (0, (_HyperclickProvider || _load_HyperclickProvider()).findTargetLocation)({ path: projectPath + file, - name: targetName, + name: targetName }).then(location => { const line = targetsByFile[file][targetName]; if (line !== -1) { expect(location).toEqual({ path: projectPath + file, line, - column: 0, + column: 0 }); } else { expect(location).toEqual({ path: projectPath + file, line: 0, - column: 0, + column: 0 }); } }); @@ -136,4 +122,4 @@ describe('HyperclickProvider', () => { } } }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-buck/__tests__/BuckBuildSystem-test.js b/pkg/nuclide-buck/__tests__/BuckBuildSystem-test.js index 900d386e2b..aa66eb1683 100644 --- a/pkg/nuclide-buck/__tests__/BuckBuildSystem-test.js +++ b/pkg/nuclide-buck/__tests__/BuckBuildSystem-test.js @@ -1,3 +1,13 @@ +'use strict'; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _BuckBuildSystem; + +function _load_BuckBuildSystem() { + return _BuckBuildSystem = require('../lib/BuckBuildSystem'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,97 +15,67 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import {Observable} from 'rxjs'; -import {BuckBuildSystem} from '../lib/BuckBuildSystem'; -import invariant from 'assert'; - describe('BuckBuildSystem', () => { let buckBuildSystem; beforeEach(() => { - buckBuildSystem = new BuckBuildSystem(); + buckBuildSystem = new (_BuckBuildSystem || _load_BuckBuildSystem()).BuckBuildSystem(); }); describe('_consumeEventStream', () => { it("doesn't swallow log messages", async () => { await (async () => { - const result = await buckBuildSystem - ._consumeEventStream( - Observable.from([ - {type: 'log', message: 'test', level: 'error'}, - {type: 'log', message: 'test2', level: 'warning'}, - {type: 'progress', progress: 1}, - ]), - '', - ) - .toArray() - .toPromise(); + const result = await buckBuildSystem._consumeEventStream(_rxjsBundlesRxMinJs.Observable.from([{ type: 'log', message: 'test', level: 'error' }, { type: 'log', message: 'test2', level: 'warning' }, { type: 'progress', progress: 1 }]), '').toArray().toPromise(); - expect(result).toEqual([ - {type: 'message', message: {text: 'test', level: 'error'}}, - {type: 'message', message: {text: 'test2', level: 'warning'}}, - {type: 'progress', progress: 1}, - ]); + expect(result).toEqual([{ type: 'message', message: { text: 'test', level: 'error' } }, { type: 'message', message: { text: 'test2', level: 'warning' } }, { type: 'progress', progress: 1 }]); })(); }); it('emits diagnostics', async () => { - const diagnostics = [] - const subscription = buckBuildSystem - .getDiagnosticProvider() - .updates.subscribe(update => { - // Make a deep copy (since the messages will change.) - const deepCopy = Array.from(update.entries()) - .map(([key, value]) => [key, Array.from(value)]); - diagnostics.push(new Map(deepCopy)); - }); + const diagnostics = []; + const subscription = buckBuildSystem.getDiagnosticProvider().updates.subscribe(update => { + // Make a deep copy (since the messages will change.) + const deepCopy = Array.from(update.entries()).map(([key, value]) => [key, Array.from(value)]); + diagnostics.push(new Map(deepCopy)); + }); const diagnostic = { providerName: 'Buck', type: 'Error', - filePath: 'a', + filePath: 'a' }; - const result = await buckBuildSystem - ._consumeEventStream( - Observable.from([ - { - type: 'diagnostics', - diagnostics: [diagnostic], - }, - { - type: 'diagnostics', - diagnostics: [{...diagnostic, type: 'Warning'}], - }, - { - type: 'diagnostics', - diagnostics: [{...diagnostic, filePath: 'b'}], - }, - ]), - '', - ) - .toArray() - .toPromise(); + const result = await buckBuildSystem._consumeEventStream(_rxjsBundlesRxMinJs.Observable.from([{ + type: 'diagnostics', + diagnostics: [diagnostic] + }, { + type: 'diagnostics', + diagnostics: [Object.assign({}, diagnostic, { type: 'Warning' })] + }, { + type: 'diagnostics', + diagnostics: [Object.assign({}, diagnostic, { filePath: 'b' })] + }]), '').toArray().toPromise(); // Check for the message indicating to look in diagnostics. expect(result.length).toEqual(1); const msg = result[0]; expect(msg.type).toEqual('message'); - invariant(msg.type === 'message'); + + if (!(msg.type === 'message')) { + throw new Error('Invariant violation: "msg.type === \'message\'"'); + } + expect(msg.message.level).toEqual('info'); expect(msg.message.text).toContain('Diagnostics'); - expect(diagnostics).toEqual([ - new Map([['a', [diagnostic]]]), - new Map([['a', [diagnostic, {...diagnostic, type: 'Warning'}]]]), - // No need to emit diagnostics for 'a' again. - new Map([['b', [{...diagnostic, filePath: 'b'}]]]), - ]); + expect(diagnostics).toEqual([new Map([['a', [diagnostic]]]), new Map([['a', [diagnostic, Object.assign({}, diagnostic, { type: 'Warning' })]]]), + // No need to emit diagnostics for 'a' again. + new Map([['b', [Object.assign({}, diagnostic, { filePath: 'b' })]]])]); subscription.unsubscribe(); }); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-buck/__tests__/BuckEventStream-test.js b/pkg/nuclide-buck/__tests__/BuckEventStream-test.js index c5fba1c3c9..6bf6e7644f 100644 --- a/pkg/nuclide-buck/__tests__/BuckEventStream-test.js +++ b/pkg/nuclide-buck/__tests__/BuckEventStream-test.js @@ -1,3 +1,13 @@ +'use strict'; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _BuckEventStream; + +function _load_BuckEventStream() { + return _BuckEventStream = require('../lib/BuckEventStream'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,135 +15,92 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import {Subject} from 'rxjs'; -import {combineEventStreams} from '../lib/BuckEventStream'; - describe('combineEventStreams', () => { let socketSubject; let processSubject; beforeEach(() => { - socketSubject = new Subject(); - processSubject = new Subject(); + socketSubject = new _rxjsBundlesRxMinJs.Subject(); + processSubject = new _rxjsBundlesRxMinJs.Subject(); }); it('takes non-log-level messages from the process', async () => { await (async () => { - const combinedStream = combineEventStreams( - 'build', - socketSubject, - processSubject, - ); + const combinedStream = (0, (_BuckEventStream || _load_BuckEventStream()).combineEventStreams)('build', socketSubject, processSubject); const promise = combinedStream.toArray().toPromise(); - socketSubject.next({type: 'progress', progress: 0}); + socketSubject.next({ type: 'progress', progress: 0 }); - processSubject.next({type: 'log', message: 'skip', level: 'log'}); - processSubject.next({type: 'log', message: 'take1', level: 'error'}); - processSubject.next({type: 'log', message: 'take2', level: 'log'}); + processSubject.next({ type: 'log', message: 'skip', level: 'log' }); + processSubject.next({ type: 'log', message: 'take1', level: 'error' }); + processSubject.next({ type: 'log', message: 'take2', level: 'log' }); processSubject.complete(); const result = await promise; - expect(result).toEqual([ - {type: 'progress', progress: 0}, - {type: 'log', message: 'take1', level: 'error'}, - {type: 'log', message: 'take2', level: 'log'}, - ]); + expect(result).toEqual([{ type: 'progress', progress: 0 }, { type: 'log', message: 'take1', level: 'error' }, { type: 'log', message: 'take2', level: 'log' }]); })(); }); it('falls back to process output when socket is empty', async () => { await (async () => { - const combinedStream = combineEventStreams( - 'build', - socketSubject, - processSubject, - ); + const combinedStream = (0, (_BuckEventStream || _load_BuckEventStream()).combineEventStreams)('build', socketSubject, processSubject); const promise = combinedStream.toArray().toPromise(); - processSubject.next({type: 'log', message: 'take1', level: 'log'}); - processSubject.next({type: 'log', message: 'take2', level: 'log'}); - processSubject.next({type: 'log', message: 'take3', level: 'error'}); + processSubject.next({ type: 'log', message: 'take1', level: 'log' }); + processSubject.next({ type: 'log', message: 'take2', level: 'log' }); + processSubject.next({ type: 'log', message: 'take3', level: 'error' }); processSubject.complete(); const result = await promise; - expect(result).toEqual([ - {type: 'log', message: 'take1', level: 'log'}, - {type: 'log', message: 'take2', level: 'log'}, - {type: 'log', message: 'take3', level: 'error'}, - ]); + expect(result).toEqual([{ type: 'log', message: 'take1', level: 'log' }, { type: 'log', message: 'take2', level: 'log' }, { type: 'log', message: 'take3', level: 'error' }]); })(); }); it('test: takes process messages after build finishes', async () => { await (async () => { - const combinedStream = combineEventStreams( - 'test', - socketSubject, - processSubject, - ); + const combinedStream = (0, (_BuckEventStream || _load_BuckEventStream()).combineEventStreams)('test', socketSubject, processSubject); const promise = combinedStream.toArray().toPromise(); - processSubject.next({type: 'log', message: 'take', level: 'log'}); - socketSubject.next({type: 'progress', progress: 1}); - processSubject.next({type: 'log', message: 'take', level: 'log'}); + processSubject.next({ type: 'log', message: 'take', level: 'log' }); + socketSubject.next({ type: 'progress', progress: 1 }); + processSubject.next({ type: 'log', message: 'take', level: 'log' }); processSubject.complete(); const result = await promise; - expect(result).toEqual([ - {type: 'log', message: 'take', level: 'log'}, - {type: 'progress', progress: null}, - {type: 'log', message: 'take', level: 'log'}, - ]); + expect(result).toEqual([{ type: 'log', message: 'take', level: 'log' }, { type: 'progress', progress: null }, { type: 'log', message: 'take', level: 'log' }]); })(); }); it('run: takes process messages after build finishes', async () => { await (async () => { - const combinedStream = combineEventStreams( - 'test', - socketSubject, - processSubject, - ); + const combinedStream = (0, (_BuckEventStream || _load_BuckEventStream()).combineEventStreams)('test', socketSubject, processSubject); const promise = combinedStream.toArray().toPromise(); - processSubject.next({type: 'log', message: 'take', level: 'log'}); - socketSubject.next({type: 'progress', progress: 1}); - processSubject.next({type: 'log', message: 'take', level: 'log'}); + processSubject.next({ type: 'log', message: 'take', level: 'log' }); + socketSubject.next({ type: 'progress', progress: 1 }); + processSubject.next({ type: 'log', message: 'take', level: 'log' }); processSubject.complete(); const result = await promise; - expect(result).toEqual([ - {type: 'log', message: 'take', level: 'log'}, - {type: 'progress', progress: null}, - {type: 'log', message: 'take', level: 'log'}, - ]); + expect(result).toEqual([{ type: 'log', message: 'take', level: 'log' }, { type: 'progress', progress: null }, { type: 'log', message: 'take', level: 'log' }]); })(); }); it('install: adds installing message after build finish', async () => { await (async () => { - const combinedStream = combineEventStreams( - 'install', - socketSubject, - processSubject, - ); + const combinedStream = (0, (_BuckEventStream || _load_BuckEventStream()).combineEventStreams)('install', socketSubject, processSubject); const promise = combinedStream.toArray().toPromise(); - socketSubject.next({type: 'progress', progress: 1}); - processSubject.next({type: 'log', message: 'skip', level: 'log'}); + socketSubject.next({ type: 'progress', progress: 1 }); + processSubject.next({ type: 'log', message: 'skip', level: 'log' }); processSubject.complete(); const result = await promise; - expect(result).toEqual([ - {type: 'progress', progress: 1}, - {type: 'progress', progress: null}, - {type: 'log', message: 'Installing...', level: 'info'}, - ]); + expect(result).toEqual([{ type: 'progress', progress: 1 }, { type: 'progress', progress: null }, { type: 'log', message: 'Installing...', level: 'info' }]); })(); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-buck/__tests__/Epics-test.js b/pkg/nuclide-buck/__tests__/Epics-test.js index f028788144..b771b4849a 100644 --- a/pkg/nuclide-buck/__tests__/Epics-test.js +++ b/pkg/nuclide-buck/__tests__/Epics-test.js @@ -1,76 +1,76 @@ -/** - * 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 - */ - -import {Observable} from 'rxjs'; -import {ActionsObservable} from 'nuclide-commons/redux-observable'; -import * as BuckBase from '../../nuclide-buck-base'; -import * as Actions from '../lib/redux/Actions'; -import { - setProjectRootEpic, - setBuildTargetEpic, - setRuleTypeEpic, -} from '../lib/redux/Epics'; +'use strict'; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _reduxObservable; + +function _load_reduxObservable() { + return _reduxObservable = require('../../../modules/nuclide-commons/redux-observable'); +} + +var _nuclideBuckBase; + +function _load_nuclideBuckBase() { + return _nuclideBuckBase = _interopRequireWildcard(require('../../nuclide-buck-base')); +} + +var _Actions; + +function _load_Actions() { + return _Actions = _interopRequireWildcard(require('../lib/redux/Actions')); +} + +var _Epics; + +function _load_Epics() { + return _Epics = require('../lib/redux/Epics'); +} + +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 mockPlatformService = { - getPlatformGroups(buckRoot, ruleType, buildTarget): ?any { + getPlatformGroups(buckRoot, ruleType, buildTarget) { return null; - }, -}; + } +}; /** + * 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. + * + * + * @format + */ const mockStore = { dispatch(action) {}, - getState(): any { + getState() { return { buckRoot: '/test', buildTarget: 'test', - selectedDevice: {udid: 'two', flavor: 'chocolate'}, - platformService: mockPlatformService, + selectedDevice: { udid: 'two', flavor: 'chocolate' }, + platformService: mockPlatformService }; - }, + } }; describe('setProjectRootEpic', () => { it('Sets the Buck root to null for null projects', async () => { await (async () => { - const stream = await setProjectRootEpic( - new ActionsObservable(Observable.of(Actions.setProjectRoot(null))), - mockStore, - ) - .toArray() - .toPromise(); - - expect(stream).toEqual([ - {type: Actions.SET_BUCK_ROOT, buckRoot: null}, - Actions.setBuildTarget('test'), - ]); + const stream = await (0, (_Epics || _load_Epics()).setProjectRootEpic)(new (_reduxObservable || _load_reduxObservable()).ActionsObservable(_rxjsBundlesRxMinJs.Observable.of((_Actions || _load_Actions()).setProjectRoot(null))), mockStore).toArray().toPromise(); + + expect(stream).toEqual([{ type: (_Actions || _load_Actions()).SET_BUCK_ROOT, buckRoot: null }, (_Actions || _load_Actions()).setBuildTarget('test')]); })(); }); it('Gets the Buck root for a real project', async () => { await (async () => { - jest - .spyOn(BuckBase, 'getBuckProjectRoot') - .mockReturnValue(Promise.resolve('test_buck')); - - const stream = await setProjectRootEpic( - new ActionsObservable(Observable.of(Actions.setProjectRoot('test'))), - mockStore, - ) - .toArray() - .toPromise(); - - expect(stream).toEqual([ - {type: Actions.SET_BUCK_ROOT, buckRoot: 'test_buck'}, - Actions.setBuildTarget('test'), - ]); + jest.spyOn(_nuclideBuckBase || _load_nuclideBuckBase(), 'getBuckProjectRoot').mockReturnValue(Promise.resolve('test_buck')); + + const stream = await (0, (_Epics || _load_Epics()).setProjectRootEpic)(new (_reduxObservable || _load_reduxObservable()).ActionsObservable(_rxjsBundlesRxMinJs.Observable.of((_Actions || _load_Actions()).setProjectRoot('test'))), mockStore).toArray().toPromise(); + + expect(stream).toEqual([{ type: (_Actions || _load_Actions()).SET_BUCK_ROOT, buckRoot: 'test_buck' }, (_Actions || _load_Actions()).setBuildTarget('test')]); })(); }); }); @@ -78,39 +78,27 @@ describe('setProjectRootEpic', () => { describe('setBuildTargetEpic', () => { it('sets a null rule type and resolved build target with an empty build target', async () => { await (async () => { - const stream = await setBuildTargetEpic( - new ActionsObservable(Observable.of(Actions.setBuildTarget(''))), - mockStore, - ) - .toArray() - .toPromise(); - - expect(stream).toEqual([{type: Actions.SET_RULE_TYPE, ruleType: null}]); + const stream = await (0, (_Epics || _load_Epics()).setBuildTargetEpic)(new (_reduxObservable || _load_reduxObservable()).ActionsObservable(_rxjsBundlesRxMinJs.Observable.of((_Actions || _load_Actions()).setBuildTarget(''))), mockStore).toArray().toPromise(); + + expect(stream).toEqual([{ type: (_Actions || _load_Actions()).SET_RULE_TYPE, ruleType: null }]); })(); }); it('sets the rule type and resolved build target to what buck service resolves', async () => { await (async () => { const fakeResolvedRule = {}; - jest.spyOn(BuckBase, 'getBuckService').mockReturnValue({ + jest.spyOn(_nuclideBuckBase || _load_nuclideBuckBase(), 'getBuckService').mockReturnValue({ buildRuleTypeFor() { return Promise.resolve(fakeResolvedRule); - }, + } }); - const stream = await setBuildTargetEpic( - new ActionsObservable(Observable.of(Actions.setBuildTarget('test'))), - mockStore, - ) - .toArray() - .toPromise(); - - expect(stream).toEqual([ - { - type: Actions.SET_RULE_TYPE, - ruleType: fakeResolvedRule, - }, - ]); + const stream = await (0, (_Epics || _load_Epics()).setBuildTargetEpic)(new (_reduxObservable || _load_reduxObservable()).ActionsObservable(_rxjsBundlesRxMinJs.Observable.of((_Actions || _load_Actions()).setBuildTarget('test'))), mockStore).toArray().toPromise(); + + expect(stream).toEqual([{ + type: (_Actions || _load_Actions()).SET_RULE_TYPE, + ruleType: fakeResolvedRule + }]); })(); }); }); @@ -118,39 +106,19 @@ describe('setBuildTargetEpic', () => { describe('setRuleTypeEpic', () => { it('sets platforms to an empty array for null ruleType', async () => { await (async () => { - const stream = await setRuleTypeEpic( - new ActionsObservable( - Observable.of({type: Actions.SET_RULE_TYPE, ruleType: null}), - ), - mockStore, - ) - .toArray() - .toPromise(); - - expect(stream).toEqual([ - {type: Actions.SET_PLATFORM_GROUPS, platformGroups: []}, - ]); + const stream = await (0, (_Epics || _load_Epics()).setRuleTypeEpic)(new (_reduxObservable || _load_reduxObservable()).ActionsObservable(_rxjsBundlesRxMinJs.Observable.of({ type: (_Actions || _load_Actions()).SET_RULE_TYPE, ruleType: null })), mockStore).toArray().toPromise(); + + expect(stream).toEqual([{ type: (_Actions || _load_Actions()).SET_PLATFORM_GROUPS, platformGroups: [] }]); })(); }); it('sets platform groups to groups returned from platform service', async () => { await (async () => { - jest - .spyOn(mockPlatformService, 'getPlatformGroups') - .mockReturnValue(Observable.of('random platforms')); - - const stream = await setRuleTypeEpic( - new ActionsObservable( - Observable.of({type: Actions.SET_RULE_TYPE, ruleType: 'haha'}), - ), - mockStore, - ) - .toArray() - .toPromise(); - - expect(stream).toEqual([ - {type: Actions.SET_PLATFORM_GROUPS, platformGroups: 'random platforms'}, - ]); + jest.spyOn(mockPlatformService, 'getPlatformGroups').mockReturnValue(_rxjsBundlesRxMinJs.Observable.of('random platforms')); + + const stream = await (0, (_Epics || _load_Epics()).setRuleTypeEpic)(new (_reduxObservable || _load_reduxObservable()).ActionsObservable(_rxjsBundlesRxMinJs.Observable.of({ type: (_Actions || _load_Actions()).SET_RULE_TYPE, ruleType: 'haha' })), mockStore).toArray().toPromise(); + + expect(stream).toEqual([{ type: (_Actions || _load_Actions()).SET_PLATFORM_GROUPS, platformGroups: 'random platforms' }]); })(); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-buck/lib/BuckBuildSystem.js b/pkg/nuclide-buck/lib/BuckBuildSystem.js index a2d1d874b5..71e0dc9cf5 100644 --- a/pkg/nuclide-buck/lib/BuckBuildSystem.js +++ b/pkg/nuclide-buck/lib/BuckBuildSystem.js @@ -1,3 +1,50 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.BuckBuildSystem = undefined; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _tasks; + +function _load_tasks() { + return _tasks = require('../../commons-node/tasks'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _BuckEventStream; + +function _load_BuckEventStream() { + return _BuckEventStream = require('./BuckEventStream'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,306 +52,159 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {BuckEvent} from './BuckEventStream'; -import type {LegacyProcessMessage, TaskEvent} from 'nuclide-commons/process'; -import type {ResolvedBuildTarget} from '../../nuclide-buck-rpc/lib/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import typeof * as BuckService from '../../nuclide-buck-rpc'; -import type { - BuckBuildTask, - BuckBuildOptions, - BuckBuildOutput, - BuckSubcommand, - TaskSettings, -} from './types'; -import type { - DiagnosticInvalidationMessage, - DiagnosticProviderUpdate, - ObservableDiagnosticProvider, -} from 'atom-ide-ui'; - -import {Observable, Subject, TimeoutError} from 'rxjs'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import { - createMessage, - createResult, - taskFromObservable, -} from '../../commons-node/tasks'; -import {getLogger} from 'log4js'; -import {getBuckServiceByNuclideUri} from '../../nuclide-remote-connection'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import { - combineEventStreams, - getDiagnosticEvents, - getEventsFromSocket, - getEventsFromProcess, -} from './BuckEventStream'; - const SOCKET_TIMEOUT = 30000; -export type {BuckSubcommand} from './types'; - -export class BuckBuildSystem { - _diagnosticUpdates: Subject = new Subject(); - _diagnosticInvalidations: Subject< - DiagnosticInvalidationMessage, - > = new Subject(); - - build(opts: BuckBuildOptions): BuckBuildTask { - const {root, target, args} = opts; - let buildOutput: ?BuckBuildOutput = null; +class BuckBuildSystem { + constructor() { + this._diagnosticUpdates = new _rxjsBundlesRxMinJs.Subject(); + this._diagnosticInvalidations = new _rxjsBundlesRxMinJs.Subject(); + } - const task = taskFromObservable( - this.runSubcommand( - root, - 'build', - target, - {buildArguments: args}, - false, - null, - ).do(event => { - if (event.type === 'result') { - buildOutput = ((event.result: any): BuckBuildOutput); - } - }), - ); - return { - ...task, - getBuildOutput(): BuckBuildOutput { + build(opts) { + const { root, target, args } = opts; + let buildOutput = null; + + const task = (0, (_tasks || _load_tasks()).taskFromObservable)(this.runSubcommand(root, 'build', target, { buildArguments: args }, false, null).do(event => { + if (event.type === 'result') { + buildOutput = event.result; + } + })); + return Object.assign({}, task, { + getBuildOutput() { if (buildOutput == null) { throw new Error('No build output!'); } return buildOutput; - }, - }; + } + }); } - runSubcommand( - buckRoot: NuclideUri, - subcommand: BuckSubcommand, - buildTarget: ResolvedBuildTarget, - taskSettings: TaskSettings, - isDebug: boolean, - udid: ?string, - processEventCallback: ?( - processStream: Observable, - ) => Observable, - skipLaunchAfterInstall?: boolean = false, - ): Observable { + runSubcommand(buckRoot, subcommand, buildTarget, taskSettings, isDebug, udid, processEventCallback, skipLaunchAfterInstall = false) { // Clear Buck diagnostics every time we run a buck command. - this._diagnosticInvalidations.next({scope: 'all'}); - const buckService = getBuckServiceByNuclideUri(buckRoot); + this._diagnosticInvalidations.next({ scope: 'all' }); + const buckService = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getBuckServiceByNuclideUri)(buckRoot); const buildArguments = taskSettings.buildArguments || []; const runArguments = taskSettings.runArguments || []; const targetString = getCommandStringForResolvedBuildTarget(buildTarget); - return Observable.fromPromise(buckService.getHTTPServerPort(buckRoot)) - .catch(err => { - getLogger('nuclide-buck').warn( - `Failed to get httpPort for ${nuclideUri.getPath(buckRoot)}`, - err, - ); - return Observable.of(-1); - }) - .switchMap(httpPort => { - let socketEvents = null; - if (httpPort > 0) { - socketEvents = getEventsFromSocket( - buckService.getWebSocketStream(buckRoot, httpPort).refCount(), - ).share(); + return _rxjsBundlesRxMinJs.Observable.fromPromise(buckService.getHTTPServerPort(buckRoot)).catch(err => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-buck').warn(`Failed to get httpPort for ${(_nuclideUri || _load_nuclideUri()).default.getPath(buckRoot)}`, err); + return _rxjsBundlesRxMinJs.Observable.of(-1); + }).switchMap(httpPort => { + let socketEvents = null; + if (httpPort > 0) { + socketEvents = (0, (_BuckEventStream || _load_BuckEventStream()).getEventsFromSocket)(buckService.getWebSocketStream(buckRoot, httpPort).refCount()).share(); + } + + const args = runArguments.length > 0 && (subcommand === 'run' || subcommand === 'install' || subcommand === 'test') ? buildArguments.concat(['--']).concat(runArguments) : buildArguments; + + const processMessages = runBuckCommand(buckService, buckRoot, targetString, subcommand, args, isDebug, udid, skipLaunchAfterInstall).share(); + const processEvents = (0, (_BuckEventStream || _load_BuckEventStream()).getEventsFromProcess)(processMessages).share(); + + let httpRecommendation; + let mergedEvents; + if (socketEvents == null) { + // Without a websocket, just pipe the Buck output directly. + mergedEvents = processEvents; + httpRecommendation = (0, (_tasks || _load_tasks()).createMessage)('For better logs, set httpserver.port in your Buck config and restart Nuclide.', 'info'); + } else { + mergedEvents = (0, (_BuckEventStream || _load_BuckEventStream()).combineEventStreams)(subcommand, socketEvents, processEvents).share(); + httpRecommendation = _rxjsBundlesRxMinJs.Observable.empty(); + } + + return _rxjsBundlesRxMinJs.Observable.concat(httpRecommendation, + // Wait until the socket starts up before triggering the Buck process. + socketEvents == null ? _rxjsBundlesRxMinJs.Observable.empty() : socketEvents.filter(event => event.type === 'socket-connected').take(1).timeout(SOCKET_TIMEOUT).catch(err => { + if (err instanceof _rxjsBundlesRxMinJs.TimeoutError) { + throw new Error('Timed out connecting to Buck server.'); } - - const args = - runArguments.length > 0 && - (subcommand === 'run' || - subcommand === 'install' || - subcommand === 'test') - ? buildArguments.concat(['--']).concat(runArguments) - : buildArguments; - - const processMessages = runBuckCommand( - buckService, - buckRoot, - targetString, - subcommand, - args, - isDebug, - udid, - skipLaunchAfterInstall, - ).share(); - const processEvents = getEventsFromProcess(processMessages).share(); - - let httpRecommendation; - let mergedEvents; - if (socketEvents == null) { - // Without a websocket, just pipe the Buck output directly. - mergedEvents = processEvents; - httpRecommendation = createMessage( - 'For better logs, set httpserver.port in your Buck config and restart Nuclide.', - 'info', - ); - } else { - mergedEvents = combineEventStreams( - subcommand, - socketEvents, - processEvents, - ).share(); - httpRecommendation = Observable.empty(); - } - - return Observable.concat( - httpRecommendation, - // Wait until the socket starts up before triggering the Buck process. - socketEvents == null - ? Observable.empty() - : socketEvents - .filter(event => event.type === 'socket-connected') - .take(1) - .timeout(SOCKET_TIMEOUT) - .catch(err => { - if (err instanceof TimeoutError) { - throw new Error('Timed out connecting to Buck server.'); - } - throw err; - }) - .ignoreElements(), - this._consumeEventStream( - Observable.merge( - mergedEvents, - featureConfig.get('nuclide-buck.compileErrorDiagnostics') - ? getDiagnosticEvents(mergedEvents, buckRoot) - : Observable.empty(), - processEventCallback != null - ? processEventCallback(processMessages) - : Observable.empty(), - ), - buckRoot, - ), - ); - }) - .share(); + throw err; + }).ignoreElements(), this._consumeEventStream(_rxjsBundlesRxMinJs.Observable.merge(mergedEvents, (_featureConfig || _load_featureConfig()).default.get('nuclide-buck.compileErrorDiagnostics') ? (0, (_BuckEventStream || _load_BuckEventStream()).getDiagnosticEvents)(mergedEvents, buckRoot) : _rxjsBundlesRxMinJs.Observable.empty(), processEventCallback != null ? processEventCallback(processMessages) : _rxjsBundlesRxMinJs.Observable.empty()), buckRoot)); + }).share(); } - getDiagnosticProvider(): ObservableDiagnosticProvider { + getDiagnosticProvider() { return { updates: this._diagnosticUpdates, - invalidations: this._diagnosticInvalidations, + invalidations: this._diagnosticInvalidations }; } /** * Processes side diagnostics, converts relevant events to TaskEvents. */ - _consumeEventStream( - events: Observable, - buckRoot: NuclideUri, - ): Observable { + _consumeEventStream(events, buckRoot) { // TODO: the Diagnostics API does not allow emitting one message at a time. // We have to accumulate messages per-file and emit them all. const fileDiagnostics = new Map(); // Save error messages until the end so diagnostics have a chance to finish. // Real exceptions will not be handled by this, of course. let errorMessage = null; - return Observable.concat( - events.flatMap(event => { - if (event.type === 'progress') { - return Observable.of(event); - } else if (event.type === 'log') { - return createMessage(event.message, event.level); - } else if (event.type === 'build-output') { - const {target, path, successType} = event.output; - return Observable.concat( - createMessage(`Target: ${target}`, 'log'), - createMessage(`Output: ${path}`, 'log'), - createMessage(`Success type: ${successType}`, 'log'), - createResult({ - ...event.output, - path: nuclideUri.join(buckRoot, path), - }), - ); - } else if (event.type === 'diagnostics') { - // Warning: side effects below - const {diagnostics} = event; - // Update only the files that changed in this message. - // Since emitting messages for a file invalidates it, we have to - // be careful to emit all previous messages for it as well. - const changedFiles = new Map(); - diagnostics.forEach(diagnostic => { - let messages = fileDiagnostics.get(diagnostic.filePath); - if (messages == null) { - messages = []; - fileDiagnostics.set(diagnostic.filePath, messages); - } - messages.push(diagnostic); - changedFiles.set(diagnostic.filePath, messages); - }); - this._diagnosticUpdates.next(changedFiles); - } else if (event.type === 'error') { - errorMessage = event.message; - } - return Observable.empty(); - }), - Observable.defer(() => { - if (fileDiagnostics.size > 0) { - return createMessage( - 'Compilation errors detected: open the Diagnostics pane to jump to them.', - 'info', - ); - } else { - return Observable.empty(); - } - }), - Observable.defer(() => { - if (errorMessage != null) { - throw new Error(errorMessage); - } - return Observable.empty(); - }), - ); + return _rxjsBundlesRxMinJs.Observable.concat(events.flatMap(event => { + if (event.type === 'progress') { + return _rxjsBundlesRxMinJs.Observable.of(event); + } else if (event.type === 'log') { + return (0, (_tasks || _load_tasks()).createMessage)(event.message, event.level); + } else if (event.type === 'build-output') { + const { target, path, successType } = event.output; + return _rxjsBundlesRxMinJs.Observable.concat((0, (_tasks || _load_tasks()).createMessage)(`Target: ${target}`, 'log'), (0, (_tasks || _load_tasks()).createMessage)(`Output: ${path}`, 'log'), (0, (_tasks || _load_tasks()).createMessage)(`Success type: ${successType}`, 'log'), (0, (_tasks || _load_tasks()).createResult)(Object.assign({}, event.output, { + path: (_nuclideUri || _load_nuclideUri()).default.join(buckRoot, path) + }))); + } else if (event.type === 'diagnostics') { + // Warning: side effects below + const { diagnostics } = event; + // Update only the files that changed in this message. + // Since emitting messages for a file invalidates it, we have to + // be careful to emit all previous messages for it as well. + const changedFiles = new Map(); + diagnostics.forEach(diagnostic => { + let messages = fileDiagnostics.get(diagnostic.filePath); + if (messages == null) { + messages = []; + fileDiagnostics.set(diagnostic.filePath, messages); + } + messages.push(diagnostic); + changedFiles.set(diagnostic.filePath, messages); + }); + this._diagnosticUpdates.next(changedFiles); + } else if (event.type === 'error') { + errorMessage = event.message; + } + return _rxjsBundlesRxMinJs.Observable.empty(); + }), _rxjsBundlesRxMinJs.Observable.defer(() => { + if (fileDiagnostics.size > 0) { + return (0, (_tasks || _load_tasks()).createMessage)('Compilation errors detected: open the Diagnostics pane to jump to them.', 'info'); + } else { + return _rxjsBundlesRxMinJs.Observable.empty(); + } + }), _rxjsBundlesRxMinJs.Observable.defer(() => { + if (errorMessage != null) { + throw new Error(errorMessage); + } + return _rxjsBundlesRxMinJs.Observable.empty(); + })); } } -function runBuckCommand( - buckService: BuckService, - buckRoot: string, - buildTarget: string, - subcommand: BuckSubcommand, - args: Array, - debug: boolean, - simulator: ?string, - skipLaunchAfterInstall?: boolean = false, -): Observable { +exports.BuckBuildSystem = BuckBuildSystem; +function runBuckCommand(buckService, buckRoot, buildTarget, subcommand, args, debug, simulator, skipLaunchAfterInstall = false) { // TODO(T17463635) if (debug) { // Stop any existing debugging sessions, as install hangs if an existing // app that's being overwritten is being debugged. - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'debugger:stop-debugging', - ); + atom.commands.dispatch(atom.views.getView(atom.workspace), 'debugger:stop-debugging'); } const targets = splitTargets(buildTarget); if (subcommand === 'install') { - return buckService - .installWithOutput( - buckRoot, - targets, - args, - simulator, - !skipLaunchAfterInstall, - debug, - ) - .refCount(); + return buckService.installWithOutput(buckRoot, targets, args, simulator, !skipLaunchAfterInstall, debug).refCount(); } else if (subcommand === 'build') { return buckService.buildWithOutput(buckRoot, targets, args).refCount(); } else if (subcommand === 'test') { - return buckService - .testWithOutput(buckRoot, targets, args, debug) - .refCount(); + return buckService.testWithOutput(buckRoot, targets, args, debug).refCount(); } else if (subcommand === 'run') { return buckService.runWithOutput(buckRoot, targets, args).refCount(); } else { @@ -312,14 +212,12 @@ function runBuckCommand( } } -function getCommandStringForResolvedBuildTarget( - target: ResolvedBuildTarget, -): string { - const {qualifiedName, flavors} = target; +function getCommandStringForResolvedBuildTarget(target) { + const { qualifiedName, flavors } = target; const separator = flavors.length > 0 ? '#' : ''; return `${qualifiedName}${separator}${flavors.join(',')}`; } -function splitTargets(buildTarget: string): Array { +function splitTargets(buildTarget) { return buildTarget.trim().split(/\s+/); -} +} \ No newline at end of file diff --git a/pkg/nuclide-buck/lib/BuckClangProvider.js b/pkg/nuclide-buck/lib/BuckClangProvider.js index 0f91657ed3..c5e768c17f 100644 --- a/pkg/nuclide-buck/lib/BuckClangProvider.js +++ b/pkg/nuclide-buck/lib/BuckClangProvider.js @@ -1,3 +1,60 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getClangProvider = getClangProvider; + +var _SimpleCache; + +function _load_SimpleCache() { + return _SimpleCache = require('../../../modules/nuclide-commons/SimpleCache'); +} + +var _types; + +function _load_types() { + return _types = require('../../nuclide-buck-rpc/lib/types'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _BuckTaskRunner; + +function _load_BuckTaskRunner() { + return _BuckTaskRunner = require('./BuckTaskRunner'); +} + +var _ClangFlagsFileWatcher; + +function _load_ClangFlagsFileWatcher() { + return _ClangFlagsFileWatcher = require('../../nuclide-clang-base/lib/ClangFlagsFileWatcher'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,32 +62,15 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {BuckClangCompilationDatabase} from '../../nuclide-buck-rpc/lib/types'; -import type {ClangRequestSettings} from '../../nuclide-clang-rpc/lib/rpc-types'; -import type {ClangConfigurationProvider} from '../../nuclide-clang/lib/types'; -import type {BusySignalService} from 'atom-ide-ui'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {CompilationDatabaseParams, ConsolePrinter} from './types'; - -import {SimpleCache} from 'nuclide-commons/SimpleCache'; -import {convertBuckClangCompilationDatabase} from '../../nuclide-buck-rpc/lib/types'; -import {track} from '../../nuclide-analytics'; -import {getBuckServiceByNuclideUri} from '../../nuclide-remote-connection'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {BuckTaskRunner, CONSOLE_VIEW_URI} from './BuckTaskRunner'; -import {ClangFlagsFileWatcher} from '../../nuclide-clang-base/lib/ClangFlagsFileWatcher'; - -const WARNING_HINT = - 'Hint: Try **Nuclide > Clang > Clean and Rebuild** once fixed.'; +const WARNING_HINT = 'Hint: Try **Nuclide > Clang > Clean and Rebuild** once fixed.'; const SHOW_NOTIFICATION_CONFIG = 'nuclide-buck.buildDbErrorNotify'; // Strip off remote error, which is JSON object on last line of error message. -function cleanupErrorMessage(message: string): string { +function cleanupErrorMessage(message) { const trimmed = message.trim(); const lastNewline = trimmed.lastIndexOf('\n'); if (lastNewline !== -1) { @@ -39,233 +79,142 @@ function cleanupErrorMessage(message: string): string { return trimmed; } -function constructNotificationOptions( - clickCallback?: () => void, -): atom$NotificationOptions { - const buttons = [ - { - text: 'Show in console', - onDidClick: () => { - // eslint-disable-next-line nuclide-internal/atom-apis - atom.workspace.open(CONSOLE_VIEW_URI, {searchAllPanes: true}); - if (clickCallback) { - clickCallback(); - } - }, - }, - { - text: 'Never show again', - onDidClick: () => { - featureConfig.set(SHOW_NOTIFICATION_CONFIG, false); - if (clickCallback) { - clickCallback(); - } - }, - }, - ]; - return {dismissable: true, buttons}; +function constructNotificationOptions(clickCallback) { + const buttons = [{ + text: 'Show in console', + onDidClick: () => { + // eslint-disable-next-line nuclide-internal/atom-apis + atom.workspace.open((_BuckTaskRunner || _load_BuckTaskRunner()).CONSOLE_VIEW_URI, { searchAllPanes: true }); + if (clickCallback) { + clickCallback(); + } + } + }, { + text: 'Never show again', + onDidClick: () => { + (_featureConfig || _load_featureConfig()).default.set(SHOW_NOTIFICATION_CONFIG, false); + if (clickCallback) { + clickCallback(); + } + } + }]; + return { dismissable: true, buttons }; } -function emitCompilationDbWarnings( - db: BuckClangCompilationDatabase, - consolePrinter: ?ConsolePrinter, -): void { +function emitCompilationDbWarnings(db, consolePrinter) { if (db.warnings.length > 0) { if (consolePrinter) { - db.warnings.forEach(text => consolePrinter({text, level: 'warning'})); + db.warnings.forEach(text => consolePrinter({ text, level: 'warning' })); } - if (featureConfig.get(SHOW_NOTIFICATION_CONFIG)) { - const notification = atom.notifications.addWarning( - [ - 'Buck: warnings detected while fetching compile commands,', - 'some language services may not work properly.', - WARNING_HINT, - ].join(' '), - constructNotificationOptions(() => - // Notification doesn't dismiss itself on click. - notification.dismiss(), - ), - ); + if ((_featureConfig || _load_featureConfig()).default.get(SHOW_NOTIFICATION_CONFIG)) { + const notification = atom.notifications.addWarning(['Buck: warnings detected while fetching compile commands,', 'some language services may not work properly.', WARNING_HINT].join(' '), constructNotificationOptions(() => + // Notification doesn't dismiss itself on click. + notification.dismiss())); } } } -function emitCompilationDbError( - errorMessage: string, - consolePrinter: ?ConsolePrinter, -): void { +function emitCompilationDbError(errorMessage, consolePrinter) { if (consolePrinter) { - consolePrinter({text: cleanupErrorMessage(errorMessage), level: 'error'}); + consolePrinter({ text: cleanupErrorMessage(errorMessage), level: 'error' }); } - if (featureConfig.get(SHOW_NOTIFICATION_CONFIG)) { - const notification = atom.notifications.addError( - [ - 'Buck error: build failed while fetching compile commands.', - WARNING_HINT, - ].join(' '), - constructNotificationOptions(() => notification.dismiss()), - ); + if ((_featureConfig || _load_featureConfig()).default.get(SHOW_NOTIFICATION_CONFIG)) { + const notification = atom.notifications.addError(['Buck error: build failed while fetching compile commands.', WARNING_HINT].join(' '), constructNotificationOptions(() => notification.dismiss())); } } class Provider { - _projectRootCache: SimpleCache> = new SimpleCache(); - _compilationDBCache: SimpleCache< - string, - Promise, - > = new SimpleCache(); - _host: NuclideUri; - _params: CompilationDatabaseParams; - _flagsFileWatcher: ClangFlagsFileWatcher; + constructor(host, params) { + this._projectRootCache = new (_SimpleCache || _load_SimpleCache()).SimpleCache(); + this._compilationDBCache = new (_SimpleCache || _load_SimpleCache()).SimpleCache(); - constructor(host: NuclideUri, params: CompilationDatabaseParams) { this._host = host; - this._flagsFileWatcher = new ClangFlagsFileWatcher(host); + this._flagsFileWatcher = new (_ClangFlagsFileWatcher || _load_ClangFlagsFileWatcher()).ClangFlagsFileWatcher(host); this._params = params; } - _reportCompilationDBBusySignalWhile( - src: string, - getBusySignalService: () => ?BusySignalService, - dbPromise: Promise, - ): Promise { + _reportCompilationDBBusySignalWhile(src, getBusySignalService, dbPromise) { const busySignal = getBusySignalService(); - return busySignal == null - ? dbPromise - : busySignal.reportBusyWhile( - 'Generating Buck compilation database for "' + - nuclideUri.basename(src) + - '"', - () => dbPromise, - ); + return busySignal == null ? dbPromise : busySignal.reportBusyWhile('Generating Buck compilation database for "' + (_nuclideUri || _load_nuclideUri()).default.basename(src) + '"', () => dbPromise); } - getCompilationDatabase( - src: string, - getBusySignalService: () => ?BusySignalService, - getConsolePrinter: () => ?ConsolePrinter, - ): Promise { + getCompilationDatabase(src, getBusySignalService, getConsolePrinter) { const consolePrinter = getConsolePrinter(); return this._compilationDBCache.getOrCreate(src, () => { - return this._reportCompilationDBBusySignalWhile( - src, - getBusySignalService, - getBuckServiceByNuclideUri(this._host) - .getCompilationDatabase(src, this._params) - .refCount() - .do(db => { - if (db != null && db.flagsFile != null) { - this._flagsFileWatcher.watch(db.flagsFile, src, () => - this.resetForSource(src), - ); - } - if (db != null) { - emitCompilationDbWarnings(db, consolePrinter); - } - track('buck-clang.getSettings', { - src, - db, - warningsLength: db != null ? db.warnings.length : 0, - }); - }) - .toPromise() - .catch(error => { - emitCompilationDbError(error.message, consolePrinter); - }), - ); + return this._reportCompilationDBBusySignalWhile(src, getBusySignalService, (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getBuckServiceByNuclideUri)(this._host).getCompilationDatabase(src, this._params).refCount().do(db => { + if (db != null && db.flagsFile != null) { + this._flagsFileWatcher.watch(db.flagsFile, src, () => this.resetForSource(src)); + } + if (db != null) { + emitCompilationDbWarnings(db, consolePrinter); + } + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('buck-clang.getSettings', { + src, + db, + warningsLength: db != null ? db.warnings.length : 0 + }); + }).toPromise().catch(error => { + emitCompilationDbError(error.message, consolePrinter); + })); }); } - getProjectRoot(src: string): Promise { - return this._projectRootCache.getOrCreate(src, () => - getBuckServiceByNuclideUri(this._host).getRootForPath(src), - ); + getProjectRoot(src) { + return this._projectRootCache.getOrCreate(src, () => (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getBuckServiceByNuclideUri)(this._host).getRootForPath(src)); } - resetForSource(src: string): void { + resetForSource(src) { this._compilationDBCache.delete(src); - getBuckServiceByNuclideUri(this._host).resetCompilationDatabaseForSource( - src, - this._params, - ); + (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getBuckServiceByNuclideUri)(this._host).resetCompilationDatabaseForSource(src, this._params); this._flagsFileWatcher.resetForSource(src); } - reset(): void { + reset() { this._compilationDBCache.clear(); - getBuckServiceByNuclideUri(this._host).resetCompilationDatabase( - this._params, - ); + (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getBuckServiceByNuclideUri)(this._host).resetCompilationDatabase(this._params); this._flagsFileWatcher.reset(); } } -const providersCache = new SimpleCache({ - keyFactory: ([host, params: CompilationDatabaseParams]) => - JSON.stringify([nuclideUri.getHostnameOpt(host) || '', params]), - dispose: provider => provider.reset(), +const providersCache = new (_SimpleCache || _load_SimpleCache()).SimpleCache({ + keyFactory: ([host, params]) => JSON.stringify([(_nuclideUri || _load_nuclideUri()).default.getHostnameOpt(host) || '', params]), + dispose: provider => provider.reset() }); -function getProvider( - host: NuclideUri, - params: CompilationDatabaseParams, -): Provider { - return providersCache.getOrCreate( - [host, params], - () => new Provider(host, params), - ); +function getProvider(host, params) { + return providersCache.getOrCreate([host, params], () => new Provider(host, params)); } -const supportsSourceCache: SimpleCache< - string, - Promise, -> = new SimpleCache(); +const supportsSourceCache = new (_SimpleCache || _load_SimpleCache()).SimpleCache(); -export function getClangProvider( - taskRunner: BuckTaskRunner, - getBusySignalService: () => ?BusySignalService, - getConsolePrinter: () => ?ConsolePrinter, -): ClangConfigurationProvider { +function getClangProvider(taskRunner, getBusySignalService, getConsolePrinter) { return { - async supportsSource(src: string): Promise { - return supportsSourceCache.getOrCreate( - src, - async () => - (await getBuckServiceByNuclideUri(src).getRootForPath(src)) != null, - ); + async supportsSource(src) { + return supportsSourceCache.getOrCreate(src, async () => (await (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getBuckServiceByNuclideUri)(src).getRootForPath(src)) != null); }, - async getSettings(src: string): Promise { + async getSettings(src) { const params = taskRunner.getCompilationDatabaseParamsForCurrentContext(); const provider = getProvider(src, params); - const [buckCompilationDatabase, projectRoot] = await Promise.all([ - provider.getCompilationDatabase( - src, - getBusySignalService, - getConsolePrinter, - ), - provider.getProjectRoot(src), - ]); + const [buckCompilationDatabase, projectRoot] = await Promise.all([provider.getCompilationDatabase(src, getBusySignalService, getConsolePrinter), provider.getProjectRoot(src)]); if (projectRoot == null) { return null; } return { projectRoot, - compilationDatabase: convertBuckClangCompilationDatabase( - buckCompilationDatabase, - ), + compilationDatabase: (0, (_types || _load_types()).convertBuckClangCompilationDatabase)(buckCompilationDatabase) }; }, - resetForSource(src: string): void { + resetForSource(src) { const params = taskRunner.getCompilationDatabaseParamsForCurrentContext(); getProvider(src, params).resetForSource(src); supportsSourceCache.delete(src); }, - reset(src: string): void { + reset(src) { const params = taskRunner.getCompilationDatabaseParamsForCurrentContext(); providersCache.delete([src, params]); supportsSourceCache.clear(); }, - priority: 100, + priority: 100 }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-buck/lib/BuckEventStream.js b/pkg/nuclide-buck/lib/BuckEventStream.js index 1779a00ef8..42ad39573b 100644 --- a/pkg/nuclide-buck/lib/BuckEventStream.js +++ b/pkg/nuclide-buck/lib/BuckEventStream.js @@ -1,3 +1,41 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getEventsFromSocket = getEventsFromSocket; +exports.getEventsFromProcess = getEventsFromProcess; +exports.combineEventStreams = combineEventStreams; +exports.getDiagnosticEvents = getDiagnosticEvents; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _stripAnsi; + +function _load_stripAnsi() { + return _stripAnsi = _interopRequireDefault(require('strip-ansi')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _DiagnosticsParser; + +function _load_DiagnosticsParser() { + return _DiagnosticsParser = _interopRequireDefault(require('./DiagnosticsParser')); +} + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,50 +43,15 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {BuckWebSocketMessage} from '../../nuclide-buck-rpc'; -import type {Level} from 'nuclide-commons/process'; -import type {DiagnosticMessage} from 'atom-ide-ui'; -import type {LegacyProcessMessage} from 'nuclide-commons/process'; -import type {BuckBuildOutput, BuckSubcommand} from './types'; - -import {Observable} from 'rxjs'; -import stripAnsi from 'strip-ansi'; -import {getLogger} from 'log4js'; -import DiagnosticsParser from './DiagnosticsParser'; -import {exitEventToMessage} from 'nuclide-commons/process'; - const PROGRESS_OUTPUT_INTERVAL = 5 * 1000; const BUILD_FAILED_MESSAGE = 'BUILD FAILED:'; const BUILD_OUTPUT_REGEX = /^OK {3}(.*?) (.*?) (.*?)$/; -export type BuckEvent = - | { - type: 'progress', - progress: ?number, - } - | { - type: 'log', - message: string, - level: Level, - } - | { - type: 'error', - message: string, - } - | { - type: 'diagnostics', - diagnostics: Array, - } - | { - type: 'socket-connected', - } - | {type: 'build-output', output: BuckBuildOutput}; - -function convertJavaLevel(level: string): Level { +function convertJavaLevel(level) { switch (level) { case 'INFO': return 'info'; @@ -60,105 +63,85 @@ function convertJavaLevel(level: string): Level { return 'log'; } -export function getEventsFromSocket( - socketStream: Observable, -): Observable { - const log = (message, level = 'log') => - Observable.of({ - type: 'log', - message, - level, - }); +function getEventsFromSocket(socketStream) { + const log = (message, level = 'log') => _rxjsBundlesRxMinJs.Observable.of({ + type: 'log', + message, + level + }); - const eventStream = socketStream - .flatMap((message: BuckWebSocketMessage) => { - switch (message.type) { - case 'SocketConnected': - return Observable.of({type: 'socket-connected'}); - case 'ParseStarted': - return log('Parsing BUCK files...'); - case 'ParseFinished': - return log('Parsing finished. Starting build...'); - case 'ConsoleEvent': - const match = message.message.match(BUILD_OUTPUT_REGEX); - if (match != null && match.length === 4) { - // The result is also printed to stdout and converted into build-output there. - return Observable.empty(); - } else if (message.message !== '') { - return log(message.message, convertJavaLevel(message.level.name)); - } else { - return Observable.empty(); - } - case 'InstallFinished': - return log('Install finished.', 'info'); - case 'BuildFinished': - return log( - `Build finished with exit code ${message.exitCode}.`, - message.exitCode === 0 ? 'info' : 'error', - ); - case 'BuildProgressUpdated': - return Observable.of({ - type: 'progress', - progress: message.progressValue, - }); - case 'CompilerErrorEvent': - // TODO: forward suggestions to diagnostics as autofixes - return log(message.error, 'error'); - } - return Observable.empty(); - }) - .catch(err => { - getLogger('nuclide-buck').error('Got Buck websocket error', err); - // Return to indeterminate progress. - return Observable.of({ - type: 'progress', - progress: null, - }); - }) - .share(); + const eventStream = socketStream.flatMap(message => { + switch (message.type) { + case 'SocketConnected': + return _rxjsBundlesRxMinJs.Observable.of({ type: 'socket-connected' }); + case 'ParseStarted': + return log('Parsing BUCK files...'); + case 'ParseFinished': + return log('Parsing finished. Starting build...'); + case 'ConsoleEvent': + const match = message.message.match(BUILD_OUTPUT_REGEX); + if (match != null && match.length === 4) { + // The result is also printed to stdout and converted into build-output there. + return _rxjsBundlesRxMinJs.Observable.empty(); + } else if (message.message !== '') { + return log(message.message, convertJavaLevel(message.level.name)); + } else { + return _rxjsBundlesRxMinJs.Observable.empty(); + } + case 'InstallFinished': + return log('Install finished.', 'info'); + case 'BuildFinished': + return log(`Build finished with exit code ${message.exitCode}.`, message.exitCode === 0 ? 'info' : 'error'); + case 'BuildProgressUpdated': + return _rxjsBundlesRxMinJs.Observable.of({ + type: 'progress', + progress: message.progressValue + }); + case 'CompilerErrorEvent': + // TODO: forward suggestions to diagnostics as autofixes + return log(message.error, 'error'); + } + return _rxjsBundlesRxMinJs.Observable.empty(); + }).catch(err => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-buck').error('Got Buck websocket error', err); + // Return to indeterminate progress. + return _rxjsBundlesRxMinJs.Observable.of({ + type: 'progress', + progress: null + }); + }).share(); // Periodically emit log events for progress updates. const progressEvents = eventStream.switchMap(event => { - if ( - event.type === 'progress' && - event.progress != null && - event.progress > 0 && - event.progress < 1 - ) { + if (event.type === 'progress' && event.progress != null && event.progress > 0 && event.progress < 1) { return log(`Building... [${Math.round(event.progress * 100)}%]`); } - return Observable.empty(); + return _rxjsBundlesRxMinJs.Observable.empty(); }); - return eventStream.merge( - progressEvents - .take(1) - .concat(progressEvents.sampleTime(PROGRESS_OUTPUT_INTERVAL)), - ); + return eventStream.merge(progressEvents.take(1).concat(progressEvents.sampleTime(PROGRESS_OUTPUT_INTERVAL))); } -export function getEventsFromProcess( - processStream: Observable, // TODO(T17463635) -): Observable { +function getEventsFromProcess(processStream) { return processStream.map(message => { switch (message.kind) { case 'error': return { type: 'error', - message: `Buck failed: ${message.error.message}`, + message: `Buck failed: ${message.error.message}` }; case 'exit': - const logMessage = `Buck exited with ${exitEventToMessage(message)}.`; + const logMessage = `Buck exited with ${(0, (_process || _load_process()).exitEventToMessage)(message)}.`; if (message.exitCode === 0) { return { type: 'log', message: logMessage, - level: 'info', + level: 'info' }; } return { type: 'error', - message: logMessage, + message: logMessage }; case 'stderr': case 'stdout': @@ -169,104 +152,74 @@ export function getEventsFromProcess( output: { target: match[1], successType: match[2], - path: match[3], - }, + path: match[3] + } }; } else { return { type: 'log', // Some Buck steps output ansi escape codes regardless of terminal setting. - message: stripAnsi(message.data), + message: (0, (_stripAnsi || _load_stripAnsi()).default)(message.data), // Build failure messages typically do not show up in the web socket. // TODO(hansonw): fix this on the Buck side - level: - message.data.indexOf(BUILD_FAILED_MESSAGE) === -1 - ? 'log' - : 'error', + level: message.data.indexOf(BUILD_FAILED_MESSAGE) === -1 ? 'log' : 'error' }; } default: - (message: empty); + message; throw new Error('impossible'); } }); } -export function combineEventStreams( - subcommand: BuckSubcommand, - socketEvents: Observable, - processEvents: Observable, -): Observable { +function combineEventStreams(subcommand, socketEvents, processEvents) { // Every build finishes with a 100% progress event. - function isBuildFinishEvent(event: BuckEvent) { + function isBuildFinishEvent(event) { return event.type === 'progress' && event.progress === 1; } - function isRegularLogMessage(event: BuckEvent) { + function isRegularLogMessage(event) { return event.type === 'log' && event.level === 'log'; } // Socket stream never stops, so use the process lifetime. - const finiteSocketEvents = socketEvents - .takeUntil( - processEvents - .ignoreElements() - // Despite the docs, takeUntil doesn't respond to completion. - .concat(Observable.of(null)), - ) - .share(); - let mergedEvents = Observable.merge( - finiteSocketEvents, - // Take all process output until the first socket message. - // There's a slight risk of output duplication if the socket message is late, - // but this is pretty rare. - processEvents.takeUntil(finiteSocketEvents).takeWhile(isRegularLogMessage), - // Error/info logs from the process represent exit/error conditions, so always take them. - // We ensure that error/info logs will not duplicate messages from the websocket. - processEvents.skipWhile(isRegularLogMessage), - ); + const finiteSocketEvents = socketEvents.takeUntil(processEvents.ignoreElements() + // Despite the docs, takeUntil doesn't respond to completion. + .concat(_rxjsBundlesRxMinJs.Observable.of(null))).share(); + let mergedEvents = _rxjsBundlesRxMinJs.Observable.merge(finiteSocketEvents, + // Take all process output until the first socket message. + // There's a slight risk of output duplication if the socket message is late, + // but this is pretty rare. + processEvents.takeUntil(finiteSocketEvents).takeWhile(isRegularLogMessage), + // Error/info logs from the process represent exit/error conditions, so always take them. + // We ensure that error/info logs will not duplicate messages from the websocket. + processEvents.skipWhile(isRegularLogMessage)); if (subcommand === 'test' || subcommand === 'run') { // The websocket does not reliably provide test output. // After the build finishes, fall back to the Buck output stream. - mergedEvents = Observable.concat( - mergedEvents.takeUntil(finiteSocketEvents.filter(isBuildFinishEvent)), - // Return to indeterminate progress. - Observable.of({type: 'progress', progress: null}), - processEvents, - ); + mergedEvents = _rxjsBundlesRxMinJs.Observable.concat(mergedEvents.takeUntil(finiteSocketEvents.filter(isBuildFinishEvent)), + // Return to indeterminate progress. + _rxjsBundlesRxMinJs.Observable.of({ type: 'progress', progress: null }), processEvents); } else if (subcommand === 'install') { // Add a message indicating that install has started after build completes. // The websocket does not naturally provide any indication. - mergedEvents = Observable.merge( - mergedEvents, - finiteSocketEvents.filter(isBuildFinishEvent).switchMapTo( - Observable.of( - { - type: 'progress', - progress: null, - }, - { - type: 'log', - message: 'Installing...', - level: 'info', - }, - ), - ), - ); + mergedEvents = _rxjsBundlesRxMinJs.Observable.merge(mergedEvents, finiteSocketEvents.filter(isBuildFinishEvent).switchMapTo(_rxjsBundlesRxMinJs.Observable.of({ + type: 'progress', + progress: null + }, { + type: 'log', + message: 'Installing...', + level: 'info' + }))); } return mergedEvents; } -export function getDiagnosticEvents( - events: Observable, - buckRoot: string, -): Observable { - const diagnosticsParser = new DiagnosticsParser(); +function getDiagnosticEvents(events, buckRoot) { + const diagnosticsParser = new (_DiagnosticsParser || _load_DiagnosticsParser()).default(); return events.flatMap(event => { // For log messages, try to detect compile errors and emit diagnostics. if (event.type === 'log') { - return Observable.fromPromise( - diagnosticsParser.getDiagnostics(event.message, event.level, buckRoot), - ).map(diagnostics => ({type: 'diagnostics', diagnostics})); + return _rxjsBundlesRxMinJs.Observable.fromPromise(diagnosticsParser.getDiagnostics(event.message, event.level, buckRoot)).map(diagnostics => ({ type: 'diagnostics', diagnostics })); } - return Observable.empty(); + return _rxjsBundlesRxMinJs.Observable.empty(); }); -} +} \ No newline at end of file diff --git a/pkg/nuclide-buck/lib/BuckTaskRunner.js b/pkg/nuclide-buck/lib/BuckTaskRunner.js index 306f4e9bb8..84a18e15cb 100644 --- a/pkg/nuclide-buck/lib/BuckTaskRunner.js +++ b/pkg/nuclide-buck/lib/BuckTaskRunner.js @@ -1,3 +1,155 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.BuckTaskRunner = exports.CONSOLE_VIEW_URI = exports.TASKS = undefined; +exports.isDebugTask = isDebugTask; +exports.getBuckSubcommandForTaskType = getBuckSubcommandForTaskType; + +var _DeploymentTarget; + +function _load_DeploymentTarget() { + return _DeploymentTarget = require('./DeploymentTarget'); +} + +var _PlatformService; + +function _load_PlatformService() { + return _PlatformService = require('./PlatformService'); +} + +var _reduxMin; + +function _load_reduxMin() { + return _reduxMin = require('redux/dist/redux.min.js'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _tasks; + +function _load_tasks() { + return _tasks = require('../../commons-node/tasks'); +} + +var _nuclideArtillery; + +function _load_nuclideArtillery() { + return _nuclideArtillery = require('../../nuclide-artillery'); +} + +var _BuckBuildSystem; + +function _load_BuckBuildSystem() { + return _BuckBuildSystem = require('./BuckBuildSystem'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _reduxObservable; + +function _load_reduxObservable() { + return _reduxObservable = require('../../../modules/nuclide-commons/redux-observable'); +} + +var _bindObservableAsProps; + +function _load_bindObservableAsProps() { + return _bindObservableAsProps = require('../../../modules/nuclide-commons-ui/bindObservableAsProps'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _Icon; + +function _load_Icon() { + return _Icon = require('../../../modules/nuclide-commons-ui/Icon'); +} + +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 _BuckToolbar; + +function _load_BuckToolbar() { + return _BuckToolbar = _interopRequireDefault(require('./BuckToolbar')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _shallowequal; + +function _load_shallowequal() { + return _shallowequal = _interopRequireDefault(require('shallowequal')); +} + +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 TASKS = exports.TASKS = [{ + type: 'build', + label: 'Build', + description: 'Build the specified Buck target', + icon: 'tools' +}, { + type: 'run', + label: 'Run', + description: 'Run the specfied Buck target', + icon: 'triangle-right' +}, { + type: 'test', + label: 'Test', + description: 'Test the specfied Buck target', + icon: 'check' +}, { + type: 'debug', + label: 'Build and launch debugger', + description: 'Build, launch and debug the specfied Buck target', + icon: 'nuclicon-debugger' +}, { + type: 'debug-launch-no-build', + label: 'Launch debugger (skip build)', + description: 'Launch and debug the specfied Buck target (skip building)', + icon: 'nuclicon-debugger' +}, { + type: 'debug-attach', + label: 'Attach Debugger', + description: 'Attach the debugger to the specfied Buck target', + icon: 'nuclicon-debugger' +}]; + +// This must match URI defined in ../../nuclide-console/lib/ui/ConsoleContainer /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,91 +157,13 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {TaskMetadata} from '../../nuclide-task-runner/lib/types'; -import type {Task} from '../../commons-node/tasks'; -import type { - AppState, - SerializedState, - Store, - TaskType, - CompilationDatabaseParams, - TaskInfo, - BuckSubcommand, -} from './types'; -import {formatDeploymentTarget} from './DeploymentTarget'; -import {PlatformService} from './PlatformService'; - -import invariant from 'assert'; -import {applyMiddleware, createStore} from 'redux'; -import {Observable, Subject} from 'rxjs'; -import {createMessage, taskFromObservable} from '../../commons-node/tasks'; -import {NuclideArtilleryTrace} from '../../nuclide-artillery'; -import {BuckBuildSystem} from './BuckBuildSystem'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import { - combineEpics, - createEpicMiddleware, -} from 'nuclide-commons/redux-observable'; - -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import {getLogger} from 'log4js'; -import {Icon} from 'nuclide-commons-ui/Icon'; -import * as Actions from './redux/Actions'; -import * as Epics from './redux/Epics'; -import Reducers from './redux/Reducers'; -import BuckToolbar from './BuckToolbar'; -import * as React from 'react'; -import {arrayEqual} from 'nuclide-commons/collection'; -import shallowequal from 'shallowequal'; - -export const TASKS = [ - { - type: 'build', - label: 'Build', - description: 'Build the specified Buck target', - icon: 'tools', - }, - { - type: 'run', - label: 'Run', - description: 'Run the specfied Buck target', - icon: 'triangle-right', - }, - { - type: 'test', - label: 'Test', - description: 'Test the specfied Buck target', - icon: 'check', - }, - { - type: 'debug', - label: 'Build and launch debugger', - description: 'Build, launch and debug the specfied Buck target', - icon: 'nuclicon-debugger', - }, - { - type: 'debug-launch-no-build', - label: 'Launch debugger (skip build)', - description: 'Launch and debug the specfied Buck target (skip building)', - icon: 'nuclicon-debugger', - }, - { - type: 'debug-attach', - label: 'Attach Debugger', - description: 'Attach the debugger to the specfied Buck target', - icon: 'nuclicon-debugger', - }, -]; +const CONSOLE_VIEW_URI = exports.CONSOLE_VIEW_URI = 'atom://nuclide/console'; -// This must match URI defined in ../../nuclide-console/lib/ui/ConsoleContainer -export const CONSOLE_VIEW_URI = 'atom://nuclide/console'; - -function shouldEnableTask(taskType: TaskType, ruleType: string): boolean { +function shouldEnableTask(taskType, ruleType) { switch (taskType) { case 'build': case 'test': @@ -105,154 +179,112 @@ function shouldEnableTask(taskType: TaskType, ruleType: string): boolean { } } -export function isDebugTask(taskType: TaskType | string) { +function isDebugTask(taskType) { return taskType.startsWith('debug'); } -export function getBuckSubcommandForTaskType( - taskType: TaskType | string, -): BuckSubcommand { - invariant(taskType === 'build' || taskType === 'run' || taskType === 'test'); +function getBuckSubcommandForTaskType(taskType) { + if (!(taskType === 'build' || taskType === 'run' || taskType === 'test')) { + throw new Error('Invariant violation: "taskType === \'build\' || taskType === \'run\' || taskType === \'test\'"'); + } + return taskType; } -export class BuckTaskRunner { - _store: Store; - _disposables: UniversalDisposable; - _extraUi: ?React.ComponentType; - id: string; - name: string; - _serializedState: ?SerializedState; - _buildSystem: BuckBuildSystem; - _platformService: PlatformService; - _completedTasksObservable: Subject; - - constructor(initialState: ?SerializedState) { +class BuckTaskRunner { + + constructor(initialState) { this.id = 'buck'; this.name = 'Buck'; - this._buildSystem = new BuckBuildSystem(); + this._buildSystem = new (_BuckBuildSystem || _load_BuckBuildSystem()).BuckBuildSystem(); this._serializedState = initialState; - this._disposables = new UniversalDisposable(); - this._platformService = new PlatformService(); - this._completedTasksObservable = new Subject(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._platformService = new (_PlatformService || _load_PlatformService()).PlatformService(); + this._completedTasksObservable = new _rxjsBundlesRxMinJs.Subject(); } - getExtraUi(): React.ComponentType { + getExtraUi() { if (this._extraUi == null) { const store = this._getStore(); const boundActions = { - setBuildTarget: buildTarget => - store.dispatch(Actions.setBuildTarget(buildTarget)), - setDeploymentTarget: deploymentTarget => - store.dispatch(Actions.setDeploymentTarget(deploymentTarget)), - setTaskSettings: settings => - store.dispatch(Actions.setTaskSettings(settings)), + setBuildTarget: buildTarget => store.dispatch((_Actions || _load_Actions()).setBuildTarget(buildTarget)), + setDeploymentTarget: deploymentTarget => store.dispatch((_Actions || _load_Actions()).setDeploymentTarget(deploymentTarget)), + setTaskSettings: settings => store.dispatch((_Actions || _load_Actions()).setTaskSettings(settings)) }; - this._extraUi = bindObservableAsProps( - // $FlowFixMe: type symbol-observable - Observable.from(store) - .map(appState => ({appState, ...boundActions})) - .filter(props => props.appState.buckRoot != null), - BuckToolbar, - ); + this._extraUi = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)( + // $FlowFixMe: type symbol-observable + _rxjsBundlesRxMinJs.Observable.from(store).map(appState => Object.assign({ appState }, boundActions)).filter(props => props.appState.buckRoot != null), (_BuckToolbar || _load_BuckToolbar()).default); } return this._extraUi; } - getIcon(): React.ComponentType { - return () => ( - - ); + getIcon() { + return () => _react.createElement((_Icon || _load_Icon()).Icon, { icon: 'nuclicon-buck', className: 'nuclide-buck-task-runner-icon' }); } - getBuildSystem(): BuckBuildSystem { + getBuildSystem() { return this._buildSystem; } - getPlatformService(): PlatformService { + getPlatformService() { return this._platformService; } - getBuildTarget(): ?string { + getBuildTarget() { return this._getStore().getState().buildTarget; } - getCompletedTasks(): rxjs$Observable { + getCompletedTasks() { return this._completedTasksObservable; } - setBuildTarget(buildTarget: string) { - this._getStore().dispatch(Actions.setBuildTarget(buildTarget)); + setBuildTarget(buildTarget) { + this._getStore().dispatch((_Actions || _load_Actions()).setBuildTarget(buildTarget)); } - setProjectRoot( - projectRoot: ?NuclideUri, - callback: (enabled: boolean, taskList: Array) => mixed, - ): IDisposable { + setProjectRoot(projectRoot, callback) { // $FlowFixMe: type symbol-observable - const storeReady: Observable = Observable.from(this._getStore()) - .distinctUntilChanged() - .filter( - (state: AppState) => - !state.isLoadingBuckProject && state.projectRoot === projectRoot, - ) - .share(); - - const enabledObservable = storeReady - .map(state => state.buckRoot != null) - .distinctUntilChanged(); - - const tasksObservable = storeReady - .map(state => { - const {buildRuleType, platformGroups, selectedDeploymentTarget} = state; - - const tasksFromPlatform = new Set(); - if ( - selectedDeploymentTarget != null && - selectedDeploymentTarget.platform.isMobile - ) { - selectedDeploymentTarget.platform - .tasksForDevice(selectedDeploymentTarget.device) - .forEach(taskType => tasksFromPlatform.add(taskType)); - } else if (buildRuleType != null) { - const ruleType = buildRuleType; - platformGroups.forEach(platformGroup => { - platformGroup.platforms.forEach(platform => { - if (!platform.isMobile) { - platform - .tasksForBuildRuleType(ruleType) - .forEach(taskType => tasksFromPlatform.add(taskType)); - } - }); + const storeReady = _rxjsBundlesRxMinJs.Observable.from(this._getStore()).distinctUntilChanged().filter(state => !state.isLoadingBuckProject && state.projectRoot === projectRoot).share(); + + const enabledObservable = storeReady.map(state => state.buckRoot != null).distinctUntilChanged(); + + const tasksObservable = storeReady.map(state => { + const { buildRuleType, platformGroups, selectedDeploymentTarget } = state; + + const tasksFromPlatform = new Set(); + if (selectedDeploymentTarget != null && selectedDeploymentTarget.platform.isMobile) { + selectedDeploymentTarget.platform.tasksForDevice(selectedDeploymentTarget.device).forEach(taskType => tasksFromPlatform.add(taskType)); + } else if (buildRuleType != null) { + const ruleType = buildRuleType; + platformGroups.forEach(platformGroup => { + platformGroup.platforms.forEach(platform => { + if (!platform.isMobile) { + platform.tasksForBuildRuleType(ruleType).forEach(taskType => tasksFromPlatform.add(taskType)); + } }); - } - return TASKS.map(task => { - const enabled = - !state.isLoadingPlatforms && - buildRuleType != null && - (tasksFromPlatform.size > 0 - ? tasksFromPlatform.has(task.type) - : shouldEnableTask(task.type, buildRuleType.type)); - - return {...task, disabled: !enabled}; }); - }) - .distinctUntilChanged((a, b) => arrayEqual(a, b, shallowequal)); + } + return TASKS.map(task => { + const enabled = !state.isLoadingPlatforms && buildRuleType != null && (tasksFromPlatform.size > 0 ? tasksFromPlatform.has(task.type) : shouldEnableTask(task.type, buildRuleType.type)); - const subscription = Observable.combineLatest( - enabledObservable, - tasksObservable, - ).subscribe(([enabled, tasks]) => callback(enabled, tasks)); + return Object.assign({}, task, { disabled: !enabled }); + }); + }).distinctUntilChanged((a, b) => (0, (_collection || _load_collection()).arrayEqual)(a, b, (_shallowequal || _load_shallowequal()).default)); + + const subscription = _rxjsBundlesRxMinJs.Observable.combineLatest(enabledObservable, tasksObservable).subscribe(([enabled, tasks]) => callback(enabled, tasks)); - this._getStore().dispatch(Actions.setProjectRoot(projectRoot)); + this._getStore().dispatch((_Actions || _load_Actions()).setProjectRoot(projectRoot)); - return new UniversalDisposable(subscription); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(subscription); } - _getStore(): Store { + _getStore() { if (this._store == null) { - invariant(this._serializedState != null); - const initialState: AppState = { + if (!(this._serializedState != null)) { + throw new Error('Invariant violation: "this._serializedState != null"'); + } + + const initialState = { platformGroups: [], platformService: this._platformService, projectRoot: null, @@ -267,48 +299,39 @@ export class BuckTaskRunner { userSelectedDeploymentTarget: null, taskSettings: this._serializedState.taskSettings || {}, platformProviderUi: null, - lastSessionPlatformGroupName: this._serializedState - .selectedPlatformGroupName, + lastSessionPlatformGroupName: this._serializedState.selectedPlatformGroupName, lastSessionPlatformName: this._serializedState.selectedPlatformName, - lastSessionDeviceGroupName: this._serializedState - .selectedDeviceGroupName, - lastSessionDeviceName: this._serializedState.selectedDeviceName, + lastSessionDeviceGroupName: this._serializedState.selectedDeviceGroupName, + lastSessionDeviceName: this._serializedState.selectedDeviceName }; - const epics = Object.keys(Epics) - .map(k => Epics[k]) - .filter(epic => typeof epic === 'function'); - const rootEpic = (actions, store) => - combineEpics(...epics)(actions, store) - // Log errors and continue. - .catch((err, stream) => { - getLogger('nuclide-buck').error(err); - return stream; - }); - 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 = (actions, store) => (0, (_reduxObservable || _load_reduxObservable()).combineEpics)(...epics)(actions, store) + // Log errors and continue. + .catch((err, stream) => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-buck').error(err); + return stream; + }); + this._store = (0, (_reduxMin || _load_reduxMin()).createStore)((_Reducers || _load_Reducers()).default, initialState, (0, (_reduxMin || _load_reduxMin()).applyMiddleware)((0, (_reduxObservable || _load_reduxObservable()).createEpicMiddleware)(rootEpic))); } return this._store; } - getCompilationDatabaseParamsForCurrentContext(): CompilationDatabaseParams { - const {selectedDeploymentTarget} = this._getStore().getState(); - const empty = {flavorsForTarget: [], args: [], useDefaultPlatform: true}; + getCompilationDatabaseParamsForCurrentContext() { + const { selectedDeploymentTarget } = this._getStore().getState(); + const empty = { flavorsForTarget: [], args: [], useDefaultPlatform: true }; if (selectedDeploymentTarget == null) { return empty; } - const {platform} = selectedDeploymentTarget; + const { platform } = selectedDeploymentTarget; if (typeof platform.getCompilationDatabaseParams === 'function') { return platform.getCompilationDatabaseParams(); } return empty; } - runTask(taskType: string): Task { + runTask(taskType) { // eslint-disable-next-line nuclide-internal/atom-apis - atom.workspace.open(CONSOLE_VIEW_URI, {searchAllPanes: true}); + atom.workspace.open(CONSOLE_VIEW_URI, { searchAllPanes: true }); const state = this._getStore().getState(); const { @@ -316,75 +339,53 @@ export class BuckTaskRunner { buildRuleType, buildTarget, selectedDeploymentTarget, - taskSettings, + taskSettings } = state; - invariant(buckRoot != null); - invariant(buildRuleType); - const deploymentTargetString = formatDeploymentTarget( - selectedDeploymentTarget, - ); - const deploymentString = - deploymentTargetString === '' ? '' : ` on "${deploymentTargetString}"`; - - const task = taskFromObservable( - Observable.concat( - createMessage( - `Resolving ${taskType} command for "${buildTarget}"${deploymentString}`, - 'log', - ), - Observable.defer(() => { - const trace = NuclideArtilleryTrace.begin('nuclide_buck', taskType); - if (selectedDeploymentTarget) { - const {platform, device} = selectedDeploymentTarget; - return platform - .runTask( - this._buildSystem, - ((taskType: any): TaskType), - buildRuleType.buildTarget, - taskSettings, - device, - ) - .do({ - error() { - trace.end(); - }, - complete() { - trace.end(); - }, - }); + if (!(buckRoot != null)) { + throw new Error('Invariant violation: "buckRoot != null"'); + } + + if (!buildRuleType) { + throw new Error('Invariant violation: "buildRuleType"'); + } + + const deploymentTargetString = (0, (_DeploymentTarget || _load_DeploymentTarget()).formatDeploymentTarget)(selectedDeploymentTarget); + const deploymentString = deploymentTargetString === '' ? '' : ` on "${deploymentTargetString}"`; + + const task = (0, (_tasks || _load_tasks()).taskFromObservable)(_rxjsBundlesRxMinJs.Observable.concat((0, (_tasks || _load_tasks()).createMessage)(`Resolving ${taskType} command for "${buildTarget}"${deploymentString}`, 'log'), _rxjsBundlesRxMinJs.Observable.defer(() => { + const trace = (_nuclideArtillery || _load_nuclideArtillery()).NuclideArtilleryTrace.begin('nuclide_buck', taskType); + if (selectedDeploymentTarget) { + const { platform, device } = selectedDeploymentTarget; + return platform.runTask(this._buildSystem, taskType, buildRuleType.buildTarget, taskSettings, device).do({ + error() { + trace.end(); + }, + complete() { + trace.end(); + } + }); + } else { + let subcommand; + if (isDebugTask(taskType)) { + if (buildRuleType.type.endsWith('test')) { + subcommand = 'test'; } else { - let subcommand; - if (isDebugTask(taskType)) { - if (buildRuleType.type.endsWith('test')) { - subcommand = 'test'; - } else { - subcommand = 'build'; - } - } else { - subcommand = getBuckSubcommandForTaskType(taskType); - } - return this._buildSystem - .runSubcommand( - buckRoot, - subcommand, - buildRuleType.buildTarget, - taskSettings, - isDebugTask(taskType), - null, - ) - .do({ - error() { - trace.end(); - }, - complete() { - trace.end(); - }, - }); + subcommand = 'build'; + } + } else { + subcommand = getBuckSubcommandForTaskType(taskType); + } + return this._buildSystem.runSubcommand(buckRoot, subcommand, buildRuleType.buildTarget, taskSettings, isDebugTask(taskType), null).do({ + error() { + trace.end(); + }, + complete() { + trace.end(); } - }), - ), - ); + }); + } + }))); task.onDidComplete(() => { this._completedTasksObservable.next({ @@ -392,32 +393,31 @@ export class BuckTaskRunner { buildRuleType, buildTarget, deploymentTarget: selectedDeploymentTarget, - taskSettings, + taskSettings }); }); - return { - ...task, + return Object.assign({}, task, { getTrackingData: () => ({ buildTarget, deploymentTarget: deploymentTargetString, ruleType: buildRuleType.type, - taskSettings: state.taskSettings, - }), - }; + taskSettings: state.taskSettings + }) + }); } - dispose(): void { + dispose() { this._disposables.dispose(); } - serialize(): ?SerializedState { + serialize() { // If we haven't had to load and create the Flux stuff yet, don't do it now. if (this._store == null) { return; } const state = this._store.getState(); - const {buildTarget, taskSettings} = state; + const { buildTarget, taskSettings } = state; const target = state.selectedDeploymentTarget; let selectedPlatformGroupName; let selectedPlatformName; @@ -426,8 +426,7 @@ export class BuckTaskRunner { if (target != null) { selectedPlatformGroupName = target.platformGroup.name; selectedPlatformName = target.platform.name; - selectedDeviceGroupName = - target.deviceGroup != null ? target.deviceGroup.name : null; + selectedDeviceGroupName = target.deviceGroup != null ? target.deviceGroup.name : null; selectedDeviceName = target.device != null ? target.device.name : null; } else { // In case the user quits before the session is restored, forward the session restoration. @@ -443,7 +442,8 @@ export class BuckTaskRunner { selectedPlatformGroupName, selectedPlatformName, selectedDeviceGroupName, - selectedDeviceName, + selectedDeviceName }; } } +exports.BuckTaskRunner = BuckTaskRunner; \ No newline at end of file diff --git a/pkg/nuclide-buck/lib/BuckToolbar.js b/pkg/nuclide-buck/lib/BuckToolbar.js index 2ab829a2d8..3829733888 100644 --- a/pkg/nuclide-buck/lib/BuckToolbar.js +++ b/pkg/nuclide-buck/lib/BuckToolbar.js @@ -1,53 +1,64 @@ -/** - * 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 - */ - -import type { - AppState, - DeploymentTarget, - DeviceGroup, - MobilePlatform, - PlatformGroup, - TaskSettings, -} from './types'; -import type {Option} from 'nuclide-commons-ui/Dropdown'; - -import * as React from 'react'; -import shallowequal from 'shallowequal'; - -import {formatDeploymentTarget} from './DeploymentTarget'; -import BuckToolbarSettings from './ui/BuckToolbarSettings'; -import BuckToolbarTargetSelector from './ui/BuckToolbarTargetSelector'; -import {Button, ButtonSizes} from 'nuclide-commons-ui/Button'; -import {Dropdown} from 'nuclide-commons-ui/Dropdown'; -import {LoadingSpinner} from 'nuclide-commons-ui/LoadingSpinner'; -import addTooltip from 'nuclide-commons-ui/addTooltip'; -import invariant from 'assert'; - -type Props = { - appState: AppState, - setBuildTarget(buildTarget: string): void, - setDeploymentTarget(deploymentTarget: DeploymentTarget): void, - setTaskSettings(settings: TaskSettings): void, -}; - -type State = { - settingsVisible: boolean, -}; - -type DropdownGroup = { - header: Option, - selectableOptions: Array
    { - this.setState({ - attachPort: this._getPortFromHHVMArgs(item.command), - }); - }} - collapsable={true} - /> - ) : null} - - - - + attachPort: this._getPortFromHHVMArgs(item.command) + }); + }, + collapsable: true + }) : null + ) + ) + ) ); } - _getPortFromHHVMArgs(command: string): ?number { + _getPortFromHHVMArgs(command) { const pattern = /--vsDebugPort(=|\s+)([0-9]+)/gi; const match = pattern.exec(command); return match != null && match.length >= 3 ? parseInt(match[2], 10) : null; } - _getPathMenuItems(): Array<{label: string, value: number}> { - const connections = RemoteConnection.getByHostname( - nuclideUri.getHostname(this.props.targetUri), - ); + _getPathMenuItems() { + const connections = (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).RemoteConnection.getByHostname((_nuclideUri || _load_nuclideUri()).default.getHostname(this.props.targetUri)); return connections.map((connection, index) => { const pathToProject = connection.getPath(); return { label: pathToProject, - value: index, + value: index }; }); } - _handlePathsDropdownChange = (newIndex: number): void => { - this.setState({ - selectedPathIndex: newIndex, - pathMenuItems: this._getPathMenuItems(), - }); - }; - - async _handleAttachButtonClick(): Promise { + async _handleAttachButtonClick() { // Start a debug session with the user-supplied information. - const {hostname} = nuclideUri.parseRemoteUri(this.props.targetUri); - const selectedPath = - this.state.attachType === 'webserver' - ? this.state.pathMenuItems[this.state.selectedPathIndex].label - : '/'; - - await this.props.startAttachProcessInfo( - nuclideUri.createRemoteUri(hostname, selectedPath), - this.state.attachPort, - this.state.attachType === 'webserver', - ); + const { hostname } = (_nuclideUri || _load_nuclideUri()).default.parseRemoteUri(this.props.targetUri); + const selectedPath = this.state.attachType === 'webserver' ? this.state.pathMenuItems[this.state.selectedPathIndex].label : '/'; + + await this.props.startAttachProcessInfo((_nuclideUri || _load_nuclideUri()).default.createRemoteUri(hostname, selectedPath), this.state.attachPort, this.state.attachType === 'webserver'); - serializeDebuggerConfig(...this._getSerializationArgs(), { + (0, (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).serializeDebuggerConfig)(...this._getSerializationArgs(), { selectedPath, - attachType: this.state.attachType, + attachType: this.state.attachType }); } } +exports.AttachUiComponent = AttachUiComponent; \ No newline at end of file diff --git a/pkg/nuclide-debugger-vsp/lib/HhvmLaunchAttachProvider.js b/pkg/nuclide-debugger-vsp/lib/HhvmLaunchAttachProvider.js index 1bc33c7e3b..ea0435b698 100644 --- a/pkg/nuclide-debugger-vsp/lib/HhvmLaunchAttachProvider.js +++ b/pkg/nuclide-debugger-vsp/lib/HhvmLaunchAttachProvider.js @@ -1,3 +1,65 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getLaunchProcessInfo = getLaunchProcessInfo; +exports.startAttachProcessInfo = startAttachProcessInfo; + +var _debugger; + +function _load_debugger() { + return _debugger = require('../../../modules/nuclide-commons-atom/debugger'); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _string; + +function _load_string() { + return _string = require('../../../modules/nuclide-commons/string'); +} + +var _nuclideDebuggerCommon; + +function _load_nuclideDebuggerCommon() { + return _nuclideDebuggerCommon = require('../../../modules/nuclide-debugger-common'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _HhvmLaunchUiComponent; + +function _load_HhvmLaunchUiComponent() { + return _HhvmLaunchUiComponent = require('./HhvmLaunchUiComponent'); +} + +var _HhvmAttachUiComponent; + +function _load_HhvmAttachUiComponent() { + return _HhvmAttachUiComponent = require('./HhvmAttachUiComponent'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,164 +67,107 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - DebuggerConfigAction, - ControlButtonSpecification, -} from 'nuclide-debugger-common'; -import type { - HHVMLaunchConfig, - HHVMAttachConfig, -} from '../../nuclide-debugger-hhvm-rpc'; - -import {getDebuggerService} from 'nuclide-commons-atom/debugger'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {shellParse} from 'nuclide-commons/string'; -import { - DebuggerLaunchAttachProvider, - VsAdapterTypes, - VspProcessInfo, -} from 'nuclide-debugger-common'; -import * as React from 'react'; -import {LaunchUiComponent} from './HhvmLaunchUiComponent'; -import {AttachUiComponent} from './HhvmAttachUiComponent'; -import invariant from 'assert'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -type PhpDebuggerSessionConfig = { - hhvmRuntimeArgs: string, - hhvmRuntimePath: string, - hhvmServerAttachPort: number, -}; - const CUSTOM_CPABILITIES = { completionsRequest: true, conditionalBreakpoints: true, continueToLocation: true, setVariable: true, - threads: true, + threads: true }; const CUSTOM_ATTACH_PROPERTIES = { customControlButtons: getCustomControlButtons(), - threadsComponentTitle: 'Requests', + threadsComponentTitle: 'Requests' }; -function getCustomControlButtons(): Array { - const customControlButtons = [ - { - icon: 'link-external', - title: 'Toggle HTTP Request Sender', - onClick: () => - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'nuclide-http-request-sender:toggle-http-request-edit-dialog', - ), - }, - ]; +function getCustomControlButtons() { + const customControlButtons = [{ + icon: 'link-external', + title: 'Toggle HTTP Request Sender', + onClick: () => atom.commands.dispatch(atom.views.getView(atom.workspace), 'nuclide-http-request-sender:toggle-http-request-edit-dialog') + }]; try { return customControlButtons.concat( - // $FlowFB - require('./fb-HhvmServices').customControlButtons, - ); + // $FlowFB + require('./fb-HhvmServices').customControlButtons); } catch (_) { return customControlButtons; } } -export default class HhvmLaunchAttachProvider extends DebuggerLaunchAttachProvider { - constructor(debuggingTypeName: string, targetUri: string) { +class HhvmLaunchAttachProvider extends (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).DebuggerLaunchAttachProvider { + constructor(debuggingTypeName, targetUri) { super(debuggingTypeName, targetUri); } - getCallbacksForAction(action: DebuggerConfigAction) { + getCallbacksForAction(action) { return { /** * Whether this provider is enabled or not. */ - isEnabled: (): Promise => { - return Promise.resolve(nuclideUri.isRemote(this.getTargetUri())); + isEnabled: () => { + return Promise.resolve((_nuclideUri || _load_nuclideUri()).default.isRemote(this.getTargetUri())); }, /** * Returns a list of supported debugger types + environments for the specified action. */ - getDebuggerTypeNames: super.getCallbacksForAction(action) - .getDebuggerTypeNames, + getDebuggerTypeNames: super.getCallbacksForAction(action).getDebuggerTypeNames, /** * Returns the UI component for configuring the specified debugger type and action. */ - getComponent: ( - debuggerTypeName: string, - configIsValidChanged: (valid: boolean) => void, - ) => { + getComponent: (debuggerTypeName, configIsValidChanged) => { if (action === 'launch') { - return ( - - ); + return _react.createElement((_HhvmLaunchUiComponent || _load_HhvmLaunchUiComponent()).LaunchUiComponent, { + targetUri: this.getTargetUri(), + configIsValidChanged: configIsValidChanged, + getLaunchProcessInfo: getLaunchProcessInfo + }); } else if (action === 'attach') { - return ( - - ); + return _react.createElement((_HhvmAttachUiComponent || _load_HhvmAttachUiComponent()).AttachUiComponent, { + targetUri: this.getTargetUri(), + configIsValidChanged: configIsValidChanged, + startAttachProcessInfo: startAttachProcessInfo + }); } else { - invariant(false, 'Unrecognized action for component.'); + if (!false) { + throw new Error('Unrecognized action for component.'); + } } - }, + } }; } - dispose(): void {} + dispose() {} } -function getConfig(): PhpDebuggerSessionConfig { - return (featureConfig.get('nuclide-debugger-php'): any); +exports.default = HhvmLaunchAttachProvider; +function getConfig() { + return (_featureConfig || _load_featureConfig()).default.get('nuclide-debugger-php'); } // Determines the debug configuration for launching the HHVM debugger -function _getHHVMLaunchConfig( - targetUri: NuclideUri, - scriptPath: string, - scriptArgs: string, - scriptWrapperCommand: ?string, - runInTerminal: boolean, - cwdPath: string, -): HHVMLaunchConfig { +function _getHHVMLaunchConfig(targetUri, scriptPath, scriptArgs, scriptWrapperCommand, runInTerminal, cwdPath) { const userConfig = getConfig(); const deferLaunch = runInTerminal; // Honor any PHP configuration the user has in Nuclide settings. - const phpRuntimePath = - userConfig.hhvmRuntimePath != null - ? String(userConfig.hhvmRuntimePath) - : null; - const hhvmRuntimeArgs = shellParse( - userConfig.hhvmRuntimeArgs != null - ? String(userConfig.hhvmRuntimeArgs) - : '', - ); - - const config: HHVMLaunchConfig = { - targetUri: nuclideUri.getPath(targetUri), + const phpRuntimePath = userConfig.hhvmRuntimePath != null ? String(userConfig.hhvmRuntimePath) : null; + const hhvmRuntimeArgs = (0, (_string || _load_string()).shellParse)(userConfig.hhvmRuntimeArgs != null ? String(userConfig.hhvmRuntimeArgs) : ''); + + const config = { + targetUri: (_nuclideUri || _load_nuclideUri()).default.getPath(targetUri), action: 'launch', launchScriptPath: scriptPath, - scriptArgs: shellParse(scriptArgs), + scriptArgs: (0, (_string || _load_string()).shellParse)(scriptArgs), hhvmRuntimeArgs, - deferLaunch, + deferLaunch }; if (cwdPath != null && cwdPath !== '') { @@ -180,43 +185,18 @@ function _getHHVMLaunchConfig( return config; } -export async function getLaunchProcessInfo( - targetUri: NuclideUri, - scriptPath: string, - scriptArgs: string, - scriptWrapperCommand: ?string, - runInTerminal: boolean, - cwdPath: string, -): Promise { - const config = _getHHVMLaunchConfig( - targetUri, - scriptPath, - scriptArgs, - scriptWrapperCommand, - runInTerminal, - cwdPath, - ); - const adapterType = VsAdapterTypes.HHVM; - return new VspProcessInfo( - targetUri, - 'launch', - adapterType, - null, - config, - CUSTOM_CPABILITIES, - ); +async function getLaunchProcessInfo(targetUri, scriptPath, scriptArgs, scriptWrapperCommand, runInTerminal, cwdPath) { + const config = _getHHVMLaunchConfig(targetUri, scriptPath, scriptArgs, scriptWrapperCommand, runInTerminal, cwdPath); + const adapterType = (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsAdapterTypes.HHVM; + return new (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VspProcessInfo(targetUri, 'launch', adapterType, null, config, CUSTOM_CPABILITIES); } -function _getHHVMAttachConfig( - targetUri: NuclideUri, - attachPort: ?number, -): HHVMAttachConfig { +function _getHHVMAttachConfig(targetUri, attachPort) { // Note: not specifying startup document or debug port here, the backend // will use the default parameters. We can surface these options in the - // Attach Dialog if users need to be able to customize them in the future. - const config: HHVMAttachConfig = { - targetUri: nuclideUri.getPath(targetUri), - action: 'attach', + const config = { + targetUri: (_nuclideUri || _load_nuclideUri()).default.getPath(targetUri), + action: 'attach' }; // If attach port is not specified by the caller, see if one is specified @@ -236,47 +216,29 @@ function _getHHVMAttachConfig( return config; } -export async function startAttachProcessInfo( - targetUri: NuclideUri, - attachPort: ?number, - serverAttach: boolean, -): Promise { +async function startAttachProcessInfo(targetUri, attachPort, serverAttach) { const config = _getHHVMAttachConfig(targetUri, attachPort); - const processInfo = new VspProcessInfo( - targetUri, - 'attach', - VsAdapterTypes.HHVM, - null, - config, - CUSTOM_CPABILITIES, - CUSTOM_ATTACH_PROPERTIES, - ); - - const debugService = await getDebuggerService(); + const processInfo = new (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VspProcessInfo(targetUri, 'attach', (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsAdapterTypes.HHVM, null, config, CUSTOM_CPABILITIES, CUSTOM_ATTACH_PROPERTIES); + + const debugService = await (0, (_debugger || _load_debugger()).getDebuggerService)(); const startDebuggingPromise = debugService.startDebugging(processInfo); try { // $FlowFB const services = require('./fb-HhvmServices'); services.startSlog(); - processInfo.addCustomDisposable( - new UniversalDisposable(() => { - services.stopSlog(); + processInfo.addCustomDisposable(new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { + services.stopSlog(); - if (serverAttach) { - services.stopCrashHandler(processInfo); - } - }), - ); + if (serverAttach) { + services.stopCrashHandler(processInfo); + } + })); if (serverAttach) { await startDebuggingPromise; - services.startCrashHandler( - targetUri, - processInfo, - startAttachProcessInfo, - ); + services.startCrashHandler(targetUri, processInfo, startAttachProcessInfo); } } catch (_) {} return processInfo; -} +} \ No newline at end of file diff --git a/pkg/nuclide-debugger-vsp/lib/HhvmLaunchUiComponent.js b/pkg/nuclide-debugger-vsp/lib/HhvmLaunchUiComponent.js index 977bda4b20..28e07a3328 100644 --- a/pkg/nuclide-debugger-vsp/lib/HhvmLaunchUiComponent.js +++ b/pkg/nuclide-debugger-vsp/lib/HhvmLaunchUiComponent.js @@ -1,3 +1,70 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LaunchUiComponent = undefined; + +var _react = _interopRequireWildcard(require('react')); + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../../../modules/nuclide-commons-ui/AtomInput'); +} + +var _debugger; + +function _load_debugger() { + return _debugger = require('../../../modules/nuclide-commons-atom/debugger'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _Dropdown; + +function _load_Dropdown() { + return _Dropdown = require('../../../modules/nuclide-commons-ui/Dropdown'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _nuclideDebuggerCommon; + +function _load_nuclideDebuggerCommon() { + return _nuclideDebuggerCommon = require('../../../modules/nuclide-debugger-common'); +} + +var _Checkbox; + +function _load_Checkbox() { + return _Checkbox = require('../../../modules/nuclide-commons-ui/Checkbox'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,196 +72,165 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ /* global localStorage */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {VspProcessInfo} from 'nuclide-debugger-common'; - -import * as React from 'react'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {getDebuggerService} from 'nuclide-commons-atom/debugger'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import nullthrows from 'nullthrows'; -import {Dropdown} from 'nuclide-commons-ui/Dropdown'; -import {RemoteConnection} from '../../nuclide-remote-connection'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import { - serializeDebuggerConfig, - deserializeDebuggerConfig, -} from 'nuclide-debugger-common'; -import {Checkbox} from 'nuclide-commons-ui/Checkbox'; - const MAX_RECENTLY_LAUNCHED = 5; -type Props = { - targetUri: NuclideUri, - configIsValidChanged: (valid: boolean) => void, - getLaunchProcessInfo: ( - targetUri: NuclideUri, - scriptPath: string, - scriptArgs: string, - scriptWrapperCommand: ?string, - runInTerminal: boolean, - cwdPath: string, - ) => Promise, -}; - -type State = { - recentlyLaunchedScripts: Array<{label: string, value: string}>, - recentlyLaunchedScript: ?string, - runInTerminal: boolean, - cwd: ?string, - scriptArgs: ?string, -}; - -export class LaunchUiComponent extends React.Component { - _disposables: UniversalDisposable = new UniversalDisposable(); - _scriptPath: ?AtomInput; - _scriptArgs: ?AtomInput; - _cwdPath: ?AtomInput; - - constructor(props: Props) { +class LaunchUiComponent extends _react.Component { + + constructor(props) { super(props); - (this: any)._handleLaunchButtonClick = this._handleLaunchButtonClick.bind( - this, - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + + this._handleRecentSelectionChange = newValue => { + this.setState({ + recentlyLaunchedScript: newValue + }); + }; + + this._getActiveFilePath = () => { + const editor = atom.workspace.getActiveTextEditor(); + if (editor != null) { + const fileUri = editor.getPath(); + if (fileUri != null && this._isValidScriptUri(fileUri)) { + return (_nuclideUri || _load_nuclideUri()).default.getPath(fileUri); + } + } + return ''; + }; + + this._handleLaunchButtonClick = this._handleLaunchButtonClick.bind(this); this.state = { recentlyLaunchedScripts: this._getRecentlyLaunchedScripts(), recentlyLaunchedScript: null, runInTerminal: false, scriptArgs: null, - cwd: this._getLastCwd(), + cwd: this._getLastCwd() }; } _getSerializationArgs() { - return [ - nuclideUri.isRemote(this.props.targetUri) - ? nuclideUri.getHostname(this.props.targetUri) - : 'local', - 'launch', - 'php', - ]; + return [(_nuclideUri || _load_nuclideUri()).default.isRemote(this.props.targetUri) ? (_nuclideUri || _load_nuclideUri()).default.getHostname(this.props.targetUri) : 'local', 'launch', 'php']; } - componentDidMount(): void { - deserializeDebuggerConfig( - ...this._getSerializationArgs(), - (transientSettings, savedSettings) => { - this.setState({ - recentlyLaunchedScript: savedSettings.scriptPath || '', - cwd: savedSettings.cwdPath || '', - scriptArgs: savedSettings.scriptArgs || '', - }); - }, - ); + componentDidMount() { + (0, (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).deserializeDebuggerConfig)(...this._getSerializationArgs(), (transientSettings, savedSettings) => { + this.setState({ + recentlyLaunchedScript: savedSettings.scriptPath || '', + cwd: savedSettings.cwdPath || '', + scriptArgs: savedSettings.scriptArgs || '' + }); + }); this.props.configIsValidChanged(this._debugButtonShouldEnable()); - this._disposables.add( - atom.commands.add('atom-workspace', { - 'core:confirm': () => { - if (this._debugButtonShouldEnable()) { - this._handleLaunchButtonClick(); - } - }, - }), - ); + this._disposables.add(atom.commands.add('atom-workspace', { + 'core:confirm': () => { + if (this._debugButtonShouldEnable()) { + this._handleLaunchButtonClick(); + } + } + })); } componentWillUnmount() { this._disposables.dispose(); } - setState(newState: Object): void { - super.setState(newState, () => - this.props.configIsValidChanged(this._debugButtonShouldEnable()), - ); + setState(newState) { + super.setState(newState, () => this.props.configIsValidChanged(this._debugButtonShouldEnable())); } - _debugButtonShouldEnable(): boolean { - return ( - this.state.recentlyLaunchedScript != null && - this.state.recentlyLaunchedScript.trim() !== '' - ); + _debugButtonShouldEnable() { + return this.state.recentlyLaunchedScript != null && this.state.recentlyLaunchedScript.trim() !== ''; } - render(): React.Node { - return ( -
    - - {/* $FlowFixMe(>=0.53.0) Flow suppress */} - - - { - this._scriptPath = input; - }} - tabIndex="11" - placeholderText="/path/to/my/script.php arg1 arg2" - initialValue={this._getActiveFilePath()} - value={this.state.recentlyLaunchedScript || ''} - onDidChange={value => this.setState({recentlyLaunchedScript: value})} - /> - - { - this._scriptArgs = input; - }} - tabIndex="12" - value={this.state.scriptArgs || ''} - onDidChange={value => this.setState({scriptArgs: value})} - /> - - { - this._cwdPath = input; - }} - placeholderText="Optional. Working directory to launch script in." - initialValue="" - value={this.state.cwd || ''} - onDidChange={value => this.setState({cwd: value})} - /> - this.setState({runInTerminal: checked})} - title="When checked, the target script's STDIN and STDOUT will be redirected to a new Nuclide Terminal pane" - /> -
    + render() { + return _react.createElement( + 'div', + { className: 'block' }, + _react.createElement( + 'label', + null, + 'Recently launched commands: ' + ), + _react.createElement((_Dropdown || _load_Dropdown()).Dropdown, { + className: 'inline-block debugger-recently-launched', + options: [{ label: '', value: null }, ...this.state.recentlyLaunchedScripts], + onChange: this._handleRecentSelectionChange, + value: this.state.recentlyLaunchedScript + }), + _react.createElement( + 'label', + null, + 'Script path: ' + ), + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + ref: input => { + this._scriptPath = input; + }, + tabIndex: '11', + placeholderText: '/path/to/my/script.php arg1 arg2', + initialValue: this._getActiveFilePath(), + value: this.state.recentlyLaunchedScript || '', + onDidChange: value => this.setState({ recentlyLaunchedScript: value }) + }), + _react.createElement( + 'label', + null, + 'Script arguments: ' + ), + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + ref: input => { + this._scriptArgs = input; + }, + tabIndex: '12', + value: this.state.scriptArgs || '', + onDidChange: value => this.setState({ scriptArgs: value }) + }), + _react.createElement( + 'label', + null, + 'Current Working Directory: ' + ), + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + tabIndex: '13', + ref: input => { + this._cwdPath = input; + }, + placeholderText: 'Optional. Working directory to launch script in.', + initialValue: '', + value: this.state.cwd || '', + onDidChange: value => this.setState({ cwd: value }) + }), + _react.createElement((_Checkbox || _load_Checkbox()).Checkbox, { + checked: this.state.runInTerminal, + label: 'Run in Terminal', + onChange: checked => this.setState({ runInTerminal: checked }), + title: 'When checked, the target script\'s STDIN and STDOUT will be redirected to a new Nuclide Terminal pane' + }) ); } _getRecentlyLaunchedKey() { - const hostname = nuclideUri.getHostname(this.props.targetUri); + const hostname = (_nuclideUri || _load_nuclideUri()).default.getHostname(this.props.targetUri); return 'debugger-php.recentlyLaunchedScripts:' + hostname; } _getCwdKey() { - const hostname = nuclideUri.getHostname(this.props.targetUri); + const hostname = (_nuclideUri || _load_nuclideUri()).default.getHostname(this.props.targetUri); return 'debugger-php.Cwd:' + hostname; } - _getLastCwd(): ?string { + _getLastCwd() { const lastCwd = localStorage.getItem(this._getCwdKey()); return lastCwd; } - _getRecentlyLaunchedScripts(): Array<{label: string, value: string}> { - const recentlyLaunched = localStorage.getItem( - this._getRecentlyLaunchedKey(), - ); + _getRecentlyLaunchedScripts() { + const recentlyLaunched = localStorage.getItem(this._getRecentlyLaunchedKey()); if (recentlyLaunched == null) { return []; } @@ -203,16 +239,12 @@ export class LaunchUiComponent extends React.Component { return items.filter(script => script !== '').map(script => { return { label: script, - value: script, + value: script }; }); } - _setRecentlyLaunchedScript( - script: string, - recentlyLaunched: Array<{label: string, value: string}>, - cwd: string, - ): void { + _setRecentlyLaunchedScript(script, recentlyLaunched, cwd) { // Act like a simple MRU cache, move the script being launched to the front. // NOTE: this array is expected to be really tiny. const scriptNames = [script]; @@ -222,87 +254,51 @@ export class LaunchUiComponent extends React.Component { } }); - localStorage.setItem( - this._getRecentlyLaunchedKey(), - JSON.stringify(scriptNames), - ); + localStorage.setItem(this._getRecentlyLaunchedKey(), JSON.stringify(scriptNames)); localStorage.setItem(this._getCwdKey(), cwd); this.setState({ recentlyLaunchedScripts: this._getRecentlyLaunchedScripts(), - recentlyLaunchedScript: script, + recentlyLaunchedScript: script }); } - _getPathMenuItems(): Array<{label: string, value: number}> { - const hostname = nuclideUri.getHostname(this.props.targetUri); - const connections = RemoteConnection.getByHostname(hostname); + _getPathMenuItems() { + const hostname = (_nuclideUri || _load_nuclideUri()).default.getHostname(this.props.targetUri); + const connections = (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).RemoteConnection.getByHostname(hostname); return connections.map((connection, index) => { const pathToProject = connection.getPath(); return { label: pathToProject, - value: index, + value: index }; }); } - _handleRecentSelectionChange = (newValue: string): void => { - this.setState({ - recentlyLaunchedScript: newValue, - }); - }; - - async _handleLaunchButtonClick(): Promise { - const scriptPath = nullthrows(this._scriptPath) - .getText() - .trim(); - const cwdPath = nullthrows(this._cwdPath) - .getText() - .trim(); - const scriptArgs = nullthrows(this._scriptArgs) - .getText() - .trim(); - - this._setRecentlyLaunchedScript( - scriptPath, - this.state.recentlyLaunchedScripts, - cwdPath, - ); + async _handleLaunchButtonClick() { + const scriptPath = (0, (_nullthrows || _load_nullthrows()).default)(this._scriptPath).getText().trim(); + const cwdPath = (0, (_nullthrows || _load_nullthrows()).default)(this._cwdPath).getText().trim(); + const scriptArgs = (0, (_nullthrows || _load_nullthrows()).default)(this._scriptArgs).getText().trim(); - const processInfo = await this.props.getLaunchProcessInfo( - this.props.targetUri, - scriptPath, - scriptArgs, - null, - this.state.runInTerminal, - cwdPath, - ); + this._setRecentlyLaunchedScript(scriptPath, this.state.recentlyLaunchedScripts, cwdPath); - const debuggerService = await getDebuggerService(); + const processInfo = await this.props.getLaunchProcessInfo(this.props.targetUri, scriptPath, scriptArgs, null, this.state.runInTerminal, cwdPath); + + const debuggerService = await (0, (_debugger || _load_debugger()).getDebuggerService)(); debuggerService.startDebugging(processInfo); - serializeDebuggerConfig(...this._getSerializationArgs(), { + (0, (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).serializeDebuggerConfig)(...this._getSerializationArgs(), { scriptPath, scriptArgs, - cwdPath, + cwdPath }); } - _getActiveFilePath = (): string => { - const editor = atom.workspace.getActiveTextEditor(); - if (editor != null) { - const fileUri = editor.getPath(); - if (fileUri != null && this._isValidScriptUri(fileUri)) { - return nuclideUri.getPath(fileUri); - } - } - return ''; - }; - - _isValidScriptUri(uri: NuclideUri): boolean { - if (!nuclideUri.isRemote(uri)) { + _isValidScriptUri(uri) { + if (!(_nuclideUri || _load_nuclideUri()).default.isRemote(uri)) { return false; } - const scriptPath = nuclideUri.getPath(uri); + const scriptPath = (_nuclideUri || _load_nuclideUri()).default.getPath(uri); return scriptPath.endsWith('.php') || scriptPath.endsWith('.hh'); } } +exports.LaunchUiComponent = LaunchUiComponent; \ No newline at end of file diff --git a/pkg/nuclide-debugger-vsp/lib/main.js b/pkg/nuclide-debugger-vsp/lib/main.js index 26d5f3eb2b..2066d0f985 100644 --- a/pkg/nuclide-debugger-vsp/lib/main.js +++ b/pkg/nuclide-debugger-vsp/lib/main.js @@ -1,38 +1,69 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type { - NuclideDebuggerProvider, - DebuggerConfigurationProvider, -} from 'nuclide-debugger-common'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import {VsAdapterTypes} from 'nuclide-debugger-common'; -import {getNativeAutoGenConfig} from 'nuclide-debugger-common/autogen-utils'; -import passesGK from '../../commons-node/passesGK'; -import {AutoGenLaunchAttachProvider} from 'nuclide-debugger-common/AutoGenLaunchAttachProvider'; -import HhvmLaunchAttachProvider from './HhvmLaunchAttachProvider'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import fsPromise from 'nuclide-commons/fsPromise'; -import {getPrepackAutoGenConfig, resolveConfiguration} from './utils'; -// eslint-disable-next-line nuclide-internal/prefer-nuclide-uri -import path from 'path'; +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _nuclideDebuggerCommon; + +function _load_nuclideDebuggerCommon() { + return _nuclideDebuggerCommon = require('../../../modules/nuclide-debugger-common'); +} + +var _autogenUtils; + +function _load_autogenUtils() { + return _autogenUtils = require('../../../modules/nuclide-debugger-common/autogen-utils'); +} + +var _passesGK; + +function _load_passesGK() { + return _passesGK = _interopRequireDefault(require('../../commons-node/passesGK')); +} + +var _AutoGenLaunchAttachProvider; + +function _load_AutoGenLaunchAttachProvider() { + return _AutoGenLaunchAttachProvider = require('../../../modules/nuclide-debugger-common/AutoGenLaunchAttachProvider'); +} + +var _HhvmLaunchAttachProvider; + +function _load_HhvmLaunchAttachProvider() { + return _HhvmLaunchAttachProvider = _interopRequireDefault(require('./HhvmLaunchAttachProvider')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _utils; + +function _load_utils() { + return _utils = require('./utils'); +} + +var _path = _interopRequireDefault(require('path')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class Activation { - _subscriptions: UniversalDisposable; constructor() { - this._subscriptions = new UniversalDisposable(); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); - fsPromise.exists(path.join(__dirname, 'fb-marker')).then(exists => { + (_fsPromise || _load_fsPromise()).default.exists(_path.default.join(__dirname, 'fb-marker')).then(exists => { const isOpenSource = !exists; this._registerPrepackDebugProvider(isOpenSource); this._registerLLDBProvider(); @@ -40,59 +71,60 @@ class Activation { }); } - _registerDebugProvider(provider: NuclideDebuggerProvider): void { - this._subscriptions.add( - atom.packages.serviceHub.provide('debugger.provider', '0.0.0', provider), - ); + _registerDebugProvider(provider) { + this._subscriptions.add(atom.packages.serviceHub.provide('debugger.provider', '0.0.0', provider)); } - async _registerPrepackDebugProvider(isOpenSource: boolean): Promise { - if ((await passesGK('nuclide_debugger_prepack')) || isOpenSource) { + async _registerPrepackDebugProvider(isOpenSource) { + if ((await (0, (_passesGK || _load_passesGK()).default)('nuclide_debugger_prepack')) || isOpenSource) { this._registerDebugProvider({ - type: VsAdapterTypes.PREPACK, + type: (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsAdapterTypes.PREPACK, getLaunchAttachProvider: connection => { - return new AutoGenLaunchAttachProvider( - 'Prepack', - connection, - getPrepackAutoGenConfig(), - ); - }, + return new (_AutoGenLaunchAttachProvider || _load_AutoGenLaunchAttachProvider()).AutoGenLaunchAttachProvider('Prepack', connection, (0, (_utils || _load_utils()).getPrepackAutoGenConfig)()); + } }); } } _registerLLDBProvider() { this._registerDebugProvider({ - type: VsAdapterTypes.NATIVE_LLDB, + type: (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsAdapterTypes.NATIVE_LLDB, getLaunchAttachProvider: connection => { - return new AutoGenLaunchAttachProvider( - 'Native - LLDB (C/C++)', - connection, - getNativeAutoGenConfig(VsAdapterTypes.NATIVE_LLDB), - ); - }, + return new (_AutoGenLaunchAttachProvider || _load_AutoGenLaunchAttachProvider()).AutoGenLaunchAttachProvider('Native - LLDB (C/C++)', connection, (0, (_autogenUtils || _load_autogenUtils()).getNativeAutoGenConfig)((_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsAdapterTypes.NATIVE_LLDB)); + } }); } - async _registerHHVMDebugProvider(): Promise { + async _registerHHVMDebugProvider() { this._registerDebugProvider({ - type: VsAdapterTypes.HHVM, + type: (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsAdapterTypes.HHVM, getLaunchAttachProvider: connection => { - return new HhvmLaunchAttachProvider('Hack / PHP', connection); - }, + return new (_HhvmLaunchAttachProvider || _load_HhvmLaunchAttachProvider()).default('Hack / PHP', connection); + } }); } - createDebuggerConfigurator(): DebuggerConfigurationProvider { + createDebuggerConfigurator() { return { - resolveConfiguration, - adapterType: VsAdapterTypes.NATIVE_LLDB, + resolveConfiguration: (_utils || _load_utils()).resolveConfiguration, + adapterType: (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsAdapterTypes.NATIVE_LLDB }; } - dispose(): void { + dispose() { this._subscriptions.dispose(); } } +// eslint-disable-next-line nuclide-internal/prefer-nuclide-uri +/** + * 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. + * + * strict-local + * @format + */ -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-debugger-vsp/lib/utils.js b/pkg/nuclide-debugger-vsp/lib/utils.js index 60ca96fa1a..9d50dea1a7 100644 --- a/pkg/nuclide-debugger-vsp/lib/utils.js +++ b/pkg/nuclide-debugger-vsp/lib/utils.js @@ -1,3 +1,32 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getPrepackAutoGenConfig = getPrepackAutoGenConfig; +exports.resolveConfiguration = resolveConfiguration; +exports.getNativeAutoGenConfig = getNativeAutoGenConfig; +exports.getNativeVSPLaunchProcessInfo = getNativeVSPLaunchProcessInfo; +exports.getNativeVSPAttachProcessInfo = getNativeVSPAttachProcessInfo; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _nuclideDebuggerCommon; + +function _load_nuclideDebuggerCommon() { + return _nuclideDebuggerCommon = require('../../../modules/nuclide-debugger-common'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,54 +34,24 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {IProcessConfig, VsAdapterType} from 'nuclide-debugger-common'; -import type { - AutoGenConfig, - AutoGenLaunchConfig, - NativeVsAdapterType, - AutoGenAttachConfig, -} from 'nuclide-debugger-common/types'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import { - VsAdapterTypes, - VspProcessInfo, - getVSCodeDebuggerAdapterServiceByNuclideUri, -} from 'nuclide-debugger-common'; -import * as React from 'react'; - -export type VspNativeDebuggerLaunchBuilderParms = { - args: Array, - cwd: string, - env: Array, - sourcePath: string, -}; - -export type VspNativeDebuggerAttachBuilderParms = { - pid?: number, - sourcePath: string, - stopCommands?: Array, -}; - -export function getPrepackAutoGenConfig(): AutoGenConfig { +function getPrepackAutoGenConfig() { const fileToPrepack = { name: 'sourceFile', type: 'string', description: 'Input the file you want to Prepack. Use absolute paths.', required: true, - visible: true, + visible: true }; const prepackRuntimePath = { name: 'prepackRuntime', type: 'string', - description: - 'Prepack executable path (e.g. lib/prepack-cli.js). Use absolute paths.', + description: 'Prepack executable path (e.g. lib/prepack-cli.js). Use absolute paths.', required: false, - visible: true, + visible: true }; const argumentsProperty = { name: 'prepackArguments', @@ -61,26 +60,26 @@ export function getPrepackAutoGenConfig(): AutoGenConfig { description: 'Arguments to start Prepack', required: false, defaultValue: '', - visible: true, + visible: true }; - const autoGenLaunchConfig: AutoGenLaunchConfig = { + const autoGenLaunchConfig = { launch: true, - vsAdapterType: VsAdapterTypes.PREPACK, + vsAdapterType: (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsAdapterTypes.PREPACK, threads: false, properties: [fileToPrepack, prepackRuntimePath, argumentsProperty], scriptPropertyName: 'fileToPrepack', scriptExtension: '.js', cwdPropertyName: null, - header: null, + header: null }; return { launch: autoGenLaunchConfig, - attach: null, + attach: null }; } -async function lldbVspAdapterWrapperPath(program: NuclideUri): Promise { +async function lldbVspAdapterWrapperPath(program) { try { // $FlowFB return require('./fb-LldbVspAdapterPath').getLldbVspAdapterPath(program); @@ -89,28 +88,20 @@ async function lldbVspAdapterWrapperPath(program: NuclideUri): Promise { } } -export async function resolveConfiguration( - configuration: IProcessConfig, -): Promise { - const {adapterExecutable, targetUri} = configuration; +async function resolveConfiguration(configuration) { + const { adapterExecutable, targetUri } = configuration; if (adapterExecutable == null) { throw new Error('Cannot resolve configuration for unset adapterExecutable'); } - const debuggerService = getVSCodeDebuggerAdapterServiceByNuclideUri( - configuration.targetUri, - ); + const debuggerService = (0, (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).getVSCodeDebuggerAdapterServiceByNuclideUri)(configuration.targetUri); let sourcePath = configuration.config.sourcePath; if (sourcePath == null || sourcePath.trim() === '') { if (configuration.debugMode === 'launch') { - sourcePath = await debuggerService.getBuckRootFromUri( - configuration.config.program, - ); + sourcePath = await debuggerService.getBuckRootFromUri(configuration.config.program); } else if (configuration.config.pid != null) { - sourcePath = await debuggerService.getBuckRootFromPid( - configuration.config.pid, - ); + sourcePath = await debuggerService.getBuckRootFromPid(configuration.config.pid); } } @@ -121,29 +112,26 @@ export async function resolveConfiguration( adapterExecutable.command = await lldbVspAdapterWrapperPath(targetUri); - return { - ...configuration, + return Object.assign({}, configuration, { config, - adapterExecutable, - }; + adapterExecutable + }); } -export function getNativeAutoGenConfig( - vsAdapterType: NativeVsAdapterType, -): AutoGenConfig { +function getNativeAutoGenConfig(vsAdapterType) { const program = { name: 'program', type: 'path', description: 'Input the program/executable you want to launch', required: true, - visible: true, + visible: true }; const cwd = { name: 'cwd', type: 'path', description: 'Working directory for the launched executable', required: true, - visible: true, + visible: true }; const args = { name: 'args', @@ -152,7 +140,7 @@ export function getNativeAutoGenConfig( description: 'Arguments to the executable', required: false, defaultValue: '', - visible: true, + visible: true }; const env = { name: 'env', @@ -161,7 +149,7 @@ export function getNativeAutoGenConfig( description: 'Environment variables (e.g., SHELL=/bin/bash PATH=/bin)', required: false, defaultValue: '', - visible: true, + visible: true }; const sourcePath = { name: 'sourcePath', @@ -169,21 +157,25 @@ export function getNativeAutoGenConfig( description: 'Optional base path for sources', required: false, defaultValue: '', - visible: true, + visible: true }; - const debugTypeMessage = `using ${ - vsAdapterType === VsAdapterTypes.NATIVE_GDB ? 'gdb' : 'lldb' - }`; + const debugTypeMessage = `using ${vsAdapterType === (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsAdapterTypes.NATIVE_GDB ? 'gdb' : 'lldb'}`; - const autoGenLaunchConfig: AutoGenLaunchConfig = { + const autoGenLaunchConfig = { launch: true, vsAdapterType, threads: true, properties: [program, cwd, args, env, sourcePath], scriptPropertyName: 'program', cwdPropertyName: 'working directory', - header:

    Debug native programs {debugTypeMessage}.

    , + header: _react.createElement( + 'p', + null, + 'Debug native programs ', + debugTypeMessage, + '.' + ) }; const pid = { @@ -191,45 +183,34 @@ export function getNativeAutoGenConfig( type: 'process', description: '', required: true, - visible: true, + visible: true }; - const autoGenAttachConfig: AutoGenAttachConfig = { + 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 }; } -export async function getNativeVSPLaunchProcessInfo( - adapter: VsAdapterType, - program: NuclideUri, - args: VspNativeDebuggerLaunchBuilderParms, -): Promise { - return new VspProcessInfo( - program, - 'launch', - adapter, - null, - { - program: nuclideUri.getPath(program), - ...args, - }, - {threads: true}, - ); +async function getNativeVSPLaunchProcessInfo(adapter, program, args) { + return new (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VspProcessInfo(program, 'launch', adapter, null, Object.assign({ + program: (_nuclideUri || _load_nuclideUri()).default.getPath(program) + }, args), { threads: true }); } -export async function getNativeVSPAttachProcessInfo( - adapter: VsAdapterType, - targetUri: NuclideUri, - args: VspNativeDebuggerAttachBuilderParms, -): Promise { - return new VspProcessInfo(targetUri, 'attach', adapter, null, args, { - threads: true, +async function getNativeVSPAttachProcessInfo(adapter, targetUri, args) { + return new (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VspProcessInfo(targetUri, 'attach', adapter, null, args, { + threads: true }); -} +} \ No newline at end of file diff --git a/pkg/nuclide-deep-link/__atom_tests__/DeepLinkService-test.js b/pkg/nuclide-deep-link/__atom_tests__/DeepLinkService-test.js index c6f666371a..6ede843cb5 100644 --- a/pkg/nuclide-deep-link/__atom_tests__/DeepLinkService-test.js +++ b/pkg/nuclide-deep-link/__atom_tests__/DeepLinkService-test.js @@ -1,45 +1,63 @@ -/** - * 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 strict-local - * @format - */ - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import electron from 'electron'; -import nullthrows from 'nullthrows'; -import DeepLinkService from '../lib/DeepLinkService'; -import waitsFor from '../../../jest/waits_for'; - -const remote = nullthrows(electron.remote); +'use strict'; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _electron = _interopRequireDefault(require('electron')); + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _DeepLinkService; + +function _load_DeepLinkService() { + return _DeepLinkService = _interopRequireDefault(require('../lib/DeepLinkService')); +} + +var _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../../../jest/waits_for')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const remote = (0, (_nullthrows || _load_nullthrows()).default)(_electron.default.remote); /** + * 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. + * + * strict-local + * @format + */ describe('DeepLinkService', () => { it('allows subscriptions to messages', async () => { - const service = new DeepLinkService(); + const service = new (_DeepLinkService || _load_DeepLinkService()).default(); const testSpy1 = jest.fn(); const testSpy11 = jest.fn(); const testSpy2 = jest.fn(); // Make sure multiple subscriptions go through. - const disposables = new UniversalDisposable( - service.subscribeToPath('test1', testSpy1), - service.subscribeToPath('test1', testSpy11), - service.subscribeToPath('test2', testSpy2), - ); + const disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(service.subscribeToPath('test1', testSpy1), service.subscribeToPath('test1', testSpy11), service.subscribeToPath('test2', testSpy2)); const browserWindow = remote.getCurrentWindow(); - service.sendDeepLink(browserWindow, 'test1', {a: '1'}); - service.sendDeepLink(browserWindow, 'test2/', {b: '2'}); + service.sendDeepLink(browserWindow, 'test1', { a: '1' }); + service.sendDeepLink(browserWindow, 'test2/', { b: '2' }); - await waitsFor(() => testSpy1.mock.calls.length > 0); + await (0, (_waits_for || _load_waits_for()).default)(() => testSpy1.mock.calls.length > 0); - expect(testSpy1).toHaveBeenCalledWith({a: '1'}); - expect(testSpy11).toHaveBeenCalledWith({a: '1'}); - expect(testSpy2).toHaveBeenCalledWith({b: '2'}); + expect(testSpy1).toHaveBeenCalledWith({ a: '1' }); + expect(testSpy11).toHaveBeenCalledWith({ a: '1' }); + expect(testSpy2).toHaveBeenCalledWith({ b: '2' }); // Make sure observers get cleaned up. disposables.dispose(); @@ -48,23 +66,20 @@ describe('DeepLinkService', () => { }); it('opens target=_blank links in a new window', async () => { - const service = new DeepLinkService(); + const service = new (_DeepLinkService || _load_DeepLinkService()).default(); const windows = remote.BrowserWindow.getAllWindows(); const browserWindow = remote.getCurrentWindow(); // Opening a modal marks the window as non-blank. const panel = atom.workspace.addModalPanel({ - item: document.createElement('div'), + item: document.createElement('div') }); - service.sendDeepLink(browserWindow, 'test1', {a: '1', target: '_blank'}); + service.sendDeepLink(browserWindow, 'test1', { a: '1', target: '_blank' }); - await waitsFor( - () => remote.BrowserWindow.getAllWindows().length > windows.length, - 'new window to open', - ); + await (0, (_waits_for || _load_waits_for()).default)(() => remote.BrowserWindow.getAllWindows().length > windows.length, 'new window to open'); // Ideally we'd also check that the URL made it through.. but that's too difficult. service.dispose(); panel.destroy(); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-deep-link/lib/DeepLinkService.js b/pkg/nuclide-deep-link/lib/DeepLinkService.js index 19d6aeea55..52f4cfb968 100644 --- a/pkg/nuclide-deep-link/lib/DeepLinkService.js +++ b/pkg/nuclide-deep-link/lib/DeepLinkService.js @@ -1,142 +1,153 @@ -/** - * 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 - */ - -import type {DeepLinkParams} from './types'; - -import electron from 'electron'; -import invariant from 'assert'; -import url from 'url'; -import {Observable} from 'rxjs'; -import {maxBy} from 'lodash'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {observeDeepLinks, sendDeepLink} from '../../commons-atom/deep-link'; -import SharedObservableCache from '../../commons-node/SharedObservableCache'; - -const {ipcRenderer, remote} = electron; -invariant(ipcRenderer != null && remote != null); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _maxBy2; + +function _load_maxBy() { + return _maxBy2 = _interopRequireDefault(require('lodash/maxBy')); +} + +exports._openInNewWindow = _openInNewWindow; + +var _electron = _interopRequireDefault(require('electron')); + +var _url = _interopRequireDefault(require('url')); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _deepLink; + +function _load_deepLink() { + return _deepLink = require('../../commons-atom/deep-link'); +} + +var _SharedObservableCache; + +function _load_SharedObservableCache() { + return _SharedObservableCache = _interopRequireDefault(require('../../commons-node/SharedObservableCache')); +} + +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) 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. + * + * + * @format + */ + +const { ipcRenderer, remote } = _electron.default; + +if (!(ipcRenderer != null && remote != null)) { + throw new Error('Invariant violation: "ipcRenderer != null && remote != null"'); +} // This function relies on each step being synchronous. // May break in future Atom versions. -export function _openInNewWindow(uri: string): void { + + +function _openInNewWindow(uri) { const windows = remote.BrowserWindow.getAllWindows(); // First, open a new window. // There's no explicit API but we'll send the standard command. - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'application:new-window', - ); + atom.commands.dispatch(atom.views.getView(atom.workspace), 'application:new-window'); const newWindows = remote.BrowserWindow.getAllWindows(); - invariant( - newWindows.length > windows.length, - 'Expected new window to appear', - ); + + if (!(newWindows.length > windows.length)) { + throw new Error('Expected new window to appear'); + } // We'll assume the highest ID is new. (Electron IDs are auto-incrementing.) // (This is also non-null because the invariant above guarantees > 0). - const newWindow: electron$BrowserWindow = maxBy(newWindows, w => w.id); + + + const newWindow = (0, (_maxBy2 || _load_maxBy()).default)(newWindows, w => w.id); // Atom's definition of 'window:loaded' waits for all packages to load. // Thus, it's safe to send the URI after this point. // https://github.com/atom/atom/blob/910fbeee31d67eb711ec0771e7c26fa408c091eb/static/index.js#L106 - newWindow.once(('window:loaded': any), () => { + newWindow.once('window:loaded', () => { // Needs to match sendURIMessage: // https://github.com/atom/atom/blob/d2d3ad9fb8a4aadb2fe0e53edf7d95bd109fc0f7/src/main-process/atom-window.js#L286 newWindow.send('uri-message', uri); }); } -function isWindowBlank(lastDeepLinkUptime: ?number): boolean { +function isWindowBlank(lastDeepLinkUptime) { // A window is considered empty if: // 1) it has no open projects // 2) it has no visible modal panels // 3) no deep link was opened recently const BLANK_DEEP_LINK_EXPIRY = 3; - return ( - atom.project.getPaths().length === 0 && - !atom.workspace.getModalPanels().some(x => x.isVisible()) && - (lastDeepLinkUptime == null || - process.uptime() - lastDeepLinkUptime < BLANK_DEEP_LINK_EXPIRY) - ); + return atom.project.getPaths().length === 0 && !atom.workspace.getModalPanels().some(x => x.isVisible()) && (lastDeepLinkUptime == null || process.uptime() - lastDeepLinkUptime < BLANK_DEEP_LINK_EXPIRY); } -export default class DeepLinkService { - _disposable: UniversalDisposable; - _observers: Map>; - _observables: SharedObservableCache; - _pendingEvents: Map>; +class DeepLinkService { constructor() { this._observers = new Map(); this._pendingEvents = new Map(); - this._observables = new SharedObservableCache(path => { - return Observable.create(observer => { + this._observables = new (_SharedObservableCache || _load_SharedObservableCache()).default(path => { + return _rxjsBundlesRxMinJs.Observable.create(observer => { this._observers.set(path, observer); return () => this._observers.delete(path); }).share(); }); let lastDeepLinkUptime = null; - this._disposable = new UniversalDisposable( - observeDeepLinks().subscribe(({message, params}) => { - // This is a special feature that mimics the browser's target=_blank. - // Opens up a new Atom window and sends it back to the Atom URI handler. - // If the current window is already 'blank' then we'll use the current one, though. - if (params.target === '_blank' && !isWindowBlank(lastDeepLinkUptime)) { - // Can't recurse indefinitely! - const {target, ...paramsWithoutTarget} = params; - _openInNewWindow( - url.format({ - protocol: 'atom:', - slashes: true, - host: 'nuclide', - pathname: message, - query: paramsWithoutTarget, - }), - ); - return; - } - const path = message.replace(/\/+$/, ''); - const observer = this._observers.get(path); - if (observer != null) { - observer.next(params); - } - lastDeepLinkUptime = process.uptime(); - }), - () => this._observers.forEach(observer => observer.complete()), - ); + this._disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default((0, (_deepLink || _load_deepLink()).observeDeepLinks)().subscribe(({ message, params }) => { + // This is a special feature that mimics the browser's target=_blank. + // Opens up a new Atom window and sends it back to the Atom URI handler. + // If the current window is already 'blank' then we'll use the current one, though. + if (params.target === '_blank' && !isWindowBlank(lastDeepLinkUptime)) { + // Can't recurse indefinitely! + const { target } = params, + paramsWithoutTarget = _objectWithoutProperties(params, ['target']); + _openInNewWindow(_url.default.format({ + protocol: 'atom:', + slashes: true, + host: 'nuclide', + pathname: message, + query: paramsWithoutTarget + })); + return; + } + const path = message.replace(/\/+$/, ''); + const observer = this._observers.get(path); + if (observer != null) { + observer.next(params); + } + lastDeepLinkUptime = process.uptime(); + }), () => this._observers.forEach(observer => observer.complete())); } - dispose(): void { + dispose() { this._disposable.dispose(); } - subscribeToPath( - path: string, - callback: (params: DeepLinkParams) => mixed, - ): IDisposable { - const result = new UniversalDisposable( - this._observables.get(path).subscribe(callback), - ); + subscribeToPath(path, callback) { + const result = new (_UniversalDisposable || _load_UniversalDisposable()).default(this._observables.get(path).subscribe(callback)); return result; } - sendDeepLink( - browserWindow: electron$BrowserWindow, - path: string, - params: DeepLinkParams, - ): void { - sendDeepLink(browserWindow, path, params); + sendDeepLink(browserWindow, path, params) { + (0, (_deepLink || _load_deepLink()).sendDeepLink)(browserWindow, path, params); browserWindow.focus(); } } +exports.default = DeepLinkService; \ No newline at end of file diff --git a/pkg/nuclide-deep-link/lib/main.js b/pkg/nuclide-deep-link/lib/main.js index 8ffa8af3d6..5512254aca 100644 --- a/pkg/nuclide-deep-link/lib/main.js +++ b/pkg/nuclide-deep-link/lib/main.js @@ -1,37 +1,45 @@ -/** - * 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 - */ - -import type {DeepLinkService} from './types'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import {default as DeepLinkServiceImpl} from './DeepLinkService'; +'use strict'; + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _DeepLinkService; + +function _load_DeepLinkService() { + return _DeepLinkService = _interopRequireDefault(require('./DeepLinkService')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class Activation { - _service: DeepLinkServiceImpl; - constructor(state: ?Object): void { - this._service = new DeepLinkServiceImpl(); + constructor(state) { + this._service = new (_DeepLinkService || _load_DeepLinkService()).default(); } dispose() { this._service.dispose(); } - provideDeepLinkService(): DeepLinkService { + provideDeepLinkService() { // Only expose the public methods of the service. return { subscribeToPath: this._service.subscribeToPath.bind(this._service), - sendDeepLink: this._service.sendDeepLink.bind(this._service), + sendDeepLink: this._service.sendDeepLink.bind(this._service) }; } -} +} /** + * 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. + * + * + * @format + */ -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-deep-link/lib/types.js b/pkg/nuclide-deep-link/lib/types.js index 15caf1e7f0..a726efc43f 100644 --- a/pkg/nuclide-deep-link/lib/types.js +++ b/pkg/nuclide-deep-link/lib/types.js @@ -1,35 +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 strict-local - * @format - */ - -import type {DeepLinkParams} from '../../commons-atom/deep-link'; - -export type {DeepLinkParams}; - -export type DeepLinkService = { - /** - * Subscribes to all links of the form atom://nuclide/path?a=x,b=y,... - * Trailing slashes will be stripped off the path. - * Query parameters will be parsed and provided to the callback. - */ - subscribeToPath( - path: string, - callback: (params: DeepLinkParams) => mixed, - ): IDisposable, - - /** - * Manually send a deep link to another Atom window. - */ - sendDeepLink( - browserWindow: electron$BrowserWindow, - path: string, - params: DeepLinkParams, - ): void, -}; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-definition-preview-provider/lib/main.js b/pkg/nuclide-definition-preview-provider/lib/main.js index b231af9223..85ff4dbcbd 100644 --- a/pkg/nuclide-definition-preview-provider/lib/main.js +++ b/pkg/nuclide-definition-preview-provider/lib/main.js @@ -1,3 +1,16 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.provideDefinitionPreview = provideDefinitionPreview; + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,28 +18,16 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {Definition, DefinitionPreviewProvider} from 'atom-ide-ui'; - -import {getDefinitionPreviewServiceByNuclideUri} from '../../nuclide-remote-connection'; - -export function provideDefinitionPreview(): DefinitionPreviewProvider { +function provideDefinitionPreview() { return { - async getDefinitionPreview( - definition: Definition, - ): Promise { - const service = await getDefinitionPreviewServiceByNuclideUri( - definition.path, - ); + async getDefinitionPreview(definition) { + const service = await (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getDefinitionPreviewServiceByNuclideUri)(definition.path); return service.getDefinitionPreview(definition); - }, + } }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-definition-preview-rpc/lib/DefinitionPreviewService.js b/pkg/nuclide-definition-preview-rpc/lib/DefinitionPreviewService.js index 82f6836de7..47f213132e 100644 --- a/pkg/nuclide-definition-preview-rpc/lib/DefinitionPreviewService.js +++ b/pkg/nuclide-definition-preview-rpc/lib/DefinitionPreviewService.js @@ -1,3 +1,16 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getDefinitionPreview = getDefinitionPreview; + +var _symbolDefinitionPreview; + +function _load_symbolDefinitionPreview() { + return _symbolDefinitionPreview = require('../../../modules/nuclide-commons/symbol-definition-preview'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,20 +18,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {Definition} from 'atom-ide-ui'; - -import {getDefinitionPreview as getDefinitionPreviewImpl} from 'nuclide-commons/symbol-definition-preview'; - -export function getDefinitionPreview( - definition: Definition, -): Promise { - return getDefinitionPreviewImpl(definition); -} +function getDefinitionPreview(definition) { + return (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)(definition); +} \ No newline at end of file diff --git a/pkg/nuclide-definition-preview-rpc/lib/DefinitionPreviewServiceProxy.js b/pkg/nuclide-definition-preview-rpc/lib/DefinitionPreviewServiceProxy.js new file mode 100644 index 0000000000..07d884492f --- /dev/null +++ b/pkg/nuclide-definition-preview-rpc/lib/DefinitionPreviewServiceProxy.js @@ -0,0 +1,209 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + + remoteModule.getDefinitionPreview = function (arg0) { + return _client.callRemoteFunction("DefinitionPreviewService/getDefinitionPreview", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "definition", + type: { + kind: "named", + name: "Definition" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "object", + fields: [{ + name: "mime", + type: { + kind: "string" + }, + optional: false + }, { + name: "contents", + type: { + kind: "string" + }, + optional: false + }, { + name: "encoding", + type: { + kind: "string" + }, + optional: false + }] + } + }); + }); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + Definition: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 15 + }, + name: "Definition", + definition: { + kind: "object", + fields: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "position", + type: { + kind: "named", + name: "atom$Point" + }, + optional: false + }, { + name: "range", + type: { + kind: "named", + name: "atom$Range" + }, + optional: true + }, { + name: "name", + type: { + kind: "string" + }, + optional: true + }, { + name: "projectRoot", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: true + }, { + name: "language", + type: { + kind: "string" + }, + optional: false + }] + } + }, + getDefinitionPreview: { + kind: "function", + name: "getDefinitionPreview", + location: { + type: "source", + fileName: "DefinitionPreviewService.js", + line: 16 + }, + type: { + location: { + type: "source", + fileName: "DefinitionPreviewService.js", + line: 16 + }, + kind: "function", + argumentTypes: [{ + name: "definition", + type: { + kind: "named", + name: "Definition" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "object", + fields: [{ + name: "mime", + type: { + kind: "string" + }, + optional: false + }, { + name: "contents", + type: { + kind: "string" + }, + optional: false + }, { + name: "encoding", + type: { + kind: "string" + }, + optional: false + }] + } + } + } + } + } + } +}); \ No newline at end of file diff --git a/pkg/nuclide-definition-preview/lib/DefinitionPreviewView.js b/pkg/nuclide-definition-preview/lib/DefinitionPreviewView.js index 5ccb75b8fd..df58ad6f5c 100644 --- a/pkg/nuclide-definition-preview/lib/DefinitionPreviewView.js +++ b/pkg/nuclide-definition-preview/lib/DefinitionPreviewView.js @@ -1,3 +1,66 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DefinitionPreviewView = undefined; + +var _Button; + +function _load_Button() { + return _Button = require('../../../modules/nuclide-commons-ui/Button'); +} + +var _Block; + +function _load_Block() { + return _Block = require('../../../modules/nuclide-commons-ui/Block'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _goToLocation; + +function _load_goToLocation() { + return _goToLocation = require('../../../modules/nuclide-commons-atom/go-to-location'); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _AtomTextEditor; + +function _load_AtomTextEditor() { + return _AtomTextEditor = require('../../../modules/nuclide-commons-ui/AtomTextEditor'); +} + +var _analytics; + +function _load_analytics() { + return _analytics = _interopRequireDefault(require('../../../modules/nuclide-commons/analytics')); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _atom = require('atom'); + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,50 +68,41 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {ContextElementProps} from '../../nuclide-context-view/lib/types'; -import type {Definition} from 'atom-ide-ui'; - -import {Button, ButtonSizes} from 'nuclide-commons-ui/Button'; -import {Block} from 'nuclide-commons-ui/Block'; -import * as React from 'react'; -import {goToLocation} from 'nuclide-commons-atom/go-to-location'; -import nullthrows from 'nullthrows'; -import {bufferForUri} from '../../nuclide-remote-connection'; -import {AtomTextEditor} from 'nuclide-commons-ui/AtomTextEditor'; -import analytics from 'nuclide-commons/analytics'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import invariant from 'assert'; -import {TextBuffer} from 'atom'; - const MINIMUM_EDITOR_HEIGHT = 10; const EDITOR_HEIGHT_DELTA = 10; -type State = { - buffer: atom$TextBuffer, - editorHeight: number, // Height in ems to render the AtomTextEditor. -}; - -export class DefinitionPreviewView extends React.Component< - ContextElementProps, - State, -> { - _editor: ?AtomTextEditor; - _settingsChangeDisposable: IDisposable; +class DefinitionPreviewView extends _react.Component { - constructor(props: ContextElementProps) { + constructor(props) { super(props); - const buffer = - props.definition != null - ? bufferForUri(props.definition.path) - : new TextBuffer(); - const heightSetting = (featureConfig.get( - 'nuclide-definition-preview.editorHeight', - ): any); - let height: number = 50; + + this._openCurrentDefinitionInMainEditor = () => { + (_analytics || _load_analytics()).default.track('nuclide-definition-preview:openInMainEditor'); + const def = this.props.definition; + if (def != null) { + (0, (_goToLocation || _load_goToLocation()).goToLocation)(def.path, { + line: def.position.row, + column: def.position.column, + center: true + }); + } + }; + + this._increaseEditorHeight = () => { + this._setEditorHeight(this.state.editorHeight + EDITOR_HEIGHT_DELTA); + }; + + this._decreaseEditorHeight = () => { + this._setEditorHeight(this.state.editorHeight - EDITOR_HEIGHT_DELTA); + }; + + const buffer = props.definition != null ? (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).bufferForUri)(props.definition.path) : new _atom.TextBuffer(); + const heightSetting = (_featureConfig || _load_featureConfig()).default.get('nuclide-definition-preview.editorHeight'); + let height = 50; if (heightSetting != null) { height = heightSetting; } @@ -57,169 +111,159 @@ export class DefinitionPreviewView extends React.Component< } this.state = { buffer, - editorHeight: height, + editorHeight: height }; - this._settingsChangeDisposable = featureConfig.observe( - 'nuclide-definition-preview.editorHeight', - (newHeight: any) => this._setEditorHeight((newHeight: number)), - ); + this._settingsChangeDisposable = (_featureConfig || _load_featureConfig()).default.observe('nuclide-definition-preview.editorHeight', newHeight => this._setEditorHeight(newHeight)); } - componentWillReceiveProps(newProps: ContextElementProps): void { + componentWillReceiveProps(newProps) { if (newProps.definition != null) { const definition = newProps.definition; // The buffer always needs to point to the right file path, so create a new one with // the correct path if the new definition prop has a different path than the // currently loaded buffer. if (definition.path !== this.state.buffer.getPath()) { - this.setState({buffer: bufferForUri(definition.path)}); + this.setState({ buffer: (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).bufferForUri)(definition.path) }); } } else { // A null definition has no associated file path, so make a new TextBuffer() // that doesn't have an associated file path. - this.setState({buffer: new TextBuffer()}); + this.setState({ buffer: new _atom.TextBuffer() }); } } // Loads the current buffer in state if it's not already loaded. - async _loadBuffer(): Promise { + async _loadBuffer() { if (!this.state.buffer.loaded) { await this.state.buffer.load(); } } - componentDidUpdate(prevProps: ContextElementProps, prevState: State): void { + componentDidUpdate(prevProps, prevState) { if (this.props.definition != null) { this._finishRendering(this.props.definition); } } - componentWillUnmount(): void { + componentWillUnmount() { this._settingsChangeDisposable.dispose(); } - async _finishRendering(definition: Definition): Promise { + async _finishRendering(definition) { await this._loadBuffer(); this._scrollToRow(definition.position.row); const editor = this.getEditor(); editor.getDecorations().forEach(decoration => decoration.destroy()); - invariant(this.props.definition != null); + + if (!(this.props.definition != null)) { + throw new Error('Invariant violation: "this.props.definition != null"'); + } + const marker = editor.markBufferPosition(definition.position); editor.decorateMarker(marker, { type: 'line', - class: 'debugger-current-line-highlight', + class: 'debugger-current-line-highlight' }); } - render(): React.Node { - const {ContextViewMessage, definition} = this.props; - const atMinHeight = - this.state.editorHeight - EDITOR_HEIGHT_DELTA < MINIMUM_EDITOR_HEIGHT; + render() { + const { ContextViewMessage, definition } = this.props; + const atMinHeight = this.state.editorHeight - EDITOR_HEIGHT_DELTA < MINIMUM_EDITOR_HEIGHT; // Show either a "No definition" message or the definition in an editors - return definition == null ? ( - - ) : ( -
    -
    - { - this._editor = editor; - }} - gutterHidden={true} - lineNumberGutterVisible={false} - path={definition.path} - // Should be readonly, but can't because we can only make buffers readonly, - // We can't do readonly on editor granularity. - readOnly={false} - textBuffer={this.state.buffer} - syncTextContents={false} - /> - -
    -
    + return definition == null ? _react.createElement(ContextViewMessage, { message: ContextViewMessage.NO_DEFINITION }) : _react.createElement( + 'div', + { className: 'pane-item nuclide-definition-preview' }, + _react.createElement( + 'div', + { + className: 'nuclide-definition-preview-editor', + style: { height: `${this.state.editorHeight}em` } }, + _react.createElement((_AtomTextEditor || _load_AtomTextEditor()).AtomTextEditor, { + ref: editor => { + this._editor = editor; + }, + gutterHidden: true, + lineNumberGutterVisible: false, + path: definition.path + // Should be readonly, but can't because we can only make buffers readonly, + // We can't do readonly on editor granularity. + , readOnly: false, + textBuffer: this.state.buffer, + syncTextContents: false + }), + _react.createElement(ButtonContainer, { + _openCurrentDefinitionInMainEditor: this._openCurrentDefinitionInMainEditor, + _increaseEditorHeight: this._increaseEditorHeight, + _decreaseEditorHeight: this._decreaseEditorHeight, + atMinHeight: atMinHeight + }) + ) ); } - _openCurrentDefinitionInMainEditor = (): void => { - analytics.track('nuclide-definition-preview:openInMainEditor'); - const def = this.props.definition; - if (def != null) { - goToLocation(def.path, { - line: def.position.row, - column: def.position.column, - center: true, - }); - } - }; - // Sets the height of the definition preview editor only if it satisfies the minimum height - _setEditorHeight(height: number): void { + _setEditorHeight(height) { if (height !== this.state.editorHeight && height >= MINIMUM_EDITOR_HEIGHT) { - featureConfig.set('nuclide-definition-preview.editorHeight', height); - this.setState({editorHeight: height}); + (_featureConfig || _load_featureConfig()).default.set('nuclide-definition-preview.editorHeight', height); + this.setState({ editorHeight: height }); } } - _increaseEditorHeight = (): void => { - this._setEditorHeight(this.state.editorHeight + EDITOR_HEIGHT_DELTA); - }; - - _decreaseEditorHeight = (): void => { - this._setEditorHeight(this.state.editorHeight - EDITOR_HEIGHT_DELTA); - }; - - getEditor(): atom$TextEditor { - return nullthrows(this._editor).getModel(); + getEditor() { + return (0, (_nullthrows || _load_nullthrows()).default)(this._editor).getModel(); } - _scrollToRow(row: number): void { - this.getEditor().scrollToBufferPosition([row, 0], {center: true}); + _scrollToRow(row) { + this.getEditor().scrollToBufferPosition([row, 0], { center: true }); } } -type ButtonContainerProps = { - _openCurrentDefinitionInMainEditor: () => void, - _increaseEditorHeight: () => void, - _decreaseEditorHeight: () => void, - atMinHeight: boolean, -}; - -const ButtonContainer = (props: ButtonContainerProps) => { - return ( - -
    -
    - Height: - - -
    -
    - -
    -
    -
    +exports.DefinitionPreviewView = DefinitionPreviewView; + + +const ButtonContainer = props => { + return _react.createElement( + (_Block || _load_Block()).Block, + null, + _react.createElement( + 'div', + { className: 'nuclide-definition-preview-buttons' }, + _react.createElement( + 'div', + { className: 'nuclide-definition-preview-buttons-left' }, + _react.createElement( + 'span', + { style: { paddingRight: '1em' } }, + 'Height:' + ), + _react.createElement( + (_Button || _load_Button()).Button, + { + onClick: props._decreaseEditorHeight, + size: (_Button || _load_Button()).ButtonSizes.SMALL, + disabled: props.atMinHeight }, + '-' + ), + _react.createElement( + (_Button || _load_Button()).Button, + { + onClick: props._increaseEditorHeight, + size: (_Button || _load_Button()).ButtonSizes.SMALL }, + '+' + ) + ), + _react.createElement( + 'div', + { className: 'nuclide-definition-preview-buttons-right' }, + _react.createElement( + (_Button || _load_Button()).Button, + { + onClick: props._openCurrentDefinitionInMainEditor, + size: (_Button || _load_Button()).ButtonSizes.SMALL }, + 'Open in main editor' + ) + ) + ) ); -}; +}; \ No newline at end of file diff --git a/pkg/nuclide-definition-preview/lib/main.js b/pkg/nuclide-definition-preview/lib/main.js index 6f371060a2..25012a99f4 100644 --- a/pkg/nuclide-definition-preview/lib/main.js +++ b/pkg/nuclide-definition-preview/lib/main.js @@ -1,45 +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 - * @format - */ - -import type { - ContextProvider, - NuclideContextView, -} from '../../nuclide-context-view/lib/types'; - -import {DefinitionPreviewView} from './DefinitionPreviewView'; -import * as React from 'react'; -import invariant from 'assert'; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.activate = activate; +exports.deactivate = deactivate; +exports.consumeNuclideContextView = consumeNuclideContextView; + +var _DefinitionPreviewView; + +function _load_DefinitionPreviewView() { + return _DefinitionPreviewView = require('./DefinitionPreviewView'); +} + +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; } } // Unique ID of this context provider -const PROVIDER_ID: string = 'nuclide-definition-preview'; -const PROVIDER_TITLE: string = 'Definition Preview'; +const PROVIDER_ID = 'nuclide-definition-preview'; /** + * 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. + * + * + * @format + */ + +const PROVIDER_TITLE = 'Definition Preview'; class Activation { - provider: ContextProvider; - contextViewRegistration: ?IDisposable; constructor() { // $FlowFixMe(>=0.53.0) Flow suppress this.provider = { - getElementFactory: () => React.createFactory(DefinitionPreviewView), + getElementFactory: () => _react.createFactory((_DefinitionPreviewView || _load_DefinitionPreviewView()).DefinitionPreviewView), id: PROVIDER_ID, - title: PROVIDER_TITLE, + title: PROVIDER_TITLE }; } - getContextProvider(): ContextProvider { + getContextProvider() { return this.provider; } - setContextViewRegistration(registration: IDisposable): void { + setContextViewRegistration(registration) { this.contextViewRegistration = registration; } @@ -50,27 +57,26 @@ class Activation { } } -let activation: ?Activation = null; +let activation = null; -export function activate(state: Object | void) { +function activate(state) { if (activation == null) { activation = new Activation(); } } -export function deactivate() { +function deactivate() { if (activation != null) { activation.dispose(); activation = null; } } -export async function consumeNuclideContextView( - contextView: NuclideContextView, -): Promise { - invariant(activation != null); - const registration = await contextView.registerProvider( - activation.getContextProvider(), - ); +async function consumeNuclideContextView(contextView) { + if (!(activation != null)) { + throw new Error('Invariant violation: "activation != null"'); + } + + const registration = await contextView.registerProvider(activation.getContextProvider()); activation.setContextViewRegistration(registration); -} +} \ No newline at end of file diff --git a/pkg/nuclide-deprecation-cop/lib/main.js b/pkg/nuclide-deprecation-cop/lib/main.js index 59036c1d49..f6789357a8 100644 --- a/pkg/nuclide-deprecation-cop/lib/main.js +++ b/pkg/nuclide-deprecation-cop/lib/main.js @@ -1,19 +1,36 @@ -/** - * 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 - */ +'use strict'; + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} -import {getLogger} from 'log4js'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {track} from '../../nuclide-analytics'; -import updateKeymap from './updateKeymap'; +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _updateKeymap; + +function _load_updateKeymap() { + return _updateKeymap = _interopRequireDefault(require('./updateKeymap')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Put deprecated commands with their new equivalents here. @@ -24,8 +41,17 @@ import updateKeymap from './updateKeymap'; const DEPRECATED_CONSOLE_COMMANDS = { 'nuclide-console:toggle': 'console:toggle', 'nuclide-console:clear': 'console:clear', - 'nuclide-console:copy-message': 'console:copy-message', -}; + 'nuclide-console:copy-message': 'console:copy-message' +}; /** + * 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. + * + * + * @format + */ const DEPRECATED_DEBUGGER_COMMANDS = { 'nuclide-debugger:toggle': 'debugger:toggle', @@ -38,17 +64,15 @@ const DEPRECATED_DEBUGGER_COMMANDS = { 'nuclide-debugger:step-into': 'debugger:step-into', 'nuclide-debugger:step-out': 'debugger:step-out', 'nuclide-debugger:run-to-location': 'debugger:run-to-location', - 'nuclide-debugger:toggle-breakpoint': 'debugger:toggle-breakpoint', + 'nuclide-debugger:toggle-breakpoint': 'debugger:toggle-breakpoint' }; const DEPRECATED_FILE_TREE_COMMANDS = { - 'nuclide-file-tree:set-current-working-root': - 'tree-view:set-current-working-root', + 'nuclide-file-tree:set-current-working-root': 'tree-view:set-current-working-root', 'nuclide-file-tree:add-file': 'tree-view:add-file', 'nuclide-file-tree:add-file-relative': 'tree-view:add-file-relative', 'nuclide-file-tree:add-folder': 'tree-view:add-folder', - 'nuclide-file-tree:remove-project-folder-selection': - 'tree-view:remove-project-folder-selection', + 'nuclide-file-tree:remove-project-folder-selection': 'tree-view:remove-project-folder-selection', 'nuclide-file-tree:toggle': 'tree-view:toggle', 'nuclide-file-tree:toggle-focus': 'tree-view:toggle-focus', 'nuclide-file-tree:reveal-active-file': 'tree-view:reveal-active-file', @@ -58,21 +82,14 @@ const DEPRECATED_FILE_TREE_COMMANDS = { 'nuclide-file-tree:duplicate-selection': 'tree-view:duplicate-selection', 'nuclide-file-tree:expand-directory': 'tree-view:expand-directory', 'nuclide-file-tree:collapse-directory': 'tree-view:collapse-directory', - 'nuclide-file-tree:recursive-expand-directory': - 'tree-view:recursive-expand-directory', - 'nuclide-file-tree:recursive-collapse-directory': - 'tree-view:recursive-collapse-directory', - 'nuclide-file-tree:recursive-collapse-all': - 'tree-view:recursive-collapse-all', + 'nuclide-file-tree:recursive-expand-directory': 'tree-view:recursive-expand-directory', + 'nuclide-file-tree:recursive-collapse-directory': 'tree-view:recursive-collapse-directory', + 'nuclide-file-tree:recursive-collapse-all': 'tree-view:recursive-collapse-all', 'nuclide-file-tree:open-selected-entry': 'tree-view:open-selected-entry', - 'nuclide-file-tree:open-selected-entry-right': - 'tree-view:open-selected-entry-right', - 'nuclide-file-tree:open-selected-entry-left': - 'tree-view:open-selected-entry-left', - 'nuclide-file-tree:open-selected-entry-up': - 'tree-view:open-selected-entry-up', - 'nuclide-file-tree:open-selected-entry-down': - 'tree-view:open-selected-entry-down', + 'nuclide-file-tree:open-selected-entry-right': 'tree-view:open-selected-entry-right', + 'nuclide-file-tree:open-selected-entry-left': 'tree-view:open-selected-entry-left', + 'nuclide-file-tree:open-selected-entry-up': 'tree-view:open-selected-entry-up', + 'nuclide-file-tree:open-selected-entry-down': 'tree-view:open-selected-entry-down', 'nuclide-file-tree:search-in-directory': 'tree-view:search-in-directory', 'nuclide-file-tree:remove': 'tree-view:remove', 'nuclide-file-tree:remove-letter': 'tree-view:remove-letter', @@ -149,86 +166,62 @@ const DEPRECATED_FILE_TREE_COMMANDS = { 'nuclide-file-tree:go-to-letter-x': 'tree-view:go-to-letter-x', 'nuclide-file-tree:go-to-letter-y': 'tree-view:go-to-letter-y', 'nuclide-file-tree:go-to-letter-z': 'tree-view:go-to-letter-z', - 'nuclide-file-tree:go-to-letter-~': 'tree-view:go-to-letter-~', + 'nuclide-file-tree:go-to-letter-~': 'tree-view:go-to-letter-~' }; const DEPRECATED_TERMINAL_COMMANDS = { 'nuclide-terminal:new-terminal': 'atom-ide-terminal:new-terminal', - 'nuclide-terminal:toggle-terminal-focus': - 'atom-ide-terminal:toggle-terminal-focus', + 'nuclide-terminal:toggle-terminal-focus': 'atom-ide-terminal:toggle-terminal-focus', 'nuclide-terminal:add-escape-prefix': 'atom-ide-terminal:add-escape-prefix', 'nuclide-terminal:create-paste': 'atom-ide-terminal:create-paste', - 'nuclide-terminal:clear': 'atom-ide-terminal:clear', + 'nuclide-terminal:clear': 'atom-ide-terminal:clear' }; const DEPRECATED_SOURCE_CONTROL_COMMANDS = { - 'fb-interactive-smartlog:copy-differential-id': - 'fb-interactive-smartlog:copy-diff-number', - 'fb-interactive-smartlog:copy-revision-hash': - 'fb-interactive-smartlog:copy-commit-hash', - 'fb-interactive-smartlog:strip-revision': - 'fb-interactive-smartlog:strip-commit', - 'fb-interactive-smartlog:abandon-revision': - 'fb-interactive-smartlog:abandon-diff', - 'fb-interactive-smartlog:accept-revision': - 'fb-interactive-smartlog:accept-diff', - 'fb-interactive-smartlog:publish-revision': - 'fb-interactive-smartlog:publish-diff', - 'fb-interactive-smartlog:reclaim-revision': - 'fb-interactive-smartlog:reclaim-diff', - 'fb-interactive-smartlog:reject-revision': - 'fb-interactive-smartlog:reject-diff', - 'fb-interactive-smartlog:request-revision': - 'fb-interactive-smartlog:request-diff', - 'fb-interactive-smartlog:rethink-revision': - 'fb-interactive-smartlog:rethink-diff', + 'fb-interactive-smartlog:copy-differential-id': 'fb-interactive-smartlog:copy-diff-number', + 'fb-interactive-smartlog:copy-revision-hash': 'fb-interactive-smartlog:copy-commit-hash', + 'fb-interactive-smartlog:strip-revision': 'fb-interactive-smartlog:strip-commit', + 'fb-interactive-smartlog:abandon-revision': 'fb-interactive-smartlog:abandon-diff', + 'fb-interactive-smartlog:accept-revision': 'fb-interactive-smartlog:accept-diff', + 'fb-interactive-smartlog:publish-revision': 'fb-interactive-smartlog:publish-diff', + 'fb-interactive-smartlog:reclaim-revision': 'fb-interactive-smartlog:reclaim-diff', + 'fb-interactive-smartlog:reject-revision': 'fb-interactive-smartlog:reject-diff', + 'fb-interactive-smartlog:request-revision': 'fb-interactive-smartlog:request-diff', + 'fb-interactive-smartlog:rethink-revision': 'fb-interactive-smartlog:rethink-diff' }; -const DEPRECATED_COMMANDS = { - ...DEPRECATED_CONSOLE_COMMANDS, - ...DEPRECATED_DEBUGGER_COMMANDS, - ...DEPRECATED_FILE_TREE_COMMANDS, - ...DEPRECATED_TERMINAL_COMMANDS, - ...DEPRECATED_SOURCE_CONTROL_COMMANDS, -}; +const DEPRECATED_COMMANDS = Object.assign({}, DEPRECATED_CONSOLE_COMMANDS, DEPRECATED_DEBUGGER_COMMANDS, DEPRECATED_FILE_TREE_COMMANDS, DEPRECATED_TERMINAL_COMMANDS, DEPRECATED_SOURCE_CONTROL_COMMANDS); class Activation { - _disposables: UniversalDisposable; - _warnedCommands: Set; constructor() { this._warnedCommands = new Set(); - this._disposables = new UniversalDisposable(this._deprecateCommands()); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(this._deprecateCommands()); // $FlowIgnore: private API const keymapPath = atom.keymaps.getUserKeymapPath(); - updateKeymap(keymapPath, DEPRECATED_COMMANDS).catch(err => { + (0, (_updateKeymap || _load_updateKeymap()).default)(keymapPath, DEPRECATED_COMMANDS).catch(err => { // Nonexistent keymaps are normal. if (err.code !== 'ENOENT') { - getLogger('nuclide-deprecation-cop').error( - 'Error updating user keymap:', - err, - ); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-deprecation-cop').error('Error updating user keymap:', err); } }); } - _deprecateCommands(): IDisposable { + _deprecateCommands() { // Catch any direct invocations of the commands (context menu, dispatch). - return atom.commands.onWillDispatch((event: any) => { + return atom.commands.onWillDispatch(event => { const command = event.type; if (!DEPRECATED_COMMANDS.hasOwnProperty(command)) { return; } const newCommand = DEPRECATED_COMMANDS[command]; if (!this._warnedCommands.has(command)) { - track('deprecated-command-dispatched', {command}); + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('deprecated-command-dispatched', { command }); atom.notifications.addWarning('Nuclide: Deprecated Command', { icon: 'nuclicon-nuclide', - description: - `The command \`${command}\` has been deprecated.\n` + - `Please use the new command \`${newCommand}\`.`, - dismissable: true, + description: `The command \`${command}\` has been deprecated.\n` + `Please use the new command \`${newCommand}\`.`, + dismissable: true }); this._warnedCommands.add(command); } @@ -236,9 +229,9 @@ class Activation { }); } - dispose(): void { + dispose() { this._disposables.dispose(); } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-deprecation-cop/lib/updateKeymap.js b/pkg/nuclide-deprecation-cop/lib/updateKeymap.js index 71222159fe..d09d3f4789 100644 --- a/pkg/nuclide-deprecation-cop/lib/updateKeymap.js +++ b/pkg/nuclide-deprecation-cop/lib/updateKeymap.js @@ -1,73 +1,71 @@ -/** - * 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 - */ +'use strict'; -import escapeRegExp from 'escape-string-regexp'; -import fsPromise from 'nuclide-commons/fsPromise'; -import {track} from '../../nuclide-analytics'; +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _escapeStringRegexp; + +function _load_escapeStringRegexp() { + return _escapeStringRegexp = _interopRequireDefault(require('escape-string-regexp')); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} -function quoteRegExp(str: string): string { +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function quoteRegExp(str) { const boundary = '([\'"])'; return `${boundary}(${str})${boundary}`; -} +} /** + * 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. + * + * + * @format + */ -export default (async function updateKeymap( - keymapPath: string, - deprecatedCommands: {[command: string]: string}, -): Promise { - const keymapFile = await fsPromise.readFile(keymapPath, 'utf8'); +exports.default = async function updateKeymap(keymapPath, deprecatedCommands) { + const keymapFile = await (_fsPromise || _load_fsPromise()).default.readFile(keymapPath, 'utf8'); // Search for all deprecated commands (whole words, escaped). - const mergedRegExp = Object.keys(deprecatedCommands) - .map(escapeRegExp) - .join('|'); + const mergedRegExp = Object.keys(deprecatedCommands).map((_escapeStringRegexp || _load_escapeStringRegexp()).default).join('|'); const matches = keymapFile.match(new RegExp(quoteRegExp(mergedRegExp), 'g')); if (matches != null) { // Format as a list. const matchesSet = new Set(matches.map(m => m.substr(1, m.length - 2))); const matchesArray = Array.from(matchesSet); - const matchesList = matchesArray - .map(command => `- \`${command}\``) - .join('\n'); + const matchesList = matchesArray.map(command => `- \`${command}\``).join('\n'); return new Promise(resolve => { - const notification = atom.notifications.addInfo( - 'Nuclide: Deprecated Commands', - { - icon: 'nuclicon-nuclide', - description: - 'Your keymap contains the following deprecated commands:' + - `\n\n${matchesList}\n\n` + - 'Would you like to update your keymap?', - dismissable: true, - buttons: [ - { - text: 'Update Keymap', - className: 'icon icon-keyboard', - onDidClick: async () => { - track('deprecated-command-replaced', {commands: matchesArray}); - const replaced = matchesArray.reduce( - (str, match) => - str.replace( - new RegExp(quoteRegExp(escapeRegExp(match)), 'g'), - `$1${deprecatedCommands[match]}$3`, - ), - keymapFile, - ); - await fsPromise.writeFile(keymapPath, replaced); - atom.notifications.addSuccess('Keymap successfully updated!'); - notification.dismiss(); - resolve(); - }, - }, - ], - }, - ); + const notification = atom.notifications.addInfo('Nuclide: Deprecated Commands', { + icon: 'nuclicon-nuclide', + description: 'Your keymap contains the following deprecated commands:' + `\n\n${matchesList}\n\n` + 'Would you like to update your keymap?', + dismissable: true, + buttons: [{ + text: 'Update Keymap', + className: 'icon icon-keyboard', + onDidClick: async () => { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('deprecated-command-replaced', { commands: matchesArray }); + const replaced = matchesArray.reduce((str, match) => str.replace(new RegExp(quoteRegExp((0, (_escapeStringRegexp || _load_escapeStringRegexp()).default)(match)), 'g'), `$1${deprecatedCommands[match]}$3`), keymapFile); + await (_fsPromise || _load_fsPromise()).default.writeFile(keymapPath, replaced); + atom.notifications.addSuccess('Keymap successfully updated!'); + notification.dismiss(); + resolve(); + } + }] + }); }); } -}); +}; \ No newline at end of file diff --git a/pkg/nuclide-deprecation-cop/spec/updateKeymap-spec.js b/pkg/nuclide-deprecation-cop/spec/updateKeymap-spec.js deleted file mode 100644 index e804f16b94..0000000000 --- a/pkg/nuclide-deprecation-cop/spec/updateKeymap-spec.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * 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 - */ - -import fs from 'fs'; -import temp from 'temp'; -temp.track(); - -import updateKeymap from '../lib/updateKeymap'; - -describe('updateKeymap', () => { - it('updates a user keymap', () => { - let notification; - let updatePromise; - const {path} = temp.openSync({suffix: 'test.cson'}); - - waitsForPromise(async () => { - fs.writeFileSync(path, '"alt-w": "command"\n"ctrl-w": "command-1"'); - - spyOn(atom.notifications, 'addInfo').andCallFake((title, data) => { - notification = data; - return {dismiss: () => {}}; - }); - - updatePromise = updateKeymap(path, { - command: 'new-command', - 'command-1': 'new-command-1', - }); - }); - - waitsFor(() => notification != null); - - waitsForPromise(async () => { - expect(notification.description).toContain('- `command`\n- `command-1`'); - notification.buttons[0].onDidClick(); - - await updatePromise; - const file = fs.readFileSync(path, 'utf8'); - expect(file).toBe('"alt-w": "new-command"\n"ctrl-w": "new-command-1"'); - }); - }); -}); diff --git a/pkg/nuclide-device-panel-android/lib/Registration.js b/pkg/nuclide-device-panel-android/lib/Registration.js index 5835f94dde..ea33ff166d 100644 --- a/pkg/nuclide-device-panel-android/lib/Registration.js +++ b/pkg/nuclide-device-panel-android/lib/Registration.js @@ -1,3 +1,54 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.registerDevicePanelProviders = registerDevicePanelProviders; + +var _AdbDevicePoller; + +function _load_AdbDevicePoller() { + return _AdbDevicePoller = require('../../../modules/nuclide-adb/lib/AdbDevicePoller'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _AndroidDeviceInfoProvider; + +function _load_AndroidDeviceInfoProvider() { + return _AndroidDeviceInfoProvider = require('./providers/AndroidDeviceInfoProvider'); +} + +var _AndroidDeviceProcessesProvider; + +function _load_AndroidDeviceProcessesProvider() { + return _AndroidDeviceProcessesProvider = require('./providers/AndroidDeviceProcessesProvider'); +} + +var _AndroidDeviceStopProcessProvider; + +function _load_AndroidDeviceStopProcessProvider() { + return _AndroidDeviceStopProcessProvider = require('./providers/AndroidDeviceStopProcessProvider'); +} + +var _AvdComponentProvider; + +function _load_AvdComponentProvider() { + return _AvdComponentProvider = require('./providers/AvdComponentProvider'); +} + +var _AdbTunnelingProvider; + +function _load_AdbTunnelingProvider() { + return _AdbTunnelingProvider = require('./providers/AdbTunnelingProvider'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,32 +56,13 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {DevicePanelServiceApi} from 'nuclide-debugger-common/types'; - -import {observeAndroidDevicesX} from 'nuclide-adb/lib/AdbDevicePoller'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {AndroidDeviceInfoProvider} from './providers/AndroidDeviceInfoProvider'; -import {AndroidDeviceProcessesProvider} from './providers/AndroidDeviceProcessesProvider'; -import {AndroidDeviceStopProcessProvider} from './providers/AndroidDeviceStopProcessProvider'; -import {AvdComponentProvider} from './providers/AvdComponentProvider'; -import {AdbTunnelingProvider} from './providers/AdbTunnelingProvider'; - -export function registerDevicePanelProviders( - api: DevicePanelServiceApi, -): IDisposable { - return new UniversalDisposable( - api.registerListProvider({ - getType: () => 'Android', - observe: host => observeAndroidDevicesX(host), - }), - api.registerInfoProvider(new AndroidDeviceInfoProvider()), - api.registerProcessesProvider(new AndroidDeviceProcessesProvider()), - api.registerProcessTaskProvider(new AndroidDeviceStopProcessProvider()), - api.registerDeviceTypeComponentProvider(new AvdComponentProvider()), - api.registerDeviceTypeComponentProvider(new AdbTunnelingProvider()), - ); -} +function registerDevicePanelProviders(api) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(api.registerListProvider({ + getType: () => 'Android', + observe: host => (0, (_AdbDevicePoller || _load_AdbDevicePoller()).observeAndroidDevicesX)(host) + }), api.registerInfoProvider(new (_AndroidDeviceInfoProvider || _load_AndroidDeviceInfoProvider()).AndroidDeviceInfoProvider()), api.registerProcessesProvider(new (_AndroidDeviceProcessesProvider || _load_AndroidDeviceProcessesProvider()).AndroidDeviceProcessesProvider()), api.registerProcessTaskProvider(new (_AndroidDeviceStopProcessProvider || _load_AndroidDeviceStopProcessProvider()).AndroidDeviceStopProcessProvider()), api.registerDeviceTypeComponentProvider(new (_AvdComponentProvider || _load_AvdComponentProvider()).AvdComponentProvider()), api.registerDeviceTypeComponentProvider(new (_AdbTunnelingProvider || _load_AdbTunnelingProvider()).AdbTunnelingProvider())); +} \ No newline at end of file diff --git a/pkg/nuclide-device-panel-android/lib/main.js b/pkg/nuclide-device-panel-android/lib/main.js index 63fc663610..9c085a0da6 100644 --- a/pkg/nuclide-device-panel-android/lib/main.js +++ b/pkg/nuclide-device-panel-android/lib/main.js @@ -1,3 +1,25 @@ +'use strict'; + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _Registration; + +function _load_Registration() { + return _Registration = require('./Registration'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,30 +27,23 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {DevicePanelServiceApi} from 'nuclide-debugger-common/types'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {registerDevicePanelProviders} from './Registration'; - class Activation { - _disposables: UniversalDisposable; constructor() { - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - dispose(): void { + dispose() { this._disposables.dispose(); } - consumeDevicePanelServiceApi(api: DevicePanelServiceApi): void { - this._disposables.add(registerDevicePanelProviders(api)); + consumeDevicePanelServiceApi(api) { + this._disposables.add((0, (_Registration || _load_Registration()).registerDevicePanelProviders)(api)); } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-device-panel-android/lib/providers/AdbTunnelingProvider.js b/pkg/nuclide-device-panel-android/lib/providers/AdbTunnelingProvider.js index 207969f062..cbad01eb14 100644 --- a/pkg/nuclide-device-panel-android/lib/providers/AdbTunnelingProvider.js +++ b/pkg/nuclide-device-panel-android/lib/providers/AdbTunnelingProvider.js @@ -1,3 +1,46 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AdbTunnelingProvider = undefined; + +var _bindObservableAsProps; + +function _load_bindObservableAsProps() { + return _bindObservableAsProps = require('../../../../modules/nuclide-commons-ui/bindObservableAsProps'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../../modules/nuclide-commons/nuclideUri')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _Tunneling; + +function _load_Tunneling() { + return _Tunneling = require('../../../nuclide-adb-sdb-base/lib/Tunneling'); +} + +var _AdbTunnelButton; + +function _load_AdbTunnelButton() { + return _AdbTunnelButton = require('../ui/AdbTunnelButton'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,78 +48,57 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - DeviceTypeComponentProvider, - DeviceTypeComponent, -} from 'nuclide-debugger-common/types'; - -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import { - isAdbTunneled, - startTunnelingAdb as plainStartTunnelingAdb, - stopTunnelingAdb, -} from '../../../nuclide-adb-sdb-base/lib/Tunneling'; -import {AdbTunnelButton} from '../ui/AdbTunnelButton'; -import * as React from 'react'; - -let startTunnelingAdb = plainStartTunnelingAdb; +let startTunnelingAdb = (_Tunneling || _load_Tunneling()).startTunnelingAdb; try { const { - fbStartTunnelingAdb, + fbStartTunnelingAdb // $eslint-disable-next-line $FlowFB } = require('../../../nuclide-adb-sdb-base/lib/fb-Tunneling'); startTunnelingAdb = fbStartTunnelingAdb; } catch (e) {} -export class AdbTunnelingProvider implements DeviceTypeComponentProvider { - getType = (): string => { - return 'Android'; - }; - - observe = ( - host: NuclideUri, - callback: (?DeviceTypeComponent) => void, - ): IDisposable => { - const disposable = new UniversalDisposable(); - if (!nuclideUri.isRemote(host)) { - callback(null); - return disposable; - } - callback({ - position: 'host_selector', - type: () => { - const BoundButton = bindObservableAsProps( - isAdbTunneled(host).map(value => ({ +class AdbTunnelingProvider { + constructor() { + this.getType = () => { + return 'Android'; + }; + + this.observe = (host, callback) => { + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + if (!(_nuclideUri || _load_nuclideUri()).default.isRemote(host)) { + callback(null); + return disposable; + } + callback({ + position: 'host_selector', + type: () => { + const BoundButton = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)((0, (_Tunneling || _load_Tunneling()).isAdbTunneled)(host).map(value => ({ host, status: value ? 'active' : 'inactive', enable: () => { let noMoreNotifications = false; - startTunnelingAdb(host) - .do(() => (noMoreNotifications = true)) - .subscribe({ - error: e => { - if (!noMoreNotifications) { - atom.notifications.addError(e); - } - stopTunnelingAdb(host); - }, - }); + startTunnelingAdb(host).do(() => noMoreNotifications = true).subscribe({ + error: e => { + if (!noMoreNotifications) { + atom.notifications.addError(e); + } + (0, (_Tunneling || _load_Tunneling()).stopTunnelingAdb)(host); + } + }); }, - disable: () => stopTunnelingAdb(host), - })), - AdbTunnelButton, - ); - return ; - }, - key: 'adb tunneling', - }); - return disposable; - }; + disable: () => (0, (_Tunneling || _load_Tunneling()).stopTunnelingAdb)(host) + })), (_AdbTunnelButton || _load_AdbTunnelButton()).AdbTunnelButton); + return _react.createElement(BoundButton, null); + }, + key: 'adb tunneling' + }); + return disposable; + }; + } + } +exports.AdbTunnelingProvider = AdbTunnelingProvider; \ No newline at end of file diff --git a/pkg/nuclide-device-panel-android/lib/providers/AndroidDeviceInfoProvider.js b/pkg/nuclide-device-panel-android/lib/providers/AndroidDeviceInfoProvider.js index 6f45e0d6c9..e8e1c4ed2a 100644 --- a/pkg/nuclide-device-panel-android/lib/providers/AndroidDeviceInfoProvider.js +++ b/pkg/nuclide-device-panel-android/lib/providers/AndroidDeviceInfoProvider.js @@ -1,3 +1,18 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AndroidDeviceInfoProvider = undefined; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _utils; + +function _load_utils() { + return _utils = require('../../../../modules/nuclide-adb/lib/utils'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,47 +20,36 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {DeviceInfoProvider, Device} from 'nuclide-debugger-common/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import {Observable} from 'rxjs'; -import {getAdbServiceByNuclideUri} from 'nuclide-adb/lib/utils'; - -export class AndroidDeviceInfoProvider implements DeviceInfoProvider { - getType(): string { +class AndroidDeviceInfoProvider { + getType() { return 'Android'; } - fetch(host: NuclideUri, device: Device): Observable> { - return getAdbServiceByNuclideUri(host) - .getDeviceInfo(device) - .refCount() - .map(props => { - const infoMap = new Map(); - for (const [key, value] of props) { - const beautifulKey = key.toLowerCase().replace('_', ' '); - infoMap.set( - beautifulKey.charAt(0).toUpperCase() + beautifulKey.slice(1), - value, - ); - } - return infoMap; - }); + fetch(host, device) { + return (0, (_utils || _load_utils()).getAdbServiceByNuclideUri)(host).getDeviceInfo(device).refCount().map(props => { + const infoMap = new Map(); + for (const [key, value] of props) { + const beautifulKey = key.toLowerCase().replace('_', ' '); + infoMap.set(beautifulKey.charAt(0).toUpperCase() + beautifulKey.slice(1), value); + } + return infoMap; + }); } - getTitle(): string { + getTitle() { return 'Device information'; } - getPriority(): number { + getPriority() { return 100; } - isSupported(): Observable { - return Observable.of(true); + isSupported() { + return _rxjsBundlesRxMinJs.Observable.of(true); } } +exports.AndroidDeviceInfoProvider = AndroidDeviceInfoProvider; \ No newline at end of file diff --git a/pkg/nuclide-device-panel-android/lib/providers/AndroidDeviceProcessesProvider.js b/pkg/nuclide-device-panel-android/lib/providers/AndroidDeviceProcessesProvider.js index edfca4ccfe..b20b278d75 100644 --- a/pkg/nuclide-device-panel-android/lib/providers/AndroidDeviceProcessesProvider.js +++ b/pkg/nuclide-device-panel-android/lib/providers/AndroidDeviceProcessesProvider.js @@ -1,3 +1,18 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AndroidDeviceProcessesProvider = undefined; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _utils; + +function _load_utils() { + return _utils = require('../../../../modules/nuclide-adb/lib/utils'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,34 +20,18 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type { - Device, - DeviceProcessesProvider, - Process, -} from 'nuclide-debugger-common/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import {Observable} from 'rxjs'; -import {getAdbServiceByNuclideUri} from 'nuclide-adb/lib/utils'; - -export class AndroidDeviceProcessesProvider implements DeviceProcessesProvider { - getType(): string { +class AndroidDeviceProcessesProvider { + getType() { return 'Android'; } - observe(host: NuclideUri, device: Device): Observable { + observe(host, device) { const intervalTime = 3000; - return Observable.interval(intervalTime) - .startWith(0) - .switchMap(() => - getAdbServiceByNuclideUri(host) - .getProcesses(device, intervalTime) - .refCount() - .catch(() => Observable.of([])), - ); + return _rxjsBundlesRxMinJs.Observable.interval(intervalTime).startWith(0).switchMap(() => (0, (_utils || _load_utils()).getAdbServiceByNuclideUri)(host).getProcesses(device, intervalTime).refCount().catch(() => _rxjsBundlesRxMinJs.Observable.of([]))); } } +exports.AndroidDeviceProcessesProvider = AndroidDeviceProcessesProvider; \ No newline at end of file diff --git a/pkg/nuclide-device-panel-android/lib/providers/AndroidDeviceStopProcessProvider.js b/pkg/nuclide-device-panel-android/lib/providers/AndroidDeviceStopProcessProvider.js index ddbac0f2a4..61a91cbf96 100644 --- a/pkg/nuclide-device-panel-android/lib/providers/AndroidDeviceStopProcessProvider.js +++ b/pkg/nuclide-device-panel-android/lib/providers/AndroidDeviceStopProcessProvider.js @@ -1,3 +1,18 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AndroidDeviceStopProcessProvider = undefined; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _utils; + +function _load_utils() { + return _utils = require('../../../../modules/nuclide-adb/lib/utils'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,52 +20,33 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type { - Device, - DeviceProcessTaskProvider, - Process, - ProcessTaskType, -} from 'nuclide-debugger-common/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import {Observable} from 'rxjs'; -import {getAdbServiceByNuclideUri} from 'nuclide-adb/lib/utils'; - -export class AndroidDeviceStopProcessProvider - implements DeviceProcessTaskProvider { - getType(): string { +class AndroidDeviceStopProcessProvider { + getType() { return 'Android'; } - getTaskType(): ProcessTaskType { + getTaskType() { return 'KILL'; } - getName(): string { + getName() { return 'Stop process/package'; } - isSupported(proc: Process): boolean { + isSupported(proc) { return true; } - getSupportedPIDs( - host: NuclideUri, - device: Device, - procs: Process[], - ): Observable> { - return Observable.of(new Set(procs.map(proc => proc.pid))); + getSupportedPIDs(host, device, procs) { + return _rxjsBundlesRxMinJs.Observable.of(new Set(procs.map(proc => proc.pid))); } - async run(host: NuclideUri, device: Device, proc: Process): Promise { - return getAdbServiceByNuclideUri(host).stopProcess( - device, - proc.name, - proc.pid, - ); + async run(host, device, proc) { + return (0, (_utils || _load_utils()).getAdbServiceByNuclideUri)(host).stopProcess(device, proc.name, proc.pid); } } +exports.AndroidDeviceStopProcessProvider = AndroidDeviceStopProcessProvider; \ No newline at end of file diff --git a/pkg/nuclide-device-panel-android/lib/providers/AvdComponentProvider.js b/pkg/nuclide-device-panel-android/lib/providers/AvdComponentProvider.js index 0794d76d10..4b33286079 100644 --- a/pkg/nuclide-device-panel-android/lib/providers/AvdComponentProvider.js +++ b/pkg/nuclide-device-panel-android/lib/providers/AvdComponentProvider.js @@ -1,61 +1,115 @@ -/** - * 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 strict-local - * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {Expected} from 'nuclide-commons/expected'; -import type { - DeviceTypeComponent, - DeviceTypeComponentProvider, -} from 'nuclide-debugger-common/types'; - -import {WatchmanClient} from 'nuclide-watchman-helpers'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Expect} from 'nuclide-commons/expected'; -import invariant from 'assert'; -import fsPromise from 'nuclide-commons/fsPromise'; -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import os from 'os'; -import {Observable, Subject} from 'rxjs'; -import {runCommand} from 'nuclide-commons/process'; -import AvdTable from '../ui/AvdTable'; - -export type Avd = { - name: string, - running: boolean, - pid?: number, -}; - -const AVD_DIRECTORY = `${os.homedir()}/.android/avd`; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AvdComponentProvider = undefined; + +var _nuclideWatchmanHelpers; + +function _load_nuclideWatchmanHelpers() { + return _nuclideWatchmanHelpers = require('../../../../modules/nuclide-watchman-helpers'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../../modules/nuclide-commons/nuclideUri')); +} + +var _expected; + +function _load_expected() { + return _expected = require('../../../../modules/nuclide-commons/expected'); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../../modules/nuclide-commons/fsPromise')); +} + +var _bindObservableAsProps; + +function _load_bindObservableAsProps() { + return _bindObservableAsProps = require('../../../../modules/nuclide-commons-ui/bindObservableAsProps'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _os = _interopRequireDefault(require('os')); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _process; + +function _load_process() { + return _process = require('../../../../modules/nuclide-commons/process'); +} + +var _AvdTable; + +function _load_AvdTable() { + return _AvdTable = _interopRequireDefault(require('../ui/AvdTable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const AVD_DIRECTORY = `${_os.default.homedir()}/.android/avd`; /** + * 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. + * + * strict-local + * @format + */ + const AVD_LOCKFILE = 'hardware-qemu.ini.lock'; // We create a temporary .watchmanconfig so Watchman recognizes the AVD // directory as a project root. const AVD_WATCHMAN_CONFIG = `${AVD_DIRECTORY}/.watchmanconfig`; -export class AvdComponentProvider implements DeviceTypeComponentProvider { - _refresh: Subject = new Subject(); - _emulator: ?string; +class AvdComponentProvider { + constructor() { + this._refresh = new _rxjsBundlesRxMinJs.Subject(); + + this._populateAvdPIDs = avds => { + return _rxjsBundlesRxMinJs.Observable.fromPromise(Promise.all(avds.map(this._populateAvdPID))); + }; + + this._refreshAvds = () => { + this._refresh.next(); + }; + + this._startAvd = avd => { + if (!(this._emulator != null)) { + throw new Error('Invariant violation: "this._emulator != null"'); + } - getType(): string { + (0, (_process || _load_process()).runCommand)(this._emulator, ['@' + avd.name]).subscribe(stdout => {}, err => { + atom.notifications.addError(`Failed to start up emulator ${avd.name}.`, { + detail: err, + dismissable: true + }); + }); + }; + } + + getType() { return 'Android'; } - observe( - host: NuclideUri, - callback: (?DeviceTypeComponent) => void, - ): IDisposable { + observe(host, callback) { // TODO (T26257016): Don't hide the table when ADB tunneling is on. - if (nuclideUri.isRemote(host)) { + if ((_nuclideUri || _load_nuclideUri()).default.isRemote(host)) { callback(null); - return new UniversalDisposable(); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(); } const disposables = this._watchAvdDirectory(); @@ -63,43 +117,39 @@ export class AvdComponentProvider implements DeviceTypeComponentProvider { const getProps = this._getAvds().map(avds => { return { avds, - startAvd: this._startAvd, + startAvd: this._startAvd }; }); const props = getProps.concat(this._refresh.exhaustMap(_ => getProps)); callback({ position: 'below_table', - type: bindObservableAsProps(props, AvdTable), - key: 'emulators', + type: (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)(props, (_AvdTable || _load_AvdTable()).default), + key: 'emulators' }); return disposables; } - _watchAvdDirectory(): IDisposable { - const watchAvdDirectory: Promise<() => mixed> = (async () => { - const avdDirectoryExists = await fsPromise.exists(AVD_DIRECTORY); + _watchAvdDirectory() { + const watchAvdDirectory = (async () => { + const avdDirectoryExists = await (_fsPromise || _load_fsPromise()).default.exists(AVD_DIRECTORY); if (!avdDirectoryExists) { return () => {}; } // Create a .watchmanconfig so Watchman recognizes the AVD directory as a // project root. - await fsPromise.writeFile(AVD_WATCHMAN_CONFIG, '{}'); - - const watchmanClient = new WatchmanClient(); - const watchmanSubscription = await watchmanClient.watchDirectoryRecursive( - AVD_DIRECTORY, - AVD_DIRECTORY, - { - expression: ['match', '*.avd'], - }, - ); + await (_fsPromise || _load_fsPromise()).default.writeFile(AVD_WATCHMAN_CONFIG, '{}'); + + const watchmanClient = new (_nuclideWatchmanHelpers || _load_nuclideWatchmanHelpers()).WatchmanClient(); + const watchmanSubscription = await watchmanClient.watchDirectoryRecursive(AVD_DIRECTORY, AVD_DIRECTORY, { + expression: ['match', '*.avd'] + }); watchmanSubscription.on('change', () => { this._refreshAvds(); }); - return () => fsPromise.unlink(AVD_WATCHMAN_CONFIG).catch(() => {}); + return () => (_fsPromise || _load_fsPromise()).default.unlink(AVD_WATCHMAN_CONFIG).catch(() => {}); })(); return { @@ -107,80 +157,50 @@ export class AvdComponentProvider implements DeviceTypeComponentProvider { watchAvdDirectory.then(dispose => { dispose(); }); - }, + } }; } - _getEmulator(): Observable { - return Observable.defer(async () => { + _getEmulator() { + return _rxjsBundlesRxMinJs.Observable.defer(async () => { const androidHome = process.env.ANDROID_HOME; - const emulator = - androidHome != null ? `${androidHome}/tools/emulator` : null; + const emulator = androidHome != null ? `${androidHome}/tools/emulator` : null; if (emulator == null) { return null; } - const exists = await fsPromise.exists(emulator); + const exists = await (_fsPromise || _load_fsPromise()).default.exists(emulator); this._emulator = exists ? emulator : null; return this._emulator; }); } - _parseAvds(emulatorOutput: string): Array { + _parseAvds(emulatorOutput) { const trimmedOutput = emulatorOutput.trim(); - return trimmedOutput === '' ? [] : trimmedOutput.split(os.EOL); + return trimmedOutput === '' ? [] : trimmedOutput.split(_os.default.EOL); } - async _populateAvdPID(avdName: string): Promise { + async _populateAvdPID(avdName) { const lockFile = `${AVD_DIRECTORY}/${avdName}.avd/${AVD_LOCKFILE}`; - if (await fsPromise.exists(lockFile)) { - const pid = parseInt(await fsPromise.readFile(lockFile, 'utf8'), 10); + if (await (_fsPromise || _load_fsPromise()).default.exists(lockFile)) { + const pid = parseInt((await (_fsPromise || _load_fsPromise()).default.readFile(lockFile, 'utf8')), 10); return { name: avdName, running: true, - pid, + pid }; } else { return { name: avdName, - running: false, + running: false }; } } - _populateAvdPIDs = (avds: Array): Observable> => { - return Observable.fromPromise(Promise.all(avds.map(this._populateAvdPID))); - }; - - _getAvds(): Observable>> { + _getAvds() { return this._getEmulator().switchMap(emulator => { - return emulator != null - ? runCommand(emulator, ['-list-avds']) - .map(this._parseAvds) - .switchMap(this._populateAvdPIDs) - .map(Expect.value) - : Observable.of( - Expect.error(new Error("Cannot find 'emulator' command.")), - ); + return emulator != null ? (0, (_process || _load_process()).runCommand)(emulator, ['-list-avds']).map(this._parseAvds).switchMap(this._populateAvdPIDs).map((_expected || _load_expected()).Expect.value) : _rxjsBundlesRxMinJs.Observable.of((_expected || _load_expected()).Expect.error(new Error("Cannot find 'emulator' command."))); }); } - _refreshAvds = (): void => { - this._refresh.next(); - }; - - _startAvd = (avd: Avd): void => { - invariant(this._emulator != null); - runCommand(this._emulator, ['@' + avd.name]).subscribe( - stdout => {}, - err => { - atom.notifications.addError( - `Failed to start up emulator ${avd.name}.`, - { - detail: err, - dismissable: true, - }, - ); - }, - ); - }; } +exports.AvdComponentProvider = AvdComponentProvider; \ No newline at end of file diff --git a/pkg/nuclide-device-panel-android/lib/ui/AdbTunnelButton.js b/pkg/nuclide-device-panel-android/lib/ui/AdbTunnelButton.js index 6aa11aa924..6c6dfa0c98 100644 --- a/pkg/nuclide-device-panel-android/lib/ui/AdbTunnelButton.js +++ b/pkg/nuclide-device-panel-android/lib/ui/AdbTunnelButton.js @@ -1,62 +1,67 @@ -/** - * 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 - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import classnames from 'classnames'; -import {Button} from 'nuclide-commons-ui/Button'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import * as React from 'react'; - -type Props = { - host: NuclideUri, - status: 'active' | 'inactive', - enable: () => void, - disable: () => void, -}; - -export function AdbTunnelButton(props: Props): React.Element { - const {host, enable, disable, status} = props; - const className = classnames( - 'nuclide-device-panel-android-tunnel-control', - status, - ); - const tooltipAction = - status === 'inactive' - ? 'Reroute adb to know about localhost (where Atom is running) devices' - : `Switch adb back to devices on ${prettify(host)}`; - return ( -
    { - return {data}; - })} - /> - ); + return _react.createElement((_Table || _load_Table()).Table, { + collapsable: false, + columns: [{ + title: 'Emulators', + key: 'avd', + component: this._renderAvd.bind(this) + }], + emptyComponent: this._renderEmptyComponent, + fixedHeader: true, + rows: rowData.map(data => { + return { data }; + }) + }); } } +exports.default = AvdTable; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-device-panel-ios/lib/main.js b/pkg/nuclide-device-panel-ios/lib/main.js index 443a33a0bd..3e4ebb2459 100644 --- a/pkg/nuclide-device-panel-ios/lib/main.js +++ b/pkg/nuclide-device-panel-ios/lib/main.js @@ -1,70 +1,86 @@ -/** - * 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 strict-local - * @format - */ - -import type { - DeviceArchitecture, - DevicePanelServiceApi, -} from 'nuclide-debugger-common/types'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Observable} from 'rxjs'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Expect} from 'nuclide-commons/expected'; -import {getDevices} from '../../nuclide-fbsimctl'; +'use strict'; + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _expected; + +function _load_expected() { + return _expected = require('../../../modules/nuclide-commons/expected'); +} + +var _nuclideFbsimctl; + +function _load_nuclideFbsimctl() { + return _nuclideFbsimctl = require('../../nuclide-fbsimctl'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class Activation { - _disposables = new UniversalDisposable(); - _type = 'iOS'; + constructor() { + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._type = 'iOS'; + } - consumeDevicePanelServiceApi(api: DevicePanelServiceApi): void { + consumeDevicePanelServiceApi(api) { this._disposables.add(this.registerDeviceList(api)); } - registerDeviceList(api: DevicePanelServiceApi): IDisposable { + registerDeviceList(api) { return api.registerListProvider({ observe: host => { - if (nuclideUri.isRemote(host)) { - return Observable.of( - Expect.error( - new Error( - 'iOS devices on remote hosts are not currently supported.', - ), - ), - ); + if ((_nuclideUri || _load_nuclideUri()).default.isRemote(host)) { + return _rxjsBundlesRxMinJs.Observable.of((_expected || _load_expected()).Expect.error(new Error('iOS devices on remote hosts are not currently supported.'))); } else { - return getDevices().map(devices => { + return (0, (_nuclideFbsimctl || _load_nuclideFbsimctl()).getDevices)().map(devices => { if (devices instanceof Error) { - return Expect.error(devices); + return (_expected || _load_expected()).Expect.error(devices); } else { - return Expect.value( - devices.map(device => ({ - name: device.udid, - port: 0, - displayName: device.name, - architecture: devicePanelArchitecture(device.arch), - rawArchitecture: device.arch, - ignoresSelection: true, - })), - ); + return (_expected || _load_expected()).Expect.value(devices.map(device => ({ + name: device.udid, + port: 0, + displayName: device.name, + architecture: devicePanelArchitecture(device.arch), + rawArchitecture: device.arch, + ignoresSelection: true + }))); } }); } }, - getType: () => this._type, + getType: () => this._type }); } -} +} /** + * 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. + * + * strict-local + * @format + */ -function devicePanelArchitecture(arch: string): DeviceArchitecture { +function devicePanelArchitecture(arch) { switch (arch) { case 'x86_64': return 'x86_64'; @@ -80,4 +96,4 @@ function devicePanelArchitecture(arch: string): DeviceArchitecture { } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-device-panel-tizen/lib/Registration.js b/pkg/nuclide-device-panel-tizen/lib/Registration.js index 3c630c5ee8..78fa13368f 100644 --- a/pkg/nuclide-device-panel-tizen/lib/Registration.js +++ b/pkg/nuclide-device-panel-tizen/lib/Registration.js @@ -1,3 +1,42 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.registerDevicePanelProviders = registerDevicePanelProviders; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _SdbDevicePoller; + +function _load_SdbDevicePoller() { + return _SdbDevicePoller = require('../../nuclide-adb-sdb-base/lib/SdbDevicePoller'); +} + +var _TizenDeviceInfoProvider; + +function _load_TizenDeviceInfoProvider() { + return _TizenDeviceInfoProvider = require('./providers/TizenDeviceInfoProvider'); +} + +var _TizenDeviceProcessesProvider; + +function _load_TizenDeviceProcessesProvider() { + return _TizenDeviceProcessesProvider = require('./providers/TizenDeviceProcessesProvider'); +} + +var _TizenDeviceStopProcessProvider; + +function _load_TizenDeviceStopProcessProvider() { + return _TizenDeviceStopProcessProvider = require('./providers/TizenDeviceStopProcessProvider'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,48 +44,25 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {DevicePanelServiceApi} from 'nuclide-debugger-common/types'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {observeTizenDevicesX} from '../../nuclide-adb-sdb-base/lib/SdbDevicePoller'; -import {TizenDeviceInfoProvider} from './providers/TizenDeviceInfoProvider'; -import {TizenDeviceProcessesProvider} from './providers/TizenDeviceProcessesProvider'; -import {TizenDeviceStopProcessProvider} from './providers/TizenDeviceStopProcessProvider'; - -export function registerDevicePanelProviders( - api: DevicePanelServiceApi, -): IDisposable { +function registerDevicePanelProviders(api) { let lastRegistration; - return new UniversalDisposable( - () => { - if (lastRegistration != null) { - lastRegistration.dispose(); - } - }, - atom.config.observe( - 'nuclide.nuclide-device-panel-tizen.register', - (value: boolean) => { - if (lastRegistration != null) { - lastRegistration.dispose(); - } - if (value) { - lastRegistration = new UniversalDisposable( - api.registerListProvider({ - getType: () => 'Tizen', - observe: host => observeTizenDevicesX(host), - }), - api.registerInfoProvider(new TizenDeviceInfoProvider()), - api.registerProcessesProvider(new TizenDeviceProcessesProvider()), - api.registerProcessTaskProvider( - new TizenDeviceStopProcessProvider(), - ), - ); - } - }, - ), - ); -} + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { + if (lastRegistration != null) { + lastRegistration.dispose(); + } + }, atom.config.observe('nuclide.nuclide-device-panel-tizen.register', value => { + if (lastRegistration != null) { + lastRegistration.dispose(); + } + if (value) { + lastRegistration = new (_UniversalDisposable || _load_UniversalDisposable()).default(api.registerListProvider({ + getType: () => 'Tizen', + observe: host => (0, (_SdbDevicePoller || _load_SdbDevicePoller()).observeTizenDevicesX)(host) + }), api.registerInfoProvider(new (_TizenDeviceInfoProvider || _load_TizenDeviceInfoProvider()).TizenDeviceInfoProvider()), api.registerProcessesProvider(new (_TizenDeviceProcessesProvider || _load_TizenDeviceProcessesProvider()).TizenDeviceProcessesProvider()), api.registerProcessTaskProvider(new (_TizenDeviceStopProcessProvider || _load_TizenDeviceStopProcessProvider()).TizenDeviceStopProcessProvider())); + } + })); +} \ No newline at end of file diff --git a/pkg/nuclide-device-panel-tizen/lib/main.js b/pkg/nuclide-device-panel-tizen/lib/main.js index 63fc663610..9c085a0da6 100644 --- a/pkg/nuclide-device-panel-tizen/lib/main.js +++ b/pkg/nuclide-device-panel-tizen/lib/main.js @@ -1,3 +1,25 @@ +'use strict'; + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _Registration; + +function _load_Registration() { + return _Registration = require('./Registration'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,30 +27,23 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {DevicePanelServiceApi} from 'nuclide-debugger-common/types'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {registerDevicePanelProviders} from './Registration'; - class Activation { - _disposables: UniversalDisposable; constructor() { - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - dispose(): void { + dispose() { this._disposables.dispose(); } - consumeDevicePanelServiceApi(api: DevicePanelServiceApi): void { - this._disposables.add(registerDevicePanelProviders(api)); + consumeDevicePanelServiceApi(api) { + this._disposables.add((0, (_Registration || _load_Registration()).registerDevicePanelProviders)(api)); } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-device-panel-tizen/lib/providers/TizenDeviceInfoProvider.js b/pkg/nuclide-device-panel-tizen/lib/providers/TizenDeviceInfoProvider.js index 282a13cdd5..4fe6eed991 100644 --- a/pkg/nuclide-device-panel-tizen/lib/providers/TizenDeviceInfoProvider.js +++ b/pkg/nuclide-device-panel-tizen/lib/providers/TizenDeviceInfoProvider.js @@ -1,3 +1,18 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.TizenDeviceInfoProvider = undefined; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../../nuclide-remote-connection'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,46 +20,37 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {DeviceInfoProvider, Device} from 'nuclide-debugger-common/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import {Observable} from 'rxjs'; -import {getSdbServiceByNuclideUri} from '../../../nuclide-remote-connection'; - -export class TizenDeviceInfoProvider implements DeviceInfoProvider { - getType(): string { +class TizenDeviceInfoProvider { + getType() { return 'Tizen'; } - fetch(host: NuclideUri, device: Device): Observable> { - return getSdbServiceByNuclideUri(host) - .getDeviceInfo(device) - .refCount() - .map(props => { - const infoMap = new Map(); - for (const [key, value] of props) { - let beautifulKey = key.toLowerCase().replace('_', ' '); - beautifulKey = - beautifulKey.charAt(0).toUpperCase() + beautifulKey.slice(1); - infoMap.set(beautifulKey, value); - } - return infoMap; - }); + fetch(host, device) { + return (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getSdbServiceByNuclideUri)(host).getDeviceInfo(device).refCount().map(props => { + const infoMap = new Map(); + for (const [key, value] of props) { + let beautifulKey = key.toLowerCase().replace('_', ' '); + beautifulKey = beautifulKey.charAt(0).toUpperCase() + beautifulKey.slice(1); + infoMap.set(beautifulKey, value); + } + return infoMap; + }); } - getTitle(): string { + getTitle() { return 'Device information'; } - getPriority(): number { + getPriority() { return 100; } - isSupported(): Observable { - return Observable.of(true); + isSupported() { + return _rxjsBundlesRxMinJs.Observable.of(true); } } +exports.TizenDeviceInfoProvider = TizenDeviceInfoProvider; \ No newline at end of file diff --git a/pkg/nuclide-device-panel-tizen/lib/providers/TizenDeviceProcessesProvider.js b/pkg/nuclide-device-panel-tizen/lib/providers/TizenDeviceProcessesProvider.js index ed405bcf6e..96f4c47115 100644 --- a/pkg/nuclide-device-panel-tizen/lib/providers/TizenDeviceProcessesProvider.js +++ b/pkg/nuclide-device-panel-tizen/lib/providers/TizenDeviceProcessesProvider.js @@ -1,3 +1,18 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.TizenDeviceProcessesProvider = undefined; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../../nuclide-remote-connection'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,34 +20,18 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type { - Device, - DeviceProcessesProvider, - Process, -} from 'nuclide-debugger-common/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import {Observable} from 'rxjs'; -import {getSdbServiceByNuclideUri} from '../../../nuclide-remote-connection'; - -export class TizenDeviceProcessesProvider implements DeviceProcessesProvider { - getType(): string { +class TizenDeviceProcessesProvider { + getType() { return 'Tizen'; } - observe(host: NuclideUri, device: Device): Observable { + observe(host, device) { const intervalTime = 3000; - return Observable.interval(intervalTime) - .startWith(0) - .switchMap(() => - getSdbServiceByNuclideUri(host) - .getProcesses(device, intervalTime) - .refCount() - .catch(() => Observable.of([])), - ); + return _rxjsBundlesRxMinJs.Observable.interval(intervalTime).startWith(0).switchMap(() => (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getSdbServiceByNuclideUri)(host).getProcesses(device, intervalTime).refCount().catch(() => _rxjsBundlesRxMinJs.Observable.of([]))); } } +exports.TizenDeviceProcessesProvider = TizenDeviceProcessesProvider; \ No newline at end of file diff --git a/pkg/nuclide-device-panel-tizen/lib/providers/TizenDeviceStopProcessProvider.js b/pkg/nuclide-device-panel-tizen/lib/providers/TizenDeviceStopProcessProvider.js index 899622430f..0aa48884f1 100644 --- a/pkg/nuclide-device-panel-tizen/lib/providers/TizenDeviceStopProcessProvider.js +++ b/pkg/nuclide-device-panel-tizen/lib/providers/TizenDeviceStopProcessProvider.js @@ -1,3 +1,18 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.TizenDeviceStopProcessProvider = undefined; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../../nuclide-remote-connection'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,52 +20,33 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type { - Device, - DeviceProcessTaskProvider, - Process, - ProcessTaskType, -} from 'nuclide-debugger-common/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import {Observable} from 'rxjs'; -import {getSdbServiceByNuclideUri} from '../../../nuclide-remote-connection'; - -export class TizenDeviceStopProcessProvider - implements DeviceProcessTaskProvider { - getType(): string { +class TizenDeviceStopProcessProvider { + getType() { return 'Tizen'; } - getTaskType(): ProcessTaskType { + getTaskType() { return 'KILL'; } - getName(): string { + getName() { return 'Stop process/package'; } - isSupported(proc: Process): boolean { + isSupported(proc) { return true; } - getSupportedPIDs( - host: NuclideUri, - device: Device, - procs: Process[], - ): Observable> { - return Observable.of(new Set(procs.map(proc => proc.pid))); + getSupportedPIDs(host, device, procs) { + return _rxjsBundlesRxMinJs.Observable.of(new Set(procs.map(proc => proc.pid))); } - async run(host: NuclideUri, device: Device, proc: Process): Promise { - return getSdbServiceByNuclideUri(host).stopProcess( - device, - proc.name, - proc.pid, - ); + async run(host, device, proc) { + return (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getSdbServiceByNuclideUri)(host).stopProcess(device, proc.name, proc.pid); } } +exports.TizenDeviceStopProcessProvider = TizenDeviceStopProcessProvider; \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/DevicePanelWorkspaceView.js b/pkg/nuclide-device-panel/lib/DevicePanelWorkspaceView.js index 7bbfd17292..fd51422fd8 100644 --- a/pkg/nuclide-device-panel/lib/DevicePanelWorkspaceView.js +++ b/pkg/nuclide-device-panel/lib/DevicePanelWorkspaceView.js @@ -1,3 +1,40 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DevicePanelWorkspaceView = exports.WORKSPACE_VIEW_URI = undefined; + +var _react = _interopRequireWildcard(require('react')); + +var _renderReactRoot; + +function _load_renderReactRoot() { + return _renderReactRoot = require('../../../modules/nuclide-commons-ui/renderReactRoot'); +} + +var _RootPanel; + +function _load_RootPanel() { + return _RootPanel = require('./ui/RootPanel'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _bindObservableAsProps; + +function _load_bindObservableAsProps() { + return _bindObservableAsProps = require('../../../modules/nuclide-commons-ui/bindObservableAsProps'); +} + +var _Actions; + +function _load_Actions() { + return _Actions = _interopRequireWildcard(require('./redux/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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,26 +42,15 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {Props} from './ui/RootPanel'; -import type {Store, AppState} from './types'; - -import * as React from 'react'; -import {renderReactRoot} from 'nuclide-commons-ui/renderReactRoot'; -import {RootPanel} from './ui/RootPanel'; -import {Observable} from 'rxjs'; -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import * as Actions from './redux/Actions'; - -export const WORKSPACE_VIEW_URI = 'atom://nuclide/devices'; +const WORKSPACE_VIEW_URI = exports.WORKSPACE_VIEW_URI = 'atom://nuclide/devices'; -export class DevicePanelWorkspaceView { - _store: Store; +class DevicePanelWorkspaceView { - constructor(store: Store) { + constructor(store) { this._store = store; } @@ -36,33 +62,33 @@ export class DevicePanelWorkspaceView { return 'device-mobile'; } - getPreferredWidth(): number { + getPreferredWidth() { return 400; } - getURI(): string { + getURI() { return WORKSPACE_VIEW_URI; } - getDefaultLocation(): string { + getDefaultLocation() { return 'right'; } - _appStateToProps(state: AppState): Props { - const toggleDevicePolling = (isActive: boolean) => { - this._store.dispatch(Actions.toggleDevicePolling(isActive)); + _appStateToProps(state) { + const toggleDevicePolling = isActive => { + this._store.dispatch((_Actions || _load_Actions()).toggleDevicePolling(isActive)); }; - const toggleProcessPolling = (isActive: boolean) => { - this._store.dispatch(Actions.toggleProcessPolling(isActive)); + const toggleProcessPolling = isActive => { + this._store.dispatch((_Actions || _load_Actions()).toggleProcessPolling(isActive)); }; const setHost = host => { - this._store.dispatch(Actions.setHost(host)); + this._store.dispatch((_Actions || _load_Actions()).setHost(host)); }; const setDeviceType = deviceType => { - this._store.dispatch(Actions.setDeviceType(deviceType)); + this._store.dispatch((_Actions || _load_Actions()).setDeviceType(deviceType)); }; const setDevice = device => { - this._store.dispatch(Actions.setDevice(device)); + this._store.dispatch((_Actions || _load_Actions()).setDevice(device)); }; return { devices: state.devices, @@ -83,25 +109,22 @@ export class DevicePanelWorkspaceView { toggleProcessPolling, setHost, setDeviceType, - setDevice, + setDevice }; } - getElement(): HTMLElement { - const PreparedDevicePanel = bindObservableAsProps( - // $FlowFixMe: Teach flow about Symbol.observable - Observable.from(this._store) - .distinctUntilChanged() - .map(state => this._appStateToProps(state)), - RootPanel, - ); + getElement() { + const PreparedDevicePanel = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)( + // $FlowFixMe: Teach flow about Symbol.observable + _rxjsBundlesRxMinJs.Observable.from(this._store).distinctUntilChanged().map(state => this._appStateToProps(state)), (_RootPanel || _load_RootPanel()).RootPanel); - return renderReactRoot(); + return (0, (_renderReactRoot || _load_renderReactRoot()).renderReactRoot)(_react.createElement(PreparedDevicePanel, null)); } - serialize(): {deserializer: string} { + serialize() { return { - deserializer: 'nuclide.DevicePanelWorkspaceView', + deserializer: 'nuclide.DevicePanelWorkspaceView' }; } } +exports.DevicePanelWorkspaceView = DevicePanelWorkspaceView; \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/DeviceTask.js b/pkg/nuclide-device-panel/lib/DeviceTask.js index 373a993474..9f647bbb4c 100644 --- a/pkg/nuclide-device-panel/lib/DeviceTask.js +++ b/pkg/nuclide-device-panel/lib/DeviceTask.js @@ -1,65 +1,51 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {TaskEvent} from 'nuclide-commons/process'; -import type {IDeviceTask} from 'nuclide-debugger-common/types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DeviceTask = undefined; -import {Observable, ReplaySubject, Subscription} from 'rxjs'; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); -export class DeviceTask implements IDeviceTask { - _name: string; - _taskFactory: () => Observable; - _subscription: ?Subscription = null; - _events: ReplaySubject = new ReplaySubject(1); +class DeviceTask { + + constructor(taskFactory, name) { + this._subscription = null; + this._events = new _rxjsBundlesRxMinJs.ReplaySubject(1); - constructor(taskFactory: () => Observable, name: string) { this._taskFactory = taskFactory; this._name = name; this._events.next(null); } - getName(): string { + getName() { return this._name; } - getTaskEvents(): Observable { + getTaskEvents() { return this._events; } - start(): void { + start() { const task = this._taskFactory().share(); - this._subscription = task.subscribe( - message => { - this._events.next(message); - if (message.type === 'result') { - atom.notifications.addSuccess( - `Device task '${this._name}' succeeded.`, - ); - } - }, - () => { - atom.notifications.addError(`Device task '${this._name}' failed.`); - this._finishRun(); - }, - () => { - this._finishRun(); - }, - ); + this._subscription = task.subscribe(message => { + this._events.next(message); + if (message.type === 'result') { + atom.notifications.addSuccess(`Device task '${this._name}' succeeded.`); + } + }, () => { + atom.notifications.addError(`Device task '${this._name}' failed.`); + this._finishRun(); + }, () => { + this._finishRun(); + }); } - cancel(): void { + cancel() { this._finishRun(); } - _finishRun(): void { + _finishRun() { if (this._subscription != null) { this._subscription.unsubscribe(); this._subscription = null; @@ -67,3 +53,13 @@ export class DeviceTask implements IDeviceTask { this._events.next(null); } } +exports.DeviceTask = DeviceTask; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/constants.js b/pkg/nuclide-device-panel/lib/constants.js index e8396c8e65..94245a9065 100644 --- a/pkg/nuclide-device-panel/lib/constants.js +++ b/pkg/nuclide-device-panel/lib/constants.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,18 +10,18 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ const ANALYTICS_PREFIX = 'nuclide-device-panel'; -export const AnalyticsActions = Object.freeze({ +const AnalyticsActions = exports.AnalyticsActions = Object.freeze({ APPINFOTABLES_DATA_VALUE: `${ANALYTICS_PREFIX}:app-info-tables.data.value`, APPINFOTABLES_DATA_ERROR: `${ANALYTICS_PREFIX}:app-info-tables.data.error`, APPINFOTABLES_UI_MOUNT: `${ANALYTICS_PREFIX}:app-info-tables.ui.mount`, APPINFOTABLES_UI_UNMOUNT: `${ANALYTICS_PREFIX}:app-info-tables.ui.unmount`, APPINFOVALUECELL_UI_VALUE: `${ANALYTICS_PREFIX}:app-info-value-cell.ui.value`, APPINFOVALUECELL_UI_ERROR: `${ANALYTICS_PREFIX}:app-info-value-cell.ui.error`, - APPINFOVALUECELL_UI_EDITINGSTATECHANGE: `${ANALYTICS_PREFIX}:app-info-value-cell.ui.editing-state-change`, -}); + APPINFOVALUECELL_UI_EDITINGSTATECHANGE: `${ANALYTICS_PREFIX}:app-info-value-cell.ui.editing-state-change` +}); \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/main.js b/pkg/nuclide-device-panel/lib/main.js index 3c7a228236..795c95f363 100644 --- a/pkg/nuclide-device-panel/lib/main.js +++ b/pkg/nuclide-device-panel/lib/main.js @@ -1,3 +1,81 @@ +'use strict'; + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _DevicePanelWorkspaceView; + +function _load_DevicePanelWorkspaceView() { + return _DevicePanelWorkspaceView = require('./DevicePanelWorkspaceView'); +} + +var _ServerConnection; + +function _load_ServerConnection() { + return _ServerConnection = require('../../nuclide-remote-connection/lib/ServerConnection'); +} + +var _reduxObservable; + +function _load_reduxObservable() { + return _reduxObservable = require('../../../modules/nuclide-commons/redux-observable'); +} + +var _reduxMin; + +function _load_reduxMin() { + return _reduxMin = require('redux/dist/redux.min.js'); +} + +var _createEmptyAppState; + +function _load_createEmptyAppState() { + return _createEmptyAppState = require('./redux/createEmptyAppState'); +} + +var _Reducers; + +function _load_Reducers() { + return _Reducers = _interopRequireWildcard(require('./redux/Reducers')); +} + +var _Actions; + +function _load_Actions() { + return _Actions = _interopRequireWildcard(require('./redux/Actions')); +} + +var _Epics; + +function _load_Epics() { + return _Epics = _interopRequireWildcard(require('./redux/Epics')); +} + +var _providers; + +function _load_providers() { + return _providers = require('./providers'); +} + +var _destroyItemWhere; + +function _load_destroyItemWhere() { + return _destroyItemWhere = require('../../../modules/nuclide-commons-atom/destroyItemWhere'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,107 +83,56 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import createPackage from 'nuclide-commons-atom/createPackage'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import { - DevicePanelWorkspaceView, - WORKSPACE_VIEW_URI, -} from './DevicePanelWorkspaceView'; -import invariant from 'assert'; -import {ServerConnection} from '../../nuclide-remote-connection/lib/ServerConnection'; -import { - combineEpics, - createEpicMiddleware, -} from 'nuclide-commons/redux-observable'; -import {applyMiddleware, createStore} from 'redux'; -import {createEmptyAppState} from './redux/createEmptyAppState'; -import * as Reducers from './redux/Reducers'; -import * as Actions from './redux/Actions'; -import * as Epics from './redux/Epics'; -import {getProviders} from './providers'; -import {destroyItemWhere} from 'nuclide-commons-atom/destroyItemWhere'; - -import type {Store} from './types'; -import type {DevicePanelServiceApi} from 'nuclide-debugger-common/types'; - let activation = null; class Activation { - _disposables: UniversalDisposable; - _store: Store; - - constructor(state: ?Object) { - const epics = Object.keys(Epics) - .map(k => Epics[k]) - .filter(epic => typeof epic === 'function'); - this._store = createStore( - Reducers.app, - createEmptyAppState(), - applyMiddleware(createEpicMiddleware(combineEpics(...epics))), - ); - this._disposables = new UniversalDisposable( - ServerConnection.observeRemoteConnections().subscribe(conns => { - const hosts = conns.map(conn => conn.getUriOfRemotePath('/')); - this._store.dispatch(Actions.setHosts([''].concat(hosts))); - }), - this._registerCommandAndOpener(), - ); + + constructor(state) { + const epics = Object.keys(_Epics || _load_Epics()).map(k => (_Epics || _load_Epics())[k]).filter(epic => typeof epic === 'function'); + this._store = (0, (_reduxMin || _load_reduxMin()).createStore)((_Reducers || _load_Reducers()).app, (0, (_createEmptyAppState || _load_createEmptyAppState()).createEmptyAppState)(), (0, (_reduxMin || _load_reduxMin()).applyMiddleware)((0, (_reduxObservable || _load_reduxObservable()).createEpicMiddleware)((0, (_reduxObservable || _load_reduxObservable()).combineEpics)(...epics)))); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default((_ServerConnection || _load_ServerConnection()).ServerConnection.observeRemoteConnections().subscribe(conns => { + const hosts = conns.map(conn => conn.getUriOfRemotePath('/')); + this._store.dispatch((_Actions || _load_Actions()).setHosts([''].concat(hosts))); + }), this._registerCommandAndOpener()); } - dispose(): void { + dispose() { this._disposables.dispose(); } - _registerCommandAndOpener(): UniversalDisposable { - return new UniversalDisposable( - atom.workspace.addOpener(uri => { - if (uri === WORKSPACE_VIEW_URI) { - return new DevicePanelWorkspaceView(this._store); - } - }), - () => destroyItemWhere(item => item instanceof DevicePanelWorkspaceView), - atom.commands.add( - 'atom-workspace', - 'nuclide-devices-panel:toggle', - () => { - atom.workspace.toggle(WORKSPACE_VIEW_URI); - }, - ), - ); + _registerCommandAndOpener() { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(atom.workspace.addOpener(uri => { + if (uri === (_DevicePanelWorkspaceView || _load_DevicePanelWorkspaceView()).WORKSPACE_VIEW_URI) { + return new (_DevicePanelWorkspaceView || _load_DevicePanelWorkspaceView()).DevicePanelWorkspaceView(this._store); + } + }), () => (0, (_destroyItemWhere || _load_destroyItemWhere()).destroyItemWhere)(item => item instanceof (_DevicePanelWorkspaceView || _load_DevicePanelWorkspaceView()).DevicePanelWorkspaceView), atom.commands.add('atom-workspace', 'nuclide-devices-panel:toggle', () => { + atom.workspace.toggle((_DevicePanelWorkspaceView || _load_DevicePanelWorkspaceView()).WORKSPACE_VIEW_URI); + })); } - deserializeDevicePanelState(): DevicePanelWorkspaceView { - return new DevicePanelWorkspaceView(this._store); + deserializeDevicePanelState() { + return new (_DevicePanelWorkspaceView || _load_DevicePanelWorkspaceView()).DevicePanelWorkspaceView(this._store); } - _refreshDeviceTypes(): void { - this._store.dispatch( - Actions.setDeviceTypes( - Array.from(getProviders().deviceList) - .map(p => p.getType()) - .sort((a, b) => a.localeCompare(b)), - ), - ); + _refreshDeviceTypes() { + this._store.dispatch((_Actions || _load_Actions()).setDeviceTypes(Array.from((0, (_providers || _load_providers()).getProviders)().deviceList).map(p => p.getType()).sort((a, b) => a.localeCompare(b)))); } - _createProviderRegistration( - providers: Set, - onDispose?: () => void, - ): (provider: T) => UniversalDisposable { - return (provider: T) => { - invariant( - activation != null, - 'Device panel service API used after deactivation', - ); + _createProviderRegistration(providers, onDispose) { + return provider => { + if (!(activation != null)) { + throw new Error('Device panel service API used after deactivation'); + } + providers.add(provider); if (onDispose != null) { onDispose(); } - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { if (activation != null) { providers.delete(provider); } @@ -113,44 +140,24 @@ class Activation { }; } - provideDevicePanelServiceApi(): DevicePanelServiceApi { + provideDevicePanelServiceApi() { activation = this; this._disposables.add(() => { activation = null; }); - const providers = getProviders(); + const providers = (0, (_providers || _load_providers()).getProviders)(); return { - registerListProvider: this._createProviderRegistration( - providers.deviceList, - () => this._refreshDeviceTypes(), - ), - registerInfoProvider: this._createProviderRegistration( - providers.deviceInfo, - ), - registerProcessesProvider: this._createProviderRegistration( - providers.deviceProcesses, - ), - registerTaskProvider: this._createProviderRegistration( - providers.deviceTask, - ), - registerProcessTaskProvider: this._createProviderRegistration( - providers.processTask, - ), - registerDeviceTypeTaskProvider: this._createProviderRegistration( - providers.deviceTypeTask, - () => this._refreshDeviceTypes(), - ), - registerDeviceActionProvider: this._createProviderRegistration( - providers.deviceAction, - ), - registerAppInfoProvider: this._createProviderRegistration( - providers.appInfo, - ), - registerDeviceTypeComponentProvider: this._createProviderRegistration( - providers.deviceTypeComponent, - ), + registerListProvider: this._createProviderRegistration(providers.deviceList, () => this._refreshDeviceTypes()), + registerInfoProvider: this._createProviderRegistration(providers.deviceInfo), + registerProcessesProvider: this._createProviderRegistration(providers.deviceProcesses), + registerTaskProvider: this._createProviderRegistration(providers.deviceTask), + registerProcessTaskProvider: this._createProviderRegistration(providers.processTask), + registerDeviceTypeTaskProvider: this._createProviderRegistration(providers.deviceTypeTask, () => this._refreshDeviceTypes()), + registerDeviceActionProvider: this._createProviderRegistration(providers.deviceAction), + registerAppInfoProvider: this._createProviderRegistration(providers.appInfo), + registerDeviceTypeComponentProvider: this._createProviderRegistration(providers.deviceTypeComponent) }; } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/providers.js b/pkg/nuclide-device-panel/lib/providers.js index 0110472999..d9952510dd 100644 --- a/pkg/nuclide-device-panel/lib/providers.js +++ b/pkg/nuclide-device-panel/lib/providers.js @@ -1,3 +1,9 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getProviders = getProviders; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,35 +11,11 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type { - DeviceListProvider, - DeviceInfoProvider, - DeviceProcessesProvider, - DeviceTaskProvider, - DeviceProcessTaskProvider, - DeviceTypeTaskProvider, - DeviceActionProvider, - DeviceAppInfoProvider, - DeviceTypeComponentProvider, -} from 'nuclide-debugger-common/types'; - -type DeviceProviders = { - deviceList: Set, - deviceInfo: Set, - deviceTask: Set, - deviceProcesses: Set, - processTask: Set, - deviceTypeTask: Set, - deviceAction: Set, - appInfo: Set, - deviceTypeComponent: Set, -}; - -const providers: DeviceProviders = { +const providers = { deviceList: new Set(), deviceInfo: new Set(), deviceTask: new Set(), @@ -42,9 +24,9 @@ const providers: DeviceProviders = { deviceTypeTask: new Set(), deviceAction: new Set(), appInfo: new Set(), - deviceTypeComponent: new Set(), + deviceTypeComponent: new Set() }; -export function getProviders(): DeviceProviders { +function getProviders() { return providers; -} +} \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/redux/Actions.js b/pkg/nuclide-device-panel/lib/redux/Actions.js index 8cec01bd7c..53fa5a3305 100644 --- a/pkg/nuclide-device-panel/lib/redux/Actions.js +++ b/pkg/nuclide-device-panel/lib/redux/Actions.js @@ -1,178 +1,157 @@ -/** - * 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 strict-local - * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - SetDeviceTypesAction, - SetDeviceTypeAction, - SetDevicesAction, - SetDeviceTasksAction, - SetDeviceAction, - SetHostsAction, - SetHostAction, - SetInfoTablesAction, - SetAppInfoTablesAction, - SetProcessesAction, - SetProcessTasksAction, - SetDeviceTypeTasksAction, - SetDeviceTypeComponentsAction, - ToggleDevicePollingAction, - ToggleProcessPollingAction, -} from '../types'; -import type { - Device, - Process, - ProcessTask, - AppInfoRow, - DeviceTypeComponent, - ComponentPosition, - IDeviceTask, -} from 'nuclide-debugger-common/types'; -import type {Expected} from 'nuclide-commons/expected'; - -import * as Immutable from 'immutable'; - -export const SET_DEVICE_TYPES = 'SET_DEVICE_TYPES'; -export const SET_DEVICE_TYPE = 'SET_DEVICE_TYPE'; -export const SET_DEVICES = 'SET_DEVICES'; -export const SET_DEVICE = 'SET_DEVICE'; -export const SET_DEVICE_TASKS = 'SET_DEVICE_TASKS'; -export const SET_HOSTS = 'SET_HOSTS'; -export const SET_HOST = 'SET_HOST'; -export const SET_INFO_TABLES = 'SET_INFO_TABLES'; -export const SET_APP_INFO_TABLES = 'SET_APP_INFO_TABLES'; -export const SET_PROCESSES = 'SET_PROCESSES'; -export const SET_PROCESS_TASKS = 'SET_PROCESS_TASKS'; -export const TOGGLE_DEVICE_POLLING = 'TOGGLE_DEVICE_POLLING'; -export const TOGGLE_PROCESS_POLLING = 'TOGGLE_PROCESS_POLLING'; -export const SET_DEVICE_TYPE_TASKS = 'SET_DEVICE_TYPE_TASKS'; -export const SET_DEVICE_TYPE_COMPONENTS = 'SET_DEVICE_TYPE_COMPONENTS'; - -export function toggleDevicePolling( - isActive: boolean, -): ToggleDevicePollingAction { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SET_DEVICE_TYPE_COMPONENTS = exports.SET_DEVICE_TYPE_TASKS = exports.TOGGLE_PROCESS_POLLING = exports.TOGGLE_DEVICE_POLLING = exports.SET_PROCESS_TASKS = exports.SET_PROCESSES = exports.SET_APP_INFO_TABLES = exports.SET_INFO_TABLES = exports.SET_HOST = exports.SET_HOSTS = exports.SET_DEVICE_TASKS = exports.SET_DEVICE = exports.SET_DEVICES = exports.SET_DEVICE_TYPE = exports.SET_DEVICE_TYPES = undefined; +exports.toggleDevicePolling = toggleDevicePolling; +exports.toggleProcessPolling = toggleProcessPolling; +exports.setInfoTables = setInfoTables; +exports.setAppInfoTables = setAppInfoTables; +exports.setProcesses = setProcesses; +exports.setProcessTasks = setProcessTasks; +exports.setDevices = setDevices; +exports.setHosts = setHosts; +exports.setHost = setHost; +exports.setDeviceType = setDeviceType; +exports.setDeviceTypes = setDeviceTypes; +exports.setDevice = setDevice; +exports.setDeviceTasks = setDeviceTasks; +exports.setDeviceTypeTasks = setDeviceTypeTasks; +exports.setDeviceTypeComponents = setDeviceTypeComponents; + +var _immutable; + +function _load_immutable() { + return _immutable = _interopRequireWildcard(require('immutable')); +} + +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 SET_DEVICE_TYPES = exports.SET_DEVICE_TYPES = 'SET_DEVICE_TYPES'; /** + * 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. + * + * strict-local + * @format + */ + +const SET_DEVICE_TYPE = exports.SET_DEVICE_TYPE = 'SET_DEVICE_TYPE'; +const SET_DEVICES = exports.SET_DEVICES = 'SET_DEVICES'; +const SET_DEVICE = exports.SET_DEVICE = 'SET_DEVICE'; +const SET_DEVICE_TASKS = exports.SET_DEVICE_TASKS = 'SET_DEVICE_TASKS'; +const SET_HOSTS = exports.SET_HOSTS = 'SET_HOSTS'; +const SET_HOST = exports.SET_HOST = 'SET_HOST'; +const SET_INFO_TABLES = exports.SET_INFO_TABLES = 'SET_INFO_TABLES'; +const SET_APP_INFO_TABLES = exports.SET_APP_INFO_TABLES = 'SET_APP_INFO_TABLES'; +const SET_PROCESSES = exports.SET_PROCESSES = 'SET_PROCESSES'; +const SET_PROCESS_TASKS = exports.SET_PROCESS_TASKS = 'SET_PROCESS_TASKS'; +const TOGGLE_DEVICE_POLLING = exports.TOGGLE_DEVICE_POLLING = 'TOGGLE_DEVICE_POLLING'; +const TOGGLE_PROCESS_POLLING = exports.TOGGLE_PROCESS_POLLING = 'TOGGLE_PROCESS_POLLING'; +const SET_DEVICE_TYPE_TASKS = exports.SET_DEVICE_TYPE_TASKS = 'SET_DEVICE_TYPE_TASKS'; +const SET_DEVICE_TYPE_COMPONENTS = exports.SET_DEVICE_TYPE_COMPONENTS = 'SET_DEVICE_TYPE_COMPONENTS'; + +function toggleDevicePolling(isActive) { return { type: TOGGLE_DEVICE_POLLING, - payload: {isActive}, + payload: { isActive } }; } -export function toggleProcessPolling( - isActive: boolean, -): ToggleProcessPollingAction { +function toggleProcessPolling(isActive) { return { type: TOGGLE_PROCESS_POLLING, - payload: {isActive}, + payload: { isActive } }; } -export function setInfoTables( - infoTables: Map>, -): SetInfoTablesAction { +function setInfoTables(infoTables) { return { type: SET_INFO_TABLES, - payload: {infoTables}, + payload: { infoTables } }; } -export function setAppInfoTables( - appInfoTables: Map>, -): SetAppInfoTablesAction { +function setAppInfoTables(appInfoTables) { return { type: SET_APP_INFO_TABLES, - payload: {appInfoTables}, + payload: { appInfoTables } }; } -export function setProcesses(processes: Process[]): SetProcessesAction { +function setProcesses(processes) { return { type: SET_PROCESSES, - payload: {processes}, + payload: { processes } }; } -export function setProcessTasks( - processTasks: ProcessTask[], -): SetProcessTasksAction { +function setProcessTasks(processTasks) { return { type: SET_PROCESS_TASKS, - payload: {processTasks}, + payload: { processTasks } }; } -export function setDevices(devices: Expected): SetDevicesAction { +function setDevices(devices) { return { type: SET_DEVICES, - payload: {devices}, + payload: { devices } }; } -export function setHosts(hosts: NuclideUri[]): SetHostsAction { +function setHosts(hosts) { return { type: SET_HOSTS, - payload: {hosts}, + payload: { hosts } }; } -export function setHost(host: NuclideUri): SetHostAction { +function setHost(host) { return { type: SET_HOST, - payload: {host}, + payload: { host } }; } -export function setDeviceType(deviceType: ?string): SetDeviceTypeAction { +function setDeviceType(deviceType) { return { type: SET_DEVICE_TYPE, - payload: {deviceType}, + payload: { deviceType } }; } -export function setDeviceTypes(deviceTypes: string[]): SetDeviceTypesAction { +function setDeviceTypes(deviceTypes) { return { type: SET_DEVICE_TYPES, - payload: {deviceTypes}, + payload: { deviceTypes } }; } -export function setDevice(device: ?Device): SetDeviceAction { +function setDevice(device) { return { type: SET_DEVICE, - payload: {device}, + payload: { device } }; } -export function setDeviceTasks( - deviceTasks: IDeviceTask[], -): SetDeviceTasksAction { +function setDeviceTasks(deviceTasks) { return { type: SET_DEVICE_TASKS, - payload: {deviceTasks}, + payload: { deviceTasks } }; } -export function setDeviceTypeTasks( - deviceTypeTasks: IDeviceTask[], -): SetDeviceTypeTasksAction { +function setDeviceTypeTasks(deviceTypeTasks) { return { type: SET_DEVICE_TYPE_TASKS, - payload: {deviceTypeTasks}, + payload: { deviceTypeTasks } }; } -export function setDeviceTypeComponents( - components: Immutable.Map< - ComponentPosition, - Immutable.List, - >, -): SetDeviceTypeComponentsAction { - return {type: SET_DEVICE_TYPE_COMPONENTS, payload: {components}}; -} +function setDeviceTypeComponents(components) { + return { type: SET_DEVICE_TYPE_COMPONENTS, payload: { components } }; +} \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/redux/Epics.js b/pkg/nuclide-device-panel/lib/redux/Epics.js index 2022646ea0..3f786be112 100644 --- a/pkg/nuclide-device-panel/lib/redux/Epics.js +++ b/pkg/nuclide-device-panel/lib/redux/Epics.js @@ -1,3 +1,83 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.pollDevicesEpic = pollDevicesEpic; +exports.pollProcessesEpic = pollProcessesEpic; +exports.setDeviceEpic = setDeviceEpic; +exports.setDeviceTypesEpic = setDeviceTypesEpic; +exports.setDeviceTypeEpic = setDeviceTypeEpic; +exports.setProcessesEpic = setProcessesEpic; +exports.setAppInfoEpic = setAppInfoEpic; +exports.setDeviceTypeComponentsEpic = setDeviceTypeComponentsEpic; + +var _log4js; + +function _load_log4js() { + return _log4js = _interopRequireDefault(require('log4js')); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../../modules/nuclide-commons/collection'); +} + +var _SimpleCache; + +function _load_SimpleCache() { + return _SimpleCache = require('../../../../modules/nuclide-commons/SimpleCache'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../../nuclide-analytics'); +} + +var _constants; + +function _load_constants() { + return _constants = require('../constants'); +} + +var _Actions; + +function _load_Actions() { + return _Actions = _interopRequireWildcard(require('./Actions')); +} + +var _providers; + +function _load_providers() { + return _providers = require('../providers'); +} + +var _DeviceTask; + +function _load_DeviceTask() { + return _DeviceTask = require('../DeviceTask'); +} + +var _shallowequal; + +function _load_shallowequal() { + return _shallowequal = _interopRequireDefault(require('shallowequal')); +} + +var _immutable; + +function _load_immutable() { + return _immutable = _interopRequireWildcard(require('immutable')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,254 +85,146 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {ActionsObservable} from 'nuclide-commons/redux-observable'; -import type { - ProcessTask, - Process, - AppInfoRow, - DeviceAppInfoProvider, - DeviceTypeComponent, - IDeviceTask, - Device as DeviceIdType, -} from 'nuclide-debugger-common/types'; -import type {Action, Store, AppState} from '../types'; - -import log4js from 'log4js'; -import {arrayEqual, arrayFlatten, collect} from 'nuclide-commons/collection'; -import {SimpleCache} from 'nuclide-commons/SimpleCache'; -import {Observable} from 'rxjs'; -import {track} from '../../../nuclide-analytics'; -import {AnalyticsActions} from '../constants'; -import * as Actions from './Actions'; -import invariant from 'assert'; -import {getProviders} from '../providers'; -import {DeviceTask} from '../DeviceTask'; -import shallowEqual from 'shallowequal'; -import * as Immutable from 'immutable'; - -export function pollDevicesEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions - .ofType(Actions.TOGGLE_DEVICE_POLLING) - .map(action => { - invariant(action.type === Actions.TOGGLE_DEVICE_POLLING); - return [store.getState(), action.payload.isActive]; - }) - .distinctUntilChanged( - ([stateA, isActiveA], [stateB, isActiveB]) => - stateA.deviceType === stateB.deviceType && - stateA.host === stateB.host && - isActiveA === isActiveB, - ) - .switchMap(([state, isActive]) => { - if (state.deviceType == null || !isActive) { - return Observable.empty(); - } - for (const fetcher of getProviders().deviceList) { - if (fetcher.getType() === state.deviceType) { - return fetcher - .observe(state.host) - .map(devices => Actions.setDevices(devices)); - } +function pollDevicesEpic(actions, store) { + return actions.ofType((_Actions || _load_Actions()).TOGGLE_DEVICE_POLLING).map(action => { + if (!(action.type === (_Actions || _load_Actions()).TOGGLE_DEVICE_POLLING)) { + throw new Error('Invariant violation: "action.type === Actions.TOGGLE_DEVICE_POLLING"'); + } + + return [store.getState(), action.payload.isActive]; + }).distinctUntilChanged(([stateA, isActiveA], [stateB, isActiveB]) => stateA.deviceType === stateB.deviceType && stateA.host === stateB.host && isActiveA === isActiveB).switchMap(([state, isActive]) => { + if (state.deviceType == null || !isActive) { + return _rxjsBundlesRxMinJs.Observable.empty(); + } + for (const fetcher of (0, (_providers || _load_providers()).getProviders)().deviceList) { + if (fetcher.getType() === state.deviceType) { + return fetcher.observe(state.host).map(devices => (_Actions || _load_Actions()).setDevices(devices)); } - return Observable.empty(); - }); + } + return _rxjsBundlesRxMinJs.Observable.empty(); + }); } -export function pollProcessesEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions - .ofType(Actions.TOGGLE_PROCESS_POLLING) - .switchMap(action => { - invariant(action.type === Actions.TOGGLE_PROCESS_POLLING); - return Observable.of([store.getState(), action.payload.isActive]); - }) - .distinctUntilChanged( - ([stateA, isActiveA], [stateB, isActiveB]) => - stateA.deviceType === stateB.deviceType && - stateA.host === stateB.host && - shallowEqual(stateA.device, stateB.device) && - isActiveA === isActiveB, - ) - .switchMap(([state, isActive]) => { - const device = state.device; - if (device == null || !isActive) { - return Observable.empty(); - } - const providers = Array.from(getProviders().deviceProcesses).filter( - provider => provider.getType() === state.deviceType, - ); - if (providers[0] != null) { - return providers[0] - .observe(state.host, device) - .map(processes => Actions.setProcesses(processes)); - } - return Observable.empty(); - }); +function pollProcessesEpic(actions, store) { + return actions.ofType((_Actions || _load_Actions()).TOGGLE_PROCESS_POLLING).switchMap(action => { + if (!(action.type === (_Actions || _load_Actions()).TOGGLE_PROCESS_POLLING)) { + throw new Error('Invariant violation: "action.type === Actions.TOGGLE_PROCESS_POLLING"'); + } + + return _rxjsBundlesRxMinJs.Observable.of([store.getState(), action.payload.isActive]); + }).distinctUntilChanged(([stateA, isActiveA], [stateB, isActiveB]) => stateA.deviceType === stateB.deviceType && stateA.host === stateB.host && (0, (_shallowequal || _load_shallowequal()).default)(stateA.device, stateB.device) && isActiveA === isActiveB).switchMap(([state, isActive]) => { + const device = state.device; + if (device == null || !isActive) { + return _rxjsBundlesRxMinJs.Observable.empty(); + } + const providers = Array.from((0, (_providers || _load_providers()).getProviders)().deviceProcesses).filter(provider => provider.getType() === state.deviceType); + if (providers[0] != null) { + return providers[0].observe(state.host, device).map(processes => (_Actions || _load_Actions()).setProcesses(processes)); + } + return _rxjsBundlesRxMinJs.Observable.empty(); + }); } -export function setDeviceEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions.ofType(Actions.SET_DEVICE).switchMap(action => { - invariant(action.type === Actions.SET_DEVICE); +function setDeviceEpic(actions, store) { + return actions.ofType((_Actions || _load_Actions()).SET_DEVICE).switchMap(action => { + if (!(action.type === (_Actions || _load_Actions()).SET_DEVICE)) { + throw new Error('Invariant violation: "action.type === Actions.SET_DEVICE"'); + } + const state = store.getState(); - return Observable.merge( - getInfoTables(state).switchMap(infoTables => - Observable.of(Actions.setInfoTables(infoTables)), - ), - getProcessTasks(state).switchMap(processTasks => - Observable.of(Actions.setProcessTasks(processTasks)), - ), - getDeviceTasks(state).switchMap(deviceTasks => - Observable.of(Actions.setDeviceTasks(deviceTasks)), - ), - ); + return _rxjsBundlesRxMinJs.Observable.merge(getInfoTables(state).switchMap(infoTables => _rxjsBundlesRxMinJs.Observable.of((_Actions || _load_Actions()).setInfoTables(infoTables))), getProcessTasks(state).switchMap(processTasks => _rxjsBundlesRxMinJs.Observable.of((_Actions || _load_Actions()).setProcessTasks(processTasks))), getDeviceTasks(state).switchMap(deviceTasks => _rxjsBundlesRxMinJs.Observable.of((_Actions || _load_Actions()).setDeviceTasks(deviceTasks)))); }); } -export function setDeviceTypesEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions.ofType(Actions.SET_DEVICE_TYPES).switchMap(action => { - invariant(action.type === Actions.SET_DEVICE_TYPES); +function setDeviceTypesEpic(actions, store) { + return actions.ofType((_Actions || _load_Actions()).SET_DEVICE_TYPES).switchMap(action => { + if (!(action.type === (_Actions || _load_Actions()).SET_DEVICE_TYPES)) { + throw new Error('Invariant violation: "action.type === Actions.SET_DEVICE_TYPES"'); + } + const state = store.getState(); - const deviceType = - state.deviceType != null ? state.deviceType : state.deviceTypes[0]; - return Observable.merge( - Observable.of(Actions.setDeviceType(deviceType)), - Observable.of(Actions.toggleDevicePolling(state.isPollingDevices)), - ); + const deviceType = state.deviceType != null ? state.deviceType : state.deviceTypes[0]; + return _rxjsBundlesRxMinJs.Observable.merge(_rxjsBundlesRxMinJs.Observable.of((_Actions || _load_Actions()).setDeviceType(deviceType)), _rxjsBundlesRxMinJs.Observable.of((_Actions || _load_Actions()).toggleDevicePolling(state.isPollingDevices))); }); } -const deviceTypeTaskCache = new SimpleCache({ - keyFactory: ([state: AppState, providerName: string]) => - JSON.stringify([state.host, state.deviceType, providerName]), +const deviceTypeTaskCache = new (_SimpleCache || _load_SimpleCache()).SimpleCache({ + keyFactory: ([state, providerName]) => JSON.stringify([state.host, state.deviceType, providerName]) }); -export function setDeviceTypeEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions.ofType(Actions.SET_DEVICE_TYPE).switchMap(action => { +function setDeviceTypeEpic(actions, store) { + return actions.ofType((_Actions || _load_Actions()).SET_DEVICE_TYPE).switchMap(action => { const state = store.getState(); - return Observable.of( - Array.from(getProviders().deviceTypeTask) - .filter(provider => provider.getType() === state.deviceType) - .map(provider => - deviceTypeTaskCache.getOrCreate( - [state, provider.getName()], - () => - new DeviceTask( - () => provider.getTask(state.host), - provider.getName(), - ), - ), - ), - ).map(tasks => - Actions.setDeviceTypeTasks( - tasks.sort((a, b) => a.getName().localeCompare(b.getName())), - ), - ); + return _rxjsBundlesRxMinJs.Observable.of(Array.from((0, (_providers || _load_providers()).getProviders)().deviceTypeTask).filter(provider => provider.getType() === state.deviceType).map(provider => deviceTypeTaskCache.getOrCreate([state, provider.getName()], () => new (_DeviceTask || _load_DeviceTask()).DeviceTask(() => provider.getTask(state.host), provider.getName())))).map(tasks => (_Actions || _load_Actions()).setDeviceTypeTasks(tasks.sort((a, b) => a.getName().localeCompare(b.getName())))); }); } -export function setProcessesEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions.ofType(Actions.SET_PROCESSES).switchMap(action => { +function setProcessesEpic(actions, store) { + return actions.ofType((_Actions || _load_Actions()).SET_PROCESSES).switchMap(action => { const state = store.getState(); - return getProcessTasks(state).switchMap(processTasks => - Observable.of(Actions.setProcessTasks(processTasks)), - ); + return getProcessTasks(state).switchMap(processTasks => _rxjsBundlesRxMinJs.Observable.of((_Actions || _load_Actions()).setProcessTasks(processTasks))); }); } -export function setAppInfoEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return observeProcessNamesOfInterest(actions, store) - .switchMap(processNames => { - const {device, host} = store.getState(); - if (device == null || processNames.length === 0) { - return Observable.of(new Map()); - } - const providers = Array.from(getProviders().appInfo); - return observeAppInfoTables(processNames, providers, host, device); - }) - .map(appInfoTables => Actions.setAppInfoTables(appInfoTables)); +function setAppInfoEpic(actions, store) { + return observeProcessNamesOfInterest(actions, store).switchMap(processNames => { + const { device, host } = store.getState(); + if (device == null || processNames.length === 0) { + return _rxjsBundlesRxMinJs.Observable.of(new Map()); + } + const providers = Array.from((0, (_providers || _load_providers()).getProviders)().appInfo); + return observeAppInfoTables(processNames, providers, host, device); + }).map(appInfoTables => (_Actions || _load_Actions()).setAppInfoTables(appInfoTables)); } -export function setDeviceTypeComponentsEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions.ofType(Actions.SET_DEVICE_TYPE).switchMap(action => { - invariant(action.type === Actions.SET_DEVICE_TYPE); - const {deviceType} = action.payload; - const {host} = store.getState(); +function setDeviceTypeComponentsEpic(actions, store) { + return actions.ofType((_Actions || _load_Actions()).SET_DEVICE_TYPE).switchMap(action => { + if (!(action.type === (_Actions || _load_Actions()).SET_DEVICE_TYPE)) { + throw new Error('Invariant violation: "action.type === Actions.SET_DEVICE_TYPE"'); + } + + const { deviceType } = action.payload; + const { host } = store.getState(); if (deviceType == null) { - return Observable.empty(); + return _rxjsBundlesRxMinJs.Observable.empty(); } - const providers = Array.from(getProviders().deviceTypeComponent).filter( - provider => provider.getType() === deviceType, - ); + const providers = Array.from((0, (_providers || _load_providers()).getProviders)().deviceTypeComponent).filter(provider => provider.getType() === deviceType); if (providers.length === 0) { - return Observable.empty(); + return _rxjsBundlesRxMinJs.Observable.empty(); } - const combinedComponents: Observable< - Array, - > = Observable.from( - providers.map(provider => - Observable.create(observer => { - const disposable = provider.observe(host, component => { - observer.next(component); - }); - return () => { - disposable.dispose(); - }; - }) - .startWith(null) - .catch(e => { - log4js.getLogger().error(e); - return Observable.of(null); - }), - ), - // $FlowFixMe add combineAll to flow + const combinedComponents = _rxjsBundlesRxMinJs.Observable.from(providers.map(provider => _rxjsBundlesRxMinJs.Observable.create(observer => { + const disposable = provider.observe(host, component => { + observer.next(component); + }); + return () => { + disposable.dispose(); + }; + }).startWith(null).catch(e => { + (_log4js || _load_log4js()).default.getLogger().error(e); + return _rxjsBundlesRxMinJs.Observable.of(null); + })) + // $FlowFixMe add combineAll to flow ).combineAll(); - const groupedComponents = combinedComponents.map(components => - Immutable.List(components) - .filter(c => c != null) - .map(c => { - invariant(c != null); - return c; - }) - .groupBy(c => c.position), - ); - - return groupedComponents.map(value => - Actions.setDeviceTypeComponents(Immutable.Map(value)), - ); + const groupedComponents = combinedComponents.map(components => (_immutable || _load_immutable()).List(components).filter(c => c != null).map(c => { + if (!(c != null)) { + throw new Error('Invariant violation: "c != null"'); + } + + return c; + }).groupBy(c => c.position)); + + return groupedComponents.map(value => (_Actions || _load_Actions()).setDeviceTypeComponents((_immutable || _load_immutable()).Map(value))); }); } -function uniqueArray(array: Array): Array { +function uniqueArray(array) { return Array.from(new Set(array)); } @@ -260,25 +232,13 @@ function uniqueArray(array: Array): Array { // are needed by the AppInfo providers are observed. A new value is produced // every time the list of process names changes (a new process started running // or a running process was shut down). -function observeProcessNamesOfInterest( - actions: ActionsObservable, - store: Store, -): Observable> { - return actions - .ofType(Actions.SET_PROCESSES) - .map(action => { - const providers = Array.from(getProviders().appInfo); - const processNamesOfInterest = new Set( - providers.map(provider => provider.getProcessName()), - ); - const processes = store.getState().processes.getOrDefault([]); - return uniqueArray( - processes - .filter(process => processNamesOfInterest.has(process.name)) - .map(process => process.name), - ); - }) - .distinctUntilChanged(arrayEqual); +function observeProcessNamesOfInterest(actions, store) { + return actions.ofType((_Actions || _load_Actions()).SET_PROCESSES).map(action => { + const providers = Array.from((0, (_providers || _load_providers()).getProviders)().appInfo); + const processNamesOfInterest = new Set(providers.map(provider => provider.getProcessName())); + const processes = store.getState().processes.getOrDefault([]); + return uniqueArray(processes.filter(process => processNamesOfInterest.has(process.name)).map(process => process.name)); + }).distinctUntilChanged((_collection || _load_collection()).arrayEqual); } // Given a list of process names and providers it returns an observable for a @@ -287,180 +247,104 @@ function observeProcessNamesOfInterest( // AppInfoRow contains the values observed on each provider for the // corresponding application name. // This observable only emits a value when any of value is changed. -function observeAppInfoTables( - processNames: Array, - providers: Array, - host: string, - device: DeviceIdType, -): Observable>> { +function observeAppInfoTables(processNames, providers, host, device) { const observables = processNames.map(processName => { - const providersForProcess = providers.filter( - provider => provider.getProcessName() === processName, - ); + const providersForProcess = providers.filter(provider => provider.getProcessName() === processName); return observeAppInfoTable(providersForProcess, host, device); }); const resultSelector = (...multipleAppInfoRows) => - // Creates a Map that groups by all appInfoRow by appName: - // Map> - collect( - arrayFlatten(multipleAppInfoRows).map(appInfoRow => [ - appInfoRow.appName, - appInfoRow, - ]), - ); + // Creates a Map that groups by all appInfoRow by appName: + // Map> + (0, (_collection || _load_collection()).collect)((0, (_collection || _load_collection()).arrayFlatten)(multipleAppInfoRows).map(appInfoRow => [appInfoRow.appName, appInfoRow])); // $FlowFixMe - combineLatest type spec doesn't support spread operator. - return Observable.combineLatest(...observables, resultSelector); + return _rxjsBundlesRxMinJs.Observable.combineLatest(...observables, resultSelector); } -function observeAppInfoTable( - tableProviders: Array, - host: string, - device: DeviceIdType, -): Observable> { - return observeAppInfoProviderValues(tableProviders, host, device).map( - values => { - return tableProviders.map((provider, index) => ({ - appName: provider.getAppName(), - name: provider.getName(), - ...values[index], // {value, isError?} - canUpdate: provider.canUpdate(), - update: provider.update, - })); - }, - ); +function observeAppInfoTable(tableProviders, host, device) { + return observeAppInfoProviderValues(tableProviders, host, device).map(values => { + return tableProviders.map((provider, index) => Object.assign({ + appName: provider.getAppName(), + name: provider.getName() + }, values[index], { // {value, isError?} + canUpdate: provider.canUpdate(), + update: provider.update + })); + }); } // Given an array of providers it subscribes to the values of all of them. It // returns an observer to an array of all the produced values from the // providers. A new array is produced every time any of values changes. const APP_INFO_UPDATE_INTERVAL = 3000; -function observeAppInfoProviderValues( - providers: Array, - host: string, - device: DeviceIdType, -): Observable> { - const observables = providers.map(provider => - Observable.timer(0, APP_INFO_UPDATE_INTERVAL) - .switchMap(() => { - return provider - .observe(host, device) - .map(value => ({value})) - .catch(error => Observable.of({value: error.message, isError: true})); - }) - .distinctUntilChanged(shallowEqual) - .do(item => { - if (item.isError) { - track(AnalyticsActions.APPINFOTABLES_DATA_ERROR, item); - } else { - track(AnalyticsActions.APPINFOTABLES_DATA_VALUE, item); - } - }), - ); +function observeAppInfoProviderValues(providers, host, device) { + const observables = providers.map(provider => _rxjsBundlesRxMinJs.Observable.timer(0, APP_INFO_UPDATE_INTERVAL).switchMap(() => { + return provider.observe(host, device).map(value => ({ value })).catch(error => _rxjsBundlesRxMinJs.Observable.of({ value: error.message, isError: true })); + }).distinctUntilChanged((_shallowequal || _load_shallowequal()).default).do(item => { + if (item.isError) { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)((_constants || _load_constants()).AnalyticsActions.APPINFOTABLES_DATA_ERROR, item); + } else { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)((_constants || _load_constants()).AnalyticsActions.APPINFOTABLES_DATA_VALUE, item); + } + })); // $FlowFixMe - combineLatest type spec doesn't support spread operator. - return Observable.combineLatest(...observables); + return _rxjsBundlesRxMinJs.Observable.combineLatest(...observables); } -function getInfoTables( - state: AppState, -): Observable>> { +function getInfoTables(state) { const device = state.device; if (device == null) { - return Observable.of(new Map()); + return _rxjsBundlesRxMinJs.Observable.of(new Map()); } - return Observable.merge( - ...Array.from(getProviders().deviceInfo) - .filter(provider => provider.getType() === state.deviceType) - .map(provider => { - return provider - .isSupported(state.host) - .switchMap(isSupported => { - if (!isSupported) { - return Observable.empty(); - } - return provider.fetch(state.host, device).map(list => ({ - title: provider.getTitle(), - list, - priority: - provider.getPriority === undefined - ? -1 - : provider.getPriority(), - })); - }) - .catch(() => Observable.empty()); - }), - ) - .toArray() - .map(infoTables => - infoTables - .sort((a, b) => b.priority - a.priority) - .map(table => [table.title, table.list]), - ) - .map(infoTables => new Map(infoTables)); + return _rxjsBundlesRxMinJs.Observable.merge(...Array.from((0, (_providers || _load_providers()).getProviders)().deviceInfo).filter(provider => provider.getType() === state.deviceType).map(provider => { + return provider.isSupported(state.host).switchMap(isSupported => { + if (!isSupported) { + return _rxjsBundlesRxMinJs.Observable.empty(); + } + return provider.fetch(state.host, device).map(list => ({ + title: provider.getTitle(), + list, + priority: provider.getPriority === undefined ? -1 : provider.getPriority() + })); + }).catch(() => _rxjsBundlesRxMinJs.Observable.empty()); + })).toArray().map(infoTables => infoTables.sort((a, b) => b.priority - a.priority).map(table => [table.title, table.list])).map(infoTables => new Map(infoTables)); } -function getProcessTasks(state: AppState): Observable { +function getProcessTasks(state) { const device = state.device; if (device == null) { - return Observable.of([]); + return _rxjsBundlesRxMinJs.Observable.of([]); } - return Observable.merge( - ...Array.from(getProviders().processTask) - .filter(provider => provider.getType() === state.deviceType) - .map(provider => { - const processes = state.processes.isError ? [] : state.processes.value; - return provider - .getSupportedPIDs(state.host, device, processes) - .map(supportedSet => { - return { - type: provider.getTaskType(), - run: (proc: Process) => provider.run(state.host, device, proc), - isSupported: (proc: Process) => supportedSet.has(proc.pid), - name: provider.getName(), - }; - }); - }), - ).toArray(); + return _rxjsBundlesRxMinJs.Observable.merge(...Array.from((0, (_providers || _load_providers()).getProviders)().processTask).filter(provider => provider.getType() === state.deviceType).map(provider => { + const processes = state.processes.isError ? [] : state.processes.value; + return provider.getSupportedPIDs(state.host, device, processes).map(supportedSet => { + return { + type: provider.getTaskType(), + run: proc => provider.run(state.host, device, proc), + isSupported: proc => supportedSet.has(proc.pid), + name: provider.getName() + }; + }); + })).toArray(); } // The actual device tasks are cached so that if a task is running when the store switches back and // forth from the device associated with that task, the same running task is used -const deviceTaskCache = new SimpleCache({ - keyFactory: ([state: AppState, providerName: string]) => - JSON.stringify([state.host, state.deviceType, providerName]), +const deviceTaskCache = new (_SimpleCache || _load_SimpleCache()).SimpleCache({ + keyFactory: ([state, providerName]) => JSON.stringify([state.host, state.deviceType, providerName]) }); -function getDeviceTasks(state: AppState): Observable { +function getDeviceTasks(state) { const device = state.device; if (device == null) { - return Observable.of([]); + return _rxjsBundlesRxMinJs.Observable.of([]); } - return Observable.merge( - ...Array.from(getProviders().deviceTask) - .filter(provider => provider.getType() === state.deviceType) - .map(provider => { - return provider - .isSupported(state.host) - .switchMap(isSupported => { - if (!isSupported) { - return Observable.empty(); - } - return Observable.of( - deviceTaskCache.getOrCreate( - [state, provider.getName()], - () => - new DeviceTask( - () => provider.getTask(state.host, device), - provider.getName(), - ), - ), - ); - }) - .catch(() => Observable.empty()); - }), - ) - .toArray() - .map(actions => - actions.sort((a, b) => a.getName().localeCompare(b.getName())), - ); -} + return _rxjsBundlesRxMinJs.Observable.merge(...Array.from((0, (_providers || _load_providers()).getProviders)().deviceTask).filter(provider => provider.getType() === state.deviceType).map(provider => { + return provider.isSupported(state.host).switchMap(isSupported => { + if (!isSupported) { + return _rxjsBundlesRxMinJs.Observable.empty(); + } + return _rxjsBundlesRxMinJs.Observable.of(deviceTaskCache.getOrCreate([state, provider.getName()], () => new (_DeviceTask || _load_DeviceTask()).DeviceTask(() => provider.getTask(state.host, device), provider.getName()))); + }).catch(() => _rxjsBundlesRxMinJs.Observable.empty()); + })).toArray().map(actions => actions.sort((a, b) => a.getName().localeCompare(b.getName()))); +} \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/redux/Reducers.js b/pkg/nuclide-device-panel/lib/redux/Reducers.js index 0cada8c73e..96b7b3191f 100644 --- a/pkg/nuclide-device-panel/lib/redux/Reducers.js +++ b/pkg/nuclide-device-panel/lib/redux/Reducers.js @@ -1,3 +1,30 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.app = app; + +var _Actions; + +function _load_Actions() { + return _Actions = _interopRequireWildcard(require('./Actions')); +} + +var _immutable; + +function _load_immutable() { + return _immutable = _interopRequireWildcard(require('immutable')); +} + +var _expected; + +function _load_expected() { + return _expected = require('../../../../modules/nuclide-commons/expected'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,148 +32,123 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {Action, AppState} from '../types'; -import type {Device} from 'nuclide-debugger-common/types'; -import type {Expected} from 'nuclide-commons/expected'; - -import * as Actions from './Actions'; -import * as Immutable from 'immutable'; -import {Expect} from 'nuclide-commons/expected'; - -export function app(state: AppState, action: Action): AppState { +function app(state, action) { switch (action.type) { - case Actions.SET_HOST: - const {host} = action.payload; - return { - ...state, + case (_Actions || _load_Actions()).SET_HOST: + const { host } = action.payload; + return Object.assign({}, state, { device: null, - devices: Expect.pendingValue([]), - infoTables: Expect.pendingValue(new Map()), - processes: Expect.pendingValue([]), + devices: (_expected || _load_expected()).Expect.pendingValue([]), + infoTables: (_expected || _load_expected()).Expect.pendingValue(new Map()), + processes: (_expected || _load_expected()).Expect.pendingValue([]), actions: [], processTasks: [], - deviceTypeComponents: Immutable.Map(), + deviceTypeComponents: (_immutable || _load_immutable()).Map(), isDeviceConnected: false, - host, - }; + host + }); - case Actions.SET_DEVICE_TYPE: - const {deviceType} = action.payload; + case (_Actions || _load_Actions()).SET_DEVICE_TYPE: + const { deviceType } = action.payload; if (deviceType === state.deviceType) { return state; } - return { - ...state, + return Object.assign({}, state, { deviceType, device: null, - devices: Expect.pendingValue([]), - infoTables: Expect.pendingValue(new Map()), - processes: Expect.pendingValue([]), + devices: (_expected || _load_expected()).Expect.pendingValue([]), + infoTables: (_expected || _load_expected()).Expect.pendingValue(new Map()), + processes: (_expected || _load_expected()).Expect.pendingValue([]), actions: [], processTasks: [], - deviceTypeComponents: Immutable.Map(), - isDeviceConnected: false, - }; - - case Actions.SET_DEVICE_TYPES: - const {deviceTypes} = action.payload; - return { - ...state, - deviceTypes, - }; - - case Actions.SET_DEVICE: - const {device} = action.payload; - return { - ...state, + deviceTypeComponents: (_immutable || _load_immutable()).Map(), + isDeviceConnected: false + }); + + case (_Actions || _load_Actions()).SET_DEVICE_TYPES: + const { deviceTypes } = action.payload; + return Object.assign({}, state, { + deviceTypes + }); + + case (_Actions || _load_Actions()).SET_DEVICE: + const { device } = action.payload; + return Object.assign({}, state, { device, - isDeviceConnected: isDeviceConnected(device, state.devices), - }; + isDeviceConnected: isDeviceConnected(device, state.devices) + }); - case Actions.SET_DEVICES: - const {devices} = action.payload; - return { - ...state, + case (_Actions || _load_Actions()).SET_DEVICES: + const { devices } = action.payload; + return Object.assign({}, state, { devices, - isDeviceConnected: isDeviceConnected(state.device, devices), - }; - - case Actions.SET_INFO_TABLES: - const {infoTables} = action.payload; - return { - ...state, - infoTables: Expect.value(infoTables), - }; - - case Actions.SET_APP_INFO_TABLES: - const {appInfoTables} = action.payload; - return { - ...state, - appInfoTables: Expect.value(appInfoTables), - }; - - case Actions.SET_PROCESSES: - const {processes} = action.payload; - return { - ...state, - processes: Expect.value(processes), - }; - - case Actions.SET_PROCESS_TASKS: - const {processTasks} = action.payload; - return { - ...state, - processTasks, - }; - - case Actions.SET_HOSTS: - const {hosts} = action.payload; - return { - ...state, - hosts, - }; - - case Actions.SET_DEVICE_TASKS: - const {deviceTasks} = action.payload; - return { - ...state, - deviceTasks, - }; - - case Actions.SET_DEVICE_TYPE_TASKS: - const {deviceTypeTasks} = action.payload; - return { - ...state, - deviceTypeTasks, - }; - - case Actions.SET_DEVICE_TYPE_COMPONENTS: + isDeviceConnected: isDeviceConnected(state.device, devices) + }); + + case (_Actions || _load_Actions()).SET_INFO_TABLES: + const { infoTables } = action.payload; + return Object.assign({}, state, { + infoTables: (_expected || _load_expected()).Expect.value(infoTables) + }); + + case (_Actions || _load_Actions()).SET_APP_INFO_TABLES: + const { appInfoTables } = action.payload; + return Object.assign({}, state, { + appInfoTables: (_expected || _load_expected()).Expect.value(appInfoTables) + }); + + case (_Actions || _load_Actions()).SET_PROCESSES: + const { processes } = action.payload; + return Object.assign({}, state, { + processes: (_expected || _load_expected()).Expect.value(processes) + }); + + case (_Actions || _load_Actions()).SET_PROCESS_TASKS: + const { processTasks } = action.payload; + return Object.assign({}, state, { + processTasks + }); + + case (_Actions || _load_Actions()).SET_HOSTS: + const { hosts } = action.payload; + return Object.assign({}, state, { + hosts + }); + + case (_Actions || _load_Actions()).SET_DEVICE_TASKS: + const { deviceTasks } = action.payload; + return Object.assign({}, state, { + deviceTasks + }); + + case (_Actions || _load_Actions()).SET_DEVICE_TYPE_TASKS: + const { deviceTypeTasks } = action.payload; + return Object.assign({}, state, { + deviceTypeTasks + }); + + case (_Actions || _load_Actions()).SET_DEVICE_TYPE_COMPONENTS: const deviceTypeComponents = action.payload.components; - return { - ...state, - deviceTypeComponents, - }; - - case Actions.TOGGLE_DEVICE_POLLING: - const {isActive} = action.payload; - return { - ...state, - isPollingDevices: isActive, - }; + return Object.assign({}, state, { + deviceTypeComponents + }); + + case (_Actions || _load_Actions()).TOGGLE_DEVICE_POLLING: + const { isActive } = action.payload; + return Object.assign({}, state, { + isPollingDevices: isActive + }); default: return state; } } -function isDeviceConnected( - device: ?Device, - deviceList: Expected, -): boolean { +function isDeviceConnected(device, deviceList) { if (device == null || deviceList.isError) { return false; } @@ -156,4 +158,4 @@ function isDeviceConnected( } } return false; -} +} \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/redux/createEmptyAppState.js b/pkg/nuclide-device-panel/lib/redux/createEmptyAppState.js index 3180e137b1..fc31d3dc61 100644 --- a/pkg/nuclide-device-panel/lib/redux/createEmptyAppState.js +++ b/pkg/nuclide-device-panel/lib/redux/createEmptyAppState.js @@ -1,36 +1,50 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {AppState} from '../types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.createEmptyAppState = createEmptyAppState; -import {Expect} from 'nuclide-commons/expected'; -import * as Immutable from 'immutable'; +var _expected; -export function createEmptyAppState(): AppState { +function _load_expected() { + return _expected = require('../../../../modules/nuclide-commons/expected'); +} + +var _immutable; + +function _load_immutable() { + return _immutable = _interopRequireWildcard(require('immutable')); +} + +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 createEmptyAppState() { return { hosts: [''], host: '', - devices: Expect.pendingValue([]), + devices: (_expected || _load_expected()).Expect.pendingValue([]), deviceType: null, deviceTypes: [], device: null, deviceTasks: [], - infoTables: Expect.pendingValue(new Map()), - appInfoTables: Expect.pendingValue(new Map()), - processes: Expect.pendingValue([]), + infoTables: (_expected || _load_expected()).Expect.pendingValue(new Map()), + appInfoTables: (_expected || _load_expected()).Expect.pendingValue(new Map()), + processes: (_expected || _load_expected()).Expect.pendingValue([]), processTasks: [], isDeviceConnected: false, supportedPidsPerTask: new Map(), deviceTypeTasks: [], isPollingDevices: false, - deviceTypeComponents: Immutable.Map(), + deviceTypeComponents: (_immutable || _load_immutable()).Map() }; -} +} /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/types.js b/pkg/nuclide-device-panel/lib/types.js index 0e0c788854..5b486b13c4 100644 --- a/pkg/nuclide-device-panel/lib/types.js +++ b/pkg/nuclide-device-panel/lib/types.js @@ -1,183 +1,9 @@ -/** - * 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 - */ +'use strict'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {Expected} from 'nuclide-commons/expected'; -import type { - Process, - Device, - AppInfoRow, - ProcessTask, - IDeviceTask, - ComponentPosition, - DeviceTypeComponent, -} from 'nuclide-debugger-common/types'; +var _immutable; -import * as Immutable from 'immutable'; +function _load_immutable() { + return _immutable = _interopRequireWildcard(require('immutable')); +} -// -// Store -// - -export type AppState = { - hosts: NuclideUri[], - host: NuclideUri, - devices: Expected, - deviceType: ?string, - deviceTypes: string[], - device: ?Device, - infoTables: Expected>>, - appInfoTables: Expected>>, - processes: Expected, - processTasks: ProcessTask[], - deviceTasks: IDeviceTask[], - isDeviceConnected: boolean, - deviceTypeTasks: IDeviceTask[], - isPollingDevices: boolean, - deviceTypeComponents: Immutable.Map< - ComponentPosition, - Immutable.List, - >, -}; - -export type Store = { - getState(): AppState, - dispatch(action: Action): void, -}; - -// -// Action types -// - -export type SetDevicesAction = { - type: 'SET_DEVICES', - payload: { - devices: Expected, - }, -}; - -export type SetHostsAction = { - type: 'SET_HOSTS', - payload: { - hosts: NuclideUri[], - }, -}; - -export type SetHostAction = { - type: 'SET_HOST', - payload: { - host: NuclideUri, - }, -}; - -export type SetDeviceTypeAction = { - type: 'SET_DEVICE_TYPE', - payload: { - deviceType: ?string, - }, -}; - -export type SetDeviceTypesAction = { - type: 'SET_DEVICE_TYPES', - payload: { - deviceTypes: string[], - }, -}; - -export type SetDeviceAction = { - type: 'SET_DEVICE', - payload: { - device: ?Device, - }, -}; - -export type SetInfoTablesAction = { - type: 'SET_INFO_TABLES', - payload: { - infoTables: Map>, - }, -}; - -export type SetAppInfoTablesAction = { - type: 'SET_APP_INFO_TABLES', - payload: { - appInfoTables: Map>, - }, -}; - -export type SetProcessesAction = { - type: 'SET_PROCESSES', - payload: { - processes: Process[], - }, -}; - -export type SetProcessTasksAction = { - type: 'SET_PROCESS_TASKS', - payload: { - processTasks: ProcessTask[], - }, -}; - -export type SetDeviceTasksAction = { - type: 'SET_DEVICE_TASKS', - payload: { - deviceTasks: IDeviceTask[], - }, -}; - -export type ToggleDevicePollingAction = { - type: 'TOGGLE_DEVICE_POLLING', - payload: { - isActive: boolean, - }, -}; - -export type ToggleProcessPollingAction = { - type: 'TOGGLE_PROCESS_POLLING', - payload: { - isActive: boolean, - }, -}; - -export type SetDeviceTypeTasksAction = { - type: 'SET_DEVICE_TYPE_TASKS', - payload: { - deviceTypeTasks: IDeviceTask[], - }, -}; - -export type SetDeviceTypeComponentsAction = { - type: 'SET_DEVICE_TYPE_COMPONENTS', - payload: { - components: Immutable.Map< - ComponentPosition, - Immutable.List, - >, - }, -}; - -export type Action = - | ToggleDevicePollingAction - | ToggleProcessPollingAction - | SetHostAction - | SetHostsAction - | SetDevicesAction - | SetDeviceTypeAction - | SetDeviceTypesAction - | SetInfoTablesAction - | SetAppInfoTablesAction - | SetProcessesAction - | SetProcessTasksAction - | SetDeviceTasksAction - | SetDeviceTypeTasksAction - | SetDeviceAction - | SetDeviceTypeComponentsAction; +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/pkg/nuclide-device-panel/lib/ui/AppInfoTable.js b/pkg/nuclide-device-panel/lib/ui/AppInfoTable.js index 0ac8343010..e360c5c55f 100644 --- a/pkg/nuclide-device-panel/lib/ui/AppInfoTable.js +++ b/pkg/nuclide-device-panel/lib/ui/AppInfoTable.js @@ -1,3 +1,38 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AppInfoTable = undefined; + +var _react = _interopRequireWildcard(require('react')); + +var _Table; + +function _load_Table() { + return _Table = require('../../../../modules/nuclide-commons-ui/Table'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../../nuclide-analytics'); +} + +var _constants; + +function _load_constants() { + return _constants = require('../constants'); +} + +var _AppInfoValueCell; + +function _load_AppInfoValueCell() { + return _AppInfoValueCell = require('./AppInfoValueCell'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,65 +40,54 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {AppInfoRow} from 'nuclide-debugger-common/types'; - -import * as React from 'react'; -import {Table} from 'nuclide-commons-ui/Table'; -import {track} from '../../../nuclide-analytics'; -import {AnalyticsActions} from '../constants'; -import {AppInfoValueCell} from './AppInfoValueCell'; - -type Props = { - title: string, - rows: Array, -}; - -export class AppInfoTable extends React.PureComponent { +class AppInfoTable extends _react.PureComponent { componentDidMount() { - track(AnalyticsActions.APPINFOTABLES_UI_MOUNT, { - rows: this.props.rows.map(row => row.name), + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)((_constants || _load_constants()).AnalyticsActions.APPINFOTABLES_UI_MOUNT, { + rows: this.props.rows.map(row => row.name) }); } componentWillUnmount() { - track(AnalyticsActions.APPINFOTABLES_UI_UNMOUNT); + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)((_constants || _load_constants()).AnalyticsActions.APPINFOTABLES_UI_UNMOUNT); } - render(): React.Node { + render() { const rows = this.props.rows.map(row => ({ - data: {property: row.name, rowData: row}, + data: { property: row.name, rowData: row } })); - const columns = [ - { - key: 'property', - title: 'Property', - width: 0.4, - }, - { - component: AppInfoValueCell, - key: 'rowData', - title: 'Value', - width: 0.6, - }, - ]; - const emptyComponent = () =>
    No information
    ; - - return ( -
    -
    - + const columns = [{ + key: 'property', + title: 'Property', + width: 0.4 + }, { + component: (_AppInfoValueCell || _load_AppInfoValueCell()).AppInfoValueCell, + key: 'rowData', + title: 'Value', + width: 0.6 + }]; + const emptyComponent = () => _react.createElement( + 'div', + { className: 'padded' }, + 'No information' + ); + + return _react.createElement( + 'div', + null, + _react.createElement((_Table || _load_Table()).Table, { + collapsable: false, + columns: columns, + maxBodyHeight: '99999px', + emptyComponent: emptyComponent, + rows: rows, + headerTitle: this.props.title, + enableKeyboardNavigation: true + }) ); } } +exports.AppInfoTable = AppInfoTable; \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/ui/AppInfoValueCell.js b/pkg/nuclide-device-panel/lib/ui/AppInfoValueCell.js index 39cc4bc869..614f2b4d4f 100644 --- a/pkg/nuclide-device-panel/lib/ui/AppInfoValueCell.js +++ b/pkg/nuclide-device-panel/lib/ui/AppInfoValueCell.js @@ -1,3 +1,46 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AppInfoValueCell = undefined; + +var _addTooltip; + +function _load_addTooltip() { + return _addTooltip = _interopRequireDefault(require('../../../../modules/nuclide-commons-ui/addTooltip')); +} + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../../../../modules/nuclide-commons-ui/AtomInput'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _classnames; + +function _load_classnames() { + return _classnames = _interopRequireDefault(require('classnames')); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../../nuclide-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 }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,97 +48,59 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import addTooltip from 'nuclide-commons-ui/addTooltip'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import * as React from 'react'; -import classnames from 'classnames'; -import {track} from '../../../nuclide-analytics'; -import {AnalyticsActions} from '../constants'; - const MAX_ERROR_LINE_LENGTH = 80; const MAX_NUMBER_ERROR_LINES = 10; const UPDATED_DELAY = 1000; -type Props = { - data: { - value: string, - isError?: boolean, - canUpdate?: boolean, - update?: (value: string) => Promise, - }, -}; - -type EditingState = 'none' | 'editing' | 'syncing' | 'updated' | 'error'; - -type State = { - value: string, - editingState: EditingState, - editingValue: ?string, -}; - -export class AppInfoValueCell extends React.PureComponent { - constructor(props: Props) { +class AppInfoValueCell extends _react.PureComponent { + constructor(props) { super(props); this.state = { value: props.data.value, editingState: 'none', - editingValue: null, + editingValue: null }; } - componentWillReceiveProps(nextProps: Props) { + componentWillReceiveProps(nextProps) { if (this.state.editingState === 'none') { - this.setState({value: nextProps.data.value}); + this.setState({ value: nextProps.data.value }); } } - _updateValue(newValue: string): Promise { - const updateFunction = - this.props.data.update || (value => Promise.resolve()); + _updateValue(newValue) { + const updateFunction = this.props.data.update || (value => Promise.resolve()); this._setEditingState('syncing'); - return updateFunction(newValue) - .catch(error => { - this._setEditingState('error'); - }) - .then(() => { - this._setEditingState('syncing', {value: newValue}); - }) - .then(() => { - setTimeout( - () => this._setEditingState('none', {editingValue: null}), - UPDATED_DELAY, - ); - }); + return updateFunction(newValue).catch(error => { + this._setEditingState('error'); + }).then(() => { + this._setEditingState('syncing', { value: newValue }); + }).then(() => { + setTimeout(() => this._setEditingState('none', { editingValue: null }), UPDATED_DELAY); + }); } - _prepareErrorMessage(error: string): string { - return error - .split(/\n/g) - .filter(line => line.length > 0) - .map(line => line.slice(0, MAX_ERROR_LINE_LENGTH)) - .slice(0, MAX_NUMBER_ERROR_LINES) - .join('
    '); + _prepareErrorMessage(error) { + return error.split(/\n/g).filter(line => line.length > 0).map(line => line.slice(0, MAX_ERROR_LINE_LENGTH)).slice(0, MAX_NUMBER_ERROR_LINES).join('
    '); } - _renderError(error: string): React.Node { - return ( - - ); + _renderError(error) { + return _react.createElement('span', { + className: 'icon icon-alert' + // eslint-disable-next-line nuclide-internal/jsx-simple-callback-refs + , ref: (0, (_addTooltip || _load_addTooltip()).default)({ + title: this._prepareErrorMessage(error), + delay: 0 + }) + }); } - _getEditingStateIcon(editingState: EditingState): string { + _getEditingStateIcon(editingState) { switch (editingState) { case 'none': return 'pencil'; @@ -110,68 +115,59 @@ export class AppInfoValueCell extends React.PureComponent { } } - _setEditingState(editingState: EditingState, otherState?: $Supertype) { - const newState = {...otherState, editingState}; - track(AnalyticsActions.APPINFOVALUECELL_UI_EDITINGSTATECHANGE, newState); + _setEditingState(editingState, otherState) { + const newState = Object.assign({}, otherState, { editingState }); + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)((_constants || _load_constants()).AnalyticsActions.APPINFOVALUECELL_UI_EDITINGSTATECHANGE, newState); this.setState(newState); } - _renderEditableValue(value: any): React.Node { - const {editingState} = this.state; - const editingValue = - this.state.editingValue == null ? value : this.state.editingValue; + _renderEditableValue(value) { + const { editingState } = this.state; + const editingValue = this.state.editingValue == null ? value : this.state.editingValue; if (editingState === 'editing') { - return ( - this.setState({editingValue: newValue})} - onBlur={() => this._updateValue(editingValue)} - onConfirm={() => this._updateValue(editingValue)} - /> - ); + return _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + tabIndex: '-1', + autofocus: true, + size: 'sm', + defaultValue: value, + value: editingValue, + onDidChange: newValue => this.setState({ editingValue: newValue }), + onBlur: () => this._updateValue(editingValue), + onConfirm: () => this._updateValue(editingValue) + }); } else { - return ( -
    - {value} - { - if (this.state.editingState === 'none') { - this._setEditingState('editing'); - } - }} - /> -
    + return _react.createElement( + 'div', + null, + value, + _react.createElement('span', { + role: 'button', + tabIndex: '0', + className: (0, (_classnames || _load_classnames()).default)('icon', 'nuclide-device-panel-app-info-button', 'icon-' + this._getEditingStateIcon(this.state.editingState), { + 'nuclide-device-panel-app-info-button-edit': this.state.editingState === 'none' + }), + onClick: () => { + if (this.state.editingState === 'none') { + this._setEditingState('editing'); + } + } + }) ); } } - render(): React.Node { - const {canUpdate, isError} = this.props.data; - const {value} = this.state; + render() { + const { canUpdate, isError } = this.props.data; + const { value } = this.state; if (isError) { - track(AnalyticsActions.APPINFOVALUECELL_UI_ERROR); + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)((_constants || _load_constants()).AnalyticsActions.APPINFOVALUECELL_UI_ERROR); return this._renderError(value); } if (this.state.editingState === 'none') { - track(AnalyticsActions.APPINFOVALUECELL_UI_VALUE); + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)((_constants || _load_constants()).AnalyticsActions.APPINFOVALUECELL_UI_VALUE); } if (canUpdate) { @@ -181,3 +177,4 @@ export class AppInfoValueCell extends React.PureComponent { return value; } } +exports.AppInfoValueCell = AppInfoValueCell; \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/ui/DevicePanel.js b/pkg/nuclide-device-panel/lib/ui/DevicePanel.js index bfedef297c..20a0eb8eb5 100644 --- a/pkg/nuclide-device-panel/lib/ui/DevicePanel.js +++ b/pkg/nuclide-device-panel/lib/ui/DevicePanel.js @@ -1,3 +1,56 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DevicePanel = undefined; + +var _bindObservableAsProps; + +function _load_bindObservableAsProps() { + return _bindObservableAsProps = require('../../../../modules/nuclide-commons-ui/bindObservableAsProps'); +} + +var _Icon; + +function _load_Icon() { + return _Icon = require('../../../../modules/nuclide-commons-ui/Icon'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _AppInfoTable; + +function _load_AppInfoTable() { + return _AppInfoTable = require('./AppInfoTable'); +} + +var _InfoTable; + +function _load_InfoTable() { + return _InfoTable = require('./InfoTable'); +} + +var _ProcessTable; + +function _load_ProcessTable() { + return _ProcessTable = require('./ProcessTable'); +} + +var _TaskButton; + +function _load_TaskButton() { + return _TaskButton = require('./TaskButton'); +} + +var _LoadingSpinner; + +function _load_LoadingSpinner() { + return _LoadingSpinner = require('../../../../modules/nuclide-commons-ui/LoadingSpinner'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,168 +58,140 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {Expected} from 'nuclide-commons/expected'; -import type { - Process, - IDeviceTask, - ProcessTask, - AppInfoRow, -} from 'nuclide-debugger-common/types'; -import type {Props as TaskButtonPropsType} from './TaskButton'; -import type {TaskEvent} from 'nuclide-commons/process'; - -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import {Icon} from 'nuclide-commons-ui/Icon'; -import * as React from 'react'; -import {AppInfoTable} from './AppInfoTable'; -import {InfoTable} from './InfoTable'; -import {ProcessTable} from './ProcessTable'; -import {TaskButton} from './TaskButton'; -import {LoadingSpinner} from 'nuclide-commons-ui/LoadingSpinner'; - -type Props = {| - toggleProcessPolling: (isActive: boolean) => void, - goToRootPanel: () => void, - infoTables: Expected>>, - appInfoTables: Expected>>, - processes: Expected, - processTasks: ProcessTask[], - deviceTasks: IDeviceTask[], - isDeviceConnected: boolean, -|}; - -export class DevicePanel extends React.Component { - _createInfoTables(): React.Element[] { +class DevicePanel extends _react.Component { + _createInfoTables() { if (this.props.infoTables.isError) { - return [ -
    - { - // $FlowFixMe - this.props.infoTables.error - } -
    , - ]; + return [_react.createElement( + 'div', + { className: 'block', key: 'infoTableError' }, + + // $FlowFixMe + this.props.infoTables.error + )]; } else if (this.props.infoTables.isPending) { - return []; + return [_react.createElement((_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinner, { size: 'EXTRA_SMALL', key: 'infoTableLoading' })]; } else { - return Array.from(this.props.infoTables.value.entries()).map( - ([title, infoTable]) => ( -
    - -
    - ), - ); + return Array.from(this.props.infoTables.value.entries()).map(([title, infoTable]) => _react.createElement( + 'div', + { className: 'block', key: title }, + _react.createElement((_InfoTable || _load_InfoTable()).InfoTable, { title: title, table: infoTable }) + )); } } - _createAppInfoTables(): React.Element[] { + _createAppInfoTables() { const appInfoTables = this.props.appInfoTables; if (appInfoTables.isError) { - return [ -
    - { - // $FlowFixMe - appInfoTables.error - } -
    , - ]; + return [_react.createElement( + 'div', + { className: 'block', key: 'infoTableError' }, + + // $FlowFixMe + appInfoTables.error + )]; } else if (appInfoTables.isPending) { - return []; + return [_react.createElement((_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinner, { size: 'EXTRA_SMALL', key: 'infoTableLoading' })]; } else { - return Array.from(appInfoTables.value.entries()).map( - ([appName, appInfoRows]) => ( -
    - -
    - ), - ); + return Array.from(appInfoTables.value.entries()).map(([appName, appInfoRows]) => _react.createElement( + 'div', + { className: 'block', key: appName }, + _react.createElement((_AppInfoTable || _load_AppInfoTable()).AppInfoTable, { title: appName, rows: appInfoRows }) + )); } } - _createProcessTable(): React.Element { - return ( -
    - -
    + _createProcessTable() { + return _react.createElement( + 'div', + { className: 'block', key: 'process-table' }, + _react.createElement((_ProcessTable || _load_ProcessTable()).ProcessTable, { + processes: this.props.processes, + processTasks: this.props.processTasks, + toggleProcessPolling: this.props.toggleProcessPolling + }) ); } - _taskEventsToProps( - task: IDeviceTask, - taskEvent: ?TaskEvent, - ): TaskButtonPropsType { + _taskEventsToProps(task, taskEvent) { return { name: task.getName(), start: () => task.start(), cancel: () => task.cancel(), isRunning: taskEvent != null, - progress: null, + progress: null }; } - _getTasks(): React.Element { + _getTasks() { const tasks = Array.from(this.props.deviceTasks).map(task => { - const StreamedTaskButton = bindObservableAsProps( - task - .getTaskEvents() - .distinctUntilChanged() - .map(taskEvent => this._taskEventsToProps(task, taskEvent)), - TaskButton, - ); - return ; + const StreamedTaskButton = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)(task.getTaskEvents().distinctUntilChanged().map(taskEvent => this._taskEventsToProps(task, taskEvent)), (_TaskButton || _load_TaskButton()).TaskButton); + return _react.createElement(StreamedTaskButton, { key: task.getName() }); }); - return ( -
    {tasks}
    + return _react.createElement( + 'div', + { className: 'block nuclide-device-panel-tasks-container' }, + tasks ); } - _getBackButton(): React.Element { - return ( - + _getBackButton() { + return _react.createElement( + 'div', + { className: 'block' }, + _react.createElement( + 'span', + null, + _react.createElement( + 'a', + { + className: 'nuclide-device-panel-text-with-icon', + onClick: () => this.props.goToRootPanel() }, + _react.createElement( + (_Icon || _load_Icon()).Icon, + { icon: 'chevron-left' }, + 'Choose another device' + ) + ) + ) ); } - _getStatus(): ?React.Element { + _getStatus() { if (this.props.isDeviceConnected) { return null; } - return ( -
    - - Disconnected - -
    + return _react.createElement( + 'div', + { className: 'block' }, + _react.createElement( + 'span', + { className: 'nuclide-device-panel-text-with-icon nuclide-device-panel-disconnected-icon' }, + _react.createElement( + (_Icon || _load_Icon()).Icon, + { icon: 'primitive-dot' }, + 'Disconnected' + ) + ) ); } - render(): React.Node { - return ( -
    - {this._getBackButton()} - {this._getStatus()} - {this._getTasks()} - {this._createInfoTables()} - {this._createAppInfoTables()} - {this._createProcessTable()} -
    + render() { + return _react.createElement( + 'div', + null, + this._getBackButton(), + this._getStatus(), + this._getTasks(), + this._createInfoTables(), + this._createAppInfoTables(), + this._createProcessTable() ); } } +exports.DevicePanel = DevicePanel; \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/ui/DeviceTable.js b/pkg/nuclide-device-panel/lib/ui/DeviceTable.js index 4cb264a5e9..a89232b144 100644 --- a/pkg/nuclide-device-panel/lib/ui/DeviceTable.js +++ b/pkg/nuclide-device-panel/lib/ui/DeviceTable.js @@ -1,40 +1,76 @@ -/** - * 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 - */ - -import type { - Device, - DeviceAction, - DeviceActionProvider, -} from 'nuclide-debugger-common/types'; -import type {Expected} from 'nuclide-commons/expected'; - -import * as React from 'react'; -import {Table} from 'nuclide-commons-ui/Table'; -import {getProviders} from '../providers'; -import {DeviceTaskButton} from './DeviceTaskButton'; -import {LoadingSpinner} from 'nuclide-commons-ui/LoadingSpinner'; - -type Props = {| - setDevice: (?Device) => void, - devices: Expected, - // TODO Remove disable - // eslint-disable-next-line react/no-unused-prop-types - device: ?Device, -|}; - -export class DeviceTable extends React.Component { - _getActionsForDevice( - device: Device, - actionProviders: Set, - ): Array { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DeviceTable = undefined; + +var _react = _interopRequireWildcard(require('react')); + +var _Table; + +function _load_Table() { + return _Table = require('../../../../modules/nuclide-commons-ui/Table'); +} + +var _providers; + +function _load_providers() { + return _providers = require('../providers'); +} + +var _DeviceTaskButton; + +function _load_DeviceTaskButton() { + return _DeviceTaskButton = require('./DeviceTaskButton'); +} + +var _LoadingSpinner; + +function _load_LoadingSpinner() { + return _LoadingSpinner = require('../../../../modules/nuclide-commons-ui/LoadingSpinner'); +} + +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 DeviceTable extends _react.Component { + constructor(...args) { + var _temp; + + return _temp = super(...args), this._pendingComponent = () => { + return _react.createElement( + 'div', + { className: 'padded' }, + _react.createElement((_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinner, { size: 'EXTRA_SMALL' }) + ); + }, this._noDevicesComponent = () => { + return _react.createElement( + 'div', + { className: 'padded' }, + 'No devices connected' + ); + }, this._handleDeviceWillSelect = (item, selectedIndex, event) => { + if (event != null) { + let element = event.target; + while (element != null) { + if (element.classList.contains('nuclide-device-panel-device-action-button')) { + return false; + } + element = element.parentElement; + } + } + if (!this.props.devices.isError && this.props.devices.value[selectedIndex].ignoresSelection) { + return false; + } + return true; + }, this._handleDeviceTableSelection = (item, selectedDeviceIndex) => { + if (!this.props.devices.isError) { + this.props.setDevice(this.props.devices.value[selectedDeviceIndex]); + } + }, _temp; + } + + _getActionsForDevice(device, actionProviders) { const actions = []; for (const provider of actionProviders) { const deviceActions = provider.getActionsForDevice(device); @@ -45,70 +81,54 @@ export class DeviceTable extends React.Component { return actions; } - render(): React.Node { + render() { const devices = this.props.devices.getOrDefault([]); - const actionProviders = getProviders().deviceAction; - const anyActions = - devices.length > 0 && - devices.find( - device => this._getActionsForDevice(device, actionProviders).length > 0, - ) != null; + const actionProviders = (0, (_providers || _load_providers()).getProviders)().deviceAction; + const anyActions = devices.length > 0 && devices.find(device => this._getActionsForDevice(device, actionProviders).length > 0) != null; const rows = devices.map(_device => { const actions = this._getActionsForDevice(_device, actionProviders); return { data: { name: _device.displayName, - actions: - actions.length === 0 ? null : ( - - ), - }, + actions: actions.length === 0 ? null : _react.createElement((_DeviceTaskButton || _load_DeviceTaskButton()).DeviceTaskButton, { + actions: actions, + device: _device, + icon: 'device-mobile', + title: 'Device actions' + }) + } }; }); - const columns = anyActions - ? [ - { - key: 'name', - title: 'Devices', - width: 0.7, - }, - { - key: 'actions', - title: 'Actions', - width: 0.3, - }, - ] - : [ - { - key: 'name', - title: 'Devices', - width: 1.0, - }, - ]; - - return ( -
    - ); + const columns = anyActions ? [{ + key: 'name', + title: 'Devices', + width: 0.7 + }, { + key: 'actions', + title: 'Actions', + width: 0.3 + }] : [{ + key: 'name', + title: 'Devices', + width: 1.0 + }]; + + return _react.createElement((_Table || _load_Table()).Table, { + collapsable: false, + columns: columns, + fixedHeader: true, + maxBodyHeight: '99999px', + emptyComponent: this._getEmptyComponent(), + selectable: true, + onSelect: this._handleDeviceTableSelection, + onWillSelect: this._handleDeviceWillSelect, + rows: rows + }); } // Passes down identical stateless components so === for them works as expected - _getEmptyComponent(): () => React.Element { + _getEmptyComponent() { if (this.props.devices.isError) { return this._getErrorComponent(this.props.devices.error.message); } else if (this.props.devices.isPending) { @@ -118,65 +138,26 @@ export class DeviceTable extends React.Component { } } - _pendingComponent = (): React.Element => { - return ( -
    - -
    - ); - }; - - _noDevicesComponent = (): React.Element => { - return
    No devices connected
    ; - }; - - _lastErrorMessage: string; - _lastErrorComponent: () => React.Element; - _getErrorComponent(message: string): () => React.Element { + _getErrorComponent(message) { if (this._lastErrorMessage !== message) { this._lastErrorMessage = message; - this._lastErrorComponent = () => ( -
    - {message} -
    + this._lastErrorComponent = () => _react.createElement( + 'div', + { className: 'padded nuclide-device-panel-device-list-error' }, + message ); } return this._lastErrorComponent; } - _handleDeviceWillSelect = ( - item: any, - selectedIndex: number, - event: Event | SyntheticEvent<*>, - ): boolean => { - if (event != null) { - let element = ((event.target: any): HTMLElement); - while (element != null) { - if ( - element.classList.contains( - 'nuclide-device-panel-device-action-button', - ) - ) { - return false; - } - element = element.parentElement; - } - } - if ( - !this.props.devices.isError && - this.props.devices.value[selectedIndex].ignoresSelection - ) { - return false; - } - return true; - }; - - _handleDeviceTableSelection = ( - item: any, - selectedDeviceIndex: number, - ): void => { - if (!this.props.devices.isError) { - this.props.setDevice(this.props.devices.value[selectedDeviceIndex]); - } - }; } +exports.DeviceTable = DeviceTable; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/ui/DeviceTaskButton.js b/pkg/nuclide-device-panel/lib/ui/DeviceTaskButton.js index d37d7aa5dc..55d0021182 100644 --- a/pkg/nuclide-device-panel/lib/ui/DeviceTaskButton.js +++ b/pkg/nuclide-device-panel/lib/ui/DeviceTaskButton.js @@ -1,53 +1,57 @@ -/** - * 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 - */ - -import type {Device, DeviceAction} from 'nuclide-debugger-common/types'; -import type {IconName} from 'nuclide-commons-ui/Icon'; - -import {Dropdown} from 'nuclide-commons-ui/Dropdown'; -import * as React from 'react'; -import {Icon} from 'nuclide-commons-ui/Icon'; - -type Props = {| - actions: DeviceAction[], - device: Device, - icon: IconName, - title: string, -|}; - -export class DeviceTaskButton extends React.Component { - render(): React.Node { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DeviceTaskButton = undefined; + +var _Dropdown; + +function _load_Dropdown() { + return _Dropdown = require('../../../../modules/nuclide-commons-ui/Dropdown'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _Icon; + +function _load_Icon() { + return _Icon = require('../../../../modules/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; } } + +class DeviceTaskButton extends _react.Component { + render() { const options = this.props.actions; if (options.length === 0) { - return ; + return _react.createElement('span', null); } else { - const placeholder: any = ( - - ); - return ( -
    - ({ - value: option, - label: option.name, - }))} - placeholder={placeholder} - size="xs" - onChange={(action: DeviceAction) => - action != null && action.callback(this.props.device) - } - /> -
    + const placeholder = _react.createElement((_Icon || _load_Icon()).Icon, { icon: this.props.icon, title: this.props.title }); + return _react.createElement( + 'div', + { className: 'nuclide-device-panel-device-action-button' }, + _react.createElement((_Dropdown || _load_Dropdown()).Dropdown, { + isFlat: true, + options: options.map(option => ({ + value: option, + label: option.name + })), + placeholder: placeholder, + size: 'xs', + onChange: action => action != null && action.callback(this.props.device) + }) ); } } } +exports.DeviceTaskButton = DeviceTaskButton; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/ui/InfoTable.js b/pkg/nuclide-device-panel/lib/ui/InfoTable.js index 3634849d00..98193a7d3b 100644 --- a/pkg/nuclide-device-panel/lib/ui/InfoTable.js +++ b/pkg/nuclide-device-panel/lib/ui/InfoTable.js @@ -1,3 +1,20 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.InfoTable = undefined; + +var _react = _interopRequireWildcard(require('react')); + +var _Table; + +function _load_Table() { + return _Table = require('../../../../modules/nuclide-commons-ui/Table'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,48 +22,42 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import * as React from 'react'; -import {Table} from 'nuclide-commons-ui/Table'; - -type Props = {| - table: Map, - title: string, -|}; - -export class InfoTable extends React.Component { - render(): React.Node { +class InfoTable extends _react.Component { + render() { const rows = Array.from(this.props.table.entries()).map(([key, value]) => ({ - data: {property: key, value}, + data: { property: key, value } })); - const columns = [ - { - key: 'property', - title: 'Property', - width: 0.4, - }, - { - key: 'value', - title: 'Value', - width: 0.6, - }, - ]; - const emptyComponent = () =>
    No information
    ; - - return ( -
    -
    - + const columns = [{ + key: 'property', + title: 'Property', + width: 0.4 + }, { + key: 'value', + title: 'Value', + width: 0.6 + }]; + const emptyComponent = () => _react.createElement( + 'div', + { className: 'padded' }, + 'No information' + ); + + return _react.createElement( + 'div', + null, + _react.createElement((_Table || _load_Table()).Table, { + collapsable: false, + columns: columns, + maxBodyHeight: '99999px', + emptyComponent: emptyComponent, + rows: rows, + headerTitle: this.props.title + }) ); } } +exports.InfoTable = InfoTable; \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/ui/ProcessTable.js b/pkg/nuclide-device-panel/lib/ui/ProcessTable.js index a9f841de77..4676b1c362 100644 --- a/pkg/nuclide-device-panel/lib/ui/ProcessTable.js +++ b/pkg/nuclide-device-panel/lib/ui/ProcessTable.js @@ -1,61 +1,72 @@ -/** - * 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 - */ - -import type {Process, ProcessTask} from 'nuclide-debugger-common/types'; -import type {Expected} from 'nuclide-commons/expected'; - -import {ProcessTaskButton} from './ProcessTaskButton'; -import * as React from 'react'; -import {Table} from 'nuclide-commons-ui/Table'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {LoadingSpinner} from 'nuclide-commons-ui/LoadingSpinner'; - -type Props = {| - toggleProcessPolling: (isActive: boolean) => void, - processTasks: ProcessTask[], - processes: Expected, -|}; - -type ColumnName = 'pid' | 'user' | 'name' | 'cpuUsage' | 'memUsage' | 'debug'; - -type State = { - filterText: string, - sortedColumn: ?ColumnName, - sortDescending: boolean, -}; - -export class ProcessTable extends React.Component { - constructor(props: Props) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ProcessTable = undefined; + +var _ProcessTaskButton; + +function _load_ProcessTaskButton() { + return _ProcessTaskButton = require('./ProcessTaskButton'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _Table; + +function _load_Table() { + return _Table = require('../../../../modules/nuclide-commons-ui/Table'); +} + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../../../../modules/nuclide-commons-ui/AtomInput'); +} + +var _LoadingSpinner; + +function _load_LoadingSpinner() { + return _LoadingSpinner = require('../../../../modules/nuclide-commons-ui/LoadingSpinner'); +} + +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 ProcessTable extends _react.Component { + constructor(props) { super(props); + this._handleSort = (sortedColumn, sortDescending) => { + this.setState({ sortedColumn, sortDescending }); + }; + + this._handleFilterTextChange = text => { + this.setState({ + filterText: text + }); + }; + this.state = { filterText: '', sortedColumn: 'cpuUsage', - sortDescending: true, + sortDescending: true }; } - componentDidMount(): void { + componentDidMount() { this.props.toggleProcessPolling(true); } - componentWillUnmount(): void { + componentWillUnmount() { this.props.toggleProcessPolling(false); } - _formatCpuUsage(cpu: ?number): string { + _formatCpuUsage(cpu) { return cpu == null ? '' : cpu.toFixed(2) + '%'; } - _formatMemUsage(mem: ?number): string { + _formatMemUsage(mem) { if (mem == null) { return ''; } else if (mem < 1024) { @@ -65,154 +76,132 @@ export class ProcessTable extends React.Component { } } - _handleSort = (sortedColumn: ?ColumnName, sortDescending: boolean): void => { - this.setState({sortedColumn, sortDescending}); - }; - - _sortProcesses( - processes: Process[], - sortedColumnName: ?ColumnName, - sortDescending: boolean, - ): Process[] { + _sortProcesses(processes, sortedColumnName, sortDescending) { if (sortedColumnName == null) { return processes; } // compare numerically the following fields - const compare: any = ['cpuUsage', 'memUsage', 'pid', 'debug'].includes( - sortedColumnName, - ) - ? (a: ?number, b: ?number, isAsc: boolean): number => { - const cmp = - // flowlint-next-line sketchy-null-number:off - (a || Number.NEGATIVE_INFINITY) - (b || Number.NEGATIVE_INFINITY); - return isAsc ? cmp : -cmp; - } - : (a: string, b: string, isAsc: boolean): number => { - const cmp = a.toLowerCase().localeCompare(b.toLowerCase()); - return isAsc ? cmp : -cmp; - }; + const compare = ['cpuUsage', 'memUsage', 'pid', 'debug'].includes(sortedColumnName) ? (a, b, isAsc) => { + const cmp = + // flowlint-next-line sketchy-null-number:off + (a || Number.NEGATIVE_INFINITY) - (b || Number.NEGATIVE_INFINITY); + return isAsc ? cmp : -cmp; + } : (a, b, isAsc) => { + const cmp = a.toLowerCase().localeCompare(b.toLowerCase()); + return isAsc ? cmp : -cmp; + }; return processes.sort((a, b) => - // $FlowFixMe: Process doesn't have a debug field. - compare(a[sortedColumnName], b[sortedColumnName], !sortDescending), - ); + // $FlowFixMe: Process doesn't have a debug field. + compare(a[sortedColumnName], b[sortedColumnName], !sortDescending)); } - render(): React.Node { + render() { const filterRegex = new RegExp(this.state.filterText, 'i'); let processComponent; if (this.props.processes.isError) { - processComponent =
    {this.props.processes.error.toString()}
    ; - } else if (this.props.processes.isPending) { - processComponent = ( - + processComponent = _react.createElement( + 'div', + null, + this.props.processes.error.toString() ); + } else if (this.props.processes.isPending) { + processComponent = _react.createElement((_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinner, { size: 'EXTRA_SMALL', key: 'infoTableLoading' }); } else { - const rows = this._sortProcesses( - this.props.processes.value.filter( - item => - filterRegex.test(item.user) || - filterRegex.test(`${item.pid}`) || - filterRegex.test(item.name), - ), - this.state.sortedColumn, - this.state.sortDescending, - ).map(item => ({ + const rows = this._sortProcesses(this.props.processes.value.filter(item => filterRegex.test(item.user) || filterRegex.test(`${item.pid}`) || filterRegex.test(item.name)), this.state.sortedColumn, this.state.sortDescending).map(item => ({ data: { - pid: ( -
    - - {item.pid} -
    + pid: _react.createElement( + 'div', + null, + _react.createElement((_ProcessTaskButton || _load_ProcessTaskButton()).ProcessTaskButton, { + icon: 'x', + proc: item, + taskType: 'KILL', + nameIfManyTasks: 'Kill process', + tasks: this.props.processTasks + }), + item.pid ), user: item.user, name: item.name, cpuUsage: this._formatCpuUsage(item.cpuUsage), memUsage: this._formatMemUsage(item.memUsage), - debug: ( - - ), - }, + debug: _react.createElement((_ProcessTaskButton || _load_ProcessTaskButton()).ProcessTaskButton, { + icon: 'nuclicon-debugger', + className: 'nuclide-device-panel-debug-button', + proc: item, + taskType: 'DEBUG', + nameIfManyTasks: 'Debug process', + tasks: this.props.processTasks + }) + } })); - const columns = [ - { - key: 'pid', - title: 'PID', - width: 0.17, - }, - { - key: 'name', - title: 'Name', - width: 0.31, - }, - { - key: 'user', - title: 'User', - width: 0.13, - }, - { - key: 'cpuUsage', - title: 'CPU', - width: 0.15, - }, - { - key: 'memUsage', - title: 'Mem', - width: 0.15, - }, - { - key: 'debug', - title: 'Debug', - width: 0.08, - }, - ]; - const emptyComponent = () =>
    No information
    ; - processComponent = ( -
    + const columns = [{ + key: 'pid', + title: 'PID', + width: 0.17 + }, { + key: 'name', + title: 'Name', + width: 0.31 + }, { + key: 'user', + title: 'User', + width: 0.13 + }, { + key: 'cpuUsage', + title: 'CPU', + width: 0.15 + }, { + key: 'memUsage', + title: 'Mem', + width: 0.15 + }, { + key: 'debug', + title: 'Debug', + width: 0.08 + }]; + const emptyComponent = () => _react.createElement( + 'div', + { className: 'padded' }, + 'No information' ); + processComponent = _react.createElement((_Table || _load_Table()).Table, { + collapsable: false, + columns: columns, + maxBodyHeight: '99999px', + emptyComponent: emptyComponent, + rows: rows, + sortable: true, + onSort: this._handleSort, + sortedColumn: this.state.sortedColumn, + sortDescending: this.state.sortDescending, + className: 'nuclide-device-panel-process-table' + }); } - return ( -
    - - {processComponent} -
    + return _react.createElement( + 'div', + null, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + placeholderText: 'Filter process...', + initialValue: this.state.filterText, + onDidChange: this._handleFilterTextChange, + size: 'sm' + }), + processComponent ); } - _handleFilterTextChange = (text: string): void => { - this.setState({ - filterText: text, - }); - }; } +exports.ProcessTable = ProcessTable; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/ui/ProcessTaskButton.js b/pkg/nuclide-device-panel/lib/ui/ProcessTaskButton.js index ce3bd16dfc..152165d1d0 100644 --- a/pkg/nuclide-device-panel/lib/ui/ProcessTaskButton.js +++ b/pkg/nuclide-device-panel/lib/ui/ProcessTaskButton.js @@ -1,75 +1,67 @@ -/** - * 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 - */ +'use strict'; -import type { - Process, - ProcessTask, - ProcessTaskType, -} from 'nuclide-debugger-common/types'; -import type {IconName} from 'nuclide-commons-ui/Icon'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ProcessTaskButton = undefined; -import {Dropdown} from 'nuclide-commons-ui/Dropdown'; -import * as React from 'react'; -import {Icon} from 'nuclide-commons-ui/Icon'; +var _Dropdown; -type Props = {| - tasks: ProcessTask[], - proc: Process, - icon: IconName, - taskType: ProcessTaskType, - className?: string, - nameIfManyTasks: string, -|}; +function _load_Dropdown() { + return _Dropdown = require('../../../../modules/nuclide-commons-ui/Dropdown'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _Icon; + +function _load_Icon() { + return _Icon = require('../../../../modules/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; } } -export class ProcessTaskButton extends React.Component { - _getTaskOptions(): {value: ProcessTask, label: string}[] { - return this.props.tasks - .filter( - task => - task.type === this.props.taskType && - task.isSupported(this.props.proc), - ) - .map(task => ({value: task, label: task.name})); +class ProcessTaskButton extends _react.Component { + _getTaskOptions() { + return this.props.tasks.filter(task => task.type === this.props.taskType && task.isSupported(this.props.proc)).map(task => ({ value: task, label: task.name })); } - render(): React.Node { + render() { const options = this._getTaskOptions(); if (options.length === 0) { - return
    ; + return _react.createElement('div', null); } else if (options.length === 1) { - return ( - options[0].value.run(this.props.proc)}> - - + return _react.createElement( + 'span', + { onClick: () => options[0].value.run(this.props.proc) }, + _react.createElement((_Icon || _load_Icon()).Icon, { + icon: this.props.icon, + title: options[0].label, + className: this.props.className + }) ); } else { - const placeholder: any = ( - - ); + const placeholder = _react.createElement((_Icon || _load_Icon()).Icon, { icon: this.props.icon, title: this.props.nameIfManyTasks }); return ( // $FlowFixMe(>=0.53.0) Flow suppress - - task != null && task.run(this.props.proc) - } - /> + _react.createElement((_Dropdown || _load_Dropdown()).Dropdown, { + isFlat: true, + options: options, + placeholder: placeholder, + size: 'xs', + onChange: task => task != null && task.run(this.props.proc) + }) ); } } } +exports.ProcessTaskButton = ProcessTaskButton; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/ui/RootPanel.js b/pkg/nuclide-device-panel/lib/ui/RootPanel.js index 8dea7198c1..f21fe6dae7 100644 --- a/pkg/nuclide-device-panel/lib/ui/RootPanel.js +++ b/pkg/nuclide-device-panel/lib/ui/RootPanel.js @@ -1,197 +1,196 @@ -/** - * 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 - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - AppInfoRow, - ComponentPosition, - Device, - DeviceTypeComponent, - Process, - ProcessTask, - IDeviceTask, -} from 'nuclide-debugger-common/types'; -import type {Expected} from 'nuclide-commons/expected'; -import type {TaskEvent} from 'nuclide-commons/process'; -import type {Props as TaskButtonPropsType} from './TaskButton'; - -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import {TaskButton} from './TaskButton'; -import * as React from 'react'; -import {PanelComponentScroller} from 'nuclide-commons-ui/PanelComponentScroller'; -import invariant from 'assert'; -import {Selectors} from './Selectors'; -import {DeviceTable} from './DeviceTable'; -import {DevicePanel} from './DevicePanel'; -import * as Immutable from 'immutable'; - -export type Props = {| - setHost: (host: NuclideUri) => void, - setDeviceType: (deviceType: string) => void, - setDevice: (device: ?Device) => void, - toggleDevicePolling: (isActive: boolean) => void, - toggleProcessPolling: (isActive: boolean) => void, - processTasks: ProcessTask[], - hosts: NuclideUri[], - devices: Expected, - host: NuclideUri, - deviceTypes: string[], - deviceType: ?string, - deviceTasks: IDeviceTask[], - device: ?Device, - infoTables: Expected>>, - appInfoTables: Expected>>, - processes: Expected, - isDeviceConnected: boolean, - deviceTypeTasks: IDeviceTask[], - deviceTypeComponents: Immutable.Map< - ComponentPosition, - Immutable.List, - >, -|}; - -export class RootPanel extends React.Component { - constructor(props: Props) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RootPanel = undefined; + +var _bindObservableAsProps; + +function _load_bindObservableAsProps() { + return _bindObservableAsProps = require('../../../../modules/nuclide-commons-ui/bindObservableAsProps'); +} + +var _TaskButton; + +function _load_TaskButton() { + return _TaskButton = require('./TaskButton'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _PanelComponentScroller; + +function _load_PanelComponentScroller() { + return _PanelComponentScroller = require('../../../../modules/nuclide-commons-ui/PanelComponentScroller'); +} + +var _Selectors; + +function _load_Selectors() { + return _Selectors = require('./Selectors'); +} + +var _DeviceTable; + +function _load_DeviceTable() { + return _DeviceTable = require('./DeviceTable'); +} + +var _DevicePanel; + +function _load_DevicePanel() { + return _DevicePanel = require('./DevicePanel'); +} + +var _immutable; + +function _load_immutable() { + return _immutable = _interopRequireWildcard(require('immutable')); +} + +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 RootPanel extends _react.Component { + constructor(props) { super(props); - invariant(props.hosts.length > 0); + + this._getHostSelectorComponents = () => { + return this.props.deviceTypeComponents.get('host_selector') || (_immutable || _load_immutable()).List(); + }; + + this._getDeviceTypeComponents = position => { + const components = this.props.deviceTypeComponents.get(position); + if (components == null) { + return null; + } + const nodes = components.map(component => { + const Type = component.type; + return _react.createElement(Type, { key: component.key }); + }); + + return _react.createElement( + 'div', + { className: `block nuclide-device-panel-components-${position}` }, + nodes + ); + }; + + this._goToRootPanel = () => { + this.props.setDevice(null); + }; + + if (!(props.hosts.length > 0)) { + throw new Error('Invariant violation: "props.hosts.length > 0"'); + } } - componentDidMount(): void { + componentDidMount() { this.props.toggleDevicePolling(true); } - componentWillUnmount(): void { + componentWillUnmount() { this.props.toggleDevicePolling(false); } - _createDeviceTable(): ?React.Element { + _createDeviceTable() { // eslint-disable-next-line eqeqeq if (this.props.deviceType === null) { return null; } - return ( - - ); + return _react.createElement((_DeviceTable || _load_DeviceTable()).DeviceTable, { + devices: this.props.devices, + device: this.props.device, + setDevice: this.props.setDevice + }); } - _taskEventsToProps( - task: IDeviceTask, - taskEvent: ?TaskEvent, - ): TaskButtonPropsType { + _taskEventsToProps(task, taskEvent) { return { name: task.getName(), start: () => task.start(), cancel: () => task.cancel(), isRunning: taskEvent != null, - progress: null, + progress: null }; } - _getTasks(): ?React.Element { + _getTasks() { const tasks = Array.from(this.props.deviceTypeTasks).map(task => { - const StreamedTaskButton = bindObservableAsProps( - task - .getTaskEvents() - .distinctUntilChanged() - .map(taskEvent => this._taskEventsToProps(task, taskEvent)), - TaskButton, - ); - return ; + const StreamedTaskButton = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)(task.getTaskEvents().distinctUntilChanged().map(taskEvent => this._taskEventsToProps(task, taskEvent)), (_TaskButton || _load_TaskButton()).TaskButton); + return _react.createElement(StreamedTaskButton, { key: task.getName() }); }); if (tasks.length < 1) { return null; } - return ( -
    {tasks}
    + return _react.createElement( + 'div', + { className: 'block nuclide-device-panel-tasks-container' }, + tasks ); } - _getHostSelectorComponents = (): Immutable.List => { - return ( - this.props.deviceTypeComponents.get('host_selector') || Immutable.List() - ); - }; - - _getDeviceTypeComponents = ( - position: 'above_table' | 'below_table', - ): ?React.Element => { - const components = this.props.deviceTypeComponents.get(position); - if (components == null) { - return null; - } - const nodes = components.map(component => { - const Type = component.type; - return ; - }); - - return ( -
    - {nodes} -
    - ); - }; - - _goToRootPanel = (): void => { - this.props.setDevice(null); - }; - - _getInnerPanel(): React.Element { + _getInnerPanel() { if (this.props.device != null) { - return ( -
    - -
    + return _react.createElement( + 'div', + { className: 'block' }, + _react.createElement((_DevicePanel || _load_DevicePanel()).DevicePanel, { + infoTables: this.props.infoTables, + appInfoTables: this.props.appInfoTables, + processes: this.props.processes, + processTasks: this.props.processTasks, + deviceTasks: this.props.deviceTasks, + goToRootPanel: this._goToRootPanel, + toggleProcessPolling: this.props.toggleProcessPolling, + isDeviceConnected: this.props.isDeviceConnected + }) ); } - return ( -
    - - {this._getDeviceTypeComponents('above_table')} -
    {this._createDeviceTable()}
    - {this._getTasks()} - {this._getDeviceTypeComponents('below_table')} -
    + return _react.createElement( + 'div', + null, + _react.createElement((_Selectors || _load_Selectors()).Selectors, { + deviceType: this.props.deviceType, + deviceTypes: this.props.deviceTypes, + hosts: this.props.hosts, + host: this.props.host, + setDeviceType: this.props.setDeviceType, + toggleDevicePolling: this.props.toggleDevicePolling, + setHost: this.props.setHost, + hostSelectorComponents: this._getHostSelectorComponents() + }), + this._getDeviceTypeComponents('above_table'), + _react.createElement( + 'div', + { className: 'block' }, + this._createDeviceTable() + ), + this._getTasks(), + this._getDeviceTypeComponents('below_table') ); } - render(): React.Node { - return ( - -
    - {this._getInnerPanel()} -
    -
    + render() { + return _react.createElement( + (_PanelComponentScroller || _load_PanelComponentScroller()).PanelComponentScroller, + null, + _react.createElement( + 'div', + { className: 'nuclide-device-panel-container' }, + this._getInnerPanel() + ) ); } } +exports.RootPanel = RootPanel; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-device-panel/lib/ui/Selectors.js b/pkg/nuclide-device-panel/lib/ui/Selectors.js index e3320dc9e9..59dae2c73b 100644 --- a/pkg/nuclide-device-panel/lib/ui/Selectors.js +++ b/pkg/nuclide-device-panel/lib/ui/Selectors.js @@ -1,133 +1,151 @@ -/** - * 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 - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {Option} from 'nuclide-commons-ui/Dropdown'; -import type {DeviceTypeComponent} from 'nuclide-debugger-common/types'; - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import * as React from 'react'; -import * as Immutable from 'immutable'; -import {Dropdown} from 'nuclide-commons-ui/Dropdown'; -import {Button, ButtonTypes} from 'nuclide-commons-ui/Button'; -import {ButtonGroup, ButtonGroupSizes} from 'nuclide-commons-ui/ButtonGroup'; - -const FB_HOST_SUFFIX = '.facebook.com'; - -type Props = {| - setHost: (host: NuclideUri) => void, - setDeviceType: (deviceType: string) => void, - toggleDevicePolling: (isActive: boolean) => void, - hosts: NuclideUri[], - host: NuclideUri, - deviceTypes: string[], - deviceType: ?string, - hostSelectorComponents: Immutable.List, -|}; - -export class Selectors extends React.Component { - componentDidMount(): void { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Selectors = undefined; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../../modules/nuclide-commons/nuclideUri')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _immutable; + +function _load_immutable() { + return _immutable = _interopRequireWildcard(require('immutable')); +} + +var _Dropdown; + +function _load_Dropdown() { + return _Dropdown = require('../../../../modules/nuclide-commons-ui/Dropdown'); +} + +var _Button; + +function _load_Button() { + return _Button = require('../../../../modules/nuclide-commons-ui/Button'); +} + +var _ButtonGroup; + +function _load_ButtonGroup() { + return _ButtonGroup = require('../../../../modules/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; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const FB_HOST_SUFFIX = '.facebook.com'; /** + * 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. + * + * + * @format + */ + +class Selectors extends _react.Component { + constructor(...args) { + var _temp; + + return _temp = super(...args), this._getHostSelectorNodes = () => { + return this.props.hostSelectorComponents.map(component => { + const Type = component.type; + return _react.createElement(Type, { key: component.key }); + }); + }, _temp; + } + + componentDidMount() { if (this.props.deviceTypes.length > 0) { this._setDeviceType(this.props.deviceTypes[0]); } } - _getLabelForHost(host: string): string { + _getLabelForHost(host) { if (host === '') { return 'local'; } - const hostName = nuclideUri.getHostname(host); - return hostName.endsWith(FB_HOST_SUFFIX) - ? hostName.substring(0, hostName.length - FB_HOST_SUFFIX.length) - : hostName; + const hostName = (_nuclideUri || _load_nuclideUri()).default.getHostname(host); + return hostName.endsWith(FB_HOST_SUFFIX) ? hostName.substring(0, hostName.length - FB_HOST_SUFFIX.length) : hostName; } - _getHostOptions(): Array
    - - - - - - - - - {stats.map((stat, s) => { - const props: Object = {}; - return ( - - - - - ); - })} - -
    MetricValue - Toolbar -
    {stat.name}{stat.value}
    +class BasicStatsSectionComponent extends _react.Component { + render() { + const stats = [{ + name: 'CPU', + value: `${this.props.cpuPercentage.toFixed(0)}%` + }, { + name: 'Heap', + value: `${this.props.heapPercentage.toFixed(1)}%` + }, { + name: 'Memory', + value: `${Math.floor(this.props.memory / 1024 / 1024)}MB` + }, { + name: 'Handles', + value: `${this.props.activeHandles}` + }, { + name: 'Child processes', + value: `${this.props.activeHandlesByType.childprocess.length}` + }, { + name: 'Event loop', + value: `${this.props.activeRequests}` + }, { + name: 'Attached DOM Nodes', + value: `${this.props.attachedDomNodes != null ? this.props.attachedDomNodes : 'N/A - are your devtools open?'}` + }, { + name: 'Retained DOM Nodes', + value: `${this.props.domNodes != null ? this.props.domNodes : 'N/A - are your devtools open?'}` + }, { + name: 'DOM Listeners', + value: `${this.props.domListeners != null ? this.props.domListeners : 'N/A - are your devtools open?'}` + }]; + return _react.createElement( + 'table', + { className: 'table' }, + _react.createElement( + 'thead', + null, + _react.createElement( + 'tr', + null, + _react.createElement( + 'th', + { width: '30%' }, + 'Metric' + ), + _react.createElement( + 'th', + { width: '50%' }, + 'Value' + ), + _react.createElement( + 'th', + { width: '20%', className: 'text-right' }, + 'Toolbar' + ) + ) + ), + _react.createElement( + 'tbody', + null, + stats.map((stat, s) => { + const props = {}; + return _react.createElement( + 'tr', + Object.assign({}, props, { key: s }), + _react.createElement( + 'th', + null, + stat.name + ), + _react.createElement( + 'td', + null, + stat.value + ) + ); + }) + ) ); } } +exports.default = BasicStatsSectionComponent; \ No newline at end of file diff --git a/pkg/nuclide-health/lib/ui/sections/ChildProcessTreeComponent.js b/pkg/nuclide-health/lib/ui/sections/ChildProcessTreeComponent.js index b9a75c3c3e..e295ae91dc 100644 --- a/pkg/nuclide-health/lib/ui/sections/ChildProcessTreeComponent.js +++ b/pkg/nuclide-health/lib/ui/sections/ChildProcessTreeComponent.js @@ -1,85 +1,76 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {ChildProcessInfo} from '../../types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -import * as React from 'react'; -import HandlesTableComponent from './HandlesTableComponent'; +var _react = _interopRequireWildcard(require('react')); -type Props = { - childProcessesTree: ?ChildProcessInfo, -}; +var _HandlesTableComponent; -type ProcessWithLevel = { - process: ChildProcessInfo, - level: number, -}; +function _load_HandlesTableComponent() { + return _HandlesTableComponent = _interopRequireDefault(require('./HandlesTableComponent')); +} + +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; } } -export default class ChildProcessTreeComponent extends React.Component { - render(): React.Node { - const {childProcessesTree} = this.props; +class ChildProcessTreeComponent extends _react.Component { + render() { + const { childProcessesTree } = this.props; if (!childProcessesTree) { - return
    ; + return _react.createElement('div', null); } const handles = []; flatten(handles, childProcessesTree, 0); - return ( -
    - '\u00A0'.repeat(level * 3) + process.pid} - columns={[ - { - title: 'CPU %', - value: ({process, level}) => process.cpuPercentage, - widthPercentage: 5, - }, - { - title: 'In', - value: ({process}) => - process.ioBytesStats && process.ioBytesStats.stdin, - widthPercentage: 3, - }, - { - title: 'Out', - value: ({process}) => - process.ioBytesStats && process.ioBytesStats.stdout, - widthPercentage: 3, - }, - { - title: 'Err', - value: ({process}) => - process.ioBytesStats && process.ioBytesStats.stderr, - widthPercentage: 3, - }, - { - title: 'Command', - value: ({process, level}) => process.command, - widthPercentage: 56, - }, - ]} - /> -
    + return _react.createElement( + 'div', + null, + _react.createElement((_HandlesTableComponent || _load_HandlesTableComponent()).default, { + title: 'Process tree', + handles: handles, + keyed: ({ process, level }) => '\u00A0'.repeat(level * 3) + process.pid, + columns: [{ + title: 'CPU %', + value: ({ process, level }) => process.cpuPercentage, + widthPercentage: 5 + }, { + title: 'In', + value: ({ process }) => process.ioBytesStats && process.ioBytesStats.stdin, + widthPercentage: 3 + }, { + title: 'Out', + value: ({ process }) => process.ioBytesStats && process.ioBytesStats.stdout, + widthPercentage: 3 + }, { + title: 'Err', + value: ({ process }) => process.ioBytesStats && process.ioBytesStats.stderr, + widthPercentage: 3 + }, { + title: 'Command', + value: ({ process, level }) => process.command, + widthPercentage: 56 + }] + }) ); } } -function flatten( - handles: Array, - process: ChildProcessInfo, - level: number, -): void { - handles.push({process, level}); +exports.default = ChildProcessTreeComponent; /** + * 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. + * + * strict-local + * @format + */ + +function flatten(handles, process, level) { + handles.push({ process, level }); process.children.forEach(child => flatten(handles, child, level + 1)); -} +} \ No newline at end of file diff --git a/pkg/nuclide-health/lib/ui/sections/CommandsSectionComponent.js b/pkg/nuclide-health/lib/ui/sections/CommandsSectionComponent.js index 443f3896de..95f1e28bdb 100644 --- a/pkg/nuclide-health/lib/ui/sections/CommandsSectionComponent.js +++ b/pkg/nuclide-health/lib/ui/sections/CommandsSectionComponent.js @@ -1,3 +1,19 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _process; + +function _load_process() { + return _process = require('../../../../../modules/nuclide-commons/process'); +} + +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; } } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,40 +21,64 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import {loggedCalls} from 'nuclide-commons/process'; - -import * as React from 'react'; - -export default class CommandsSectionComponent extends React.Component<{}> { - _lastRenderCount: number; +class CommandsSectionComponent extends _react.Component { shouldComponentUpdate() { - return this._lastRenderCount !== loggedCalls.length; + return this._lastRenderCount !== (_process || _load_process()).loggedCalls.length; } render() { - this._lastRenderCount = loggedCalls.length; - return ( - - - - - - - - {loggedCalls.map((call, i) => ( - - - - - - ))} - -
    TimeDuration (ms)Command
    {call.time.toTimeString().replace(/ .+/, '')}{call.duration}{call.command}
    + this._lastRenderCount = (_process || _load_process()).loggedCalls.length; + return _react.createElement( + 'table', + { className: 'table' }, + _react.createElement( + 'thead', + null, + _react.createElement( + 'th', + { width: '10%' }, + 'Time' + ), + _react.createElement( + 'th', + { width: '10%' }, + 'Duration (ms)' + ), + _react.createElement( + 'th', + null, + 'Command' + ) + ), + _react.createElement( + 'tbody', + null, + (_process || _load_process()).loggedCalls.map((call, i) => _react.createElement( + 'tr', + { key: i }, + _react.createElement( + 'td', + null, + call.time.toTimeString().replace(/ .+/, '') + ), + _react.createElement( + 'td', + null, + call.duration + ), + _react.createElement( + 'td', + null, + call.command + ) + )) + ) ); } } +exports.default = CommandsSectionComponent; \ No newline at end of file diff --git a/pkg/nuclide-health/lib/ui/sections/HandlesTableComponent.js b/pkg/nuclide-health/lib/ui/sections/HandlesTableComponent.js index dec1454908..9e0433aca4 100644 --- a/pkg/nuclide-health/lib/ui/sections/HandlesTableComponent.js +++ b/pkg/nuclide-health/lib/ui/sections/HandlesTableComponent.js @@ -1,41 +1,21 @@ -/** - * 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 - */ +"use strict"; -import * as React from 'react'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -type Props = { - title: string, - handles: Array, - keyed: Function, - columns: Array<{ - title: string, - value: (handle: T, index: number) => ?string | ?number, - widthPercentage: number, - }>, -}; +var _react = _interopRequireWildcard(require("react")); -export default class HandlesTableComponent extends React.Component< - Props, - void, -> { - props: Props; +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; } } - previousHandleSummaries: Object; +class HandlesTableComponent extends _react.Component { - constructor(props: Object) { + constructor(props) { super(props); this.previousHandleSummaries = {}; } - getHandleSummaries(handles: Array): Object { + getHandleSummaries(handles) { const handleSummaries = {}; handles.forEach((handle, h) => { const summarizedHandle = {}; @@ -47,57 +27,84 @@ export default class HandlesTableComponent extends React.Component< return handleSummaries; } - render(): React.Node { + render() { if (this.props.handles.length === 0) { - return
    ; + return _react.createElement("div", null); } const handleSummaries = this.getHandleSummaries(this.props.handles); - const component = ( -
    -

    {this.props.title}

    - - - - - {this.props.columns.map((column, c) => ( - - ))} - - - - {Object.keys(handleSummaries).map(key => { - const handleSummary = handleSummaries[key]; - const previousHandle = this.previousHandleSummaries[key]; - return ( - - - {this.props.columns.map((column, c) => { - let className = ''; - if ( - previousHandle && - previousHandle[c] !== handleSummary[c] - ) { - className = 'nuclide-health-handle-updated'; - } - return ( - - ); - })} - - ); - })} - -
    ID - {column.title} -
    {key} - {handleSummary[c]} -
    -
    + const component = _react.createElement( + "div", + null, + _react.createElement( + "h3", + null, + this.props.title + ), + _react.createElement( + "table", + { className: "table" }, + _react.createElement( + "thead", + null, + _react.createElement( + "tr", + null, + _react.createElement( + "th", + { width: "10%" }, + "ID" + ), + this.props.columns.map((column, c) => _react.createElement( + "th", + { key: c, width: `${column.widthPercentage}%` }, + column.title + )) + ) + ), + _react.createElement( + "tbody", + null, + Object.keys(handleSummaries).map(key => { + const handleSummary = handleSummaries[key]; + const previousHandle = this.previousHandleSummaries[key]; + return _react.createElement( + "tr", + { + key: key, + className: previousHandle ? '' : 'nuclide-health-handle-new' }, + _react.createElement( + "th", + null, + key + ), + this.props.columns.map((column, c) => { + let className = ''; + if (previousHandle && previousHandle[c] !== handleSummary[c]) { + className = 'nuclide-health-handle-updated'; + } + return _react.createElement( + "td", + { key: c, className: className }, + handleSummary[c] + ); + }) + ); + }) + ) + ) ); this.previousHandleSummaries = handleSummaries; return component; } } +exports.default = HandlesTableComponent; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-health/spec/getChildProcesses-spec.js b/pkg/nuclide-health/spec/getChildProcesses-spec.js deleted file mode 100644 index 8339a81c21..0000000000 --- a/pkg/nuclide-health/spec/getChildProcesses-spec.js +++ /dev/null @@ -1,218 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import type {ChildProcessInfo} from '../lib/types'; -import type {PsInfo, ProcessSummary} from '../lib/getChildProcesses'; - -import {Observable} from 'rxjs'; -import nullthrows from 'nullthrows'; -import * as nuclideProcess from 'nuclide-commons/process'; - -import { - durationInSeconds, - queryPs, - childProcessTree, - childProcessSummary, -} from '../lib/getChildProcesses'; - -type QueryPsEntry = { - line: string, - ps: PsInfo, - isDescendant: boolean, - children: Array, -}; - -function fakePsEntry( - pid: number, - ppid: number, - command: string, - isDescendant: boolean, - ...children: Array -): QueryPsEntry { - const pcpu = 1; - const time = 2; - const rss = 3; - const vsz = 4; - return { - line: ` ${pid} ${ppid} ${pcpu} ${time} ${rss} ${vsz} ${command} `, - ps: {pid, ppid, pcpu, time, rss, vsz, command}, - isDescendant, - children, - }; -} - -function fakeSummary(command: string, count: number): ProcessSummary { - return { - command, - count, - pcpu: count, - time: count * 2, - rss: count * 3, - vsz: count * 4, - }; -} - -function setProcessPid(pid: number): number { - const original = process.pid; - Object.defineProperty(process, 'pid', {value: pid}); - return original; -} - -function checkQueryPs( - mockPid: number, - data: Array, - summary: Array, -): void { - describe('sample data', () => { - const descendants = data.filter(x => x.isDescendant); - let originalPid: number; - - beforeEach(() => { - originalPid = setProcessPid(mockPid); - spyOn(nuclideProcess, 'runCommand').andCallFake((cmd, args, options) => { - expect(cmd).toEqual('ps'); - expect(args).toEqual(['-eo', 'pid,ppid,pcpu,time,rss,vsz,command']); - return Observable.of( - ' PID PPID %CPU TIME RSS VSZ COMMAND\n' + - data.map(entry => entry.line + '\n').join(''), - ); - }); - }); - afterEach(() => { - setProcessPid(originalPid); - }); - - it('parses', () => { - waitsForPromise(async () => { - const expected = new Map(data.map(entry => [entry.ps.pid, entry.ps])); - const actual = await queryPs('command').toPromise(); - expect(actual).toEqual(expected); - }); - }); - - it('summarizes', () => { - waitsForPromise(async () => { - const actual = await queryPs('command') - .map(childProcessSummary) - .toPromise(); - expect(actual).toEqual(summary); - }); - }); - - it('converts to tree', () => { - waitsForPromise(async () => { - const expectedMap = new Map(descendants.map(x => [x.ps.pid, x])); - const actual = await queryPs('command') - .map(childProcessTree) - .toPromise(); - if (expectedMap.size === 0) { - expect(actual).toBe(null); - return; - } - function check(node: ChildProcessInfo): number { - let count = 1; - const expected = nullthrows(expectedMap.get(node.pid)); - expect(node.children.length).toBe(expected.children.length); - for (const child of node.children) { - expect(expected.children.includes(child.pid)).toBe(true); - count += check(child); - } - return count; - } - const count = check(nullthrows(actual)); - expect(count).toBe(data.filter(x => x.isDescendant).length); - }); - }); - }); -} - -describe('getChildProcesses', () => { - describe('single process', () => { - checkQueryPs( - 2, - [fakePsEntry(1, 0, 'init', false), fakePsEntry(2, 1, 'nuclide', true)], - [fakeSummary('nuclide', 1)], - ); - }); - - describe('other processes', () => { - checkQueryPs( - 5, - [ - fakePsEntry(1, 0, 'init', false), - fakePsEntry(2, 1, 'launchd', false), - fakePsEntry(3, 1, 'cron', false), - fakePsEntry(4, 1, 'mdworker', false), - fakePsEntry(5, 1, 'nuclide', true), - fakePsEntry(6, 1, 'chrome', false), - fakePsEntry(7, 1, 'iTerm2', false), - fakePsEntry(8, 7, 'bash', false), - ], - [fakeSummary('nuclide', 1)], - ); - }); - - describe('direct sub-processes', () => { - checkQueryPs( - 2, - [ - fakePsEntry(1, 0, 'init', false), - fakePsEntry(2, 1, 'nuclide', true, 3, 4, 5, 6), - fakePsEntry(3, 2, 'flow', true), - fakePsEntry(4, 2, 'hg', true), - fakePsEntry(5, 2, 'flow', true), - fakePsEntry(6, 2, 'hg', true), - ], - [fakeSummary('flow', 2), fakeSummary('hg', 2), fakeSummary('nuclide', 1)], - ); - }); - - describe('sub-process tree', () => { - checkQueryPs( - 2, - [ - fakePsEntry(1, 0, 'init', false), - fakePsEntry(2, 1, 'nuclide', true, 3, 4), - fakePsEntry(3, 2, 'flow', true, 5, 6), - fakePsEntry(4, 2, 'hg', true, 7, 8), - fakePsEntry(5, 3, 'flow', true), - fakePsEntry(6, 3, 'flow', true), - fakePsEntry(7, 4, 'hg', true), - fakePsEntry(8, 4, 'hg', true), - ], - [fakeSummary('flow', 3), fakeSummary('hg', 3), fakeSummary('nuclide', 1)], - ); - }); - - describe('missing process', () => { - checkQueryPs(1, [], []); - }); - - describe('durationInSeconds', () => { - it('handles integers', () => { - expect(durationInSeconds('5')).toBe(5); - }); - it('handles doubles', () => { - expect(durationInSeconds('2.5')).toBe(2.5); - }); - it('handles minutes', () => { - expect(durationInSeconds('5:00')).toBe(5 * 60); - }); - it('handles hours', () => { - expect(durationInSeconds('5:00:00')).toBe(5 * 60 * 60); - }); - it('handles everything at once', () => { - expect(durationInSeconds('500:10:20.5')).toBe( - 500 * 60 * 60 + 10 * 60 + 20.5, - ); - }); - }); -}); diff --git a/pkg/nuclide-health/spec/getDOMCounters-spec.js b/pkg/nuclide-health/spec/getDOMCounters-spec.js deleted file mode 100644 index f1f6c9991c..0000000000 --- a/pkg/nuclide-health/spec/getDOMCounters-spec.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * 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 strict - * @format - */ - -import invariant from 'assert'; -import {remote} from 'electron'; -import {getLogger} from 'log4js'; -import getDOMCounters from '../lib/getDOMCounters'; - -invariant(remote != null); - -describe('getDOMCounters', () => { - it('returns reasonable values', () => { - waitsForPromise(async () => { - const counters = await getDOMCounters(); - invariant(counters != null, 'Expected non-null counters'); - expect(counters.nodes).toBeGreaterThan(10); - expect(counters.attachedNodes).toBeLessThan(counters.nodes); - expect(counters.jsEventListeners).toBeGreaterThan(10); - getLogger().debug('getDOMCounters():', JSON.stringify(counters)); - }); - }); - - it('returns null if a debugger is attached', () => { - waitsForPromise(async () => { - const chromeDebugger = remote.getCurrentWebContents().debugger; - invariant(chromeDebugger != null); - - chromeDebugger.attach('1.1'); - const counters = await getDOMCounters(); - expect(counters).toBeNull(); - chromeDebugger.detach(); - }); - }); -}); diff --git a/pkg/nuclide-health/spec/health-spec.js b/pkg/nuclide-health/spec/health-spec.js deleted file mode 100644 index 6a2f6fe2c9..0000000000 --- a/pkg/nuclide-health/spec/health-spec.js +++ /dev/null @@ -1,98 +0,0 @@ -/** - * 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 - */ - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import invariant from 'assert'; -import {WORKSPACE_VIEW_URI} from '../lib/HealthPaneItem'; - -const openHealthPane = () => { - // eslint-disable-next-line nuclide-internal/atom-apis - atom.workspace.open(WORKSPACE_VIEW_URI, {searchAllPanes: true}); -}; - -function findHealthPaneAndItem(): {pane: ?atom$Pane, item: ?Object} { - for (const pane of atom.workspace.getPanes()) { - for (const item of pane.getItems()) { - if (item.getTitle() === 'Health') { - return {pane, item}; - } - } - } - return {pane: null, item: null}; -} - -describe('Health', () => { - beforeEach(() => { - waitsForPromise( - {label: 'workspace views to load', timeout: 10000}, - async () => { - jasmine.unspy(window, 'setTimeout'); - await atom.packages.activatePackage(nuclideUri.join(__dirname, '..')); - }, - ); - }); - - it('contains stats after its first refresh', () => { - let element; - let pane; - let item; - runs(() => { - openHealthPane(); - waits(2000); - }); - waitsFor(() => { - const {pane: pane_, item: item_} = findHealthPaneAndItem(); - pane = pane_; - item = item_; - return item != null && pane != null; - }, 500); - runs(() => { - invariant(item != null); - expect(item.getTitle()).toEqual('Health'); - element = atom.views.getView(item); - }); - waitsFor(() => element.innerHTML.trim() !== '', 500); - runs(() => { - expect(element.innerHTML).toContain('Stats'); - expect(element.innerHTML).toContain('CPU'); - expect(element.innerHTML).toContain('Heap'); - expect(element.innerHTML).toContain('Memory'); - expect(element.innerHTML).toContain('Handles'); - expect(element.innerHTML).toContain('Event loop'); - }); - }); - - it('disappears when closed', () => { - runs(() => { - openHealthPane(); - }); - let pane; - let item; - waitsFor(() => { - const {pane: pane_, item: item_} = findHealthPaneAndItem(); - pane = pane_; - item = item_; - return item != null && pane != null; - }, 500); - runs(() => { - invariant(pane != null); - invariant(item != null); - pane.activateItem(item); - atom.commands.dispatch(atom.views.getView(atom.workspace), 'core:close'); - }); - waits(500); - runs(() => { - // Explicitly cast the result to boolean rather than using `.toBeFalsy()` - // since Jasmine crashes when trying to pretty print the item. - expect(Boolean(findHealthPaneAndItem().item)).toBe(false); - }); - }); -}); diff --git a/pkg/nuclide-health/spec/trackKeyLatency-spec.js b/pkg/nuclide-health/spec/trackKeyLatency-spec.js deleted file mode 100644 index fc2517b06a..0000000000 --- a/pkg/nuclide-health/spec/trackKeyLatency-spec.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -/* global requestAnimationFrame */ - -import {jasmineAttachWorkspace} from 'nuclide-commons-atom/test-helpers'; -import trackKeyLatency, {KEYSTROKES_TO_IGNORE} from '../lib/trackKeyLatency'; -import {HistogramTracker} from '../../nuclide-analytics'; - -beforeEach(() => { - jasmineAttachWorkspace(); -}); - -describe('trackKeyLatency', () => { - it('is able to measure key latency', () => { - const trackSpy = spyOn(HistogramTracker.prototype, 'track'); - const disposable = trackKeyLatency(); - - waitsForPromise(async () => { - const editor = await atom.workspace.open(); - advanceClock(1000); // trigger the initial delay - - for (let i = 0; i < KEYSTROKES_TO_IGNORE + 1; i++) { - editor.insertText('x'); - } - }); - - waitsFor(() => trackSpy.callCount === 2); - - runs(() => { - expect(trackSpy.callCount).toBe(2); - // $FlowIgnore: mixed types - expect(trackSpy.calls[0].args[0]).toBeLessThan(trackSpy.calls[1].args[0]); - disposable.dispose(); - }); - }); -}); - -// This is more of an assertion that the assumptions in trackKeyLatency hold up; -// in particular that an animation frame is enough to flush the DOM update. -describe('TextEditor', () => { - it('updates the DOM after an animation frame', () => { - waitsForPromise(async () => { - const editor = await atom.workspace.open(); - const insertText = '!!!!!'; - const innerHTMLPromise = new Promise(resolve => { - editor.onDidChange(() => { - setImmediate(() => { - requestAnimationFrame(() => { - resolve(editor.getElement().innerHTML); - }); - }); - }); - }); - editor.insertText(insertText); - expect(await innerHTMLPromise).toContain(insertText); - }); - }); -}); diff --git a/pkg/nuclide-health/spec/trackNewEditorLatency-spec.js b/pkg/nuclide-health/spec/trackNewEditorLatency-spec.js deleted file mode 100644 index 5ab75809af..0000000000 --- a/pkg/nuclide-health/spec/trackNewEditorLatency-spec.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import {HistogramTracker} from '../../nuclide-analytics'; -import trackNewEditorLatency from '../lib/trackNewEditorLatency'; - -describe('trackNewEditorLatency', () => { - it('tracks latency of switching between editors', () => { - trackNewEditorLatency(); - const tracks = []; - spyOn(HistogramTracker.prototype, 'track').andCallFake(function(value) { - tracks.push([this._eventName, value]); - }); - waitsForPromise(async () => { - await atom.workspace.open(__filename); - await atom.workspace.open(); - }); - waitsFor(() => { - return tracks.length > 0; - }); - runs(() => { - expect(tracks.length).toBe(2); - expect(tracks[0][0]).toBe('open-editor'); - expect(tracks[1][0]).toBe('open-editor'); - }); - // This needs to be separate (otherwise it blends into the 'add' event). - waitsForPromise(async () => { - await atom.workspace.open(__filename); - }); - waitsFor(() => { - return tracks.length > 2; - }); - runs(() => { - expect(tracks.length).toBe(3); - expect(tracks[2][0]).toBe('switch-editor'); - }); - }); -}); diff --git a/pkg/nuclide-hg-repository-client/lib/HgRepositoryClient.js b/pkg/nuclide-hg-repository-client/lib/HgRepositoryClient.js index c24e037c24..82e46e804e 100644 --- a/pkg/nuclide-hg-repository-client/lib/HgRepositoryClient.js +++ b/pkg/nuclide-hg-repository-client/lib/HgRepositoryClient.js @@ -1,3 +1,92 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.HgRepositoryClient = undefined; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _string; + +function _load_string() { + return _string = require('../../../modules/nuclide-commons/string'); +} + +var _eventKit; + +function _load_eventKit() { + return _eventKit = require('event-kit'); +} + +var _observable; + +function _load_observable() { + return _observable = require('../../../modules/nuclide-commons/observable'); +} + +var _RevisionsCache; + +function _load_RevisionsCache() { + return _RevisionsCache = _interopRequireDefault(require('./RevisionsCache')); +} + +var _hgConstants; + +function _load_hgConstants() { + return _hgConstants = require('../../nuclide-hg-rpc/lib/hg-constants'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _lruCache; + +function _load_lruCache() { + return _lruCache = _interopRequireDefault(require('lru-cache')); +} + +var _observePaneItemVisibility; + +function _load_observePaneItemVisibility() { + return _observePaneItemVisibility = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/observePaneItemVisibility')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,78 +94,15 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {DeadlineRequest} from 'nuclide-commons/promise'; -import typeof * as HgService from '../../nuclide-hg-rpc/lib/HgService'; -import type { - AmendModeValue, - BookmarkInfo, - CheckoutOptions, - HgRepositorySubscriptions, - DiffInfo, - LineDiff, - OperationProgress, - RevisionInfo, - RevisionShowInfo, - MergeConflicts, - RevisionFileChanges, - StatusCodeNumberValue, - StatusCodeIdValue, - VcsLogResponse, - RevisionInfoFetched, -} from '../../nuclide-hg-rpc/lib/HgService'; -import type {LegacyProcessMessage} from 'nuclide-commons/process'; -import type {LRUCache} from 'lru-cache'; -import type {ConnectableObservable} from 'rxjs'; - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {timeoutAfterDeadline} from 'nuclide-commons/promise'; -import {stringifyError} from 'nuclide-commons/string'; -import {Emitter} from 'event-kit'; -import { - cacheWhileSubscribed, - fastDebounce, - compact, -} from 'nuclide-commons/observable'; -import RevisionsCache from './RevisionsCache'; -import { - StatusCodeIdToNumber, - StatusCodeNumber, -} from '../../nuclide-hg-rpc/lib/hg-constants'; -import {BehaviorSubject, Observable, Subject} from 'rxjs'; -import LRU from 'lru-cache'; -import observePaneItemVisibility from 'nuclide-commons-atom/observePaneItemVisibility'; -import {getLogger} from 'log4js'; -import nullthrows from 'nullthrows'; - const STATUS_DEBOUNCE_DELAY_MS = 300; const REVISION_DEBOUNCE_DELAY = 300; const BOOKMARKS_DEBOUNCE_DELAY = 200; const FETCH_BOOKMARKS_TIMEOUT = 15 * 1000; -export type RevisionStatusDisplay = { - id: number, - name: string, - className: ?string, - latestDiff: number, // id of the latest diff within this revision - seriesLandBlocker?: string, - seriesLandBlockerMessage?: string, -}; - -type HgRepositoryOptions = { - /** The origin URL of this repository. */ - originURL: ?string, - - /** The working directory of this repository. */ - workingDirectory: atom$Directory | RemoteDirectory, - - /** The root directory that is opened in Atom, which this Repository serves. */ - projectRootDirectory?: atom$Directory, -}; - /** * * Section: Constants, Type Definitions @@ -85,18 +111,7 @@ type HgRepositoryOptions = { const DID_CHANGE_CONFLICT_STATE = 'did-change-conflict-state'; -export type RevisionStatuses = Map; - -type RevisionStatusCache = { - getCachedRevisionStatuses(): Map, - observeRevisionStatusesChanges(): Observable, - refresh(): void, -}; - -function getRevisionStatusCache( - revisionsCache: RevisionsCache, - workingDirectoryPath: string, -): RevisionStatusCache { +function getRevisionStatusCache(revisionsCache, workingDirectoryPath) { try { // $FlowFB const FbRevisionStatusCache = require('./fb/RevisionStatusCache').default; @@ -107,9 +122,9 @@ function getRevisionStatusCache( return new Map(); }, observeRevisionStatusesChanges() { - return Observable.empty(); + return _rxjsBundlesRxMinJs.Observable.empty(); }, - refresh() {}, + refresh() {} }; } } @@ -128,71 +143,9 @@ function getRevisionStatusCache( * in addition to providing asynchronous methods for some getters. */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {AdditionalLogFile} from '../../nuclide-logging/lib/rpc-types'; -import type {RemoteDirectory} from '../../nuclide-remote-connection'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {mapTransform} from 'nuclide-commons/collection'; +class HgRepositoryClient { -export type HgStatusChanges = { - statusChanges: Observable>, - isCalculatingChanges: Observable, -}; - -export class HgRepositoryClient { - // An instance of HgRepositoryClient may be cloned to share the subscriptions - // across multiple atom projects in the same hg repository, but allow - // overriding of certain functionality depending on project root. To make sure - // that changes to member vars are seen between all cloned instances, wrap - // them in this object. - // Not all properties need to be shared, but it was easier for the time-being - // to do so. The only properties that TRULY need to be shared are those that - // are assigned to from a cloned instance. A future refactor could possibly - // better separate between those that are needed to be shared and those that - // aren't. An even better--but more involved--future refactor could possibly - // eliminate all instances of assigning to a member property from a cloned - // instance in the first place. - // Do not reassign this object. - _sharedMembers: { - rootRepo: HgRepositoryClient, - path: string, - workingDirectory: atom$Directory | RemoteDirectory, - workingDirectoryPath: string, - projectDirectory: ?atom$Directory, - repoSubscriptions: Promise, - originURL: ?string, - service: HgService, - emitter: Emitter, - subscriptions: UniversalDisposable, - hgStatusCache: Map, // legacy, only for uncommitted - hgUncommittedStatusChanges: HgStatusChanges, - hgHeadStatusChanges: HgStatusChanges, - hgStackStatusChanges: HgStatusChanges, - revisionsCache: RevisionsCache, - revisionStatusCache: RevisionStatusCache, - revisionIdToFileChanges: LRUCache, - fileContentsAtRevisionIds: LRUCache>, - currentHeadId: ?string, - bookmarks: BehaviorSubject<{ - isLoading: boolean, - bookmarks: Array, - }>, - - isInConflict: boolean, - isDestroyed: boolean, - isFetchingPathStatuses: Subject, - manualStatusRefreshRequests: Subject, - - // absolute path of file to DiffInfo - bufferDiffsFromHeadCache: Map, - }; - - constructor( - repoPath: string, - hgService: HgService, - options: HgRepositoryOptions, - ) { + constructor(repoPath, hgService, options) { // $FlowFixMe - by the end of the constructor, all the members should be initialized this._sharedMembers = {}; @@ -205,225 +158,118 @@ export class HgRepositoryClient { this._sharedMembers.service = hgService; this._sharedMembers.isInConflict = false; this._sharedMembers.isDestroyed = false; - this._sharedMembers.revisionsCache = new RevisionsCache( - this._sharedMembers.workingDirectoryPath, - hgService, - ); - this._sharedMembers.revisionStatusCache = getRevisionStatusCache( - this._sharedMembers.revisionsCache, - this._sharedMembers.workingDirectory.getPath(), - ); - this._sharedMembers.revisionIdToFileChanges = new LRU({max: 100}); - this._sharedMembers.fileContentsAtRevisionIds = new LRU({max: 20}); - - this._sharedMembers.emitter = new Emitter(); - this._sharedMembers.subscriptions = new UniversalDisposable( - this._sharedMembers.emitter, - ); - this._sharedMembers.isFetchingPathStatuses = new Subject(); - this._sharedMembers.manualStatusRefreshRequests = new Subject(); + this._sharedMembers.revisionsCache = new (_RevisionsCache || _load_RevisionsCache()).default(this._sharedMembers.workingDirectoryPath, hgService); + this._sharedMembers.revisionStatusCache = getRevisionStatusCache(this._sharedMembers.revisionsCache, this._sharedMembers.workingDirectory.getPath()); + this._sharedMembers.revisionIdToFileChanges = new (_lruCache || _load_lruCache()).default({ max: 100 }); + this._sharedMembers.fileContentsAtRevisionIds = new (_lruCache || _load_lruCache()).default({ max: 20 }); + + this._sharedMembers.emitter = new (_eventKit || _load_eventKit()).Emitter(); + this._sharedMembers.subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(this._sharedMembers.emitter); + this._sharedMembers.isFetchingPathStatuses = new _rxjsBundlesRxMinJs.Subject(); + this._sharedMembers.manualStatusRefreshRequests = new _rxjsBundlesRxMinJs.Subject(); this._sharedMembers.hgStatusCache = new Map(); - this._sharedMembers.bookmarks = new BehaviorSubject({ + this._sharedMembers.bookmarks = new _rxjsBundlesRxMinJs.BehaviorSubject({ isLoading: true, - bookmarks: [], + bookmarks: [] }); this._sharedMembers.bufferDiffsFromHeadCache = new Map(); - this._sharedMembers.repoSubscriptions = this._sharedMembers.service - .createRepositorySubscriptions(this._sharedMembers.workingDirectoryPath) - .catch(error => { - atom.notifications.addWarning( - 'Mercurial: failed to subscribe to watchman!', - ); - getLogger('nuclide-hg-repository-client').error( - `Failed to subscribe to watchman in ${ - this._sharedMembers.workingDirectoryPath - }`, - error, - ); - return null; - }); - const fileChanges = this._tryObserve(s => - s.observeFilesDidChange().refCount(), - ); - const repoStateChanges = Observable.merge( - this._tryObserve(s => s.observeHgRepoStateDidChange().refCount()), - this._sharedMembers.manualStatusRefreshRequests, - ); - const activeBookmarkChanges = this._tryObserve(s => - s.observeActiveBookmarkDidChange().refCount(), - ); - const allBookmarkChanges = this._tryObserve(s => - s.observeBookmarksDidChange().refCount(), - ); - const conflictStateChanges = this._tryObserve(s => - s.observeHgConflictStateDidChange().refCount(), - ); - const commitChanges = this._tryObserve(s => - s.observeHgCommitsDidChange().refCount(), - ); - - this._sharedMembers.hgUncommittedStatusChanges = this._observeStatus( - fileChanges, - repoStateChanges, - () => - this._sharedMembers.service.fetchStatuses( - this._sharedMembers.workingDirectoryPath, - ), - ); - - this._sharedMembers.hgStackStatusChanges = this._observeStatus( - fileChanges, - repoStateChanges, - () => - this._sharedMembers.service.fetchStackStatuses( - this._sharedMembers.workingDirectoryPath, - ), - ); - - this._sharedMembers.hgHeadStatusChanges = this._observeStatus( - fileChanges, - repoStateChanges, - () => - this._sharedMembers.service.fetchHeadStatuses( - this._sharedMembers.workingDirectoryPath, - ), - ); - - const statusChangesSubscription = this._sharedMembers.hgUncommittedStatusChanges.statusChanges.subscribe( - statuses => { - this._sharedMembers.hgStatusCache = statuses; - this._sharedMembers.emitter.emit('did-change-statuses'); - }, - ); - - const shouldRevisionsUpdate = Observable.merge( - this._sharedMembers.bookmarks.asObservable(), - commitChanges, - repoStateChanges, - ).let(fastDebounce(REVISION_DEBOUNCE_DELAY)); - - const bookmarksUpdates = Observable.merge( - activeBookmarkChanges, - allBookmarkChanges, - ) - .startWith(null) - .let(fastDebounce(BOOKMARKS_DEBOUNCE_DELAY)) - .switchMap(() => - Observable.defer(() => { - return Observable.fromPromise( - this._sharedMembers.service.fetchBookmarks( - this._sharedMembers.workingDirectoryPath, - ), - ).timeout(FETCH_BOOKMARKS_TIMEOUT); - }) - .retry(2) - .catch(error => { - getLogger('nuclide-hg-repository-client').error( - 'failed to fetch bookmarks info:', - error, - ); - return Observable.empty(); - }), - ); - - this._sharedMembers.subscriptions.add( - statusChangesSubscription, - bookmarksUpdates.subscribe(bookmarks => - this._sharedMembers.bookmarks.next({isLoading: false, bookmarks}), - ), - conflictStateChanges.subscribe(this._conflictStateChanged.bind(this)), - shouldRevisionsUpdate.subscribe(() => { - this._sharedMembers.revisionsCache.refreshRevisions(); - }), - ); + this._sharedMembers.repoSubscriptions = this._sharedMembers.service.createRepositorySubscriptions(this._sharedMembers.workingDirectoryPath).catch(error => { + atom.notifications.addWarning('Mercurial: failed to subscribe to watchman!'); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-repository-client').error(`Failed to subscribe to watchman in ${this._sharedMembers.workingDirectoryPath}`, error); + return null; + }); + const fileChanges = this._tryObserve(s => s.observeFilesDidChange().refCount()); + const repoStateChanges = _rxjsBundlesRxMinJs.Observable.merge(this._tryObserve(s => s.observeHgRepoStateDidChange().refCount()), this._sharedMembers.manualStatusRefreshRequests); + const activeBookmarkChanges = this._tryObserve(s => s.observeActiveBookmarkDidChange().refCount()); + const allBookmarkChanges = this._tryObserve(s => s.observeBookmarksDidChange().refCount()); + const conflictStateChanges = this._tryObserve(s => s.observeHgConflictStateDidChange().refCount()); + const commitChanges = this._tryObserve(s => s.observeHgCommitsDidChange().refCount()); + + this._sharedMembers.hgUncommittedStatusChanges = this._observeStatus(fileChanges, repoStateChanges, () => this._sharedMembers.service.fetchStatuses(this._sharedMembers.workingDirectoryPath)); + + this._sharedMembers.hgStackStatusChanges = this._observeStatus(fileChanges, repoStateChanges, () => this._sharedMembers.service.fetchStackStatuses(this._sharedMembers.workingDirectoryPath)); + + this._sharedMembers.hgHeadStatusChanges = this._observeStatus(fileChanges, repoStateChanges, () => this._sharedMembers.service.fetchHeadStatuses(this._sharedMembers.workingDirectoryPath)); + + const statusChangesSubscription = this._sharedMembers.hgUncommittedStatusChanges.statusChanges.subscribe(statuses => { + this._sharedMembers.hgStatusCache = statuses; + this._sharedMembers.emitter.emit('did-change-statuses'); + }); + + const shouldRevisionsUpdate = _rxjsBundlesRxMinJs.Observable.merge(this._sharedMembers.bookmarks.asObservable(), commitChanges, repoStateChanges).let((0, (_observable || _load_observable()).fastDebounce)(REVISION_DEBOUNCE_DELAY)); + + const bookmarksUpdates = _rxjsBundlesRxMinJs.Observable.merge(activeBookmarkChanges, allBookmarkChanges).startWith(null).let((0, (_observable || _load_observable()).fastDebounce)(BOOKMARKS_DEBOUNCE_DELAY)).switchMap(() => _rxjsBundlesRxMinJs.Observable.defer(() => { + return _rxjsBundlesRxMinJs.Observable.fromPromise(this._sharedMembers.service.fetchBookmarks(this._sharedMembers.workingDirectoryPath)).timeout(FETCH_BOOKMARKS_TIMEOUT); + }).retry(2).catch(error => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-repository-client').error('failed to fetch bookmarks info:', error); + return _rxjsBundlesRxMinJs.Observable.empty(); + })); + + this._sharedMembers.subscriptions.add(statusChangesSubscription, bookmarksUpdates.subscribe(bookmarks => this._sharedMembers.bookmarks.next({ isLoading: false, bookmarks })), conflictStateChanges.subscribe(this._conflictStateChanged.bind(this)), shouldRevisionsUpdate.subscribe(() => { + this._sharedMembers.revisionsCache.refreshRevisions(); + })); } // A single root HgRepositoryClient can back multiple HgRepositoryClients // via differential inheritance. This gets the 'original' HgRepositoryClient - getRootRepoClient(): HgRepositoryClient { + + // An instance of HgRepositoryClient may be cloned to share the subscriptions + // across multiple atom projects in the same hg repository, but allow + // overriding of certain functionality depending on project root. To make sure + // that changes to member vars are seen between all cloned instances, wrap + // them in this object. + // Not all properties need to be shared, but it was easier for the time-being + // to do so. The only properties that TRULY need to be shared are those that + // are assigned to from a cloned instance. A future refactor could possibly + // better separate between those that are needed to be shared and those that + // aren't. An even better--but more involved--future refactor could possibly + // eliminate all instances of assigning to a member property from a cloned + // instance in the first place. + // Do not reassign this object. + getRootRepoClient() { return this._sharedMembers.rootRepo; } // this._repoSubscriptions can potentially fail if Watchman fails. // The current behavior is to behave as if no changes ever occur. - _tryObserve( - observe: (s: HgRepositorySubscriptions) => Observable, - ): Observable { - return Observable.fromPromise( - this._sharedMembers.repoSubscriptions, - ).switchMap(repoSubscriptions => { + _tryObserve(observe) { + return _rxjsBundlesRxMinJs.Observable.fromPromise(this._sharedMembers.repoSubscriptions).switchMap(repoSubscriptions => { if (repoSubscriptions == null) { - return Observable.never(); + return _rxjsBundlesRxMinJs.Observable.never(); } return observe(repoSubscriptions); }); } - async getAdditionalLogFiles( - deadline: DeadlineRequest, - ): Promise> { + async getAdditionalLogFiles(deadline) { const path = this._sharedMembers.workingDirectory.getPath(); - const prefix = nuclideUri.isRemote(path) - ? `${nuclideUri.getHostname(path)}:` - : ''; - const results = await timeoutAfterDeadline( - deadline, - this._sharedMembers.service.getAdditionalLogFiles( - this._sharedMembers.workingDirectoryPath, - deadline - 1000, - ), - ).catch(e => [{title: `${path}:hg`, data: stringifyError(e)}]); - return results.map(log => ({...log, title: prefix + log.title})); - } - - _observeStatus( - fileChanges: Observable>, - repoStateChanges: Observable, - fetchStatuses: () => ConnectableObservable< - Map, - >, - ): HgStatusChanges { - const triggers = Observable.merge(fileChanges, repoStateChanges) - .let(fastDebounce(STATUS_DEBOUNCE_DELAY_MS)) - .share() - .startWith(null); + const prefix = (_nuclideUri || _load_nuclideUri()).default.isRemote(path) ? `${(_nuclideUri || _load_nuclideUri()).default.getHostname(path)}:` : ''; + const results = await (0, (_promise || _load_promise()).timeoutAfterDeadline)(deadline, this._sharedMembers.service.getAdditionalLogFiles(this._sharedMembers.workingDirectoryPath, deadline - 1000)).catch(e => [{ title: `${path}:hg`, data: (0, (_string || _load_string()).stringifyError)(e) }]); + return results.map(log => Object.assign({}, log, { title: prefix + log.title })); + } + + _observeStatus(fileChanges, repoStateChanges, fetchStatuses) { + const triggers = _rxjsBundlesRxMinJs.Observable.merge(fileChanges, repoStateChanges).let((0, (_observable || _load_observable()).fastDebounce)(STATUS_DEBOUNCE_DELAY_MS)).share().startWith(null); // Share comes before startWith. That's because fileChanges/repoStateChanges // are already hot and can be shared fine. But we want both our subscribers, // statusChanges and isCalculatingChanges, to pick up their own copy of // startWith(null) no matter which order they subscribe. - const statusChanges = cacheWhileSubscribed( - triggers - .switchMap(() => { - this._sharedMembers.isFetchingPathStatuses.next(true); - return fetchStatuses() - .refCount() - .catch(error => { - getLogger('nuclide-hg-repository-client').error( - 'HgService cannot fetch statuses', - error, - ); - return Observable.empty(); - }) - .finally(() => { - this._sharedMembers.isFetchingPathStatuses.next(false); - }); - }) - .map(uriToStatusIds => - mapTransform(uriToStatusIds, (v, k) => StatusCodeIdToNumber[v]), - ), - ); - - const isCalculatingChanges = cacheWhileSubscribed( - Observable.merge( - triggers.map(_ => true), - statusChanges.map(_ => false), - ).distinctUntilChanged(), - ); - - return {statusChanges, isCalculatingChanges}; + const statusChanges = (0, (_observable || _load_observable()).cacheWhileSubscribed)(triggers.switchMap(() => { + this._sharedMembers.isFetchingPathStatuses.next(true); + return fetchStatuses().refCount().catch(error => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-repository-client').error('HgService cannot fetch statuses', error); + return _rxjsBundlesRxMinJs.Observable.empty(); + }).finally(() => { + this._sharedMembers.isFetchingPathStatuses.next(false); + }); + }).map(uriToStatusIds => (0, (_collection || _load_collection()).mapTransform)(uriToStatusIds, (v, k) => (_hgConstants || _load_hgConstants()).StatusCodeIdToNumber[v]))); + + const isCalculatingChanges = (0, (_observable || _load_observable()).cacheWhileSubscribed)(_rxjsBundlesRxMinJs.Observable.merge(triggers.map(_ => true), statusChanges.map(_ => false)).distinctUntilChanged()); + + return { statusChanges, isCalculatingChanges }; } destroy() { @@ -442,11 +288,11 @@ export class HgRepositoryClient { }); } - isDestroyed(): boolean { + isDestroyed() { return this._sharedMembers.isDestroyed; } - _conflictStateChanged(isInConflict: boolean): void { + _conflictStateChanged(isInConflict) { this._sharedMembers.isInConflict = isInConflict; this._sharedMembers.emitter.emit(DID_CHANGE_CONFLICT_STATE); } @@ -457,85 +303,68 @@ export class HgRepositoryClient { * */ - onDidDestroy(callback: () => mixed): IDisposable { + onDidDestroy(callback) { return this._sharedMembers.emitter.on('did-destroy', callback); } - onDidChangeStatus( - callback: (event: { - path: string, - pathStatus: StatusCodeNumberValue, - }) => mixed, - ): IDisposable { + onDidChangeStatus(callback) { return this._sharedMembers.emitter.on('did-change-status', callback); } - observeBookmarks(): Observable> { - return this._sharedMembers.bookmarks - .asObservable() - .filter(b => !b.isLoading) - .map(b => b.bookmarks); + observeBookmarks() { + return this._sharedMembers.bookmarks.asObservable().filter(b => !b.isLoading).map(b => b.bookmarks); } - observeRevisionChanges(): Observable { + observeRevisionChanges() { return this._sharedMembers.revisionsCache.observeRevisionChanges(); } - observeIsFetchingRevisions(): Observable { + observeIsFetchingRevisions() { return this._sharedMembers.revisionsCache.observeIsFetchingRevisions(); } - observeIsFetchingPathStatuses(): Observable { + observeIsFetchingPathStatuses() { return this._sharedMembers.isFetchingPathStatuses.asObservable(); } - observeRevisionStatusesChanges(): Observable { + observeRevisionStatusesChanges() { return this._sharedMembers.revisionStatusCache.observeRevisionStatusesChanges(); } - observeUncommittedStatusChanges(): HgStatusChanges { + observeUncommittedStatusChanges() { return this._sharedMembers.hgUncommittedStatusChanges; } - observeHeadStatusChanges(): HgStatusChanges { + observeHeadStatusChanges() { return this._sharedMembers.hgHeadStatusChanges; } - observeStackStatusChanges(): HgStatusChanges { + observeStackStatusChanges() { return this._sharedMembers.hgStackStatusChanges; } - _observePaneItemVisibility(item: Object): Observable { - return observePaneItemVisibility(item); + _observePaneItemVisibility(item) { + return (0, (_observePaneItemVisibility || _load_observePaneItemVisibility()).default)(item); } - observeOperationProgressChanges(): Observable { - return this._tryObserve(s => - s.observeHgOperationProgressDidChange().refCount(), - ); + observeOperationProgressChanges() { + return this._tryObserve(s => s.observeHgOperationProgressDidChange().refCount()); } - onDidChangeStatuses(callback: () => mixed): IDisposable { + onDidChangeStatuses(callback) { return this._sharedMembers.emitter.on('did-change-statuses', callback); } - onDidChangeConflictState(callback: () => mixed): IDisposable { + onDidChangeConflictState(callback) { return this._sharedMembers.emitter.on(DID_CHANGE_CONFLICT_STATE, callback); } - observeLockFiles(): Observable> { + observeLockFiles() { return this._tryObserve(s => s.observeLockFilesDidChange().refCount()); } - observeHeadRevision(): Observable { - return this.observeRevisionChanges() - .map(revisionInfoFetched => - revisionInfoFetched.revisions.find(revision => revision.isHead), - ) - .let(compact) - .distinctUntilChanged( - (prevRev, nextRev) => prevRev.hash === nextRev.hash, - ); + observeHeadRevision() { + return this.observeRevisionChanges().map(revisionInfoFetched => revisionInfoFetched.revisions.find(revision => revision.isHead)).let((_observable || _load_observable()).compact).distinctUntilChanged((prevRev, nextRev) => prevRev.hash === nextRev.hash); } /** @@ -544,107 +373,98 @@ export class HgRepositoryClient { * */ - getType(): string { + getType() { return 'hg'; } - getPath(): string { + getPath() { return this._sharedMembers.path; } - getWorkingDirectory(): string { + getWorkingDirectory() { return this._sharedMembers.workingDirectory.getPath(); } // @return The path of the root project folder in Atom that this // HgRepositoryClient provides information about. - getProjectDirectory(): string { + getProjectDirectory() { return this.getInternalProjectDirectory().getPath(); } // This function exists to be shadowed - getInternalProjectDirectory(): atom$Directory { - return nullthrows(this._sharedMembers.projectDirectory); + getInternalProjectDirectory() { + return (0, (_nullthrows || _load_nullthrows()).default)(this._sharedMembers.projectDirectory); } // TODO This is a stub. - isProjectAtRoot(): boolean { + isProjectAtRoot() { return true; } - relativize(filePath: NuclideUri): string { + relativize(filePath) { return this._sharedMembers.workingDirectory.relativize(filePath); } // TODO This is a stub. - hasBranch(branch: string): boolean { + hasBranch(branch) { return false; } /** * @return The current Hg bookmark. */ - getShortHead(filePath?: NuclideUri): string { - return ( - this._sharedMembers.bookmarks - .getValue() - .bookmarks.filter(bookmark => bookmark.active) - .map(bookmark => bookmark.bookmark)[0] || '' - ); + getShortHead(filePath) { + return this._sharedMembers.bookmarks.getValue().bookmarks.filter(bookmark => bookmark.active).map(bookmark => bookmark.bookmark)[0] || ''; } // TODO This is a stub. - isSubmodule(path: NuclideUri): boolean { + isSubmodule(path) { return false; } // TODO This is a stub. - getAheadBehindCount(reference: string, path: NuclideUri): number { + getAheadBehindCount(reference, path) { return 0; } // TODO This is a stub. - getCachedUpstreamAheadBehindCount( - path: ?NuclideUri, - ): {ahead: number, behind: number} { + getCachedUpstreamAheadBehindCount(path) { return { ahead: 0, - behind: 0, + behind: 0 }; } // TODO This is a stub. - getConfigValue(key: string, path: ?string): ?string { + getConfigValue(key, path) { return null; } - getOriginURL(path: ?string): ?string { + getOriginURL(path) { return this._sharedMembers.originURL; } // TODO This is a stub. - getUpstreamBranch(path: ?string): ?string { + getUpstreamBranch(path) { return null; } // TODO This is a stub. - getReferences( - path: ?NuclideUri, - ): {heads: Array, remotes: Array, tags: Array} { + getReferences(path) { return { heads: [], remotes: [], - tags: [], + tags: [] }; } // TODO This is a stub. - getReferenceTarget(reference: string, path: ?NuclideUri): ?string { + getReferenceTarget(reference, path) { return null; } // Added for conflict detection. - isInConflict(): boolean { + isInConflict() { return this._sharedMembers.isInConflict; } @@ -656,7 +476,7 @@ export class HgRepositoryClient { // TODO (jessicalin) Can we change the API to make this method return a Promise? // If not, might need to do a synchronous `hg status` query. - isPathModified(filePath: ?NuclideUri): boolean { + isPathModified(filePath) { // flowlint-next-line sketchy-null-string:off if (!filePath) { return false; @@ -671,7 +491,7 @@ export class HgRepositoryClient { // TODO (jessicalin) Can we change the API to make this method return a Promise? // If not, might need to do a synchronous `hg status` query. - isPathNew(filePath: ?NuclideUri): boolean { + isPathNew(filePath) { // flowlint-next-line sketchy-null-string:off if (!filePath) { return false; @@ -684,7 +504,7 @@ export class HgRepositoryClient { } } - isPathAdded(filePath: ?NuclideUri): boolean { + isPathAdded(filePath) { // flowlint-next-line sketchy-null-string:off if (!filePath) { return false; @@ -697,7 +517,7 @@ export class HgRepositoryClient { } } - isPathUntracked(filePath: ?NuclideUri): boolean { + isPathUntracked(filePath) { // flowlint-next-line sketchy-null-string:off if (!filePath) { return false; @@ -713,7 +533,7 @@ export class HgRepositoryClient { // TODO (jessicalin) Can we change the API to make this method return a Promise? // If not, this method lies a bit by using cached information. // TODO (jessicalin) Make this work for ignored directories. - isPathIgnored(filePath: ?NuclideUri): boolean { + isPathIgnored(filePath) { // flowlint-next-line sketchy-null-string:off if (!filePath) { return false; @@ -733,55 +553,46 @@ export class HgRepositoryClient { /** * Checks if the given path is within the repo directory (i.e. `.hg/`). */ - _isPathWithinHgRepo(filePath: NuclideUri): boolean { - return ( - filePath === this.getPath() || - filePath.indexOf(this.getPath() + '/') === 0 - ); + _isPathWithinHgRepo(filePath) { + return filePath === this.getPath() || filePath.indexOf(this.getPath() + '/') === 0; } /** * Checks whether a path is relevant to this HgRepositoryClient. A path is * defined as 'relevant' if it is within the project directory opened within the repo. */ - isPathRelevant(filePath: NuclideUri): boolean { - return ( - this.getInternalProjectDirectory().contains(filePath) || - this.getInternalProjectDirectory().getPath() === filePath - ); + isPathRelevant(filePath) { + return this.getInternalProjectDirectory().contains(filePath) || this.getInternalProjectDirectory().getPath() === filePath; } - isPathRelevantToRepository(filePath: NuclideUri): boolean { - return ( - this._sharedMembers.workingDirectory.contains(filePath) || - this._sharedMembers.workingDirectory.getPath() === filePath - ); + isPathRelevantToRepository(filePath) { + return this._sharedMembers.workingDirectory.contains(filePath) || this._sharedMembers.workingDirectory.getPath() === filePath; } // non-used stub. - getDirectoryStatus(directoryPath: ?string): StatusCodeNumberValue { - return StatusCodeNumber.CLEAN; + getDirectoryStatus(directoryPath) { + return (_hgConstants || _load_hgConstants()).StatusCodeNumber.CLEAN; } // We don't want to do any synchronous 'hg status' calls. Just use cached values. - getPathStatus(filePath: NuclideUri): StatusCodeNumberValue { + getPathStatus(filePath) { return this.getCachedPathStatus(filePath); } - getCachedPathStatus(filePath: ?NuclideUri): StatusCodeNumberValue { + getCachedPathStatus(filePath) { // flowlint-next-line sketchy-null-string:off if (!filePath) { - return StatusCodeNumber.CLEAN; + return (_hgConstants || _load_hgConstants()).StatusCodeNumber.CLEAN; } const cachedStatus = this._sharedMembers.hgStatusCache.get(filePath); if (cachedStatus) { return cachedStatus; } - return StatusCodeNumber.CLEAN; + return (_hgConstants || _load_hgConstants()).StatusCodeNumber.CLEAN; } // getAllPathStatuses -- this legacy API gets only uncommitted statuses - getAllPathStatuses(): {[filePath: NuclideUri]: StatusCodeNumberValue} { + getAllPathStatuses() { const pathStatuses = Object.create(null); for (const [filePath, status] of this._sharedMembers.hgStatusCache) { pathStatuses[filePath] = status; @@ -790,32 +601,28 @@ export class HgRepositoryClient { return pathStatuses; } - isStatusModified(status: ?number): boolean { - return status === StatusCodeNumber.MODIFIED; + isStatusModified(status) { + return status === (_hgConstants || _load_hgConstants()).StatusCodeNumber.MODIFIED; } - isStatusDeleted(status: ?number): boolean { - return ( - status === StatusCodeNumber.MISSING || status === StatusCodeNumber.REMOVED - ); + isStatusDeleted(status) { + return status === (_hgConstants || _load_hgConstants()).StatusCodeNumber.MISSING || status === (_hgConstants || _load_hgConstants()).StatusCodeNumber.REMOVED; } - isStatusNew(status: ?number): boolean { - return ( - status === StatusCodeNumber.ADDED || status === StatusCodeNumber.UNTRACKED - ); + isStatusNew(status) { + return status === (_hgConstants || _load_hgConstants()).StatusCodeNumber.ADDED || status === (_hgConstants || _load_hgConstants()).StatusCodeNumber.UNTRACKED; } - isStatusAdded(status: ?number): boolean { - return status === StatusCodeNumber.ADDED; + isStatusAdded(status) { + return status === (_hgConstants || _load_hgConstants()).StatusCodeNumber.ADDED; } - isStatusUntracked(status: ?number): boolean { - return status === StatusCodeNumber.UNTRACKED; + isStatusUntracked(status) { + return status === (_hgConstants || _load_hgConstants()).StatusCodeNumber.UNTRACKED; } - isStatusIgnored(status: ?number): boolean { - return status === StatusCodeNumber.IGNORED; + isStatusIgnored(status) { + return status === (_hgConstants || _load_hgConstants()).StatusCodeNumber.IGNORED; } /** @@ -824,27 +631,25 @@ export class HgRepositoryClient { * */ - setDiffInfo(filePath: NuclideUri, diffInfo: DiffInfo): void { + setDiffInfo(filePath, diffInfo) { if (this.isPathRelevantToRepository(filePath)) { this._sharedMembers.bufferDiffsFromHeadCache.set(filePath, diffInfo); } } - deleteDiffInfo(filePath: NuclideUri): void { + deleteDiffInfo(filePath) { this._sharedMembers.bufferDiffsFromHeadCache.delete(filePath); } - clearAllDiffInfo(): void { + clearAllDiffInfo() { this._sharedMembers.bufferDiffsFromHeadCache.clear(); } - getDiffStats(filePath: NuclideUri): {added: number, deleted: number} { - return ( - this._sharedMembers.bufferDiffsFromHeadCache.get(filePath) || { - added: 0, - deleted: 0, - } - ); + getDiffStats(filePath) { + return this._sharedMembers.bufferDiffsFromHeadCache.get(filePath) || { + added: 0, + deleted: 0 + }; } /** @@ -857,7 +662,7 @@ export class HgRepositoryClient { // TODO (tjfryan): diff gutters is a pull-based API, but we calculate diffs in a // push-based way. This can lead to some cases like committing changes // sometimes won't clear gutters until changes are made to the buffer - getLineDiffs(filePath: NuclideUri, text: ?string): Array { + getLineDiffs(filePath, text) { const diffInfo = this._sharedMembers.bufferDiffsFromHeadCache.get(filePath); return diffInfo != null ? diffInfo.lineDiffs : []; } @@ -868,24 +673,13 @@ export class HgRepositoryClient { * */ - fetchMergeConflicts(): Observable { - return this._sharedMembers.service - .fetchMergeConflicts(this._sharedMembers.workingDirectoryPath) - .refCount(); + fetchMergeConflicts() { + return this._sharedMembers.service.fetchMergeConflicts(this._sharedMembers.workingDirectoryPath).refCount(); } - markConflictedFile( - filePath: NuclideUri, - resolved: boolean, - ): Observable { + markConflictedFile(filePath, resolved) { // TODO(T17463635) - return this._sharedMembers.service - .markConflictedFile( - this._sharedMembers.workingDirectoryPath, - filePath, - resolved, - ) - .refCount(); + return this._sharedMembers.service.markConflictedFile(this._sharedMembers.workingDirectoryPath, filePath, resolved).refCount(); } /** @@ -898,87 +692,39 @@ export class HgRepositoryClient { * That extends the `GitRepository` implementation which takes a single file path. * Here, it's possible to pass an array of file paths to revert/checkout-head. */ - checkoutHead(filePathsArg: NuclideUri | Array): Promise { - const filePaths = Array.isArray(filePathsArg) - ? filePathsArg - : [filePathsArg]; - return this._sharedMembers.service.revert( - this._sharedMembers.workingDirectoryPath, - filePaths, - ); - } - - checkoutReference( - reference: string, - create: boolean, - options?: CheckoutOptions, - ): Observable { + checkoutHead(filePathsArg) { + const filePaths = Array.isArray(filePathsArg) ? filePathsArg : [filePathsArg]; + return this._sharedMembers.service.revert(this._sharedMembers.workingDirectoryPath, filePaths); + } + + checkoutReference(reference, create, options) { // TODO(T17463635) - return this._sharedMembers.service - .checkout( - this._sharedMembers.workingDirectoryPath, - reference, - create, - options, - ) - .refCount(); - } - - show(revision: number): Observable { - return this._sharedMembers.service - .show(this._sharedMembers.workingDirectoryPath, revision) - .refCount(); - } - - diff( - revision: number | string, - options: { - // diffCommitted uses the -c flag instead of -r, fetches committed changes - // '--unified n' gives us n lines of context around the change - // '--noprefix' omits the a/ and b/ prefixes from filenames - // '--nodates' avoids appending dates to the file path line - unified?: number, - diffCommitted?: boolean, - noPrefix?: boolean, - noDates?: boolean, - } = {}, - ): Observable { - const {unified, diffCommitted, noPrefix, noDates} = options; - return this._sharedMembers.service - .diff( - this._sharedMembers.workingDirectoryPath, - String(revision), - unified, - diffCommitted, - noPrefix, - noDates, - ) - .refCount(); - } - - purge(): Promise { - return this._sharedMembers.service.purge( - this._sharedMembers.workingDirectoryPath, - ); - } - - stripReference(reference: string): Promise { - return this._sharedMembers.service.strip( - this._sharedMembers.workingDirectoryPath, - reference, - ); - } - - uncommit(): Promise { - return this._sharedMembers.service.uncommit( - this._sharedMembers.workingDirectoryPath, - ); - } - - checkoutForkBase(): Promise { - return this._sharedMembers.service.checkoutForkBase( - this._sharedMembers.workingDirectoryPath, - ); + return this._sharedMembers.service.checkout(this._sharedMembers.workingDirectoryPath, reference, create, options).refCount(); + } + + show(revision) { + return this._sharedMembers.service.show(this._sharedMembers.workingDirectoryPath, revision).refCount(); + } + + diff(revision, options = {}) { + const { unified, diffCommitted, noPrefix, noDates } = options; + return this._sharedMembers.service.diff(this._sharedMembers.workingDirectoryPath, String(revision), unified, diffCommitted, noPrefix, noDates).refCount(); + } + + purge() { + return this._sharedMembers.service.purge(this._sharedMembers.workingDirectoryPath); + } + + stripReference(reference) { + return this._sharedMembers.service.strip(this._sharedMembers.workingDirectoryPath, reference); + } + + uncommit() { + return this._sharedMembers.service.uncommit(this._sharedMembers.workingDirectoryPath); + } + + checkoutForkBase() { + return this._sharedMembers.service.checkoutForkBase(this._sharedMembers.workingDirectoryPath); } /** @@ -986,27 +732,16 @@ export class HgRepositoryClient { * Section: Bookmarks * */ - createBookmark(name: string, revision: ?string): Promise { - return this._sharedMembers.service.createBookmark( - this._sharedMembers.workingDirectoryPath, - name, - revision, - ); + createBookmark(name, revision) { + return this._sharedMembers.service.createBookmark(this._sharedMembers.workingDirectoryPath, name, revision); } - deleteBookmark(name: string): Promise { - return this._sharedMembers.service.deleteBookmark( - this._sharedMembers.workingDirectoryPath, - name, - ); + deleteBookmark(name) { + return this._sharedMembers.service.deleteBookmark(this._sharedMembers.workingDirectoryPath, name); } - renameBookmark(name: string, nextName: string): Promise { - return this._sharedMembers.service.renameBookmark( - this._sharedMembers.workingDirectoryPath, - name, - nextName, - ); + renameBookmark(name, nextName) { + return this._sharedMembers.service.renameBookmark(this._sharedMembers.workingDirectoryPath, name, nextName); } /** @@ -1020,139 +755,90 @@ export class HgRepositoryClient { * Section: Repository State at Specific Revisions * */ - fetchFileContentAtRevision( - filePath: NuclideUri, - revision: string, - ): Observable { - let fileContentsAtRevision = this._sharedMembers.fileContentsAtRevisionIds.get( - revision, - ); + fetchFileContentAtRevision(filePath, revision) { + let fileContentsAtRevision = this._sharedMembers.fileContentsAtRevisionIds.get(revision); if (fileContentsAtRevision == null) { fileContentsAtRevision = new Map(); - this._sharedMembers.fileContentsAtRevisionIds.set( - revision, - fileContentsAtRevision, - ); + this._sharedMembers.fileContentsAtRevisionIds.set(revision, fileContentsAtRevision); } const committedContents = fileContentsAtRevision.get(filePath); if (committedContents != null) { - return Observable.of(committedContents); + return _rxjsBundlesRxMinJs.Observable.of(committedContents); } else { - return this._sharedMembers.service - .fetchFileContentAtRevision( - this._sharedMembers.workingDirectoryPath, - filePath, - revision, - ) - .refCount() - .do(contents => fileContentsAtRevision.set(filePath, contents)); + return this._sharedMembers.service.fetchFileContentAtRevision(this._sharedMembers.workingDirectoryPath, filePath, revision).refCount().do(contents => fileContentsAtRevision.set(filePath, contents)); } } - fetchMultipleFilesContentAtRevision( - filePaths: Array, - revision: string, - ): Observable> { + fetchMultipleFilesContentAtRevision(filePaths, revision) { return this.runCommand(['cat', '-Tjson', ...filePaths]).map(JSON.parse); } - fetchFilesChangedAtRevision( - revision: string, - ): Observable { + fetchFilesChangedAtRevision(revision) { const changes = this._sharedMembers.revisionIdToFileChanges.get(revision); if (changes != null) { - return Observable.of(changes); + return _rxjsBundlesRxMinJs.Observable.of(changes); } else { - return this._sharedMembers.service - .fetchFilesChangedAtRevision( - this._sharedMembers.workingDirectoryPath, - revision, - ) - .refCount() - .do(fetchedChanges => - this._sharedMembers.revisionIdToFileChanges.set( - revision, - fetchedChanges, - ), - ); + return this._sharedMembers.service.fetchFilesChangedAtRevision(this._sharedMembers.workingDirectoryPath, revision).refCount().do(fetchedChanges => this._sharedMembers.revisionIdToFileChanges.set(revision, fetchedChanges)); } } - fetchFilesChangedSinceRevision( - revision: string, - ): Observable> { - return this._sharedMembers.service - .fetchStatuses(this._sharedMembers.workingDirectoryPath, revision) - .refCount() - .map(fileStatuses => { - const statusesWithCodeIds = new Map(); - for (const [filePath, code] of fileStatuses) { - statusesWithCodeIds.set(filePath, StatusCodeIdToNumber[code]); - } - return statusesWithCodeIds; - }); + fetchFilesChangedSinceRevision(revision) { + return this._sharedMembers.service.fetchStatuses(this._sharedMembers.workingDirectoryPath, revision).refCount().map(fileStatuses => { + const statusesWithCodeIds = new Map(); + for (const [filePath, code] of fileStatuses) { + statusesWithCodeIds.set(filePath, (_hgConstants || _load_hgConstants()).StatusCodeIdToNumber[code]); + } + return statusesWithCodeIds; + }); } - fetchRevisionInfoBetweenHeadAndBase(): Promise> { - return this._sharedMembers.service.fetchRevisionInfoBetweenHeadAndBase( - this._sharedMembers.workingDirectoryPath, - ); + fetchRevisionInfoBetweenHeadAndBase() { + return this._sharedMembers.service.fetchRevisionInfoBetweenHeadAndBase(this._sharedMembers.workingDirectoryPath); } - fetchSmartlogRevisions(): Observable> { - return this._sharedMembers.service - .fetchSmartlogRevisions(this._sharedMembers.workingDirectoryPath) - .refCount(); + fetchSmartlogRevisions() { + return this._sharedMembers.service.fetchSmartlogRevisions(this._sharedMembers.workingDirectoryPath).refCount(); } - refreshRevisions(): void { + refreshRevisions() { this._sharedMembers.revisionsCache.refreshRevisions(); } - refreshRevisionsStatuses(): void { + refreshRevisionsStatuses() { this._sharedMembers.revisionStatusCache.refresh(); } - getCachedRevisions(): Array { + getCachedRevisions() { return this._sharedMembers.revisionsCache.getCachedRevisions().revisions; } - getCachedRevisionStatuses(): RevisionStatuses { + getCachedRevisionStatuses() { return this._sharedMembers.revisionStatusCache.getCachedRevisionStatuses(); } // See HgService.getBaseRevision. - getBaseRevision(): Promise { - return this._sharedMembers.service.getBaseRevision( - this._sharedMembers.workingDirectoryPath, - ); + getBaseRevision() { + return this._sharedMembers.service.getBaseRevision(this._sharedMembers.workingDirectoryPath); } // See HgService.getBlameAtHead. - getBlameAtHead(filePath: NuclideUri): Promise> { - return this._sharedMembers.service.getBlameAtHead( - this._sharedMembers.workingDirectoryPath, - filePath, - ); + getBlameAtHead(filePath) { + return this._sharedMembers.service.getBlameAtHead(this._sharedMembers.workingDirectoryPath, filePath); } - getTemplateCommitMessage(): Promise { - return this._sharedMembers.service.getTemplateCommitMessage( - this._sharedMembers.workingDirectoryPath, - ); + getTemplateCommitMessage() { + return this._sharedMembers.service.getTemplateCommitMessage(this._sharedMembers.workingDirectoryPath); } - getHeadCommitMessage(): Promise { - return this._sharedMembers.service.getHeadCommitMessage( - this._sharedMembers.workingDirectoryPath, - ); + getHeadCommitMessage() { + return this._sharedMembers.service.getHeadCommitMessage(this._sharedMembers.workingDirectoryPath); } /** * Return relative paths to status code number values object. * matching `GitRepositoryAsync` implementation. */ - getCachedPathStatuses(): {[filePath: string]: StatusCodeNumberValue} { + getCachedPathStatuses() { const absoluteCodePaths = this.getAllPathStatuses(); const relativeCodePaths = {}; for (const absolutePath in absoluteCodePaths) { @@ -1162,229 +848,114 @@ export class HgRepositoryClient { return relativeCodePaths; } - getConfigValueAsync(key: string, path: ?string): Promise { - return this._sharedMembers.service.getConfigValueAsync( - this._sharedMembers.workingDirectoryPath, - key, - ); + getConfigValueAsync(key, path) { + return this._sharedMembers.service.getConfigValueAsync(this._sharedMembers.workingDirectoryPath, key); } // See HgService.getDifferentialRevisionForChangeSetId. - getDifferentialRevisionForChangeSetId(changeSetId: string): Promise { - return this._sharedMembers.service.getDifferentialRevisionForChangeSetId( - this._sharedMembers.workingDirectoryPath, - changeSetId, - ); - } - - getSmartlog(ttyOutput: boolean, concise: boolean): Promise { - return this._sharedMembers.service.getSmartlog( - this._sharedMembers.workingDirectoryPath, - ttyOutput, - concise, - ); - } - - copy( - filePaths: Array, - destPath: NuclideUri, - after: boolean = false, - ): Promise { - return this._sharedMembers.service.copy( - this._sharedMembers.workingDirectoryPath, - filePaths, - destPath, - after, - ); - } - - rename( - filePaths: Array, - destPath: NuclideUri, - after: boolean = false, - ): Promise { - return this._sharedMembers.service.rename( - this._sharedMembers.workingDirectoryPath, - filePaths, - destPath, - after, - ); - } - - remove(filePaths: Array, after: boolean = false): Promise { - return this._sharedMembers.service.remove( - this._sharedMembers.workingDirectoryPath, - filePaths, - after, - ); - } - - forget(filePaths: Array): Promise { - return this._sharedMembers.service.forget( - this._sharedMembers.workingDirectoryPath, - filePaths, - ); - } - - addAll(filePaths: Array): Promise { - return this._sharedMembers.service.add( - this._sharedMembers.workingDirectoryPath, - filePaths, - ); - } - - commit( - message: string, - filePaths: Array = [], - ): Observable { + getDifferentialRevisionForChangeSetId(changeSetId) { + return this._sharedMembers.service.getDifferentialRevisionForChangeSetId(this._sharedMembers.workingDirectoryPath, changeSetId); + } + + getSmartlog(ttyOutput, concise) { + return this._sharedMembers.service.getSmartlog(this._sharedMembers.workingDirectoryPath, ttyOutput, concise); + } + + copy(filePaths, destPath, after = false) { + return this._sharedMembers.service.copy(this._sharedMembers.workingDirectoryPath, filePaths, destPath, after); + } + + rename(filePaths, destPath, after = false) { + return this._sharedMembers.service.rename(this._sharedMembers.workingDirectoryPath, filePaths, destPath, after); + } + + remove(filePaths, after = false) { + return this._sharedMembers.service.remove(this._sharedMembers.workingDirectoryPath, filePaths, after); + } + + forget(filePaths) { + return this._sharedMembers.service.forget(this._sharedMembers.workingDirectoryPath, filePaths); + } + + addAll(filePaths) { + return this._sharedMembers.service.add(this._sharedMembers.workingDirectoryPath, filePaths); + } + + commit(message, filePaths = []) { // TODO(T17463635) - return this._sharedMembers.service - .commit(this._sharedMembers.workingDirectoryPath, message, filePaths) - .refCount() - .do(processMessage => - this._clearOnSuccessExit(processMessage, filePaths), - ); - } - - amend( - message: ?string, - amendMode: AmendModeValue, - filePaths: Array = [], - ): Observable { + return this._sharedMembers.service.commit(this._sharedMembers.workingDirectoryPath, message, filePaths).refCount().do(processMessage => this._clearOnSuccessExit(processMessage, filePaths)); + } + + amend(message, amendMode, filePaths = []) { // TODO(T17463635) - return this._sharedMembers.service - .amend( - this._sharedMembers.workingDirectoryPath, - message, - amendMode, - filePaths, - ) - .refCount() - .do(processMessage => - this._clearOnSuccessExit(processMessage, filePaths), - ); - } - - restack(): Observable { - return this._sharedMembers.service - .restack(this._sharedMembers.workingDirectoryPath) - .refCount(); - } - - editCommitMessage( - revision: string, - message: string, - ): Observable { - return this._sharedMembers.service - .editCommitMessage( - this._sharedMembers.workingDirectoryPath, - revision, - message, - ) - .refCount(); - } - - _clearOnSuccessExit( - message: LegacyProcessMessage, - filePaths: Array, - ) { + return this._sharedMembers.service.amend(this._sharedMembers.workingDirectoryPath, message, amendMode, filePaths).refCount().do(processMessage => this._clearOnSuccessExit(processMessage, filePaths)); + } + + restack() { + return this._sharedMembers.service.restack(this._sharedMembers.workingDirectoryPath).refCount(); + } + + editCommitMessage(revision, message) { + return this._sharedMembers.service.editCommitMessage(this._sharedMembers.workingDirectoryPath, revision, message).refCount(); + } + + _clearOnSuccessExit(message, filePaths) { if (message.kind === 'exit' && message.exitCode === 0) { this._clearClientCache(filePaths); } } - revert(filePaths: Array, toRevision?: ?string): Promise { - return this._sharedMembers.service.revert( - this._sharedMembers.workingDirectoryPath, - filePaths, - toRevision, - ); + revert(filePaths, toRevision) { + return this._sharedMembers.service.revert(this._sharedMembers.workingDirectoryPath, filePaths, toRevision); } - log(filePaths: Array, limit?: ?number): Promise { + log(filePaths, limit) { // TODO(mbolin): Return an Observable so that results appear faster. // Unfortunately, `hg log -Tjson` is not Observable-friendly because it will // not parse as JSON until all of the data has been printed to stdout. - return this._sharedMembers.service.log( - this._sharedMembers.workingDirectoryPath, - filePaths, - limit, - ); + return this._sharedMembers.service.log(this._sharedMembers.workingDirectoryPath, filePaths, limit); } - getFullHashForRevision(rev: string): Promise { - return this._sharedMembers.service.getFullHashForRevision( - this._sharedMembers.workingDirectoryPath, - rev, - ); + getFullHashForRevision(rev) { + return this._sharedMembers.service.getFullHashForRevision(this._sharedMembers.workingDirectoryPath, rev); } - continueOperation( - commandWithOptions: Array, - ): Observable { + continueOperation(commandWithOptions) { // TODO(T17463635) - return this._sharedMembers.service - .continueOperation( - this._sharedMembers.workingDirectoryPath, - commandWithOptions, - ) - .refCount(); + return this._sharedMembers.service.continueOperation(this._sharedMembers.workingDirectoryPath, commandWithOptions).refCount(); } - abortOperation(commandWithOptions: Array): Observable { - return this._sharedMembers.service - .abortOperation( - this._sharedMembers.workingDirectoryPath, - commandWithOptions, - ) - .refCount(); + abortOperation(commandWithOptions) { + return this._sharedMembers.service.abortOperation(this._sharedMembers.workingDirectoryPath, commandWithOptions).refCount(); } - resolveAllFiles(): Observable { - return this._sharedMembers.service - .resolveAllFiles(this._sharedMembers.workingDirectoryPath) - .refCount(); + resolveAllFiles() { + return this._sharedMembers.service.resolveAllFiles(this._sharedMembers.workingDirectoryPath).refCount(); } - rebase( - destination: string, - source?: string, - ): Observable { + rebase(destination, source) { // TODO(T17463635) - return this._sharedMembers.service - .rebase(this._sharedMembers.workingDirectoryPath, destination, source) - .refCount(); + return this._sharedMembers.service.rebase(this._sharedMembers.workingDirectoryPath, destination, source).refCount(); } - reorderWithinStack(orderedRevisions: Array): Observable { - return this._sharedMembers.service - .reorderWithinStack( - this._sharedMembers.workingDirectoryPath, - orderedRevisions, - ) - .refCount(); + reorderWithinStack(orderedRevisions) { + return this._sharedMembers.service.reorderWithinStack(this._sharedMembers.workingDirectoryPath, orderedRevisions).refCount(); } - pull(options?: Array = []): Observable { + pull(options = []) { // TODO(T17463635) - return this._sharedMembers.service - .pull(this._sharedMembers.workingDirectoryPath, options) - .refCount(); + return this._sharedMembers.service.pull(this._sharedMembers.workingDirectoryPath, options).refCount(); } - fold(from: string, to: string, message: string): Observable { - return this._sharedMembers.service - .fold(this._sharedMembers.workingDirectoryPath, from, to, message) - .refCount(); + fold(from, to, message) { + return this._sharedMembers.service.fold(this._sharedMembers.workingDirectoryPath, from, to, message).refCount(); } - _clearClientCache(filePaths: Array): void { + _clearClientCache(filePaths) { if (filePaths.length === 0) { this._sharedMembers.hgStatusCache = new Map(); } else { - this._sharedMembers.hgStatusCache = new Map( - this._sharedMembers.hgStatusCache, - ); + this._sharedMembers.hgStatusCache = new Map(this._sharedMembers.hgStatusCache); filePaths.forEach(filePath => { this._sharedMembers.hgStatusCache.delete(filePath); }); @@ -1392,19 +963,16 @@ export class HgRepositoryClient { this._sharedMembers.emitter.emit('did-change-statuses'); } - requestPathStatusRefresh(): void { + requestPathStatusRefresh() { this._sharedMembers.manualStatusRefreshRequests.next(); } - runCommand(args: Array): Observable { - return this._sharedMembers.service - .runCommand(this._sharedMembers.workingDirectoryPath, args) - .refCount(); + runCommand(args) { + return this._sharedMembers.service.runCommand(this._sharedMembers.workingDirectoryPath, args).refCount(); } - observeExecution(args: Array): Observable { - return this._sharedMembers.service - .observeExecution(this._sharedMembers.workingDirectoryPath, args) - .refCount(); + observeExecution(args) { + return this._sharedMembers.service.observeExecution(this._sharedMembers.workingDirectoryPath, args).refCount(); } } +exports.HgRepositoryClient = HgRepositoryClient; \ No newline at end of file diff --git a/pkg/nuclide-hg-repository-client/lib/RevisionsCache.js b/pkg/nuclide-hg-repository-client/lib/RevisionsCache.js index 26a546a65e..586d25aa8b 100644 --- a/pkg/nuclide-hg-repository-client/lib/RevisionsCache.js +++ b/pkg/nuclide-hg-repository-client/lib/RevisionsCache.js @@ -1,3 +1,29 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _observable; + +function _load_observable() { + return _observable = require('../../../modules/nuclide-commons/observable'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,18 +31,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {RevisionInfoFetched} from '../../nuclide-hg-rpc/lib/HgService'; -import typeof * as HgService from '../../nuclide-hg-rpc/lib/HgService'; - -import {arrayEqual} from 'nuclide-commons/collection'; -import {fastDebounce} from 'nuclide-commons/observable'; -import {BehaviorSubject, Observable, Subject, TimeoutError} from 'rxjs'; -import {getLogger} from 'log4js'; - const FETCH_REVISIONS_DEBOUNCE_MS = 100; // The request timeout is 60 seconds anyways. const FETCH_REVISIONS_TIMEOUT_MS = 50 * 1000; @@ -26,17 +44,14 @@ const FETCH_REVISIONS_RETRY_COUNT = 2; // That's because commit ids are unique and incremental. // Also, any write operation will update them. // That way, we guarantee we only update the revisions state if the revisions are changed. -function isEqualRevisions( - revisionsFetched1: RevisionInfoFetched, - revisionsFetched2: RevisionInfoFetched, -): boolean { +function isEqualRevisions(revisionsFetched1, revisionsFetched2) { const { revisions: revisions1, - fromFilesystem: fromFilesystem1, + fromFilesystem: fromFilesystem1 } = revisionsFetched1; const { revisions: revisions2, - fromFilesystem: fromFilesystem2, + fromFilesystem: fromFilesystem2 } = revisionsFetched2; const areBothFromFileSystem = fromFilesystem1 === fromFilesystem2; if (revisions1 === revisions2 && areBothFromFileSystem) { @@ -45,91 +60,62 @@ function isEqualRevisions( if (revisions1 == null || revisions2 == null) { return false; } - return ( - areBothFromFileSystem && - arrayEqual(revisions1, revisions2, (revision1, revision2) => { - return ( - revision1.id === revision2.id && - revision1.isHead === revision2.isHead && - arrayEqual(revision1.tags, revision2.tags) && - arrayEqual(revision1.bookmarks, revision2.bookmarks) - ); - }) - ); + return areBothFromFileSystem && (0, (_collection || _load_collection()).arrayEqual)(revisions1, revisions2, (revision1, revision2) => { + return revision1.id === revision2.id && revision1.isHead === revision2.isHead && (0, (_collection || _load_collection()).arrayEqual)(revision1.tags, revision2.tags) && (0, (_collection || _load_collection()).arrayEqual)(revision1.bookmarks, revision2.bookmarks); + }); } -export default class RevisionsCache { - _workingDirectory: string; - _revisions: BehaviorSubject; - _lazyRevisionFetcher: Observable; - _fetchRevisionsRequests: Subject; - _isFetchingRevisions: Subject; - _service: HgService; +class RevisionsCache { - constructor(workingDirectory: string, service: HgService) { + constructor(workingDirectory, service) { this._workingDirectory = workingDirectory; - this._revisions = new BehaviorSubject({ + this._revisions = new _rxjsBundlesRxMinJs.BehaviorSubject({ revisions: [], - fromFilesystem: false, + fromFilesystem: false }); - this._fetchRevisionsRequests = new Subject(); - this._isFetchingRevisions = new Subject(); + this._fetchRevisionsRequests = new _rxjsBundlesRxMinJs.Subject(); + this._isFetchingRevisions = new _rxjsBundlesRxMinJs.Subject(); this._service = service; - this._lazyRevisionFetcher = this._fetchRevisionsRequests - .startWith(null) // Initially, no refresh requests applied. - .let(fastDebounce(FETCH_REVISIONS_DEBOUNCE_MS)) - .switchMap(() => - // Using `defer` will guarantee a fresh subscription / execution on retries, - // even though `_fetchSmartlogRevisions` returns a `refCount`ed shared Observable. - Observable.defer(() => this._fetchSmartlogRevisions()) - .retry(FETCH_REVISIONS_RETRY_COUNT) - .catch(error => { - getLogger('nuclide-hg-repository-client').error( - 'RevisionsCache Error:', - error, - ); - // Failed to fetch smartlog, timeout and return an empty array - return Observable.of({revisions: [], fromFilesystem: true}); - }), - ) - .distinctUntilChanged(isEqualRevisions) - .do(revisions => this._revisions.next(revisions)) - // $FlowFixMe - .shareReplay(1); + this._lazyRevisionFetcher = this._fetchRevisionsRequests.startWith(null) // Initially, no refresh requests applied. + .let((0, (_observable || _load_observable()).fastDebounce)(FETCH_REVISIONS_DEBOUNCE_MS)).switchMap(() => + // Using `defer` will guarantee a fresh subscription / execution on retries, + // even though `_fetchSmartlogRevisions` returns a `refCount`ed shared Observable. + _rxjsBundlesRxMinJs.Observable.defer(() => this._fetchSmartlogRevisions()).retry(FETCH_REVISIONS_RETRY_COUNT).catch(error => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-repository-client').error('RevisionsCache Error:', error); + // Failed to fetch smartlog, timeout and return an empty array + return _rxjsBundlesRxMinJs.Observable.of({ revisions: [], fromFilesystem: true }); + })).distinctUntilChanged(isEqualRevisions).do(revisions => this._revisions.next(revisions)) + // $FlowFixMe + .shareReplay(1); } - _fetchSmartlogRevisions(): Observable { + _fetchSmartlogRevisions() { this._isFetchingRevisions.next(true); - return this._service - .fetchSmartlogRevisions(this._workingDirectory) - .refCount() - .map(revisions => ({revisions, fromFilesystem: true})) - .timeout(FETCH_REVISIONS_TIMEOUT_MS) - .catch(err => { - if (err instanceof TimeoutError) { - throw new Error('Timed out fetching smartlog revisions'); - } - throw err; - }) - .finally(() => { - this._isFetchingRevisions.next(false); - }); + return this._service.fetchSmartlogRevisions(this._workingDirectory).refCount().map(revisions => ({ revisions, fromFilesystem: true })).timeout(FETCH_REVISIONS_TIMEOUT_MS).catch(err => { + if (err instanceof _rxjsBundlesRxMinJs.TimeoutError) { + throw new Error('Timed out fetching smartlog revisions'); + } + throw err; + }).finally(() => { + this._isFetchingRevisions.next(false); + }); } - refreshRevisions(): void { + refreshRevisions() { this._fetchRevisionsRequests.next(null); } - getCachedRevisions(): RevisionInfoFetched { + getCachedRevisions() { return this._revisions.getValue(); } - observeRevisionChanges(): Observable { + observeRevisionChanges() { return this._lazyRevisionFetcher.startWith(this.getCachedRevisions()); } - observeIsFetchingRevisions(): Observable { + observeIsFetchingRevisions() { return this._isFetchingRevisions.asObservable(); } } +exports.default = RevisionsCache; \ No newline at end of file diff --git a/pkg/nuclide-hg-repository-client/lib/main.js b/pkg/nuclide-hg-repository-client/lib/main.js index c55ec7b1a3..43a444d621 100644 --- a/pkg/nuclide-hg-repository-client/lib/main.js +++ b/pkg/nuclide-hg-repository-client/lib/main.js @@ -1,14 +1,23 @@ -/** - * 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 strict-local - * @format - */ - -import {HgRepositoryClient} from './HgRepositoryClient'; - -export {HgRepositoryClient}; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.HgRepositoryClient = undefined; + +var _HgRepositoryClient; + +function _load_HgRepositoryClient() { + return _HgRepositoryClient = require('./HgRepositoryClient'); +} + +exports.HgRepositoryClient = (_HgRepositoryClient || _load_HgRepositoryClient()).HgRepositoryClient; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-hg-repository-client/spec/HgRepositoryClient-spec.js b/pkg/nuclide-hg-repository-client/spec/HgRepositoryClient-spec.js deleted file mode 100644 index dbaf3c80c8..0000000000 --- a/pkg/nuclide-hg-repository-client/spec/HgRepositoryClient-spec.js +++ /dev/null @@ -1,357 +0,0 @@ -/** - * 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 - */ - -import typeof * as HgServiceType from '../../nuclide-hg-rpc/lib/HgService'; - -import {Directory} from 'atom'; -import {HgRepositoryClient} from '../lib/HgRepositoryClient'; -import MockHgService from '../../nuclide-hg-rpc/__mocks__/MockHgService'; -import {StatusCodeNumber} from '../../nuclide-hg-rpc/lib/hg-constants'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {Observable} from 'rxjs'; -import temp from 'temp'; - -temp.track(); - -describe('HgRepositoryClient', () => { - const tempDir = temp.mkdirSync('testproj'); - const tempSubDir = temp.mkdirSync({dir: tempDir}); - - const repoPath = nuclideUri.join(tempDir, '.hg'); - const workingDirectory = new Directory(tempDir); - const projectDirectory = new Directory(tempSubDir); - const repoOptions = { - originURL: 'http://test.com/testproj', - workingDirectory, - projectRootDirectory: projectDirectory, - }; - - // Manufactures the absolute path of a file that should pass as being - // within the repo. - const createFilePath = filename => { - return nuclideUri.join(projectDirectory.getPath(), filename); - }; - - // Some test "absolute" paths. - const PATH_1 = createFilePath('test1.js'); - const PATH_2 = createFilePath('test2.js'); - const PATH_3 = createFilePath('test3.js'); - const PATH_4 = createFilePath('test4.js'); - const PATH_5 = createFilePath('test5.js'); - const PATH_6 = createFilePath('test6.js'); - const PATH_7 = createFilePath('test7.js'); - const PATH_CALLED_NULL = createFilePath('null'); - const PATH_CALLED_UNDEFINED = createFilePath('undefined'); - - let mockHgService: HgServiceType = (null: any); - let repo: HgRepositoryClient = (null: any); - - beforeEach(() => { - mockHgService = ((new MockHgService(): any): HgServiceType); - repo = new HgRepositoryClient(repoPath, mockHgService, repoOptions); - }); - - describe('::getType()', () => { - it('returns "hg"', () => { - expect(repo.getType()).toBe('hg'); - }); - }); - - describe('::getProjectDirectory', () => { - it( - 'returns the path of the root project folder in Atom that this Client provides information' + - ' about.', - () => { - expect(repo.getProjectDirectory()).toBe(projectDirectory.getPath()); - }, - ); - }); - - describe('::isPathIgnored', () => { - it('returns true if the path is marked ignored in the cache.', () => { - // Force the state of the cache. - repo._sharedMembers.hgStatusCache = new Map([ - [PATH_1, StatusCodeNumber.IGNORED], - ]); - expect(repo.isPathIgnored(PATH_1)).toBe(true); - }); - - it('returns true if the path is, or is within, the .hg directory.', () => { - expect(repo.isPathIgnored(repoPath)).toBe(true); - expect(repo.isPathIgnored(nuclideUri.join(repoPath, 'blah'))).toBe(true); - }); - - it('returns false if the path is not in the cache and is not the .hg directory.', () => { - expect(repo.isPathIgnored('/A/Random/Path')).toBe(false); - const parsedPath = nuclideUri.parsePath(repoPath); - expect(repo.isPathIgnored(parsedPath.root)).toBe(false); - expect(repo.isPathIgnored(parsedPath.dir)).toBe(false); - }); - - it( - 'returns false if the path is null or undefined, but handles files with those' + - ' names.', - () => { - // Force the state of the cache. - repo._sharedMembers.hgStatusCache = new Map([ - [PATH_CALLED_NULL, StatusCodeNumber.IGNORED], - [PATH_CALLED_UNDEFINED, StatusCodeNumber.IGNORED], - ]); - expect(repo.isPathIgnored(null)).toBe(false); - expect(repo.isPathIgnored(undefined)).toBe(false); - expect(repo.isPathIgnored(PATH_CALLED_NULL)).toBe(true); - expect(repo.isPathIgnored(PATH_CALLED_UNDEFINED)).toBe(true); - }, - ); - }); - - describe('::isPathNew', () => { - it( - 'returns false if the path is null or undefined, but handles files with those' + - ' names.', - () => { - // Force the state of the cache. - repo._sharedMembers.hgStatusCache = new Map([ - [PATH_CALLED_NULL, StatusCodeNumber.ADDED], - [PATH_CALLED_UNDEFINED, StatusCodeNumber.ADDED], - ]); - expect(repo.isPathNew(null)).toBe(false); - expect(repo.isPathNew(undefined)).toBe(false); - expect(repo.isPathNew(PATH_CALLED_NULL)).toBe(true); - expect(repo.isPathNew(PATH_CALLED_UNDEFINED)).toBe(true); - }, - ); - }); - - describe('::isPathModified', () => { - it( - 'returns false if the path is null or undefined, but handles files with those' + - ' names.', - () => { - // Force the state of the cache. - repo._sharedMembers.hgStatusCache = new Map([ - [PATH_CALLED_NULL, StatusCodeNumber.MODIFIED], - [PATH_CALLED_UNDEFINED, StatusCodeNumber.MODIFIED], - ]); - expect(repo.isPathModified(null)).toBe(false); - expect(repo.isPathModified(undefined)).toBe(false); - expect(repo.isPathModified(PATH_CALLED_NULL)).toBe(true); - expect(repo.isPathModified(PATH_CALLED_UNDEFINED)).toBe(true); - }, - ); - }); - - describe('::isPathAdded', () => { - it( - 'returns false if the path is null, untracked, modified or deleted' + - ' names.', - () => { - // Force the state of the cache. - repo._sharedMembers.hgStatusCache = new Map([ - [PATH_CALLED_NULL, StatusCodeNumber.ADDED], - [PATH_CALLED_UNDEFINED, StatusCodeNumber.ADDED], - [PATH_1, StatusCodeNumber.ADDED], - [PATH_2, StatusCodeNumber.CLEAN], - [PATH_3, StatusCodeNumber.IGNORED], - [PATH_4, StatusCodeNumber.MISSING], - [PATH_5, StatusCodeNumber.MODIFIED], - [PATH_6, StatusCodeNumber.REMOVED], - [PATH_7, StatusCodeNumber.UNTRACKED], - ]); - expect(repo.isPathAdded(null)).toBe(false); - expect(repo.isPathAdded(undefined)).toBe(false); - expect(repo.isPathAdded(PATH_CALLED_NULL)).toBe(true); - expect(repo.isPathAdded(PATH_CALLED_UNDEFINED)).toBe(true); - expect(repo.isPathAdded(PATH_1)).toBe(true); - expect(repo.isPathAdded(PATH_2)).toBe(false); - expect(repo.isPathAdded(PATH_3)).toBe(false); - expect(repo.isPathAdded(PATH_4)).toBe(false); - expect(repo.isPathAdded(PATH_5)).toBe(false); - expect(repo.isPathAdded(PATH_6)).toBe(false); - expect(repo.isPathAdded(PATH_7)).toBe(false); - }, - ); - }); - - describe('::isPathUntracked', () => { - it( - 'returns false if the path is null, untracked, modified or deleted' + - ' names.', - () => { - // Force the state of the cache. - repo._sharedMembers.hgStatusCache = new Map([ - [PATH_CALLED_NULL, StatusCodeNumber.UNTRACKED], - [PATH_CALLED_UNDEFINED, StatusCodeNumber.UNTRACKED], - [PATH_1, StatusCodeNumber.UNTRACKED], - [PATH_2, StatusCodeNumber.CLEAN], - [PATH_3, StatusCodeNumber.IGNORED], - [PATH_4, StatusCodeNumber.MISSING], - [PATH_5, StatusCodeNumber.MODIFIED], - [PATH_6, StatusCodeNumber.REMOVED], - [PATH_7, StatusCodeNumber.ADDED], - ]); - expect(repo.isPathUntracked(null)).toBe(false); - expect(repo.isPathUntracked(undefined)).toBe(false); - expect(repo.isPathUntracked(PATH_CALLED_NULL)).toBe(true); - expect(repo.isPathUntracked(PATH_CALLED_UNDEFINED)).toBe(true); - expect(repo.isPathUntracked(PATH_1)).toBe(true); - expect(repo.isPathUntracked(PATH_2)).toBe(false); - expect(repo.isPathUntracked(PATH_3)).toBe(false); - expect(repo.isPathUntracked(PATH_4)).toBe(false); - expect(repo.isPathUntracked(PATH_5)).toBe(false); - expect(repo.isPathUntracked(PATH_6)).toBe(false); - expect(repo.isPathUntracked(PATH_7)).toBe(false); - }, - ); - }); - - describe('::getCachedPathStatus', () => { - beforeEach(() => { - repo._sharedMembers.hgStatusCache = new Map([ - [PATH_1, StatusCodeNumber.MODIFIED], - [PATH_2, StatusCodeNumber.IGNORED], - ]); - }); - - it('retrieves cached hg status.', () => { - // Force the state of the cache. - const status = repo.getCachedPathStatus(PATH_1); - expect(repo.isStatusModified(status)).toBe(true); - expect(repo.isStatusNew(status)).toBe(false); - }); - - it('retrieves cached hg ignore status.', () => { - const status = repo.getCachedPathStatus(PATH_2); - // The status codes have no meaning; just test the expected translated - // meanings. - expect(repo.isStatusModified(status)).toBe(false); - expect(repo.isStatusNew(status)).toBe(false); - }); - - it('returns a clean status by default.', () => { - const status = repo.getCachedPathStatus('path-not-in-cache'); - // The status codes have no meaning; just test the expected translated - // meanings. - expect(repo.isStatusModified(status)).toBe(false); - expect(repo.isStatusNew(status)).toBe(false); - }); - }); - - describe('the hgDiffCache', () => { - beforeEach(() => { - // Unfortunately, when the temp files in these tests are opened in the editor, - // editor.getPath() returns the original file path with '/private/' appended - // to it. Thus, the path returned from editor.getPath() (which is what is - // used in HgRepository) would fail a real 'contains' method. So we override - // this to the expected path. - featureConfig.set('nuclide-hg-repository.enableDiffStats', true); - const workingDirectoryClone = new Directory(tempDir); - spyOn(workingDirectory, 'contains').andCallFake(filePath => { - const prefix = '/private'; - if (filePath.startsWith(prefix)) { - const prefixRemovedPath = filePath.slice(prefix.length); - return workingDirectoryClone.contains(prefixRemovedPath); - } - return workingDirectoryClone.contains(filePath); - }); - - const projectDirectoryClone = new Directory(tempSubDir); - spyOn(projectDirectory, 'contains').andCallFake(filePath => { - const prefix = '/private'; - if (filePath.startsWith(prefix)) { - const prefixRemovedPath = filePath.slice(prefix.length); - return projectDirectoryClone.contains(prefixRemovedPath); - } - return projectDirectoryClone.contains(filePath); - }); - - spyOn(repo, '_updateDiffInfo').andReturn(Observable.of('fake')); - spyOn(repo, '_observePaneItemVisibility').andReturn(Observable.of(true)); - }); - }); - - describe('::_updateDiffInfo', () => { - const mockDiffInfo = { - added: 2, - deleted: 11, - lineDiffs: [ - { - oldStart: 150, - oldLines: 11, - newStart: 150, - newLines: 2, - }, - ], - }; - - beforeEach(() => { - spyOn(repo, '_getCurrentHeadId').andReturn(Observable.of('test')); - spyOn( - repo._sharedMembers.service, - 'fetchFileContentAtRevision', - ).andCallFake(filePath => { - return new Observable.of('test').publish(); - }); - spyOn(repo, '_getFileDiffs').andCallFake(pathsToFetch => { - const diffs = []; - for (const filePath of pathsToFetch) { - diffs.push([filePath, mockDiffInfo]); - } - return Observable.of(diffs); - }); - spyOn(workingDirectory, 'contains').andCallFake(() => { - return true; - }); - }); - }); - - describe('::getCachedPathStatus/::getPathStatus', () => { - it('handles a null or undefined input "path" but handles paths with those names.', () => { - // Force the state of the cache. - repo._sharedMembers.hgStatusCache = new Map([ - [PATH_CALLED_NULL, StatusCodeNumber.MODIFIED], - [PATH_CALLED_UNDEFINED, StatusCodeNumber.MODIFIED], - ]); - expect(repo.getCachedPathStatus(null)).toBe(StatusCodeNumber.CLEAN); - expect(repo.getCachedPathStatus(undefined)).toBe(StatusCodeNumber.CLEAN); - expect(repo.getCachedPathStatus(PATH_CALLED_NULL)).toBe( - StatusCodeNumber.MODIFIED, - ); - expect(repo.getCachedPathStatus(PATH_CALLED_UNDEFINED)).toBe( - StatusCodeNumber.MODIFIED, - ); - }); - }); - - describe('::isStatusModified', () => { - it('returns false for a null or undefined input.', () => { - expect(repo.isStatusModified(null)).toBe(false); - expect(repo.isStatusModified(undefined)).toBe(false); - }); - }); - - describe('::isStatusNew', () => { - it('returns false for a null or undefined input.', () => { - expect(repo.isStatusNew(null)).toBe(false); - expect(repo.isStatusNew(undefined)).toBe(false); - }); - }); - - describe('::destroy', () => { - it('should do cleanup without throwing an exception.', () => { - const spy = jasmine.createSpy(); - repo.onDidDestroy(spy); - repo.destroy(); - expect(spy).toHaveBeenCalled(); - }); - }); -}); diff --git a/pkg/nuclide-hg-repository/lib/HgRepositoryProvider.js b/pkg/nuclide-hg-repository/lib/HgRepositoryProvider.js index 81aa62a5ee..48caf983f9 100644 --- a/pkg/nuclide-hg-repository/lib/HgRepositoryProvider.js +++ b/pkg/nuclide-hg-repository/lib/HgRepositoryProvider.js @@ -1,32 +1,59 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _atom = require('atom'); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} -import {Directory} from 'atom'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {trackTiming} from '../../nuclide-analytics'; -import { - RemoteDirectory, - getHgServiceByNuclideUri, -} from '../../nuclide-remote-connection'; -import {HgRepositoryClient} from '../../nuclide-hg-repository-client'; -import {getLogger} from 'log4js'; -import {findHgRepository} from '../../nuclide-source-control-helpers'; -import invariant from 'assert'; - -const logger = getLogger('nuclide-hg-repository'); - -type RefCountedRepo = { - refCount: number, - repo: HgRepositoryClient, -}; +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideHgRepositoryClient; + +function _load_nuclideHgRepositoryClient() { + return _nuclideHgRepositoryClient = require('../../nuclide-hg-repository-client'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _nuclideSourceControlHelpers; + +function _load_nuclideSourceControlHelpers() { + return _nuclideSourceControlHelpers = require('../../nuclide-source-control-helpers'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-repository'); /** + * 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. + * + * strict-local + * @format + */ /** * @param directory Either a RemoteDirectory or Directory we are interested in. @@ -40,67 +67,59 @@ type RefCountedRepo = { * repository (i.e. if it's a remote directory, the URI minus the hostname). * If the directory is not part of a Mercurial repository, returns null. */ -function getRepositoryDescription( - directory: atom$Directory | RemoteDirectory, -): ?{ - originURL: ?string, - repoPath: string, - workingDirectory: atom$Directory | RemoteDirectory, -} { - if (directory instanceof RemoteDirectory) { +function getRepositoryDescription(directory) { + if (directory instanceof (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).RemoteDirectory) { const repositoryDescription = directory.getHgRepositoryDescription(); - if ( - repositoryDescription == null || - repositoryDescription.repoPath == null - ) { + if (repositoryDescription == null || repositoryDescription.repoPath == null) { return null; } const serverConnection = directory._server; - const {repoPath, originURL, workingDirectoryPath} = repositoryDescription; + const { repoPath, originURL, workingDirectoryPath } = repositoryDescription; const workingDirectoryLocalPath = workingDirectoryPath; // These paths are all relative to the remote fs. We need to turn these into URIs. const repoUri = serverConnection.getUriOfRemotePath(repoPath); - const workingDirectoryUri = serverConnection.getUriOfRemotePath( - workingDirectoryPath, - ); + const workingDirectoryUri = serverConnection.getUriOfRemotePath(workingDirectoryPath); return { originURL, repoPath: repoUri, workingDirectory: serverConnection.createDirectory(workingDirectoryUri), - workingDirectoryLocalPath, + workingDirectoryLocalPath }; } else { - const repositoryDescription = findHgRepository(directory.getPath()); + const repositoryDescription = (0, (_nuclideSourceControlHelpers || _load_nuclideSourceControlHelpers()).findHgRepository)(directory.getPath()); if (repositoryDescription == null) { return null; } - const {repoPath, originURL, workingDirectoryPath} = repositoryDescription; + const { repoPath, originURL, workingDirectoryPath } = repositoryDescription; return { originURL, repoPath, - workingDirectory: new Directory(workingDirectoryPath), + workingDirectory: new _atom.Directory(workingDirectoryPath) }; } } -export default class HgRepositoryProvider { +class HgRepositoryProvider { + constructor() { + this._activeRepositoryClients = new Map(); + } // Allow having multiple project roots under the same repo while sharing // the underlying HgRepositoryClient. - _activeRepositoryClients: Map = new Map(); - repositoryForDirectory(directory: Directory): Promise { + + repositoryForDirectory(directory) { return Promise.resolve(this.repositoryForDirectorySync(directory)); } - repositoryForDirectorySync(directory: Directory): ?HgRepositoryClient { - return trackTiming('hg-repository.repositoryForDirectorySync', () => { + repositoryForDirectorySync(directory) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)('hg-repository.repositoryForDirectorySync', () => { try { const repositoryDescription = getRepositoryDescription(directory); if (!repositoryDescription) { return null; } - const {originURL, repoPath, workingDirectory} = repositoryDescription; + const { originURL, repoPath, workingDirectory } = repositoryDescription; // extend the underlying instance of HgRepositoryClient to prevent // having multiple clients for multiple project roots inside the same @@ -111,31 +130,34 @@ export default class HgRepositoryProvider { if (activeRepoClientInfo != null) { activeRepoClientInfo.refCount++; } else { - const hgService = getHgServiceByNuclideUri(directory.getPath()); - const activeRepoClient = new HgRepositoryClient(repoPath, hgService, { + const hgService = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getHgServiceByNuclideUri)(directory.getPath()); + const activeRepoClient = new (_nuclideHgRepositoryClient || _load_nuclideHgRepositoryClient()).HgRepositoryClient(repoPath, hgService, { workingDirectory, - originURL, + originURL }); activeRepoClientInfo = { refCount: 1, - repo: activeRepoClient, + repo: activeRepoClient }; activeRepositoryClients.set(repoPath, activeRepoClientInfo); } let destroyed = false; - const localDisposables = new UniversalDisposable(); + const localDisposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); /* eslint-disable no-inner-declarations */ function ProjectHgRepositoryClient() { - this.getInternalProjectDirectory = function(): atom$Directory { + this.getInternalProjectDirectory = function () { return directory; }; - this.destroy = function(): void { - invariant(activeRepoClientInfo != null); + this.destroy = function () { + if (!(activeRepoClientInfo != null)) { + throw new Error('Invariant violation: "activeRepoClientInfo != null"'); + } + if (!destroyed && --activeRepoClientInfo.refCount === 0) { destroyed = true; activeRepoClientInfo.repo.destroy(); @@ -147,12 +169,12 @@ export default class HgRepositoryProvider { // Allow consumers to use `onDidDestroy` for the ProjectRepos. // `getRootRepo()` can be used to add an onDidDestroy for the base // repo - this.onDidDestroy = function(callback: () => mixed): IDisposable { + this.onDidDestroy = function (callback) { localDisposables.add(callback); return { dispose() { localDisposables.remove(callback); - }, + } }; }; } @@ -160,16 +182,12 @@ export default class HgRepositoryProvider { ProjectHgRepositoryClient.prototype = activeRepoClientInfo.repo; // $FlowFixMe: this object has an HgRepositoryClient instance in its prototype chain - return ((new ProjectHgRepositoryClient(): any): HgRepositoryClient); + return new ProjectHgRepositoryClient(); } catch (err) { - logger.error( - 'Failed to create an HgRepositoryClient for ', - directory.getPath(), - ', error: ', - err, - ); + logger.error('Failed to create an HgRepositoryClient for ', directory.getPath(), ', error: ', err); return null; } }); } } +exports.default = HgRepositoryProvider; \ No newline at end of file diff --git a/pkg/nuclide-hg-repository/lib/main.js b/pkg/nuclide-hg-repository/lib/main.js index fcfb50f857..f81477b222 100644 --- a/pkg/nuclide-hg-repository/lib/main.js +++ b/pkg/nuclide-hg-repository/lib/main.js @@ -1,69 +1,79 @@ -/** - * 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 - */ - -import type {DeadlineRequest} from 'nuclide-commons/promise'; -import type FileTreeContextMenu from '../../nuclide-file-tree/lib/FileTreeContextMenu'; -import type {HgRepositoryClient} from '../../nuclide-hg-repository-client'; -import type { - AdditionalLogFile, - AdditionalLogFilesProvider, -} from '../../nuclide-logging/lib/rpc-types'; - -import invariant from 'assert'; -import { - arrayCompact, - mapTransform, - collect, - arrayFlatten, -} from 'nuclide-commons/collection'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import registerGrammar from '../../commons-atom/register-grammar'; -import {repositoryForPath} from '../../nuclide-vcs-base'; -import {addPath, confirmAndRevertPath} from '../../nuclide-vcs-base'; -import HgRepositoryProvider from './HgRepositoryProvider'; - -const HG_ADD_TREE_CONTEXT_MENU_PRIORITY = 400; -const HG_REVERT_FILE_TREE_CONTEXT_MENU_PRIORITY = 1050; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.activate = activate; +exports.addItemsToFileTreeContextMenu = addItemsToFileTreeContextMenu; +exports.deactivate = deactivate; +exports.createHgRepositoryProvider = createHgRepositoryProvider; +exports.createHgAdditionalLogFilesProvider = createHgAdditionalLogFilesProvider; + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} -let subscriptions: ?UniversalDisposable = null; +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _registerGrammar; + +function _load_registerGrammar() { + return _registerGrammar = _interopRequireDefault(require('../../commons-atom/register-grammar')); +} -type HgContenxtMenuAction = 'Revert' | 'Add'; +var _nuclideVcsBase; + +function _load_nuclideVcsBase() { + return _nuclideVcsBase = require('../../nuclide-vcs-base'); +} + +var _HgRepositoryProvider; + +function _load_HgRepositoryProvider() { + return _HgRepositoryProvider = _interopRequireDefault(require('./HgRepositoryProvider')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const HG_ADD_TREE_CONTEXT_MENU_PRIORITY = 400; /** + * 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. + * + * + * @format + */ + +const HG_REVERT_FILE_TREE_CONTEXT_MENU_PRIORITY = 1050; + +let subscriptions = null; // A file is revertable if it's changed or added. // A file is addable if it's untracked. // A directory is revertable if it contains changed files. -function shouldDisplayActionTreeItem( - contextMenu: FileTreeContextMenu, - action: HgContenxtMenuAction, -): boolean { +function shouldDisplayActionTreeItem(contextMenu, action) { if (action === 'Revert') { const node = contextMenu.getSingleSelectedNode(); if (node == null || node.repo == null || node.repo.getType() !== 'hg') { return false; } else { - const hgRepository: HgRepositoryClient = (node.repo: any); - return ( - hgRepository.isStatusModified(node.vcsStatusCode) || - hgRepository.isStatusAdded(node.vcsStatusCode) - ); + const hgRepository = node.repo; + return hgRepository.isStatusModified(node.vcsStatusCode) || hgRepository.isStatusAdded(node.vcsStatusCode); } } else if (action === 'Add') { const nodes = contextMenu.getSelectedNodes(); return nodes.every(node => { - if ( - node.repo == null || - node.repo.getType() !== 'hg' || - // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - typeof node.repo.isStatusUntracked !== 'function' - ) { + if (node.repo == null || node.repo.getType() !== 'hg' || + // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) + typeof node.repo.isStatusUntracked !== 'function') { return false; } return node.repo.isStatusUntracked(node.vcsStatusCode); @@ -73,143 +83,113 @@ function shouldDisplayActionTreeItem( } } -function getActivePathAndHgRepository(): ?{ - activePath: string, - repository: HgRepositoryClient, -} { +function getActivePathAndHgRepository() { const editor = atom.workspace.getActiveTextEditor(); if (editor == null || !editor.getPath()) { return null; } const filePath = editor.getPath() || ''; - const repository = repositoryForPath(filePath); + const repository = (0, (_nuclideVcsBase || _load_nuclideVcsBase()).repositoryForPath)(filePath); if (repository == null || repository.getType() !== 'hg') { return null; } - const hgRepository: HgRepositoryClient = (repository: any); + const hgRepository = repository; return { repository: hgRepository, - activePath: filePath, + activePath: filePath }; } -function isActivePathRevertable(): boolean { +function isActivePathRevertable() { const activeRepositoryInfo = getActivePathAndHgRepository(); if (activeRepositoryInfo == null) { return false; } - const {repository, activePath} = activeRepositoryInfo; + const { repository, activePath } = activeRepositoryInfo; return repository.isPathModified(activePath); } -function isActivePathAddable(): boolean { +function isActivePathAddable() { const activeRepositoryInfo = getActivePathAndHgRepository(); if (activeRepositoryInfo == null) { return false; } - const {repository, activePath} = activeRepositoryInfo; + const { repository, activePath } = activeRepositoryInfo; return repository.isPathUntracked(activePath); } -export function activate(state: any): void { - subscriptions = new UniversalDisposable(); - - subscriptions.add( - atom.commands.add( - 'atom-text-editor', - 'nuclide-hg-repository:confirm-and-revert', - event => { - const editorElement: atom$TextEditorElement = (event.currentTarget: any); - confirmAndRevertPath(editorElement.getModel().getPath()); - }, - ), - ); - - subscriptions.add( - atom.commands.add( - 'atom-text-editor', - 'nuclide-hg-repository:add', - event => { - const editorElement: atom$TextEditorElement = (event.currentTarget: any); - addPath(editorElement.getModel().getPath()); - }, - ), - ); +function activate(state) { + subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + + subscriptions.add(atom.commands.add('atom-text-editor', 'nuclide-hg-repository:confirm-and-revert', event => { + const editorElement = event.currentTarget; + (0, (_nuclideVcsBase || _load_nuclideVcsBase()).confirmAndRevertPath)(editorElement.getModel().getPath()); + })); + + subscriptions.add(atom.commands.add('atom-text-editor', 'nuclide-hg-repository:add', event => { + const editorElement = event.currentTarget; + (0, (_nuclideVcsBase || _load_nuclideVcsBase()).addPath)(editorElement.getModel().getPath()); + })); // Text editor context menu items. - subscriptions.add( - atom.contextMenu.add({ - 'atom-text-editor': [ - {type: 'separator'}, - { - label: 'Source Control', - submenu: [ - { - label: 'Revert', - command: 'nuclide-hg-repository:confirm-and-revert', - shouldDisplay() { - return isActivePathRevertable(); - }, - }, - { - label: 'Add to Mercurial', - command: 'nuclide-hg-repository:add', - shouldDisplay() { - return isActivePathAddable(); - }, - }, - ], - shouldDisplay() { - return getActivePathAndHgRepository() != null; - }, - }, - {type: 'separator'}, - ], - }), - ); - - registerGrammar('source.ini', ['.hgrc']); + subscriptions.add(atom.contextMenu.add({ + 'atom-text-editor': [{ type: 'separator' }, { + label: 'Source Control', + submenu: [{ + label: 'Revert', + command: 'nuclide-hg-repository:confirm-and-revert', + shouldDisplay() { + return isActivePathRevertable(); + } + }, { + label: 'Add to Mercurial', + command: 'nuclide-hg-repository:add', + shouldDisplay() { + return isActivePathAddable(); + } + }], + shouldDisplay() { + return getActivePathAndHgRepository() != null; + } + }, { type: 'separator' }] + })); + + (0, (_registerGrammar || _load_registerGrammar()).default)('source.ini', ['.hgrc']); } -export function addItemsToFileTreeContextMenu( - contextMenu: FileTreeContextMenu, -): IDisposable { - invariant(subscriptions); - - const revertContextDisposable = contextMenu.addItemToSourceControlMenu( - { - label: 'Revert', - callback() { - // TODO(most): support reverting multiple nodes at once. - const revertNode = contextMenu.getSingleSelectedNode(); - confirmAndRevertPath(revertNode == null ? null : revertNode.uri); - }, - shouldDisplay() { - return shouldDisplayActionTreeItem(contextMenu, 'Revert'); - }, +function addItemsToFileTreeContextMenu(contextMenu) { + if (!subscriptions) { + throw new Error('Invariant violation: "subscriptions"'); + } + + const revertContextDisposable = contextMenu.addItemToSourceControlMenu({ + label: 'Revert', + callback() { + // TODO(most): support reverting multiple nodes at once. + const revertNode = contextMenu.getSingleSelectedNode(); + (0, (_nuclideVcsBase || _load_nuclideVcsBase()).confirmAndRevertPath)(revertNode == null ? null : revertNode.uri); }, - HG_REVERT_FILE_TREE_CONTEXT_MENU_PRIORITY, - ); + shouldDisplay() { + return shouldDisplayActionTreeItem(contextMenu, 'Revert'); + } + }, HG_REVERT_FILE_TREE_CONTEXT_MENU_PRIORITY); subscriptions.add(revertContextDisposable); - const addContextDisposable = contextMenu.addItemToSourceControlMenu( - { - label: 'Add to Mercurial', - callback() { - const nodes = contextMenu.getSelectedNodes(); - for (const addNode of nodes) { - addPath(addNode == null ? null : addNode.uri); - } - }, - shouldDisplay() { - return shouldDisplayActionTreeItem(contextMenu, 'Add'); - }, + const addContextDisposable = contextMenu.addItemToSourceControlMenu({ + label: 'Add to Mercurial', + callback() { + const nodes = contextMenu.getSelectedNodes(); + for (const addNode of nodes) { + (0, (_nuclideVcsBase || _load_nuclideVcsBase()).addPath)(addNode == null ? null : addNode.uri); + } }, - HG_ADD_TREE_CONTEXT_MENU_PRIORITY, - ); + shouldDisplay() { + return shouldDisplayActionTreeItem(contextMenu, 'Add'); + } + }, HG_ADD_TREE_CONTEXT_MENU_PRIORITY); subscriptions.add(addContextDisposable); - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { if (subscriptions != null) { subscriptions.remove(revertContextDisposable); subscriptions.remove(addContextDisposable); @@ -217,51 +197,35 @@ export function addItemsToFileTreeContextMenu( }); } -export function deactivate(state: any): void { +function deactivate(state) { if (subscriptions != null) { subscriptions.dispose(); subscriptions = null; } } -export function createHgRepositoryProvider() { - return new HgRepositoryProvider(); +function createHgRepositoryProvider() { + return new (_HgRepositoryProvider || _load_HgRepositoryProvider()).default(); } -async function getAllHgAdditionalLogFiles( - deadline: DeadlineRequest, -): Promise> { +async function getAllHgAdditionalLogFiles(deadline) { // Atom provides one repository object per project. - const repositories: Array = atom.project.getRepositories(); + const repositories = atom.project.getRepositories(); // We want to avoid duplication in the case where two different projects both // are served by the same repository path. // Start by transforming into an array of [path, HgRepositoryClient] pairs. - const hgRepositories: Array<[string, HgRepositoryClient]> = arrayCompact( - repositories.map( - r => - r != null && r.getType() === 'hg' - ? [r.getWorkingDirectory(), ((r: any): HgRepositoryClient)] - : null, - ), - ); + const hgRepositories = (0, (_collection || _load_collection()).arrayCompact)(repositories.map(r => r != null && r.getType() === 'hg' ? [r.getWorkingDirectory(), r] : null)); // For each repository path, arbitrarily pick just the first of the // HgRepositoryClients that serves that path. - const uniqueRepositories: Array = Array.from( - mapTransform( - collect(hgRepositories), - (clients, dir) => clients[0], - ).values(), - ); - - const results: Array> = await Promise.all( - uniqueRepositories.map(r => r.getAdditionalLogFiles(deadline)), - ); - return arrayFlatten(results); + const uniqueRepositories = Array.from((0, (_collection || _load_collection()).mapTransform)((0, (_collection || _load_collection()).collect)(hgRepositories), (clients, dir) => clients[0]).values()); + + const results = await Promise.all(uniqueRepositories.map(r => r.getAdditionalLogFiles(deadline))); + return (0, (_collection || _load_collection()).arrayFlatten)(results); } -export function createHgAdditionalLogFilesProvider(): AdditionalLogFilesProvider { +function createHgAdditionalLogFilesProvider() { return { id: 'hg', - getAdditionalLogFiles: getAllHgAdditionalLogFiles, + getAdditionalLogFiles: getAllHgAdditionalLogFiles }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-hg-repository/spec/HgRepositoryProvider-spec.js b/pkg/nuclide-hg-repository/spec/HgRepositoryProvider-spec.js deleted file mode 100644 index 97376b282f..0000000000 --- a/pkg/nuclide-hg-repository/spec/HgRepositoryProvider-spec.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * 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 - */ - -import {Directory} from 'atom'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import HgRepositoryProvider from '../lib/HgRepositoryProvider'; -import invariant from 'assert'; -import {runCommand} from 'nuclide-commons/process'; -import {generateFixture} from 'nuclide-commons/test-helpers'; -import fsPromise from 'nuclide-commons/fsPromise'; - -describe('HgRepositoryProvider', () => { - const provider = new HgRepositoryProvider(); - it('shares underlying repository for multiple directories in the same repo', () => { - waitsForPromise({timeout: 30000}, async () => { - const tempDir = await generateFixture( - 'hg_repo_provider_test', - new Map([['folder/foo', 'foo']]), - ); - - const repoPath = await fsPromise.realpath(tempDir); - await runCommand('hg', ['init'], {cwd: repoPath}).toPromise(); - - const folderPath = nuclideUri.join(repoPath, 'folder'); - - const baseDirectory = new Directory(repoPath); - const folderDirectory = new Directory(folderPath); - - const baseRepo = provider.repositoryForDirectorySync(baseDirectory); - const folderRepo = provider.repositoryForDirectorySync(folderDirectory); - invariant(baseRepo != null && folderRepo != null); - - expect(baseRepo.getProjectDirectory()).not.toBe( - folderRepo.getProjectDirectory(), - ); - - // compare private members to guarantee they have the same underlying HgRepositoryClient - // arbitrarily chose _emitter - expect(baseRepo.getRootRepoClient()).toBe(folderRepo.getRootRepoClient()); - - let folderRepoDestroyed = false; - let folderRepoRootDestroyed = false; - folderRepo.onDidDestroy(() => { - folderRepoDestroyed = true; - }); - folderRepo.getRootRepoClient().onDidDestroy(() => { - folderRepoRootDestroyed = true; - }); - folderRepo.destroy(); - expect(folderRepoDestroyed).toBe(true); - expect(folderRepoRootDestroyed).toBe(false); - - const folderRepo2 = provider.repositoryForDirectorySync(folderDirectory); - invariant(folderRepo2 != null); - expect(baseRepo.getRootRepoClient()).toBe( - folderRepo2.getRootRepoClient(), - ); - - folderRepo2.destroy(); - baseRepo.destroy(); - // refCount should hit 0 and remove the original underlying HgRepositoryClient - // thus triggering the onDidDestroy for the underlying repo - expect(folderRepoRootDestroyed).toBe(true); - - const baseRepo2 = provider.repositoryForDirectorySync(baseDirectory); - invariant(baseRepo2 != null); - expect(baseRepo.getRootRepoClient()).not.toBe( - baseRepo2.getRootRepoClient(), - ); - expect(baseRepo.getProjectDirectory()).toBe( - baseRepo2.getProjectDirectory(), - ); - - baseRepo2.destroy(); - - await fsPromise.rimraf(repoPath); - }); - }); -}); diff --git a/pkg/nuclide-hg-rpc/__mocks__/MockHgService.js b/pkg/nuclide-hg-rpc/__mocks__/MockHgService.js index bfdbd09934..340f40aeb6 100644 --- a/pkg/nuclide-hg-rpc/__mocks__/MockHgService.js +++ b/pkg/nuclide-hg-rpc/__mocks__/MockHgService.js @@ -1,99 +1,96 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); -import {ConnectableObservable, Observable, Subject} from 'rxjs'; -import type {DiffInfo, StatusCodeIdValue, BookmarkInfo} from '../lib/HgService'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); class MockHgRepositorySubscriptions { - observeFilesDidChange(): ConnectableObservable> { - return new Subject().publish(); + observeFilesDidChange() { + return new _rxjsBundlesRxMinJs.Subject().publish(); } - observeHgIgnoreFileDidChange(): ConnectableObservable { - return new Subject().publish(); + observeHgIgnoreFileDidChange() { + return new _rxjsBundlesRxMinJs.Subject().publish(); } - observeHgRepoStateDidChange(): ConnectableObservable { - return new Subject().publish(); + observeHgRepoStateDidChange() { + return new _rxjsBundlesRxMinJs.Subject().publish(); } - observeHgCommitsDidChange(): ConnectableObservable { - return new Subject().publish(); + observeHgCommitsDidChange() { + return new _rxjsBundlesRxMinJs.Subject().publish(); } - observeHgConflictStateDidChange(): ConnectableObservable { - return new Subject().publish(); + observeHgConflictStateDidChange() { + return new _rxjsBundlesRxMinJs.Subject().publish(); } - observeActiveBookmarkDidChange(): ConnectableObservable { - return new Subject().publish(); + observeActiveBookmarkDidChange() { + return new _rxjsBundlesRxMinJs.Subject().publish(); } - observeBookmarksDidChange(): ConnectableObservable { - return new Subject().publish(); + observeBookmarksDidChange() { + return new _rxjsBundlesRxMinJs.Subject().publish(); } } // This class is meant to be stubbed out. -export default class MockHgService { - createRepositorySubscriptions(): Promise { +/** + * 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. + * + * + * @format + */ + +class MockHgService { + createRepositorySubscriptions() { return Promise.resolve(new MockHgRepositorySubscriptions()); } - fetchStatuses( - filePaths: Array, - options: ?any, - ): ConnectableObservable> { - return new Subject().publish(); + fetchStatuses(filePaths, options) { + return new _rxjsBundlesRxMinJs.Subject().publish(); } - deleteBookmark(name: string): Promise { + deleteBookmark(name) { return Promise.resolve(); } - renameBookmark(name: string, nextName: string): Promise { + renameBookmark(name, nextName) { return Promise.resolve(); } - fetchDiffInfo( - filePaths: Array, - ): Promise> { + fetchDiffInfo(filePaths) { return Promise.resolve(null); } - fetchActiveBookmark(): Promise { + fetchActiveBookmark() { return Promise.resolve(''); } - fetchBookmarks(): Promise> { + fetchBookmarks() { return Promise.resolve([]); } - dispose(): Promise { + dispose() { return Promise.resolve(); } - getHeadId(): Observable { - return new Observable(); + getHeadId() { + return new _rxjsBundlesRxMinJs.Observable(); } - getFullHashForRevision(): Promise { + getFullHashForRevision() { return Promise.resolve(null); } - fetchFileContentAtRevision( - filePath: NuclideUri, - revision: string, - ): ConnectableObservable { - return new Subject().publish(); + fetchFileContentAtRevision(filePath, revision) { + return new _rxjsBundlesRxMinJs.Subject().publish(); } } +exports.default = MockHgService; \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/__mocks__/MockHgTypes.js b/pkg/nuclide-hg-rpc/__mocks__/MockHgTypes.js index 6eb7ab91a7..0a8db4cce4 100644 --- a/pkg/nuclide-hg-rpc/__mocks__/MockHgTypes.js +++ b/pkg/nuclide-hg-rpc/__mocks__/MockHgTypes.js @@ -1,18 +1,11 @@ -/** - * 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 - */ +'use strict'; -import type {RevisionInfo} from '../lib/HgService'; - -export function createMockRevisionInfo(customValues: Object): RevisionInfo { - const blankRevisionInfo: RevisionInfo = { +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.createMockRevisionInfo = createMockRevisionInfo; +function createMockRevisionInfo(customValues) { + const blankRevisionInfo = { author: '', bookmarks: [], branch: '', @@ -27,11 +20,17 @@ export function createMockRevisionInfo(customValues: Object): RevisionInfo { successorInfo: null, tags: [], title: 'foo', - files: [], + files: [] }; - return { - ...blankRevisionInfo, - ...customValues, - }; -} + return Object.assign({}, blankRevisionInfo, customValues); +} /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/__tests__/HgService-test.js b/pkg/nuclide-hg-rpc/__tests__/HgService-test.js index 41a479f8fd..71b3cc33f6 100644 --- a/pkg/nuclide-hg-rpc/__tests__/HgService-test.js +++ b/pkg/nuclide-hg-rpc/__tests__/HgService-test.js @@ -1,24 +1,34 @@ -/** - * 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 strict-local - * @format - */ - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import * as HgService from '../lib/HgService'; -import * as hgUtils from '../lib/hg-utils'; -import { - AmendMode, - StatusCodeId, - MergeConflictStatus, -} from '../lib/hg-constants'; -import invariant from 'assert'; -import {Observable, Subject} from 'rxjs'; +'use strict'; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _HgService; + +function _load_HgService() { + return _HgService = _interopRequireWildcard(require('../lib/HgService')); +} + +var _hgUtils; + +function _load_hgUtils() { + return _hgUtils = _interopRequireWildcard(require('../lib/hg-utils')); +} + +var _hgConstants; + +function _load_hgConstants() { + return _hgConstants = require('../lib/hg-constants'); +} + +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 }; } const mockOutput = ` [ @@ -83,15 +93,24 @@ const mockOutput = ` } ] } -]`; +]`; /** + * 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. + * + * strict-local + * @format + */ describe('HgService', () => { - const hgService = HgService; + const hgService = _HgService || _load_HgService(); const TEST_WORKING_DIRECTORY = '/Test/Working/Directory/'; - const PATH_1 = nuclideUri.join(TEST_WORKING_DIRECTORY, 'test1.js'); - const PATH_2 = nuclideUri.join(TEST_WORKING_DIRECTORY, 'test2.js'); - function relativize(filePath: string): string { - return nuclideUri.relative(TEST_WORKING_DIRECTORY, filePath); + const PATH_1 = (_nuclideUri || _load_nuclideUri()).default.join(TEST_WORKING_DIRECTORY, 'test1.js'); + const PATH_2 = (_nuclideUri || _load_nuclideUri()).default.join(TEST_WORKING_DIRECTORY, 'test2.js'); + function relativize(filePath) { + return (_nuclideUri || _load_nuclideUri()).default.relative(TEST_WORKING_DIRECTORY, filePath); } describe('::createBookmark', () => { @@ -100,27 +119,17 @@ describe('HgService', () => { it('calls the appropriate `hg` command to add', async () => { await (async () => { - jest.spyOn(hgUtils, 'hgAsyncExecute').mockImplementation(() => {}); + jest.spyOn(_hgUtils || _load_hgUtils(), 'hgAsyncExecute').mockImplementation(() => {}); await hgService.createBookmark(TEST_WORKING_DIRECTORY, BOOKMARK_NAME); - expect(hgUtils.hgAsyncExecute).toHaveBeenCalledWith( - ['bookmark', BOOKMARK_NAME], - {cwd: TEST_WORKING_DIRECTORY}, - ); + expect((_hgUtils || _load_hgUtils()).hgAsyncExecute).toHaveBeenCalledWith(['bookmark', BOOKMARK_NAME], { cwd: TEST_WORKING_DIRECTORY }); })(); }); it('calls the appropriate `hg` command to add with base revision', async () => { await (async () => { - jest.spyOn(hgUtils, 'hgAsyncExecute').mockImplementation(() => {}); - await hgService.createBookmark( - TEST_WORKING_DIRECTORY, - BOOKMARK_NAME, - BASE_REVISION, - ); - expect(hgUtils.hgAsyncExecute).toHaveBeenCalledWith( - ['bookmark', '--rev', BASE_REVISION, BOOKMARK_NAME], - {cwd: TEST_WORKING_DIRECTORY}, - ); + jest.spyOn(_hgUtils || _load_hgUtils(), 'hgAsyncExecute').mockImplementation(() => {}); + await hgService.createBookmark(TEST_WORKING_DIRECTORY, BOOKMARK_NAME, BASE_REVISION); + expect((_hgUtils || _load_hgUtils()).hgAsyncExecute).toHaveBeenCalledWith(['bookmark', '--rev', BASE_REVISION, BOOKMARK_NAME], { cwd: TEST_WORKING_DIRECTORY }); })(); }); }); @@ -130,12 +139,9 @@ describe('HgService', () => { it('calls the appropriate `hg` command to delete', async () => { await (async () => { - jest.spyOn(hgUtils, 'hgAsyncExecute').mockImplementation(() => {}); + jest.spyOn(_hgUtils || _load_hgUtils(), 'hgAsyncExecute').mockImplementation(() => {}); await hgService.deleteBookmark(TEST_WORKING_DIRECTORY, BOOKMARK_NAME); - expect(hgUtils.hgAsyncExecute).toHaveBeenCalledWith( - ['bookmarks', '--delete', BOOKMARK_NAME], - {cwd: TEST_WORKING_DIRECTORY}, - ); + expect((_hgUtils || _load_hgUtils()).hgAsyncExecute).toHaveBeenCalledWith(['bookmarks', '--delete', BOOKMARK_NAME], { cwd: TEST_WORKING_DIRECTORY }); })(); }); }); @@ -145,16 +151,9 @@ describe('HgService', () => { it('calls the appropriate `hg` command to rename', async () => { await (async () => { - jest.spyOn(hgUtils, 'hgAsyncExecute').mockImplementation(() => {}); - await hgService.renameBookmark( - TEST_WORKING_DIRECTORY, - BOOKMARK_NAME, - 'fried-chicken', - ); - expect(hgUtils.hgAsyncExecute).toHaveBeenCalledWith( - ['bookmarks', '--rename', BOOKMARK_NAME, 'fried-chicken'], - {cwd: TEST_WORKING_DIRECTORY}, - ); + jest.spyOn(_hgUtils || _load_hgUtils(), 'hgAsyncExecute').mockImplementation(() => {}); + await hgService.renameBookmark(TEST_WORKING_DIRECTORY, BOOKMARK_NAME, 'fried-chicken'); + expect((_hgUtils || _load_hgUtils()).hgAsyncExecute).toHaveBeenCalledWith(['bookmarks', '--rename', BOOKMARK_NAME, 'fried-chicken'], { cwd: TEST_WORKING_DIRECTORY }); })(); }); }); @@ -171,32 +170,35 @@ describe('HgService', () => { const expectedDiffInfo = { added: 2, deleted: 1, - lineDiffs: [ - { - oldStart: 150, - oldLines: 1, - newStart: 150, - newLines: 2, - }, - ], + lineDiffs: [{ + oldStart: 150, + oldLines: 1, + newStart: 150, + newLines: 2 + }] }; it('fetches the unified diff output for the given path.', async () => { // Test set up: mock out dependency on hg. - invariant(hgService); - jest - .spyOn(hgUtils, 'hgAsyncExecute') - .mockImplementation((args, options) => { - expect(args.pop()).toBe(PATH_1); - return Promise.resolve({stdout: mockHgDiffOutput}); - }); - - invariant(hgService); - const pathToDiffInfo = await hgService.fetchDiffInfo( - TEST_WORKING_DIRECTORY, - [PATH_1], - ); - invariant(pathToDiffInfo); + if (!hgService) { + throw new Error('Invariant violation: "hgService"'); + } + + jest.spyOn(_hgUtils || _load_hgUtils(), 'hgAsyncExecute').mockImplementation((args, options) => { + expect(args.pop()).toBe(PATH_1); + return Promise.resolve({ stdout: mockHgDiffOutput }); + }); + + if (!hgService) { + throw new Error('Invariant violation: "hgService"'); + } + + const pathToDiffInfo = await hgService.fetchDiffInfo(TEST_WORKING_DIRECTORY, [PATH_1]); + + if (!pathToDiffInfo) { + throw new Error('Invariant violation: "pathToDiffInfo"'); + } + expect(pathToDiffInfo.size).toBe(1); expect(pathToDiffInfo.get(PATH_1)).toEqual(expectedDiffInfo); }); @@ -204,27 +206,19 @@ describe('HgService', () => { describe('::getConfigValueAsync', () => { it('calls `hg config` with the passed key', async () => { - jest - .spyOn(hgUtils, 'hgAsyncExecute') - .mockImplementation((args, options) => { - expect(args).toEqual(['config', 'committemplate.emptymsg']); - // Return the Object shape expected by `HgServiceBase`. - return {stdout: ''}; - }); - await hgService.getConfigValueAsync( - TEST_WORKING_DIRECTORY, - 'committemplate.emptymsg', - ); + jest.spyOn(_hgUtils || _load_hgUtils(), 'hgAsyncExecute').mockImplementation((args, options) => { + expect(args).toEqual(['config', 'committemplate.emptymsg']); + // Return the Object shape expected by `HgServiceBase`. + return { stdout: '' }; + }); + await hgService.getConfigValueAsync(TEST_WORKING_DIRECTORY, 'committemplate.emptymsg'); }); it('returns `null` on errors', async () => { - jest.spyOn(hgUtils, 'hgAsyncExecute').mockImplementation(() => { + jest.spyOn(_hgUtils || _load_hgUtils(), 'hgAsyncExecute').mockImplementation(() => { throw new Error('Something failed'); }); - const config = await hgService.getConfigValueAsync( - TEST_WORKING_DIRECTORY, - 'non.existent.config', - ); + const config = await hgService.getConfigValueAsync(TEST_WORKING_DIRECTORY, 'non.existent.config'); expect(config).toBeNull(); }); }); @@ -232,21 +226,15 @@ describe('HgService', () => { describe('::rename', () => { it('can rename files', async () => { let wasCalled = false; - jest - .spyOn(hgUtils, 'hgAsyncExecute') - .mockImplementation((args, options) => { - expect(args.length).toBe(3); - expect(args.pop()).toBe('file_2.txt'); - expect(args.pop()).toBe('file_1.txt'); - expect(args.pop()).toBe('rename'); - wasCalled = true; - }); + jest.spyOn(_hgUtils || _load_hgUtils(), 'hgAsyncExecute').mockImplementation((args, options) => { + expect(args.length).toBe(3); + expect(args.pop()).toBe('file_2.txt'); + expect(args.pop()).toBe('file_1.txt'); + expect(args.pop()).toBe('rename'); + wasCalled = true; + }); await (async () => { - await hgService.rename( - TEST_WORKING_DIRECTORY, - ['file_1.txt'], - 'file_2.txt', - ); + await hgService.rename(TEST_WORKING_DIRECTORY, ['file_1.txt'], 'file_2.txt'); expect(wasCalled).toBeTruthy(); })(); }); @@ -255,15 +243,13 @@ describe('HgService', () => { describe('::remove', () => { it('can remove files', async () => { let wasCalled = false; - jest - .spyOn(hgUtils, 'hgAsyncExecute') - .mockImplementation((args, options) => { - expect(args.length).toBe(3); - expect(args.pop()).toBe('file.txt'); - expect(args.pop()).toBe('-f'); - expect(args.pop()).toBe('remove'); - wasCalled = true; - }); + jest.spyOn(_hgUtils || _load_hgUtils(), 'hgAsyncExecute').mockImplementation((args, options) => { + expect(args.length).toBe(3); + expect(args.pop()).toBe('file.txt'); + expect(args.pop()).toBe('-f'); + expect(args.pop()).toBe('remove'); + wasCalled = true; + }); await (async () => { await hgService.remove(TEST_WORKING_DIRECTORY, ['file.txt']); expect(wasCalled).toBeTruthy(); @@ -274,14 +260,12 @@ describe('HgService', () => { describe('::add', () => { it('can add files', async () => { let wasCalled = false; - jest - .spyOn(hgUtils, 'hgAsyncExecute') - .mockImplementation((args, options) => { - expect(args.length).toBe(2); - expect(args.pop()).toBe('file.txt'); - expect(args.pop()).toBe('add'); - wasCalled = true; - }); + jest.spyOn(_hgUtils || _load_hgUtils(), 'hgAsyncExecute').mockImplementation((args, options) => { + expect(args.length).toBe(2); + expect(args.pop()).toBe('file.txt'); + expect(args.pop()).toBe('add'); + wasCalled = true; + }); await hgService.add(TEST_WORKING_DIRECTORY, ['file.txt']); expect(wasCalled).toBeTruthy(); }); @@ -291,42 +275,37 @@ describe('HgService', () => { const commitMessage = 'foo\n\nbar\nbaz'; const processMessage = { kind: 'stdout', - data: 'Fake message for testing', + data: 'Fake message for testing' }; let committedToHg = false; let expectedArgs = null; beforeEach(() => { expectedArgs = null; committedToHg = false; - jest - .spyOn(hgUtils, 'hgObserveExecution') - .mockImplementation((_args, options) => { - const args = _args; - expect(expectedArgs).not.toBeNull(); - // eslint-disable-next-line eqeqeq - invariant(expectedArgs !== null); - expect(args.length).toBe( - expectedArgs.length, - `\nExpected args: [${expectedArgs.toString()}]\nActual args: [${args.toString()}]`, - ); - while (args.length > 0) { - const expectedArg = expectedArgs.pop(); - expect(args.pop()).toBe(expectedArg); - } - committedToHg = true; - return Observable.of(processMessage); - }); + jest.spyOn(_hgUtils || _load_hgUtils(), 'hgObserveExecution').mockImplementation((_args, options) => { + const args = _args; + expect(expectedArgs).not.toBeNull(); + // eslint-disable-next-line eqeqeq + + if (!(expectedArgs !== null)) { + throw new Error('Invariant violation: "expectedArgs !== null"'); + } + + expect(args.length).toBe(expectedArgs.length, `\nExpected args: [${expectedArgs.toString()}]\nActual args: [${args.toString()}]`); + while (args.length > 0) { + const expectedArg = expectedArgs.pop(); + expect(args.pop()).toBe(expectedArg); + } + committedToHg = true; + return _rxjsBundlesRxMinJs.Observable.of(processMessage); + }); }); describe('::commit', () => { it('can commit changes', async () => { expectedArgs = ['commit', '-m', commitMessage]; await (async () => { - await hgService - .commit(TEST_WORKING_DIRECTORY, commitMessage) - .refCount() - .toArray() - .toPromise(); + await hgService.commit(TEST_WORKING_DIRECTORY, commitMessage).refCount().toArray().toPromise(); expect(committedToHg).toBeTruthy(); })(); }); @@ -336,11 +315,7 @@ describe('HgService', () => { it('can amend changes with a message', async () => { expectedArgs = ['amend', '-m', commitMessage]; await (async () => { - await hgService - .amend(TEST_WORKING_DIRECTORY, commitMessage, AmendMode.CLEAN) - .refCount() - .toArray() - .toPromise(); + await hgService.amend(TEST_WORKING_DIRECTORY, commitMessage, (_hgConstants || _load_hgConstants()).AmendMode.CLEAN).refCount().toArray().toPromise(); expect(committedToHg).toBeTruthy(); })(); }); @@ -348,33 +323,21 @@ describe('HgService', () => { it('can amend changes without a message', async () => { expectedArgs = ['amend']; await (async () => { - await hgService - .amend(TEST_WORKING_DIRECTORY, null, AmendMode.CLEAN) - .refCount() - .toArray() - .toPromise(); + await hgService.amend(TEST_WORKING_DIRECTORY, null, (_hgConstants || _load_hgConstants()).AmendMode.CLEAN).refCount().toArray().toPromise(); expect(committedToHg).toBeTruthy(); })(); }); it('can amend with --rebase & a commit message', async () => { expectedArgs = ['amend', '--rebase', '-m', commitMessage]; - await hgService - .amend(TEST_WORKING_DIRECTORY, commitMessage, AmendMode.REBASE) - .refCount() - .toArray() - .toPromise(); + await hgService.amend(TEST_WORKING_DIRECTORY, commitMessage, (_hgConstants || _load_hgConstants()).AmendMode.REBASE).refCount().toArray().toPromise(); // 'Looks like commit did not happen' expect(committedToHg).toBeTruthy(); }); it('can amend with --fixup', async () => { expectedArgs = ['amend', '--fixup']; - await hgService - .amend(TEST_WORKING_DIRECTORY, null, AmendMode.FIXUP) - .refCount() - .toArray() - .toPromise(); + await hgService.amend(TEST_WORKING_DIRECTORY, null, (_hgConstants || _load_hgConstants()).AmendMode.FIXUP).refCount().toArray().toPromise(); expect(committedToHg).toBeTruthy(); }); }); @@ -383,43 +346,35 @@ describe('HgService', () => { describe('::fetchMergeConflicts', () => { it('fetches rich merge conflict data', async () => { let wasCalled = false; - jest - .spyOn(hgUtils, 'hgRunCommand') - .mockImplementation((args, options) => { - wasCalled = true; - return Observable.of(mockOutput); - }); - const mergeConflictsEnriched = await hgService - .fetchMergeConflicts(TEST_WORKING_DIRECTORY) - .refCount() - .toPromise(); + jest.spyOn(_hgUtils || _load_hgUtils(), 'hgRunCommand').mockImplementation((args, options) => { + wasCalled = true; + return _rxjsBundlesRxMinJs.Observable.of(mockOutput); + }); + const mergeConflictsEnriched = await hgService.fetchMergeConflicts(TEST_WORKING_DIRECTORY).refCount().toPromise(); expect(wasCalled).toBeTruthy(); expect(mergeConflictsEnriched).not.toBeNull(); - invariant(mergeConflictsEnriched != null); + + if (!(mergeConflictsEnriched != null)) { + throw new Error('Invariant violation: "mergeConflictsEnriched != null"'); + } + expect(mergeConflictsEnriched.conflicts.length).toBe(2); const conflicts = mergeConflictsEnriched.conflicts; - expect(conflicts[0].status).toBe(MergeConflictStatus.BOTH_CHANGED); - expect(conflicts[1].status).toBe(MergeConflictStatus.DELETED_IN_OURS); + expect(conflicts[0].status).toBe((_hgConstants || _load_hgConstants()).MergeConflictStatus.BOTH_CHANGED); + expect(conflicts[1].status).toBe((_hgConstants || _load_hgConstants()).MergeConflictStatus.DELETED_IN_OURS); }); }); describe('::resolveConflictedFile()', () => { beforeEach(() => { - jest.spyOn(hgUtils, 'hgObserveExecution').mockImplementation(path => { - return Observable.empty(); + jest.spyOn(_hgUtils || _load_hgUtils(), 'hgObserveExecution').mockImplementation(path => { + return _rxjsBundlesRxMinJs.Observable.empty(); }); }); it('calls hg resolve', async () => { - await hgService - .markConflictedFile(TEST_WORKING_DIRECTORY, PATH_1, /* resolved */ true) - .refCount() - .toArray() - .toPromise(); - expect(hgUtils.hgObserveExecution).toHaveBeenCalledWith( - ['resolve', '-m', PATH_1], - {cwd: TEST_WORKING_DIRECTORY}, - ); + await hgService.markConflictedFile(TEST_WORKING_DIRECTORY, PATH_1, /* resolved */true).refCount().toArray().toPromise(); + expect((_hgUtils || _load_hgUtils()).hgObserveExecution).toHaveBeenCalledWith(['resolve', '-m', PATH_1], { cwd: TEST_WORKING_DIRECTORY }); }); }); @@ -428,15 +383,11 @@ describe('HgService', () => { let hgRepoSubscriptions; beforeEach(() => { - hgRepoSubscriptions = new HgService.HgRepositorySubscriptions( - TEST_WORKING_DIRECTORY, - ); + hgRepoSubscriptions = new (_HgService || _load_HgService()).HgRepositorySubscriptions(TEST_WORKING_DIRECTORY); mergeDirectoryExists = false; - jest - .spyOn(hgRepoSubscriptions, '_checkMergeDirectoryExists') - .mockImplementation(() => { - return mergeDirectoryExists; - }); + jest.spyOn(hgRepoSubscriptions, '_checkMergeDirectoryExists').mockImplementation(() => { + return mergeDirectoryExists; + }); }); it("reports no conflicts when the merge directory isn't there", async () => { @@ -479,17 +430,11 @@ describe('HgService', () => { describe('::_disposeObserver', () => { it('should end published observables when disposed', async () => { await (async () => { - const subject: Subject> = new Subject(); - const repoSubscriptions = new HgService.HgRepositorySubscriptions( - TEST_WORKING_DIRECTORY, - ); + const subject = new _rxjsBundlesRxMinJs.Subject(); + const repoSubscriptions = new (_HgService || _load_HgService()).HgRepositorySubscriptions(TEST_WORKING_DIRECTORY); repoSubscriptions._lockFilesDidChange = subject; - const locksObservable = repoSubscriptions - .observeLockFilesDidChange() - .refCount() - .toArray() - .toPromise(); + const locksObservable = repoSubscriptions.observeLockFilesDidChange().refCount().toArray().toPromise(); const m1 = new Map([['hello', true]]); const m2 = new Map([['goodbye', false]]); subject.next(m1); @@ -504,4 +449,4 @@ describe('HgService', () => { })(); }); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/__tests__/hg-diff-output-parser-test.js b/pkg/nuclide-hg-rpc/__tests__/hg-diff-output-parser-test.js index e6585a0644..6a7a30b30a 100644 --- a/pkg/nuclide-hg-rpc/__tests__/hg-diff-output-parser-test.js +++ b/pkg/nuclide-hg-rpc/__tests__/hg-diff-output-parser-test.js @@ -1,18 +1,10 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import { - parseHgDiffUnifiedOutput, - parseMultiFileHgDiffUnifiedOutput, -} from '../lib/hg-diff-output-parser'; +var _hgDiffOutputParser; + +function _load_hgDiffOutputParser() { + return _hgDiffOutputParser = require('../lib/hg-diff-output-parser'); +} const MULTI_CHUNK_CHANGE_HG_DIFF_OUTPUT = `diff --git a/test-test/blah/blah.js b/test-test/blah/blah.js --- a/jar-rename/blah/blah.js @@ -26,7 +18,16 @@ diff --git a/test.xml b/test.xml @@ -152,0 +153,3 @@ + +test -+test`; ++test`; /** + * 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. + * + * strict-local + * @format + */ const MULTI_CHUNK_ADD_MOVE_COPY_DELETE_CHANGES = `diff --git a/add.js b/add.js --- /dev/null @@ -84,103 +85,90 @@ describe('hg-diff-output-parser', () => { describe('parseHgDiffUnifiedOutput', () => { it('parses a summary line correctly when both old and new line counts are explicit.', () => { const testOutput = '@@ -150,11 +150,2 @@'; - const diffInfo = parseHgDiffUnifiedOutput(testOutput); + const diffInfo = (0, (_hgDiffOutputParser || _load_hgDiffOutputParser()).parseHgDiffUnifiedOutput)(testOutput); expect(diffInfo).toEqual({ added: 2, deleted: 11, - lineDiffs: [ - { - oldStart: 150, - oldLines: 11, - newStart: 150, - newLines: 2, - }, - ], + lineDiffs: [{ + oldStart: 150, + oldLines: 11, + newStart: 150, + newLines: 2 + }] }); }); it('parses a summary line correctly when both old and new line counts are left out.', () => { const testOutput = '@@ -150 +150 @@'; - const diffInfo = parseHgDiffUnifiedOutput(testOutput); + const diffInfo = (0, (_hgDiffOutputParser || _load_hgDiffOutputParser()).parseHgDiffUnifiedOutput)(testOutput); expect(diffInfo).toEqual({ added: 1, deleted: 1, - lineDiffs: [ - { - oldStart: 150, - oldLines: 1, - newStart: 150, - newLines: 1, - }, - ], + lineDiffs: [{ + oldStart: 150, + oldLines: 1, + newStart: 150, + newLines: 1 + }] }); }); it('parses a summary line correctly when the old line count is left out.', () => { const testOutput = '@@ -150 +150,2 @@'; - const diffInfo = parseHgDiffUnifiedOutput(testOutput); + const diffInfo = (0, (_hgDiffOutputParser || _load_hgDiffOutputParser()).parseHgDiffUnifiedOutput)(testOutput); expect(diffInfo).toEqual({ added: 2, deleted: 1, - lineDiffs: [ - { - oldStart: 150, - oldLines: 1, - newStart: 150, - newLines: 2, - }, - ], + lineDiffs: [{ + oldStart: 150, + oldLines: 1, + newStart: 150, + newLines: 2 + }] }); }); it('parses a summary line correctly when the new line count is left out.', () => { const testOutput = '@@ -150,11 +150 @@'; - const diffInfo = parseHgDiffUnifiedOutput(testOutput); + const diffInfo = (0, (_hgDiffOutputParser || _load_hgDiffOutputParser()).parseHgDiffUnifiedOutput)(testOutput); expect(diffInfo).toEqual({ added: 1, deleted: 11, - lineDiffs: [ - { - oldStart: 150, - oldLines: 11, - newStart: 150, - newLines: 1, - }, - ], + lineDiffs: [{ + oldStart: 150, + oldLines: 11, + newStart: 150, + newLines: 1 + }] }); }); it('parses a full diff output correctly when multiple chunks changes.', () => { - const diffInfo = parseHgDiffUnifiedOutput( - MULTI_CHUNK_CHANGE_HG_DIFF_OUTPUT, - ); + const diffInfo = (0, (_hgDiffOutputParser || _load_hgDiffOutputParser()).parseHgDiffUnifiedOutput)(MULTI_CHUNK_CHANGE_HG_DIFF_OUTPUT); expect(diffInfo).toEqual({ added: 5, deleted: 0, - lineDiffs: [ - { - oldStart: 1, - oldLines: 0, - newStart: 2, - newLines: 2, - }, - { - oldStart: 152, - oldLines: 0, - newStart: 153, - newLines: 3, - }, - ], + lineDiffs: [{ + oldStart: 1, + oldLines: 0, + newStart: 2, + newLines: 2 + }, { + oldStart: 152, + oldLines: 0, + newStart: 153, + newLines: 3 + }] }); }); it('handles empty string as input.', () => { - const diffInfoForNull = parseHgDiffUnifiedOutput(''); - const diffInfoForEmptyString = parseHgDiffUnifiedOutput(''); + const diffInfoForNull = (0, (_hgDiffOutputParser || _load_hgDiffOutputParser()).parseHgDiffUnifiedOutput)(''); + const diffInfoForEmptyString = (0, (_hgDiffOutputParser || _load_hgDiffOutputParser()).parseHgDiffUnifiedOutput)(''); expect(diffInfoForNull).toEqual({ added: 0, deleted: 0, - lineDiffs: [], + lineDiffs: [] }); expect(diffInfoForEmptyString).toEqual(diffInfoForNull); }); @@ -188,103 +176,85 @@ describe('hg-diff-output-parser', () => { describe('parseMultiFileHgDiffUnifiedOutput', () => { it('parses the diff information correctly for each file.', () => { - const diffInfoForManyFiles = parseMultiFileHgDiffUnifiedOutput( - MULTI_FILE_HG_DIFF_OUTPUT, - ); + const diffInfoForManyFiles = (0, (_hgDiffOutputParser || _load_hgDiffOutputParser()).parseMultiFileHgDiffUnifiedOutput)(MULTI_FILE_HG_DIFF_OUTPUT); expect(diffInfoForManyFiles.size).toBe(2); expect(diffInfoForManyFiles.get('test-test/blah/blah.js')).toEqual({ added: 1, deleted: 0, - lineDiffs: [ - { - oldStart: 90, - oldLines: 0, - newStart: 91, - newLines: 1, - }, - ], + lineDiffs: [{ + oldStart: 90, + oldLines: 0, + newStart: 91, + newLines: 1 + }] }); expect(diffInfoForManyFiles.get('test-test/foo/foo.js')).toEqual({ added: 12, deleted: 1, - lineDiffs: [ - { - oldStart: 12, - oldLines: 1, - newStart: 12, - newLines: 4, - }, - { - oldStart: 28, - oldLines: 0, - newStart: 32, - newLines: 4, - }, - { - oldStart: 123, - oldLines: 0, - newStart: 131, - newLines: 4, - }, - ], + lineDiffs: [{ + oldStart: 12, + oldLines: 1, + newStart: 12, + newLines: 4 + }, { + oldStart: 28, + oldLines: 0, + newStart: 32, + newLines: 4 + }, { + oldStart: 123, + oldLines: 0, + newStart: 131, + newLines: 4 + }] }); }); describe('parseMultiFileHgDiffUnifiedOutput', () => { it('parses the diff information correctly for each file.', () => { - const diffInfoForManyFiles = parseMultiFileHgDiffUnifiedOutput( - MULTI_CHUNK_ADD_MOVE_COPY_DELETE_CHANGES, - ); + const diffInfoForManyFiles = (0, (_hgDiffOutputParser || _load_hgDiffOutputParser()).parseMultiFileHgDiffUnifiedOutput)(MULTI_CHUNK_ADD_MOVE_COPY_DELETE_CHANGES); expect(diffInfoForManyFiles.size).toBe(4); expect(diffInfoForManyFiles.get('add.js')).toEqual({ added: 1, deleted: 0, - lineDiffs: [ - { - oldStart: 0, - oldLines: 0, - newStart: 1, - newLines: 1, - }, - ], + lineDiffs: [{ + oldStart: 0, + oldLines: 0, + newStart: 1, + newLines: 1 + }] }); expect(diffInfoForManyFiles.get('delete.txt')).toEqual({ added: 0, deleted: 1, - lineDiffs: [ - { - oldStart: 1, - oldLines: 1, - newStart: 0, - newLines: 0, - }, - ], + lineDiffs: [{ + oldStart: 1, + oldLines: 1, + newStart: 0, + newLines: 0 + }] }); expect(diffInfoForManyFiles.get('copyafter.txt')).toEqual({ added: 1, deleted: 1, - lineDiffs: [ - { - oldStart: 1, - oldLines: 1, - newStart: 1, - newLines: 1, - }, - ], + lineDiffs: [{ + oldStart: 1, + oldLines: 1, + newStart: 1, + newLines: 1 + }] }); expect(diffInfoForManyFiles.get('renameafter.txt')).toEqual({ added: 1, deleted: 1, - lineDiffs: [ - { - oldStart: 1, - oldLines: 1, - newStart: 1, - newLines: 1, - }, - ], + lineDiffs: [{ + oldStart: 1, + oldLines: 1, + newStart: 1, + newLines: 1 + }] }); }); }); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/__tests__/hg-revision-expression-helpers-test.js b/pkg/nuclide-hg-rpc/__tests__/hg-revision-expression-helpers-test.js index 19d5248b6a..514efed559 100644 --- a/pkg/nuclide-hg-rpc/__tests__/hg-revision-expression-helpers-test.js +++ b/pkg/nuclide-hg-rpc/__tests__/hg-revision-expression-helpers-test.js @@ -1,3 +1,17 @@ +'use strict'; + +var _hgRevisionExpressionHelpers; + +function _load_hgRevisionExpressionHelpers() { + return _hgRevisionExpressionHelpers = require('../lib/hg-revision-expression-helpers'); +} + +var _hgConstants; + +function _load_hgConstants() { + return _hgConstants = require('../lib/hg-constants'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,27 +19,19 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import { - expressionForRevisionsBeforeHead, - parseRevisionInfoOutput, - INFO_REV_END_MARK, - NULL_CHAR, -} from '../lib/hg-revision-expression-helpers'; -import {SuccessorType} from '../lib/hg-constants'; - describe('hg-revision-expression-helpers', () => { describe('expressionForRevisionsBeforeHead', () => { it('returns a correct expression <= 0 revisions before head.', () => { - expect(expressionForRevisionsBeforeHead(0)).toBe('.'); - expect(expressionForRevisionsBeforeHead(-2)).toBe('.'); + expect((0, (_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).expressionForRevisionsBeforeHead)(0)).toBe('.'); + expect((0, (_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).expressionForRevisionsBeforeHead)(-2)).toBe('.'); }); it('returns a correct expression for > 0 revisions before head.', () => { - expect(expressionForRevisionsBeforeHead(3)).toBe('.~3'); + expect((0, (_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).expressionForRevisionsBeforeHead)(3)).toBe('.~3'); }); }); @@ -45,10 +51,10 @@ Author Name a343fb3 default draft -b-1${NULL_CHAR}b-2${NULL_CHAR} +b-1${(_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).NULL_CHAR}b-2${(_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).NULL_CHAR} -tip${NULL_CHAR} -a343fb211111${NULL_CHAR}000000000000${NULL_CHAR} +tip${(_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).NULL_CHAR} +a343fb211111${(_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).NULL_CHAR}000000000000${(_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).NULL_CHAR} @ ["temp.txt"] @@ -58,7 +64,7 @@ a343fb211111${NULL_CHAR}000000000000${NULL_CHAR} ${commit1Description} -${INFO_REV_END_MARK} +${(_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).INFO_REV_END_MARK} 123 Commit 2 'title'. Author Name @@ -67,9 +73,9 @@ a343fb2 default public -remote/master${NULL_CHAR} +remote/master${(_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).NULL_CHAR} -abc123411111${NULL_CHAR}000000000000${NULL_CHAR} +abc123411111${(_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).NULL_CHAR}000000000000${(_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).NULL_CHAR} ["temp.txt"] @@ -79,52 +85,49 @@ af3435454321 ${commit2Description} -${INFO_REV_END_MARK} +${(_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).INFO_REV_END_MARK} `; - expect(parseRevisionInfoOutput(revisionsString)).toEqual([ - { - id: 124, - isHead: true, - files: ['temp.txt'], - title: "Commit 1 'title'.", - author: 'Author Name', - hash: 'a343fb3', - bookmarks: ['b-1', 'b-2'], - remoteBookmarks: [], - date: new Date('2015-10-15 16:03 -0700'), - branch: 'default', - phase: 'draft', - tags: ['tip'], - parents: ['a343fb211111'], - description: commit1Description, - successorInfo: null, - }, - { - id: 123, - isHead: false, - files: ['temp.txt'], - title: "Commit 2 'title'.", - author: 'Author Name', - hash: 'a343fb2', - bookmarks: [], - remoteBookmarks: ['remote/master'], - date: new Date('2015-10-15 16:02 -0700'), - branch: 'default', - phase: 'public', - tags: [], - parents: ['abc123411111'], - description: commit2Description, - successorInfo: { - hash: 'af3435454321', - type: SuccessorType.AMEND, - }, - }, - ]); + expect((0, (_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).parseRevisionInfoOutput)(revisionsString)).toEqual([{ + id: 124, + isHead: true, + files: ['temp.txt'], + title: "Commit 1 'title'.", + author: 'Author Name', + hash: 'a343fb3', + bookmarks: ['b-1', 'b-2'], + remoteBookmarks: [], + date: new Date('2015-10-15 16:03 -0700'), + branch: 'default', + phase: 'draft', + tags: ['tip'], + parents: ['a343fb211111'], + description: commit1Description, + successorInfo: null + }, { + id: 123, + isHead: false, + files: ['temp.txt'], + title: "Commit 2 'title'.", + author: 'Author Name', + hash: 'a343fb2', + bookmarks: [], + remoteBookmarks: ['remote/master'], + date: new Date('2015-10-15 16:02 -0700'), + branch: 'default', + phase: 'public', + tags: [], + parents: ['abc123411111'], + description: commit2Description, + successorInfo: { + hash: 'af3435454321', + type: (_hgConstants || _load_hgConstants()).SuccessorType.AMEND + } + }]); }); it('skips an entry if invalid - should never happen', () => { - expect(parseRevisionInfoOutput('revision:123')).toEqual([]); + expect((0, (_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).parseRevisionInfoOutput)('revision:123')).toEqual([]); }); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/__tests__/hg-revision-state-helpers-test.js b/pkg/nuclide-hg-rpc/__tests__/hg-revision-state-helpers-test.js index 2c96b03e6c..6ae6f431c3 100644 --- a/pkg/nuclide-hg-rpc/__tests__/hg-revision-state-helpers-test.js +++ b/pkg/nuclide-hg-rpc/__tests__/hg-revision-state-helpers-test.js @@ -1,3 +1,19 @@ +'use strict'; + +var _hgRevisionStateHelpers; + +function _load_hgRevisionStateHelpers() { + return _hgRevisionStateHelpers = require('../lib/hg-revision-state-helpers'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,22 +21,19 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import {parseRevisionFileChangeOutput} from '../lib/hg-revision-state-helpers'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - describe('parseRevisionFileChangeOutput', () => { const testWorkingDirectory = '/Hg/Working/Directory'; - const test1 = nuclideUri.join(testWorkingDirectory, 'test1.js'); - const test2 = nuclideUri.join(testWorkingDirectory, 'test2.js'); - const test3 = nuclideUri.join(testWorkingDirectory, 'test3.js'); - const test4 = nuclideUri.join(testWorkingDirectory, 'test4.js'); - const test5 = nuclideUri.join(testWorkingDirectory, 'test5.js'); - const testOrig1 = nuclideUri.join(testWorkingDirectory, 'test-orig1.js'); - const testOrig2 = nuclideUri.join(testWorkingDirectory, 'test-orig2.js'); + const test1 = (_nuclideUri || _load_nuclideUri()).default.join(testWorkingDirectory, 'test1.js'); + const test2 = (_nuclideUri || _load_nuclideUri()).default.join(testWorkingDirectory, 'test2.js'); + const test3 = (_nuclideUri || _load_nuclideUri()).default.join(testWorkingDirectory, 'test3.js'); + const test4 = (_nuclideUri || _load_nuclideUri()).default.join(testWorkingDirectory, 'test4.js'); + const test5 = (_nuclideUri || _load_nuclideUri()).default.join(testWorkingDirectory, 'test5.js'); + const testOrig1 = (_nuclideUri || _load_nuclideUri()).default.join(testWorkingDirectory, 'test-orig1.js'); + const testOrig2 = (_nuclideUri || _load_nuclideUri()).default.join(testWorkingDirectory, 'test-orig2.js'); it('correctly parses a revision with files added, deleted, copied, and modified.', () => { // This output is in the form of the REVISION_FILE_CHANGES_TEMPLATE in @@ -30,16 +43,13 @@ file-adds: test1.js test2.js file-dels: test3.js test4.js file-copies: test1.js (test-orig1.js)test2.js (test-orig2.js) file-mods: test4.js test5.js`; - const result = parseRevisionFileChangeOutput( - testOutput, - testWorkingDirectory, - ); + const result = (0, (_hgRevisionStateHelpers || _load_hgRevisionStateHelpers()).parseRevisionFileChangeOutput)(testOutput, testWorkingDirectory); const expectedResult = { all: [test1, test2, test3, test4, test5], added: [test1, test2], deleted: [test3, test4], - copied: [{from: testOrig1, to: test1}, {from: testOrig2, to: test2}], - modified: [test4, test5], + copied: [{ from: testOrig1, to: test1 }, { from: testOrig2, to: test2 }], + modified: [test4, test5] }; expect(result).toEqual(expectedResult); }); @@ -54,17 +64,14 @@ file-adds: file-dels: file-copies: file-mods:`; - const result = parseRevisionFileChangeOutput( - testOutput, - testWorkingDirectory, - ); + const result = (0, (_hgRevisionStateHelpers || _load_hgRevisionStateHelpers()).parseRevisionFileChangeOutput)(testOutput, testWorkingDirectory); const expectedResult = { all: [], added: [], deleted: [], copied: [], - modified: [], + modified: [] }; expect(result).toEqual(expectedResult); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/lib/HgService.js b/pkg/nuclide-hg-rpc/lib/HgService.js index c906394744..c01b91c71c 100644 --- a/pkg/nuclide-hg-rpc/lib/HgService.js +++ b/pkg/nuclide-hg-rpc/lib/HgService.js @@ -1,3 +1,175 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.HgRepositorySubscriptions = undefined; +exports.createRepositorySubscriptions = createRepositorySubscriptions; +exports.fetchStatuses = fetchStatuses; +exports.fetchStackStatuses = fetchStackStatuses; +exports.fetchHeadStatuses = fetchHeadStatuses; +exports.getAdditionalLogFiles = getAdditionalLogFiles; +exports.fetchDiffInfo = fetchDiffInfo; +exports.createBookmark = createBookmark; +exports.deleteBookmark = deleteBookmark; +exports.renameBookmark = renameBookmark; +exports.fetchActiveBookmark = fetchActiveBookmark; +exports.fetchBookmarks = fetchBookmarks; +exports.fetchFileContentAtRevision = fetchFileContentAtRevision; +exports.batchFetchFileContentsAtRevision = batchFetchFileContentsAtRevision; +exports.fetchFilesChangedAtRevision = fetchFilesChangedAtRevision; +exports.fetchRevisionInfoBetweenHeadAndBase = fetchRevisionInfoBetweenHeadAndBase; +exports.fetchSmartlogRevisions = fetchSmartlogRevisions; +exports.getBaseRevision = getBaseRevision; +exports.getBlameAtHead = getBlameAtHead; +exports.getConfigValueAsync = getConfigValueAsync; +exports.getDifferentialRevisionForChangeSetId = getDifferentialRevisionForChangeSetId; +exports.getSmartlog = getSmartlog; +exports.commit = commit; +exports.editCommitMessage = editCommitMessage; +exports.amend = amend; +exports.restack = restack; +exports.revert = revert; +exports.checkout = checkout; +exports.show = show; +exports.diff = diff; +exports.purge = purge; +exports.uncommit = uncommit; +exports.strip = strip; +exports.checkoutForkBase = checkoutForkBase; +exports.rename = rename; +exports.remove = remove; +exports.forget = forget; +exports.add = add; +exports.getTemplateCommitMessage = getTemplateCommitMessage; +exports.getHeadCommitMessage = getHeadCommitMessage; +exports.log = log; +exports.fetchMergeConflicts = fetchMergeConflicts; +exports.markConflictedFile = markConflictedFile; +exports.continueOperation = continueOperation; +exports.abortOperation = abortOperation; +exports.resolveAllFiles = resolveAllFiles; +exports.rebase = rebase; +exports.reorderWithinStack = reorderWithinStack; +exports.pull = pull; +exports.copy = copy; +exports.getHeadId = getHeadId; +exports.getFullHashForRevision = getFullHashForRevision; +exports.fold = fold; +exports.runCommand = runCommand; +exports.observeExecution = observeExecution; +exports.gitDiffStrings = gitDiffStrings; + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _observable; + +function _load_observable() { + return _observable = require('../../../modules/nuclide-commons/observable'); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _string; + +function _load_string() { + return _string = require('../../../modules/nuclide-commons/string'); +} + +var _nuclideWatchmanHelpers; + +function _load_nuclideWatchmanHelpers() { + return _nuclideWatchmanHelpers = require('../../../modules/nuclide-watchman-helpers'); +} + +var _gitDiff; + +function _load_gitDiff() { + return _gitDiff = require('./git-diff'); +} + +var _fs = _interopRequireDefault(require('fs')); + +var _hgConstants; + +function _load_hgConstants() { + return _hgConstants = require('./hg-constants'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _hgDiffOutputParser; + +function _load_hgDiffOutputParser() { + return _hgDiffOutputParser = require('./hg-diff-output-parser'); +} + +var _hgRevisionExpressionHelpers; + +function _load_hgRevisionExpressionHelpers() { + return _hgRevisionExpressionHelpers = require('./hg-revision-expression-helpers'); +} + +var _hgRevisionStateHelpers; + +function _load_hgRevisionStateHelpers() { + return _hgRevisionStateHelpers = _interopRequireWildcard(require('./hg-revision-state-helpers')); +} + +var _hgUtils; + +function _load_hgUtils() { + return _hgUtils = require('./hg-utils'); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _debounce; + +function _load_debounce() { + return _debounce = _interopRequireDefault(require('../../../modules/nuclide-commons/debounce')); +} + +var _hgBookmarkHelpers; + +function _load_hgBookmarkHelpers() { + return _hgBookmarkHelpers = _interopRequireWildcard(require('./hg-bookmark-helpers')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _watchFileCreationAndDeletion; + +function _load_watchFileCreationAndDeletion() { + return _watchFileCreationAndDeletion = require('./watchFileCreationAndDeletion'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,73 +177,21 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {ConnectableObservable} from 'rxjs'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {LegacyProcessMessage} from 'nuclide-commons/process'; -import type {DeadlineRequest} from 'nuclide-commons/promise'; -import type {AdditionalLogFile} from '../../nuclide-logging/lib/rpc-types'; -import type {HgExecOptions} from './hg-exec-types'; - -import {takeIterable} from 'nuclide-commons/collection'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {fastDebounce} from 'nuclide-commons/observable'; -import {timeoutAfterDeadline} from 'nuclide-commons/promise'; -import {stringifyError} from 'nuclide-commons/string'; -import {WatchmanClient} from 'nuclide-watchman-helpers'; -import {gitDiffStrings as gitDiffStringsImpl} from './git-diff'; -import fs from 'fs'; - -import { - MergeConflictStatus, - HisteditActions, - LockFilesList, -} from './hg-constants'; -import {Subject, ReplaySubject} from 'rxjs'; -import {parseMultiFileHgDiffUnifiedOutput} from './hg-diff-output-parser'; -import { - expressionForCommonAncestor, - expressionForRevisionsBeforeHead, - fetchRevisionInfoBetweenRevisions, - fetchRevisionInfo, - fetchRevisionsInfo, - fetchSmartlogRevisions as fetchSmartlogRevisionsImpl, -} from './hg-revision-expression-helpers'; -import * as StateHelpers from './hg-revision-state-helpers'; -import { - formatCommitMessage, - hgAsyncExecute, - hgObserveExecution, - hgRunCommand, -} from './hg-utils'; -import fsPromise from 'nuclide-commons/fsPromise'; -import debounce from 'nuclide-commons/debounce'; - -import * as BookmarkHelpers from './hg-bookmark-helpers'; -import {getLogger} from 'log4js'; -import {Observable} from 'rxjs'; -import {subscribeToFilesCreateAndDelete} from './watchFileCreationAndDeletion'; - -const logger = getLogger('nuclide-hg-rpc'); +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc'); const DEFAULT_ARC_PROJECT_FORK_BASE = 'remote/master'; const DEFAULT_FORK_BASE_NAME = 'default'; -const WATCHMAN_SUBSCRIPTION_NAME_PRIMARY = - 'hg-repository-watchman-subscription-primary'; -const WATCHMAN_SUBSCRIPTION_NAME_HGBOOKMARK = - 'hg-repository-watchman-subscription-hgbookmark'; -const WATCHMAN_SUBSCRIPTION_NAME_HGBOOKMARKS = - 'hg-repository-watchman-subscription-hgbookmarks'; +const WATCHMAN_SUBSCRIPTION_NAME_PRIMARY = 'hg-repository-watchman-subscription-primary'; +const WATCHMAN_SUBSCRIPTION_NAME_HGBOOKMARK = 'hg-repository-watchman-subscription-hgbookmark'; +const WATCHMAN_SUBSCRIPTION_NAME_HGBOOKMARKS = 'hg-repository-watchman-subscription-hgbookmarks'; const WATCHMAN_HG_DIR_STATE = 'hg-repository-watchman-subscription-dirstate'; -const WATCHMAN_SUBSCRIPTION_NAME_CONFLICTS = - 'hg-repository-watchman-subscription-conflicts'; -const WATCHMAN_SUBSCRIPTION_NAME_PROGRESS = - 'hg-repository-watchman-subscription-progress'; -const WATCHMAN_SUBSCRIPTION_NAME_LOCK_FILES = - 'hg-repository-watchman-subscription-lock-files'; +const WATCHMAN_SUBSCRIPTION_NAME_CONFLICTS = 'hg-repository-watchman-subscription-conflicts'; +const WATCHMAN_SUBSCRIPTION_NAME_PROGRESS = 'hg-repository-watchman-subscription-progress'; +const WATCHMAN_SUBSCRIPTION_NAME_LOCK_FILES = 'hg-repository-watchman-subscription-lock-files'; const CHECK_CONFLICT_DELAY_MS = 2000; const COMMIT_CHANGE_DEBOUNCE_MS = 1000; @@ -85,25 +205,13 @@ const NUM_FETCH_STATUSES_LIMIT = 200; // Suffixes of hg error messages that indicate that an error is safe to ignore, // and should not warrant a user-visible error. These generally happen // when performing an hg operation on a non-existent or untracked file. -const IGNORABLE_ERROR_SUFFIXES = [ - 'abort: no files to copy', - 'No such file or directory', - 'does not exist!', -]; +const IGNORABLE_ERROR_SUFFIXES = ['abort: no files to copy', 'No such file or directory', 'does not exist!']; /** * These are status codes used by Mercurial's output. * Documented in http://selenic.com/hg/help/status. */ -export type StatusCodeIdValue = 'A' | 'C' | 'I' | 'M' | '!' | 'R' | '?' | 'U'; -export type MergeConflictStatusValue = - | 'both changed' - | 'deleted in theirs' - | 'deleted in ours' - | 'resolved'; - -export type MergeConflictStatusCodeId = 'R' | 'U'; /** * Internally, the HgRepository uses the string StatusCodeId to do bookkeeping. @@ -113,179 +221,26 @@ export type MergeConflictStatusCodeId = 'R' | 'U'; * The numbers themselves should not matter; they are meant to be passed * to ::isStatusNew/::isStatusModified to be interpreted. */ -export type StatusCodeNumberValue = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8; - -export type LineDiff = { - oldStart: number, - oldLines: number, - newStart: number, - newLines: number, -}; - -export type BookmarkInfo = { - active: boolean, - bookmark: string, - node: string, -}; - -export type DiffInfo = { - added: number, - deleted: number, - lineDiffs: Array, -}; - -export type CommitPhaseType = 'public' | 'draft' | 'secret'; - -export type SuccessorTypeValue = - | 'public' - | 'amend' - | 'rebase' - | 'split' - | 'fold' - | 'histedit'; - -export type HisteditActionsValue = 'pick'; - -export type RevisionSuccessorInfo = { - hash: string, - type: SuccessorTypeValue, -}; - -export type RevisionInfo = { - author: string, - bookmarks: Array, - branch: string, - date: Date, - description: string, - hash: string, - id: number, - isHead: boolean, - remoteBookmarks: Array, - parents: Array, - phase: CommitPhaseType, - successorInfo: ?RevisionSuccessorInfo, - tags: Array, - title: string, - files: Array, -}; - -export type RevisionShowInfo = { - diff: string, -}; - -export type RevisionInfoFetched = { - revisions: Array, - fromFilesystem: boolean, -}; - -export type AsyncExecuteRet = { - command?: string, - errorMessage?: string, - exitCode: number, - stderr: string, - stdout: string, -}; - -export type RevisionFileCopy = { - from: NuclideUri, - to: NuclideUri, -}; - -export type RevisionFileChanges = { - all: Array, - added: Array, - deleted: Array, - copied: Array, - modified: Array, -}; - -export type VcsLogEntry = { - node: string, - user: string, - desc: string, - date: [number, number], -}; - -export type VcsLogResponse = { - entries: Array, -}; + // Information about file for local, base and other commit that caused the conflict -export type MergeConflictSideFileData = { - contents: ?string, - exists: boolean, - isexec: ?boolean, - issymlink: ?boolean, -}; + // Information about the output file -export type MergeConflictOutputFileData = MergeConflictSideFileData & { - path: NuclideUri, -}; - -export type MergeConflictFileData = { - base: MergeConflictSideFileData, - local: MergeConflictSideFileData, - other: MergeConflictSideFileData, - output: MergeConflictOutputFileData, - status: MergeConflictStatusValue, - conflictCount?: number, -}; - -export type MergeConflicts = { - conflicts: Array, - command: string, - command_details: { - cmd: string, - to_abort: string, - to_continue: string, - }, -}; - -export type CheckoutSideName = 'ours' | 'theirs'; - -export type AmendModeValue = 'Clean' | 'Rebase' | 'Fixup'; - -export type CheckoutOptions = { - clean?: true, -}; - -export type OperationProgressState = { - active: ?boolean, - estimate_sec: ?number, - estimate_str: ?string, - item: ?string, - pos: ?number, - speed_str: ?string, - topic: ?string, - total: ?number, - unit: ?string, - units_per_sec: ?number, -}; -export type OperationProgress = { - topics: Array, - state: Object, -}; - -async function logWhenSubscriptionEstablished( - sub: Promise, - subName: string, -): Promise { + + +async function logWhenSubscriptionEstablished(sub, subName) { await sub; logger.debug(`Watchman subscription ${subName} established.`); } -async function getForkBaseName(directoryPath: string): Promise { +async function getForkBaseName(directoryPath) { try { // $FlowFB - const {readArcConfig} = require('../../fb-arcanist-rpc'); + const { readArcConfig } = require('../../fb-arcanist-rpc'); const arcConfig = await readArcConfig(directoryPath); if (arcConfig != null) { - return ( - arcConfig['arc.feature.start.default'] || - arcConfig['arc.land.onto.default'] || - DEFAULT_ARC_PROJECT_FORK_BASE - ); + return arcConfig['arc.feature.start.default'] || arcConfig['arc.land.onto.default'] || DEFAULT_ARC_PROJECT_FORK_BASE; } } catch (err) {} return DEFAULT_FORK_BASE_NAME; @@ -295,7 +250,7 @@ async function getForkBaseName(directoryPath: string): Promise { * @return Array of additional watch expressions to apply to the primary * watchman subscription. */ -function getPrimaryWatchmanSubscriptionRefinements(): Array { +function getPrimaryWatchmanSubscriptionRefinements() { let refinements = []; try { // $FlowFB @@ -306,7 +261,7 @@ function getPrimaryWatchmanSubscriptionRefinements(): Array { return refinements; } -function resolvePathForPlatform(path: string): string { +function resolvePathForPlatform(path) { // hg resolve on win has a bug where it returns path with both unix // and win separators (T22157755). We normalize the path here. if (process.platform === 'win32') { @@ -316,74 +271,57 @@ function resolvePathForPlatform(path: string): string { } /** @return .hg/store directory for the specified Hg working directory root. */ -async function findStoreDirectory(workingDirectory: string): Promise { +async function findStoreDirectory(workingDirectory) { // If .hg/sharedpath is present, then this directory is using the Hg "share" // extension, in which case it is sharing the store with the .hg folder // specified by .hg/sharedpath. // // Note that we could be extra paranoid and watch for changes to // .hg/sharedpath, but that seems too rare to be worth the extra complexity. - const sharedpath = nuclideUri.join(workingDirectory, '.hg', 'sharedpath'); + const sharedpath = (_nuclideUri || _load_nuclideUri()).default.join(workingDirectory, '.hg', 'sharedpath'); let hgFolderWithStore; try { - hgFolderWithStore = await fsPromise.readFile(sharedpath, 'utf8'); + hgFolderWithStore = await (_fsPromise || _load_fsPromise()).default.readFile(sharedpath, 'utf8'); } catch (error) { if (error.code === 'ENOENT') { // .hg/sharedpath does not exist: use .hg in workingDirectory. - hgFolderWithStore = nuclideUri.join(workingDirectory, '.hg'); + hgFolderWithStore = (_nuclideUri || _load_nuclideUri()).default.join(workingDirectory, '.hg'); } else { throw error; } } - return nuclideUri.join(hgFolderWithStore, 'store'); -} - -export class HgRepositorySubscriptions { - _isInConflict: boolean; - _watchmanClient: ?WatchmanClient; - _origBackupPath: ?string; - - _workingDirectory: string; - _filesDidChangeObserver: Subject; - _hgActiveBookmarkDidChangeObserver: Subject; - _lockFilesDidChange: Observable>; - _hgBookmarksDidChangeObserver: Subject; - _hgRepoStateDidChangeObserver: Subject; - _hgRepoCommitsDidChangeObserver: Subject; - _hgConflictStateDidChangeObserver: Subject; - _hgOperationProgressDidChangeObserver: Subject; - _debouncedCheckConflictChange: () => void; - _hgStoreDirWatcher: ?fs.FSWatcher; - _disposeObserver: Subject; // used to limit lifespan of other observables - - static async create( - workingDirectory: string, - ): Promise { + return (_nuclideUri || _load_nuclideUri()).default.join(hgFolderWithStore, 'store'); +} + +class HgRepositorySubscriptions { + // used to limit lifespan of other observables + + static async create(workingDirectory) { const repoSubscriptions = new HgRepositorySubscriptions(workingDirectory); await repoSubscriptions._subscribeToWatchman(); return repoSubscriptions; } // DO NOT USE DIRECTLY: Use the static `create` instead. - constructor(workingDirectory: string) { + constructor(workingDirectory) { this._workingDirectory = workingDirectory; - this._filesDidChangeObserver = new Subject(); - this._hgActiveBookmarkDidChangeObserver = new Subject(); - this._lockFilesDidChange = Observable.empty(); - this._hgBookmarksDidChangeObserver = new Subject(); - this._hgRepoStateDidChangeObserver = new Subject(); - this._hgConflictStateDidChangeObserver = new Subject(); - this._hgRepoCommitsDidChangeObserver = new Subject(); - this._hgOperationProgressDidChangeObserver = new Subject(); + this._filesDidChangeObserver = new _rxjsBundlesRxMinJs.Subject(); + this._hgActiveBookmarkDidChangeObserver = new _rxjsBundlesRxMinJs.Subject(); + this._lockFilesDidChange = _rxjsBundlesRxMinJs.Observable.empty(); + this._hgBookmarksDidChangeObserver = new _rxjsBundlesRxMinJs.Subject(); + this._hgRepoStateDidChangeObserver = new _rxjsBundlesRxMinJs.Subject(); + this._hgConflictStateDidChangeObserver = new _rxjsBundlesRxMinJs.Subject(); + this._hgRepoCommitsDidChangeObserver = new _rxjsBundlesRxMinJs.Subject(); + this._hgOperationProgressDidChangeObserver = new _rxjsBundlesRxMinJs.Subject(); this._isInConflict = false; - this._debouncedCheckConflictChange = debounce(() => { + this._debouncedCheckConflictChange = (0, (_debounce || _load_debounce()).default)(() => { this._checkConflictChange(); }, CHECK_CONFLICT_DELAY_MS); - this._disposeObserver = new ReplaySubject(); + this._disposeObserver = new _rxjsBundlesRxMinJs.ReplaySubject(); } - async dispose(): Promise { + async dispose() { this._disposeObserver.next(); this._disposeObserver.complete(); this._filesDidChangeObserver.complete(); @@ -398,132 +336,77 @@ export class HgRepositorySubscriptions { await this._cleanUpWatchman(); } - async _subscribeToWatchman(): Promise { + async _subscribeToWatchman() { // Using a local variable here to allow better type refinement. - const watchmanClient = new WatchmanClient(); + const watchmanClient = new (_nuclideWatchmanHelpers || _load_nuclideWatchmanHelpers()).WatchmanClient(); this._watchmanClient = watchmanClient; const workingDirectory = this._workingDirectory; - let primarySubscriptionExpression: Array = [ - 'allof', - ['not', ['dirname', '.hg']], - // Hg appears to modify temporary files that begin with these - // prefixes, every time a file is saved. - ['not', ['match', 'hg-checkexec-*', 'wholename']], - ['not', ['match', 'hg-checklink-*', 'wholename']], - // This watchman subscription is used to determine when and which - // files to fetch new statuses for. There is no reason to include - // directories in these updates, and in fact they may make us overfetch - // statuses. (See diff summary of D2021498.) - // This line restricts this subscription to only return files. - ['type', 'f'], - ]; - primarySubscriptionExpression = primarySubscriptionExpression.concat( - getPrimaryWatchmanSubscriptionRefinements(), - ); + let primarySubscriptionExpression = ['allof', ['not', ['dirname', '.hg']], + // Hg appears to modify temporary files that begin with these + // prefixes, every time a file is saved. + ['not', ['match', 'hg-checkexec-*', 'wholename']], ['not', ['match', 'hg-checklink-*', 'wholename']], + // This watchman subscription is used to determine when and which + // files to fetch new statuses for. There is no reason to include + // directories in these updates, and in fact they may make us overfetch + // statuses. (See diff summary of D2021498.) + // This line restricts this subscription to only return files. + ['type', 'f']]; + primarySubscriptionExpression = primarySubscriptionExpression.concat(getPrimaryWatchmanSubscriptionRefinements()); // Subscribe to changes to files unrelated to source control. - const primarySubscriptionPromise = watchmanClient.watchDirectoryRecursive( - workingDirectory, - WATCHMAN_SUBSCRIPTION_NAME_PRIMARY, - { - fields: ['name', 'exists', 'new'], - expression: primarySubscriptionExpression, - defer: ['hg.update'], - empty_on_fresh_instance: true, - }, - ); - logWhenSubscriptionEstablished( - primarySubscriptionPromise, - WATCHMAN_SUBSCRIPTION_NAME_PRIMARY, - ); + const primarySubscriptionPromise = watchmanClient.watchDirectoryRecursive(workingDirectory, WATCHMAN_SUBSCRIPTION_NAME_PRIMARY, { + fields: ['name', 'exists', 'new'], + expression: primarySubscriptionExpression, + defer: ['hg.update'], + empty_on_fresh_instance: true + }); + logWhenSubscriptionEstablished(primarySubscriptionPromise, WATCHMAN_SUBSCRIPTION_NAME_PRIMARY); // Subscribe to changes to files unrelated to source control. - const conflictStateSubscriptionPromise = watchmanClient.watchDirectoryRecursive( - workingDirectory, - WATCHMAN_SUBSCRIPTION_NAME_CONFLICTS, - { - fields: ['name', 'exists', 'new'], - expression: ['name', '.hg/merge', 'wholename'], - defer: ['hg.update'], - empty_on_fresh_instance: true, - }, - ); - logWhenSubscriptionEstablished( - conflictStateSubscriptionPromise, - WATCHMAN_SUBSCRIPTION_NAME_CONFLICTS, - ); + const conflictStateSubscriptionPromise = watchmanClient.watchDirectoryRecursive(workingDirectory, WATCHMAN_SUBSCRIPTION_NAME_CONFLICTS, { + fields: ['name', 'exists', 'new'], + expression: ['name', '.hg/merge', 'wholename'], + defer: ['hg.update'], + empty_on_fresh_instance: true + }); + logWhenSubscriptionEstablished(conflictStateSubscriptionPromise, WATCHMAN_SUBSCRIPTION_NAME_CONFLICTS); // Subscribe to changes to the active Mercurial bookmark. - const hgActiveBookmarkSubscriptionPromise = watchmanClient.watchDirectoryRecursive( - workingDirectory, - WATCHMAN_SUBSCRIPTION_NAME_HGBOOKMARK, - { - fields: ['name', 'exists'], - expression: ['name', '.hg/bookmarks.current', 'wholename'], - defer: ['hg.update'], - empty_on_fresh_instance: true, - }, - ); - logWhenSubscriptionEstablished( - hgActiveBookmarkSubscriptionPromise, - WATCHMAN_SUBSCRIPTION_NAME_HGBOOKMARK, - ); + const hgActiveBookmarkSubscriptionPromise = watchmanClient.watchDirectoryRecursive(workingDirectory, WATCHMAN_SUBSCRIPTION_NAME_HGBOOKMARK, { + fields: ['name', 'exists'], + expression: ['name', '.hg/bookmarks.current', 'wholename'], + defer: ['hg.update'], + empty_on_fresh_instance: true + }); + logWhenSubscriptionEstablished(hgActiveBookmarkSubscriptionPromise, WATCHMAN_SUBSCRIPTION_NAME_HGBOOKMARK); // Subscribe to changes in Mercurial bookmarks. - const hgBookmarksSubscriptionPromise = watchmanClient.watchDirectoryRecursive( - workingDirectory, - WATCHMAN_SUBSCRIPTION_NAME_HGBOOKMARKS, - { - fields: ['name', 'exists'], - expression: ['name', '.hg/bookmarks', 'wholename'], - defer: ['hg.update'], - empty_on_fresh_instance: true, - }, - ); - logWhenSubscriptionEstablished( - hgBookmarksSubscriptionPromise, - WATCHMAN_SUBSCRIPTION_NAME_HGBOOKMARKS, - ); - - const dirStateSubscriptionPromise = watchmanClient.watchDirectoryRecursive( - workingDirectory, - WATCHMAN_HG_DIR_STATE, - { - fields: ['name'], - expression: ['name', '.hg/dirstate', 'wholename'], - defer: ['hg.update'], - empty_on_fresh_instance: true, - }, - ); - logWhenSubscriptionEstablished( - dirStateSubscriptionPromise, - WATCHMAN_HG_DIR_STATE, - ); - - const progressSubscriptionPromise = watchmanClient.watchDirectoryRecursive( - workingDirectory, - WATCHMAN_SUBSCRIPTION_NAME_PROGRESS, - { - fields: ['name'], - expression: ['name', '.hg/progress', 'wholename'], - empty_on_fresh_instance: true, - defer_vcs: false, - }, - ); - logWhenSubscriptionEstablished( - progressSubscriptionPromise, - WATCHMAN_SUBSCRIPTION_NAME_PROGRESS, - ); - - this._lockFilesDidChange = subscribeToFilesCreateAndDelete( - watchmanClient, - workingDirectory, - LockFilesList, - WATCHMAN_SUBSCRIPTION_NAME_LOCK_FILES, - ) - .publish() - .refCount(); + const hgBookmarksSubscriptionPromise = watchmanClient.watchDirectoryRecursive(workingDirectory, WATCHMAN_SUBSCRIPTION_NAME_HGBOOKMARKS, { + fields: ['name', 'exists'], + expression: ['name', '.hg/bookmarks', 'wholename'], + defer: ['hg.update'], + empty_on_fresh_instance: true + }); + logWhenSubscriptionEstablished(hgBookmarksSubscriptionPromise, WATCHMAN_SUBSCRIPTION_NAME_HGBOOKMARKS); + + const dirStateSubscriptionPromise = watchmanClient.watchDirectoryRecursive(workingDirectory, WATCHMAN_HG_DIR_STATE, { + fields: ['name'], + expression: ['name', '.hg/dirstate', 'wholename'], + defer: ['hg.update'], + empty_on_fresh_instance: true + }); + logWhenSubscriptionEstablished(dirStateSubscriptionPromise, WATCHMAN_HG_DIR_STATE); + + const progressSubscriptionPromise = watchmanClient.watchDirectoryRecursive(workingDirectory, WATCHMAN_SUBSCRIPTION_NAME_PROGRESS, { + fields: ['name'], + expression: ['name', '.hg/progress', 'wholename'], + empty_on_fresh_instance: true, + defer_vcs: false + }); + logWhenSubscriptionEstablished(progressSubscriptionPromise, WATCHMAN_SUBSCRIPTION_NAME_PROGRESS); + + this._lockFilesDidChange = (0, (_watchFileCreationAndDeletion || _load_watchFileCreationAndDeletion()).subscribeToFilesCreateAndDelete)(watchmanClient, workingDirectory, (_hgConstants || _load_hgConstants()).LockFilesList, WATCHMAN_SUBSCRIPTION_NAME_LOCK_FILES).publish().refCount(); // Those files' changes indicate a commit-changing action has been applied to the repository, // Watchman currently (v4.7) ignores `.hg/store` file updates. @@ -531,53 +414,27 @@ export class HgRepositorySubscriptions { const hgStoreDirectory = await findStoreDirectory(workingDirectory); const commitChangeIndicators = ['00changelog.i', 'obsstore', 'inhibit']; try { - this._hgStoreDirWatcher = fs.watch( - hgStoreDirectory, - (event, fileName) => { - if (commitChangeIndicators.indexOf(fileName) === -1) { - this._commitsDidChange(); - } - }, - ); - getLogger('nuclide-hg-rpc').debug('Node watcher created for .hg/store.'); + this._hgStoreDirWatcher = _fs.default.watch(hgStoreDirectory, (event, fileName) => { + if (commitChangeIndicators.indexOf(fileName) === -1) { + this._commitsDidChange(); + } + }); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').debug('Node watcher created for .hg/store.'); } catch (error) { - getLogger('nuclide-hg-rpc').error( - 'Error when creating node watcher for hg store', - error, - ); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').error('Error when creating node watcher for hg store', error); } - const [ - primarySubscription, - hgActiveBookmarkSubscription, - hgBookmarksSubscription, - dirStateSubscription, - conflictStateSubscription, - progressSubscription, - ] = await Promise.all([ - primarySubscriptionPromise, - hgActiveBookmarkSubscriptionPromise, - hgBookmarksSubscriptionPromise, - dirStateSubscriptionPromise, - conflictStateSubscriptionPromise, - progressSubscriptionPromise, - ]); + const [primarySubscription, hgActiveBookmarkSubscription, hgBookmarksSubscription, dirStateSubscription, conflictStateSubscription, progressSubscription] = await Promise.all([primarySubscriptionPromise, hgActiveBookmarkSubscriptionPromise, hgBookmarksSubscriptionPromise, dirStateSubscriptionPromise, conflictStateSubscriptionPromise, progressSubscriptionPromise]); primarySubscription.on('change', this._filesDidChange.bind(this)); - hgActiveBookmarkSubscription.on( - 'change', - this._hgActiveBookmarkDidChange.bind(this), - ); + hgActiveBookmarkSubscription.on('change', this._hgActiveBookmarkDidChange.bind(this)); hgBookmarksSubscription.on('change', this._hgBookmarksDidChange.bind(this)); dirStateSubscription.on('change', this._emitHgRepoStateChanged.bind(this)); conflictStateSubscription.on('change', this._debouncedCheckConflictChange); - progressSubscription.on( - 'change', - this._hgOperationProgressDidChange.bind(this), - ); + progressSubscription.on('change', this._hgOperationProgressDidChange.bind(this)); } - async _cleanUpWatchman(): Promise { + async _cleanUpWatchman() { if (this._watchmanClient != null) { await this._watchmanClient.dispose(); this._watchmanClient = null; @@ -587,48 +444,44 @@ export class HgRepositorySubscriptions { /** * @param fileChanges The latest changed watchman files. */ - _filesDidChange(fileChanges: Array): void { + _filesDidChange(fileChanges) { if (fileChanges.length > FILES_CHANGED_LIMIT) { this._emitHgRepoStateChanged(); return; } const workingDirectory = this._workingDirectory; - const changedFiles = fileChanges.map(change => - nuclideUri.join(workingDirectory, change.name), - ); + const changedFiles = fileChanges.map(change => (_nuclideUri || _load_nuclideUri()).default.join(workingDirectory, change.name)); this._filesDidChangeObserver.next(changedFiles); } - _commitsDidChange(): void { + _commitsDidChange() { this._hgRepoCommitsDidChangeObserver.next(); } - _checkMergeDirectoryExists(): Promise { - return fsPromise.exists( - nuclideUri.join(this._workingDirectory, '.hg', 'merge'), - ); + _checkMergeDirectoryExists() { + return (_fsPromise || _load_fsPromise()).default.exists((_nuclideUri || _load_nuclideUri()).default.join(this._workingDirectory, '.hg', 'merge')); } - async _checkConflictChange(): Promise { + async _checkConflictChange() { const mergeDirectoryExists = await this._checkMergeDirectoryExists(); this._isInConflict = mergeDirectoryExists; this._hgConflictStateDidChangeObserver.next(mergeDirectoryExists); } - _emitHgRepoStateChanged(): void { + _emitHgRepoStateChanged() { this._hgRepoStateDidChangeObserver.next(); } - _hgActiveBookmarkDidChange(): void { + _hgActiveBookmarkDidChange() { this._hgActiveBookmarkDidChangeObserver.next(); } - _hgBookmarksDidChange(): void { + _hgBookmarksDidChange() { this._hgBookmarksDidChangeObserver.next(); } - _hgOperationProgressDidChange(): void { + _hgOperationProgressDidChange() { this._hgOperationProgressDidChangeObserver.next(); } @@ -637,7 +490,7 @@ export class HgRepositorySubscriptions { * .hgignore files. (See ::onHgIgnoreFileDidChange.) * @return A Observable which emits the changed file paths. */ - observeFilesDidChange(): ConnectableObservable> { + observeFilesDidChange() { return this._filesDidChangeObserver.publish(); } @@ -645,28 +498,25 @@ export class HgRepositorySubscriptions { * Observes that a Mercurial repository commits state have changed * (e.g. commit, amend, histedit, strip, rebase) that would require refetching from the service. */ - observeHgCommitsDidChange(): ConnectableObservable { - return ( - this._hgRepoCommitsDidChangeObserver - // Upon rebase, this can fire once per added commit! - // Apply a generous debounce to avoid overloading the RPC connection. - .let(fastDebounce(COMMIT_CHANGE_DEBOUNCE_MS)) - .publish() - ); + observeHgCommitsDidChange() { + return this._hgRepoCommitsDidChangeObserver + // Upon rebase, this can fire once per added commit! + // Apply a generous debounce to avoid overloading the RPC connection. + .let((0, (_observable || _load_observable()).fastDebounce)(COMMIT_CHANGE_DEBOUNCE_MS)).publish(); } /** * Observes that a Mercurial event has occurred (e.g. histedit) that would * potentially invalidate any data cached from responses from this service. */ - observeHgRepoStateDidChange(): ConnectableObservable { + observeHgRepoStateDidChange() { return this._hgRepoStateDidChangeObserver.publish(); } /** * Observes when a Mercurial repository enters and exits a rebase state. */ - observeHgConflictStateDidChange(): ConnectableObservable { + observeHgConflictStateDidChange() { this._checkConflictChange(); return this._hgConflictStateDidChangeObserver.publish(); } @@ -674,59 +524,40 @@ export class HgRepositorySubscriptions { /** * Observes when the Mercurial operation progress has changed */ - observeHgOperationProgressDidChange(): ConnectableObservable { - return this._hgOperationProgressDidChangeObserver - .let(fastDebounce(50)) - .switchMap(() => - Observable.fromPromise( - fsPromise.readFile( - nuclideUri.join(this._workingDirectory, '.hg', 'progress'), - 'utf8', - ), - ) - .catch(() => { - getLogger('nuclide-hg-rpc').error( - '.hg/progress changed but could not be read', - ); - return Observable.empty(); - }) - .filter(content => content.length > 0) - .map(content => JSON.parse(content)) - .catch(() => { - getLogger('nuclide-hg-rpc').error( - '.hg/progress changed but its contents could not be parsed as JSON', - ); - return Observable.empty(); - }), - ) - .publish(); + observeHgOperationProgressDidChange() { + return this._hgOperationProgressDidChangeObserver.let((0, (_observable || _load_observable()).fastDebounce)(50)).switchMap(() => _rxjsBundlesRxMinJs.Observable.fromPromise((_fsPromise || _load_fsPromise()).default.readFile((_nuclideUri || _load_nuclideUri()).default.join(this._workingDirectory, '.hg', 'progress'), 'utf8')).catch(() => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').error('.hg/progress changed but could not be read'); + return _rxjsBundlesRxMinJs.Observable.empty(); + }).filter(content => content.length > 0).map(content => JSON.parse(content)).catch(() => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').error('.hg/progress changed but its contents could not be parsed as JSON'); + return _rxjsBundlesRxMinJs.Observable.empty(); + })).publish(); } /** * Observes that the active Mercurial bookmark has changed. */ - observeActiveBookmarkDidChange(): ConnectableObservable { + observeActiveBookmarkDidChange() { return this._hgActiveBookmarkDidChangeObserver.publish(); } /** * Observes that the Mercurial working directory lock has changed. */ - observeLockFilesDidChange(): ConnectableObservable> { + observeLockFilesDidChange() { return this._lockFilesDidChange.takeUntil(this._disposeObserver).publish(); } /** * Observes that Mercurial bookmarks have changed. */ - observeBookmarksDidChange(): ConnectableObservable { + observeBookmarksDidChange() { return this._hgBookmarksDidChangeObserver.publish(); } } -export function createRepositorySubscriptions( - workingDirectory: NuclideUri, -): Promise { +exports.HgRepositorySubscriptions = HgRepositorySubscriptions; +function createRepositorySubscriptions(workingDirectory) { return HgRepositorySubscriptions.create(workingDirectory); } @@ -737,81 +568,59 @@ export function createRepositorySubscriptions( /** * Shells out of the `hg status` to get the statuses of the paths. */ -export function fetchStatuses( - workingDirectory: NuclideUri, - toRevision?: string, -): ConnectableObservable> { +function fetchStatuses(workingDirectory, toRevision) { const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; const args = ['status', '-Tjson']; if (toRevision != null) { args.push('--rev', toRevision); } - return hgRunCommand(args, execOptions) - .map(stdout => { - const statusMap = new Map(); - const statuses = JSON.parse(stdout); - for (const status of takeIterable(statuses, NUM_FETCH_STATUSES_LIMIT)) { - statusMap.set( - nuclideUri.join(workingDirectory, status.path), - status.status, - ); - } - return statusMap; - }) - .publish(); + return (0, (_hgUtils || _load_hgUtils()).hgRunCommand)(args, execOptions).map(stdout => { + const statusMap = new Map(); + const statuses = JSON.parse(stdout); + for (const status of (0, (_collection || _load_collection()).takeIterable)(statuses, NUM_FETCH_STATUSES_LIMIT)) { + statusMap.set((_nuclideUri || _load_nuclideUri()).default.join(workingDirectory, status.path), status.status); + } + return statusMap; + }).publish(); } /** * Like fetchStatuses, but first calculates the root of the current * stack and fetches changes since that revision. */ -export function fetchStackStatuses( - workingDirectory: NuclideUri, -): ConnectableObservable> { +function fetchStackStatuses(workingDirectory) { // Note: an alternative which doesn't depend upon reading .arcconfig in getForkBaseName is: // return fetchStatuses(workingDirectory, ('ancestor(ancestor((not public()) and (:: .))^ or .)') // Both the code below and the alternative above have identical performance. - return Observable.fromPromise(getForkBaseName(workingDirectory)) // e.g. "master" - .switchMap(forkBaseName => { - const root = expressionForCommonAncestor(forkBaseName); // e.g. "ancestor(master, .)" - return fetchStatuses(workingDirectory, root).refCount(); - }) - .publish(); + return _rxjsBundlesRxMinJs.Observable.fromPromise(getForkBaseName(workingDirectory)) // e.g. "master" + .switchMap(forkBaseName => { + const root = (0, (_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).expressionForCommonAncestor)(forkBaseName); // e.g. "ancestor(master, .)" + return fetchStatuses(workingDirectory, root).refCount(); + }).publish(); } /** * Like fetchStatuses, but first checks whether the head is public. If so, returns * changes *since* the head. If not, returns changes *including* the head. */ -export function fetchHeadStatuses( - workingDirectory: NuclideUri, -): ConnectableObservable> { - return fetchStatuses( - workingDirectory, - 'ancestor(. or (. and (not public()))^)', - ); -} - -export async function getAdditionalLogFiles( - workingDirectory: NuclideUri, - deadline: DeadlineRequest, -): Promise> { - const options = {cwd: workingDirectory}; - const base = await timeoutAfterDeadline( - deadline, - getForkBaseName(workingDirectory), - ); // e.g. master - const root = expressionForCommonAncestor(base); // ancestor(master, .) +function fetchHeadStatuses(workingDirectory) { + return fetchStatuses(workingDirectory, 'ancestor(. or (. and (not public()))^)'); +} + +async function getAdditionalLogFiles(workingDirectory, deadline) { + const options = { cwd: workingDirectory }; + const base = await (0, (_promise || _load_promise()).timeoutAfterDeadline)(deadline, getForkBaseName(workingDirectory)); // e.g. master + const root = (0, (_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).expressionForCommonAncestor)(base); // ancestor(master, .) // The ID of the root const getId = async () => { try { const args = ['id', '--rev', root]; - const output = await hgAsyncExecute(args, options); + const output = await (0, (_hgUtils || _load_hgUtils()).hgAsyncExecute)(args, options); return output.stdout ? output.stdout.trim() : ''; } catch (e) { return ` { try { const args = ['diff', '--unified', '0', '-r', root]; - const output = await hgAsyncExecute(args, options); + const output = await (0, (_hgUtils || _load_hgUtils()).hgAsyncExecute)(args, options); return output.stdout ? output.stdout.trim() : ''; } catch (e) { return ``; @@ -831,9 +640,7 @@ export async function getAdditionalLogFiles( // Summary of changes from base to current working directory const getStatus = async () => { - const statuses = await fetchStatuses(workingDirectory, root) - .refCount() - .toPromise(); + const statuses = await fetchStatuses(workingDirectory, root).refCount().toPromise(); let result = ''; for (const [filepath, status] of statuses) { result += `${status} ${filepath}\n`; @@ -841,32 +648,19 @@ export async function getAdditionalLogFiles( return result; }; - const [id, hgDiff, status] = await Promise.all([ - timeoutAfterDeadline(deadline, getId()).catch( - e => `id ${e.message}\n${e.stack}`, - ), - timeoutAfterDeadline(deadline, getDiff()).catch( - e => 'diff ' + stringifyError(e), - ), - timeoutAfterDeadline(deadline, getStatus()).catch( - e => 'status ' + stringifyError(e), - ), - ]); + const [id, hgDiff, status] = await Promise.all([(0, (_promise || _load_promise()).timeoutAfterDeadline)(deadline, getId()).catch(e => `id ${e.message}\n${e.stack}`), (0, (_promise || _load_promise()).timeoutAfterDeadline)(deadline, getDiff()).catch(e => 'diff ' + (0, (_string || _load_string()).stringifyError)(e)), (0, (_promise || _load_promise()).timeoutAfterDeadline)(deadline, getStatus()).catch(e => 'status ' + (0, (_string || _load_string()).stringifyError)(e))]); - const results: Array = []; + const results = []; // If the user is on a public revision, there's no need to provide hgdiff. results.push({ title: `${workingDirectory}:hg`, - data: - `hg update -r ${id}\n` + - (status === '' ? '' : 'hg import --no-commit hgdiff\n') + - `\n${status}`, + data: `hg update -r ${id}\n` + (status === '' ? '' : 'hg import --no-commit hgdiff\n') + `\n${status}` }); if (status !== '') { results.push({ title: `${workingDirectory}:hgdiff`, - data: hgDiff, + data: hgDiff }); } @@ -881,38 +675,26 @@ export async function getAdditionalLogFiles( * If the `hg diff` call fails, this method returns null. * If a path has no changes, it will not appear in the returned Map. */ -export async function fetchDiffInfo( - workingDirectory: NuclideUri, - filePaths: Array, -): Promise> { +async function fetchDiffInfo(workingDirectory, filePaths) { // '--unified 0' gives us 0 lines of context around each change (we don't // care about the context). // '--noprefix' omits the a/ and b/ prefixes from filenames. // '--nodates' avoids appending dates to the file path line. - const args = ['diff', '--unified', '0', '--noprefix', '--nodates'].concat( - filePaths, - ); + const args = ['diff', '--unified', '0', '--noprefix', '--nodates'].concat(filePaths); const options = { - cwd: workingDirectory, + cwd: workingDirectory }; let output; try { - output = await hgAsyncExecute(args, options); + output = await (0, (_hgUtils || _load_hgUtils()).hgAsyncExecute)(args, options); } catch (e) { - getLogger('nuclide-hg-rpc').error( - `Error when running hg diff for paths: ${filePaths.toString()} \n\tError: ${ - e.stderr - }`, - ); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').error(`Error when running hg diff for paths: ${filePaths.toString()} \n\tError: ${e.stderr}`); return null; } - const pathToDiffInfo = parseMultiFileHgDiffUnifiedOutput(output.stdout); + const pathToDiffInfo = (0, (_hgDiffOutputParser || _load_hgDiffOutputParser()).parseMultiFileHgDiffUnifiedOutput)(output.stdout); const absolutePathToDiffInfo = new Map(); for (const [filePath, diffInfo] of pathToDiffInfo) { - absolutePathToDiffInfo.set( - nuclideUri.join(workingDirectory, filePath), - diffInfo, - ); + absolutePathToDiffInfo.set((_nuclideUri || _load_nuclideUri()).default.join(workingDirectory, filePath), diffInfo); } return absolutePathToDiffInfo; } @@ -921,11 +703,7 @@ export async function fetchDiffInfo( * Section: Bookmarks */ -export function createBookmark( - workingDirectory: NuclideUri, - name: string, - revision: ?string, -): Promise { +function createBookmark(workingDirectory, name, revision) { const args = []; // flowlint-next-line sketchy-null-string:off if (revision) { @@ -936,48 +714,26 @@ export function createBookmark( return _runSimpleInWorkingDirectory(workingDirectory, 'bookmark', args); } -export function deleteBookmark( - workingDirectory: NuclideUri, - name: string, -): Promise { - return _runSimpleInWorkingDirectory(workingDirectory, 'bookmarks', [ - '--delete', - name, - ]); +function deleteBookmark(workingDirectory, name) { + return _runSimpleInWorkingDirectory(workingDirectory, 'bookmarks', ['--delete', name]); } -export function renameBookmark( - workingDirectory: NuclideUri, - name: string, - nextName: string, -): Promise { - return _runSimpleInWorkingDirectory(workingDirectory, 'bookmarks', [ - '--rename', - name, - nextName, - ]); +function renameBookmark(workingDirectory, name, nextName) { + return _runSimpleInWorkingDirectory(workingDirectory, 'bookmarks', ['--rename', name, nextName]); } /** * @return The name of the current bookmark. */ -export function fetchActiveBookmark( - workingDirectory: NuclideUri, -): Promise { - return BookmarkHelpers.fetchActiveBookmark( - nuclideUri.join(workingDirectory, '.hg'), - ); +function fetchActiveBookmark(workingDirectory) { + return (_hgBookmarkHelpers || _load_hgBookmarkHelpers()).fetchActiveBookmark((_nuclideUri || _load_nuclideUri()).default.join(workingDirectory, '.hg')); } /** * @return An Array of bookmarks for this repository. */ -export function fetchBookmarks( - workingDirectory: NuclideUri, -): Promise> { - return BookmarkHelpers.fetchBookmarks( - nuclideUri.join(workingDirectory, '.hg'), - ); +function fetchBookmarks(workingDirectory) { + return (_hgBookmarkHelpers || _load_hgBookmarkHelpers()).fetchBookmarks((_nuclideUri || _load_nuclideUri()).default.join(workingDirectory, '.hg')); } /** @@ -989,35 +745,16 @@ export function fetchBookmarks( * @param revision: An expression that hg can understand, specifying the * revision at which we want to see the file content. */ -export function fetchFileContentAtRevision( - workingDirectory: NuclideUri, - filePath: NuclideUri, - revision: string, -): ConnectableObservable { - return StateHelpers.fetchFileContentAtRevision( - filePath, - revision, - workingDirectory, - ); -} - -export function batchFetchFileContentsAtRevision( - workingDirectory: NuclideUri, - filePaths: Array, - revision: string, -): ConnectableObservable> { - return StateHelpers.batchFetchFileContentsAtRevision( - filePaths, - revision, - workingDirectory, - ); -} - -export function fetchFilesChangedAtRevision( - workingDirectory: NuclideUri, - revision: string, -): ConnectableObservable { - return StateHelpers.fetchFilesChangedAtRevision(revision, workingDirectory); +function fetchFileContentAtRevision(workingDirectory, filePath, revision) { + return (_hgRevisionStateHelpers || _load_hgRevisionStateHelpers()).fetchFileContentAtRevision(filePath, revision, workingDirectory); +} + +function batchFetchFileContentsAtRevision(workingDirectory, filePaths, revision) { + return (_hgRevisionStateHelpers || _load_hgRevisionStateHelpers()).batchFetchFileContentsAtRevision(filePaths, revision, workingDirectory); +} + +function fetchFilesChangedAtRevision(workingDirectory, revision) { + return (_hgRevisionStateHelpers || _load_hgRevisionStateHelpers()).fetchFilesChangedAtRevision(revision, workingDirectory); } /** @@ -1026,35 +763,22 @@ export function fetchFilesChangedAtRevision( * @return an array with the revision info (`title`, `author`, `date` and `id`) * or `null` if no common ancestor was found. */ -export async function fetchRevisionInfoBetweenHeadAndBase( - workingDirectory: NuclideUri, -): Promise> { +async function fetchRevisionInfoBetweenHeadAndBase(workingDirectory) { const forkBaseName = await getForkBaseName(workingDirectory); - const revisionsInfo = await fetchRevisionInfoBetweenRevisions( - expressionForCommonAncestor(forkBaseName), - expressionForRevisionsBeforeHead(0), - workingDirectory, - ); + const revisionsInfo = await (0, (_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).fetchRevisionInfoBetweenRevisions)((0, (_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).expressionForCommonAncestor)(forkBaseName), (0, (_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).expressionForRevisionsBeforeHead)(0), workingDirectory); return revisionsInfo; } -export function fetchSmartlogRevisions( - workingDirectory: NuclideUri, -): ConnectableObservable> { - return fetchSmartlogRevisionsImpl(workingDirectory); +function fetchSmartlogRevisions(workingDirectory) { + return (0, (_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).fetchSmartlogRevisions)(workingDirectory); } /** * Resolve the revision details of the base branch */ -export async function getBaseRevision( - workingDirectory: NuclideUri, -): Promise { +async function getBaseRevision(workingDirectory) { const forkBaseName = await getForkBaseName(workingDirectory); - return fetchRevisionInfo( - expressionForCommonAncestor(forkBaseName), - workingDirectory, - ); + return (0, (_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).fetchRevisionInfo)((0, (_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).expressionForCommonAncestor)(forkBaseName), workingDirectory); } /** @@ -1063,48 +787,25 @@ export async function getBaseRevision( * @param filePath The file to get blame information for. * @return An Array that maps a line number (0-indexed) to the revision info. */ -export async function getBlameAtHead( - workingDirectory: NuclideUri, - filePath: NuclideUri, -): Promise> { +async function getBlameAtHead(workingDirectory, filePath) { let revisionsByLine; try { - revisionsByLine = (await hgAsyncExecute( - [ - 'blame', - '-c', // Query the hash - '-T', - '{lines % "{node|short}\n"}', // Just display the hash per line - '-r', - 'wdir()', // Blank out uncommitted changes - filePath, - ], - {cwd: workingDirectory}, - )).stdout.split('\n'); + revisionsByLine = (await (0, (_hgUtils || _load_hgUtils()).hgAsyncExecute)(['blame', '-c', // Query the hash + '-T', '{lines % "{node|short}\n"}', // Just display the hash per line + '-r', 'wdir()', // Blank out uncommitted changes + filePath], { cwd: workingDirectory })).stdout.split('\n'); } catch (e) { - getLogger('nuclide-hg-rpc').error( - `LocalHgServiceBase failed to fetch blame for file: ${filePath}. Error: ${ - e.stderr - }`, - ); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').error(`LocalHgServiceBase failed to fetch blame for file: ${filePath}. Error: ${e.stderr}`); throw e; } - const uniqueRevisions = [...(new Set(revisionsByLine.filter(e => e)): any)]; + const uniqueRevisions = [...new Set(revisionsByLine.filter(e => e))]; let revisionsArray; try { - revisionsArray = await fetchRevisionsInfo( - uniqueRevisions.join('+'), - workingDirectory, - {hidden: true, shouldLimit: false}, - ).toPromise(); + revisionsArray = await (0, (_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).fetchRevisionsInfo)(uniqueRevisions.join('+'), workingDirectory, { hidden: true, shouldLimit: false }).toPromise(); } catch (e) { - getLogger('nuclide-hg-rpc').error( - `LocalHgServiceBase failed to fetch blame for file: ${filePath}. Error: ${ - e.stderr - }`, - ); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').error(`LocalHgServiceBase failed to fetch blame for file: ${filePath}. Error: ${e.stderr}`); throw e; } @@ -1120,20 +821,15 @@ export async function getBlameAtHead( * Returns the value of the config item at `key`. * @param key Name of config item */ -export async function getConfigValueAsync( - workingDirectory: NuclideUri, - key: string, -): Promise { +async function getConfigValueAsync(workingDirectory, key) { const args = ['config', key]; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; try { - return (await hgAsyncExecute(args, execOptions)).stdout.trim(); + return (await (0, (_hgUtils || _load_hgUtils()).hgAsyncExecute)(args, execOptions)).stdout.trim(); } catch (e) { - getLogger('nuclide-hg-rpc').error( - `Failed to fetch Hg config for key ${key}. Error: ${e.toString()}`, - ); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').error(`Failed to fetch Hg config for key ${key}. Error: ${e.toString()}`); return null; } } @@ -1144,31 +840,18 @@ export async function getConfigValueAsync( * This implementation relies on the "phabdiff" template being available as defined in: * https://bitbucket.org/facebook/hg-experimental/src/fbf23b3f96bade5986121a7c57d7400585d75f54/phabdiff.py. */ -export async function getDifferentialRevisionForChangeSetId( - workingDirectory: NuclideUri, - changeSetId: string, -): Promise { - const args = [ - 'log', - '-T', - '{phabdiff}\n', - '--limit', - '1', - '--rev', - changeSetId, - ]; +async function getDifferentialRevisionForChangeSetId(workingDirectory, changeSetId) { + const args = ['log', '-T', '{phabdiff}\n', '--limit', '1', '--rev', changeSetId]; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; try { - const output = await hgAsyncExecute(args, execOptions); + const output = await (0, (_hgUtils || _load_hgUtils()).hgAsyncExecute)(args, execOptions); const stdout = output.stdout.trim(); return stdout ? stdout : null; } catch (e) { // This should not happen: `hg log` does not error even if it does not recognize the template. - getLogger('nuclide-hg-rpc').error( - `Failed when trying to get differential revision for: ${changeSetId}`, - ); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').error(`Failed when trying to get differential revision for: ${changeSetId}`); return null; } } @@ -1180,47 +863,37 @@ export async function getDifferentialRevisionForChangeSetId( * @param concise true to run `hg smartlog`; false to run `hg ssl`. * @return The output from running the command. */ -export async function getSmartlog( - workingDirectory: NuclideUri, - ttyOutput: boolean, - concise: boolean, -): Promise { +async function getSmartlog(workingDirectory, ttyOutput, concise) { // disable the pager extension so that 'hg ssl' terminates. We can't just use // HGPLAIN because we have not found a way to get colored output when we do. const args = ['--config', 'extensions.pager=!', concise ? 'ssl' : 'smartlog']; const execOptions = { cwd: workingDirectory, NO_HGPLAIN: concise, // `hg ssl` is likely user-defined. - TTY_OUTPUT: ttyOutput, + TTY_OUTPUT: ttyOutput }; - return hgAsyncExecute(args, execOptions); + return (0, (_hgUtils || _load_hgUtils()).hgAsyncExecute)(args, execOptions); } -function _commitCode( - workingDirectory: NuclideUri, - message: ?string, - args: Array, -): Observable { +function _commitCode(workingDirectory, message, args) { // TODO(T17463635) let editMergeConfigs; - return Observable.fromPromise( - (async () => { - if (message == null) { - return args; - } else { - return [...args, '-m', formatCommitMessage(message)]; - } - })(), - ).switchMap(argumentsWithCommitFile => { + return _rxjsBundlesRxMinJs.Observable.fromPromise((async () => { + if (message == null) { + return args; + } else { + return [...args, '-m', (0, (_hgUtils || _load_hgUtils()).formatCommitMessage)(message)]; + } + })()).switchMap(argumentsWithCommitFile => { const execArgs = argumentsWithCommitFile; - const execOptions: HgExecOptions = { - cwd: workingDirectory, + const execOptions = { + cwd: workingDirectory }; if (editMergeConfigs != null) { execArgs.push(...editMergeConfigs.args); execOptions.HGEDITOR = editMergeConfigs.hgEditor; } - return hgObserveExecution(execArgs, execOptions); + return (0, (_hgUtils || _load_hgUtils()).hgObserveExecution)(execArgs, execOptions); }); } @@ -1229,16 +902,9 @@ function _commitCode( * @param message Commit message. * @param filePaths List of changed files to commit. If empty, all will be committed */ -export function commit( - workingDirectory: NuclideUri, - message: string, - filePaths: Array = [], -): ConnectableObservable { +function commit(workingDirectory, message, filePaths = []) { // TODO(T17463635) - return _commitCode(workingDirectory, message, [ - 'commit', - ...filePaths, - ]).publish(); + return _commitCode(workingDirectory, message, ['commit', ...filePaths]).publish(); } /* @@ -1247,16 +913,12 @@ export function commit( * @param message New commit message * @return Process update message while running metaedit */ -export function editCommitMessage( - workingDirectory: NuclideUri, - revision: string, - message: string, -): ConnectableObservable { +function editCommitMessage(workingDirectory, revision, message) { const args = ['metaedit', '-r', revision, '-m', message]; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgObserveExecution(args, execOptions).publish(); + return (0, (_hgUtils || _load_hgUtils()).hgObserveExecution)(args, execOptions).publish(); } /** @@ -1268,12 +930,7 @@ export function editCommitMessage( * Fixup to fix the stacked commits, rebasing them on top of this commit. * @param filePaths List of changed files to commit. If empty, all will be committed */ -export function amend( - workingDirectory: NuclideUri, - message: ?string, - amendMode: AmendModeValue, - filePaths: Array = [], -): ConnectableObservable { +function amend(workingDirectory, message, amendMode, filePaths = []) { // TODO(T17463635) const args = ['amend', ...filePaths]; switch (amendMode) { @@ -1286,27 +943,21 @@ export function amend( args.push('--fixup'); break; default: - (amendMode: empty); + amendMode; throw new Error('Unexpected AmendMode'); } return _commitCode(workingDirectory, message, args).publish(); } -export function restack( - workingDirectory: NuclideUri, -): ConnectableObservable { +function restack(workingDirectory) { const args = ['rebase', '--restack']; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgObserveExecution(args, execOptions).publish(); + return (0, (_hgUtils || _load_hgUtils()).hgObserveExecution)(args, execOptions).publish(); } -export function revert( - workingDirectory: NuclideUri, - filePaths: Array, - toRevision: ?string, -): Promise { +function revert(workingDirectory, filePaths, toRevision) { const args = [...filePaths]; if (toRevision != null) { args.push('--rev', toRevision); @@ -1314,25 +965,16 @@ export function revert( return _runSimpleInWorkingDirectory(workingDirectory, 'revert', args); } -async function _runSimpleInWorkingDirectory( - workingDirectory: NuclideUri, - action: string, - args: Array, -): Promise { +async function _runSimpleInWorkingDirectory(workingDirectory, action, args) { const options = { - cwd: workingDirectory, + cwd: workingDirectory }; const cmd = [action].concat(args); try { - await hgAsyncExecute(cmd, options); + await (0, (_hgUtils || _load_hgUtils()).hgAsyncExecute)(cmd, options); } catch (e) { const errorString = e.stderr || e.message || e.toString(); - getLogger('nuclide-hg-rpc').error( - 'hg %s failed with [%s] arguments: %s', - action, - args.toString(), - errorString, - ); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').error('hg %s failed with [%s] arguments: %s', action, args.toString(), errorString); throw new Error(errorString); } } @@ -1342,46 +984,29 @@ async function _runSimpleInWorkingDirectory( * @param create Currently, this parameter is ignored. * @param options. */ -export function checkout( - workingDirectory: NuclideUri, - revision: string, - create: boolean, - options?: CheckoutOptions, -): ConnectableObservable { +function checkout(workingDirectory, revision, create, options) { // TODO(T17463635) const args = ['checkout', revision]; if (options && options.clean) { args.push('--clean'); } const executionOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgObserveExecution(args, executionOptions).publish(); + return (0, (_hgUtils || _load_hgUtils()).hgObserveExecution)(args, executionOptions).publish(); } -export function show( - workingDirectory: NuclideUri, - revision: number, -): ConnectableObservable { +function show(workingDirectory, revision) { const args = ['show', `${revision}`, '--git', '-Tjson']; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgRunCommand(args, execOptions) - .map(stdout => { - return JSON.parse(stdout)[0]; - }) - .publish(); + return (0, (_hgUtils || _load_hgUtils()).hgRunCommand)(args, execOptions).map(stdout => { + return JSON.parse(stdout)[0]; + }).publish(); } -export function diff( - workingDirectory: NuclideUri, - revision: string, - unified: ?number, - diffCommitted: ?boolean, - noPrefix: ?boolean, - noDates: ?boolean, -): ConnectableObservable { +function diff(workingDirectory, revision, unified, diffCommitted, noPrefix, noDates) { const args = ['diff', diffCommitted ? '-c' : '-r', revision]; if (unified != null) { args.push('--unified', `${unified}`); @@ -1393,32 +1018,29 @@ export function diff( args.push('--nodates'); } const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgRunCommand(args, execOptions).publish(); + return (0, (_hgUtils || _load_hgUtils()).hgRunCommand)(args, execOptions).publish(); } /** * Removes files not tracked by Mercurial. */ -export function purge(workingDirectory: NuclideUri): Promise { +function purge(workingDirectory) { return _runSimpleInWorkingDirectory(workingDirectory, 'purge', []); } /** * Undoes the effect of a local commit, specifically the working directory parent. */ -export function uncommit(workingDirectory: NuclideUri): Promise { +function uncommit(workingDirectory) { return _runSimpleInWorkingDirectory(workingDirectory, 'uncommit', []); } /** * @param revision This could be a changeset ID, name of a bookmark, revision number, etc. */ -export function strip( - workingDirectory: NuclideUri, - revision: string, -): Promise { +function strip(workingDirectory, revision) { return _runSimpleInWorkingDirectory(workingDirectory, 'hide', [revision]); } @@ -1426,13 +1048,9 @@ export function strip( * @param revision This could be a changeset ID, name of a bookmark, revision number, etc. * @param create Currently, this parameter is ignored. */ -export async function checkoutForkBase( - workingDirectory: NuclideUri, -): Promise { +async function checkoutForkBase(workingDirectory) { const forkBaseName = await getForkBaseName(workingDirectory); - await _runSimpleInWorkingDirectory(workingDirectory, 'checkout', [ - forkBaseName, - ]); + await _runSimpleInWorkingDirectory(workingDirectory, 'checkout', [forkBaseName]); } /* @@ -1440,7 +1058,7 @@ export async function checkoutForkBase( * are generally harmless and should not create an error notification. * This checks the error string in order to avoid potentially slow hg pre-checks. */ -function _rethrowErrorIfHelpful(e: Error): void { +function _rethrowErrorIfHelpful(e) { if (!IGNORABLE_ERROR_SUFFIXES.some(s => e.message.endsWith(s + '\n'))) { throw e; } @@ -1451,16 +1069,9 @@ function _rethrowErrorIfHelpful(e: Error): void { * @param filePaths Which files should be renamed/moved. * @param destPath What should the file be renamed/moved to. */ -export async function rename( - workingDirectory: NuclideUri, - filePaths: Array, - destPath: NuclideUri, - after?: boolean, -): Promise { - const args = [ - ...filePaths.map(p => nuclideUri.getPath(p)), // Sources - nuclideUri.getPath(destPath), // Dest - ]; +async function rename(workingDirectory, filePaths, destPath, after) { + const args = [...filePaths.map(p => (_nuclideUri || _load_nuclideUri()).default.getPath(p)), // Sources + (_nuclideUri || _load_nuclideUri()).default.getPath(destPath)]; if (after) { args.unshift('--after'); } @@ -1479,12 +1090,8 @@ export async function rename( * Remove a file versioned under Hg. * @param filePath Which file should be removed. */ -export async function remove( - workingDirectory: NuclideUri, - filePaths: Array, - after?: boolean, -): Promise { - const args = ['-f', ...filePaths.map(p => nuclideUri.getPath(p))]; +async function remove(workingDirectory, filePaths, after) { + const args = ['-f', ...filePaths.map(p => (_nuclideUri || _load_nuclideUri()).default.getPath(p))]; if (after) { args.unshift('--after'); } @@ -1505,11 +1112,8 @@ export async function remove( * The file will remain in the working directory. * @param filePath Which file(s) should be forgotten. */ -export async function forget( - workingDirectory: NuclideUri, - filePaths: Array, -): Promise { - const args = [...filePaths.map(p => nuclideUri.getPath(p))]; +async function forget(workingDirectory, filePaths) { + const args = [...filePaths.map(p => (_nuclideUri || _load_nuclideUri()).default.getPath(p))]; try { await _runSimpleInWorkingDirectory(workingDirectory, 'forget', args); } catch (e) { @@ -1521,65 +1125,42 @@ export async function forget( * Version a new file under Hg. * @param filePath Which file should be versioned. */ -export function add( - workingDirectory: NuclideUri, - filePaths: Array, -): Promise { +function add(workingDirectory, filePaths) { return _runSimpleInWorkingDirectory(workingDirectory, 'add', filePaths); } -export async function getTemplateCommitMessage( - workingDirectory: NuclideUri, -): Promise { +async function getTemplateCommitMessage(workingDirectory) { const args = ['debugcommitmessage']; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; try { - const {stdout} = await hgAsyncExecute(args, execOptions); + const { stdout } = await (0, (_hgUtils || _load_hgUtils()).hgAsyncExecute)(args, execOptions); return stdout; } catch (e) { - getLogger('nuclide-hg-rpc').error( - 'Failed when trying to get template commit message', - ); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').error('Failed when trying to get template commit message'); return null; } } -export async function getHeadCommitMessage( - workingDirectory: NuclideUri, -): Promise { - const args = [ - 'log', - '-T', - '{desc}\n', - '--limit', - '1', - '--rev', - expressionForRevisionsBeforeHead(0), - ]; +async function getHeadCommitMessage(workingDirectory) { + const args = ['log', '-T', '{desc}\n', '--limit', '1', '--rev', (0, (_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).expressionForRevisionsBeforeHead)(0)]; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; try { - const output = await hgAsyncExecute(args, execOptions); + const output = await (0, (_hgUtils || _load_hgUtils()).hgAsyncExecute)(args, execOptions); const stdout = output.stdout.trim(); return stdout || null; } catch (e) { // This should not happen: `hg log` does not error even if it does not recognize the template. - getLogger('nuclide-hg-rpc').error( - 'Failed when trying to get head commit message', - ); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').error('Failed when trying to get head commit message'); return null; } } -export async function log( - workingDirectory: NuclideUri, - filePaths: Array, - limit?: ?number, -): Promise { +async function log(workingDirectory, filePaths, limit) { const args = ['log', '-Tjson']; if (limit != null && limit > 0) { args.push('--limit', String(limit)); @@ -1589,113 +1170,83 @@ export async function log( } const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - const result = await hgAsyncExecute(args, execOptions); + const result = await (0, (_hgUtils || _load_hgUtils()).hgAsyncExecute)(args, execOptions); const entries = JSON.parse(result.stdout); - return {entries}; -} - -export function fetchMergeConflicts( - workingDirectory: NuclideUri, -): ConnectableObservable { - const args = [ - 'resolve', - '--tool=internal:dumpjson', - '--all', - '--config', - 'extensions.conflictinfo=', - ]; + return { entries }; +} + +function fetchMergeConflicts(workingDirectory) { + const args = ['resolve', '--tool=internal:dumpjson', '--all', '--config', 'extensions.conflictinfo=']; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return ( - hgRunCommand(args, execOptions) - .map(data => { - const parsedData = JSON.parse(data)[0]; - if (parsedData.command == null) { - return null; - } - const conflicts = parsedData.conflicts.map(conflict => { - const {local, other} = conflict; - let status; - conflict.output.path = resolvePathForPlatform(conflict.output.path); - if (local.exists && other.exists) { - status = MergeConflictStatus.BOTH_CHANGED; - } else if (local.exists) { - status = MergeConflictStatus.DELETED_IN_THEIRS; - } else { - status = MergeConflictStatus.DELETED_IN_OURS; - } - - return { - ...conflict, - status, - }; - }); - return { - ...parsedData, - conflicts, - }; - }) - // `resolve --all` returns a non-zero exit code when there's no conflicts. - .catch(() => Observable.of(null)) - .publish() - ); -} - -export function markConflictedFile( - workingDirectory: NuclideUri, - filePath: NuclideUri, - resolved: boolean, -): ConnectableObservable { + return (0, (_hgUtils || _load_hgUtils()).hgRunCommand)(args, execOptions).map(data => { + const parsedData = JSON.parse(data)[0]; + if (parsedData.command == null) { + return null; + } + const conflicts = parsedData.conflicts.map(conflict => { + const { local, other } = conflict; + let status; + conflict.output.path = resolvePathForPlatform(conflict.output.path); + if (local.exists && other.exists) { + status = (_hgConstants || _load_hgConstants()).MergeConflictStatus.BOTH_CHANGED; + } else if (local.exists) { + status = (_hgConstants || _load_hgConstants()).MergeConflictStatus.DELETED_IN_THEIRS; + } else { + status = (_hgConstants || _load_hgConstants()).MergeConflictStatus.DELETED_IN_OURS; + } + + return Object.assign({}, conflict, { + status + }); + }); + return Object.assign({}, parsedData, { + conflicts + }); + }) + // `resolve --all` returns a non-zero exit code when there's no conflicts. + .catch(() => _rxjsBundlesRxMinJs.Observable.of(null)).publish(); +} + +function markConflictedFile(workingDirectory, filePath, resolved) { // TODO(T17463635) // -m marks file as resolved, -u marks file as unresolved const fileStatus = resolved ? '-m' : '-u'; const args = ['resolve', fileStatus, filePath]; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgObserveExecution(args, execOptions).publish(); + return (0, (_hgUtils || _load_hgUtils()).hgObserveExecution)(args, execOptions).publish(); } -export function continueOperation( - workingDirectory: NuclideUri, - args: Array, -): ConnectableObservable { +function continueOperation(workingDirectory, args) { // TODO(T17463635) const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgObserveExecution(args, execOptions).publish(); + return (0, (_hgUtils || _load_hgUtils()).hgObserveExecution)(args, execOptions).publish(); } -export function abortOperation( - workingDirectory: NuclideUri, - commandWithOptions: Array, -): ConnectableObservable { +function abortOperation(workingDirectory, commandWithOptions) { const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgRunCommand(commandWithOptions, execOptions).publish(); + return (0, (_hgUtils || _load_hgUtils()).hgRunCommand)(commandWithOptions, execOptions).publish(); } -export function resolveAllFiles( - workingDirectory: NuclideUri, -): ConnectableObservable { +function resolveAllFiles(workingDirectory) { const args = ['resolve', '--all']; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgObserveExecution(args, execOptions).publish(); + return (0, (_hgUtils || _load_hgUtils()).hgObserveExecution)(args, execOptions).publish(); } -export function rebase( - workingDirectory: NuclideUri, - destination: string, - source?: string, -): ConnectableObservable { +function rebase(workingDirectory, destination, source) { // TODO(T17463635) const args = ['rebase', '-d', destination]; @@ -1703,9 +1254,9 @@ export function rebase( args.push('-s', source); } const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgObserveExecution(args, execOptions).publish(); + return (0, (_hgUtils || _load_hgUtils()).hgObserveExecution)(args, execOptions).publish(); } /** @@ -1714,42 +1265,32 @@ export function rebase( * stack above where any reordering takes place, and there can be no * branches off of any revision in the stack except the top one. */ -export function reorderWithinStack( - workingDirectory: NuclideUri, - orderedRevisions: Array, -): ConnectableObservable { - const args = [ - 'histedit', - '--commands', - '-', // read from stdin instead of a file - ]; +function reorderWithinStack(workingDirectory, orderedRevisions) { + const args = ['histedit', '--commands', '-']; const commandsJson = JSON.stringify({ histedit: orderedRevisions.map(hash => { return { node: hash, - action: HisteditActions.PICK, + action: (_hgConstants || _load_hgConstants()).HisteditActions.PICK }; - }), + }) }); const execOptions = { cwd: workingDirectory, - input: commandsJson, + input: commandsJson }; - return hgRunCommand(args, execOptions).publish(); + return (0, (_hgUtils || _load_hgUtils()).hgRunCommand)(args, execOptions).publish(); } -export function pull( - workingDirectory: NuclideUri, - options: Array, -): ConnectableObservable { +function pull(workingDirectory, options) { // TODO(T17463635) const args = ['pull', ...options]; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgObserveExecution(args, execOptions).publish(); + return (0, (_hgUtils || _load_hgUtils()).hgObserveExecution)(args, execOptions).publish(); } /** @@ -1757,16 +1298,9 @@ export function pull( * @param filePaths Which files should be copied. * @param destPath What should the new file be named to. */ -export async function copy( - workingDirectory: NuclideUri, - filePaths: Array, - destPath: NuclideUri, - after?: boolean, -): Promise { - const args = [ - ...filePaths.map(p => nuclideUri.getPath(p)), // Sources - nuclideUri.getPath(destPath), // Dest - ]; +async function copy(workingDirectory, filePaths, destPath, after) { + const args = [...filePaths.map(p => (_nuclideUri || _load_nuclideUri()).default.getPath(p)), // Sources + (_nuclideUri || _load_nuclideUri()).default.getPath(destPath)]; if (after) { args.unshift('--after'); } @@ -1784,28 +1318,23 @@ export async function copy( /** * Gets the current head revision hash */ -export function getHeadId( - workingDirectory: NuclideUri, -): ConnectableObservable { +function getHeadId(workingDirectory) { const args = ['log', '--template', '{node}', '--limit', '1']; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgRunCommand(args, execOptions).publish(); + return (0, (_hgUtils || _load_hgUtils()).hgRunCommand)(args, execOptions).publish(); } /** * Given a short hash or revset, returns the full 40-char hash. */ -export async function getFullHashForRevision( - workingDirectory: NuclideUri, - rev: string, -): Promise { +async function getFullHashForRevision(workingDirectory, rev) { const args = ['log', '--template', '{node}', '--limit', '1', '-r', rev]; const options = { - cwd: workingDirectory, + cwd: workingDirectory }; - const output = await hgAsyncExecute(args, options); + const output = await (0, (_hgUtils || _load_hgUtils()).hgAsyncExecute)(args, options); return output.stdout ? output.stdout.trim() : null; } @@ -1814,46 +1343,32 @@ export async function getFullHashForRevision( * @param to This could be a changeset ID, name of a bookmark, revision number, etc. * @param message New message for the resulting folded commit. */ -export function fold( - workingDirectory: NuclideUri, - from: string, - to: string, - message: string, -): ConnectableObservable { +function fold(workingDirectory, from, to, message) { const args = ['fold', '--exact', `${from}::${to}`, '--message', message]; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgRunCommand(args, execOptions).publish(); + return (0, (_hgUtils || _load_hgUtils()).hgRunCommand)(args, execOptions).publish(); } -export function runCommand( - workingDirectory: NuclideUri, - args: Array, -): ConnectableObservable { +function runCommand(workingDirectory, args) { const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgRunCommand(args, execOptions).publish(); + return (0, (_hgUtils || _load_hgUtils()).hgRunCommand)(args, execOptions).publish(); } -export function observeExecution( - workingDirectory: NuclideUri, - args: Array, -): ConnectableObservable { +function observeExecution(workingDirectory, args) { const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgObserveExecution(args, execOptions).publish(); + return (0, (_hgUtils || _load_hgUtils()).hgObserveExecution)(args, execOptions).publish(); } // not really Hg functionality, but this was chosen to be the best current home // for this method as it spawns processes and should live in an remote service -export function gitDiffStrings( - oldContents: string, - newContents: string, -): ConnectableObservable { - return gitDiffStringsImpl(oldContents, newContents).publish(); -} +function gitDiffStrings(oldContents, newContents) { + return (0, (_gitDiff || _load_gitDiff()).gitDiffStrings)(oldContents, newContents).publish(); +} \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/lib/HgServiceProxy.js b/pkg/nuclide-hg-rpc/lib/HgServiceProxy.js new file mode 100644 index 0000000000..41a3ab5a06 --- /dev/null +++ b/pkg/nuclide-hg-rpc/lib/HgServiceProxy.js @@ -0,0 +1,5246 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + remoteModule.HgRepositorySubscriptions = class { + static create(arg0) { + return _client.callRemoteFunction("HgRepositorySubscriptions/create", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "HgRepositorySubscriptions" + }); + }); + } + + constructor() { + throw Error("constructors are not supported for remote objects"); + } + + observeFilesDidChange() { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "HgService.js", + line: 342 + }, + name: "HgRepositorySubscriptions" + }), "observeFilesDidChange", "observable", _client.marshalArguments(Array.from(arguments), [])).map(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + }); + }).publish(); + } + + observeHgCommitsDidChange() { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "HgService.js", + line: 342 + }, + name: "HgRepositorySubscriptions" + }), "observeHgCommitsDidChange", "observable", _client.marshalArguments(Array.from(arguments), [])).map(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }).publish(); + } + + observeHgRepoStateDidChange() { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "HgService.js", + line: 342 + }, + name: "HgRepositorySubscriptions" + }), "observeHgRepoStateDidChange", "observable", _client.marshalArguments(Array.from(arguments), [])).map(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }).publish(); + } + + observeHgConflictStateDidChange() { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "HgService.js", + line: 342 + }, + name: "HgRepositorySubscriptions" + }), "observeHgConflictStateDidChange", "observable", _client.marshalArguments(Array.from(arguments), [])).map(value => { + return _client.unmarshal(value, { + kind: "boolean" + }); + }).publish(); + } + + observeHgOperationProgressDidChange() { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "HgService.js", + line: 342 + }, + name: "HgRepositorySubscriptions" + }), "observeHgOperationProgressDidChange", "observable", _client.marshalArguments(Array.from(arguments), [])).map(value => { + return _client.unmarshal(value, { + kind: "any" + }); + }).publish(); + } + + observeActiveBookmarkDidChange() { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "HgService.js", + line: 342 + }, + name: "HgRepositorySubscriptions" + }), "observeActiveBookmarkDidChange", "observable", _client.marshalArguments(Array.from(arguments), [])).map(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }).publish(); + } + + observeLockFilesDidChange() { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "HgService.js", + line: 342 + }, + name: "HgRepositorySubscriptions" + }), "observeLockFilesDidChange", "observable", _client.marshalArguments(Array.from(arguments), [])).map(value => { + return _client.unmarshal(value, { + kind: "map", + keyType: { + kind: "string" + }, + valueType: { + kind: "boolean" + } + }); + }).publish(); + } + + observeBookmarksDidChange() { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "HgService.js", + line: 342 + }, + name: "HgRepositorySubscriptions" + }), "observeBookmarksDidChange", "observable", _client.marshalArguments(Array.from(arguments), [])).map(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }).publish(); + } + + dispose() { + return _client.disposeRemoteObject(this); + } + + }; + + remoteModule.createRepositorySubscriptions = function (arg0) { + return _client.callRemoteFunction("HgService/createRepositorySubscriptions", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "HgRepositorySubscriptions" + }); + }); + }; + + remoteModule.fetchStatuses = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/fetchStatuses", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "toRevision", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "map", + keyType: { + kind: "named", + name: "NuclideUri" + }, + valueType: { + kind: "named", + name: "StatusCodeIdValue" + } + }); + }).publish(); + }; + + remoteModule.fetchStackStatuses = function (arg0) { + return _client.callRemoteFunction("HgService/fetchStackStatuses", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "map", + keyType: { + kind: "named", + name: "NuclideUri" + }, + valueType: { + kind: "named", + name: "StatusCodeIdValue" + } + }); + }).publish(); + }; + + remoteModule.fetchHeadStatuses = function (arg0) { + return _client.callRemoteFunction("HgService/fetchHeadStatuses", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "map", + keyType: { + kind: "named", + name: "NuclideUri" + }, + valueType: { + kind: "named", + name: "StatusCodeIdValue" + } + }); + }).publish(); + }; + + remoteModule.getAdditionalLogFiles = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/getAdditionalLogFiles", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "deadline", + type: { + kind: "named", + name: "DeadlineRequest" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "AdditionalLogFile" + } + }); + }); + }; + + remoteModule.fetchDiffInfo = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/fetchDiffInfo", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "map", + keyType: { + kind: "named", + name: "NuclideUri" + }, + valueType: { + kind: "named", + name: "DiffInfo" + } + } + }); + }); + }; + + remoteModule.createBookmark = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("HgService/createBookmark", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "name", + type: { + kind: "string" + } + }, { + name: "revision", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.deleteBookmark = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/deleteBookmark", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "name", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.renameBookmark = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("HgService/renameBookmark", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "name", + type: { + kind: "string" + } + }, { + name: "nextName", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.fetchActiveBookmark = function (arg0) { + return _client.callRemoteFunction("HgService/fetchActiveBookmark", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }); + }; + + remoteModule.fetchBookmarks = function (arg0) { + return _client.callRemoteFunction("HgService/fetchBookmarks", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "BookmarkInfo" + } + }); + }); + }; + + remoteModule.fetchFileContentAtRevision = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("HgService/fetchFileContentAtRevision", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "revision", + type: { + kind: "string" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }).publish(); + }; + + remoteModule.batchFetchFileContentsAtRevision = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("HgService/batchFetchFileContentsAtRevision", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }, { + name: "revision", + type: { + kind: "string" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "map", + keyType: { + kind: "named", + name: "NuclideUri" + }, + valueType: { + kind: "string" + } + }); + }).publish(); + }; + + remoteModule.fetchFilesChangedAtRevision = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/fetchFilesChangedAtRevision", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "revision", + type: { + kind: "string" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "RevisionFileChanges" + }); + }).publish(); + }; + + remoteModule.fetchRevisionInfoBetweenHeadAndBase = function (arg0) { + return _client.callRemoteFunction("HgService/fetchRevisionInfoBetweenHeadAndBase", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "RevisionInfo" + } + }); + }); + }; + + remoteModule.fetchSmartlogRevisions = function (arg0) { + return _client.callRemoteFunction("HgService/fetchSmartlogRevisions", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "RevisionInfo" + } + }); + }).publish(); + }; + + remoteModule.getBaseRevision = function (arg0) { + return _client.callRemoteFunction("HgService/getBaseRevision", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "RevisionInfo" + }); + }); + }; + + remoteModule.getBlameAtHead = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/getBlameAtHead", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "nullable", + type: { + kind: "named", + name: "RevisionInfo" + } + } + }); + }); + }; + + remoteModule.getConfigValueAsync = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/getConfigValueAsync", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "key", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "string" + } + }); + }); + }; + + remoteModule.getDifferentialRevisionForChangeSetId = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/getDifferentialRevisionForChangeSetId", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "changeSetId", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "string" + } + }); + }); + }; + + remoteModule.getSmartlog = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("HgService/getSmartlog", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "ttyOutput", + type: { + kind: "boolean" + } + }, { + name: "concise", + type: { + kind: "boolean" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "AsyncExecuteRet" + }); + }); + }; + + remoteModule.commit = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("HgService/commit", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "message", + type: { + kind: "string" + } + }, { + name: "filePaths", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.editCommitMessage = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("HgService/editCommitMessage", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "revision", + type: { + kind: "string" + } + }, { + name: "message", + type: { + kind: "string" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.amend = function (arg0, arg1, arg2, arg3) { + return _client.callRemoteFunction("HgService/amend", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "message", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }, { + name: "amendMode", + type: { + kind: "named", + name: "AmendModeValue" + } + }, { + name: "filePaths", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.restack = function (arg0) { + return _client.callRemoteFunction("HgService/restack", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.revert = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("HgService/revert", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }, { + name: "toRevision", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.checkout = function (arg0, arg1, arg2, arg3) { + return _client.callRemoteFunction("HgService/checkout", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "revision", + type: { + kind: "string" + } + }, { + name: "create", + type: { + kind: "boolean" + } + }, { + name: "options", + type: { + kind: "nullable", + type: { + kind: "named", + name: "CheckoutOptions" + } + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.show = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/show", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "revision", + type: { + kind: "number" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "RevisionShowInfo" + }); + }).publish(); + }; + + remoteModule.diff = function (arg0, arg1, arg2, arg3, arg4, arg5) { + return _client.callRemoteFunction("HgService/diff", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "revision", + type: { + kind: "string" + } + }, { + name: "unified", + type: { + kind: "nullable", + type: { + kind: "number" + } + } + }, { + name: "diffCommitted", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + } + }, { + name: "noPrefix", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + } + }, { + name: "noDates", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }).publish(); + }; + + remoteModule.purge = function (arg0) { + return _client.callRemoteFunction("HgService/purge", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.uncommit = function (arg0) { + return _client.callRemoteFunction("HgService/uncommit", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.strip = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/strip", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "revision", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.checkoutForkBase = function (arg0) { + return _client.callRemoteFunction("HgService/checkoutForkBase", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.rename = function (arg0, arg1, arg2, arg3) { + return _client.callRemoteFunction("HgService/rename", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }, { + name: "destPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "after", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.remove = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("HgService/remove", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }, { + name: "after", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.forget = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/forget", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.add = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/add", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.getTemplateCommitMessage = function (arg0) { + return _client.callRemoteFunction("HgService/getTemplateCommitMessage", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "string" + } + }); + }); + }; + + remoteModule.getHeadCommitMessage = function (arg0) { + return _client.callRemoteFunction("HgService/getHeadCommitMessage", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "string" + } + }); + }); + }; + + remoteModule.log = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("HgService/log", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }, { + name: "limit", + type: { + kind: "nullable", + type: { + kind: "number" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "VcsLogResponse" + }); + }); + }; + + remoteModule.fetchMergeConflicts = function (arg0) { + return _client.callRemoteFunction("HgService/fetchMergeConflicts", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "MergeConflicts" + } + }); + }).publish(); + }; + + remoteModule.markConflictedFile = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("HgService/markConflictedFile", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "resolved", + type: { + kind: "boolean" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.continueOperation = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/continueOperation", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "args", + type: { + kind: "array", + type: { + kind: "string" + } + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.abortOperation = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/abortOperation", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "commandWithOptions", + type: { + kind: "array", + type: { + kind: "string" + } + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }).publish(); + }; + + remoteModule.resolveAllFiles = function (arg0) { + return _client.callRemoteFunction("HgService/resolveAllFiles", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.rebase = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("HgService/rebase", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "destination", + type: { + kind: "string" + } + }, { + name: "source", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.reorderWithinStack = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/reorderWithinStack", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "orderedRevisions", + type: { + kind: "array", + type: { + kind: "string" + } + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }).publish(); + }; + + remoteModule.pull = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/pull", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "options", + type: { + kind: "array", + type: { + kind: "string" + } + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.copy = function (arg0, arg1, arg2, arg3) { + return _client.callRemoteFunction("HgService/copy", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }, { + name: "destPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "after", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.getHeadId = function (arg0) { + return _client.callRemoteFunction("HgService/getHeadId", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }).publish(); + }; + + remoteModule.getFullHashForRevision = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/getFullHashForRevision", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "rev", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "string" + } + }); + }); + }; + + remoteModule.fold = function (arg0, arg1, arg2, arg3) { + return _client.callRemoteFunction("HgService/fold", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "from", + type: { + kind: "string" + } + }, { + name: "to", + type: { + kind: "string" + } + }, { + name: "message", + type: { + kind: "string" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }).publish(); + }; + + remoteModule.runCommand = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/runCommand", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "args", + type: { + kind: "array", + type: { + kind: "string" + } + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }).publish(); + }; + + remoteModule.observeExecution = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/observeExecution", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "args", + type: { + kind: "array", + type: { + kind: "string" + } + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LegacyProcessMessage" + }); + }).publish(); + }; + + remoteModule.gitDiffStrings = function (arg0, arg1) { + return _client.callRemoteFunction("HgService/gitDiffStrings", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "oldContents", + type: { + kind: "string" + } + }, { + name: "newContents", + type: { + kind: "string" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }).publish(); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + StatusCodeIdValue: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 98 + }, + name: "StatusCodeIdValue", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "A" + }, { + kind: "string-literal", + value: "C" + }, { + kind: "string-literal", + value: "I" + }, { + kind: "string-literal", + value: "M" + }, { + kind: "string-literal", + value: "!" + }, { + kind: "string-literal", + value: "R" + }, { + kind: "string-literal", + value: "?" + }, { + kind: "string-literal", + value: "U" + }] + } + }, + MergeConflictStatusValue: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 100 + }, + name: "MergeConflictStatusValue", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "both changed" + }, { + kind: "string-literal", + value: "deleted in theirs" + }, { + kind: "string-literal", + value: "deleted in ours" + }, { + kind: "string-literal", + value: "resolved" + }] + } + }, + MergeConflictStatusCodeId: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 106 + }, + name: "MergeConflictStatusCodeId", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "R" + }, { + kind: "string-literal", + value: "U" + }] + } + }, + StatusCodeNumberValue: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 116 + }, + name: "StatusCodeNumberValue", + definition: { + kind: "union", + types: [{ + kind: "number-literal", + value: 1 + }, { + kind: "number-literal", + value: 2 + }, { + kind: "number-literal", + value: 3 + }, { + kind: "number-literal", + value: 4 + }, { + kind: "number-literal", + value: 5 + }, { + kind: "number-literal", + value: 6 + }, { + kind: "number-literal", + value: 7 + }, { + kind: "number-literal", + value: 8 + }] + } + }, + LineDiff: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 118 + }, + name: "LineDiff", + definition: { + kind: "object", + fields: [{ + name: "oldStart", + type: { + kind: "number" + }, + optional: false + }, { + name: "oldLines", + type: { + kind: "number" + }, + optional: false + }, { + name: "newStart", + type: { + kind: "number" + }, + optional: false + }, { + name: "newLines", + type: { + kind: "number" + }, + optional: false + }] + } + }, + BookmarkInfo: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 125 + }, + name: "BookmarkInfo", + definition: { + kind: "object", + fields: [{ + name: "active", + type: { + kind: "boolean" + }, + optional: false + }, { + name: "bookmark", + type: { + kind: "string" + }, + optional: false + }, { + name: "node", + type: { + kind: "string" + }, + optional: false + }] + } + }, + DiffInfo: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 131 + }, + name: "DiffInfo", + definition: { + kind: "object", + fields: [{ + name: "added", + type: { + kind: "number" + }, + optional: false + }, { + name: "deleted", + type: { + kind: "number" + }, + optional: false + }, { + name: "lineDiffs", + type: { + kind: "array", + type: { + kind: "named", + name: "LineDiff" + } + }, + optional: false + }] + } + }, + CommitPhaseType: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 137 + }, + name: "CommitPhaseType", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "public" + }, { + kind: "string-literal", + value: "draft" + }, { + kind: "string-literal", + value: "secret" + }] + } + }, + SuccessorTypeValue: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 139 + }, + name: "SuccessorTypeValue", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "public" + }, { + kind: "string-literal", + value: "amend" + }, { + kind: "string-literal", + value: "rebase" + }, { + kind: "string-literal", + value: "split" + }, { + kind: "string-literal", + value: "fold" + }, { + kind: "string-literal", + value: "histedit" + }] + } + }, + HisteditActionsValue: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 147 + }, + name: "HisteditActionsValue", + definition: { + kind: "string-literal", + value: "pick" + } + }, + RevisionSuccessorInfo: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 149 + }, + name: "RevisionSuccessorInfo", + definition: { + kind: "object", + fields: [{ + name: "hash", + type: { + kind: "string" + }, + optional: false + }, { + name: "type", + type: { + kind: "named", + name: "SuccessorTypeValue" + }, + optional: false + }] + } + }, + RevisionInfo: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 154 + }, + name: "RevisionInfo", + definition: { + kind: "object", + fields: [{ + name: "author", + type: { + kind: "string" + }, + optional: false + }, { + name: "bookmarks", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "branch", + type: { + kind: "string" + }, + optional: false + }, { + name: "date", + type: { + kind: "named", + name: "Date" + }, + optional: false + }, { + name: "description", + type: { + kind: "string" + }, + optional: false + }, { + name: "hash", + type: { + kind: "string" + }, + optional: false + }, { + name: "id", + type: { + kind: "number" + }, + optional: false + }, { + name: "isHead", + type: { + kind: "boolean" + }, + optional: false + }, { + name: "remoteBookmarks", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "parents", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "phase", + type: { + kind: "named", + name: "CommitPhaseType" + }, + optional: false + }, { + name: "successorInfo", + type: { + kind: "nullable", + type: { + kind: "named", + name: "RevisionSuccessorInfo" + } + }, + optional: false + }, { + name: "tags", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "title", + type: { + kind: "string" + }, + optional: false + }, { + name: "files", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + }, + optional: false + }] + } + }, + RevisionShowInfo: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 172 + }, + name: "RevisionShowInfo", + definition: { + kind: "object", + fields: [{ + name: "diff", + type: { + kind: "string" + }, + optional: false + }] + } + }, + RevisionInfoFetched: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 176 + }, + name: "RevisionInfoFetched", + definition: { + kind: "object", + fields: [{ + name: "revisions", + type: { + kind: "array", + type: { + kind: "named", + name: "RevisionInfo" + } + }, + optional: false + }, { + name: "fromFilesystem", + type: { + kind: "boolean" + }, + optional: false + }] + } + }, + AsyncExecuteRet: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 181 + }, + name: "AsyncExecuteRet", + definition: { + kind: "object", + fields: [{ + name: "command", + type: { + kind: "string" + }, + optional: true + }, { + name: "errorMessage", + type: { + kind: "string" + }, + optional: true + }, { + name: "exitCode", + type: { + kind: "number" + }, + optional: false + }, { + name: "stderr", + type: { + kind: "string" + }, + optional: false + }, { + name: "stdout", + type: { + kind: "string" + }, + optional: false + }] + } + }, + RevisionFileCopy: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 189 + }, + name: "RevisionFileCopy", + definition: { + kind: "object", + fields: [{ + name: "from", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "to", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }] + } + }, + RevisionFileChanges: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 194 + }, + name: "RevisionFileChanges", + definition: { + kind: "object", + fields: [{ + name: "all", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + }, + optional: false + }, { + name: "added", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + }, + optional: false + }, { + name: "deleted", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + }, + optional: false + }, { + name: "copied", + type: { + kind: "array", + type: { + kind: "named", + name: "RevisionFileCopy" + } + }, + optional: false + }, { + name: "modified", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + }, + optional: false + }] + } + }, + VcsLogEntry: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 202 + }, + name: "VcsLogEntry", + definition: { + kind: "object", + fields: [{ + name: "node", + type: { + kind: "string" + }, + optional: false + }, { + name: "user", + type: { + kind: "string" + }, + optional: false + }, { + name: "desc", + type: { + kind: "string" + }, + optional: false + }, { + name: "date", + type: { + kind: "tuple", + types: [{ + kind: "number" + }, { + kind: "number" + }] + }, + optional: false + }] + } + }, + VcsLogResponse: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 209 + }, + name: "VcsLogResponse", + definition: { + kind: "object", + fields: [{ + name: "entries", + type: { + kind: "array", + type: { + kind: "named", + name: "VcsLogEntry" + } + }, + optional: false + }] + } + }, + MergeConflictSideFileData: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 214 + }, + name: "MergeConflictSideFileData", + definition: { + kind: "object", + fields: [{ + name: "contents", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "exists", + type: { + kind: "boolean" + }, + optional: false + }, { + name: "isexec", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + }, + optional: false + }, { + name: "issymlink", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + }, + optional: false + }] + } + }, + MergeConflictOutputFileData: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 222 + }, + name: "MergeConflictOutputFileData", + definition: { + kind: "intersection", + types: [{ + kind: "named", + name: "MergeConflictSideFileData" + }, { + kind: "object", + fields: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }] + }], + flattened: { + kind: "object", + fields: [{ + name: "contents", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "exists", + type: { + kind: "boolean" + }, + optional: false + }, { + name: "isexec", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + }, + optional: false + }, { + name: "issymlink", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + }, + optional: false + }, { + name: "path", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }] + } + } + }, + MergeConflictFileData: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 226 + }, + name: "MergeConflictFileData", + definition: { + kind: "object", + fields: [{ + name: "base", + type: { + kind: "named", + name: "MergeConflictSideFileData" + }, + optional: false + }, { + name: "local", + type: { + kind: "named", + name: "MergeConflictSideFileData" + }, + optional: false + }, { + name: "other", + type: { + kind: "named", + name: "MergeConflictSideFileData" + }, + optional: false + }, { + name: "output", + type: { + kind: "named", + name: "MergeConflictOutputFileData" + }, + optional: false + }, { + name: "status", + type: { + kind: "named", + name: "MergeConflictStatusValue" + }, + optional: false + }, { + name: "conflictCount", + type: { + kind: "number" + }, + optional: true + }] + } + }, + MergeConflicts: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 235 + }, + name: "MergeConflicts", + definition: { + kind: "object", + fields: [{ + name: "conflicts", + type: { + kind: "array", + type: { + kind: "named", + name: "MergeConflictFileData" + } + }, + optional: false + }, { + name: "command", + type: { + kind: "string" + }, + optional: false + }, { + name: "command_details", + type: { + kind: "object", + fields: [{ + name: "cmd", + type: { + kind: "string" + }, + optional: false + }, { + name: "to_abort", + type: { + kind: "string" + }, + optional: false + }, { + name: "to_continue", + type: { + kind: "string" + }, + optional: false + }] + }, + optional: false + }] + } + }, + CheckoutSideName: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 245 + }, + name: "CheckoutSideName", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "ours" + }, { + kind: "string-literal", + value: "theirs" + }] + } + }, + AmendModeValue: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 247 + }, + name: "AmendModeValue", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "Clean" + }, { + kind: "string-literal", + value: "Rebase" + }, { + kind: "string-literal", + value: "Fixup" + }] + } + }, + CheckoutOptions: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 249 + }, + name: "CheckoutOptions", + definition: { + kind: "object", + fields: [{ + name: "clean", + type: { + kind: "boolean-literal", + value: true + }, + optional: true + }] + } + }, + OperationProgressState: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 253 + }, + name: "OperationProgressState", + definition: { + kind: "object", + fields: [{ + name: "active", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + }, + optional: false + }, { + name: "estimate_sec", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }, { + name: "estimate_str", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "item", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "pos", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }, { + name: "speed_str", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "topic", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "total", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }, { + name: "unit", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "units_per_sec", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }] + } + }, + OperationProgress: { + kind: "alias", + location: { + type: "source", + fileName: "HgService.js", + line: 265 + }, + name: "OperationProgress", + definition: { + kind: "object", + fields: [{ + name: "topics", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "state", + type: { + kind: "named", + name: "Object" + }, + optional: false + }] + } + }, + HgRepositorySubscriptions: { + kind: "interface", + name: "HgRepositorySubscriptions", + location: { + type: "source", + fileName: "HgService.js", + line: 342 + }, + staticMethods: { + create: { + location: { + type: "source", + fileName: "HgService.js", + line: 360 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "HgRepositorySubscriptions" + } + } + } + }, + instanceMethods: { + dispose: { + location: { + type: "source", + fileName: "HgService.js", + line: 386 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + }, + observeFilesDidChange: { + location: { + type: "source", + fileName: "HgService.js", + line: 640 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "observable", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + } + }, + observeHgCommitsDidChange: { + location: { + type: "source", + fileName: "HgService.js", + line: 648 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "observable", + type: { + kind: "void" + } + } + }, + observeHgRepoStateDidChange: { + location: { + type: "source", + fileName: "HgService.js", + line: 662 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "observable", + type: { + kind: "void" + } + } + }, + observeHgConflictStateDidChange: { + location: { + type: "source", + fileName: "HgService.js", + line: 669 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "observable", + type: { + kind: "boolean" + } + } + }, + observeHgOperationProgressDidChange: { + location: { + type: "source", + fileName: "HgService.js", + line: 677 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "observable", + type: { + kind: "any" + } + } + }, + observeActiveBookmarkDidChange: { + location: { + type: "source", + fileName: "HgService.js", + line: 708 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "observable", + type: { + kind: "void" + } + } + }, + observeLockFilesDidChange: { + location: { + type: "source", + fileName: "HgService.js", + line: 715 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "observable", + type: { + kind: "map", + keyType: { + kind: "string" + }, + valueType: { + kind: "boolean" + } + } + } + }, + observeBookmarksDidChange: { + location: { + type: "source", + fileName: "HgService.js", + line: 722 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "observable", + type: { + kind: "void" + } + } + } + } + }, + createRepositorySubscriptions: { + kind: "function", + name: "createRepositorySubscriptions", + location: { + type: "source", + fileName: "HgService.js", + line: 727 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 727 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "HgRepositorySubscriptions" + } + } + } + }, + fetchStatuses: { + kind: "function", + name: "fetchStatuses", + location: { + type: "source", + fileName: "HgService.js", + line: 740 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 740 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "toRevision", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "observable", + type: { + kind: "map", + keyType: { + kind: "named", + name: "NuclideUri" + }, + valueType: { + kind: "named", + name: "StatusCodeIdValue" + } + } + } + } + }, + fetchStackStatuses: { + kind: "function", + name: "fetchStackStatuses", + location: { + type: "source", + fileName: "HgService.js", + line: 771 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 771 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "observable", + type: { + kind: "map", + keyType: { + kind: "named", + name: "NuclideUri" + }, + valueType: { + kind: "named", + name: "StatusCodeIdValue" + } + } + } + } + }, + fetchHeadStatuses: { + kind: "function", + name: "fetchHeadStatuses", + location: { + type: "source", + fileName: "HgService.js", + line: 790 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 790 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "observable", + type: { + kind: "map", + keyType: { + kind: "named", + name: "NuclideUri" + }, + valueType: { + kind: "named", + name: "StatusCodeIdValue" + } + } + } + } + }, + AdditionalLogFile: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 31 + }, + name: "AdditionalLogFile", + definition: { + kind: "object", + fields: [{ + name: "title", + type: { + kind: "string" + }, + optional: false + }, { + name: "data", + type: { + kind: "string" + }, + optional: false + }] + } + }, + DeadlineRequest: { + kind: "alias", + location: { + type: "source", + fileName: "promise.js", + line: 210 + }, + name: "DeadlineRequest", + definition: { + kind: "number" + } + }, + getAdditionalLogFiles: { + kind: "function", + name: "getAdditionalLogFiles", + location: { + type: "source", + fileName: "HgService.js", + line: 799 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 799 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "deadline", + type: { + kind: "named", + name: "DeadlineRequest" + } + }], + returnType: { + kind: "promise", + type: { + kind: "array", + type: { + kind: "named", + name: "AdditionalLogFile" + } + } + } + } + }, + fetchDiffInfo: { + kind: "function", + name: "fetchDiffInfo", + location: { + type: "source", + fileName: "HgService.js", + line: 884 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 884 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "map", + keyType: { + kind: "named", + name: "NuclideUri" + }, + valueType: { + kind: "named", + name: "DiffInfo" + } + } + } + } + } + }, + createBookmark: { + kind: "function", + name: "createBookmark", + location: { + type: "source", + fileName: "HgService.js", + line: 924 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 924 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "name", + type: { + kind: "string" + } + }, { + name: "revision", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + deleteBookmark: { + kind: "function", + name: "deleteBookmark", + location: { + type: "source", + fileName: "HgService.js", + line: 939 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 939 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "name", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + renameBookmark: { + kind: "function", + name: "renameBookmark", + location: { + type: "source", + fileName: "HgService.js", + line: 949 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 949 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "name", + type: { + kind: "string" + } + }, { + name: "nextName", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + fetchActiveBookmark: { + kind: "function", + name: "fetchActiveBookmark", + location: { + type: "source", + fileName: "HgService.js", + line: 964 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 964 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "string" + } + } + } + }, + fetchBookmarks: { + kind: "function", + name: "fetchBookmarks", + location: { + type: "source", + fileName: "HgService.js", + line: 975 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 975 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "array", + type: { + kind: "named", + name: "BookmarkInfo" + } + } + } + } + }, + fetchFileContentAtRevision: { + kind: "function", + name: "fetchFileContentAtRevision", + location: { + type: "source", + fileName: "HgService.js", + line: 992 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 992 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "revision", + type: { + kind: "string" + } + }], + returnType: { + kind: "observable", + type: { + kind: "string" + } + } + } + }, + batchFetchFileContentsAtRevision: { + kind: "function", + name: "batchFetchFileContentsAtRevision", + location: { + type: "source", + fileName: "HgService.js", + line: 1004 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1004 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }, { + name: "revision", + type: { + kind: "string" + } + }], + returnType: { + kind: "observable", + type: { + kind: "map", + keyType: { + kind: "named", + name: "NuclideUri" + }, + valueType: { + kind: "string" + } + } + } + } + }, + fetchFilesChangedAtRevision: { + kind: "function", + name: "fetchFilesChangedAtRevision", + location: { + type: "source", + fileName: "HgService.js", + line: 1016 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1016 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "revision", + type: { + kind: "string" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "RevisionFileChanges" + } + } + } + }, + fetchRevisionInfoBetweenHeadAndBase: { + kind: "function", + name: "fetchRevisionInfoBetweenHeadAndBase", + location: { + type: "source", + fileName: "HgService.js", + line: 1029 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1029 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "array", + type: { + kind: "named", + name: "RevisionInfo" + } + } + } + } + }, + fetchSmartlogRevisions: { + kind: "function", + name: "fetchSmartlogRevisions", + location: { + type: "source", + fileName: "HgService.js", + line: 1041 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1041 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "observable", + type: { + kind: "array", + type: { + kind: "named", + name: "RevisionInfo" + } + } + } + } + }, + getBaseRevision: { + kind: "function", + name: "getBaseRevision", + location: { + type: "source", + fileName: "HgService.js", + line: 1050 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1050 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "RevisionInfo" + } + } + } + }, + getBlameAtHead: { + kind: "function", + name: "getBlameAtHead", + location: { + type: "source", + fileName: "HgService.js", + line: 1066 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1066 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "array", + type: { + kind: "nullable", + type: { + kind: "named", + name: "RevisionInfo" + } + } + } + } + } + }, + getConfigValueAsync: { + kind: "function", + name: "getConfigValueAsync", + location: { + type: "source", + fileName: "HgService.js", + line: 1123 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1123 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "key", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + } + } + }, + getDifferentialRevisionForChangeSetId: { + kind: "function", + name: "getDifferentialRevisionForChangeSetId", + location: { + type: "source", + fileName: "HgService.js", + line: 1147 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1147 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "changeSetId", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + } + } + }, + getSmartlog: { + kind: "function", + name: "getSmartlog", + location: { + type: "source", + fileName: "HgService.js", + line: 1183 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1183 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "ttyOutput", + type: { + kind: "boolean" + } + }, { + name: "concise", + type: { + kind: "boolean" + } + }], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "AsyncExecuteRet" + } + } + } + }, + ProcessExitMessage: { + kind: "alias", + location: { + type: "source", + fileName: "process.js", + line: 665 + }, + name: "ProcessExitMessage", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "exit" + }, + optional: false + }, { + name: "exitCode", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }, { + name: "signal", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }] + } + }, + ProcessMessage: { + kind: "alias", + location: { + type: "source", + fileName: "process.js", + line: 671 + }, + name: "ProcessMessage", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "stdout" + }, + optional: false + }, { + name: "data", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "stderr" + }, + optional: false + }, { + name: "data", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "exit" + }, + optional: false + }, { + name: "exitCode", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }, { + name: "signal", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }] + }], + discriminantField: "kind" + } + }, + LegacyProcessMessage: { + kind: "alias", + location: { + type: "source", + fileName: "process.js", + line: 684 + }, + name: "LegacyProcessMessage", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "stdout" + }, + optional: false + }, { + name: "data", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "stderr" + }, + optional: false + }, { + name: "data", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "exit" + }, + optional: false + }, { + name: "exitCode", + type: { + kind: "nullable", + type: { + kind: "number" + } + }, + optional: false + }, { + name: "signal", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "error" + }, + optional: false + }, { + name: "error", + type: { + kind: "named", + name: "Object" + }, + optional: false + }] + }], + discriminantField: "kind" + } + }, + commit: { + kind: "function", + name: "commit", + location: { + type: "source", + fileName: "HgService.js", + line: 1232 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1232 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "message", + type: { + kind: "string" + } + }, { + name: "filePaths", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + editCommitMessage: { + kind: "function", + name: "editCommitMessage", + location: { + type: "source", + fileName: "HgService.js", + line: 1250 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1250 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "revision", + type: { + kind: "string" + } + }, { + name: "message", + type: { + kind: "string" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + amend: { + kind: "function", + name: "amend", + location: { + type: "source", + fileName: "HgService.js", + line: 1271 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1271 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "message", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }, { + name: "amendMode", + type: { + kind: "named", + name: "AmendModeValue" + } + }, { + name: "filePaths", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + restack: { + kind: "function", + name: "restack", + location: { + type: "source", + fileName: "HgService.js", + line: 1295 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1295 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + revert: { + kind: "function", + name: "revert", + location: { + type: "source", + fileName: "HgService.js", + line: 1305 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1305 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }, { + name: "toRevision", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + checkout: { + kind: "function", + name: "checkout", + location: { + type: "source", + fileName: "HgService.js", + line: 1345 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1345 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "revision", + type: { + kind: "string" + } + }, { + name: "create", + type: { + kind: "boolean" + } + }, { + name: "options", + type: { + kind: "nullable", + type: { + kind: "named", + name: "CheckoutOptions" + } + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + show: { + kind: "function", + name: "show", + location: { + type: "source", + fileName: "HgService.js", + line: 1362 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1362 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "revision", + type: { + kind: "number" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "RevisionShowInfo" + } + } + } + }, + diff: { + kind: "function", + name: "diff", + location: { + type: "source", + fileName: "HgService.js", + line: 1377 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1377 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "revision", + type: { + kind: "string" + } + }, { + name: "unified", + type: { + kind: "nullable", + type: { + kind: "number" + } + } + }, { + name: "diffCommitted", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + } + }, { + name: "noPrefix", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + } + }, { + name: "noDates", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + } + }], + returnType: { + kind: "observable", + type: { + kind: "string" + } + } + } + }, + purge: { + kind: "function", + name: "purge", + location: { + type: "source", + fileName: "HgService.js", + line: 1404 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1404 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + uncommit: { + kind: "function", + name: "uncommit", + location: { + type: "source", + fileName: "HgService.js", + line: 1411 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1411 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + strip: { + kind: "function", + name: "strip", + location: { + type: "source", + fileName: "HgService.js", + line: 1418 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1418 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "revision", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + checkoutForkBase: { + kind: "function", + name: "checkoutForkBase", + location: { + type: "source", + fileName: "HgService.js", + line: 1429 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1429 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + rename: { + kind: "function", + name: "rename", + location: { + type: "source", + fileName: "HgService.js", + line: 1454 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1454 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }, { + name: "destPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "after", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + remove: { + kind: "function", + name: "remove", + location: { + type: "source", + fileName: "HgService.js", + line: 1482 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1482 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }, { + name: "after", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + forget: { + kind: "function", + name: "forget", + location: { + type: "source", + fileName: "HgService.js", + line: 1508 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1508 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + add: { + kind: "function", + name: "add", + location: { + type: "source", + fileName: "HgService.js", + line: 1524 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1524 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + getTemplateCommitMessage: { + kind: "function", + name: "getTemplateCommitMessage", + location: { + type: "source", + fileName: "HgService.js", + line: 1531 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1531 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + } + } + }, + getHeadCommitMessage: { + kind: "function", + name: "getHeadCommitMessage", + location: { + type: "source", + fileName: "HgService.js", + line: 1550 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1550 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + } + } + }, + log: { + kind: "function", + name: "log", + location: { + type: "source", + fileName: "HgService.js", + line: 1578 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1578 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }, { + name: "limit", + type: { + kind: "nullable", + type: { + kind: "number" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "VcsLogResponse" + } + } + } + }, + fetchMergeConflicts: { + kind: "function", + name: "fetchMergeConflicts", + location: { + type: "source", + fileName: "HgService.js", + line: 1599 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1599 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "observable", + type: { + kind: "nullable", + type: { + kind: "named", + name: "MergeConflicts" + } + } + } + } + }, + markConflictedFile: { + kind: "function", + name: "markConflictedFile", + location: { + type: "source", + fileName: "HgService.js", + line: 1647 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1647 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "resolved", + type: { + kind: "boolean" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + continueOperation: { + kind: "function", + name: "continueOperation", + location: { + type: "source", + fileName: "HgService.js", + line: 1662 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1662 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "args", + type: { + kind: "array", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + abortOperation: { + kind: "function", + name: "abortOperation", + location: { + type: "source", + fileName: "HgService.js", + line: 1674 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1674 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "commandWithOptions", + type: { + kind: "array", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "observable", + type: { + kind: "string" + } + } + } + }, + resolveAllFiles: { + kind: "function", + name: "resolveAllFiles", + location: { + type: "source", + fileName: "HgService.js", + line: 1684 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1684 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + rebase: { + kind: "function", + name: "rebase", + location: { + type: "source", + fileName: "HgService.js", + line: 1694 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1694 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "destination", + type: { + kind: "string" + } + }, { + name: "source", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + reorderWithinStack: { + kind: "function", + name: "reorderWithinStack", + location: { + type: "source", + fileName: "HgService.js", + line: 1717 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1717 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "orderedRevisions", + type: { + kind: "array", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "observable", + type: { + kind: "string" + } + } + } + }, + pull: { + kind: "function", + name: "pull", + location: { + type: "source", + fileName: "HgService.js", + line: 1742 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1742 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "options", + type: { + kind: "array", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + copy: { + kind: "function", + name: "copy", + location: { + type: "source", + fileName: "HgService.js", + line: 1760 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1760 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "filePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }, { + name: "destPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "after", + type: { + kind: "nullable", + type: { + kind: "boolean" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + getHeadId: { + kind: "function", + name: "getHeadId", + location: { + type: "source", + fileName: "HgService.js", + line: 1787 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1787 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "observable", + type: { + kind: "string" + } + } + } + }, + getFullHashForRevision: { + kind: "function", + name: "getFullHashForRevision", + location: { + type: "source", + fileName: "HgService.js", + line: 1800 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1800 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "rev", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + } + } + }, + fold: { + kind: "function", + name: "fold", + location: { + type: "source", + fileName: "HgService.js", + line: 1817 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1817 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "from", + type: { + kind: "string" + } + }, { + name: "to", + type: { + kind: "string" + } + }, { + name: "message", + type: { + kind: "string" + } + }], + returnType: { + kind: "observable", + type: { + kind: "string" + } + } + } + }, + runCommand: { + kind: "function", + name: "runCommand", + location: { + type: "source", + fileName: "HgService.js", + line: 1832 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1832 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "args", + type: { + kind: "array", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "observable", + type: { + kind: "string" + } + } + } + }, + observeExecution: { + kind: "function", + name: "observeExecution", + location: { + type: "source", + fileName: "HgService.js", + line: 1842 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1842 + }, + kind: "function", + argumentTypes: [{ + name: "workingDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "args", + type: { + kind: "array", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "LegacyProcessMessage" + } + } + } + }, + gitDiffStrings: { + kind: "function", + name: "gitDiffStrings", + location: { + type: "source", + fileName: "HgService.js", + line: 1854 + }, + type: { + location: { + type: "source", + fileName: "HgService.js", + line: 1854 + }, + kind: "function", + argumentTypes: [{ + name: "oldContents", + type: { + kind: "string" + } + }, { + name: "newContents", + type: { + kind: "string" + } + }], + returnType: { + kind: "observable", + type: { + kind: "string" + } + } + } + } + } +}); \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/lib/git-diff.js b/pkg/nuclide-hg-rpc/lib/git-diff.js index d5ca52138f..da70aff9af 100644 --- a/pkg/nuclide-hg-rpc/lib/git-diff.js +++ b/pkg/nuclide-hg-rpc/lib/git-diff.js @@ -1,81 +1,72 @@ -/** - * 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 - */ +'use strict'; -import fsPromise from 'nuclide-commons/fsPromise'; -import {Observable} from 'rxjs'; -import {runCommandDetailed} from 'nuclide-commons/process'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.gitDiffStrings = gitDiffStrings; -export function gitDiffStrings( - oldString: string, - newString: string, -): Observable { - return makeTempFiles(oldString, newString).switchMap( - ([oldTempFile, newTempFile]) => - runCommandDetailed( - 'git', - ['diff', '--unified=0', '--no-index', oldTempFile, newTempFile], - { - killTreeWhenDone: true, - }, - ) - .map(({stdout}) => stdout) - .catch(e => { - // git diff returns with exit code 1 if there was a difference between - // the files being compared - return Observable.of(e.stdout); - }) - .finally(() => { - fsPromise.unlink(oldTempFile); - fsPromise.unlink(newTempFile); - }), - ); +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); } -function makeTempFiles( - oldString: string, - newString: string, -): Observable<[string, string]> { - let oldFilePath: string; - let newFilePath: string; - return Observable.forkJoin( - Observable.fromPromise(fsPromise.tempfile()) - .map(filePath => { - oldFilePath = filePath.trim(); - return oldFilePath; - }) - .switchMap(filePath => { - return writeContentsToFile(oldString, filePath).map(() => filePath); - }), - Observable.fromPromise(fsPromise.tempfile()) - .map(filePath => { - newFilePath = filePath.trim(); - return newFilePath; - }) - .switchMap(filePath => { - return writeContentsToFile(newString, filePath).map(() => filePath); - }), - ).catch(error => { +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function gitDiffStrings(oldString, newString) { + return makeTempFiles(oldString, newString).switchMap(([oldTempFile, newTempFile]) => (0, (_process || _load_process()).runCommandDetailed)('git', ['diff', '--unified=0', '--no-index', oldTempFile, newTempFile], { + killTreeWhenDone: true + }).map(({ stdout }) => stdout).catch(e => { + // git diff returns with exit code 1 if there was a difference between + // the files being compared + return _rxjsBundlesRxMinJs.Observable.of(e.stdout); + }).finally(() => { + (_fsPromise || _load_fsPromise()).default.unlink(oldTempFile); + (_fsPromise || _load_fsPromise()).default.unlink(newTempFile); + })); +} /** + * 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. + * + * + * @format + */ + +function makeTempFiles(oldString, newString) { + let oldFilePath; + let newFilePath; + return _rxjsBundlesRxMinJs.Observable.forkJoin(_rxjsBundlesRxMinJs.Observable.fromPromise((_fsPromise || _load_fsPromise()).default.tempfile()).map(filePath => { + oldFilePath = filePath.trim(); + return oldFilePath; + }).switchMap(filePath => { + return writeContentsToFile(oldString, filePath).map(() => filePath); + }), _rxjsBundlesRxMinJs.Observable.fromPromise((_fsPromise || _load_fsPromise()).default.tempfile()).map(filePath => { + newFilePath = filePath.trim(); + return newFilePath; + }).switchMap(filePath => { + return writeContentsToFile(newString, filePath).map(() => filePath); + })).catch(error => { if (oldFilePath != null) { - fsPromise.unlink(oldFilePath); + (_fsPromise || _load_fsPromise()).default.unlink(oldFilePath); } if (newFilePath != null) { - fsPromise.unlink(newFilePath); + (_fsPromise || _load_fsPromise()).default.unlink(newFilePath); } - return Observable.throw(error); + return _rxjsBundlesRxMinJs.Observable.throw(error); }); } -function writeContentsToFile( - contents: string, - filePath: string, -): Observable { - return Observable.fromPromise(fsPromise.writeFile(filePath, contents)); -} +function writeContentsToFile(contents, filePath) { + return _rxjsBundlesRxMinJs.Observable.fromPromise((_fsPromise || _load_fsPromise()).default.writeFile(filePath, contents)); +} \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/lib/hg-bookmark-helpers.js b/pkg/nuclide-hg-rpc/lib/hg-bookmark-helpers.js index 4d8b0ec633..8df9b9e68b 100644 --- a/pkg/nuclide-hg-rpc/lib/hg-bookmark-helpers.js +++ b/pkg/nuclide-hg-rpc/lib/hg-bookmark-helpers.js @@ -1,3 +1,31 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.fetchActiveBookmark = fetchActiveBookmark; +exports.fetchBookmarks = fetchBookmarks; + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,28 +33,22 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {BookmarkInfo} from './HgService'; - -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {getLogger} from 'log4js'; - -const logger = getLogger('nuclide-hg-rpc'); +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc'); /** * @param repoPath The full path to the repository directory (.hg). * @return A promise that resolves to the current bookmark name, if it exists, * or else an empty string. */ -export async function fetchActiveBookmark(repoPath: string): Promise { - const bookmarkFile = nuclideUri.join(repoPath, 'bookmarks.current'); +async function fetchActiveBookmark(repoPath) { + const bookmarkFile = (_nuclideUri || _load_nuclideUri()).default.join(repoPath, 'bookmarks.current'); let result; try { - result = await fsPromise.readFile(bookmarkFile, 'utf-8'); + result = await (_fsPromise || _load_fsPromise()).default.readFile(bookmarkFile, 'utf-8'); } catch (e) { if (!(e.code === 'ENOENT')) { // We expect an error if the bookmark file doesn't exist. Otherwise, the @@ -38,25 +60,20 @@ export async function fetchActiveBookmark(repoPath: string): Promise { return result; } -export async function fetchBookmarks( - repoPath: string, -): Promise> { - const bookmarkFile = nuclideUri.join(repoPath, 'bookmarks'); +async function fetchBookmarks(repoPath) { + const bookmarkFile = (_nuclideUri || _load_nuclideUri()).default.join(repoPath, 'bookmarks'); let result; try { - const bookmarks = await fsPromise.readFile(bookmarkFile, 'utf-8'); + const bookmarks = await (_fsPromise || _load_fsPromise()).default.readFile(bookmarkFile, 'utf-8'); const activeBookmark = await fetchActiveBookmark(repoPath); - result = bookmarks - .split('\n') - .filter(bookmark => bookmark.length > 0) - .map(bookmarkEntry => { - const [node, bookmark] = bookmarkEntry.split(' '); - return { - node, - bookmark, - active: activeBookmark === bookmark, - }; - }); + result = bookmarks.split('\n').filter(bookmark => bookmark.length > 0).map(bookmarkEntry => { + const [node, bookmark] = bookmarkEntry.split(' '); + return { + node, + bookmark, + active: activeBookmark === bookmark + }; + }); } catch (e) { if (!(e.code === 'ENOENT')) { // We expect an error if the bookmark file doesn't exist. Otherwise, the @@ -66,4 +83,4 @@ export async function fetchBookmarks( result = []; } return result; -} +} \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/lib/hg-constants.js b/pkg/nuclide-hg-rpc/lib/hg-constants.js index 7c13d930fe..d1e2192a1c 100644 --- a/pkg/nuclide-hg-rpc/lib/hg-constants.js +++ b/pkg/nuclide-hg-rpc/lib/hg-constants.js @@ -1,24 +1,4 @@ -/** - * 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 strict-local - * @format - */ - -import type { - AmendModeValue, - CommitPhaseType, - MergeConflictStatusCodeId, - MergeConflictStatusValue, - StatusCodeIdValue, - StatusCodeNumberValue, - SuccessorTypeValue, - HisteditActionsValue, -} from './HgService'; +'use strict'; const StatusCodeId = Object.freeze({ ADDED: 'A', @@ -28,11 +8,22 @@ const StatusCodeId = Object.freeze({ MISSING: '!', // (deleted by non-hg command, but still tracked) REMOVED: 'R', UNTRACKED: '?', - UNRESOLVED: 'U', + UNRESOLVED: 'U' }); // This is to work around flow's missing support of enums. -(StatusCodeId: {[key: string]: StatusCodeIdValue}); +/** + * 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. + * + * strict-local + * @format + */ + +StatusCodeId; const StatusCodeNumber = Object.freeze({ ADDED: 1, @@ -42,15 +33,13 @@ const StatusCodeNumber = Object.freeze({ MISSING: 5, REMOVED: 6, UNTRACKED: 7, - UNRESOLVED: 8, + UNRESOLVED: 8 }); // This is to work around flow's missing support of enums. -(StatusCodeNumber: {[key: string]: StatusCodeNumberValue}); +StatusCodeNumber; -const StatusCodeIdToNumber: { - [key: StatusCodeIdValue]: StatusCodeNumberValue, -} = { +const StatusCodeIdToNumber = { [StatusCodeId.ADDED]: StatusCodeNumber.ADDED, [StatusCodeId.CLEAN]: StatusCodeNumber.CLEAN, [StatusCodeId.IGNORED]: StatusCodeNumber.IGNORED, @@ -58,36 +47,36 @@ const StatusCodeIdToNumber: { [StatusCodeId.MISSING]: StatusCodeNumber.MISSING, [StatusCodeId.REMOVED]: StatusCodeNumber.REMOVED, [StatusCodeId.UNTRACKED]: StatusCodeNumber.UNTRACKED, - [StatusCodeId.UNRESOLVED]: StatusCodeNumber.UNRESOLVED, + [StatusCodeId.UNRESOLVED]: StatusCodeNumber.UNRESOLVED }; const MergeConflictStatus = Object.freeze({ BOTH_CHANGED: 'both changed', DELETED_IN_THEIRS: 'deleted in theirs', DELETED_IN_OURS: 'deleted in ours', - RESOLVED: 'resolved', + RESOLVED: 'resolved' }); // This is to work around flow's missing support of enums. -(MergeConflictStatus: {[key: string]: MergeConflictStatusValue}); +MergeConflictStatus; const AmendMode = Object.freeze({ CLEAN: 'Clean', FIXUP: 'Fixup', - REBASE: 'Rebase', + REBASE: 'Rebase' }); // This is to work around flow's missing support of enums. -(AmendMode: {[key: string]: AmendModeValue}); +AmendMode; const CommitPhase = Object.freeze({ PUBLIC: 'public', DRAFT: 'draft', - SECRET: 'secret', + SECRET: 'secret' }); // This is to work around flow's missing support of enums. -(CommitPhase: {[key: string]: CommitPhaseType}); +CommitPhase; const SuccessorType = Object.freeze({ PUBLIC: 'public', @@ -95,29 +84,29 @@ const SuccessorType = Object.freeze({ REBASE: 'rebase', SPLIT: 'split', FOLD: 'fold', - HISTEDIT: 'histedit', + HISTEDIT: 'histedit' }); // This is to work around flow's missing support of enums. -(SuccessorType: {[key: string]: SuccessorTypeValue}); +SuccessorType; const MergeConflictFileStatus = Object.freeze({ RESOLVED: 'R', - UNRESOLVED: 'U', + UNRESOLVED: 'U' }); -(MergeConflictFileStatus: {[key: string]: MergeConflictStatusCodeId}); +MergeConflictFileStatus; const HEAD_REVISION_EXPRESSION = '.'; const PARENT_REVISION_EXPRESSION = '.^'; const STACK_BASE_REVISION_EXPRESSION = 'ancestor(.,master)'; const HisteditActions = Object.freeze({ - PICK: 'pick', + PICK: 'pick' }); // This is to work around flow's missing support of enums. -(HisteditActions: {[key: string]: HisteditActionsValue}); +HisteditActions; // These are the files that hg creates while working and deletes when done, // we can use them to track the state of onging histedits, rebases, grafts, etc. @@ -128,17 +117,9 @@ const LockFiles = Object.freeze({ MERGE: '.hg/merge', // TODO(T25449730): actual state is in .hg/merge/state SHELVED: '.hg/shelvedstate', HISTEDIT: '.hg/histedit-state', - WLOCK: '.hg/wlock', + WLOCK: '.hg/wlock' }); -const LockFilesList: Array = [ - LockFiles.GRAFT, - LockFiles.UPDATE, - LockFiles.REBASE, - LockFiles.MERGE, - LockFiles.SHELVED, - LockFiles.HISTEDIT, - LockFiles.WLOCK, -]; +const LockFilesList = [LockFiles.GRAFT, LockFiles.UPDATE, LockFiles.REBASE, LockFiles.MERGE, LockFiles.SHELVED, LockFiles.HISTEDIT, LockFiles.WLOCK]; // eslint-disable-next-line nuclide-internal/no-commonjs module.exports = { @@ -155,5 +136,5 @@ module.exports = { SuccessorType, HisteditActions, LockFiles, - LockFilesList, -}; + LockFilesList +}; \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/lib/hg-diff-output-parser.js b/pkg/nuclide-hg-rpc/lib/hg-diff-output-parser.js index 94c1eb4281..fab94a0bdb 100644 --- a/pkg/nuclide-hg-rpc/lib/hg-diff-output-parser.js +++ b/pkg/nuclide-hg-rpc/lib/hg-diff-output-parser.js @@ -1,3 +1,21 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.parseHgDiffUnifiedOutput = parseHgDiffUnifiedOutput; +exports.parseMultiFileHgDiffUnifiedOutput = parseMultiFileHgDiffUnifiedOutput; + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _os = _interopRequireDefault(require('os')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +23,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ @@ -18,18 +36,14 @@ const HUNK_DIFF_REGEX = /@@ .* @@/g; const HUNK_OLD_INFO_REGEX = /-([0-9]+)((?:,[0-9]+)?)/; const HUNK_NEW_INFO_REGEX = /\+([0-9]+)((?:,[0-9]+)?)/; -import {lastFromArray} from 'nuclide-commons/collection'; -import os from 'os'; -import type {DiffInfo} from './HgService'; - /** * Parses the output of `hg diff --unified 0`. */ -export function parseHgDiffUnifiedOutput(output: string): DiffInfo { +function parseHgDiffUnifiedOutput(output) { const diffInfo = { added: 0, deleted: 0, - lineDiffs: [], + lineDiffs: [] }; if (!output) { return diffInfo; @@ -55,7 +69,7 @@ export function parseHgDiffUnifiedOutput(output: string): DiffInfo { diffInfo.added += newLines; diffInfo.deleted += oldLines; - diffInfo.lineDiffs.push({oldStart, oldLines, newStart, newLines}); + diffInfo.lineDiffs.push({ oldStart, oldLines, newStart, newLines }); }); return diffInfo; @@ -70,9 +84,7 @@ const DEV_NULL_FILE_PATH = '/dev/null'; * @return A map of each file path in the output (relative to the root of the * repo) to its parsed DiffInfo. */ -export function parseMultiFileHgDiffUnifiedOutput( - output: string, -): Map { +function parseMultiFileHgDiffUnifiedOutput(output) { const filePathToDiffInfo = new Map(); // Split the output by the symbols '--- '. This is specified in the Unified diff format: // http://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html#Detailed-Unified. @@ -83,31 +95,23 @@ export function parseMultiFileHgDiffUnifiedOutput( for (const diffOutputForFile of diffOutputs) { // First, extract the file name. The first line of the string should be the // old file path, except if the file was newly added. - const newLineChar = os.EOL; + const newLineChar = _os.default.EOL; const firstNewline = diffOutputForFile.indexOf(newLineChar); const oldFilePath = diffOutputForFile.slice(0, firstNewline).trim(); // line immediately following starts with "+++ ", containing the new // file path. const secondLineStart = firstNewline + newLineChar.length; - const secondNewLine = diffOutputForFile.indexOf( - newLineChar, - secondLineStart, - ); + const secondNewLine = diffOutputForFile.indexOf(newLineChar, secondLineStart); const secondLine = diffOutputForFile.slice(secondLineStart, secondNewLine); - const newFilePath = lastFromArray( - secondLine.split(SINGLE_UNIFIED_DIFF_SECOND_LINE_REGEX), - ).trim(); + const newFilePath = (0, (_collection || _load_collection()).lastFromArray)(secondLine.split(SINGLE_UNIFIED_DIFF_SECOND_LINE_REGEX)).trim(); // Then, get the parsed diff info. const lineDiffs = parseHgDiffUnifiedOutput(diffOutputForFile); // We should always try to use the new file name. If the unified diff piece // represents a deletion, the new file path is /dev/null, so we then // need to fallback to the old file path. - filePathToDiffInfo.set( - newFilePath !== DEV_NULL_FILE_PATH ? newFilePath : oldFilePath, - lineDiffs, - ); + filePathToDiffInfo.set(newFilePath !== DEV_NULL_FILE_PATH ? newFilePath : oldFilePath, lineDiffs); } return filePathToDiffInfo; -} +} \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/lib/hg-exec-types.js b/pkg/nuclide-hg-rpc/lib/hg-exec-types.js index f67d15fc6f..a726efc43f 100644 --- a/pkg/nuclide-hg-rpc/lib/hg-exec-types.js +++ b/pkg/nuclide-hg-rpc/lib/hg-exec-types.js @@ -1,20 +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 strict - * @format - */ - -import type {Observable} from 'rxjs'; - -export type HgExecOptions = {| - cwd: string, - input?: ?(string | Observable), - NO_HGPLAIN?: boolean, - TTY_OUTPUT?: boolean, - HGEDITOR?: string, -|}; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/lib/hg-revision-expression-helpers.js b/pkg/nuclide-hg-rpc/lib/hg-revision-expression-helpers.js index a2c017efeb..fac0773cf5 100644 --- a/pkg/nuclide-hg-rpc/lib/hg-revision-expression-helpers.js +++ b/pkg/nuclide-hg-rpc/lib/hg-revision-expression-helpers.js @@ -1,22 +1,38 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.NULL_CHAR = exports.INFO_REV_END_MARK = undefined; +exports.expressionForRevisionsBeforeHead = expressionForRevisionsBeforeHead; +exports.expressionForCommonAncestor = expressionForCommonAncestor; +exports.fetchCommonAncestorOfHeadAndRevision = fetchCommonAncestorOfHeadAndRevision; +exports.fetchRevisionsInfo = fetchRevisionsInfo; +exports.fetchRevisionInfoBetweenRevisions = fetchRevisionInfoBetweenRevisions; +exports.fetchRevisionInfo = fetchRevisionInfo; +exports.fetchSmartlogRevisions = fetchSmartlogRevisions; +exports.parseRevisionInfoOutput = parseRevisionInfoOutput; +exports.successorInfoToDisplay = successorInfoToDisplay; + +var _hgUtils; + +function _load_hgUtils() { + return _hgUtils = require('./hg-utils'); +} + +var _hgConstants; + +function _load_hgConstants() { + return _hgConstants = require('./hg-constants'); +} -import type {RevisionInfo, RevisionSuccessorInfo} from './HgService'; -import type {ConnectableObservable} from 'rxjs'; +var _log4js; -import {hgAsyncExecute, hgRunCommand} from './hg-utils'; -import {HEAD_REVISION_EXPRESSION, SuccessorType} from './hg-constants'; -import {getLogger} from 'log4js'; -import invariant from 'assert'; -import {Observable} from 'rxjs'; +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); /** * This file contains utilities for getting an expression to specify a certain @@ -27,8 +43,19 @@ import {Observable} from 'rxjs'; */ // Exported for testing. -export const INFO_REV_END_MARK = '<>'; -export const NULL_CHAR = '\0'; +/** + * 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. + * + * + * @format + */ + +const INFO_REV_END_MARK = exports.INFO_REV_END_MARK = '<>'; +const NULL_CHAR = exports.NULL_CHAR = '\0'; const ESCAPED_NULL_CHAR = '\\0'; // We use `{p1node|short} {p2node|short}` instead of `{parents}` @@ -61,14 +88,7 @@ const REVISION_INFO_TEMPLATE = `{rev} ${INFO_REV_END_MARK} `; -const SUCCESSOR_TEMPLATE_ORDER = [ - SuccessorType.PUBLIC, - SuccessorType.AMEND, - SuccessorType.REBASE, - SuccessorType.SPLIT, - SuccessorType.FOLD, - SuccessorType.HISTEDIT, -]; +const SUCCESSOR_TEMPLATE_ORDER = [(_hgConstants || _load_hgConstants()).SuccessorType.PUBLIC, (_hgConstants || _load_hgConstants()).SuccessorType.AMEND, (_hgConstants || _load_hgConstants()).SuccessorType.REBASE, (_hgConstants || _load_hgConstants()).SuccessorType.SPLIT, (_hgConstants || _load_hgConstants()).SuccessorType.FOLD, (_hgConstants || _load_hgConstants()).SuccessorType.HISTEDIT]; /** * @param revisionExpression An expression that can be passed to hg as an argument @@ -77,10 +97,7 @@ const SUCCESSOR_TEMPLATE_ORDER = [ * that you want a revision expression for. Passing 0 here will simply return 'revisionExpression'. * @return An expression for the 'numberOfRevsBefore'th revision before the given revision. */ -function expressionForRevisionsBefore( - revisionExpression: string, - numberOfRevsBefore: number, -): string { +function expressionForRevisionsBefore(revisionExpression, numberOfRevsBefore) { if (numberOfRevsBefore === 0) { return revisionExpression; } else { @@ -88,23 +105,18 @@ function expressionForRevisionsBefore( } } -export function expressionForRevisionsBeforeHead( - numberOfRevsBefore_: number, -): string { +function expressionForRevisionsBeforeHead(numberOfRevsBefore_) { let numberOfRevsBefore = numberOfRevsBefore_; if (numberOfRevsBefore < 0) { numberOfRevsBefore = 0; } - return expressionForRevisionsBefore( - HEAD_REVISION_EXPRESSION, - numberOfRevsBefore, - ); + return expressionForRevisionsBefore((_hgConstants || _load_hgConstants()).HEAD_REVISION_EXPRESSION, numberOfRevsBefore); } // Section: Revision Sets -export function expressionForCommonAncestor(revision: string): string { - const commonAncestorExpression = `ancestor(${revision}, ${HEAD_REVISION_EXPRESSION})`; +function expressionForCommonAncestor(revision) { + const commonAncestorExpression = `ancestor(${revision}, ${(_hgConstants || _load_hgConstants()).HEAD_REVISION_EXPRESSION})`; // shell-escape does not wrap ancestorExpression in quotes without this toString conversion. return commonAncestorExpression.toString(); } @@ -115,58 +127,25 @@ export function expressionForCommonAncestor(revision: string): string { * @return An expression for the common ancestor of the revision of interest and * the current Hg head. */ -export async function fetchCommonAncestorOfHeadAndRevision( - revision: string, - workingDirectory: string, -): Promise { +async function fetchCommonAncestorOfHeadAndRevision(revision, workingDirectory) { const ancestorExpression = expressionForCommonAncestor(revision); // shell-escape does not wrap '{rev}' in quotes unless it is double-quoted. - const args = [ - 'log', - '--template', - '{rev}', - '--rev', - ancestorExpression, - '--limit', - '1', - ]; + const args = ['log', '--template', '{rev}', '--rev', ancestorExpression, '--limit', '1']; const options = { - cwd: workingDirectory, + cwd: workingDirectory }; try { - const {stdout: ancestorRevisionNumber} = await hgAsyncExecute( - args, - options, - ); + const { stdout: ancestorRevisionNumber } = await (0, (_hgUtils || _load_hgUtils()).hgAsyncExecute)(args, options); return ancestorRevisionNumber; } catch (e) { - getLogger('nuclide-hg-rpc').warn( - 'Failed to get hg common ancestor: ', - e.stderr, - e.command, - ); - throw new Error( - 'Could not fetch common ancestor of head and revision: ' + revision, - ); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').warn('Failed to get hg common ancestor: ', e.stderr, e.command); + throw new Error('Could not fetch common ancestor of head and revision: ' + revision); } } -export function fetchRevisionsInfo( - revisionExpression: string, - workingDirectory: string, - options?: { - shouldLimit?: boolean, - hidden?: boolean, - }, -): Observable> { - const revisionLogArgs = [ - 'log', - '--template', - REVISION_INFO_TEMPLATE, - '--rev', - revisionExpression, - ]; +function fetchRevisionsInfo(revisionExpression, workingDirectory, options) { + const revisionLogArgs = ['log', '--template', REVISION_INFO_TEMPLATE, '--rev', revisionExpression]; if (options == null || options.shouldLimit == null || options.shouldLimit) { revisionLogArgs.push('--limit', '20'); } @@ -177,19 +156,12 @@ export function fetchRevisionsInfo( } const hgOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgRunCommand(revisionLogArgs, hgOptions) - .map(stdout => parseRevisionInfoOutput(stdout)) - .catch(e => { - getLogger('nuclide-hg-rpc').warn( - 'Failed to get revision info for revisions' + - ` ${revisionExpression}: ${e.stderr || e}, ${e.command}`, - ); - throw new Error( - `Could not fetch revision info for revisions: ${revisionExpression}`, - ); - }); + return (0, (_hgUtils || _load_hgUtils()).hgRunCommand)(revisionLogArgs, hgOptions).map(stdout => parseRevisionInfoOutput(stdout)).catch(e => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').warn('Failed to get revision info for revisions' + ` ${revisionExpression}: ${e.stderr || e}, ${e.command}`); + throw new Error(`Could not fetch revision info for revisions: ${revisionExpression}`); + }); } /** @@ -203,43 +175,29 @@ export function fetchRevisionsInfo( * For each RevisionInfo, the `bookmarks` field will contain the list * of bookmark names applied to that revision. */ -export function fetchRevisionInfoBetweenRevisions( - revisionFrom: string, - revisionTo: string, - workingDirectory: string, -): Promise> { +function fetchRevisionInfoBetweenRevisions(revisionFrom, revisionTo, workingDirectory) { const revisionExpression = `${revisionFrom}::${revisionTo}`; return fetchRevisionsInfo(revisionExpression, workingDirectory).toPromise(); } -export async function fetchRevisionInfo( - revisionExpression: string, - workingDirectory: string, -): Promise { - const [revisionInfo] = await fetchRevisionsInfo( - revisionExpression, - workingDirectory, - ).toPromise(); +async function fetchRevisionInfo(revisionExpression, workingDirectory) { + const [revisionInfo] = await fetchRevisionsInfo(revisionExpression, workingDirectory).toPromise(); return revisionInfo; } -export function fetchSmartlogRevisions( - workingDirectory: string, -): ConnectableObservable> { +function fetchSmartlogRevisions(workingDirectory) { // This will get the `smartlog()` expression revisions // and the head revision commits to the nearest public commit parent. const revisionExpression = 'smartlog() + parents(smartlog())'; return fetchRevisionsInfo(revisionExpression, workingDirectory, { - shouldLimit: false, + shouldLimit: false }).publish(); } /** * Helper function to `fetchRevisionInfoBetweenRevisions`. */ -export function parseRevisionInfoOutput( - revisionsInfoOutput: string, -): Array { +function parseRevisionInfoOutput(revisionsInfoOutput) { const revisions = revisionsInfoOutput.split(INFO_REV_END_MARK); const revisionInfo = []; for (const chunk of revisions) { @@ -257,40 +215,37 @@ export function parseRevisionInfoOutput( branch: revisionLines[5], // Phase is either `public`, `draft` or `secret`. // https://www.mercurial-scm.org/wiki/Phases - phase: (revisionLines[6]: any), + phase: revisionLines[6], bookmarks: splitLine(revisionLines[7]), remoteBookmarks: splitLine(revisionLines[8]), tags: splitLine(revisionLines[9]), - parents: splitLine(revisionLines[10]).filter( - hash => hash !== NO_NODE_HASH, - ), + parents: splitLine(revisionLines[10]).filter(hash => hash !== NO_NODE_HASH), isHead: revisionLines[11] === HEAD_MARKER, files: JSON.parse(revisionLines[12]), successorInfo, - description: revisionLines.slice(19).join('\n'), + description: revisionLines.slice(19).join('\n') }); } return revisionInfo; } -function parseSuccessorData( - successorLines: Array, -): ?RevisionSuccessorInfo { - invariant(successorLines.length === SUCCESSOR_TEMPLATE_ORDER.length); +function parseSuccessorData(successorLines) { + if (!(successorLines.length === SUCCESSOR_TEMPLATE_ORDER.length)) { + throw new Error('Invariant violation: "successorLines.length === SUCCESSOR_TEMPLATE_ORDER.length"'); + } + for (let i = 0; i < SUCCESSOR_TEMPLATE_ORDER.length; i++) { if (successorLines[i].length > 0) { return { hash: successorLines[i], - type: SUCCESSOR_TEMPLATE_ORDER[i], + type: SUCCESSOR_TEMPLATE_ORDER[i] }; } } return null; } -export function successorInfoToDisplay( - successorInfo: ?RevisionSuccessorInfo, -): string { +function successorInfoToDisplay(successorInfo) { if (successorInfo == null) { return ''; } @@ -312,6 +267,6 @@ export function successorInfoToDisplay( } } -function splitLine(line: string): Array { +function splitLine(line) { return line.split(NULL_CHAR).filter(e => e.length > 0); -} +} \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/lib/hg-revision-state-helpers.js b/pkg/nuclide-hg-rpc/lib/hg-revision-state-helpers.js index ba7e67f4e6..0a3dce8c56 100644 --- a/pkg/nuclide-hg-rpc/lib/hg-revision-state-helpers.js +++ b/pkg/nuclide-hg-rpc/lib/hg-revision-state-helpers.js @@ -1,23 +1,39 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.fetchFileContentAtRevision = fetchFileContentAtRevision; +exports.batchFetchFileContentsAtRevision = batchFetchFileContentsAtRevision; +exports.fetchFilesChangedAtRevision = fetchFilesChangedAtRevision; +exports.fetchFilesChangedSinceRevision = fetchFilesChangedSinceRevision; +exports.parseRevisionFileChangeOutput = parseRevisionFileChangeOutput; + +var _hgUtils; + +function _load_hgUtils() { + return _hgUtils = require('./hg-utils'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} -import type {RevisionFileChanges} from './HgService'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {ConnectableObservable} from 'rxjs'; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -import {hgRunCommand} from './hg-utils'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import invariant from 'assert'; +const ALL_FILES_LABEL = 'files:'; /** + * 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. + * + * strict-local + * @format + */ -const ALL_FILES_LABEL = 'files:'; const FILE_ADDS_LABEL = 'file-adds:'; const FILE_DELETES_LABEL = 'file-dels:'; const FILE_COPIES_LABEL = 'file-copies:'; @@ -39,37 +55,22 @@ const COPIED_FILE_PAIR_REGEX = /(.+) \((.+)/; * if the operation fails for whatever reason, including invalid input (e.g. if * you pass a filePath that does not exist at the given revision). */ -export function fetchFileContentAtRevision( - filePath: NuclideUri, - revision: string, - workingDirectory: string, -): ConnectableObservable { +function fetchFileContentAtRevision(filePath, revision, workingDirectory) { const args = ['cat', '--rev', revision, filePath]; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgRunCommand(args, execOptions).publish(); + return (0, (_hgUtils || _load_hgUtils()).hgRunCommand)(args, execOptions).publish(); } -export function batchFetchFileContentsAtRevision( - filePaths: Array, - revision: string, - workingDirectory: string, -): ConnectableObservable> { +function batchFetchFileContentsAtRevision(filePaths, revision, workingDirectory) { const args = ['cat', '--rev', revision, ...filePaths, '-Tjson']; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgRunCommand(args, execOptions) - .map(fileData => { - return new Map( - JSON.parse(fileData).map(({abspath, data}) => [ - nuclideUri.join(workingDirectory, abspath), - data, - ]), - ); - }) - .publish(); + return (0, (_hgUtils || _load_hgUtils()).hgRunCommand)(args, execOptions).map(fileData => { + return new Map(JSON.parse(fileData).map(({ abspath, data }) => [(_nuclideUri || _load_nuclideUri()).default.join(workingDirectory, abspath), data])); + }).publish(); } /** @@ -79,25 +80,12 @@ export function batchFetchFileContentsAtRevision( * if the operation fails for whatever reason, including invalid input (e.g. if * you pass an invalid revision). */ -export function fetchFilesChangedAtRevision( - revision: string, - workingDirectory: string, -): ConnectableObservable { - const args = [ - 'log', - '--template', - REVISION_FILE_CHANGES_TEMPLATE, - '--rev', - revision, - '--limit', - '1', - ]; +function fetchFilesChangedAtRevision(revision, workingDirectory) { + const args = ['log', '--template', REVISION_FILE_CHANGES_TEMPLATE, '--rev', revision, '--limit', '1']; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgRunCommand(args, execOptions) - .map(stdout => parseRevisionFileChangeOutput(stdout, workingDirectory)) - .publish(); + return (0, (_hgUtils || _load_hgUtils()).hgRunCommand)(args, execOptions).map(stdout => parseRevisionFileChangeOutput(stdout, workingDirectory)).publish(); } /** @@ -107,23 +95,15 @@ export function fetchFilesChangedAtRevision( * if the operation fails for whatever reason, including invalid input (e.g. if * you pass an invalid revision). */ -export function fetchFilesChangedSinceRevision( - revision: string, - workingDirectory: string, -): ConnectableObservable> { +function fetchFilesChangedSinceRevision(revision, workingDirectory) { const args = ['status', '--rev', revision, '-Tjson']; const execOptions = { - cwd: workingDirectory, + cwd: workingDirectory }; - return hgRunCommand(args, execOptions) - .map(stdout => { - const statuses = JSON.parse(stdout); - return absolutizeAll( - statuses.map(status => status.path), - workingDirectory, - ); - }) - .publish(); + return (0, (_hgUtils || _load_hgUtils()).hgRunCommand)(args, execOptions).map(stdout => { + const statuses = JSON.parse(stdout); + return absolutizeAll(statuses.map(status => status.path), workingDirectory); + }).publish(); } /** @@ -133,10 +113,7 @@ export function fetchFilesChangedSinceRevision( * @param workingDirectory The absolute path to the working directory of the hg repository. * @return A RevisionFileChanges object where the paths are all absolute paths. */ -export function parseRevisionFileChangeOutput( - output: string, - workingDirectory: string, -): RevisionFileChanges { +function parseRevisionFileChangeOutput(output, workingDirectory) { const lines = output.trim().split('\n'); let allFiles = lines[0].slice(ALL_FILES_LABEL.length + 1).trim(); allFiles = allFiles.length ? allFiles.split(' ') : []; @@ -160,10 +137,14 @@ export function parseRevisionFileChangeOutput( // Parse the lines, now in the form: new_file (previous_file) copiedFiles = copiedFiles.map(filePathPair => { const fileNameMatches = filePathPair.match(COPIED_FILE_PAIR_REGEX); - invariant(fileNameMatches); + + if (!fileNameMatches) { + throw new Error('Invariant violation: "fileNameMatches"'); + } + return { from: absolutize(fileNameMatches[2], workingDirectory), - to: absolutize(fileNameMatches[1], workingDirectory), + to: absolutize(fileNameMatches[1], workingDirectory) }; }); @@ -176,14 +157,14 @@ export function parseRevisionFileChangeOutput( added: addedFiles, deleted: deletedFiles, copied: copiedFiles, - modified: modifiedFiles, + modified: modifiedFiles }; } -function absolutize(filePath: string, workingDirectory: string): string { - return nuclideUri.join(workingDirectory, filePath); +function absolutize(filePath, workingDirectory) { + return (_nuclideUri || _load_nuclideUri()).default.join(workingDirectory, filePath); } -function absolutizeAll(filePaths: Array, workingDirectory: string) { +function absolutizeAll(filePaths, workingDirectory) { return filePaths.map(filePath => absolutize(filePath, workingDirectory)); -} +} \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/lib/hg-utils.js b/pkg/nuclide-hg-rpc/lib/hg-utils.js index 5f2fe5b843..0f41667640 100644 --- a/pkg/nuclide-hg-rpc/lib/hg-utils.js +++ b/pkg/nuclide-hg-rpc/lib/hg-utils.js @@ -1,28 +1,47 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.hgAsyncExecute = hgAsyncExecute; +exports.hgObserveExecution = hgObserveExecution; +exports.hgRunCommand = hgRunCommand; +exports.formatCommitMessage = formatCommitMessage; +exports.getInteractiveCommitEditorConfig = getInteractiveCommitEditorConfig; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} -import type {LegacyProcessMessage} from 'nuclide-commons/process'; -import type {HgExecOptions} from './hg-exec-types'; - -import {Observable} from 'rxjs'; -import {runCommandDetailed, ProcessExitError} from 'nuclide-commons/process'; -import {getLogger} from 'log4js'; -import fsPromise from 'nuclide-commons/fsPromise'; -import { - getOriginalEnvironment, - observeProcess, - runCommand, -} from 'nuclide-commons/process'; -import {getConnectionDetails} from '../../nuclide-remote-atom-rpc'; -import nuclideUri from 'nuclide-commons/nuclideUri'; +var _nuclideRemoteAtomRpc; + +function _load_nuclideRemoteAtomRpc() { + return _nuclideRemoteAtomRpc = require('../../nuclide-remote-atom-rpc'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // Mercurial (as of v3.7.2) [strips lines][1] matching the following prefix when a commit message is // created by an editor invoked by Mercurial. Because Nuclide is not invoked by Mercurial, Nuclide @@ -34,16 +53,22 @@ import nuclideUri from 'nuclide-commons/nuclideUri'; const COMMIT_MESSAGE_STRIP_LINE = /^HG:.*(\n|$)/gm; // Avoid spamming the hg blackbox with read-only hg commands. +/** + * 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. + * + * + * @format + */ + const EXCLUDE_FROM_HG_BLACKBOX_COMMANDS = new Set([ - // 'bookmarks' is technically another read-only command, but the possible - // --rename/--delete options make this detection unreliable. - 'cat', - 'config', // Nuclide only ever *reads* the config. - 'diff', - 'log', - 'show', - 'status', -]); +// 'bookmarks' is technically another read-only command, but the possible +// --rename/--delete options make this detection unreliable. +'cat', 'config', // Nuclide only ever *reads* the config. +'diff', 'log', 'show', 'status']); /** * Calls out to checkOutput using the 'hg' command. @@ -51,13 +76,10 @@ const EXCLUDE_FROM_HG_BLACKBOX_COMMANDS = new Set([ * - NO_HGPLAIN set if the $HGPLAIN environment variable should not be used. * - TTY_OUTPUT set if the command should be run as if it were attached to a tty. */ -export async function hgAsyncExecute( - args_: Array, - options_: HgExecOptions, -): Promise { - const {command, args, options} = await getHgExecParams(args_, options_); +async function hgAsyncExecute(args_, options_) { + const { command, args, options } = await getHgExecParams(args_, options_); try { - return await runCommandDetailed(command, args, options).toPromise(); + return await (0, (_process || _load_process()).runCommandDetailed)(command, args, options).toPromise(); } catch (err) { logAndThrowHgError(args, options, err); } @@ -66,22 +88,15 @@ export async function hgAsyncExecute( /** * Calls hg commands, returning an Observable to allow aborting and streaming progress output. */ -export function hgObserveExecution( - args_: Array, - options_: HgExecOptions, -): Observable { +function hgObserveExecution(args_, options_) { // TODO(T17463635) - return Observable.fromPromise( - getHgExecParams(args_, { - ...(options_: any), - TTY_OUTPUT: process.platform !== 'win32', - }), - ).switchMap(({command, args, options}) => { - return observeProcess(command, args, { - ...options, + return _rxjsBundlesRxMinJs.Observable.fromPromise(getHgExecParams(args_, Object.assign({}, options_, { + TTY_OUTPUT: process.platform !== 'win32' + }))).switchMap(({ command, args, options }) => { + return (0, (_process || _load_process()).observeProcess)(command, args, Object.assign({}, options, { killTreeWhenDone: true, - /* TODO(T17353599) */ isExitError: () => false, - }).catch(error => Observable.of({kind: 'error', error})); // TODO(T17463635) + /* TODO(T17353599) */isExitError: () => false + })).catch(error => _rxjsBundlesRxMinJs.Observable.of({ kind: 'error', error })); // TODO(T17463635) }); } @@ -89,28 +104,14 @@ export function hgObserveExecution( * Calls hg commands, returning an Observable to allow aborting. * Resolves to stdout. */ -export function hgRunCommand( - args_: Array, - options_: HgExecOptions, -): Observable { - return Observable.fromPromise(getHgExecParams(args_, options_)).switchMap( - ({command, args, options}) => - runCommand(command, args, {...options, killTreeWhenDone: true}), - ); +function hgRunCommand(args_, options_) { + return _rxjsBundlesRxMinJs.Observable.fromPromise(getHgExecParams(args_, options_)).switchMap(({ command, args, options }) => (0, (_process || _load_process()).runCommand)(command, args, Object.assign({}, options, { killTreeWhenDone: true }))); } -function logAndThrowHgError( - args: Array, - options: Object, - err: Error, -): void { - if (err instanceof ProcessExitError) { - getLogger('nuclide-hg-rpc').error( - `Error executing hg command: ${JSON.stringify(args)}\n` + - `stderr: ${err.stderr}\nstdout: ${String(err.stdout)}\n` + - `options: ${JSON.stringify(options)}`, - ); - const {stdout, stderr, exitCode} = err; +function logAndThrowHgError(args, options, err) { + if (err instanceof (_process || _load_process()).ProcessExitError) { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').error(`Error executing hg command: ${JSON.stringify(args)}\n` + `stderr: ${err.stderr}\nstdout: ${String(err.stdout)}\n` + `options: ${JSON.stringify(options)}`); + const { stdout, stderr, exitCode } = err; let message = 'hg error'; if (exitCode != null) { message += ` (exit code ${exitCode})`; @@ -123,24 +124,18 @@ function logAndThrowHgError( } throw new Error(message); } else { - getLogger('nuclide-hg-rpc').error( - `Error executing hg command: ${JSON.stringify(args)}\n` + - `options: ${JSON.stringify(options)}`, - ); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').error(`Error executing hg command: ${JSON.stringify(args)}\n` + `options: ${JSON.stringify(options)}`); throw err; } } -async function getHgExecParams( - args_: Array, - options_: HgExecOptions, -): Promise<{command: string, args: Array, options: Object}> { +async function getHgExecParams(args_, options_) { let args = [...args_, '--noninteractive']; let sshCommand; // expandHomeDir is not supported on windows if (process.platform !== 'win32') { - const pathToSSHConfig = nuclideUri.expandHomeDir('~/.atom/scm_ssh.sh'); - const doesSSHConfigExist = await fsPromise.exists(pathToSSHConfig); + const pathToSSHConfig = (_nuclideUri || _load_nuclideUri()).default.expandHomeDir('~/.atom/scm_ssh.sh'); + const doesSSHConfigExist = await (_fsPromise || _load_fsPromise()).default.exists(pathToSSHConfig); if (doesSSHConfigExist) { sshCommand = pathToSSHConfig; } else { @@ -148,42 +143,31 @@ async function getHgExecParams( // fail instantly rather than just wait for an input that will never arrive sshCommand = 'ssh -oBatchMode=yes -oControlMaster=no'; } - args.push( - '--config', - `ui.ssh=${sshCommand}`, - // enable the progressfile extension - '--config', - 'extensions.progressfile=', - // have the progressfile extension write to 'progress' in the repo's .hg directory - '--config', - `progress.statefile=${options_.cwd}/.hg/progress`, - // Without assuming hg is being run in a tty, the progress extension won't get used - '--config', - 'progress.assume-tty=1', - // Never show progress bar in stdout since we use the progressfile - '--config', - 'progress.renderer=none', - // Prevent user-specified merge tools from attempting to - // open interactive editors. - '--config', - 'ui.merge=:merge', - // Prevent scary error message on amend in the middle of a stack - '--config', - 'fbamend.education=', - ); + args.push('--config', `ui.ssh=${sshCommand}`, + // enable the progressfile extension + '--config', 'extensions.progressfile=', + // have the progressfile extension write to 'progress' in the repo's .hg directory + '--config', `progress.statefile=${options_.cwd}/.hg/progress`, + // Without assuming hg is being run in a tty, the progress extension won't get used + '--config', 'progress.assume-tty=1', + // Never show progress bar in stdout since we use the progressfile + '--config', 'progress.renderer=none', + // Prevent user-specified merge tools from attempting to + // open interactive editors. + '--config', 'ui.merge=:merge', + // Prevent scary error message on amend in the middle of a stack + '--config', 'fbamend.education='); } const [hgCommandName] = args; if (EXCLUDE_FROM_HG_BLACKBOX_COMMANDS.has(hgCommandName)) { args.push('--config', 'extensions.blackbox=!'); } - const options = { - ...options_, - env: { - LANG: 'en_US.utf-8', // make sure hg uses unicode if user hasn't set LANG themselves - ...(await getOriginalEnvironment()), - ATOM_BACKUP_EDITOR: 'false', - }, - }; + const options = Object.assign({}, options_, { + env: Object.assign({ + LANG: 'en_US.utf-8' }, (await (0, (_process || _load_process()).getOriginalEnvironment)()), { + ATOM_BACKUP_EDITOR: 'false' + }) + }); if (!options.NO_HGPLAIN) { // Setting HGPLAIN=1 overrides any custom aliases a user has defined. options.env.HGPLAIN = 1; @@ -200,50 +184,36 @@ async function getHgExecParams( // We have to 'unescape' to make it work correctly. args = args.map(arg => arg.replace(/\\\\/g, '\\')); } - return {command, args, options}; + return { command, args, options }; } -export function formatCommitMessage(commitMessage: string): string { +function formatCommitMessage(commitMessage) { return commitMessage.replace(COMMIT_MESSAGE_STRIP_LINE, ''); } -export async function getInteractiveCommitEditorConfig(): Promise, - hgEditor: string, -}> { - const connectionDetails = await getConnectionDetails(); +async function getInteractiveCommitEditorConfig() { + const connectionDetails = await (0, (_nuclideRemoteAtomRpc || _load_nuclideRemoteAtomRpc()).getConnectionDetails)(); if (connectionDetails == null) { - getLogger('nuclide-hg-rpc').error('CommandServer not initialized!'); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').error('CommandServer not initialized!'); return null; } // Atom RPC needs to agree with the Atom process / nuclide server on the address and port. - const hgEditor = - getAtomRpcScriptPath() + - ` -f ${connectionDetails.family} -p ${connectionDetails.port} --wait`; + const hgEditor = getAtomRpcScriptPath() + ` -f ${connectionDetails.family} -p ${connectionDetails.port} --wait`; return { - args: [ - '--config', - 'ui.interface.chunkselector=editor', - '--config', - 'extensions.edrecord=', - ], - hgEditor, + args: ['--config', 'ui.interface.chunkselector=editor', '--config', 'extensions.edrecord='], + hgEditor }; } let atomRpcEditorPath; -function getAtomRpcScriptPath(): string { +function getAtomRpcScriptPath() { if (atomRpcEditorPath == null) { try { - atomRpcEditorPath = require.resolve( - '../../nuclide-remote-atom-rpc/bin/fb-atom', - ); + atomRpcEditorPath = require.resolve('../../nuclide-remote-atom-rpc/bin/fb-atom'); } catch (error) { - atomRpcEditorPath = require.resolve( - '../../nuclide-remote-atom-rpc/bin/atom', - ); + atomRpcEditorPath = require.resolve('../../nuclide-remote-atom-rpc/bin/atom'); } } return atomRpcEditorPath; -} +} \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/lib/main.js b/pkg/nuclide-hg-rpc/lib/main.js index 9a3d6ed4b6..4e2c9453df 100644 --- a/pkg/nuclide-hg-rpc/lib/main.js +++ b/pkg/nuclide-hg-rpc/lib/main.js @@ -1,12 +1,20 @@ -/** - * 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 strict-local - * @format - */ - -export {default as hgConstants} from './hg-constants'; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _hgConstants; + +function _load_hgConstants() { + return _hgConstants = require('./hg-constants'); +} + +Object.defineProperty(exports, 'hgConstants', { + enumerable: true, + get: function () { + return _interopRequireDefault(_hgConstants || _load_hgConstants()).default; + } +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } \ No newline at end of file diff --git a/pkg/nuclide-hg-rpc/lib/watchFileCreationAndDeletion.js b/pkg/nuclide-hg-rpc/lib/watchFileCreationAndDeletion.js index 2bec0229f1..d91d2ee7c4 100644 --- a/pkg/nuclide-hg-rpc/lib/watchFileCreationAndDeletion.js +++ b/pkg/nuclide-hg-rpc/lib/watchFileCreationAndDeletion.js @@ -1,27 +1,37 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.subscribeToFilesCreateAndDelete = subscribeToFilesCreateAndDelete; + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} -import type {WatchmanClient, FileChange} from 'nuclide-watchman-helpers'; -import {getLogger} from 'log4js'; -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Observable} from 'rxjs'; +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Return a map of filename => exists in response to watchman events. * Note that this map does not necessarily contain the status of all watched files. */ -function filesCreateOrDeleteToObserver( - fileChanges: Array, -): ?Map { +function filesCreateOrDeleteToObserver(fileChanges) { const state = new Map(); for (const fileChange of fileChanges) { if (fileChange.exists) { @@ -45,59 +55,49 @@ function filesCreateOrDeleteToObserver( * Set up a watchman subscription to watch for a file's creation and deletion. * Returns a Promise so that all such subscriptions can be awaited in bulk. */ -export function subscribeToFilesCreateAndDelete( - watchmanClient: WatchmanClient, - repoPath: string, - fileNames: Array, - subscriptionName: string, -): Observable> { - const filesSubscriptionPromise = watchmanClient.watchDirectoryRecursive( - repoPath, - subscriptionName, - { - expression: ['name', fileNames, 'wholename'], - defer_vcs: false, - }, - ); - return Observable.fromPromise(filesSubscriptionPromise).switchMap( - subscription => { - getLogger('nuclide-hg-rpc').debug( - `Watchman create/delete subscription ${subscriptionName}` + - ` established for files: ${fileNames.join(',')}`, - ); - return Observable.create(observer => { - // Check each file being watched if it already exists. This is done - // individually so that no watchman event can invalidate previously - // checked files. We only bother updating if the file exists. - fileNames.map(fileName => { - const qualifiedFileName = nuclideUri.join(repoPath, fileName); - fsPromise.exists(qualifiedFileName).then(exists => { - if (exists) { - observer.next(new Map([[fileName, exists]])); - getLogger('nuclide-hg-rpc').info( - `${subscriptionName}: watched file ${fileName} already exists`, - ); - } - }); +/** + * 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. + * + * strict-local + * @format + */ + +function subscribeToFilesCreateAndDelete(watchmanClient, repoPath, fileNames, subscriptionName) { + const filesSubscriptionPromise = watchmanClient.watchDirectoryRecursive(repoPath, subscriptionName, { + expression: ['name', fileNames, 'wholename'], + defer_vcs: false + }); + return _rxjsBundlesRxMinJs.Observable.fromPromise(filesSubscriptionPromise).switchMap(subscription => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').debug(`Watchman create/delete subscription ${subscriptionName}` + ` established for files: ${fileNames.join(',')}`); + return _rxjsBundlesRxMinJs.Observable.create(observer => { + // Check each file being watched if it already exists. This is done + // individually so that no watchman event can invalidate previously + // checked files. We only bother updating if the file exists. + fileNames.map(fileName => { + const qualifiedFileName = (_nuclideUri || _load_nuclideUri()).default.join(repoPath, fileName); + (_fsPromise || _load_fsPromise()).default.exists(qualifiedFileName).then(exists => { + if (exists) { + observer.next(new Map([[fileName, exists]])); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').info(`${subscriptionName}: watched file ${fileName} already exists`); + } }); + }); - const changeSubscription = subscription.on( - 'change', - (fileChanges: Array) => { - const newState = filesCreateOrDeleteToObserver(fileChanges); - if (newState != null) { - observer.next(newState); - } - }, - ); - return () => { - getLogger('nuclide-hg-rpc').info( - `disposing of watchman subscription ${subscriptionName}`, - ); - changeSubscription.dispose(); - subscription.dispose(); - }; + const changeSubscription = subscription.on('change', fileChanges => { + const newState = filesCreateOrDeleteToObserver(fileChanges); + if (newState != null) { + observer.next(newState); + } }); - }, - ); -} + return () => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-hg-rpc').info(`disposing of watchman subscription ${subscriptionName}`); + changeSubscription.dispose(); + subscription.dispose(); + }; + }); + }); +} \ No newline at end of file diff --git a/pkg/nuclide-hhvm/lib/HhvmBuildSystem.js b/pkg/nuclide-hhvm/lib/HhvmBuildSystem.js index 63114d516e..7be51db10f 100644 --- a/pkg/nuclide-hhvm/lib/HhvmBuildSystem.js +++ b/pkg/nuclide-hhvm/lib/HhvmBuildSystem.js @@ -1,118 +1,125 @@ -/** - * 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 - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {Task} from '../../commons-node/tasks'; -import type {TaskMetadata} from '../../nuclide-task-runner/lib/types'; - -import {Observable} from 'rxjs'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import {taskFromObservable} from '../../commons-node/tasks'; -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import {Icon} from 'nuclide-commons-ui/Icon'; - -import {debug} from './HhvmDebug'; -import HhvmToolbar from './HhvmToolbar'; -import ProjectStore from './ProjectStore'; -import * as React from 'react'; - -export default class HhvmBuildSystem { - id: string; - name: string; - _projectStore: ProjectStore; - _extraUi: ?React.ComponentType; +'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('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _event; + +function _load_event() { + return _event = require('../../../modules/nuclide-commons/event'); +} + +var _tasks; + +function _load_tasks() { + return _tasks = require('../../commons-node/tasks'); +} + +var _bindObservableAsProps; + +function _load_bindObservableAsProps() { + return _bindObservableAsProps = require('../../../modules/nuclide-commons-ui/bindObservableAsProps'); +} + +var _Icon; + +function _load_Icon() { + return _Icon = require('../../../modules/nuclide-commons-ui/Icon'); +} + +var _HhvmDebug; + +function _load_HhvmDebug() { + return _HhvmDebug = require('./HhvmDebug'); +} + +var _HhvmToolbar; + +function _load_HhvmToolbar() { + return _HhvmToolbar = _interopRequireDefault(require('./HhvmToolbar')); +} + +var _ProjectStore; + +function _load_ProjectStore() { + return _ProjectStore = _interopRequireDefault(require('./ProjectStore')); +} + +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 }; } + +class HhvmBuildSystem { constructor() { this.id = 'hhvm'; this.name = 'HHVM'; - this._projectStore = new ProjectStore(); + this._projectStore = new (_ProjectStore || _load_ProjectStore()).default(); } dispose() { this._projectStore.dispose(); } - getExtraUi(): React.ComponentType { + getExtraUi() { if (this._extraUi == null) { const projectStore = this._projectStore; - const subscription = observableFromSubscribeFunction( - projectStore.onChange.bind(projectStore), - ); - this._extraUi = bindObservableAsProps( - subscription.startWith(null).mapTo({projectStore}), - HhvmToolbar, - ); + const subscription = (0, (_event || _load_event()).observableFromSubscribeFunction)(projectStore.onChange.bind(projectStore)); + this._extraUi = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)(subscription.startWith(null).mapTo({ projectStore }), (_HhvmToolbar || _load_HhvmToolbar()).default); } return this._extraUi; } - getPriority(): number { + getPriority() { return 1; // Take precedence over the Arcanist build toolbar. } - getIcon(): React.ComponentType { - return () => ( - - ); + getIcon() { + return () => _react.createElement((_Icon || _load_Icon()).Icon, { icon: 'nuclicon-hhvm', className: 'nuclide-hhvm-task-runner-icon' }); } - runTask(taskName: string): Task { - return taskFromObservable( - Observable.fromPromise( - debug( - this._projectStore.getDebugMode(), - this._projectStore.getProjectRoot(), - this._projectStore.getDebugTarget(), - this._projectStore.getUseTerminal(), - this._projectStore.getScriptArguments(), - ), - ).ignoreElements(), - ); + runTask(taskName) { + return (0, (_tasks || _load_tasks()).taskFromObservable)(_rxjsBundlesRxMinJs.Observable.fromPromise((0, (_HhvmDebug || _load_HhvmDebug()).debug)(this._projectStore.getDebugMode(), this._projectStore.getProjectRoot(), this._projectStore.getDebugTarget(), this._projectStore.getUseTerminal(), this._projectStore.getScriptArguments())).ignoreElements()); } - setProjectRoot( - projectRoot: ?NuclideUri, - callback: (enabled: boolean, taskList: Array) => mixed, - ): IDisposable { - const enabledObservable = observableFromSubscribeFunction( - this._projectStore.onChange.bind(this._projectStore), - ) - .map(() => this._projectStore) - .filter( - store => - store.getProjectRoot() === projectRoot && - // eslint-disable-next-line eqeqeq - store.isHHVMProject() !== null, - ) - .map(store => store.isHHVMProject() === true) - .distinctUntilChanged(); - - const tasksObservable = Observable.of([ - { - type: 'debug', - label: 'Debug', - description: 'Debug an HHVM project', - icon: 'nuclicon-debugger', - cancelable: false, - }, - ]); - - const subscription = Observable.combineLatest( - enabledObservable, - tasksObservable, - ).subscribe(([enabled, tasks]) => callback(enabled, tasks)); + setProjectRoot(projectRoot, callback) { + const enabledObservable = (0, (_event || _load_event()).observableFromSubscribeFunction)(this._projectStore.onChange.bind(this._projectStore)).map(() => this._projectStore).filter(store => store.getProjectRoot() === projectRoot && + // eslint-disable-next-line eqeqeq + store.isHHVMProject() !== null).map(store => store.isHHVMProject() === true).distinctUntilChanged(); + + const tasksObservable = _rxjsBundlesRxMinJs.Observable.of([{ + type: 'debug', + label: 'Debug', + description: 'Debug an HHVM project', + icon: 'nuclicon-debugger', + cancelable: false + }]); + + const subscription = _rxjsBundlesRxMinJs.Observable.combineLatest(enabledObservable, tasksObservable).subscribe(([enabled, tasks]) => callback(enabled, tasks)); this._projectStore.setProjectRoot(projectRoot); - return new UniversalDisposable(subscription); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(subscription); } } +exports.default = HhvmBuildSystem; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-hhvm/lib/HhvmDebug.js b/pkg/nuclide-hhvm/lib/HhvmDebug.js index 912abdfa04..5b64b99963 100644 --- a/pkg/nuclide-hhvm/lib/HhvmDebug.js +++ b/pkg/nuclide-hhvm/lib/HhvmDebug.js @@ -1,68 +1,68 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {DebugMode} from './types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.debug = debug; -import {getDebuggerService} from 'nuclide-commons-atom/debugger'; -// eslint-disable-next-line nuclide-internal/no-cross-atom-imports -import invariant from 'assert'; -// eslint-disable-next-line nuclide-internal/no-cross-atom-imports -import { - getLaunchProcessInfo, - startAttachProcessInfo, -} from '../../nuclide-debugger-vsp/lib/HhvmLaunchAttachProvider'; +var _debugger; + +function _load_debugger() { + return _debugger = require('../../../modules/nuclide-commons-atom/debugger'); +} -export async function debug( - debugMode: DebugMode, - activeProjectRoot: ?string, - target: string, - useTerminal: boolean, - scriptArguments: string, -): Promise { +var _HhvmLaunchAttachProvider; + +function _load_HhvmLaunchAttachProvider() { + return _HhvmLaunchAttachProvider = require('../../nuclide-debugger-vsp/lib/HhvmLaunchAttachProvider'); +} + +async function debug(debugMode, activeProjectRoot, target, useTerminal, scriptArguments) { let processInfo = null; - invariant(activeProjectRoot != null, 'Active project is null'); + + if (!(activeProjectRoot != null)) { + throw new Error('Active project is null'); + } // See if this is a custom debug mode type. + + try { // $FlowFB const helper = require('./fb-hhvm'); - processInfo = await helper.getCustomLaunchInfo( - debugMode, - activeProjectRoot, - target, - scriptArguments, - ); + processInfo = await helper.getCustomLaunchInfo(debugMode, activeProjectRoot, target, scriptArguments); } catch (e) {} if (processInfo == null) { if (debugMode === 'script') { - processInfo = await getLaunchProcessInfo( - activeProjectRoot, - target, - scriptArguments, - null /* script wrapper */, - useTerminal, - '' /* cwdPath */, + processInfo = await (0, (_HhvmLaunchAttachProvider || _load_HhvmLaunchAttachProvider()).getLaunchProcessInfo)(activeProjectRoot, target, scriptArguments, null /* script wrapper */ + , useTerminal, '' /* cwdPath */ ); } else { - await startAttachProcessInfo( - activeProjectRoot, - null /* attachPort */, - true /* serverAttach */, + await (0, (_HhvmLaunchAttachProvider || _load_HhvmLaunchAttachProvider()).startAttachProcessInfo)(activeProjectRoot, null /* attachPort */ + , true /* serverAttach */ ); return; } } - invariant(processInfo != null); - const debuggerService = await getDebuggerService(); + if (!(processInfo != null)) { + throw new Error('Invariant violation: "processInfo != null"'); + } + + const debuggerService = await (0, (_debugger || _load_debugger()).getDebuggerService)(); await debuggerService.startDebugging(processInfo); } +// eslint-disable-next-line nuclide-internal/no-cross-atom-imports + +// eslint-disable-next-line nuclide-internal/no-cross-atom-imports +/** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-hhvm/lib/HhvmToolbar.js b/pkg/nuclide-hhvm/lib/HhvmToolbar.js index 5871293a0c..65831d4063 100644 --- a/pkg/nuclide-hhvm/lib/HhvmToolbar.js +++ b/pkg/nuclide-hhvm/lib/HhvmToolbar.js @@ -1,68 +1,104 @@ -/** - * 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 - */ - -import type ProjectStore from './ProjectStore'; -import type {DebugMode} from './types'; -import {shell} from 'electron'; - -import {HACK_GRAMMARS} from '../../nuclide-hack-common/lib/constants.js'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {Dropdown} from 'nuclide-commons-ui/Dropdown'; -import {Button, ButtonSizes} from 'nuclide-commons-ui/Button'; -import {Checkbox} from 'nuclide-commons-ui/Checkbox'; -import nullthrows from 'nullthrows'; -import * as React from 'react'; -import {HhvmToolbarSettings} from './HhvmToolbarSettings'; - -const WEB_SERVER_OPTION = {label: 'Attach to WebServer', value: 'webserver'}; -const SCRIPT_OPTION = {label: 'Launch Script', value: 'script'}; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _electron = require('electron'); + +var _constants; + +function _load_constants() { + return _constants = require('../../nuclide-hack-common/lib/constants.js'); +} + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../../../modules/nuclide-commons-ui/AtomInput'); +} + +var _Dropdown; + +function _load_Dropdown() { + return _Dropdown = require('../../../modules/nuclide-commons-ui/Dropdown'); +} + +var _Button; + +function _load_Button() { + return _Button = require('../../../modules/nuclide-commons-ui/Button'); +} + +var _Checkbox; + +function _load_Checkbox() { + return _Checkbox = require('../../../modules/nuclide-commons-ui/Checkbox'); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _HhvmToolbarSettings; + +function _load_HhvmToolbarSettings() { + return _HhvmToolbarSettings = require('./HhvmToolbarSettings'); +} + +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 WEB_SERVER_OPTION = { label: 'Attach to WebServer', value: 'webserver' }; /** + * 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. + * + * + * @format + */ + +const SCRIPT_OPTION = { label: 'Launch Script', value: 'script' }; const DEBUG_OPTIONS = [WEB_SERVER_OPTION, SCRIPT_OPTION]; const NO_LAUNCH_DEBUG_OPTIONS = [WEB_SERVER_OPTION]; -type Props = { - projectStore: ProjectStore, -}; +class HhvmToolbar extends _react.Component { -type State = { - stickyScript: boolean, - useTerminal: boolean, - settingsVisible: boolean, -}; + constructor(props) { + super(props); -export default class HhvmToolbar extends React.Component { - _debugTarget: ?AtomInput; - _dropdown: ?Dropdown; + this._updateLastScriptCommand = command => { + if (this.props.projectStore.getDebugMode() !== 'webserver') { + if (this.state.stickyScript) { + this.props.projectStore.setStickyCommand(command, true); + } else { + this.props.projectStore.updateLastScriptCommand(command); + } + } + }; + + this._handleDropdownChange = value => { + this.props.projectStore.setDebugMode(value); + this._suggestTargetIfCustomDebugMode(value); + }; - constructor(props: Props) { - super(props); this.state = { stickyScript: false, useTerminal: false, - settingsVisible: false, + settingsVisible: false }; } - _updateLastScriptCommand = (command: string): void => { - if (this.props.projectStore.getDebugMode() !== 'webserver') { - if (this.state.stickyScript) { - this.props.projectStore.setStickyCommand(command, true); - } else { - this.props.projectStore.updateLastScriptCommand(command); - } - } - }; - - _getMenuItems(): Array<{label: string, value: DebugMode}> { + _getMenuItems() { const additionalOptions = []; try { // $FlowFB: This is suppressed elsewhere, so vary the filename. @@ -70,14 +106,10 @@ export default class HhvmToolbar extends React.Component { additionalOptions.push(...helpers.getAdditionalLaunchOptions()); } catch (e) {} - return this._isTargetLaunchable( - this.props.projectStore.getCurrentFilePath(), - ) - ? DEBUG_OPTIONS.concat(additionalOptions) - : NO_LAUNCH_DEBUG_OPTIONS; + return this._isTargetLaunchable(this.props.projectStore.getCurrentFilePath()) ? DEBUG_OPTIONS.concat(additionalOptions) : NO_LAUNCH_DEBUG_OPTIONS; } - _isTargetLaunchable(targetFilePath: string): boolean { + _isTargetLaunchable(targetFilePath) { if (targetFilePath.endsWith('.php') || targetFilePath.endsWith('.hh')) { return true; } @@ -85,157 +117,132 @@ export default class HhvmToolbar extends React.Component { const editorPath = editor.getPath(); if (editorPath != null && editorPath.endsWith(targetFilePath)) { const grammar = editor.getGrammar(); - return HACK_GRAMMARS.indexOf(grammar.scopeName) >= 0; + return (_constants || _load_constants()).HACK_GRAMMARS.indexOf(grammar.scopeName) >= 0; } return false; }); } - componentWillReceiveProps(nextProps: Object) { + componentWillReceiveProps(nextProps) { // Reset selected item to webserver if target is not launchable anymore. // TODO[jeffreytan]: this is ugly, refactor to make it more elegant. const store = this.props.projectStore; - if ( - store.getDebugMode() === 'script' && - !this.state.stickyScript && - !this._isTargetLaunchable(store.getCurrentFilePath()) - ) { + if (store.getDebugMode() === 'script' && !this.state.stickyScript && !this._isTargetLaunchable(store.getCurrentFilePath())) { store.setDebugMode('webserver'); } this._suggestTargetIfCustomDebugMode(store.getDebugMode()); - nullthrows(this._debugTarget).setText(store.getDebugTarget()); + (0, (_nullthrows || _load_nullthrows()).default)(this._debugTarget).setText(store.getDebugTarget()); } - render(): React.Node { + render() { const store = this.props.projectStore; const isDebugScript = store.getDebugMode() !== 'webserver'; const isDisabled = !isDebugScript; const value = store.getDebugTarget(); const openFn = () => { - const browserUri = - (this._debugTarget != null - ? this._debugTarget.getText() - : store.getDebugTarget()) || ''; + const browserUri = (this._debugTarget != null ? this._debugTarget.getText() : store.getDebugTarget()) || ''; const address = browserUri.trim().toLowerCase(); if (!address.startsWith('http://') && !address.startsWith('https://')) { - shell.openExternal('https://' + browserUri); + _electron.shell.openExternal('https://' + browserUri); } else { - shell.openExternal(browserUri); + _electron.shell.openExternal(browserUri); } }; - return ( -
    - {/* $FlowFixMe(>=0.53.0) Flow suppress */} - { - this._dropdown = dropdown; - }} - size="sm" - /> -
    - { - this._debugTarget = input; - }} - value={value} - onDidChange={isDisabled ? () => {} : this._updateLastScriptCommand} - onConfirm={openFn} - size="sm" - /> -
    - {store.getDebugMode() !== 'webserver' ? ( - - ) : ( - { - this.props.projectStore.setStickyCommand( - nullthrows(this._debugTarget).getText(), - isChecked, - ); - this.setState({stickyScript: isChecked}); - }} - tooltip={{ - title: - 'When checked, the target script will not change when switching to another editor tab', - }} - /> - )} - {store.getDebugMode() === 'script' ? ( - { - this.props.projectStore.setUseTerminal(isChecked); - this.setState({useTerminal: isChecked}); - }} - tooltip={{ - title: - "When checked, the target script's STDIN and STDOUT will be redirected to a new Nuclide Terminal pane", - }} - /> - ) : null} -
    - + return _react.createElement( + 'div', + { className: 'hhvm-toolbar' }, + _react.createElement((_Dropdown || _load_Dropdown()).Dropdown, { + className: 'inline-block', + options: this._getMenuItems(), + value: store.getDebugMode(), + onChange: this._handleDropdownChange, + ref: dropdown => { + this._dropdown = dropdown; + }, + size: 'sm' + }), + _react.createElement( + 'div', + { className: 'inline-block', style: { width: '300px' } }, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + ref: input => { + this._debugTarget = input; + }, + value: value, + onDidChange: isDisabled ? () => {} : this._updateLastScriptCommand, + onConfirm: openFn, + size: 'sm' + }) + ), + store.getDebugMode() !== 'webserver' ? _react.createElement((_Button || _load_Button()).Button, { + className: 'icon icon-gear', + size: (_Button || _load_Button()).ButtonSizes.SMALL, + title: 'Advanced settings', + style: { 'margin-right': '3px' }, + onClick: () => this._showSettings() + }) : null, + this.state.settingsVisible ? _react.createElement((_HhvmToolbarSettings || _load_HhvmToolbarSettings()).HhvmToolbarSettings, { + projectStore: this.props.projectStore, + onDismiss: () => this._hideSettings() + }) : null, + _react.createElement( + 'div', + { className: 'inline-block' }, + !isDebugScript ? _react.createElement( + (_Button || _load_Button()).Button, + { size: 'SMALL', onClick: openFn }, + 'Open In Browser' + ) : _react.createElement((_Checkbox || _load_Checkbox()).Checkbox, { + checked: this.state.stickyScript, + className: 'nuclide-hhvm-be-sticky-control', + label: 'Sticky', + onChange: isChecked => { + this.props.projectStore.setStickyCommand((0, (_nullthrows || _load_nullthrows()).default)(this._debugTarget).getText(), isChecked); + this.setState({ stickyScript: isChecked }); + }, + tooltip: { + title: 'When checked, the target script will not change when switching to another editor tab' + } + }), + store.getDebugMode() === 'script' ? _react.createElement((_Checkbox || _load_Checkbox()).Checkbox, { + checked: this.state.useTerminal, + className: 'nuclide-hhvm-use-terminal-control', + label: 'Run in Terminal', + onChange: isChecked => { + this.props.projectStore.setUseTerminal(isChecked); + this.setState({ useTerminal: isChecked }); + }, + tooltip: { + title: "When checked, the target script's STDIN and STDOUT will be redirected to a new Nuclide Terminal pane" + } + }) : null + ) ); } - _showSettings(): void { - this.setState({settingsVisible: true}); + _showSettings() { + this.setState({ settingsVisible: true }); } - _hideSettings(): void { - this.setState({settingsVisible: false}); + _hideSettings() { + this.setState({ settingsVisible: false }); } - _suggestTargetIfCustomDebugMode(debugMode: DebugMode) { + _suggestTargetIfCustomDebugMode(debugMode) { const store = this.props.projectStore; // If a custom debug mode is selected, suggest a debug target for the user. if (DEBUG_OPTIONS.find(option => option.value === debugMode) == null) { try { // $FlowFB const helpers = require('./fb-hhvm'); - const suggestedTarget = helpers.suggestDebugTargetName( - debugMode, - store.getCurrentFilePath(), - ); - store.updateLastScriptCommand( - suggestedTarget != null ? suggestedTarget : '', - ); + const suggestedTarget = helpers.suggestDebugTargetName(debugMode, store.getCurrentFilePath()); + store.updateLastScriptCommand(suggestedTarget != null ? suggestedTarget : ''); } catch (e) {} } else { store.updateLastScriptCommand(''); } } - _handleDropdownChange = (value: DebugMode) => { - this.props.projectStore.setDebugMode(value); - this._suggestTargetIfCustomDebugMode(value); - }; } +exports.default = HhvmToolbar; \ No newline at end of file diff --git a/pkg/nuclide-hhvm/lib/HhvmToolbarSettings.js b/pkg/nuclide-hhvm/lib/HhvmToolbarSettings.js index fa21fdefdd..6d9690a3e5 100644 --- a/pkg/nuclide-hhvm/lib/HhvmToolbarSettings.js +++ b/pkg/nuclide-hhvm/lib/HhvmToolbarSettings.js @@ -1,3 +1,38 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.HhvmToolbarSettings = undefined; + +var _react = _interopRequireWildcard(require('react')); + +var _Modal; + +function _load_Modal() { + return _Modal = require('../../../modules/nuclide-commons-ui/Modal'); +} + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../../../modules/nuclide-commons-ui/AtomInput'); +} + +var _Button; + +function _load_Button() { + return _Button = require('../../../modules/nuclide-commons-ui/Button'); +} + +var _ButtonGroup; + +function _load_ButtonGroup() { + return _ButtonGroup = require('../../../modules/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; } } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,64 +40,70 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type ProjectStore from './ProjectStore'; - -import * as React from 'react'; -import {Modal} from 'nuclide-commons-ui/Modal'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {Button, ButtonTypes} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; - -type Props = { - projectStore: ProjectStore, - onDismiss: () => void, -}; - -type State = { - args: string, -}; - -export class HhvmToolbarSettings extends React.Component { - constructor(props: Props) { +class HhvmToolbarSettings extends _react.Component { + constructor(props) { super(props); this.state = { - args: this.props.projectStore.getScriptArguments(), + args: this.props.projectStore.getScriptArguments() }; } - render(): React.Node { - return ( - -
    -
    -

    Script Debug Settings

    - - this.setState({args: newValue})} - size="sm" - /> -
    -
    - - - - -
    -
    -
    + } }, + 'Save' + ) + ) + ) + ) ); } } +exports.HhvmToolbarSettings = HhvmToolbarSettings; \ No newline at end of file diff --git a/pkg/nuclide-hhvm/lib/ProjectStore.js b/pkg/nuclide-hhvm/lib/ProjectStore.js index 3f83ce3870..531dbf3acf 100644 --- a/pkg/nuclide-hhvm/lib/ProjectStore.js +++ b/pkg/nuclide-hhvm/lib/ProjectStore.js @@ -1,41 +1,46 @@ -/** - * 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 - */ - -import type {DebugMode} from './types'; - -import {Emitter} from 'atom'; -import {BehaviorSubject} from 'rxjs'; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _atom = require('atom'); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _HackLanguage; + +function _load_HackLanguage() { + return _HackLanguage = require('../../nuclide-hack/lib/HackLanguage'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // eslint-disable-next-line nuclide-internal/no-cross-atom-imports -import {isFileInHackProject} from '../../nuclide-hack/lib/HackLanguage'; -import {trackTiming} from '../../nuclide-analytics'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -export default class ProjectStore { - _disposables: UniversalDisposable; - _emitter: Emitter; - _currentFilePath: string; - _projectRoot: BehaviorSubject; - _isHHVMProject: ?boolean; - _debugMode: DebugMode; - _filePathsToScriptCommand: Map; - _stickyCommand: string; - _useTerminal: boolean; - _scriptArguments: string; +class ProjectStore { constructor() { - this._emitter = new Emitter(); + this._emitter = new _atom.Emitter(); this._currentFilePath = ''; - this._projectRoot = new BehaviorSubject(); + this._projectRoot = new _rxjsBundlesRxMinJs.BehaviorSubject(); this._isHHVMProject = null; this._debugMode = 'webserver'; this._filePathsToScriptCommand = new Map(); @@ -44,24 +49,18 @@ export default class ProjectStore { this._scriptArguments = ''; const onDidChange = this._onDidChangeActivePaneItem.bind(this); - this._disposables = new UniversalDisposable( - this._projectRoot - .do(() => { - // Set the project type to a "loading" state. - this._isHHVMProject = null; - this._emitter.emit('change'); - }) - .switchMap(root => this._isFileHHVMProject(root)) - .subscribe(isHHVM => { - this._isHHVMProject = isHHVM; - this._emitter.emit('change'); - }), - atom.workspace.onDidStopChangingActivePaneItem(onDidChange), - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(this._projectRoot.do(() => { + // Set the project type to a "loading" state. + this._isHHVMProject = null; + this._emitter.emit('change'); + }).switchMap(root => this._isFileHHVMProject(root)).subscribe(isHHVM => { + this._isHHVMProject = isHHVM; + this._emitter.emit('change'); + }), atom.workspace.onDidStopChangingActivePaneItem(onDidChange)); onDidChange(); } - _onDidChangeActivePaneItem(): void { + _onDidChangeActivePaneItem() { const activeTextEditor = atom.workspace.getActiveTextEditor(); if (!activeTextEditor) { return; @@ -76,17 +75,13 @@ export default class ProjectStore { this._emitter.emit('change'); } - _isFileHHVMProject(fileUri: ?string): Promise { - return trackTiming('toolbar.isFileHHVMProject', async () => { - return ( - fileUri != null && - nuclideUri.isRemote(fileUri) && - isFileInHackProject(fileUri) - ); + _isFileHHVMProject(fileUri) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)('toolbar.isFileHHVMProject', async () => { + return fileUri != null && (_nuclideUri || _load_nuclideUri()).default.isRemote(fileUri) && (0, (_HackLanguage || _load_HackLanguage()).isFileInHackProject)(fileUri); }); } - getLastScriptCommand(filePath: string): string { + getLastScriptCommand(filePath) { const command = this._filePathsToScriptCommand.get(filePath); if (command != null) { return command; @@ -94,51 +89,48 @@ export default class ProjectStore { return ''; } - updateLastScriptCommand(command: string): void { - this._filePathsToScriptCommand.set( - nuclideUri.getPath(this._currentFilePath), - command, - ); + updateLastScriptCommand(command) { + this._filePathsToScriptCommand.set((_nuclideUri || _load_nuclideUri()).default.getPath(this._currentFilePath), command); } - onChange(callback: () => void): IDisposable { + onChange(callback) { return this._emitter.on('change', callback); } - getCurrentFilePath(): string { + getCurrentFilePath() { return this._currentFilePath; } - setProjectRoot(root: ?string): void { + setProjectRoot(root) { this._projectRoot.next(root); } - getProjectRoot(): ?string { + getProjectRoot() { return this._projectRoot.getValue(); } - isHHVMProject(): ?boolean { + isHHVMProject() { return this._isHHVMProject; } - getDebugMode(): DebugMode { + getDebugMode() { return this._debugMode; } - setDebugMode(debugMode: DebugMode): void { + setDebugMode(debugMode) { this._debugMode = debugMode; this._emitter.emit('change'); } - setScriptArguments(args: string): void { + setScriptArguments(args) { this._scriptArguments = args; } - getScriptArguments(): string { + getScriptArguments() { return this._scriptArguments; } - setStickyCommand(command: string, sticky: boolean): void { + setStickyCommand(command, sticky) { if (sticky) { this._stickyCommand = command; } else { @@ -150,21 +142,21 @@ export default class ProjectStore { } } - setUseTerminal(useTerminal: boolean): void { + setUseTerminal(useTerminal) { this._useTerminal = useTerminal; } - getUseTerminal(): boolean { + getUseTerminal() { return this._useTerminal; } - getDebugTarget(): string { + getDebugTarget() { const filePath = this._currentFilePath; if (this._debugMode !== 'webserver') { if (this._stickyCommand !== '') { return this._stickyCommand; } - const localPath = nuclideUri.getPath(filePath); + const localPath = (_nuclideUri || _load_nuclideUri()).default.getPath(filePath); const lastScriptCommand = this.getLastScriptCommand(localPath); return lastScriptCommand === '' ? localPath : lastScriptCommand; } @@ -172,8 +164,8 @@ export default class ProjectStore { // Technically this shouldn't be visible for non-remote paths, but the UI // can sometimes display the toolbar anyway. const rootPath = this._projectRoot.getValue(); - if (rootPath != null && nuclideUri.isRemote(rootPath)) { - return nuclideUri.getHostname(rootPath); + if (rootPath != null && (_nuclideUri || _load_nuclideUri()).default.isRemote(rootPath)) { + return (_nuclideUri || _load_nuclideUri()).default.getHostname(rootPath); } return ''; } @@ -182,3 +174,13 @@ export default class ProjectStore { this._disposables.dispose(); } } +exports.default = ProjectStore; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-hhvm/lib/main.js b/pkg/nuclide-hhvm/lib/main.js index f562262fbd..2b813cdbcf 100644 --- a/pkg/nuclide-hhvm/lib/main.js +++ b/pkg/nuclide-hhvm/lib/main.js @@ -1,89 +1,97 @@ -/** - * 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 - */ - -import type CwdApi from '../../nuclide-current-working-directory/lib/CwdApi'; -import type { - DeepLinkParams, - DeepLinkService, -} from '../../nuclide-deep-link/lib/types'; -import type {RemoteProjectsService} from '../../nuclide-remote-projects'; -import type {TaskRunnerServiceApi} from '../../nuclide-task-runner/lib/types'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {goToLocation} from 'nuclide-commons-atom/go-to-location'; -import {track} from '../../nuclide-analytics'; -import invariant from 'assert'; -// eslint-disable-next-line nuclide-internal/no-cross-atom-imports -import {startAttachProcessInfo} from '../../nuclide-debugger-vsp/lib/HhvmLaunchAttachProvider'; -import HhvmBuildSystem from './HhvmBuildSystem'; +'use strict'; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _goToLocation; + +function _load_goToLocation() { + return _goToLocation = require('../../../modules/nuclide-commons-atom/go-to-location'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _HhvmLaunchAttachProvider; +function _load_HhvmLaunchAttachProvider() { + return _HhvmLaunchAttachProvider = require('../../nuclide-debugger-vsp/lib/HhvmLaunchAttachProvider'); +} + +var _HhvmBuildSystem; + +function _load_HhvmBuildSystem() { + return _HhvmBuildSystem = _interopRequireDefault(require('./HhvmBuildSystem')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// eslint-disable-next-line nuclide-internal/no-cross-atom-imports class Activation { - _buildSystem: ?HhvmBuildSystem; - _disposables: UniversalDisposable; - _cwdApi: ?CwdApi; - _remoteProjectsService: ?RemoteProjectsService; - constructor(state: ?Object) { - this._disposables = new UniversalDisposable(); + constructor(state) { + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } dispose() { this._disposables.dispose(); } - consumeTaskRunnerServiceApi(api: TaskRunnerServiceApi): void { + consumeTaskRunnerServiceApi(api) { this._disposables.add(api.register(this._getBuildSystem())); } - consumeCwdApi(api: CwdApi): IDisposable { + consumeCwdApi(api) { this._cwdApi = api; - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { this._cwdApi = null; }); } - consumeRemoteProjectsService(service: RemoteProjectsService): IDisposable { + consumeRemoteProjectsService(service) { this._remoteProjectsService = service; - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { this._remoteProjectsService = null; }); } - consumeDeepLinkService(deepLink: DeepLinkService): void { - this._disposables.add( - deepLink.subscribeToPath('attach-hhvm', params => { - this._debugDeepWithHhvm(params); - }), - ); + consumeDeepLinkService(deepLink) { + this._disposables.add(deepLink.subscribeToPath('attach-hhvm', params => { + this._debugDeepWithHhvm(params); + })); } - _getBuildSystem(): HhvmBuildSystem { + _getBuildSystem() { if (this._buildSystem == null) { - const buildSystem = new HhvmBuildSystem(); + const buildSystem = new (_HhvmBuildSystem || _load_HhvmBuildSystem()).default(); this._disposables.add(buildSystem); this._buildSystem = buildSystem; } return this._buildSystem; } - async _debugDeepWithHhvm(params: DeepLinkParams): Promise { - const {nuclidePath, hackRoot, line, addBreakpoint, source} = params; + async _debugDeepWithHhvm(params) { + const { nuclidePath, hackRoot, line, addBreakpoint, source } = params; - if ( - typeof nuclidePath !== 'string' || - !nuclideUri.isRemote(nuclidePath) || - typeof hackRoot !== 'string' - ) { + if (typeof nuclidePath !== 'string' || !(_nuclideUri || _load_nuclideUri()).default.isRemote(nuclidePath) || typeof hackRoot !== 'string') { atom.notifications.addError('Invalid arguments.'); return; } @@ -91,14 +99,13 @@ class Activation { const pathString = decodeURIComponent(String(nuclidePath)); const hackRootString = decodeURIComponent(String(hackRoot)); - const startDebugger = - params.noDebugger == null || params.noDebugger !== 'true'; + const startDebugger = params.noDebugger == null || params.noDebugger !== 'true'; - track('nuclide-attach-hhvm-deeplink', { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('nuclide-attach-hhvm-deeplink', { pathString, line, addBreakpoint, - source, + source }); if (this._remoteProjectsService == null) { @@ -106,41 +113,33 @@ class Activation { return; } else { const remoteProjectsService = this._remoteProjectsService; - await new Promise(resolve => - remoteProjectsService.waitForRemoteProjectReload(resolve), - ); + await new Promise(resolve => remoteProjectsService.waitForRemoteProjectReload(resolve)); } - const host = nuclideUri.getHostname(pathString); + const host = (_nuclideUri || _load_nuclideUri()).default.getHostname(pathString); // Allow only valid hostname characters, per RFC 952: // https://tools.ietf.org/html/rfc952 const invalidMatch = host.match(/[^A-Za-z0-9\-._]+/); if (invalidMatch != null) { - atom.notifications.addError( - 'The specified host name contained invalid characters.', - ); + atom.notifications.addError('The specified host name contained invalid characters.'); return; } - const cwd = nuclideUri.createRemoteUri(host, hackRootString); - const notification = atom.notifications.addInfo( - startDebugger - ? `Connecting to ${host} and attaching debugger...` - : `Connecting to ${host}...`, - { - dismissable: true, - }, - ); - - invariant(this._remoteProjectsService != null); - const remoteConnection = await this._remoteProjectsService.createRemoteConnection( - { - host, - path: nuclideUri.getPath(cwd), - displayTitle: host, - }, - ); + const cwd = (_nuclideUri || _load_nuclideUri()).default.createRemoteUri(host, hackRootString); + const notification = atom.notifications.addInfo(startDebugger ? `Connecting to ${host} and attaching debugger...` : `Connecting to ${host}...`, { + dismissable: true + }); + + if (!(this._remoteProjectsService != null)) { + throw new Error('Invariant violation: "this._remoteProjectsService != null"'); + } + + const remoteConnection = await this._remoteProjectsService.createRemoteConnection({ + host, + path: (_nuclideUri || _load_nuclideUri()).default.getPath(cwd), + displayTitle: host + }); if (remoteConnection == null) { atom.notifications.addError(`Could not connect to ${host}`); @@ -149,12 +148,8 @@ class Activation { // The hostname might have changed slightly from what was passed in due to // DNS lookup, so create a new remote URI rather than using cwd from above. - const hackRootUri = remoteConnection - .getConnection() - .getUriOfRemotePath(hackRootString); - const navUri = remoteConnection - .getConnection() - .getUriOfRemotePath(nuclideUri.getPath(pathString)); + const hackRootUri = remoteConnection.getConnection().getUriOfRemotePath(hackRootString); + const navUri = remoteConnection.getConnection().getUriOfRemotePath((_nuclideUri || _load_nuclideUri()).default.getPath(pathString)); // Set the current project root. if (this._cwdApi != null) { @@ -164,10 +159,10 @@ class Activation { // Open the script path in the editor. const lineNumber = parseInt(line, 10); if (Number.isNaN(lineNumber)) { - goToLocation(navUri); + (0, (_goToLocation || _load_goToLocation()).goToLocation)(navUri); } else { // NOTE: line numbers start at 0, so subtract 1. - goToLocation(navUri, {line: lineNumber - 1}); + (0, (_goToLocation || _load_goToLocation()).goToLocation)(navUri, { line: lineNumber - 1 }); } if (startDebugger) { @@ -177,15 +172,22 @@ class Activation { // TODO debuggerService.addBreakpoint(navUri, lineNumber - 1); } - await startAttachProcessInfo( - hackRootUri, - null /* attachPort */, - true /* serverAttach */, + await (0, (_HhvmLaunchAttachProvider || _load_HhvmLaunchAttachProvider()).startAttachProcessInfo)(hackRootUri, null /* attachPort */ + , true /* serverAttach */ ); } notification.dismiss(); } -} - -createPackage(module.exports, Activation); +} /** + * 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. + * + * + * @format + */ + +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-hhvm/lib/types.js b/pkg/nuclide-hhvm/lib/types.js index 726fa0334f..a726efc43f 100644 --- a/pkg/nuclide-hhvm/lib/types.js +++ b/pkg/nuclide-hhvm/lib/types.js @@ -1,17 +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 strict - * @format - */ - -// $FlowFB -import type {CustomDebugMode} from './fb-types'; - -export type PhpDebugMode = 'webserver' | 'script'; - -export type DebugMode = PhpDebugMode | CustomDebugMode; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-home/lib/HomeFeatureComponent.js b/pkg/nuclide-home/lib/HomeFeatureComponent.js index b7189fec68..ee691b22df 100644 --- a/pkg/nuclide-home/lib/HomeFeatureComponent.js +++ b/pkg/nuclide-home/lib/HomeFeatureComponent.js @@ -1,65 +1,85 @@ -/** - * 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 - */ +'use strict'; -import * as React from 'react'; -import {Button, ButtonSizes} from 'nuclide-commons-ui/Button'; -import {track} from '../../nuclide-analytics'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -type Props = { - title: string, - icon: string, - description: string | React.Element, - command: ?(string | (() => void)), -}; +var _react = _interopRequireWildcard(require('react')); -export default class HomeFeatureComponent extends React.Component { - _tryIt = (): void => { - const {command, title} = this.props; - if (command == null) { - return; - } - track('home-feature-tried', {title}); - switch (typeof command) { - case 'string': - atom.commands.dispatch(atom.views.getView(atom.workspace), command, { - _source: 'nuclide-home', - }); - return; - case 'function': - command(); +var _Button; + +function _load_Button() { + return _Button = require('../../../modules/nuclide-commons-ui/Button'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-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; } } + +class HomeFeatureComponent extends _react.Component { + constructor(...args) { + var _temp; + + return _temp = super(...args), this._tryIt = () => { + const { command, title } = this.props; + if (command == null) { return; - default: - throw new Error('Invalid command value'); - } - }; + } + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('home-feature-tried', { title }); + switch (typeof command) { + case 'string': + atom.commands.dispatch(atom.views.getView(atom.workspace), command, { + _source: 'nuclide-home' + }); + return; + case 'function': + command(); + return; + default: + throw new Error('Invalid command value'); + } + }, _temp; + } - render(): React.Node { - const {title, command} = this.props; - return ( -
    - - {title} - {// flowlint-next-line sketchy-null-string:off - command ? ( - - ) : null} - -
    {this.props.description}
    -
    + render() { + const { title, command } = this.props; + return _react.createElement( + 'details', + { className: 'nuclide-home-card' }, + _react.createElement( + 'summary', + { + className: `nuclide-home-summary icon icon-${this.props.icon}` }, + title, + // flowlint-next-line sketchy-null-string:off + command ? _react.createElement( + (_Button || _load_Button()).Button, + { + className: 'pull-right nuclide-home-tryit', + size: (_Button || _load_Button()).ButtonSizes.SMALL, + onClick: this._tryIt }, + 'Try it' + ) : null + ), + _react.createElement( + 'div', + { className: 'nuclide-home-detail' }, + this.props.description + ) ); } } +exports.default = HomeFeatureComponent; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-home/lib/HomePaneItem.js b/pkg/nuclide-home/lib/HomePaneItem.js index 826c40d10e..ac5578f49c 100644 --- a/pkg/nuclide-home/lib/HomePaneItem.js +++ b/pkg/nuclide-home/lib/HomePaneItem.js @@ -1,153 +1,211 @@ -/** - * 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 - */ - -import type {HomeFragments} from './types'; -import type {Observable, BehaviorSubject} from 'rxjs'; - -import * as Immutable from 'immutable'; -import * as React from 'react'; -import HomeFeatureComponent from './HomeFeatureComponent'; -import createUtmUrl from './createUtmUrl'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import NuclideLogo from 'nuclide-commons-ui/NuclideLogo'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Checkbox} from 'nuclide-commons-ui/Checkbox'; -import {track} from '../../nuclide-analytics'; - -export const WORKSPACE_VIEW_URI = 'atom://nuclide/home'; - -const NUCLIDE_DOCS_URL = createUtmUrl('http://nuclide.io', 'welcome'); -const DEFAULT_WELCOME = ( -
    -

    - Thanks for trying Nuclide, Facebook's -
    - unified developer environment. -

    -
      -
    • - Get Started! In-depth docs on our - features. -
    • -
    • - GitHub Pull requests, - issues, and feedback. -
    • -
    -

    - We hope you enjoy using Nuclide -
    - at least as much as we enjoy building it. -

    -
    -); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.WORKSPACE_VIEW_URI = undefined; + +var _immutable; + +function _load_immutable() { + return _immutable = _interopRequireWildcard(require('immutable')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _HomeFeatureComponent; + +function _load_HomeFeatureComponent() { + return _HomeFeatureComponent = _interopRequireDefault(require('./HomeFeatureComponent')); +} + +var _createUtmUrl; + +function _load_createUtmUrl() { + return _createUtmUrl = _interopRequireDefault(require('./createUtmUrl')); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _NuclideLogo; + +function _load_NuclideLogo() { + return _NuclideLogo = _interopRequireDefault(require('../../../modules/nuclide-commons-ui/NuclideLogo')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _Checkbox; + +function _load_Checkbox() { + return _Checkbox = require('../../../modules/nuclide-commons-ui/Checkbox'); +} + +var _nuclideAnalytics; -type Props = { - allHomeFragmentsStream: BehaviorSubject>, -}; +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-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; } } + +const WORKSPACE_VIEW_URI = exports.WORKSPACE_VIEW_URI = 'atom://nuclide/home'; /** + * 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. + * + * + * @format + */ + +const NUCLIDE_DOCS_URL = (0, (_createUtmUrl || _load_createUtmUrl()).default)('http://nuclide.io', 'welcome'); +const DEFAULT_WELCOME = _react.createElement( + 'div', + null, + _react.createElement( + 'p', + null, + 'Thanks for trying Nuclide, Facebook\'s', + _react.createElement('br', null), + 'unified developer environment.' + ), + _react.createElement( + 'ul', + { className: 'text-left' }, + _react.createElement( + 'li', + null, + _react.createElement( + 'a', + { href: NUCLIDE_DOCS_URL }, + 'Get Started!' + ), + ' In-depth docs on our features.' + ), + _react.createElement( + 'li', + null, + _react.createElement( + 'a', + { href: 'https://github.com/facebook/nuclide' }, + 'GitHub' + ), + ' Pull requests, issues, and feedback.' + ) + ), + _react.createElement( + 'p', + null, + 'We hope you enjoy using Nuclide', + _react.createElement('br', null), + 'at least as much as we enjoy building it.' + ) +); -export default class HomePaneItem extends React.Component< - Props, - { - allHomeFragments: Immutable.Set, - showOnStartup: boolean, - }, -> { - _disposables: ?UniversalDisposable; +class HomePaneItem extends _react.Component { - constructor(props: Props) { + constructor(props) { super(props); + + this._handleShowOnStartupChange = checked => { + (_featureConfig || _load_featureConfig()).default.set('nuclide-home.showHome', checked); + }; + this.state = { - showOnStartup: Boolean(featureConfig.get('nuclide-home.showHome')), - allHomeFragments: Immutable.Set(), + showOnStartup: Boolean((_featureConfig || _load_featureConfig()).default.get('nuclide-home.showHome')), + allHomeFragments: (_immutable || _load_immutable()).Set() }; } componentDidMount() { // Note: We're assuming that the allHomeFragmentsStream prop never changes. - this._disposables = new UniversalDisposable( - this.props.allHomeFragmentsStream.subscribe(allHomeFragments => - this.setState({allHomeFragments}), - ), - (featureConfig.observeAsStream('nuclide-home.showHome'): Observable< - any, - >).subscribe(showOnStartup => { - this.setState({showOnStartup}); - }), - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(this.props.allHomeFragmentsStream.subscribe(allHomeFragments => this.setState({ allHomeFragments })), (_featureConfig || _load_featureConfig()).default.observeAsStream('nuclide-home.showHome').subscribe(showOnStartup => { + this.setState({ showOnStartup }); + })); } render() { const welcomes = []; const features = []; - const sortedHomeFragments = Array.from(this.state.allHomeFragments).sort( - (fragmentA, fragmentB) => - (fragmentB.priority || 0) - (fragmentA.priority || 0), - ); + const sortedHomeFragments = Array.from(this.state.allHomeFragments).sort((fragmentA, fragmentB) => (fragmentB.priority || 0) - (fragmentA.priority || 0)); sortedHomeFragments.forEach(fragment => { - const {welcome, feature} = fragment; + const { welcome, feature } = fragment; if (welcome) { - welcomes.push(
    {welcome}
    ); + welcomes.push(_react.createElement( + 'div', + { key: welcomes.length }, + welcome + )); } if (feature) { - features.push( - , - ); + features.push(_react.createElement((_HomeFeatureComponent || _load_HomeFeatureComponent()).default, Object.assign({ key: features.length }, feature))); } }); - const containers = [ -
    -
    - -

    Welcome to Nuclide

    -
    -
    - {welcomes.length > 0 ? welcomes : DEFAULT_WELCOME} -
    -
    - -
    -
    , - ]; + const containers = [_react.createElement( + 'div', + { key: 'welcome', className: 'nuclide-home-container' }, + _react.createElement( + 'section', + { className: 'text-center' }, + _react.createElement((_NuclideLogo || _load_NuclideLogo()).default, { className: 'nuclide-home-logo' }), + _react.createElement( + 'h1', + { className: 'nuclide-home-title' }, + 'Welcome to Nuclide' + ) + ), + _react.createElement( + 'section', + { className: 'text-center', onClick: trackAnchorClicks }, + welcomes.length > 0 ? welcomes : DEFAULT_WELCOME + ), + _react.createElement( + 'section', + { className: 'text-center' }, + _react.createElement((_Checkbox || _load_Checkbox()).Checkbox, { + checked: this.state.showOnStartup, + onChange: this._handleShowOnStartupChange, + label: 'Show this screen on startup.' + }) + ) + )]; if (features.length > 0) { - containers.push( -
    - {features} -
    , - ); + containers.push(_react.createElement( + 'div', + { key: 'features', className: 'nuclide-home-container' }, + features + )); } return ( // Re-use styles from the Atom welcome pane where possible. -
    - {containers} -
    + _react.createElement( + 'div', + { className: 'nuclide-home pane-item padded nuclide-home-containers' }, + containers + ) ); } - _handleShowOnStartupChange = (checked: boolean): void => { - featureConfig.set('nuclide-home.showHome', checked); - }; - - getTitle(): string { + getTitle() { return 'Home'; } - getIconName(): string { + getIconName() { return 'home'; } @@ -156,11 +214,11 @@ export default class HomePaneItem extends React.Component< return false; } - getURI(): string { + getURI() { return WORKSPACE_VIEW_URI; } - getDefaultLocation(): string { + getDefaultLocation() { return 'center'; } @@ -171,14 +229,15 @@ export default class HomePaneItem extends React.Component< } } -function trackAnchorClicks(e: SyntheticMouseEvent<>) { - const {target} = e; +exports.default = HomePaneItem; +function trackAnchorClicks(e) { + const { target } = e; // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) if (target.tagName !== 'A' || target.href == null) { return; } // $FlowFixMe - const {href, innerText} = target; - track('home-link-clicked', {href, text: innerText}); -} + const { href, innerText } = target; + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('home-link-clicked', { href, text: innerText }); +} \ No newline at end of file diff --git a/pkg/nuclide-home/lib/createUtmUrl.js b/pkg/nuclide-home/lib/createUtmUrl.js index dba02b9b89..504a566b6b 100644 --- a/pkg/nuclide-home/lib/createUtmUrl.js +++ b/pkg/nuclide-home/lib/createUtmUrl.js @@ -1,3 +1,9 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = createUtmUrl; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,10 +11,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -export default function createUtmUrl(url: string, campaign: string) { +function createUtmUrl(url, campaign) { return `${url}/?utm_source=nuclide&utm_medium=app&utm_campaign=${campaign}`; -} +} \ No newline at end of file diff --git a/pkg/nuclide-home/lib/main.js b/pkg/nuclide-home/lib/main.js index 545e4fcc85..142862d8d0 100644 --- a/pkg/nuclide-home/lib/main.js +++ b/pkg/nuclide-home/lib/main.js @@ -1,99 +1,136 @@ -/** - * 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 - */ - -import type {HomeFragments} from './types'; - -import createUtmUrl from './createUtmUrl'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {viewableFromReactElement} from '../../commons-atom/viewableFromReactElement'; -import HomePaneItem, {WORKSPACE_VIEW_URI} from './HomePaneItem'; -import * as Immutable from 'immutable'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import {destroyItemWhere} from 'nuclide-commons-atom/destroyItemWhere'; -import * as React from 'react'; -import {BehaviorSubject} from 'rxjs'; -import {shell} from 'electron'; -import passesGK from '../../commons-node/passesGK'; - -const SHOW_NUCLIDE_ONBOARDING_GATEKEEPER = 'nuclide_onboarding'; +'use strict'; + +var _createUtmUrl; + +function _load_createUtmUrl() { + return _createUtmUrl = _interopRequireDefault(require('./createUtmUrl')); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _viewableFromReactElement; + +function _load_viewableFromReactElement() { + return _viewableFromReactElement = require('../../commons-atom/viewableFromReactElement'); +} + +var _HomePaneItem; + +function _load_HomePaneItem() { + return _HomePaneItem = _interopRequireDefault(require('./HomePaneItem')); +} + +var _HomePaneItem2; + +function _load_HomePaneItem2() { + return _HomePaneItem2 = require('./HomePaneItem'); +} + +var _immutable; + +function _load_immutable() { + return _immutable = _interopRequireWildcard(require('immutable')); +} + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _destroyItemWhere; + +function _load_destroyItemWhere() { + return _destroyItemWhere = require('../../../modules/nuclide-commons-atom/destroyItemWhere'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _electron = require('electron'); + +var _passesGK; + +function _load_passesGK() { + return _passesGK = _interopRequireDefault(require('../../commons-node/passesGK')); +} + +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 SHOW_NUCLIDE_ONBOARDING_GATEKEEPER = 'nuclide_onboarding'; /** + * 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. + * + * + * @format + */ class Activation { // A stream of all of the fragments. This is essentially the state of our panel. - _allHomeFragmentsStream: BehaviorSubject< - Immutable.Set, - > = new BehaviorSubject(Immutable.Set()); + constructor(state) { + this._allHomeFragmentsStream = new _rxjsBundlesRxMinJs.BehaviorSubject((_immutable || _load_immutable()).Set()); - _subscriptions: UniversalDisposable; - - constructor(state: ?Object) { this._subscriptions = this._registerCommandAndOpener(); this._considerDisplayingHome(); this._subscriptions.add( - // eslint-disable-next-line nuclide-internal/atom-apis - atom.commands.add('atom-workspace', 'nuclide-home:open-docs', e => { - const url = createUtmUrl('https://nuclide.io/docs', 'help'); - shell.openExternal(url); - }), - ); + // eslint-disable-next-line nuclide-internal/atom-apis + atom.commands.add('atom-workspace', 'nuclide-home:open-docs', e => { + const url = (0, (_createUtmUrl || _load_createUtmUrl()).default)('https://nuclide.io/docs', 'help'); + _electron.shell.openExternal(url); + })); } - setHomeFragments(homeFragments: HomeFragments): UniversalDisposable { - this._allHomeFragmentsStream.next( - this._allHomeFragmentsStream.getValue().add(homeFragments), - ); - return new UniversalDisposable(() => { - this._allHomeFragmentsStream.next( - this._allHomeFragmentsStream.getValue().remove(homeFragments), - ); + setHomeFragments(homeFragments) { + this._allHomeFragmentsStream.next(this._allHomeFragmentsStream.getValue().add(homeFragments)); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { + this._allHomeFragmentsStream.next(this._allHomeFragmentsStream.getValue().remove(homeFragments)); }); } - dispose(): void { - this._allHomeFragmentsStream.next(Immutable.Set()); + dispose() { + this._allHomeFragmentsStream.next((_immutable || _load_immutable()).Set()); this._subscriptions.dispose(); } async _considerDisplayingHome() { - const showHome = - featureConfig.get('nuclide-home.showHome') && - (await !passesGK(SHOW_NUCLIDE_ONBOARDING_GATEKEEPER)); + const showHome = (_featureConfig || _load_featureConfig()).default.get('nuclide-home.showHome') && (await !(0, (_passesGK || _load_passesGK()).default)(SHOW_NUCLIDE_ONBOARDING_GATEKEEPER)); // flowlint-next-line sketchy-null-mixed:off if (showHome) { // eslint-disable-next-line nuclide-internal/atom-apis - atom.workspace.open(WORKSPACE_VIEW_URI, {searchAllPanes: true}); + atom.workspace.open((_HomePaneItem2 || _load_HomePaneItem2()).WORKSPACE_VIEW_URI, { searchAllPanes: true }); } } - _registerCommandAndOpener(): UniversalDisposable { - return new UniversalDisposable( - atom.workspace.addOpener(uri => { - if (uri === WORKSPACE_VIEW_URI) { - return viewableFromReactElement( - , - ); - } - }), - () => destroyItemWhere(item => item instanceof HomePaneItem), - atom.commands.add('atom-workspace', 'nuclide-home:toggle', () => { - atom.workspace.toggle(WORKSPACE_VIEW_URI); - }), - atom.commands.add('atom-workspace', 'nuclide-docs:open', () => { - shell.openExternal('https://nuclide.io/'); - }), - ); + _registerCommandAndOpener() { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(atom.workspace.addOpener(uri => { + if (uri === (_HomePaneItem2 || _load_HomePaneItem2()).WORKSPACE_VIEW_URI) { + return (0, (_viewableFromReactElement || _load_viewableFromReactElement()).viewableFromReactElement)(_react.createElement((_HomePaneItem || _load_HomePaneItem()).default, { + allHomeFragmentsStream: this._allHomeFragmentsStream + })); + } + }), () => (0, (_destroyItemWhere || _load_destroyItemWhere()).destroyItemWhere)(item => item instanceof (_HomePaneItem || _load_HomePaneItem()).default), atom.commands.add('atom-workspace', 'nuclide-home:toggle', () => { + atom.workspace.toggle((_HomePaneItem2 || _load_HomePaneItem2()).WORKSPACE_VIEW_URI); + }), atom.commands.add('atom-workspace', 'nuclide-docs:open', () => { + _electron.shell.openExternal('https://nuclide.io/'); + })); } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-home/lib/types.js b/pkg/nuclide-home/lib/types.js index 9be0820f8e..e043c78f40 100644 --- a/pkg/nuclide-home/lib/types.js +++ b/pkg/nuclide-home/lib/types.js @@ -1,25 +1,5 @@ -/** - * 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 - */ +'use strict'; -import * as React from 'react'; +var _react = _interopRequireWildcard(require('react')); -export type HomeFragments = { - // A string that a package can publish to the main part of the home panel. This allows for - // customized welcome messages, but should be used judiciously. - welcome?: React.Element, - feature?: { - title: string, - icon: string, - description: React.Element | string, - command?: string | (() => void), - }, - priority?: number, -}; +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/pkg/nuclide-http-request-sender/lib/Actions.js b/pkg/nuclide-http-request-sender/lib/Actions.js index 3603b2f405..6497777aaa 100644 --- a/pkg/nuclide-http-request-sender/lib/Actions.js +++ b/pkg/nuclide-http-request-sender/lib/Actions.js @@ -1,32 +1,32 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type { - UpdateStateAction, - SendRequestAction, - PartialAppState, -} from './types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.updateState = updateState; +exports.sendHttpRequest = sendHttpRequest; +const UPDATE_STATE = exports.UPDATE_STATE = 'UPDATE_STATE'; /** + * 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. + * + * strict-local + * @format + */ -export const UPDATE_STATE = 'UPDATE_STATE'; -export const SEND_REQUEST = 'SEND_REQUEST'; +const SEND_REQUEST = exports.SEND_REQUEST = 'SEND_REQUEST'; -export function updateState(state: PartialAppState): UpdateStateAction { +function updateState(state) { return { type: UPDATE_STATE, - payload: {state}, + payload: { state } }; } -export function sendHttpRequest(): SendRequestAction { +function sendHttpRequest() { return { - type: SEND_REQUEST, + type: SEND_REQUEST }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-http-request-sender/lib/Epics.js b/pkg/nuclide-http-request-sender/lib/Epics.js index 43bc6edef6..8aff57940d 100644 --- a/pkg/nuclide-http-request-sender/lib/Epics.js +++ b/pkg/nuclide-http-request-sender/lib/Epics.js @@ -1,29 +1,37 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {ActionsObservable} from 'nuclide-commons/redux-observable'; -import type {Action, Store, Parameter} from './types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.sendHttpRequest = sendHttpRequest; -import * as Actions from './Actions'; -import {Observable} from 'rxjs'; -import querystring from 'querystring'; -import invariant from 'assert'; -import xfetch from '../../commons-node/xfetch'; -import {track} from '../../nuclide-analytics'; +var _Actions; -function _formatUri( - method: string, - uri: string, - parameters: Array, -): string { +function _load_Actions() { + return _Actions = _interopRequireWildcard(require('./Actions')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _querystring = _interopRequireDefault(require('querystring')); + +var _xfetch; + +function _load_xfetch() { + return _xfetch = _interopRequireDefault(require('../../commons-node/xfetch')); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-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; } } + +function _formatUri(method, uri, parameters) { // Generate object of valid and non-duplicate parameter key/value pairs const queryParameters = parameters.reduce((paramObj, param) => { if (param && param.key) { @@ -34,33 +42,35 @@ function _formatUri( } return paramObj; }, {}); - const queryString = querystring.stringify(queryParameters); + const queryString = _querystring.default.stringify(queryParameters); return `${uri}${queryString ? '?' : ''}${queryString}`; -} +} /** + * 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. + * + * strict-local + * @format + */ -export function sendHttpRequest( - actions: ActionsObservable, - store: Store, -): Observable { - return ( - actions - .ofType(Actions.SEND_REQUEST) - .do(action => { - invariant(action.type === Actions.SEND_REQUEST); - const credentials = 'include'; // We always want to send cookies. - const {uri, method, headers, body, parameters} = store.getState(); - const formattedUri = encodeURI(_formatUri(method, uri, parameters)); - const options = - method === 'POST' - ? {method, credentials, headers, body} - : {method, credentials, headers}; - track('nuclide-http-request-sender:http-request', { - formattedUri, - options, - }); - xfetch(formattedUri, options); - }) - // This epic is just for side-effects. - .ignoreElements() - ); -} +function sendHttpRequest(actions, store) { + return actions.ofType((_Actions || _load_Actions()).SEND_REQUEST).do(action => { + if (!(action.type === (_Actions || _load_Actions()).SEND_REQUEST)) { + throw new Error('Invariant violation: "action.type === Actions.SEND_REQUEST"'); + } + + const credentials = 'include'; // We always want to send cookies. + const { uri, method, headers, body, parameters } = store.getState(); + const formattedUri = encodeURI(_formatUri(method, uri, parameters)); + const options = method === 'POST' ? { method, credentials, headers, body } : { method, credentials, headers }; + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('nuclide-http-request-sender:http-request', { + formattedUri, + options + }); + (0, (_xfetch || _load_xfetch()).default)(formattedUri, options); + }) + // This epic is just for side-effects. + .ignoreElements(); +} \ No newline at end of file diff --git a/pkg/nuclide-http-request-sender/lib/ParameterInput.js b/pkg/nuclide-http-request-sender/lib/ParameterInput.js index f02a5b8e6e..30c2893f53 100644 --- a/pkg/nuclide-http-request-sender/lib/ParameterInput.js +++ b/pkg/nuclide-http-request-sender/lib/ParameterInput.js @@ -1,3 +1,26 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParameterInput = undefined; + +var _react = _interopRequireWildcard(require('react')); + +var _Button; + +function _load_Button() { + return _Button = require('../../../modules/nuclide-commons-ui/Button'); +} + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../../../modules/nuclide-commons-ui/AtomInput'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,88 +28,77 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {Parameter} from './types'; - -import * as React from 'react'; -import {Button} from 'nuclide-commons-ui/Button'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; - -type PropsType = { - index: number, - paramKey: string, - paramValue: string, - isDuplicate: boolean, - updateParameter: (index: number, parameter: Parameter) => void, - removeParameter: (index: number) => void, -}; - -export class ParameterInput extends React.Component { - props: PropsType; +class ParameterInput extends _react.Component { - constructor(props: PropsType) { + constructor(props) { super(props); - (this: any)._handleUpdateKey = this._handleUpdateKey.bind(this); - (this: any)._handleUpdateValue = this._handleUpdateValue.bind(this); - (this: any)._handleRemoveParameter = this._handleRemoveParameter.bind(this); - (this: any)._getErrorStyle = this._getErrorStyle.bind(this); + this._handleUpdateKey = this._handleUpdateKey.bind(this); + this._handleUpdateValue = this._handleUpdateValue.bind(this); + this._handleRemoveParameter = this._handleRemoveParameter.bind(this); + this._getErrorStyle = this._getErrorStyle.bind(this); } - _handleUpdateKey(newKey: string): void { + _handleUpdateKey(newKey) { this.props.updateParameter(this.props.index, { key: newKey, - value: this.props.paramValue, + value: this.props.paramValue }); } - _handleUpdateValue(newValue: string): void { + _handleUpdateValue(newValue) { this.props.updateParameter(this.props.index, { key: this.props.paramKey, - value: newValue, + value: newValue }); } - _handleRemoveParameter(): void { + _handleRemoveParameter() { this.props.removeParameter(this.props.index); } - _getErrorStyle(): ?Object { - return this.props.isDuplicate - ? { - borderColor: '#ff6347', - boxShadow: '0 0 0 1px #ff6347', - backgroundColor: '#312426', - } - : null; + _getErrorStyle() { + return this.props.isDuplicate ? { + borderColor: '#ff6347', + boxShadow: '0 0 0 1px #ff6347', + backgroundColor: '#312426' + } : null; } - render(): React.Node { + render() { const style = this._getErrorStyle(); - return ( -
    -
    -
    - - -
    - -
    -
    + return _react.createElement( + 'div', + null, + _react.createElement( + 'div', + { className: 'nuclide-parameter-container' }, + _react.createElement( + 'div', + { className: 'nuclide-parameter-input-container' }, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + onDidChange: this._handleUpdateKey, + initialValue: this.props.paramKey, + style: style + }), + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + onDidChange: this._handleUpdateValue, + initialValue: this.props.paramValue, + style: style + }) + ), + _react.createElement( + (_Button || _load_Button()).Button, + { + className: 'nuclide-parameter-button', + onClick: this._handleRemoveParameter }, + 'X' + ) + ) ); } } +exports.ParameterInput = ParameterInput; \ No newline at end of file diff --git a/pkg/nuclide-http-request-sender/lib/Reducers.js b/pkg/nuclide-http-request-sender/lib/Reducers.js index 2368ecb4ad..45363ea122 100644 --- a/pkg/nuclide-http-request-sender/lib/Reducers.js +++ b/pkg/nuclide-http-request-sender/lib/Reducers.js @@ -1,3 +1,18 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.app = app; + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,23 +20,17 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {Action, AppState} from './types'; - -import * as Actions from './Actions'; - -export function app(state: AppState, action: Action): AppState { +function app(state, action) { switch (action.type) { - case Actions.UPDATE_STATE: { - const {state: newState} = action.payload; - return { - ...state, - ...newState, - }; - } + case (_Actions || _load_Actions()).UPDATE_STATE: + { + const { state: newState } = action.payload; + return Object.assign({}, state, newState); + } } return state; -} +} \ No newline at end of file diff --git a/pkg/nuclide-http-request-sender/lib/RequestEditDialog.js b/pkg/nuclide-http-request-sender/lib/RequestEditDialog.js index 6a26e86627..f2a368fb8c 100644 --- a/pkg/nuclide-http-request-sender/lib/RequestEditDialog.js +++ b/pkg/nuclide-http-request-sender/lib/RequestEditDialog.js @@ -1,245 +1,316 @@ -/** - * 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 - */ - -import type {BoundActionCreators, Parameter} from './types'; - -import * as React from 'react'; -import {Button, ButtonTypes} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; -import {Dropdown} from 'nuclide-commons-ui/Dropdown'; -import {AtomTextEditor} from 'nuclide-commons-ui/AtomTextEditor'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {ParameterInput} from './ParameterInput'; -import invariant from 'assert'; -import shallowequal from 'shallowequal'; - -type Headers = {[key: string]: string}; - -type PropsType = { - actionCreators: BoundActionCreators, - uri: string, - method: string, - headers: Headers, - body: ?string, - parameters: Array, -}; - -const METHOD_DROPDOWN_OPTIONS = [ - {label: 'GET', value: 'GET'}, - {label: 'POST', value: 'POST'}, -]; - -export class RequestEditDialog extends React.Component { - props: PropsType; - _editorComponent: ?AtomTextEditor; - - constructor(props: PropsType) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RequestEditDialog = undefined; + +var _react = _interopRequireWildcard(require('react')); + +var _Button; + +function _load_Button() { + return _Button = require('../../../modules/nuclide-commons-ui/Button'); +} + +var _ButtonGroup; + +function _load_ButtonGroup() { + return _ButtonGroup = require('../../../modules/nuclide-commons-ui/ButtonGroup'); +} + +var _Dropdown; + +function _load_Dropdown() { + return _Dropdown = require('../../../modules/nuclide-commons-ui/Dropdown'); +} + +var _AtomTextEditor; + +function _load_AtomTextEditor() { + return _AtomTextEditor = require('../../../modules/nuclide-commons-ui/AtomTextEditor'); +} + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../../../modules/nuclide-commons-ui/AtomInput'); +} + +var _ParameterInput; + +function _load_ParameterInput() { + return _ParameterInput = require('./ParameterInput'); +} + +var _shallowequal; + +function _load_shallowequal() { + return _shallowequal = _interopRequireDefault(require('shallowequal')); +} + +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 METHOD_DROPDOWN_OPTIONS = [{ label: 'GET', value: 'GET' }, { label: 'POST', value: 'POST' }]; /** + * 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. + * + * + * @format + */ + +class RequestEditDialog extends _react.Component { + + constructor(props) { super(props); + + this._onSendHttpRequest = () => { + this.props.actionCreators.sendHttpRequest(); + this._toggleDialog(); + }; + + this._onCancel = () => { + this._toggleDialog(); + }; + this._editorComponent = null; - (this: any)._onCancel = this._onCancel.bind(this); - (this: any)._onSendHttpRequest = this._onSendHttpRequest.bind(this); - (this: any)._handleParameterChange = this._handleParameterChange.bind(this); - (this: any)._handleRemoveParameter = this._handleRemoveParameter.bind(this); - (this: any)._getParameters = this._getParameters.bind(this); + this._onCancel = this._onCancel.bind(this); + this._onSendHttpRequest = this._onSendHttpRequest.bind(this); + this._handleParameterChange = this._handleParameterChange.bind(this); + this._handleRemoveParameter = this._handleRemoveParameter.bind(this); + this._getParameters = this._getParameters.bind(this); } - shouldComponentUpdate(nextProps: PropsType): boolean { - const {uri, method, headers, body, parameters} = this.props; - return ( - nextProps.uri !== uri || - nextProps.method !== method || - nextProps.body !== body || - !shallowequal(nextProps.headers, headers) || - !shallowequal(nextProps.parameters, parameters) - ); + shouldComponentUpdate(nextProps) { + const { uri, method, headers, body, parameters } = this.props; + return nextProps.uri !== uri || nextProps.method !== method || nextProps.body !== body || !(0, (_shallowequal || _load_shallowequal()).default)(nextProps.headers, headers) || !(0, (_shallowequal || _load_shallowequal()).default)(nextProps.parameters, parameters); } - componentDidMount(): void { + componentDidMount() { this._componentDidRender(); } - componentDidUpdate(): void { + componentDidUpdate() { this._componentDidRender(); } /** * This method should be called after every render to set the AtomTextEditor text. */ - _componentDidRender(): void { + _componentDidRender() { const editorComponent = this._editorComponent; - invariant(editorComponent != null); + + if (!(editorComponent != null)) { + throw new Error('Invariant violation: "editorComponent != null"'); + } + const editor = editorComponent.getModel(); - invariant(editor != null); + + if (!(editor != null)) { + throw new Error('Invariant violation: "editor != null"'); + } + const jsonGrammar = atom.grammars.grammarForScopeName('source.json'); - invariant(jsonGrammar != null); + + if (!(jsonGrammar != null)) { + throw new Error('Invariant violation: "jsonGrammar != null"'); + } + editor.setGrammar(jsonGrammar); editor.setText(JSON.stringify(this.props.headers, null, 2)); } - _onSendHttpRequest = (): void => { - this.props.actionCreators.sendHttpRequest(); - this._toggleDialog(); - }; - - _onCancel = (): void => { - this._toggleDialog(); - }; - - _toggleDialog(): void { - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'nuclide-http-request-sender:toggle-http-request-edit-dialog', - ); + _toggleDialog() { + atom.commands.dispatch(atom.views.getView(atom.workspace), 'nuclide-http-request-sender:toggle-http-request-edit-dialog'); } - _handleTextBufferChange(event: atom$AggregatedTextEditEvent): void { + _handleTextBufferChange(event) { // TODO: It's better to store changes, even if they are illegal JSON. let headers; try { const editorComponent = this._editorComponent; - invariant(editorComponent != null); + + if (!(editorComponent != null)) { + throw new Error('Invariant violation: "editorComponent != null"'); + } + const editor = editorComponent.getModel(); - invariant(editor != null); + + if (!(editor != null)) { + throw new Error('Invariant violation: "editor != null"'); + } + headers = JSON.parse(editor.getText()); } catch (_) { return; // Do not store illegal JSON. } - this.props.actionCreators.updateState({headers}); + this.props.actionCreators.updateState({ headers }); } - _renderRequestBody(): React.Element | null { + _renderRequestBody() { if (this.props.method !== 'POST') { return null; } - return ( -
    - - this.props.actionCreators.updateState({body})} - /> -
    + return _react.createElement( + 'div', + null, + _react.createElement( + 'label', + null, + 'Body' + ), + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + onDidChange: body => this.props.actionCreators.updateState({ body }) + }) ); } - _renderRequestParameters(): React.Element | null { + _renderRequestParameters() { const parameterObj = {}; - return ( -
    - -
    - - -
    - {this.props.parameters.map((parameter, index) => { - if (!parameter) { - return null; - } - const key = parameter.key; - const value = parameter.value; - const trimmedKey = key.trim(); - const output = ( - - ); - - parameterObj[trimmedKey] = true; - return output; - })} -
    + return _react.createElement( + 'div', + null, + _react.createElement( + 'label', + null, + 'Parameters' + ), + _react.createElement( + 'div', + { className: 'nuclide-parameter-input-container' }, + _react.createElement( + 'label', + null, + 'Key' + ), + _react.createElement( + 'label', + null, + 'Value' + ) + ), + this.props.parameters.map((parameter, index) => { + if (!parameter) { + return null; + } + const key = parameter.key; + const value = parameter.value; + const trimmedKey = key.trim(); + const output = _react.createElement((_ParameterInput || _load_ParameterInput()).ParameterInput, { + key: index, + index: index, + paramKey: key, + paramValue: value, + isDuplicate: Boolean(key && parameterObj[trimmedKey]), + updateParameter: this._handleParameterChange, + removeParameter: this._handleRemoveParameter + }); + + parameterObj[trimmedKey] = true; + return output; + }) ); } - _getParameters(): Array { - return this.props.parameters.map( - param => (param == null ? null : {...param}), - ); + _getParameters() { + return this.props.parameters.map(param => param == null ? null : Object.assign({}, param)); } - _handleParameterChange(index: number, parameter: Parameter): void { + _handleParameterChange(index, parameter) { const parameters = this._getParameters(); parameters[index] = parameter; this._updateParameterState(index, parameters); } - _handleRemoveParameter(index: number): void { + _handleRemoveParameter(index) { const parameters = this._getParameters(); parameters[index] = null; this._updateParameterState(index, parameters); } - _updateParameterState( - modifiedIndex: number, - parameters: Array, - ): void { + _updateParameterState(modifiedIndex, parameters) { // If last parameter is modified, add new parameter if (modifiedIndex === parameters.length - 1) { - parameters.push({key: '', value: ''}); + parameters.push({ key: '', value: '' }); } - this.props.actionCreators.updateState({parameters}); + this.props.actionCreators.updateState({ parameters }); } - render(): React.Node { - return ( -
    -
    - - this.props.actionCreators.updateState({uri})} - /> - - this.props.actionCreators.updateState({method})} - /> - {this._renderRequestParameters()} - {this._renderRequestBody()} - -
    - { - this._editorComponent = editorComponent; - }} - tabIndex="3" - autoGrow={false} - softWrapped={true} - onDidTextBufferChange={this._handleTextBufferChange.bind(this)} - /> -
    - - - - -
    -
    + render() { + return _react.createElement( + 'div', + { className: 'block' }, + _react.createElement( + 'div', + { className: 'nuclide-edit-request-dialog' }, + _react.createElement( + 'label', + null, + 'URI: ' + ), + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + tabIndex: '1', + placeholderText: 'https://www.facebook.com', + value: this.props.uri, + onDidChange: uri => this.props.actionCreators.updateState({ uri }) + }), + _react.createElement( + 'label', + null, + 'Method:' + ), + _react.createElement((_Dropdown || _load_Dropdown()).Dropdown, { + className: 'nuclide-edit-request-method-select', + value: this.props.method, + options: METHOD_DROPDOWN_OPTIONS, + onChange: method => this.props.actionCreators.updateState({ method }) + }), + this._renderRequestParameters(), + this._renderRequestBody(), + _react.createElement( + 'label', + null, + 'Headers: ' + ), + _react.createElement( + 'div', + { className: 'nuclide-http-request-sender-headers' }, + _react.createElement((_AtomTextEditor || _load_AtomTextEditor()).AtomTextEditor, { + ref: editorComponent => { + this._editorComponent = editorComponent; + }, + tabIndex: '3', + autoGrow: false, + softWrapped: true, + onDidTextBufferChange: this._handleTextBufferChange.bind(this) + }) + ), + _react.createElement( + (_ButtonGroup || _load_ButtonGroup()).ButtonGroup, + { className: 'nuclide-http-request-sender-button-group' }, + _react.createElement( + (_Button || _load_Button()).Button, + { + buttonType: (_Button || _load_Button()).ButtonTypes.PRIMARY, + tabIndex: '5', + onClick: this._onSendHttpRequest }, + 'Send HTTP Request' + ), + _react.createElement( + (_Button || _load_Button()).Button, + { tabIndex: '4', onClick: this._onCancel }, + 'Cancel' + ) + ) + ) ); } } +exports.RequestEditDialog = RequestEditDialog; \ No newline at end of file diff --git a/pkg/nuclide-http-request-sender/lib/main.js b/pkg/nuclide-http-request-sender/lib/main.js index 41721418cb..187bb8fc17 100644 --- a/pkg/nuclide-http-request-sender/lib/main.js +++ b/pkg/nuclide-http-request-sender/lib/main.js @@ -1,3 +1,75 @@ +'use strict'; + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _reactDom = _interopRequireDefault(require('react-dom')); + +var _RequestEditDialog; + +function _load_RequestEditDialog() { + return _RequestEditDialog = require('./RequestEditDialog'); +} + +var _reduxMin; + +function _load_reduxMin() { + return _reduxMin = require('redux/dist/redux.min.js'); +} + +var _Actions; + +function _load_Actions() { + return _Actions = _interopRequireWildcard(require('./Actions')); +} + +var _Epics; + +function _load_Epics() { + return _Epics = _interopRequireWildcard(require('./Epics')); +} + +var _Reducers; + +function _load_Reducers() { + return _Reducers = _interopRequireWildcard(require('./Reducers')); +} + +var _reduxObservable; + +function _load_reduxObservable() { + return _reduxObservable = require('../../../modules/nuclide-commons/redux-observable'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _bindObservableAsProps; + +function _load_bindObservableAsProps() { + return _bindObservableAsProps = require('../../../modules/nuclide-commons-ui/bindObservableAsProps'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,75 +77,40 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {Store, BoundActionCreators, PartialAppState} from './types'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import {RequestEditDialog} from './RequestEditDialog'; -import {applyMiddleware, bindActionCreators, createStore} from 'redux'; -import * as Actions from './Actions'; -import * as Epics from './Epics'; -import * as Reducers from './Reducers'; -import { - combineEpics, - createEpicMiddleware, -} from 'nuclide-commons/redux-observable'; -import {Observable} from 'rxjs'; -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import {track} from '../../nuclide-analytics'; - -export type HttpRequestSenderApi = { - updateRequestEditDialogDefaults(defaults: PartialAppState): void, -}; - class Activation { - _disposables: UniversalDisposable; - _requestEditDialog: ?atom$Panel; - _store: Store; - _actionCreators: BoundActionCreators; - constructor(): void { + constructor() { const initialState = { uri: 'example.com', method: 'GET', headers: { - cookie: '', + cookie: '' }, body: null, - parameters: [{key: '', value: ''}], + parameters: [{ key: '', value: '' }] }; - const epics = Object.keys(Epics) - .map(k => Epics[k]) - .filter(epic => typeof epic === 'function'); - const rootEpic = combineEpics(...epics); - this._store = createStore( - Reducers.app, - initialState, - applyMiddleware(createEpicMiddleware(rootEpic)), - ); - this._actionCreators = bindActionCreators(Actions, this._store.dispatch); + 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, (_reduxMin || _load_reduxMin()).createStore)((_Reducers || _load_Reducers()).app, initialState, (0, (_reduxMin || _load_reduxMin()).applyMiddleware)((0, (_reduxObservable || _load_reduxObservable()).createEpicMiddleware)(rootEpic))); + this._actionCreators = (0, (_reduxMin || _load_reduxMin()).bindActionCreators)(_Actions || _load_Actions(), this._store.dispatch); this._requestEditDialog = null; - this._disposables = new UniversalDisposable( - atom.commands.add('atom-workspace', { - 'nuclide-http-request-sender:toggle-http-request-edit-dialog': () => { - track('nuclide-http-request-sender:toggle-http-request-edit-dialog'); - this._toggleRequestEditDialog(); - }, - 'nuclide-http-request-sender:send-http-request': () => { - track('nuclide-http-request-sender:send-http-request'); - this._actionCreators.sendHttpRequest(); - }, - }), - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(atom.commands.add('atom-workspace', { + 'nuclide-http-request-sender:toggle-http-request-edit-dialog': () => { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('nuclide-http-request-sender:toggle-http-request-edit-dialog'); + this._toggleRequestEditDialog(); + }, + 'nuclide-http-request-sender:send-http-request': () => { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('nuclide-http-request-sender:send-http-request'); + this._actionCreators.sendHttpRequest(); + } + })); } - _toggleRequestEditDialog(): void { + _toggleRequestEditDialog() { const dialog = this._createModalIfNeeded(); if (dialog.isVisible()) { dialog.hide(); @@ -82,44 +119,37 @@ class Activation { } } - _createModalIfNeeded(): atom$Panel { + _createModalIfNeeded() { if (this._requestEditDialog != null) { return this._requestEditDialog; } - const BoundEditDialog = bindObservableAsProps( - // $FlowFixMe -- Flow doesn't know about the Observable symbol used by from(). - Observable.from(this._store), - RequestEditDialog, - ); + const BoundEditDialog = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)( + // $FlowFixMe -- Flow doesn't know about the Observable symbol used by from(). + _rxjsBundlesRxMinJs.Observable.from(this._store), (_RequestEditDialog || _load_RequestEditDialog()).RequestEditDialog); const container = document.createElement('div'); const requestEditDialog = atom.workspace.addModalPanel({ item: container, - visible: false, + visible: false }); - ReactDOM.render( - , - container, - ); - this._disposables.add( - new UniversalDisposable(() => { - requestEditDialog.destroy(); - this._requestEditDialog = null; - ReactDOM.unmountComponentAtNode(container); - }), - ); + _reactDom.default.render(_react.createElement(BoundEditDialog, { actionCreators: this._actionCreators }), container); + this._disposables.add(new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { + requestEditDialog.destroy(); + this._requestEditDialog = null; + _reactDom.default.unmountComponentAtNode(container); + })); this._requestEditDialog = requestEditDialog; return requestEditDialog; } - provideHttpRequestSender(): HttpRequestSenderApi { + provideHttpRequestSender() { return { - updateRequestEditDialogDefaults: this._actionCreators.updateState, + updateRequestEditDialogDefaults: this._actionCreators.updateState }; } - dispose(): void { + dispose() { this._disposables.dispose(); } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-http-request-sender/lib/types.js b/pkg/nuclide-http-request-sender/lib/types.js index 533fb6bd15..a726efc43f 100644 --- a/pkg/nuclide-http-request-sender/lib/types.js +++ b/pkg/nuclide-http-request-sender/lib/types.js @@ -1,56 +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 - */ - -type Verb = 'GET' | 'POST'; - -export type AppState = { - uri: string, - method: Verb, - headers: {[key: string]: string}, - body: ?string, - parameters: Array, -}; - -export type PartialAppState = { - uri?: string, - method?: Verb, - headers?: {[key: string]: string}, - body?: ?string, - parameters?: Array, -}; - -export type Store = { - getState(): AppState, - dispatch(action: Action): void, -}; - -export type BoundActionCreators = { - updateState(state: PartialAppState): void, - sendHttpRequest(): void, -}; - -export type UpdateStateAction = { - type: 'UPDATE_STATE', - payload: { - state: Object, - }, -}; - -export type SendRequestAction = { - type: 'SEND_REQUEST', -}; - -export type Parameter = ?{ - key: string, - value: string, -}; - -export type Action = UpdateStateAction | SendRequestAction; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-image-view/VendorLib/image-view/spec/fixtures/binary-file-2.png b/pkg/nuclide-image-view/VendorLib/image-view/spec/fixtures/binary-file-2.png deleted file mode 100755 index 711c4daa15..0000000000 Binary files a/pkg/nuclide-image-view/VendorLib/image-view/spec/fixtures/binary-file-2.png and /dev/null differ diff --git a/pkg/nuclide-image-view/VendorLib/image-view/spec/fixtures/binary-file.png b/pkg/nuclide-image-view/VendorLib/image-view/spec/fixtures/binary-file.png deleted file mode 100755 index b4d6eb7c34..0000000000 Binary files a/pkg/nuclide-image-view/VendorLib/image-view/spec/fixtures/binary-file.png and /dev/null differ diff --git a/pkg/nuclide-image-view/VendorLib/image-view/spec/image-editor-spec.coffee b/pkg/nuclide-image-view/VendorLib/image-view/spec/image-editor-spec.coffee deleted file mode 100755 index 9fd1063ff6..0000000000 --- a/pkg/nuclide-image-view/VendorLib/image-view/spec/image-editor-spec.coffee +++ /dev/null @@ -1,123 +0,0 @@ -# @generated SignedSource<<5e6046634ce0927b58fa9f68d8a587df>> -path = require 'path' -ImageEditor = require '../lib/image-editor' - -describe "ImageEditor", -> - describe ".deserialize(state)", -> - it "returns undefined if no file exists at the given path", -> - spyOn(console, 'warn') # suppress logging in spec - editor = new ImageEditor(path.join(__dirname, 'fixtures', 'binary-file.png')) - state = editor.serialize() - expect(ImageEditor.deserialize(state)).toBeDefined() - state.filePath = 'bogus' - expect(ImageEditor.deserialize(state)).toBeUndefined() - - describe ".copy()", -> - it "returns another ImageEditor for the same file", -> - editor = new ImageEditor(path.join(__dirname, 'fixtures', 'binary-file.png')) - newEditor = editor.copy() - expect(newEditor.getPath()).toBe(editor.getPath()) - - describe ".activate()", -> - it "registers a project opener that handles image file extension", -> - waitsForPromise -> - atom.packages.activatePackage('image-view') - - runs -> - atom.workspace.open(path.join(__dirname, 'fixtures', 'binary-file.png')) - - waitsFor -> - atom.workspace.getActivePaneItem() instanceof ImageEditor - - runs -> - expect(atom.workspace.getActivePaneItem().getTitle()).toBe 'binary-file.png' - atom.workspace.destroyActivePaneItem() - - waitsFor -> - Promise.resolve(atom.packages.deactivatePackage('image-view')) - - runs -> - atom.workspace.open(path.join(__dirname, 'fixtures', 'binary-file.png')) - - waitsFor -> - atom.workspace.getActivePaneItem()? - - runs -> - expect(atom.workspace.getActivePaneItem() instanceof ImageEditor).toBe false - - describe "::onDidTerminatePendingState", -> - item = null - pendingSpy = null - - beforeEach -> - pendingSpy = jasmine.createSpy("onDidTerminatePendingState") - - waitsForPromise -> - atom.packages.activatePackage('image-view') - - it "is called when pending state gets terminated for the active ImageEditor", -> - runs -> - atom.workspace.open(path.join(__dirname, 'fixtures', 'binary-file.png'), pending: true) - - waitsFor -> - atom.workspace.getActivePane().getPendingItem() instanceof ImageEditor - - runs -> - item = atom.workspace.getActivePane().getPendingItem() - expect(item.getTitle()).toBe 'binary-file.png' - item.onDidTerminatePendingState pendingSpy - item.terminatePendingState() - expect(pendingSpy).toHaveBeenCalled() - - it "is not called when the ImageEditor is not pending", -> - runs -> - atom.workspace.open(path.join(__dirname, 'fixtures', 'binary-file.png'), pending: false) - - waitsFor -> - atom.workspace.getActivePaneItem() instanceof ImageEditor - - runs -> - item = atom.workspace.getActivePaneItem() - expect(item.getTitle()).toBe 'binary-file.png' - item.onDidTerminatePendingState pendingSpy - item.terminatePendingState() - expect(pendingSpy).not.toHaveBeenCalled() - - describe "::getAllowedLocations", -> - it "ensures that ImageEditor opens in workspace center", -> - waitsForPromise -> - atom.packages.activatePackage('image-view') - - runs -> - atom.workspace.open(path.join(__dirname, 'fixtures', 'binary-file.png'), {location: 'right'}) - - waitsFor -> - atom.workspace.getActivePaneItem() instanceof ImageEditor - - runs -> - expect(atom.workspace.getCenter().getActivePaneItem().getTitle()).toBe 'binary-file.png' - - describe "when the image gets reopened", -> - beforeEach -> - waitsForPromise -> - atom.packages.activatePackage('image-view') - - it "should not change the URI between each reopen", -> - uri = null - - runs -> - atom.workspace.open(path.join(__dirname, 'fixtures', 'binary-file.png')) - - waitsFor -> - atom.workspace.getActivePaneItem() instanceof ImageEditor - - runs -> - uri = atom.workspace.getActivePaneItem().getURI() - atom.workspace.destroyActivePaneItem() - atom.workspace.reopenItem() - - waitsFor -> - atom.workspace.getActivePaneItem() instanceof ImageEditor - - runs -> - expect(atom.workspace.getActivePaneItem().getURI()).toBe uri diff --git a/pkg/nuclide-image-view/VendorLib/image-view/spec/image-editor-view-spec.coffee b/pkg/nuclide-image-view/VendorLib/image-view/spec/image-editor-view-spec.coffee deleted file mode 100755 index 3da39fd60b..0000000000 --- a/pkg/nuclide-image-view/VendorLib/image-view/spec/image-editor-view-spec.coffee +++ /dev/null @@ -1,163 +0,0 @@ -# @generated SignedSource<> -ImageEditorView = require '../lib/image-editor-view' -ImageEditor = require '../lib/image-editor' - -describe "ImageEditorView", -> - [editor, view, filePath, filePath2, workspaceElement] = [] - - beforeEach -> - workspaceElement = atom.views.getView(atom.workspace) - filePath = atom.project.getDirectories()[0].resolve('binary-file.png') - filePath2 = atom.project.getDirectories()[0].resolve('binary-file-2.png') - editor = new ImageEditor(filePath) - view = new ImageEditorView(editor) - view.element.style.height = '100px' - jasmine.attachToDOM(view.element) - - waitsFor -> view.loaded - - afterEach -> - editor.destroy() - view.destroy() - - it "displays the image for a path", -> - expect(view.refs.image.src).toContain '/fixtures/binary-file.png' - - describe "when the image is changed", -> - it "reloads the image", -> - spyOn(view, 'updateImageURI') - editor.file.emitter.emit('did-change') - expect(view.updateImageURI).toHaveBeenCalled() - - describe "when the image is moved", -> - it "updates the title", -> - titleHandler = jasmine.createSpy('titleHandler') - editor.onDidChangeTitle(titleHandler) - editor.file.emitter.emit('did-rename') - - expect(titleHandler).toHaveBeenCalled() - - describe "image-view:reload", -> - it "reloads the image", -> - spyOn(view, 'updateImageURI') - atom.commands.dispatch view.element, 'image-view:reload' - expect(view.updateImageURI).toHaveBeenCalled() - - describe "image-view:zoom-in", -> - it "increases the image size by 25%", -> - atom.commands.dispatch view.element, 'image-view:zoom-in' - expect(view.refs.image.offsetWidth).toBe 13 - expect(view.refs.image.offsetHeight).toBe 13 - - describe "image-view:zoom-out", -> - it "decreases the image size by 25%", -> - atom.commands.dispatch view.element, 'image-view:zoom-out' - expect(view.refs.image.offsetWidth).toBe 8 - expect(view.refs.image.offsetHeight).toBe 8 - - describe "image-view:reset-zoom", -> - it "restores the image to the original size", -> - atom.commands.dispatch view.element, 'image-view:zoom-in' - expect(view.refs.image.offsetWidth).not.toBe 10 - expect(view.refs.image.offsetHeight).not.toBe 10 - atom.commands.dispatch view.element, 'image-view:reset-zoom' - expect(view.refs.image.offsetWidth).toBe 10 - expect(view.refs.image.offsetHeight).toBe 10 - - describe ".adjustSize(factor)", -> - it "does not allow a zoom percentage lower than 10%", -> - view.adjustSize(0) - expect(view.refs.resetZoomButton.textContent).toBe '10%' - - describe "ImageEditorStatusView", -> - [imageSizeStatus] = [] - - beforeEach -> - view.destroy() - jasmine.attachToDOM(workspaceElement) - - waitsForPromise -> - atom.packages.activatePackage('image-view') - - waitsForPromise -> - atom.workspace.open(filePath) - - runs -> - editor = atom.workspace.getActivePaneItem() - view = editor.view - view.element.style.height = '100px' - - waitsFor -> - view.loaded - - waitsForPromise -> - atom.packages.activatePackage('status-bar') - - runs -> - statusBar = workspaceElement.querySelector('status-bar') - imageSizeStatus = statusBar.leftPanel.querySelector('.status-image') - expect(imageSizeStatus).toExist() - - it "displays the size of the image", -> - expect(imageSizeStatus.textContent).toBe '10x10 392B' - - describe "when special characters are used in the file name", -> - describe "when '?' exists in the file name", -> - it "is replaced with %3F", -> - newEditor = new ImageEditor('/test/file/?.png') - expect(newEditor.getEncodedURI()).toBe('file:///test/file/%3F.png') - - describe "when '#' exists in the file name", -> - it "is replaced with %23", -> - newEditor = new ImageEditor('/test/file/#.png') - expect(newEditor.getEncodedURI()).toBe('file:///test/file/%23.png') - - describe "when '%2F' exists in the file name", -> - it "should properly encode the %", -> - newEditor = new ImageEditor('/test/file/%2F.png') - expect(newEditor.getEncodedURI()).toBe('file:///test/file/%252F.png') - - describe "when multiple special characters exist in the file name", -> - it "are all replaced with escaped characters", -> - newEditor = new ImageEditor('/test/file/a?#b#?.png') - expect(newEditor.getEncodedURI()).toBe('file:///test/file/a%3F%23b%23%3F.png') - - describe "when multiple images are opened at the same time", -> - beforeEach -> - view.destroy() - jasmine.attachToDOM(workspaceElement) - - waitsForPromise -> - atom.packages.activatePackage('image-view') - - it "correctly calculates originalWidth and originalHeight for all opened images", -> - imageEditor1 = null - imageEditor2 = null - - openedCount = 0 - originalOpen = atom.workspace.open.bind(atom.workspace) - spyOn(atom.workspace, 'open').andCallFake (uri, options) -> - originalOpen(uri, options).then -> openedCount++ - - runs -> - atom.workspace.open(filePath) - atom.workspace.open(filePath2) - - waitsFor 'open to be called twice', -> - openedCount is 2 - - runs -> - expect(atom.workspace.getActivePane().getItems().length).toBe 2 - imageEditor1 = atom.workspace.getActivePane().getItems()[0] - imageEditor2 = atom.workspace.getActivePane().getItems()[1] - expect(imageEditor1).toBe instanceof ImageEditor - expect(imageEditor2).toBe instanceof ImageEditor - - waitsFor -> - imageEditor1.view.loaded and imageEditor2.view.loaded - - runs -> - expect(imageEditor1.view.originalWidth).toBe 10 - expect(imageEditor1.view.originalHeight).toBe 10 - expect(imageEditor2.view.originalWidth).toBe 10 - expect(imageEditor2.view.originalHeight).toBe 10 diff --git a/pkg/nuclide-image-view/lib/ImageEditor.js b/pkg/nuclide-image-view/lib/ImageEditor.js index baab3340b1..20252c8394 100644 --- a/pkg/nuclide-image-view/lib/ImageEditor.js +++ b/pkg/nuclide-image-view/lib/ImageEditor.js @@ -1,3 +1,45 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _ImageEditorView; + +function _load_ImageEditorView() { + return _ImageEditorView = _interopRequireDefault(require('./ImageEditorView')); +} + +var _LocalFileCopy; + +function _load_LocalFileCopy() { + return _LocalFileCopy = _interopRequireDefault(require('./LocalFileCopy')); +} + +var _atom = require('atom'); + +var _event; + +function _load_event() { + return _event = require('../../../modules/nuclide-commons/event'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,44 +47,27 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import ImageEditorView from './ImageEditorView'; -import LocalFileCopy from './LocalFileCopy'; -import {File} from 'atom'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {ReplaySubject, Subject} from 'rxjs'; - -export default class ImageEditor { - _disposed: ReplaySubject = new ReplaySubject(1); - _didTerminatePendingState: Subject = new Subject(); - file: File | LocalFileCopy; - _view: ?ImageEditorView; - - constructor(filePath: string) { - this.file = nuclideUri.isRemote(filePath) - ? new LocalFileCopy(filePath) - : new File(filePath); - observableFromSubscribeFunction(cb => this.file.onDidDelete(cb)) - .takeUntil(this._disposed) - .subscribe(() => { - const pane = atom.workspace.paneForURI(filePath); - try { - pane.destroyItem(pane.itemForURI(filePath)); - } catch (e) { - // eslint-disable-next-line no-console - console.warn( - `Could not destroy pane after external file was deleted: ${e}`, - ); - } - this.destroy(); - }); +class ImageEditor { + + constructor(filePath) { + this._disposed = new _rxjsBundlesRxMinJs.ReplaySubject(1); + this._didTerminatePendingState = new _rxjsBundlesRxMinJs.Subject(); + + this.file = (_nuclideUri || _load_nuclideUri()).default.isRemote(filePath) ? new (_LocalFileCopy || _load_LocalFileCopy()).default(filePath) : new _atom.File(filePath); + (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => this.file.onDidDelete(cb)).takeUntil(this._disposed).subscribe(() => { + const pane = atom.workspace.paneForURI(filePath); + try { + pane.destroyItem(pane.itemForURI(filePath)); + } catch (e) { + // eslint-disable-next-line no-console + console.warn(`Could not destroy pane after external file was deleted: ${e}`); + } + this.destroy(); + }); } isModified() { @@ -55,131 +80,106 @@ export default class ImageEditor { getElement() { if (this._view == null) { - this._view = new ImageEditorView(this); + this._view = new (_ImageEditorView || _load_ImageEditorView()).default(this); } return this._view.getElement(); } serialize() { // We use the same name as Atom's deserializer since we're replacing it. - return {filePath: this.getPath(), deserializer: 'ImageEditor'}; + return { filePath: this.getPath(), deserializer: 'ImageEditor' }; } terminatePendingState() { - if ( - this.isEqual( - atom.workspace - .getCenter() - .getActivePane() - .getPendingItem(), - ) - ) { + if (this.isEqual(atom.workspace.getCenter().getActivePane().getPendingItem())) { this._didTerminatePendingState.next(); } } - whenReady(callback: () => mixed): IDisposable { - if (this.file instanceof LocalFileCopy) { + whenReady(callback) { + if (this.file instanceof (_LocalFileCopy || _load_LocalFileCopy()).default) { return this.file.whenReady(callback); } callback(); - return new UniversalDisposable(); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - onDidTerminatePendingState(callback: () => mixed): IDisposable { - return new UniversalDisposable( - this._didTerminatePendingState.takeUntil(this._disposed).subscribe(() => { - callback(); - }), - ); + onDidTerminatePendingState(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(this._didTerminatePendingState.takeUntil(this._disposed).subscribe(() => { + callback(); + })); } // Register a callback for when the image file changes - onDidChange(callback: () => void): IDisposable { - return new UniversalDisposable( - observableFromSubscribeFunction(cb => this.file.onDidChange(cb)) - .takeUntil(this._disposed) - .subscribe(() => { - callback(); - }), - ); + onDidChange(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default((0, (_event || _load_event()).observableFromSubscribeFunction)(cb => this.file.onDidChange(cb)).takeUntil(this._disposed).subscribe(() => { + callback(); + })); } // Register a callback for whne the image's title changes - onDidChangeTitle(callback: (title: string) => mixed): IDisposable { - return new UniversalDisposable( - observableFromSubscribeFunction(cb => this.file.onDidRename(cb)) - .takeUntil(this._disposed) - .map(() => this.getTitle()) - .subscribe(title => { - callback(title); - }), - ); - } - - destroy(): void { + onDidChangeTitle(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default((0, (_event || _load_event()).observableFromSubscribeFunction)(cb => this.file.onDidRename(cb)).takeUntil(this._disposed).map(() => this.getTitle()).subscribe(title => { + callback(title); + })); + } + + destroy() { this._disposed.next(); if (this._view != null) { this._view.destroy(); } } - getAllowedLocations(): Array { + getAllowedLocations() { return ['center']; } // Retrieves the filename of the open file. // // This is `'untitled'` if the file is new and not saved to the disk. - getTitle(): string { + getTitle() { const filePath = this.getPath(); if (filePath) { - return nuclideUri.basename(filePath); + return (_nuclideUri || _load_nuclideUri()).default.basename(filePath); } else { return 'untitled'; } } // Retrieves the absolute path to the image. - getPath(): string { + getPath() { return this.file.getPath(); } - getLocalPath(): ?string { - return typeof this.file.getLocalPath === 'function' - ? this.file.getLocalPath() - : this.file.getPath(); + getLocalPath() { + return typeof this.file.getLocalPath === 'function' ? this.file.getLocalPath() : this.file.getPath(); } // Retrieves the URI of the image. - getURI(): NuclideUri { + getURI() { return this.getPath(); } // Retrieves the encoded URI of the image. - getEncodedURI(): ?string { + getEncodedURI() { // IMPORTANT: This shouldn't be called before `whenReady()`! If it is, you could get `null`. const path = this.getLocalPath(); - return path == null - ? null - : `file://${encodeURI(path.replace(/\\/g, '/')) - .replace(/#/g, '%23') - .replace(/\?/g, '%3F')}`; + return path == null ? null : `file://${encodeURI(path.replace(/\\/g, '/')).replace(/#/g, '%23').replace(/\?/g, '%3F')}`; } // Compares two {ImageEditor}s to determine equality. // // Equality is based on the condition that the two URIs are the same. - isEqual(other: any): boolean { + isEqual(other) { return other instanceof ImageEditor && this.getURI() === other.getURI(); } // Essential: Invoke the given callback when the editor is destroyed. - onDidDestroy(callback: () => mixed): IDisposable { - return new UniversalDisposable( - this._disposed.subscribe(() => { - callback(); - }), - ); + onDidDestroy(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(this._disposed.subscribe(() => { + callback(); + })); } } +exports.default = ImageEditor; \ No newline at end of file diff --git a/pkg/nuclide-image-view/lib/ImageEditorView.js b/pkg/nuclide-image-view/lib/ImageEditorView.js index 47b2cc0542..fdb652dd6a 100644 --- a/pkg/nuclide-image-view/lib/ImageEditorView.js +++ b/pkg/nuclide-image-view/lib/ImageEditorView.js @@ -1,57 +1,56 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _UniversalDisposable; -import type ImageEditor from './ImageEditor'; +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _imageEditorView; + +function _load_imageEditorView() { + return _imageEditorView = _interopRequireDefault(require('../VendorLib/image-view/lib/image-editor-view')); +} -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import AtomImageEditorView from '../VendorLib/image-view/lib/image-editor-view'; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * This view wraps the vendored one. This is necessary because the Atom ImageEditorView performs * a stat on the file so we neeed to make sure that the (local) file exists. */ -export default class ImageEditorView { - _disposables: UniversalDisposable; - _realView: ?AtomImageEditorView; - element: HTMLElement; +class ImageEditorView { - constructor(editor: ImageEditor) { + constructor(editor) { this.element = document.createElement('div'); this.element.className = 'nuclide-image-view-wrapper'; - this._disposables = new UniversalDisposable( - // We need to defer loading the real view until the local file is ready because it assumes it - // exists. - editor.whenReady(() => { - // AtomImageEditorView tries to do a stat using the result of `getPath()` so we give it a - // proxy that always returns the local path instead of the real editor. (We don't want to - // change the editor's `getPath()` because other things use that for display purposes and we - // want to show the remote path.) - const proxy = new Proxy(editor, { - get(obj, prop) { - if (prop === 'getPath') { - return editor.getLocalPath; - } - // $FlowIgnore - return obj[prop]; - }, - }); - this._realView = new AtomImageEditorView(proxy); - this.element.appendChild(this._realView.element); - }), - () => { - if (this._realView != null) { - this._realView.destroy(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default( + // We need to defer loading the real view until the local file is ready because it assumes it + // exists. + editor.whenReady(() => { + // AtomImageEditorView tries to do a stat using the result of `getPath()` so we give it a + // proxy that always returns the local path instead of the real editor. (We don't want to + // change the editor's `getPath()` because other things use that for display purposes and we + // want to show the remote path.) + const proxy = new Proxy(editor, { + get(obj, prop) { + if (prop === 'getPath') { + return editor.getLocalPath; + } + // $FlowIgnore + return obj[prop]; } - }, - ); + }); + this._realView = new (_imageEditorView || _load_imageEditorView()).default(proxy); + this.element.appendChild(this._realView.element); + }), () => { + if (this._realView != null) { + this._realView.destroy(); + } + }); } getElement() { @@ -62,3 +61,13 @@ export default class ImageEditorView { this._disposables.dispose(); } } +exports.default = ImageEditorView; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-image-view/lib/LocalFileCopy.js b/pkg/nuclide-image-view/lib/LocalFileCopy.js index a8a976bdb4..a6bb3141b2 100644 --- a/pkg/nuclide-image-view/lib/LocalFileCopy.js +++ b/pkg/nuclide-image-view/lib/LocalFileCopy.js @@ -1,82 +1,111 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _atom = require('atom'); + +var _crypto = _interopRequireDefault(require('crypto')); + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _projects; + +function _load_projects() { + return _projects = require('../../../modules/nuclide-commons-atom/projects'); +} + +var _event; + +function _load_event() { + return _event = require('../../../modules/nuclide-commons/event'); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _stream; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import {File} from 'atom'; -import crypto from 'crypto'; -import {getLogger} from 'log4js'; -import {getFileForPath} from 'nuclide-commons-atom/projects'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {writeToStream} from 'nuclide-commons/stream'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import nullthrows from 'nullthrows'; -import os from 'os'; -import {BehaviorSubject, Observable, ReplaySubject} from 'rxjs'; -import temp from 'temp'; -import {getFileSystemServiceByNuclideUri} from '../../nuclide-remote-connection'; +function _load_stream() { + return _stream = require('../../../modules/nuclide-commons/stream'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _os = _interopRequireDefault(require('os')); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _temp; + +function _load_temp() { + return _temp = _interopRequireDefault(require('temp')); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A file-like object that represents a local copy of a remote file. */ -export default class LocalFileCopy { - _initialFilePath: NuclideUri; - _remoteFile: BehaviorSubject = new BehaviorSubject(); - _tmpFile: BehaviorSubject = new BehaviorSubject(); - _disposed: ReplaySubject = new ReplaySubject(1); +class LocalFileCopy { + + constructor(filePath) { + this._remoteFile = new _rxjsBundlesRxMinJs.BehaviorSubject(); + this._tmpFile = new _rxjsBundlesRxMinJs.BehaviorSubject(); + this._disposed = new _rxjsBundlesRxMinJs.ReplaySubject(1); - constructor(filePath: NuclideUri) { this._initialFilePath = filePath; - getRemoteFile(filePath) - .takeUntil(this._disposed) - .subscribe(remoteFile => { - this._remoteFile.next(remoteFile); - }); - ((this._remoteFile.filter(Boolean): any): Observable) - .switchMap(file => - observableFromSubscribeFunction(cb => file.onDidChange(cb)) - .startWith(null) - .switchMap(path => copyToLocalTempFile(file.getPath())) - .catch(err => { - // TODO: Improve error handling by updating view instead of resorting to notifications. - atom.notifications.addError( - 'There was an error loading the image. Please close the tab and try again.', - {dismissable: true}, - ); - getLogger('nuclide-image-view').error(err); - return Observable.empty(); - }), - ) - .takeUntil(this._disposed) - .subscribe(tmpFile => { - this._tmpFile.next(tmpFile); - }); + getRemoteFile(filePath).takeUntil(this._disposed).subscribe(remoteFile => { + this._remoteFile.next(remoteFile); + }); + this._remoteFile.filter(Boolean).switchMap(file => (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => file.onDidChange(cb)).startWith(null).switchMap(path => copyToLocalTempFile(file.getPath())).catch(err => { + // TODO: Improve error handling by updating view instead of resorting to notifications. + atom.notifications.addError('There was an error loading the image. Please close the tab and try again.', { dismissable: true }); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-image-view').error(err); + return _rxjsBundlesRxMinJs.Observable.empty(); + })).takeUntil(this._disposed).subscribe(tmpFile => { + this._tmpFile.next(tmpFile); + }); } - dispose(): void { + dispose() { this._disposed.next(); } - whenReady(callback: () => mixed): IDisposable { - return new UniversalDisposable( - this._tmpFile - .filter(Boolean) - .take(1) - .takeUntil(this._disposed) - .subscribe(() => { - callback(); - }), - ); + whenReady(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(this._tmpFile.filter(Boolean).take(1).takeUntil(this._disposed).subscribe(() => { + callback(); + })); } getPath() { @@ -89,112 +118,77 @@ export default class LocalFileCopy { return tmpFile == null ? null : tmpFile.getPath(); } - onDidChange(callback: () => mixed): IDisposable { - return new UniversalDisposable( - this._tmpFile.takeUntil(this._disposed).subscribe(() => { - callback(); - }), - ); + onDidChange(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(this._tmpFile.takeUntil(this._disposed).subscribe(() => { + callback(); + })); } - onDidRename(callback: () => mixed): IDisposable { - return new UniversalDisposable( - this._remoteFile - .filter(Boolean) - .switchMap(remoteFile => - observableFromSubscribeFunction(cb => - nullthrows(remoteFile).onDidRename(cb), - ), - ) - .takeUntil(this._disposed) - .subscribe(() => { - callback(); - }), - ); + onDidRename(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(this._remoteFile.filter(Boolean).switchMap(remoteFile => (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => (0, (_nullthrows || _load_nullthrows()).default)(remoteFile).onDidRename(cb))).takeUntil(this._disposed).subscribe(() => { + callback(); + })); } - onDidDelete(callback: () => mixed): IDisposable { - return new UniversalDisposable( - this._remoteFile - .filter(Boolean) - .switchMap(remoteFile => - observableFromSubscribeFunction(cb => - nullthrows(remoteFile).onDidDelete(cb), - ), - ) - .takeUntil(this._disposed) - .subscribe(() => { - callback(); - }), - ); + onDidDelete(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(this._remoteFile.filter(Boolean).switchMap(remoteFile => (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => (0, (_nullthrows || _load_nullthrows()).default)(remoteFile).onDidDelete(cb))).takeUntil(this._disposed).subscribe(() => { + callback(); + })); } } -function copyToLocalTempFile(remotePath: string): Observable { - return Observable.defer(async () => { - const fsService = getFileSystemServiceByNuclideUri(remotePath); - const {mtime} = await fsService.stat(remotePath); - return {fsService, mtime}; - }).switchMap(({fsService, mtime}) => { - const cacheDir = nuclideUri.join(os.tmpdir(), 'nuclide-remote-images'); +exports.default = LocalFileCopy; /** + * 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. + * + * + * @format + */ + +function copyToLocalTempFile(remotePath) { + return _rxjsBundlesRxMinJs.Observable.defer(async () => { + const fsService = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getFileSystemServiceByNuclideUri)(remotePath); + const { mtime } = await fsService.stat(remotePath); + return { fsService, mtime }; + }).switchMap(({ fsService, mtime }) => { + const cacheDir = (_nuclideUri || _load_nuclideUri()).default.join(_os.default.tmpdir(), 'nuclide-remote-images'); // Create a unique filename based on the path and mtime. We use a hash so we don't run into // filename length restrictions. - const hash = crypto - .createHash('md5') - .update(remotePath) - .digest('hex') - .slice(0, 7); - const extname = nuclideUri.extname(remotePath); - const basename = nuclideUri.basename(remotePath); + const hash = _crypto.default.createHash('md5').update(remotePath).digest('hex').slice(0, 7); + const extname = (_nuclideUri || _load_nuclideUri()).default.extname(remotePath); + const basename = (_nuclideUri || _load_nuclideUri()).default.basename(remotePath); const name = basename.slice(0, basename.length - extname.length); - const tmpFilePath = nuclideUri.join( - cacheDir, - `${name}-${hash}-${mtime.getTime()}${extname}`, - ); - return Observable.fromPromise(fsPromise.exists(tmpFilePath)).switchMap( - exists => { - if (exists) { - return Observable.of(new File(tmpFilePath)); - } - return fsService - .createReadStream(remotePath) - .refCount() - .let(writeToTempFile(tmpFilePath)); - }, - ); + const tmpFilePath = (_nuclideUri || _load_nuclideUri()).default.join(cacheDir, `${name}-${hash}-${mtime.getTime()}${extname}`); + return _rxjsBundlesRxMinJs.Observable.fromPromise((_fsPromise || _load_fsPromise()).default.exists(tmpFilePath)).switchMap(exists => { + if (exists) { + return _rxjsBundlesRxMinJs.Observable.of(new _atom.File(tmpFilePath)); + } + return fsService.createReadStream(remotePath).refCount().let(writeToTempFile(tmpFilePath)); + }); }); } -const writeToTempFile = (targetPath: string) => ( - source: Observable, -): Observable => { - return Observable.defer(() => { - const writeStream = temp.createWriteStream(); - return writeToStream(source, writeStream) - .ignoreElements() - .concat( - Observable.defer(async () => { - // Move the file to the final destination. - await fsPromise.mkdirp(nuclideUri.dirname(targetPath)); - await fsPromise.mv(writeStream.path, targetPath); - return new File(targetPath); - }), - ); +const writeToTempFile = targetPath => source => { + return _rxjsBundlesRxMinJs.Observable.defer(() => { + const writeStream = (_temp || _load_temp()).default.createWriteStream(); + return (0, (_stream || _load_stream()).writeToStream)(source, writeStream).ignoreElements().concat(_rxjsBundlesRxMinJs.Observable.defer(async () => { + // Move the file to the final destination. + await (_fsPromise || _load_fsPromise()).default.mkdirp((_nuclideUri || _load_nuclideUri()).default.dirname(targetPath)); + await (_fsPromise || _load_fsPromise()).default.mv(writeStream.path, targetPath); + return new _atom.File(targetPath); + })); }); }; // We have to wait for so much. -function getRemoteFile(path: string): Observable { - return observableFromSubscribeFunction(cb => - atom.packages.serviceHub.consume('nuclide-remote-projects', '0.0.0', cb), - ) - .switchMap(service => { - if (service == null) { - return Observable.of(null); - } - return observableFromSubscribeFunction(cb => - service.waitForRemoteProjectReload(cb), - ).map(() => getFileForPath(path)); - }) - .take(1); -} +function getRemoteFile(path) { + return (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => atom.packages.serviceHub.consume('nuclide-remote-projects', '0.0.0', cb)).switchMap(service => { + if (service == null) { + return _rxjsBundlesRxMinJs.Observable.of(null); + } + return (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => service.waitForRemoteProjectReload(cb)).map(() => (0, (_projects || _load_projects()).getFileForPath)(path)); + }).take(1); +} \ No newline at end of file diff --git a/pkg/nuclide-image-view/lib/main.js b/pkg/nuclide-image-view/lib/main.js index 2cf8372938..3708fd1141 100644 --- a/pkg/nuclide-image-view/lib/main.js +++ b/pkg/nuclide-image-view/lib/main.js @@ -1,44 +1,71 @@ -/** - * 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 - */ - -import disablePackage, { - DisabledReason, -} from '../../commons-atom/disablePackage'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import ImageEditor from './ImageEditor'; +'use strict'; + +var _disablePackage; + +function _load_disablePackage() { + return _disablePackage = _interopRequireDefault(require('../../commons-atom/disablePackage')); +} + +var _disablePackage2; + +function _load_disablePackage2() { + return _disablePackage2 = require('../../commons-atom/disablePackage'); +} + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _ImageEditor; + +function _load_ImageEditor() { + return _ImageEditor = _interopRequireDefault(require('./ImageEditor')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class Activation { - _disposables: IDisposable; - - constructor(state: ?mixed) { - this._disposables = new UniversalDisposable( - atom.workspace.addOpener(openUri), - // If you enable this package, we need to disable image-view. - disablePackage('image-view', {reason: DisabledReason.REIMPLEMENTED}), - ); + + constructor(state) { + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(atom.workspace.addOpener(openUri), + // If you enable this package, we need to disable image-view. + (0, (_disablePackage || _load_disablePackage()).default)('image-view', { reason: (_disablePackage2 || _load_disablePackage2()).DisabledReason.REIMPLEMENTED })); } - deserializeImageEditor(state): ImageEditor { - return new ImageEditor(state.filePath); + deserializeImageEditor(state) { + return new (_ImageEditor || _load_ImageEditor()).default(state.filePath); } - dispose(): void { + dispose() { this._disposables.dispose(); } -} +} /** + * 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. + * + * + * @format + */ -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); -function openUri(uri: string): ?ImageEditor { - return nuclideUri.looksLikeImageUri(uri) ? new ImageEditor(uri) : null; -} +function openUri(uri) { + return (_nuclideUri || _load_nuclideUri()).default.looksLikeImageUri(uri) ? new (_ImageEditor || _load_ImageEditor()).default(uri) : null; +} \ No newline at end of file diff --git a/pkg/nuclide-infer-al/lib/main.js b/pkg/nuclide-infer-al/lib/main.js index dff6ca472c..ac44ef5c90 100644 --- a/pkg/nuclide-infer-al/lib/main.js +++ b/pkg/nuclide-infer-al/lib/main.js @@ -1,3 +1,43 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.provideLint = provideLint; + +var _atom = require('atom'); + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const requests = new _rxjsBundlesRxMinJs.Subject(); + +// Check for a new version every 10 minutes. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,137 +45,92 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {LinterMessage, LinterProvider} from 'atom-ide-ui'; - -import {Range} from 'atom'; -import {getLogger} from 'log4js'; -import {Observable, Subject} from 'rxjs'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {runCommand, runCommandDetailed} from 'nuclide-commons/process'; -import featureConfig from 'nuclide-commons-atom/feature-config'; - -const requests: Subject = new Subject(); - -// Check for a new version every 10 minutes. const DOWNLOAD_INTERVAL = 10 * 60 * 1000; // Display a "fetching" notification if it hasn't completed within 5s. const DOWNLOAD_NOTIFICATION_DELAY = 5 * 1000; -let cachedVersionCheck: ?Observable = null; +let cachedVersionCheck = null; let versionCheckTime = 0; -function getInferCommand(): string { - return String(featureConfig.get('nuclide-infer-al.pathToInfer')); +function getInferCommand() { + return String((_featureConfig || _load_featureConfig()).default.get('nuclide-infer-al.pathToInfer')); } -function checkVersion(cwd: string): Observable { - if ( - cachedVersionCheck == null || - Date.now() - versionCheckTime > DOWNLOAD_INTERVAL - ) { +function checkVersion(cwd) { + if (cachedVersionCheck == null || Date.now() - versionCheckTime > DOWNLOAD_INTERVAL) { versionCheckTime = Date.now(); - cachedVersionCheck = runCommand(getInferCommand(), ['--version'], { - cwd, + cachedVersionCheck = (0, (_process || _load_process()).runCommand)(getInferCommand(), ['--version'], { + cwd }) - // Return true as long as there's no error. - .mapTo(true) - .catch(err => { - getLogger('nuclide-infer-al').error( - 'Error running infer --version:', - err, - ); - atom.notifications.addError('Error running Infer', { - description: String(err), - dismissable: true, - }); - return Observable.of(false); - }) - .race( - // By using 'race', this won't show up if the version comes back first. - Observable.timer(DOWNLOAD_NOTIFICATION_DELAY) - .do(() => { - atom.notifications.addInfo('Fetching Infer...', { - description: - 'Fetching the latest version of Infer. This may take quite some time initially...', - dismissable: true, - }); - }) - .concat(Observable.never()) - .ignoreElements(), - ) - // Share this and make it replayable. - .publishReplay(1) - .refCount(); + // Return true as long as there's no error. + .mapTo(true).catch(err => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-infer-al').error('Error running infer --version:', err); + atom.notifications.addError('Error running Infer', { + description: String(err), + dismissable: true + }); + return _rxjsBundlesRxMinJs.Observable.of(false); + }).race( + // By using 'race', this won't show up if the version comes back first. + _rxjsBundlesRxMinJs.Observable.timer(DOWNLOAD_NOTIFICATION_DELAY).do(() => { + atom.notifications.addInfo('Fetching Infer...', { + description: 'Fetching the latest version of Infer. This may take quite some time initially...', + dismissable: true + }); + }).concat(_rxjsBundlesRxMinJs.Observable.never()).ignoreElements()) + // Share this and make it replayable. + .publishReplay(1).refCount(); return cachedVersionCheck; } return cachedVersionCheck; } -export function provideLint(): LinterProvider { +function provideLint() { return { name: 'nuclide-infer-al', grammarScopes: ['source.infer.al'], scope: 'file', lintOnFly: false, - lint(editor: atom$TextEditor): Promise> { + lint(editor) { const src = editor.getPath(); - if (src == null || nuclideUri.isRemote(src)) { + if (src == null || (_nuclideUri || _load_nuclideUri()).default.isRemote(src)) { return Promise.resolve([]); } - const cwd = nuclideUri.dirname(src); + const cwd = (_nuclideUri || _load_nuclideUri()).default.dirname(src); requests.next(); - return checkVersion(cwd) - .take(1) - .switchMap(success => { - if (!success) { - return Observable.of(null); + return checkVersion(cwd).take(1).switchMap(success => { + if (!success) { + return _rxjsBundlesRxMinJs.Observable.of(null); + } + return (0, (_process || _load_process()).runCommandDetailed)(getInferCommand(), ['--linters-def-file', src, '--no-default-linters', '--linters-validate-syntax-only'], { isExitError: () => false, cwd }).map(result => { + if (result.exitCode === 0) { + return []; + } else { + const json = JSON.parse(result.stdout); + return json.map(e => ({ + name: 'Error', + type: 'Error', + html: '
    ' + e.description + '
    ', + filePath: e.filename, + range: new _atom.Range([e.line - 1, 0], [e.line, 0]) + })); } - return ( - runCommandDetailed( - getInferCommand(), - [ - '--linters-def-file', - src, - '--no-default-linters', - '--linters-validate-syntax-only', - ], - {isExitError: () => false, cwd}, - ) - .map(result => { - if (result.exitCode === 0) { - return []; - } else { - const json = JSON.parse(result.stdout); - return json.map(e => ({ - name: 'Error', - type: 'Error', - html: '
    ' + e.description + '
    ', - filePath: e.filename, - range: new Range([e.line - 1, 0], [e.line, 0]), - })); - } - }) - .catch(err => { - getLogger('nuclide-infer-al').error( - 'Error running Infer command: ', - err, - ); - atom.notifications.addError('Error running Infer', { - description: String(err), - dismissable: true, - }); - return Observable.of(null); - }) - // Stop if we get a new request in the meantime. - .takeUntil(requests) - ); + }).catch(err => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-infer-al').error('Error running Infer command: ', err); + atom.notifications.addError('Error running Infer', { + description: String(err), + dismissable: true + }); + return _rxjsBundlesRxMinJs.Observable.of(null); }) - .toPromise(); - }, + // Stop if we get a new request in the meantime. + .takeUntil(requests); + }).toPromise(); + } }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-ios-simulator-logs/lib/Activation.js b/pkg/nuclide-ios-simulator-logs/lib/Activation.js index 38b497cd87..05c872c5f8 100644 --- a/pkg/nuclide-ios-simulator-logs/lib/Activation.js +++ b/pkg/nuclide-ios-simulator-logs/lib/Activation.js @@ -1,39 +1,55 @@ -/** - * 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 - */ - -import type {OutputService} from 'atom-ide-ui'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import formatEnoentNotification from '../../commons-atom/format-enoent-notification'; -import {LogTailer} from '../../nuclide-console-base/lib/LogTailer'; -import {createMessageStream} from './createMessageStream'; -import {createProcessStream} from './createProcessStream'; -import {Observable} from 'rxjs'; - -export default class Activation { - _disposables: UniversalDisposable; - _iosLogTailer: LogTailer; - - constructor(state: ?Object) { - this._iosLogTailer = new LogTailer({ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _formatEnoentNotification; + +function _load_formatEnoentNotification() { + return _formatEnoentNotification = _interopRequireDefault(require('../../commons-atom/format-enoent-notification')); +} + +var _LogTailer; + +function _load_LogTailer() { + return _LogTailer = require('../../nuclide-console-base/lib/LogTailer'); +} + +var _createMessageStream; + +function _load_createMessageStream() { + return _createMessageStream = require('./createMessageStream'); +} + +var _createProcessStream; + +function _load_createProcessStream() { + return _createProcessStream = require('./createProcessStream'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Activation { + + constructor(state) { + this._iosLogTailer = new (_LogTailer || _load_LogTailer()).LogTailer({ name: 'iOS Simulator Logs', - messages: Observable.defer(() => - createMessageStream(createProcessStream()), - ), + messages: _rxjsBundlesRxMinJs.Observable.defer(() => (0, (_createMessageStream || _load_createMessageStream()).createMessageStream)((0, (_createProcessStream || _load_createProcessStream()).createProcessStream)())), handleError(err) { - if ((err: any).code === 'ENOENT') { - const {message, meta} = formatEnoentNotification({ + if (err.code === 'ENOENT') { + const { message, meta } = (0, (_formatEnoentNotification || _load_formatEnoentNotification()).default)({ feature: 'iOS Syslog tailing', toolName: 'syslog', - pathSetting: 'nuclide-ios-simulator-logs.pathToSyslog', + pathSetting: 'nuclide-ios-simulator-logs.pathToSyslog' }); atom.notifications.addError(message, meta); return; @@ -43,40 +59,44 @@ export default class Activation { trackingEvents: { start: 'ios-simulator-logs:start', stop: 'ios-simulator-logs:stop', - restart: 'ios-simulator-logs:restart', - }, + restart: 'ios-simulator-logs:restart' + } }); - this._disposables = new UniversalDisposable( - () => { - this._iosLogTailer.stop(); - }, - atom.commands.add('atom-workspace', { - 'nuclide-ios-simulator-logs:start': () => this._iosLogTailer.start(), - 'nuclide-ios-simulator-logs:stop': () => this._iosLogTailer.stop(), - 'nuclide-ios-simulator-logs:restart': () => - this._iosLogTailer.restart(), - }), - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { + this._iosLogTailer.stop(); + }, atom.commands.add('atom-workspace', { + 'nuclide-ios-simulator-logs:start': () => this._iosLogTailer.start(), + 'nuclide-ios-simulator-logs:stop': () => this._iosLogTailer.stop(), + 'nuclide-ios-simulator-logs:restart': () => this._iosLogTailer.restart() + })); } - consumeOutputService(api: OutputService): void { - this._disposables.add( - api.registerOutputProvider({ - id: 'iOS Simulator Logs', - messages: this._iosLogTailer.getMessages(), - observeStatus: cb => this._iosLogTailer.observeStatus(cb), - start: () => { - this._iosLogTailer.start(); - }, - stop: () => { - this._iosLogTailer.stop(); - }, - }), - ); + consumeOutputService(api) { + this._disposables.add(api.registerOutputProvider({ + id: 'iOS Simulator Logs', + messages: this._iosLogTailer.getMessages(), + observeStatus: cb => this._iosLogTailer.observeStatus(cb), + start: () => { + this._iosLogTailer.start(); + }, + stop: () => { + this._iosLogTailer.stop(); + } + })); } dispose() { this._disposables.dispose(); } } +exports.default = Activation; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-ios-simulator-logs/lib/createMessage.js b/pkg/nuclide-ios-simulator-logs/lib/createMessage.js index 44b463fdb5..b1d74b8d5d 100644 --- a/pkg/nuclide-ios-simulator-logs/lib/createMessage.js +++ b/pkg/nuclide-ios-simulator-logs/lib/createMessage.js @@ -1,51 +1,62 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.createMessage = createMessage; -import type {ConsoleLevel, ConsoleMessage} from 'atom-ide-ui'; -import type {AslLevel, AslRecord} from './types'; +var _parseMessageText; -import {parseMessageText} from './parseMessageText'; +function _load_parseMessageText() { + return _parseMessageText = require('./parseMessageText'); +} /** * Convert a structured logcat entry into the format that nuclide-console wants. */ -export function createMessage(record: AslRecord): ConsoleMessage { - const {text, level, tags} = parseMessageText(record.Message); +function createMessage(record) { + const { text, level, tags } = (0, (_parseMessageText || _load_parseMessageText()).parseMessageText)(record.Message); if (record.Facility) { tags.push(record.Facility); } return { text, level: level == null ? getLevel(record.Level) : level, - tags: tags.length === 0 ? undefined : tags, + tags: tags.length === 0 ? undefined : tags }; -} +} /** + * 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. + * + * strict-local + * @format + */ -function getLevel(level: AslLevel): ConsoleLevel { +function getLevel(level) { switch (level) { case '0': // Emergency case '1': // Alert case '2': // Critical - case '3': // Error + case '3': + // Error return 'error'; - case '4': // Warning + case '4': + // Warning return 'warning'; - case '5': // Notice + case '5': + // Notice return 'log'; - case '6': // Info + case '6': + // Info return 'info'; - case '7': // Debug + case '7': + // Debug return 'debug'; default: - (level: empty); + level; throw new Error(`Invalid ASL level: ${level}`); } -} +} \ No newline at end of file diff --git a/pkg/nuclide-ios-simulator-logs/lib/createMessageStream.js b/pkg/nuclide-ios-simulator-logs/lib/createMessageStream.js index b8aebf8fcb..e4cf8f5654 100644 --- a/pkg/nuclide-ios-simulator-logs/lib/createMessageStream.js +++ b/pkg/nuclide-ios-simulator-logs/lib/createMessageStream.js @@ -1,3 +1,38 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.createMessageStream = createMessageStream; + +var _observable; + +function _load_observable() { + return _observable = require('../../../modules/nuclide-commons/observable'); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _createMessage; + +function _load_createMessage() { + return _createMessage = require('./createMessage'); +} + +var _plist; + +function _load_plist() { + return _plist = _interopRequireDefault(require('plist')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,71 +40,48 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {ConsoleMessage} from 'atom-ide-ui'; - -import {bufferUntil} from 'nuclide-commons/observable'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {createMessage} from './createMessage'; -import plist from 'plist'; -import {Observable} from 'rxjs'; - -export function createMessageStream( - line$: Observable, -): Observable { +function createMessageStream(line$) { // Group the lines into valid plist strings. - const messages = line$ - .let(bufferUntil(line => line.trim() === '')) - // Don't include empty buffers. This happens if the stream completes since we opened a new - // buffer when the previous record ended. - .filter(lines => lines.length > 1) - .map(lines => lines.join('')) - // Parse the plists. Each parsed plist contains an array which, in turn, *may* contain dicts - // (that correspond to records). We just want those dicts so we use `flatMap()`. - .flatMap(xml => plist.parse(xml)) - // Exclude dicts that don't have any message property. - .filter(record => record.hasOwnProperty('Message')) - // Exclude blacklisted senders. - // FIXME: This is a stopgap. What we really need to do is identify the currently running app and - // only show its messages. ): - .filter(record => { - const blacklist = ((featureConfig.get( - 'nuclide-ios-simulator-logs.senderBlacklist', - ): any): Array); - return blacklist.indexOf(record.Sender) === -1; - }) - // Format the messages for Nuclide. - .map(createMessage); + const messages = line$.let((0, (_observable || _load_observable()).bufferUntil)(line => line.trim() === '')) + // Don't include empty buffers. This happens if the stream completes since we opened a new + // buffer when the previous record ended. + .filter(lines => lines.length > 1).map(lines => lines.join('')) + // Parse the plists. Each parsed plist contains an array which, in turn, *may* contain dicts + // (that correspond to records). We just want those dicts so we use `flatMap()`. + .flatMap(xml => (_plist || _load_plist()).default.parse(xml)) + // Exclude dicts that don't have any message property. + .filter(record => record.hasOwnProperty('Message')) + // Exclude blacklisted senders. + // FIXME: This is a stopgap. What we really need to do is identify the currently running app and + // only show its messages. ): + .filter(record => { + const blacklist = (_featureConfig || _load_featureConfig()).default.get('nuclide-ios-simulator-logs.senderBlacklist'); + return blacklist.indexOf(record.Sender) === -1; + }) + // Format the messages for Nuclide. + .map((_createMessage || _load_createMessage()).createMessage); return filter(messages); } -function filter( - messages: Observable, -): Observable { - const patterns = featureConfig - .observeAsStream('nuclide-ios-simulator-logs.whitelistedTags') - .map((source: any) => { - try { - return new RegExp(source); - } catch (err) { - atom.notifications.addError( - 'The nuclide-ios-simulator-logs.whitelistedTags setting contains an invalid regular' + - ' expression string. Fix it in your Atom settings.', - ); - return /.*/; - } - }); - - return messages - .withLatestFrom(patterns) - .filter(([message, pattern]) => { - // Add an empty tag to untagged messages so they cfeaturean be matched by `.*` etc. - const tags = message.tags == null ? [''] : message.tags; - return tags.some(tag => pattern.test(tag)); - }) - .map(([message, pattern]) => message); -} +function filter(messages) { + const patterns = (_featureConfig || _load_featureConfig()).default.observeAsStream('nuclide-ios-simulator-logs.whitelistedTags').map(source => { + try { + return new RegExp(source); + } catch (err) { + atom.notifications.addError('The nuclide-ios-simulator-logs.whitelistedTags setting contains an invalid regular' + ' expression string. Fix it in your Atom settings.'); + return (/.*/ + ); + } + }); + + return messages.withLatestFrom(patterns).filter(([message, pattern]) => { + // Add an empty tag to untagged messages so they cfeaturean be matched by `.*` etc. + const tags = message.tags == null ? [''] : message.tags; + return tags.some(tag => pattern.test(tag)); + }).map(([message, pattern]) => message); +} \ No newline at end of file diff --git a/pkg/nuclide-ios-simulator-logs/lib/createProcessStream.js b/pkg/nuclide-ios-simulator-logs/lib/createProcessStream.js index 6203753db8..56c863a5d5 100644 --- a/pkg/nuclide-ios-simulator-logs/lib/createProcessStream.js +++ b/pkg/nuclide-ios-simulator-logs/lib/createProcessStream.js @@ -1,76 +1,78 @@ -/** - * 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 - */ - -import {observeProcess} from 'nuclide-commons/process'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import invariant from 'assert'; -import os from 'os'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Observable} from 'rxjs'; - -const VALID_UDID = /^[a-f0-9-]+$/i; - -export function createProcessStream(): Observable { - const currentDeviceUdids = observeProcess( - 'bash', - ['-c', WATCH_CURRENT_UDID_SCRIPT], - {/* TODO(T17353599) */ isExitError: () => false}, - ) - .catch(error => Observable.of({kind: 'error', error})) // TODO(T17463635) +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.createProcessStream = createProcessStream; + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _os = _interopRequireDefault(require('os')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const VALID_UDID = /^[a-f0-9-]+$/i; /** + * 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. + * + * + * @format + */ + +function createProcessStream() { + const currentDeviceUdids = (0, (_process || _load_process()).observeProcess)('bash', ['-c', WATCH_CURRENT_UDID_SCRIPT], { /* TODO(T17353599) */isExitError: () => false }).catch(error => _rxjsBundlesRxMinJs.Observable.of({ kind: 'error', error })) // TODO(T17463635) + .map(event => { + if (event.kind === 'error') { + throw event.error; + } else if (event.kind === 'exit' && event.exitCode !== 0) { + throw new Error('Error getting active iOS Simulator'); + } + return event; + }).filter(event => event.kind === 'stdout').map(event => { + if (!(typeof event.data === 'string')) { + throw new Error('Invariant violation: "typeof event.data === \'string\'"'); + } + + return event.data; + }).map(output => output.trim()).filter(udid => VALID_UDID.test(udid)).distinctUntilChanged(); + + // Whenever the current device changes, start tailing that device's logs. + return currentDeviceUdids.switchMap(udid => { + const logDir = (_nuclideUri || _load_nuclideUri()).default.join(_os.default.homedir(), 'Library', 'Logs', 'CoreSimulator', udid, 'asl'); + return (0, (_process || _load_process()).observeProcess)((_featureConfig || _load_featureConfig()).default.get('nuclide-ios-simulator-logs.pathToSyslog'), ['-w', '-F', 'xml', '-d', logDir], { /* TODO(T17353599) */isExitError: () => false }).catch(error => _rxjsBundlesRxMinJs.Observable.of({ kind: 'error', error })) // TODO(T17463635) .map(event => { if (event.kind === 'error') { throw event.error; - } else if (event.kind === 'exit' && event.exitCode !== 0) { - throw new Error('Error getting active iOS Simulator'); } return event; - }) - .filter(event => event.kind === 'stdout') - .map(event => { - invariant(typeof event.data === 'string'); - return event.data; - }) - .map(output => output.trim()) - .filter(udid => VALID_UDID.test(udid)) - .distinctUntilChanged(); + }).filter(event => event.kind === 'stdout').map(event => { + if (!(typeof event.data === 'string')) { + throw new Error('Invariant violation: "typeof event.data === \'string\'"'); + } - // Whenever the current device changes, start tailing that device's logs. - return currentDeviceUdids.switchMap(udid => { - const logDir = nuclideUri.join( - os.homedir(), - 'Library', - 'Logs', - 'CoreSimulator', - udid, - 'asl', - ); - return observeProcess( - ((featureConfig.get( - 'nuclide-ios-simulator-logs.pathToSyslog', - ): any): string), - ['-w', '-F', 'xml', '-d', logDir], - {/* TODO(T17353599) */ isExitError: () => false}, - ) - .catch(error => Observable.of({kind: 'error', error})) // TODO(T17463635) - .map(event => { - if (event.kind === 'error') { - throw event.error; - } - return event; - }) - .filter(event => event.kind === 'stdout') - .map(event => { - invariant(typeof event.data === 'string'); - return event.data; - }); + return event.data; + }); }); } @@ -82,4 +84,4 @@ const WATCH_CURRENT_UDID_SCRIPT = ` defaults read com.apple.iphonesimulator CurrentDeviceUDID; sleep 2; done; -`; +`; \ No newline at end of file diff --git a/pkg/nuclide-ios-simulator-logs/lib/main.js b/pkg/nuclide-ios-simulator-logs/lib/main.js index 0c6bd6b8ce..4f6add8222 100644 --- a/pkg/nuclide-ios-simulator-logs/lib/main.js +++ b/pkg/nuclide-ios-simulator-logs/lib/main.js @@ -1,33 +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 - * @format - */ - -import type {OutputService} from 'atom-ide-ui'; - -import invariant from 'assert'; -import Activation from './Activation'; - -let activation: ?Object = null; - -export function activate(state: ?Object) { - invariant(activation == null); - activation = new Activation(state); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.activate = activate; +exports.deactivate = deactivate; +exports.consumeOutputService = consumeOutputService; + +var _Activation; + +function _load_Activation() { + return _Activation = _interopRequireDefault(require('./Activation')); } -export function deactivate() { - invariant(activation); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +let activation = null; /** + * 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. + * + * + * @format + */ + +function activate(state) { + if (!(activation == null)) { + throw new Error('Invariant violation: "activation == null"'); + } + + activation = new (_Activation || _load_Activation()).default(state); +} + +function deactivate() { + if (!activation) { + throw new Error('Invariant violation: "activation"'); + } + activation.dispose(); activation = null; } -export function consumeOutputService(api: OutputService): void { - invariant(activation); +function consumeOutputService(api) { + if (!activation) { + throw new Error('Invariant violation: "activation"'); + } + activation.consumeOutputService(api); -} +} \ No newline at end of file diff --git a/pkg/nuclide-ios-simulator-logs/lib/parseMessageText.js b/pkg/nuclide-ios-simulator-logs/lib/parseMessageText.js index 0df0b8aaaa..6ae71164ea 100644 --- a/pkg/nuclide-ios-simulator-logs/lib/parseMessageText.js +++ b/pkg/nuclide-ios-simulator-logs/lib/parseMessageText.js @@ -1,3 +1,9 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.parseMessageText = parseMessageText; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,32 +11,24 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {ConsoleLevel} from 'atom-ide-ui'; - -type Parsed = { - text: string, - level: ?ConsoleLevel, - tags: Array, -}; - const TAG_RE = /\[([^[\]]*)]/g; const TAG_PATTERN = '\\[[^\\[\\]]*\\]'; // The same as TAG_RE but without capturing, for embedding. const DATETIME_PATTERN = '\\d{4}-\\d{2}-\\d{2} \\d+:\\d+:\\d+\\.\\d+'; const PARTS_PATTERN = `${DATETIME_PATTERN}( (?:${TAG_PATTERN})+ ?)?([\\s\\S]*)`; const PARTS_RE = new RegExp(PARTS_PATTERN); -export function parseMessageText(raw: string): Parsed { +function parseMessageText(raw) { const messageMatch = raw.match(PARTS_RE); if (messageMatch == null) { return { text: raw, level: null, - tags: [], + tags: [] }; } @@ -38,7 +36,7 @@ export function parseMessageText(raw: string): Parsed { const tags = []; let level; let tagMatch; - while ((tagMatch = TAG_RE.exec(tagsPart))) { + while (tagMatch = TAG_RE.exec(tagsPart)) { const tag = tagMatch[1]; switch (tag) { case 'info': @@ -57,5 +55,5 @@ export function parseMessageText(raw: string): Parsed { } } - return {text, level, tags}; -} + return { text, level, tags }; +} \ No newline at end of file diff --git a/pkg/nuclide-ios-simulator-logs/lib/types.js b/pkg/nuclide-ios-simulator-logs/lib/types.js index faa90880ef..a726efc43f 100644 --- a/pkg/nuclide-ios-simulator-logs/lib/types.js +++ b/pkg/nuclide-ios-simulator-logs/lib/types.js @@ -1,29 +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 strict - * @format - */ - -export type AslLevel = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7'; - -export type AslRecord = { - ASLMessageID: string, - Time: string, - TimeNanoSec: string, - Level: AslLevel, - PID: string, - UID: string, - GID: string, - ReadGID: string, - Host: string, - Sender: string, - Facility: string, - Message: string, - ASLSHIM: string, - SenderMachUUID: string, -}; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-ios-simulator-logs/spec/createMessageStream-spec.js b/pkg/nuclide-ios-simulator-logs/spec/createMessageStream-spec.js deleted file mode 100644 index ec1cc3eb1d..0000000000 --- a/pkg/nuclide-ios-simulator-logs/spec/createMessageStream-spec.js +++ /dev/null @@ -1,144 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {createMessageStream} from '../lib/createMessageStream'; -import {Observable} from 'rxjs'; - -describe('createMessageStream', () => { - it('splits the output by record', () => { - const original = featureConfig.observeAsStream.bind(featureConfig); - spyOn(featureConfig, 'observeAsStream').andCallFake( - name => - name === 'nuclide-ios-simulator-logs.whitelistedTags' - ? Observable.of('.*') - : original(name), - ); - waitsForPromise(async () => { - const output = Observable.from(OUTPUT_LINES); - const messages = await createMessageStream(output) - .map(message => message.text) - .toArray() - .toPromise(); - expect(messages).toEqual(['Message 1', 'Message 2']); - }); - }); - - it('only includes messages with whitelisted tags', () => { - waitsForPromise(async () => { - const original = featureConfig.observeAsStream.bind(featureConfig); - spyOn(featureConfig, 'observeAsStream').andCallFake( - name => - name === 'nuclide-ios-simulator-logs.whitelistedTags' - ? Observable.of('X|ExampleTag') - : original(name), - ); - const output = Observable.from(OUTPUT_LINES); - const messages = await createMessageStream(output) - .map(message => message.text) - .toArray() - .toPromise(); - expect(messages).toEqual(['Message 2']); - }); - }); - - it('shows an error (once) if the regular expression is invalid', () => { - spyOn(atom.notifications, 'addError'); - const original = featureConfig.observeAsStream.bind(featureConfig); - spyOn(featureConfig, 'observeAsStream').andCallFake( - name => - name === 'nuclide-ios-simulator-logs.whitelistedTags' - ? Observable.of('(') - : original(name), - ); - - waitsForPromise(async () => { - const output = Observable.from(OUTPUT_LINES); - await createMessageStream(output).toPromise(); - expect(atom.notifications.addError.callCount).toBe(1); - }); - }); -}); - -const OUTPUT_LINES = [ - '', - '', - '', - '', - ' ', - ' ASLMessageID', - ' 54706', - ' Time', - ' Feb 17 12:52:17', - ' TimeNanoSec', - ' 469585000', - ' Level', - ' 2', - ' PID', - ' 38152', - ' UID', - ' 1507447745', - ' GID', - ' 1876110778', - ' ReadGID', - ' 80', - ' Host', - ' matthewwith-mbp', - ' Sender', - ' UIExplorer', - ' Facility', - ' user', - ' Message', - ' Message 1', - ' ASLSHIM', - ' 1', - ' SenderMachUUID', - ' 09F5C0C0-7587-39E8-A92E-7B130965D76C', - ' ', - '', - '', - '', - '', - '', - '', - ' ', - ' ASLMessageID', - ' 54706', - ' Time', - ' Feb 17 12:52:17', - ' TimeNanoSec', - ' 469585000', - ' Level', - ' 2', - ' PID', - ' 38152', - ' UID', - ' 1507447745', - ' GID', - ' 1876110778', - ' ReadGID', - ' 80', - ' Host', - ' matthewwith-mbp', - ' Sender', - ' UIExplorer', - ' Facility', - ' user', - ' Message', - ' 2016-08-24 15:58:33.113 [ExampleTag] Message 2', - ' ASLSHIM', - ' 1', - ' SenderMachUUID', - ' 09F5C0C0-7587-39E8-A92E-7B130965D76C', - ' ', - '', - '', -]; diff --git a/pkg/nuclide-ios-simulator-logs/spec/parseMessageText-spec.js b/pkg/nuclide-ios-simulator-logs/spec/parseMessageText-spec.js deleted file mode 100644 index 1b88bf4768..0000000000 --- a/pkg/nuclide-ios-simulator-logs/spec/parseMessageText-spec.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import {parseMessageText} from '../lib/parseMessageText'; - -describe('parseMessageText', () => { - /* eslint-disable max-len */ - const lines = [ - // TODO: Test no tags? - '2016-08-24 15:58:33.113 [info][tid:com.facebook.react.JavaScript] This is info', - '2016-08-24 15:58:33.113 [warn][tid:com.facebook.react.JavaScript] This is warn', - '2016-08-24 15:58:33.114 [error][tid:com.facebook.react.JavaScript] This is error', - '2016-08-24 15:58:33.154 [info][tid:com.facebook.react.JavaScript] Running application "Something" with appParams: {"rootTag":1,"initialProps":{}}. __DEV__ === true, development-level warning are ON, performance optimizations are OFF', - '2016-08-24 15:58:33.172 [info][tid:com.facebook.react.JavaScript] [Something] Checking for update.', - '2016-08-24 15:58:33.657 [info][tid:com.facebook.react.JavaScript] [Something] App is up to date.', - '2016-08-24 15:38:04.364 [debug][core.react][tid:main][] [RCTModuleData.m:103] The module RCTDiskCacheStore is returning nil from its constructor. You may need to instantiate it yourself and pass it into the bridge.', - '2016-08-24 15:58:33.113 [info][tid:com.facebook.react.JavaScript] This\nis\ninfo', - ]; - /* eslint-enable max-len */ - - const parsed = lines.map(parseMessageText); - - it('parses tags', () => { - expect(parsed.map(message => message.tags)).toEqual([ - ['tid:com.facebook.react.JavaScript'], - ['tid:com.facebook.react.JavaScript'], - ['tid:com.facebook.react.JavaScript'], - ['tid:com.facebook.react.JavaScript'], - ['tid:com.facebook.react.JavaScript'], - ['tid:com.facebook.react.JavaScript'], - ['core.react', 'tid:main'], - ['tid:com.facebook.react.JavaScript'], - ]); - }); - - it('parses levels', () => { - expect(parsed.map(message => message.level)).toEqual([ - 'info', - 'warning', - 'error', - 'info', - 'info', - 'info', - 'debug', - 'info', - ]); - }); - - it('parses text', () => { - expect(parsed.map(message => message.text)).toEqual([ - /* eslint-disable max-len */ - 'This is info', - 'This is warn', - 'This is error', - 'Running application "Something" with appParams: {"rootTag":1,"initialProps":{}}. __DEV__ === true, development-level warning are ON, performance optimizations are OFF', - '[Something] Checking for update.', - '[Something] App is up to date.', - '[RCTModuleData.m:103] The module RCTDiskCacheStore is returning nil from its constructor. You may need to instantiate it yourself and pass it into the bridge.', - 'This\nis\ninfo', - /* eslint-enable max-len */ - ]); - }); - - it('ends the tag list when it encounters a tag with brackets in it', () => { - // eslint-disable-next-line max-len - const line = - '2016-08-24 17:39:32.278 [debug][cpuspindetector][tid:com.facebook.FBTimer][-[FBCPUSpinDetector _checkUsage]] Begin check usage'; - const {tags, text} = parseMessageText(line); - expect(tags).toEqual(['cpuspindetector', 'tid:com.facebook.FBTimer']); - expect(text).toBe('[-[FBCPUSpinDetector _checkUsage]] Begin check usage'); - }); - - it('handles messages with weird bracket situations', () => { - // eslint-disable-next-line max-len - const line = '2016-08-24 17:39:32.278 [abc][def]g]h'; - const {tags, text} = parseMessageText(line); - expect(tags).toEqual(['abc', 'def']); - expect(text).toBe('g]h'); - }); -}); diff --git a/pkg/nuclide-js-imports-client/lib/DashProjectSymbolProvider.js b/pkg/nuclide-js-imports-client/lib/DashProjectSymbolProvider.js index 3bdef29904..40c3cfcc25 100644 --- a/pkg/nuclide-js-imports-client/lib/DashProjectSymbolProvider.js +++ b/pkg/nuclide-js-imports-client/lib/DashProjectSymbolProvider.js @@ -1,48 +1,42 @@ -/** - * 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 strict-local - * @format - */ - -// $FlowFB -import type {ProjectSymbol} from '../../fb-go-to-project-symbol-dash-provider/lib/types'; -import type {AtomLanguageService} from '../../nuclide-language-service'; -import type {LanguageService} from '../../nuclide-language-service/lib/LanguageService'; - -import {Observable} from 'rxjs'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -export default class Omni2ProjectSymbolProvider { - _languageService: AtomLanguageService; - - constructor(languageService: AtomLanguageService) { +'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('../../../modules/nuclide-commons/UniversalDisposable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Omni2ProjectSymbolProvider { + + constructor(languageService) { this._languageService = languageService; } - searchSymbolsForDirectory( - query: string, - directory: atom$Directory, - callback: (Array) => mixed, - ): IDisposable { + searchSymbolsForDirectory(query, directory, callback) { const directoryPath = directory.getPath(); - const results = Observable.defer(() => - this._languageService.getLanguageServiceForUri(directoryPath), - ) - .switchMap( - service => - service == null - ? Observable.of([]) - : service.symbolSearch(query, [directoryPath]), - ) - .map(searchResults => searchResults || []) - .catch(() => Observable.of([])); - - return new UniversalDisposable(results.subscribe(callback)); + const results = _rxjsBundlesRxMinJs.Observable.defer(() => this._languageService.getLanguageServiceForUri(directoryPath)).switchMap(service => service == null ? _rxjsBundlesRxMinJs.Observable.of([]) : service.symbolSearch(query, [directoryPath])).map(searchResults => searchResults || []).catch(() => _rxjsBundlesRxMinJs.Observable.of([])); + + return new (_UniversalDisposable || _load_UniversalDisposable()).default(results.subscribe(callback)); } } +exports.default = Omni2ProjectSymbolProvider; /** + * 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. + * + * strict-local + * @format + */ + +// $FlowFB \ No newline at end of file diff --git a/pkg/nuclide-js-imports-client/lib/JSSymbolSearchProvider.js b/pkg/nuclide-js-imports-client/lib/JSSymbolSearchProvider.js index b995619036..3574f379d7 100644 --- a/pkg/nuclide-js-imports-client/lib/JSSymbolSearchProvider.js +++ b/pkg/nuclide-js-imports-client/lib/JSSymbolSearchProvider.js @@ -1,40 +1,31 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {AtomLanguageService} from '../../nuclide-language-service'; -import type { - LanguageService, - SymbolResult, -} from '../../nuclide-language-service/lib/LanguageService'; /** * This service allows other packages to search JS symbols using language service */ -export default class JSSymbolSearchProvider { - _languageService: AtomLanguageService; +class JSSymbolSearchProvider { - constructor(languageService: AtomLanguageService) { + constructor(languageService) { this._languageService = languageService; } - async searchJSSymbol( - query: string, - directoryUri: NuclideUri, - ): Promise> { - const uriLanguageService = await this._languageService.getLanguageServiceForUri( - directoryUri, - ); - return uriLanguageService - ? uriLanguageService.symbolSearch(query, [directoryUri]) - : null; + async searchJSSymbol(query, directoryUri) { + const uriLanguageService = await this._languageService.getLanguageServiceForUri(directoryUri); + return uriLanguageService ? uriLanguageService.symbolSearch(query, [directoryUri]) : null; } } +exports.default = JSSymbolSearchProvider; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-js-imports-client/lib/QuickOpenProvider.js b/pkg/nuclide-js-imports-client/lib/QuickOpenProvider.js index 0fee6a9253..8fe48f2034 100644 --- a/pkg/nuclide-js-imports-client/lib/QuickOpenProvider.js +++ b/pkg/nuclide-js-imports-client/lib/QuickOpenProvider.js @@ -1,108 +1,105 @@ -/** - * 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 - */ - -import type {AtomLanguageService} from '../../nuclide-language-service'; -import type {LanguageService} from '../../nuclide-language-service/lib/LanguageService'; -import type {SymbolResult} from '../../nuclide-quick-open/lib/types'; - -import humanizePath from 'nuclide-commons-atom/humanizePath'; -import {arrayCompact, collect, arrayFlatten} from 'nuclide-commons/collection'; -import {asyncFind} from 'nuclide-commons/promise'; -import * as React from 'react'; - -export default class QuickOpenProvider { - providerType = 'GLOBAL'; - name = 'JSImportsService'; - display = { - title: 'JS Symbols', - prompt: 'Search JavaScript symbols...', - action: 'nuclide-js-imports:toggle-provider', - }; - - _languageService: AtomLanguageService; - - constructor(languageService: AtomLanguageService) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _humanizePath; + +function _load_humanizePath() { + return _humanizePath = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/humanizePath')); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +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 }; } + +class QuickOpenProvider { + + constructor(languageService) { + this.providerType = 'GLOBAL'; + this.name = 'JSImportsService'; + this.display = { + title: 'JS Symbols', + prompt: 'Search JavaScript symbols...', + action: 'nuclide-js-imports:toggle-provider' + }; + this._languageService = languageService; } - async _getDirectoriesByService( - directories: Array, - ): Promise>> { - return collect( - arrayCompact( - await Promise.all( - // Flow's inference engine blows up without the annotation :( - directories.map( - async (directory): Promise => { - const path = directory.getPath(); - const service = await this._languageService.getLanguageServiceForUri( - path, - ); - return service != null ? [service, path] : null; - }, - ), - ), - ), - ); + async _getDirectoriesByService(directories) { + return (0, (_collection || _load_collection()).collect)((0, (_collection || _load_collection()).arrayCompact)((await Promise.all( + // Flow's inference engine blows up without the annotation :( + directories.map(async directory => { + const path = directory.getPath(); + const service = await this._languageService.getLanguageServiceForUri(path); + return service != null ? [service, path] : null; + }))))); } - async isEligibleForDirectories( - directories: Array, - ): Promise { - const directoriesByService = await this._getDirectoriesByService( - directories, - ); - return ( - (await asyncFind(Array.from(directoriesByService), ([service, paths]) => - service.supportsSymbolSearch(paths), - )) != null - ); + async isEligibleForDirectories(directories) { + const directoriesByService = await this._getDirectoriesByService(directories); + return (await (0, (_promise || _load_promise()).asyncFind)(Array.from(directoriesByService), ([service, paths]) => service.supportsSymbolSearch(paths))) != null; } - async executeQuery( - query: string, - directories: Array, - ): Promise> { + async executeQuery(query, directories) { if (query.length === 0) { return []; } - const directoriesByService = await this._getDirectoriesByService( - directories, - ); - const results = await Promise.all( - Array.from(directoriesByService).map(([service, paths]) => - service.symbolSearch(query, paths), - ), - ); - return arrayFlatten(arrayCompact(results)); + const directoriesByService = await this._getDirectoriesByService(directories); + const results = await Promise.all(Array.from(directoriesByService).map(([service, paths]) => service.symbolSearch(query, paths))); + return (0, (_collection || _load_collection()).arrayFlatten)((0, (_collection || _load_collection()).arrayCompact)(results)); } // TODO: Standardize on a generic SymbolResult renderer. - getComponentForItem(item: SymbolResult): React.Element { + getComponentForItem(item) { const name = item.name || ''; // flowlint-next-line sketchy-null-string:off - const symbolClasses = item.icon - ? `file icon icon-${item.icon}` - : 'file icon no-icon'; - return ( -
    - - {name} - - - {humanizePath(item.path)} - -
    + const symbolClasses = item.icon ? `file icon icon-${item.icon}` : 'file icon no-icon'; + return _react.createElement( + 'div', + { title: item.hoverText || '' }, + _react.createElement( + 'span', + { className: symbolClasses }, + _react.createElement( + 'code', + null, + name + ) + ), + _react.createElement( + 'span', + { className: 'omnisearch-symbol-result-filename' }, + (0, (_humanizePath || _load_humanizePath()).default)(item.path) + ) ); } } +exports.default = QuickOpenProvider; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-js-imports-client/lib/main.js b/pkg/nuclide-js-imports-client/lib/main.js index aaf12cb3ee..37b21f9d5d 100644 --- a/pkg/nuclide-js-imports-client/lib/main.js +++ b/pkg/nuclide-js-imports-client/lib/main.js @@ -1,3 +1,79 @@ +'use strict'; + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _textEdit; + +function _load_textEdit() { + return _textEdit = require('../../../modules/nuclide-commons-atom/text-edit'); +} + +var _constantsForClient; + +function _load_constantsForClient() { + return _constantsForClient = require('../../nuclide-js-imports-server/src/utils/constantsForClient'); +} + +var _nuclideLanguageService; + +function _load_nuclideLanguageService() { + return _nuclideLanguageService = require('../../nuclide-language-service'); +} + +var _nuclideLanguageServiceRpc; + +function _load_nuclideLanguageServiceRpc() { + return _nuclideLanguageServiceRpc = require('../../nuclide-language-service-rpc'); +} + +var _nuclideOpenFiles; + +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _QuickOpenProvider; + +function _load_QuickOpenProvider() { + return _QuickOpenProvider = _interopRequireDefault(require('./QuickOpenProvider')); +} + +var _JSSymbolSearchProvider; + +function _load_JSSymbolSearchProvider() { + return _JSSymbolSearchProvider = _interopRequireDefault(require('./JSSymbolSearchProvider')); +} + +var _DashProjectSymbolProvider; + +function _load_DashProjectSymbolProvider() { + return _DashProjectSymbolProvider = _interopRequireDefault(require('./DashProjectSymbolProvider')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,72 +81,32 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ // $FlowFB -import type {ProjectSymbolSearchProvider} from '../../fb-go-to-project-symbol-dash-provider/lib/types'; -import type {CodeActionConfig} from '../../nuclide-language-service/lib/CodeActionProvider'; -import type { - GlobalProviderType, - SymbolResult, -} from '../../nuclide-quick-open/lib/types'; -import type {ServerConnection} from '../../nuclide-remote-connection'; -import type {AtomLanguageServiceConfig} from '../../nuclide-language-service/lib/AtomLanguageService'; -import type {LanguageService} from '../../nuclide-language-service/lib/LanguageService'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -import {applyTextEditsToBuffer} from 'nuclide-commons-atom/text-edit'; -import {TAB_SIZE_SIGNIFYING_FIX_ALL_IMPORTS_FORMATTING} from '../../nuclide-js-imports-server/src/utils/constantsForClient'; -import { - AtomLanguageService, - getHostServices, -} from '../../nuclide-language-service'; -import {NullLanguageService} from '../../nuclide-language-service-rpc'; -import { - getNotifierByConnection, - getFileVersionOfEditor, -} from '../../nuclide-open-files'; -import {getVSCodeLanguageServiceByConnection} from '../../nuclide-remote-connection'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import QuickOpenProvider from './QuickOpenProvider'; -import JSSymbolSearchProvider from './JSSymbolSearchProvider'; -import DashProjectSymbolProvider from './DashProjectSymbolProvider'; - -async function connectToJSImportsService( - connection: ?ServerConnection, -): Promise { - const [fileNotifier, host] = await Promise.all([ - getNotifierByConnection(connection), - getHostServices(), - ]); - - const service = getVSCodeLanguageServiceByConnection(connection); - const lspService = await service.createMultiLspLanguageService( - 'jsimports', - './pkg/nuclide-js-imports-server/src/index-entry.js', - [], - { - fileNotifier, - host, - logCategory: 'jsimports', - logLevel: (featureConfig.get('nuclide-js-imports-client.logLevel'): any), - projectFileNames: ['.flowconfig'], - fileExtensions: ['.js', '.jsx'], - initializationOptions: getAutoImportSettings(), - fork: true, - }, - ); - return lspService || new NullLanguageService(); +async function connectToJSImportsService(connection) { + const [fileNotifier, host] = await Promise.all([(0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getNotifierByConnection)(connection), (0, (_nuclideLanguageService || _load_nuclideLanguageService()).getHostServices)()]); + + const service = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getVSCodeLanguageServiceByConnection)(connection); + const lspService = await service.createMultiLspLanguageService('jsimports', './pkg/nuclide-js-imports-server/src/index-entry.js', [], { + fileNotifier, + host, + logCategory: 'jsimports', + logLevel: (_featureConfig || _load_featureConfig()).default.get('nuclide-js-imports-client.logLevel'), + projectFileNames: ['.flowconfig'], + fileExtensions: ['.js', '.jsx'], + initializationOptions: getAutoImportSettings(), + fork: true + }); + return lspService || new (_nuclideLanguageServiceRpc || _load_nuclideLanguageServiceRpc()).NullLanguageService(); } -function createLanguageService(): AtomLanguageService { +function createLanguageService() { const diagnosticsConfig = { version: '0.2.0', - analyticsEventName: 'jsimports.observe-diagnostics', + analyticsEventName: 'jsimports.observe-diagnostics' }; const autocompleteConfig = { @@ -79,28 +115,28 @@ function createLanguageService(): AtomLanguageService { excludeLowerPriority: false, analytics: { eventName: 'nuclide-js-imports', - shouldLogInsertedSuggestion: false, + shouldLogInsertedSuggestion: false }, disableForSelector: null, autocompleteCacherConfig: null, - supportsResolve: false, + supportsResolve: false }; - const codeActionConfig: CodeActionConfig = { + const codeActionConfig = { version: '0.1.0', priority: 0, analyticsEventName: 'jsimports.codeAction', - applyAnalyticsEventName: 'jsimports.applyCodeAction', + applyAnalyticsEventName: 'jsimports.applyCodeAction' }; - const atomConfig: AtomLanguageServiceConfig = { + const atomConfig = { name: 'JSAutoImports', grammars: ['source.js.jsx', 'source.js'], diagnostics: diagnosticsConfig, autocomplete: autocompleteConfig, - codeAction: codeActionConfig, + codeAction: codeActionConfig }; - return new AtomLanguageService(connectToJSImportsService, atomConfig); + return new (_nuclideLanguageService || _load_nuclideLanguageService()).AtomLanguageService(connectToJSImportsService, atomConfig); } function getAutoImportSettings() { @@ -110,33 +146,26 @@ function getAutoImportSettings() { // their settings and send DidChangeConfiguration requests to the server. // TODO: Observe settings changes + send to the server. return { - diagnosticsWhitelist: featureConfig.get( - 'nuclide-js-imports-client.diagnosticsWhitelist', - ), - requiresWhitelist: featureConfig.get( - 'nuclide-js-imports-client.requiresWhitelist', - ), + diagnosticsWhitelist: (_featureConfig || _load_featureConfig()).default.get('nuclide-js-imports-client.diagnosticsWhitelist'), + requiresWhitelist: (_featureConfig || _load_featureConfig()).default.get('nuclide-js-imports-client.requiresWhitelist') }; } class Activation { - _languageService: AtomLanguageService; - _quickOpenProvider: QuickOpenProvider; - _commandSubscription: UniversalDisposable; constructor() { this._languageService = createLanguageService(); this._languageService.activate(); - this._quickOpenProvider = new QuickOpenProvider(this._languageService); - this._commandSubscription = new UniversalDisposable(); + this._quickOpenProvider = new (_QuickOpenProvider || _load_QuickOpenProvider()).default(this._languageService); + this._commandSubscription = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - provideProjectSymbolSearch(): ProjectSymbolSearchProvider { - return new DashProjectSymbolProvider(this._languageService); + provideProjectSymbolSearch() { + return new (_DashProjectSymbolProvider || _load_DashProjectSymbolProvider()).default(this._languageService); } - provideJSSymbolSearchService(): JSSymbolSearchProvider { - return new JSSymbolSearchProvider(this._languageService); + provideJSSymbolSearchService() { + return new (_JSSymbolSearchProvider || _load_JSSymbolSearchProvider()).default(this._languageService); } dispose() { @@ -144,70 +173,51 @@ class Activation { this._commandSubscription.dispose(); } - registerQuickOpenProvider(): GlobalProviderType { + registerQuickOpenProvider() { return this._quickOpenProvider; } - consumeOrganizeRequiresService( - organizeRequires: ({ - addedRequires: boolean, - missingExports: boolean, - }) => void, - ): UniversalDisposable { - this._commandSubscription.add( - atom.commands.add( - 'atom-text-editor', - 'nuclide-js-imports:auto-require', - async () => { - const editor = atom.workspace.getActiveTextEditor(); - if (editor == null) { - return; - } - const fileVersion = await getFileVersionOfEditor(editor); - if (fileVersion == null) { - return; - } - const buffer = editor.getBuffer(); - const range = buffer.getRange(); - const languageService = await this._languageService.getLanguageServiceForUri( - editor.getPath(), - ); - if (languageService == null) { - return; - } - const triggerOptions = { - // secret code - tabSize: TAB_SIZE_SIGNIFYING_FIX_ALL_IMPORTS_FORMATTING, - // just for typechecking to pass - insertSpaces: true, - }; - const result = await languageService.formatSource( - fileVersion, - range, - triggerOptions, - ); - const beforeEditsCheckpoint = buffer.createCheckpoint(); - // First add all new imports naively - if (result != null) { - if (!applyTextEditsToBuffer(buffer, result)) { - // TODO(T24077432): Show the error to the user - throw new Error('Could not apply edits to text buffer.'); - } - } - // Then use nuclide-format-js to properly format the imports - const successfulEdits = (result || []).filter( - edit => edit.newText !== '', - ); - organizeRequires({ - addedRequires: successfulEdits.length > 0, - missingExports: successfulEdits.length !== (result || []).length, - }); - buffer.groupChangesSinceCheckpoint(beforeEditsCheckpoint); - }, - ), - ); + consumeOrganizeRequiresService(organizeRequires) { + this._commandSubscription.add(atom.commands.add('atom-text-editor', 'nuclide-js-imports:auto-require', async () => { + const editor = atom.workspace.getActiveTextEditor(); + if (editor == null) { + return; + } + const fileVersion = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor); + if (fileVersion == null) { + return; + } + const buffer = editor.getBuffer(); + const range = buffer.getRange(); + const languageService = await this._languageService.getLanguageServiceForUri(editor.getPath()); + if (languageService == null) { + return; + } + const triggerOptions = { + // secret code + tabSize: (_constantsForClient || _load_constantsForClient()).TAB_SIZE_SIGNIFYING_FIX_ALL_IMPORTS_FORMATTING, + // just for typechecking to pass + insertSpaces: true + }; + const result = await languageService.formatSource(fileVersion, range, triggerOptions); + const beforeEditsCheckpoint = buffer.createCheckpoint(); + // First add all new imports naively + if (result != null) { + if (!(0, (_textEdit || _load_textEdit()).applyTextEditsToBuffer)(buffer, result)) { + // TODO(T24077432): Show the error to the user + throw new Error('Could not apply edits to text buffer.'); + } + } + // Then use nuclide-format-js to properly format the imports + const successfulEdits = (result || []).filter(edit => edit.newText !== ''); + organizeRequires({ + addedRequires: successfulEdits.length > 0, + missingExports: successfulEdits.length !== (result || []).length + }); + buffer.groupChangesSinceCheckpoint(beforeEditsCheckpoint); + })); return this._commandSubscription; } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/__mocks__/fixtures/testFile.js b/pkg/nuclide-js-imports-server/__mocks__/fixtures/testFile.js index f4dd8b848d..9441253615 100644 --- a/pkg/nuclide-js-imports-server/__mocks__/fixtures/testFile.js +++ b/pkg/nuclide-js-imports-server/__mocks__/fixtures/testFile.js @@ -1,18 +1,20 @@ -/** - * 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 strict - * @format - */ +'use strict'; -export type MyFakeTypeForTesting = 'string'; - -export class MyFakeClassForTesting { - foo(): string { +Object.defineProperty(exports, "__esModule", { + value: true +}); +class MyFakeClassForTesting { + foo() { return 'bar'; } } +exports.MyFakeClassForTesting = MyFakeClassForTesting; /** + * 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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/__mocks__/fixtures/testFile2.js b/pkg/nuclide-js-imports-server/__mocks__/fixtures/testFile2.js index 31de444a10..1762e4d413 100644 --- a/pkg/nuclide-js-imports-server/__mocks__/fixtures/testFile2.js +++ b/pkg/nuclide-js-imports-server/__mocks__/fixtures/testFile2.js @@ -1,18 +1,20 @@ -/** - * 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 strict - * @format - */ +'use strict'; -export type SomeType = 'string'; - -export class FooBarClass { - foo(): string { +Object.defineProperty(exports, "__esModule", { + value: true +}); +class FooBarClass { + foo() { return 'bar'; } } +exports.FooBarClass = FooBarClass; /** + * 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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/__tests__/AutoImportsManager-test.js b/pkg/nuclide-js-imports-server/__tests__/AutoImportsManager-test.js index 7a294a1915..222e4e176a 100644 --- a/pkg/nuclide-js-imports-server/__tests__/AutoImportsManager-test.js +++ b/pkg/nuclide-js-imports-server/__tests__/AutoImportsManager-test.js @@ -1,26 +1,18 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import {AutoImportsManager} from '../src/lib/AutoImportsManager'; +var _AutoImportsManager; + +function _load_AutoImportsManager() { + return _AutoImportsManager = require('../src/lib/AutoImportsManager'); +} describe('AutoImportsManager', () => { it('Can provide a basic missing value import', () => { const file1 = 'export function Foo(){return x?.y;}'; const file2 = 'Foo();'; - const autoImportsManager = new AutoImportsManager([]); + const autoImportsManager = new (_AutoImportsManager || _load_AutoImportsManager()).AutoImportsManager([]); autoImportsManager.indexFile('file1.js', file1); - const missingImports = autoImportsManager.findMissingImports( - 'file2.js', - file2, - ); + const missingImports = autoImportsManager.findMissingImports('file2.js', file2); expect(missingImports).toBeDefined(); expect(missingImports.length).toBe(1); expect(missingImports[0].symbol.id).toBe('Foo'); @@ -29,12 +21,9 @@ describe('AutoImportsManager', () => { it('Can provide a basic missing type import', () => { const file1 = "export type MyType = 'string' "; const file2 = "const val: MyType = 'something'; MyType();"; - const autoImportsManager = new AutoImportsManager([]); + const autoImportsManager = new (_AutoImportsManager || _load_AutoImportsManager()).AutoImportsManager([]); autoImportsManager.indexFile('file1.js', file1); - const missingImports = autoImportsManager.findMissingImports( - 'file2.js', - file2, - ); + const missingImports = autoImportsManager.findMissingImports('file2.js', file2); expect(missingImports).toBeDefined(); expect(missingImports.length).toBe(1); expect(missingImports[0].symbol.id).toBe('MyType'); @@ -43,12 +32,9 @@ describe('AutoImportsManager', () => { it('Open files are automatically indexed', () => { const file1 = "export type MyType = 'string' "; const file2 = "const val: MyType = 'something'"; - const autoImportsManager = new AutoImportsManager([]); + const autoImportsManager = new (_AutoImportsManager || _load_AutoImportsManager()).AutoImportsManager([]); autoImportsManager.indexFile('file1.js', file1); - const missingImports = autoImportsManager.findMissingImports( - 'file2.js', - file2, - ); + const missingImports = autoImportsManager.findMissingImports('file2.js', file2); expect(missingImports).toBeDefined(); expect(missingImports.length).toBe(1); expect(missingImports[0].symbol.id).toBe('MyType'); @@ -57,11 +43,8 @@ describe('AutoImportsManager', () => { it('Does not provide imports if no import with that id is indexed.', () => { const file = 'const val : Atom$Point = {a: 1, b: 2}'; - const autoImportsManager = new AutoImportsManager([]); - const missingImports = autoImportsManager.findMissingImports( - 'file1,js', - file, - ); + const autoImportsManager = new (_AutoImportsManager || _load_AutoImportsManager()).AutoImportsManager([]); + const missingImports = autoImportsManager.findMissingImports('file1,js', file); expect(missingImports).toBeDefined(); expect(missingImports.length).toBe(0); }); @@ -69,31 +52,37 @@ describe('AutoImportsManager', () => { const exportProgram = 'export class SomeClass {}'; const missingImportProgram = 'type SomeType = {someClass: SomeClass}'; const fileName = '/Users/unixname/testfile.js'; - const autoImportsManager = new AutoImportsManager([]); + const autoImportsManager = new (_AutoImportsManager || _load_AutoImportsManager()).AutoImportsManager([]); autoImportsManager.indexFile('someFile.js', exportProgram); autoImportsManager.findMissingImports(fileName, missingImportProgram); const empty = autoImportsManager.getSuggestedImportsForRange(fileName, { - start: {line: 0, character: 0}, - end: {line: 0, character: 0}, + start: { line: 0, character: 0 }, + end: { line: 0, character: 0 } }); expect(empty.length).toBe(0); const bigRange = autoImportsManager.getSuggestedImportsForRange(fileName, { - start: {line: 0, character: 1}, - end: {line: 1000, character: 1}, + start: { line: 0, character: 1 }, + end: { line: 1000, character: 1 } }); expect(bigRange.length).toBe(1); - const exactRange = autoImportsManager.getSuggestedImportsForRange( - fileName, - { - start: {line: 0, character: 28}, - end: {line: 0, character: 37}, - }, - ); + const exactRange = autoImportsManager.getSuggestedImportsForRange(fileName, { + start: { line: 0, character: 28 }, + end: { line: 0, character: 37 } + }); expect(exactRange.length).toBe(1); const halfRange = autoImportsManager.getSuggestedImportsForRange(fileName, { - start: {line: 0, character: 28}, - end: {line: 0, character: 33}, + start: { line: 0, character: 28 }, + end: { line: 0, character: 33 } }); expect(halfRange.length).toBe(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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/__tests__/AutoImportsWorker-test.js b/pkg/nuclide-js-imports-server/__tests__/AutoImportsWorker-test.js index d976f524fd..8bf99660e0 100644 --- a/pkg/nuclide-js-imports-server/__tests__/AutoImportsWorker-test.js +++ b/pkg/nuclide-js-imports-server/__tests__/AutoImportsWorker-test.js @@ -1,169 +1,119 @@ -/** - * 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 - */ +'use strict'; -// jest.unmock('log4js'); +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _testHelpers; + +function _load_testHelpers() { + return _testHelpers = require('../../../modules/nuclide-commons/test-helpers'); +} + +var _AutoImportsWorker; + +function _load_AutoImportsWorker() { + return _AutoImportsWorker = require('../src/lib/AutoImportsWorker'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _fileIndex; -import {Observable} from 'rxjs'; -import {generateFixture} from 'nuclide-commons/test-helpers'; -import {indexDirectory, indexNodeModules} from '../src/lib/AutoImportsWorker'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {getFileIndex} from '../src/lib/file-index'; +function _load_fileIndex() { + return _fileIndex = require('../src/lib/file-index'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const hasteSettings = { isHaste: false, useNameReducers: false, nameReducers: [], nameReducerWhitelist: [], - nameReducerBlacklist: [], -}; + nameReducerBlacklist: [] +}; /** + * 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. + * + * + * @format + */ + +// jest.unmock('log4js'); const configFromFlow = { moduleDirs: [], - hasteSettings, + hasteSettings }; describe('AutoImportsWorker', () => { let fileIndex; - const dirPath = nuclideUri.join(__dirname, '../__mocks__/fixtures'); + const dirPath = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures'); beforeEach(async () => { await (async () => { - fileIndex = await getFileIndex(dirPath, configFromFlow); + fileIndex = await (0, (_fileIndex || _load_fileIndex()).getFileIndex)(dirPath, configFromFlow); })(); }); it('Should index imports in a directory asynchronously', async () => { await (async () => { - const ids = await indexDirectory(fileIndex, hasteSettings) - .concatAll() - .concatMap(update => update.exports) - .map(jsExport => jsExport.id) - .toArray() - .toPromise(); - - expect(ids.sort()).toEqual([ - 'FooBarClass', - 'MyFakeClassForTesting', - 'MyFakeTypeForTesting', - 'SomeType', - ]); + const ids = await (0, (_AutoImportsWorker || _load_AutoImportsWorker()).indexDirectory)(fileIndex, hasteSettings).concatAll().concatMap(update => update.exports).map(jsExport => jsExport.id).toArray().toPromise(); + + expect(ids.sort()).toEqual(['FooBarClass', 'MyFakeClassForTesting', 'MyFakeTypeForTesting', 'SomeType']); })(); }); }); describe('AutoImportsWorker main files indexer', () => { // Create fixtures for these tests. - let dirPath: string = (null: any); + let dirPath = null; let fileIndex; beforeEach(async () => { await (async () => { - dirPath = await generateFixture( - 'main_tests', - new Map([ - ['some_package/package.json', '{"main": "./lib/main.js"}'], - ['some_package/lib/main.js', 'export class SomeTestClass {}'], - ['some_package/lib/someOtherFile.js', 'export class Something {}'], - ['another_package/package.json', 'this isnt valid json'], - [ - 'complicated_package/modules/lib/tools/package.json', - '{"main": "../../main.js"}', - ], - [ - 'complicated_package/modules/main.js', - 'export type SomeType = string', - ], - [ - 'package_with_main_without_extension/package.json', - '{"main": "./main"}', - ], - [ - 'package_with_main_without_extension/main.js', - 'export class AnotherClass {}', - ], - ['package_json_without_main/package.json', '{"name": "package"}'], - ['package_json_without_main/index.js', 'export class Test{}'], - ]), - ); - fileIndex = await getFileIndex(dirPath, configFromFlow); + dirPath = await (0, (_testHelpers || _load_testHelpers()).generateFixture)('main_tests', new Map([['some_package/package.json', '{"main": "./lib/main.js"}'], ['some_package/lib/main.js', 'export class SomeTestClass {}'], ['some_package/lib/someOtherFile.js', 'export class Something {}'], ['another_package/package.json', 'this isnt valid json'], ['complicated_package/modules/lib/tools/package.json', '{"main": "../../main.js"}'], ['complicated_package/modules/main.js', 'export type SomeType = string'], ['package_with_main_without_extension/package.json', '{"main": "./main"}'], ['package_with_main_without_extension/main.js', 'export class AnotherClass {}'], ['package_json_without_main/package.json', '{"name": "package"}'], ['package_json_without_main/index.js', 'export class Test{}']])); + fileIndex = await (0, (_fileIndex || _load_fileIndex()).getFileIndex)(dirPath, configFromFlow); })(); }); it('Should correctly mark files as main', async () => { await (async () => { - const exports = await indexDirectory(fileIndex, hasteSettings) - .concatAll() - .concatMap(update => update.exports) - .toArray() - .toPromise(); - - const exportById = new Map( - exports.map(exp => [exp.id, exp.directoryForMainFile]), - ); - expect(exportById.get('SomeTestClass')).toBe( - nuclideUri.join(dirPath, 'some_package'), - ); + const exports = await (0, (_AutoImportsWorker || _load_AutoImportsWorker()).indexDirectory)(fileIndex, hasteSettings).concatAll().concatMap(update => update.exports).toArray().toPromise(); + + const exportById = new Map(exports.map(exp => [exp.id, exp.directoryForMainFile])); + expect(exportById.get('SomeTestClass')).toBe((_nuclideUri || _load_nuclideUri()).default.join(dirPath, 'some_package')); expect(exportById.has('Something')).toBeTruthy(); expect(exportById.get('Something')).toBe(undefined); expect(exportById.get('SomeType')).toBe(undefined); - expect(exportById.get('AnotherClass')).toBe( - nuclideUri.join(dirPath, 'package_with_main_without_extension'), - ); - expect(exportById.get('Test')).toBe( - nuclideUri.join(dirPath, 'package_json_without_main'), - ); + expect(exportById.get('AnotherClass')).toBe((_nuclideUri || _load_nuclideUri()).default.join(dirPath, 'package_with_main_without_extension')); + expect(exportById.get('Test')).toBe((_nuclideUri || _load_nuclideUri()).default.join(dirPath, 'package_json_without_main')); })(); }); }); describe('AutoImportsWorker node_modules indexer', () => { - let dirPath: string = (null: any); + let dirPath = null; let fileIndex; beforeEach(async () => { await (async () => { - dirPath = await generateFixture( - 'main_tests', - new Map([ - ['node_modules/log4js/package.json', '{"main": "./lib/log4js.js"}'], - [ - 'node_modules/log4js/lib/log4js.js', - 'module.exports = {getLogger: () => {}}', - ], - ['node_modules/left-pad/package.json', '{"main": "./lib"}'], - ['node_modules/left-pad/lib/index.js', 'module.exports = {};'], - ]), - ); + dirPath = await (0, (_testHelpers || _load_testHelpers()).generateFixture)('main_tests', new Map([['node_modules/log4js/package.json', '{"main": "./lib/log4js.js"}'], ['node_modules/log4js/lib/log4js.js', 'module.exports = {getLogger: () => {}}'], ['node_modules/left-pad/package.json', '{"main": "./lib"}'], ['node_modules/left-pad/lib/index.js', 'module.exports = {};']])); // Deliberately sabotage spawn() to exercise the glob indexer. - const spawnSpy = jest - .spyOn(require('nuclide-commons/process'), 'spawn') - .mockReturnValue(Observable.throw()); - fileIndex = await getFileIndex(dirPath, configFromFlow); + const spawnSpy = jest.spyOn(require('../../../modules/nuclide-commons/process'), 'spawn').mockReturnValue(_rxjsBundlesRxMinJs.Observable.throw()); + fileIndex = await (0, (_fileIndex || _load_fileIndex()).getFileIndex)(dirPath, configFromFlow); expect(spawnSpy).toHaveBeenCalled(); })(); }); it('Should index node_modules correctly', async () => { await (async () => { - const files = await indexNodeModules(fileIndex) - .concatAll() - .map(data => data && data.file) - .toArray() - .toPromise(); + const files = await (0, (_AutoImportsWorker || _load_AutoImportsWorker()).indexNodeModules)(fileIndex).concatAll().map(data => data && data.file).toArray().toPromise(); files.sort(); - expect(files).toEqual([ - require.resolve( - nuclideUri.join(dirPath, 'node_modules/left-pad/lib/index.js'), - ), - require.resolve( - nuclideUri.join(dirPath, 'node_modules/log4js/lib/log4js.js'), - ), - ]); + expect(files).toEqual([require.resolve((_nuclideUri || _load_nuclideUri()).default.join(dirPath, 'node_modules/left-pad/lib/index.js')), require.resolve((_nuclideUri || _load_nuclideUri()).default.join(dirPath, 'node_modules/log4js/lib/log4js.js'))]); })(); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/__tests__/CommandExecutor-test.js b/pkg/nuclide-js-imports-server/__tests__/CommandExecutor-test.js index bdac0493a8..7ddf68c5d8 100644 --- a/pkg/nuclide-js-imports-server/__tests__/CommandExecutor-test.js +++ b/pkg/nuclide-js-imports-server/__tests__/CommandExecutor-test.js @@ -1,3 +1,23 @@ +'use strict'; + +var _CommandExecutor; + +function _load_CommandExecutor() { + return _CommandExecutor = require('../src/CommandExecutor'); +} + +var _AutoImportsManager; + +function _load_AutoImportsManager() { + return _AutoImportsManager = require('../src/lib/AutoImportsManager'); +} + +var _ImportFormatter; + +function _load_ImportFormatter() { + return _ImportFormatter = require('../src/lib/ImportFormatter'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,89 +25,60 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import invariant from 'assert'; +function getProgramBody(src) { + const ast = (0, (_AutoImportsManager || _load_AutoImportsManager()).parseFile)(src); -import {getEditsForImport} from '../src/CommandExecutor'; -import {parseFile} from '../src/lib/AutoImportsManager'; -import {ImportFormatter} from '../src/lib/ImportFormatter'; + if (!(ast != null)) { + throw new Error('Invariant violation: "ast != null"'); + } -function getProgramBody(src: string) { - const ast = parseFile(src); - invariant(ast != null); return ast.program.body; } describe('CommandExecutor', () => { it('can create new imports', () => { - const importFormatter = new ImportFormatter([], false); - expect( - getEditsForImport( - importFormatter, - '/a/test.js', - { - id: 'test', - uri: '/a/test2.js', - line: 1, - isTypeExport: false, - isDefault: true, - }, - getProgramBody('function f() {}'), - ), - ).toEqual([ - { - range: {start: {line: 0, character: 0}, end: {line: 0, character: 0}}, - newText: "import test from './test2';\n\n", - }, - ]); + const importFormatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter([], false); + expect((0, (_CommandExecutor || _load_CommandExecutor()).getEditsForImport)(importFormatter, '/a/test.js', { + id: 'test', + uri: '/a/test2.js', + line: 1, + isTypeExport: false, + isDefault: true + }, getProgramBody('function f() {}'))).toEqual([{ + range: { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } }, + newText: "import test from './test2';\n\n" + }]); }); it('can create new requires', () => { - const importFormatter = new ImportFormatter([], true); - expect( - getEditsForImport( - importFormatter, - '/a/test.js', - { - id: 'test', - uri: '/a/test2.js', - line: 1, - hasteName: 'test2', - isTypeExport: false, - isDefault: true, - }, - getProgramBody('function f() {}'), - ), - ).toEqual([ - { - range: {start: {line: 0, character: 0}, end: {line: 0, character: 0}}, - newText: "const test = require('test2');\n\n", - }, - ]); - - expect( - getEditsForImport( - importFormatter, - '/a/test.js', - { - id: 'test', - uri: '/a/test2.js', - line: 1, - hasteName: 'test2', - isTypeExport: false, - isDefault: false, - }, - getProgramBody('function f() {}\nlet fake;'), - ), - ).toEqual([ - { - range: {start: {line: 0, character: 0}, end: {line: 0, character: 0}}, - newText: "const {test} = require('test2');\n\n", - }, - ]); + const importFormatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter([], true); + expect((0, (_CommandExecutor || _load_CommandExecutor()).getEditsForImport)(importFormatter, '/a/test.js', { + id: 'test', + uri: '/a/test2.js', + line: 1, + hasteName: 'test2', + isTypeExport: false, + isDefault: true + }, getProgramBody('function f() {}'))).toEqual([{ + range: { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } }, + newText: "const test = require('test2');\n\n" + }]); + + expect((0, (_CommandExecutor || _load_CommandExecutor()).getEditsForImport)(importFormatter, '/a/test.js', { + id: 'test', + uri: '/a/test2.js', + line: 1, + hasteName: 'test2', + isTypeExport: false, + isDefault: false + }, getProgramBody('function f() {}\nlet fake;'))).toEqual([{ + range: { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } }, + newText: "const {test} = require('test2');\n\n" + }]); }); it('preserves ordering of imports', () => { @@ -100,154 +91,71 @@ import {z} from '../relative'; import {w} from './local'; `; - const importFormatter = new ImportFormatter(['node_modules'], false); + const importFormatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter(['node_modules'], false); function getExport(id, uri, isTypeExport = false, isDefault = false) { - return {id, uri, line: 1, isTypeExport, isDefault}; + return { id, uri, line: 1, isTypeExport, isDefault }; } - expect( - getEditsForImport( - importFormatter, - '/a/test.js', - getExport('test', 'node_modules/abc', true), - getProgramBody(sourceFile), - ), - ).toEqual([ - { - range: {start: {line: 1, character: 0}, end: {line: 1, character: 0}}, - newText: "import type {test} from 'abc';\n", - }, - ]); - - expect( - getEditsForImport( - importFormatter, - '/a/test.js', - getExport('test', 'node_modules/ghi', true), - getProgramBody(sourceFile), - ), - ).toEqual([ - { - range: {start: {line: 2, character: 0}, end: {line: 2, character: 0}}, - newText: "import type {test} from 'ghi';\n", - }, - ]); - - expect( - getEditsForImport( - importFormatter, - '/a/test.js', - getExport('test', '/abc.js'), - getProgramBody(sourceFile), - ), - ).toEqual([ - { - range: {start: {line: 5, character: 0}, end: {line: 5, character: 0}}, - newText: "import {test} from '../abc';\n", - }, - ]); - - expect( - getEditsForImport( - importFormatter, - '/a/test.js', - getExport('test', '/a/abc.js'), - getProgramBody(sourceFile), - ), - ).toEqual([ - { - range: {start: {line: 6, character: 0}, end: {line: 6, character: 0}}, - newText: "import {test} from './abc';\n", - }, - ]); - - expect( - getEditsForImport( - importFormatter, - '/a/test.js', - getExport('test', '/a/xyz.js'), - getProgramBody(sourceFile), - ), - ).toEqual([ - { - range: {start: {line: 7, character: 0}, end: {line: 7, character: 0}}, - newText: "import {test} from './xyz';\n", - }, - ]); + expect((0, (_CommandExecutor || _load_CommandExecutor()).getEditsForImport)(importFormatter, '/a/test.js', getExport('test', 'node_modules/abc', true), getProgramBody(sourceFile))).toEqual([{ + range: { start: { line: 1, character: 0 }, end: { line: 1, character: 0 } }, + newText: "import type {test} from 'abc';\n" + }]); + + expect((0, (_CommandExecutor || _load_CommandExecutor()).getEditsForImport)(importFormatter, '/a/test.js', getExport('test', 'node_modules/ghi', true), getProgramBody(sourceFile))).toEqual([{ + range: { start: { line: 2, character: 0 }, end: { line: 2, character: 0 } }, + newText: "import type {test} from 'ghi';\n" + }]); + + expect((0, (_CommandExecutor || _load_CommandExecutor()).getEditsForImport)(importFormatter, '/a/test.js', getExport('test', '/abc.js'), getProgramBody(sourceFile))).toEqual([{ + range: { start: { line: 5, character: 0 }, end: { line: 5, character: 0 } }, + newText: "import {test} from '../abc';\n" + }]); + + expect((0, (_CommandExecutor || _load_CommandExecutor()).getEditsForImport)(importFormatter, '/a/test.js', getExport('test', '/a/abc.js'), getProgramBody(sourceFile))).toEqual([{ + range: { start: { line: 6, character: 0 }, end: { line: 6, character: 0 } }, + newText: "import {test} from './abc';\n" + }]); + + expect((0, (_CommandExecutor || _load_CommandExecutor()).getEditsForImport)(importFormatter, '/a/test.js', getExport('test', '/a/xyz.js'), getProgramBody(sourceFile))).toEqual([{ + range: { start: { line: 7, character: 0 }, end: { line: 7, character: 0 } }, + newText: "import {test} from './xyz';\n" + }]); }); it('can insert into existing imports', () => { - const importFormatter = new ImportFormatter([], false); - expect( - getEditsForImport( - importFormatter, - '/a/test.js', - { - id: 'b', - uri: '/a/test2.js', - line: 1, - isTypeExport: false, - isDefault: false, - }, - getProgramBody( - "import type {a} from './test2';\nimport {a} from './test2';", - ), - ), - ).toEqual([ - { - range: {start: {line: 1, character: 9}, end: {line: 1, character: 9}}, - newText: ', b', - }, - ]); - - expect( - getEditsForImport( - importFormatter, - '/a/test.js', - { - id: 'c', - uri: '/a/test2.js', - line: 1, - isTypeExport: false, - isDefault: false, - }, - getProgramBody("const {a, b} = require('./test2');"), - ), - ).toEqual([ - { - range: {start: {line: 0, character: 11}, end: {line: 0, character: 11}}, - newText: ', c', - }, - ]); - - expect( - getEditsForImport( - importFormatter, - '/a/test.js', - { - id: 'newType', - uri: '/a/test2.js', - line: 1, - isTypeExport: true, - isDefault: false, - }, - getProgramBody( - [ - 'import type {', - ' type1,', - ' type2,', - ' type3,', - ' type4,', - '} from "./test2"', - ].join('\n'), - ), - ), - ).toEqual([ - { - range: {start: {line: 4, character: 7}, end: {line: 4, character: 7}}, - newText: ',\n newType', - }, - ]); + const importFormatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter([], false); + expect((0, (_CommandExecutor || _load_CommandExecutor()).getEditsForImport)(importFormatter, '/a/test.js', { + id: 'b', + uri: '/a/test2.js', + line: 1, + isTypeExport: false, + isDefault: false + }, getProgramBody("import type {a} from './test2';\nimport {a} from './test2';"))).toEqual([{ + range: { start: { line: 1, character: 9 }, end: { line: 1, character: 9 } }, + newText: ', b' + }]); + + expect((0, (_CommandExecutor || _load_CommandExecutor()).getEditsForImport)(importFormatter, '/a/test.js', { + id: 'c', + uri: '/a/test2.js', + line: 1, + isTypeExport: false, + isDefault: false + }, getProgramBody("const {a, b} = require('./test2');"))).toEqual([{ + range: { start: { line: 0, character: 11 }, end: { line: 0, character: 11 } }, + newText: ', c' + }]); + + expect((0, (_CommandExecutor || _load_CommandExecutor()).getEditsForImport)(importFormatter, '/a/test.js', { + id: 'newType', + uri: '/a/test2.js', + line: 1, + isTypeExport: true, + isDefault: false + }, getProgramBody(['import type {', ' type1,', ' type2,', ' type3,', ' type4,', '} from "./test2"'].join('\n')))).toEqual([{ + range: { start: { line: 4, character: 7 }, end: { line: 4, character: 7 } }, + newText: ',\n newType' + }]); }); it('groups imports/requires with their own kind', () => { @@ -259,38 +167,20 @@ import {x} from 'abc'; const z = require('xyz'); `; - const importFormatter = new ImportFormatter(['node_modules'], true); + const importFormatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter(['node_modules'], true); function getExport(id, uri, isTypeExport = false, isDefault = false) { - return {id, uri, line: 1, isTypeExport, isDefault}; + return { id, uri, line: 1, isTypeExport, isDefault }; } - expect( - getEditsForImport( - importFormatter, - '/a/test.js', - getExport('test', 'node_modules/def', false), - getProgramBody(sourceFile), - ), - ).toEqual([ - { - range: {start: {line: 5, character: 0}, end: {line: 5, character: 0}}, - newText: "const {test} = require('def');\n", - }, - ]); + expect((0, (_CommandExecutor || _load_CommandExecutor()).getEditsForImport)(importFormatter, '/a/test.js', getExport('test', 'node_modules/def', false), getProgramBody(sourceFile))).toEqual([{ + range: { start: { line: 5, character: 0 }, end: { line: 5, character: 0 } }, + newText: "const {test} = require('def');\n" + }]); importFormatter.useRequire = false; - expect( - getEditsForImport( - importFormatter, - '/a/test.js', - getExport('test', 'node_modules/def', false), - getProgramBody(sourceFile), - ), - ).toEqual([ - { - range: {start: {line: 4, character: 0}, end: {line: 4, character: 0}}, - newText: "import {test} from 'def';\n", - }, - ]); + expect((0, (_CommandExecutor || _load_CommandExecutor()).getEditsForImport)(importFormatter, '/a/test.js', getExport('test', 'node_modules/def', false), getProgramBody(sourceFile))).toEqual([{ + range: { start: { line: 4, character: 0 }, end: { line: 4, character: 0 } }, + newText: "import {test} from 'def';\n" + }]); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/__tests__/Completions-test.js b/pkg/nuclide-js-imports-server/__tests__/Completions-test.js index 45c0d0b264..e95972c3aa 100644 --- a/pkg/nuclide-js-imports-server/__tests__/Completions-test.js +++ b/pkg/nuclide-js-imports-server/__tests__/Completions-test.js @@ -1,45 +1,42 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import {ImportFormatter} from '../src/lib/ImportFormatter'; -import { - getImportInformation, - provideFullImportCompletions, - provideImportFileCompletions, -} from '../src/Completions'; -import {AutoImportsManager} from '../src/lib/AutoImportsManager'; +var _ImportFormatter; + +function _load_ImportFormatter() { + return _ImportFormatter = require('../src/lib/ImportFormatter'); +} + +var _Completions; + +function _load_Completions() { + return _Completions = require('../src/Completions'); +} + +var _AutoImportsManager; + +function _load_AutoImportsManager() { + return _AutoImportsManager = require('../src/lib/AutoImportsManager'); +} describe('getImportInformation', () => { it('Should correctly parse value imports', () => { - const importInformation = getImportInformation('import {something}'); + const importInformation = (0, (_Completions || _load_Completions()).getImportInformation)('import {something}'); expect(importInformation).toBeDefined(); expect(importInformation && importInformation.ids.length).toBe(1); expect(importInformation && importInformation.ids[0]).toBe('something'); - expect(importInformation && importInformation.importType).toBe( - 'namedValue', - ); + expect(importInformation && importInformation.importType).toBe('namedValue'); expect(importInformation && importInformation.isComplete).toBe(true); }); it('Should correctly parse default imports', () => { - const importInformation = getImportInformation('import TextDocuments '); + const importInformation = (0, (_Completions || _load_Completions()).getImportInformation)('import TextDocuments '); expect(importInformation).toBeDefined(); expect(importInformation && importInformation.ids.length).toBe(1); expect(importInformation && importInformation.ids[0]).toBe('TextDocuments'); - expect(importInformation && importInformation.importType).toBe( - 'defaultValue', - ); + expect(importInformation && importInformation.importType).toBe('defaultValue'); expect(importInformation && importInformation.isComplete).toBe(true); }); it('Should correctly parse type imports', () => { - const importInformation = getImportInformation('import type {SomeType }'); + const importInformation = (0, (_Completions || _load_Completions()).getImportInformation)('import type {SomeType }'); expect(importInformation).toBeDefined(); expect(importInformation && importInformation.ids.length).toBe(1); expect(importInformation && importInformation.ids[0]).toBe('SomeType'); @@ -47,24 +44,18 @@ describe('getImportInformation', () => { expect(importInformation && importInformation.isComplete).toBe(true); }); it('Should correctly parse multiple values', () => { - const importInformation = getImportInformation( - 'import {one, two, three, four}', - ); + const importInformation = (0, (_Completions || _load_Completions()).getImportInformation)('import {one, two, three, four}'); expect(importInformation).toBeDefined(); expect(importInformation && importInformation.ids.length).toBe(4); expect(importInformation && importInformation.ids[0]).toBe('one'); expect(importInformation && importInformation.ids[1]).toBe('two'); expect(importInformation && importInformation.ids[2]).toBe('three'); expect(importInformation && importInformation.ids[3]).toBe('four'); - expect(importInformation && importInformation.importType).toBe( - 'namedValue', - ); + expect(importInformation && importInformation.importType).toBe('namedValue'); expect(importInformation && importInformation.isComplete).toBe(true); }); it('Should correctly parse multiple types', () => { - const importInformation = getImportInformation( - 'import type {One, Two, Three, Four,}', - ); + const importInformation = (0, (_Completions || _load_Completions()).getImportInformation)('import type {One, Two, Three, Four,}'); expect(importInformation).toBeDefined(); expect(importInformation && importInformation.ids.length).toBe(4); expect(importInformation && importInformation.ids[0]).toBe('One'); @@ -74,75 +65,55 @@ describe('getImportInformation', () => { expect(importInformation && importInformation.importType).toBe('namedType'); }); it('Should ignore extra whitespace', () => { - const importInformation = getImportInformation( - ' import { something } ', - ); + const importInformation = (0, (_Completions || _load_Completions()).getImportInformation)(' import { something } '); expect(importInformation).toBeDefined(); expect(importInformation && importInformation.ids.length).toBe(1); expect(importInformation && importInformation.ids[0]).toBe('something'); expect(importInformation && importInformation.isComplete).toBe(true); }); it('Should handle importing type defaults', () => { - const importInformation = getImportInformation( - 'import type TextDocuments ', - ); + const importInformation = (0, (_Completions || _load_Completions()).getImportInformation)('import type TextDocuments '); expect(importInformation).toBeDefined(); expect(importInformation && importInformation.ids.length).toBe(1); expect(importInformation && importInformation.ids[0]).toBe('TextDocuments'); - expect(importInformation && importInformation.importType).toBe( - 'defaultType', - ); + expect(importInformation && importInformation.importType).toBe('defaultType'); expect(importInformation && importInformation.isComplete).toBe(true); }); it('Should handle all valid Javascript identifiers', () => { - const importInformation = getImportInformation( - 'import {WORKSPACE_VIEW_URI, $DOLLAR_SIGNS$}', - ); + const importInformation = (0, (_Completions || _load_Completions()).getImportInformation)('import {WORKSPACE_VIEW_URI, $DOLLAR_SIGNS$}'); expect(importInformation).toBeDefined(); expect(importInformation && importInformation.ids.length).toBe(2); - expect(importInformation && importInformation.ids[0]).toBe( - 'WORKSPACE_VIEW_URI', - ); - expect(importInformation && importInformation.ids[1]).toBe( - '$DOLLAR_SIGNS$', - ); - expect(importInformation && importInformation.importType).toBe( - 'namedValue', - ); + expect(importInformation && importInformation.ids[0]).toBe('WORKSPACE_VIEW_URI'); + expect(importInformation && importInformation.ids[1]).toBe('$DOLLAR_SIGNS$'); + expect(importInformation && importInformation.importType).toBe('namedValue'); expect(importInformation && importInformation.isComplete).toBe(true); }); it('Should correctly parse incomplete default import', () => { - const importInformation = getImportInformation('import TextDoc'); + const importInformation = (0, (_Completions || _load_Completions()).getImportInformation)('import TextDoc'); expect(importInformation).toBeDefined(); expect(importInformation && importInformation.ids.length).toBe(1); expect(importInformation && importInformation.ids[0]).toBe('TextDoc'); - expect(importInformation && importInformation.importType).toBe( - 'defaultValue', - ); + expect(importInformation && importInformation.importType).toBe('defaultValue'); expect(importInformation && importInformation.isComplete).toBe(false); }); it('Should correctly parse incomplete default type import', () => { - const importInformation = getImportInformation('import type TextDoc'); + const importInformation = (0, (_Completions || _load_Completions()).getImportInformation)('import type TextDoc'); expect(importInformation).toBeDefined(); expect(importInformation && importInformation.ids.length).toBe(1); expect(importInformation && importInformation.ids[0]).toBe('TextDoc'); - expect(importInformation && importInformation.importType).toBe( - 'defaultType', - ); + expect(importInformation && importInformation.importType).toBe('defaultType'); expect(importInformation && importInformation.isComplete).toBe(false); }); it('Should correctly parse incomplete named value import', () => { - const importInformation = getImportInformation('import {AutoImpor'); + const importInformation = (0, (_Completions || _load_Completions()).getImportInformation)('import {AutoImpor'); expect(importInformation).toBeDefined(); expect(importInformation && importInformation.ids.length).toBe(1); expect(importInformation && importInformation.ids[0]).toBe('AutoImpor'); - expect(importInformation && importInformation.importType).toBe( - 'namedValue', - ); + expect(importInformation && importInformation.importType).toBe('namedValue'); expect(importInformation && importInformation.isComplete).toBe(false); }); it('Should correctly parse incomplete named type import', () => { - const importInformation = getImportInformation('import type {AutoImpor'); + const importInformation = (0, (_Completions || _load_Completions()).getImportInformation)('import type {AutoImpor'); expect(importInformation).toBeDefined(); expect(importInformation && importInformation.ids.length).toBe(1); expect(importInformation && importInformation.ids[0]).toBe('AutoImpor'); @@ -150,80 +121,73 @@ describe('getImportInformation', () => { expect(importInformation && importInformation.isComplete).toBe(false); }); it('Should correctly parse incomplete require', () => { - const importInformation = getImportInformation('const CSS'); + const importInformation = (0, (_Completions || _load_Completions()).getImportInformation)('const CSS'); expect(importInformation).toBeDefined(); expect(importInformation && importInformation.ids.length).toBe(1); expect(importInformation && importInformation.ids[0]).toBe('CSS'); - expect(importInformation && importInformation.importType).toBe( - 'requireImport', - ); + expect(importInformation && importInformation.importType).toBe('requireImport'); expect(importInformation && importInformation.isComplete).toBe(false); }); it('Should correctly parse complete require', () => { - const importInformation = getImportInformation('const CSS '); + const importInformation = (0, (_Completions || _load_Completions()).getImportInformation)('const CSS '); expect(importInformation).toBeDefined(); expect(importInformation && importInformation.ids.length).toBe(1); expect(importInformation && importInformation.ids[0]).toBe('CSS'); - expect(importInformation && importInformation.importType).toBe( - 'requireImport', - ); + expect(importInformation && importInformation.importType).toBe('requireImport'); expect(importInformation && importInformation.isComplete).toBe(true); }); it('Should not match const with leading whitespace', () => { - let importInformation = getImportInformation(' const CSS'); + let importInformation = (0, (_Completions || _load_Completions()).getImportInformation)(' const CSS'); expect(importInformation).toBeNull(); - importInformation = getImportInformation(' const CSS'); + importInformation = (0, (_Completions || _load_Completions()).getImportInformation)(' const CSS'); expect(importInformation).toBeNull(); - importInformation = getImportInformation(' const CSS'); + importInformation = (0, (_Completions || _load_Completions()).getImportInformation)(' const CSS'); expect(importInformation).toBeNull(); }); it('Should correctly parse destructured require statement', () => { - const importInformation = getImportInformation( - 'const {someId, someOtherType}', - ); + const importInformation = (0, (_Completions || _load_Completions()).getImportInformation)('const {someId, someOtherType}'); expect(importInformation).toBeDefined(); expect(importInformation && importInformation.ids.length).toBe(2); expect(importInformation && importInformation.ids[0]).toBe('someId'); expect(importInformation && importInformation.ids[1]).toBe('someOtherType'); - expect(importInformation && importInformation.importType).toBe( - 'requireDestructured', - ); + expect(importInformation && importInformation.importType).toBe('requireDestructured'); expect(importInformation && importInformation.isComplete).toBe(true); }); it('Should correctly parse incomplete destructured require statement', () => { - const importInformation = getImportInformation('const {some'); + const importInformation = (0, (_Completions || _load_Completions()).getImportInformation)('const {some'); expect(importInformation).toBeDefined(); expect(importInformation && importInformation.ids.length).toBe(1); expect(importInformation && importInformation.ids[0]).toBe('some'); - expect(importInformation && importInformation.importType).toBe( - 'requireDestructured', - ); + expect(importInformation && importInformation.importType).toBe('requireDestructured'); expect(importInformation && importInformation.isComplete).toBe(false); }); -}); +}); /** + * 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. + * + * strict-local + * @format + */ describe('Completion Functions', () => { let autoImportsManager; let importsFormatter; beforeEach(() => { - autoImportsManager = new AutoImportsManager([]); - importsFormatter = new ImportFormatter(['/a/node_modules'], false); + autoImportsManager = new (_AutoImportsManager || _load_AutoImportsManager()).AutoImportsManager([]); + importsFormatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter(['/a/node_modules'], false); autoImportsManager.indexFile('/a/b/test2.js', 'export function test2() {}'); - autoImportsManager.indexFile( - '/a/above.js', - 'export function test() {}\nexport function testAbove() {}', - ); + autoImportsManager.indexFile('/a/above.js', 'export function test() {}\nexport function testAbove() {}'); autoImportsManager.indexFile('/a/b/test3.js', 'export function test() {}'); - autoImportsManager.indexFile( - '/a/node_modules/module', - 'export function test() {}\nexport class MyClass {}', - ); + autoImportsManager.indexFile('/a/node_modules/module', 'export function test() {}\nexport class MyClass {}'); }); function getCompletionText(completion) { - const {textEdit} = completion; + const { textEdit } = completion; if (textEdit == null) { return ''; } @@ -235,25 +199,12 @@ describe('Completion Functions', () => { const importInformation = { ids: ['test'], importType: 'namedValue', - isComplete: false, + isComplete: false }; - const completions = provideFullImportCompletions( - importInformation, - importsFormatter, - autoImportsManager, - '/a/b/test.js', - '', - 0, - ); + const completions = (0, (_Completions || _load_Completions()).provideFullImportCompletions)(importInformation, importsFormatter, autoImportsManager, '/a/b/test.js', '', 0); // 1) IDs need to be ordered by relevance. // 2) For the same ID, prefer node modules -> same directory -> other directories. - expect(completions.map(getCompletionText)).toEqual([ - "import {test} from './test3';", - "import {test} from '../above';", - "import {test} from 'module';", - "import {test2} from './test2';", - "import {testAbove} from '../above';", - ]); + expect(completions.map(getCompletionText)).toEqual(["import {test} from './test3';", "import {test} from '../above';", "import {test} from 'module';", "import {test2} from './test2';", "import {testAbove} from '../above';"]); }); }); @@ -262,88 +213,43 @@ describe('Completion Functions', () => { const importInformation = { ids: ['test', 'testAbove'], importType: 'namedValue', - isComplete: false, + isComplete: false }; - const completions = provideImportFileCompletions( - importInformation, - importsFormatter, - autoImportsManager, - '/a/b/test.js', - '', - 0, - ); - expect(completions.map(getCompletionText)).toEqual([ - "import {test, testAbove} from '../above';", - ]); + const completions = (0, (_Completions || _load_Completions()).provideImportFileCompletions)(importInformation, importsFormatter, autoImportsManager, '/a/b/test.js', '', 0); + expect(completions.map(getCompletionText)).toEqual(["import {test, testAbove} from '../above';"]); importInformation.ids = ['test']; - const singleCompletions = provideImportFileCompletions( - importInformation, - importsFormatter, - autoImportsManager, - '/a/b/test.js', - '', - 0, - ); - expect(singleCompletions.map(getCompletionText)).toEqual([ - "import {test} from './test3';", - "import {test} from '../above';", - "import {test} from 'module';", - ]); + const singleCompletions = (0, (_Completions || _load_Completions()).provideImportFileCompletions)(importInformation, importsFormatter, autoImportsManager, '/a/b/test.js', '', 0); + expect(singleCompletions.map(getCompletionText)).toEqual(["import {test} from './test3';", "import {test} from '../above';", "import {test} from 'module';"]); }); it('does not complete within the same file', () => { const importInformation = { ids: ['test'], importType: 'namedValue', - isComplete: false, + isComplete: false }; - const completions = provideImportFileCompletions( - importInformation, - importsFormatter, - autoImportsManager, - '/a/b/test3.js', - '', - 0, - ); + const completions = (0, (_Completions || _load_Completions()).provideImportFileCompletions)(importInformation, importsFormatter, autoImportsManager, '/a/b/test3.js', '', 0); expect(completions.map(getCompletionText)).toEqual([ - // Note the absence of test3.js. - "import {test} from '../above';", - "import {test} from 'module';", - ]); + // Note the absence of test3.js. + "import {test} from '../above';", "import {test} from 'module';"]); }); it('does not suggest functions for type imports', () => { const importInformation = { ids: ['test'], importType: 'namedType', - isComplete: false, + isComplete: false }; - const completions = provideImportFileCompletions( - importInformation, - importsFormatter, - autoImportsManager, - '/a/b/test3.js', - '', - 0, - ); + const completions = (0, (_Completions || _load_Completions()).provideImportFileCompletions)(importInformation, importsFormatter, autoImportsManager, '/a/b/test3.js', '', 0); expect(completions.map(getCompletionText)).toEqual([]); }); it('suggests classes for type imports', () => { const importInformation = { ids: ['MyClass'], importType: 'namedType', - isComplete: false, + isComplete: false }; - const completions = provideImportFileCompletions( - importInformation, - importsFormatter, - autoImportsManager, - '/a/b/test3.js', - '', - 0, - ); - expect(completions.map(getCompletionText)).toEqual([ - "import type {MyClass} from 'module';", - ]); + const completions = (0, (_Completions || _load_Completions()).provideImportFileCompletions)(importInformation, importsFormatter, autoImportsManager, '/a/b/test3.js', '', 0); + expect(completions.map(getCompletionText)).toEqual(["import type {MyClass} from 'module';"]); }); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/__tests__/ExportIndex-test.js b/pkg/nuclide-js-imports-server/__tests__/ExportIndex-test.js index 120daab62e..d204328e86 100644 --- a/pkg/nuclide-js-imports-server/__tests__/ExportIndex-test.js +++ b/pkg/nuclide-js-imports-server/__tests__/ExportIndex-test.js @@ -1,96 +1,79 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import {ExportIndex} from '../src/lib/ExportIndex'; +var _ExportIndex; + +function _load_ExportIndex() { + return _ExportIndex = require('../src/lib/ExportIndex'); +} describe('ExportIndex', () => { it('should filter by prefix', () => { - const exportIndex = new ExportIndex(); - exportIndex.setAll('someFile.js', [ - { - id: 'SomeExport', - isDefault: false, - isTypeExport: false, - uri: 'someFile.js', - line: 1, - }, - { - id: 'SomeExport2', - isDefault: false, - isTypeExport: false, - uri: 'someFile.js', - line: 1, - }, - { - id: 'AnotherExport', - isDefault: false, - isTypeExport: false, - uri: 'someFile.js', - line: 1, - }, - ]); + const exportIndex = new (_ExportIndex || _load_ExportIndex()).ExportIndex(); + exportIndex.setAll('someFile.js', [{ + id: 'SomeExport', + isDefault: false, + isTypeExport: false, + uri: 'someFile.js', + line: 1 + }, { + id: 'SomeExport2', + isDefault: false, + isTypeExport: false, + uri: 'someFile.js', + line: 1 + }, { + id: 'AnotherExport', + isDefault: false, + isTypeExport: false, + uri: 'someFile.js', + line: 1 + }]); const ids = exportIndex.getIdsMatching('Some', 10); expect(ids.length).toBe(2); expect(ids.find(e => e === 'SomeExport')).toBeDefined(); expect(ids.find(e => e === 'SomeExport2')).toBeDefined(); }); it('should filter by prefix after files have been cleared', () => { - const exportIndex = new ExportIndex(); - exportIndex.setAll('someFile.js', [ - { - id: 'AutoImportsManager', - isDefault: false, - isTypeExport: false, - uri: 'someFile.js', - line: 1, - }, - { - id: 'AutoImportsManager-spec.js', - isDefault: false, - isTypeExport: false, - uri: 'someFile.js', - line: 1, - }, - { - id: 'AutoImportsWorker', - isDefault: false, - isTypeExport: false, - uri: 'someFile.js', - line: 1, - }, - { - id: 'AutoImports', - isDefault: false, - isTypeExport: false, - uri: 'someFile.js', - line: 1, - }, - ]); + const exportIndex = new (_ExportIndex || _load_ExportIndex()).ExportIndex(); + exportIndex.setAll('someFile.js', [{ + id: 'AutoImportsManager', + isDefault: false, + isTypeExport: false, + uri: 'someFile.js', + line: 1 + }, { + id: 'AutoImportsManager-spec.js', + isDefault: false, + isTypeExport: false, + uri: 'someFile.js', + line: 1 + }, { + id: 'AutoImportsWorker', + isDefault: false, + isTypeExport: false, + uri: 'someFile.js', + line: 1 + }, { + id: 'AutoImports', + isDefault: false, + isTypeExport: false, + uri: 'someFile.js', + line: 1 + }]); exportIndex.clearExportsFromFile('someFile.js'); - exportIndex.setAll('someFile.js', [ - { - id: 'AutoImportsWorker', - isDefault: false, - isTypeExport: false, - uri: 'someFile.js', - line: 1, - }, - { - id: 'SomethingElse', - isDefault: false, - isTypeExport: false, - uri: 'someFile.js', - line: 1, - }, - ]); + exportIndex.setAll('someFile.js', [{ + id: 'AutoImportsWorker', + isDefault: false, + isTypeExport: false, + uri: 'someFile.js', + line: 1 + }, { + id: 'SomethingElse', + isDefault: false, + isTypeExport: false, + uri: 'someFile.js', + line: 1 + }]); const ids = exportIndex.getIdsMatching('Auto', 100); expect(ids.length).toBe(1); const ids2 = exportIndex.getIdsMatching('SomethingElse', 100); @@ -99,27 +82,32 @@ describe('ExportIndex', () => { expect(ids3.length).toBe(1); }); it('should fuzzy match', () => { - const exportIndex = new ExportIndex(); - exportIndex.setAll('someFile.js', [ - { - id: 'SomeClass', - isDefault: false, - isTypeExport: false, - uri: 'someFile.js', - line: 1, - }, - ]); - exportIndex.setAll('anotherFile.js', [ - { - id: 'SomeOtherClass', - isDefault: false, - isTypeExport: false, - uri: 'anotherFile.js', - line: 1, - }, - ]); + const exportIndex = new (_ExportIndex || _load_ExportIndex()).ExportIndex(); + exportIndex.setAll('someFile.js', [{ + id: 'SomeClass', + isDefault: false, + isTypeExport: false, + uri: 'someFile.js', + line: 1 + }]); + exportIndex.setAll('anotherFile.js', [{ + id: 'SomeOtherClass', + isDefault: false, + isTypeExport: false, + uri: 'anotherFile.js', + line: 1 + }]); exportIndex.clearExportsFromFile('someFile.js'); const ids = exportIndex.getIdsMatching('SeOther', 100); expect(ids.length).toBe(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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/__tests__/ExportManager-test.js b/pkg/nuclide-js-imports-server/__tests__/ExportManager-test.js index a646e4ce25..b3e7a2f72e 100644 --- a/pkg/nuclide-js-imports-server/__tests__/ExportManager-test.js +++ b/pkg/nuclide-js-imports-server/__tests__/ExportManager-test.js @@ -1,3 +1,19 @@ +'use strict'; + +var _ExportManager; + +function _load_ExportManager() { + return _ExportManager = require('../src/lib/ExportManager'); +} + +var _babylon; + +function _load_babylon() { + return _babylon = _interopRequireWildcard(require('babylon')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,29 +21,20 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import {ExportManager} from '../src/lib/ExportManager'; -import * as babylon from 'babylon'; - const babylonOptions = { sourceType: 'module', - plugins: [ - 'jsx', - 'flow', - 'exportExtensions', - 'exportNamespaceFrom', - 'objectRestSpread', - ], + plugins: ['jsx', 'flow', 'exportExtensions', 'exportNamespaceFrom', 'objectRestSpread'] }; describe('ExportManager', () => { it('Should index let export', () => { const program = 'export let x = 3;'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile', ast); const exp = manager.getExportsIndex().getExportsFromId('x'); expect(exp).toBeDefined(); @@ -40,8 +47,8 @@ describe('ExportManager', () => { }); it('Should index class export', () => { const program = 'export class NewClass {};'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile', ast); const exp = manager.getExportsIndex().getExportsFromId('NewClass'); expect(exp).toBeDefined(); @@ -54,8 +61,8 @@ describe('ExportManager', () => { }); it('Should index default class export', () => { const program = 'export default class NewClass {};'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile', ast); const exp = manager.getExportsIndex().getExportsFromId('NewClass'); expect(exp).toBeDefined(); @@ -68,8 +75,8 @@ describe('ExportManager', () => { }); it('Should index function export', () => { const program = 'export function myFunc(){return 1;};'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile', ast); const exp = manager.getExportsIndex().getExportsFromId('myFunc'); expect(exp).toBeDefined(); @@ -82,8 +89,8 @@ describe('ExportManager', () => { }); it('Should index default function export', () => { const program = 'export default function myFunc(){ return 1;};'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile', ast); const exp = manager.getExportsIndex().getExportsFromId('myFunc'); expect(exp).toBeDefined(); @@ -96,8 +103,8 @@ describe('ExportManager', () => { }); it('Should index variable export', () => { const program = 'const x = 3; export {x}; '; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile', ast); const exp = manager.getExportsIndex().getExportsFromId('x'); expect(exp).toBeDefined(); @@ -110,8 +117,8 @@ describe('ExportManager', () => { }); it('Should index multiple variables export', () => { const program = 'const x = 3; const y = 4; export {x, y}; '; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile', ast); const expX = manager.getExportsIndex().getExportsFromId('x'); expect(expX).toBeDefined(); @@ -131,8 +138,8 @@ describe('ExportManager', () => { }); it('Should index variable default export', () => { const program = 'const x = 3; export default x;'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile', ast); const exp = manager.getExportsIndex().getExportsFromId('x'); expect(exp).toBeDefined(); @@ -143,10 +150,9 @@ describe('ExportManager', () => { expect(exp[0].isDefault).toBe(true); }); it('Should index type exports', () => { - const program = - "type Foo = 'string'; type Bar = 'number'; export type {Foo, Bar};"; - const ast = babylon.parse(program, babylonOptions); - const manager = new ExportManager(); + const program = "type Foo = 'string'; type Bar = 'number'; export type {Foo, Bar};"; + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); manager.addFile('testFile', ast); const expFoo = manager.getExportsIndex().getExportsFromId('Foo'); expect(expFoo).toBeDefined(); @@ -166,14 +172,14 @@ describe('ExportManager', () => { }); it('Should handle empty export', () => { const program = 'export {}'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile', ast); }); it('Should index module.exports with named function', () => { const program = 'module.exports = function myFunc(){};'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile', ast); const exp = manager.getExportsIndex().getExportsFromId('myFunc'); expect(exp).toBeDefined(); @@ -185,21 +191,19 @@ describe('ExportManager', () => { expect(exp[0].isDefault).toBe(true); // Treat the filename as a default export too. const defaultExp = manager.getExportsIndex().getExportsFromId('testFile'); - expect(defaultExp).toEqual([ - { - id: 'testFile', - isTypeExport: false, - type: 'ObjectExpression', - uri: 'testFile', - line: 1, - isDefault: true, - }, - ]); + expect(defaultExp).toEqual([{ + id: 'testFile', + isTypeExport: false, + type: 'ObjectExpression', + uri: 'testFile', + line: 1, + isDefault: true + }]); }); it('Should index module.exports with object', () => { const program = "module.exports = {foo: 'foo', bar: 'bar'}"; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile', ast); const exp = manager.getExportsIndex().getExportsFromId('foo'); expect(exp).toBeDefined(); @@ -212,18 +216,17 @@ describe('ExportManager', () => { }); // TODO: actually index the values of the spread. it('Should index module.exports with a spread', () => { - const program = - "const X = {}; module.exports = {...X, [foo]: 'ignore', foo: 'foo'}"; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const program = "const X = {}; module.exports = {...X, [foo]: 'ignore', foo: 'foo'}"; + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile', ast); const exp = manager.getExportsIndex().getExportsFromId('foo'); expect(exp).toBeDefined(); }); it('Should index module.exports with quoted key', () => { const program = "const val = 3; module.exports = {'SOME_KEY': 3,}"; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile', ast); const exp = manager.getExportsIndex().getExportsFromId('SOME_KEY'); expect(exp.length).toBe(1); @@ -231,8 +234,8 @@ describe('ExportManager', () => { }); it('Should index exports member expressions', () => { const program = 'exports.SOME_KEY = 3;'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile', ast); const exp = manager.getExportsIndex().getExportsFromId('SOME_KEY'); expect(exp.length).toBe(1); @@ -241,8 +244,8 @@ describe('ExportManager', () => { }); it('Should index module.exports with named class', () => { const program = 'exports = class MyClass{};'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile', ast); const exp = manager.getExportsIndex().getExportsFromId('MyClass'); expect(exp).toBeDefined(); @@ -255,8 +258,8 @@ describe('ExportManager', () => { }); it('Should index module.exports with assignment', () => { const program = 'exports = test = 1;'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile', ast); const exp = manager.getExportsIndex().getExportsFromId('test'); expect(exp).toBeDefined(); @@ -270,9 +273,9 @@ describe('ExportManager', () => { it('Should index duplicate symbols in different files', () => { const program1 = 'export function Foo(){};'; const program2 = 'export class Foo{};'; - const manager = new ExportManager(); - const ast1 = babylon.parse(program1, babylonOptions); - const ast2 = babylon.parse(program2, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast1 = (_babylon || _load_babylon()).parse(program1, babylonOptions); + const ast2 = (_babylon || _load_babylon()).parse(program2, babylonOptions); manager.addFile('file1.js', ast1); manager.addFile('file2.js', ast2); const exp = manager.getExportsIndex().getExportsFromId('Foo'); @@ -283,15 +286,15 @@ describe('ExportManager', () => { }); it('Should clear file when added twice', () => { const program = 'export function Foo(){};'; - const manager = new ExportManager(); - let ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + let ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('file1.js', ast); let exp = manager.getExportsIndex().getExportsFromId('Foo'); expect(exp).toBeDefined(); expect(exp.length).toBe(1); const refactoredProgram = 'export function Bar(){};'; - ast = babylon.parse(refactoredProgram, babylonOptions); + ast = (_babylon || _load_babylon()).parse(refactoredProgram, babylonOptions); manager.addFile('file1.js', ast); exp = manager.getExportsIndex().getExportsFromId('Foo'); expect(exp).toBeDefined(); @@ -302,8 +305,8 @@ describe('ExportManager', () => { }); it('Should support export all with name', () => { const program = "export * as X from 'foo';"; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile.js', ast); const exp = manager.getExportsIndex().getExportsFromId('X'); expect(exp).toBeDefined(); @@ -312,9 +315,9 @@ describe('ExportManager', () => { it('Exports with same symbol in different files', () => { const program1 = 'export const b = 4;'; const program2 = 'const a = 1; const b = 2; export {a, b}'; - const ast1 = babylon.parse(program1, babylonOptions); - const ast2 = babylon.parse(program2, babylonOptions); - const manager = new ExportManager(); + const ast1 = (_babylon || _load_babylon()).parse(program1, babylonOptions); + const ast2 = (_babylon || _load_babylon()).parse(program2, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); manager.addFile('file1.js', ast1); manager.addFile('file2.js', ast2); const expA = manager.getExportsIndex().getExportsFromId('a'); @@ -326,8 +329,8 @@ describe('ExportManager', () => { }); it('Should support export default object', () => { const program = 'const a =1; const b = 2; export default {a, b}'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile.js', ast); const exp = manager.getExportsIndex().getExportsFromId('testFile'); expect(exp).toBeDefined(); @@ -335,8 +338,8 @@ describe('ExportManager', () => { }); it('Should support export default function', () => { const program = 'export default function(){}'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('testFile.js', ast); const exp = manager.getExportsIndex().getExportsFromId('testFile'); expect(exp).toBeDefined(); @@ -344,8 +347,8 @@ describe('ExportManager', () => { }); it('Should support export default array', () => { const program = 'export default [0, 1, 2, 3]'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('some-test-file.js', ast); const exp = manager.getExportsIndex().getExportsFromId('someTestFile'); expect(exp).toBeDefined(); @@ -353,8 +356,8 @@ describe('ExportManager', () => { }); it('Should index default unnamed exports with dashes as camelCase', () => { const program = 'const a =1; const b = 2; export default {a, b}'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('some-file.js', ast); const exp = manager.getExportsIndex().getExportsFromId('someFile'); expect(exp).toBeDefined(); @@ -362,23 +365,21 @@ describe('ExportManager', () => { }); it('Should index module.exports entire object as default', () => { const program = 'const a = 1; const b = 2; module.exports = {a, b}'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('SomeFileWithExports.js', ast); - const exp = manager - .getExportsIndex() - .getExportsFromId('SomeFileWithExports'); + const exp = manager.getExportsIndex().getExportsFromId('SomeFileWithExports'); expect(exp).toBeDefined(); expect(exp.length).toBe(1); }); it('Should index module.exports idenfitier default', () => { const program = 'const CSS = {}; module.exports = CSS'; - const manager = new ExportManager(); - const ast = babylon.parse(program, babylonOptions); + const manager = new (_ExportManager || _load_ExportManager()).ExportManager(); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); manager.addFile('SomeFileWithExports.js', ast); const exp = manager.getExportsIndex().getExportsFromId('CSS'); expect(exp).toBeDefined(); expect(exp.length).toBe(1); expect(exp[0].isDefault).toBe(true); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/__tests__/HasteUtils-test.js b/pkg/nuclide-js-imports-server/__tests__/HasteUtils-test.js index 2fc630e1a3..4687731f05 100644 --- a/pkg/nuclide-js-imports-server/__tests__/HasteUtils-test.js +++ b/pkg/nuclide-js-imports-server/__tests__/HasteUtils-test.js @@ -1,98 +1,96 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import nullthrows from 'nullthrows'; -import {getHasteName} from '../src/lib/HasteUtils'; -import {parseFile} from '../src/lib/AutoImportsManager'; +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _HasteUtils; + +function _load_HasteUtils() { + return _HasteUtils = require('../src/lib/HasteUtils'); +} + +var _AutoImportsManager; + +function _load_AutoImportsManager() { + return _AutoImportsManager = require('../src/lib/AutoImportsManager'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } describe('getHasteName', () => { it('returns null for non-haste files', () => { - const ast = nullthrows(parseFile('export function f() {}')); - expect( - getHasteName('/test.js', ast, { - isHaste: true, - useNameReducers: false, - nameReducers: [], - nameReducerWhitelist: [], - nameReducerBlacklist: [], - }), - ).toBe(null); + const ast = (0, (_nullthrows || _load_nullthrows()).default)((0, (_AutoImportsManager || _load_AutoImportsManager()).parseFile)('export function f() {}')); + expect((0, (_HasteUtils || _load_HasteUtils()).getHasteName)('/test.js', ast, { + isHaste: true, + useNameReducers: false, + nameReducers: [], + nameReducerWhitelist: [], + nameReducerBlacklist: [] + })).toBe(null); }); it('special-cases mocks', () => { - const ast = nullthrows(parseFile('/* @providesModule asdfasdf */')); - expect( - getHasteName('/__mocks__/test.mock.js', ast, { - isHaste: true, - useNameReducers: false, - nameReducers: [], - nameReducerWhitelist: [], - nameReducerBlacklist: [], - }), - ).toBe('test'); + const ast = (0, (_nullthrows || _load_nullthrows()).default)((0, (_AutoImportsManager || _load_AutoImportsManager()).parseFile)('/* @providesModule asdfasdf */')); + expect((0, (_HasteUtils || _load_HasteUtils()).getHasteName)('/__mocks__/test.mock.js', ast, { + isHaste: true, + useNameReducers: false, + nameReducers: [], + nameReducerWhitelist: [], + nameReducerBlacklist: [] + })).toBe('test'); }); it('detects @providesModule', () => { - const ast = nullthrows( - parseFile('/* @providesModule test1234\nblah */ export function f() {}'), - ); - expect( - getHasteName('/test.js', ast, { - isHaste: true, - useNameReducers: false, - nameReducers: [], - nameReducerWhitelist: [], - nameReducerBlacklist: [], - }), - ).toBe('test1234'); + const ast = (0, (_nullthrows || _load_nullthrows()).default)((0, (_AutoImportsManager || _load_AutoImportsManager()).parseFile)('/* @providesModule test1234\nblah */ export function f() {}')); + expect((0, (_HasteUtils || _load_HasteUtils()).getHasteName)('/test.js', ast, { + isHaste: true, + useNameReducers: false, + nameReducers: [], + nameReducerWhitelist: [], + nameReducerBlacklist: [] + })).toBe('test1234'); }); it('uses name reducers', () => { - const ast = nullthrows(parseFile('export function f() {}')); - const providesModuleAst = nullthrows( - parseFile('/* @providesModule test1234\nblah */ export function f() {}'), - ); + const ast = (0, (_nullthrows || _load_nullthrows()).default)((0, (_AutoImportsManager || _load_AutoImportsManager()).parseFile)('export function f() {}')); + const providesModuleAst = (0, (_nullthrows || _load_nullthrows()).default)((0, (_AutoImportsManager || _load_AutoImportsManager()).parseFile)('/* @providesModule test1234\nblah */ export function f() {}')); const hasteSettings = { isHaste: true, useNameReducers: true, nameReducers: [ - // basename - {regexp: /^.*\/([a-zA-Z0-9$_.-]+\.js(\.flow)?)$/, replacement: '$1'}, - // strip .js or .js.flow suffix - {regexp: /^(.*)\.js(\.flow)?$/, replacement: '$1'}, - ], + // basename + { regexp: /^.*\/([a-zA-Z0-9$_.-]+\.js(\.flow)?)$/, replacement: '$1' }, + // strip .js or .js.flow suffix + { regexp: /^(.*)\.js(\.flow)?$/, replacement: '$1' }], nameReducerWhitelist: [/\/a\/.*/], - nameReducerBlacklist: [/\/a\/b\/.*/], + nameReducerBlacklist: [/\/a\/b\/.*/] }; - expect(getHasteName('/a/test.js', ast, hasteSettings)).toBe('test'); - expect(getHasteName('/a/test2.js.flow', ast, hasteSettings)).toBe('test2'); - expect(getHasteName('/a/b/test.js', ast, hasteSettings)).toBe(null); - expect(getHasteName('/b/test.js', ast, hasteSettings)).toBe(null); + expect((0, (_HasteUtils || _load_HasteUtils()).getHasteName)('/a/test.js', ast, hasteSettings)).toBe('test'); + expect((0, (_HasteUtils || _load_HasteUtils()).getHasteName)('/a/test2.js.flow', ast, hasteSettings)).toBe('test2'); + expect((0, (_HasteUtils || _load_HasteUtils()).getHasteName)('/a/b/test.js', ast, hasteSettings)).toBe(null); + expect((0, (_HasteUtils || _load_HasteUtils()).getHasteName)('/b/test.js', ast, hasteSettings)).toBe(null); // Falls back to @providesModule, even when blacklisted. - expect(getHasteName('/b/test.js', providesModuleAst, hasteSettings)).toBe( - 'test1234', - ); + expect((0, (_HasteUtils || _load_HasteUtils()).getHasteName)('/b/test.js', providesModuleAst, hasteSettings)).toBe('test1234'); // No whitelist = everything - expect( - getHasteName('/c/test.js', ast, { - ...hasteSettings, - nameReducerWhitelist: [], - }), - ).toBe('test'); + expect((0, (_HasteUtils || _load_HasteUtils()).getHasteName)('/c/test.js', ast, Object.assign({}, hasteSettings, { + nameReducerWhitelist: [] + }))).toBe('test'); // Test default reducer - expect( - getHasteName('/a/test.js', ast, {...hasteSettings, nameReducers: []}), - ).toBe('test'); + expect((0, (_HasteUtils || _load_HasteUtils()).getHasteName)('/a/test.js', ast, Object.assign({}, hasteSettings, { nameReducers: [] }))).toBe('test'); }); -}); +}); /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/__tests__/ImportFormatter-test.js b/pkg/nuclide-js-imports-server/__tests__/ImportFormatter-test.js index d5ffda52dd..764f2806c0 100644 --- a/pkg/nuclide-js-imports-server/__tests__/ImportFormatter-test.js +++ b/pkg/nuclide-js-imports-server/__tests__/ImportFormatter-test.js @@ -1,175 +1,126 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import {ImportFormatter} from '../src/lib/ImportFormatter'; +var _ImportFormatter; -import type {JSExport} from '../src/lib/types'; +function _load_ImportFormatter() { + return _ImportFormatter = require('../src/lib/ImportFormatter'); +} describe('ImportFormatter', () => { it('Should properly format filenames', () => { - const suggestedImport: JSExport = { + const suggestedImport = { id: 'SomeSymbol', uri: '/Users/login/home/root/someFile.js', line: 1, isTypeExport: false, - isDefault: false, + isDefault: false }; - const formatter = new ImportFormatter([], false); - expect( - formatter.formatImportFile( - '/Users/login/home/root/subdirectory/file.js', - suggestedImport, - ), - ).toBe('../someFile'); + const formatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter([], false); + expect(formatter.formatImportFile('/Users/login/home/root/subdirectory/file.js', suggestedImport)).toBe('../someFile'); }); it('Should properly format filesnames with modules', () => { - const suggestedImport: JSExport = { + const suggestedImport = { id: 'SomeSymbol', uri: '/Users/login/home/root/subdirectory/modules/module1/someFile.js', line: 1, isTypeExport: false, - isDefault: false, + isDefault: false }; - const formatter = new ImportFormatter( - ['/Users/login/home/root/subdirectory/modules'], - false, - ); - expect( - formatter.formatImportFile( - '/Users/login/home/root/subdirectory/someProject/someSubdirectory/file.js', - suggestedImport, - ), - ).toBe('module1/someFile'); + const formatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter(['/Users/login/home/root/subdirectory/modules'], false); + expect(formatter.formatImportFile('/Users/login/home/root/subdirectory/someProject/someSubdirectory/file.js', suggestedImport)).toBe('module1/someFile'); }); it('Should properly format filesnames with leading period', () => { - const suggestedImport: JSExport = { + const suggestedImport = { id: 'SomeSymbol', uri: '/Users/login/home/root/subdirectory/types.js', line: 1, isTypeExport: false, - isDefault: false, + isDefault: false }; - const formatter = new ImportFormatter( - ['/Users/login/home/root/subdirectory/modules'], - false, - ); - expect( - formatter.formatImportFile( - '/Users/login/home/root/subdirectory/file.js', - suggestedImport, - ), - ).toBe('./types'); + const formatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter(['/Users/login/home/root/subdirectory/modules'], false); + expect(formatter.formatImportFile('/Users/login/home/root/subdirectory/file.js', suggestedImport)).toBe('./types'); }); it('Should properly format import statement for values', () => { - const suggestedImport: JSExport = { + const suggestedImport = { id: 'SomeSymbol', uri: '/Users/login/home/root/someFile.js', line: 1, isTypeExport: false, - isDefault: false, + isDefault: false }; - const formatter = new ImportFormatter([], false); - expect( - formatter.formatImport( - '/Users/login/home/root/subdirectory/file.js', - suggestedImport, - ), - ).toBe("import {SomeSymbol} from '../someFile';"); + const formatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter([], false); + expect(formatter.formatImport('/Users/login/home/root/subdirectory/file.js', suggestedImport)).toBe("import {SomeSymbol} from '../someFile';"); }); it('Should properly format import statement for types', () => { - const suggestedImport: JSExport = { + const suggestedImport = { id: 'SomeType', uri: '/Users/login/home/root/someFile.js', line: 1, isTypeExport: true, - isDefault: false, + isDefault: false }; - const formatter = new ImportFormatter([], false); - expect( - formatter.formatImport( - '/Users/login/home/root/subdirectory/file.js', - suggestedImport, - ), - ).toBe("import type {SomeType} from '../someFile';"); + const formatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter([], false); + expect(formatter.formatImport('/Users/login/home/root/subdirectory/file.js', suggestedImport)).toBe("import type {SomeType} from '../someFile';"); }); it('Should properly format import statement for default exports', () => { - const suggestedImport: JSExport = { + const suggestedImport = { id: 'SomeSymbol', uri: '/Users/login/home/root/someFile.js', line: 1, isTypeExport: false, - isDefault: true, + isDefault: true }; - const formatter = new ImportFormatter([], false); - expect( - formatter.formatImport( - '/Users/login/home/root/subdirectory/file.js', - suggestedImport, - ), - ).toBe("import SomeSymbol from '../someFile';"); + const formatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter([], false); + expect(formatter.formatImport('/Users/login/home/root/subdirectory/file.js', suggestedImport)).toBe("import SomeSymbol from '../someFile';"); }); it('Should provide a relative import for files within the same module', () => { - const suggestedImport: JSExport = { + const suggestedImport = { id: 'SomeSymbol', uri: '/Users/modules/atom-ide-ui/somePackage/someFile.js', line: 1, isTypeExport: false, - isDefault: true, + isDefault: true }; - const formatter = new ImportFormatter(['/Users/modules'], false); - expect( - formatter.formatImport( - '/Users/modules/atom-ide-ui/aDifferentPackage/lib/anotherFile.js', - suggestedImport, - ), - ).toBe("import SomeSymbol from '../../somePackage/someFile';"); + const formatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter(['/Users/modules'], false); + expect(formatter.formatImport('/Users/modules/atom-ide-ui/aDifferentPackage/lib/anotherFile.js', suggestedImport)).toBe("import SomeSymbol from '../../somePackage/someFile';"); }); it('Should NOT provide a relative import for files NOT within the same module', () => { - const suggestedImport: JSExport = { + const suggestedImport = { id: 'SomeSymbol', uri: '/Users/modules/atom-ide-ui/somePackage/someFile.js', line: 1, isTypeExport: false, - isDefault: true, + isDefault: true }; - const formatter = new ImportFormatter(['/Users/modules'], false); - expect( - formatter.formatImport( - '/Users/modules/nuclide-commons/aDifferentPackage/lib/anotherFile.js', - suggestedImport, - ), - ).toBe("import SomeSymbol from 'atom-ide-ui/somePackage/someFile';"); + const formatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter(['/Users/modules'], false); + expect(formatter.formatImport('/Users/modules/nuclide-commons/aDifferentPackage/lib/anotherFile.js', suggestedImport)).toBe("import SomeSymbol from 'atom-ide-ui/somePackage/someFile';"); }); it('Should correctly handle haste formatting with JS files', () => { - const suggestedImport: JSExport = { + const suggestedImport = { id: 'SomeSymbol', uri: '/Users/modules/somePackage/somePackage/AutoImportsManager.js', line: 1, hasteName: 'AutoImportsManagerHaste', isTypeExport: false, - isDefault: true, + isDefault: true }; - const formatter = new ImportFormatter([], true); - expect( - formatter.formatImportFile( - '/Users/modules/somePackage/somePackage/AutoImportsManager.js', - suggestedImport, - ), - ).toBe('AutoImportsManagerHaste'); + const formatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter([], true); + expect(formatter.formatImportFile('/Users/modules/somePackage/somePackage/AutoImportsManager.js', suggestedImport)).toBe('AutoImportsManagerHaste'); }); -}); +}); /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/__tests__/UndefinedSymbolManager-test.js b/pkg/nuclide-js-imports-server/__tests__/UndefinedSymbolManager-test.js index af78292e98..c29720e780 100644 --- a/pkg/nuclide-js-imports-server/__tests__/UndefinedSymbolManager-test.js +++ b/pkg/nuclide-js-imports-server/__tests__/UndefinedSymbolManager-test.js @@ -1,3 +1,19 @@ +'use strict'; + +var _babylon; + +function _load_babylon() { + return _babylon = _interopRequireWildcard(require('babylon')); +} + +var _UndefinedSymbolManager; + +function _load_UndefinedSymbolManager() { + return _UndefinedSymbolManager = require('../src/lib/UndefinedSymbolManager'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,24 +21,21 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import * as babylon from 'babylon'; -import {UndefinedSymbolManager} from '../src/lib/UndefinedSymbolManager'; - const babylonOptions = { sourceType: 'module', - plugins: ['jsx', 'flow', 'exportExtensions'], + plugins: ['jsx', 'flow', 'exportExtensions'] }; describe('UndefinedSymbolManager', () => { /* Value Tests */ it('Should find undefined values in a function', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'function myFunc(){return x; };'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(1); @@ -30,9 +43,9 @@ describe('UndefinedSymbolManager', () => { expect(undefinedSymbols[0].type).toBe('value'); }); it('Should find undefined React in JSX component', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'const x = ;'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(2); @@ -42,9 +55,9 @@ describe('UndefinedSymbolManager', () => { expect(undefinedSymbols[1].type).toBe('value'); }); it('Should find undefined React in JSX tag', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'const x =
    ;'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(1); @@ -52,9 +65,9 @@ describe('UndefinedSymbolManager', () => { expect(undefinedSymbols[0].type).toBe('value'); }); it('Should find undefined React in JSX fragment', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'const x = <>test;'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(1); @@ -62,9 +75,9 @@ describe('UndefinedSymbolManager', () => { expect(undefinedSymbols[0].type).toBe('value'); }); it('Should not find undefined React in JSX component with @csx tag', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = '/**@csx*/ const x = ;'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(1); @@ -72,9 +85,9 @@ describe('UndefinedSymbolManager', () => { expect(undefinedSymbols[0].type).toBe('value'); }); it('Should have special treatment for the fbt tag', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'const x = ;'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(1); @@ -82,35 +95,33 @@ describe('UndefinedSymbolManager', () => { expect(undefinedSymbols[0].type).toBe('value'); }); it('Should not declare all globals as undefined', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'var x = 10; function myFunc(){ return x; };'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(0); }); it('Should not declare as undefined if imported', () => { - const manager = new UndefinedSymbolManager([]); - const program = - "import {x} from './someFile'; function myFunc(){ return x;}"; - const ast = babylon.parse(program, babylonOptions); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); + const program = "import {x} from './someFile'; function myFunc(){ return x;}"; + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(0); }); it('Should not declare as undefined if declared after', () => { - const manager = new UndefinedSymbolManager([]); - const program = - 'export type Y = { f(x: X): void }; class X implements Y {}'; - const ast = babylon.parse(program, babylonOptions); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); + const program = 'export type Y = { f(x: X): void }; class X implements Y {}'; + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(0); }); it('Should find undefined object', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'myFunc.doSomething();'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(1); @@ -118,9 +129,9 @@ describe('UndefinedSymbolManager', () => { expect(undefinedSymbols[0].type).toBe('value'); }); it('Should catch undefined assignment', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'const val = iamnotdefined;'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(1); @@ -128,28 +139,28 @@ describe('UndefinedSymbolManager', () => { expect(undefinedSymbols[0].type).toBe('value'); }); it('Should allow loose declarations', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'iamnotdefined = 1; x = iamnotdefined;'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(0); }); it('Should allow labelled statements', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'loop: while (true) continue loop;'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(0); }); it('Should handle /* global */ comments', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = ` /* global Test, Test2: false, Test3 */ const x = Test + Test2 + Test3 + Test4; `; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(1); @@ -158,9 +169,9 @@ describe('UndefinedSymbolManager', () => { /* Type Tests */ it('Should find undeclared types in assignment', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'const val : MyType = 10'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(1); @@ -168,9 +179,9 @@ describe('UndefinedSymbolManager', () => { expect(undefinedSymbols[0].type).toBe('type'); }); it('Should find undeclared types in function', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'function myFunc(): SomeType {return 10;}'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(1); @@ -178,42 +189,41 @@ describe('UndefinedSymbolManager', () => { expect(undefinedSymbols[0].type).toBe('type'); }); it('Should not declare as undefined, if type is imported', () => { - const manager = new UndefinedSymbolManager([]); - const program = - "import type MyType from 'module'; const val : MyType = 10;"; - const ast = babylon.parse(program, babylonOptions); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); + const program = "import type MyType from 'module'; const val : MyType = 10;"; + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(0); }); it('Should not declare as undefined if declared as var', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'const x = {}; function myFunc(): x {}'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(0); }); it('Should not declare as undefined if declared as object destructure', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'const {x} = {}; function myFunc(): x {}'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(0); }); it('Should not declare as undefined if declared as array destructure', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'const [x] = []; function myFunc(): x {}'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols).toBeDefined(); expect(undefinedSymbols.length).toBe(0); }); it('Should store location correctly', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'new ClassThatDoesNotExist();'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols.length).toBe(1); expect(undefinedSymbols[0].id).toBe('ClassThatDoesNotExist'); @@ -226,120 +236,114 @@ describe('UndefinedSymbolManager', () => { /* False Positive Tests */ it('Builtins do not trigger diagnostics', () => { - const manager = new UndefinedSymbolManager(['']); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager(['']); const program = 'new Iterator();'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols.length).toBe(0); }); it('Globals do not trigger diagnostics', () => { - const manager = new UndefinedSymbolManager(['process']); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager(['process']); const program = 'const dir = process.cwd()'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols.length).toBe(0); }); it('Type identifiers should not trigger diagnostics', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'type MyType = {a: number, b: string}'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols.length).toBe(0); }); it('Class imports should be treated as types', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = "import {SomeClass} from 'file'; var instance: SomeClass; "; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols.length).toBe(0); }); it('TypeAliases are not treated as undeclared types', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = "type MyType = 'string' | 'number' "; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols.length).toBe(0); }); it('Keeps track of types declared before', () => { - const manager = new UndefinedSymbolManager([]); - const program = - "type MyType = 'string' | 'number'; const val: MyType = 10; "; - const ast = babylon.parse(program, babylonOptions); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); + const program = "type MyType = 'string' | 'number'; const val: MyType = 10; "; + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols.length).toBe(0); }); it('Keeps track of types declared after', () => { - const manager = new UndefinedSymbolManager([]); - const program = - "const val: MyType = 10; type MyType = 'string' | 'number';"; - const ast = babylon.parse(program, babylonOptions); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); + const program = "const val: MyType = 10; type MyType = 'string' | 'number';"; + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols.length).toBe(0); }); it('Works correctly with typeof', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'type X = typeof Y;'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols.length).toBe(1); expect(undefinedSymbols[0].id).toBe('Y'); expect(undefinedSymbols[0].type).toBe('value'); }); it('Works correctly with type members', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = 'type X = Immutable.Map.XYZ;'; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols.length).toBe(1); expect(undefinedSymbols[0].id).toBe('Immutable'); expect(undefinedSymbols[0].type).toBe('type'); }); it('No false positives with generics', () => { - const manager = new UndefinedSymbolManager([]); - const program = - 'class GenericList { returnsA(something: A): A { return something; }}'; - const ast = babylon.parse(program, babylonOptions); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); + const program = 'class GenericList { returnsA(something: A): A { return something; }}'; + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols.length).toBe(0); }); it('No false positives from ObjectTypeIndexers', () => { - const manager = new UndefinedSymbolManager([]); - const program = - 'type log4js$Config = { levels?: {[name: string]: string},}'; - const ast = babylon.parse(program, babylonOptions); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); + const program = 'type log4js$Config = { levels?: {[name: string]: string},}'; + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols.length).toBe(0); }); it('No false positives from React elements', () => { - const manager = new UndefinedSymbolManager([]); - const program = - "import React from 'react'; class Element {render(): React.Element {return (
  • );}}"; - const ast = babylon.parse(program, babylonOptions); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); + const program = "import React from 'react'; class Element {render(): React.Element {return (
  • );}}"; + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols.length).toBe(0); }); it('Do not provide undefined symbols for declared flow modules', () => { - const manager = new UndefinedSymbolManager([]); - const program = - "import SomeModule from 'a'; const thing: SomeModule.SomeType = 5;"; - const ast = babylon.parse(program, babylonOptions); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); + const program = "import SomeModule from 'a'; const thing: SomeModule.SomeType = 5;"; + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols.length).toBe(0); }); it('Should work with declare type', () => { - const manager = new UndefinedSymbolManager([]); + const manager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager([]); const program = ` declare type Options = {}; declare function f(options: Options): void; declare var Variable: string; `; - const ast = babylon.parse(program, babylonOptions); + const ast = (_babylon || _load_babylon()).parse(program, babylonOptions); const undefinedSymbols = manager.findUndefined(ast); expect(undefinedSymbols.length).toBe(0); }); it('should not error with non-standard environments', () => { // eslint-disable-next-line no-new - new UndefinedSymbolManager(['asdf']); + new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager(['asdf']); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/__tests__/getConfig-test.js b/pkg/nuclide-js-imports-server/__tests__/getConfig-test.js index 43967d25b9..55a1c48e72 100644 --- a/pkg/nuclide-js-imports-server/__tests__/getConfig-test.js +++ b/pkg/nuclide-js-imports-server/__tests__/getConfig-test.js @@ -1,127 +1,91 @@ -/** - * 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 - */ +'use strict'; -import * as globals from 'globals'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {getConfigFromFlow, getEslintGlobals} from '../src/Config'; +var _globals; + +function _load_globals() { + return _globals = _interopRequireWildcard(require('globals')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _Config; + +function _load_Config() { + return _Config = require('../src/Config'); +} + +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; } } describe('getConfig', () => { it('reads haste configs', () => { - const root = nuclideUri.join( - __dirname, - '../__mocks__/fixtures', - 'flowconfig_haste', - ); - expect(getConfigFromFlow(root)).toEqual({ - moduleDirs: [nuclideUri.join(root, 'node_modules')], + const root = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures', 'flowconfig_haste'); + expect((0, (_Config || _load_Config()).getConfigFromFlow)(root)).toEqual({ + moduleDirs: [(_nuclideUri || _load_nuclideUri()).default.join(root, 'node_modules')], hasteSettings: { isHaste: true, useNameReducers: true, - nameReducers: [ - {regexp: /^.*\/([a-zA-Z0-9$_.-]+\.js(\.flow)?)$/, replacement: '$1'}, - {regexp: /^(.*)\.js(\.flow)?$/, replacement: '$1'}, - ], + nameReducers: [{ regexp: /^.*\/([a-zA-Z0-9$_.-]+\.js(\.flow)?)$/, replacement: '$1' }, { regexp: /^(.*)\.js(\.flow)?$/, replacement: '$1' }], nameReducerWhitelist: [new RegExp(root + '/whitelist/.*')], - nameReducerBlacklist: [ - /.*\/__tests__\/.*/, - /.*\/__mocks__\/.*/, - new RegExp(root + '/blacklist/.*'), - ], - }, + nameReducerBlacklist: [/.*\/__tests__\/.*/, /.*\/__mocks__\/.*/, new RegExp(root + '/blacklist/.*')] + } }); }); it('reads modules', () => { - const root = nuclideUri.join( - __dirname, - '../__mocks__/fixtures', - 'flowconfig_modules', - ); - expect(getConfigFromFlow(root)).toEqual({ - moduleDirs: [ - nuclideUri.join(root, 'node_modules'), - nuclideUri.join(root, 'modules'), - nuclideUri.join(root, 'yarn_workspaces'), - nuclideUri.join(root, 'yarn_workspaces2'), - ], + const root = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures', 'flowconfig_modules'); + expect((0, (_Config || _load_Config()).getConfigFromFlow)(root)).toEqual({ + moduleDirs: [(_nuclideUri || _load_nuclideUri()).default.join(root, 'node_modules'), (_nuclideUri || _load_nuclideUri()).default.join(root, 'modules'), (_nuclideUri || _load_nuclideUri()).default.join(root, 'yarn_workspaces'), (_nuclideUri || _load_nuclideUri()).default.join(root, 'yarn_workspaces2')], hasteSettings: { isHaste: false, useNameReducers: false, nameReducers: [], nameReducerWhitelist: [], - nameReducerBlacklist: [], - }, + nameReducerBlacklist: [] + } }); }); -}); +}); /** + * 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. + * + * + * @format + */ describe('getEslintGlobals', () => { it('works on projects with .eslintrc', () => { - const root = nuclideUri.join( - __dirname, - '../__mocks__/fixtures', - 'eslintrc', - ); - expect(getEslintGlobals(root)).toEqual([ - 'atom', - 'window', - 'browser', - 'chrome', - 'opr', - ]); + const root = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures', 'eslintrc'); + expect((0, (_Config || _load_Config()).getEslintGlobals)(root)).toEqual(['atom', 'window', 'browser', 'chrome', 'opr']); }); it('works on projects with .eslintrc.js', () => { - const root = nuclideUri.join( - __dirname, - '../__mocks__/fixtures', - 'eslintrcjs', - ); - expect(getEslintGlobals(root)).toEqual([ - 'atom', - 'window', - 'browser', - 'chrome', - 'opr', - ]); + const root = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures', 'eslintrcjs'); + expect((0, (_Config || _load_Config()).getEslintGlobals)(root)).toEqual(['atom', 'window', 'browser', 'chrome', 'opr']); }); it('works on projects with an eslintConfig', () => { - const root = nuclideUri.join( - __dirname, - '../__mocks__/fixtures', - 'eslintConfig', - ); - expect(getEslintGlobals(root)).toEqual([ - 'atom', - 'window', - 'browser', - 'chrome', - 'opr', - ]); + const root = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures', 'eslintConfig'); + expect((0, (_Config || _load_Config()).getEslintGlobals)(root)).toEqual(['atom', 'window', 'browser', 'chrome', 'opr']); }); it('falls back to getting all environments', () => { - const root = nuclideUri.join( - __dirname, - '../__mocks__/fixtures', - 'flowconfig_modules', - ); + const root = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures', 'flowconfig_modules'); const allGlobals = new Set(); - Object.values(globals).forEach((obj: any) => { + Object.values(_globals || _load_globals()).forEach(obj => { Object.keys(obj).forEach(x => allGlobals.add(x)); }); - const eslintGlobals = getEslintGlobals(root); + const eslintGlobals = (0, (_Config || _load_Config()).getEslintGlobals)(root); expect(eslintGlobals).toContain('window'); expect(eslintGlobals).toContain('document'); expect(eslintGlobals).toEqual(Array.from(allGlobals)); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/cli/runOnProject.js b/pkg/nuclide-js-imports-server/cli/runOnProject.js index a7e368b152..3a755aad79 100644 --- a/pkg/nuclide-js-imports-server/cli/runOnProject.js +++ b/pkg/nuclide-js-imports-server/cli/runOnProject.js @@ -1,3 +1,53 @@ +'use strict'; + +var _os = _interopRequireDefault(require('os')); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _Config; + +function _load_Config() { + return _Config = require('../src/Config'); +} + +var _AutoImportsManager; + +function _load_AutoImportsManager() { + return _AutoImportsManager = require('../src/lib/AutoImportsManager'); +} + +var _AutoImportsWorker; + +function _load_AutoImportsWorker() { + return _AutoImportsWorker = require('../src/lib/AutoImportsWorker'); +} + +var _fileIndex; + +function _load_fileIndex() { + return _fileIndex = require('../src/lib/file-index'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,45 +55,27 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ /* eslint-disable no-console */ -import invariant from 'assert'; -import os from 'os'; -import {Observable} from 'rxjs'; -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {observeProcess} from 'nuclide-commons/process'; -import {getEslintGlobals, getConfigFromFlow} from '../src/Config'; -import {AutoImportsManager} from '../src/lib/AutoImportsManager'; -import {indexDirectory, indexNodeModules} from '../src/lib/AutoImportsWorker'; -import {getFileIndex} from '../src/lib/file-index'; - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -const DEFAULT_PROJECT_PATH = nuclideUri.join(__dirname, '..', '..', '..'); +const DEFAULT_PROJECT_PATH = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '..', '..', '..'); let numErrors = 0; let numFiles = 0; async function main() { - const root = - process.argv.length === 3 ? toPath(process.argv[2]) : DEFAULT_PROJECT_PATH; - - const autoImportsManager = new AutoImportsManager(getEslintGlobals(root)); - const configFromFlow = getConfigFromFlow(root); - const {hasteSettings} = configFromFlow; - - const index = await getFileIndex(root, configFromFlow); - const cpus = os.cpus(); - const indexDirStream = indexDirectory( - index, - hasteSettings, - cpus ? Math.max(1, cpus.length) : 1, - ).do({ + const root = process.argv.length === 3 ? toPath(process.argv[2]) : DEFAULT_PROJECT_PATH; + + const autoImportsManager = new (_AutoImportsManager || _load_AutoImportsManager()).AutoImportsManager((0, (_Config || _load_Config()).getEslintGlobals)(root)); + const configFromFlow = (0, (_Config || _load_Config()).getConfigFromFlow)(root); + const { hasteSettings } = configFromFlow; + + const index = await (0, (_fileIndex || _load_fileIndex()).getFileIndex)(root, configFromFlow); + const cpus = _os.default.cpus(); + const indexDirStream = (0, (_AutoImportsWorker || _load_AutoImportsWorker()).indexDirectory)(index, hasteSettings, cpus ? Math.max(1, cpus.length) : 1).do({ next: exportForFiles => { exportForFiles.forEach(exportForFile => { autoImportsManager.handleUpdateForFile(exportForFile); @@ -54,10 +86,10 @@ async function main() { }, complete: () => { console.log(`Finished indexing source code for ${root}`); - }, + } }); - const indexModulesStream = indexNodeModules(index).do({ + const indexModulesStream = (0, (_AutoImportsWorker || _load_AutoImportsWorker()).indexNodeModules)(index).do({ next: exportForFiles => { exportForFiles.forEach(exportForFile => { autoImportsManager.handleUpdateForFile(exportForFile); @@ -68,74 +100,49 @@ async function main() { }, complete: () => { console.log(`Finished indexing node modules ${root}`); - }, + } }); console.log('Began indexing all files'); // Check all files for missing imports - Observable.merge(indexModulesStream, indexDirStream) - .concat( - // Don't bother checking non-Flow files. - observeProcess('flow', [ - 'ls', - root, - '--ignore', - '.*/\\(node_modules\\|VendorLib\\|3rdParty\\)/.*', - ]) - .filter(event => event.kind === 'stdout') - .mergeMap(event => { - invariant(event.kind === 'stdout'); - return checkFileForMissingImports( - event.data.trim(), - autoImportsManager, - ); - }, 10), - ) - .subscribe({ - complete: () => { - // Report the results - console.log( - `Ran on ${numFiles} files. Terminated with ${numErrors} errors.`, - ); - process.exit(numErrors > 0 ? 1 : 0); - }, - }); + _rxjsBundlesRxMinJs.Observable.merge(indexModulesStream, indexDirStream).concat( + // Don't bother checking non-Flow files. + (0, (_process || _load_process()).observeProcess)('flow', ['ls', root, '--ignore', '.*/\\(node_modules\\|VendorLib\\|3rdParty\\)/.*']).filter(event => event.kind === 'stdout').mergeMap(event => { + if (!(event.kind === 'stdout')) { + throw new Error('Invariant violation: "event.kind === \'stdout\'"'); + } + + return checkFileForMissingImports(event.data.trim(), autoImportsManager); + }, 10)).subscribe({ + complete: () => { + // Report the results + console.log(`Ran on ${numFiles} files. Terminated with ${numErrors} errors.`); + process.exit(numErrors > 0 ? 1 : 0); + } + }); } -function checkFileForMissingImports( - file: NuclideUri, - autoImportsManager: AutoImportsManager, -) { +function checkFileForMissingImports(file, autoImportsManager) { numFiles++; - return fsPromise.readFile(file, 'utf8').then( - fileContents => { - const missingImports = autoImportsManager - .findMissingImports(file, fileContents) - .filter(missingImport => missingImport.symbol.type === 'value'); - if (missingImports.length > 0) { - console.log(JSON.stringify({file, missingImports}, null, 2)); - } - }, - err => { - if (err) { - numErrors++; - console.log( - 'Error with checking for missing imports with file', - file, - 'Error:', - err, - ); - } - }, - ); + return (_fsPromise || _load_fsPromise()).default.readFile(file, 'utf8').then(fileContents => { + const missingImports = autoImportsManager.findMissingImports(file, fileContents).filter(missingImport => missingImport.symbol.type === 'value'); + if (missingImports.length > 0) { + console.log(JSON.stringify({ file, missingImports }, null, 2)); + } + }, err => { + if (err) { + numErrors++; + console.log('Error with checking for missing imports with file', file, 'Error:', err); + } + }); } -function toPath(filename: NuclideUri): NuclideUri { - if (nuclideUri.isAbsolute(filename)) { +function toPath(filename) { + if ((_nuclideUri || _load_nuclideUri()).default.isAbsolute(filename)) { return filename; } - return nuclideUri.normalize(nuclideUri.join(process.cwd(), filename)); + return (_nuclideUri || _load_nuclideUri()).default.normalize((_nuclideUri || _load_nuclideUri()).default.join(process.cwd(), filename)); } -main(); +main(); \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/logging/initializeLogging.js b/pkg/nuclide-js-imports-server/logging/initializeLogging.js index ab42a8f0b5..a303e16148 100644 --- a/pkg/nuclide-js-imports-server/logging/initializeLogging.js +++ b/pkg/nuclide-js-imports-server/logging/initializeLogging.js @@ -1,26 +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 - * @format - */ - -import log4js from 'log4js'; -import {setupLoggingService} from '../../nuclide-logging'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import os from 'os'; -import {IConnection} from 'vscode-languageserver'; - -const MAX_LOG_SIZE = 16 * 1024; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = initializeLogging; +exports.initializeLoggerForWorker = initializeLoggerForWorker; + +var _log4js; + +function _load_log4js() { + return _log4js = _interopRequireDefault(require('log4js')); +} + +var _nuclideLogging; + +function _load_nuclideLogging() { + return _nuclideLogging = require('../../nuclide-logging'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _os = _interopRequireDefault(require('os')); + +var _vscodeLanguageserver; + +function _load_vscodeLanguageserver() { + return _vscodeLanguageserver = require('vscode-languageserver'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const MAX_LOG_SIZE = 16 * 1024; /** + * 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. + * + * + * @format + */ + const MAX_LOG_BACKUPS = 1; -const LOG_FILE_PATH = nuclideUri.join( - os.tmpdir(), - 'nuclide-js-imports-server.log', -); +const LOG_FILE_PATH = (_nuclideUri || _load_nuclideUri()).default.join(_os.default.tmpdir(), 'nuclide-js-imports-server.log'); // Configure log4js to not log to console, since // writing arbitrary data to stdout will break JSON RPC if we're running over @@ -28,21 +54,17 @@ const LOG_FILE_PATH = nuclideUri.join( // // Additionally, add an appender to log over the rpc connection so logging appears // in the client environment, independent of stdio, node rpc, socket, etc. -export default function initializeLogging(connection: IConnection) { - setupLoggingService(); - log4js.configure({ - appenders: [ - { - type: 'logLevelFilter', - level: 'DEBUG', - appender: { - connection, - type: require.resolve( - '../../nuclide-lsp-implementation-common/connectionConsoleAppender', - ), - }, - }, - ], +function initializeLogging(connection) { + (0, (_nuclideLogging || _load_nuclideLogging()).setupLoggingService)(); + (_log4js || _load_log4js()).default.configure({ + appenders: [{ + type: 'logLevelFilter', + level: 'DEBUG', + appender: { + connection, + type: require.resolve('../../nuclide-lsp-implementation-common/connectionConsoleAppender') + } + }] }); // Don't let anything write to the true stdio as it could break JSON RPC @@ -51,37 +73,35 @@ export default function initializeLogging(connection: IConnection) { catchUnhandledExceptions(); } -export function initializeLoggerForWorker(): void { +function initializeLoggerForWorker() { // TODO: Ideally worker messages would go to the parent, which could send them back to the client. - setupLoggingService(); - log4js.configure({ - appenders: [ - { - type: 'logLevelFilter', - level: 'DEBUG', - appender: { - type: 'file', - filename: LOG_FILE_PATH, - maxLogSize: MAX_LOG_SIZE, - backups: MAX_LOG_BACKUPS, - layout: { - type: 'pattern', - // Format log in following pattern: - // yyyy-MM-dd HH:mm:ss.mil $Level (pid:$pid) $categroy - $message. - pattern: `%d{ISO8601} %p (pid:${process.pid}) %c - %m`, - }, - }, - }, - ], + (0, (_nuclideLogging || _load_nuclideLogging()).setupLoggingService)(); + (_log4js || _load_log4js()).default.configure({ + appenders: [{ + type: 'logLevelFilter', + level: 'DEBUG', + appender: { + type: 'file', + filename: LOG_FILE_PATH, + maxLogSize: MAX_LOG_SIZE, + backups: MAX_LOG_BACKUPS, + layout: { + type: 'pattern', + // Format log in following pattern: + // yyyy-MM-dd HH:mm:ss.mil $Level (pid:$pid) $categroy - $message. + pattern: `%d{ISO8601} %p (pid:${process.pid}) %c - %m` + } + } + }] }); catchUnhandledExceptions(); } function catchUnhandledExceptions() { - const logger = log4js.getLogger('js-imports-server'); + const logger = (_log4js || _load_log4js()).default.getLogger('js-imports-server'); process.on('uncaughtException', e => { logger.error('uncaughtException', e); - log4js.shutdown(() => process.abort()); + (_log4js || _load_log4js()).default.shutdown(() => process.abort()); }); process.on('unhandledRejection', e => logger.error('unhandledRejection', e)); -} +} \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/CodeActions.js b/pkg/nuclide-js-imports-server/src/CodeActions.js index 68e7658f6c..a049c8eaf8 100644 --- a/pkg/nuclide-js-imports-server/src/CodeActions.js +++ b/pkg/nuclide-js-imports-server/src/CodeActions.js @@ -1,3 +1,52 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.CodeActions = undefined; + +var _vscodeLanguageserver; + +function _load_vscodeLanguageserver() { + return _vscodeLanguageserver = require('vscode-languageserver'); +} + +var _AutoImportsManager; + +function _load_AutoImportsManager() { + return _AutoImportsManager = require('./lib/AutoImportsManager'); +} + +var _ImportFormatter; + +function _load_ImportFormatter() { + return _ImportFormatter = require('./lib/ImportFormatter'); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _Diagnostics; + +function _load_Diagnostics() { + return _Diagnostics = require('./Diagnostics'); +} + +var _util; + +function _load_util() { + return _util = require('./utils/util'); +} + +var _lspUtils; + +function _load_lspUtils() { + return _lspUtils = require('../../nuclide-lsp-implementation-common/lsp-utils'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,119 +54,64 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import {Command, Diagnostic} from 'vscode-languageserver'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {AddImportCommandParams} from './CommandExecutor'; - -import {AutoImportsManager} from './lib/AutoImportsManager'; -import {ImportFormatter} from './lib/ImportFormatter'; -import {arrayFlatten} from 'nuclide-commons/collection'; -import {DIAGNOSTIC_SOURCE} from './Diagnostics'; -import {babelLocationToAtomRange} from './utils/util'; -import {lspRangeToAtomRange} from '../../nuclide-lsp-implementation-common/lsp-utils'; -import {compareForSuggestion} from './utils/util'; - const CODE_ACTIONS_LIMIT = 10; const FLOW_DIAGNOSTIC_SOURCE = 'Flow'; -export class CodeActions { - autoImportsManager: AutoImportsManager; - importFormatter: ImportFormatter; +class CodeActions { - constructor( - autoImportsManager: AutoImportsManager, - importFormatter: ImportFormatter, - ) { + constructor(autoImportsManager, importFormatter) { this.autoImportsManager = autoImportsManager; this.importFormatter = importFormatter; } - provideCodeActions( - diagnostics: Array, - fileUri: NuclideUri, - ): Array { - return arrayFlatten( - diagnostics.map(diagnostic => - diagnosticToCommands( - this.autoImportsManager, - this.importFormatter, - diagnostic, - fileUri, - ), - ), - ); + provideCodeActions(diagnostics, fileUri) { + return (0, (_collection || _load_collection()).arrayFlatten)(diagnostics.map(diagnostic => diagnosticToCommands(this.autoImportsManager, this.importFormatter, diagnostic, fileUri))); } } -function diagnosticToCommands( - autoImportsManager: AutoImportsManager, - importFormatter: ImportFormatter, - diagnostic: Diagnostic, - fileWithDiagnostic: NuclideUri, -): Array { - if ( - diagnostic.source === DIAGNOSTIC_SOURCE || - diagnostic.source === FLOW_DIAGNOSTIC_SOURCE - ) { - return arrayFlatten( - autoImportsManager - .getSuggestedImportsForRange(fileWithDiagnostic, diagnostic.range) - .filter(suggestedImport => { - // For Flow's diagnostics, only fire for missing types (exact match) - if (diagnostic.source === FLOW_DIAGNOSTIC_SOURCE) { - if (suggestedImport.symbol.type !== 'type') { - return false; - } - const range = babelLocationToAtomRange( - suggestedImport.symbol.location, - ); - const diagnosticRange = lspRangeToAtomRange(diagnostic.range); - return range.isEqual(diagnosticRange); - } - // Otherwise this has to be a value import. - return suggestedImport.symbol.type === 'value'; - }) - // Create a CodeAction for each file with an export. - .map(missingImport => - missingImport.filesWithExport.map(jsExport => ({ - ...jsExport, - // Force this to be imported as a type/value depending on the context. - isTypeExport: missingImport.symbol.type === 'type', - })), - ), - ) - .map(fileWithExport => ({ - fileWithExport, - importPath: importFormatter.formatImportFile( - fileWithDiagnostic, - fileWithExport, - ), - })) - .sort((a, b) => compareForSuggestion(a.importPath, b.importPath)) - .slice(0, CODE_ACTIONS_LIMIT) - .map(({fileWithExport, importPath}) => { - const addImportArgs: AddImportCommandParams = [ - fileWithExport, - fileWithDiagnostic, - ]; - let verb; - if (fileWithExport.isTypeExport) { - verb = 'Import type'; - } else if (importFormatter.useRequire) { - verb = 'Require'; - } else { - verb = 'Import'; +exports.CodeActions = CodeActions; +function diagnosticToCommands(autoImportsManager, importFormatter, diagnostic, fileWithDiagnostic) { + if (diagnostic.source === (_Diagnostics || _load_Diagnostics()).DIAGNOSTIC_SOURCE || diagnostic.source === FLOW_DIAGNOSTIC_SOURCE) { + return (0, (_collection || _load_collection()).arrayFlatten)(autoImportsManager.getSuggestedImportsForRange(fileWithDiagnostic, diagnostic.range).filter(suggestedImport => { + // For Flow's diagnostics, only fire for missing types (exact match) + if (diagnostic.source === FLOW_DIAGNOSTIC_SOURCE) { + if (suggestedImport.symbol.type !== 'type') { + return false; } - return { - title: `${verb} from ${importPath}`, - command: 'addImport', - arguments: addImportArgs, - }; - }); + const range = (0, (_util || _load_util()).babelLocationToAtomRange)(suggestedImport.symbol.location); + const diagnosticRange = (0, (_lspUtils || _load_lspUtils()).lspRangeToAtomRange)(diagnostic.range); + return range.isEqual(diagnosticRange); + } + // Otherwise this has to be a value import. + return suggestedImport.symbol.type === 'value'; + }) + // Create a CodeAction for each file with an export. + .map(missingImport => missingImport.filesWithExport.map(jsExport => Object.assign({}, jsExport, { + // Force this to be imported as a type/value depending on the context. + isTypeExport: missingImport.symbol.type === 'type' + })))).map(fileWithExport => ({ + fileWithExport, + importPath: importFormatter.formatImportFile(fileWithDiagnostic, fileWithExport) + })).sort((a, b) => (0, (_util || _load_util()).compareForSuggestion)(a.importPath, b.importPath)).slice(0, CODE_ACTIONS_LIMIT).map(({ fileWithExport, importPath }) => { + const addImportArgs = [fileWithExport, fileWithDiagnostic]; + let verb; + if (fileWithExport.isTypeExport) { + verb = 'Import type'; + } else if (importFormatter.useRequire) { + verb = 'Require'; + } else { + verb = 'Import'; + } + return { + title: `${verb} from ${importPath}`, + command: 'addImport', + arguments: addImportArgs + }; + }); } return []; -} +} \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/CommandExecutor.js b/pkg/nuclide-js-imports-server/src/CommandExecutor.js index 8918fcca69..1af1483328 100644 --- a/pkg/nuclide-js-imports-server/src/CommandExecutor.js +++ b/pkg/nuclide-js-imports-server/src/CommandExecutor.js @@ -1,203 +1,164 @@ -/** - * 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 - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {AutoImportsManager} from './lib/AutoImportsManager'; -import type {JSExport, JSImport} from './lib/types'; -import type TextDocuments from '../../nuclide-lsp-implementation-common/TextDocuments'; -import type { - WorkspaceEdit, - TextEdit, -} from '../../nuclide-vscode-language-service-rpc/lib/protocol'; - -import {arrayFlatten} from 'nuclide-commons/collection'; -import {IConnection} from 'vscode-languageserver'; -import {ImportFormatter} from './lib/ImportFormatter'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {parseFile} from './lib/AutoImportsManager'; -import {Range} from 'simple-text-buffer'; -import {compareForInsertion, getRequiredModule} from './utils/util'; -import {atomRangeToLSPRange} from '../../nuclide-lsp-implementation-common/lsp-utils'; - -export type AddImportCommandParams = [JSExport, NuclideUri]; - -type EditParams = { - row: number, - column: number, - indent?: number, - newLinesBefore: number, - newLinesAfter: number, -}; +'use strict'; -export class CommandExecutor { - static COMMANDS = { - addImport: true, - }; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.CommandExecutor = undefined; +exports.getEditsForImport = getEditsForImport; + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _vscodeLanguageserver; + +function _load_vscodeLanguageserver() { + return _vscodeLanguageserver = require('vscode-languageserver'); +} + +var _ImportFormatter; + +function _load_ImportFormatter() { + return _ImportFormatter = require('./lib/ImportFormatter'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _AutoImportsManager; + +function _load_AutoImportsManager() { + return _AutoImportsManager = require('./lib/AutoImportsManager'); +} - connection: IConnection; - autoImportsManager: AutoImportsManager; - importFormatter: ImportFormatter; - documents: TextDocuments; - - constructor( - connection: IConnection, - autoImportsManager: AutoImportsManager, - importFormatter: ImportFormatter, - documents: TextDocuments, - ) { +var _simpleTextBuffer; + +function _load_simpleTextBuffer() { + return _simpleTextBuffer = require('simple-text-buffer'); +} + +var _util; + +function _load_util() { + return _util = require('./utils/util'); +} + +var _lspUtils; + +function _load_lspUtils() { + return _lspUtils = require('../../nuclide-lsp-implementation-common/lsp-utils'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class CommandExecutor { + + constructor(connection, autoImportsManager, importFormatter, documents) { this.connection = connection; this.autoImportsManager = autoImportsManager; this.importFormatter = importFormatter; this.documents = documents; } - executeCommand(command: $Keys, args: any) { + executeCommand(command, args) { switch (command) { case 'addImport': - return this._addImport((args: AddImportCommandParams)); + return this._addImport(args); default: - (command: empty); + command; throw new Error(`Unexpected command ${command}`); } } - _addImport(args: AddImportCommandParams) { + _addImport(args) { const [missingImport, fileMissingImport] = args; - const ast = parseFile( - this.documents - .get(nuclideUri.nuclideUriToUri(fileMissingImport)) - .getText(), - ); + const ast = (0, (_AutoImportsManager || _load_AutoImportsManager()).parseFile)(this.documents.get((_nuclideUri || _load_nuclideUri()).default.nuclideUriToUri(fileMissingImport)).getText()); if (ast == null || ast.program == null || ast.program.body == null) { // File could not be parsed. If this is reached, we shouldn't be applying // addImport anyways since the file must have changed from when we computed // the CodeAction. return; } - const {body} = ast.program; - const edits = getEditsForImport( - this.importFormatter, - fileMissingImport, - missingImport, - body, - ); - - const lspUri = nuclideUri.nuclideUriToUri(fileMissingImport); + const { body } = ast.program; + const edits = getEditsForImport(this.importFormatter, fileMissingImport, missingImport, body); + + const lspUri = (_nuclideUri || _load_nuclideUri()).default.nuclideUriToUri(fileMissingImport); // Version 2.0 LSP const changes = {}; changes[lspUri] = edits; // Version 3.0 LSP - const documentChanges = [ - { - textDocument: { - uri: lspUri, - version: this.documents.get(lspUri).version, - }, - edits, + const documentChanges = [{ + textDocument: { + uri: lspUri, + version: this.documents.get(lspUri).version }, - ]; + edits + }]; - this.connection.workspace.applyEdit( - ({changes, documentChanges}: WorkspaceEdit), - ); + this.connection.workspace.applyEdit({ changes, documentChanges }); } - getEditsForFixingAllImports(fileMissingImport: NuclideUri): Array { - const fileMissingImportUri = nuclideUri.nuclideUriToUri(fileMissingImport); - const ast = parseFile(this.documents.get(fileMissingImportUri).getText()); + getEditsForFixingAllImports(fileMissingImport) { + const fileMissingImportUri = (_nuclideUri || _load_nuclideUri()).default.nuclideUriToUri(fileMissingImport); + const ast = (0, (_AutoImportsManager || _load_AutoImportsManager()).parseFile)(this.documents.get(fileMissingImportUri).getText()); if (ast == null || ast.program == null || ast.program.body == null) { // TODO(T24077432): Figure out when this happens and throw an error return []; } - const {body} = ast.program; - return arrayFlatten( - this.autoImportsManager - .findMissingImportsInAST(fileMissingImport, ast, false) - .map(({filesWithExport, symbol}) => { - if (filesWithExport.length === 0) { - return undecidableImportEdits(); - } - const missingImport = findClosestImport( - symbol.id, - fileMissingImport, - filesWithExport, - ); - if (!missingImport) { - return undecidableImportEdits(); - } - return getEditsForImport( - this.importFormatter, - fileMissingImport, - missingImport, - body, - ); - }), - ); + const { body } = ast.program; + return (0, (_collection || _load_collection()).arrayFlatten)(this.autoImportsManager.findMissingImportsInAST(fileMissingImport, ast, false).map(({ filesWithExport, symbol }) => { + if (filesWithExport.length === 0) { + return undecidableImportEdits(); + } + const missingImport = findClosestImport(symbol.id, fileMissingImport, filesWithExport); + if (!missingImport) { + return undecidableImportEdits(); + } + return getEditsForImport(this.importFormatter, fileMissingImport, missingImport, body); + })); } } -export function getEditsForImport( - importFormatter: ImportFormatter, - fileMissingImport: NuclideUri, - missingImport: JSExport, - programBody: Array, -): Array { - const importPath = importFormatter.formatImportFile( - fileMissingImport, - missingImport, - ); - const insertEdit = insertIntoExistingImport( - importPath, - missingImport, - programBody, - ); +exports.CommandExecutor = CommandExecutor; /** + * 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. + * + * + * @format + */ + +CommandExecutor.COMMANDS = { + addImport: true +}; +function getEditsForImport(importFormatter, fileMissingImport, missingImport, programBody) { + const importPath = importFormatter.formatImportFile(fileMissingImport, missingImport); + const insertEdit = insertIntoExistingImport(importPath, missingImport, programBody); if (insertEdit != null) { return [createEdit(missingImport.id, insertEdit)]; } - return [ - createEdit( - importFormatter.formatImport(fileMissingImport, missingImport), - createNewImport( - missingImport, - programBody, - importPath, - importFormatter.useRequire, - ), - ), - ]; + return [createEdit(importFormatter.formatImport(fileMissingImport, missingImport), createNewImport(missingImport, programBody, importPath, importFormatter.useRequire))]; } -function createEdit( - insertText: string, - {row, column, indent, newLinesAfter, newLinesBefore}: EditParams, -): TextEdit { +function createEdit(insertText, { row, column, indent, newLinesAfter, newLinesBefore }) { return { - range: atomRangeToLSPRange(new Range([row, column], [row, column])), + range: (0, (_lspUtils || _load_lspUtils()).atomRangeToLSPRange)(new (_simpleTextBuffer || _load_simpleTextBuffer()).Range([row, column], [row, column])), newText: - // We're always going to insert before any trailing commas, so it's safe to always add one. - (column === 0 ? '' : ',') + - '\n'.repeat(newLinesBefore) + - ' '.repeat(indent || 0) + - insertText + - '\n'.repeat(newLinesAfter), + // We're always going to insert before any trailing commas, so it's safe to always add one. + (column === 0 ? '' : ',') + '\n'.repeat(newLinesBefore) + ' '.repeat(indent || 0) + insertText + '\n'.repeat(newLinesAfter) }; } // Find a position where we can just insert the missing ID. -function insertIntoExistingImport( - importPath: string, - missingImport: JSExport, - programBody: Array, -): ?EditParams { +function insertIntoExistingImport(importPath, missingImport, programBody) { // For now, we won't allow mixed imports (e.g. import {type X, Y}) if (missingImport.isDefault) { return null; @@ -210,13 +171,13 @@ function insertIntoExistingImport( if (jsImport.type === 'require') { const declaration = node.declarations[0]; if (declaration.id.type === 'ObjectPattern') { - const {properties} = declaration.id; + const { properties } = declaration.id; return positionAfterNode(node, properties[properties.length - 1]); } } else { const isTypeImport = jsImport.type === 'importType'; if (isTypeImport === missingImport.isTypeExport) { - const {specifiers} = node; + const { specifiers } = node; return positionAfterNode(node, specifiers[specifiers.length - 1]); } } @@ -227,26 +188,26 @@ function insertIntoExistingImport( // e.g. after X in const {X|} = require('...') function positionAfterNode(importNode, afterNode) { const hasNewline = importNode.loc.start.line !== importNode.loc.end.line; - const {line, column} = afterNode.loc.end; + const { line, column } = afterNode.loc.end; return { row: line - 1, column, indent: hasNewline ? afterNode.loc.start.column : 1, newLinesAfter: 0, - newLinesBefore: Number(hasNewline), + newLinesBefore: Number(hasNewline) }; } -function getJSImport(node: Object): ?JSImport { +function getJSImport(node) { switch (node.type) { // const {X} = require('..'); case 'VariableDeclaration': if (node.declarations.length === 1 && node.declarations[0].init != null) { - const importPath = getRequiredModule(node.declarations[0].init); + const importPath = (0, (_util || _load_util()).getRequiredModule)(node.declarations[0].init); if (importPath != null) { return { type: 'require', - importPath, + importPath }; } } @@ -254,28 +215,23 @@ function getJSImport(node: Object): ?JSImport { case 'ImportDeclaration': return { type: node.importKind === 'type' ? 'importType' : 'import', - importPath: node.source.value, + importPath: node.source.value }; } } -function createNewImport( - missingImport: JSExport, - programBody: Array, - importPath: string, - useRequire: boolean, -): EditParams { +function createNewImport(missingImport, programBody, importPath, useRequire) { const nodesByType = { require: [], import: [], - importType: [], + importType: [] }; programBody.forEach(node => { const jsImport = getJSImport(node); if (jsImport != null) { nodesByType[jsImport.type].push({ node, - importPath: jsImport.importPath, + importPath: jsImport.importPath }); } }); @@ -291,31 +247,23 @@ function createNewImport( } } else { // Make sure we try to insert imports/requires in their own group (if possible). - const preferred = useRequire - ? [nodesByType.require, nodesByType.import] - : [nodesByType.import, nodesByType.require]; + const preferred = useRequire ? [nodesByType.require, nodesByType.import] : [nodesByType.import, nodesByType.require]; for (const nodes of preferred) { if (nodes.length > 0) { return insertInto(nodes, importPath); } } if (nodesByType.importType.length > 0) { - return insertAfter( - nodesByType.importType[nodesByType.importType.length - 1].node, - 1, - ); + return insertAfter(nodesByType.importType[nodesByType.importType.length - 1].node, 1); } } return insertBefore(programBody[0], 1); } -function insertInto( - imports: Array<{node: Object, importPath: string}>, - importPath: string, -): EditParams { +function insertInto(imports, importPath) { for (const importNode of imports) { // Find the first import that we can be inserted before. - if (compareForInsertion(importPath, importNode.importPath) < 0) { + if ((0, (_util || _load_util()).compareForInsertion)(importPath, importNode.importPath) < 0) { return insertBefore(importNode.node); } } @@ -326,34 +274,32 @@ function insertInto( // Insert at the start of the next line: // // -function insertAfter(node: Object, spacing: number = 0): EditParams { +function insertAfter(node, spacing = 0) { return { row: node.loc.end.line, // 1-based column: 0, newLinesAfter: 1, - newLinesBefore: spacing, + newLinesBefore: spacing }; } // Insert at the start of the line: // <\ntext\n> -function insertBefore(node: Object, spacing: number = 0): EditParams { +function insertBefore(node, spacing = 0) { return { row: node.loc.start.line - 1, // 1-based column: 0, newLinesAfter: 1 + spacing, - newLinesBefore: 0, + newLinesBefore: 0 }; } // Signal across RPC that the import had no available exports, via empty newText -function undecidableImportEdits(): Array { - return [ - { - range: atomRangeToLSPRange(new Range([0, 0], [0, 0])), - newText: '', - }, - ]; +function undecidableImportEdits() { + return [{ + range: (0, (_lspUtils || _load_lspUtils()).atomRangeToLSPRange)(new (_simpleTextBuffer || _load_simpleTextBuffer()).Range([0, 0], [0, 0])), + newText: '' + }]; } // Chooses the import suggestion which has the most similar file URI @@ -361,19 +307,15 @@ function undecidableImportEdits(): Array { // needed to get from to the other) or most similar module identifier // to the missing symbol identifier. // Returns null if the closest import cannot be determined -function findClosestImport( - identifier: string, - fileURI: NuclideUri, - filesWithExport: Array, -): ?JSExport { - const fileURIParts = nuclideUri.split(fileURI); - const closestExports = findSmallestByMeasure(filesWithExport, ({uri}) => { - const exportURIParts = nuclideUri.split(uri); +function findClosestImport(identifier, fileURI, filesWithExport) { + const fileURIParts = (_nuclideUri || _load_nuclideUri()).default.split(fileURI); + const closestExports = findSmallestByMeasure(filesWithExport, ({ uri }) => { + const exportURIParts = (_nuclideUri || _load_nuclideUri()).default.split(uri); return computeURIDistance(fileURIParts, exportURIParts); }); if (closestExports.length > 1) { - const closestByModuleID = findSmallestByMeasure(closestExports, ({uri}) => { + const closestByModuleID = findSmallestByMeasure(closestExports, ({ uri }) => { const id = moduleID(uri); return id === identifier ? 0 : id.indexOf(identifier) !== -1 ? 1 : 2; }); @@ -386,7 +328,7 @@ function findClosestImport( return closestExports[0]; } -function computeURIDistance(uriA: Array, uriB: Array): number { +function computeURIDistance(uriA, uriB) { let i = 0; while (uriA[i] === uriB[i] && uriA[i] != null) { i++; @@ -395,15 +337,12 @@ function computeURIDistance(uriA: Array, uriB: Array): number { return uriA.length - i + 1.75 * (uriB.length - i); } -function findSmallestByMeasure( - list: Array, - measure: T => number, -): Array { +function findSmallestByMeasure(list, measure) { const smallestIndices = new Set(findIndicesOfSmallest(list.map(measure))); return list.filter((_, i) => smallestIndices.has(i)); } -function findIndicesOfSmallest(list: Array): Array { +function findIndicesOfSmallest(list) { let indecesOfSmallest = [0]; let smallest = list[0]; list.forEach((item, index) => { @@ -417,7 +356,7 @@ function findIndicesOfSmallest(list: Array): Array { return indecesOfSmallest; } -function moduleID(fileURI: string): string { - const parts = nuclideUri.split(fileURI); +function moduleID(fileURI) { + const parts = (_nuclideUri || _load_nuclideUri()).default.split(fileURI); return parts[parts.length - 1].replace(/\.\w+$/, ''); -} +} \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/Completions.js b/pkg/nuclide-js-imports-server/src/Completions.js index 8c2be8db1d..b4e6d4f84b 100644 --- a/pkg/nuclide-js-imports-server/src/Completions.js +++ b/pkg/nuclide-js-imports-server/src/Completions.js @@ -1,38 +1,53 @@ -/** - * 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 - */ +'use strict'; -import { - type CompletionItem, - type TextDocumentPositionParams, - type TextEdit, - CompletionItemKind, -} from '../../nuclide-vscode-language-service-rpc/lib/protocol'; -import type {ImportType} from './lib/ImportFormatter'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Completions = undefined; +exports.provideFullImportCompletions = provideFullImportCompletions; +exports.provideImportFileCompletions = provideImportFileCompletions; +exports.getImportInformation = getImportInformation; -import {AutoImportsManager} from './lib/AutoImportsManager'; -import {ImportFormatter, createImportStatement} from './lib/ImportFormatter'; -import {compareForSuggestion} from './utils/util'; -import {setIntersect} from 'nuclide-commons/collection'; +var _protocol; -import type TextDocuments from '../../nuclide-lsp-implementation-common/TextDocuments'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {JSExport} from './lib/types'; +function _load_protocol() { + return _protocol = require('../../nuclide-vscode-language-service-rpc/lib/protocol'); +} -type ImportInformation = { - ids: Array, - importType: ImportType, - isComplete: boolean, -}; +var _AutoImportsManager; + +function _load_AutoImportsManager() { + return _AutoImportsManager = require('./lib/AutoImportsManager'); +} + +var _ImportFormatter; + +function _load_ImportFormatter() { + return _ImportFormatter = require('./lib/ImportFormatter'); +} + +var _util; + +function _load_util() { + return _util = require('./utils/util'); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} -const MAX_RESULTS = 200; +const MAX_RESULTS = 200; /** + * 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. + * + * + * @format + */ const INCOMPLETE_IMPORT_REGEX = { namedType: /^\s*import\s+type\s+{\s*([$\w]+)$/, @@ -40,7 +55,7 @@ const INCOMPLETE_IMPORT_REGEX = { defaultType: /^\s*import\s+type\s+([$\w]+)$/, defaultValue: /^\s*import\s+([$\w]+)$/, requireImport: /^const\s+([$\w]+)$/, - requireDestructured: /^const\s+{\s*([$\w]+)$/, + requireDestructured: /^const\s+{\s*([$\w]+)$/ }; const IMPORT_STATEMENT_REGEXES = { @@ -49,78 +64,41 @@ const IMPORT_STATEMENT_REGEXES = { defaultType: /^\s*import\s+type\s+([$\w]+)\s+(.*)/, defaultValue: /^\s*import\s+([$\w]+)\s+(.*)/, requireImport: /^const\s+([$\w]+)\s+(.*)/, - requireDestructured: /^const\s+{\s*([$\w\s,]+)\s*}\s*(.*)/, + requireDestructured: /^const\s+{\s*([$\w\s,]+)\s*}\s*(.*)/ }; -export class Completions { - documents: TextDocuments; - autoImportsManager: AutoImportsManager; - importsFormatter: ImportFormatter; +class Completions { - constructor( - documents: TextDocuments, - autoImportsManager: AutoImportsManager, - importsFormatter: ImportFormatter, - ) { + constructor(documents, autoImportsManager, importsFormatter) { this.documents = documents; this.autoImportsManager = autoImportsManager; this.importsFormatter = importsFormatter; } - provideCompletions( - textDocumentPosition: TextDocumentPositionParams, - nuclideFormattedUri: NuclideUri, - ): Array { - const {position, textDocument} = textDocumentPosition; + provideCompletions(textDocumentPosition, nuclideFormattedUri) { + const { position, textDocument } = textDocumentPosition; // TODO(seansegal): Handle imports broken up on multiple lines. - const line = this.documents - .get(textDocument.uri) - .buffer.lineForRow(position.line); + const line = this.documents.get(textDocument.uri).buffer.lineForRow(position.line); - if ( - positionIsAtLineEnd(line, position) && - // Check if line starts with "import" (or "const") before matching all regexes. - isImportStatement(line) && - line.indexOf(';') < 0 - ) { + if (positionIsAtLineEnd(line, position) && + // Check if line starts with "import" (or "const") before matching all regexes. + isImportStatement(line) && line.indexOf(';') < 0) { const prefix = line.substr(0, position.character); const importInformation = getImportInformation(prefix); if (importInformation) { - return importInformation.isComplete - ? provideImportFileCompletions( - importInformation, - this.importsFormatter, - this.autoImportsManager, - nuclideFormattedUri, - line, - position.line, - ) - : provideFullImportCompletions( - importInformation, - this.importsFormatter, - this.autoImportsManager, - nuclideFormattedUri, - line, - position.line, - ); + return importInformation.isComplete ? provideImportFileCompletions(importInformation, this.importsFormatter, this.autoImportsManager, nuclideFormattedUri, line, position.line) : provideFullImportCompletions(importInformation, this.importsFormatter, this.autoImportsManager, nuclideFormattedUri, line, position.line); } } return []; } } -// Provides autocompletion of IDs that could be imported. When selected +exports.Completions = Completions; // Provides autocompletion of IDs that could be imported. When selected // the entire import line is added. -export function provideFullImportCompletions( - importInformation: ImportInformation, - importsFormatter: ImportFormatter, - autoImportsManager: AutoImportsManager, - nuclideFormattedUri: NuclideUri, - line: string, - lineNum: number, -): Array { - const {ids, importType} = importInformation; + +function provideFullImportCompletions(importInformation, importsFormatter, autoImportsManager, nuclideFormattedUri, line, lineNum) { + const { ids, importType } = importInformation; const exportsIndex = autoImportsManager.exportsManager.getExportsIndex(); // 1) Find all IDs that fuzzily match the given string. const matchingIds = exportsIndex.getIdsMatching(ids[0], MAX_RESULTS); @@ -132,121 +110,69 @@ export function provideFullImportCompletions( // 2) For each ID, find all exports for the ID. const exportsForId = exportsIndex.getExportsFromId(id); // 3) Filter and sort the exports, and add them to the return list of completions. - const importPaths = filterSuggestions(exportsForId, importType) - .filter(jsExport => jsExport.uri !== nuclideFormattedUri) - .map(suggestion => - importsFormatter.formatImportFile(nuclideFormattedUri, suggestion), - ) - .sort(compareForSuggestion); - return results.concat( - importPaths.slice(0, needed).map(importPath => { - return { - label: id, - kind: CompletionItemKind.Module, - inlineDetail: importsFormatter.stripLeadingDots(importPath), - textEdit: createLineEdit( - lineNum, - line, - createImportStatement(id, importPath, importType), - ), - }; - }), - ); + const importPaths = filterSuggestions(exportsForId, importType).filter(jsExport => jsExport.uri !== nuclideFormattedUri).map(suggestion => importsFormatter.formatImportFile(nuclideFormattedUri, suggestion)).sort((_util || _load_util()).compareForSuggestion); + return results.concat(importPaths.slice(0, needed).map(importPath => { + return { + label: id, + kind: (_protocol || _load_protocol()).CompletionItemKind.Module, + inlineDetail: importsFormatter.stripLeadingDots(importPath), + textEdit: createLineEdit(lineNum, line, (0, (_ImportFormatter || _load_ImportFormatter()).createImportStatement)(id, importPath, importType)) + }; + })); }, []); } // Given a list of IDs that are already typed, provide autocompletion for // the files that those IDs might be imported from. -export function provideImportFileCompletions( - importInformation: ImportInformation, - importsFormatter: ImportFormatter, - autoImportsManager: AutoImportsManager, - nuclideFormattedUri: NuclideUri, - line: string, - lineNum: number, -): Array { - const {ids, importType} = importInformation; +function provideImportFileCompletions(importInformation, importsFormatter, autoImportsManager, nuclideFormattedUri, line, lineNum) { + const { ids, importType } = importInformation; // Intersect all exports for `ids` and then filter/sort the result. - const suggestions = findCommonSuggestions( - autoImportsManager, - ids, - importType, - ); - return filterSuggestions(suggestions, importType) - .filter(jsExport => jsExport.uri !== nuclideFormattedUri) - .map(suggestion => - importsFormatter.formatImportFile(nuclideFormattedUri, suggestion), - ) - .sort(compareForSuggestion) - .slice(0, MAX_RESULTS) - .map(importPath => { - return { - label: - importType === 'requireImport' || importType === 'requireDestructured' - ? `= require('${importPath}');` - : `from '${importPath}';`, - kind: CompletionItemKind.Module, - textEdit: createLineEdit( - lineNum, - line, - createImportStatement(ids.join(', '), importPath, importType), - ), - }; - }); + const suggestions = findCommonSuggestions(autoImportsManager, ids, importType); + return filterSuggestions(suggestions, importType).filter(jsExport => jsExport.uri !== nuclideFormattedUri).map(suggestion => importsFormatter.formatImportFile(nuclideFormattedUri, suggestion)).sort((_util || _load_util()).compareForSuggestion).slice(0, MAX_RESULTS).map(importPath => { + return { + label: importType === 'requireImport' || importType === 'requireDestructured' ? `= require('${importPath}');` : `from '${importPath}';`, + kind: (_protocol || _load_protocol()).CompletionItemKind.Module, + textEdit: createLineEdit(lineNum, line, (0, (_ImportFormatter || _load_ImportFormatter()).createImportStatement)(ids.join(', '), importPath, importType)) + }; + }); } // Find a list of URIs that contain all the given exports, // and return a representative export for each one. -function findCommonSuggestions( - autoImportsManager: AutoImportsManager, - ids: Array, - importType: ImportType, -): Array { - const suggestionsForEachId = ids.map(id => - autoImportsManager.findFilesWithSymbol(id), - ); +function findCommonSuggestions(autoImportsManager, ids, importType) { + const suggestionsForEachId = ids.map(id => autoImportsManager.findFilesWithSymbol(id)); if (suggestionsForEachId.length === 1) { return suggestionsForEachId[0]; } - const commonUris = suggestionsForEachId.reduce( - (aggregated, suggestionForId) => { - return setIntersect(aggregated, new Set(suggestionForId.map(s => s.uri))); - }, - new Set(suggestionsForEachId[0].map(s => s.uri)), - ); + const commonUris = suggestionsForEachId.reduce((aggregated, suggestionForId) => { + return (0, (_collection || _load_collection()).setIntersect)(aggregated, new Set(suggestionForId.map(s => s.uri))); + }, new Set(suggestionsForEachId[0].map(s => s.uri))); return suggestionsForEachId[0].filter(e => commonUris.has(e.uri)); } -function filterSuggestions( - suggestions: Array, - importType: ImportType, -): Array { +function filterSuggestions(suggestions, importType) { // Filter out suggestions based on the import type switch (importType) { case 'defaultValue': return suggestions.filter(exp => exp.isDefault && !exp.isTypeExport); case 'defaultType': - return suggestions.filter( - exp => exp.isDefault && (exp.isTypeExport || canBeTypeImported(exp)), - ); + return suggestions.filter(exp => exp.isDefault && (exp.isTypeExport || canBeTypeImported(exp))); case 'namedValue': return suggestions.filter(exp => !exp.isDefault && !exp.isTypeExport); case 'namedType': - return suggestions.filter( - exp => !exp.isDefault && (exp.isTypeExport || canBeTypeImported(exp)), - ); + return suggestions.filter(exp => !exp.isDefault && (exp.isTypeExport || canBeTypeImported(exp))); case 'requireImport': return suggestions.filter(exp => exp.isDefault && !exp.isTypeExport); case 'requireDestructured': return suggestions.filter(exp => !exp.isDefault && !exp.isTypeExport); default: - (importType: empty); + importType; return suggestions; } } // Exported for testing -export function getImportInformation(line: string): ?ImportInformation { +function getImportInformation(line) { for (const importType of Object.keys(IMPORT_STATEMENT_REGEXES)) { const importStatement = line.match(IMPORT_STATEMENT_REGEXES[importType]); if (importStatement && importStatement.length > 1) { @@ -256,12 +182,9 @@ export function getImportInformation(line: string): ?ImportInformation { continue; } return { - ids: importStatement[1] - .split(',') - .map(id => id.trim()) - .filter(id => id.length > 0), + ids: importStatement[1].split(',').map(id => id.trim()).filter(id => id.length > 0), isComplete: true, - importType, + importType }; } } @@ -271,41 +194,34 @@ export function getImportInformation(line: string): ?ImportInformation { return { ids: [importStatement[1]], isComplete: false, - importType, + importType }; } } return null; } -function createLineEdit( - lineNum: number, - lineText: string, - newText: string, -): TextEdit { +function createLineEdit(lineNum, lineText, newText) { return { range: { - start: {line: lineNum, character: 0}, - end: {line: lineNum, character: lineText.length}, + start: { line: lineNum, character: 0 }, + end: { line: lineNum, character: lineText.length } }, - newText, + newText }; } -function isImportStatement(line: string): boolean { - return /^\s*import/.test(line) || /^const/.test(line); +function isImportStatement(line) { + return (/^\s*import/.test(line) || /^const/.test(line) + ); } // -function canBeTypeImported(exp: JSExport): boolean { - return ( - exp.type !== 'FunctionDeclaration' && - exp.type !== 'FunctionExpression' && - exp.type !== 'VariableDeclaration' - ); +function canBeTypeImported(exp) { + return exp.type !== 'FunctionDeclaration' && exp.type !== 'FunctionExpression' && exp.type !== 'VariableDeclaration'; } -function positionIsAtLineEnd(line: string, position: Object): boolean { +function positionIsAtLineEnd(line, position) { if (line.length === position.character) { return true; } @@ -313,4 +229,4 @@ function positionIsAtLineEnd(line: string, position: Object): boolean { // Still provide autocomplete if there is trailing whitespace. // Editor bracket matchers often insert a trailing "}", which should also be ignored. return remainder === '' || remainder === '}'; -} +} \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/Config.js b/pkg/nuclide-js-imports-server/src/Config.js index 46d564e7e6..fc17bf0f91 100644 --- a/pkg/nuclide-js-imports-server/src/Config.js +++ b/pkg/nuclide-js-imports-server/src/Config.js @@ -1,28 +1,39 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.serializeConfig = serializeConfig; +exports.getEslintGlobals = getEslintGlobals; +exports.getConfigFromFlow = getConfigFromFlow; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _fs = _interopRequireDefault(require('fs')); + +var _globals; + +function _load_globals() { + return _globals = _interopRequireWildcard(require('globals')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} -import nuclideUri from 'nuclide-commons/nuclideUri'; -import fs from 'fs'; -import * as globalsModule from 'globals'; -import {getLogger} from 'log4js'; -import vm from 'vm'; +var _vm = _interopRequireDefault(require('vm')); -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; +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 ALL_ENVS = Object.keys(globalsModule); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -export type ConfigFromFlow = $ReadOnly<{| - moduleDirs: Array, - hasteSettings: HasteSettings, -|}>; +const ALL_ENVS = Object.keys(_globals || _load_globals()); /** * Haste settings are surprisingly complicated. @@ -31,16 +42,19 @@ export type ConfigFromFlow = $ReadOnly<{| * - When useNameReducers is enabled, we'll attempt to resolve whitelisted files *without* * @providesModule purely using their name, excluding files in the blacklist. */ -export type HasteSettings = $ReadOnly<{| - isHaste: boolean, - useNameReducers: boolean, - nameReducers: Array<{regexp: RegExp, replacement: string}>, - nameReducerWhitelist: Array, - nameReducerBlacklist: Array, -|}>; - -export function serializeConfig(config: ConfigFromFlow): string { - const {moduleDirs, hasteSettings: settings} = config; +/** + * 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. + * + * + * @format + */ + +function serializeConfig(config) { + const { moduleDirs, hasteSettings: settings } = config; // RegExps aren't normally stringifyable. return JSON.stringify({ moduleDirs, @@ -49,132 +63,94 @@ export function serializeConfig(config: ConfigFromFlow): string { useNameReducers: settings.useNameReducers, nameReducers: settings.nameReducers.map(reducer => ({ regexp: reducer.regexp.toString(), - replacement: reducer.replacement, + replacement: reducer.replacement })), nameReducerBlacklist: settings.nameReducerBlacklist.map(String), - nameReducerWhitelist: settings.nameReducerWhitelist.map(String), - }, + nameReducerWhitelist: settings.nameReducerWhitelist.map(String) + } }); } -export function getEslintGlobals(root: NuclideUri): Array { - return ( - parseEslintrc(nuclideUri.join(root, '.eslintrc')) || - parseEslintrcJs(nuclideUri.join(root, '.eslintrc.js')) || - packageJsonEslintConfig(nuclideUri.join(root, 'package.json')) || - Array.from(getGlobalsForEnvs(ALL_ENVS)) - ); +function getEslintGlobals(root) { + return parseEslintrc((_nuclideUri || _load_nuclideUri()).default.join(root, '.eslintrc')) || parseEslintrcJs((_nuclideUri || _load_nuclideUri()).default.join(root, '.eslintrc.js')) || packageJsonEslintConfig((_nuclideUri || _load_nuclideUri()).default.join(root, 'package.json')) || Array.from(getGlobalsForEnvs(ALL_ENVS)); } -export function getConfigFromFlow(root: NuclideUri): ConfigFromFlow { +function getConfigFromFlow(root) { let moduleDirs = []; let hasteSettings = { isHaste: false, useNameReducers: false, nameReducers: [], nameReducerWhitelist: [], - nameReducerBlacklist: [], + nameReducerBlacklist: [] }; try { - const flowFile = nuclideUri.join(root, '.flowconfig'); - const flowConfigContents = fs.readFileSync(flowFile, 'utf8'); - moduleDirs = flowConfigToResolveDirnames( - flowFile, - flowConfigContents, - ).concat(getYarnWorkspaces(root)); + const flowFile = (_nuclideUri || _load_nuclideUri()).default.join(root, '.flowconfig'); + const flowConfigContents = _fs.default.readFileSync(flowFile, 'utf8'); + moduleDirs = flowConfigToResolveDirnames(flowFile, flowConfigContents).concat(getYarnWorkspaces(root)); hasteSettings = flowConfigToHasteSettings(root, flowConfigContents); } catch (error) {} return { moduleDirs, - hasteSettings, + hasteSettings }; } -function flowConfigToResolveDirnames( - flowFile: string, - flowFileContents: string, -): Array { - const resolveDirs = flowFileContents.match( - /module.system.node.resolve_dirname=([^\s]+)/g, - ); - return resolveDirs - ? resolveDirs.map(dirString => - nuclideUri.join(nuclideUri.dirname(flowFile), dirString.split('=')[1]), - ) - : [nuclideUri.join(nuclideUri.dirname(flowFile), 'node_modules')]; +function flowConfigToResolveDirnames(flowFile, flowFileContents) { + const resolveDirs = flowFileContents.match(/module.system.node.resolve_dirname=([^\s]+)/g); + return resolveDirs ? resolveDirs.map(dirString => (_nuclideUri || _load_nuclideUri()).default.join((_nuclideUri || _load_nuclideUri()).default.dirname(flowFile), dirString.split('=')[1])) : [(_nuclideUri || _load_nuclideUri()).default.join((_nuclideUri || _load_nuclideUri()).default.dirname(flowFile), 'node_modules')]; } -function flowConfigToHasteSettings( - root: NuclideUri, - flowFileContents: string, -): HasteSettings { +function flowConfigToHasteSettings(root, flowFileContents) { const isHaste = Boolean(flowFileContents.match(/module.system=haste/)); - const useNameReducers = Boolean( - flowFileContents.match(/module.system.haste.use_name_reducers=true/), - ); - function getPatterns(dirs: Array) { - return dirs - .map(dirString => dirString.split('=')[1]) - .map(line => new RegExp(line.replace('', root))); + const useNameReducers = Boolean(flowFileContents.match(/module.system.haste.use_name_reducers=true/)); + function getPatterns(dirs) { + return dirs.map(dirString => dirString.split('=')[1]).map(line => new RegExp(line.replace('', root))); } let nameReducers = []; let nameReducerWhitelist = []; let nameReducerBlacklist = []; if (useNameReducers) { - const nameReducerMatches = - flowFileContents.match(/module.system.haste.name_reducers=(.+)$/gm) || []; + const nameReducerMatches = flowFileContents.match(/module.system.haste.name_reducers=(.+)$/gm) || []; nameReducers = nameReducerMatches.map(line => { const value = line.substr(line.indexOf('=') + 1); // Default reducer (example): // '^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1' - const [regexString, replacementString] = value - .split('->') - .map(x => x.trim()); + const [regexString, replacementString] = value.split('->').map(x => x.trim()); const regexp = new RegExp( - // OCaml regexes escape parentheses. - regexString - .substr(1, regexString.length - 2) - .replace(/\\([()])/g, '$1'), - ); + // OCaml regexes escape parentheses. + regexString.substr(1, regexString.length - 2).replace(/\\([()])/g, '$1')); // OCaml uses \1, \2 while JS uses $1, $2... - const replacement = replacementString - .substr(1, replacementString.length - 2) - .replace(/\\[0-9]/g, '$$1'); - return {regexp, replacement}; + const replacement = replacementString.substr(1, replacementString.length - 2).replace(/\\[0-9]/g, '$$1'); + return { regexp, replacement }; }); - nameReducerWhitelist = getPatterns( - flowFileContents.match(/module.system.haste.paths.whitelist=([^\s]+)/g) || - [], - ); - nameReducerBlacklist = getPatterns( - flowFileContents.match(/module.system.haste.paths.blacklist=([^\s]+)/g) || - [], - ); + nameReducerWhitelist = getPatterns(flowFileContents.match(/module.system.haste.paths.whitelist=([^\s]+)/g) || []); + nameReducerBlacklist = getPatterns(flowFileContents.match(/module.system.haste.paths.blacklist=([^\s]+)/g) || []); } return { isHaste, useNameReducers, nameReducers, nameReducerWhitelist, - nameReducerBlacklist, + nameReducerBlacklist }; } -function parseEslintrc(eslintFile: string): ?Array { +function parseEslintrc(eslintFile) { try { - const json = JSON.parse(fs.readFileSync(eslintFile, 'utf8')); + const json = JSON.parse(_fs.default.readFileSync(eslintFile, 'utf8')); return parseEslintConfig(json); } catch (err) {} return null; } -function parseEslintrcJs(eslintFile: string): ?Array { +function parseEslintrcJs(eslintFile) { try { - const js = fs.readFileSync(eslintFile, 'utf8'); + const js = _fs.default.readFileSync(eslintFile, 'utf8'); // Hopefully .eslintrc.js doesn't require very much. - const sandbox: any = {module: {}, require}; - const context = vm.createContext(sandbox); - vm.runInContext(js, context); + const sandbox = { module: {}, require }; + const context = _vm.default.createContext(sandbox); + _vm.default.runInContext(js, context); if (sandbox.module.exports) { return parseEslintConfig(sandbox.module.exports); } else if (sandbox.exports) { @@ -184,9 +160,9 @@ function parseEslintrcJs(eslintFile: string): ?Array { return null; } -function packageJsonEslintConfig(packageJsonFile: string): ?Array { +function packageJsonEslintConfig(packageJsonFile) { try { - const json = JSON.parse(fs.readFileSync(packageJsonFile, 'utf8')); + const json = JSON.parse(_fs.default.readFileSync(packageJsonFile, 'utf8')); if (json.eslintConfig) { return parseEslintConfig(json.eslintConfig); } @@ -194,7 +170,7 @@ function packageJsonEslintConfig(packageJsonFile: string): ?Array { return null; } -function parseEslintConfig(config: Object): Array { +function parseEslintConfig(config) { let globals = new Set(); if (config.globals && typeof config.globals === 'object') { globals = new Set(Object.keys(config.globals)); @@ -207,46 +183,34 @@ function parseEslintConfig(config: Object): Array { return Array.from(globals); } -function getGlobalsForEnvs(envs: Array): Set { +function getGlobalsForEnvs(envs) { const globals = new Set(); envs.forEach(env => { - if (globalsModule[env]) { - Object.keys(globalsModule[env]).forEach(x => globals.add(x)); + if ((_globals || _load_globals())[env]) { + Object.keys((_globals || _load_globals())[env]).forEach(x => globals.add(x)); } }); return globals; } -function getYarnWorkspaces(root: string): Array { +function getYarnWorkspaces(root) { try { - const packageJsonFile = nuclideUri.join(root, 'package.json'); - const json = JSON.parse(fs.readFileSync(packageJsonFile, 'utf8')); + const packageJsonFile = (_nuclideUri || _load_nuclideUri()).default.join(root, 'package.json'); + const json = JSON.parse(_fs.default.readFileSync(packageJsonFile, 'utf8')); if (Array.isArray(json.workspaces)) { - return Array.from( - new Set( - json.workspaces - .map(workspace => { - // Yarn workspaces can be a glob pattern (folder/*) or specific paths. - // Either way, getting the dirname should work for most cases. - if (typeof workspace === 'string') { - try { - return nuclideUri.resolve( - root, - nuclideUri.dirname(workspace), - ); - } catch (err) { - getLogger('js-imports-server').error( - `Could not parse Yarn workspace: ${workspace}`, - err, - ); - return null; - } - } - }) - .filter(Boolean), - ), - ); + return Array.from(new Set(json.workspaces.map(workspace => { + // Yarn workspaces can be a glob pattern (folder/*) or specific paths. + // Either way, getting the dirname should work for most cases. + if (typeof workspace === 'string') { + try { + return (_nuclideUri || _load_nuclideUri()).default.resolve(root, (_nuclideUri || _load_nuclideUri()).default.dirname(workspace)); + } catch (err) { + (0, (_log4js || _load_log4js()).getLogger)('js-imports-server').error(`Could not parse Yarn workspace: ${workspace}`, err); + return null; + } + } + }).filter(Boolean))); } } catch (err) {} return []; -} +} \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/Diagnostics.js b/pkg/nuclide-js-imports-server/src/Diagnostics.js index 9abea1c4e9..55cdaca989 100644 --- a/pkg/nuclide-js-imports-server/src/Diagnostics.js +++ b/pkg/nuclide-js-imports-server/src/Diagnostics.js @@ -1,70 +1,71 @@ -/** - * 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 - */ +'use strict'; -import {DiagnosticSeverity} from 'vscode-languageserver'; -import {AutoImportsManager} from './lib/AutoImportsManager'; -import {ImportFormatter} from './lib/ImportFormatter'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Diagnostics = exports.DIAGNOSTIC_SOURCE = undefined; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {ImportSuggestion} from './lib/types'; +var _vscodeLanguageserver; -export const DIAGNOSTIC_SOURCE = 'JS Auto-imports'; +function _load_vscodeLanguageserver() { + return _vscodeLanguageserver = require('vscode-languageserver'); +} + +var _AutoImportsManager; + +function _load_AutoImportsManager() { + return _AutoImportsManager = require('./lib/AutoImportsManager'); +} + +var _ImportFormatter; -export class Diagnostics { - autoImportsManager: AutoImportsManager; - importFormatter: ImportFormatter; +function _load_ImportFormatter() { + return _ImportFormatter = require('./lib/ImportFormatter'); +} + +const DIAGNOSTIC_SOURCE = exports.DIAGNOSTIC_SOURCE = 'JS Auto-imports'; /** + * 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. + * + * + * @format + */ + +class Diagnostics { - constructor( - autoImportsManager: AutoImportsManager, - importFormatter: ImportFormatter, - ) { + constructor(autoImportsManager, importFormatter) { this.autoImportsManager = autoImportsManager; this.importFormatter = importFormatter; } - findDiagnosticsForFile(text: string, uri: NuclideUri) { + findDiagnosticsForFile(text, uri) { // Note: Don't return diagnostics for types. // It's too hard to match Flow's knowledge of types, particularly flow libs & flow builtins. // Instead, we'll rely on returning code actions for Flow's diagnostics. // (Of course, this is a much slower user experience, but being wrong is even worse.) - return this.autoImportsManager - .findMissingImports(uri, text) - .filter(missingImport => missingImport.symbol.type === 'value') - .map(missingImport => - missingImportToDiagnostic(this.importFormatter, missingImport, uri), - ); + return this.autoImportsManager.findMissingImports(uri, text).filter(missingImport => missingImport.symbol.type === 'value').map(missingImport => missingImportToDiagnostic(this.importFormatter, missingImport, uri)); } } -function missingImportToDiagnostic( - importFormatter: ImportFormatter, - importSuggestion: ImportSuggestion, - uri: NuclideUri, -) { - const {symbol} = importSuggestion; +exports.Diagnostics = Diagnostics; +function missingImportToDiagnostic(importFormatter, importSuggestion, uri) { + const { symbol } = importSuggestion; return { - severity: DiagnosticSeverity.Information, + severity: (_vscodeLanguageserver || _load_vscodeLanguageserver()).DiagnosticSeverity.Information, range: { start: { character: symbol.location.start.col, - line: symbol.location.start.line - 1, + line: symbol.location.start.line - 1 }, end: { character: symbol.location.end.col, - line: symbol.location.end.line - 1, - }, + line: symbol.location.end.line - 1 + } }, - message: - `The ${symbol.type} ${symbol.id} is not imported.\n` + - 'Select a suggestion from the text editor.', - source: DIAGNOSTIC_SOURCE, + message: `The ${symbol.type} ${symbol.id} is not imported.\n` + 'Select a suggestion from the text editor.', + source: DIAGNOSTIC_SOURCE }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/Settings.js b/pkg/nuclide-js-imports-server/src/Settings.js index 997b97c1e0..4c63c19975 100644 --- a/pkg/nuclide-js-imports-server/src/Settings.js +++ b/pkg/nuclide-js-imports-server/src/Settings.js @@ -1,3 +1,8 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,17 +10,17 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -export const Settings = { +const Settings = exports.Settings = { // If initializationOptions are not used or the whitelist is empty, this will // determine whether diagnostics + code actions are displayed. shouldProvideDiagnosticsDefault: true, hasteSettings: { // When true, we will assume that all JS files have a default export // with the same ID as the filename. - shouldAddAllFilesAsDefaultExport: true, - }, -}; + shouldAddAllFilesAsDefaultExport: true + } +}; \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/WorkspaceSymbols.js b/pkg/nuclide-js-imports-server/src/WorkspaceSymbols.js index 00ec1b11b2..f89cd35146 100644 --- a/pkg/nuclide-js-imports-server/src/WorkspaceSymbols.js +++ b/pkg/nuclide-js-imports-server/src/WorkspaceSymbols.js @@ -1,88 +1,87 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type { - SymbolInformation, - WorkspaceSymbolParams, -} from '../../nuclide-vscode-language-service-rpc/lib/protocol'; -import type {AutoImportsManager} from './lib/AutoImportsManager'; -import type {ExportType} from './lib/types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.WorkspaceSymbols = undefined; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {SymbolKind} from '../../nuclide-vscode-language-service-rpc/lib/protocol'; +var _nuclideUri; -const WORKSPACE_SYMBOLS_LIMIT = 30; +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _protocol; + +function _load_protocol() { + return _protocol = require('../../nuclide-vscode-language-service-rpc/lib/protocol'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const WORKSPACE_SYMBOLS_LIMIT = 30; /** + * 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. + * + * strict-local + * @format + */ -function exportTypeToSymbolKind(type?: ExportType): $Values { +function exportTypeToSymbolKind(type) { switch (type) { case 'FunctionDeclaration': case 'FunctionExpression': - return SymbolKind.Function; + return (_protocol || _load_protocol()).SymbolKind.Function; case 'ClassDeclaration': case 'ClassExpression': - return SymbolKind.Class; + return (_protocol || _load_protocol()).SymbolKind.Class; case 'VariableDeclaration': - return SymbolKind.Variable; + return (_protocol || _load_protocol()).SymbolKind.Variable; case 'InterfaceDeclaration': case 'TypeAlias': - return SymbolKind.Interface; + return (_protocol || _load_protocol()).SymbolKind.Interface; case 'ObjectExpression': - return SymbolKind.Module; + return (_protocol || _load_protocol()).SymbolKind.Module; case 'NumericLiteral': - return SymbolKind.Number; + return (_protocol || _load_protocol()).SymbolKind.Number; case 'StringLiteral': - return SymbolKind.String; + return (_protocol || _load_protocol()).SymbolKind.String; default: - return SymbolKind.Module; + return (_protocol || _load_protocol()).SymbolKind.Module; } } -export class WorkspaceSymbols { - static getWorkspaceSymbols( - autoImportsManager: AutoImportsManager, - params: WorkspaceSymbolParams, - ): Array { +class WorkspaceSymbols { + static getWorkspaceSymbols(autoImportsManager, params) { const index = autoImportsManager.exportsManager.getExportsIndex(); - const matchingIds = index.getIdsMatching( - params.query, - WORKSPACE_SYMBOLS_LIMIT, - ); + const matchingIds = index.getIdsMatching(params.query, WORKSPACE_SYMBOLS_LIMIT); return matchingIds.reduce((acc, id) => { if (acc.length >= WORKSPACE_SYMBOLS_LIMIT) { return acc; } const needed = WORKSPACE_SYMBOLS_LIMIT - acc.length; - return acc.concat( - index - .getExportsFromId(id) - .slice(0, needed) - .map(jsExport => { - const position = { - line: jsExport.line - 1, - character: 0, // TODO: not really needed for now. - }; - return { - name: id, - containerName: jsExport.hasteName, - kind: exportTypeToSymbolKind(jsExport.type), - location: { - uri: nuclideUri.nuclideUriToUri(jsExport.uri), - range: { - start: position, - end: position, - }, - }, - }; - }), - ); + return acc.concat(index.getExportsFromId(id).slice(0, needed).map(jsExport => { + const position = { + line: jsExport.line - 1, + character: 0 // TODO: not really needed for now. + }; + return { + name: id, + containerName: jsExport.hasteName, + kind: exportTypeToSymbolKind(jsExport.type), + location: { + uri: (_nuclideUri || _load_nuclideUri()).default.nuclideUriToUri(jsExport.uri), + range: { + start: position, + end: position + } + } + }; + })); }, []); } } +exports.WorkspaceSymbols = WorkspaceSymbols; \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/index.js b/pkg/nuclide-js-imports-server/src/index.js index 920a256949..de8528aeca 100755 --- a/pkg/nuclide-js-imports-server/src/index.js +++ b/pkg/nuclide-js-imports-server/src/index.js @@ -1,3 +1,115 @@ +'use strict'; + +var _idx; + +function _load_idx() { + return _idx = _interopRequireDefault(require('idx')); +} + +var _vscodeLanguageserver; + +function _load_vscodeLanguageserver() { + return _vscodeLanguageserver = require('vscode-languageserver'); +} + +var _vscodeJsonrpc; + +function _load_vscodeJsonrpc() { + return _vscodeJsonrpc = require('vscode-jsonrpc'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _SafeStreamMessageReader; + +function _load_SafeStreamMessageReader() { + return _SafeStreamMessageReader = _interopRequireDefault(require('../../../modules/nuclide-commons/SafeStreamMessageReader')); +} + +var _AutoImportsManager; + +function _load_AutoImportsManager() { + return _AutoImportsManager = require('./lib/AutoImportsManager'); +} + +var _TextDocuments; + +function _load_TextDocuments() { + return _TextDocuments = _interopRequireDefault(require('../../nuclide-lsp-implementation-common/TextDocuments')); +} + +var _ImportFormatter; + +function _load_ImportFormatter() { + return _ImportFormatter = require('./lib/ImportFormatter'); +} + +var _Completions; + +function _load_Completions() { + return _Completions = require('./Completions'); +} + +var _Diagnostics; + +function _load_Diagnostics() { + return _Diagnostics = require('./Diagnostics'); +} + +var _Settings; + +function _load_Settings() { + return _Settings = require('./Settings'); +} + +var _CodeActions; + +function _load_CodeActions() { + return _CodeActions = require('./CodeActions'); +} + +var _CommandExecutor; + +function _load_CommandExecutor() { + return _CommandExecutor = require('./CommandExecutor'); +} + +var _initializeLogging; + +function _load_initializeLogging() { + return _initializeLogging = _interopRequireDefault(require('../logging/initializeLogging')); +} + +var _Config; + +function _load_Config() { + return _Config = require('./Config'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _constantsForClient; + +function _load_constantsForClient() { + return _constantsForClient = require('./utils/constantsForClient'); +} + +var _WorkspaceSymbols; + +function _load_WorkspaceSymbols() { + return _WorkspaceSymbols = require('./WorkspaceSymbols'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,122 +117,63 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import idx from 'idx'; -import {createConnection} from 'vscode-languageserver'; - -import {StreamMessageWriter} from 'vscode-jsonrpc'; -import {getLogger} from 'log4js'; - -import SafeStreamMessageReader from 'nuclide-commons/SafeStreamMessageReader'; -import {AutoImportsManager} from './lib/AutoImportsManager'; -import TextDocuments from '../../nuclide-lsp-implementation-common/TextDocuments'; -import {ImportFormatter} from './lib/ImportFormatter'; -import {Completions} from './Completions'; -import {Diagnostics} from './Diagnostics'; -import {Settings} from './Settings'; -import {CodeActions} from './CodeActions'; -import {CommandExecutor} from './CommandExecutor'; - -import initializeLogging from '../logging/initializeLogging'; -import {getEslintGlobals, getConfigFromFlow} from './Config'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {TAB_SIZE_SIGNIFYING_FIX_ALL_IMPORTS_FORMATTING} from './utils/constantsForClient'; -import {WorkspaceSymbols} from './WorkspaceSymbols'; - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - CodeActionParams, - Command, - CompletionItem, - ExecuteCommandParams, - InitializeResult, - SymbolInformation, - TextDocumentPositionParams, - WorkspaceSymbolParams, -} from '../../nuclide-vscode-language-service-rpc/lib/protocol'; - -const reader = new SafeStreamMessageReader(process.stdin); -const writer = new StreamMessageWriter(process.stdout); - -const connection = createConnection(reader, writer); -initializeLogging(connection); - -const logger = getLogger('nuclide-js-imports-server'); - -const documents: TextDocuments = new TextDocuments(); +const reader = new (_SafeStreamMessageReader || _load_SafeStreamMessageReader()).default(process.stdin); +const writer = new (_vscodeJsonrpc || _load_vscodeJsonrpc()).StreamMessageWriter(process.stdout); + +const connection = (0, (_vscodeLanguageserver || _load_vscodeLanguageserver()).createConnection)(reader, writer); +(0, (_initializeLogging || _load_initializeLogging()).default)(connection); + +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-js-imports-server'); + +const documents = new (_TextDocuments || _load_TextDocuments()).default(); // This will be set based on initializationOptions. const shouldProvideFlags = { - diagnostics: false, + diagnostics: false }; -let autoImportsManager = new AutoImportsManager([]); -let importFormatter = new ImportFormatter([], false); -let completion = new Completions( - documents, - autoImportsManager, - importFormatter, -); -let diagnostics = new Diagnostics(autoImportsManager, importFormatter); -let codeActions = new CodeActions(autoImportsManager, importFormatter); -let commandExecuter = new CommandExecutor( - connection, - autoImportsManager, - importFormatter, - documents, -); - -connection.onInitialize( - (params): InitializeResult => { - const root = params.rootPath || process.cwd(); - logger.debug('Server initialized.'); - const eslintGlobals = getEslintGlobals(root); - const flowConfig = getConfigFromFlow(root); - shouldProvideFlags.diagnostics = shouldProvideDiagnostics(params, root); - importFormatter = new ImportFormatter( - flowConfig.moduleDirs, - shouldUseRequires(params, root), - ); - autoImportsManager = new AutoImportsManager(eslintGlobals); - autoImportsManager.indexAndWatchDirectory(root); - completion = new Completions( - documents, - autoImportsManager, - importFormatter, - ); - diagnostics = new Diagnostics(autoImportsManager, importFormatter); - codeActions = new CodeActions(autoImportsManager, importFormatter); - commandExecuter = new CommandExecutor( - connection, - autoImportsManager, - importFormatter, - documents, - ); - return { - capabilities: { - textDocumentSync: documents.syncKind, - completionProvider: { - resolveProvider: true, - triggerCharacters: getAllTriggerCharacters(), - }, - codeActionProvider: true, - documentFormattingProvider: true, - executeCommandProvider: Array.from( - Object.keys(CommandExecutor.COMMANDS), - ), - workspaceSymbolProvider: true, +let autoImportsManager = new (_AutoImportsManager || _load_AutoImportsManager()).AutoImportsManager([]); +let importFormatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter([], false); +let completion = new (_Completions || _load_Completions()).Completions(documents, autoImportsManager, importFormatter); +let diagnostics = new (_Diagnostics || _load_Diagnostics()).Diagnostics(autoImportsManager, importFormatter); +let codeActions = new (_CodeActions || _load_CodeActions()).CodeActions(autoImportsManager, importFormatter); +let commandExecuter = new (_CommandExecutor || _load_CommandExecutor()).CommandExecutor(connection, autoImportsManager, importFormatter, documents); + +connection.onInitialize(params => { + const root = params.rootPath || process.cwd(); + logger.debug('Server initialized.'); + const eslintGlobals = (0, (_Config || _load_Config()).getEslintGlobals)(root); + const flowConfig = (0, (_Config || _load_Config()).getConfigFromFlow)(root); + shouldProvideFlags.diagnostics = shouldProvideDiagnostics(params, root); + importFormatter = new (_ImportFormatter || _load_ImportFormatter()).ImportFormatter(flowConfig.moduleDirs, shouldUseRequires(params, root)); + autoImportsManager = new (_AutoImportsManager || _load_AutoImportsManager()).AutoImportsManager(eslintGlobals); + autoImportsManager.indexAndWatchDirectory(root); + completion = new (_Completions || _load_Completions()).Completions(documents, autoImportsManager, importFormatter); + diagnostics = new (_Diagnostics || _load_Diagnostics()).Diagnostics(autoImportsManager, importFormatter); + codeActions = new (_CodeActions || _load_CodeActions()).CodeActions(autoImportsManager, importFormatter); + commandExecuter = new (_CommandExecutor || _load_CommandExecutor()).CommandExecutor(connection, autoImportsManager, importFormatter, documents); + return { + capabilities: { + textDocumentSync: documents.syncKind, + completionProvider: { + resolveProvider: true, + triggerCharacters: getAllTriggerCharacters() }, - }; - }, -); + codeActionProvider: true, + documentFormattingProvider: true, + executeCommandProvider: Array.from(Object.keys((_CommandExecutor || _load_CommandExecutor()).CommandExecutor.COMMANDS)), + workspaceSymbolProvider: true + } + }; +}); documents.onDidOpenTextDocument(params => { try { - const uri = nuclideUri.uriToNuclideUri(params.textDocument.uri); + const uri = (_nuclideUri || _load_nuclideUri()).default.uriToNuclideUri(params.textDocument.uri); if (uri != null) { autoImportsManager.workerIndexFile(uri, params.textDocument.getText()); findAndSendDiagnostics(params.textDocument.getText(), uri); @@ -132,7 +185,7 @@ documents.onDidOpenTextDocument(params => { documents.onDidChangeContent(params => { try { - const uri = nuclideUri.uriToNuclideUri(params.textDocument.uri); + const uri = (_nuclideUri || _load_nuclideUri()).default.uriToNuclideUri(params.textDocument.uri); if (uri != null) { autoImportsManager.workerIndexFile(uri, params.textDocument.getText()); findAndSendDiagnostics(params.textDocument.getText(), uri); @@ -144,76 +197,54 @@ documents.onDidChangeContent(params => { documents.onDidClose(params => { // Clear out diagnostics. - connection.sendDiagnostics({uri: params.textDocument.uri, diagnostics: []}); + connection.sendDiagnostics({ uri: params.textDocument.uri, diagnostics: [] }); }); -function findAndSendDiagnostics(text: string, uri: NuclideUri): void { +function findAndSendDiagnostics(text, uri) { if (shouldProvideFlags.diagnostics) { const diagnosticsForFile = diagnostics.findDiagnosticsForFile(text, uri); connection.sendDiagnostics({ - uri: nuclideUri.nuclideUriToUri(uri), - diagnostics: diagnosticsForFile, + uri: (_nuclideUri || _load_nuclideUri()).default.nuclideUriToUri(uri), + diagnostics: diagnosticsForFile }); } } // Code completion: -connection.onCompletion( - (textDocumentPosition: TextDocumentPositionParams): Array => { - const nuclideFormattedUri = nuclideUri.uriToNuclideUri( - textDocumentPosition.textDocument.uri, - ); - return nuclideFormattedUri != null - ? completion.provideCompletions(textDocumentPosition, nuclideFormattedUri) - : []; - }, -); - -connection.onCodeAction( - (codeActionParams: CodeActionParams): Array => { - try { - const uri = nuclideUri.uriToNuclideUri(codeActionParams.textDocument.uri); - return uri != null - ? codeActions.provideCodeActions( - codeActionParams.context && codeActionParams.context.diagnostics, - uri, - ) - : []; - } catch (error) { - logger.error(error); - return []; - } - }, -); - -connection.onExecuteCommand( - (params: ExecuteCommandParams): any => { - const {command, arguments: args} = params; - logger.debug('Executing command', command, 'with args', args); - commandExecuter.executeCommand((command: any), args); - }, -); - -connection.onWorkspaceSymbol( - (params: WorkspaceSymbolParams): Array => { - return WorkspaceSymbols.getWorkspaceSymbols(autoImportsManager, params); - }, -); +connection.onCompletion(textDocumentPosition => { + const nuclideFormattedUri = (_nuclideUri || _load_nuclideUri()).default.uriToNuclideUri(textDocumentPosition.textDocument.uri); + return nuclideFormattedUri != null ? completion.provideCompletions(textDocumentPosition, nuclideFormattedUri) : []; +}); + +connection.onCodeAction(codeActionParams => { + try { + const uri = (_nuclideUri || _load_nuclideUri()).default.uriToNuclideUri(codeActionParams.textDocument.uri); + return uri != null ? codeActions.provideCodeActions(codeActionParams.context && codeActionParams.context.diagnostics, uri) : []; + } catch (error) { + logger.error(error); + return []; + } +}); + +connection.onExecuteCommand(params => { + const { command, arguments: args } = params; + logger.debug('Executing command', command, 'with args', args); + commandExecuter.executeCommand(command, args); +}); + +connection.onWorkspaceSymbol(params => { + return (_WorkspaceSymbols || _load_WorkspaceSymbols()).WorkspaceSymbols.getWorkspaceSymbols(autoImportsManager, params); +}); connection.onDocumentFormatting(params => { - const fileUri = nuclideUri.uriToNuclideUri(params.textDocument.uri); - return Promise.resolve( - params.options.tabSize !== TAB_SIZE_SIGNIFYING_FIX_ALL_IMPORTS_FORMATTING || - fileUri == null - ? [] - : commandExecuter.getEditsForFixingAllImports(fileUri), - ); + const fileUri = (_nuclideUri || _load_nuclideUri()).default.uriToNuclideUri(params.textDocument.uri); + return Promise.resolve(params.options.tabSize !== (_constantsForClient || _load_constantsForClient()).TAB_SIZE_SIGNIFYING_FIX_ALL_IMPORTS_FORMATTING || fileUri == null ? [] : commandExecuter.getEditsForFixingAllImports(fileUri)); }); documents.listen(connection); connection.listen(); -function getAllTriggerCharacters(): Array { +function getAllTriggerCharacters() { const characters = [' ', '}', '=']; // Add all the characters from A-z for (let char = 'A'.charCodeAt(0); char <= 'z'.charCodeAt(0); char++) { @@ -222,16 +253,16 @@ function getAllTriggerCharacters(): Array { return characters; } -function shouldProvideDiagnostics(params: Object, root: NuclideUri): boolean { - const diagnosticsWhitelist = - idx(params, _ => _.initializationOptions.diagnosticsWhitelist) || []; - return diagnosticsWhitelist.length !== 0 - ? diagnosticsWhitelist.some(regex => root.match(new RegExp(regex))) - : Settings.shouldProvideDiagnosticsDefault; +function shouldProvideDiagnostics(params, root) { + var _ref, _ref2; + + const diagnosticsWhitelist = ((_ref = params) != null ? (_ref2 = _ref.initializationOptions) != null ? _ref2.diagnosticsWhitelist : _ref2 : _ref) || []; + return diagnosticsWhitelist.length !== 0 ? diagnosticsWhitelist.some(regex => root.match(new RegExp(regex))) : (_Settings || _load_Settings()).Settings.shouldProvideDiagnosticsDefault; } -function shouldUseRequires(params: Object, root: NuclideUri): boolean { - const requiresWhitelist = - idx(params, _ => _.initializationOptions.requiresWhitelist) || []; +function shouldUseRequires(params, root) { + var _ref3, _ref4; + + const requiresWhitelist = ((_ref3 = params) != null ? (_ref4 = _ref3.initializationOptions) != null ? _ref4.requiresWhitelist : _ref4 : _ref3) || []; return requiresWhitelist.some(regex => root.match(new RegExp(regex))); -} +} \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/lib/AutoImportsManager.js b/pkg/nuclide-js-imports-server/src/lib/AutoImportsManager.js index 69bf38810c..4fee251520 100644 --- a/pkg/nuclide-js-imports-server/src/lib/AutoImportsManager.js +++ b/pkg/nuclide-js-imports-server/src/lib/AutoImportsManager.js @@ -1,3 +1,71 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AutoImportsManager = exports.babylonOptions = undefined; +exports.parseFile = parseFile; + +var _child_process = _interopRequireDefault(require('child_process')); + +var _ExportManager; + +function _load_ExportManager() { + return _ExportManager = require('./ExportManager'); +} + +var _UndefinedSymbolManager; + +function _load_UndefinedSymbolManager() { + return _UndefinedSymbolManager = require('./UndefinedSymbolManager'); +} + +var _babylon; + +function _load_babylon() { + return _babylon = _interopRequireWildcard(require('babylon')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../../modules/nuclide-commons/nuclideUri')); +} + +var _util; + +function _load_util() { + return _util = require('../utils/util'); +} + +var _lspUtils; + +function _load_lspUtils() { + return _lspUtils = require('../../../nuclide-lsp-implementation-common/lsp-utils'); +} + +var _simpleTextBuffer; + +function _load_simpleTextBuffer() { + return _simpleTextBuffer = require('simple-text-buffer'); +} + +var _vscodeLanguageserver; + +function _load_vscodeLanguageserver() { + return _vscodeLanguageserver = require('vscode-languageserver'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,39 +73,16 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import child_process from 'child_process'; -import {ExportManager} from './ExportManager'; -import {UndefinedSymbolManager} from './UndefinedSymbolManager'; -import * as babylon from 'babylon'; -import {getLogger} from 'log4js'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {babelLocationToAtomRange} from '../utils/util'; -import {lspRangeToAtomRange} from '../../../nuclide-lsp-implementation-common/lsp-utils'; -import {Range} from 'simple-text-buffer'; -import {IRange} from 'vscode-languageserver'; - -import type {ImportSuggestion} from './types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {JSExport, UndefinedSymbol} from './types'; -import type {ExportUpdateForFile} from './AutoImportsWorker'; - -export const babylonOptions = { +const babylonOptions = exports.babylonOptions = { sourceType: 'module', - plugins: [ - 'jsx', - 'flow', - 'exportExtensions', - 'objectRestSpread', - 'classProperties', - 'optionalChaining', - ], + plugins: ['jsx', 'flow', 'exportExtensions', 'objectRestSpread', 'classProperties', 'optionalChaining'] }; -const logger = getLogger(); +const logger = (0, (_log4js || _load_log4js()).getLogger)(); // Whether files that have disabled eslint with a comment should be ignored. const IGNORE_ESLINT_DISABLED_FILES = true; @@ -47,22 +92,17 @@ const LARGE_FILE_LIMIT = 2000000; const MAX_CRASHES = 3; -export class AutoImportsManager { - suggestedImports: Map>; - exportsManager: ExportManager; - undefinedSymbolsManager: UndefinedSymbolManager; - crashes: number; - worker: ?child_process$ChildProcess; +class AutoImportsManager { - constructor(globals: Array) { + constructor(globals) { this.suggestedImports = new Map(); - this.exportsManager = new ExportManager(); - this.undefinedSymbolsManager = new UndefinedSymbolManager(globals); + this.exportsManager = new (_ExportManager || _load_ExportManager()).ExportManager(); + this.undefinedSymbolsManager = new (_UndefinedSymbolManager || _load_UndefinedSymbolManager()).UndefinedSymbolManager(globals); this.crashes = 0; } // Only indexes the file (used for testing purposes) - indexFile(fileUri: NuclideUri, code: string): void { + indexFile(fileUri, code) { const ast = parseFile(code); if (ast) { this.exportsManager.addFile(fileUri, ast); @@ -71,20 +111,15 @@ export class AutoImportsManager { // Indexes an entire directory recursively in another process, watches for changes // and listens for messages from this process to index a file. - indexAndWatchDirectory(root: NuclideUri) { + indexAndWatchDirectory(root) { logger.debug('Indexing the directory', root, 'recursively'); - const worker = child_process.fork( - nuclideUri.join(__dirname, 'AutoImportsWorker-entry.js'), - [root], - ); - worker.on('message', (updateForFile: Array) => { + const worker = _child_process.default.fork((_nuclideUri || _load_nuclideUri()).default.join(__dirname, 'AutoImportsWorker-entry.js'), [root]); + worker.on('message', updateForFile => { updateForFile.forEach(this.handleUpdateForFile.bind(this)); }); worker.on('exit', code => { - logger.error( - `AutoImportsWorker exited with code ${code} (retry: ${this.crashes})`, - ); + logger.error(`AutoImportsWorker exited with code ${code} (retry: ${this.crashes})`); this.crashes += 1; if (this.crashes < MAX_CRASHES) { this.indexAndWatchDirectory(root); @@ -98,44 +133,31 @@ export class AutoImportsManager { // Tells the AutoImportsWorker to index a file. indexAndWatchDirectory must be // called first on a directory that is a parent of fileUri. - workerIndexFile(fileUri: NuclideUri, fileContents: string) { + workerIndexFile(fileUri, fileContents) { if (this.worker == null) { logger.debug(`Worker is not running when asked to index ${fileUri}`); return; } - this.worker.send({fileUri, fileContents}); + this.worker.send({ fileUri, fileContents }); } - findMissingImports( - fileUri: NuclideUri, - code: string, - onlyAvailableExports: boolean = true, - ): Array { + findMissingImports(fileUri, code, onlyAvailableExports = true) { const ast = parseFile(code); return this.findMissingImportsInAST(fileUri, ast, onlyAvailableExports); } - findMissingImportsInAST( - fileUri: NuclideUri, - ast: ?Object, - onlyAvailableExports: boolean, - ): Array { + findMissingImportsInAST(fileUri, ast, onlyAvailableExports) { if (ast == null || checkEslint(ast)) { return []; } - const missingImports = undefinedSymbolsToMissingImports( - fileUri, - this.undefinedSymbolsManager.findUndefined(ast), - this.exportsManager, - onlyAvailableExports, - ); + const missingImports = undefinedSymbolsToMissingImports(fileUri, this.undefinedSymbolsManager.findUndefined(ast), this.exportsManager, onlyAvailableExports); this.suggestedImports.set(fileUri, missingImports); return missingImports; } - handleUpdateForFile(update: ExportUpdateForFile) { - const {updateType, file, exports} = update; + handleUpdateForFile(update) { + const { updateType, file, exports } = update; switch (updateType) { case 'setExports': this.exportsManager.setExportsForFile(file, exports); @@ -146,32 +168,27 @@ export class AutoImportsManager { } } - findFilesWithSymbol(id: string): Array { + findFilesWithSymbol(id) { return this.exportsManager.getExportsIndex().getExportsFromId(id); } - getSuggestedImportsForRange( - file: NuclideUri, - range: IRange, - ): Array { + getSuggestedImportsForRange(file, range) { const suggestedImports = this.suggestedImports.get(file) || []; return suggestedImports.filter(suggestedImport => { // We use intersectsWith instead of containsRange to be compatible with clients // like VSCode which may request small ranges (the range of the current word). - return Range.fromObject(lspRangeToAtomRange(range)).intersectsWith( - babelLocationToAtomRange(suggestedImport.symbol.location), - true, - ); + return (_simpleTextBuffer || _load_simpleTextBuffer()).Range.fromObject((0, (_lspUtils || _load_lspUtils()).lspRangeToAtomRange)(range)).intersectsWith((0, (_util || _load_util()).babelLocationToAtomRange)(suggestedImport.symbol.location), true); }); } } -export function parseFile(code: string): ?Object { +exports.AutoImportsManager = AutoImportsManager; +function parseFile(code) { if (code.length >= LARGE_FILE_LIMIT) { return null; } try { - return babylon.parse(code, babylonOptions); + return (_babylon || _load_babylon()).parse(code, babylonOptions); } catch (error) { // Encountered a parsing error. We don't log anything because this will be // quite common as this function can and will be called on every file edit. @@ -179,43 +196,23 @@ export function parseFile(code: string): ?Object { } } -function undefinedSymbolsToMissingImports( - fileUri: NuclideUri, - undefinedSymbols: Array, - exportsManager: ExportManager, - onlyAvailableExports: boolean, -): Array { - return undefinedSymbols - .map(symbol => { - const isValue = symbol.type === 'value'; - return { - symbol, - filesWithExport: exportsManager - .getExportsIndex() - .getExportsFromId(symbol.id) - .filter(jsExport => { - // Value imports cannot use type exports. - if (isValue && jsExport.isTypeExport) { - return false; - } - // No self imports. - return jsExport.uri !== fileUri; - }), - }; - }) - .filter( - result => !onlyAvailableExports || result.filesWithExport.length > 0, - ); +function undefinedSymbolsToMissingImports(fileUri, undefinedSymbols, exportsManager, onlyAvailableExports) { + return undefinedSymbols.map(symbol => { + const isValue = symbol.type === 'value'; + return { + symbol, + filesWithExport: exportsManager.getExportsIndex().getExportsFromId(symbol.id).filter(jsExport => { + // Value imports cannot use type exports. + if (isValue && jsExport.isTypeExport) { + return false; + } + // No self imports. + return jsExport.uri !== fileUri; + }) + }; + }).filter(result => !onlyAvailableExports || result.filesWithExport.length > 0); } -function checkEslint(ast: Object): boolean { - return ( - IGNORE_ESLINT_DISABLED_FILES && - (ast.comments && - ast.comments.find( - comment => - comment.type === 'CommentBlock' && - comment.value.trim() === 'eslint-disable', - )) - ); -} +function checkEslint(ast) { + return IGNORE_ESLINT_DISABLED_FILES && ast.comments && ast.comments.find(comment => comment.type === 'CommentBlock' && comment.value.trim() === 'eslint-disable'); +} \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/lib/AutoImportsWorker.js b/pkg/nuclide-js-imports-server/src/lib/AutoImportsWorker.js index f0492e3b79..aa3195eaaa 100644 --- a/pkg/nuclide-js-imports-server/src/lib/AutoImportsWorker.js +++ b/pkg/nuclide-js-imports-server/src/lib/AutoImportsWorker.js @@ -1,40 +1,110 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _memoize2; + +function _load_memoize() { + return _memoize2 = _interopRequireDefault(require('lodash/memoize')); +} + +exports.indexDirectory = indexDirectory; +exports.indexNodeModules = indexNodeModules; + +var _crypto = _interopRequireDefault(require('crypto')); + +var _log4js; + +function _load_log4js() { + return _log4js = _interopRequireDefault(require('log4js')); +} + +var _os = _interopRequireDefault(require('os')); + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../../modules/nuclide-commons/nuclideUri')); +} + +var _observable; + +function _load_observable() { + return _observable = require('../../../../modules/nuclide-commons/observable'); +} + +var _ExportCache; + +function _load_ExportCache() { + return _ExportCache = _interopRequireDefault(require('./ExportCache')); +} + +var _ExportManager; + +function _load_ExportManager() { + return _ExportManager = require('./ExportManager'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _AutoImportsManager; + +function _load_AutoImportsManager() { + return _AutoImportsManager = require('./AutoImportsManager'); +} + +var _initializeLogging; + +function _load_initializeLogging() { + return _initializeLogging = require('../../logging/initializeLogging'); +} + +var _Config; -import crypto from 'crypto'; -import {memoize} from 'lodash'; -import log4js from 'log4js'; -import os from 'os'; -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {compact} from 'nuclide-commons/observable'; -import ExportCache from './ExportCache'; -import {getExportsFromAst, idFromFileName} from './ExportManager'; -import {Observable} from 'rxjs'; -import {parseFile} from './AutoImportsManager'; -import {initializeLoggerForWorker} from '../../logging/initializeLogging'; -import {getConfigFromFlow} from '../Config'; -import {niceSafeSpawn} from 'nuclide-commons/nice'; -import invariant from 'assert'; -import {getHasteName, hasteReduceName} from './HasteUtils'; -import {watchDirectory, getFileIndex} from './file-index'; - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {HasteSettings} from '../Config'; -import type {JSExport} from './types'; -import type {FileChange} from 'nuclide-watchman-helpers'; -import type {FileIndex} from './file-index'; - -initializeLoggerForWorker(); -const logger = log4js.getLogger('js-imports-worker'); +function _load_Config() { + return _Config = require('../Config'); +} + +var _nice; + +function _load_nice() { + return _nice = require('../../../../modules/nuclide-commons/nice'); +} + +var _HasteUtils; + +function _load_HasteUtils() { + return _HasteUtils = require('./HasteUtils'); +} + +var _fileIndex; + +function _load_fileIndex() { + return _fileIndex = require('./file-index'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +(0, (_initializeLogging || _load_initializeLogging()).initializeLoggerForWorker)(); /** + * 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. + * + * + * @format + */ + +const logger = (_log4js || _load_log4js()).default.getLogger('js-imports-worker'); const CONCURRENCY = 1; @@ -42,17 +112,10 @@ const CONCURRENCY = 1; // For this reason, it's very important to send updates in smaller batches. const BATCH_SIZE = 500; -const cpus = os.cpus(); +const cpus = _os.default.cpus(); const MAX_WORKERS = cpus ? Math.max(1, Math.round(cpus.length / 2)) : 1; const MIN_FILES_PER_WORKER = 100; -export type ExportUpdateForFile = { - updateType: 'setExports' | 'deleteExports', - file: NuclideUri, - sha1?: string, - exports: Array, -}; - async function main() { if (process.argv.length > 2 && process.argv[2] === '--child') { return runChild(); @@ -64,8 +127,8 @@ async function main() { return; } const root = process.argv[2]; - const configFromFlow = getConfigFromFlow(root); - const {hasteSettings} = configFromFlow; + const configFromFlow = (0, (_Config || _load_Config()).getConfigFromFlow)(root); + const { hasteSettings } = configFromFlow; // Listen for open files that should be indexed immediately setupParentMessagesHandler(root, hasteSettings); @@ -74,113 +137,78 @@ async function main() { watchDirectoryRecursively(root, hasteSettings); // Build up the initial index with all files recursively from the root. - const index = await getFileIndex(root, configFromFlow); - const newCache = new ExportCache({root, configFromFlow}); - - Observable.merge( - indexDirectory(index, hasteSettings), - indexNodeModules(index), - ).subscribe( - message => { - sendUpdatesBatched(message); - message.forEach(update => { - if (update.sha1 != null) { - newCache.set( - {filePath: update.file, sha1: update.sha1}, - update.exports, - ); - } - }); - }, - error => { - logger.error('Received error while indexing files', error); - }, - () => { - newCache.save().then(success => { - if (success) { - logger.info(`Saved cache of size ${newCache.getByteSize()}`); - } else { - logger.warn(`Failed to save cache to ${newCache.getPath()}`); - } - disposeForGC(index, newCache); - }); - }, - ); + const index = await (0, (_fileIndex || _load_fileIndex()).getFileIndex)(root, configFromFlow); + const newCache = new (_ExportCache || _load_ExportCache()).default({ root, configFromFlow }); + + _rxjsBundlesRxMinJs.Observable.merge(indexDirectory(index, hasteSettings), indexNodeModules(index)).subscribe(message => { + sendUpdatesBatched(message); + message.forEach(update => { + if (update.sha1 != null) { + newCache.set({ filePath: update.file, sha1: update.sha1 }, update.exports); + } + }); + }, error => { + logger.error('Received error while indexing files', error); + }, () => { + newCache.save().then(success => { + if (success) { + logger.info(`Saved cache of size ${newCache.getByteSize()}`); + } else { + logger.warn(`Failed to save cache to ${newCache.getPath()}`); + } + disposeForGC(index, newCache); + }); + }); } // It appears that the index/cache objects are retained by RxJS. // To enable garbage collection after indexing, manually clear out the objects. -function disposeForGC(index: FileIndex, cache: ExportCache) { +function disposeForGC(index, cache) { index.jsFiles.length = 0; index.nodeModulesPackageJsonFiles.length = 0; index.mainFiles.clear(); - index.exportCache._cache = (null: any); - cache._cache = (null: any); + index.exportCache._cache = null; + cache._cache = null; } // Watches a directory for changes and reindexes files as needed. -function watchDirectoryRecursively( - root: NuclideUri, - hasteSettings: HasteSettings, -) { - watchDirectory(root) - .mergeMap( - (fileChange: FileChange) => - handleFileChange(root, fileChange, hasteSettings), - CONCURRENCY, - ) - .subscribe( - () => {}, - error => { - logger.error(`Failed to watch ${root}`, error); - }, - ); +function watchDirectoryRecursively(root, hasteSettings) { + (0, (_fileIndex || _load_fileIndex()).watchDirectory)(root).mergeMap(fileChange => handleFileChange(root, fileChange, hasteSettings), CONCURRENCY).subscribe(() => {}, error => { + logger.error(`Failed to watch ${root}`, error); + }); } -async function handleFileChange( - root: NuclideUri, - fileChange: FileChange, - hasteSettings: HasteSettings, -): Promise { +async function handleFileChange(root, fileChange, hasteSettings) { if (fileChange.exists) { // File created or modified - const exportForFile = await getExportsForFileWithMain( - fileChange.name, - hasteSettings, - ); + const exportForFile = await getExportsForFileWithMain(fileChange.name, hasteSettings); if (exportForFile) { sendUpdatesBatched([exportForFile]); } } else { // File deleted. - sendUpdatesBatched([ - { - updateType: 'deleteExports', - file: fileChange.name, - exports: [], - }, - ]); + sendUpdatesBatched([{ + updateType: 'deleteExports', + file: fileChange.name, + exports: [] + }]); } } // Exported for testing purposes. -export function indexDirectory( - {root, exportCache, jsFiles, mainFiles}: FileIndex, - hasteSettings: HasteSettings, - maxWorkers?: number = MAX_WORKERS, -): Observable> { +function indexDirectory({ root, exportCache, jsFiles, mainFiles }, hasteSettings, maxWorkers = MAX_WORKERS) { let cachedUpdates = []; const files = []; - jsFiles.forEach(({name, sha1}) => { - const filePath = nuclideUri.join(root, name); + jsFiles.forEach(({ name, sha1 }) => { + const filePath = (_nuclideUri || _load_nuclideUri()).default.join(root, name); if (sha1 != null) { - const cached = exportCache.get({filePath, sha1}); + const cached = exportCache.get({ filePath, sha1 }); if (cached != null) { cachedUpdates.push({ updateType: 'setExports', file: filePath, sha1, - exports: cached, + exports: cached }); return; } @@ -189,96 +217,66 @@ export function indexDirectory( }); // To get faster results, we can send up the Haste reduced names as a default export. if (hasteSettings.isHaste && hasteSettings.useNameReducers) { - cachedUpdates = cachedUpdates.concat( - getHasteNames(root, files, hasteSettings), - ); + cachedUpdates = cachedUpdates.concat(getHasteNames(root, files, hasteSettings)); } logger.info(`Indexing ${files.length} files`); // As an optimization, shuffle the files so that the work is well distributed. shuffle(files); - const numWorkers = Math.min( - Math.max(1, Math.floor(files.length / MIN_FILES_PER_WORKER)), - maxWorkers, - ); + const numWorkers = Math.min(Math.max(1, Math.floor(files.length / MIN_FILES_PER_WORKER)), maxWorkers); const filesPerWorker = Math.ceil(files.length / numWorkers); - const workerMessages = Observable.range(0, numWorkers) - .mergeMap(workerId => { - return niceSafeSpawn( - process.execPath, - [ - nuclideUri.join(__dirname, 'AutoImportsWorker-entry.js'), - '--child', - root, - ], - { - stdio: ['inherit', 'inherit', 'inherit', 'ipc'], - }, - ); - }) - .mergeMap((worker, workerId) => { - invariant(typeof workerId === 'number'); // For Flow - const updateStream = Observable.fromEvent(worker, 'message') - .takeUntil( - Observable.fromEvent(worker, 'error').do(error => { - logger.warn(`Worker ${workerId} had received`, error); - }), - ) - .takeUntil( - Observable.fromEvent(worker, 'exit').do(() => { - logger.debug(`Worker ${workerId} terminated.`); - }), - ); - return Observable.merge( - updateStream, - Observable.timer(0) - .do(() => { - worker.send({ - files: files.slice( - workerId * filesPerWorker, - Math.min((workerId + 1) * filesPerWorker, files.length), - ), - }); - }) - .ignoreElements(), - ); + const workerMessages = _rxjsBundlesRxMinJs.Observable.range(0, numWorkers).mergeMap(workerId => { + return (0, (_nice || _load_nice()).niceSafeSpawn)(process.execPath, [(_nuclideUri || _load_nuclideUri()).default.join(__dirname, 'AutoImportsWorker-entry.js'), '--child', root], { + stdio: ['inherit', 'inherit', 'inherit', 'ipc'] }); - - return Observable.of(cachedUpdates) - .concat(workerMessages) - .map(message => { - // Inject the main files at this point, since we have a list of all map files. - // This could be pure but it's just not worth the cost. - message.forEach(update => { - const mainDir = mainFiles.get(update.file); - if (mainDir != null) { - decorateExportUpdateWithMainDirectory(update, mainDir); - } + }).mergeMap((worker, workerId) => { + if (!(typeof workerId === 'number')) { + throw new Error('Invariant violation: "typeof workerId === \'number\'"'); + } // For Flow + + + const updateStream = _rxjsBundlesRxMinJs.Observable.fromEvent(worker, 'message').takeUntil(_rxjsBundlesRxMinJs.Observable.fromEvent(worker, 'error').do(error => { + logger.warn(`Worker ${workerId} had received`, error); + })).takeUntil(_rxjsBundlesRxMinJs.Observable.fromEvent(worker, 'exit').do(() => { + logger.debug(`Worker ${workerId} terminated.`); + })); + return _rxjsBundlesRxMinJs.Observable.merge(updateStream, _rxjsBundlesRxMinJs.Observable.timer(0).do(() => { + worker.send({ + files: files.slice(workerId * filesPerWorker, Math.min((workerId + 1) * filesPerWorker, files.length)) }); - return message; + }).ignoreElements()); + }); + + return _rxjsBundlesRxMinJs.Observable.of(cachedUpdates).concat(workerMessages).map(message => { + // Inject the main files at this point, since we have a list of all map files. + // This could be pure but it's just not worth the cost. + message.forEach(update => { + const mainDir = mainFiles.get(update.file); + if (mainDir != null) { + decorateExportUpdateWithMainDirectory(update, mainDir); + } }); + return message; + }); } -const getPackageJson = memoize(async (dir: NuclideUri) => { +const getPackageJson = (0, (_memoize2 || _load_memoize()).default)(async dir => { // Bail out at the FS root. - const parent = nuclideUri.dirname(dir); + const parent = (_nuclideUri || _load_nuclideUri()).default.dirname(dir); if (parent === dir) { return null; } - const packageJson = nuclideUri.join(dir, 'package.json'); + const packageJson = (_nuclideUri || _load_nuclideUri()).default.join(dir, 'package.json'); let fileContents; try { - fileContents = await fsPromise.readFile(packageJson, 'utf8'); + fileContents = await (_fsPromise || _load_fsPromise()).default.readFile(packageJson, 'utf8'); } catch (err) { return getPackageJson(parent); } try { return { dirname: dir, - main: nuclideUri.resolve( - dir, - JSON.parse(fileContents).main || 'index.js', - ), + main: (_nuclideUri || _load_nuclideUri()).default.resolve(dir, JSON.parse(fileContents).main || 'index.js') }; } catch (err) { return null; @@ -289,97 +287,66 @@ const getPackageJson = memoize(async (dir: NuclideUri) => { * Returns the directory of the nearest package.json if `file` matches the "main" field. * This ensures that e.g. package/index.js can be imported as just "package". */ -async function checkIfMain(file: NuclideUri): Promise { - const pkgJson = await getPackageJson(nuclideUri.dirname(file)); - return pkgJson != null && - nuclideUri.stripExtension(pkgJson.main) === nuclideUri.stripExtension(file) - ? pkgJson.dirname - : null; +async function checkIfMain(file) { + const pkgJson = await getPackageJson((_nuclideUri || _load_nuclideUri()).default.dirname(file)); + return pkgJson != null && (_nuclideUri || _load_nuclideUri()).default.stripExtension(pkgJson.main) === (_nuclideUri || _load_nuclideUri()).default.stripExtension(file) ? pkgJson.dirname : null; } -function getExportsForFileWithMain( - path: NuclideUri, - hasteSettings: HasteSettings, - fileContents?: string, -): Promise { - return Promise.all([ - getExportsForFile(path, hasteSettings, fileContents), - checkIfMain(path), - ]).then(([data, directoryForMainFile]) => { - return data - ? decorateExportUpdateWithMainDirectory(data, directoryForMainFile) - : null; +function getExportsForFileWithMain(path, hasteSettings, fileContents) { + return Promise.all([getExportsForFile(path, hasteSettings, fileContents), checkIfMain(path)]).then(([data, directoryForMainFile]) => { + return data ? decorateExportUpdateWithMainDirectory(data, directoryForMainFile) : null; }); } -async function getExportsForFile( - file: NuclideUri, - hasteSettings: HasteSettings, - fileContents_?: string, -): Promise { +async function getExportsForFile(file, hasteSettings, fileContents_) { try { - const fileContents = - fileContents_ != null - ? fileContents_ - : await fsPromise.readFile(file, 'utf8'); - const sha1 = crypto - .createHash('sha1') - .update(fileContents) - .digest('hex'); + const fileContents = fileContents_ != null ? fileContents_ : await (_fsPromise || _load_fsPromise()).default.readFile(file, 'utf8'); + const sha1 = _crypto.default.createHash('sha1').update(fileContents).digest('hex'); const update = { updateType: 'setExports', file, sha1, - exports: [], + exports: [] }; - const ast = parseFile(fileContents); + const ast = (0, (_AutoImportsManager || _load_AutoImportsManager()).parseFile)(fileContents); if (ast == null) { return update; } - const hasteName = getHasteName(file, ast, hasteSettings); + const hasteName = (0, (_HasteUtils || _load_HasteUtils()).getHasteName)(file, ast, hasteSettings); // TODO(hansonw): Support mixed-mode haste + non-haste imports. // For now, if Haste is enabled, we'll only suggest Haste imports. if (hasteSettings.isHaste && hasteName == null) { return update; } - const exports = getExportsFromAst(file, ast); + const exports = (0, (_ExportManager || _load_ExportManager()).getExportsFromAst)(file, ast); if (hasteName != null) { exports.forEach(jsExport => { jsExport.hasteName = hasteName; }); } - return {...update, exports}; + return Object.assign({}, update, { exports }); } catch (err) { logger.error(`Unexpected error indexing ${file}`, err); return null; } } -function setupDisconnectedParentHandler(): void { +function setupDisconnectedParentHandler() { process.on('disconnect', () => { logger.debug('Parent process disconnected. AutoImportsWorker terminating.'); process.exit(0); }); } -function setupParentMessagesHandler( - root: string, - hasteSettings: HasteSettings, -): void { +function setupParentMessagesHandler(root, hasteSettings) { process.on('message', async message => { - const {fileUri, fileContents} = message; + const { fileUri, fileContents } = message; if (fileUri == null || fileContents == null) { - logger.warn( - 'AutoImportsWorker received a message from parent without a fileUri or fileContents', - ); + logger.warn('AutoImportsWorker received a message from parent without a fileUri or fileContents'); return; } try { - const exportUpdate = await getExportsForFileWithMain( - fileUri, - hasteSettings, - fileContents, - ); + const exportUpdate = await getExportsForFileWithMain(fileUri, hasteSettings, fileContents); if (exportUpdate != null) { sendUpdatesBatched([exportUpdate]); } @@ -389,92 +356,61 @@ function setupParentMessagesHandler( }); } -function getHasteNames( - root: NuclideUri, - files: Array, - hasteSettings: HasteSettings, -): Array { - return files - .map( - (file): ?ExportUpdateForFile => { - const hasteName = hasteReduceName(file, hasteSettings); - if (hasteName == null) { - return null; - } - return { - file, - updateType: 'setExports', - exports: [ - { - id: idFromFileName(hasteName), - uri: nuclideUri.join(root, file), - line: 1, - hasteName, - isTypeExport: false, - isDefault: true, - }, - ], - }; - }, - ) - .filter(Boolean); +function getHasteNames(root, files, hasteSettings) { + return files.map(file => { + const hasteName = (0, (_HasteUtils || _load_HasteUtils()).hasteReduceName)(file, hasteSettings); + if (hasteName == null) { + return null; + } + return { + file, + updateType: 'setExports', + exports: [{ + id: (0, (_ExportManager || _load_ExportManager()).idFromFileName)(hasteName), + uri: (_nuclideUri || _load_nuclideUri()).default.join(root, file), + line: 1, + hasteName, + isTypeExport: false, + isDefault: true + }] + }; + }).filter(Boolean); } -export function indexNodeModules({ +function indexNodeModules({ root, exportCache, - nodeModulesPackageJsonFiles, -}: FileIndex): Observable> { - return Observable.from(nodeModulesPackageJsonFiles) - .mergeMap(file => handleNodeModule(root, file, exportCache), MAX_WORKERS) - .let(compact) - .bufferCount(BATCH_SIZE); + nodeModulesPackageJsonFiles +}) { + return _rxjsBundlesRxMinJs.Observable.from(nodeModulesPackageJsonFiles).mergeMap(file => handleNodeModule(root, file, exportCache), MAX_WORKERS).let((_observable || _load_observable()).compact).bufferCount(BATCH_SIZE); } -async function handleNodeModule( - root: NuclideUri, - packageJsonFile: string, - exportCache: ExportCache, -): Promise { - const file = nuclideUri.join(root, packageJsonFile); +async function handleNodeModule(root, packageJsonFile, exportCache) { + const file = (_nuclideUri || _load_nuclideUri()).default.join(root, packageJsonFile); try { - const fileContents = await fsPromise.readFile(file, 'utf8'); + const fileContents = await (_fsPromise || _load_fsPromise()).default.readFile(file, 'utf8'); const packageJson = JSON.parse(fileContents); - const entryPoint = require.resolve( - nuclideUri.join(nuclideUri.dirname(file), packageJson.main || ''), - ); - const entryContents = await fsPromise.readFile(entryPoint, 'utf8'); - const sha1 = crypto - .createHash('sha1') - .update(entryContents) - .digest('hex'); - const cachedUpdate = exportCache.get({filePath: entryPoint, sha1}); + const entryPoint = require.resolve((_nuclideUri || _load_nuclideUri()).default.join((_nuclideUri || _load_nuclideUri()).default.dirname(file), packageJson.main || '')); + const entryContents = await (_fsPromise || _load_fsPromise()).default.readFile(entryPoint, 'utf8'); + const sha1 = _crypto.default.createHash('sha1').update(entryContents).digest('hex'); + const cachedUpdate = exportCache.get({ filePath: entryPoint, sha1 }); if (cachedUpdate != null) { return { updateType: 'setExports', file: entryPoint, sha1, - exports: cachedUpdate, + exports: cachedUpdate }; } // TODO(hansonw): How do we handle haste modules inside Node modules? // For now we'll just treat them as usual. - const update = await getExportsForFile( - entryPoint, - { - isHaste: false, - useNameReducers: false, - nameReducers: [], - nameReducerBlacklist: [], - nameReducerWhitelist: [], - }, - entryContents, - ); - return update - ? decorateExportUpdateWithMainDirectory( - update, - nuclideUri.join(root, nuclideUri.dirname(packageJsonFile)), - ) - : update; + const update = await getExportsForFile(entryPoint, { + isHaste: false, + useNameReducers: false, + nameReducers: [], + nameReducerBlacklist: [], + nameReducerWhitelist: [] + }, entryContents); + return update ? decorateExportUpdateWithMainDirectory(update, (_nuclideUri || _load_nuclideUri()).default.join(root, (_nuclideUri || _load_nuclideUri()).default.dirname(packageJsonFile))) : update; } catch (error) { // Some modules just can't be required; that's perfectly normal. if (error.code !== 'MODULE_NOT_FOUND') { @@ -484,40 +420,34 @@ async function handleNodeModule( } } -function decorateExportUpdateWithMainDirectory( - update: ExportUpdateForFile, - directoryForMainFile: ?NuclideUri, -) { - if ( - update.exports.length > 0 && - directoryForMainFile !== update.exports[0].directoryForMainFile - ) { +function decorateExportUpdateWithMainDirectory(update, directoryForMainFile) { + if (update.exports.length > 0 && directoryForMainFile !== update.exports[0].directoryForMainFile) { update.exports = update.exports.map(exp => { if (directoryForMainFile == null) { delete exp.directoryForMainFile; return exp; } else { - return {...exp, directoryForMainFile}; + return Object.assign({}, exp, { directoryForMainFile }); } }); } return update; } -function sendUpdatesBatched(exportsForFiles: Array): void { +function sendUpdatesBatched(exportsForFiles) { for (let i = 0; i < exportsForFiles.length; i += BATCH_SIZE) { send(exportsForFiles.slice(i, i + BATCH_SIZE)); } } -async function send(message: mixed) { +async function send(message) { if (typeof process.send === 'function') { return new Promise((resolve, reject) => { - invariant(typeof process.send === 'function'); - return process.send( - message, - err => (err == null ? resolve() : reject(err)), - ); + if (!(typeof process.send === 'function')) { + throw new Error('Invariant violation: "typeof process.send === \'function\'"'); + } + + return process.send(message, err => err == null ? resolve() : reject(err)); }); } } @@ -530,20 +460,15 @@ function runChild() { logger.error('Child started with incorrect number of arguments'); return; } - const root: NuclideUri = process.argv[3]; - const {hasteSettings} = getConfigFromFlow(root); + const root = process.argv[3]; + const { hasteSettings } = (0, (_Config || _load_Config()).getConfigFromFlow)(root); process.on('message', message => { - const {files} = message; - Observable.from(files) - .concatMap((file, index) => { - // Note that we explicitly skip the main check here. - // The parent process has a index of main files which is more efficient! - return getExportsForFile(nuclideUri.join(root, file), hasteSettings); - }) - .let(compact) - .bufferCount(BATCH_SIZE) - .mergeMap(send, SEND_CONCURRENCY) - .subscribe({complete: () => process.exit(0)}); + const { files } = message; + _rxjsBundlesRxMinJs.Observable.from(files).concatMap((file, index) => { + // Note that we explicitly skip the main check here. + // The parent process has a index of main files which is more efficient! + return getExportsForFile((_nuclideUri || _load_nuclideUri()).default.join(root, file), hasteSettings); + }).let((_observable || _load_observable()).compact).bufferCount(BATCH_SIZE).mergeMap(send, SEND_CONCURRENCY).subscribe({ complete: () => process.exit(0) }); }); } @@ -556,4 +481,4 @@ function shuffle(array) { } } -main(); +main(); \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/lib/ExportCache.js b/pkg/nuclide-js-imports-server/src/lib/ExportCache.js index d6fdd0a253..7fefbb2d46 100644 --- a/pkg/nuclide-js-imports-server/src/lib/ExportCache.js +++ b/pkg/nuclide-js-imports-server/src/lib/ExportCache.js @@ -1,55 +1,62 @@ -/** - * 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 strict-local - * @format - */ - -import type {ConfigFromFlow} from '../Config'; -import type {JSExport} from './types'; - -import crypto from 'crypto'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import os from 'os'; -import DiskCache from '../../../commons-node/DiskCache'; -import {serializeConfig} from '../Config'; - -const CACHE_DIR = nuclideUri.join(os.tmpdir(), 'nuclide-js-imports-cache'); -const CACHE_VERSION = 2; // Bump this for any breaking changes. +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _crypto = _interopRequireDefault(require('crypto')); + +var _nuclideUri; -export type CacheParams = { - root: string, - configFromFlow: ConfigFromFlow, -}; +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../../modules/nuclide-commons/nuclideUri')); +} + +var _os = _interopRequireDefault(require('os')); -export type FileWithHash = { - filePath: string, - sha1: string, -}; +var _DiskCache; + +function _load_DiskCache() { + return _DiskCache = _interopRequireDefault(require('../../../commons-node/DiskCache')); +} + +var _Config; + +function _load_Config() { + return _Config = require('../Config'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const CACHE_DIR = (_nuclideUri || _load_nuclideUri()).default.join(_os.default.tmpdir(), 'nuclide-js-imports-cache'); /** + * 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. + * + * strict-local + * @format + */ + +const CACHE_VERSION = 2; // Bump this for any breaking changes. -function getCachePath({root, configFromFlow}: CacheParams): string { - const hash = crypto.createHash('sha1'); +function getCachePath({ root, configFromFlow }) { + const hash = _crypto.default.createHash('sha1'); hash.update(`${root}:${CACHE_VERSION}\n`); - hash.update(serializeConfig(configFromFlow)); - const fileName = - nuclideUri.basename(root) + '-' + hash.digest('hex').substr(0, 8); - return nuclideUri.join(CACHE_DIR, fileName); + hash.update((0, (_Config || _load_Config()).serializeConfig)(configFromFlow)); + const fileName = (_nuclideUri || _load_nuclideUri()).default.basename(root) + '-' + hash.digest('hex').substr(0, 8); + return (_nuclideUri || _load_nuclideUri()).default.join(CACHE_DIR, fileName); } -function getCacheKey({filePath, sha1}: FileWithHash) { +function getCacheKey({ filePath, sha1 }) { // We can truncate the sha1 hash, as collisions are very unlikely. return `${filePath}:${sha1.substr(0, 8)}`; } -export default class ExportCache extends DiskCache< - FileWithHash, - Array, -> { - constructor(params: CacheParams) { +class ExportCache extends (_DiskCache || _load_DiskCache()).default { + constructor(params) { super(getCachePath(params), getCacheKey); } } +exports.default = ExportCache; \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/lib/ExportIndex.js b/pkg/nuclide-js-imports-server/src/lib/ExportIndex.js index 49bcdc326f..f8698e6529 100644 --- a/pkg/nuclide-js-imports-server/src/lib/ExportIndex.js +++ b/pkg/nuclide-js-imports-server/src/lib/ExportIndex.js @@ -1,41 +1,37 @@ -/** - * 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 - */ - -import ExportMatcher from './ExportMatcher'; - -import type {JSExport} from './types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -export class ExportIndex { - exportsForId: Map>; - exportsForFile: Map>; - exportIdMatcher: ExportMatcher; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ExportIndex = undefined; + +var _ExportMatcher; + +function _load_ExportMatcher() { + return _ExportMatcher = _interopRequireDefault(require('./ExportMatcher')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class ExportIndex { constructor() { this.exportsForId = new Map(); this.exportsForFile = new Map(); - this.exportIdMatcher = new ExportMatcher(); + this.exportIdMatcher = new (_ExportMatcher || _load_ExportMatcher()).default(); } clearAllExports() { this.exportsForId = new Map(); this.exportsForFile = new Map(); - this.exportIdMatcher = new ExportMatcher(); + this.exportIdMatcher = new (_ExportMatcher || _load_ExportMatcher()).default(); } - hasExport(id: string) { + hasExport(id) { return this.exportsForId.has(id); } - clearExportsFromFile(file: NuclideUri) { + clearExportsFromFile(file) { const toClear = this.exportsForFile.get(file); if (!toClear) { return; @@ -54,7 +50,7 @@ export class ExportIndex { }); } - getExportsFromId(id: string): Array { + getExportsFromId(id) { const indexExports = this.exportsForId.get(id); if (indexExports) { return Array.from(indexExports); @@ -62,22 +58,20 @@ export class ExportIndex { return []; } - getIdsMatching(query: string, maxResults: number): Array { - return this.exportIdMatcher - .match(query, { - caseSensitive: false, - maxResults, - }) - .map(result => result.value); + getIdsMatching(query, maxResults) { + return this.exportIdMatcher.match(query, { + caseSensitive: false, + maxResults + }).map(result => result.value); } - setAll(file: NuclideUri, exports: Array) { + setAll(file, exports) { this.clearExportsFromFile(file); exports.forEach(exp => this._add(exp)); } - _add(newExport: JSExport) { - const {id, uri} = newExport; + _add(newExport) { + const { id, uri } = newExport; const idExports = this.exportsForId.get(id); const fileExports = this.exportsForFile.get(uri); @@ -95,3 +89,13 @@ export class ExportIndex { } } } +exports.ExportIndex = ExportIndex; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/lib/ExportManager.js b/pkg/nuclide-js-imports-server/src/lib/ExportManager.js index 12af74eed7..c09a478313 100644 --- a/pkg/nuclide-js-imports-server/src/lib/ExportManager.js +++ b/pkg/nuclide-js-imports-server/src/lib/ExportManager.js @@ -1,29 +1,58 @@ -/** - * 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 - */ - -import * as t from '@babel/types'; -import {ExportIndex} from './ExportIndex'; -import {getLogger} from 'log4js'; -import {arrayCompact} from 'nuclide-commons/collection'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {JSExport} from './types'; - -const logger = getLogger(); - -export function getExportsFromAst( - fileUri: NuclideUri, - ast: Object, -): Array { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ExportManager = undefined; +exports.getExportsFromAst = getExportsFromAst; +exports.idFromFileName = idFromFileName; + +var _types; + +function _load_types() { + return _types = _interopRequireWildcard(require('@babel/types')); +} + +var _ExportIndex; + +function _load_ExportIndex() { + return _ExportIndex = require('./ExportIndex'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../../modules/nuclide-commons/collection'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../../modules/nuclide-commons/nuclideUri')); +} + +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 logger = (0, (_log4js || _load_log4js()).getLogger)(); /** + * 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. + * + * + * @format + */ + +function getExportsFromAst(fileUri, ast) { const exports = []; try { traverseTreeAndIndexExports(ast, fileUri, exports); @@ -33,66 +62,53 @@ export function getExportsFromAst( return exports; } -export class ExportManager { - _exportIndex: ExportIndex; +class ExportManager { constructor() { - this._exportIndex = new ExportIndex(); + this._exportIndex = new (_ExportIndex || _load_ExportIndex()).ExportIndex(); } - setExportsForFile(fileUri: NuclideUri, exports: Array) { + setExportsForFile(fileUri, exports) { this._exportIndex.setAll(fileUri, exports); } - clearExportsFromFile(fileUri: NuclideUri) { + clearExportsFromFile(fileUri) { this._exportIndex.clearExportsFromFile(fileUri); } - addFile(fileUri: NuclideUri, ast: Object) { + addFile(fileUri, ast) { const exports = []; traverseTreeAndIndexExports(ast, fileUri, exports); this._exportIndex.setAll(fileUri, exports); } - hasExport(id: string): boolean { + hasExport(id) { return this._exportIndex.hasExport(id); } - getExportsIndex(): ExportIndex { + getExportsIndex() { return this._exportIndex; } } -function isModuleExports(node: Object): boolean { - return ( - (t.isMemberExpression(node) && - node.object.name === 'module' && - node.property.name === 'exports') || - (t.isIdentifier(node) && node.name === 'exports') - ); +exports.ExportManager = ExportManager; +function isModuleExports(node) { + return (_types || _load_types()).isMemberExpression(node) && node.object.name === 'module' && node.property.name === 'exports' || (_types || _load_types()).isIdentifier(node) && node.name === 'exports'; } -function addModuleExports( - rightNode: Object, - fileUri: NuclideUri, - exportIndex: Array, -): void { +function addModuleExports(rightNode, fileUri, exportIndex) { const isTypeExport = false; // You can only module.exports a value (not a type) expressionToExports(rightNode, isTypeExport, fileUri).forEach(exp => { exportIndex.push(exp); }); } -function addDefaultDeclarationToExportIndex( - node: Object, - fileUri: NuclideUri, - exportIndex: Array, -): void { +function addDefaultDeclarationToExportIndex(node, fileUri, exportIndex) { // Only values can be exported as default (not types) const isTypeExport = false; const isDefault = true; - if (t.isObjectExpression(node.declaration)) { + if ((_types || _load_types()).isObjectExpression(node.declaration)) { // (ex: export default {someObject, otherObject}) // Assume the id will be the name of the file. const id = idFromFileName(fileUri); @@ -101,83 +117,56 @@ function addDefaultDeclarationToExportIndex( uri: fileUri, line: node.loc.start.line, isDefault, - isTypeExport, + isTypeExport }); return; } - declarationToExport( - node.declaration, - isTypeExport, - fileUri, - isDefault, - ).forEach(exp => { + declarationToExport(node.declaration, isTypeExport, fileUri, isDefault).forEach(exp => { exportIndex.push(exp); }); } -function addNamedDeclarationToExportIndex( - node: Object, - fileUri: NuclideUri, - exportIndex: Array, -): void { +function addNamedDeclarationToExportIndex(node, fileUri, exportIndex) { const isDefault = false; // export class Foo if (node && node.declaration) { - const {declaration, exportKind} = node; - declarationToExport( - declaration, - exportKind === 'type', - fileUri, - isDefault, - ).forEach(exp => { + const { declaration, exportKind } = node; + declarationToExport(declaration, exportKind === 'type', fileUri, isDefault).forEach(exp => { exportIndex.push(exp); }); } else if (node.specifiers) { // export {foo, bar} from ... - const {exportKind} = node; + const { exportKind } = node; node.specifiers.forEach(specifier => { - exportIndex.push( - specifierToExport(specifier, fileUri, exportKind === 'type', isDefault), - ); + exportIndex.push(specifierToExport(specifier, fileUri, exportKind === 'type', isDefault)); }); } else { throw new Error('ExportNamedDeclaration without declaration or specifiers'); } } -function specifierToExport( - node: Object, - fileUri: NuclideUri, - isTypeExport: boolean, - isDefault: boolean, -): JSExport { +function specifierToExport(node, fileUri, isTypeExport, isDefault) { return { id: node.exported.name, uri: fileUri, line: node.loc.start.line, isTypeExport, - isDefault, + isDefault }; } -function expressionToExports( - expression: Object, - isTypeExport: boolean, - fileUri: NuclideUri, -): Array { +function expressionToExports(expression, isTypeExport, fileUri) { // Index the entire 'module.exports' as a default export. const defaultId = idFromFileName(fileUri); - const result = [ - { - id: defaultId, - uri: fileUri, - line: expression.loc.start.line, - type: 'ObjectExpression', - isTypeExport, - isDefault: true, - }, - ]; + const result = [{ + id: defaultId, + uri: fileUri, + line: expression.loc.start.line, + type: 'ObjectExpression', + isTypeExport, + isDefault: true + }]; const ident = expression.id != null ? expression.id.name : expression.name; if (ident && ident !== defaultId) { @@ -187,68 +176,52 @@ function expressionToExports( line: expression.loc.start.line, type: expression.type, isTypeExport, - isDefault: true, // Treated as default export + isDefault: true // Treated as default export }); - } else if (t.isObjectExpression(expression)) { + } else if ((_types || _load_types()).isObjectExpression(expression)) { // Index each property of the object - const propertyExports = arrayCompact( - expression.properties.map(property => { - if (property.type === 'SpreadElement' || property.computed) { - return null; - } - return { - id: - property.key.type === 'StringLiteral' - ? property.key.value - : property.key.name, - uri: fileUri, - line: property.key.loc.start.line, - type: expression.type, - isTypeExport, - isDefault: false, - }; - }), - ); + const propertyExports = (0, (_collection || _load_collection()).arrayCompact)(expression.properties.map(property => { + if (property.type === 'SpreadElement' || property.computed) { + return null; + } + return { + id: property.key.type === 'StringLiteral' ? property.key.value : property.key.name, + uri: fileUri, + line: property.key.loc.start.line, + type: expression.type, + isTypeExport, + isDefault: false + }; + })); return result.concat(propertyExports); - } else if ( - t.isAssignmentExpression(expression) && - t.isIdentifier(expression.left) && - expression.left.name !== defaultId - ) { + } else if ((_types || _load_types()).isAssignmentExpression(expression) && (_types || _load_types()).isIdentifier(expression.left) && expression.left.name !== defaultId) { result.push({ id: expression.left.name, uri: fileUri, line: expression.left.loc.start.line, type: expression.right.type, isTypeExport, - isDefault: true, // Treated as default export + isDefault: true // Treated as default export }); } return result; } -function declarationToExport( - declaration: Object, - isTypeExport: boolean, - fileUri: NuclideUri, - isDefault: boolean, -): Array { +function declarationToExport(declaration, isTypeExport, fileUri, isDefault) { // export MyType; if (declaration.id || declaration.name) { - return [ - { - id: declaration.name || declaration.id.name, - uri: fileUri, - line: declaration.loc.start.line, - type: declaration.type, - isTypeExport, - isDefault, - }, - ]; + return [{ + id: declaration.name || declaration.id.name, + uri: fileUri, + line: declaration.loc.start.line, + type: declaration.type, + isTypeExport, + isDefault + }]; } // export const x = 3; if (declaration.declarations) { - const {declarations} = declaration; + const { declarations } = declaration; // We currently use map but if there were more than one, there would be a // lint error (one-var) so we could simplify this by just taking the first element of the array. return declarations.map(decl => { @@ -258,36 +231,30 @@ function declarationToExport( line: decl.id.loc.start.line, type: declaration.type, isTypeExport, - isDefault, + isDefault }; }); } // Unnamed default exports if (isDefault === true) { - return [ - { - id: idFromFileName(fileUri), - uri: fileUri, - line: declaration.loc.start.line, - isTypeExport: false, - type: declaration.type, - isDefault, - }, - ]; + return [{ + id: idFromFileName(fileUri), + uri: fileUri, + line: declaration.loc.start.line, + isTypeExport: false, + type: declaration.type, + isDefault + }]; } return []; } -function traverseTreeAndIndexExports( - ast: Object, - fileUri: NuclideUri, - exportIndex: Array, -): void { +function traverseTreeAndIndexExports(ast, fileUri, exportIndex) { // As an optimization, only traverse top-level nodes instead of the whole AST. if (ast && ast.program && ast.program.body) { - const {body} = ast.program; + const { body } = ast.program; body.forEach(node => { - const {type} = node; + const { type } = node; switch (type) { case 'ExportNamedDeclaration': addNamedDeclarationToExportIndex(node, fileUri, exportIndex); @@ -296,32 +263,20 @@ function traverseTreeAndIndexExports( addDefaultDeclarationToExportIndex(node, fileUri, exportIndex); break; case 'ExpressionStatement': - if ( - node.expression && - node.expression.type === 'AssignmentExpression' - ) { - const {left, right} = node.expression; + if (node.expression && node.expression.type === 'AssignmentExpression') { + const { left, right } = node.expression; if (isModuleExports(left)) { addModuleExports(right, fileUri, exportIndex); - } else if ( - t.isMemberExpression(left) && - isModuleExports(left.object) && - t.isIdentifier(left.property) - ) { + } else if ((_types || _load_types()).isMemberExpression(left) && isModuleExports(left.object) && (_types || _load_types()).isIdentifier(left.property)) { exportIndex.push({ id: left.property.name, uri: fileUri, line: left.property.loc.start.line, type: - // Exclude easy cases from being imported as types. - right.type === 'ObjectExpression' || - right.type === 'FunctionExpression' || - right.type === 'NumericLiteral' || - right.type === 'StringLiteral' - ? right.type - : undefined, + // Exclude easy cases from being imported as types. + right.type === 'ObjectExpression' || right.type === 'FunctionExpression' || right.type === 'NumericLiteral' || right.type === 'StringLiteral' ? right.type : undefined, isTypeExport: false, - isDefault: false, + isDefault: false }); } } @@ -331,25 +286,21 @@ function traverseTreeAndIndexExports( } } -export function idFromFileName(fileUri: NuclideUri): string { - const fileName = nuclideUri.basename(fileUri); +function idFromFileName(fileUri) { + const fileName = (_nuclideUri || _load_nuclideUri()).default.basename(fileUri); const dotIndex = fileName.indexOf('.'); const stripped = dotIndex >= 0 ? fileName.substr(0, dotIndex) : fileName; return stripped.indexOf('-') >= 0 ? dashToCamelCase(stripped) : stripped; } -function dashToCamelCase(string: string): string { +function dashToCamelCase(string) { return string // Maintain capitalization of the first "word" - ? string - .split('-') - .map((el, i) => (i === 0 ? el : capitalize(el))) - .join('') - : ''; + ? string.split('-').map((el, i) => i === 0 ? el : capitalize(el)).join('') : ''; } -function capitalize(word: string): string { +function capitalize(word) { if (!word) { return ''; } return word[0].toUpperCase() + word.slice(1); -} +} \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/lib/ExportMatcher.js b/pkg/nuclide-js-imports-server/src/lib/ExportMatcher.js index adad14b51c..8035d86ad9 100644 --- a/pkg/nuclide-js-imports-server/src/lib/ExportMatcher.js +++ b/pkg/nuclide-js-imports-server/src/lib/ExportMatcher.js @@ -1,69 +1,78 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); -import { - Matcher, - type MatcherOptions, - type MatchResult, -} from '../../../nuclide-fuzzy-native'; +var _nuclideFuzzyNative; + +function _load_nuclideFuzzyNative() { + return _nuclideFuzzyNative = require('../../../nuclide-fuzzy-native'); +} /** * This class batches all adds/removes from the same tick into one batch add/remove call. * Since the Matcher class is a native node module, this is several orders of magnitude * faster when dealing with large sets of files (> 10000). */ -export default class ExportMatcher { - _matcher: Matcher = new Matcher([]); - _batchScheduled: boolean = false; +class ExportMatcher { + constructor() { + this._matcher = new (_nuclideFuzzyNative || _load_nuclideFuzzyNative()).Matcher([]); + this._batchScheduled = false; + this._batch = new Map(); + + this._performBatch = () => { + const toAdd = []; + const toRemove = []; + this._batch.forEach((added, item) => { + if (added) { + toAdd.push(item); + } else { + toRemove.push(item); + } + }); + this._matcher.addCandidates(toAdd); + this._matcher.removeCandidates(toRemove); + this._batch.clear(); + this._batchScheduled = false; + }; + } // true = add, false = delete - _batch: Map = new Map(); - add(item: string) { + + add(item) { this._batch.set(item, true); this._schedule(); } - remove(item: string) { + remove(item) { this._batch.set(item, false); this._schedule(); } - match(query: string, options?: MatcherOptions): Array { + match(query, options) { // In practice, it's unlikely that we look for a match and mutate in the same tick. // But just in case... this._performBatch(); return this._matcher.match(query, options); } - _schedule(): void { + _schedule() { if (!this._batchScheduled) { this._batchScheduled = true; process.nextTick(this._performBatch); } } - _performBatch = () => { - const toAdd = []; - const toRemove = []; - this._batch.forEach((added, item) => { - if (added) { - toAdd.push(item); - } else { - toRemove.push(item); - } - }); - this._matcher.addCandidates(toAdd); - this._matcher.removeCandidates(toRemove); - this._batch.clear(); - this._batchScheduled = false; - }; } +exports.default = ExportMatcher; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/lib/HasteUtils.js b/pkg/nuclide-js-imports-server/src/lib/HasteUtils.js index f520346186..ff810d7ca8 100644 --- a/pkg/nuclide-js-imports-server/src/lib/HasteUtils.js +++ b/pkg/nuclide-js-imports-server/src/lib/HasteUtils.js @@ -1,60 +1,54 @@ -/** - * 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 - */ +'use strict'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {HasteSettings} from '../Config'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.hasteReduceName = hasteReduceName; +exports.getHasteName = getHasteName; -import nuclideUri from 'nuclide-commons/nuclideUri'; +var _nuclideUri; -export function hasteReduceName( - file: NuclideUri, - hasteSettings: HasteSettings, -): ?string { +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../../modules/nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function hasteReduceName(file, hasteSettings) { if (!hasteSettings.useNameReducers) { return null; } const { nameReducers, nameReducerWhitelist, - nameReducerBlacklist, + nameReducerBlacklist } = hasteSettings; - if ( - (nameReducerWhitelist.length === 0 || - nameReducerWhitelist.some(r => r.test(file))) && - !nameReducerBlacklist.some(r => r.test(file)) - ) { + if ((nameReducerWhitelist.length === 0 || nameReducerWhitelist.some(r => r.test(file))) && !nameReducerBlacklist.some(r => r.test(file))) { if (nameReducers.length === 0) { // The default name reducer. - return nuclideUri.stripExtension(nuclideUri.basename(file)); + return (_nuclideUri || _load_nuclideUri()).default.stripExtension((_nuclideUri || _load_nuclideUri()).default.basename(file)); } - return nameReducers.reduce( - (hasteName, reducer) => - hasteName.replace(reducer.regexp, reducer.replacement), - file, - ); + return nameReducers.reduce((hasteName, reducer) => hasteName.replace(reducer.regexp, reducer.replacement), file); } -} +} /** + * 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. + * + * + * @format + */ -export function getHasteName( - file: NuclideUri, - ast: Object, - hasteSettings: HasteSettings, -): ?string { +function getHasteName(file, ast, hasteSettings) { if (!hasteSettings.isHaste) { return null; } // __mocks__ is also special cased in Flow. No joke: // https://github.com/facebook/flow/blob/master/src/services/inference/module_js.ml#L473 if (file.includes('/__mocks__/')) { - const basename = nuclideUri.basename(file); + const basename = (_nuclideUri || _load_nuclideUri()).default.basename(file); const extIndex = basename.indexOf('.'); // The extension separator 1) must exist, and 2) can't be at the start. // https://caml.inria.fr/pub/docs/manual-ocaml/libref/Filename.html#VALchop_extension @@ -78,4 +72,4 @@ export function getHasteName( } } return null; -} +} \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/lib/ImportFormatter.js b/pkg/nuclide-js-imports-server/src/lib/ImportFormatter.js index 2a824584b8..d688fadc1e 100644 --- a/pkg/nuclide-js-imports-server/src/lib/ImportFormatter.js +++ b/pkg/nuclide-js-imports-server/src/lib/ImportFormatter.js @@ -1,48 +1,43 @@ -/** - * 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 - */ - -import nuclideUri from 'nuclide-commons/nuclideUri'; - -import type {JSExport} from './types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -const EXTENTIONS_TO_REMOVE = ['.js']; - -export type ImportType = - | 'namedType' - | 'namedValue' - | 'defaultType' - | 'defaultValue' - | 'requireImport' - | 'requireDestructured'; - -export class ImportFormatter { - moduleDirs: Array; - useRequire: boolean; - - constructor(dirs: Array, useRequire: boolean) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ImportFormatter = undefined; +exports.createImportStatement = createImportStatement; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../../modules/nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const EXTENTIONS_TO_REMOVE = ['.js']; /** + * 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. + * + * + * @format + */ + +class ImportFormatter { + + constructor(dirs, useRequire) { this.moduleDirs = dirs; this.useRequire = useRequire; } - formatImport(file: NuclideUri, exp: JSExport): string { + formatImport(file, exp) { const importPath = this.formatImportFile(file, exp); - return createImportStatement( - exp.id, - importPath, - getImportType(exp, this.useRequire), - ); + return createImportStatement(exp.id, importPath, getImportType(exp, this.useRequire)); } - formatImportFile(file: NuclideUri, exp: JSExport): string { + formatImportFile(file, exp) { if (exp.hasteName != null) { return exp.hasteName; } @@ -53,27 +48,21 @@ export class ImportFormatter { return removeFileExtensions(pathRelativeToModules); } - let pathRelativeToFile = nuclideUri.relative(nuclideUri.dirname(file), uri); + let pathRelativeToFile = (_nuclideUri || _load_nuclideUri()).default.relative((_nuclideUri || _load_nuclideUri()).default.dirname(file), uri); // Convert types.js => ./types.js - pathRelativeToFile = pathRelativeToFile.startsWith('.') - ? pathRelativeToFile - : './' + pathRelativeToFile; + pathRelativeToFile = pathRelativeToFile.startsWith('.') ? pathRelativeToFile : './' + pathRelativeToFile; return removeFileExtensions(pathRelativeToFile); } - stripLeadingDots(file: NuclideUri): NuclideUri { - return file.startsWith('..') - ? nuclideUri.join('', ...nuclideUri.split(file).filter(e => e !== '..')) - : file; + stripLeadingDots(file) { + return file.startsWith('..') ? (_nuclideUri || _load_nuclideUri()).default.join('', ...(_nuclideUri || _load_nuclideUri()).default.split(file).filter(e => e !== '..')) : file; } } -function getImportType( - {isDefault, isTypeExport}: JSExport, - useRequire: boolean, -): ImportType { +exports.ImportFormatter = ImportFormatter; +function getImportType({ isDefault, isTypeExport }, useRequire) { if (isTypeExport) { return isDefault ? 'defaultType' : 'namedType'; } else if (useRequire) { @@ -82,11 +71,7 @@ function getImportType( return isDefault ? 'defaultValue' : 'namedValue'; } -export function createImportStatement( - id: string, - importPath: string, - importType: ImportType, -): string { +function createImportStatement(id, importPath, importType) { switch (importType) { case 'namedValue': return `import {${id}} from '${importPath}';`; @@ -101,16 +86,12 @@ export function createImportStatement( case 'defaultType': return `import type ${id} from '${importPath}';`; default: - (importType: empty); + importType; throw new Error(`Invalid import type ${importType}`); } } -function handleModules( - fileWithExport: NuclideUri, - fileMissingImport: NuclideUri, - moduleDirs: Array, -): ?string { +function handleModules(fileWithExport, fileMissingImport, moduleDirs) { const moduleDirOfExport = getFileModuleDirectory(fileWithExport, moduleDirs); // flowlint-next-line sketchy-null-string:off @@ -120,30 +101,22 @@ function handleModules( // If the export is from a module, we need to check if we are importing the // file from that same module. If so, the import must be relative. - const moduleDirOfImport = getFileModuleDirectory( - fileMissingImport, - moduleDirs, - ); - if ( - moduleDirOfImport != null && - moduleDirOfImport === moduleDirOfExport && - getModule(fileMissingImport, moduleDirOfImport) === - getModule(fileWithExport, moduleDirOfExport) - ) { + const moduleDirOfImport = getFileModuleDirectory(fileMissingImport, moduleDirs); + if (moduleDirOfImport != null && moduleDirOfImport === moduleDirOfExport && getModule(fileMissingImport, moduleDirOfImport) === getModule(fileWithExport, moduleDirOfExport)) { // Import should be relative to the file we are importing from, so return null. return null; } // Import should be relative to the module. - return nuclideUri.relative(moduleDirOfExport, fileWithExport); + return (_nuclideUri || _load_nuclideUri()).default.relative(moduleDirOfExport, fileWithExport); } -function abbreviateMainFiles(exp: JSExport): string { +function abbreviateMainFiles(exp) { // flowlint-next-line sketchy-null-string:off return exp.directoryForMainFile || exp.uri; } -function removeFileExtensions(file: NuclideUri): string { +function removeFileExtensions(file) { for (const extension of EXTENTIONS_TO_REMOVE) { if (file.endsWith(extension)) { return file.substring(0, file.length - extension.length); @@ -152,13 +125,10 @@ function removeFileExtensions(file: NuclideUri): string { return file; } -function getFileModuleDirectory( - file: NuclideUri, - moduleDirs: Array, -): ?string { - return moduleDirs.find(moduleDir => nuclideUri.contains(moduleDir, file)); +function getFileModuleDirectory(file, moduleDirs) { + return moduleDirs.find(moduleDir => (_nuclideUri || _load_nuclideUri()).default.contains(moduleDir, file)); } -function getModule(file: NuclideUri, moduleDirectory: string): ?string { - return nuclideUri.split(nuclideUri.relative(moduleDirectory, file))[0]; -} +function getModule(file, moduleDirectory) { + return (_nuclideUri || _load_nuclideUri()).default.split((_nuclideUri || _load_nuclideUri()).default.relative(moduleDirectory, file))[0]; +} \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/lib/UndefinedSymbolManager.js b/pkg/nuclide-js-imports-server/src/lib/UndefinedSymbolManager.js index d9b442311d..814d33eb55 100644 --- a/pkg/nuclide-js-imports-server/src/lib/UndefinedSymbolManager.js +++ b/pkg/nuclide-js-imports-server/src/lib/UndefinedSymbolManager.js @@ -1,31 +1,40 @@ -/** - * 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 - */ +'use strict'; -import traverse from '@babel/traverse'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.UndefinedSymbolManager = undefined; -import type {UndefinedSymbol} from './types'; +var _traverse; + +function _load_traverse() { + return _traverse = _interopRequireDefault(require('@babel/traverse')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const BUILT_INS = ['Iterator', '__DEV__']; /** + * 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. + * + * + * @format + */ -const BUILT_INS = ['Iterator', '__DEV__']; const FBT_TAG = 'fbt'; const REACT_MODULE_NAME = 'React'; const JSX_CSX_PRAGMA_REGEX = /\*?\s*@csx/; -export class UndefinedSymbolManager { - globals: Set; +class UndefinedSymbolManager { - constructor(globals: Array) { + constructor(globals) { this.globals = new Set(BUILT_INS.concat(globals)); } - findUndefined(ast: Object): Array { + findUndefined(ast) { try { return traverseTreeForUndefined(ast, this.globals); } catch (error) { @@ -37,15 +46,13 @@ export class UndefinedSymbolManager { } } -function traverseTreeForUndefined( - ast: Object, - globals: Set, -): Array { +exports.UndefinedSymbolManager = UndefinedSymbolManager; +function traverseTreeForUndefined(ast, globals) { const undefinedSymbols = []; const definedTypes = new Set(); const definedValues = new Set(); - ast.comments.forEach(({type, value}) => { + ast.comments.forEach(({ type, value }) => { // Parses out /* global a, b, c: true, d: false */ if (type === 'CommentBlock') { const trimmed = value.trim(); @@ -61,7 +68,7 @@ function traverseTreeForUndefined( }); let csx = false; - traverse(ast, { + (0, (_traverse || _load_traverse()).default)(ast, { ImportDeclaration: path => { saveImports(path, definedTypes); }, @@ -101,24 +108,17 @@ function traverseTreeForUndefined( GenericTypeAnnotation: { exit(path) { findUndefinedTypes(path, undefinedSymbols, globals); - }, + } }, Identifier(path) { // Allow identifiers on the LHS of an assignment. // In non-strict JavaScript, this might just be a declaration. - if ( - path.parent.type === 'AssignmentExpression' && - path.node === path.parent.left - ) { + if (path.parent.type === 'AssignmentExpression' && path.node === path.parent.left) { definedValues.add(path.node.name); } }, Program(path) { - csx = - csx || - path.parent.comments.some(({value}) => - JSX_CSX_PRAGMA_REGEX.test(value), - ); + csx = csx || path.parent.comments.some(({ value }) => JSX_CSX_PRAGMA_REGEX.test(value)); }, JSXFragment(path) { if (!csx) { @@ -139,31 +139,20 @@ function traverseTreeForUndefined( if (path.node.label && path.node.label.name) { definedValues.add(path.node.label.name); } - }, + } }); - return undefinedSymbols.filter( - symbol => - (symbol.type === 'value' && !definedValues.has(symbol.id)) || - (symbol.type === 'type' && !definedTypes.has(symbol.id)), - ); + return undefinedSymbols.filter(symbol => symbol.type === 'value' && !definedValues.has(symbol.id) || symbol.type === 'type' && !definedTypes.has(symbol.id)); } -function findUndefinedValues( - path: Object, - undefinedSymbols: Array, - globals: Set, -) { - const {node, scope} = path; +function findUndefinedValues(path, undefinedSymbols, globals) { + const { node, scope } = path; if ( - // Type Annotations are considered identifiers, so ignore them - isTypeIdentifier(path.parent.type) || - // Other weird cases where we want to ignore identifiers - path.parent.type === 'ExportSpecifier' || // export {a} from 'a' (a would be undefined) - (path.parent.type === 'QualifiedTypeIdentifier' && - path.parentKey !== 'qualification') || // SomeModule.SomeType - globals.has(node.name) || - scope.hasBinding(node.name) - ) { + // Type Annotations are considered identifiers, so ignore them + isTypeIdentifier(path.parent.type) || + // Other weird cases where we want to ignore identifiers + path.parent.type === 'ExportSpecifier' || // export {a} from 'a' (a would be undefined) + path.parent.type === 'QualifiedTypeIdentifier' && path.parentKey !== 'qualification' || // SomeModule.SomeType + globals.has(node.name) || scope.hasBinding(node.name)) { return; } @@ -171,18 +160,14 @@ function findUndefinedValues( id: node.name, type: path.parent.type === 'QualifiedTypeIdentifier' ? 'type' : 'value', location: { - start: {line: node.loc.start.line, col: node.loc.start.column}, - end: {line: node.loc.end.line, col: node.loc.end.column}, - }, + start: { line: node.loc.start.line, col: node.loc.start.column }, + end: { line: node.loc.end.line, col: node.loc.end.column } + } }); } -function findUndefinedReact( - path: Object, - undefinedSymbols: Array, - globals: Set, -) { - const {node, scope} = path; +function findUndefinedReact(path, undefinedSymbols, globals) { + const { node, scope } = path; if (scope.hasBinding(REACT_MODULE_NAME)) { return; @@ -192,24 +177,16 @@ function findUndefinedReact( id: REACT_MODULE_NAME, type: 'value', location: { - start: {line: node.loc.start.line, col: node.loc.start.column}, - end: {line: node.loc.end.line, col: node.loc.end.column}, - }, + start: { line: node.loc.start.line, col: node.loc.start.column }, + end: { line: node.loc.end.line, col: node.loc.end.column } + } }); } -function findUndefinedTypes( - path: Object, - undefinedSymbols: Array, - globals: Set, -) { - const {node, scope} = path; +function findUndefinedTypes(path, undefinedSymbols, globals) { + const { node, scope } = path; - if ( - globals.has(node.id.name) || - path.parent.type === 'TypeAlias' || - scope.hasBinding(node.id.name) - ) { + if (globals.has(node.id.name) || path.parent.type === 'TypeAlias' || scope.hasBinding(node.id.name)) { return; } @@ -219,39 +196,29 @@ function findUndefinedTypes( // "typeof" must refer to a value. type: path.parent.type === 'TypeofTypeAnnotation' ? 'value' : 'type', location: { - start: {line: node.loc.start.line, col: node.loc.start.column}, - end: {line: node.loc.end.line, col: node.loc.end.column}, - }, + start: { line: node.loc.start.line, col: node.loc.start.column }, + end: { line: node.loc.end.line, col: node.loc.end.column } + } }); } } -function saveImports(path: Object, definedTypes: Set) { +function saveImports(path, definedTypes) { path.node.specifiers.forEach(specifier => { definedTypes.add(specifier.local.name); }); } -function save(path: Object, definedTypes: Set) { +function save(path, definedTypes) { if (path.node.id) { definedTypes.add(path.node.id.name); } } -function saveTypeParameters(path: Object, definedTypes: Set) { +function saveTypeParameters(path, definedTypes) { definedTypes.add(path.node.name); } -function isTypeIdentifier(node: Object) { - return ( - node === 'GenericTypeAnnotation' || - node === 'ObjectTypeIndexer' || - node === 'TypeAlias' || - node === 'FunctionTypeParam' || - node === 'ObjectTypeProperty' || - node === 'InterfaceDeclaration' || - node === 'DeclareClass' || - node === 'InterfaceExtends' || - node === 'ClassImplements' - ); -} +function isTypeIdentifier(node) { + return node === 'GenericTypeAnnotation' || node === 'ObjectTypeIndexer' || node === 'TypeAlias' || node === 'FunctionTypeParam' || node === 'ObjectTypeProperty' || node === 'InterfaceDeclaration' || node === 'DeclareClass' || node === 'InterfaceExtends' || node === 'ClassImplements'; +} \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/lib/file-index.js b/pkg/nuclide-js-imports-server/src/lib/file-index.js index 35fe0e0e4e..71b183b685 100644 --- a/pkg/nuclide-js-imports-server/src/lib/file-index.js +++ b/pkg/nuclide-js-imports-server/src/lib/file-index.js @@ -1,57 +1,87 @@ -/** - * 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 - */ - -import type {FileChange} from 'nuclide-watchman-helpers'; -import type {ConfigFromFlow} from '../Config'; - -import {getLogger} from 'log4js'; -import {arrayFlatten} from 'nuclide-commons/collection'; -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {getOutputStream, spawn} from 'nuclide-commons/process'; -import {asyncLimit} from 'nuclide-commons/promise'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import os from 'os'; -import {Observable} from 'rxjs'; -import {WatchmanClient} from 'nuclide-watchman-helpers'; -import ExportCache from './ExportCache'; - -const TO_IGNORE = ['**/node_modules/**', '**/VendorLib/**', '**/flow-typed/**']; - -export type FileWithHash = { - // All files in the index will be relative to the given root. - name: string, - // Watchman supports retrieving the SHA1 of files from list-files. - sha1: ?string, -}; - -export type FileIndex = { - root: string, - exportCache: ExportCache, - // All non-ignored *.js files. - jsFiles: Array, - // All node_modules/*/package.json files. - nodeModulesPackageJsonFiles: Array, - // A map of main files to their directories (as defined in package.json). - mainFiles: Map, -}; - -export async function getFileIndex( - root: string, - configFromFlow: ConfigFromFlow, -): Promise { - const client = new WatchmanClient(); - const exportCache = new ExportCache({root, configFromFlow}); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getFileIndex = getFileIndex; +exports.watchDirectory = watchDirectory; + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../../modules/nuclide-commons/collection'); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../../modules/nuclide-commons/nuclideUri')); +} + +var _process; + +function _load_process() { + return _process = require('../../../../modules/nuclide-commons/process'); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../../modules/nuclide-commons/promise'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _os = _interopRequireDefault(require('os')); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideWatchmanHelpers; + +function _load_nuclideWatchmanHelpers() { + return _nuclideWatchmanHelpers = require('../../../../modules/nuclide-watchman-helpers'); +} + +var _ExportCache; + +function _load_ExportCache() { + return _ExportCache = _interopRequireDefault(require('./ExportCache')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const TO_IGNORE = ['**/node_modules/**', '**/VendorLib/**', '**/flow-typed/**']; /** + * 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. + * + * + * @format + */ + +async function getFileIndex(root, configFromFlow) { + const client = new (_nuclideWatchmanHelpers || _load_nuclideWatchmanHelpers()).WatchmanClient(); + const exportCache = new (_ExportCache || _load_ExportCache()).default({ root, configFromFlow }); const loadPromise = exportCache.load().then(success => { - const logger = getLogger('js-imports-server'); + const logger = (0, (_log4js || _load_log4js()).getLogger)('js-imports-server'); if (success) { logger.info(`Restored exports cache: ${exportCache.getByteSize()} bytes`); } else { @@ -60,41 +90,20 @@ export async function getFileIndex( }); // This is easier and performant enough to express as a glob. - const nodeModulesPackageJsonFilesPromise = globListFiles( - root, - 'node_modules/*/package.json', - ); - const [jsFiles, nodeModulesPackageJsonFiles, mainFiles] = await Promise.all([ - watchmanListFiles(client, root, '*.js').catch(err => { - getLogger('js-imports-server').warn( - 'Failed to get files with Watchman: falling back to glob', - err, - ); - return hgListFiles(root, '**.js', TO_IGNORE) - .catch(() => findListFiles(root, '*.js', TO_IGNORE)) - .catch(() => globListFiles(root, '**/*.js', TO_IGNORE)) - .catch(() => []) - .then(filesWithoutHash); - }), - nodeModulesPackageJsonFilesPromise, - watchmanListFiles(client, root, 'package.json') - .then(files => getMainFiles(root, files.map(file => file.name))) - .catch(() => { - return hgListFiles(root, '**/package.json', TO_IGNORE) - .catch(() => findListFiles(root, 'package.json', TO_IGNORE)) - .catch(() => globListFiles(root, '**/package.json', TO_IGNORE)) - .catch(() => []) - .then(files => getMainFiles(root, files)); - }), - loadPromise, - ]); + const nodeModulesPackageJsonFilesPromise = globListFiles(root, 'node_modules/*/package.json'); + const [jsFiles, nodeModulesPackageJsonFiles, mainFiles] = await Promise.all([watchmanListFiles(client, root, '*.js').catch(err => { + (0, (_log4js || _load_log4js()).getLogger)('js-imports-server').warn('Failed to get files with Watchman: falling back to glob', err); + return hgListFiles(root, '**.js', TO_IGNORE).catch(() => findListFiles(root, '*.js', TO_IGNORE)).catch(() => globListFiles(root, '**/*.js', TO_IGNORE)).catch(() => []).then(filesWithoutHash); + }), nodeModulesPackageJsonFilesPromise, watchmanListFiles(client, root, 'package.json').then(files => getMainFiles(root, files.map(file => file.name))).catch(() => { + return hgListFiles(root, '**/package.json', TO_IGNORE).catch(() => findListFiles(root, 'package.json', TO_IGNORE)).catch(() => globListFiles(root, '**/package.json', TO_IGNORE)).catch(() => []).then(files => getMainFiles(root, files)); + }), loadPromise]); client.dispose(); - return {root, exportCache, jsFiles, nodeModulesPackageJsonFiles, mainFiles}; + return { root, exportCache, jsFiles, nodeModulesPackageJsonFiles, mainFiles }; } function getOutputLines(command, args, opts) { - return spawn(command, args, opts).switchMap(proc => { - return getOutputStream(proc).reduce((acc, result) => { + return (0, (_process || _load_process()).spawn)(command, args, opts).switchMap(proc => { + return (0, (_process || _load_process()).getOutputStream)(proc).reduce((acc, result) => { if (result.kind === 'stdout') { acc.push(result.data.trimRight()); } @@ -103,146 +112,87 @@ function getOutputLines(command, args, opts) { }); } -function hgListFiles( - root: string, - pattern: string, - ignore: Array, -): Promise> { - const ignorePatterns = arrayFlatten(ignore.map(x => ['-X', x])); +function hgListFiles(root, pattern, ignore) { + const ignorePatterns = (0, (_collection || _load_collection()).arrayFlatten)(ignore.map(x => ['-X', x])); return getOutputLines('hg', ['files', '-I', pattern, ...ignorePatterns], { - cwd: root, + cwd: root }).toPromise(); } -function findListFiles( - root: string, - pattern: string, - ignore: Array, -): Promise> { - const ignorePatterns = arrayFlatten(ignore.map(x => ['-not', '-path', x])); - return ( - getOutputLines('find', ['.', '-name', pattern, ...ignorePatterns], { - cwd: root, - }) - // Strip the leading "./". - .map(files => files.map(f => f.substr(2))) - .toPromise() - ); -} - -function globListFiles( - root: string, - pattern: string, - ignore?: Array, -): Promise> { - return fsPromise.glob(pattern, {cwd: root, ignore}); -} - -function watchmanListFiles( - client: WatchmanClient, - root: string, - pattern: string, -): Promise> { - return client - .listFiles(root, getWatchmanExpression(root, pattern)) - .then((files: Array) => - files.map(data => ({name: data.name, sha1: data['content.sha1hex']})), - ); -} - -async function getMainFiles( - root: string, - packageJsons: Array, -): Promise> { - const cpus = os.cpus(); - const results = await asyncLimit( - packageJsons, - cpus ? Math.max(1, cpus.length) : 1, - async packageJson => { - try { - const fullPath = nuclideUri.join(root, packageJson); - const data = await fsPromise.readFile(fullPath, 'utf8'); - let main = JSON.parse(data).main || 'index.js'; - // Ignore things that go outside the scope of the package.json. - if (main.startsWith('..')) { - return null; - } - if (!main.endsWith('.js')) { - main += '.js'; - } - const dirname = nuclideUri.dirname(fullPath); - // Note: the main file may not necessarily exist. - // We don't really need to check existence here, since non-existent files - // will never be indexed anyway. - return [nuclideUri.resolve(dirname, main), dirname]; - } catch (err) { +function findListFiles(root, pattern, ignore) { + const ignorePatterns = (0, (_collection || _load_collection()).arrayFlatten)(ignore.map(x => ['-not', '-path', x])); + return getOutputLines('find', ['.', '-name', pattern, ...ignorePatterns], { + cwd: root + }) + // Strip the leading "./". + .map(files => files.map(f => f.substr(2))).toPromise(); +} + +function globListFiles(root, pattern, ignore) { + return (_fsPromise || _load_fsPromise()).default.glob(pattern, { cwd: root, ignore }); +} + +function watchmanListFiles(client, root, pattern) { + return client.listFiles(root, getWatchmanExpression(root, pattern)).then(files => files.map(data => ({ name: data.name, sha1: data['content.sha1hex'] }))); +} + +async function getMainFiles(root, packageJsons) { + const cpus = _os.default.cpus(); + const results = await (0, (_promise || _load_promise()).asyncLimit)(packageJsons, cpus ? Math.max(1, cpus.length) : 1, async packageJson => { + try { + const fullPath = (_nuclideUri || _load_nuclideUri()).default.join(root, packageJson); + const data = await (_fsPromise || _load_fsPromise()).default.readFile(fullPath, 'utf8'); + let main = JSON.parse(data).main || 'index.js'; + // Ignore things that go outside the scope of the package.json. + if (main.startsWith('..')) { return null; } - }, - ); + if (!main.endsWith('.js')) { + main += '.js'; + } + const dirname = (_nuclideUri || _load_nuclideUri()).default.dirname(fullPath); + // Note: the main file may not necessarily exist. + // We don't really need to check existence here, since non-existent files + // will never be indexed anyway. + return [(_nuclideUri || _load_nuclideUri()).default.resolve(dirname, main), dirname]; + } catch (err) { + return null; + } + }); return new Map(results.filter(Boolean)); } -function filesWithoutHash(files: Array): Array { - return files.map(name => ({name, sha1: null})); +function filesWithoutHash(files) { + return files.map(name => ({ name, sha1: null })); } // TODO: watch node_modules and package.json files for changes. -export function watchDirectory(root: string): Observable { - return Observable.defer(() => { - const watchmanClient = new WatchmanClient(); - return Observable.using( - () => new UniversalDisposable(watchmanClient), - () => - Observable.fromPromise( - watchmanClient.watchDirectoryRecursive( - root, - 'js-imports-subscription', - getWatchmanExpression(root, '*.js'), - ), - ).switchMap(watchmanSubscription => { - return Observable.fromEvent(watchmanSubscription, 'change').switchMap( - (changes: Array) => - Observable.from( - changes - .map(change => { - const name = nuclideUri.join( - watchmanSubscription.root, - change.name, - ); - if (!nuclideUri.contains(root, name)) { - return null; - } - return { - ...change, - name, - }; - }) - .filter(Boolean), - ), - ); - }), - ); +function watchDirectory(root) { + return _rxjsBundlesRxMinJs.Observable.defer(() => { + const watchmanClient = new (_nuclideWatchmanHelpers || _load_nuclideWatchmanHelpers()).WatchmanClient(); + return _rxjsBundlesRxMinJs.Observable.using(() => new (_UniversalDisposable || _load_UniversalDisposable()).default(watchmanClient), () => _rxjsBundlesRxMinJs.Observable.fromPromise(watchmanClient.watchDirectoryRecursive(root, 'js-imports-subscription', getWatchmanExpression(root, '*.js'))).switchMap(watchmanSubscription => { + return _rxjsBundlesRxMinJs.Observable.fromEvent(watchmanSubscription, 'change').switchMap(changes => _rxjsBundlesRxMinJs.Observable.from(changes.map(change => { + const name = (_nuclideUri || _load_nuclideUri()).default.join(watchmanSubscription.root, change.name); + if (!(_nuclideUri || _load_nuclideUri()).default.contains(root, name)) { + return null; + } + return Object.assign({}, change, { + name + }); + }).filter(Boolean))); + })); }); } -function getWatchmanExpression(root: string, pattern: string) { +function getWatchmanExpression(root, pattern) { return { - expression: [ - 'allof', - ['match', pattern], - ['type', 'f'], - ...getWatchmanMatchesFromIgnoredFiles(), - ], - fields: ['name', 'content.sha1hex'], + expression: ['allof', ['match', pattern], ['type', 'f'], ...getWatchmanMatchesFromIgnoredFiles()], + fields: ['name', 'content.sha1hex'] }; } function getWatchmanMatchesFromIgnoredFiles() { return TO_IGNORE.map(patternToIgnore => { - return [ - 'not', - ['match', patternToIgnore, 'wholename', {includedotfiles: true}], - ]; + return ['not', ['match', patternToIgnore, 'wholename', { includedotfiles: true }]]; }); -} +} \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/lib/types.js b/pkg/nuclide-js-imports-server/src/lib/types.js index 8200b6044a..a726efc43f 100644 --- a/pkg/nuclide-js-imports-server/src/lib/types.js +++ b/pkg/nuclide-js-imports-server/src/lib/types.js @@ -1,66 +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 - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -// Warning: this list is not comprehensive. -// Other AST types may potentially be exported as well. -export type ExportType = - | 'FunctionDeclaration' - | 'ClassDeclaration' - | 'VariableDeclaration' - | 'InterfaceDeclaration' - | 'ObjectExpression' - | 'FunctionExpression' - | 'ClassExpression' - | 'TypeAlias' - | 'NumericLiteral' - | 'StringLiteral'; - -export type ImportSuggestion = { - symbol: UndefinedSymbol, - filesWithExport: Array, -}; - -export type JSImport = { - type: 'require' | 'import' | 'importType', - importPath: string, -}; - -export type JSExport = { - id: string, - uri: NuclideUri, - line: number, // Line number (1-based for AST consistency) - isTypeExport: boolean, - isDefault: boolean, - hasteName?: string, - directoryForMainFile?: NuclideUri, - type?: ExportType, -}; - -export type UndefinedSymbol = { - id: string, - type: 'value' | 'type', - location: Location, -}; - -type Location = { - start: {col: number, line: number}, - end: {col: number, line: number}, -}; - -export type BabylonOptions = { - allowImportExportEverywhere?: boolean, - allowReturnOutsideFunction?: boolean, - sourceType?: 'module' | 'script', - startLine?: number, - plugins: Array, -}; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/utils/constantsForClient.js b/pkg/nuclide-js-imports-server/src/utils/constantsForClient.js index e412f1e40b..70b5771f05 100644 --- a/pkg/nuclide-js-imports-server/src/utils/constantsForClient.js +++ b/pkg/nuclide-js-imports-server/src/utils/constantsForClient.js @@ -1,3 +1,8 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,10 +10,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ // We use a magical constants to determine whether format command // is intended for us. -export const TAB_SIZE_SIGNIFYING_FIX_ALL_IMPORTS_FORMATTING = 43; +const TAB_SIZE_SIGNIFYING_FIX_ALL_IMPORTS_FORMATTING = exports.TAB_SIZE_SIGNIFYING_FIX_ALL_IMPORTS_FORMATTING = 43; \ No newline at end of file diff --git a/pkg/nuclide-js-imports-server/src/utils/util.js b/pkg/nuclide-js-imports-server/src/utils/util.js index c5b7d05778..96e7e456a0 100644 --- a/pkg/nuclide-js-imports-server/src/utils/util.js +++ b/pkg/nuclide-js-imports-server/src/utils/util.js @@ -1,21 +1,22 @@ -/** - * 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 - */ +'use strict'; -import {Point, Range} from 'simple-text-buffer'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.babelLocationToAtomRange = babelLocationToAtomRange; +exports.importPathToPriority = importPathToPriority; +exports.compareForInsertion = compareForInsertion; +exports.compareForSuggestion = compareForSuggestion; +exports.getRequiredModule = getRequiredModule; + +var _simpleTextBuffer; + +function _load_simpleTextBuffer() { + return _simpleTextBuffer = require('simple-text-buffer'); +} -export function babelLocationToAtomRange(location: Object): atom$Range { - return new Range( - new Point(location.start.line - 1, location.start.col), - new Point(location.end.line - 1, location.end.col), - ); +function babelLocationToAtomRange(location) { + return new (_simpleTextBuffer || _load_simpleTextBuffer()).Range(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(location.start.line - 1, location.start.col), new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(location.end.line - 1, location.end.col)); } /** @@ -24,11 +25,22 @@ export function babelLocationToAtomRange(location: Object): atom$Range { * - Relative paths in other directories (../*) * - Local paths (./*) */ +/** + * 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. + * + * + * @format + */ + const MODULES_PRIORITY = -1; const RELATIVE_PRIORITY = 0; const LOCAL_PRIORITY = 1; -export function importPathToPriority(path: string): number { +function importPathToPriority(path) { if (path.startsWith('..')) { return RELATIVE_PRIORITY; } @@ -38,11 +50,11 @@ export function importPathToPriority(path: string): number { return MODULES_PRIORITY; } -function isLowerCase(s: string) { +function isLowerCase(s) { return s.toLowerCase() === s; } -export function compareForInsertion(path1: string, path2: string): number { +function compareForInsertion(path1, path2) { const p1 = importPathToPriority(path1); const p2 = importPathToPriority(path2); if (p1 !== p2) { @@ -61,7 +73,7 @@ export function compareForInsertion(path1: string, path2: string): number { return path1.localeCompare(path2); } -export function compareForSuggestion(path1: string, path2: string): number { +function compareForSuggestion(path1, path2) { const p1 = importPathToPriority(path1); const p2 = importPathToPriority(path2); if (p1 !== p2) { @@ -76,14 +88,8 @@ export function compareForSuggestion(path1: string, path2: string): number { } // Check if an AST node is a require call, and returns the literal value. -export function getRequiredModule(node: Object): ?string { - if ( - node.type === 'CallExpression' && - node.callee.type === 'Identifier' && - node.callee.name === 'require' && - node.arguments[0] && - node.arguments[0].type === 'StringLiteral' - ) { +function getRequiredModule(node) { + if (node.type === 'CallExpression' && node.callee.type === 'Identifier' && node.callee.name === 'require' && node.arguments[0] && node.arguments[0].type === 'StringLiteral') { return node.arguments[0].value; } -} +} \ No newline at end of file diff --git a/pkg/nuclide-json/__atom_tests__/JSONOutlineProvider-test.js b/pkg/nuclide-json/__atom_tests__/JSONOutlineProvider-test.js index 484c2204ca..169adbd85b 100644 --- a/pkg/nuclide-json/__atom_tests__/JSONOutlineProvider-test.js +++ b/pkg/nuclide-json/__atom_tests__/JSONOutlineProvider-test.js @@ -1,3 +1,13 @@ +'use strict'; + +var _atom = require('atom'); + +var _JSONOutlineProvider; + +function _load_JSONOutlineProvider() { + return _JSONOutlineProvider = require('../lib/JSONOutlineProvider'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,33 +15,30 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import {Point} from 'atom'; - -import invariant from 'assert'; -import {getOutline} from '../lib/JSONOutlineProvider'; - describe('getOutline', () => { it('should outline the top-level properties of an object', () => { const json = '{"foo": {"subobj": 5}, "bar": 6}'; - const outline = getOutline(json); + const outline = (0, (_JSONOutlineProvider || _load_JSONOutlineProvider()).getOutline)(json); - invariant(outline != null); + if (!(outline != null)) { + throw new Error('Invariant violation: "outline != null"'); + } const outlineTrees = outline.outlineTrees; expect(outlineTrees.length).toBe(2); expect(outlineTrees[0].plainText).toEqual('foo'); - expect(outlineTrees[0].startPosition).toEqual(new Point(0, 1)); - expect(outlineTrees[0].endPosition).toEqual(new Point(0, 21)); + expect(outlineTrees[0].startPosition).toEqual(new _atom.Point(0, 1)); + expect(outlineTrees[0].endPosition).toEqual(new _atom.Point(0, 21)); expect(outlineTrees[0].children.length).toEqual(0); expect(outlineTrees[1].plainText).toEqual('bar'); - expect(outlineTrees[1].startPosition).toEqual(new Point(0, 23)); - expect(outlineTrees[1].endPosition).toEqual(new Point(0, 31)); + expect(outlineTrees[1].startPosition).toEqual(new _atom.Point(0, 23)); + expect(outlineTrees[1].endPosition).toEqual(new _atom.Point(0, 31)); expect(outlineTrees[1].children.length).toEqual(0); }); @@ -39,30 +46,32 @@ describe('getOutline', () => { // This won't be valid JSON, but since we are using a real JS parser we need to make sure that // this sort of input doesn't do really weird stuff. const json = '{"foo": 5, [5 + 3]: 3, "bar": 2, 3: 4}'; - const outline = getOutline(json); + const outline = (0, (_JSONOutlineProvider || _load_JSONOutlineProvider()).getOutline)(json); - invariant(outline != null); + if (!(outline != null)) { + throw new Error('Invariant violation: "outline != null"'); + } const outlineTrees = outline.outlineTrees; expect(outlineTrees.length).toBe(2); expect(outlineTrees[0].plainText).toEqual('foo'); - expect(outlineTrees[0].startPosition).toEqual(new Point(0, 1)); - expect(outlineTrees[0].endPosition).toEqual(new Point(0, 9)); + expect(outlineTrees[0].startPosition).toEqual(new _atom.Point(0, 1)); + expect(outlineTrees[0].endPosition).toEqual(new _atom.Point(0, 9)); expect(outlineTrees[0].children.length).toEqual(0); expect(outlineTrees[1].plainText).toEqual('bar'); - expect(outlineTrees[1].startPosition).toEqual(new Point(0, 23)); - expect(outlineTrees[1].endPosition).toEqual(new Point(0, 31)); + expect(outlineTrees[1].startPosition).toEqual(new _atom.Point(0, 23)); + expect(outlineTrees[1].endPosition).toEqual(new _atom.Point(0, 31)); expect(outlineTrees[1].children.length).toEqual(0); }); it('should return null on a syntax error', () => { // This is kind of sad but the babel-core parser doesn't seem to do any error recovery. - expect(getOutline('{')).toBeNull(); + expect((0, (_JSONOutlineProvider || _load_JSONOutlineProvider()).getOutline)('{')).toBeNull(); }); it('should return null if there is not a top-level object', () => { - expect(getOutline('[]')).toBeNull(); + expect((0, (_JSONOutlineProvider || _load_JSONOutlineProvider()).getOutline)('[]')).toBeNull(); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-json/__atom_tests__/NPMHyperclickProvider-test.js b/pkg/nuclide-json/__atom_tests__/NPMHyperclickProvider-test.js index 925eff5f83..d67746aeec 100644 --- a/pkg/nuclide-json/__atom_tests__/NPMHyperclickProvider-test.js +++ b/pkg/nuclide-json/__atom_tests__/NPMHyperclickProvider-test.js @@ -1,3 +1,13 @@ +'use strict'; + +var _atom = require('atom'); + +var _NPMHyperclickProvider; + +function _load_NPMHyperclickProvider() { + return _NPMHyperclickProvider = require('../lib/NPMHyperclickProvider'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,14 +15,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import {Range} from 'atom'; - -import {getPackageUrlForRange} from '../lib/NPMHyperclickProvider'; - const sampleJSON = `{ "someProperty": { "thing": "0.0.0" @@ -32,89 +38,33 @@ const sampleJSON = `{ describe('getPackageUrlForRange', () => { it('should provide an npm URL for a dependency', () => { - expect( - getPackageUrlForRange( - sampleJSON, - '"npm-package"', - new Range([5, 4], [5, 17]), - ), - ).toEqual('https://www.npmjs.com/package/npm-package/'); + expect((0, (_NPMHyperclickProvider || _load_NPMHyperclickProvider()).getPackageUrlForRange)(sampleJSON, '"npm-package"', new _atom.Range([5, 4], [5, 17]))).toEqual('https://www.npmjs.com/package/npm-package/'); }); it('should not provide a URL for a dependency with a non-literal property', () => { - expect( - getPackageUrlForRange( - sampleJSON, - '"something-else"', - new Range([6, 4], [6, 20]), - ), - ).toBeNull(); + expect((0, (_NPMHyperclickProvider || _load_NPMHyperclickProvider()).getPackageUrlForRange)(sampleJSON, '"something-else"', new _atom.Range([6, 4], [6, 20]))).toBeNull(); }); it('should not provide a URL for a nested property in a dependency', () => { - expect( - getPackageUrlForRange( - sampleJSON, - '"what-is-this"', - new Range([7, 6], [7, 20]), - ), - ).toBeNull(); + expect((0, (_NPMHyperclickProvider || _load_NPMHyperclickProvider()).getPackageUrlForRange)(sampleJSON, '"what-is-this"', new _atom.Range([7, 6], [7, 20]))).toBeNull(); }); it('should not provide a URL for a dependency with a non-semver version', () => { - expect( - getPackageUrlForRange( - sampleJSON, - '"git-url"', - new Range([9, 4], [9, 13]), - ), - ).toBeNull(); - expect( - getPackageUrlForRange( - sampleJSON, - '"file-path"', - new Range([10, 4], [10, 15]), - ), - ).toBeNull(); - expect( - getPackageUrlForRange( - sampleJSON, - '"http-url"', - new Range([11, 4], [11, 14]), - ), - ).toBeNull(); + expect((0, (_NPMHyperclickProvider || _load_NPMHyperclickProvider()).getPackageUrlForRange)(sampleJSON, '"git-url"', new _atom.Range([9, 4], [9, 13]))).toBeNull(); + expect((0, (_NPMHyperclickProvider || _load_NPMHyperclickProvider()).getPackageUrlForRange)(sampleJSON, '"file-path"', new _atom.Range([10, 4], [10, 15]))).toBeNull(); + expect((0, (_NPMHyperclickProvider || _load_NPMHyperclickProvider()).getPackageUrlForRange)(sampleJSON, '"http-url"', new _atom.Range([11, 4], [11, 14]))).toBeNull(); }); it('should provide a URL for a github dependency', () => { - expect( - getPackageUrlForRange( - sampleJSON, - '"github"', - new Range([12, 4], [12, 12]), - ), - ).toEqual('https://github.com/facebook/nuclide/tree/v0.130.0'); - expect( - getPackageUrlForRange( - sampleJSON, - '"github-prefix"', - new Range([13, 4], [13, 19]), - ), - ).toEqual('https://github.com/facebook/nuclide'); + expect((0, (_NPMHyperclickProvider || _load_NPMHyperclickProvider()).getPackageUrlForRange)(sampleJSON, '"github"', new _atom.Range([12, 4], [12, 12]))).toEqual('https://github.com/facebook/nuclide/tree/v0.130.0'); + expect((0, (_NPMHyperclickProvider || _load_NPMHyperclickProvider()).getPackageUrlForRange)(sampleJSON, '"github-prefix"', new _atom.Range([13, 4], [13, 19]))).toEqual('https://github.com/facebook/nuclide'); }); it('should not provide a URL for the "dependencies" string itself', () => { - expect( - getPackageUrlForRange( - sampleJSON, - '"dependencies"', - new Range([4, 2], [4, 16]), - ), - ).toBeNull(); + expect((0, (_NPMHyperclickProvider || _load_NPMHyperclickProvider()).getPackageUrlForRange)(sampleJSON, '"dependencies"', new _atom.Range([4, 2], [4, 16]))).toBeNull(); }); it('should not provide a URL for non-dependencies', () => { - expect( - getPackageUrlForRange(sampleJSON, '"thing"', new Range([2, 4], [2, 11])), - ).toBeNull(); + expect((0, (_NPMHyperclickProvider || _load_NPMHyperclickProvider()).getPackageUrlForRange)(sampleJSON, '"thing"', new _atom.Range([2, 4], [2, 11]))).toBeNull(); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-json/lib/CodeFormatHelpers.js b/pkg/nuclide-json/lib/CodeFormatHelpers.js index c195dc6d97..d3d664a2a6 100644 --- a/pkg/nuclide-json/lib/CodeFormatHelpers.js +++ b/pkg/nuclide-json/lib/CodeFormatHelpers.js @@ -1,32 +1,31 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import {trackTiming} from '../../nuclide-analytics'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -export default class CodeFormatHelpers { - static formatEntireFile( - editor: atom$TextEditor, - range: atom$Range, - ): Promise<{ - newCursor?: number, - formatted: string, - }> { - return trackTiming('json.formatCode', () => { +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +class CodeFormatHelpers { + static formatEntireFile(editor, range) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)('json.formatCode', () => { const buffer_as_json = JSON.parse(editor.getBuffer().getText()); - const formatted = JSON.stringify( - buffer_as_json, - null, - editor.getTabLength(), - ); - return Promise.resolve({formatted}); + const formatted = JSON.stringify(buffer_as_json, null, editor.getTabLength()); + return Promise.resolve({ formatted }); }); } } +exports.default = CodeFormatHelpers; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-json/lib/JSONOutlineProvider.js b/pkg/nuclide-json/lib/JSONOutlineProvider.js index b7cad07a1d..e0195b9850 100644 --- a/pkg/nuclide-json/lib/JSONOutlineProvider.js +++ b/pkg/nuclide-json/lib/JSONOutlineProvider.js @@ -1,3 +1,16 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getOutline = getOutline; + +var _parsing; + +function _load_parsing() { + return _parsing = require('./parsing'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,37 +18,29 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {Outline} from 'atom-ide-ui'; - -import {parseJSON, babelPosToPoint} from './parsing'; - -export function getOutline(text: string): ?Outline { - const expression = parseJSON(text); +function getOutline(text) { + const expression = (0, (_parsing || _load_parsing()).parseJSON)(text); if (expression == null) { return null; } if (expression.type === 'ObjectExpression') { const outlineTrees = expression.properties - // Filter out property keys that aren't string literals, such as computed properties. They - // aren't valid JSON but nothing actually enforces that we are getting valid JSON and we are - // using a full JS parser so we have to handle cases like this. - .filter( - prop => - prop.type === 'ObjectProperty' && prop.key.type === 'StringLiteral', - ) - .map(prop => { - return { - plainText: String(prop.key.value), - startPosition: babelPosToPoint(prop.loc.start), - endPosition: babelPosToPoint(prop.loc.end), - children: [], - }; - }); - return {outlineTrees}; + // Filter out property keys that aren't string literals, such as computed properties. They + // aren't valid JSON but nothing actually enforces that we are getting valid JSON and we are + // using a full JS parser so we have to handle cases like this. + .filter(prop => prop.type === 'ObjectProperty' && prop.key.type === 'StringLiteral').map(prop => { + return { + plainText: String(prop.key.value), + startPosition: (0, (_parsing || _load_parsing()).babelPosToPoint)(prop.loc.start), + endPosition: (0, (_parsing || _load_parsing()).babelPosToPoint)(prop.loc.end), + children: [] + }; + }); + return { outlineTrees }; } return null; -} +} \ No newline at end of file diff --git a/pkg/nuclide-json/lib/NPMHyperclickProvider.js b/pkg/nuclide-json/lib/NPMHyperclickProvider.js index 9f3695a251..916cecc8bb 100644 --- a/pkg/nuclide-json/lib/NPMHyperclickProvider.js +++ b/pkg/nuclide-json/lib/NPMHyperclickProvider.js @@ -1,29 +1,45 @@ -/** - * 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 - */ - -import type {HyperclickProvider, HyperclickSuggestion} from 'atom-ide-ui'; - -import semver from 'semver'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {shell} from 'electron'; - -import {parseJSON, babelLocToRange} from './parsing'; - -const DEPENDENCY_PROPERTIES = new Set([ - 'dependencies', - 'devDependencies', - 'optionalDependencies', -]); - -export function getNPMHyperclickProvider(): HyperclickProvider { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getNPMHyperclickProvider = getNPMHyperclickProvider; +exports.getPackageUrlForRange = getPackageUrlForRange; + +var _semver; + +function _load_semver() { + return _semver = _interopRequireDefault(require('semver')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _electron = require('electron'); + +var _parsing; + +function _load_parsing() { + return _parsing = require('./parsing'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const DEPENDENCY_PROPERTIES = new Set(['dependencies', 'devDependencies', 'optionalDependencies']); /** + * 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. + * + * + * @format + */ + +function getNPMHyperclickProvider() { return npmHyperclickProvider; } @@ -32,14 +48,10 @@ const npmHyperclickProvider = { providerName: 'npm-package-json', getSuggestionForWord, // Capture just text in quotes - wordRegExp: /"[^"]*"/g, + wordRegExp: /"[^"]*"/g }; -function getSuggestionForWord( - textEditor: atom$TextEditor, - text: string, - range: atom$Range, -): Promise { +function getSuggestionForWord(textEditor, text, range) { if (text === '' || !isPackageJson(textEditor)) { return Promise.resolve(null); } @@ -50,22 +62,18 @@ function getSuggestionForWord( return Promise.resolve(null); } - const suggestion: HyperclickSuggestion = { + const suggestion = { range, callback: () => { - shell.openExternal(packageUrl); - }, + _electron.shell.openExternal(packageUrl); + } }; return Promise.resolve(suggestion); } // Exported for testing. We could derive the token from the json text and the range, but since // hyperclick provides it we may as well use it. -export function getPackageUrlForRange( - json: string, - token: string, - range: atom$Range, -): ?string { +function getPackageUrlForRange(json, token, range) { const version = getDependencyVersion(json, range); if (version == null) { return null; @@ -77,18 +85,14 @@ export function getPackageUrlForRange( return getPackageUrl(packageName, version); } -function isPackageJson(textEditor: atom$TextEditor): boolean { +function isPackageJson(textEditor) { const scopeName = textEditor.getGrammar().scopeName; const filePath = textEditor.getPath(); - return ( - scopeName === 'source.json' && - filePath != null && - nuclideUri.basename(filePath) === 'package.json' - ); + return scopeName === 'source.json' && filePath != null && (_nuclideUri || _load_nuclideUri()).default.basename(filePath) === 'package.json'; } -function getPackageUrl(packageName: string, version: string): ?string { - if (semver.valid(version)) { +function getPackageUrl(packageName, version) { + if ((_semver || _load_semver()).default.valid(version)) { return `https://www.npmjs.com/package/${packageName}/`; } @@ -112,20 +116,15 @@ function getPackageUrl(packageName: string, version: string): ?string { } // Return the version string, if it exists -function getDependencyVersion(json: string, range: atom$Range): ?string { - const ast = parseJSON(json); +function getDependencyVersion(json, range) { + const ast = (0, (_parsing || _load_parsing()).parseJSON)(json); if (ast == null) { // parse error return null; } const pathToNode = getPathToNodeForRange(ast, range); - if ( - pathToNode != null && - pathToNode.length === 2 && - DEPENDENCY_PROPERTIES.has(pathToNode[0].key.value) && - isValidVersion(pathToNode[1].value) - ) { + if (pathToNode != null && pathToNode.length === 2 && DEPENDENCY_PROPERTIES.has(pathToNode[0].key.value) && isValidVersion(pathToNode[1].value)) { const valueNode = pathToNode[1].value; if (isValidVersion(valueNode)) { return valueNode.value; @@ -136,23 +135,20 @@ function getDependencyVersion(json: string, range: atom$Range): ?string { return null; } -function isValidVersion(valueASTNode: Object): boolean { +function isValidVersion(valueASTNode) { return valueASTNode.type === 'StringLiteral'; } // return an array of property AST nodes -function getPathToNodeForRange( - objectExpression: Object, - range: atom$Range, -): ?Array { +function getPathToNodeForRange(objectExpression, range) { const properties = objectExpression.properties; if (properties == null) { return null; } for (const property of properties) { - const propertyRange = babelLocToRange(property.loc); + const propertyRange = (0, (_parsing || _load_parsing()).babelLocToRange)(property.loc); if (propertyRange.containsRange(range)) { - const keyRange = babelLocToRange(property.key.loc); + const keyRange = (0, (_parsing || _load_parsing()).babelLocToRange)(property.key.loc); if (keyRange.isEqual(range)) { return [property]; } @@ -165,4 +161,4 @@ function getPathToNodeForRange( } } return null; -} +} \ No newline at end of file diff --git a/pkg/nuclide-json/lib/main.js b/pkg/nuclide-json/lib/main.js index 59171fd8ae..59465181ef 100644 --- a/pkg/nuclide-json/lib/main.js +++ b/pkg/nuclide-json/lib/main.js @@ -1,76 +1,96 @@ -/** - * 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 - */ - -import type { - CodeFormatProvider, - HyperclickProvider, - Outline, - OutlineProvider, -} from 'atom-ide-ui'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -import {getOutline} from './JSONOutlineProvider'; -import {getNPMHyperclickProvider} from './NPMHyperclickProvider'; - -import CodeFormatHelpers from './CodeFormatHelpers'; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.activate = activate; +exports.deactivate = deactivate; +exports.provideOutlines = provideOutlines; +exports.getHyperclickProvider = getHyperclickProvider; +exports.provideCodeFormat = provideCodeFormat; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _JSONOutlineProvider; + +function _load_JSONOutlineProvider() { + return _JSONOutlineProvider = require('./JSONOutlineProvider'); +} + +var _NPMHyperclickProvider; + +function _load_NPMHyperclickProvider() { + return _NPMHyperclickProvider = require('./NPMHyperclickProvider'); +} + +var _CodeFormatHelpers; + +function _load_CodeFormatHelpers() { + return _CodeFormatHelpers = _interopRequireDefault(require('./CodeFormatHelpers')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class Activation { - _disposables: UniversalDisposable; - constructor(state: ?Object) { - this._disposables = new UniversalDisposable(); + constructor(state) { + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - dispose(): void { + dispose() { this._disposables.dispose(); } -} +} /** + * 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. + * + * + * @format + */ -let activation: ?Activation = null; +let activation = null; -export function activate(state: ?Object): void { +function activate(state) { if (activation == null) { activation = new Activation(state); } } -export function deactivate(): void { +function deactivate() { if (activation != null) { activation.dispose(); activation = null; } } -export function provideOutlines(): OutlineProvider { +function provideOutlines() { return { grammarScopes: ['source.json'], priority: 1, name: 'Nuclide JSON', - getOutline(editor: atom$TextEditor): Promise { - return Promise.resolve(getOutline(editor.getText())); - }, + getOutline(editor) { + return Promise.resolve((0, (_JSONOutlineProvider || _load_JSONOutlineProvider()).getOutline)(editor.getText())); + } }; } -export function getHyperclickProvider(): HyperclickProvider { - return getNPMHyperclickProvider(); +function getHyperclickProvider() { + return (0, (_NPMHyperclickProvider || _load_NPMHyperclickProvider()).getNPMHyperclickProvider)(); } -export function provideCodeFormat(): CodeFormatProvider { +function provideCodeFormat() { return { grammarScopes: ['source.json'], priority: 1, formatEntireFile(editor, range) { - return CodeFormatHelpers.formatEntireFile(editor, range); - }, + return (_CodeFormatHelpers || _load_CodeFormatHelpers()).default.formatEntireFile(editor, range); + } }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-json/lib/parsing.js b/pkg/nuclide-json/lib/parsing.js index aedadad085..2b5bdadaa6 100644 --- a/pkg/nuclide-json/lib/parsing.js +++ b/pkg/nuclide-json/lib/parsing.js @@ -1,53 +1,62 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.parseJSON = parseJSON; +exports.babelPosToPoint = babelPosToPoint; +exports.babelLocToRange = babelLocToRange; -import invariant from 'assert'; -import {Point, Range} from 'atom'; -import * as babylon from 'babylon'; +var _atom = require('atom'); -type BabelPos = { - line: number, - column: number, -}; +var _babylon; + +function _load_babylon() { + return _babylon = _interopRequireWildcard(require('babylon')); +} -type BabelLoc = { - start: BabelPos, - end: BabelPos, -}; +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; } } /** * Returns a Babel Expression AST node, or null if the parse does not succeed. */ -export function parseJSON(json: string): ?Object { +function parseJSON(json) { // This messes up the positions but without it, babel won't parse the text as an expression. const jsonWithParens = '(\n' + json + '\n)'; try { - const ast: Object = babylon.parse(jsonWithParens, {sourceType: 'script'}); + const ast = (_babylon || _load_babylon()).parse(jsonWithParens, { sourceType: 'script' }); if (ast.type === 'File') { - invariant(ast.program.body[0].type === 'ExpressionStatement'); + if (!(ast.program.body[0].type === 'ExpressionStatement')) { + throw new Error('Invariant violation: "ast.program.body[0].type === \'ExpressionStatement\'"'); + } + return ast.program.body[0].expression; } else if (ast.type === 'Program') { - invariant(ast.body[0].type === 'ExpressionStatement'); + if (!(ast.body[0].type === 'ExpressionStatement')) { + throw new Error('Invariant violation: "ast.body[0].type === \'ExpressionStatement\'"'); + } + return ast.body[0].expression; } } catch (e) {} return null; -} +} /** + * 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. + * + * + * @format + */ -export function babelPosToPoint(pos: BabelPos): atom$Point { +function babelPosToPoint(pos) { // Need to subtract 2: one to move from 1-indexed to 0-indexed, another to account for the open // paren we had to add on the first line. - return new Point(pos.line - 2, pos.column); + return new _atom.Point(pos.line - 2, pos.column); } -export function babelLocToRange(loc: BabelLoc): atom$Range { - return new Range(babelPosToPoint(loc.start), babelPosToPoint(loc.end)); -} +function babelLocToRange(loc) { + return new _atom.Range(babelPosToPoint(loc.start), babelPosToPoint(loc.end)); +} \ No newline at end of file diff --git a/pkg/nuclide-key-binding-hint-status/lib/KeyBindingHint.js b/pkg/nuclide-key-binding-hint-status/lib/KeyBindingHint.js index 767e0c3ed4..80574c38f8 100644 --- a/pkg/nuclide-key-binding-hint-status/lib/KeyBindingHint.js +++ b/pkg/nuclide-key-binding-hint-status/lib/KeyBindingHint.js @@ -1,3 +1,48 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = _interopRequireWildcard(require('react')); + +var _Icon; + +function _load_Icon() { + return _Icon = require('../../../modules/nuclide-commons-ui/Icon'); +} + +var _addTooltip; + +function _load_addTooltip() { + return _addTooltip = _interopRequireDefault(require('../../../modules/nuclide-commons-ui/addTooltip')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _humanizeKeystroke; + +function _load_humanizeKeystroke() { + return _humanizeKeystroke = _interopRequireDefault(require('../../../modules/nuclide-commons/humanizeKeystroke')); +} + +var _humanizeEventName; + +function _load_humanizeEventName() { + return _humanizeEventName = _interopRequireDefault(require('../../commons-node/humanizeEventName')); +} + +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; } } + +/* global KeyboardEvent */ + +// Given a command name, return an array of human readable key bindings. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,105 +50,98 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import * as React from 'react'; -import {Icon} from 'nuclide-commons-ui/Icon'; -import addTooltip from 'nuclide-commons-ui/addTooltip'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import humanizeKeystroke from 'nuclide-commons/humanizeKeystroke'; -import humanizeEventName from '../../commons-node/humanizeEventName'; - -/* global KeyboardEvent */ - -// Given a command name, return an array of human readable key bindings. -function keyBindingsFromCommand(commandName: string): Array { +function keyBindingsFromCommand(commandName) { const keyBindings = atom.keymaps.findKeyBindings({ command: commandName, // Adding the target allows us to filter out keymaps for other OSs. - target: window.document.activeElement, + target: window.document.activeElement }); const humanizedKeyBindings = keyBindings.map(binding => { - return humanizeKeystroke(binding.keystrokes); + return (0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)(binding.keystrokes); }); return humanizedKeyBindings; } -type State = { - event: ?Event, -}; - -export default class KeyBindingHint extends React.Component { - _areProcessingUserEvent: boolean; - _disposables: UniversalDisposable; +class KeyBindingHint extends _react.Component { - constructor(props: any) { + constructor(props) { super(props); + + this._handleWillDispatch = event => { + // We don't care about events dispatched by other events. + if (!this._areProcessingUserEvent) { + this._areProcessingUserEvent = true; + // If they are already using the keyboard, they don't need our advice. + // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) + if (event.originalEvent instanceof KeyboardEvent) { + this.setState({ event: null }); + } else { + this.setState({ event }); + } + // Nested events are handled within a single event loop. By handling only + // the first event of a given loop, we approximate only responding to user + // instigated events. + setImmediate(this._userEventComplete); + } + }; + + this._userEventComplete = () => { + this._areProcessingUserEvent = false; + }; + this._areProcessingUserEvent = false; - this.state = {event: null}; + this.state = { event: null }; - this._disposables = new UniversalDisposable( - atom.commands.onWillDispatch(this._handleWillDispatch), - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(atom.commands.onWillDispatch(this._handleWillDispatch)); } - render(): React.Node { - const {event} = this.state; + render() { + const { event } = this.state; if (event == null) { - return
    ; + return _react.createElement('div', null); } const keyBindings = keyBindingsFromCommand(event.type); if (!keyBindings.length) { // TODO: Consider indicating that this command lacks a binding. // TODO: Consider allowing the user to create a binding via a context menu. - return
    ; + return _react.createElement('div', null); } const firstBinding = keyBindings.length ? keyBindings[0] : ''; - const tooltip = addTooltip({ - title: humanizeEventName(event.type), + const tooltip = (0, (_addTooltip || _load_addTooltip()).default)({ + title: (0, (_humanizeEventName || _load_humanizeEventName()).default)(event.type), keyBindingCommand: event.type, placement: 'top', - keyBindingTarget: window.document.activeElement, + keyBindingTarget: window.document.activeElement }); return ( // eslint-disable-next-line nuclide-internal/jsx-simple-callback-refs -
    - - {firstBinding} - -
    + _react.createElement( + 'div', + { ref: tooltip }, + _react.createElement( + (_Icon || _load_Icon()).Icon, + { icon: 'keyboard' }, + _react.createElement( + 'span', + { style: { paddingLeft: '5px' } }, + firstBinding + ) + ) + ) ); } - componentWillUnmount(): void { + componentWillUnmount() { this._disposables.dispose(); } - _handleWillDispatch = (event: Event) => { - // We don't care about events dispatched by other events. - if (!this._areProcessingUserEvent) { - this._areProcessingUserEvent = true; - // If they are already using the keyboard, they don't need our advice. - // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - if (event.originalEvent instanceof KeyboardEvent) { - this.setState({event: null}); - } else { - this.setState({event}); - } - // Nested events are handled within a single event loop. By handling only - // the first event of a given loop, we approximate only responding to user - // instigated events. - setImmediate(this._userEventComplete); - } - }; - - _userEventComplete = () => { - this._areProcessingUserEvent = false; - }; } +exports.default = KeyBindingHint; \ No newline at end of file diff --git a/pkg/nuclide-key-binding-hint-status/lib/main.js b/pkg/nuclide-key-binding-hint-status/lib/main.js index c1b7543618..0ff3aa7b02 100644 --- a/pkg/nuclide-key-binding-hint-status/lib/main.js +++ b/pkg/nuclide-key-binding-hint-status/lib/main.js @@ -1,3 +1,31 @@ +'use strict'; + +var _react = _interopRequireWildcard(require('react')); + +var _reactDom = _interopRequireDefault(require('react-dom')); + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _KeyBindingHint; + +function _load_KeyBindingHint() { + return _KeyBindingHint = _interopRequireDefault(require('./KeyBindingHint')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,32 +33,29 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ const STATUS_BAR_PRIORITY = 500; // TODO: Allow the user to toggle this feature. -import invariant from 'assert'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import KeyBindingHint from './KeyBindingHint'; + class Activation { - _disposables: UniversalDisposable; - _statusNode: ?HTMLElement; - constructor(state: ?mixed) { + constructor(state) { this._statusNode = document.createElement('div'); this._statusNode.classList.add('inline-block', 'text'); - invariant(this._statusNode); - ReactDOM.render(, this._statusNode); - this._disposables = new UniversalDisposable(() => { - ReactDOM.unmountComponentAtNode(this._statusNode); + if (!this._statusNode) { + throw new Error('Invariant violation: "this._statusNode"'); + } + + _reactDom.default.render(_react.createElement((_KeyBindingHint || _load_KeyBindingHint()).default, null), this._statusNode); + + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { + _reactDom.default.unmountComponentAtNode(this._statusNode); this._statusNode = null; }); } @@ -38,7 +63,7 @@ class Activation { consumeStatusBar(statusBar) { const keyBindingStatusBar = statusBar.addLeftTile({ item: this._statusNode, - priority: STATUS_BAR_PRIORITY, + priority: STATUS_BAR_PRIORITY }); this._disposables.add(() => { @@ -46,9 +71,9 @@ class Activation { }); } - dispose(): void { + dispose() { this._disposables.dispose(); } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-language-hack/spec/fixtures/syntax_test_hack_generics.php b/pkg/nuclide-language-hack/spec/fixtures/syntax_test_hack_generics.php deleted file mode 100644 index 88183e0887..0000000000 --- a/pkg/nuclide-language-hack/spec/fixtures/syntax_test_hack_generics.php +++ /dev/null @@ -1,59 +0,0 @@ -// SYNTAX TEST "text.html.hack" -(bool $flag) { -// <- storage.type.function.php -// ^^^^^^^^^ entity.name.function.php -// ^^^ meta.generics.php -// ^ storage.type.php -} - -function nested, TVector>>(bool $flag) { -// <- storage.type.function.php -// ^^^^^^ entity.name.function.php -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.generics.php -// ^^^^^^ ^^^^ ^^ ^^ ^^^^^^^ ^^ storage.type.php -} - -function constrained(bool $flag) { -// <- storage.type.function.php -// ^^^^^^^^^^^ entity.name.function.php -// ^^^^^^^^^^ meta.generics.php -// ^^^^^^^^ storage.type.php -} - -function constrained(bool $flag) { -// <- storage.type.function.php -// ^^^^^^^^^^^ entity.name.function.php -// ^^^^^^^^^^^^^^^^ meta.generics.php -// ^^^^^^^^^^^^^^ storage.type.php -} - -function something<+T, -Ta>(bool $flag) { -// <- storage.type.function.php -// ^^^^^^^^^ entity.name.function.php -// ^^^^^^^^^ meta.generics.php -// ^^ ^^^ storage.type.php -} - -class Something<+T, -Ta> { -// <- storage.type.class.php -// ^^^^^^^^^ entity.name.type.class.php -// ^^^^^^^^^ meta.generics.php -// ^^ ^^^ storage.type.php -} - -trait Something<+T, -Ta> { -// <- storage.type.trait.php -// ^^^^^^^^^ entity.name.type.class.php -// ^^^^^^^^^ meta.generics.php -// ^^ ^^^ storage.type.php -} - -interface Something<+T, -Ta> extends Another, YetAnother { -// <- storage.type.interface.php -// ^^^^^^^^^ ^^^^^^^ ^^^^^^^^^^ entity.name.type.class.php -// ^^^^^^^^^ ^^^ ^^^^ meta.generics.php -// ^^ ^^^ ^ ^^ storage.type.php -// ^^^^^^^ storage.modifier.extends.php -} diff --git a/pkg/nuclide-language-hack/spec/fixtures/syntax_test_hack_operators.php b/pkg/nuclide-language-hack/spec/fixtures/syntax_test_hack_operators.php deleted file mode 100644 index 2b2a54f536..0000000000 --- a/pkg/nuclide-language-hack/spec/fixtures/syntax_test_hack_operators.php +++ /dev/null @@ -1,15 +0,0 @@ -// SYNTAX TEST "text.html.hack" - $b; -// ^^ keyword.operator.class.php -$r = dict[$a => $b]; -// ^^ keyword.operator.key.php -$r = $a ==> $b; -// ^^^ keyword.operator.lambda.php -$r = $a |> $b; -// ^^ keyword.operator.pipe.php diff --git a/pkg/nuclide-language-hack/spec/fixtures/syntax_test_hack_typedecl.php b/pkg/nuclide-language-hack/spec/fixtures/syntax_test_hack_typedecl.php deleted file mode 100644 index b2149bdfb9..0000000000 --- a/pkg/nuclide-language-hack/spec/fixtures/syntax_test_hack_typedecl.php +++ /dev/null @@ -1,21 +0,0 @@ -// SYNTAX TEST "text.html.hack" - = Something>>; -// <- storage.type.typedecl.php -// ^^^^^^^^^^^^ entity.name.type.typedecl -// ^^^^^^^^^^^ meta.generics.php -// ^ keyword.operator.assignment.php -// ^ punctuation.termination.expression.php - -type TFuncType = (function(int):int); -// <- storage.type.typedecl.php -// ^^^^^^^^^ entity.name.type.typedecl -// ^ keyword.operator.assignment.php -// ^ punctuation.termination.expression.php diff --git a/pkg/nuclide-language-hack/spec/fixtures/syntax_test_hack_typing.php b/pkg/nuclide-language-hack/spec/fixtures/syntax_test_hack_typing.php deleted file mode 100644 index cf7d17a7c1..0000000000 --- a/pkg/nuclide-language-hack/spec/fixtures/syntax_test_hack_typing.php +++ /dev/null @@ -1,210 +0,0 @@ -// SYNTAX TEST "text.html.hack" - { - // ^ punctuation.definition.type.php - // ^ support.class.php - // ^ support.class.php - // ^ storage.type.php - // ^ punctuation.section.scope.begin.php -} - -interface ISomething { - - function example(): void; - // ^ punctuation.definition.type.php - // ^ support.class.php - // ^ punctuation.terminator.expression.php - function example2(): void; - // ^ punctuation.definition.type.php - // ^ support.class.php - // ^ punctuation.terminator.expression.php -} - -function exampleWithDefaultParameters( - URI $href_uri, - ?Something $filter = null, - // ^ support.class.php - // ^ keyword.operator.assignment.php - // ^^^^ constant.language.php - // ^ meta.function.arguments.php - bool $notfilter = false, - // ^ storage.type.php - // ^ keyword.operator.assignment.php - // ^^^^^ constant.language.php - // ^ meta.function.arguments.php - SomeEnum $mode = SomeEnum::NORMAL, - // ^ support.class.php - // ^ keyword.operator.assignment.php - // ^^^^^^^^ support.class.php - // ^^^^^^ constant.other.class.php - // ^ meta.function.arguments.php -): void { - -} - -function f($x) { - // ^ punctuation.definition.variable - // ^ variable.other.php -} - -function f($x = 5) { - // ^ keyword.operator.assignment - // ^ constant.numeric.php -} - -function f($x = []) { - // ^ keyword.operator.assignment - // ^ punctuation.section.array.begin - // ^ punctuation.section.array.end -} - -function f(int $x = 5) { - // ^ keyword.operator.assignment - // ^ constant.numeric.php -} - -function f(array $x = []) { - // ^ keyword.operator.assignment - // ^ punctuation.section.array.begin - // ^ punctuation.section.array.end -} - -function f($x, $y) { - // ^ punctuation.definition.variable - // ^ variable.other.php - // ^ punctuation.definition.variable - // ^ variable.other.php -} - -function f(array $x): void { - // ^^^^^ storage.type.array.php -} - -function f( array $x): void { - // ^^^^^ storage.type.array.php -} - -function f(array $x, array $y): void { - // ^^^^^ storage.type.array.php -} - -function f(int $x): void { - // ^^^ storage.type.php -} - -function f(int $x, shape('vc' => int) $y): shape('vc' => int) { - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.arguments.php -} - -function f(int $x, shape('vc' => int) $y): shape('vc' => int) { - // ^^^^^^^^^^^^^^^^^^ storage.type.shape.php -} - -function f(int $x, shape('vc' => int) $y): shape('vc' => int) { - // ^ punctuation.definition.string.begin.php - // ^^ meta.string-contents.quoted.single.php - // ^ punctuation.definition.string.end.php - // ^^ .keyword.operator.key.php - // ^^^ .storage.type.php -} - -function f(int $x, shape('vc' => int) $y): shape('vc' => int) { - // ^ punctuation.definition.variable - // ^ variable.other.php -} - -function f(int $x, shape('vc' => int) $y): shape('vc' => int) { - // ^^^^^^^^^^^^^^^^^^ storage.type.shape.php -} - -function f(int $x, shape('vc' => int) $y): shape('vc' => int) { - // ^ punctuation.definition.string.begin.php - // ^^ meta.string-contents.quoted.single.php - // ^ punctuation.definition.string.end.php - // ^^ .keyword.operator.key.php - // ^^^ .storage.type.php -} - -function f(): shape('vc' => shape('vc' => int)) { - // ^^^^^^^^^^^^^^^^^^ storage.type.shape.php - // ^ punctuation.definition.string.begin.php - // ^^ meta.string-contents.quoted.single.php - // ^ punctuation.definition.string.end.php - // ^^ .keyword.operator.key.php - // ^^^ .storage.type.php -} - -function f(): { - $n = Foo\bar($test); - // ^^^ entity.name.type.namespace.php - // ^ punctuation.separator.inheritance.php - // ^^^ entity.name.function.php - - $n = Foo\Bar\Test\fn($t); - // ^^^ entity.name.type.namespace.php - // ^ punctuation.separator.inheritance.php - // ^^^ entity.name.type.namespace.php - // ^ punctuation.separator.inheritance.php - // ^^^^ entity.name.type.namespace.php - // ^ punctuation.separator.inheritance.php - // ^^ entity.name.function.php -} - -function f(): shape(...) { - // ^^^^^^^^^^ storage.type.shape.php -} - -class Something { - public static function f(int $x, shape('vc' => int) $y): shape('vc' => int) { - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.arguments.php - } - - public static function f(int $x, shape('vc' => int) $y): shape('vc' => int) { - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.arguments.php - } -} - -function f(int $x, dict $y): void { - // ^^^^ support.class.php -} - -function f((bool, int, ?int) $y): void { - // ^^^^ storage.type.php - // ^ punctuation.definition.variable - // ^ variable.other.php -} - -function f(int $x, (int, ?int) $y): void { - // ^^^ storage.type.php - // ^^^ storage.type.php - // ^ punctuation.definition.variable - // ^ variable.other.php -} - -function f(int $x, dict $y): void { - // ^^^^ support.class.php - // ^^^ storage.type.php - // ^^^ storage.type.php - // ^ punctuation.definition.variable - // ^ variable.other.php -} - -function f(int $a, arraykey $b, keyarray $c, ints $d, lint $e): void { - // ^^^ storage.type.php - // ^^^^^^^^ support.class.php - // ^^^^^^^^ support.class.php - // ^^^^ support.class.php - // ^^^^ support.class.php -} - -function f(array $a, array $b, keyarray $c, arrays $d): void { - // ^^^^^ storage.type.array.php - // ^^^ storage.type.php - // ^^^^^ storage.type.array.php - // ^^^^ support.class.php - // ^^^^^^^^ support.class.php - // ^^^ storage.type.php - // ^^^^^^ support.class.php - // ^^^^ support.class.php -} diff --git a/pkg/nuclide-language-hack/spec/fixtures/syntax_test_xhp.php b/pkg/nuclide-language-hack/spec/fixtures/syntax_test_xhp.php deleted file mode 100644 index 688869acad..0000000000 --- a/pkg/nuclide-language-hack/spec/fixtures/syntax_test_xhp.php +++ /dev/null @@ -1,55 +0,0 @@ -// SYNTAX TEST "text.html.hack" - - // ^ entity.name.tag.open.xhp - // ^ entity.other.attribute-name.xhp - // ^ meta.embedded.expression.php punctuation.section.embedded.begin.xhp - // ^ constant.numeric - // ^ entity.other.attribute-name.xhp - // ^ string.quoted.double.php - - // <- punctuation.definition.tag.xhp - - // ^ comment.block.html punctuation.definition.comment.html - - - // ^ entity.name.tag.close.xhp - ); -} - -function exampleLiteralCollections() { - return ( - return - // ^ support.class.php - // ^ punctuation.section.array.begin.php - // ^ punctuation.section.array.end.php - // ^ punctuation.section.embedded.end.xhp - ); -} - -function exampleXHPBracketHighlighting() { - return ( - - { -// ^ punctuation.section.embedded.begin.xhp - - if (true) {} -// ^ punctuation.section.scope.begin.php -// ^ punctuation.section.scope.end.php - } -// ^ punctuation.section.embedded.end.xhp - - ) -} diff --git a/pkg/nuclide-language-hack/spec/hack-spec.js b/pkg/nuclide-language-hack/spec/hack-spec.js deleted file mode 100644 index c28711a39d..0000000000 --- a/pkg/nuclide-language-hack/spec/hack-spec.js +++ /dev/null @@ -1,1260 +0,0 @@ -/** - * 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 - */ - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import invariant from 'assert'; -import grammarTest from 'atom-grammar-test'; - -describe('PHP grammar', () => { - let grammar: atom$Grammar = (null: any); - - beforeEach(() => { - waitsForPromise(() => - atom.packages.activatePackage('nuclide-language-hack'), - ); - runs(() => { - const hackGrammar = atom.grammars.grammarForScopeName('text.html.hack'); - invariant(hackGrammar); - grammar = hackGrammar; - }); - }); - - it('parses the grammar', () => { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - expect(grammar.scopeName).toBe('text.html.hack'); - }); - - describe('operators', () => { - it('should tokenize = correctly', () => { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(' { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(' { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(' { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(' { - expect(grammar).toBeTruthy(); - if (!grammar) { - return; - } - const tokens = grammar.tokenizeLines(' { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(' { - expect(grammar).toBeTruthy(); - const inputs = [ - ' { - const tokens = grammar.tokenizeLines(input); - expect(tokens[1][5].scopes).toContain('string.unquoted.heredoc.php'); - expect(tokens[1][6].scopes).toContain('string.unquoted.heredoc.php'); - expect(tokens[1][6].scopes).toContain('keyword.operator.heredoc.php'); - // Interpolated variables should still be highlighted. - expect(tokens[2][2].scopes).toContain('variable.other.php'); - - // The middle 'EOTXT' should not be considered an operator since it - // doesn't end with a semicolon and newline. - expect(tokens[3][0].scopes).toContain('string.unquoted.heredoc.php'); - expect(tokens[3][0].scopes).not.toContain( - 'keyword.operator.heredoc.php', - ); - - // The last one does end with a semicolon, so it should be considered an - // operator. - expect(tokens[5][0].scopes).toContain('string.unquoted.heredoc.php'); - expect(tokens[5][0].scopes).toContain('keyword.operator.heredoc.php'); - }); - }); - - describe('combined operators', () => { - it('should tokenize += correctly', () => { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(' { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(' { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(' { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(' { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(' { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(' { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(' { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(' { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(' { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines('>= correctly', () => { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines('>= 2;'); - expect(tokens[1][0]).toEqual({ - value: '$', - scopes: [ - 'text.html.hack', - 'meta.embedded.block.php', - 'source.hack', - 'variable.other.php', - 'punctuation.definition.variable.php', - ], - }); - expect(tokens[1][1]).toEqual({ - value: 'test', - scopes: [ - 'text.html.hack', - 'meta.embedded.block.php', - 'source.hack', - 'variable.other.php', - ], - }); - expect(tokens[1][2]).toEqual({ - value: ' ', - scopes: ['text.html.hack', 'meta.embedded.block.php', 'source.hack'], - }); - expect(tokens[1][3]).toEqual({ - value: '>>=', - scopes: [ - 'text.html.hack', - 'meta.embedded.block.php', - 'source.hack', - 'keyword.operator.assignment.php', - ], - }); - expect(tokens[1][4]).toEqual({ - value: ' ', - scopes: ['text.html.hack', 'meta.embedded.block.php', 'source.hack'], - }); - expect(tokens[1][5]).toEqual({ - value: '2', - scopes: [ - 'text.html.hack', - 'meta.embedded.block.php', - 'source.hack', - 'constant.numeric.php', - ], - }); - expect(tokens[1][6]).toEqual({ - value: ';', - scopes: [ - 'text.html.hack', - 'meta.embedded.block.php', - 'source.hack', - 'punctuation.terminator.expression.php', - ], - }); - }); - - // eslint-disable-next-line jasmine/no-disabled-tests - xit('should tokenize namespace at the same line as { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(' { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(' { - const CLASS_WITH_MAGIC_METHOD = ` { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(CLASS_WITH_MAGIC_METHOD); - expect(tokens[2][7]).toEqual({ - value: '__get', - scopes: [ - 'text.html.hack', - 'meta.embedded.block.php', - 'source.hack', - 'meta.function.php', - 'support.function.magic.php', - ], - }); - }); - - it('recognizes magic methods with line breaks after the identifier', () => { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(CLASS_WITH_TRICKY_MAGIC_METHOD); - expect(tokens[2][7]).toEqual({ - value: '__get', - scopes: [ - 'text.html.hack', - 'meta.embedded.block.php', - 'source.hack', - 'meta.function.php', - 'support.function.magic.php', - ], - }); - }); - - it("recognizes when methods aren't magic methods (even though they're close)", () => { - expect(grammar).toBeTruthy(); - grammar = grammar || {}; - const tokens = grammar.tokenizeLines(CLASS_WITHOUT_MAGIC_METHOD); - expect(tokens[2][7]).toEqual({ - value: '__getSomething', - scopes: [ - 'text.html.hack', - 'meta.embedded.block.php', - 'source.hack', - 'meta.function.php', - 'entity.name.function.php', - ], - }); - }); - }); - - describe('lambda variable capturing', () => { - it('parses correctly without a return type', () => { - invariant(grammar != null); - const tokens = grammar.tokenizeLines(' token.value === 'use'); - expect(useToken).not.toBeUndefined(); - invariant(useToken != null); - expect(useToken.scopes).toContain('keyword.other.function.use.php'); - }); - - it('parses correctly with a return type', () => { - invariant(grammar != null); - const tokens = grammar.tokenizeLines( - ' token.value === 'use'); - expect(useToken).not.toBeUndefined(); - invariant(useToken != null); - expect(useToken.scopes).toContain('keyword.other.function.use.php'); - }); - - it("doesn't terminate the closure when there's a type annotation", () => { - invariant(grammar != null); - const tokens = grammar.tokenizeLines( - ' !token.scopes.includes('meta.function.closure.php')) - .map(token => token.value); - expect(nonClosureTokens.length).toBe( - 0, - `These tokens are missing the closure tag: ${nonClosureTokens.join( - ', ', - )}`, - ); - }); - }); - - describe('function typehints', () => { - it('terminates the function scope', () => { - invariant(grammar != null); - const tokens = grammar.tokenizeLines( - ' token.value === 'test'); - invariant(testToken != null); - expect(testToken.scopes).toContain('variable.other.php'); - }); - }); -}); diff --git a/pkg/nuclide-language-service-rpc/lib/HostServicesAggregator.js b/pkg/nuclide-language-service-rpc/lib/HostServicesAggregator.js index 75d03154e3..a1501c6d22 100644 --- a/pkg/nuclide-language-service-rpc/lib/HostServicesAggregator.js +++ b/pkg/nuclide-language-service-rpc/lib/HostServicesAggregator.js @@ -1,3 +1,21 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.forkHostServices = forkHostServices; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// This is how we declare in Flow that a type fulfills an interface. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,26 +23,14 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {ShowNotificationLevel, Progress, HostServices} from './rpc-types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {TextEdit} from 'nuclide-commons-atom/text-edit'; - -import invariant from 'assert'; -import {Subject, ConnectableObservable, Observable} from 'rxjs'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; +null; +null; -// This is how we declare in Flow that a type fulfills an interface. -(((null: any): HostServicesAggregator): HostServices); -(((null: any): HostServicesRelay): HostServices); - -export async function forkHostServices( - host: HostServices, - logger: log4js$Logger, -): Promise { +async function forkHostServices(host, logger) { const child = new HostServicesAggregator(); const howChildShouldRelayBackToHost = await host.childRegister(child); child.initialize(howChildShouldRelayBackToHost, logger); @@ -67,13 +73,12 @@ export async function forkHostServices( } class HostServicesAggregator { - _parent: HostServices; - _childRelays: Map = new Map(); - _counter: number = 0; - _logger: log4js$Logger; - _isDisposed: boolean = false; constructor() { + this._childRelays = new Map(); + this._counter = 0; + this._isDisposed = false; + // HostServiceAggregator objects are only ever constructed from forkHostServices: // 1. it calls the constructor (here) // 2. it calls parent.childRegister(child) @@ -82,72 +87,51 @@ class HostServicesAggregator { this._childRelays.set(0, relay); } - initialize(parent: HostServices, logger: log4js$Logger): void { + initialize(parent, logger) { this._parent = parent; this._logger = logger; } - _selfRelay(): HostServicesRelay { + _selfRelay() { const relay = this._childRelays.get(0); - invariant(relay != null); + + if (!(relay != null)) { + throw new Error('Invariant violation: "relay != null"'); + } + return relay; } - consoleNotification( - source: string, - level: ShowNotificationLevel, - text: string, - ): void { + consoleNotification(source, level, text) { this._selfRelay().consoleNotification(source, level, text); } - dialogNotification( - level: ShowNotificationLevel, - text: string, - ): ConnectableObservable { + dialogNotification(level, text) { return this._selfRelay().dialogNotification(level, text); } - applyTextEditsForMultipleFiles( - changes: Map>, - ): Promise { + applyTextEditsForMultipleFiles(changes) { return this._selfRelay().applyTextEditsForMultipleFiles(changes); } - dialogRequest( - level: ShowNotificationLevel, - text: string, - buttonLabels: Array, - closeLabel: string, - ): ConnectableObservable { - return this._selfRelay().dialogRequest( - level, - text, - buttonLabels, - closeLabel, - ); + dialogRequest(level, text, buttonLabels, closeLabel) { + return this._selfRelay().dialogRequest(level, text, buttonLabels, closeLabel); } - showProgress( - title: string, - options?: {|debounce?: boolean|}, - ): Promise { + showProgress(title, options) { return this._selfRelay().showProgress(title, options); } - showActionRequired( - title: string, - options?: {|clickable?: boolean|}, - ): ConnectableObservable { + showActionRequired(title, options) { return this._selfRelay().showActionRequired(title, options); } - isDisposed(): boolean { + isDisposed() { return this._isDisposed; } // Call 'dispose' to dispose of the aggregate and all its children - dispose(): void { + dispose() { // Guard against double-disposal (see below). if (this._isDisposed) { return; @@ -178,7 +162,7 @@ class HostServicesAggregator { } } - async childRegister(child: HostServices): Promise { + async childRegister(child) { // The code which has a HostServices object doesn't necessarily know that // its parent might have been disposed. And if it tries to fork, that // should still succeed and produce a disposed child HostServices object. @@ -194,22 +178,14 @@ class HostServicesAggregator { } class HostServicesRelay { - _aggregator: HostServicesAggregator; - _id: number; - // - _child: ?HostServices; // _childIsDisposed is consumed by using observable.takeUntil(_childIsDisposed), // which unsubscribes from 'obs' as soon as _childIsDisposed.next() gets // fired. It is signaled by calling _disposables.dispose(), which fires // the _childIsDisposed.next(). - _childIsDisposed: Subject = new Subject(); - _disposables: UniversalDisposable = new UniversalDisposable(); - - constructor( - aggregator: HostServicesAggregator, - id: number, - child: ?HostServices, - ) { + constructor(aggregator, id, child) { + this._childIsDisposed = new _rxjsBundlesRxMinJs.Subject(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._aggregator = aggregator; this._id = id; this._child = child; @@ -217,73 +193,48 @@ class HostServicesRelay { this._childIsDisposed.next(); }); } + // - consoleNotification( - source: string, - level: ShowNotificationLevel, - text: string, - ): void { + + consoleNotification(source, level, text) { if (this._aggregator.isDisposed()) { return; } this._aggregator._parent.consoleNotification(source, level, text); } - dialogNotification( - level: ShowNotificationLevel, - text: string, - ): ConnectableObservable { + dialogNotification(level, text) { if (this._aggregator.isDisposed()) { - return Observable.empty().publish(); + return _rxjsBundlesRxMinJs.Observable.empty().publish(); } - return this._aggregator._parent - .dialogNotification(level, text) - .refCount() - .takeUntil(this._childIsDisposed) - .publish(); + return this._aggregator._parent.dialogNotification(level, text).refCount().takeUntil(this._childIsDisposed).publish(); // If the host is disposed, then the ConnectedObservable we return will // complete without ever having emitted a value. If you .toPromise on it // your promise will complete successfully with value 'undefined'. } - dialogRequest( - level: ShowNotificationLevel, - text: string, - buttonLabels: Array, - closeLabel: string, - ): ConnectableObservable { + dialogRequest(level, text, buttonLabels, closeLabel) { if (this._aggregator.isDisposed()) { - return Observable.empty().publish(); + return _rxjsBundlesRxMinJs.Observable.empty().publish(); } - return this._aggregator._parent - .dialogRequest(level, text, buttonLabels, closeLabel) - .refCount() - .takeUntil(this._childIsDisposed) - .publish(); + return this._aggregator._parent.dialogRequest(level, text, buttonLabels, closeLabel).refCount().takeUntil(this._childIsDisposed).publish(); } - applyTextEditsForMultipleFiles( - changes: Map>, - ): Promise { + applyTextEditsForMultipleFiles(changes) { if (this._aggregator.isDisposed()) { return Promise.resolve(false); } return this._aggregator._parent.applyTextEditsForMultipleFiles(changes); } - async showProgress( - title: string, - options?: {|debounce?: boolean|}, - ): Promise { + async showProgress(title, options) { // TODO: this whole function would work better with CancellationToken, // particularly in the case where a HostAggregator is disposed after the // request has already been sent out to its parent. In the absence of // CancellationToken, we can't cancel the parent, and instead have to - // wait until it *displays* progress before immediately disposing it. - - const no_op: Progress = { + const no_op = { setTitle: _ => {}, - dispose: () => {}, + dispose: () => {} }; // If we're already disposed, then return a no-op wrapper. @@ -294,7 +245,7 @@ class HostServicesRelay { // Otherwise, we are going to make a request to our parent. const parentPromise = this._aggregator._parent.showProgress(title, options); const cancel = this._childIsDisposed.toPromise(); - let progress: ?Progress = await Promise.race([parentPromise, cancel]); + let progress = await Promise.race([parentPromise, cancel]); // Should a cancellation come while we're waiting for our parent, // then we'll immediately return a no-op wrapper and ensure that @@ -302,11 +253,7 @@ class HostServicesRelay { // The "or" check below is in case parentProgress returned something // but also either the parent aggregator or the child aggregator // were disposed. - if ( - progress == null || - this._aggregator.isDisposed() || - this._disposables.disposed - ) { + if (progress == null || this._aggregator.isDisposed() || this._disposables.disposed) { parentPromise.then(progress2 => progress2.dispose()); return no_op; } @@ -314,7 +261,7 @@ class HostServicesRelay { // Here our parent has already displayed 'winner'. It will be disposed // either when we ourselves get disposed, or when our caller disposes // of the wrapper we return them, whichever happens first. - const wrapper: Progress = { + const wrapper = { setTitle: title2 => { if (progress != null) { progress.setTitle(title2); @@ -326,27 +273,20 @@ class HostServicesRelay { progress.dispose(); progress = null; } - }, + } }; this._disposables.add(wrapper); return wrapper; } - showActionRequired( - title: string, - options?: {|clickable?: boolean|}, - ): ConnectableObservable { + showActionRequired(title, options) { if (this._aggregator.isDisposed()) { - return Observable.empty().publish(); + return _rxjsBundlesRxMinJs.Observable.empty().publish(); } - return this._aggregator._parent - .showActionRequired(title, options) - .refCount() - .takeUntil(this._childIsDisposed) - .publish(); + return this._aggregator._parent.showActionRequired(title, options).refCount().takeUntil(this._childIsDisposed).publish(); } - dispose(): void { + dispose() { if (!this._disposables.disposed) { // Remember, this is a notification relayed from one of the children that // it has just finished its "dispose" method. That's what a relay is. @@ -356,7 +296,9 @@ class HostServicesRelay { } } - childRegister(child: HostServices): Promise { - invariant(false, 'relay should never be asked to relay childRegister'); + childRegister(child) { + if (!false) { + throw new Error('relay should never be asked to relay childRegister'); + } } -} +} \ No newline at end of file diff --git a/pkg/nuclide-language-service-rpc/lib/MultiProjectLanguageService.js b/pkg/nuclide-language-service-rpc/lib/MultiProjectLanguageService.js index 20a20e1302..416d3b802c 100644 --- a/pkg/nuclide-language-service-rpc/lib/MultiProjectLanguageService.js +++ b/pkg/nuclide-language-service-rpc/lib/MultiProjectLanguageService.js @@ -1,68 +1,72 @@ -/** - * 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 - */ +'use strict'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {DeadlineRequest} from 'nuclide-commons/promise'; -import type {SearchStrategy} from 'nuclide-commons/ConfigCache'; -import type {AdditionalLogFile} from '../../nuclide-logging/lib/rpc-types'; -import type {FileVersion} from '../../nuclide-open-files-rpc/lib/rpc-types'; -import type {TextEdit} from 'nuclide-commons-atom/text-edit'; -import type {TypeHint} from '../../nuclide-type-hint/lib/rpc-types'; -import type {CoverageResult} from '../../nuclide-type-coverage/lib/rpc-types'; -import type { - DefinitionQueryResult, - FindReferencesReturn, - Outline, - CodeAction, - SignatureHelp, -} from 'atom-ide-ui'; -import type { - AutocompleteRequest, - AutocompleteResult, - FileDiagnosticMap, - FileDiagnosticMessage, - FormatOptions, - LanguageService, - SymbolResult, - Completion, - CodeLensData, - StatusData, -} from '../../nuclide-language-service/lib/LanguageService'; -import type {HostServices} from '../../nuclide-language-service-rpc/lib/rpc-types'; -import type {ConnectableObservable} from 'rxjs'; - -import invariant from 'assert'; -import {timeoutAfterDeadline} from 'nuclide-commons/promise'; -import {stringifyError} from 'nuclide-commons/string'; -import {FileCache, ConfigObserver} from '../../nuclide-open-files-rpc'; -import {Cache} from 'nuclide-commons/cache'; -import {Observable} from 'rxjs'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {compact} from 'nuclide-commons/observable'; -import {arrayCompact, arrayFlatten, collect} from 'nuclide-commons/collection'; -import {ConfigCache} from 'nuclide-commons/ConfigCache'; -import {ensureInvalidations, NullLanguageService} from '..'; - -export class MultiProjectLanguageService { - // Maps project dir => LanguageService - _processes: Cache>; - _resources: UniversalDisposable; - _configCache: ConfigCache; - _logger: log4js$Logger; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.MultiProjectLanguageService = undefined; + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _string; + +function _load_string() { + return _string = require('../../../modules/nuclide-commons/string'); +} + +var _nuclideOpenFilesRpc; + +function _load_nuclideOpenFilesRpc() { + return _nuclideOpenFilesRpc = require('../../nuclide-open-files-rpc'); +} + +var _cache; + +function _load_cache() { + return _cache = require('../../../modules/nuclide-commons/cache'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _observable; + +function _load_observable() { + return _observable = require('../../../modules/nuclide-commons/observable'); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _ConfigCache; + +function _load_ConfigCache() { + return _ConfigCache = require('../../../modules/nuclide-commons/ConfigCache'); +} + +var _; + +function _load_() { + return _ = require('..'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class MultiProjectLanguageService { // Promises for when AtomLanguageService has called into this feature - _observeDiagnosticsPromise: Promise; - _observeDiagnosticsPromiseResolver: () => void; - _observeStatusPromise: Promise; - _observeStatusPromiseResolver: () => void; + // Maps project dir => LanguageService constructor() { this._observeDiagnosticsPromise = new Promise((resolve, reject) => { this._observeDiagnosticsPromiseResolver = resolve; @@ -72,23 +76,12 @@ export class MultiProjectLanguageService { }); } - initialize( - logger: log4js$Logger, - fileCache: FileCache, - host: HostServices, - projectFileNames: Array, - projectFileSearchStrategy: ?SearchStrategy, - fileExtensions: Array, - languageServiceFactory: (projectDir: NuclideUri) => Promise, - ) { + initialize(logger, fileCache, host, projectFileNames, projectFileSearchStrategy, fileExtensions, languageServiceFactory) { this._logger = logger; - this._resources = new UniversalDisposable(); - this._configCache = new ConfigCache( - projectFileNames, - projectFileSearchStrategy != null ? projectFileSearchStrategy : undefined, - ); + this._resources = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._configCache = new (_ConfigCache || _load_ConfigCache()).ConfigCache(projectFileNames, projectFileSearchStrategy != null ? projectFileSearchStrategy : undefined); - this._processes = new Cache(languageServiceFactory, value => { + this._processes = new (_cache || _load_cache()).Cache(languageServiceFactory, value => { value.then(process => { if (process != null) { process.dispose(); @@ -99,72 +92,50 @@ export class MultiProjectLanguageService { this._resources.add(host, this._processes); // Observe projects as they are opened - const configObserver = new ConfigObserver( - fileCache, - fileExtensions, - filePath => this._configCache.getConfigDir(filePath), - ); - this._resources.add( - configObserver, - configObserver.observeConfigs().subscribe(configs => { - this._ensureProcesses(configs); - }), - ); + const configObserver = new (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).ConfigObserver(fileCache, fileExtensions, filePath => this._configCache.getConfigDir(filePath)); + this._resources.add(configObserver, configObserver.observeConfigs().subscribe(configs => { + this._ensureProcesses(configs); + })); this._resources.add(() => { this._closeProcesses(); }); // Remove fileCache when the remote connection shuts down - this._resources.add( - fileCache - .observeFileEvents() - .ignoreElements() - .subscribe( - undefined, // next - undefined, // error - () => { - this._logger.info('fileCache shutting down.'); - this._closeProcesses(); - }, - ), - ); - } - - findProjectDir(filePath: NuclideUri): Promise { + this._resources.add(fileCache.observeFileEvents().ignoreElements().subscribe(undefined, // next + undefined, // error + () => { + this._logger.info('fileCache shutting down.'); + this._closeProcesses(); + })); + } + + findProjectDir(filePath) { return this._configCache.getConfigDir(filePath); } - async _getLanguageServiceForFile(filePath: string): Promise { + async _getLanguageServiceForFile(filePath) { const service = await this.getLanguageServiceForFile(filePath); if (service != null) { return service; } else { - return new NullLanguageService(); + return new (_ || _load_()).NullLanguageService(); } } - async _getLanguageServicesForFiles( - filePaths: Array, - ): Promise]>> { - const promises: Array> = filePaths.map( - async filePath => { - const service = await this._getLanguageServiceForFile(filePath); - return service ? [service, filePath] : null; - }, - ); + async _getLanguageServicesForFiles(filePaths) { + const promises = filePaths.map(async filePath => { + const service = await this._getLanguageServiceForFile(filePath); + return service ? [service, filePath] : null; + }); - const fileServices: Array = await Promise.all( - promises, - ); + const fileServices = await Promise.all(promises); - const results: Map> = collect( - arrayCompact(fileServices), - ); + const results = (0, (_collection || _load_collection()).collect)((0, (_collection || _load_collection()).arrayCompact)(fileServices)); return Array.from(results); } - async getLanguageServiceForFile(filePath: string): Promise { + async getLanguageServiceForFile(filePath) { const projectDir = await this.findProjectDir(filePath); if (projectDir == null) { return null; @@ -184,342 +155,200 @@ export class MultiProjectLanguageService { // for the given configPaths. // Closes all LanguageServices not in configPaths, and starts // new LanguageServices for any paths in configPaths. - _ensureProcesses(configPaths: Set): void { - this._logger.info( - `MultiProjectLanguageService ensureProcesses. ${Array.from( - configPaths, - ).join(', ')}`, - ); + _ensureProcesses(configPaths) { + this._logger.info(`MultiProjectLanguageService ensureProcesses. ${Array.from(configPaths).join(', ')}`); this._processes.setKeys(configPaths); } // Closes all LanguageServices for this fileCache. - _closeProcesses(): void { - this._logger.info( - 'Shutting down LanguageServices ' + - `${Array.from(this._processes.keys()).join(',')}`, - ); + _closeProcesses() { + this._logger.info('Shutting down LanguageServices ' + `${Array.from(this._processes.keys()).join(',')}`); this._processes.clear(); } - observeLanguageServices(): Observable { + observeLanguageServices() { this._logger.info('observing connections'); - return compact( - this._processes - .observeValues() - .switchMap(process => Observable.fromPromise(process)), - ); + return (0, (_observable || _load_observable()).compact)(this._processes.observeValues().switchMap(process => _rxjsBundlesRxMinJs.Observable.fromPromise(process))); } - async getAllLanguageServices(): Promise> { - const lsPromises: Array> = [...this._processes.values()]; - return arrayCompact(await Promise.all(lsPromises)); + async getAllLanguageServices() { + const lsPromises = [...this._processes.values()]; + return (0, (_collection || _load_collection()).arrayCompact)((await Promise.all(lsPromises))); } - async getDiagnostics(fileVersion: FileVersion): Promise { - return (await this._getLanguageServiceForFile( - fileVersion.filePath, - )).getDiagnostics(fileVersion); + async getDiagnostics(fileVersion) { + return (await this._getLanguageServiceForFile(fileVersion.filePath)).getDiagnostics(fileVersion); } - hasObservedDiagnostics(): Promise { + hasObservedDiagnostics() { return this._observeDiagnosticsPromise; } - observeDiagnostics(): ConnectableObservable { + observeDiagnostics() { this._observeDiagnosticsPromiseResolver(); - return this.observeLanguageServices() - .mergeMap((process: LanguageService) => { - this._logger.trace('observeDiagnostics'); - return ensureInvalidations( - this._logger, - process - .observeDiagnostics() - .refCount() - .catch(error => { - this._logger.error('Error: observeDiagnostics', error); - return Observable.empty(); - }), - ); - }) - .publish(); - } - - hasObservedStatus(): Promise { + return this.observeLanguageServices().mergeMap(process => { + this._logger.trace('observeDiagnostics'); + return (0, (_ || _load_()).ensureInvalidations)(this._logger, process.observeDiagnostics().refCount().catch(error => { + this._logger.error('Error: observeDiagnostics', error); + return _rxjsBundlesRxMinJs.Observable.empty(); + })); + }).publish(); + } + + hasObservedStatus() { return this._observeStatusPromise; } - observeStatus(fileVersion: FileVersion): ConnectableObservable { + observeStatus(fileVersion) { this._observeStatusPromiseResolver(); - return Observable.fromPromise( - this._getLanguageServiceForFile(fileVersion.filePath), - ) - .flatMap(ls => ls.observeStatus(fileVersion).refCount()) - .publish(); - } - - async clickStatus( - fileVersion: FileVersion, - id: string, - button: string, - ): Promise { - return (await this._getLanguageServiceForFile( - fileVersion.filePath, - )).clickStatus(fileVersion, id, button); - } - - async getAutocompleteSuggestions( - fileVersion: FileVersion, - position: atom$Point, - request: AutocompleteRequest, - ): Promise { - return (await this._getLanguageServiceForFile( - fileVersion.filePath, - )).getAutocompleteSuggestions(fileVersion, position, request); - } - - async resolveAutocompleteSuggestion( - suggestion: Completion, - ): Promise { - invariant( - suggestion.remoteUri != null, - 'remoteUri for autocomplete resolution should have been set by AutocompleteProvider.', - ); + return _rxjsBundlesRxMinJs.Observable.fromPromise(this._getLanguageServiceForFile(fileVersion.filePath)).flatMap(ls => ls.observeStatus(fileVersion).refCount()).publish(); + } + + async clickStatus(fileVersion, id, button) { + return (await this._getLanguageServiceForFile(fileVersion.filePath)).clickStatus(fileVersion, id, button); + } + + async getAutocompleteSuggestions(fileVersion, position, request) { + return (await this._getLanguageServiceForFile(fileVersion.filePath)).getAutocompleteSuggestions(fileVersion, position, request); + } + + async resolveAutocompleteSuggestion(suggestion) { + if (!(suggestion.remoteUri != null)) { + throw new Error('remoteUri for autocomplete resolution should have been set by AutocompleteProvider.'); + } // We're running this "locally" (from RPC point of view), so strip remote // URIs and just take the path. - const languageService = await this._getLanguageServiceForFile( - suggestion.remoteUri, - ); + + + const languageService = await this._getLanguageServiceForFile(suggestion.remoteUri); return languageService.resolveAutocompleteSuggestion(suggestion); } - async getDefinition( - fileVersion: FileVersion, - position: atom$Point, - ): Promise { - return (await this._getLanguageServiceForFile( - fileVersion.filePath, - )).getDefinition(fileVersion, position); - } - - findReferences( - fileVersion: FileVersion, - position: atom$Point, - ): ConnectableObservable { - return Observable.fromPromise( - this._getLanguageServiceForFile(fileVersion.filePath), - ) - .concatMap(ls => ls.findReferences(fileVersion, position).refCount()) - .publish(); - } - - async getCoverage(filePath: NuclideUri): Promise { - return (await this._getLanguageServiceForFile(filePath)).getCoverage( - filePath, - ); - } - - async onToggleCoverage(set: boolean): Promise { - await Promise.all( - (await this.getAllLanguageServices()).map(async languageService => { - const ls = await languageService; - ls.onToggleCoverage(set); - }), - ); - } - - async getOutline(fileVersion: FileVersion): Promise { - return (await this._getLanguageServiceForFile( - fileVersion.filePath, - )).getOutline(fileVersion); - } - - async getCodeLens(fileVersion: FileVersion): Promise> { - return (await this._getLanguageServiceForFile( - fileVersion.filePath, - )).getCodeLens(fileVersion); - } - - async resolveCodeLens( - filePath: NuclideUri, - codeLens: CodeLensData, - ): Promise { - return (await this._getLanguageServiceForFile(filePath)).resolveCodeLens( - filePath, - codeLens, - ); - } - - async getAdditionalLogFiles( - deadline: DeadlineRequest, - ): Promise> { - const roots: Array = Array.from(this._processes.keys()); - - const results = await Promise.all( - roots.map(async root => { - try { - const service = await timeoutAfterDeadline( - deadline, - this._processes.get(root), - ); - if (service == null) { - return [{title: root, data: 'no language service'}]; - } else { - return timeoutAfterDeadline( - deadline, - service.getAdditionalLogFiles(deadline - 1000), - ); - } - } catch (e) { - return [{title: root, data: stringifyError(e)}]; + async getDefinition(fileVersion, position) { + return (await this._getLanguageServiceForFile(fileVersion.filePath)).getDefinition(fileVersion, position); + } + + findReferences(fileVersion, position) { + return _rxjsBundlesRxMinJs.Observable.fromPromise(this._getLanguageServiceForFile(fileVersion.filePath)).concatMap(ls => ls.findReferences(fileVersion, position).refCount()).publish(); + } + + async getCoverage(filePath) { + return (await this._getLanguageServiceForFile(filePath)).getCoverage(filePath); + } + + async onToggleCoverage(set) { + await Promise.all((await this.getAllLanguageServices()).map(async languageService => { + const ls = await languageService; + ls.onToggleCoverage(set); + })); + } + + async getOutline(fileVersion) { + return (await this._getLanguageServiceForFile(fileVersion.filePath)).getOutline(fileVersion); + } + + async getCodeLens(fileVersion) { + return (await this._getLanguageServiceForFile(fileVersion.filePath)).getCodeLens(fileVersion); + } + + async resolveCodeLens(filePath, codeLens) { + return (await this._getLanguageServiceForFile(filePath)).resolveCodeLens(filePath, codeLens); + } + + async getAdditionalLogFiles(deadline) { + const roots = Array.from(this._processes.keys()); + + const results = await Promise.all(roots.map(async root => { + try { + const service = await (0, (_promise || _load_promise()).timeoutAfterDeadline)(deadline, this._processes.get(root)); + if (service == null) { + return [{ title: root, data: 'no language service' }]; + } else { + return (0, (_promise || _load_promise()).timeoutAfterDeadline)(deadline, service.getAdditionalLogFiles(deadline - 1000)); } - }), - ); - return arrayFlatten(results); - } - - async getCodeActions( - fileVersion: FileVersion, - range: atom$Range, - diagnostics: Array, - ): Promise> { - return (await this._getLanguageServiceForFile( - fileVersion.filePath, - )).getCodeActions(fileVersion, range, diagnostics); - } - - async typeHint( - fileVersion: FileVersion, - position: atom$Point, - ): Promise { - return (await this._getLanguageServiceForFile( - fileVersion.filePath, - )).typeHint(fileVersion, position); - } - - async highlight( - fileVersion: FileVersion, - position: atom$Point, - ): Promise> { - return (await this._getLanguageServiceForFile( - fileVersion.filePath, - )).highlight(fileVersion, position); - } - - async formatSource( - fileVersion: FileVersion, - range: atom$Range, - options: FormatOptions, - ): Promise> { - return (await this._getLanguageServiceForFile( - fileVersion.filePath, - )).formatSource(fileVersion, range, options); - } - - async formatEntireFile( - fileVersion: FileVersion, - range: atom$Range, - options: FormatOptions, - ): Promise { - return (await this._getLanguageServiceForFile( - fileVersion.filePath, - )).formatEntireFile(fileVersion, range, options); - } - - async formatAtPosition( - fileVersion: FileVersion, - position: atom$Point, - triggerCharacter: string, - options: FormatOptions, - ): Promise> { - return (await this._getLanguageServiceForFile( - fileVersion.filePath, - )).formatAtPosition(fileVersion, position, triggerCharacter, options); - } - - async signatureHelp( - fileVersion: FileVersion, - position: atom$Point, - ): Promise { - return (await this._getLanguageServiceForFile( - fileVersion.filePath, - )).signatureHelp(fileVersion, position); - } - - async supportsSymbolSearch(directories: Array): Promise { - const serviceDirectories = await this._getLanguageServicesForFiles( - directories, - ); - const eligibilities = await Promise.all( - serviceDirectories.map(([service, dirs]) => - service.supportsSymbolSearch(dirs), - ), - ); + } catch (e) { + return [{ title: root, data: (0, (_string || _load_string()).stringifyError)(e) }]; + } + })); + return (0, (_collection || _load_collection()).arrayFlatten)(results); + } + + async getCodeActions(fileVersion, range, diagnostics) { + return (await this._getLanguageServiceForFile(fileVersion.filePath)).getCodeActions(fileVersion, range, diagnostics); + } + + async typeHint(fileVersion, position) { + return (await this._getLanguageServiceForFile(fileVersion.filePath)).typeHint(fileVersion, position); + } + + async highlight(fileVersion, position) { + return (await this._getLanguageServiceForFile(fileVersion.filePath)).highlight(fileVersion, position); + } + + async formatSource(fileVersion, range, options) { + return (await this._getLanguageServiceForFile(fileVersion.filePath)).formatSource(fileVersion, range, options); + } + + async formatEntireFile(fileVersion, range, options) { + return (await this._getLanguageServiceForFile(fileVersion.filePath)).formatEntireFile(fileVersion, range, options); + } + + async formatAtPosition(fileVersion, position, triggerCharacter, options) { + return (await this._getLanguageServiceForFile(fileVersion.filePath)).formatAtPosition(fileVersion, position, triggerCharacter, options); + } + + async signatureHelp(fileVersion, position) { + return (await this._getLanguageServiceForFile(fileVersion.filePath)).signatureHelp(fileVersion, position); + } + + async supportsSymbolSearch(directories) { + const serviceDirectories = await this._getLanguageServicesForFiles(directories); + const eligibilities = await Promise.all(serviceDirectories.map(([service, dirs]) => service.supportsSymbolSearch(dirs))); return eligibilities.some(e => e); } - async symbolSearch( - query: string, - directories: Array, - ): Promise> { + async symbolSearch(query, directories) { if (query.length === 0) { return []; } - const serviceDirectories = await this._getLanguageServicesForFiles( - directories, - ); - const results = await Promise.all( - serviceDirectories.map(([service, dirs]) => - service.symbolSearch(query, dirs), - ), - ); - return arrayFlatten(arrayCompact(results)); - } - - async getProjectRoot(filePath: NuclideUri): Promise { - return (await this._getLanguageServiceForFile(filePath)).getProjectRoot( - filePath, - ); - } - - async isFileInProject(filePath: NuclideUri): Promise { - return (await this._getLanguageServiceForFile(filePath)).isFileInProject( - filePath, - ); - } - - async getExpandedSelectionRange( - fileVersion: FileVersion, - currentSelection: atom$Range, - ): Promise { - return (await this._getLanguageServiceForFile( - fileVersion.filePath, - )).getExpandedSelectionRange(fileVersion, currentSelection); - } - - async getCollapsedSelectionRange( - fileVersion: FileVersion, - currentSelection: atom$Range, - originalCursorPosition: atom$Point, - ): Promise { - return (await this._getLanguageServiceForFile( - fileVersion.filePath, - )).getCollapsedSelectionRange( - fileVersion, - currentSelection, - originalCursorPosition, - ); - } - - dispose(): void { + const serviceDirectories = await this._getLanguageServicesForFiles(directories); + const results = await Promise.all(serviceDirectories.map(([service, dirs]) => service.symbolSearch(query, dirs))); + return (0, (_collection || _load_collection()).arrayFlatten)((0, (_collection || _load_collection()).arrayCompact)(results)); + } + + async getProjectRoot(filePath) { + return (await this._getLanguageServiceForFile(filePath)).getProjectRoot(filePath); + } + + async isFileInProject(filePath) { + return (await this._getLanguageServiceForFile(filePath)).isFileInProject(filePath); + } + + async getExpandedSelectionRange(fileVersion, currentSelection) { + return (await this._getLanguageServiceForFile(fileVersion.filePath)).getExpandedSelectionRange(fileVersion, currentSelection); + } + + async getCollapsedSelectionRange(fileVersion, currentSelection, originalCursorPosition) { + return (await this._getLanguageServiceForFile(fileVersion.filePath)).getCollapsedSelectionRange(fileVersion, currentSelection, originalCursorPosition); + } + + dispose() { this._resources.dispose(); } } -// Enforces that an instance of MultiProjectLanguageService satisfies the LanguageService type -(((null: any): MultiProjectLanguageService<>): LanguageService); +exports.MultiProjectLanguageService = MultiProjectLanguageService; // Enforces that an instance of MultiProjectLanguageService satisfies the LanguageService type +/** + * 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. + * + * + * @format + */ + +null; \ No newline at end of file diff --git a/pkg/nuclide-language-service-rpc/lib/NullLanguageService.js b/pkg/nuclide-language-service-rpc/lib/NullLanguageService.js index fc4ee1b1b5..fa9ecde050 100644 --- a/pkg/nuclide-language-service-rpc/lib/NullLanguageService.js +++ b/pkg/nuclide-language-service-rpc/lib/NullLanguageService.js @@ -1,210 +1,134 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.NullLanguageService = undefined; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {DeadlineRequest} from 'nuclide-commons/promise'; -import type {AdditionalLogFile} from '../../nuclide-logging/lib/rpc-types'; -import type {FileVersion} from '../../nuclide-open-files-rpc/lib/rpc-types'; -import type {TextEdit} from 'nuclide-commons-atom/text-edit'; -import type {TypeHint} from '../../nuclide-type-hint/lib/rpc-types'; -import type {CoverageResult} from '../../nuclide-type-coverage/lib/rpc-types'; -import type { - DefinitionQueryResult, - FindReferencesReturn, - Outline, - CodeAction, - SignatureHelp, -} from 'atom-ide-ui'; -import type {ConnectableObservable} from 'rxjs'; -import type { - AutocompleteRequest, - AutocompleteResult, - FileDiagnosticMap, - FileDiagnosticMessage, - FormatOptions, - LanguageService, - SymbolResult, - Completion, - CodeLensData, - StatusData, -} from '../../nuclide-language-service/lib/LanguageService'; - -import {Observable} from 'rxjs'; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); // An implementation of LanguageService which always returns no results. // Useful for implementing aggregate language services. -export class NullLanguageService { - getDiagnostics(fileVersion: FileVersion): Promise { +class NullLanguageService { + getDiagnostics(fileVersion) { return Promise.resolve(null); } - observeDiagnostics(): ConnectableObservable { - return Observable.empty().publish(); + observeDiagnostics() { + return _rxjsBundlesRxMinJs.Observable.empty().publish(); } - getAutocompleteSuggestions( - fileVersion: FileVersion, - position: atom$Point, - request: AutocompleteRequest, - ): Promise { + getAutocompleteSuggestions(fileVersion, position, request) { return Promise.resolve(null); } - resolveAutocompleteSuggestion(suggestion: Completion): Promise { + resolveAutocompleteSuggestion(suggestion) { return Promise.resolve(null); } - getDefinition( - fileVersion: FileVersion, - position: atom$Point, - ): Promise { + getDefinition(fileVersion, position) { return Promise.resolve(null); } - onToggleCoverage(set: boolean): Promise { + onToggleCoverage(set) { return Promise.resolve(undefined); } - findReferences( - fileVersion: FileVersion, - position: atom$Point, - ): ConnectableObservable { - return Observable.of(null).publish(); + findReferences(fileVersion, position) { + return _rxjsBundlesRxMinJs.Observable.of(null).publish(); } - getCoverage(filePath: NuclideUri): Promise { + getCoverage(filePath) { return Promise.resolve(null); } - getOutline(fileVersion: FileVersion): Promise { + getOutline(fileVersion) { return Promise.resolve(null); } - getCodeLens(fileVersion: FileVersion): Promise> { + getCodeLens(fileVersion) { return Promise.resolve(null); } - resolveCodeLens( - filePath: NuclideUri, - codeLens: CodeLensData, - ): Promise { + resolveCodeLens(filePath, codeLens) { return Promise.resolve(null); } - getAdditionalLogFiles( - deadline: DeadlineRequest, - ): Promise> { + getAdditionalLogFiles(deadline) { return Promise.resolve([]); } - getCodeActions( - fileVersion: FileVersion, - range: atom$Range, - diagnostics: Array, - ): Promise> { + getCodeActions(fileVersion, range, diagnostics) { return Promise.resolve([]); } - typeHint(fileVersion: FileVersion, position: atom$Point): Promise { + typeHint(fileVersion, position) { return Promise.resolve(null); } - highlight( - fileVersion: FileVersion, - position: atom$Point, - ): Promise> { + highlight(fileVersion, position) { return Promise.resolve(null); } - formatSource( - fileVersion: FileVersion, - range: atom$Range, - options: FormatOptions, - ): Promise> { + formatSource(fileVersion, range, options) { return Promise.resolve(null); } - formatEntireFile( - fileVersion: FileVersion, - range: atom$Range, - options: FormatOptions, - ): Promise { + formatEntireFile(fileVersion, range, options) { return Promise.resolve(null); } - formatAtPosition( - fileVersion: FileVersion, - position: atom$Point, - triggerCharacter: string, - options: FormatOptions, - ): Promise> { + formatAtPosition(fileVersion, position, triggerCharacter, options) { return Promise.resolve(null); } - signatureHelp( - fileVersion: FileVersion, - position: atom$Point, - ): Promise { + signatureHelp(fileVersion, position) { return Promise.resolve(null); } - supportsSymbolSearch(directories: Array): Promise { + supportsSymbolSearch(directories) { return Promise.resolve(false); } - symbolSearch( - query: string, - directories: Array, - ): Promise> { + symbolSearch(query, directories) { return Promise.resolve(null); } - getProjectRoot(fileUri: NuclideUri): Promise { + getProjectRoot(fileUri) { return Promise.resolve(null); } - isFileInProject(fileUri: NuclideUri): Promise { + isFileInProject(fileUri) { return Promise.resolve(false); } - getExpandedSelectionRange( - fileVersion: FileVersion, - currentSelection: atom$Range, - ): Promise { + getExpandedSelectionRange(fileVersion, currentSelection) { return Promise.resolve(null); } - getCollapsedSelectionRange( - fileVersion: FileVersion, - currentSelection: atom$Range, - originalCursorPosition: atom$Point, - ): Promise { + getCollapsedSelectionRange(fileVersion, currentSelection, originalCursorPosition) { return Promise.resolve(null); } - observeStatus(fileVersion: FileVersion): ConnectableObservable { - return Observable.of({kind: 'null'}).publish(); + observeStatus(fileVersion) { + return _rxjsBundlesRxMinJs.Observable.of({ kind: 'null' }).publish(); } - async clickStatus( - fileVersion: FileVersion, - id: string, - button: string, - ): Promise {} + async clickStatus(fileVersion, id, button) {} - dispose(): void {} + dispose() {} } -// Assert that NullLanguageService satisifes the LanguageService interface: -(((null: any): NullLanguageService): LanguageService); +exports.NullLanguageService = NullLanguageService; // Assert that NullLanguageService satisifes the LanguageService interface: +/** + * 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. + * + * + * @format + */ + +null; \ No newline at end of file diff --git a/pkg/nuclide-language-service-rpc/lib/ServerLanguageService.js b/pkg/nuclide-language-service-rpc/lib/ServerLanguageService.js index fed89feb13..03961e0025 100644 --- a/pkg/nuclide-language-service-rpc/lib/ServerLanguageService.js +++ b/pkg/nuclide-language-service-rpc/lib/ServerLanguageService.js @@ -1,3 +1,23 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ServerLanguageService = undefined; +exports.ensureInvalidations = ensureInvalidations; + +var _nuclideOpenFilesRpc; + +function _load_nuclideOpenFilesRpc() { + return _nuclideOpenFilesRpc = require('../../nuclide-open-files-rpc'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +// This is a version of the LanguageService interface which operates on a +// single modified file at a time. This provides a simplified interface +// for LanguageService implementors, at the cost of providing language analysis +// which can not reflect multiple edited files. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,472 +25,235 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {AdditionalLogFile} from '../../nuclide-logging/lib/rpc-types'; -import type {FileVersion} from '../../nuclide-open-files-rpc/lib/rpc-types'; -import type {TextEdit} from 'nuclide-commons-atom/text-edit'; -import type {TypeHint} from '../../nuclide-type-hint/lib/rpc-types'; -import type {CoverageResult} from '../../nuclide-type-coverage/lib/rpc-types'; -import type { - DefinitionQueryResult, - FindReferencesReturn, - Outline, - CodeAction, - SignatureHelp, -} from 'atom-ide-ui'; -import type { - AutocompleteRequest, - AutocompleteResult, - FileDiagnosticMap, - FileDiagnosticMessage, - FormatOptions, - LanguageService, - SymbolResult, - Completion, - CodeLensData, - StatusData, -} from '../../nuclide-language-service/lib/LanguageService'; -import type {FileNotifier} from '../../nuclide-open-files-rpc/lib/rpc-types'; -import type {ConnectableObservable} from 'rxjs'; - -import invariant from 'assert'; -import {getBufferAtVersion} from '../../nuclide-open-files-rpc'; -import {FileCache} from '../../nuclide-open-files-rpc'; -import {Observable} from 'rxjs'; +class ServerLanguageService { + + constructor(fileNotifier, service) { + if (!(fileNotifier instanceof (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).FileCache)) { + throw new Error('Invariant violation: "fileNotifier instanceof FileCache"'); + } -// This is a version of the LanguageService interface which operates on a -// single modified file at a time. This provides a simplified interface -// for LanguageService implementors, at the cost of providing language analysis -// which can not reflect multiple edited files. -export type SingleFileLanguageService = { - getDiagnostics( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - ): Promise, - - observeDiagnostics(): Observable, - - getAutocompleteSuggestions( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, - activatedManually: boolean, - prefix: string, - ): Promise, - - resolveAutocompleteSuggestion(suggestion: Completion): Promise, - - getDefinition( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, - ): Promise, - - findReferences( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, - ): Observable, - - getCoverage(filePath: NuclideUri): Promise, - - getOutline( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - ): Promise, - - onToggleCoverage(set: boolean): Promise, - - getCodeActions( - filePath: NuclideUri, - range: atom$Range, - diagnostics: Array, - ): Promise>, - - typeHint( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, - ): Promise, - - highlight( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, - ): Promise>, - - formatSource( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - range: atom$Range, - options: FormatOptions, - ): Promise>, - - formatEntireFile( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - range: atom$Range, - options: FormatOptions, - ): Promise, - - formatAtPosition( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, - triggerCharacter: string, - options: FormatOptions, - ): Promise>, - - signatureHelp( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, - ): Promise, - - getProjectRoot(fileUri: NuclideUri): Promise, - - isFileInProject(fileUri: NuclideUri): Promise, - - getExpandedSelectionRange( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - currentSelection: atom$Range, - ): Promise, - - getCollapsedSelectionRange( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - currentSelection: atom$Range, - originalCursorPosition: atom$Point, - ): Promise, - - dispose(): void, -}; - -export class ServerLanguageService< - T: SingleFileLanguageService = SingleFileLanguageService, -> { - _fileCache: FileCache; - _service: T; - - constructor(fileNotifier: FileNotifier, service: T) { - invariant(fileNotifier instanceof FileCache); this._fileCache = fileNotifier; this._service = service; } - getSingleFileLanguageService(): T { + getSingleFileLanguageService() { return this._service; } - async getDiagnostics(fileVersion: FileVersion): Promise { + async getDiagnostics(fileVersion) { const filePath = fileVersion.filePath; - const buffer = await getBufferAtVersion(fileVersion); + const buffer = await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion); if (buffer == null) { return null; } return this._service.getDiagnostics(filePath, buffer); } - observeDiagnostics(): ConnectableObservable { + observeDiagnostics() { return this._service.observeDiagnostics().publish(); } - async getAutocompleteSuggestions( - fileVersion: FileVersion, - position: atom$Point, - request: AutocompleteRequest, - ): Promise { + async getAutocompleteSuggestions(fileVersion, position, request) { const filePath = fileVersion.filePath; - const buffer = await getBufferAtVersion(fileVersion); + const buffer = await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion); if (buffer == null) { // TODO: this should return null so the empty list doesn't get cached - return {isIncomplete: false, items: []}; + return { isIncomplete: false, items: [] }; } - return this._service.getAutocompleteSuggestions( - filePath, - buffer, - position, - request.activatedManually, - request.prefix, - ); + return this._service.getAutocompleteSuggestions(filePath, buffer, position, request.activatedManually, request.prefix); } - async resolveAutocompleteSuggestion( - suggestion: Completion, - ): Promise { + async resolveAutocompleteSuggestion(suggestion) { return this._service.resolveAutocompleteSuggestion(suggestion); } - async getDefinition( - fileVersion: FileVersion, - position: atom$Point, - ): Promise { + async getDefinition(fileVersion, position) { const filePath = fileVersion.filePath; - const buffer = await getBufferAtVersion(fileVersion); + const buffer = await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion); if (buffer == null) { return null; } return this._service.getDefinition(filePath, buffer, position); } - findReferences( - fileVersion: FileVersion, - position: atom$Point, - ): ConnectableObservable { + findReferences(fileVersion, position) { const filePath = fileVersion.filePath; - return Observable.fromPromise(getBufferAtVersion(fileVersion)) - .concatMap(buffer => { - if (buffer == null) { - return Observable.of(null); - } - return this._service.findReferences(filePath, buffer, position); - }) - .publish(); + return _rxjsBundlesRxMinJs.Observable.fromPromise((0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion)).concatMap(buffer => { + if (buffer == null) { + return _rxjsBundlesRxMinJs.Observable.of(null); + } + return this._service.findReferences(filePath, buffer, position); + }).publish(); } - getCoverage(filePath: NuclideUri): Promise { + getCoverage(filePath) { return this._service.getCoverage(filePath); } - onToggleCoverage(set: boolean): Promise { + onToggleCoverage(set) { return this._service.onToggleCoverage(set); } - async getAdditionalLogFiles(): Promise> { + async getAdditionalLogFiles() { // TODO (if it's ever needed): push this request to the this._service return []; } - async getCodeActions( - fileVersion: FileVersion, - range: atom$Range, - diagnostics: Array, - ): Promise> { - const {filePath} = fileVersion; + async getCodeActions(fileVersion, range, diagnostics) { + const { filePath } = fileVersion; return this._service.getCodeActions(filePath, range, diagnostics); } - async getOutline(fileVersion: FileVersion): Promise { + async getOutline(fileVersion) { const filePath = fileVersion.filePath; - const buffer = await getBufferAtVersion(fileVersion); + const buffer = await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion); if (buffer == null) { return null; } return this._service.getOutline(filePath, buffer); } - async getCodeLens(fileVersion: FileVersion): Promise> { + async getCodeLens(fileVersion) { return null; } - async resolveCodeLens( - filePath: NuclideUri, - codeLens: CodeLensData, - ): Promise { + async resolveCodeLens(filePath, codeLens) { return null; } - async typeHint( - fileVersion: FileVersion, - position: atom$Point, - ): Promise { + async typeHint(fileVersion, position) { const filePath = fileVersion.filePath; - const buffer = await getBufferAtVersion(fileVersion); + const buffer = await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion); if (buffer == null) { return null; } return this._service.typeHint(filePath, buffer, position); } - async highlight( - fileVersion: FileVersion, - position: atom$Point, - ): Promise> { + async highlight(fileVersion, position) { const filePath = fileVersion.filePath; - const buffer = await getBufferAtVersion(fileVersion); + const buffer = await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion); if (buffer == null) { return []; } return this._service.highlight(filePath, buffer, position); } - async formatSource( - fileVersion: FileVersion, - range: atom$Range, - options: FormatOptions, - ): Promise> { + async formatSource(fileVersion, range, options) { const filePath = fileVersion.filePath; - const buffer = await getBufferAtVersion(fileVersion); + const buffer = await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion); if (buffer == null) { return null; } return this._service.formatSource(filePath, buffer, range, options); } - async formatEntireFile( - fileVersion: FileVersion, - range: atom$Range, - options: FormatOptions, - ): Promise { + async formatEntireFile(fileVersion, range, options) { const filePath = fileVersion.filePath; - const buffer = await getBufferAtVersion(fileVersion); + const buffer = await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion); if (buffer == null) { return null; } return this._service.formatEntireFile(filePath, buffer, range, options); } - async formatAtPosition( - fileVersion: FileVersion, - position: atom$Point, - triggerCharacter: string, - options: FormatOptions, - ): Promise> { + async formatAtPosition(fileVersion, position, triggerCharacter, options) { const filePath = fileVersion.filePath; - const buffer = await getBufferAtVersion(fileVersion); + const buffer = await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion); if (buffer == null) { return null; } - return this._service.formatAtPosition( - filePath, - buffer, - position, - triggerCharacter, - options, - ); + return this._service.formatAtPosition(filePath, buffer, position, triggerCharacter, options); } - async signatureHelp( - fileVersion: FileVersion, - position: atom$Point, - ): Promise { + async signatureHelp(fileVersion, position) { const filePath = fileVersion.filePath; - const buffer = await getBufferAtVersion(fileVersion); + const buffer = await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion); if (buffer == null) { return null; } return this._service.signatureHelp(filePath, buffer, position); } - supportsSymbolSearch(directories: Array): Promise { + supportsSymbolSearch(directories) { return Promise.resolve(false); // A single-file language service by definition cannot offer // "project-wide symbol search". If you want your language to offer // symbols, you'll have to implement LanguageService directly. } - symbolSearch( - query: string, - directories: Array, - ): Promise> { + symbolSearch(query, directories) { return Promise.resolve(null); } - getProjectRoot(fileUri: NuclideUri): Promise { + getProjectRoot(fileUri) { return this._service.getProjectRoot(fileUri); } - async isFileInProject(fileUri: NuclideUri): Promise { + async isFileInProject(fileUri) { return this._service.isFileInProject(fileUri); } - async getExpandedSelectionRange( - fileVersion: FileVersion, - currentSelection: atom$Range, - ): Promise { + async getExpandedSelectionRange(fileVersion, currentSelection) { const filePath = fileVersion.filePath; - const buffer = await getBufferAtVersion(fileVersion); + const buffer = await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion); if (buffer == null) { return null; } - return this._service.getExpandedSelectionRange( - filePath, - buffer, - currentSelection, - ); + return this._service.getExpandedSelectionRange(filePath, buffer, currentSelection); } - async getCollapsedSelectionRange( - fileVersion: FileVersion, - currentSelection: atom$Range, - originalCursorPosition: atom$Point, - ): Promise { + async getCollapsedSelectionRange(fileVersion, currentSelection, originalCursorPosition) { const filePath = fileVersion.filePath; - const buffer = await getBufferAtVersion(fileVersion); + const buffer = await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion); if (buffer == null) { return null; } - return this._service.getCollapsedSelectionRange( - filePath, - buffer, - currentSelection, - originalCursorPosition, - ); + return this._service.getCollapsedSelectionRange(filePath, buffer, currentSelection, originalCursorPosition); } - observeStatus(fileVersion: FileVersion): ConnectableObservable { - return Observable.of({kind: 'null'}).publish(); + observeStatus(fileVersion) { + return _rxjsBundlesRxMinJs.Observable.of({ kind: 'null' }).publish(); } - async clickStatus( - fileVersion: FileVersion, - id: string, - button: string, - ): Promise {} + async clickStatus(fileVersion, id, button) {} - dispose(): void { + dispose() { this._service.dispose(); } } -// Assert that ServerLanguageService satisifes the LanguageService interface: -(((null: any): ServerLanguageService<>): LanguageService); +exports.ServerLanguageService = ServerLanguageService; // Assert that ServerLanguageService satisifes the LanguageService interface: + +null; -export function ensureInvalidations( - logger: log4js$Logger, - diagnostics: Observable, -): Observable { +function ensureInvalidations(logger, diagnostics) { const filesWithErrors = new Set(); - const trackedDiagnostics: Observable = diagnostics.do( - (diagnosticMap: FileDiagnosticMap) => { - for (const [filePath, messages] of diagnosticMap) { - if (messages.length === 0) { - logger.debug(`Removing ${filePath} from files with errors`); - filesWithErrors.delete(filePath); - } else { - logger.debug(`Adding ${filePath} to files with errors`); - filesWithErrors.add(filePath); - } + const trackedDiagnostics = diagnostics.do(diagnosticMap => { + for (const [filePath, messages] of diagnosticMap) { + if (messages.length === 0) { + logger.debug(`Removing ${filePath} from files with errors`); + filesWithErrors.delete(filePath); + } else { + logger.debug(`Adding ${filePath} to files with errors`); + filesWithErrors.add(filePath); } - }, - ); - - const fileInvalidations: Observable = Observable.defer( - () => { - logger.debug('Clearing errors after stream closed'); - return Observable.of( - new Map( - Array.from(filesWithErrors).map(file => { - logger.debug(`Clearing errors for ${file} after connection closed`); - return [file, []]; - }), - ), - ); - }, - ); + } + }); + + const fileInvalidations = _rxjsBundlesRxMinJs.Observable.defer(() => { + logger.debug('Clearing errors after stream closed'); + return _rxjsBundlesRxMinJs.Observable.of(new Map(Array.from(filesWithErrors).map(file => { + logger.debug(`Clearing errors for ${file} after connection closed`); + return [file, []]; + }))); + }); return trackedDiagnostics.concat(fileInvalidations); -} +} \ No newline at end of file diff --git a/pkg/nuclide-language-service-rpc/lib/TypeHintFromSnippet.js b/pkg/nuclide-language-service-rpc/lib/TypeHintFromSnippet.js index 471fbf0451..cce681cdf5 100644 --- a/pkg/nuclide-language-service-rpc/lib/TypeHintFromSnippet.js +++ b/pkg/nuclide-language-service-rpc/lib/TypeHintFromSnippet.js @@ -1,19 +1,18 @@ -/** - * 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 strict - * @format - */ +'use strict'; -import type {TypeHint} from '../../nuclide-type-hint/lib/rpc-types'; - -export function typeHintFromSnippet( - snippet: string, - range: atom$Range, -): TypeHint { - return {hint: [{type: 'snippet', value: snippet}], range}; -} +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.typeHintFromSnippet = typeHintFromSnippet; +function typeHintFromSnippet(snippet, range) { + return { hint: [{ type: 'snippet', value: snippet }], range }; +} /** + * 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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-language-service-rpc/lib/main.js b/pkg/nuclide-language-service-rpc/lib/main.js index 64f1f9bdc8..1c7203fd39 100644 --- a/pkg/nuclide-language-service-rpc/lib/main.js +++ b/pkg/nuclide-language-service-rpc/lib/main.js @@ -1,25 +1,76 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -export type {SingleFileLanguageService} from './ServerLanguageService'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -export { - ServerLanguageService, - ensureInvalidations, -} from './ServerLanguageService'; +var _ServerLanguageService; -export {NullLanguageService} from './NullLanguageService'; +function _load_ServerLanguageService() { + return _ServerLanguageService = require('./ServerLanguageService'); +} -export {MultiProjectLanguageService} from './MultiProjectLanguageService'; +Object.defineProperty(exports, 'ServerLanguageService', { + enumerable: true, + get: function () { + return (_ServerLanguageService || _load_ServerLanguageService()).ServerLanguageService; + } +}); +Object.defineProperty(exports, 'ensureInvalidations', { + enumerable: true, + get: function () { + return (_ServerLanguageService || _load_ServerLanguageService()).ensureInvalidations; + } +}); -export {forkHostServices} from './HostServicesAggregator'; +var _NullLanguageService; -export {typeHintFromSnippet} from './TypeHintFromSnippet'; +function _load_NullLanguageService() { + return _NullLanguageService = require('./NullLanguageService'); +} + +Object.defineProperty(exports, 'NullLanguageService', { + enumerable: true, + get: function () { + return (_NullLanguageService || _load_NullLanguageService()).NullLanguageService; + } +}); + +var _MultiProjectLanguageService; + +function _load_MultiProjectLanguageService() { + return _MultiProjectLanguageService = require('./MultiProjectLanguageService'); +} + +Object.defineProperty(exports, 'MultiProjectLanguageService', { + enumerable: true, + get: function () { + return (_MultiProjectLanguageService || _load_MultiProjectLanguageService()).MultiProjectLanguageService; + } +}); + +var _HostServicesAggregator; + +function _load_HostServicesAggregator() { + return _HostServicesAggregator = require('./HostServicesAggregator'); +} + +Object.defineProperty(exports, 'forkHostServices', { + enumerable: true, + get: function () { + return (_HostServicesAggregator || _load_HostServicesAggregator()).forkHostServices; + } +}); + +var _TypeHintFromSnippet; + +function _load_TypeHintFromSnippet() { + return _TypeHintFromSnippet = require('./TypeHintFromSnippet'); +} + +Object.defineProperty(exports, 'typeHintFromSnippet', { + enumerable: true, + get: function () { + return (_TypeHintFromSnippet || _load_TypeHintFromSnippet()).typeHintFromSnippet; + } +}); \ No newline at end of file diff --git a/pkg/nuclide-language-service-rpc/lib/rpc-types.js b/pkg/nuclide-language-service-rpc/lib/rpc-types.js index fd6005b7de..2ce867e78c 100644 --- a/pkg/nuclide-language-service-rpc/lib/rpc-types.js +++ b/pkg/nuclide-language-service-rpc/lib/rpc-types.js @@ -1,69 +1,3 @@ -/** - * 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 - */ +'use strict'; -import {ConnectableObservable} from 'rxjs'; - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {TextEdit} from 'nuclide-commons-atom/text-edit'; - -export type ShowNotificationLevel = 'info' | 'log' | 'warning' | 'error'; - -// This interface is exposed by the client to the server -export interface HostServices { - consoleNotification( - source: string, - level: ShowNotificationLevel, - text: string, - ): void; - - dialogNotification( - level: ShowNotificationLevel, - text: string, - ): ConnectableObservable; - - dialogRequest( - level: ShowNotificationLevel, - text: string, - buttonLabels: Array, - closeLabel: string, - ): ConnectableObservable; - - // showProgress shows the busy spinner with a tooltip message that can update - // over time. Use the returned Progress interface to update title if wanted, - // and to dispose when done. - showProgress( - title: string, - options?: {|debounce?: boolean|}, - ): Promise; - - // showActionRequired shows an icon with the tooltip message. If clickable, - // then the user can click on the message, which will generate a next(). - // Unsubscribe when done. - showActionRequired( - title: string, - options?: {|clickable?: boolean|}, - ): ConnectableObservable; - - dispose(): void; - - // Internal implementation method. Normally we'd keep it private. - // But we need it to be remotable across NuclideRPC, so it must be public. - childRegister(child: HostServices): Promise; - - applyTextEditsForMultipleFiles( - changes: Map>, - ): Promise; -} - -export interface Progress { - setTitle(title: string): void; - dispose(): void; -} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); \ No newline at end of file diff --git a/pkg/nuclide-language-service-rpc/spec/HostServicesAggregator-spec.js b/pkg/nuclide-language-service-rpc/spec/HostServicesAggregator-spec.js deleted file mode 100644 index 371fe66f3e..0000000000 --- a/pkg/nuclide-language-service-rpc/spec/HostServicesAggregator-spec.js +++ /dev/null @@ -1,309 +0,0 @@ -/** - * 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 - */ - -import type {HostServices} from '../lib/rpc-types'; - -import {Observable} from 'rxjs'; -import {forkHostServices} from '../'; - -describe('HostServicesAggregator', () => { - let hostObj; - let host; - let hostRelayObj; - let hostRelay; - let logger; - - beforeEach(() => { - hostObj = jasmine.createSpyObj('host', [ - 'consoleNotification', - 'dialogNotification', - 'dialogRequest', - 'showProgress', - 'dispose', - 'childRegister', - ]); - hostRelayObj = jasmine.createSpyObj('hostRelay', [ - 'consoleNotification', - 'dialogNotification', - 'dialogRequest', - 'showProgress', - 'dispose', - 'childRegister', - ]); - hostObj.childRegister = jasmine - .createSpy('childRegister') - .andReturn(Promise.resolve(hostRelayObj)); - hostRelayObj.consoleNotification = jasmine - .createSpy('consoleNotification') - .andCallFake(hostObj.consoleNotification); - host = ((hostObj: any): HostServices); - hostRelay = ((hostRelayObj: any): HostServices); - - logger = ((jasmine.createSpyObj('logger', [ - 'debug', - 'trace', - 'info', - 'error', - 'setLevel', - ]): any): log4js$Logger); - }); - - it('relays to parent', () => { - waitsForPromise(async () => { - const child1 = await forkHostServices(host, logger); - - expect(host.childRegister.callCount).toEqual(1); - expect(host.childRegister).toHaveBeenCalledWith(child1); - - child1.consoleNotification('fred', 'warning', 'hello'); - - expect(hostRelay.consoleNotification.callCount).toEqual(1); - expect(host.consoleNotification.callCount).toEqual(1); - expect(host.consoleNotification).toHaveBeenCalledWith( - 'fred', - 'warning', - 'hello', - ); - - const child2 = await forkHostServices(host, logger); - - expect(host.childRegister.callCount).toEqual(2); - expect(host.childRegister).toHaveBeenCalledWith(child2); - - child2.consoleNotification('jones', 'info', 'world'); - - expect(hostRelay.consoleNotification.callCount).toEqual(2); - expect(host.consoleNotification.callCount).toEqual(2); - expect(host.consoleNotification).toHaveBeenCalledWith( - 'jones', - 'info', - 'world', - ); - }); - }); - - it('relays through aggregator', () => { - waitsForPromise(async () => { - const aggregator = await forkHostServices(host, logger); - const originalMethod = aggregator.childRegister.bind(aggregator); - let returnValue; - spyOn(aggregator, 'childRegister').andCallFake(child => { - returnValue = originalMethod(child); - return returnValue; - }); - spyOn(aggregator, 'consoleNotification').andCallThrough(); - - const child1 = await forkHostServices(aggregator, logger); - const relayForChild1 = ((await returnValue: any): HostServices); - spyOn(relayForChild1, 'consoleNotification').andCallThrough(); - - const child2 = await forkHostServices(aggregator, logger); - const relayForChild2 = ((await returnValue: any): HostServices); - spyOn(relayForChild2, 'consoleNotification').andCallThrough(); - - expect(host.childRegister.callCount).toEqual(1); - expect(aggregator.childRegister.callCount).toEqual(2); - - child1.consoleNotification('fred', 'warning', 'hello'); - - expect(aggregator.consoleNotification.callCount).toEqual(0); - expect(relayForChild1.consoleNotification.callCount).toEqual(1); - expect(relayForChild2.consoleNotification.callCount).toEqual(0); - expect(host.consoleNotification.callCount).toEqual(1); - - child2.consoleNotification('jones', 'info', 'world'); - - expect(aggregator.consoleNotification.callCount).toEqual(0); - expect(relayForChild1.consoleNotification.callCount).toEqual(1); - expect(relayForChild2.consoleNotification.callCount).toEqual(1); - expect(host.consoleNotification.callCount).toEqual(2); - }); - }); - - it('has its own relay#0 unrelated to children', () => { - waitsForPromise(async () => { - const aggregator = await forkHostServices(host, logger); - spyOn(aggregator, 'consoleNotification').andCallThrough(); - const originalMethod = aggregator.childRegister.bind(aggregator); - let returnValue; - spyOn(aggregator, 'childRegister').andCallFake(child => { - returnValue = originalMethod(child); - return returnValue; - }); - const child = await forkHostServices(aggregator, logger); - const relayForChild = ((await returnValue: any): HostServices); - spyOn(relayForChild, 'consoleNotification').andCallThrough(); - - aggregator.consoleNotification('alfred', 'error', 'oops'); - - expect(relayForChild.consoleNotification.callCount).toEqual(0); - expect(aggregator.consoleNotification.callCount).toEqual(1); - expect(hostRelay.consoleNotification.callCount).toEqual(1); - - child.consoleNotification('jones', 'warning', 'what'); - - expect(relayForChild.consoleNotification.callCount).toEqual(1); - expect(aggregator.consoleNotification.callCount).toEqual(1); - expect(hostRelay.consoleNotification.callCount).toEqual(2); - }); - }); - - it('disposes all remaining children', () => { - waitsForPromise(async () => { - const aggregator = await forkHostServices(host, logger); - const child1 = await forkHostServices(aggregator, logger); - const child2 = await forkHostServices(aggregator, logger); - spyOn(aggregator, 'dispose').andCallThrough(); - spyOn(child1, 'dispose').andCallThrough(); - spyOn(child2, 'dispose').andCallThrough(); - - child1.dispose(); - - expect(child1.dispose.callCount).toEqual(1); - expect(child2.dispose.callCount).toEqual(0); - expect(aggregator.dispose.callCount).toEqual(0); - expect(hostRelay.dispose.callCount).toEqual(0); - expect(host.dispose.callCount).toEqual(0); - - aggregator.dispose(); - - expect(child1.dispose.callCount).toEqual(1); - expect(child2.dispose.callCount).toEqual(1); - expect(aggregator.dispose.callCount).toEqual(1); - expect(hostRelay.dispose.callCount).toEqual(1); - expect(host.dispose.callCount).toEqual(0); - }); - }); - - it('relays progress to parent', () => { - waitsForPromise(async () => { - const wrapper1 = jasmine.createSpyObj('w1', ['setTitle', 'dispose']); - const wrapper2 = jasmine.createSpyObj('w2', ['setTitle', 'dispose']); - const wrappers = [wrapper1, wrapper2]; - hostRelayObj.showProgress = jasmine - .createSpy('showProgress') - .andCallFake(() => wrappers.shift()); - const child = await forkHostServices(host, logger); - - const p1 = await child.showProgress('ping1'); - p1.setTitle('a'); - expect(wrapper1.setTitle.mostRecentCall.args[0]).toEqual('a'); - - const p2 = await child.showProgress('ping2'); - p2.setTitle('b'); - expect(wrapper1.setTitle.mostRecentCall.args[0]).toEqual('a'); - expect(wrapper2.setTitle.mostRecentCall.args[0]).toEqual('b'); - - expect(wrapper2.dispose.callCount).toEqual(0); - p2.dispose(); - expect(wrapper2.dispose.callCount).toEqual(1); - - expect(wrapper1.dispose.callCount).toEqual(0); - p1.dispose(); - expect(wrapper1.dispose.callCount).toEqual(1); - }); - }); - - it('disposes progress cleanly', () => { - waitsForPromise(async () => { - const wrapper = jasmine.createSpyObj('wrapper', ['setTitle', 'dispose']); - hostRelayObj.showProgress = jasmine - .createSpy('showProgress') - .andReturn(Promise.resolve(wrapper)); - - const child = await forkHostServices(host, logger); - const p = await child.showProgress('ping'); - child.dispose(); - expect(wrapper.dispose.callCount).toEqual(1); - p.setTitle('a'); - expect(wrapper.setTitle.callCount).toEqual(0); - p.dispose(); - expect(wrapper.dispose.callCount).toEqual(1); - }); - }); - - it('has no races on showProgress and child disposal', () => { - waitsForPromise(async () => { - const wrapper = jasmine.createSpyObj('wrapper', ['setTitle', 'dispose']); - hostRelayObj.showProgress = jasmine - .createSpy('showProgress') - .andReturn(Promise.resolve(wrapper)); - - const child1 = await forkHostServices(host, logger); - const child2 = await forkHostServices(child1, logger); - const pPromise = child2.showProgress('ping'); - child2.dispose(); - const p = await pPromise; - expect(wrapper.dispose.callCount).toEqual(1); - p.setTitle('a'); - expect(wrapper.setTitle.callCount).toEqual(0); - p.dispose(); - expect(wrapper.dispose.callCount).toEqual(1); - }); - }); - - it('will unsubscribe from dialogs upon dispose', () => { - waitsForPromise(async () => { - let hasSubscribed = false; - let hasUnsubscribed = false; - - hostRelayObj.dialogRequest = jasmine.createSpy('dialogRequest').andReturn( - Observable.create(observer => { - hasSubscribed = true; - return () => { - hasUnsubscribed = true; - }; - }).publish(), - ); - - const aggregator = await forkHostServices(host, logger); - - expect(hasSubscribed).toEqual(false); - - const promise = aggregator - .dialogRequest('info', 'hello', [], 'close') - .refCount() - .toPromise(); - - expect(hasSubscribed).toEqual(true); - expect(hasUnsubscribed).toEqual(false); - - aggregator.dispose(); - - expect(hasUnsubscribed).toEqual(true); - expect(await promise).toBeUndefined(); - }); - }); - - it('is no-op after dispose', () => { - waitsForPromise(async () => { - const aggregator1 = await forkHostServices(host, logger); - const aggregator2 = await forkHostServices(aggregator1, logger); - aggregator1.dispose(); - aggregator2.consoleNotification('noop', 'warning', 'goodbye'); - }); - }); - - it('forks disposed children after dispose', () => { - waitsForPromise(async () => { - const aggregator = await forkHostServices(host, logger); - aggregator.consoleNotification('op', 'warning', 'hello'); - expect(hostRelay.consoleNotification.callCount).toEqual(1); - aggregator.dispose(); - - const child = await forkHostServices(aggregator, logger); - expect((child: any).isDisposed()).toEqual(true); - child.consoleNotification('noop', 'warning', 'goodbye'); - expect(hostRelay.consoleNotification.callCount).toEqual(1); - child.dispose(); - }); - }); -}); diff --git a/pkg/nuclide-language-service/lib/AdditionalLogFileProvider.js b/pkg/nuclide-language-service/lib/AdditionalLogFileProvider.js index 24a1a05360..47c5d7614f 100644 --- a/pkg/nuclide-language-service/lib/AdditionalLogFileProvider.js +++ b/pkg/nuclide-language-service/lib/AdditionalLogFileProvider.js @@ -1,70 +1,72 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {DeadlineRequest} from 'nuclide-commons/promise'; -import type {AdditionalLogFile} from '../../nuclide-logging/lib/rpc-types'; -import type {LanguageService} from './LanguageService'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LanguageAdditionalLogFilesProvider = undefined; -import {arrayFlatten} from 'nuclide-commons/collection'; -import {timeoutAfterDeadline} from 'nuclide-commons/promise'; -import {stringifyError} from 'nuclide-commons/string'; -import {ConnectionCache} from '../../nuclide-remote-connection'; +var _collection; -export class LanguageAdditionalLogFilesProvider { - id: string = 'als'; - _name: string; - _connectionToLanguageService: ConnectionCache; +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _string; + +function _load_string() { + return _string = require('../../../modules/nuclide-commons/string'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +class LanguageAdditionalLogFilesProvider { + + constructor(name, connectionToLanguageService) { + this.id = 'als'; - constructor(name: string, connectionToLanguageService: ConnectionCache) { this._name = name; this._connectionToLanguageService = connectionToLanguageService; } - static register( - name: string, - connectionToLanguageService: ConnectionCache, - ): IDisposable { - return atom.packages.serviceHub.provide( - 'additional-log-files', - '0.0.0', - new LanguageAdditionalLogFilesProvider(name, connectionToLanguageService), - ); + static register(name, connectionToLanguageService) { + return atom.packages.serviceHub.provide('additional-log-files', '0.0.0', new LanguageAdditionalLogFilesProvider(name, connectionToLanguageService)); } - async getAdditionalLogFiles( - deadline: DeadlineRequest, - ): Promise> { + async getAdditionalLogFiles(deadline) { const resultsForConnection = async (prefix, connection) => { const service = await this._connectionToLanguageService.get(connection); const subResults = await service.getAdditionalLogFiles(deadline - 1000); - return subResults.map(log => ({...log, title: prefix + log.title})); + return subResults.map(log => Object.assign({}, log, { title: prefix + log.title })); }; const connections = Array.from(this._connectionToLanguageService.keys()); - const results = await Promise.all( - connections.map(connection => { - const prefix = - `[${this._name}]` + - (connection == null ? '' : connection.getRemoteHostname() + ':'); - return timeoutAfterDeadline( - deadline, - resultsForConnection(prefix, connection), - ).catch(e => [ - { - title: `${prefix}language_service`, - data: stringifyError(e), - }, - ]); - }), - ); - return arrayFlatten(results); + const results = await Promise.all(connections.map(connection => { + const prefix = `[${this._name}]` + (connection == null ? '' : connection.getRemoteHostname() + ':'); + return (0, (_promise || _load_promise()).timeoutAfterDeadline)(deadline, resultsForConnection(prefix, connection)).catch(e => [{ + title: `${prefix}language_service`, + data: (0, (_string || _load_string()).stringifyError)(e) + }]); + })); + return (0, (_collection || _load_collection()).arrayFlatten)(results); } } +exports.LanguageAdditionalLogFilesProvider = LanguageAdditionalLogFilesProvider; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/AtomLanguageService.js b/pkg/nuclide-language-service/lib/AtomLanguageService.js index 0d4a8cef4e..969cc4c80b 100644 --- a/pkg/nuclide-language-service/lib/AtomLanguageService.js +++ b/pkg/nuclide-language-service/lib/AtomLanguageService.js @@ -1,336 +1,260 @@ -/** - * 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 strict-local - * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {LanguageService} from './LanguageService'; -import type {ServerConnection} from '../../nuclide-remote-connection'; -import type {CodeHighlightConfig} from './CodeHighlightProvider'; -import type {OutlineViewConfig} from './OutlineViewProvider'; -import type {StatusConfig} from './StatusProvider'; -import type {TypeCoverageConfig} from './TypeCoverageProvider'; -import type {DefinitionConfig} from './DefinitionProvider'; -import type {TypeHintConfig} from './TypeHintProvider'; -import type {CodeFormatConfig} from './CodeFormatProvider'; -import type {FindReferencesConfig} from './FindReferencesProvider'; -import type {CodeActionConfig} from './CodeActionProvider'; -import type { - AutocompleteConfig, - OnDidInsertSuggestionCallback, -} from './AutocompleteProvider'; -import type {DiagnosticsConfig} from './DiagnosticsProvider'; -import type {SignatureHelpConfig} from './SignatureHelpProvider'; -import type {SyntacticSelectionConfig} from './SyntacticSelectionProvider'; -import type {BusySignalService} from 'atom-ide-ui'; - -import {ConnectionCache} from '../../nuclide-remote-connection'; -import {Observable} from 'rxjs'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {LanguageAdditionalLogFilesProvider} from './AdditionalLogFileProvider'; -import {CodeHighlightProvider} from './CodeHighlightProvider'; -import {OutlineViewProvider} from './OutlineViewProvider'; -import {StatusProvider} from './StatusProvider'; -import {TypeCoverageProvider} from './TypeCoverageProvider'; -import {DefinitionProvider} from './DefinitionProvider'; -import {TypeHintProvider} from './TypeHintProvider'; -import {CodeFormatProvider} from './CodeFormatProvider'; -import {FindReferencesProvider} from './FindReferencesProvider'; -import {AutocompleteProvider} from './AutocompleteProvider'; -import {registerDiagnostics} from './DiagnosticsProvider'; -import {CodeActionProvider} from './CodeActionProvider'; -import {SignatureHelpProvider} from './SignatureHelpProvider'; -import {SyntacticSelectionProvider} from './SyntacticSelectionProvider'; -import {getLogger} from 'log4js'; - -export type BusySignalProvider = { - reportBusyWhile(message: string, f: () => Promise): Promise, -}; - -export type AtomLanguageServiceConfig = {| - name: string, - grammars: Array, - highlight?: CodeHighlightConfig, - outline?: OutlineViewConfig, - coverage?: TypeCoverageConfig, - definition?: DefinitionConfig, - typeHint?: TypeHintConfig, - codeFormat?: CodeFormatConfig, - findReferences?: FindReferencesConfig, - autocomplete?: AutocompleteConfig, - diagnostics?: DiagnosticsConfig, - codeAction?: CodeActionConfig, - signatureHelp?: SignatureHelpConfig, - syntacticSelection?: SyntacticSelectionConfig, - status?: StatusConfig, -|}; - -export class AtomLanguageService { - _config: AtomLanguageServiceConfig; - _onDidInsertSuggestion: ?OnDidInsertSuggestionCallback; - _connectionToLanguageService: ConnectionCache; - _subscriptions: UniversalDisposable; - _logger: log4js$Logger; - - constructor( - languageServiceFactory: (connection: ?ServerConnection) => Promise, - config: AtomLanguageServiceConfig, - onDidInsertSuggestion: ?OnDidInsertSuggestionCallback, - logger: log4js$Logger = getLogger('nuclide-language-service'), - ) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AtomLanguageService = undefined; + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _AdditionalLogFileProvider; + +function _load_AdditionalLogFileProvider() { + return _AdditionalLogFileProvider = require('./AdditionalLogFileProvider'); +} + +var _CodeHighlightProvider; + +function _load_CodeHighlightProvider() { + return _CodeHighlightProvider = require('./CodeHighlightProvider'); +} + +var _OutlineViewProvider; + +function _load_OutlineViewProvider() { + return _OutlineViewProvider = require('./OutlineViewProvider'); +} + +var _StatusProvider; + +function _load_StatusProvider() { + return _StatusProvider = require('./StatusProvider'); +} + +var _TypeCoverageProvider; + +function _load_TypeCoverageProvider() { + return _TypeCoverageProvider = require('./TypeCoverageProvider'); +} + +var _DefinitionProvider; + +function _load_DefinitionProvider() { + return _DefinitionProvider = require('./DefinitionProvider'); +} + +var _TypeHintProvider; + +function _load_TypeHintProvider() { + return _TypeHintProvider = require('./TypeHintProvider'); +} + +var _CodeFormatProvider; + +function _load_CodeFormatProvider() { + return _CodeFormatProvider = require('./CodeFormatProvider'); +} + +var _FindReferencesProvider; + +function _load_FindReferencesProvider() { + return _FindReferencesProvider = require('./FindReferencesProvider'); +} + +var _AutocompleteProvider; + +function _load_AutocompleteProvider() { + return _AutocompleteProvider = require('./AutocompleteProvider'); +} + +var _DiagnosticsProvider; + +function _load_DiagnosticsProvider() { + return _DiagnosticsProvider = require('./DiagnosticsProvider'); +} + +var _CodeActionProvider; + +function _load_CodeActionProvider() { + return _CodeActionProvider = require('./CodeActionProvider'); +} + +var _SignatureHelpProvider; + +function _load_SignatureHelpProvider() { + return _SignatureHelpProvider = require('./SignatureHelpProvider'); +} + +var _SyntacticSelectionProvider; + +function _load_SyntacticSelectionProvider() { + return _SyntacticSelectionProvider = require('./SyntacticSelectionProvider'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class AtomLanguageService { + + constructor(languageServiceFactory, config, onDidInsertSuggestion, logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-language-service')) { this._config = config; this._onDidInsertSuggestion = onDidInsertSuggestion; this._logger = logger; - this._subscriptions = new UniversalDisposable(); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); const lazy = true; - this._connectionToLanguageService = new ConnectionCache( - languageServiceFactory, - lazy, - ); + this._connectionToLanguageService = new (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).ConnectionCache(languageServiceFactory, lazy); this._subscriptions.add(this._connectionToLanguageService); } - _selector(): string { + _selector() { return this._config.grammars.join(', '); } - activate(): void { - let busySignalService: ?BusySignalService = null; + activate() { + let busySignalService = null; const busySignalProvider = { - reportBusyWhile(message, f: () => Promise): Promise { + reportBusyWhile(message, f) { if (busySignalService != null) { return busySignalService.reportBusyWhile(message, f); } else { return f(); } - }, + } }; - this._subscriptions.add( - atom.packages.serviceHub.consume( - 'atom-ide-busy-signal', - '0.1.0', - service => { - this._subscriptions.add(service); - busySignalService = service; - return new UniversalDisposable(() => { - this._subscriptions.remove(service); - busySignalService = null; - }); - }, - ), - ); + this._subscriptions.add(atom.packages.serviceHub.consume('atom-ide-busy-signal', '0.1.0', service => { + this._subscriptions.add(service); + busySignalService = service; + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { + this._subscriptions.remove(service); + busySignalService = null; + }); + })); const highlightConfig = this._config.highlight; if (highlightConfig != null) { - this._subscriptions.add( - CodeHighlightProvider.register( - this._config.name, - this._config.grammars, - highlightConfig, - this._connectionToLanguageService, - ), - ); + this._subscriptions.add((_CodeHighlightProvider || _load_CodeHighlightProvider()).CodeHighlightProvider.register(this._config.name, this._config.grammars, highlightConfig, this._connectionToLanguageService)); } const outlineConfig = this._config.outline; if (outlineConfig != null) { - this._subscriptions.add( - OutlineViewProvider.register( - this._config.name, - this._config.grammars, - outlineConfig, - this._connectionToLanguageService, - ), - ); + this._subscriptions.add((_OutlineViewProvider || _load_OutlineViewProvider()).OutlineViewProvider.register(this._config.name, this._config.grammars, outlineConfig, this._connectionToLanguageService)); } const coverageConfig = this._config.coverage; if (coverageConfig != null) { - this._subscriptions.add( - TypeCoverageProvider.register( - this._config.name, - this._selector(), - coverageConfig, - this._connectionToLanguageService, - ), - ); + this._subscriptions.add((_TypeCoverageProvider || _load_TypeCoverageProvider()).TypeCoverageProvider.register(this._config.name, this._selector(), coverageConfig, this._connectionToLanguageService)); } const definitionConfig = this._config.definition; if (definitionConfig != null) { - this._subscriptions.add( - DefinitionProvider.register( - this._config.name, - this._config.grammars, - definitionConfig, - this._connectionToLanguageService, - ), - ); + this._subscriptions.add((_DefinitionProvider || _load_DefinitionProvider()).DefinitionProvider.register(this._config.name, this._config.grammars, definitionConfig, this._connectionToLanguageService)); } const typeHintConfig = this._config.typeHint; if (typeHintConfig != null) { - this._subscriptions.add( - TypeHintProvider.register( - this._config.name, - this._selector(), - typeHintConfig, - this._connectionToLanguageService, - ), - ); + this._subscriptions.add((_TypeHintProvider || _load_TypeHintProvider()).TypeHintProvider.register(this._config.name, this._selector(), typeHintConfig, this._connectionToLanguageService)); } const codeFormatConfig = this._config.codeFormat; if (codeFormatConfig != null) { - this._subscriptions.add( - CodeFormatProvider.register( - this._config.name, - this._config.grammars, - codeFormatConfig, - this._connectionToLanguageService, - ), - ); + this._subscriptions.add((_CodeFormatProvider || _load_CodeFormatProvider()).CodeFormatProvider.register(this._config.name, this._config.grammars, codeFormatConfig, this._connectionToLanguageService)); } const findReferencesConfig = this._config.findReferences; if (findReferencesConfig != null) { - this._subscriptions.add( - FindReferencesProvider.register( - this._config.name, - this._config.grammars, - findReferencesConfig, - this._connectionToLanguageService, - ), - ); + this._subscriptions.add((_FindReferencesProvider || _load_FindReferencesProvider()).FindReferencesProvider.register(this._config.name, this._config.grammars, findReferencesConfig, this._connectionToLanguageService)); } const autocompleteConfig = this._config.autocomplete; if (autocompleteConfig != null) { - this._subscriptions.add( - AutocompleteProvider.register( - this._config.name, - this._config.grammars, - autocompleteConfig, - this._onDidInsertSuggestion, - this._connectionToLanguageService, - ), - ); + this._subscriptions.add((_AutocompleteProvider || _load_AutocompleteProvider()).AutocompleteProvider.register(this._config.name, this._config.grammars, autocompleteConfig, this._onDidInsertSuggestion, this._connectionToLanguageService)); } const diagnosticsConfig = this._config.diagnostics; if (diagnosticsConfig != null) { - this._subscriptions.add( - registerDiagnostics( - this._config.name, - this._config.grammars, - diagnosticsConfig, - this._logger, - this._connectionToLanguageService, - busySignalProvider, - ), - ); + this._subscriptions.add((0, (_DiagnosticsProvider || _load_DiagnosticsProvider()).registerDiagnostics)(this._config.name, this._config.grammars, diagnosticsConfig, this._logger, this._connectionToLanguageService, busySignalProvider)); } const codeActionConfig = this._config.codeAction; if (codeActionConfig != null) { - this._subscriptions.add( - CodeActionProvider.register( - this._config.name, - this._config.grammars, - codeActionConfig, - this._connectionToLanguageService, - ), - ); + this._subscriptions.add((_CodeActionProvider || _load_CodeActionProvider()).CodeActionProvider.register(this._config.name, this._config.grammars, codeActionConfig, this._connectionToLanguageService)); } - const {signatureHelp} = this._config; + const { signatureHelp } = this._config; if (signatureHelp != null) { - this._subscriptions.add( - SignatureHelpProvider.register( - this._config.grammars, - signatureHelp, - this._connectionToLanguageService, - ), - ); + this._subscriptions.add((_SignatureHelpProvider || _load_SignatureHelpProvider()).SignatureHelpProvider.register(this._config.grammars, signatureHelp, this._connectionToLanguageService)); } const syntacticSelection = this._config.syntacticSelection; if (syntacticSelection != null) { - this._subscriptions.add( - SyntacticSelectionProvider.register( - this._config.name, - this._config.grammars, - syntacticSelection, - this._connectionToLanguageService, - ), - ); + this._subscriptions.add((_SyntacticSelectionProvider || _load_SyntacticSelectionProvider()).SyntacticSelectionProvider.register(this._config.name, this._config.grammars, syntacticSelection, this._connectionToLanguageService)); } const status = this._config.status; if (status != null) { - this._subscriptions.add( - StatusProvider.register( - this._config.name, - this._config.grammars, - status, - this._connectionToLanguageService, - ), - ); + this._subscriptions.add((_StatusProvider || _load_StatusProvider()).StatusProvider.register(this._config.name, this._config.grammars, status, this._connectionToLanguageService)); } - this._subscriptions.add( - LanguageAdditionalLogFilesProvider.register( - this._config.name, - this._connectionToLanguageService, - ), - ); + this._subscriptions.add((_AdditionalLogFileProvider || _load_AdditionalLogFileProvider()).LanguageAdditionalLogFilesProvider.register(this._config.name, this._connectionToLanguageService)); } - async getLanguageServiceForUri(fileUri: ?NuclideUri): Promise { + async getLanguageServiceForUri(fileUri) { return this._connectionToLanguageService.getForUri(fileUri); } - async isFileInProject(fileUri: NuclideUri): Promise { - const languageService = this._connectionToLanguageService.getExistingForUri( - fileUri, - ); + async isFileInProject(fileUri) { + const languageService = this._connectionToLanguageService.getExistingForUri(fileUri); if (languageService == null) { return false; } return (await languageService).isFileInProject(fileUri); } - getCachedLanguageServices(): Iterator<[?ServerConnection, Promise]> { + getCachedLanguageServices() { return this._connectionToLanguageService.entries(); } - observeLanguageServices(): Observable { - return this._connectionToLanguageService - .observeValues() - .switchMap(languageService => { - return Observable.fromPromise(languageService); - }); + observeLanguageServices() { + return this._connectionToLanguageService.observeValues().switchMap(languageService => { + return _rxjsBundlesRxMinJs.Observable.fromPromise(languageService); + }); } - observeConnectionLanguageEntries(): Observable<[?ServerConnection, T]> { - return this._connectionToLanguageService - .observeEntries() - .switchMap(([connection, servicePromise]) => { - return Observable.fromPromise(servicePromise).map(languageService => [ - connection, - languageService, - ]); - }); + observeConnectionLanguageEntries() { + return this._connectionToLanguageService.observeEntries().switchMap(([connection, servicePromise]) => { + return _rxjsBundlesRxMinJs.Observable.fromPromise(servicePromise).map(languageService => [connection, languageService]); + }); } - dispose(): void { + dispose() { this._subscriptions.dispose(); } } +exports.AtomLanguageService = AtomLanguageService; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/AutocompleteProvider.js b/pkg/nuclide-language-service/lib/AutocompleteProvider.js index 97927cd13f..1e84724df6 100644 --- a/pkg/nuclide-language-service/lib/AutocompleteProvider.js +++ b/pkg/nuclide-language-service/lib/AutocompleteProvider.js @@ -1,80 +1,60 @@ -/** - * 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 - */ - -import type {AutocompleteCacherConfig} from '../../commons-atom/AutocompleteCacher'; - -import type { - AutocompleteResult, - AutocompleteRequest, - Completion, - LanguageService, -} from './LanguageService'; -import type {AutocompleteAnalytics} from '../../nuclide-autocomplete/lib/types'; - -import invariant from 'assert'; -import fuzzaldrinPlus from 'fuzzaldrin-plus'; -import {Point, Range} from 'simple-text-buffer'; -import {wordAtPosition} from 'nuclide-commons-atom/range'; -import {ConnectionCache} from '../../nuclide-remote-connection'; -import {getFileVersionOfEditor} from '../../nuclide-open-files'; -import AutocompleteCacher from '../../commons-atom/AutocompleteCacher'; -import {applyTextEditsToBuffer} from 'nuclide-commons-atom/text-edit'; - -export type OnDidInsertSuggestionArgument = { - editor: atom$TextEditor, - triggerPosition: atom$Point, - suggestion: Completion, -}; - -export type OnDidInsertSuggestionCallback = ( - arg: OnDidInsertSuggestionArgument, -) => mixed; - -export type AutocompleteConfig = {| - inclusionPriority: number, - suggestionPriority: number, - disableForSelector: ?string, - excludeLowerPriority: boolean, - analytics: AutocompleteAnalytics, - autocompleteCacherConfig: ?AutocompleteCacherConfig, - supportsResolve: boolean, -|}; - -export class AutocompleteProvider { - name: string; - selector: string; - inclusionPriority: number; - suggestionPriority: number; - disableForSelector: ?string; - excludeLowerPriority: boolean; - analytics: AutocompleteAnalytics; - onDidInsertSuggestion: OnDidInsertSuggestionCallback; - _onDidInsertSuggestion: ?OnDidInsertSuggestionCallback; - _connectionToLanguageService: ConnectionCache; - _autocompleteCacher: ?AutocompleteCacher; - _supportsResolve: boolean; - - constructor( - name: string, - selector: string, - inclusionPriority: number, - suggestionPriority: number, - disableForSelector: ?string, - excludeLowerPriority: boolean, - analytics: AutocompleteAnalytics, - onDidInsertSuggestion: ?OnDidInsertSuggestionCallback, - autocompleteCacherConfig: ?AutocompleteCacherConfig, - connectionToLanguageService: ConnectionCache, - supportsResolve: boolean, - ) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AutocompleteProvider = undefined; +exports.updateAutocompleteResults = updateAutocompleteResults; +exports.updateAutocompleteFirstResults = updateAutocompleteFirstResults; +exports.updateAutocompleteResultRanges = updateAutocompleteResultRanges; + +var _fuzzaldrinPlus; + +function _load_fuzzaldrinPlus() { + return _fuzzaldrinPlus = _interopRequireDefault(require('fuzzaldrin-plus')); +} + +var _simpleTextBuffer; + +function _load_simpleTextBuffer() { + return _simpleTextBuffer = require('simple-text-buffer'); +} + +var _range; + +function _load_range() { + return _range = require('../../../modules/nuclide-commons-atom/range'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideOpenFiles; + +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} + +var _AutocompleteCacher; + +function _load_AutocompleteCacher() { + return _AutocompleteCacher = _interopRequireDefault(require('../../commons-atom/AutocompleteCacher')); +} + +var _textEdit; + +function _load_textEdit() { + return _textEdit = require('../../../modules/nuclide-commons-atom/text-edit'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class AutocompleteProvider { + + constructor(name, selector, inclusionPriority, suggestionPriority, disableForSelector, excludeLowerPriority, analytics, onDidInsertSuggestion, autocompleteCacherConfig, connectionToLanguageService, supportsResolve) { this.name = name; this.selector = selector; this.inclusionPriority = inclusionPriority; @@ -85,10 +65,7 @@ export class AutocompleteProvider { this._supportsResolve = supportsResolve; if (autocompleteCacherConfig != null) { - this._autocompleteCacher = new AutocompleteCacher( - request => this._getSuggestionsFromLanguageService(request), - autocompleteCacherConfig, - ); + this._autocompleteCacher = new (_AutocompleteCacher || _load_AutocompleteCacher()).default(request => this._getSuggestionsFromLanguageService(request), autocompleteCacherConfig); } this._onDidInsertSuggestion = onDidInsertSuggestion; @@ -103,38 +80,13 @@ export class AutocompleteProvider { this.analytics = analytics; } - static register( - name: string, - grammars: Array, - config: AutocompleteConfig, - onDidInsertSuggestion: ?OnDidInsertSuggestionCallback, - connectionToLanguageService: ConnectionCache, - ): IDisposable { - return atom.packages.serviceHub.provide( - 'nuclide-autocomplete.provider', - '0.0.0', - new AutocompleteProvider( - name, - // tree-sitter grammars won't include the ".". - grammars - .map(grammar => (grammar.includes('.') ? '.' + grammar : grammar)) - .join(', '), - config.inclusionPriority, - config.suggestionPriority, - config.disableForSelector, - config.excludeLowerPriority, - config.analytics, - onDidInsertSuggestion, - config.autocompleteCacherConfig, - connectionToLanguageService, - config.supportsResolve, - ), - ); + static register(name, grammars, config, onDidInsertSuggestion, connectionToLanguageService) { + return atom.packages.serviceHub.provide('nuclide-autocomplete.provider', '0.0.0', new AutocompleteProvider(name, + // tree-sitter grammars won't include the ".". + grammars.map(grammar => grammar.includes('.') ? '.' + grammar : grammar).join(', '), config.inclusionPriority, config.suggestionPriority, config.disableForSelector, config.excludeLowerPriority, config.analytics, onDidInsertSuggestion, config.autocompleteCacherConfig, connectionToLanguageService, config.supportsResolve)); } - async getSuggestions( - request: atom$AutocompleteRequest, - ): Promise> { + async getSuggestions(request) { let result; if (this._autocompleteCacher != null) { result = await this._autocompleteCacher.getSuggestions(request); @@ -144,32 +96,24 @@ export class AutocompleteProvider { return result != null ? result.items : null; } - async _getSuggestionsFromLanguageService( - request: atom$AutocompleteRequest, - ): Promise { - const {editor} = request; + async _getSuggestionsFromLanguageService(request) { + const { editor } = request; const editorPath = editor.getPath(); - const languageService = this._connectionToLanguageService.getForUri( - editorPath, - ); - const fileVersion = await getFileVersionOfEditor(editor); + const languageService = this._connectionToLanguageService.getForUri(editorPath); + const fileVersion = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor); if (languageService == null || fileVersion == null) { - return {isIncomplete: false, items: []}; + return { isIncomplete: false, items: [] }; } const langSpecificPrefix = getLanguageSpecificPrefix(request); - const results = await (await languageService).getAutocompleteSuggestions( - fileVersion, - getPosition(request), - generateAutocompleteRequest(request, langSpecificPrefix), - ); + const results = await (await languageService).getAutocompleteSuggestions(fileVersion, getPosition(request), generateAutocompleteRequest(request, langSpecificPrefix)); if (results == null) { return null; } const uniqueIndex = Math.floor(Math.random() * 1000000000); - results.items.forEach((c: Completion, index) => { + results.items.forEach((c, index) => { // textEdits aren't part of autocomplete-plus - we handle it in // onDidInsertSuggestion above. We need to make this suggestion a no-op otherwise. // There's no perfect solution at the moment, but the two options are: @@ -194,42 +138,36 @@ export class AutocompleteProvider { c.snippet = `$${uniqueIndex + index}`; // Don't try to replace anything. c.replacementPrefix = ''; - } else if ( - c.replacementPrefix == null && - langSpecificPrefix !== request.prefix - ) { + } else if (c.replacementPrefix == null && langSpecificPrefix !== request.prefix) { // Here's where we patch up the prefix in the results, if necessary c.replacementPrefix = langSpecificPrefix; } - invariant(editorPath != null); + if (!(editorPath != null)) { + throw new Error('Invariant violation: "editorPath != null"'); + } + c.remoteUri = editorPath; }); return results; } - async getSuggestionDetailsOnSelect( - suggestion: Completion, - ): Promise { + async getSuggestionDetailsOnSelect(suggestion) { if (!this._supportsResolve) { return null; } - const languageService = this._connectionToLanguageService.getForUri( - suggestion.remoteUri, - ); + const languageService = this._connectionToLanguageService.getForUri(suggestion.remoteUri); if (languageService == null) { return null; } - const resolved = await (await languageService).resolveAutocompleteSuggestion( - suggestion, - ); + const resolved = await (await languageService).resolveAutocompleteSuggestion(suggestion); if (resolved != null) { // A few members of the suggestion aren't RPC-able (such as the provider), // so merge the objects together. - const result = {...suggestion, ...resolved}; + const result = Object.assign({}, suggestion, resolved); // Some language services (such as LspLanguageService) store a separate // cached version of the original completion that we're resolving since @@ -244,12 +182,8 @@ export class AutocompleteProvider { if (suggestion.textEdits != null && resolved.textEdits != null) { const suggestionTextEdits = suggestion.textEdits; const resolvedTextEdits = resolved.textEdits; - const localTextEdits = new Map( - suggestionTextEdits.map(textEdit => [textEdit.newText, textEdit]), - ); - const remoteTextEdits = new Map( - resolvedTextEdits.map(textEdit => [textEdit.newText, textEdit]), - ); + const localTextEdits = new Map(suggestionTextEdits.map(textEdit => [textEdit.newText, textEdit])); + const remoteTextEdits = new Map(resolvedTextEdits.map(textEdit => [textEdit.newText, textEdit])); localTextEdits.forEach((textEdit, idx) => { const remoteTextEdit = remoteTextEdits.get(idx); if (remoteTextEdit != null) { @@ -265,10 +199,19 @@ export class AutocompleteProvider { } } -function maybeApplyTextEdits( - insertedSuggestionArgument: OnDidInsertSuggestionArgument, -) { - const {editor, suggestion} = insertedSuggestionArgument; +exports.AutocompleteProvider = AutocompleteProvider; /** + * 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. + * + * + * @format + */ + +function maybeApplyTextEdits(insertedSuggestionArgument) { + const { editor, suggestion } = insertedSuggestionArgument; const textEdits = suggestion.textEdits; if (textEdits != null) { const cursors = editor.getCursors(); @@ -278,28 +221,23 @@ function maybeApplyTextEdits( // existing multi-autocomplete functionality that we had in insertText // completions. const textEdit = textEdits[0]; - const matches = cursor => - cursor.getBufferPosition().isEqual(textEdit.oldRange.end); + const matches = cursor => cursor.getBufferPosition().isEqual(textEdit.oldRange.end); const shouldCopy = cursors.some(matches); if (shouldCopy) { - const columnDelta = - textEdit.oldRange.end.column - textEdit.oldRange.start.column; + const columnDelta = textEdit.oldRange.end.column - textEdit.oldRange.start.column; for (const cursor of cursors) { if (!matches(cursor) && cursor.getBufferColumn() - columnDelta >= 0) { const newOldEnd = cursor.getBufferPosition(); - const newOldStart = Point.fromObject([ - newOldEnd.row, - newOldEnd.column - columnDelta, - ]); - const newOldRange = Range.fromObject([newOldStart, newOldEnd]); - textEdits.push({...textEdit, oldRange: newOldRange}); + const newOldStart = (_simpleTextBuffer || _load_simpleTextBuffer()).Point.fromObject([newOldEnd.row, newOldEnd.column - columnDelta]); + const newOldRange = (_simpleTextBuffer || _load_simpleTextBuffer()).Range.fromObject([newOldStart, newOldEnd]); + textEdits.push(Object.assign({}, textEdit, { oldRange: newOldRange })); } } } } - applyTextEditsToBuffer(editor.getBuffer(), textEdits); + (0, (_textEdit || _load_textEdit()).applyTextEditsToBuffer)(editor.getBuffer(), textEdits); } } @@ -331,8 +269,8 @@ function maybeApplyTextEdits( // prefix from Autocomplete's, then we'll suggest that to the language // service, and we'll patch the output of the language service to reflect // this. -function getLanguageSpecificPrefix(request: atom$AutocompleteRequest): string { - const {editor} = request; +function getLanguageSpecificPrefix(request) { + const { editor } = request; const position = getPosition(request); const defaultWordRules = editor.getNonWordCharacters(); @@ -346,7 +284,7 @@ function getLanguageSpecificPrefix(request: atom$AutocompleteRequest): string { // In case of automatic requests, we'd like to know what character triggered // the autocomplete request. That information isn't provided to us, so the // best we can do is find the character to the left of the position. -function findTriggerCharacter(request: atom$AutocompleteRequest): ?string { +function findTriggerCharacter(request) { if (request.activatedManually != null && request.activatedManually) { return null; } @@ -356,71 +294,51 @@ function findTriggerCharacter(request: atom$AutocompleteRequest): ?string { return '\n'; } - const range = new Range([position.row, position.column - 1], position); + const range = new (_simpleTextBuffer || _load_simpleTextBuffer()).Range([position.row, position.column - 1], position); return request.editor.getTextInBufferRange(range); } // TODO(ljw): the following line uses the position of the cursor -- // shouldn't it be using request.bufferPosition instead? -function getPosition(request: atom$AutocompleteRequest): atom$Point { +function getPosition(request) { return request.editor.getLastCursor().getBufferPosition(); } -function generateAutocompleteRequest( - request: atom$AutocompleteRequest, - prefix: string, -): AutocompleteRequest { - const {activatedManually} = request; +function generateAutocompleteRequest(request, prefix) { + const { activatedManually } = request; return { activatedManually: activatedManually == null ? false : activatedManually, triggerCharacter: findTriggerCharacter(request), - prefix, + prefix }; } -function findAtomWordPrefix( - editor: atom$TextEditor, - position: atom$Point, -): string { - const positionOneCharBefore = new Point( - position.row, - Math.max(0, position.column - 1), - ); - const match = wordAtPosition(editor, positionOneCharBefore, { - includeNonWordCharacters: false, +function findAtomWordPrefix(editor, position) { + const positionOneCharBefore = new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(position.row, Math.max(0, position.column - 1)); + const match = (0, (_range || _load_range()).wordAtPosition)(editor, positionOneCharBefore, { + includeNonWordCharacters: false }); if (match == null) { return ''; } - return editor.getTextInBufferRange(new Range(match.range.start, position)); + return editor.getTextInBufferRange(new (_simpleTextBuffer || _load_simpleTextBuffer()).Range(match.range.start, position)); } -function padEnd(s: string, targetLength: number, padString: string): string { +function padEnd(s, targetLength, padString) { const padLength = Math.max(targetLength - s.length, 0); return s + padString.repeat(padLength); } -export function updateAutocompleteResults( - originalRequest: atom$AutocompleteRequest, - currentRequest: atom$AutocompleteRequest, - firstResult: AutocompleteResult, -): ?AutocompleteResult { +function updateAutocompleteResults(originalRequest, currentRequest, firstResult) { if (firstResult.isIncomplete) { return null; } const results = updateAutocompleteFirstResults(currentRequest, firstResult); - return updateAutocompleteResultRanges( - originalRequest, - currentRequest, - results, - ); + return updateAutocompleteResultRanges(originalRequest, currentRequest, results); } -export function updateAutocompleteFirstResults( - request: atom$AutocompleteRequest, - firstResult: AutocompleteResult, -): AutocompleteResult { +function updateAutocompleteFirstResults(request, firstResult) { // This function is sometimes called because the user invoked autocomplete // manually, e.g. pressing ctrl+space at "x.|" or "x.f|". Or it's invoked // from updateAutocompleteResults because there was it had previously @@ -455,23 +373,19 @@ export function updateAutocompleteFirstResults( // This 'reduce' takes ~25ms for 1000 items, largely in the scoring. The rest // of the function takes negligible time. - const baseScore = prefix === '' ? 1 : fuzzaldrinPlus.score(prefix, prefix); + const baseScore = prefix === '' ? 1 : (_fuzzaldrinPlus || _load_fuzzaldrinPlus()).default.score(prefix, prefix); - const items: Array<{filterScore: number, completion: Completion}> = []; + const items = []; for (const item of firstResult.items) { // If there are text edits, the first one will be used for scoring purposes. - const firstTextEdit = - item.textEdits != null && item.textEdits.length > 0 - ? item.textEdits[0].newText - : null; + const firstTextEdit = item.textEdits != null && item.textEdits.length > 0 ? item.textEdits[0].newText : null; const text = - // flowlint-next-line sketchy-null-string:off - item.displayText || item.snippet || item.text || firstTextEdit || ''; + // flowlint-next-line sketchy-null-string:off + item.displayText || item.snippet || item.text || firstTextEdit || ''; // flowlint-next-line sketchy-null-string:off const filterText = padEnd(item.filterText || text, 40, ' '); // If no prefix, then include all items and avoid doing work to score. - const filterScore: number = - prefix === '' ? 1 : fuzzaldrinPlus.score(filterText, prefix); + const filterScore = prefix === '' ? 1 : (_fuzzaldrinPlus || _load_fuzzaldrinPlus()).default.score(filterText, prefix); // Score of 0 means the item fails the filter. if (filterScore === 0) { continue; @@ -480,16 +394,15 @@ export function updateAutocompleteFirstResults( if (filterScore / baseScore < SCORE_THRESHOLD) { continue; } - const completion: Completion = { - ...item, + const completion = Object.assign({}, item, { // flowlint-next-line sketchy-null-string:off - sortText: item.sortText || text, - }; + sortText: item.sortText || text + }); // If there are no textEdits, then a replacement prefix is needed. if (firstTextEdit == null) { completion.replacementPrefix = prefix; } - items.push({filterScore, completion}); + items.push({ filterScore, completion }); } // Step [2+3]: sort by filterScore, and within that by sortText. We do a sort @@ -504,7 +417,11 @@ export function updateAutocompleteFirstResults( } else { const a = itemA.completion.sortText; const b = itemB.completion.sortText; - invariant(a != null && b != null); + + if (!(a != null && b != null)) { + throw new Error('Invariant violation: "a != null && b != null"'); + } + if (a.startsWith('_') === b.startsWith('_')) { return a.localeCompare(b); } else if (a.startsWith('_')) { @@ -515,19 +432,13 @@ export function updateAutocompleteFirstResults( } }); - return {...firstResult, items: items.map(item => item.completion)}; + return Object.assign({}, firstResult, { items: items.map(item => item.completion) }); } // Gotta be careful not to mutate here or we could mess up the cache for // subsequent requests. -export function updateAutocompleteResultRanges( - originalRequest: atom$AutocompleteRequest, - currentRequest: atom$AutocompleteRequest, - cachedResult: AutocompleteResult, -): AutocompleteResult { - const needsUpdate = cachedResult.items.some( - item => item.textEdits != null && item.textEdits.length > 0, - ); +function updateAutocompleteResultRanges(originalRequest, currentRequest, cachedResult) { + const needsUpdate = cachedResult.items.some(item => item.textEdits != null && item.textEdits.length > 0); if (!needsUpdate) { return cachedResult; } @@ -539,27 +450,19 @@ export function updateAutocompleteResultRanges( const textEdits = item.textEdits.map(textEdit => { const oldRange = textEdit.oldRange; - if ( - oldRange.end.column === originalRequest.bufferPosition.column && - oldRange.end.row === originalRequest.bufferPosition.row - ) { - return { - ...textEdit, - oldRange: new Range( - oldRange.start, - new Point(oldRange.end.row, currentRequest.bufferPosition.column), - ), - }; + if (oldRange.end.column === originalRequest.bufferPosition.column && oldRange.end.row === originalRequest.bufferPosition.row) { + return Object.assign({}, textEdit, { + oldRange: new (_simpleTextBuffer || _load_simpleTextBuffer()).Range(oldRange.start, new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(oldRange.end.row, currentRequest.bufferPosition.column)) + }); } else { return textEdit; } }); - return {...item, textEdits}; + return Object.assign({}, item, { textEdits }); }); - return { - ...cachedResult, - items, - }; -} + return Object.assign({}, cachedResult, { + items + }); +} \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/CodeActionProvider.js b/pkg/nuclide-language-service/lib/CodeActionProvider.js index c58fe8fd75..d68f5a6948 100644 --- a/pkg/nuclide-language-service/lib/CodeActionProvider.js +++ b/pkg/nuclide-language-service/lib/CodeActionProvider.js @@ -1,46 +1,31 @@ -/** - * 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 - */ +'use strict'; -import type {LanguageService} from './LanguageService'; -import type { - CodeAction, - CodeActionProvider as CodeActionProviderType, - DiagnosticMessage, -} from 'atom-ide-ui'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.CodeActionProvider = undefined; -import {ConnectionCache} from '../../nuclide-remote-connection'; -import {getFileVersionOfEditor} from '../../nuclide-open-files'; -import {trackTiming} from '../../nuclide-analytics'; +var _nuclideRemoteConnection; -export type CodeActionConfig = {| - version: '0.1.0', - priority: number, - analyticsEventName: string, - applyAnalyticsEventName: string, -|}; +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} -export class CodeActionProvider { - grammarScopes: Array; - priority: number; - name: string; - _analyticsEventName: string; - _applyAnalyticsEventName: string; - _connectionToLanguageService: ConnectionCache; +var _nuclideOpenFiles; - constructor( - name: string, - grammarScopes: Array, - config: CodeActionConfig, - connectionToLanguageService: ConnectionCache, - ) { +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +class CodeActionProvider { + + constructor(name, grammarScopes, config, connectionToLanguageService) { this.name = name; this.grammarScopes = grammarScopes; this.priority = config.priority; @@ -49,63 +34,48 @@ export class CodeActionProvider { this._connectionToLanguageService = connectionToLanguageService; } - static register( - name: string, - grammarScopes: Array, - config: CodeActionConfig, - connectionToLanguageService: ConnectionCache, - ): IDisposable { - return atom.packages.serviceHub.provide( - 'code-actions', - config.version, - new CodeActionProvider( - name, - grammarScopes, - config, - connectionToLanguageService, - ), - ); + static register(name, grammarScopes, config, connectionToLanguageService) { + return atom.packages.serviceHub.provide('code-actions', config.version, new CodeActionProvider(name, grammarScopes, config, connectionToLanguageService)); } - getCodeActions( - editor: atom$TextEditor, - range: atom$Range, - diagnostics: Array, - ): Promise> { - return trackTiming(this._analyticsEventName, async () => { - const fileVersion = await getFileVersionOfEditor(editor); - const languageService = this._connectionToLanguageService.getForUri( - editor.getPath(), - ); + getCodeActions(editor, range, diagnostics) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(this._analyticsEventName, async () => { + const fileVersion = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor); + const languageService = this._connectionToLanguageService.getForUri(editor.getPath()); if (languageService == null || fileVersion == null) { return []; } - const codeActions = await (await languageService).getCodeActions( - fileVersion, - range, - // $FlowIssue: Flow doesn't understand this. - diagnostics.map(d => ({...d, actions: undefined})), - ); + const codeActions = await (await languageService).getCodeActions(fileVersion, range, + // $FlowIssue: Flow doesn't understand this. + diagnostics.map(d => Object.assign({}, d, { actions: undefined }))); return codeActions.map(action => ({ apply: () => { - return trackTiming( - this._applyAnalyticsEventName, - action.apply.bind(action), - ); + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(this._applyAnalyticsEventName, action.apply.bind(action)); }, getTitle() { return action.getTitle(); }, dispose() { return action.dispose(); - }, + } })); }); } } -// Ensures that CodeActionProvider has all the fields and methods defined in +exports.CodeActionProvider = CodeActionProvider; // Ensures that CodeActionProvider has all the fields and methods defined in // the CodeActionProvider type in the atom-ide-code-actions package. -(((null: any): CodeActionProvider): CodeActionProviderType); +/** + * 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. + * + * + * @format + */ + +null; \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/CodeFormatProvider.js b/pkg/nuclide-language-service/lib/CodeFormatProvider.js index baf4663a0c..ca8bb37adf 100644 --- a/pkg/nuclide-language-service/lib/CodeFormatProvider.js +++ b/pkg/nuclide-language-service/lib/CodeFormatProvider.js @@ -1,60 +1,39 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {FormatOptions, LanguageService} from './LanguageService'; -import type { - RangeCodeFormatProvider, - FileCodeFormatProvider, - OnTypeCodeFormatProvider, -} from 'atom-ide-ui'; -import type {TextEdit} from 'nuclide-commons-atom/text-edit'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.CodeFormatProvider = undefined; -import {ConnectionCache} from '../../nuclide-remote-connection'; -import {trackTiming} from '../../nuclide-analytics'; -import {getFileVersionOfEditor} from '../../nuclide-open-files'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; +var _nuclideRemoteConnection; -export type CodeFormatConfig = {| - version: '0.1.0', - priority: number, - analyticsEventName: string, +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} - // If true, support formatting at ranges. Also, use the range formatter to - // format the whole document. If false, only support formatting the whole - // document, using the document formatter. - canFormatRanges: boolean, +var _nuclideOpenFiles; - // If true, support formatting at a position (such as for as-you-type - // formatting). If false, don't support that. - canFormatAtPosition: boolean, +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} - // If true, cursor will be moved back to original position after TextEdit(s) - // are applied. If false, TextEdit(s) may move the cursor. - keepCursorPosition?: boolean, -|}; +var _UniversalDisposable; -export class CodeFormatProvider { - name: string; - grammarScopes: Array; - priority: number; - _analyticsEventName: string; - _connectionToLanguageService: ConnectionCache; +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} - constructor( - name: string, - grammarScopes: Array, - priority: number, - analyticsEventName: string, - connectionToLanguageService: ConnectionCache, - ) { +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class CodeFormatProvider { + + constructor(name, grammarScopes, priority, analyticsEventName, connectionToLanguageService) { this.name = name; this.grammarScopes = grammarScopes; this.priority = priority; @@ -62,91 +41,39 @@ export class CodeFormatProvider { this._connectionToLanguageService = connectionToLanguageService; } - static register( - name: string, - grammarScopes: Array, - config: CodeFormatConfig, - connectionToLanguageService: ConnectionCache, - ): IDisposable { - const disposable = new UniversalDisposable( - config.canFormatRanges - ? atom.packages.serviceHub.provide( - 'code-format.range', - config.version, - new RangeFormatProvider( - name, - grammarScopes, - config.priority, - config.analyticsEventName, - connectionToLanguageService, - ).provide(), - ) - : atom.packages.serviceHub.provide( - 'code-format.file', - config.version, - new FileFormatProvider( - name, - grammarScopes, - config.priority, - config.analyticsEventName, - connectionToLanguageService, - ).provide(), - ), - ); + static register(name, grammarScopes, config, connectionToLanguageService) { + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(config.canFormatRanges ? atom.packages.serviceHub.provide('code-format.range', config.version, new RangeFormatProvider(name, grammarScopes, config.priority, config.analyticsEventName, connectionToLanguageService).provide()) : atom.packages.serviceHub.provide('code-format.file', config.version, new FileFormatProvider(name, grammarScopes, config.priority, config.analyticsEventName, connectionToLanguageService).provide())); if (config.canFormatAtPosition) { - disposable.add( - atom.packages.serviceHub.provide( - 'code-format.onType', - config.version, - new PositionFormatProvider( - name, - grammarScopes, - config.priority, - config.analyticsEventName, - connectionToLanguageService, - config.keepCursorPosition, - ).provide(), - ), - ); + disposable.add(atom.packages.serviceHub.provide('code-format.onType', config.version, new PositionFormatProvider(name, grammarScopes, config.priority, config.analyticsEventName, connectionToLanguageService, config.keepCursorPosition).provide())); } return disposable; } } -class RangeFormatProvider extends CodeFormatProvider { - constructor( - name: string, - grammarScopes: Array, - priority: number, - analyticsEventName: string, - connectionToLanguageService: ConnectionCache, - ) { - super( - name, - grammarScopes, - priority, - analyticsEventName, - connectionToLanguageService, - ); +exports.CodeFormatProvider = CodeFormatProvider; /** + * 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. + * + * strict-local + * @format + */ + +class RangeFormatProvider extends CodeFormatProvider { + constructor(name, grammarScopes, priority, analyticsEventName, connectionToLanguageService) { + super(name, grammarScopes, priority, analyticsEventName, connectionToLanguageService); } - formatCode( - editor: atom$TextEditor, - range: atom$Range, - ): Promise> { - return trackTiming(this._analyticsEventName, async () => { - const fileVersion = await getFileVersionOfEditor(editor); - const languageService = this._connectionToLanguageService.getForUri( - editor.getPath(), - ); + formatCode(editor, range) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(this._analyticsEventName, async () => { + const fileVersion = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor); + const languageService = this._connectionToLanguageService.getForUri(editor.getPath()); if (languageService != null && fileVersion != null) { - const result = await (await languageService).formatSource( - fileVersion, - range, - getFormatOptions(editor), - ); + const result = await (await languageService).formatSource(fileVersion, range, getFormatOptions(editor)); if (result != null) { return result; } @@ -156,106 +83,57 @@ class RangeFormatProvider extends CodeFormatProvider { }); } - provide(): RangeCodeFormatProvider { + provide() { return { formatCode: this.formatCode.bind(this), grammarScopes: this.grammarScopes, - priority: this.priority, + priority: this.priority }; } } -class FileFormatProvider extends CodeFormatProvider { - constructor( - name: string, - grammarScopes: Array, - priority: number, - analyticsEventName: string, - connectionToLanguageService: ConnectionCache, - ) { - super( - name, - grammarScopes, - priority, - analyticsEventName, - connectionToLanguageService, - ); +class FileFormatProvider extends CodeFormatProvider { + constructor(name, grammarScopes, priority, analyticsEventName, connectionToLanguageService) { + super(name, grammarScopes, priority, analyticsEventName, connectionToLanguageService); } - formatEntireFile( - editor: atom$TextEditor, - range: atom$Range, - ): Promise<{ - newCursor?: number, - formatted: string, - }> { - return trackTiming(this._analyticsEventName, async () => { - const fileVersion = await getFileVersionOfEditor(editor); - const languageService = this._connectionToLanguageService.getForUri( - editor.getPath(), - ); + formatEntireFile(editor, range) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(this._analyticsEventName, async () => { + const fileVersion = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor); + const languageService = this._connectionToLanguageService.getForUri(editor.getPath()); if (languageService != null && fileVersion != null) { - const result = await (await languageService).formatEntireFile( - fileVersion, - range, - getFormatOptions(editor), - ); + const result = await (await languageService).formatEntireFile(fileVersion, range, getFormatOptions(editor)); if (result != null) { return result; } } - return {formatted: editor.getText()}; + return { formatted: editor.getText() }; }); } - provide(): FileCodeFormatProvider { + provide() { return { formatEntireFile: this.formatEntireFile.bind(this), grammarScopes: this.grammarScopes, - priority: this.priority, + priority: this.priority }; } } -class PositionFormatProvider extends CodeFormatProvider { - keepCursorPosition: boolean; +class PositionFormatProvider extends CodeFormatProvider { - constructor( - name: string, - grammarScopes: Array, - priority: number, - analyticsEventName: string, - connectionToLanguageService: ConnectionCache, - keepCursorPosition?: boolean = false, - ) { - super( - name, - grammarScopes, - priority, - analyticsEventName, - connectionToLanguageService, - ); + constructor(name, grammarScopes, priority, analyticsEventName, connectionToLanguageService, keepCursorPosition = false) { + super(name, grammarScopes, priority, analyticsEventName, connectionToLanguageService); this.keepCursorPosition = keepCursorPosition; } - formatAtPosition( - editor: atom$TextEditor, - position: atom$Point, - character: string, - ): Promise> { - return trackTiming(this._analyticsEventName, async () => { - const fileVersion = await getFileVersionOfEditor(editor); - const languageService = this._connectionToLanguageService.getForUri( - editor.getPath(), - ); + formatAtPosition(editor, position, character) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(this._analyticsEventName, async () => { + const fileVersion = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor); + const languageService = this._connectionToLanguageService.getForUri(editor.getPath()); if (languageService != null && fileVersion != null) { - const result = await (await languageService).formatAtPosition( - fileVersion, - position, - character, - getFormatOptions(editor), - ); + const result = await (await languageService).formatAtPosition(fileVersion, position, character, getFormatOptions(editor)); if (result != null) { return result; } @@ -265,19 +143,19 @@ class PositionFormatProvider extends CodeFormatProvider { }); } - provide(): OnTypeCodeFormatProvider { + provide() { return { formatAtPosition: this.formatAtPosition.bind(this), grammarScopes: this.grammarScopes, priority: this.priority, - keepCursorPosition: this.keepCursorPosition, + keepCursorPosition: this.keepCursorPosition }; } } -function getFormatOptions(editor: atom$TextEditor): FormatOptions { +function getFormatOptions(editor) { return { tabSize: editor.getTabLength(), - insertSpaces: editor.getSoftTabs(), + insertSpaces: editor.getSoftTabs() }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/CodeHighlightProvider.js b/pkg/nuclide-language-service/lib/CodeHighlightProvider.js index 29a0d275f8..0f7218c984 100644 --- a/pkg/nuclide-language-service/lib/CodeHighlightProvider.js +++ b/pkg/nuclide-language-service/lib/CodeHighlightProvider.js @@ -1,3 +1,30 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.CodeHighlightProvider = undefined; + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideOpenFiles; + +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} + +var _atom = require('atom'); + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,38 +32,13 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {CodeHighlightProvider as CodeHighlightProviderType} from 'atom-ide-ui'; -import type {LanguageService} from './LanguageService'; - -import {trackTiming} from '../../nuclide-analytics'; -import {ConnectionCache} from '../../nuclide-remote-connection'; -import {getFileVersionOfEditor} from '../../nuclide-open-files'; -import {Range} from 'atom'; - -export type CodeHighlightConfig = {| - version: '0.1.0', - priority: number, - analyticsEventName: string, -|}; - -export class CodeHighlightProvider { - name: string; - grammarScopes: Array; - priority: number; - _analyticsEventName: string; - _connectionToLanguageService: ConnectionCache; - - constructor( - name: string, - grammarScopes: Array, - priority: number, - analyticsEventName: string, - connectionToLanguageService: ConnectionCache, - ) { +class CodeHighlightProvider { + + constructor(name, grammarScopes, priority, analyticsEventName, connectionToLanguageService) { this.name = name; this.grammarScopes = grammarScopes; this.priority = priority; @@ -44,51 +46,27 @@ export class CodeHighlightProvider { this._connectionToLanguageService = connectionToLanguageService; } - highlight( - editor: atom$TextEditor, - position: atom$Point, - ): Promise> { - return trackTiming(this._analyticsEventName, async () => { - const fileVersion = await getFileVersionOfEditor(editor); - const languageService = this._connectionToLanguageService.getForUri( - editor.getPath(), - ); + highlight(editor, position) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(this._analyticsEventName, async () => { + const fileVersion = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor); + const languageService = this._connectionToLanguageService.getForUri(editor.getPath()); if (languageService == null || fileVersion == null) { return null; } - const result = await (await languageService).highlight( - fileVersion, - position, - ); + const result = await (await languageService).highlight(fileVersion, position); if (result == null) { return null; } - return result.map(range => new Range(range.start, range.end)); + return result.map(range => new _atom.Range(range.start, range.end)); }); } - static register( - name: string, - grammarScopes: Array, - config: CodeHighlightConfig, - connectionToLanguageService: ConnectionCache, - ): IDisposable { - return atom.packages.serviceHub.provide( - 'code-highlight', - config.version, - new CodeHighlightProvider( - name, - grammarScopes, - config.priority, - config.analyticsEventName, - connectionToLanguageService, - ), - ); + static register(name, grammarScopes, config, connectionToLanguageService) { + return atom.packages.serviceHub.provide('code-highlight', config.version, new CodeHighlightProvider(name, grammarScopes, config.priority, config.analyticsEventName, connectionToLanguageService)); } } -(((null: any): CodeHighlightProvider< - LanguageService, ->): CodeHighlightProviderType); +exports.CodeHighlightProvider = CodeHighlightProvider; +null; \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/DefinitionProvider.js b/pkg/nuclide-language-service/lib/DefinitionProvider.js index 6fe05e288a..2150091d10 100644 --- a/pkg/nuclide-language-service/lib/DefinitionProvider.js +++ b/pkg/nuclide-language-service/lib/DefinitionProvider.js @@ -1,41 +1,31 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {DefinitionQueryResult} from 'atom-ide-ui'; -import type {LanguageService} from './LanguageService'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DefinitionProvider = undefined; -import {ConnectionCache} from '../../nuclide-remote-connection'; -import {trackTiming} from '../../nuclide-analytics'; -import {getFileVersionOfEditor} from '../../nuclide-open-files'; +var _nuclideRemoteConnection; -export type DefinitionConfig = {| - version: '0.1.0', - priority: number, - definitionEventName: string, -|}; +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _nuclideOpenFiles; + +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} -export class DefinitionProvider { - name: string; - priority: number; - grammarScopes: Array; - _definitionEventName: string; - _connectionToLanguageService: ConnectionCache; +class DefinitionProvider { - constructor( - name: string, - grammars: Array, - priority: number, - definitionEventName: string, - connectionToLanguageService: ConnectionCache, - ) { + constructor(name, grammars, priority, definitionEventName, connectionToLanguageService) { this.name = name; this.priority = priority; this.grammarScopes = grammars; @@ -43,34 +33,14 @@ export class DefinitionProvider { this._connectionToLanguageService = connectionToLanguageService; } - static register( - name: string, - grammars: Array, - config: DefinitionConfig, - connectionToLanguageService: ConnectionCache, - ): IDisposable { - return atom.packages.serviceHub.provide( - 'definitions', - config.version, - new DefinitionProvider( - name, - grammars, - config.priority, - config.definitionEventName, - connectionToLanguageService, - ), - ); + static register(name, grammars, config, connectionToLanguageService) { + return atom.packages.serviceHub.provide('definitions', config.version, new DefinitionProvider(name, grammars, config.priority, config.definitionEventName, connectionToLanguageService)); } - async getDefinition( - editor: TextEditor, - position: atom$Point, - ): Promise { - return trackTiming(this._definitionEventName, async () => { - const fileVersion = await getFileVersionOfEditor(editor); - const languageService = this._connectionToLanguageService.getForUri( - editor.getPath(), - ); + async getDefinition(editor, position) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(this._definitionEventName, async () => { + const fileVersion = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor); + const languageService = this._connectionToLanguageService.getForUri(editor.getPath()); if (languageService == null || fileVersion == null) { return null; } @@ -78,3 +48,13 @@ export class DefinitionProvider { }); } } +exports.DefinitionProvider = DefinitionProvider; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/DiagnosticsProvider.js b/pkg/nuclide-language-service/lib/DiagnosticsProvider.js index aa8b9ed709..1aedcd1ac2 100644 --- a/pkg/nuclide-language-service/lib/DiagnosticsProvider.js +++ b/pkg/nuclide-language-service/lib/DiagnosticsProvider.js @@ -1,125 +1,112 @@ -/** - * 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 - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - DiagnosticInvalidationCallback, - DiagnosticInvalidationMessage, - DiagnosticProviderUpdate, - DiagnosticUpdateCallback, -} from 'atom-ide-ui'; -import type { - FileDiagnosticMap, - LanguageService, - FileDiagnosticProviderUpdate, -} from './LanguageService'; -import type {BusySignalProvider} from './AtomLanguageService'; - -import {Cache} from 'nuclide-commons/cache'; -import {ConnectionCache} from '../../nuclide-remote-connection'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {track, trackTiming} from '../../nuclide-analytics'; -import {RequestSerializer} from 'nuclide-commons/promise'; -import {DiagnosticsProviderBase} from './DiagnosticsProviderBase'; -import {onDidRemoveProjectPath} from 'nuclide-commons-atom/projects'; -import {getFileVersionOfEditor} from '../../nuclide-open-files'; -import {Observable} from 'rxjs'; -import {ServerConnection} from '../../nuclide-remote-connection'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {ensureInvalidations} from '../../nuclide-language-service-rpc'; - -export type DiagnosticsConfig = - | FileDiagnosticsConfig - | ObservableDiagnosticsConfig; - -export type FileDiagnosticsConfig = {| - version: '0.1.0', - shouldRunOnTheFly: boolean, - analyticsEventName: string, -|}; - -export type ObservableDiagnosticsConfig = {| - version: '0.2.0', - analyticsEventName: string, -|}; - -export function registerDiagnostics( - name: string, - grammars: Array, - config: DiagnosticsConfig, - logger: log4js$Logger, - connectionToLanguageService: ConnectionCache, - busySignalProvider: BusySignalProvider, -): IDisposable { - const result = new UniversalDisposable(); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ObservableDiagnosticProvider = exports.FileDiagnosticsProvider = undefined; +exports.registerDiagnostics = registerDiagnostics; + +var _cache; + +function _load_cache() { + return _cache = require('../../../modules/nuclide-commons/cache'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _DiagnosticsProviderBase; + +function _load_DiagnosticsProviderBase() { + return _DiagnosticsProviderBase = require('./DiagnosticsProviderBase'); +} + +var _projects; + +function _load_projects() { + return _projects = require('../../../modules/nuclide-commons-atom/projects'); +} + +var _nuclideOpenFiles; + +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _event; + +function _load_event() { + return _event = require('../../../modules/nuclide-commons/event'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _nuclideLanguageServiceRpc; + +function _load_nuclideLanguageServiceRpc() { + return _nuclideLanguageServiceRpc = require('../../nuclide-language-service-rpc'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function registerDiagnostics(name, grammars, config, logger, connectionToLanguageService, busySignalProvider) { + const result = new (_UniversalDisposable || _load_UniversalDisposable()).default(); let provider; switch (config.version) { case '0.1.0': - provider = new FileDiagnosticsProvider( - name, - grammars, - config.shouldRunOnTheFly, - config.analyticsEventName, - connectionToLanguageService, - busySignalProvider, - ); + provider = new FileDiagnosticsProvider(name, grammars, config.shouldRunOnTheFly, config.analyticsEventName, connectionToLanguageService, busySignalProvider); result.add(provider); break; case '0.2.0': - provider = new ObservableDiagnosticProvider( - config.analyticsEventName, - grammars, - logger, - connectionToLanguageService, - ); + provider = new ObservableDiagnosticProvider(config.analyticsEventName, grammars, logger, connectionToLanguageService); break; default: - (config.version: empty); + config.version; throw new Error('Unexpected diagnostics version'); } - result.add( - atom.packages.serviceHub.provide( - 'DEPRECATED-diagnostics', - config.version, - provider, - ), - ); + result.add(atom.packages.serviceHub.provide('DEPRECATED-diagnostics', config.version, provider)); return result; -} +} /** + * 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. + * + * + * @format + */ -export class FileDiagnosticsProvider { - name: string; - _busySignalProvider: BusySignalProvider; - _providerBase: DiagnosticsProviderBase; - _requestSerializer: RequestSerializer; - _subscriptions: UniversalDisposable; +class FileDiagnosticsProvider { - /** - * Maps hack root to the set of file paths under that root for which we have - * ever reported diagnostics. - */ - _projectRootToFilePaths: Map>; - _analyticsEventName: string; - _connectionToLanguageService: ConnectionCache; - - constructor( - name: string, - grammars: Array, - shouldRunOnTheFly: boolean, - analyticsEventName: string, - connectionToLanguageService: ConnectionCache, - busySignalProvider: BusySignalProvider, - ProviderBase: typeof DiagnosticsProviderBase = DiagnosticsProviderBase, - ) { + constructor(name, grammars, shouldRunOnTheFly, analyticsEventName, connectionToLanguageService, busySignalProvider, ProviderBase = (_DiagnosticsProviderBase || _load_DiagnosticsProviderBase()).DiagnosticsProviderBase) { this.name = name; this._analyticsEventName = analyticsEventName; this._busySignalProvider = busySignalProvider; @@ -128,66 +115,56 @@ export class FileDiagnosticsProvider { grammarScopes: new Set(grammars), shouldRunOnTheFly, onTextEditorEvent: editor => this._runDiagnostics(editor), - onNewUpdateSubscriber: callback => - this._receivedNewUpdateSubscriber(callback), + onNewUpdateSubscriber: callback => this._receivedNewUpdateSubscriber(callback) }; this._providerBase = new ProviderBase(utilsOptions); - this._requestSerializer = new RequestSerializer(); + this._requestSerializer = new (_promise || _load_promise()).RequestSerializer(); this._projectRootToFilePaths = new Map(); - this._subscriptions = new UniversalDisposable(); - this._subscriptions.add( - onDidRemoveProjectPath(projectPath => { - this.invalidateProjectPath(projectPath); - }), - this._providerBase, - ); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._subscriptions.add((0, (_projects || _load_projects()).onDidRemoveProjectPath)(projectPath => { + this.invalidateProjectPath(projectPath); + }), this._providerBase); } - _runDiagnostics(textEditor: atom$TextEditor): void { - this._busySignalProvider.reportBusyWhile( - `${this.name}: Waiting for diagnostics`, - () => this._runDiagnosticsImpl(textEditor), - ); + /** + * Maps hack root to the set of file paths under that root for which we have + * ever reported diagnostics. + */ + + + _runDiagnostics(textEditor) { + this._busySignalProvider.reportBusyWhile(`${this.name}: Waiting for diagnostics`, () => this._runDiagnosticsImpl(textEditor)); } - _runDiagnosticsImpl(textEditor: atom$TextEditor): Promise { - return trackTiming(this._analyticsEventName, async () => { + _runDiagnosticsImpl(textEditor) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(this._analyticsEventName, async () => { let filePath = textEditor.getPath(); if (filePath == null) { return; } - const diagnosisResult = await this._requestSerializer.run( - this.findDiagnostics(textEditor), - ); - if ( - diagnosisResult.status === 'outdated' || - diagnosisResult.result == null - ) { + const diagnosisResult = await this._requestSerializer.run(this.findDiagnostics(textEditor)); + if (diagnosisResult.status === 'outdated' || diagnosisResult.result == null) { return; } - const diagnostics: DiagnosticProviderUpdate = diagnosisResult.result; + const diagnostics = diagnosisResult.result; filePath = textEditor.getPath(); if (filePath == null) { return; } - const languageService = this._connectionToLanguageService.getForUri( - filePath, - ); + const languageService = this._connectionToLanguageService.getForUri(filePath); if (languageService == null) { return; } - const projectRoot = await (await languageService).getProjectRoot( - filePath, - ); + const projectRoot = await (await languageService).getProjectRoot(filePath); if (projectRoot == null) { return; } this._providerBase.publishMessageInvalidation({ scope: 'file', - filePaths: [filePath], + filePaths: [filePath] }); this._invalidatePathsForProjectRoot(projectRoot); @@ -214,7 +191,7 @@ export class FileDiagnosticsProvider { }); } - _getPathsToInvalidate(projectRoot: NuclideUri): Array { + _getPathsToInvalidate(projectRoot) { const filePaths = this._projectRootToFilePaths.get(projectRoot); if (!filePaths) { return []; @@ -222,7 +199,7 @@ export class FileDiagnosticsProvider { return Array.from(filePaths); } - _receivedNewUpdateSubscriber(callback: DiagnosticUpdateCallback): void { + _receivedNewUpdateSubscriber(callback) { // Every time we get a new subscriber, we need to push results to them. This // logic is common to all providers and should be abstracted out (t7813069) // @@ -230,51 +207,42 @@ export class FileDiagnosticsProvider { // probably remove the activeTextEditor parameter. const activeTextEditor = atom.workspace.getActiveTextEditor(); if (activeTextEditor) { - if ( - this._providerBase - .getGrammarScopes() - .has(activeTextEditor.getGrammar().scopeName) - ) { + if (this._providerBase.getGrammarScopes().has(activeTextEditor.getGrammar().scopeName)) { this._runDiagnostics(activeTextEditor); } } } - setRunOnTheFly(runOnTheFly: boolean): void { + setRunOnTheFly(runOnTheFly) { this._providerBase.setRunOnTheFly(runOnTheFly); } - onMessageUpdate(callback: DiagnosticUpdateCallback): IDisposable { + onMessageUpdate(callback) { return this._providerBase.onMessageUpdate(callback); } - onMessageInvalidation(callback: DiagnosticInvalidationCallback): IDisposable { + onMessageInvalidation(callback) { return this._providerBase.onMessageInvalidation(callback); } // Called when a directory is removed from the file tree. - invalidateProjectPath(projectPath: NuclideUri): void { + invalidateProjectPath(projectPath) { Array.from(this._projectRootToFilePaths.keys()) - // This filter is over broad, the real filter should be - // no open dir in the File Tree contains the root. - // This will err on the side of removing messages, - // which should be fine, as they will come back once a file is reopened - // or edited. - .filter( - rootPath => - nuclideUri.contains(projectPath, rootPath) || - nuclideUri.contains(rootPath, projectPath), - ) - .forEach(removedPath => { - this._invalidatePathsForProjectRoot(removedPath); - }); + // This filter is over broad, the real filter should be + // no open dir in the File Tree contains the root. + // This will err on the side of removing messages, + // which should be fine, as they will come back once a file is reopened + // or edited. + .filter(rootPath => (_nuclideUri || _load_nuclideUri()).default.contains(projectPath, rootPath) || (_nuclideUri || _load_nuclideUri()).default.contains(rootPath, projectPath)).forEach(removedPath => { + this._invalidatePathsForProjectRoot(removedPath); + }); } - _invalidatePathsForProjectRoot(projectRoot: NuclideUri): void { + _invalidatePathsForProjectRoot(projectRoot) { const pathsToInvalidate = this._getPathsToInvalidate(projectRoot); this._providerBase.publishMessageInvalidation({ scope: 'file', - filePaths: pathsToInvalidate, + filePaths: pathsToInvalidate }); this._projectRootToFilePaths.delete(projectRoot); } @@ -283,11 +251,9 @@ export class FileDiagnosticsProvider { this._subscriptions.dispose(); } - async findDiagnostics(editor: atom$TextEditor): Promise { - const fileVersion = await getFileVersionOfEditor(editor); - const languageService = this._connectionToLanguageService.getForUri( - editor.getPath(), - ); + async findDiagnostics(editor) { + const fileVersion = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor); + const languageService = this._connectionToLanguageService.getForUri(editor.getPath()); if (languageService == null || fileVersion == null) { return null; } @@ -296,127 +262,72 @@ export class FileDiagnosticsProvider { } } -export class ObservableDiagnosticProvider { - updates: Observable; - invalidations: Observable; - _analyticsEventName: string; - _grammarScopes: Set; - _connectionToLanguageService: ConnectionCache; - _connectionToFiles: Cache>; - _logger: log4js$Logger; - _subscriptions: UniversalDisposable; - - constructor( - analyticsEventName: string, - grammars: Array, - logger: log4js$Logger, - connectionToLanguageService: ConnectionCache, - ) { +exports.FileDiagnosticsProvider = FileDiagnosticsProvider; +class ObservableDiagnosticProvider { + + constructor(analyticsEventName, grammars, logger, connectionToLanguageService) { this._grammarScopes = new Set(grammars); this._logger = logger; this._analyticsEventName = analyticsEventName; - this._connectionToFiles = new Cache(connection => new Set()); + this._connectionToFiles = new (_cache || _load_cache()).Cache(connection => new Set()); this._connectionToLanguageService = connectionToLanguageService; - this.updates = this._connectionToLanguageService - .observeEntries() - .mergeMap(([connection, languageService]) => { - const connectionName = ServerConnection.toDebugString(connection); - this._logger.debug( - `Starting observing diagnostics ${connectionName}, ${ - this._analyticsEventName - }`, - ); - return Observable.fromPromise(languageService) - .catch(error => { - this._logger.error( - `Error: languageService, ${this._analyticsEventName}`, - error, - ); - return Observable.empty(); - }) - .mergeMap((language: LanguageService) => { - this._logger.debug( - `Observing diagnostics ${connectionName}, ${ - this._analyticsEventName - }`, - ); - return ensureInvalidations( - this._logger, - language - .observeDiagnostics() - .refCount() - .catch(error => { - this._logger.error( - `Error: observeDiagnostics, ${this._analyticsEventName}`, - error, - ); - return Observable.empty(); - }), - ); - }) - .map((updates: FileDiagnosticMap) => { - track(this._analyticsEventName); - const filePathToMessages = new Map(); - updates.forEach((messages, filePath) => { - const fileCache = this._connectionToFiles.get(connection); - if (messages.length === 0) { - fileCache.delete(filePath); - } else { - fileCache.add(filePath); - } - filePathToMessages.set(filePath, messages); - }); - return filePathToMessages; - }); - }) - .catch(error => { - this._logger.error( - `Error: observeEntries, ${this._analyticsEventName}`, - error, - ); - throw error; + this.updates = this._connectionToLanguageService.observeEntries().mergeMap(([connection, languageService]) => { + const connectionName = (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).ServerConnection.toDebugString(connection); + this._logger.debug(`Starting observing diagnostics ${connectionName}, ${this._analyticsEventName}`); + return _rxjsBundlesRxMinJs.Observable.fromPromise(languageService).catch(error => { + this._logger.error(`Error: languageService, ${this._analyticsEventName}`, error); + return _rxjsBundlesRxMinJs.Observable.empty(); + }).mergeMap(language => { + this._logger.debug(`Observing diagnostics ${connectionName}, ${this._analyticsEventName}`); + return (0, (_nuclideLanguageServiceRpc || _load_nuclideLanguageServiceRpc()).ensureInvalidations)(this._logger, language.observeDiagnostics().refCount().catch(error => { + this._logger.error(`Error: observeDiagnostics, ${this._analyticsEventName}`, error); + return _rxjsBundlesRxMinJs.Observable.empty(); + })); + }).map(updates => { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)(this._analyticsEventName); + const filePathToMessages = new Map(); + updates.forEach((messages, filePath) => { + const fileCache = this._connectionToFiles.get(connection); + if (messages.length === 0) { + fileCache.delete(filePath); + } else { + fileCache.add(filePath); + } + filePathToMessages.set(filePath, messages); + }); + return filePathToMessages; }); + }).catch(error => { + this._logger.error(`Error: observeEntries, ${this._analyticsEventName}`, error); + throw error; + }); - this.invalidations = observableFromSubscribeFunction( - ServerConnection.onDidCloseServerConnection, - ) - .map(connection => { - this._logger.debug( - `Diagnostics closing ${connection.getRemoteHostname()}, ${ - this._analyticsEventName - }`, - ); - const files = Array.from(this._connectionToFiles.get(connection)); - this._connectionToFiles.delete(connection); - return { - scope: 'file', - filePaths: files, - }; - }) - .catch(error => { - this._logger.error( - `Error: invalidations, ${this._analyticsEventName} ${error}`, - ); - throw error; - }); + this.invalidations = (0, (_event || _load_event()).observableFromSubscribeFunction)((_nuclideRemoteConnection || _load_nuclideRemoteConnection()).ServerConnection.onDidCloseServerConnection).map(connection => { + this._logger.debug(`Diagnostics closing ${connection.getRemoteHostname()}, ${this._analyticsEventName}`); + const files = Array.from(this._connectionToFiles.get(connection)); + this._connectionToFiles.delete(connection); + return { + scope: 'file', + filePaths: files + }; + }).catch(error => { + this._logger.error(`Error: invalidations, ${this._analyticsEventName} ${error}`); + throw error; + }); // this._connectionToFiles is lazy, but diagnostics should appear as soon as // a file belonging to the connection is open. // Monitor open text editors and trigger a connection for each one, if needed. - this._subscriptions = new UniversalDisposable( - atom.workspace.observeTextEditors(editor => { - const path = editor.getPath(); - if ( - path != null && - this._grammarScopes.has(editor.getGrammar().scopeName) - ) { - this._connectionToLanguageService.getForUri(path); - } - }), - ); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(atom.workspace.observeTextEditors(editor => { + const path = editor.getPath(); + if (path != null && this._grammarScopes.has(editor.getGrammar().scopeName)) { + this._connectionToLanguageService.getForUri(path); + } + })); } - dispose(): void { + dispose() { this._subscriptions.dispose(); } } +exports.ObservableDiagnosticProvider = ObservableDiagnosticProvider; \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/DiagnosticsProviderBase.js b/pkg/nuclide-language-service/lib/DiagnosticsProviderBase.js index 6fbc650121..09e417abf0 100644 --- a/pkg/nuclide-language-service/lib/DiagnosticsProviderBase.js +++ b/pkg/nuclide-language-service/lib/DiagnosticsProviderBase.js @@ -1,3 +1,26 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DiagnosticsProviderBase = undefined; + +var _atom = require('atom'); + +var _textEvent; + +function _load_textEvent() { + return _textEvent = require('../../../modules/nuclide-commons-atom/text-event'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,98 +28,32 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type { - DiagnosticInvalidationCallback, - DiagnosticInvalidationMessage, - DiagnosticProviderUpdate, - DiagnosticUpdateCallback, -} from 'atom-ide-ui'; - -import {Emitter} from 'atom'; -import {TextEventDispatcher} from 'nuclide-commons-atom/text-event'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -type ProviderBaseOptions = { - /** The callback by which a provider is notified of text events, such as a file save. */ - onTextEditorEvent?: (editor: TextEditor) => mixed, - /** - * The callback by which a provider is notified that a new consumer has subscribed to diagnostic - * updates. - */ - onNewUpdateSubscriber?: (callback: DiagnosticUpdateCallback) => mixed, - /** - * The callback by which a provider is notified that a new consumer has subscribed to diagnostic - * invalidations. - */ - onNewInvalidateSubscriber?: ( - callback: DiagnosticInvalidationCallback, - ) => mixed, - /** - * If true, this will cause onTextEditorEvent to get called more often -- approximately whenever - * the user stops typing. If false, it will get called only when the user saves. - */ - shouldRunOnTheFly?: boolean, - /** - * The following two options specify which grammars the provider is interested in. Most providers - * will include a set of grammarScopes, and will therefore get notifications only about - * TextEditors that are associated with those grammarScopes. Instead, a provider may set - * enableForAllGrammars to true, and then it will get notified of changes in all TextEditors. If - * enableForAllGrammars is true, it overrides the grammars in grammarScopes. - */ - grammarScopes?: Set, - enableForAllGrammars?: boolean, -}; - const UPDATE_EVENT = 'update'; const INVALIDATE_EVENT = 'invalidate'; -let _textEventDispatcherInstance: ?TextEventDispatcher = null; +let _textEventDispatcherInstance = null; -function getTextEventDispatcher(): TextEventDispatcher { +function getTextEventDispatcher() { if (_textEventDispatcherInstance == null) { - _textEventDispatcherInstance = new TextEventDispatcher(); + _textEventDispatcherInstance = new (_textEvent || _load_textEvent()).TextEventDispatcher(); } return _textEventDispatcherInstance; } -export class DiagnosticsProviderBase { - _textEventDispatcher: TextEventDispatcher; - - _emitter: Emitter; - - _grammarScopes: Set; - _allGrammarScopes: ?boolean; +class DiagnosticsProviderBase { - _currentEventSubscription: ?IDisposable; - - _disposables: UniversalDisposable; - - // callbacks provided by client - _textEventCallback: (editor: TextEditor) => mixed; - _newUpdateSubscriberCallback: (callback: DiagnosticUpdateCallback) => mixed; - _newInvalidateSubscriberCallback: ( - callback: DiagnosticInvalidationCallback, - ) => mixed; - - constructor( - options: ProviderBaseOptions, - textEventDispatcher?: TextEventDispatcher = getTextEventDispatcher(), - ) { + constructor(options, textEventDispatcher = getTextEventDispatcher()) { this._textEventDispatcher = textEventDispatcher; - this._emitter = new Emitter(); - this._disposables = new UniversalDisposable(); + this._emitter = new _atom.Emitter(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._textEventCallback = callbackOrNoop(options.onTextEditorEvent); - this._newUpdateSubscriberCallback = callbackOrNoop( - options.onNewUpdateSubscriber, - ); - this._newInvalidateSubscriberCallback = callbackOrNoop( - options.onNewInvalidateSubscriber, - ); + this._newUpdateSubscriberCallback = callbackOrNoop(options.onNewUpdateSubscriber); + this._newInvalidateSubscriberCallback = callbackOrNoop(options.onNewInvalidateSubscriber); // The Set constructor creates an empty Set if passed null or undefined. this._grammarScopes = new Set(options.grammarScopes); @@ -108,7 +65,10 @@ export class DiagnosticsProviderBase { * Subscribes to the appropriate event depending on whether we should run on * the fly or not. */ - _subscribeToTextEditorEvent(shouldRunOnTheFly: boolean) { + + + // callbacks provided by client + _subscribeToTextEditorEvent(shouldRunOnTheFly) { this._disposeEventSubscription(); const dispatcher = this._textEventDispatcher; let subscription; @@ -116,42 +76,36 @@ export class DiagnosticsProviderBase { if (this._allGrammarScopes) { subscription = dispatcher.onAnyFileChange(this._textEventCallback); } else { - subscription = dispatcher.onFileChange( - this._grammarScopes, - this._textEventCallback, - ); + subscription = dispatcher.onFileChange(this._grammarScopes, this._textEventCallback); } } else { if (this._allGrammarScopes) { subscription = dispatcher.onAnyFileSave(this._textEventCallback); } else { - subscription = dispatcher.onFileSave( - this._grammarScopes, - this._textEventCallback, - ); + subscription = dispatcher.onFileSave(this._grammarScopes, this._textEventCallback); } } this._currentEventSubscription = subscription; } - setRunOnTheFly(runOnTheFly: boolean) { + setRunOnTheFly(runOnTheFly) { this._subscribeToTextEditorEvent(runOnTheFly); } - dispose(): void { + dispose() { this._emitter.dispose(); this._disposables.dispose(); this._disposeEventSubscription(); } - _disposeEventSubscription(): void { + _disposeEventSubscription() { if (this._currentEventSubscription) { this._currentEventSubscription.dispose(); this._currentEventSubscription = null; } } - getGrammarScopes(): Set { + getGrammarScopes() { return this._grammarScopes; } @@ -159,11 +113,11 @@ export class DiagnosticsProviderBase { * Clients can call these methods to publish messages */ - publishMessageUpdate(update: DiagnosticProviderUpdate): void { + publishMessageUpdate(update) { this._emitter.emit(UPDATE_EVENT, update); } - publishMessageInvalidation(message: DiagnosticInvalidationMessage): void { + publishMessageInvalidation(message) { this._emitter.emit(INVALIDATE_EVENT, message); } @@ -171,19 +125,20 @@ export class DiagnosticsProviderBase { * Clients should delegate to these */ - onMessageUpdate(callback: DiagnosticUpdateCallback): IDisposable { + onMessageUpdate(callback) { const disposable = this._emitter.on(UPDATE_EVENT, callback); this._newUpdateSubscriberCallback(callback); return disposable; } - onMessageInvalidation(callback: DiagnosticInvalidationCallback): IDisposable { + onMessageInvalidation(callback) { const disposable = this._emitter.on(INVALIDATE_EVENT, callback); this._newInvalidateSubscriberCallback(callback); return disposable; } } -function callbackOrNoop(callback: ?(arg: T) => mixed): (arg: T) => mixed { +exports.DiagnosticsProviderBase = DiagnosticsProviderBase; +function callbackOrNoop(callback) { return callback ? callback.bind(undefined) : () => {}; -} +} \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/FindReferencesProvider.js b/pkg/nuclide-language-service/lib/FindReferencesProvider.js index 797c516184..e2d5229bd5 100644 --- a/pkg/nuclide-language-service/lib/FindReferencesProvider.js +++ b/pkg/nuclide-language-service/lib/FindReferencesProvider.js @@ -1,93 +1,67 @@ -/** - * 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 - */ +'use strict'; -import type { - FindReferencesReturn, - FindReferencesProvider as FindReferencesProviderType, -} from 'atom-ide-ui'; -import type {LanguageService} from './LanguageService'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.FindReferencesProvider = undefined; -import {ConnectionCache} from '../../nuclide-remote-connection'; -import {trackTiming} from '../../nuclide-analytics'; -import {getFileVersionOfEditor} from '../../nuclide-open-files'; +var _nuclideRemoteConnection; -export type FindReferencesConfig = {| - version: '0.1.0', - analyticsEventName: string, -|}; +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} -export class FindReferencesProvider { - grammarScopes: Array; - name: string; - _analyticsEventName: string; - _connectionToLanguageService: ConnectionCache; +var _nuclideOpenFiles; - constructor( - name: string, - grammarScopes: Array, - analyticsEventName: string, - connectionToLanguageService: ConnectionCache, - ) { +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} + +class FindReferencesProvider { + + constructor(name, grammarScopes, analyticsEventName, connectionToLanguageService) { this.name = name; this.grammarScopes = grammarScopes; this._analyticsEventName = analyticsEventName; this._connectionToLanguageService = connectionToLanguageService; } - static register( - name: string, - grammarScopes: Array, - config: FindReferencesConfig, - connectionToLanguageService: ConnectionCache, - ): IDisposable { - return atom.packages.serviceHub.provide( - 'find-references', - config.version, - new FindReferencesProvider( - name, - grammarScopes, - config.analyticsEventName, - connectionToLanguageService, - ), - ); + static register(name, grammarScopes, config, connectionToLanguageService) { + return atom.packages.serviceHub.provide('find-references', config.version, new FindReferencesProvider(name, grammarScopes, config.analyticsEventName, connectionToLanguageService)); } - async isEditorSupported(textEditor: atom$TextEditor): Promise { - return ( - textEditor.getPath() != null && - this.grammarScopes.includes(textEditor.getGrammar().scopeName) - ); + async isEditorSupported(textEditor) { + return textEditor.getPath() != null && this.grammarScopes.includes(textEditor.getGrammar().scopeName); } - findReferences( - editor: atom$TextEditor, - position: atom$Point, - ): Promise { - return trackTiming(this._analyticsEventName, async () => { - const fileVersion = await getFileVersionOfEditor(editor); - const languageService = this._connectionToLanguageService.getForUri( - editor.getPath(), - ); + findReferences(editor, position) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(this._analyticsEventName, async () => { + const fileVersion = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor); + const languageService = this._connectionToLanguageService.getForUri(editor.getPath()); if (languageService == null || fileVersion == null) { return null; } - return (await languageService) - .findReferences(fileVersion, position) - .refCount() - .toPromise(); + return (await languageService).findReferences(fileVersion, position).refCount().toPromise(); }); } } -(((null: any): FindReferencesProvider< - LanguageService, ->): FindReferencesProviderType); +exports.FindReferencesProvider = FindReferencesProvider; /** + * 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. + * + * + * @format + */ + +null; \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/HostServices.js b/pkg/nuclide-language-service/lib/HostServices.js index 2e67cc235b..dab62ecc70 100644 --- a/pkg/nuclide-language-service/lib/HostServices.js +++ b/pkg/nuclide-language-service/lib/HostServices.js @@ -1,3 +1,51 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _memoize2; + +function _load_memoize() { + return _memoize2 = _interopRequireDefault(require('lodash/memoize')); +} + +exports.getHostServices = getHostServices; + +var _consumeFirstProvider; + +function _load_consumeFirstProvider() { + return _consumeFirstProvider = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/consumeFirstProvider')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _HostServicesAggregator; + +function _load_HostServicesAggregator() { + return _HostServicesAggregator = require('../../nuclide-language-service-rpc/lib/HostServicesAggregator'); +} + +var _textEdit; + +function _load_textEdit() { + return _textEdit = require('../../../modules/nuclide-commons-atom/text-edit'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,105 +53,67 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type { - HostServices, - Progress, - ShowNotificationLevel, -} from '../../nuclide-language-service-rpc/lib/rpc-types'; -import type {ConnectableObservable} from 'rxjs'; -import type {ConsoleApi, ConsoleService} from 'atom-ide-ui'; -import type {BusySignalService} from 'atom-ide-ui'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {TextEdit} from 'nuclide-commons-atom/text-edit'; - -import invariant from 'assert'; -import consumeFirstProvider from 'nuclide-commons-atom/consumeFirstProvider'; -import {getLogger} from 'log4js'; -import {Observable} from 'rxjs'; -import {memoize} from 'lodash'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {forkHostServices} from '../../nuclide-language-service-rpc/lib/HostServicesAggregator'; -import {applyTextEditsForMultipleFiles} from 'nuclide-commons-atom/text-edit'; - -let rootAggregatorPromise: ?Promise; -const logger = getLogger('HostServices'); - -export async function getHostServices(): Promise { +let rootAggregatorPromise; +const logger = (0, (_log4js || _load_log4js()).getLogger)('HostServices'); + +async function getHostServices() { // This method doesn't need to be async. But out of laziness we're // reusing 'forkHostServices', which is designed to work over NuclideRPC // if necessary, so it has to be async. if (rootAggregatorPromise == null) { const rootServices = new RootHostServices(); - rootAggregatorPromise = forkHostServices(rootServices, logger); + rootAggregatorPromise = (0, (_HostServicesAggregator || _load_HostServicesAggregator()).forkHostServices)(rootServices, logger); } - return forkHostServices(await rootAggregatorPromise, logger); + return (0, (_HostServicesAggregator || _load_HostServicesAggregator()).forkHostServices)((await rootAggregatorPromise), logger); } // Following type implements the HostServicesForLanguage interface -(((null: any): RootHostServices): HostServices); +null; class RootHostServices { - _busySignalServicePromise: ?Promise; - _nullProgressMessage: Progress = { - setTitle: s => {}, - dispose: () => {}, - }; - - _getConsoleService = memoize( - (): Promise => consumeFirstProvider('console', '0.1.0'), - ); + constructor() { + this._nullProgressMessage = { + setTitle: s => {}, + dispose: () => {} + }; + this._getConsoleService = (0, (_memoize2 || _load_memoize()).default)(() => (0, (_consumeFirstProvider || _load_consumeFirstProvider()).default)('console', '0.1.0')); + this._getConsoleApi = (0, (_memoize2 || _load_memoize()).default)(source => this._getConsoleService().then(createApi => createApi({ id: source, name: source }))); + } // This method creates registers sources with the atom-ide-console service, but never disposes // those registrations; there's not much point. The now-defunct sources will be visible in the // Sources UI. - _getConsoleApi = memoize( - (source: string): Promise => - this._getConsoleService().then(createApi => - createApi({id: source, name: source}), - ), - ); - - consoleNotification( - source: string, - level: ShowNotificationLevel, - text: string, - ): void { + + + consoleNotification(source, level, text) { this._getConsoleApi(source).then(api => { - api.append({text, level}); + api.append({ text, level }); }); } - dialogNotification( - level: ShowNotificationLevel, - text: string, - ): ConnectableObservable { + dialogNotification(level, text) { // We return a ConnectableObservable such that // (1) when code connects to it then we display the dialog // (2) when user dismiss the dialog then we complete the stream // (3) if code unsubscribed before that, then we dismiss the dialog - return Observable.create(observer => { + return _rxjsBundlesRxMinJs.Observable.create(observer => { const notification = this._atomNotification(level, text); notification.onDidDismiss(() => observer.complete()); return () => notification.dismiss(); }).publish(); } - dialogRequest( - level: ShowNotificationLevel, - text: string, - buttonLabels: Array, - closeLabel: string, - ): ConnectableObservable { + dialogRequest(level, text, buttonLabels, closeLabel) { // We return a ConnectedObservable such that // (1) when code connects to it then we display the dialog // (2) if user clicks a button then we do next(buttonLabel); complete() // (3) if user clicks Close then we do next(closeLabel); complete(); // (4) if code unsubscribed before that then we dismiss the dialog. - return Observable.create(observer => { + return _rxjsBundlesRxMinJs.Observable.create(observer => { let result = closeLabel; const notification = this._atomNotification(level, text, { dismissable: true, // dialog will stay up until user dismisses it @@ -112,8 +122,8 @@ class RootHostServices { onDidClick: () => { result = label; notification.dismiss(); // they don't auto-dismiss on click - }, - })), + } + })) }); notification.onDidDismiss(() => { observer.next(result); @@ -123,92 +133,70 @@ class RootHostServices { }).publish(); } - async applyTextEditsForMultipleFiles( - changes: Map>, - ): Promise { - return applyTextEditsForMultipleFiles(changes); + async applyTextEditsForMultipleFiles(changes) { + return (0, (_textEdit || _load_textEdit()).applyTextEditsForMultipleFiles)(changes); } - _getBusySignalService(): Promise { + _getBusySignalService() { // TODO(ljw): if the busy-signal-package has been disabled before this // this function is called, we'll return a promise that never completes. if (this._busySignalServicePromise == null) { this._busySignalServicePromise = new Promise((resolve, reject) => { - atom.packages.serviceHub.consume( - 'atom-ide-busy-signal', - '0.1.0', - service => { - // When the package is provided to us, resolve the promise - resolve(service); - // When the package becomes unavailable to us, put in a null promise - return new UniversalDisposable(() => { - this._busySignalServicePromise = Promise.resolve(null); - }); - }, - ); + atom.packages.serviceHub.consume('atom-ide-busy-signal', '0.1.0', service => { + // When the package is provided to us, resolve the promise + resolve(service); + // When the package becomes unavailable to us, put in a null promise + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { + this._busySignalServicePromise = Promise.resolve(null); + }); + }); }); } return this._busySignalServicePromise; } - async showProgress( - title: string, - options?: {|debounce?: boolean|}, - ): Promise { + async showProgress(title, options) { const service = await this._getBusySignalService(); - const busyMessage = - service == null - ? this._nullProgressMessage - : service.reportBusy(title, {...options}); + const busyMessage = service == null ? this._nullProgressMessage : service.reportBusy(title, Object.assign({}, options)); // The BusyMessage type from atom-ide-busy-signal happens to satisfy the // nuclide-rpc-able interface 'Progress': thus, we can return it directly. - return (busyMessage: Progress); + return busyMessage; } - showActionRequired( - title: string, - options?: {|clickable?: boolean|}, - ): ConnectableObservable { - return Observable.defer(() => this._getBusySignalService()) - .switchMap(service => { - return Observable.create(observer => { - let onDidClick; - if (options != null && options.clickable) { - onDidClick = () => { - observer.next(); - }; - } - const busyMessage = - service == null - ? this._nullProgressMessage - : service.reportBusy(title, { - waitingFor: 'user', - onDidClick, - }); - return () => busyMessage.dispose(); + showActionRequired(title, options) { + return _rxjsBundlesRxMinJs.Observable.defer(() => this._getBusySignalService()).switchMap(service => { + return _rxjsBundlesRxMinJs.Observable.create(observer => { + let onDidClick; + if (options != null && options.clickable) { + onDidClick = () => { + observer.next(); + }; + } + const busyMessage = service == null ? this._nullProgressMessage : service.reportBusy(title, { + waitingFor: 'user', + onDidClick }); - }) - .publish(); + return () => busyMessage.dispose(); + }); + }).publish(); } - dispose(): void { + dispose() { // No one can ever call this function because RootHostServices and // RootAggregator are private to this module, and we don't call dispose. - invariant(false, 'RootHostServices and RootAggregator cannot be disposed.'); + if (!false) { + throw new Error('RootHostServices and RootAggregator cannot be disposed.'); + } } - async childRegister(child: HostServices): Promise { + async childRegister(child) { return this; // Root only ever has exactly one child, the RootAggregator, // so we don't bother with registration: when the aggregator relays // commands, it will relay them straight to root services. } - _atomNotification( - level: ShowNotificationLevel, - text: string, - options?: atom$NotificationOptions, - ): atom$Notification { + _atomNotification(level, text, options) { switch (level) { case 'info': return atom.notifications.addInfo(text, options); @@ -219,7 +207,10 @@ class RootHostServices { case 'error': return atom.notifications.addError(text, options); default: - invariant(false, 'Unrecognized ShowMessageLevel'); + if (!false) { + throw new Error('Unrecognized ShowMessageLevel'); + } + } } -} +} \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/LanguageService.js b/pkg/nuclide-language-service/lib/LanguageService.js index 44f67ba4be..7c8c509fe4 100644 --- a/pkg/nuclide-language-service/lib/LanguageService.js +++ b/pkg/nuclide-language-service/lib/LanguageService.js @@ -1,3 +1,7 @@ +'use strict'; + +// This assertion ensures that Completion is a subtype of atom$AutocompleteSuggestion. If you are +// getting errors here, you have probably just updated one without updating the other. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,261 +9,22 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {DeadlineRequest} from 'nuclide-commons/promise'; -import type {AdditionalLogFile} from '../../nuclide-logging/lib/rpc-types'; -import type {FileVersion} from '../../nuclide-open-files-rpc/lib/rpc-types'; -import type {TextEdit} from 'nuclide-commons-atom/text-edit'; -import type {TypeHint} from '../../nuclide-type-hint/lib/rpc-types'; -import type {CoverageResult} from '../../nuclide-type-coverage/lib/rpc-types'; -import type { - DiagnosticFix, - DiagnosticMessage, - DiagnosticMessageKind, - DiagnosticMessageType, - DefinitionQueryResult, - DiagnosticTrace, - FindReferencesReturn, - Outline, - CodeAction, - SignatureHelp, -} from 'atom-ide-ui'; -import type {ConnectableObservable} from 'rxjs'; -import type {SymbolResult} from '../../nuclide-quick-open/lib/types'; - -export type {SymbolResult} from '../../nuclide-quick-open/lib/types'; +({}); // Subtype of atom$AutocompleteSuggestion. -export type Completion = { - // These fields are part of atom$AutocompleteSuggestion: - text?: string, - snippet?: string, - displayText?: string, - replacementPrefix?: string, - type?: ?string, - leftLabel?: ?string, - leftLabelHTML?: ?string, - rightLabel?: ?string, - rightLabelHTML?: ?string, - className?: ?string, - iconHTML?: ?string, - description?: ?string, - descriptionMarkdown?: ?string, - descriptionMoreURL?: ?string, - // These fields are extra: - filterText?: string, // used by updateAutocompleteResults - sortText?: string, // used by updateAutocompleteResults - extraData?: mixed, // used by whichever packages want to use it - // If textEdits are provided, snippet + text + replacementPrefix are **ignored** in favor of - // simply applying the given edits. - // The edits must not overlap and should contain the position of the completion request. - // Note: this is implemented in AutocompletionProvider and is not part of Atom's API. - textEdits?: Array, - - // Remote URI (or local path if the file is local) of the file in which we're - // requesting the autocomplete. This needs to be tracked inside the Completion - // in order to find the correct language server to send the resolve request to - remoteUri?: NuclideUri, -}; - -// This assertion ensures that Completion is a subtype of atom$AutocompleteSuggestion. If you are -// getting errors here, you have probably just updated one without updating the other. -((({}: any): Completion): atom$AutocompleteSuggestion); - -export type AutocompleteResult = { - isIncomplete: boolean, - items: Array, -}; - -export type FormatOptions = { - // Size of a tab in spaces. - tabSize: number, - // Prefer spaces over tabs. - insertSpaces: boolean, -}; -export type AutocompleteRequest = {| - // The request might have been triggered manually (by the user pressing - // ctrl+space) or automatically (by the user typing into the buffer). - activatedManually: boolean, - // If it was an automatic trigger, this is the character to the left of the - // caret (i.e. what the user most likely just typed). If manual, it is null. - triggerCharacter: ?string, - // Prefix is that part of whatever word the caret's on that's to the left of - // the caret. This prefix is calculated heuristically by the caller via a - // language-appropriate regex. The results of autocomplete have the option to - // override this. - prefix: string, -|}; // A (RPC-able) subset of DiagnosticMessage. -export type FileDiagnosticMessage = {| - kind?: DiagnosticMessageKind, - providerName: string, - type: DiagnosticMessageType, - filePath: NuclideUri, - text?: string, - html?: string, - range?: atom$Range, - trace?: Array, - fix?: DiagnosticFix, - actions?: void, // Help Flow believe this is a subtype. - stale?: boolean, -|}; + // Ensure that this is actually a subset. -(((null: any): FileDiagnosticMessage): DiagnosticMessage); +null; // A (RPC-able) subset of DiagnosticProviderUpdate. -export type FileDiagnosticProviderUpdate = Map< - NuclideUri, - Array, ->; - -export type FileDiagnosticMap = Map>; -export type CodeLensData = { - range: atom$Range, - command?: { - title: string, - command: string, - arguments?: Array, - }, - data?: any, -}; - -// Messages in StatusData are interpreted as Markdown. -export type StatusData = - | {|kind: 'null'|} - | {|kind: 'green', message: string|} - | {|kind: 'yellow', message: string, fraction?: number|} - | {| - kind: 'red', - id?: string, - message: string, - buttons: Array, - |}; - -export interface LanguageService { - getDiagnostics(fileVersion: FileVersion): Promise; - - observeDiagnostics(): ConnectableObservable; - - observeStatus(fileVersion: FileVersion): ConnectableObservable; - - clickStatus( - fileVersion: FileVersion, - id: string, - button: string, - ): Promise; - - getAutocompleteSuggestions( - fileVersion: FileVersion, - position: atom$Point, - request: AutocompleteRequest, - ): Promise; - - resolveAutocompleteSuggestion(suggestion: Completion): Promise; - - getDefinition( - fileVersion: FileVersion, - position: atom$Point, - ): Promise; - - findReferences( - fileVersion: FileVersion, - position: atom$Point, - ): ConnectableObservable; - - getCoverage(filePath: NuclideUri): Promise; - - getOutline(fileVersion: FileVersion): Promise; - - getCodeLens(fileVersion: FileVersion): Promise>; - - resolveCodeLens( - filePath: NuclideUri, - codeLens: CodeLensData, - ): Promise; - - /** - * Requests CodeActions from a language service. This function can be called either - * whenever the cursor position changes (in which case the range should be from - * the beginning of the current word to the cursor's position) or whenever a user interacts - * with a Diagnostic (in which case the range should be the range of that diagnostic) - * - * If no CodeActions are available, an empty array should be returned. - */ - getCodeActions( - fileVersion: FileVersion, - range: atom$Range, - diagnostics: Array, - ): Promise>; - - typeHint(fileVersion: FileVersion, position: atom$Point): Promise; - - highlight( - fileVersion: FileVersion, - position: atom$Point, - ): Promise>; - - formatSource( - fileVersion: FileVersion, - range: atom$Range, - options: FormatOptions, - ): Promise>; - - formatEntireFile( - fileVersion: FileVersion, - range: atom$Range, - options: FormatOptions, - ): Promise; - - formatAtPosition( - fileVersion: FileVersion, - position: atom$Point, - triggerCharacter: string, - options: FormatOptions, - ): Promise>; - - signatureHelp( - fileVersion: FileVersion, - position: atom$Point, - ): Promise; - - onToggleCoverage(on: boolean): Promise; - - getAdditionalLogFiles( - deadline: DeadlineRequest, - ): Promise>; - - supportsSymbolSearch(directories: Array): Promise; - - symbolSearch( - query: string, - directories: Array, - ): Promise>; - - getProjectRoot(fileUri: NuclideUri): Promise; - - isFileInProject(fileUri: NuclideUri): Promise; - - getExpandedSelectionRange( - fileVersion: FileVersion, - currentSelection: atom$Range, - ): Promise; - getCollapsedSelectionRange( - fileVersion: FileVersion, - currentSelection: atom$Range, - originalCursorPosition: atom$Point, - ): Promise; - dispose(): void; -} +// Messages in StatusData are interpreted as Markdown. \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/OutlineViewProvider.js b/pkg/nuclide-language-service/lib/OutlineViewProvider.js index 1cf5560461..728267cca8 100644 --- a/pkg/nuclide-language-service/lib/OutlineViewProvider.js +++ b/pkg/nuclide-language-service/lib/OutlineViewProvider.js @@ -1,44 +1,31 @@ -/** - * 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 - */ +'use strict'; -import type {Outline, OutlineProvider} from 'atom-ide-ui'; -import type {LanguageService} from './LanguageService'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.OutlineViewProvider = undefined; -import {ConnectionCache} from '../../nuclide-remote-connection'; -import {getFileVersionOfEditor} from '../../nuclide-open-files'; -import {trackTiming} from '../../nuclide-analytics'; +var _nuclideRemoteConnection; -export type OutlineViewConfig = {| - version: '0.1.0', - priority: number, - analyticsEventName: string, - updateOnEdit?: boolean, -|}; +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideOpenFiles; + +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} -export class OutlineViewProvider { - grammarScopes: Array; - priority: number; - name: string; - updateOnEdit: boolean | typeof undefined; - _analyticsEventName: string; - _connectionToLanguageService: ConnectionCache; +var _nuclideAnalytics; - constructor( - name: string, - grammarScopes: Array, - priority: number, - analyticsEventName: string, - updateOnEdit: ?boolean, - connectionToLanguageService: ConnectionCache, - ) { +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +class OutlineViewProvider { + + constructor(name, grammarScopes, priority, analyticsEventName, updateOnEdit, connectionToLanguageService) { this.name = name; this.grammarScopes = grammarScopes; this.priority = priority; @@ -47,32 +34,14 @@ export class OutlineViewProvider { this._connectionToLanguageService = connectionToLanguageService; } - static register( - name: string, - grammarScopes: Array, - config: OutlineViewConfig, - connectionToLanguageService: ConnectionCache, - ): IDisposable { - return atom.packages.serviceHub.provide( - 'outline-view', - config.version, - new OutlineViewProvider( - name, - grammarScopes, - config.priority, - config.analyticsEventName, - config.updateOnEdit, - connectionToLanguageService, - ), - ); + static register(name, grammarScopes, config, connectionToLanguageService) { + return atom.packages.serviceHub.provide('outline-view', config.version, new OutlineViewProvider(name, grammarScopes, config.priority, config.analyticsEventName, config.updateOnEdit, connectionToLanguageService)); } - getOutline(editor: atom$TextEditor): Promise { - return trackTiming(this._analyticsEventName, async () => { - const fileVersion = await getFileVersionOfEditor(editor); - const languageService = this._connectionToLanguageService.getForUri( - editor.getPath(), - ); + getOutline(editor) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(this._analyticsEventName, async () => { + const fileVersion = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor); + const languageService = this._connectionToLanguageService.getForUri(editor.getPath()); if (languageService == null || fileVersion == null) { return null; } @@ -82,4 +51,15 @@ export class OutlineViewProvider { } } -(((null: any): OutlineViewProvider): OutlineProvider); +exports.OutlineViewProvider = OutlineViewProvider; /** + * 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. + * + * + * @format + */ + +null; \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/SignatureHelpProvider.js b/pkg/nuclide-language-service/lib/SignatureHelpProvider.js index 1c9d6731c5..cb5fe0b6fa 100644 --- a/pkg/nuclide-language-service/lib/SignatureHelpProvider.js +++ b/pkg/nuclide-language-service/lib/SignatureHelpProvider.js @@ -1,3 +1,36 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SignatureHelpProvider = undefined; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideOpenFiles; + +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,101 +38,41 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {LanguageService} from './LanguageService'; -import type {SignatureHelp, SignatureHelpRegistry} from 'atom-ide-ui'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {ConnectionCache} from '../../nuclide-remote-connection'; -import {getFileVersionOfEditor} from '../../nuclide-open-files'; -import {trackTiming} from '../../nuclide-analytics'; - -export type SignatureHelpConfig = {| - version: '0.1.0', - priority: number, - // NOTE: We could theoretically have a 'getTriggerCharacters' API - // to resolve this asynchronously to support servers with dynamic trigger characters. - // However, we don't have any clear use cases for this yet. - triggerCharacters?: Set, - showDocBlock?: boolean, - analyticsEventName: string, -|}; - -export class SignatureHelpProvider { - grammarScopes: Array; - priority: number; - triggerCharacters: Set | void; - showDocBlock: boolean; - _analyticsEventName: string; - _connectionToLanguageService: ConnectionCache; - - constructor( - grammarScopes: Array, - config: SignatureHelpConfig, - connectionToLanguageService: ConnectionCache, - ) { +class SignatureHelpProvider { + + constructor(grammarScopes, config, connectionToLanguageService) { this.grammarScopes = grammarScopes; this.triggerCharacters = config.triggerCharacters; - this.showDocBlock = - config.showDocBlock != null ? config.showDocBlock : true; + this.showDocBlock = config.showDocBlock != null ? config.showDocBlock : true; this._analyticsEventName = config.analyticsEventName; this._connectionToLanguageService = connectionToLanguageService; } - static register( - grammarScopes: Array, - config: SignatureHelpConfig, - connectionToLanguageService: ConnectionCache, - ): IDisposable { - const disposables = new UniversalDisposable(); - disposables.add( - atom.packages.serviceHub.consume( - 'signature-help', - config.version, - (registry: SignatureHelpRegistry) => { - disposables.add( - registry( - new SignatureHelpProvider( - grammarScopes, - config, - connectionToLanguageService, - ), - ), - ); - }, - ), - ); + static register(grammarScopes, config, connectionToLanguageService) { + const disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + disposables.add(atom.packages.serviceHub.consume('signature-help', config.version, registry => { + disposables.add(registry(new SignatureHelpProvider(grammarScopes, config, connectionToLanguageService))); + })); return disposables; } - getSignatureHelp( - editor: atom$TextEditor, - position: atom$Point, - ): Promise { - return trackTiming(this._analyticsEventName, async () => { - const languageService: ?LanguageService = await this._connectionToLanguageService.getForUri( - editor.getPath(), - ); + getSignatureHelp(editor, position) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(this._analyticsEventName, async () => { + const languageService = await this._connectionToLanguageService.getForUri(editor.getPath()); if (languageService == null) { return null; } - const fileVersion = await getFileVersionOfEditor(editor); + const fileVersion = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor); if (fileVersion == null) { return null; } - const signatureHelp = await languageService.signatureHelp( - fileVersion, - position, - ); - - if ( - !this.showDocBlock && - signatureHelp != null && - signatureHelp.signatures != null - ) { + const signatureHelp = await languageService.signatureHelp(fileVersion, position); + + if (!this.showDocBlock && signatureHelp != null && signatureHelp.signatures != null) { for (const signature of signatureHelp.signatures) { delete signature.documentation; } @@ -109,3 +82,4 @@ export class SignatureHelpProvider { }); } } +exports.SignatureHelpProvider = SignatureHelpProvider; \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/StatusProvider.js b/pkg/nuclide-language-service/lib/StatusProvider.js index 7598449488..db702156f3 100644 --- a/pkg/nuclide-language-service/lib/StatusProvider.js +++ b/pkg/nuclide-language-service/lib/StatusProvider.js @@ -1,3 +1,30 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.StatusProvider = undefined; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _nuclideOpenFiles; + +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,44 +32,13 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {IconName} from 'nuclide-commons-ui/Icon'; -import type {LanguageService, StatusData} from './LanguageService'; - -import {Observable} from 'rxjs'; -import {ConnectionCache} from '../../nuclide-remote-connection'; -import {track, trackTiming} from '../../nuclide-analytics'; -import {getFileVersionOfEditor} from '../../nuclide-open-files'; - -export type StatusConfig = {| - version: '0.1.0', - priority: number, - observeEventName: string, - clickEventName: string, - icon?: IconName, -|}; - -export class StatusProvider { - name: string; - priority: number; - grammarScopes: Array; - icon: ?IconName; - _observeEventName: string; - _clickEventName: string; - _connectionToLanguageService: ConnectionCache; +class StatusProvider { - constructor( - name: string, - grammars: Array, - priority: number, - observeEventName: string, - clickEventName: string, - connectionToLanguageService: ConnectionCache, - icon?: IconName, - ) { + constructor(name, grammars, priority, observeEventName, clickEventName, connectionToLanguageService, icon) { this.name = name; this.priority = priority; this.grammarScopes = grammars; @@ -52,56 +48,26 @@ export class StatusProvider { this._connectionToLanguageService = connectionToLanguageService; } - static register( - name: string, - grammars: Array, - config: StatusConfig, - connectionToLanguageService: ConnectionCache, - ): IDisposable { - return atom.packages.serviceHub.provide( - 'nuclide-language-status', - config.version, - new StatusProvider( - name, - grammars, - config.priority, - config.observeEventName, - config.clickEventName, - connectionToLanguageService, - ), - ); + static register(name, grammars, config, connectionToLanguageService) { + return atom.packages.serviceHub.provide('nuclide-language-status', config.version, new StatusProvider(name, grammars, config.priority, config.observeEventName, config.clickEventName, connectionToLanguageService)); } - observeStatus(editor: TextEditor): Observable { - return Observable.fromPromise( - Promise.all([ - this._connectionToLanguageService.getForUri(editor.getPath()), - getFileVersionOfEditor(editor), - ]), - ).flatMap(([languageService, fileVersion]) => { + observeStatus(editor) { + return _rxjsBundlesRxMinJs.Observable.fromPromise(Promise.all([this._connectionToLanguageService.getForUri(editor.getPath()), (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor)])).flatMap(([languageService, fileVersion]) => { if (languageService == null || fileVersion == null) { - return Observable.of({kind: 'null'}); + return _rxjsBundlesRxMinJs.Observable.of({ kind: 'null' }); } - return languageService - .observeStatus(fileVersion) - .refCount() - .map(status => { - track(this._observeEventName, {status}); - return status; - }); + return languageService.observeStatus(fileVersion).refCount().map(status => { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)(this._observeEventName, { status }); + return status; + }); }); } - async clickStatus( - editor: TextEditor, - id: string, - button: string, - ): Promise { - return trackTiming(this._clickEventName, async () => { - const fileVersion = await getFileVersionOfEditor(editor); - const languageService = await this._connectionToLanguageService.getForUri( - editor.getPath(), - ); + async clickStatus(editor, id, button) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(this._clickEventName, async () => { + const fileVersion = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor); + const languageService = await this._connectionToLanguageService.getForUri(editor.getPath()); if (languageService == null || fileVersion == null) { return; } @@ -109,3 +75,4 @@ export class StatusProvider { }); } } +exports.StatusProvider = StatusProvider; \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/SyntacticSelectionProvider.js b/pkg/nuclide-language-service/lib/SyntacticSelectionProvider.js index aba7c58ea4..882579dbd2 100644 --- a/pkg/nuclide-language-service/lib/SyntacticSelectionProvider.js +++ b/pkg/nuclide-language-service/lib/SyntacticSelectionProvider.js @@ -1,44 +1,31 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SyntacticSelectionProvider = undefined; + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideOpenFiles; + +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} -import type {LanguageService} from './LanguageService'; -import type {SyntacticSelectionProvider as SyntacticSelectionProviderType} from '../../nuclide-syntactic-selection/lib/types'; - -import {ConnectionCache} from '../../nuclide-remote-connection'; -import {getFileVersionOfEditor} from '../../nuclide-open-files'; -import {trackTiming} from '../../nuclide-analytics'; - -export type SyntacticSelectionConfig = {| - version: '0.1.0', - priority: number, - expandAnalyticsEventName: string, - collapseAnalyticsEventName: string, -|}; - -export class SyntacticSelectionProvider { - grammarScopes: Array; - priority: number; - name: string; - _expandAnalyticsEventName: string; - _collapseAnalyticsEventName: string; - _connectionToLanguageService: ConnectionCache; - - constructor( - name: string, - grammarScopes: Array, - priority: number, - expandAnalyticsEventName: string, - collapseAnalyticsEventName: string, - connectionToLanguageService: ConnectionCache, - ) { +class SyntacticSelectionProvider { + + constructor(name, grammarScopes, priority, expandAnalyticsEventName, collapseAnalyticsEventName, connectionToLanguageService) { this.name = name; this.grammarScopes = grammarScopes; this.priority = priority; @@ -47,67 +34,46 @@ export class SyntacticSelectionProvider { this._connectionToLanguageService = connectionToLanguageService; } - static register( - name: string, - grammarScopes: Array, - config: SyntacticSelectionConfig, - connectionToLanguageService: ConnectionCache, - ): IDisposable { - return atom.packages.serviceHub.provide( - 'nuclide-syntactic-selection', - config.version, - new SyntacticSelectionProvider( - name, - grammarScopes, - config.priority, - config.expandAnalyticsEventName, - config.collapseAnalyticsEventName, - connectionToLanguageService, - ), - ); + static register(name, grammarScopes, config, connectionToLanguageService) { + return atom.packages.serviceHub.provide('nuclide-syntactic-selection', config.version, new SyntacticSelectionProvider(name, grammarScopes, config.priority, config.expandAnalyticsEventName, config.collapseAnalyticsEventName, connectionToLanguageService)); } - getExpandedSelectionRange(editor: atom$TextEditor): Promise { - return trackTiming(this._expandAnalyticsEventName, async () => { - const fileVersion = await getFileVersionOfEditor(editor); - const languageService = this._connectionToLanguageService.getForUri( - editor.getPath(), - ); + getExpandedSelectionRange(editor) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(this._expandAnalyticsEventName, async () => { + const fileVersion = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor); + const languageService = this._connectionToLanguageService.getForUri(editor.getPath()); if (languageService == null || fileVersion == null) { return null; } - return (await languageService).getExpandedSelectionRange( - fileVersion, - editor.getSelectedBufferRange(), - ); + return (await languageService).getExpandedSelectionRange(fileVersion, editor.getSelectedBufferRange()); }); } - getCollapsedSelectionRange( - editor: atom$TextEditor, - originalCursorPosition: atom$Point, - ): Promise { - return trackTiming(this._collapseAnalyticsEventName, async () => { - const fileVersion = await getFileVersionOfEditor(editor); - const languageService = this._connectionToLanguageService.getForUri( - editor.getPath(), - ); + getCollapsedSelectionRange(editor, originalCursorPosition) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(this._collapseAnalyticsEventName, async () => { + const fileVersion = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor); + const languageService = this._connectionToLanguageService.getForUri(editor.getPath()); if (languageService == null || fileVersion == null) { return null; } - return (await languageService).getCollapsedSelectionRange( - fileVersion, - editor.getSelectedBufferRange(), - originalCursorPosition, - ); + return (await languageService).getCollapsedSelectionRange(fileVersion, editor.getSelectedBufferRange(), originalCursorPosition); }); } } -// Ensures that SyntacticSelectionProvider has all the fields and methods defined in +exports.SyntacticSelectionProvider = SyntacticSelectionProvider; // Ensures that SyntacticSelectionProvider has all the fields and methods defined in // the SyntacticSelectionProvider type in the atom-ide-syntactic-selection package. -(((null: any): SyntacticSelectionProvider< - LanguageService, ->): SyntacticSelectionProviderType); +/** + * 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. + * + * + * @format + */ + +null; \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/TypeCoverageProvider.js b/pkg/nuclide-language-service/lib/TypeCoverageProvider.js index 20bdbdf362..8e7cdaf3ec 100644 --- a/pkg/nuclide-language-service/lib/TypeCoverageProvider.js +++ b/pkg/nuclide-language-service/lib/TypeCoverageProvider.js @@ -1,3 +1,23 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.TypeCoverageProvider = undefined; + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +// Provides Diagnostics for un-typed regions of Hack code. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,43 +25,13 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {CoverageResult} from '../../nuclide-type-coverage/lib/rpc-types'; -import type {IconName} from 'nuclide-commons-ui/Icon'; -import type {LanguageService} from './LanguageService'; - -import {ConnectionCache} from '../../nuclide-remote-connection'; -import {trackTiming} from '../../nuclide-analytics'; - -export type TypeCoverageConfig = {| - version: '0.0.0', - priority: number, - analyticsEventName: string, - icon?: IconName, -|}; +class TypeCoverageProvider { -// Provides Diagnostics for un-typed regions of Hack code. -export class TypeCoverageProvider { - displayName: string; - priority: number; - grammarScopes: string; - icon: IconName | void; - _analyticsEventName: string; - _connectionToLanguageService: ConnectionCache; - _onToggleValue: boolean; - - constructor( - name: string, - selector: string, - priority: number, - analyticsEventName: string, - icon: IconName | void, - connectionToLanguageService: ConnectionCache, - ) { + constructor(name, selector, priority, analyticsEventName, icon, connectionToLanguageService) { this.displayName = name; this.priority = priority; this.grammarScopes = selector; @@ -49,36 +39,18 @@ export class TypeCoverageProvider { this._analyticsEventName = analyticsEventName; this._connectionToLanguageService = connectionToLanguageService; this._onToggleValue = false; - this._connectionToLanguageService - .observeValues() - .subscribe(async languageService => { - const ls = await languageService; - ls.onToggleCoverage(this._onToggleValue); - }); + this._connectionToLanguageService.observeValues().subscribe(async languageService => { + const ls = await languageService; + ls.onToggleCoverage(this._onToggleValue); + }); } - static register( - name: string, - selector: string, - config: TypeCoverageConfig, - connectionToLanguageService: ConnectionCache, - ): IDisposable { - return atom.packages.serviceHub.provide( - 'nuclide-type-coverage', - config.version, - new TypeCoverageProvider( - name, - selector, - config.priority, - config.analyticsEventName, - config.icon, - connectionToLanguageService, - ), - ); + static register(name, selector, config, connectionToLanguageService) { + return atom.packages.serviceHub.provide('nuclide-type-coverage', config.version, new TypeCoverageProvider(name, selector, config.priority, config.analyticsEventName, config.icon, connectionToLanguageService)); } - async getCoverage(path: NuclideUri): Promise { - return trackTiming(this._analyticsEventName, async () => { + async getCoverage(path) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(this._analyticsEventName, async () => { const languageService = this._connectionToLanguageService.getForUri(path); if (languageService == null) { return null; @@ -88,15 +60,12 @@ export class TypeCoverageProvider { }); } - async onToggle(on: boolean): Promise { + async onToggle(on) { this._onToggleValue = on; - await Promise.all( - Array.from(this._connectionToLanguageService.values()).map( - async languageService => { - const ls = await languageService; - ls.onToggleCoverage(on); - }, - ), - ); + await Promise.all(Array.from(this._connectionToLanguageService.values()).map(async languageService => { + const ls = await languageService; + ls.onToggleCoverage(on); + })); } } +exports.TypeCoverageProvider = TypeCoverageProvider; \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/TypeHintProvider.js b/pkg/nuclide-language-service/lib/TypeHintProvider.js index 368f711a66..832b7896a5 100644 --- a/pkg/nuclide-language-service/lib/TypeHintProvider.js +++ b/pkg/nuclide-language-service/lib/TypeHintProvider.js @@ -1,41 +1,31 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {TypeHint} from '../../nuclide-type-hint/lib/rpc-types'; -import type {LanguageService} from './LanguageService'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.TypeHintProvider = undefined; -import {ConnectionCache} from '../../nuclide-remote-connection'; -import {getFileVersionOfEditor} from '../../nuclide-open-files'; -import {trackTiming} from '../../nuclide-analytics'; +var _nuclideRemoteConnection; -export type TypeHintConfig = {| - version: '0.0.0', - priority: number, - analyticsEventName: string, -|}; +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideOpenFiles; + +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} -export class TypeHintProvider { - providerName: string; - selector: string; - inclusionPriority: number; - _analyticsEventName: string; - _connectionToLanguageService: ConnectionCache; +class TypeHintProvider { - constructor( - name: string, - selector: string, - priority: number, - analyticsEventName: string, - connectionToLanguageService: ConnectionCache, - ) { + constructor(name, selector, priority, analyticsEventName, connectionToLanguageService) { this.providerName = name; this.selector = selector; this.inclusionPriority = priority; @@ -43,34 +33,14 @@ export class TypeHintProvider { this._connectionToLanguageService = connectionToLanguageService; } - static register( - name: string, - selector: string, - config: TypeHintConfig, - connectionToLanguageService: ConnectionCache, - ): IDisposable { - return atom.packages.serviceHub.provide( - 'nuclide-type-hint.provider', - config.version, - new TypeHintProvider( - name, - selector, - config.priority, - config.analyticsEventName, - connectionToLanguageService, - ), - ); + static register(name, selector, config, connectionToLanguageService) { + return atom.packages.serviceHub.provide('nuclide-type-hint.provider', config.version, new TypeHintProvider(name, selector, config.priority, config.analyticsEventName, connectionToLanguageService)); } - async typeHint( - editor: atom$TextEditor, - position: atom$Point, - ): Promise { - return trackTiming(this._analyticsEventName, async () => { - const fileVersion = await getFileVersionOfEditor(editor); - const languageService = this._connectionToLanguageService.getForUri( - editor.getPath(), - ); + async typeHint(editor, position) { + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(this._analyticsEventName, async () => { + const fileVersion = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor); + const languageService = this._connectionToLanguageService.getForUri(editor.getPath()); if (languageService == null || fileVersion == null) { return null; } @@ -79,3 +49,13 @@ export class TypeHintProvider { }); } } +exports.TypeHintProvider = TypeHintProvider; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-language-service/lib/main.js b/pkg/nuclide-language-service/lib/main.js index 61a8d38e50..50b2e9d21e 100644 --- a/pkg/nuclide-language-service/lib/main.js +++ b/pkg/nuclide-language-service/lib/main.js @@ -1,18 +1,56 @@ -/** - * 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 strict-local - * @format - */ - -export {AtomLanguageService} from './AtomLanguageService'; -export {getHostServices} from './HostServices'; -export { - updateAutocompleteResults, - updateAutocompleteFirstResults, - updateAutocompleteResultRanges, -} from './AutocompleteProvider'; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _AtomLanguageService; + +function _load_AtomLanguageService() { + return _AtomLanguageService = require('./AtomLanguageService'); +} + +Object.defineProperty(exports, 'AtomLanguageService', { + enumerable: true, + get: function () { + return (_AtomLanguageService || _load_AtomLanguageService()).AtomLanguageService; + } +}); + +var _HostServices; + +function _load_HostServices() { + return _HostServices = require('./HostServices'); +} + +Object.defineProperty(exports, 'getHostServices', { + enumerable: true, + get: function () { + return (_HostServices || _load_HostServices()).getHostServices; + } +}); + +var _AutocompleteProvider; + +function _load_AutocompleteProvider() { + return _AutocompleteProvider = require('./AutocompleteProvider'); +} + +Object.defineProperty(exports, 'updateAutocompleteResults', { + enumerable: true, + get: function () { + return (_AutocompleteProvider || _load_AutocompleteProvider()).updateAutocompleteResults; + } +}); +Object.defineProperty(exports, 'updateAutocompleteFirstResults', { + enumerable: true, + get: function () { + return (_AutocompleteProvider || _load_AutocompleteProvider()).updateAutocompleteFirstResults; + } +}); +Object.defineProperty(exports, 'updateAutocompleteResultRanges', { + enumerable: true, + get: function () { + return (_AutocompleteProvider || _load_AutocompleteProvider()).updateAutocompleteResultRanges; + } +}); \ No newline at end of file diff --git a/pkg/nuclide-language-service/spec/AutocompleteProvider-spec.js b/pkg/nuclide-language-service/spec/AutocompleteProvider-spec.js deleted file mode 100644 index 62bb1f4b28..0000000000 --- a/pkg/nuclide-language-service/spec/AutocompleteProvider-spec.js +++ /dev/null @@ -1,448 +0,0 @@ -/** - * 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 - */ - -import type {AutocompleteResult, Completion} from '../lib/LanguageService'; - -import invariant from 'assert'; -import {Point, Range} from 'atom'; -import {nextTick} from 'nuclide-commons/promise'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {jasmineAttachWorkspace} from 'nuclide-commons-atom/test-helpers'; -import {updateAutocompleteResults, updateAutocompleteFirstResults} from '..'; -import AutocompleteCacher from '../../commons-atom/AutocompleteCacher'; -import { - AutocompleteProvider, - updateAutocompleteResultRanges, -} from '../lib/AutocompleteProvider'; -import {ConnectionCache} from '../../nuclide-remote-connection'; -import path from 'path'; // eslint-disable-line nuclide-internal/prefer-nuclide-uri - -describe('AutocompleteProvider', () => { - let editor: atom$TextEditor; - let disposables: UniversalDisposable; - let onDidInsertSuggestionSpy; - - function runAutocompleteTest( - suggestions: Array, - resolver: Completion => ?Completion, - startingText: string, - mainCursorPos: atom$PointLike, - secondaryCursorPos: Array, - expectedText: string, - expectedEndingCursorPos: Array, - ) { - onDidInsertSuggestionSpy = jasmine.createSpy('onDidInsertSuggestion'); - - const mockCache = new ConnectionCache(connection => { - return ({ - getAutocompleteSuggestions(): Promise { - return Promise.resolve({ - isIncomplete: false, - items: suggestions, - }); - }, - resolveAutocompleteSuggestion( - completion: Completion, - ): Promise { - const result = resolver(completion); - if (result == null) { - return Promise.resolve(result); - } - - // Delete the provider to simulate this being an RPC call (since we - // can't move that across RPC), and text edits aren't applied if there - // isn't a provider (autocomplete-plus internals, but it's bitten us). - delete (result: any).provider; - return Promise.resolve(result); - }, - }: any); - }); - - disposables.add( - AutocompleteProvider.register( - 'test', - ['text.plain.null-grammar'], - { - inclusionPriority: 99, - suggestionPriority: 99, - disableForSelector: null, - excludeLowerPriority: true, - analytics: { - eventName: 'test', - shouldLogInsertedSuggestion: false, - }, - autocompleteCacherConfig: null, - supportsResolve: true, - }, - onDidInsertSuggestionSpy, - mockCache, - ), - ); - - waitsForPromise({timeout: 10000}, async () => { - editor = await atom.workspace.open('test.txt'); - await atom.packages.activatePackage('autocomplete-plus'); - atom.packages.loadPackage( - path.join(__dirname, '../../nuclide-autocomplete'), - ); - await atom.packages.activatePackage('nuclide-autocomplete'); - }); - - // Insert some text... - let expectedUndoText; - runs(async () => { - editor.setText(startingText); - editor.setCursorBufferPosition(mainCursorPos); - for (const secondaryCursor of secondaryCursorPos) { - editor.addCursorAtBufferPosition(secondaryCursor); - } - editor.insertText('_'); - expectedUndoText = editor.getText(); - await nextTick(); - atom.commands.dispatch( - atom.views.getView(editor), - 'autocomplete-plus:activate', - {activatedManually: false}, - ); - }); - - let suggestionList; - waitsFor('autocomplete suggestions to appear', () => { - const view = atom.views.getView(atom.workspace); - const autocompleteView = view.querySelector('.autocomplete-plus'); - if (autocompleteView == null) { - return false; - } - suggestionList = autocompleteView.querySelectorAll('li'); - return suggestionList.length > 0; - }); - - runs(() => { - expect(suggestionList.length).toEqual(suggestions.length); - for (let i = 0; i < suggestionList.length; i++) { - const displayText = suggestions[i].displayText; - invariant(displayText != null); - expect(suggestionList[i].innerText).toMatch(new RegExp(displayText)); - } - - // Confirm the autocomplete suggestion. - atom.commands.dispatch( - atom.views.getView(editor), - 'autocomplete-plus:confirm', - ); - expect(onDidInsertSuggestionSpy).toHaveBeenCalled(); - expect(editor.getText()).toBe(expectedText); - expect( - editor.getCursorBufferPositions().map(point => point.toArray()), - ).toEqual(expectedEndingCursorPos); - }); - - // Make sure that the edits were atomic. - runs(() => { - atom.commands.dispatch(atom.views.getView(editor), 'core:undo'); - expect(editor.getText()).toBe(expectedUndoText); - }); - } - - beforeEach(() => { - jasmineAttachWorkspace(); - jasmine.useRealClock(); - disposables = new UniversalDisposable(); - }); - - afterEach(() => { - disposables.dispose(); - if (editor) { - editor.destroy(); - editor = (null: any); - } - }); - - it('works with text edits', () => { - let calledResolve = false; - const suggestion1 = { - displayText: 'editSuggestion', - textEdits: [ - { - oldRange: new Range([0, 0], [0, 9]), - newText: 'test range updating', - }, - ], - // should be ignored - text: 'blah', - snippet: 'blah', - - // Add extra data to the completion to make sure that it gets returned as - // well, rather than Atom making a fresh copy. - notInSpec: 'blah', - }; - const suggestion2 = { - displayText: 'editSuggestion2', - textEdits: [], - // should be ignored - text: 'blah', - snippet: 'blah', - }; - function resolver(completion: Completion): Completion { - calledResolve = true; - expect(completion).toBe(suggestion1); - return { - ...suggestion1, - textEdits: [ - { - oldRange: new Range([1, 0], [2, 0]), - newText: '', - }, - { - // This TextEdit is identical to the one above, except that its - // range is shorter. This simulates some of our language - // services that use autocomplete caching, but have to send the - // original autocomplete (without the cache's range updating) to - // the server in order to resolve it properly. - oldRange: new Range([0, 0], [0, 4]), - newText: 'test range updating', - }, - ], - }; - } - runAutocompleteTest( - [suggestion1, suggestion2], - resolver, - 'testtest\nsecond line\nthird line\n', - [0, 4], - [[2, 3]], - 'test range updating\nthi_rd line\n', - [[0, 19], [1, 4]], - ); - runs(() => { - expect(calledResolve).toBeTruthy(); - }); - }); - - it('will duplicate text edits if there is one text edit and multiple cursors', () => { - const suggestion = { - displayText: 'editSuggestion', - textEdits: [ - { - oldRange: new Range([0, 6], [0, 11]), - newText: 'test', - }, - ], - }; - const resolver = completion => null; - runAutocompleteTest( - [suggestion], - resolver, - 'first line\nsecond line\nthird line\nfourth line', - [0, 10], - [[1, 2], [2, 5], [3, 11]], - 'first test\nse_cond line\nttest line\nfourth test', - [[0, 10], [1, 3], [2, 5], [3, 11]], - ); - }); - - it('will not apply text edits that would overlap after copying', () => { - const suggestion = { - displayText: 'editSuggestion', - textEdits: [ - { - oldRange: new Range([0, 9], [0, 12]), - newText: 'test', - }, - ], - }; - const resolver = completion => null; - runAutocompleteTest( - [suggestion], - resolver, - 'first line', - [0, 10], - [[0, 9]], - 'first lin_e_', - [[0, 12], [0, 10]], - ); - }); -}); - -describe('updateAutocompleteResultRanges', () => { - function withEditor(callback: atom$TextEditor => Promise | void) { - waitsForPromise({timeout: 10000}, async () => { - const editor = await atom.workspace.open('test.txt'); - await callback(editor); - }); - } - - function makeRequest( - point: atom$PointLike, - editor: atom$TextEditor, - ): atom$AutocompleteRequest { - return { - bufferPosition: Point.fromObject(point), - editor, - prefix: '', - scopeDescriptor: ('': any), - }; - } - - function makeResult( - oldRangesList: Array>, - sortText: ?string, - ): AutocompleteResult { - return { - isIncomplete: false, - items: oldRangesList.map(oldRanges => { - if (oldRanges) { - return { - textEdits: oldRanges.map(oldRange => ({ - oldRange, - newText: '', - })), - sortText: sortText == null ? undefined : sortText, - }; - } else { - return { - insertText: '', - }; - } - }), - }; - } - - it('updates ranges that match', () => - withEditor(editor => { - expect( - updateAutocompleteResultRanges( - makeRequest([0, 3], editor), - makeRequest([0, 5], editor), - makeResult([[Range.fromObject([[0, 0], [0, 3]])]]), - ), - ).toEqual(makeResult([[Range.fromObject([[0, 0], [0, 5]])]])); - })); - - it("ignores ranges that don't", () => - withEditor(editor => { - expect( - updateAutocompleteResultRanges( - makeRequest([0, 3], editor), - makeRequest([0, 5], editor), - makeResult([[Range.fromObject([[0, 0], [0, 4]])]]), - ), - ).toEqual(makeResult([[Range.fromObject([[0, 0], [0, 4]])]])); - })); - - it('can handle some elements without text edits', () => - withEditor(editor => { - expect( - updateAutocompleteResultRanges( - makeRequest([0, 3], editor), - makeRequest([0, 5], editor), - makeResult([[Range.fromObject([[0, 0], [0, 3]])], []]), - ), - ).toEqual(makeResult([[Range.fromObject([[0, 0], [0, 5]])], []])); - })); - - it('can handle elements with multiple text edits', () => - withEditor(editor => { - expect( - updateAutocompleteResultRanges( - makeRequest([0, 3], editor), - makeRequest([0, 5], editor), - makeResult([ - [ - Range.fromObject([[0, 0], [0, 3]]), - Range.fromObject([[0, 0], [0, 4]]), - Range.fromObject([[0, 2], [0, 3]]), - ], - ]), - ), - ).toEqual( - makeResult([ - [ - Range.fromObject([[0, 0], [0, 5]]), - Range.fromObject([[0, 0], [0, 4]]), - Range.fromObject([[0, 2], [0, 5]]), - ], - ]), - ); - })); - - it('works with interleaved requests when caching is enabled', () => - withEditor(async editor => { - function makeResponsePromise( - range: ?atom$Range, - ): {promise: Promise, resolve: () => void} { - let resolvePromise; - const promise = new Promise(resolve => { - resolvePromise = resolve; - }); - return { - promise, - resolve: () => - range == null - ? resolvePromise(null) - : resolvePromise(makeResult([[range]])), - }; - } - - const request1 = makeRequest([0, 1], editor); - const request2 = makeRequest([0, 2], editor); - const request3 = makeRequest([0, 3], editor); - const request4 = makeRequest([0, 4], editor); - let resultValue: Promise = (null: any); - const getSuggestions = jasmine - .createSpy('getSuggestions') - .andCallFake(() => resultValue); - - const autocompleteCacher = new AutocompleteCacher(getSuggestions, { - updateResults: updateAutocompleteResults, - updateFirstResults: updateAutocompleteFirstResults, - shouldFilter: () => true, - }); - - // Return null from the first request to make sure that we're properly - // attaching requests to results. - const response1Promise = makeResponsePromise(null); - resultValue = response1Promise.promise; - autocompleteCacher.getSuggestions(request1); - - const response2Promise = makeResponsePromise( - Range.fromObject([[0, 0], [0, 2]]), - ); - resultValue = response2Promise.promise; - autocompleteCacher.getSuggestions(request2); - expect(getSuggestions.callCount).toBe(2); - - // To hit this behavior we need to make at least two interleaved requests - // after the most recent request that returned null (or just at least two - // requests if none of them return null). - const response3Promise = makeResponsePromise( - Range.fromObject([[0, 0], [0, 3]]), - ); - resultValue = response3Promise.promise; - autocompleteCacher.getSuggestions(request3); - expect(getSuggestions.callCount).toBe(3); - - response1Promise.resolve(); - response2Promise.resolve(); - response3Promise.resolve(); - - resultValue = new Promise((resolve, reject) => { - reject(new Error('The third result should come from the cache.')); - }); - const resultsFromUpdatedCache = await autocompleteCacher.getSuggestions( - request4, - ); - - expect(resultsFromUpdatedCache).toEqual( - makeResult([[Range.fromObject([[0, 0], [0, 4]])]], ''), - ); - })); -}); diff --git a/pkg/nuclide-language-service/spec/DiagnosticsProvider-spec.js b/pkg/nuclide-language-service/spec/DiagnosticsProvider-spec.js deleted file mode 100644 index 96ce8418d1..0000000000 --- a/pkg/nuclide-language-service/spec/DiagnosticsProvider-spec.js +++ /dev/null @@ -1,118 +0,0 @@ -/** - * 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 - */ - -import type {ConnectableObservable} from 'rxjs'; -import type {FileDiagnosticMap, LanguageService} from '../lib/LanguageService'; - -import {getLogger} from 'log4js'; -import {Observable} from 'rxjs'; -import {ConnectionCache} from '../../nuclide-remote-connection'; -import { - FileDiagnosticsProvider, - ObservableDiagnosticProvider, -} from '../lib/DiagnosticsProvider'; - -describe('FileDiagnosticsProvider', () => { - let diagnosticsProvider: FileDiagnosticsProvider< - LanguageService, - > = (null: any); - - beforeEach(() => { - class FakeProviderBase { - dispose() {} - } - const busySignalProvider = { - reportBusyWhile(message, f: () => Promise): Promise { - return f(); - }, - }; - diagnosticsProvider = new FileDiagnosticsProvider( - 'Hack', - ['text.html.hack', 'text.html.php'], - false, - 'hack.diagnostics', - (null: any), // connectionToLanguageService - busySignalProvider, - (FakeProviderBase: any), - ); - }); - - describe('invalidateProjectPath', () => { - it('should remove corresponding errors to certain hack language', () => { - // Mock a diagnostic provider with 2 hack language roots, sharing common file real paths. - const projectRootToFilePaths = new Map(); - const root1Paths = ['/hack/root1/file.js', '/hack/common/file.js']; - const root2Paths = ['/hack/root2/file.js', '/hack/common/file.js']; - projectRootToFilePaths.set('/hack/root1', new Set(root1Paths)); - projectRootToFilePaths.set('/hack/root2', new Set(root2Paths)); - diagnosticsProvider._projectRootToFilePaths = projectRootToFilePaths; - // Mock the `publishMessageInvalidation` call to capture call arguments. - const publishHandler = jasmine.createSpy('publish'); - (diagnosticsProvider._providerBase: any).publishMessageInvalidation = publishHandler; - - diagnosticsProvider.invalidateProjectPath('/hack/root1'); - expect(publishHandler.callCount).toBe(1); - expect(publishHandler.argsForCall[0][0]).toEqual({ - scope: 'file', - filePaths: root1Paths, - }); - expect(diagnosticsProvider._projectRootToFilePaths.size).toBe(1); - expect( - diagnosticsProvider._projectRootToFilePaths.get('/hack/root2'), - ).toEqual(new Set(root2Paths)); - }); - }); -}); - -describe('ObservableDiagnosticsProvider', () => { - let connectionCache; - let diagnosticsProvider; - - const TEST_FILE = 'test.txt'; - const mockLanguageService: LanguageService = ({ - observeDiagnostics(): ConnectableObservable { - return Observable.of(new Map([[TEST_FILE, []]])).publish(); - }, - }: any); - - beforeEach(() => { - connectionCache = new ConnectionCache( - () => Promise.resolve(mockLanguageService), - /* lazy */ true, - ); - diagnosticsProvider = new ObservableDiagnosticProvider( - 'Test', - ['text.plain.null-grammar'], - getLogger('DiagnosticsProvider-spec'), - connectionCache, - ); - }); - - afterEach(() => { - diagnosticsProvider.dispose(); - }); - - it('starts a language server upon file open', () => { - waitsForPromise(async () => { - expect(connectionCache.getExistingForUri(TEST_FILE)).toBeNull(); - - const updates = diagnosticsProvider.updates.take(1).toPromise(); - - await atom.workspace.open(TEST_FILE); - - expect(await connectionCache.getExistingForUri(TEST_FILE)).toBe( - mockLanguageService, - ); - - expect(await updates).toEqual(new Map([[TEST_FILE, []]])); - }); - }); -}); diff --git a/pkg/nuclide-language-service/spec/DiagnosticsProviderBase-spec.js b/pkg/nuclide-language-service/spec/DiagnosticsProviderBase-spec.js deleted file mode 100644 index 18aa00e309..0000000000 --- a/pkg/nuclide-language-service/spec/DiagnosticsProviderBase-spec.js +++ /dev/null @@ -1,94 +0,0 @@ -/** - * 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 - */ - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {DiagnosticsProviderBase} from '../lib/DiagnosticsProviderBase'; - -const grammar = 'testgrammar'; - -describe('DiagnosticsProviderBase', () => { - let providerBase: any; - - let eventCallback: any; - let subscribedToAny: any; - let fakeEditor: any; - - let textEventCallback: any; - - class FakeEventDispatcher { - onFileChange(grammars, callback) { - eventCallback = callback; - return new UniversalDisposable(); - } - - onAnyFileChange(callback) { - subscribedToAny = true; - eventCallback = callback; - return new UniversalDisposable(); - } - } - - function newProviderBase(options) { - return new DiagnosticsProviderBase( - options, - (new FakeEventDispatcher(): any), - ); - } - - beforeEach(() => { - fakeEditor = { - getPath() { - return 'foo'; - }, - getGrammar() { - return {scopeName: grammar}; - }, - }; - eventCallback = null; - subscribedToAny = null; - - // Flow complains that a spy is not callable. - textEventCallback = (jasmine.createSpy(): any); - const options = { - grammarScopes: new Set([grammar]), - onTextEditorEvent: textEventCallback, - shouldRunOnTheFly: true, - }; - providerBase = newProviderBase(options); - }); - - it('should call the provided callback when there is a text event', () => { - eventCallback(fakeEditor); - expect(textEventCallback).toHaveBeenCalled(); - }); - - it("should subscribe to 'all' if allGrammarScopes is true", () => { - newProviderBase({ - grammarScopes: new Set([]), - enableForAllGrammars: true, - shouldRunOnTheFly: true, - }); - expect(subscribedToAny).toBe(true); - }); - - it('should send published messages to all subscribers', () => { - const callback1 = jasmine.createSpy(); - const callback2 = jasmine.createSpy(); - - providerBase.onMessageUpdate(callback1); - providerBase.onMessageUpdate(callback2); - - const update = 'this is a fake update'; - providerBase.publishMessageUpdate(update); - expect(callback1).toHaveBeenCalledWith(update); - expect(callback2).toHaveBeenCalledWith(update); - }); -}); diff --git a/pkg/nuclide-language-service/spec/fixtures/HackExample1.php b/pkg/nuclide-language-service/spec/fixtures/HackExample1.php deleted file mode 100644 index eab40744d8..0000000000 --- a/pkg/nuclide-language-service/spec/fixtures/HackExample1.php +++ /dev/null @@ -1,17 +0,0 @@ - { - $countries = await countries_gen_all(); - return array('countries' => $countries); - } - - protected function doSomething(): - Awaitable { - return await $this->genPayload(); - } -} diff --git a/pkg/nuclide-language-service/spec/fixtures/HackExample2.php b/pkg/nuclide-language-service/spec/fixtures/HackExample2.php deleted file mode 100644 index 929f2dd9e4..0000000000 --- a/pkg/nuclide-language-service/spec/fixtures/HackExample2.php +++ /dev/null @@ -1,16 +0,0 @@ - - return array('countries' => $countries); - } - - protected function doSomething($inputText): string { - return $this->genPayload(); - } -} diff --git a/pkg/nuclide-language-service/spec/fixtures/HackExample3.php b/pkg/nuclide-language-service/spec/fixtures/HackExample3.php deleted file mode 100644 index 8dcbe7add9..0000000000 --- a/pkg/nuclide-language-service/spec/fixtures/HackExample3.php +++ /dev/null @@ -1,16 +0,0 @@ - array(), - 'deleted' => array(), - 'current' => array(), - ); - } - -} diff --git a/pkg/nuclide-language-status/lib/LanguageStatusManager.js b/pkg/nuclide-language-status/lib/LanguageStatusManager.js index 95c3bfc0eb..66b88edce0 100644 --- a/pkg/nuclide-language-status/lib/LanguageStatusManager.js +++ b/pkg/nuclide-language-status/lib/LanguageStatusManager.js @@ -1,3 +1,48 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LanguageStatusManager = undefined; + +var _ProviderRegistry; + +function _load_ProviderRegistry() { + return _ProviderRegistry = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/ProviderRegistry')); +} + +var _bindObservableAsProps; + +function _load_bindObservableAsProps() { + return _bindObservableAsProps = require('../../../modules/nuclide-commons-ui/bindObservableAsProps'); +} + +var _TextEditorBanner; + +function _load_TextEditorBanner() { + return _TextEditorBanner = require('../../../modules/nuclide-commons-ui/TextEditorBanner'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _StatusComponent; + +function _load_StatusComponent() { + return _StatusComponent = _interopRequireDefault(require('./StatusComponent')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,83 +50,54 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {LanguageStatusProvider} from './types'; - -import ProviderRegistry from 'nuclide-commons-atom/ProviderRegistry'; -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import {TextEditorBanner} from 'nuclide-commons-ui/TextEditorBanner'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Observable, BehaviorSubject} from 'rxjs'; -import StatusComponent from './StatusComponent'; - -import * as React from 'react'; - -export class LanguageStatusManager { - _providerRegistry: ProviderRegistry; - _providersChanged: BehaviorSubject; - _disposables: UniversalDisposable; +class LanguageStatusManager { constructor() { - this._providerRegistry = new ProviderRegistry(); - this._providersChanged = new BehaviorSubject(); - this._disposables = new UniversalDisposable(); - this._disposables.add( - atom.workspace.observeTextEditors(this._onTextEditor), - ); + this._onTextEditor = editor => { + const props = this._providersChanged.switchMap(() => { + const providers = Array.from(this._providerRegistry.getAllProvidersForEditor(editor)); + return providers.map(provider => { + return provider.observeStatus(editor).startWith({ kind: 'null' }).map(data => ({ + provider, + data + })); + }).reduce((a, b) => _rxjsBundlesRxMinJs.Observable.combineLatest(a, b, (x, y) => x.concat(y)), _rxjsBundlesRxMinJs.Observable.of([])); + }).map(serverStatuses => ({ serverStatuses, editor })); + const StatusComponentWithProps = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)(props, (_StatusComponent || _load_StatusComponent()).default); + const statusComponentWrapper = new (_TextEditorBanner || _load_TextEditorBanner()).TextEditorBanner(editor); + statusComponentWrapper.renderUnstyled(_react.createElement(StatusComponentWithProps, null)); + this._disposables.add(statusComponentWrapper); + editor.onDidDestroy(() => { + this._disposables.remove(statusComponentWrapper); + statusComponentWrapper.dispose(); + }); + }; + + this._providerRegistry = new (_ProviderRegistry || _load_ProviderRegistry()).default(); + this._providersChanged = new _rxjsBundlesRxMinJs.BehaviorSubject(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._disposables.add(atom.workspace.observeTextEditors(this._onTextEditor)); } dispose() { this._disposables.dispose(); } - addProvider(provider: LanguageStatusProvider): IDisposable { + addProvider(provider) { this._disposables.add(this._providerRegistry.addProvider(provider)); this._providersChanged.next(); - return new UniversalDisposable(() => this._removeProvider(provider)); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => this._removeProvider(provider)); } - _removeProvider(provider: LanguageStatusProvider): void { + _removeProvider(provider) { this._providerRegistry.removeProvider(provider); this._providersChanged.next(); } - _onTextEditor = (editor: atom$TextEditor): void => { - const props = this._providersChanged - .switchMap(() => { - const providers = Array.from( - this._providerRegistry.getAllProvidersForEditor(editor), - ); - return providers - .map(provider => { - return provider - .observeStatus(editor) - .startWith({kind: 'null'}) - .map(data => ({ - provider, - data, - })); - }) - .reduce( - (a, b) => Observable.combineLatest(a, b, (x, y) => x.concat(y)), - Observable.of([]), - ); - }) - .map(serverStatuses => ({serverStatuses, editor})); - const StatusComponentWithProps = bindObservableAsProps( - props, - StatusComponent, - ); - const statusComponentWrapper = new TextEditorBanner(editor); - statusComponentWrapper.renderUnstyled(); - this._disposables.add(statusComponentWrapper); - editor.onDidDestroy(() => { - this._disposables.remove(statusComponentWrapper); - statusComponentWrapper.dispose(); - }); - }; } +exports.LanguageStatusManager = LanguageStatusManager; \ No newline at end of file diff --git a/pkg/nuclide-language-status/lib/StatusComponent.js b/pkg/nuclide-language-status/lib/StatusComponent.js index d8bb40c3c4..03d6d14ff1 100644 --- a/pkg/nuclide-language-status/lib/StatusComponent.js +++ b/pkg/nuclide-language-status/lib/StatusComponent.js @@ -1,179 +1,182 @@ -/** - * 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 - */ - -import type {StatusData} from '../../nuclide-language-service/lib/LanguageService'; -import type {LanguageStatusProvider} from './types'; - -import classnames from 'classnames'; -import marked from 'marked'; -import nullthrows from 'nullthrows'; -import {Button, ButtonTypes} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; -import {Icon} from 'nuclide-commons-ui/Icon'; -import * as React from 'react'; - -export type ServerStatus = { - provider: LanguageStatusProvider, - data: StatusData, -}; - -type Props = { - serverStatuses: Array, - editor: ?atom$TextEditor, -}; - -type State = { - hovered: boolean, - selectedServerName: ?string, -}; - -export default class StatusComponent extends React.Component { - props: Props = {serverStatuses: [], editor: null}; - state: State = {hovered: false, selectedServerName: null}; - - render(): React.Node { - const serverStatuses = this.props.serverStatuses.filter( - status => status.data.kind !== 'null', - ); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _classnames; + +function _load_classnames() { + return _classnames = _interopRequireDefault(require('classnames')); +} + +var _marked; + +function _load_marked() { + return _marked = _interopRequireDefault(require('marked')); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _Button; + +function _load_Button() { + return _Button = require('../../../modules/nuclide-commons-ui/Button'); +} + +var _ButtonGroup; + +function _load_ButtonGroup() { + return _ButtonGroup = require('../../../modules/nuclide-commons-ui/ButtonGroup'); +} + +var _Icon; + +function _load_Icon() { + return _Icon = require('../../../modules/nuclide-commons-ui/Icon'); +} + +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 }; } + +class StatusComponent extends _react.Component { + constructor(...args) { + var _temp; + + return _temp = super(...args), this.props = { serverStatuses: [], editor: null }, this.state = { hovered: false, selectedServerName: null }, this._renderDetails = status => { + if (status == null || status.data.kind === 'null') { + return null; + } + const { provider, data } = status; + const header = _react.createElement( + 'h1', + { className: 'nuclide-language-status-details-heading' }, + provider.name + ); + const progress = this._renderDetailsProgress(data); + const message = _react.createElement('div', { + dangerouslySetInnerHTML: { + __html: (0, (_marked || _load_marked()).default)(data.message) + } + }); + const buttons = this._renderDetailsButtons(status); + return _react.createElement( + 'div', + { + className: (0, (_classnames || _load_classnames()).default)('nuclide-language-status-details', 'nuclide-language-status-details-' + data.kind) }, + header, + progress, + message, + buttons + ); + }, this._renderDetailsButtons = status => { + const { provider, data } = status; + if (data.kind !== 'red' || data.buttons.length === 0) { + return null; + } + return _react.createElement( + (_ButtonGroup || _load_ButtonGroup()).ButtonGroup, + null, + data.buttons.map(b => _react.createElement( + (_Button || _load_Button()).Button, + { + key: b, + buttonType: (_Button || _load_Button()).ButtonTypes.ERROR, + onClick: () => provider.clickStatus((0, (_nullthrows || _load_nullthrows()).default)(this.props.editor), data.id || '', b) }, + b + )) + ); + }, this._renderDropdownItem = status => { + const { provider, data } = status; + // Use icon if present otherwise the first letter of the name, capitalized. + const icon = provider.icon != null ? _react.createElement((_Icon || _load_Icon()).Icon, { className: 'nuclide-language-status-icon', icon: provider.icon }) : _react.createElement( + 'div', + null, + provider.name.substr(0, 1).toUpperCase() + ); + return _react.createElement( + 'div', + { + className: (0, (_classnames || _load_classnames()).default)('nuclide-language-status-dropdown-item', 'nuclide-language-status-dropdown-item-' + data.kind), + onMouseEnter: () => this.setState({ hovered: true }), + onMouseLeave: () => this.setState({ hovered: false }), + onClick: () => { + if (this.state.selectedServerName === provider.name) { + this.setState({ selectedServerName: null }); + } else { + this.setState({ selectedServerName: provider.name }); + } + } }, + icon + ); + }, this._renderBar = (status, active) => { + const { provider, data } = status; + return _react.createElement('div', { + key: provider.name, + style: { height: this.state.hovered ? 16 : 8 }, + className: (0, (_classnames || _load_classnames()).default)('nuclide-language-status-bar', 'nuclide-language-status-bar-' + data.kind + (!active ? '-inactive' : '')), + onMouseEnter: () => this.setState({ hovered: true }), + onMouseLeave: () => this.setState({ hovered: false }) + }); + }, _temp; + } + + render() { + const serverStatuses = this.props.serverStatuses.filter(status => status.data.kind !== 'null'); const active = this.state.hovered || this.state.selectedServerName != null; - const selectedServerStatus = this.props.serverStatuses.find( - s => s.provider.name === this.state.selectedServerName, - ); - return ( -
    - {this._renderDetails(selectedServerStatus)} -
    -
    - {serverStatuses.map(status => this._renderBar(status, active))} -
    -
    s.provider.name === this.state.selectedServerName); + return _react.createElement( + 'div', + { className: 'nuclide-language-status-container' }, + this._renderDetails(selectedServerStatus), + _react.createElement( + 'div', + { className: 'nuclide-language-status-bar-and-dropdown-container' }, + _react.createElement( + 'div', + { className: 'nuclide-language-status-bar-container' }, + serverStatuses.map(status => this._renderBar(status, active)) + ), + _react.createElement( + 'div', + { // Use opacity instead of visibility so onMouseEnter still triggers - style={{opacity: active ? 1.0 : 0.0}} - className="nuclide-language-status-dropdown"> - {serverStatuses.map(this._renderDropdownItem)} -
    -
    -
    + style: { opacity: active ? 1.0 : 0.0 }, + className: 'nuclide-language-status-dropdown' }, + serverStatuses.map(this._renderDropdownItem) + ) + ) ); } - _renderDetails = (status: ?ServerStatus): ?React.Node => { - if (status == null || status.data.kind === 'null') { - return null; - } - const {provider, data} = status; - const header = ( -

    - {provider.name} -

    - ); - const progress = this._renderDetailsProgress(data); - const message = ( -
    - ); - const buttons = this._renderDetailsButtons(status); - return ( -
    - {header} - {progress} - {message} - {buttons} -
    - ); - }; - - _renderDetailsProgress(data: StatusData): ?React.Node { + _renderDetailsProgress(data) { if (data.kind !== 'yellow' || data.fraction == null) { return null; } - return
    Progress: {(data.fraction * 100).toFixed(2)}%
    ; + return _react.createElement( + 'div', + null, + 'Progress: ', + (data.fraction * 100).toFixed(2), + '%' + ); } - _renderDetailsButtons = (status: ServerStatus): ?React.Node => { - const {provider, data} = status; - if (data.kind !== 'red' || data.buttons.length === 0) { - return null; - } - return ( - - {data.buttons.map(b => ( - - ))} - - ); - }; - - _renderDropdownItem = (status: ServerStatus): React.Node => { - const {provider, data} = status; - // Use icon if present otherwise the first letter of the name, capitalized. - const icon = - provider.icon != null ? ( - - ) : ( -
    {provider.name.substr(0, 1).toUpperCase()}
    - ); - return ( -
    this.setState({hovered: true})} - onMouseLeave={() => this.setState({hovered: false})} - onClick={() => { - if (this.state.selectedServerName === provider.name) { - this.setState({selectedServerName: null}); - } else { - this.setState({selectedServerName: provider.name}); - } - }}> - {icon} -
    - ); - }; - - _renderBar = (status: ServerStatus, active: boolean): React.Node => { - const {provider, data} = status; - return ( -
    this.setState({hovered: true})} - onMouseLeave={() => this.setState({hovered: false})} - /> - ); - }; } +exports.default = StatusComponent; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-language-status/lib/main.js b/pkg/nuclide-language-status/lib/main.js index 56143c7b23..a387573000 100644 --- a/pkg/nuclide-language-status/lib/main.js +++ b/pkg/nuclide-language-status/lib/main.js @@ -1,38 +1,46 @@ -/** - * 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 - */ - -import type {LanguageStatusProvider} from './types'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import {LanguageStatusManager} from './LanguageStatusManager'; +'use strict'; + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _LanguageStatusManager; + +function _load_LanguageStatusManager() { + return _LanguageStatusManager = require('./LanguageStatusManager'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class Activation { - _languageStatusManager: LanguageStatusManager; constructor() { - this._languageStatusManager = new LanguageStatusManager(); + this._languageStatusManager = new (_LanguageStatusManager || _load_LanguageStatusManager()).LanguageStatusManager(); } dispose() { this._languageStatusManager.dispose(); } - consumeLanguageStatusProvider(provider: LanguageStatusProvider): IDisposable { + consumeLanguageStatusProvider(provider) { return this._languageStatusManager.addProvider(provider); } // FOR TESTING - triggerProviderChange(): void { + triggerProviderChange() { this._languageStatusManager._providersChanged.next(); } -} - -createPackage(module.exports, Activation); +} /** + * 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. + * + * + * @format + */ + +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-language-status/lib/types.js b/pkg/nuclide-language-status/lib/types.js index 69d441737d..a726efc43f 100644 --- a/pkg/nuclide-language-status/lib/types.js +++ b/pkg/nuclide-language-status/lib/types.js @@ -1,25 +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 - */ - -import type {IconName} from 'nuclide-commons-ui/Icon'; -import type {Observable} from 'rxjs'; -import type {StatusData} from '../../nuclide-language-service/lib/LanguageService'; - -export type LanguageStatusProvider = { - name: string, - icon: ?IconName, - grammarScopes: Array, - priority: number, - - observeStatus(editor: TextEditor): Observable, - - clickStatus(editor: TextEditor, id: string, button: string): Promise, -}; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-logging/__tests__/fileAppender-test.js b/pkg/nuclide-logging/__tests__/fileAppender-test.js index d026cefb75..b840806a15 100644 --- a/pkg/nuclide-logging/__tests__/fileAppender-test.js +++ b/pkg/nuclide-logging/__tests__/fileAppender-test.js @@ -1,55 +1,63 @@ -/** - * 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 - */ - -import fs from 'fs'; -import log4js from 'log4js'; -import temp from 'temp'; - -temp.track(); +'use strict'; + +var _fs = _interopRequireDefault(require('fs')); + +var _log4js; + +function _load_log4js() { + return _log4js = _interopRequireDefault(require('log4js')); +} + +var _temp; + +function _load_temp() { + return _temp = _interopRequireDefault(require('temp')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +(_temp || _load_temp()).default.track(); /** + * 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. + * + * + * @format + */ jest.unmock('log4js'); describe('fileAppender', () => { - let tempFile: string; + let tempFile; beforeEach(() => { - tempFile = temp.openSync().path; - log4js.configure({ - appenders: [ - { - type: require.resolve('../VendorLib/fileAppender'), - filename: tempFile, - maxLogSize: 1048576, - backups: 1, - layout: { - type: 'pattern', - // level category - message - pattern: '%p %c - %m', - }, - }, - ], + tempFile = (_temp || _load_temp()).default.openSync().path; + (_log4js || _load_log4js()).default.configure({ + appenders: [{ + type: require.resolve('../VendorLib/fileAppender'), + filename: tempFile, + maxLogSize: 1048576, + backups: 1, + layout: { + type: 'pattern', + // level category - message + pattern: '%p %c - %m' + } + }] }); }); it('flushes immediately on shutdown', async () => { await (async () => { const times = 10; - const logger = log4js.getLogger('testCategory'); + const logger = (_log4js || _load_log4js()).default.getLogger('testCategory'); for (let i = 0; i < times; i++) { logger.info('test1234'); } - await new Promise(resolve => log4js.shutdown(resolve)); + await new Promise(resolve => (_log4js || _load_log4js()).default.shutdown(resolve)); - expect(fs.readFileSync(tempFile, 'utf8')).toBe( - 'INFO testCategory - test1234\n'.repeat(times), - ); + expect(_fs.default.readFileSync(tempFile, 'utf8')).toBe('INFO testCategory - test1234\n'.repeat(times)); })(); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-logging/__tests__/processTrackingAppender-test.js b/pkg/nuclide-logging/__tests__/processTrackingAppender-test.js index 7d2456b0be..a938acacc6 100644 --- a/pkg/nuclide-logging/__tests__/processTrackingAppender-test.js +++ b/pkg/nuclide-logging/__tests__/processTrackingAppender-test.js @@ -1,3 +1,25 @@ +'use strict'; + +var _log4js; + +function _load_log4js() { + return _log4js = _interopRequireDefault(require('log4js')); +} + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../../../jest/waits_for')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,39 +27,30 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ jest.unmock('log4js'); global.NUCLIDE_DO_NOT_LOG = false; -import log4js from 'log4js'; -import {runCommand, LOG_CATEGORY} from 'nuclide-commons/process'; -import waitsFor from '../../../jest/waits_for'; - describe('processTrackingAppender', () => { - const trackSpy = jest.spyOn( - require('nuclide-commons/analytics'), - 'trackSampled', - ); + const trackSpy = jest.spyOn(require('../../../modules/nuclide-commons/analytics'), 'trackSampled'); it('captures process exits', async () => { - log4js.configure({ - appenders: [ - { - type: require.resolve('../lib/processTrackingAppender'), - category: LOG_CATEGORY, - }, - ], + (_log4js || _load_log4js()).default.configure({ + appenders: [{ + type: require.resolve('../lib/processTrackingAppender'), + category: (_process || _load_process()).LOG_CATEGORY + }] }); - await runCommand('true', ['1']).toPromise(); + await (0, (_process || _load_process()).runCommand)('true', ['1']).toPromise(); - await waitsFor(() => trackSpy.mock.calls.length > 0); + await (0, (_waits_for || _load_waits_for()).default)(() => trackSpy.mock.calls.length > 0); expect(trackSpy).toHaveBeenCalledWith('process-exit', 10, { command: 'true 1', - duration: jasmine.any(Number), + duration: jasmine.any(Number) }); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-logging/__tests__/utils-test.js b/pkg/nuclide-logging/__tests__/utils-test.js index b729f40baf..d6a26cd615 100644 --- a/pkg/nuclide-logging/__tests__/utils-test.js +++ b/pkg/nuclide-logging/__tests__/utils-test.js @@ -1,3 +1,11 @@ +'use strict'; + +var _utils; + +function _load_utils() { + return _utils = require('../lib/utils'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,36 +13,28 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ jest.unmock('log4js'); -import { - deserializeLoggingEvent, - patchErrorsOfLoggingEvent, - serializeLoggingEvent, -} from '../lib/utils'; - -import type {LoggingEvent} from '../lib/types'; - // Construct a loggingEvent following log4js event format. -function createLoggingEvent(...args: Array): LoggingEvent { +function createLoggingEvent(...args) { return { startTime: new Date(), categoryName: 'test', data: args, level: { level: 40000, - levelStr: 'ERROR', + levelStr: 'ERROR' }, logger: { category: 'arsenal', _events: { - log: [null, null], - }, - }, + log: [null, null] + } + } }; } @@ -45,14 +45,10 @@ describe('Logview Appender Utils.', () => { expect(loggingEventWithError.data[0] instanceof Error).toBe(true); expect(loggingEventWithError.data[0]).toBe(error); - const patchedLoggingEventWithError = patchErrorsOfLoggingEvent( - loggingEventWithError, - ); + const patchedLoggingEventWithError = (0, (_utils || _load_utils()).patchErrorsOfLoggingEvent)(loggingEventWithError); expect(patchedLoggingEventWithError.data[0] instanceof Error).toBe(false); expect(typeof patchedLoggingEventWithError.data[0].stack).toBe('string'); - expect( - patchedLoggingEventWithError.data[0].stackTrace instanceof Array, - ).toBe(true); + expect(patchedLoggingEventWithError.data[0].stackTrace instanceof Array).toBe(true); const callsite = patchedLoggingEventWithError.data[0].stackTrace[0]; expect(callsite.fileName).toBe(__filename); }); @@ -60,33 +56,21 @@ describe('Logview Appender Utils.', () => { it('addes error if no error exists in loggingEvent.data', () => { const loggingEventWithoutError = createLoggingEvent(); expect(loggingEventWithoutError.data.length).toBe(0); - const patchedLoggingEventWithoutError = patchErrorsOfLoggingEvent( - loggingEventWithoutError, - ); + const patchedLoggingEventWithoutError = (0, (_utils || _load_utils()).patchErrorsOfLoggingEvent)(loggingEventWithoutError); expect(typeof patchedLoggingEventWithoutError.data[0].stack).toBe('string'); }); it('Test serialization/deserialization utils.', () => { - const loggingEvent = patchErrorsOfLoggingEvent( - createLoggingEvent(new Error('123')), - ); + const loggingEvent = (0, (_utils || _load_utils()).patchErrorsOfLoggingEvent)(createLoggingEvent(new Error('123'))); - const serialization = serializeLoggingEvent(loggingEvent); + const serialization = (0, (_utils || _load_utils()).serializeLoggingEvent)(loggingEvent); expect(typeof serialization === 'string').toBe(true); - const deserialization = deserializeLoggingEvent(serialization); - expect(deserialization.startTime.toString()).toEqual( - loggingEvent.startTime.toString(), - ); + const deserialization = (0, (_utils || _load_utils()).deserializeLoggingEvent)(serialization); + expect(deserialization.startTime.toString()).toEqual(loggingEvent.startTime.toString()); expect(deserialization.categoryName).toEqual(loggingEvent.categoryName); - expect(JSON.stringify(deserialization.level)).toEqual( - JSON.stringify(loggingEvent.level), - ); - expect(JSON.stringify(deserialization.logger)).toEqual( - JSON.stringify(loggingEvent.logger), - ); - expect(JSON.stringify(deserialization.data[0])).toEqual( - JSON.stringify(loggingEvent.data[0]), - ); + expect(JSON.stringify(deserialization.level)).toEqual(JSON.stringify(loggingEvent.level)); + expect(JSON.stringify(deserialization.logger)).toEqual(JSON.stringify(loggingEvent.logger)); + expect(JSON.stringify(deserialization.data[0])).toEqual(JSON.stringify(loggingEvent.data[0])); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-logging/lib/config.js b/pkg/nuclide-logging/lib/config.js index afa28bd7ff..fc1029b31e 100644 --- a/pkg/nuclide-logging/lib/config.js +++ b/pkg/nuclide-logging/lib/config.js @@ -1,3 +1,34 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LOG_FILE_PATH = undefined; +exports.getPathToLogFile = getPathToLogFile; +exports.getDefaultConfig = getDefaultConfig; + +var _systemInfo; + +function _load_systemInfo() { + return _systemInfo = require('../../commons-node/system-info'); +} + +var _os = _interopRequireDefault(require('os')); + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,59 +36,48 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import {isRunningInTest} from '../../commons-node/system-info'; - -import os from 'os'; -import {LOG_CATEGORY as PROCESS_LOG_CATEGORY} from 'nuclide-commons/process'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - -const LOG_DIRECTORY = nuclideUri.join( - os.tmpdir(), - `/nuclide-${os.userInfo().username}-logs`, -); -export const LOG_FILE_PATH = nuclideUri.join(LOG_DIRECTORY, 'nuclide.log'); +const LOG_DIRECTORY = (_nuclideUri || _load_nuclideUri()).default.join(_os.default.tmpdir(), `/nuclide-${_os.default.userInfo().username}-logs`); +const LOG_FILE_PATH = exports.LOG_FILE_PATH = (_nuclideUri || _load_nuclideUri()).default.join(LOG_DIRECTORY, 'nuclide.log'); const MAX_LOG_SIZE = 1024 * 1024; const MAX_LOG_BACKUPS = 10; -export function getPathToLogFile(): string { +function getPathToLogFile() { return LOG_FILE_PATH; } -export function getDefaultConfig(): log4js$Config { - const appenders = [ - { - type: require.resolve('../VendorLib/fileAppender'), - filename: LOG_FILE_PATH, - maxLogSize: MAX_LOG_SIZE, - backups: MAX_LOG_BACKUPS, - layout: { - type: 'pattern', - // Format log in following pattern: - // yyyy-MM-dd HH:mm:ss.mil $Level (pid:$pid) $categroy - $message. - pattern: `%d{ISO8601} %p (pid:${process.pid}) %c - %m`, - }, - }, - ]; +function getDefaultConfig() { + const appenders = [{ + type: require.resolve('../VendorLib/fileAppender'), + filename: LOG_FILE_PATH, + maxLogSize: MAX_LOG_SIZE, + backups: MAX_LOG_BACKUPS, + layout: { + type: 'pattern', + // Format log in following pattern: + // yyyy-MM-dd HH:mm:ss.mil $Level (pid:$pid) $categroy - $message. + pattern: `%d{ISO8601} %p (pid:${process.pid}) %c - %m` + } + }]; // Anything not in Atom doesn't have a visible console. if (typeof atom === 'object') { appenders.push({ type: 'logLevelFilter', level: 'WARN', appender: { - type: require.resolve('./consoleAppender'), - }, + type: require.resolve('./consoleAppender') + } }); appenders.push({ type: 'logLevelFilter', level: 'ALL', appender: { - type: require.resolve('./nuclideConsoleAppender'), - }, + type: require.resolve('./nuclideConsoleAppender') + } }); } else { // Make sure FATAL errors make it to stderr. @@ -66,14 +86,14 @@ export function getDefaultConfig(): log4js$Config { level: 'FATAL', appender: { type: require.resolve('./consoleAppender'), - stderr: true, - }, + stderr: true + } }); } - if (!isRunningInTest()) { + if (!(0, (_systemInfo || _load_systemInfo()).isRunningInTest)()) { appenders.push({ type: require.resolve('./processTrackingAppender'), - category: PROCESS_LOG_CATEGORY, + category: (_process || _load_process()).LOG_CATEGORY }); try { const scribeAppenderPath = require.resolve('../fb/scribeAppender'); @@ -83,12 +103,12 @@ export function getDefaultConfig(): log4js$Config { level: 'ERROR', appender: { type: scribeAppenderPath, - scribeCategory: 'errorlog_arsenal', - }, + scribeCategory: 'errorlog_arsenal' + } }); } catch (err) { // We're running in open-source: ignore. } } - return {appenders}; -} + return { appenders }; +} \ No newline at end of file diff --git a/pkg/nuclide-logging/lib/consoleAppender.js b/pkg/nuclide-logging/lib/consoleAppender.js index 8bf2e9e586..e65b8c632b 100644 --- a/pkg/nuclide-logging/lib/consoleAppender.js +++ b/pkg/nuclide-logging/lib/consoleAppender.js @@ -1,23 +1,11 @@ -/** - * 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 - */ +'use strict'; + +var _util = _interopRequireDefault(require('util')); -import util from 'util'; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function layout(loggingEvent: any): Array { - const eventInfo = util.format( - '[%s] [%s] %s - ', - loggingEvent.startTime.toISOString(), - loggingEvent.level, - loggingEvent.categoryName, - ); +function layout(loggingEvent) { + const eventInfo = _util.default.format('[%s] [%s] %s - ', loggingEvent.startTime.toISOString(), loggingEvent.level, loggingEvent.categoryName); const data = loggingEvent.data.slice(); @@ -47,7 +35,18 @@ function layout(loggingEvent: any): Array { * Comparing to log4js's console appender(https://fburl.com/69861669), you can expand and explore * the object in console logged by this Appender. */ -function consoleAppender(config: Object): (loggingEvent: any) => void { +/** + * 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. + * + * + * @format + */ + +function consoleAppender(config) { return loggingEvent => { if (config.stderr) { // eslint-disable-next-line no-console @@ -62,5 +61,5 @@ function consoleAppender(config: Object): (loggingEvent: any) => void { // eslint-disable-next-line nuclide-internal/no-commonjs module.exports = { appender: consoleAppender, - configure: consoleAppender, -}; + configure: consoleAppender +}; \ No newline at end of file diff --git a/pkg/nuclide-logging/lib/main.js b/pkg/nuclide-logging/lib/main.js index ac57a67113..17afde3614 100644 --- a/pkg/nuclide-logging/lib/main.js +++ b/pkg/nuclide-logging/lib/main.js @@ -1,13 +1,58 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.initializeLogging = exports.getPathToLogFile = exports.getDefaultConfig = undefined; +exports.flushLogsAndExit = flushLogsAndExit; +exports.flushLogsAndAbort = flushLogsAndAbort; +exports.setupLoggingService = setupLoggingService; + +var _log4js; + +function _load_log4js() { + return _log4js = _interopRequireDefault(require('log4js')); +} + +var _analytics; + +function _load_analytics() { + return _analytics = require('../../../modules/nuclide-commons/analytics'); +} + +var _track; + +function _load_track() { + return _track = _interopRequireWildcard(require('../../nuclide-analytics/lib/track')); +} + +var _once; + +function _load_once() { + return _once = _interopRequireDefault(require('../../commons-node/once')); +} + +var _config; + +function _load_config() { + return _config = require('./config'); +} + +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 }; } + +exports.getDefaultConfig = (_config || _load_config()).getDefaultConfig; +exports.getPathToLogFile = (_config || _load_config()).getPathToLogFile; /** + * 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. + * + * strict-local + * @format + */ /** * This designed for logging on both Nuclide client and Nuclide server. It is based on [log4js] @@ -17,33 +62,23 @@ * to `global` object. */ -import log4js from 'log4js'; - -import {setRawAnalyticsService} from 'nuclide-commons/analytics'; -import * as rawAnalyticsService from '../../nuclide-analytics/lib/track'; - -import once from '../../commons-node/once'; -import {getDefaultConfig, getPathToLogFile} from './config'; - -export {getDefaultConfig, getPathToLogFile}; - -export function flushLogsAndExit(exitCode: number): void { - log4js.shutdown(() => process.exit(exitCode)); +function flushLogsAndExit(exitCode) { + (_log4js || _load_log4js()).default.shutdown(() => process.exit(exitCode)); } -export function flushLogsAndAbort(): void { - log4js.shutdown(() => process.abort()); +function flushLogsAndAbort() { + (_log4js || _load_log4js()).default.shutdown(() => process.abort()); } /** * Push initial default config to log4js. * Execute only once. */ -export const initializeLogging = once(() => { +const initializeLogging = exports.initializeLogging = (0, (_once || _load_once()).default)(() => { setupLoggingService(); - log4js.configure(getDefaultConfig()); + (_log4js || _load_log4js()).default.configure((0, (_config || _load_config()).getDefaultConfig)()); }); -export function setupLoggingService(): void { - setRawAnalyticsService(rawAnalyticsService); -} +function setupLoggingService() { + (0, (_analytics || _load_analytics()).setRawAnalyticsService)(_track || _load_track()); +} \ No newline at end of file diff --git a/pkg/nuclide-logging/lib/nuclideConsoleAppender.js b/pkg/nuclide-logging/lib/nuclideConsoleAppender.js index 88dc1b8433..5a7a2e3f18 100644 --- a/pkg/nuclide-logging/lib/nuclideConsoleAppender.js +++ b/pkg/nuclide-logging/lib/nuclideConsoleAppender.js @@ -1,3 +1,13 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.configure = exports.appender = undefined; +exports.getNuclideConsoleMessages = getNuclideConsoleMessages; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,38 +15,27 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {Observable} from 'rxjs'; - -import {Subject} from 'rxjs'; - -type NuclideConsoleMessage = { - data: string, - level: string, - startTime: string, - categoryName: string, -}; - let sub = null; -function getSubject(): Subject { +function getSubject() { if (sub == null) { - sub = new Subject(); + sub = new _rxjsBundlesRxMinJs.Subject(); } return sub; } -export function getNuclideConsoleMessages(): Observable { +function getNuclideConsoleMessages() { return getSubject().asObservable(); } -function consoleAppender(): (loggingEvent: any) => void { +function consoleAppender() { return loggingEvent => { getSubject().next(loggingEvent); }; } -export const appender = consoleAppender; -export const configure = consoleAppender; +const appender = exports.appender = consoleAppender; +const configure = exports.configure = consoleAppender; \ No newline at end of file diff --git a/pkg/nuclide-logging/lib/processTrackingAppender.js b/pkg/nuclide-logging/lib/processTrackingAppender.js index aa1574a403..616f553338 100644 --- a/pkg/nuclide-logging/lib/processTrackingAppender.js +++ b/pkg/nuclide-logging/lib/processTrackingAppender.js @@ -1,3 +1,35 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.appender = undefined; +exports.configure = configure; + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _string; + +function _load_string() { + return _string = require('../../../modules/nuclide-commons/string'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,34 +37,24 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import {levels} from 'log4js'; -import {ProcessLoggingEvent} from 'nuclide-commons/process'; -import {shorten} from 'nuclide-commons/string'; -import {trackSampled} from '../../nuclide-analytics'; - const SAMPLE_RATE = 10; -type LoggingEvent = { - data: Array, - level: Object, -}; - -export function configure(): (loggingEvent: LoggingEvent) => void { - return ({data, level}) => { - if (level === levels.INFO) { +function configure() { + return ({ data, level }) => { + if (level === (_log4js || _load_log4js()).levels.INFO) { const arg = data[0]; - if (arg instanceof ProcessLoggingEvent) { - trackSampled('process-exit', SAMPLE_RATE, { - command: shorten(arg.command, 100, '...'), - duration: arg.duration, + if (arg instanceof (_process || _load_process()).ProcessLoggingEvent) { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackSampled)('process-exit', SAMPLE_RATE, { + command: (0, (_string || _load_string()).shorten)(arg.command, 100, '...'), + duration: arg.duration }); } } }; } -export const appender = configure; +const appender = exports.appender = configure; \ No newline at end of file diff --git a/pkg/nuclide-logging/lib/rpc-types.js b/pkg/nuclide-logging/lib/rpc-types.js index 6751a50bf8..f3aa390e84 100644 --- a/pkg/nuclide-logging/lib/rpc-types.js +++ b/pkg/nuclide-logging/lib/rpc-types.js @@ -1,3 +1,9 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.parseLogLevel = parseLogLevel; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,46 +11,13 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {DeadlineRequest} from 'nuclide-commons/promise'; - -export type LogLevel = - | 'ALL' - | 'TRACE' - | 'DEBUG' - | 'INFO' - | 'WARN' - | 'ERROR' - | 'FATAL' - | 'OFF'; - -export type AdditionalLogFilesProvider = {| - id: string, - getAdditionalLogFiles( - deadline: DeadlineRequest, - ): Promise>, -|}; - -export type AdditionalLogFile = { - title: string, // usually a filepath - data: string, -}; - -export function parseLogLevel(s: mixed, _default: LogLevel): LogLevel { - if ( - s === 'ALL' || - s === 'TRACE' || - s === 'DEBUG' || - s === 'INFO' || - s === 'WARN' || - s === 'ERROR' || - s === 'FATAL' || - s === 'OFF' - ) { +function parseLogLevel(s, _default) { + if (s === 'ALL' || s === 'TRACE' || s === 'DEBUG' || s === 'INFO' || s === 'WARN' || s === 'ERROR' || s === 'FATAL' || s === 'OFF') { return s; } return _default; -} +} \ No newline at end of file diff --git a/pkg/nuclide-logging/lib/types.js b/pkg/nuclide-logging/lib/types.js index 0387640fd5..9a390c31f7 100644 --- a/pkg/nuclide-logging/lib/types.js +++ b/pkg/nuclide-logging/lib/types.js @@ -1,36 +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 - */ - -export type Logger = { - debug(...args: Array): mixed, - error(...args: Array): mixed, - fatal(...args: Array): mixed, - info(...args: Array): mixed, - trace(...args: Array): mixed, - warn(...args: Array): mixed, - isLevelEnabled(level: string): mixed, - setLevel(level: string): mixed, -}; - -export type LoggingEvent = { - startTime: Date, - categoryName: string, - data: Array, - level: { - level: number, - levelStr: string, - }, - logger?: { - category: string, - }, - storageKey?: string, - runtime?: any, -}; +"use strict"; \ No newline at end of file diff --git a/pkg/nuclide-logging/lib/utils.js b/pkg/nuclide-logging/lib/utils.js index 25e3c03dd5..d2e9fa9139 100644 --- a/pkg/nuclide-logging/lib/utils.js +++ b/pkg/nuclide-logging/lib/utils.js @@ -1,19 +1,31 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.patchErrorsOfLoggingEvent = patchErrorsOfLoggingEvent; +exports.serializeLoggingEvent = serializeLoggingEvent; +exports.deserializeLoggingEvent = deserializeLoggingEvent; -import log4js from 'log4js'; -import StackTrace from 'stack-trace'; +var _log4js; + +function _load_log4js() { + return _log4js = _interopRequireDefault(require('log4js')); +} + +var _stackTrace; + +function _load_stackTrace() { + return _stackTrace = _interopRequireDefault(require('stack-trace')); +} -import type {LoggingEvent} from './types'; -import safeStringify from 'json-stringify-safe'; +var _jsonStringifySafe; + +function _load_jsonStringifySafe() { + return _jsonStringifySafe = _interopRequireDefault(require('json-stringify-safe')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * JSON.stringify can't stringify instance of Error. To solve this problem, we @@ -23,10 +35,8 @@ import safeStringify from 'json-stringify-safe'; * loggingEvent.data, so that we could get stack information which helps categorization in * logview. */ -export function patchErrorsOfLoggingEvent( - loggingEvent: LoggingEvent, -): LoggingEvent { - const loggingEventCopy = {...loggingEvent}; +function patchErrorsOfLoggingEvent(loggingEvent) { + const loggingEventCopy = Object.assign({}, loggingEvent); loggingEventCopy.data = (loggingEventCopy.data || []).slice(); if (!loggingEventCopy.data.some(item => item instanceof Error)) { @@ -37,21 +47,19 @@ export function patchErrorsOfLoggingEvent( if (item instanceof Error) { // Atom already parses stack traces and stores them as rawStack - // so no need to manually parse things in that case. - const rawStack = Array.isArray(item.rawStack) - ? item.rawStack - : StackTrace.parse(item); + const rawStack = Array.isArray(item.rawStack) ? item.rawStack : (_stackTrace || _load_stackTrace()).default.parse(item); const stackTrace = rawStack.map(callsite => ({ functionName: callsite.getFunctionName(), methodName: callsite.getMethodName(), fileName: callsite.getFileName(), lineNumber: callsite.getLineNumber(), - columnNumber: callsite.getColumnNumber(), + columnNumber: callsite.getColumnNumber() })); return { name: item.name, message: item.message, stack: item.stack, - stackTrace, + stackTrace }; } return item; @@ -63,8 +71,19 @@ export function patchErrorsOfLoggingEvent( /** * Takes a loggingEvent object, returns string representation of it. */ -export function serializeLoggingEvent(loggingEvent: mixed): string { - return safeStringify(loggingEvent); +/** + * 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. + * + * + * @format + */ + +function serializeLoggingEvent(loggingEvent) { + return (0, (_jsonStringifySafe || _load_jsonStringifySafe()).default)(loggingEvent); } /** @@ -77,22 +96,20 @@ export function serializeLoggingEvent(loggingEvent: mixed): string { * so we need smart deserialization that will recreate log date and level for further processing by * log4js internals. */ -export function deserializeLoggingEvent( - loggingEventString: string, -): LoggingEvent { +function deserializeLoggingEvent(loggingEventString) { let loggingEvent; try { loggingEvent = JSON.parse(loggingEventString); loggingEvent.startTime = new Date(loggingEvent.startTime); - loggingEvent.level = log4js.levels.toLevel(loggingEvent.level.levelStr); + loggingEvent.level = (_log4js || _load_log4js()).default.levels.toLevel(loggingEvent.level.levelStr); } catch (e) { // JSON.parse failed, just log the contents probably a naughty. loggingEvent = { startTime: new Date(), categoryName: 'log4js', - level: log4js.levels.ERROR, - data: ['Unable to parse log:', loggingEventString], + level: (_log4js || _load_log4js()).default.levels.ERROR, + data: ['Unable to parse log:', loggingEventString] }; } return loggingEvent; -} +} \ No newline at end of file diff --git a/pkg/nuclide-lsp-implementation-common/TextDocument.js b/pkg/nuclide-lsp-implementation-common/TextDocument.js index 338223b69a..aa239f4ca6 100644 --- a/pkg/nuclide-lsp-implementation-common/TextDocument.js +++ b/pkg/nuclide-lsp-implementation-common/TextDocument.js @@ -1,60 +1,60 @@ -/** - * 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 - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - // flowlint-next-line untyped-type-import:off - TextDocumentContentChangeEvent, - // flowlint-next-line untyped-type-import:off - Position, -} from 'vscode-languageserver-types'; - -import invariant from 'assert'; -import SimpleTextBuffer from 'simple-text-buffer'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Emitter} from 'event-kit'; -import { - atomPointToLSPPosition, - compareLspRange, - lspPositionToAtomPoint, - lspRangeToAtomRange, -} from './lsp-utils'; - -export default class TextDocument { - buffer: SimpleTextBuffer; - isDirty: boolean = false; - languageId: string; - uri: NuclideUri; - version: number; - - _disposables: UniversalDisposable = new UniversalDisposable(); - _emitter: Emitter = new Emitter(); - - constructor(uri: string, languageId: string, version: number, text: string) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _simpleTextBuffer; + +function _load_simpleTextBuffer() { + return _simpleTextBuffer = _interopRequireDefault(require('simple-text-buffer')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../modules/nuclide-commons/UniversalDisposable')); +} + +var _eventKit; + +function _load_eventKit() { + return _eventKit = require('event-kit'); +} + +var _lspUtils; + +function _load_lspUtils() { + return _lspUtils = require('./lsp-utils'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class TextDocument { + + constructor(uri, languageId, version, text) { + this.isDirty = false; + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._emitter = new (_eventKit || _load_eventKit()).Emitter(); + + this._handleDidStopChanging = () => { + this.assertNotDisposed(); + this._emitter.emit('didStopChanging', this); + }; + this.uri = uri; this.languageId = languageId; this.version = version; - this.buffer = new SimpleTextBuffer(text); + this.buffer = new (_simpleTextBuffer || _load_simpleTextBuffer()).default(text); this._disposables.add(this._emitter); - this._disposables.add( - this.buffer.onDidStopChanging(this._handleDidStopChanging), - ); + this._disposables.add(this.buffer.onDidStopChanging(this._handleDidStopChanging)); } assertNotDisposed() { - invariant( - !this.disposed, - `TextDocument with uri ${this.uri} was already disposed`, - ); + if (!!this.disposed) { + throw new Error(`TextDocument with uri ${this.uri} was already disposed`); + } } dispose() { @@ -63,49 +63,45 @@ export default class TextDocument { this._disposables.dispose(); } - get disposed(): boolean { + get disposed() { return this._disposables.disposed; } - get lineCount(): number { + get lineCount() { this.assertNotDisposed(); return this.buffer.getLineCount(); } - getText(): string { + getText() { this.assertNotDisposed(); return this.buffer.getText(); } - offsetAt(position: Position): number { + offsetAt(position) { this.assertNotDisposed(); - return this.buffer.characterIndexForPosition( - lspPositionToAtomPoint(position), - ); + return this.buffer.characterIndexForPosition((0, (_lspUtils || _load_lspUtils()).lspPositionToAtomPoint)(position)); } - onDidDispose(handler: () => mixed): IDisposable { + onDidDispose(handler) { return this._emitter.on('dispose', handler); } - onDidStopChanging(handler: (document: TextDocument) => void): IDisposable { + onDidStopChanging(handler) { this.assertNotDisposed(); return this._emitter.on('didStopChanging', handler); } - onDidSave(handler: (document: TextDocument) => void): IDisposable { + onDidSave(handler) { this.assertNotDisposed(); return this._emitter.on('didSave', handler); } - positionAt(offset: number): Position { + positionAt(offset) { this.assertNotDisposed(); - return atomPointToLSPPosition( - this.buffer.positionForCharacterIndex(offset), - ); + return (0, (_lspUtils || _load_lspUtils()).atomPointToLSPPosition)(this.buffer.positionForCharacterIndex(offset)); } - save(text: ?string) { + save(text) { this.assertNotDisposed(); if (text != null) { this.buffer.setText(text); @@ -115,7 +111,7 @@ export default class TextDocument { this._emitter.emit('didSave', this); } - updateMany(changes: Array, version: number) { + updateMany(changes, version) { this.assertNotDisposed(); this.isDirty = true; @@ -124,20 +120,17 @@ export default class TextDocument { // Ensure that ranged changes are sorted in reverse order. // Otherwise, the changes can't be applied cleanly. changes.sort((a, b) => { - invariant( - a.range != null && b.range != null, - 'There should only be one full-text update.', - ); - return compareLspRange(b.range, a.range); + if (!(a.range != null && b.range != null)) { + throw new Error('There should only be one full-text update.'); + } + + return (0, (_lspUtils || _load_lspUtils()).compareLspRange)(b.range, a.range); }); for (const change of changes) { if (change.range != null) { // Incremental update - this.buffer.setTextInRange( - lspRangeToAtomRange(change.range), - change.text, - ); + this.buffer.setTextInRange((0, (_lspUtils || _load_lspUtils()).lspRangeToAtomRange)(change.range), change.text); } else { // Full text update this.buffer.setText(change.text); @@ -145,8 +138,14 @@ export default class TextDocument { } } - _handleDidStopChanging = () => { - this.assertNotDisposed(); - this._emitter.emit('didStopChanging', this); - }; } +exports.default = TextDocument; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-lsp-implementation-common/TextDocuments.js b/pkg/nuclide-lsp-implementation-common/TextDocuments.js index 733fcf9e26..814c17f227 100644 --- a/pkg/nuclide-lsp-implementation-common/TextDocuments.js +++ b/pkg/nuclide-lsp-implementation-common/TextDocuments.js @@ -1,3 +1,36 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _TextDocument; + +function _load_TextDocument() { + return _TextDocument = _interopRequireDefault(require('./TextDocument')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../modules/nuclide-commons/UniversalDisposable')); +} + +var _eventKit; + +function _load_eventKit() { + return _eventKit = require('event-kit'); +} + +var _vscodeLanguageserver; + +function _load_vscodeLanguageserver() { + return _vscodeLanguageserver = require('vscode-languageserver'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// flowlint-next-line untyped-type-import:off /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,134 +38,112 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type { - DidChangeTextDocumentParams, - DidCloseTextDocumentParams, - DidOpenTextDocumentParams, - DidSaveTextDocumentParams, - TextDocumentItem, -} from '../nuclide-vscode-language-service-rpc/lib/protocol'; - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -// flowlint-next-line untyped-type-import:off -import type {IConnection} from 'vscode-languageserver'; - -import invariant from 'assert'; -import TextDocument from './TextDocument'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Emitter} from 'event-kit'; -import {TextDocumentSyncKind} from 'vscode-languageserver'; - -function textDocumentFromLSPTextDocument(textDocument: TextDocumentItem) { - return new TextDocument( - textDocument.uri, - textDocument.languageId, - textDocument.version, - textDocument.text, - ); +function textDocumentFromLSPTextDocument(textDocument) { + return new (_TextDocument || _load_TextDocument()).default(textDocument.uri, textDocument.languageId, textDocument.version, textDocument.text); } -export default class TextDocuments { - _disposables = new UniversalDisposable(); - _documents: Map = new Map(); - _emitter: Emitter = new Emitter(); +class TextDocuments { constructor() { + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._documents = new Map(); + this._emitter = new (_eventKit || _load_eventKit()).Emitter(); + + this._handleDidStopChanging = textDocument => { + this._emitter.emit('didChangeContent', { textDocument }); + }; + + this._handleDidSave = textDocument => { + this._emitter.emit('didSave', { textDocument }); + }; + this._disposables.add(this._emitter); } - dispose(): void { + dispose() { this._disposables.dispose(); } - get disposed(): boolean { + get disposed() { return this._disposables.disposed; } - get syncKind(): TextDocumentSyncKind { - return TextDocumentSyncKind.Incremental; + get syncKind() { + return (_vscodeLanguageserver || _load_vscodeLanguageserver()).TextDocumentSyncKind.Incremental; } - get(uri: string): TextDocument { + get(uri) { const document = this._documents.get(uri); - invariant( - document != null, - `TextDocuments: asked for document with uri ${uri}, but no buffer was loaded`, - ); + if (!(document != null)) { + throw new Error(`TextDocuments: asked for document with uri ${uri}, but no buffer was loaded`); + } + return document; } - listen(connection: IConnection): void { - connection.onDidOpenTextDocument((e: DidOpenTextDocumentParams) => { - const {textDocument} = e; + listen(connection) { + connection.onDidOpenTextDocument(e => { + const { textDocument } = e; const document = textDocumentFromLSPTextDocument(textDocument); this.addDocument(textDocument.uri, document); }); - connection.onDidChangeTextDocument((e: DidChangeTextDocumentParams) => { - const {contentChanges, textDocument} = e; + connection.onDidChangeTextDocument(e => { + const { contentChanges, textDocument } = e; const document = this.get(textDocument.uri); document.updateMany(contentChanges, textDocument.version); }); - connection.onDidCloseTextDocument((e: DidCloseTextDocumentParams) => { + connection.onDidCloseTextDocument(e => { this.removeDocument(e.textDocument.uri); }); - connection.onDidSaveTextDocument((e: DidSaveTextDocumentParams) => { + connection.onDidSaveTextDocument(e => { const document = this.get(e.textDocument.uri); document.save(e.text); }); } - addDocument(uri: NuclideUri, document: TextDocument) { + addDocument(uri, document) { this._documents.set(uri, document); this._disposables.add(document); - this._emitter.emit('didOpenTextDocument', {textDocument: document}); + this._emitter.emit('didOpenTextDocument', { textDocument: document }); document.onDidStopChanging(this._handleDidStopChanging); document.onDidSave(this._handleDidSave); } - removeDocument(uri: NuclideUri) { + removeDocument(uri) { const document = this.get(uri); - this._emitter.emit('didClose', {textDocument: document}); + this._emitter.emit('didClose', { textDocument: document }); this._disposables.remove(document); this._documents.delete(uri); document.dispose(); } - all(): Array { + all() { return Array.from(this._documents.values()); } - onDidChangeContent(handler: (e: {textDocument: TextDocument}) => void): void { + onDidChangeContent(handler) { this._emitter.on('didChangeContent', handler); } - onDidSave(handler: (e: {textDocument: TextDocument}) => void): void { + onDidSave(handler) { this._emitter.on('didSave', handler); } - onDidOpenTextDocument( - handler: (e: {textDocument: TextDocument}) => void, - ): void { + onDidOpenTextDocument(handler) { this._emitter.on('didOpenTextDocument', handler); } - onDidClose(handler: (e: {textDocument: TextDocument}) => void): void { + onDidClose(handler) { this._emitter.on('didClose', handler); } - _handleDidStopChanging = (textDocument: TextDocument) => { - this._emitter.emit('didChangeContent', {textDocument}); - }; - - _handleDidSave = (textDocument: TextDocument) => { - this._emitter.emit('didSave', {textDocument}); - }; } +exports.default = TextDocuments; \ No newline at end of file diff --git a/pkg/nuclide-lsp-implementation-common/connectionConsoleAppender.js b/pkg/nuclide-lsp-implementation-common/connectionConsoleAppender.js index d3b3235c7e..6ef994a52d 100644 --- a/pkg/nuclide-lsp-implementation-common/connectionConsoleAppender.js +++ b/pkg/nuclide-lsp-implementation-common/connectionConsoleAppender.js @@ -1,52 +1,63 @@ -/** - * 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 - */ - -import log4js from 'log4js'; -import {IConnection} from 'vscode-languageserver'; -import { - type LogMessageParams, - MessageType, -} from '../nuclide-vscode-language-service-rpc/lib/protocol'; - -function getMessageType(levelStr: string) { +'use strict'; + +var _log4js; + +function _load_log4js() { + return _log4js = _interopRequireDefault(require('log4js')); +} + +var _vscodeLanguageserver; + +function _load_vscodeLanguageserver() { + return _vscodeLanguageserver = require('vscode-languageserver'); +} + +var _protocol; + +function _load_protocol() { + return _protocol = require('../nuclide-vscode-language-service-rpc/lib/protocol'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function getMessageType(levelStr) { switch (levelStr) { case 'ERROR': - return MessageType.Error; + return (_protocol || _load_protocol()).MessageType.Error; case 'WARN': - return MessageType.Warning; + return (_protocol || _load_protocol()).MessageType.Warning; case 'INFO': - return MessageType.Info; + return (_protocol || _load_protocol()).MessageType.Info; default: - return MessageType.Log; + return (_protocol || _load_protocol()).MessageType.Log; } -} +} /** + * 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. + * + * + * @format + */ -function appender(config: {connection: IConnection}) { - const {connection} = config; +function appender(config) { + const { connection } = config; // eslint-disable-next-line flowtype/no-weak-types - return (loggingEvent: any): void => { + return loggingEvent => { // $FlowFixMe: type log4js.layouts - const message = log4js.layouts.basicLayout(loggingEvent); - if (loggingEvent.level.level >= log4js.levels.INFO.level) { + const message = (_log4js || _load_log4js()).default.layouts.basicLayout(loggingEvent); + if (loggingEvent.level.level >= (_log4js || _load_log4js()).default.levels.INFO.level) { connection.console.log(message); } - connection.telemetry.logEvent( - ({ - type: getMessageType(loggingEvent.level.levelStr), - message, - }: LogMessageParams), - ); + connection.telemetry.logEvent({ + type: getMessageType(loggingEvent.level.levelStr), + message + }); }; } // eslint-disable-next-line nuclide-internal/no-commonjs -module.exports.configure = module.exports.appender = appender; +module.exports.configure = module.exports.appender = appender; \ No newline at end of file diff --git a/pkg/nuclide-lsp-implementation-common/lsp-utils.js b/pkg/nuclide-lsp-implementation-common/lsp-utils.js index e4ecccb6a4..5fc1b713e4 100644 --- a/pkg/nuclide-lsp-implementation-common/lsp-utils.js +++ b/pkg/nuclide-lsp-implementation-common/lsp-utils.js @@ -1,3 +1,21 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.lspPositionToAtomPoint = lspPositionToAtomPoint; +exports.atomPointToLSPPosition = atomPointToLSPPosition; +exports.lspRangeToAtomRange = lspRangeToAtomRange; +exports.atomRangeToLSPRange = atomRangeToLSPRange; +exports.compareLspPosition = compareLspPosition; +exports.compareLspRange = compareLspRange; + +var _simpleTextBuffer; + +function _load_simpleTextBuffer() { + return _simpleTextBuffer = require('simple-text-buffer'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,46 +23,40 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ // flowlint-next-line untyped-type-import:off -import type {Position, IPosition, IRange} from 'vscode-languageserver-types'; - -import {Point} from 'simple-text-buffer'; - -export function lspPositionToAtomPoint(lspPosition: IPosition): atom$Point { - return new Point(lspPosition.line, lspPosition.character); +function lspPositionToAtomPoint(lspPosition) { + return new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(lspPosition.line, lspPosition.character); } -export function atomPointToLSPPosition(atomPoint: atom$PointObject): IPosition { +function atomPointToLSPPosition(atomPoint) { return { line: atomPoint.row, - character: atomPoint.column, + character: atomPoint.column }; } -export function lspRangeToAtomRange(lspRange: IRange): atom$RangeObject { +function lspRangeToAtomRange(lspRange) { return { start: lspPositionToAtomPoint(lspRange.start), - end: lspPositionToAtomPoint(lspRange.end), + end: lspPositionToAtomPoint(lspRange.end) }; } -export function atomRangeToLSPRange(atomRange: atom$Range): IRange { +function atomRangeToLSPRange(atomRange) { return { start: atomPointToLSPPosition(atomRange.start), - end: atomPointToLSPPosition(atomRange.end), + end: atomPointToLSPPosition(atomRange.end) }; } -export function compareLspPosition(a: Position, b: Position): number { +function compareLspPosition(a, b) { return a.line - b.line || a.character - b.character; } -export function compareLspRange(a: IRange, b: IRange): number { - return ( - compareLspPosition(a.start, b.start) || compareLspPosition(a.end, b.end) - ); -} +function compareLspRange(a, b) { + return compareLspPosition(a.start, b.start) || compareLspPosition(a.end, b.end); +} \ No newline at end of file diff --git a/pkg/nuclide-marshalers-atom/lib/main.js b/pkg/nuclide-marshalers-atom/lib/main.js index 04da4553f9..8ac54834fd 100644 --- a/pkg/nuclide-marshalers-atom/lib/main.js +++ b/pkg/nuclide-marshalers-atom/lib/main.js @@ -1,50 +1,46 @@ -/** - * 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 strict-local - * @format - */ - -import type {PredefinedTransformer} from '../../nuclide-rpc'; - -import { - getRemoteNuclideUriMarshalers, - localNuclideUriMarshalers, -} from '../../nuclide-marshalers-common'; -import {Range as AtomRange, Point as AtomPoint} from 'atom'; - -const jsonToAtomPoint = json => new AtomPoint(json.row, json.column); -const jsonToAtomRange = json => - new AtomRange(jsonToAtomPoint(json.start), jsonToAtomPoint(json.end)); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getAtomSideLoopbackMarshalers = undefined; +exports.getAtomSideMarshalers = getAtomSideMarshalers; + +var _nuclideMarshalersCommon; + +function _load_nuclideMarshalersCommon() { + return _nuclideMarshalersCommon = require('../../nuclide-marshalers-common'); +} + +var _atom = require('atom'); + +const jsonToAtomPoint = json => new _atom.Point(json.row, json.column); /** + * 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. + * + * strict-local + * @format + */ + +const jsonToAtomRange = json => new _atom.Range(jsonToAtomPoint(json.start), jsonToAtomPoint(json.end)); const atomPointMarshalers = { typeName: 'atom$Point', marshaller: point => point, - unmarshaller: jsonToAtomPoint, + unmarshaller: jsonToAtomPoint }; const atomRangeMarshalers = { typeName: 'atom$Range', marshaller: range => range, - unmarshaller: jsonToAtomRange, + unmarshaller: jsonToAtomRange }; -export function getAtomSideMarshalers( - hostname: string, -): Array { - return [ - getRemoteNuclideUriMarshalers(hostname), - atomPointMarshalers, - atomRangeMarshalers, - ]; +function getAtomSideMarshalers(hostname) { + return [(0, (_nuclideMarshalersCommon || _load_nuclideMarshalersCommon()).getRemoteNuclideUriMarshalers)(hostname), atomPointMarshalers, atomRangeMarshalers]; } -export const getAtomSideLoopbackMarshalers: Array = [ - localNuclideUriMarshalers, - atomPointMarshalers, - atomRangeMarshalers, -]; +const getAtomSideLoopbackMarshalers = exports.getAtomSideLoopbackMarshalers = [(_nuclideMarshalersCommon || _load_nuclideMarshalersCommon()).localNuclideUriMarshalers, atomPointMarshalers, atomRangeMarshalers]; \ No newline at end of file diff --git a/pkg/nuclide-marshalers-common/lib/main.js b/pkg/nuclide-marshalers-common/lib/main.js index ce51addaa0..8df3bfdc3d 100644 --- a/pkg/nuclide-marshalers-common/lib/main.js +++ b/pkg/nuclide-marshalers-common/lib/main.js @@ -1,55 +1,63 @@ -/** - * 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 strict-local - * @format - */ - -import type {PredefinedTransformer} from '../../nuclide-rpc'; - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Range as ServerRange, Point as ServerPoint} from 'simple-text-buffer'; - -export function getRemoteNuclideUriMarshalers( - hostname: string, -): PredefinedTransformer { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getServerSideMarshalers = exports.localNuclideUriMarshalers = undefined; +exports.getRemoteNuclideUriMarshalers = getRemoteNuclideUriMarshalers; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _simpleTextBuffer; + +function _load_simpleTextBuffer() { + return _simpleTextBuffer = require('simple-text-buffer'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function getRemoteNuclideUriMarshalers(hostname) { return { - typeName: nuclideUri.NUCLIDE_URI_TYPE_NAME, - marshaller: remoteUri => nuclideUri.getPath(remoteUri), - unmarshaller: path => nuclideUri.createRemoteUri(hostname, path), + typeName: (_nuclideUri || _load_nuclideUri()).default.NUCLIDE_URI_TYPE_NAME, + marshaller: remoteUri => (_nuclideUri || _load_nuclideUri()).default.getPath(remoteUri), + unmarshaller: path => (_nuclideUri || _load_nuclideUri()).default.createRemoteUri(hostname, path) }; -} +} /** + * 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. + * + * strict-local + * @format + */ -export const localNuclideUriMarshalers: PredefinedTransformer = { - typeName: nuclideUri.NUCLIDE_URI_TYPE_NAME, +const localNuclideUriMarshalers = exports.localNuclideUriMarshalers = { + typeName: (_nuclideUri || _load_nuclideUri()).default.NUCLIDE_URI_TYPE_NAME, marshaller: uri => { - nuclideUri.validate(uri, false); + (_nuclideUri || _load_nuclideUri()).default.validate(uri, false); return uri; }, unmarshaller: remotePath => { - nuclideUri.validate(remotePath, false); + (_nuclideUri || _load_nuclideUri()).default.validate(remotePath, false); return remotePath; - }, + } }; -const jsonToServerPoint = json => new ServerPoint(json.row, json.column); -const jsonToServerRange = json => - new ServerRange(jsonToServerPoint(json.start), jsonToServerPoint(json.end)); +const jsonToServerPoint = json => new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(json.row, json.column); +const jsonToServerRange = json => new (_simpleTextBuffer || _load_simpleTextBuffer()).Range(jsonToServerPoint(json.start), jsonToServerPoint(json.end)); -export const getServerSideMarshalers: Array = [ - localNuclideUriMarshalers, - { - typeName: 'atom$Point', - marshaller: point => point, - unmarshaller: jsonToServerPoint, - }, - { - typeName: 'atom$Range', - marshaller: range => range, - unmarshaller: jsonToServerRange, - }, -]; +const getServerSideMarshalers = exports.getServerSideMarshalers = [localNuclideUriMarshalers, { + typeName: 'atom$Point', + marshaller: point => point, + unmarshaller: jsonToServerPoint +}, { + typeName: 'atom$Range', + marshaller: range => range, + unmarshaller: jsonToServerRange +}]; \ No newline at end of file diff --git a/pkg/nuclide-metro-rpc/__tests__/parseMessages-test.js b/pkg/nuclide-metro-rpc/__tests__/parseMessages-test.js index 31f53dd855..5e95be2fcf 100644 --- a/pkg/nuclide-metro-rpc/__tests__/parseMessages-test.js +++ b/pkg/nuclide-metro-rpc/__tests__/parseMessages-test.js @@ -1,3 +1,27 @@ +'use strict'; + +var _parseMessages; + +function _load_parseMessages() { + return _parseMessages = require('../lib/parseMessages'); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,62 +29,37 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import {parseMessages} from '../lib/parseMessages'; -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Observable} from 'rxjs'; - describe('parseMessages', () => { // Run the same tests for each format of the packager output. We do this not because we want to // stay DRY, but to ensure that we're testing for the same output for each format. - [ - 'packager-stdout-1', - 'packager-stdout-2', - 'packager-stdout-3', - 'packager-stdout-4', - ].forEach(fixtureName => { + ['packager-stdout-1', 'packager-stdout-2', 'packager-stdout-3', 'packager-stdout-4'].forEach(fixtureName => { describe(fixtureName, () => { const lines = getLines(fixtureName).publishReplay(); lines.connect(); it('parses the preamble (skipping the ceremony)', async () => { await (async () => { - const output = await parseMessages(lines) - .toArray() - .toPromise(); - expect((output[0]: any).message.text).toBe( - 'Running Metro on port 8081.', - ); + const output = await (0, (_parseMessages || _load_parseMessages()).parseMessages)(lines).toArray().toPromise(); + expect(output[0].message.text).toBe('Running Metro on port 8081.'); })(); }); it('finds the ready line', async () => { await (async () => { - const output = await parseMessages(lines) - .toArray() - .toPromise(); + const output = await (0, (_parseMessages || _load_parseMessages()).parseMessages)(lines).toArray().toPromise(); const readyLines = output.filter(line => line.type === 'ready'); - expect(readyLines.length).toBe( - 1, - 'Expected exactly one ready message.', - ); + expect(readyLines.length).toBe(1, 'Expected exactly one ready message.'); })(); }); }); }); }); -function getLines(name: string): Observable { - const pathToFile = nuclideUri.resolve( - __dirname, - '../__mocks__/fixtures', - `${name}.txt`, - ); - return Observable.defer(() => fsPromise.readFile(pathToFile)).switchMap( - contents => Observable.from(contents.toString().split('\n')), - ); -} +function getLines(name) { + const pathToFile = (_nuclideUri || _load_nuclideUri()).default.resolve(__dirname, '../__mocks__/fixtures', `${name}.txt`); + return _rxjsBundlesRxMinJs.Observable.defer(() => (_fsPromise || _load_fsPromise()).default.readFile(pathToFile)).switchMap(contents => _rxjsBundlesRxMinJs.Observable.from(contents.toString().split('\n'))); +} \ No newline at end of file diff --git a/pkg/nuclide-metro-rpc/__tests__/parseRegularLine-test.js b/pkg/nuclide-metro-rpc/__tests__/parseRegularLine-test.js index dfefb91cc9..bd1b1041d6 100644 --- a/pkg/nuclide-metro-rpc/__tests__/parseRegularLine-test.js +++ b/pkg/nuclide-metro-rpc/__tests__/parseRegularLine-test.js @@ -1,45 +1,43 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import {parseRegularLine} from '../lib/parseRegularLine'; +var _parseRegularLine; + +function _load_parseRegularLine() { + return _parseRegularLine = require('../lib/parseRegularLine'); +} describe('parseRegularLine', () => { it('parses the message when the time is in brackets', () => { - const parsed = parseRegularLine('[2:08:50 PM] This is the message text'); + const parsed = (0, (_parseRegularLine || _load_parseRegularLine()).parseRegularLine)('[2:08:50 PM] This is the message text'); expect(parsed.text).toBe('This is the message text'); }); it('parses the message when the date is included', () => { - const parsed = parseRegularLine( - '[8/30/2016, 2:10:50 PM] This is the message text', - ); + const parsed = (0, (_parseRegularLine || _load_parseRegularLine()).parseRegularLine)('[8/30/2016, 2:10:50 PM] This is the message text'); expect(parsed.text).toBe('This is the message text'); }); it('parses the message when the time is short', () => { - const parsed = parseRegularLine( - '[08/30/2016 14:08:50] This is the message text', - ); + const parsed = (0, (_parseRegularLine || _load_parseRegularLine()).parseRegularLine)('[08/30/2016 14:08:50] This is the message text'); expect(parsed.text).toBe('This is the message text'); }); it("parses the message when the timestamp's not in brackets", () => { - const parsed = parseRegularLine( - '2016-08-31 10:28:11.931 This is the message text', - ); + const parsed = (0, (_parseRegularLine || _load_parseRegularLine()).parseRegularLine)('2016-08-31 10:28:11.931 This is the message text'); expect(parsed.text).toBe('This is the message text'); }); it("parses the message when there's no timestamp", () => { - const parsed = parseRegularLine('This is the message text'); + const parsed = (0, (_parseRegularLine || _load_parseRegularLine()).parseRegularLine)('This is the message text'); expect(parsed.text).toBe('This is the message text'); }); -}); +}); /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-metro-rpc/lib/MetroService.js b/pkg/nuclide-metro-rpc/lib/MetroService.js index 6f6fcc356b..c97a92af01 100644 --- a/pkg/nuclide-metro-rpc/lib/MetroService.js +++ b/pkg/nuclide-metro-rpc/lib/MetroService.js @@ -1,32 +1,59 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getStartCommand = getStartCommand; +exports.startMetro = startMetro; +exports.reloadApp = reloadApp; +exports.buildBundle = buildBundle; +exports.buildSourceMaps = buildSourceMaps; + +var _StartCommand; + +function _load_StartCommand() { + return _StartCommand = require('./StartCommand'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _string; + +function _load_string() { + return _string = require('../../../modules/nuclide-commons/string'); +} + +var _parseMessages; + +function _load_parseMessages() { + return _parseMessages = require('./parseMessages'); +} -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - MetroEvent, - MetroStartCommand, -} from '../../nuclide-metro-rpc/lib/types'; - -import invariant from 'assert'; -import { - getStartCommandFromBuck, - getStartCommandFromNodePackage, -} from './StartCommand'; -import {ConnectableObservable, Observable} from 'rxjs'; -import {observeProcess} from 'nuclide-commons/process'; -import {shellQuote} from 'nuclide-commons/string'; -import {parseMessages} from './parseMessages'; -import xfetch from '../../commons-node/xfetch'; -import WS from 'ws'; -import {NO_METRO_PROJECT_ERROR, METRO_PORT_BUSY_ERROR} from './types'; +var _xfetch; + +function _load_xfetch() { + return _xfetch = _interopRequireDefault(require('../../commons-node/xfetch')); +} + +var _ws; + +function _load_ws() { + return _ws = _interopRequireDefault(require('ws')); +} + +var _types; + +function _load_types() { + return _types = require('./types'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Get the command that would be used if you asked to start Metro at the given URI. @@ -35,13 +62,8 @@ import {NO_METRO_PROJECT_ERROR, METRO_PORT_BUSY_ERROR} from './types'; * (i.e. where we should look for commands like this) and use that here. The current behavior * of everything having its own algorithm is bad. */ -export async function getStartCommand( - projectRoot: NuclideUri, -): Promise { - return ( - (await getStartCommandFromBuck(projectRoot)) || - getStartCommandFromNodePackage(projectRoot) - ); +async function getStartCommand(projectRoot) { + return (await (0, (_StartCommand || _load_StartCommand()).getStartCommandFromBuck)(projectRoot)) || (0, (_StartCommand || _load_StartCommand()).getStartCommandFromNodePackage)(projectRoot); } /** @@ -49,72 +71,67 @@ export async function getStartCommand( * IMPORTANT: You likely want to start Metro via the Atom service provided by nuclide-metro, * as it sets up Console integration and correctly shares its state across all of Nuclide. */ -export function startMetro( - projectRoot: NuclideUri, - editorArgs: Array, - port: number = 8081, - extraArgs: Array = [], -): ConnectableObservable { - const stdout = Observable.defer(() => getStartCommand(projectRoot)) - .switchMap( - commandInfo => - commandInfo == null - ? Observable.throw(noMetroProjectError()) - : Observable.of(commandInfo), - ) - .switchMap(commandInfo => { - const {command, cwd} = commandInfo; - return observeProcess( - command, - extraArgs.concat(commandInfo.args || []).concat([`--port=${port}`]), - { - cwd, - env: { - ...process.env, - REACT_EDITOR: shellQuote(editorArgs), - // We don't want to pass the NODE_PATH from this process - NODE_PATH: null, - }, - killTreeWhenDone: true, - }, - ).catch(error => { - if (error.exitCode === 11) { - return Observable.throw(metroPortBusyError()); - } else { - return Observable.throw(error); - } - }); - }) - .filter(event => event.kind === 'stdout') - .map(event => { - invariant(event.kind === 'stdout'); - return event.data; +/** + * 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. + * + * + * @format + */ + +function startMetro(projectRoot, editorArgs, port = 8081, extraArgs = []) { + const stdout = _rxjsBundlesRxMinJs.Observable.defer(() => getStartCommand(projectRoot)).switchMap(commandInfo => commandInfo == null ? _rxjsBundlesRxMinJs.Observable.throw(noMetroProjectError()) : _rxjsBundlesRxMinJs.Observable.of(commandInfo)).switchMap(commandInfo => { + const { command, cwd } = commandInfo; + return (0, (_process || _load_process()).observeProcess)(command, extraArgs.concat(commandInfo.args || []).concat([`--port=${port}`]), { + cwd, + env: Object.assign({}, process.env, { + REACT_EDITOR: (0, (_string || _load_string()).shellQuote)(editorArgs), + // We don't want to pass the NODE_PATH from this process + NODE_PATH: null + }), + killTreeWhenDone: true + }).catch(error => { + if (error.exitCode === 11) { + return _rxjsBundlesRxMinJs.Observable.throw(metroPortBusyError()); + } else { + return _rxjsBundlesRxMinJs.Observable.throw(error); + } }); + }).filter(event => event.kind === 'stdout').map(event => { + if (!(event.kind === 'stdout')) { + throw new Error('Invariant violation: "event.kind === \'stdout\'"'); + } - return parseMessages(stdout).publish(); + return event.data; + }); + + return (0, (_parseMessages || _load_parseMessages()).parseMessages)(stdout).publish(); } -function noMetroProjectError(): Error { +function noMetroProjectError() { const error = new Error('No Metro project found'); - (error: any).code = NO_METRO_PROJECT_ERROR; + error.code = (_types || _load_types()).NO_METRO_PROJECT_ERROR; return error; } -function metroPortBusyError(): Error { +function metroPortBusyError() { const error = new Error('Cannot start Metro because the port is busy'); - (error: any).code = METRO_PORT_BUSY_ERROR; + error.code = (_types || _load_types()).METRO_PORT_BUSY_ERROR; return error; } -export async function reloadApp(port: number = 8081): Promise { +async function reloadApp(port = 8081) { return new Promise((resolve, reject) => { const url = `ws://localhost:${port}/message?role=interface&name=Nuclide`; const message = { version: 2, - method: 'reload', + method: 'reload' }; - const ws = new WS(url); + const ws = new (_ws || _load_ws()).default(url); ws.onopen = () => { ws.send(JSON.stringify(message)); ws.close(); @@ -126,20 +143,12 @@ export async function reloadApp(port: number = 8081): Promise { }); } -export async function buildBundle( - bundleName: string, - platform: 'ios' | 'android', - port: number = 8081, -): Promise { +async function buildBundle(bundleName, platform, port = 8081) { const url = `http://localhost:${port}/${bundleName}.bundle?platform=${platform}&dev=true&minify=false`; - await xfetch(url, {method: 'HEAD'}); + await (0, (_xfetch || _load_xfetch()).default)(url, { method: 'HEAD' }); } -export async function buildSourceMaps( - bundleName: string, - platform: 'ios' | 'android', - port: number = 8081, -): Promise { +async function buildSourceMaps(bundleName, platform, port = 8081) { const url = `http://localhost:${port}/${bundleName}.map?platform=${platform}&dev=true&minify=false`; - await xfetch(url, {method: 'HEAD'}); -} + await (0, (_xfetch || _load_xfetch()).default)(url, { method: 'HEAD' }); +} \ No newline at end of file diff --git a/pkg/nuclide-metro-rpc/lib/MetroServiceProxy.js b/pkg/nuclide-metro-rpc/lib/MetroServiceProxy.js new file mode 100644 index 0000000000..d87038a042 --- /dev/null +++ b/pkg/nuclide-metro-rpc/lib/MetroServiceProxy.js @@ -0,0 +1,611 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + + remoteModule.getStartCommand = function (arg0) { + return _client.callRemoteFunction("MetroService/getStartCommand", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "projectRoot", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "MetroStartCommand" + } + }); + }); + }; + + remoteModule.startMetro = function (arg0, arg1, arg2, arg3) { + return _client.callRemoteFunction("MetroService/startMetro", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "projectRoot", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "editorArgs", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "port", + type: { + kind: "nullable", + type: { + kind: "number" + } + } + }, { + name: "extraArgs", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "string" + } + } + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "MetroEvent" + }); + }).publish(); + }; + + remoteModule.reloadApp = function (arg0) { + return _client.callRemoteFunction("MetroService/reloadApp", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "port", + type: { + kind: "nullable", + type: { + kind: "number" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.buildBundle = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("MetroService/buildBundle", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "bundleName", + type: { + kind: "string" + } + }, { + name: "platform", + type: { + kind: "union", + types: [{ + kind: "string-literal", + value: "ios" + }, { + kind: "string-literal", + value: "android" + }] + } + }, { + name: "port", + type: { + kind: "nullable", + type: { + kind: "number" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.buildSourceMaps = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("MetroService/buildSourceMaps", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "bundleName", + type: { + kind: "string" + } + }, { + name: "platform", + type: { + kind: "union", + types: [{ + kind: "string-literal", + value: "ios" + }, { + kind: "string-literal", + value: "android" + }] + } + }, { + name: "port", + type: { + kind: "nullable", + type: { + kind: "number" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + MetroStartCommand: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 21 + }, + name: "MetroStartCommand", + definition: { + kind: "object", + fields: [{ + name: "command", + type: { + kind: "string" + }, + optional: false + }, { + name: "cwd", + type: { + kind: "string" + }, + optional: false + }, { + name: "args", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: true + }] + } + }, + getStartCommand: { + kind: "function", + name: "getStartCommand", + location: { + type: "source", + fileName: "MetroService.js", + line: 38 + }, + type: { + location: { + type: "source", + fileName: "MetroService.js", + line: 38 + }, + kind: "function", + argumentTypes: [{ + name: "projectRoot", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "MetroStartCommand" + } + } + } + } + }, + ReadyEvent: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 18 + }, + name: "ReadyEvent", + definition: { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "ready" + }, + optional: false + }] + } + }, + Level: { + kind: "alias", + location: { + type: "source", + fileName: "process.js", + line: 695 + }, + name: "Level", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "info" + }, { + kind: "string-literal", + value: "log" + }, { + kind: "string-literal", + value: "warning" + }, { + kind: "string-literal", + value: "error" + }, { + kind: "string-literal", + value: "debug" + }, { + kind: "string-literal", + value: "success" + }] + } + }, + Message: { + kind: "alias", + location: { + type: "source", + fileName: "process.js", + line: 696 + }, + name: "Message", + definition: { + kind: "object", + fields: [{ + name: "text", + type: { + kind: "string" + }, + optional: false + }, { + name: "level", + type: { + kind: "named", + name: "Level" + }, + optional: false + }] + } + }, + MessageEvent: { + kind: "alias", + location: { + type: "source", + fileName: "process.js", + line: 698 + }, + name: "MessageEvent", + definition: { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "message" + }, + optional: false + }, { + name: "message", + type: { + kind: "named", + name: "Message" + }, + optional: false + }] + } + }, + MetroEvent: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 19 + }, + name: "MetroEvent", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "ready" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "message" + }, + optional: false + }, { + name: "message", + type: { + kind: "named", + name: "Message" + }, + optional: false + }] + }], + discriminantField: "type" + } + }, + startMetro: { + kind: "function", + name: "startMetro", + location: { + type: "source", + fileName: "MetroService.js", + line: 52 + }, + type: { + location: { + type: "source", + fileName: "MetroService.js", + line: 52 + }, + kind: "function", + argumentTypes: [{ + name: "projectRoot", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "editorArgs", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "port", + type: { + kind: "nullable", + type: { + kind: "number" + } + } + }, { + name: "extraArgs", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "string" + } + } + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "MetroEvent" + } + } + } + }, + reloadApp: { + kind: "function", + name: "reloadApp", + location: { + type: "source", + fileName: "MetroService.js", + line: 109 + }, + type: { + location: { + type: "source", + fileName: "MetroService.js", + line: 109 + }, + kind: "function", + argumentTypes: [{ + name: "port", + type: { + kind: "nullable", + type: { + kind: "number" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + buildBundle: { + kind: "function", + name: "buildBundle", + location: { + type: "source", + fileName: "MetroService.js", + line: 129 + }, + type: { + location: { + type: "source", + fileName: "MetroService.js", + line: 129 + }, + kind: "function", + argumentTypes: [{ + name: "bundleName", + type: { + kind: "string" + } + }, { + name: "platform", + type: { + kind: "union", + types: [{ + kind: "string-literal", + value: "ios" + }, { + kind: "string-literal", + value: "android" + }] + } + }, { + name: "port", + type: { + kind: "nullable", + type: { + kind: "number" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + buildSourceMaps: { + kind: "function", + name: "buildSourceMaps", + location: { + type: "source", + fileName: "MetroService.js", + line: 138 + }, + type: { + location: { + type: "source", + fileName: "MetroService.js", + line: 138 + }, + kind: "function", + argumentTypes: [{ + name: "bundleName", + type: { + kind: "string" + } + }, { + name: "platform", + type: { + kind: "union", + types: [{ + kind: "string-literal", + value: "ios" + }, { + kind: "string-literal", + value: "android" + }] + } + }, { + name: "port", + type: { + kind: "nullable", + type: { + kind: "number" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + } + } +}); \ No newline at end of file diff --git a/pkg/nuclide-metro-rpc/lib/StartCommand.js b/pkg/nuclide-metro-rpc/lib/StartCommand.js index a4f58413d9..97d0c4f87e 100644 --- a/pkg/nuclide-metro-rpc/lib/StartCommand.js +++ b/pkg/nuclide-metro-rpc/lib/StartCommand.js @@ -1,3 +1,37 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getStartCommandFromNodePackage = getStartCommandFromNodePackage; +exports.getStartCommandFromBuck = getStartCommandFromBuck; + +var _nuclideBuckRpc; + +function _load_nuclideBuckRpc() { + return _nuclideBuckRpc = require('../../nuclide-buck-rpc'); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _ini; + +function _load_ini() { + return _ini = _interopRequireDefault(require('ini')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,43 +39,23 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {MetroStartCommand} from './types'; - -import {getRootForPath as getBuckRootForPath} from '../../nuclide-buck-rpc'; -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import ini from 'ini'; - -type CommandWithoutProjectRoot = { - command: string, - args: Array, -}; - -export async function getStartCommandFromNodePackage( - projectRoot: NuclideUri, -): Promise { - return ( - (await getStartCommandFromNodeModules(projectRoot)) || - getStartCommandFromReactNative(projectRoot) - ); +async function getStartCommandFromNodePackage(projectRoot) { + return (await getStartCommandFromNodeModules(projectRoot)) || getStartCommandFromReactNative(projectRoot); } -export async function getStartCommandFromBuck( - projectRoot: NuclideUri, -): Promise { - const buckProjectRoot = await getBuckRootForPath(projectRoot); +async function getStartCommandFromBuck(projectRoot) { + const buckProjectRoot = await (0, (_nuclideBuckRpc || _load_nuclideBuckRpc()).getRootForPath)(projectRoot); if (buckProjectRoot == null) { return null; } // TODO(matthewwithanm): Move this to BuckUtils? - const filePath = nuclideUri.join(buckProjectRoot, '.buckconfig'); - const content = await fsPromise.readFile(filePath, 'utf8'); - const parsed = ini.parse(`scope = global\n${content}`); + const filePath = (_nuclideUri || _load_nuclideUri()).default.join(buckProjectRoot, '.buckconfig'); + const content = await (_fsPromise || _load_fsPromise()).default.readFile(filePath, 'utf8'); + const parsed = (_ini || _load_ini()).default.parse(`scope = global\n${content}`); const section = parsed['react-native']; if (section == null || section.server == null) { return null; @@ -49,7 +63,7 @@ export async function getStartCommandFromBuck( return { cwd: buckProjectRoot, args: ['--disable-global-hotkey'], - command: section.server, + command: section.server }; } @@ -57,42 +71,30 @@ export async function getStartCommandFromBuck( * Look in the nearest node_modules directory for react-native and extract the packager script if * it's found. */ -async function getStartCommandFromNodeModules( - projectRoot: NuclideUri, -): Promise { - const nodeModulesParent = await fsPromise.findNearestFile( - 'node_modules', - projectRoot, - ); +async function getStartCommandFromNodeModules(projectRoot) { + const nodeModulesParent = await (_fsPromise || _load_fsPromise()).default.findNearestFile('node_modules', projectRoot); if (nodeModulesParent == null) { return null; } - const command = await getCommandForCli( - nuclideUri.join(nodeModulesParent, 'node_modules', 'react-native'), - ); + const command = await getCommandForCli((_nuclideUri || _load_nuclideUri()).default.join(nodeModulesParent, 'node_modules', 'react-native')); - return command == null - ? null - : { - ...command, - cwd: nodeModulesParent, - }; + return command == null ? null : Object.assign({}, command, { + cwd: nodeModulesParent + }); } /** * See if this is React Native itself and, if so, return the command to run the packager. This is * special cased so that the bundled examples work out of the box. */ -async function getStartCommandFromReactNative( - dir: NuclideUri, -): Promise { - const projectRoot = await fsPromise.findNearestFile('package.json', dir); +async function getStartCommandFromReactNative(dir) { + const projectRoot = await (_fsPromise || _load_fsPromise()).default.findNearestFile('package.json', dir); if (projectRoot == null) { return null; } - const filePath = nuclideUri.join(projectRoot, 'package.json'); - const content = await fsPromise.readFile(filePath, 'utf8'); + const filePath = (_nuclideUri || _load_nuclideUri()).default.join(projectRoot, 'package.json'); + const content = await (_fsPromise || _load_fsPromise()).default.readFile(filePath, 'utf8'); const parsed = JSON.parse(content); const isReactNative = parsed.name === 'react-native'; @@ -102,24 +104,19 @@ async function getStartCommandFromReactNative( const command = await getCommandForCli(projectRoot); - return command == null - ? null - : { - ...command, - cwd: projectRoot, - }; + return command == null ? null : Object.assign({}, command, { + cwd: projectRoot + }); } -async function getCommandForCli( - pathToReactNative: NuclideUri, -): Promise { - const cliPath = nuclideUri.join(pathToReactNative, 'local-cli', 'cli.js'); - const cliExists = await fsPromise.exists(cliPath); +async function getCommandForCli(pathToReactNative) { + const cliPath = (_nuclideUri || _load_nuclideUri()).default.join(pathToReactNative, 'local-cli', 'cli.js'); + const cliExists = await (_fsPromise || _load_fsPromise()).default.exists(cliPath); if (!cliExists) { return null; } return { command: 'node', - args: [cliPath, 'start'], + args: [cliPath, 'start'] }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-metro-rpc/lib/parseMessages.js b/pkg/nuclide-metro-rpc/lib/parseMessages.js index a973eb18e6..dd147316aa 100644 --- a/pkg/nuclide-metro-rpc/lib/parseMessages.js +++ b/pkg/nuclide-metro-rpc/lib/parseMessages.js @@ -1,28 +1,37 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.parseMessages = parseMessages; + +var _parseRegularLine; + +function _load_parseRegularLine() { + return _parseRegularLine = require('./parseRegularLine'); +} -import type {MetroEvent} from './types'; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); -import {parseRegularLine} from './parseRegularLine'; -import {Observable} from 'rxjs'; +const PORT_LINE = /.*(?:Running.*|Listening )on port\s+(\d+)/; /** + * 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. + * + * strict-local + * @format + */ -const PORT_LINE = /.*(?:Running.*|Listening )on port\s+(\d+)/; const SOURCE_LIST_START = /Looking for (?:JS|JavaScript) files in/; const READY_LINE = /(packager|server) ready| {3}Starting Facebook Packager Server/i; /** * Parses output from Metro into messages. */ -export function parseMessages(raw: Observable): Observable { - return Observable.create(observer => { +function parseMessages(raw) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { let sawPreamble = false; let sawPortLine = false; let sawSourcesStart = false; @@ -31,12 +40,11 @@ export function parseMessages(raw: Observable): Observable { const sourceDirectories = []; return raw.subscribe({ - next: (line: string) => { + next: line => { // If we've seen the port and the sources, that's the preamble! Or, if we get to a line that // starts with a "[", we probably missed the closing of the preamble somehow. (Like the // output changed). - sawPreamble = - sawPreamble || (sawPortLine && sawSourcesEnd) || line.startsWith('['); + sawPreamble = sawPreamble || sawPortLine && sawSourcesEnd || line.startsWith('['); if (!sawPortLine && !sawPreamble) { const match = line.match(PORT_LINE); if (match != null) { @@ -45,8 +53,8 @@ export function parseMessages(raw: Observable): Observable { type: 'message', message: { level: 'info', - text: `Running Metro on port ${match[1]}.`, - }, + text: `Running Metro on port ${match[1]}.` + } }); return; } @@ -70,8 +78,8 @@ export function parseMessages(raw: Observable): Observable { type: 'message', message: { level: 'info', - text: `Looking for JS files in: ${sourceDirectories.join(',')}`, - }, + text: `Looking for JS files in: ${sourceDirectories.join(',')}` + } }); return; } @@ -83,11 +91,11 @@ export function parseMessages(raw: Observable): Observable { return; } - observer.next({type: 'message', message: parseRegularLine(line)}); + observer.next({ type: 'message', message: (0, (_parseRegularLine || _load_parseRegularLine()).parseRegularLine)(line) }); if (!sawReadyMessage && READY_LINE.test(line)) { sawReadyMessage = true; - observer.next({type: 'ready'}); + observer.next({ type: 'ready' }); } return; @@ -96,10 +104,10 @@ export function parseMessages(raw: Observable): Observable { // If we've gotten here, it means that we have an unhandled line in the preamble. Those are // the lines we want to ignore, so don't do anything. }, - error: (observer.error.bind(observer): (e: mixed) => mixed), - complete: (observer.complete.bind(observer): () => mixed), + error: observer.error.bind(observer), + complete: observer.complete.bind(observer) }); }); } -const isBlankLine = line => /^\s*$/.test(line); +const isBlankLine = line => /^\s*$/.test(line); \ No newline at end of file diff --git a/pkg/nuclide-metro-rpc/lib/parseRegularLine.js b/pkg/nuclide-metro-rpc/lib/parseRegularLine.js index 7386da7b65..0d3e19e4af 100644 --- a/pkg/nuclide-metro-rpc/lib/parseRegularLine.js +++ b/pkg/nuclide-metro-rpc/lib/parseRegularLine.js @@ -1,33 +1,33 @@ -/** - * 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 - */ +'use strict'; -import type {Message} from 'nuclide-commons/process'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.parseRegularLine = parseRegularLine; + + +const TIMESTAMP_FORMATS = ['\\d{1,2}:\\d{2}:\\d{2} (?:A|P)M', '\\d{1,2}/\\d{1,2}/\\d{4}, \\d{1,2}:\\d{2}:\\d{2} (?:A|P)M', '\\d{2}/\\d{2}/\\d{4} \\d{2}:\\d{2}:\\d{2}', '\\d{4}-\\d{2}-\\d{2} \\d{1,2}:\\d{2}:\\d{2}\\.\\d+']; /** + * 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. + * + * + * @format + */ -const TIMESTAMP_FORMATS = [ - '\\d{1,2}:\\d{2}:\\d{2} (?:A|P)M', - '\\d{1,2}/\\d{1,2}/\\d{4}, \\d{1,2}:\\d{2}:\\d{2} (?:A|P)M', - '\\d{2}/\\d{2}/\\d{4} \\d{2}:\\d{2}:\\d{2}', - '\\d{4}-\\d{2}-\\d{2} \\d{1,2}:\\d{2}:\\d{2}\\.\\d+', -]; const TIMESTAMP = TIMESTAMP_FORMATS.map(str => `(?:\\[?${str}\\]?)`).join('|'); const NORMAL_LINE = new RegExp(`^\\s*(?:${TIMESTAMP})\\s*(.*?)\\s*$`); const ERROR_LINE = /^\s*ERROR\s*(.*?)\s*$/; -export function parseRegularLine(line: string): Message { +function parseRegularLine(line) { const normalMatch = line.match(NORMAL_LINE); if (normalMatch != null) { // TODO (matthewwithanm): Add support for showing timestamps and include that in the message. return { level: 'log', - text: normalMatch[1], + text: normalMatch[1] }; } @@ -35,7 +35,7 @@ export function parseRegularLine(line: string): Message { if (errorMatch != null) { return { level: 'error', - text: errorMatch[1], + text: errorMatch[1] }; } @@ -44,6 +44,6 @@ export function parseRegularLine(line: string): Message { // /hot", "React packager ready."). return { level: 'log', - text: line, + text: line }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-metro-rpc/lib/types.js b/pkg/nuclide-metro-rpc/lib/types.js index cd6a074cb9..4c6f0127e6 100644 --- a/pkg/nuclide-metro-rpc/lib/types.js +++ b/pkg/nuclide-metro-rpc/lib/types.js @@ -1,25 +1,20 @@ -/** - * 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 - */ +'use strict'; -import type {MessageEvent} from 'nuclide-commons/process'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -// startMetro error codes -export const NO_METRO_PROJECT_ERROR = 'NoMetroProjectError'; -export const METRO_PORT_BUSY_ERROR = 'MetroPortBusyError'; -export type ReadyEvent = {type: 'ready'}; -export type MetroEvent = ReadyEvent | MessageEvent; +// startMetro error codes +const NO_METRO_PROJECT_ERROR = exports.NO_METRO_PROJECT_ERROR = 'NoMetroProjectError'; /** + * 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. + * + * + * @format + */ -export type MetroStartCommand = { - command: string, - cwd: string, - args?: Array, -}; +const METRO_PORT_BUSY_ERROR = exports.METRO_PORT_BUSY_ERROR = 'MetroPortBusyError'; \ No newline at end of file diff --git a/pkg/nuclide-metro/lib/DefaultMetroAtomService.js b/pkg/nuclide-metro/lib/DefaultMetroAtomService.js index 8575fdb4bb..258bf5571d 100644 --- a/pkg/nuclide-metro/lib/DefaultMetroAtomService.js +++ b/pkg/nuclide-metro/lib/DefaultMetroAtomService.js @@ -1,73 +1,106 @@ -/** - * 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 - */ - -import type {OutputProviderStatus} from 'atom-ide-ui'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {Subscription} from 'rxjs'; -import type {TunnelBehavior} from './types'; - -import invariant from 'assert'; -import {getLogger} from 'log4js'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Observable, BehaviorSubject} from 'rxjs'; -import {getMetroServiceByNuclideUri} from '../../nuclide-remote-connection'; -import {openTunnel} from './Tunnel'; -import {MetroAtomService} from './types'; -import { - NO_METRO_PROJECT_ERROR, - METRO_PORT_BUSY_ERROR, -} from '../../nuclide-metro-rpc/lib/types'; -import {LogTailer} from '../../nuclide-console-base/lib/LogTailer'; -import electron from 'electron'; - -const logger = getLogger('Metro'); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DefaultMetroAtomService = undefined; + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _Tunnel; + +function _load_Tunnel() { + return _Tunnel = require('./Tunnel'); +} + +var _types; + +function _load_types() { + return _types = require('./types'); +} + +var _types2; + +function _load_types2() { + return _types2 = require('../../nuclide-metro-rpc/lib/types'); +} + +var _LogTailer; + +function _load_LogTailer() { + return _LogTailer = require('../../nuclide-console-base/lib/LogTailer'); +} + +var _electron = _interopRequireDefault(require('electron')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const logger = (0, (_log4js || _load_log4js()).getLogger)('Metro'); /** + * 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. + * + * + * @format + */ + const GLOBAL_RELOAD_HOTKEY = 'CmdOrCtrl+Alt+R'; -const remote = electron.remote; -invariant(remote); - -export class DefaultMetroAtomService implements MetroAtomService { - _logTailer: LogTailer; - _projectRootPath: BehaviorSubject; - _port: BehaviorSubject; - _extraArgs: BehaviorSubject>; - _disposables: UniversalDisposable; - _currentTunnelSubscription: ?Subscription; - - constructor(projectRootPath: BehaviorSubject) { +const remote = _electron.default.remote; + +if (!remote) { + throw new Error('Invariant violation: "remote"'); +} + +class DefaultMetroAtomService { + + constructor(projectRootPath) { + _initialiseProps.call(this); + this._projectRootPath = projectRootPath; - this._disposables = new UniversalDisposable(); - this._port = new BehaviorSubject(8081); - this._extraArgs = new BehaviorSubject([]); - this._logTailer = this._createLogTailer( - projectRootPath, - this._port, - this._extraArgs, - ); - - this._disposables.add( - () => this.stop(), - this._registerShutdownOnWorkingRootChange(), - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._port = new _rxjsBundlesRxMinJs.BehaviorSubject(8081); + this._extraArgs = new _rxjsBundlesRxMinJs.BehaviorSubject([]); + this._logTailer = this._createLogTailer(projectRootPath, this._port, this._extraArgs); + + this._disposables.add(() => this.stop(), this._registerShutdownOnWorkingRootChange()); } - dispose = () => { +} + +exports.DefaultMetroAtomService = DefaultMetroAtomService; + +var _initialiseProps = function () { + this.dispose = () => { this._disposables.dispose(); }; - start = async ( - tunnelBehavior: TunnelBehavior, - port: number = 8081, - extraArgs: Array = [], - ): Promise => { + this.start = async (tunnelBehavior, port = 8081, extraArgs = []) => { this._port.next(port); this._extraArgs.next(extraArgs); await new Promise((resolve, reject) => { @@ -76,30 +109,22 @@ export class DefaultMetroAtomService implements MetroAtomService { if (error != null) { // Handling these errors here because LogTailer never becomes "ready" // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - if (error.code === NO_METRO_PROJECT_ERROR) { + if (error.code === (_types2 || _load_types2()).NO_METRO_PROJECT_ERROR) { atom.notifications.addError('Could not find Metro project', { dismissable: true, - description: - 'Make sure that your current working root (or its ancestor) contains a' + - ' `node_modules` directory with react-native installed, or a .buckconfig file' + - ' with a `[react-native]` section that has a `server` key.', + description: 'Make sure that your current working root (or its ancestor) contains a' + ' `node_modules` directory with react-native installed, or a .buckconfig file' + ' with a `[react-native]` section that has a `server` key.' }); // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - } else if (error.code === METRO_PORT_BUSY_ERROR) { - atom.notifications.addWarning( - 'Metro failed to start. This is expected if you are ' + - 'intentionally running Metro in a separate terminal. If not, ' + - `\`lsof -i tcp:${port}\` might help you find the process using the default port.`, - { - dismissable: true, - }, - ); + } else if (error.code === (_types2 || _load_types2()).METRO_PORT_BUSY_ERROR) { + atom.notifications.addWarning('Metro failed to start. This is expected if you are ' + 'intentionally running Metro in a separate terminal. If not, ' + `\`lsof -i tcp:${port}\` might help you find the process using the default port.`, { + dismissable: true + }); } reject(error); } else { resolve(); } - }, + } }); }); // now that the logTailer has started, start the global reload hotkey @@ -110,18 +135,20 @@ export class DefaultMetroAtomService implements MetroAtomService { }); logger.trace('hotkey register success: ' + String(success)); const projectRoot = this._projectRootPath.getValue(); - invariant(projectRoot != null); - const tunnelEvents = openTunnel(projectRoot, tunnelBehavior, port).catch( - e => { - this._closeTunnel(); - throw e; - }, - ); + + if (!(projectRoot != null)) { + throw new Error('Invariant violation: "projectRoot != null"'); + } + + const tunnelEvents = (0, (_Tunnel || _load_Tunnel()).openTunnel)(projectRoot, tunnelBehavior, port).catch(e => { + this._closeTunnel(); + throw e; + }); this._currentTunnelSubscription = tunnelEvents.subscribe(); await tunnelEvents.take(1).toPromise(); }; - stop = () => { + this.stop = () => { if (remote.globalShortcut.isRegistered(GLOBAL_RELOAD_HOTKEY)) { logger.trace('unregistering global reload hotkey'); remote.globalShortcut.unregister(GLOBAL_RELOAD_HOTKEY); @@ -130,97 +157,77 @@ export class DefaultMetroAtomService implements MetroAtomService { this._logTailer.stop(); }; - restart = () => { + this.restart = () => { this._logTailer.restart(); }; - reloadApp = () => { + this.reloadApp = () => { const path = this._projectRootPath.getValue(); if (path == null) { return; } - const metroService = getMetroServiceByNuclideUri(path); + const metroService = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getMetroServiceByNuclideUri)(path); metroService.reloadApp(this._port.getValue()); }; - observeStatus = (callback: OutputProviderStatus => void): IDisposable => { + this.observeStatus = callback => { return this._logTailer.observeStatus(callback); }; - _closeTunnel = () => { + this._closeTunnel = () => { if (this._currentTunnelSubscription != null) { this._currentTunnelSubscription.unsubscribe(); this._currentTunnelSubscription = null; } }; - _registerShutdownOnWorkingRootChange = (): Subscription => { + this._registerShutdownOnWorkingRootChange = () => { return this._projectRootPath.distinctUntilChanged().subscribe(path => { if (this._logTailer.getStatus() !== 'stopped') { this.stop(); - const notification = atom.notifications.addWarning( - 'Metro was stopped, because your Current Working Root has changed.', - { - dismissable: true, - buttons: [ - { - text: 'Start at this new working root', - onDidClick: () => { - this.start('ask_about_tunnel'); - notification.dismiss(); - }, - }, - ], - }, - ); + const notification = atom.notifications.addWarning('Metro was stopped, because your Current Working Root has changed.', { + dismissable: true, + buttons: [{ + text: 'Start at this new working root', + onDidClick: () => { + this.start('ask_about_tunnel'); + notification.dismiss(); + } + }] + }); } }); }; - _createLogTailer = ( - projectRootPath: BehaviorSubject, - port: BehaviorSubject, - extraArgs: BehaviorSubject>, - ) => { + this._createLogTailer = (projectRootPath, port, extraArgs) => { const self = this; - const metroEvents = Observable.defer(() => { + const metroEvents = _rxjsBundlesRxMinJs.Observable.defer(() => { const path = projectRootPath.getValue(); if (path == null) { - return Observable.empty(); + return _rxjsBundlesRxMinJs.Observable.empty(); } - const metroService = getMetroServiceByNuclideUri(path); - return metroService - .startMetro( - path, - getEditorArgs(path), - port.getValue(), - extraArgs.getValue(), - ) - .refCount(); + const metroService = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getMetroServiceByNuclideUri)(path); + return metroService.startMetro(path, getEditorArgs(path), port.getValue(), extraArgs.getValue()).refCount(); }).share(); - const messages = metroEvents - .filter(event => event.type === 'message') - .map(event => { - invariant(event.type === 'message'); - return {...event.message}; - }); - const ready = metroEvents - .filter(message => message.type === 'ready') - .mapTo(undefined); + const messages = metroEvents.filter(event => event.type === 'message').map(event => { + if (!(event.type === 'message')) { + throw new Error('Invariant violation: "event.type === \'message\'"'); + } - return new LogTailer({ + return Object.assign({}, event.message); + }); + const ready = metroEvents.filter(message => message.type === 'ready').mapTo(undefined); + + return new (_LogTailer || _load_LogTailer()).LogTailer({ name: 'Metro', messages, ready, handleError(error) { - atom.notifications.addError( - `Unexpected error while running Metro.\n\n${error.message}`, - { - dismissable: true, - }, - ); + atom.notifications.addError(`Unexpected error while running Metro.\n\n${error.message}`, { + dismissable: true + }); logger.warn('stopping metro due to an error'); self.stop(); @@ -228,14 +235,14 @@ export class DefaultMetroAtomService implements MetroAtomService { trackingEvents: { start: 'metro:start', stop: 'metro:stop', - restart: 'metro:restart', - }, + restart: 'metro:restart' + } }); }; -} +}; -function getEditorArgs(projectRoot: NuclideUri): Array { - if (nuclideUri.isRemote(projectRoot)) { +function getEditorArgs(projectRoot) { + if ((_nuclideUri || _load_nuclideUri()).default.isRemote(projectRoot)) { return ['atom']; } else { const args = [remote.app.getPath('exe')]; @@ -244,4 +251,4 @@ function getEditorArgs(projectRoot: NuclideUri): Array { } return args; } -} +} \ No newline at end of file diff --git a/pkg/nuclide-metro/lib/Tunnel.js b/pkg/nuclide-metro/lib/Tunnel.js index b817c7507a..29740984a8 100644 --- a/pkg/nuclide-metro/lib/Tunnel.js +++ b/pkg/nuclide-metro/lib/Tunnel.js @@ -1,87 +1,80 @@ -/** - * 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 - */ +'use strict'; -import type {SshTunnelService, Tunnel} from 'nuclide-adb/lib/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {TunnelBehavior} from './types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.openTunnel = openTunnel; -import nullthrows from 'nullthrows'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import consumeFirstProvider from 'nuclide-commons-atom/consumeFirstProvider'; -import {Observable} from 'rxjs'; +var _nullthrows; -export function openTunnel( - serviceUri: NuclideUri, - behavior: TunnelBehavior, - port: number, -): Observable<'ready'> { - if (!nuclideUri.isRemote(serviceUri) || behavior === 'do_not_open_tunnel') { - return Observable.of('ready').concat(Observable.never()); +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _consumeFirstProvider; + +function _load_consumeFirstProvider() { + return _consumeFirstProvider = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/consumeFirstProvider')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function openTunnel(serviceUri, behavior, port) { + if (!(_nuclideUri || _load_nuclideUri()).default.isRemote(serviceUri) || behavior === 'do_not_open_tunnel') { + return _rxjsBundlesRxMinJs.Observable.of('ready').concat(_rxjsBundlesRxMinJs.Observable.never()); } - return Observable.defer(() => - nullthrows(consumeFirstProvider('nuclide.ssh-tunnel')), - ) - .switchMap((service: SshTunnelService) => { - const desired = _desiredTunnelTo(serviceUri, port); - for (const tunnel of service.getOpenTunnels()) { - const {from, to} = tunnel; - if ( - from.port === desired.from.port && - from.host === desired.from.host - ) { - if ( - nuclideUri.getHostname(to.host) !== - nuclideUri.getHostname(desired.to.host) - ) { - throw new Error( - `You have a tunnel open from \`localhost:${port}\` to a different host than your ` + - 'Current Working Root. Close the tunnel in the SSH tunnels panel and try again.', - ); - } + return _rxjsBundlesRxMinJs.Observable.defer(() => (0, (_nullthrows || _load_nullthrows()).default)((0, (_consumeFirstProvider || _load_consumeFirstProvider()).default)('nuclide.ssh-tunnel'))).switchMap(service => { + const desired = _desiredTunnelTo(serviceUri, port); + for (const tunnel of service.getOpenTunnels()) { + const { from, to } = tunnel; + if (from.port === desired.from.port && from.host === desired.from.host) { + if ((_nuclideUri || _load_nuclideUri()).default.getHostname(to.host) !== (_nuclideUri || _load_nuclideUri()).default.getHostname(desired.to.host)) { + throw new Error(`You have a tunnel open from \`localhost:${port}\` to a different host than your ` + 'Current Working Root. Close the tunnel in the SSH tunnels panel and try again.'); } } - if (behavior === 'ask_about_tunnel') { - return _askToRequestTunnel(service, desired); - } else { - return service.openTunnels([desired]); - } - }) - .share(); -} + } + if (behavior === 'ask_about_tunnel') { + return _askToRequestTunnel(service, desired); + } else { + return service.openTunnels([desired]); + } + }).share(); +} /** + * 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. + * + * + * @format + */ -function _askToRequestTunnel( - service: SshTunnelService, - tunnel: Tunnel, -): Observable<'ready'> { - return Observable.create(observer => { +function _askToRequestTunnel(service, tunnel) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { let subscription; const notification = atom.notifications.addSuccess('Open tunnel?', { - detail: `Open a new tunnel so Metro becomes available at localhost:${ - tunnel.from.port - }?`, + detail: `Open a new tunnel so Metro becomes available at localhost:${tunnel.from.port}?`, icon: 'milestone', dismissable: true, - buttons: [ - { - text: 'Open tunnel', - onDidClick: () => { - subscription = service.openTunnels([tunnel]).subscribe(observer); - notification.dismiss(); - }, - }, - { - text: 'Dismiss', - onDidClick: () => notification.dismiss(), - }, - ], + buttons: [{ + text: 'Open tunnel', + onDidClick: () => { + subscription = service.openTunnels([tunnel]).subscribe(observer); + notification.dismiss(); + } + }, { + text: 'Dismiss', + onDidClick: () => notification.dismiss() + }] }); return () => { @@ -93,13 +86,13 @@ function _askToRequestTunnel( }); } -function _desiredTunnelTo(uri: NuclideUri, port: number): Tunnel { +function _desiredTunnelTo(uri, port) { return { description: 'Metro', from: { host: 'localhost', - port, + port }, - to: {host: uri, port}, + to: { host: uri, port } }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-metro/lib/main.js b/pkg/nuclide-metro/lib/main.js index 06277ddc9e..fe529308ba 100644 --- a/pkg/nuclide-metro/lib/main.js +++ b/pkg/nuclide-metro/lib/main.js @@ -1,91 +1,82 @@ -/** - * 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 - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type CwdApi from '../../nuclide-current-working-directory/lib/CwdApi'; -import type {OutputService} from 'atom-ide-ui'; -import type {MetroAtomService} from './types'; -import type {TunnelBehavior} from './types'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {BehaviorSubject} from 'rxjs'; -import {DefaultMetroAtomService} from './DefaultMetroAtomService'; +'use strict'; + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _DefaultMetroAtomService; + +function _load_DefaultMetroAtomService() { + return _DefaultMetroAtomService = require('./DefaultMetroAtomService'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class Activation { - _projectRootPath: BehaviorSubject; - _disposables: UniversalDisposable; - _metroAtomService: DefaultMetroAtomService; - - constructor(serializedState: ?Object) { - this._projectRootPath = new BehaviorSubject(null); - this._metroAtomService = new DefaultMetroAtomService(this._projectRootPath); - - this._disposables = new UniversalDisposable( - this._metroAtomService, - atom.commands.add('atom-workspace', { - // Ideally based on CWD, the commands can be disabled and the UI would explain why. - 'nuclide-metro:start': ({ - detail, - }: { - detail: { - port?: number, - tunnelBehavior?: TunnelBehavior, - extraArgs?: Array, - }, - }) => { - this._metroAtomService.start( - detail.tunnelBehavior || 'ask_about_tunnel', - detail.port, - detail.extraArgs, - ); - }, - 'nuclide-metro:stop': () => this._metroAtomService.stop(), - 'nuclide-metro:restart': () => this._metroAtomService.restart(), - 'nuclide-metro:reload-app': () => this._metroAtomService.reloadApp(), - }), - ); + + constructor(serializedState) { + this._projectRootPath = new _rxjsBundlesRxMinJs.BehaviorSubject(null); + this._metroAtomService = new (_DefaultMetroAtomService || _load_DefaultMetroAtomService()).DefaultMetroAtomService(this._projectRootPath); + + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(this._metroAtomService, atom.commands.add('atom-workspace', { + // Ideally based on CWD, the commands can be disabled and the UI would explain why. + 'nuclide-metro:start': ({ + detail + }) => { + this._metroAtomService.start(detail.tunnelBehavior || 'ask_about_tunnel', detail.port, detail.extraArgs); + }, + 'nuclide-metro:stop': () => this._metroAtomService.stop(), + 'nuclide-metro:restart': () => this._metroAtomService.restart(), + 'nuclide-metro:reload-app': () => this._metroAtomService.reloadApp() + })); } - dispose(): void { + dispose() { this._disposables.dispose(); } - provideMetroAtomService(): MetroAtomService { + provideMetroAtomService() { return this._metroAtomService; } - consumeCwdApi(api: CwdApi): void { - this._disposables.add( - api.observeCwd(dir => { - this._projectRootPath.next(dir); - }), - ); + consumeCwdApi(api) { + this._disposables.add(api.observeCwd(dir => { + this._projectRootPath.next(dir); + })); } - consumeOutputService(api: OutputService): void { - this._disposables.add( - api.registerOutputProvider({ - id: 'Metro', - messages: this._metroAtomService._logTailer.getMessages(), - observeStatus: cb => this._metroAtomService.observeStatus(cb), - start: () => { - this._metroAtomService.start('ask_about_tunnel'); - }, - stop: () => { - this._metroAtomService.stop(); - }, - }), - ); + consumeOutputService(api) { + this._disposables.add(api.registerOutputProvider({ + id: 'Metro', + messages: this._metroAtomService._logTailer.getMessages(), + observeStatus: cb => this._metroAtomService.observeStatus(cb), + start: () => { + this._metroAtomService.start('ask_about_tunnel'); + }, + stop: () => { + this._metroAtomService.stop(); + } + })); } -} +} /** + * 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. + * + * + * @format + */ -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-metro/lib/types.js b/pkg/nuclide-metro/lib/types.js index bc636831ad..a726efc43f 100644 --- a/pkg/nuclide-metro/lib/types.js +++ b/pkg/nuclide-metro/lib/types.js @@ -1,27 +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 strict-local - * @format - */ - -import type {OutputProviderStatus} from 'atom-ide-ui'; - -export type TunnelBehavior = - | 'open_tunnel_if_needed' - | 'ask_about_tunnel' - | 'do_not_open_tunnel'; - -// Manages starting Metro for the current working root and integrating it into Console. -// Use this service instead of starting Metro via nuclide-metro-rpc yourself. -export interface MetroAtomService { - start(tunnelBehavior: TunnelBehavior): Promise; - stop(): void; - reloadApp(): void; - restart(): void; - observeStatus(callback: (OutputProviderStatus) => void): IDisposable; -} +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-move-item-to-available-pane/lib/main.js b/pkg/nuclide-move-item-to-available-pane/lib/main.js index f85136fb9d..e7349ce528 100644 --- a/pkg/nuclide-move-item-to-available-pane/lib/main.js +++ b/pkg/nuclide-move-item-to-available-pane/lib/main.js @@ -1,3 +1,25 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.activate = activate; +exports.deactivate = deactivate; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _move; + +function _load_move() { + return _move = require('./move'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,34 +27,24 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {moveDown, moveLeft, moveRight, moveUp} from './move'; - class Activation { - _disposables: UniversalDisposable; - constructor(state: ?Object) { - this._disposables = new UniversalDisposable(); + constructor(state) { + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } activate() { - this._disposables.add( - atom.commands.add('atom-text-editor', { - // Pass the eta expansion of these functions to defer the loading of move.js. - 'nuclide-move-item-to-available-pane:right': event => - moveRight(((event.target: any): HTMLElement)), - 'nuclide-move-item-to-available-pane:left': event => - moveLeft(((event.target: any): HTMLElement)), - 'nuclide-move-item-to-available-pane:up': event => - moveUp(((event.target: any): HTMLElement)), - 'nuclide-move-item-to-available-pane:down': event => - moveDown(((event.target: any): HTMLElement)), - }), - ); + this._disposables.add(atom.commands.add('atom-text-editor', { + // Pass the eta expansion of these functions to defer the loading of move.js. + 'nuclide-move-item-to-available-pane:right': event => (0, (_move || _load_move()).moveRight)(event.target), + 'nuclide-move-item-to-available-pane:left': event => (0, (_move || _load_move()).moveLeft)(event.target), + 'nuclide-move-item-to-available-pane:up': event => (0, (_move || _load_move()).moveUp)(event.target), + 'nuclide-move-item-to-available-pane:down': event => (0, (_move || _load_move()).moveDown)(event.target) + })); } dispose() { @@ -40,18 +52,18 @@ class Activation { } } -let activation: ?Activation = null; +let activation = null; -export function activate(state: ?Object) { +function activate(state) { if (activation == null) { activation = new Activation(state); activation.activate(); } } -export function deactivate() { +function deactivate() { if (activation != null) { activation.dispose(); activation = null; } -} +} \ No newline at end of file diff --git a/pkg/nuclide-move-item-to-available-pane/lib/move.js b/pkg/nuclide-move-item-to-available-pane/lib/move.js index bc8f407572..89df0c307c 100644 --- a/pkg/nuclide-move-item-to-available-pane/lib/move.js +++ b/pkg/nuclide-move-item-to-available-pane/lib/move.js @@ -1,3 +1,19 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.moveUp = moveUp; +exports.moveDown = moveDown; +exports.moveRight = moveRight; +exports.moveLeft = moveLeft; + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,43 +21,33 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import invariant from 'assert'; - -import {track} from '../../nuclide-analytics'; - -type MoveOperation = 'up' | 'down' | 'right' | 'left'; - -export function moveUp(el: HTMLElement) { +function moveUp(el) { doSplit(el, 'up', (pane, params) => pane.splitUp(params)); } -export function moveDown(el: HTMLElement) { +function moveDown(el) { doSplit(el, 'down', (pane, params) => pane.splitDown(params)); } -export function moveRight(el: HTMLElement) { +function moveRight(el) { doSplit(el, 'right', (pane, params) => pane.splitRight(params)); } -export function moveLeft(el: HTMLElement) { +function moveLeft(el) { doSplit(el, 'left', (pane, params) => pane.splitLeft(params)); } -function doSplit( - el: HTMLElement, - operation: MoveOperation, - splitOperation: (pane: atom$Pane, params?: atom$PaneSplitParams) => atom$Pane, -) { +function doSplit(el, operation, splitOperation) { const pane = findNearestPane(el) || getCenter().getActivePane(); if (pane == null) { return; } - track('nuclide-move-item-to-available-pane'); + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('nuclide-move-item-to-available-pane'); const activeItem = pane.getActiveItem(); if (activeItem != null) { const targetPane = findTargetPane(pane, operation); @@ -58,7 +64,7 @@ function doSplit( // pane contains exactly zero or one items. // The new empty pane will be kept if the global atom setting // 'Destroy Empty Panes' is false, otherwise it will be removed. - const newPane = splitOperation(pane, {copyActiveItem: false}); + const newPane = splitOperation(pane, { copyActiveItem: false }); const item = pane.getActiveItem(); if (item) { pane.moveItemToPane(item, newPane, 0); @@ -68,7 +74,7 @@ function doSplit( /** * Find the Pane that contains the provided element. */ -function findNearestPane(el_: HTMLElement): ?atom$Pane { +function findNearestPane(el_) { let el = el_; while (el != null) { // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) @@ -80,53 +86,47 @@ function findNearestPane(el_: HTMLElement): ?atom$Pane { } // TODO: Replace this once our lowest supported version is 1.17 -const getCenter = () => - atom.workspace.getCenter ? atom.workspace.getCenter() : atom.workspace; +const getCenter = () => atom.workspace.getCenter ? atom.workspace.getCenter() : atom.workspace; /** * See if there is already a pane in the direction the user is trying to split. * If there are multiple, returns the "nearest" pane. */ -function findTargetPane( - activePane: atom$Pane, - operation: MoveOperation, -): ?atom$Pane { +function findTargetPane(activePane, operation) { const activeRect = atom.views.getView(activePane).getBoundingClientRect(); const predicate = createPredicate(operation, activeRect); - const paneToRect: WeakMap = new WeakMap(); - const candidatePanes = activePane - .getContainer() - .getPanes() - .filter(pane => { - if (pane === activePane) { - return false; - } else { - const rect = atom.views.getView(pane).getBoundingClientRect(); - paneToRect.set(pane, rect); - return predicate(rect); - } - }); + const paneToRect = new WeakMap(); + const candidatePanes = activePane.getContainer().getPanes().filter(pane => { + if (pane === activePane) { + return false; + } else { + const rect = atom.views.getView(pane).getBoundingClientRect(); + paneToRect.set(pane, rect); + return predicate(rect); + } + }); if (candidatePanes.length === 1) { return candidatePanes[0]; } else if (candidatePanes.length > 1) { - const xAxisComparator = (rect: ClientRect) => - Math.abs(rect.left - activeRect.left); - const yAxisComparator = (rect: ClientRect) => - Math.abs(rect.top - activeRect.top); + const xAxisComparator = rect => Math.abs(rect.left - activeRect.left); + const yAxisComparator = rect => Math.abs(rect.top - activeRect.top); const isHorizontalMove = operation === 'left' || operation === 'right'; - const primaryComparator = isHorizontalMove - ? xAxisComparator - : yAxisComparator; - const secondaryComparator = isHorizontalMove - ? yAxisComparator - : xAxisComparator; + const primaryComparator = isHorizontalMove ? xAxisComparator : yAxisComparator; + const secondaryComparator = isHorizontalMove ? yAxisComparator : xAxisComparator; candidatePanes.sort((pane1, pane2) => { const rect1 = paneToRect.get(pane1); const rect2 = paneToRect.get(pane2); - invariant(rect1 != null); - invariant(rect2 != null); + + if (!(rect1 != null)) { + throw new Error('Invariant violation: "rect1 != null"'); + } + + if (!(rect2 != null)) { + throw new Error('Invariant violation: "rect2 != null"'); + } + const comp = primaryComparator(rect1) - primaryComparator(rect2); if (comp !== 0) { return comp; @@ -140,10 +140,7 @@ function findTargetPane( } } -function createPredicate( - operation: MoveOperation, - activeRect: ClientRect, -): (rect: ClientRect) => boolean { +function createPredicate(operation, activeRect) { switch (operation) { case 'up': return rect => rect.top < activeRect.top; @@ -155,4 +152,4 @@ function createPredicate( return rect => rect.left > activeRect.left; } throw new Error(`Unknown operation: ${operation}`); -} +} \ No newline at end of file diff --git a/pkg/nuclide-move-item-to-available-pane/spec/move-spec.js b/pkg/nuclide-move-item-to-available-pane/spec/move-spec.js deleted file mode 100644 index c45573c295..0000000000 --- a/pkg/nuclide-move-item-to-available-pane/spec/move-spec.js +++ /dev/null @@ -1,170 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import fsPromise from 'nuclide-commons/fsPromise'; -import invariant from 'assert'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - -import {activate} from '../lib/main'; - -describe('nuclide-move-item-to-available-pane', () => { - it('moves items across panes and creates new ones, as appropriate', () => { - waitsForPromise(async () => { - activate(); - - const tempdir = await fsPromise.tempdir(); - await atom.workspace.open(nuclideUri.join(tempdir, 'A')); - await atom.workspace.open(nuclideUri.join(tempdir, 'B')); - await atom.workspace.open(nuclideUri.join(tempdir, 'C')); - atom.workspace.getPanes()[0].activateItemAtIndex(0); - assertWorkspaceState(['A*', 'B', 'C']); - - dispatchCmdKRight(); - assertWorkspaceState(['B', 'C'], ['A*']); - - dispatchCmdKCmdLeft(); - assertWorkspaceState(['B*', 'C'], ['A']); - - dispatchCmdKRight(); - - // TODO(mbolin): The rest of this test does not appear to run correctly because Atom does not - // seem to layout the windows "for real," so the (x, y) ClientRect for each pane is reported - // to be at (0, 0), which breaks the logic of nuclide-move-item-to-available-pane. If we can - // figure out how to fix this, this would be a much better test. For now, we leave it here so - // to illustrate the expected behavior. - - // assertWorkspaceState(['C'], ['A', 'B*']); - // - // dispatchCmdKRight(); - // assertWorkspaceState(['C'], ['A'], ['B*']); - // - // dispatchCmdKCmdLeft(); - // assertWorkspaceState(['C'], ['A*'], ['B']); - // - // dispatchCmdKLeft(); - // assertWorkspaceState(['C', 'A*'], ['B']); - // - // dispatchCmdKCmdRight(); - // assertWorkspaceState(['C', 'A'], ['B*']); - // - // dispatchCmdKLeft(); - // assertWorkspaceState(['C', 'A', 'B*']); - // - // dispatchCmdKLeft(); - // assertWorkspaceState(['B*'], ['C', 'A']); - - // TODO(mbolin): This is also an important test: - - // [A] [B, C*] [D] - // - // cmd-k down - // - // [A] [B] [D] - // [C*] - // - // cmd-k up - // - // [A] [B, C*] [D] - // - // Note that this test is necessary to verify that both the primaryComparator and - // secondaryComparator are doing their job in move.js. - }); - }); -}); - -/** - * Each descriptor represents the pane items that a pane should contain. Each - * element of a descriptor corresponds to the name of the file that the pane - * item should be displaying. If the element ends with an asterisk, that - * indicates that it should be the active pane item. - */ -function assertWorkspaceState(...descriptors: Array>) { - const workspaceDescriptors = createDescriptorForWorkspaceState() - .map(descriptor => { - return descriptor.filter(paneItem => paneItem.length > 0); - }) - .filter(descriptor => descriptor.length > 0); - expect(workspaceDescriptors).toEqual(descriptors); -} - -function createDescriptorForWorkspaceState(): Array> { - const activeItem = atom.workspace.getActiveTextEditor(); - return atom.workspace.getPanes().map(pane => { - return pane.getItems().map(item => { - const fileName = item.getPath(); - let name = nuclideUri.basename(fileName); - if (item === activeItem) { - name += '*'; - } - return name; - }); - }); -} - -function dispatchCmdKRight() { - const activeEditor = atom.workspace.getActiveTextEditor(); - invariant(activeEditor); - const wasDispatched = atom.commands.dispatch( - atom.views.getView(activeEditor), - 'nuclide-move-item-to-available-pane:right', - ); - expect(wasDispatched).toBeTruthy(); -} - -// eslint-disable-next-line no-unused-vars -function dispatchCmdKLeft() { - const activeEditor = atom.workspace.getActiveTextEditor(); - invariant(activeEditor); - const wasDispatched = atom.commands.dispatch( - atom.views.getView(activeEditor), - 'nuclide-move-item-to-available-pane:left', - ); - expect(wasDispatched).toBeTruthy(); -} - -function dispatchCmdKCmdLeft() { - // In test mode, the command appears to get dispatched successfully, but the focus does not get - // updated properly, so we have to provide some help. - const activePane = atom.workspace.getActivePane(); - const panes = atom.workspace.getPanes(); - const index = panes.indexOf(activePane); - - const activeEditor = atom.workspace.getActiveTextEditor(); - invariant(activeEditor); - const wasDispatched = atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'window:focus-pane-on-left', - ); - expect(wasDispatched).toBeTruthy(); - - const newIndex = Math.max(0, index - 1); - panes[newIndex].activate(); -} - -// eslint-disable-next-line no-unused-vars -function dispatchCmdKCmdRight() { - // In test mode, the command appears to get dispatched successfully, but the focus does not get - // updated properly, so we have to provide some help. - const activePane = atom.workspace.getActivePane(); - const panes = atom.workspace.getPanes(); - const index = panes.indexOf(activePane); - - const activeEditor = atom.workspace.getActiveTextEditor(); - invariant(activeEditor); - const wasDispatched = atom.commands.dispatch( - atom.views.getView(activeEditor), - 'window:focus-pane-on-right', - ); - expect(wasDispatched).toBe(true); - - const newIndex = Math.min(panes.length - 1, index + 1); - panes[newIndex].activate(); -} diff --git a/pkg/nuclide-navigation-stack-status-bar/lib/StatusBar.js b/pkg/nuclide-navigation-stack-status-bar/lib/StatusBar.js index d02376edb2..e9425c8af7 100644 --- a/pkg/nuclide-navigation-stack-status-bar/lib/StatusBar.js +++ b/pkg/nuclide-navigation-stack-status-bar/lib/StatusBar.js @@ -1,115 +1,144 @@ -/** - * 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 - */ - -import type {NavigationStackService} from '../../nuclide-navigation-stack'; - -import * as React from 'react'; -import {Observable} from 'rxjs'; -import {renderReactRoot} from 'nuclide-commons-ui/renderReactRoot'; -import {Button} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import shallowEqual from 'shallowequal'; -import * as analytics from '../../nuclide-analytics'; - -type Props = - | { - available: true, - enableBack: boolean, - enableForward: boolean, - onBack: () => mixed, - onForward: () => mixed, - } - | { - available: false, - }; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.consumeStatusBar = consumeStatusBar; + +var _react = _interopRequireWildcard(require('react')); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _renderReactRoot; + +function _load_renderReactRoot() { + return _renderReactRoot = require('../../../modules/nuclide-commons-ui/renderReactRoot'); +} + +var _Button; + +function _load_Button() { + return _Button = require('../../../modules/nuclide-commons-ui/Button'); +} + +var _ButtonGroup; + +function _load_ButtonGroup() { + return _ButtonGroup = require('../../../modules/nuclide-commons-ui/ButtonGroup'); +} + +var _bindObservableAsProps; + +function _load_bindObservableAsProps() { + return _bindObservableAsProps = require('../../../modules/nuclide-commons-ui/bindObservableAsProps'); +} + +var _event; + +function _load_event() { + return _event = require('../../../modules/nuclide-commons/event'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _shallowequal; + +function _load_shallowequal() { + return _shallowequal = _interopRequireDefault(require('shallowequal')); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = _interopRequireWildcard(require('../../nuclide-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; } } // Since this is a button which can change the current file, place it where // it won't change position when the current file name changes, which means way left. -const STATUS_BAR_PRIORITY = -100; - -export function consumeStatusBar( - statusBar: atom$StatusBar, - navigationStackServices: Observable, -): IDisposable { - const props: Observable = navigationStackServices - .switchMap(navigationStack => { - if (navigationStack == null) { - return Observable.of({ - available: false, - }); - } - const onBack = () => { - analytics.track('status-bar-nav-stack-clicked-back'); - navigationStack.navigateBackwards(); - }; - const onForward = () => { - analytics.track('status-bar-nav-stack-clicked-forward'); - navigationStack.navigateForwards(); - }; - return observableFromSubscribeFunction(navigationStack.subscribe).map( - stack => ({ - available: true, - enableBack: stack.hasPrevious, - enableForward: stack.hasNext, - onBack, - onForward, - }), - ); - }) - .distinctUntilChanged(shallowEqual); - const Tile = bindObservableAsProps(props, NavStackStatusBarTile); - const item = renderReactRoot(); +const STATUS_BAR_PRIORITY = -100; /** + * 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. + * + * + * @format + */ + +function consumeStatusBar(statusBar, navigationStackServices) { + const props = navigationStackServices.switchMap(navigationStack => { + if (navigationStack == null) { + return _rxjsBundlesRxMinJs.Observable.of({ + available: false + }); + } + const onBack = () => { + (_nuclideAnalytics || _load_nuclideAnalytics()).track('status-bar-nav-stack-clicked-back'); + navigationStack.navigateBackwards(); + }; + const onForward = () => { + (_nuclideAnalytics || _load_nuclideAnalytics()).track('status-bar-nav-stack-clicked-forward'); + navigationStack.navigateForwards(); + }; + return (0, (_event || _load_event()).observableFromSubscribeFunction)(navigationStack.subscribe).map(stack => ({ + available: true, + enableBack: stack.hasPrevious, + enableForward: stack.hasNext, + onBack, + onForward + })); + }).distinctUntilChanged((_shallowequal || _load_shallowequal()).default); + const Tile = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)(props, NavStackStatusBarTile); + const item = (0, (_renderReactRoot || _load_renderReactRoot()).renderReactRoot)(_react.createElement(Tile, null)); item.className = 'nuclide-navigation-stack-tile inline-block'; const statusBarTile = statusBar.addLeftTile({ item, - priority: STATUS_BAR_PRIORITY, + priority: STATUS_BAR_PRIORITY }); - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { statusBarTile.destroy(); }); } -class NavStackStatusBarTile extends React.Component { - render(): React.Node { +class NavStackStatusBarTile extends _react.Component { + render() { if (!this.props.available) { return null; } - return ( - -
    - + ${!this._finalNuxInTour ? 'Dismiss' : 'Complete'} Tour ${!this._finalNuxInTour ? nextLinkButton : ''} @@ -253,63 +231,44 @@ export class NuxView { template: `
    -
    `, +
    ` }); this._disposables.add(this._tooltipDisposable); if (nextLinkStyle === LINK_ENABLED) { - const nextElementClickListener = this._handleDisposableClick.bind( - this, - true /* continue to the next NUX in the tour */, - ); - const nextElement = document.querySelector( - `.nuclide-nux-next-link-${this._index}`, + const nextElementClickListener = this._handleDisposableClick.bind(this, true /* continue to the next NUX in the tour */ ); - invariant(nextElement != null); + const nextElement = document.querySelector(`.nuclide-nux-next-link-${this._index}`); + + if (!(nextElement != null)) { + throw new Error('Invariant violation: "nextElement != null"'); + } + nextElement.addEventListener('click', nextElementClickListener); - this._disposables.add( - new UniversalDisposable(() => - nextElement.removeEventListener('click', nextElementClickListener), - ), - ); + this._disposables.add(new (_UniversalDisposable || _load_UniversalDisposable()).default(() => nextElement.removeEventListener('click', nextElementClickListener))); } // Record the NUX as dismissed iff it is not the last NUX in the tour. // Clicking "Complete Tour" on the last NUX should be tracked as successful completion. - const dismissElementClickListener = !this._finalNuxInTour - ? this._handleDisposableClick.bind( - this, - false /* skip to the end of the tour */, - ) - : this._handleDisposableClick.bind( - this, - true /* continue to the next NUX in the tour */, - ); - const dismissElement = document.querySelector( - `.nuclide-nux-dismiss-link-${this._index}`, + const dismissElementClickListener = !this._finalNuxInTour ? this._handleDisposableClick.bind(this, false /* skip to the end of the tour */ + ) : this._handleDisposableClick.bind(this, true /* continue to the next NUX in the tour */ ); - invariant(dismissElement != null); + const dismissElement = document.querySelector(`.nuclide-nux-dismiss-link-${this._index}`); + + if (!(dismissElement != null)) { + throw new Error('Invariant violation: "dismissElement != null"'); + } + dismissElement.addEventListener('click', dismissElementClickListener); - this._disposables.add( - new UniversalDisposable(() => - dismissElement.removeEventListener( - 'click', - dismissElementClickListener, - ), - ), - ); + this._disposables.add(new (_UniversalDisposable || _load_UniversalDisposable()).default(() => dismissElement.removeEventListener('click', dismissElementClickListener))); } - _handleDisposableClick(success: boolean = true): void { + _handleDisposableClick(success = true) { // If a completion predicate exists, only consider the NUX as complete // if the completion condition has been met. // Use `success` to short circuit the check and immediately dispose of the NUX. - if ( - success && - this._completePredicate != null && - !this._completePredicate() - ) { + if (success && this._completePredicate != null && !this._completePredicate()) { return; } @@ -320,15 +279,15 @@ export class NuxView { this._onNuxComplete(success); } - showNux(): void { + showNux() { this._createNux(); } - setNuxCompleteCallback(callback: (success: boolean) => void): void { + setNuxCompleteCallback(callback) { this._callback = callback; } - _onNuxComplete(success: boolean = true): boolean { + _onNuxComplete(success = true) { if (this._callback) { this._callback(success); // Avoid the callback being invoked again. @@ -338,15 +297,16 @@ export class NuxView { return success; } - dispose(): void { + dispose() { this._disposables.dispose(); } - _track(message: string, error: ?string): void { - track('nux-view-action', { + _track(message, error) { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('nux-view-action', { tourId: this._tourId, message: `${message}`, - error: maybeToString(error), + error: (0, (_string || _load_string()).maybeToString)(error) }); } } +exports.NuxView = NuxView; \ No newline at end of file diff --git a/pkg/nuclide-nux/lib/main.js b/pkg/nuclide-nux/lib/main.js index baf214a47e..35361422aa 100644 --- a/pkg/nuclide-nux/lib/main.js +++ b/pkg/nuclide-nux/lib/main.js @@ -1,3 +1,34 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.activate = activate; +exports.deactivate = deactivate; +exports.provideRegisterNuxService = provideRegisterNuxService; +exports.provideTriggerNuxService = provideTriggerNuxService; +exports.consumeSyncCompletedNuxService = consumeSyncCompletedNuxService; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _NuxManager; + +function _load_NuxManager() { + return _NuxManager = require('./NuxManager'); +} + +var _NuxStore; + +function _load_NuxStore() { + return _NuxStore = require('./NuxStore'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,62 +36,43 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import invariant from 'assert'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {NuxManager} from './NuxManager'; -import {NuxStore} from './NuxStore'; - -import type {NuxTourModel} from './NuxModel'; - -export type RegisterNux = (nux: NuxTourModel) => IDisposable; -export type TriggerNux = (id: number) => void; -export type SyncCompletedNux = (id: number) => void; - class Activation { - _disposables: UniversalDisposable; - _nuxStore: NuxStore; - _nuxManager: NuxManager; - _syncCompletedNuxService: SyncCompletedNux; - - constructor(): void { - this._disposables = new UniversalDisposable(); - this._nuxStore = new NuxStore(); - this._nuxManager = new NuxManager( - this._nuxStore, - this._syncCompletedNux.bind(this), - ); + + constructor() { + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._nuxStore = new (_NuxStore || _load_NuxStore()).NuxStore(); + this._nuxManager = new (_NuxManager || _load_NuxManager()).NuxManager(this._nuxStore, this._syncCompletedNux.bind(this)); this._disposables.add(this._nuxStore); this._disposables.add(this._nuxManager); } - dispose(): void { + dispose() { this._serializeAndPersist(); this._disposables.dispose(); } - _serializeAndPersist(): void { + _serializeAndPersist() { this._nuxStore.serialize(); } - addNewNux(nux: NuxTourModel): IDisposable { + addNewNux(nux) { return this._nuxManager.addNewNux(nux); } - tryTriggerNux(id: number): void { + tryTriggerNux(id) { this._nuxManager.tryTriggerNux(id); } - setSyncCompletedNuxService(syncCompletedNuxService: SyncCompletedNux): void { + setSyncCompletedNuxService(syncCompletedNuxService) { this._syncCompletedNuxService = syncCompletedNuxService; } - _syncCompletedNux(id: number): void { + _syncCompletedNux(id) { if (this._syncCompletedNuxService == null) { return; } @@ -68,23 +80,23 @@ class Activation { } } -let activation: ?Activation = null; +let activation = null; -export function activate(): void { +function activate() { if (activation == null) { activation = new Activation(); } } -export function deactivate(): void { +function deactivate() { if (activation != null) { activation.dispose(); activation = null; } } -export function provideRegisterNuxService(): RegisterNux { - return (nux: NuxTourModel): IDisposable => { +function provideRegisterNuxService() { + return nux => { if (activation == null) { throw new Error('An error occurred when instantiating the NUX package.'); } @@ -95,8 +107,8 @@ export function provideRegisterNuxService(): RegisterNux { }; } -export function provideTriggerNuxService(): TriggerNux { - return (id: number): void => { +function provideTriggerNuxService() { + return id => { if (activation == null) { throw new Error('An error occurred when instantiating the NUX package.'); } @@ -104,9 +116,10 @@ export function provideTriggerNuxService(): TriggerNux { }; } -export function consumeSyncCompletedNuxService( - syncCompletedNuxService: SyncCompletedNux, -): void { - invariant(activation != null); +function consumeSyncCompletedNuxService(syncCompletedNuxService) { + if (!(activation != null)) { + throw new Error('Invariant violation: "activation != null"'); + } + activation.setSyncCompletedNuxService(syncCompletedNuxService); -} +} \ No newline at end of file diff --git a/pkg/nuclide-objc/lib/ObjectiveCBracketBalancer.js b/pkg/nuclide-objc/lib/ObjectiveCBracketBalancer.js index 0ff6668408..1b5a9f0ebd 100644 --- a/pkg/nuclide-objc/lib/ObjectiveCBracketBalancer.js +++ b/pkg/nuclide-objc/lib/ObjectiveCBracketBalancer.js @@ -1,3 +1,31 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _atom = require('atom'); + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _observeLanguageTextEditors; + +function _load_observeLanguageTextEditors() { + return _observeLanguageTextEditors = _interopRequireDefault(require('../../commons-atom/observe-language-text-editors')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const GRAMMARS = ['source.objc', 'source.objcpp']; + +/** + * This closes square brackets for Objective-C message calls. + * Clients must call `disable()` once they're done with an instance. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,40 +33,23 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import {Point} from 'atom'; - -import {trackTiming} from '../../nuclide-analytics'; -import observeLanguageTextEditors from '../../commons-atom/observe-language-text-editors'; - -const GRAMMARS = ['source.objc', 'source.objcpp']; - -/** - * This closes square brackets for Objective-C message calls. - * Clients must call `disable()` once they're done with an instance. - */ -export default class ObjectiveCBracketBalancer { - _editingSubscriptionsMap: Map; - _languageListener: ?IDisposable; +class ObjectiveCBracketBalancer { - enable(): void { + enable() { // The feature is already enabled. if (this._languageListener) { return; } this._editingSubscriptionsMap = new Map(); - this._languageListener = observeLanguageTextEditors( - GRAMMARS, - textEditor => this._enableInTextEditor(textEditor), - textEditor => this._disableInTextEditor(textEditor), - ); + this._languageListener = (0, (_observeLanguageTextEditors || _load_observeLanguageTextEditors()).default)(GRAMMARS, textEditor => this._enableInTextEditor(textEditor), textEditor => this._disableInTextEditor(textEditor)); } - disable(): void { + disable() { // The feature is already disabled. if (!this._languageListener) { return; @@ -46,22 +57,17 @@ export default class ObjectiveCBracketBalancer { this._languageListener.dispose(); this._languageListener = null; - this._editingSubscriptionsMap.forEach(subscription => - subscription.dispose(), - ); + this._editingSubscriptionsMap.forEach(subscription => subscription.dispose()); this._editingSubscriptionsMap.clear(); } - _enableInTextEditor(textEditor: TextEditor): void { + _enableInTextEditor(textEditor) { const insertTextSubscription = textEditor.onDidInsertText(event => { - trackTiming('objc:balance-bracket', () => { - const {range, text} = event; + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)('objc:balance-bracket', () => { + const { range, text } = event; if (text === ']') { const buffer = textEditor.getBuffer(); - const leftBracketInsertPosition = ObjectiveCBracketBalancer.getOpenBracketInsertPosition( - buffer, - range.start, - ); + const leftBracketInsertPosition = ObjectiveCBracketBalancer.getOpenBracketInsertPosition(buffer, range.start); if (leftBracketInsertPosition) { buffer.insert(leftBracketInsertPosition, '['); } @@ -71,7 +77,7 @@ export default class ObjectiveCBracketBalancer { this._editingSubscriptionsMap.set(textEditor, insertTextSubscription); } - _disableInTextEditor(textEditor: TextEditor): void { + _disableInTextEditor(textEditor) { const subscription = this._editingSubscriptionsMap.get(textEditor); if (subscription) { subscription.dispose(); @@ -79,16 +85,13 @@ export default class ObjectiveCBracketBalancer { } } - static getOpenBracketInsertPosition( - buffer: atom$TextBuffer, - closeBracketPosition: Point, - ): ?Point { + static getOpenBracketInsertPosition(buffer, closeBracketPosition) { const startingLine = buffer.lineForRow(closeBracketPosition.row); let singleQuoteCount = 0; let doubleQuoteCount = 0; const characterCount = { '[': 0, - ']': 0, + ']': 0 }; // Iterate through the line, determining if we have balanced brackets. @@ -108,10 +111,7 @@ export default class ObjectiveCBracketBalancer { const stringLiteralMatch = /@".*"\s.*]/.exec(startingLine); if (stringLiteralMatch) { - return Point.fromObject([ - closeBracketPosition.row, - stringLiteralMatch.index, - ]); + return _atom.Point.fromObject([closeBracketPosition.row, stringLiteralMatch.index]); } else if (characterCount['['] < characterCount[']']) { // Check if we're at the bottom of a multi-line method. const multiLineMethodRegex = /^[\s\w[]*:.*[^;{];?$/; @@ -126,17 +126,15 @@ export default class ObjectiveCBracketBalancer { } if ( - // eslint-disable-next-line eqeqeq - currentRowPlusOne !== null && - currentRowPlusOne !== closeBracketPosition.row - ) { + // eslint-disable-next-line eqeqeq + currentRowPlusOne !== null && currentRowPlusOne !== closeBracketPosition.row) { const targetLine = buffer.lineForRow(currentRowPlusOne); const targetMatch = /\S/.exec(targetLine); if (targetLine[targetMatch.index] === '[') { return null; } else { - return Point.fromObject([currentRowPlusOne, targetMatch.index]); + return _atom.Point.fromObject([currentRowPlusOne, targetMatch.index]); } } else { // We need a bracket on this line - at this point it's either @@ -154,10 +152,11 @@ export default class ObjectiveCBracketBalancer { column = 0; } - return Point.fromObject([closeBracketPosition.row, column]); + return _atom.Point.fromObject([closeBracketPosition.row, column]); } } else { return null; } } } +exports.default = ObjectiveCBracketBalancer; \ No newline at end of file diff --git a/pkg/nuclide-objc/lib/ObjectiveCColonIndenter.js b/pkg/nuclide-objc/lib/ObjectiveCColonIndenter.js index 150700e250..89dffdfd2d 100644 --- a/pkg/nuclide-objc/lib/ObjectiveCColonIndenter.js +++ b/pkg/nuclide-objc/lib/ObjectiveCColonIndenter.js @@ -1,3 +1,31 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _atom = require('atom'); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _observeLanguageTextEditors; + +function _load_observeLanguageTextEditors() { + return _observeLanguageTextEditors = _interopRequireDefault(require('../../commons-atom/observe-language-text-editors')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,15 +33,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import {Range} from 'atom'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {trackTiming} from '../../nuclide-analytics'; -import observeLanguageTextEditors from '../../commons-atom/observe-language-text-editors'; - const GRAMMARS = ['source.objc', 'source.objcpp']; // The indentation amount depends on previous lines. If the user types a colon outside of a method @@ -24,111 +47,77 @@ const NUMBER_OF_PREVIOUS_LINES_TO_SEARCH_FOR_COLONS = 25; * This provides improved Objective-C indentation by aligning colons. * Clients must call `disable()` once they're done with an instance. */ -export default class ObjectiveCColonIndenter { - _subscriptions: ?UniversalDisposable; - _insertTextSubscriptionsMap: Map; +class ObjectiveCColonIndenter { - enable(): void { + enable() { if (this._subscriptions) { return; } this._insertTextSubscriptionsMap = new Map(); - const subscriptions = (this._subscriptions = new UniversalDisposable()); + const subscriptions = this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); subscriptions.add({ dispose: () => { - this._insertTextSubscriptionsMap.forEach(subscription => - subscription.dispose(), - ); + this._insertTextSubscriptionsMap.forEach(subscription => subscription.dispose()); this._insertTextSubscriptionsMap.clear(); - }, + } }); - subscriptions.add( - observeLanguageTextEditors( - GRAMMARS, - textEditor => this._enableInTextEditor(textEditor), - textEditor => this._disableInTextEditor(textEditor), - ), - ); + subscriptions.add((0, (_observeLanguageTextEditors || _load_observeLanguageTextEditors()).default)(GRAMMARS, textEditor => this._enableInTextEditor(textEditor), textEditor => this._disableInTextEditor(textEditor))); } - disable(): void { + disable() { if (this._subscriptions) { this._subscriptions.dispose(); this._subscriptions = null; } } - _enableInTextEditor(textEditor: TextEditor): void { - this._insertTextSubscriptionsMap.set( - textEditor, - textEditor.onDidInsertText(event => { - trackTiming('objc:indent-colon', () => { - const {range, text} = event; - - // Ignore the inserted text if the user is typing in a string or comment. - // - // The scope descriptor marks the text with semantic information, - // generally used for syntax highlighting. - const isNonCodeText = textEditor - .scopeDescriptorForBufferPosition(range.start) - .getScopesArray() - .some( - scope => - scope.startsWith('string') || scope.startsWith('comment'), - ); - if (text !== ':' || isNonCodeText) { - return; - } - - const buffer = textEditor.getBuffer(); - - const currentColonPosition = range.start; - const colonColumn = ObjectiveCColonIndenter.getIndentedColonColumn( - buffer, - currentColonPosition, - ); - // flowlint-next-line sketchy-null-number:off - if (!colonColumn) { - return; - } - - // Fully replace the current line with the properly-indented line. - // - // 1. Get the current line and strip all the indentation. - const line = buffer.lineForRow(currentColonPosition.row); - const unindentedLine = line.trimLeft(); - // 2. Calculate the amount of indentation the line should end up with. - const numberOfIndentCharacters = line.length - unindentedLine.length; - const unindentedCurrentColonColumn = - currentColonPosition.column - numberOfIndentCharacters; - const totalIndentAmount = - unindentedCurrentColonColumn >= colonColumn - ? 0 - : colonColumn - unindentedCurrentColonColumn; - // 3. Replace the current line with the properly-indented line. - textEditor.setTextInBufferRange( - buffer.rangeForRow( - currentColonPosition.row, - /* includeNewline */ false, - ), - ' '.repeat(totalIndentAmount) + unindentedLine, - ); - - // Move the cursor to right after the inserted colon. - const newCursorPosition = [ - currentColonPosition.row, - totalIndentAmount + unindentedCurrentColonColumn + 1, - ]; - textEditor.setCursorBufferPosition(newCursorPosition); - textEditor.scrollToBufferPosition(newCursorPosition); - }); - }), - ); + _enableInTextEditor(textEditor) { + this._insertTextSubscriptionsMap.set(textEditor, textEditor.onDidInsertText(event => { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)('objc:indent-colon', () => { + const { range, text } = event; + + // Ignore the inserted text if the user is typing in a string or comment. + // + // The scope descriptor marks the text with semantic information, + // generally used for syntax highlighting. + const isNonCodeText = textEditor.scopeDescriptorForBufferPosition(range.start).getScopesArray().some(scope => scope.startsWith('string') || scope.startsWith('comment')); + if (text !== ':' || isNonCodeText) { + return; + } + + const buffer = textEditor.getBuffer(); + + const currentColonPosition = range.start; + const colonColumn = ObjectiveCColonIndenter.getIndentedColonColumn(buffer, currentColonPosition); + // flowlint-next-line sketchy-null-number:off + if (!colonColumn) { + return; + } + + // Fully replace the current line with the properly-indented line. + // + // 1. Get the current line and strip all the indentation. + const line = buffer.lineForRow(currentColonPosition.row); + const unindentedLine = line.trimLeft(); + // 2. Calculate the amount of indentation the line should end up with. + const numberOfIndentCharacters = line.length - unindentedLine.length; + const unindentedCurrentColonColumn = currentColonPosition.column - numberOfIndentCharacters; + const totalIndentAmount = unindentedCurrentColonColumn >= colonColumn ? 0 : colonColumn - unindentedCurrentColonColumn; + // 3. Replace the current line with the properly-indented line. + textEditor.setTextInBufferRange(buffer.rangeForRow(currentColonPosition.row, + /* includeNewline */false), ' '.repeat(totalIndentAmount) + unindentedLine); + + // Move the cursor to right after the inserted colon. + const newCursorPosition = [currentColonPosition.row, totalIndentAmount + unindentedCurrentColonColumn + 1]; + textEditor.setCursorBufferPosition(newCursorPosition); + textEditor.scrollToBufferPosition(newCursorPosition); + }); + })); } - _disableInTextEditor(textEditor: TextEditor): void { + _disableInTextEditor(textEditor) { const subscription = this._insertTextSubscriptionsMap.get(textEditor); if (subscription) { subscription.dispose(); @@ -139,10 +128,7 @@ export default class ObjectiveCColonIndenter { /** * Return the column of the colon to align with, or null if it doesn't exist. */ - static getIndentedColonColumn( - buffer: atom$TextBuffer, - startPosition: atom$Point, - ): ?number { + static getIndentedColonColumn(buffer, startPosition) { // Look for the first colon after the start of the current method. // // The general approach is to iterate backwards, checking key characters. @@ -154,44 +140,36 @@ export default class ObjectiveCColonIndenter { let column = null; let numberOfUnclosedBrackets = 0; buffer.backwardsScanInRange( - // Only stop at the key characters: `:[]+-`. - /:|\[|]|\+|-/g, - Range.fromObject([ - startPosition.translate([ - -NUMBER_OF_PREVIOUS_LINES_TO_SEARCH_FOR_COLONS, - 0, - ]), - startPosition.translate([0, -1]), - ]), - ({match, matchText, range, stop}) => { - const position = range.start; - // If we find a key character on the starting line, then the user is - // typing a single-line method (it doesn't need to be indented). - const isSingleLineMethod = position.row === startPosition.row; - // `+` or `-` means we've reached the start of a method declaration. - const isDeclaration = matchText === '+' || matchText === '-'; - if (isSingleLineMethod || isDeclaration) { - stop(); - return; - } - - // Unbalanced brackets mean we've reached the start of a method call. - if (matchText === '[') { - numberOfUnclosedBrackets--; - } else if (matchText === ']') { - numberOfUnclosedBrackets++; - } - if (numberOfUnclosedBrackets === -1) { - stop(); - return; - } - - // Keep track of the last colon that we see. - if (matchText === ':') { - ({column} = position); - } - }, - ); + // Only stop at the key characters: `:[]+-`. + /:|\[|]|\+|-/g, _atom.Range.fromObject([startPosition.translate([-NUMBER_OF_PREVIOUS_LINES_TO_SEARCH_FOR_COLONS, 0]), startPosition.translate([0, -1])]), ({ match, matchText, range, stop }) => { + const position = range.start; + // If we find a key character on the starting line, then the user is + // typing a single-line method (it doesn't need to be indented). + const isSingleLineMethod = position.row === startPosition.row; + // `+` or `-` means we've reached the start of a method declaration. + const isDeclaration = matchText === '+' || matchText === '-'; + if (isSingleLineMethod || isDeclaration) { + stop(); + return; + } + + // Unbalanced brackets mean we've reached the start of a method call. + if (matchText === '[') { + numberOfUnclosedBrackets--; + } else if (matchText === ']') { + numberOfUnclosedBrackets++; + } + if (numberOfUnclosedBrackets === -1) { + stop(); + return; + } + + // Keep track of the last colon that we see. + if (matchText === ':') { + ({ column } = position); + } + }); return column; } } +exports.default = ObjectiveCColonIndenter; \ No newline at end of file diff --git a/pkg/nuclide-objc/lib/main.js b/pkg/nuclide-objc/lib/main.js index c3a1c6c852..ee268d0ae6 100644 --- a/pkg/nuclide-objc/lib/main.js +++ b/pkg/nuclide-objc/lib/main.js @@ -1,35 +1,39 @@ -/** - * 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 - */ - -import featureConfig from 'nuclide-commons-atom/feature-config'; -import ObjectiveCColonIndenter from './ObjectiveCColonIndenter'; -import ObjectiveCBracketBalancer from './ObjectiveCBracketBalancer'; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.activate = activate; +exports.deactivate = deactivate; + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _ObjectiveCColonIndenter; + +function _load_ObjectiveCColonIndenter() { + return _ObjectiveCColonIndenter = _interopRequireDefault(require('./ObjectiveCColonIndenter')); +} + +var _ObjectiveCBracketBalancer; + +function _load_ObjectiveCBracketBalancer() { + return _ObjectiveCBracketBalancer = _interopRequireDefault(require('./ObjectiveCBracketBalancer')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class Activation { - _indentFeature: ObjectiveCColonIndenter; - _bracketFeature: ObjectiveCBracketBalancer; - _configSubscription: IDisposable; constructor() { - this._indentFeature = new ObjectiveCColonIndenter(); + this._indentFeature = new (_ObjectiveCColonIndenter || _load_ObjectiveCColonIndenter()).default(); this._indentFeature.enable(); - this._bracketFeature = new ObjectiveCBracketBalancer(); - this._configSubscription = featureConfig.observe( - 'nuclide-objc.enableAutomaticSquareBracketInsertion', - enabled => - enabled - ? this._bracketFeature.enable() - : this._bracketFeature.disable(), - ); + this._bracketFeature = new (_ObjectiveCBracketBalancer || _load_ObjectiveCBracketBalancer()).default(); + this._configSubscription = (_featureConfig || _load_featureConfig()).default.observe('nuclide-objc.enableAutomaticSquareBracketInsertion', enabled => enabled ? this._bracketFeature.enable() : this._bracketFeature.disable()); } dispose() { @@ -37,19 +41,28 @@ class Activation { this._bracketFeature.disable(); this._indentFeature.disable(); } -} +} /** + * 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. + * + * + * @format + */ -let activation: ?Activation; +let activation; -export function activate(state: ?mixed): void { +function activate(state) { if (!activation) { activation = new Activation(); } } -export function deactivate(): void { +function deactivate() { if (activation) { activation.dispose(); activation = null; } -} +} \ No newline at end of file diff --git a/pkg/nuclide-objc/spec/ObjectiveCBracketBalancer-spec.js b/pkg/nuclide-objc/spec/ObjectiveCBracketBalancer-spec.js deleted file mode 100644 index 41b697c65d..0000000000 --- a/pkg/nuclide-objc/spec/ObjectiveCBracketBalancer-spec.js +++ /dev/null @@ -1,181 +0,0 @@ -/** - * 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 - */ - -import {Point, TextBuffer} from 'atom'; -import ObjectiveCBracketBalancer from '../lib/ObjectiveCBracketBalancer'; - -const {getOpenBracketInsertPosition} = ObjectiveCBracketBalancer; - -describe('ObjectiveCBracketBalancer', () => { - describe('getOpenBracketInsertPosition', () => { - it( - 'returns the correct point on a line that contains no space before the close' + - ' bracket', - () => { - expect( - getOpenBracketInsertPosition( - new TextBuffer(']'), - Point.fromObject([0, 0]), - ), - ).toEqual(Point.fromObject([0, 0])); - }, - ); - - it( - 'returns the correct point on a line that contains only whitespace before the close' + - ' bracket', - () => { - expect( - getOpenBracketInsertPosition( - new TextBuffer(' ]'), - Point.fromObject([0, 3]), - ), - ).toEqual(Point.fromObject([0, 3])); - }, - ); - - it('inserts an open bracket at the start of an unbalanced simple expression', () => { - expect( - getOpenBracketInsertPosition( - new TextBuffer('self setEnabled:NO]'), - Point.fromObject([0, 18]), - ), - ).toEqual(Point.fromObject([0, 0])); - }); - - it('does not insert an open bracket when completing a balanced simple expression', () => { - expect( - getOpenBracketInsertPosition( - new TextBuffer('[self setEnabled:NO]'), - Point.fromObject([0, 19]), - ), - ).toEqual(null); - }); - - it('inserts an open bracket at the beginning of an unbalanced nested expression', () => { - expect( - getOpenBracketInsertPosition( - new TextBuffer('[self foo] setEnabled:NO]'), - Point.fromObject([0, 24]), - ), - ).toEqual(Point.fromObject([0, 0])); - }); - - it('does not insert an open bracket when completing a balanced nested expression', () => { - expect( - getOpenBracketInsertPosition( - new TextBuffer('[[self foo] setEnabled:NO]'), - Point.fromObject([0, 25]), - ), - ).toEqual(null); - }); - - it( - 'inserts an open bracket at the beginning of an unbalanced nested expression with an open' + - ' bracket in a string literal', - () => { - expect( - getOpenBracketInsertPosition( - new TextBuffer('[self fooWithBar:@"tricky ["] setEnabled:NO]'), - Point.fromObject([0, 43]), - ), - ).toEqual(Point.fromObject([0, 0])); - }, - ); - - it( - 'inserts an open bracket at the beginning of an unbalanced nested expression with an open' + - ' bracket in a char literal', - () => { - expect( - getOpenBracketInsertPosition( - new TextBuffer("[self fooWithBar:'['] setEnabled:NO]"), - Point.fromObject([0, 35]), - ), - ).toEqual(Point.fromObject([0, 0])); - }, - ); - - it( - 'does not insert an open bracket at the beginning of a balanced nested expression with an' + - ' open bracket in a char literal', - () => { - expect( - getOpenBracketInsertPosition( - new TextBuffer("[foo('[') setEnabled:NO]"), - Point.fromObject([0, 23]), - ), - ).toEqual(null); - }, - ); - - it( - 'inserts an open bracket before the nearest expression when within an existing balanced' + - ' bracket pair', - () => { - // Start with: [self setFoo:@"bar" |] - // cursor ^ - // Type ] and we should insert the [ before @"bar" - // Ending with: [self setFoo:[@"bar" ]] - expect( - getOpenBracketInsertPosition( - new TextBuffer('[self setFoo:@"bar" ]'), - Point.fromObject([0, 20]), - ), - ).toEqual(Point.fromObject([0, 13])); - }, - ); - - it('inserts an open bracket at the beginning of an unbalanced expression across multiple lines', () => { - expect( - getOpenBracketInsertPosition( - new TextBuffer('foo setFoo:@"foo"\nbar:@"bar"\nbaz:@"baz"]'), - Point.fromObject([2, 10]), - ), - ).toEqual(Point.fromObject([0, 0])); - }); - - it( - 'does not insert an open bracket at the beginning of a balanced expression across multiple' + - ' lines', - () => { - expect( - getOpenBracketInsertPosition( - new TextBuffer('[foo setFoo:@"foo"\nbar:@"bar"\nbaz:@"baz"]'), - Point.fromObject([2, 10]), - ), - ).toEqual(null); - }, - ); - - it('inserts an open bracket after an equals sign when initalizing or messaging a class', () => { - expect( - getOpenBracketInsertPosition( - new TextBuffer('NSObject *foo = NSObject alloc]'), - Point.fromObject([0, 30]), - ), - ).toEqual(Point.fromObject([0, 16])); - }); - - it( - 'does not insert an open bracket after an equals sign when initalizing or messaging a class' + - ' with balanced brackets', - () => { - expect( - getOpenBracketInsertPosition( - new TextBuffer('[[NSObject alloc] init]'), - Point.fromObject([0, 22]), - ), - ).toEqual(null); - }, - ); - }); -}); diff --git a/pkg/nuclide-objc/spec/ObjectiveCColonIndenter-spec.js b/pkg/nuclide-objc/spec/ObjectiveCColonIndenter-spec.js deleted file mode 100644 index 708ee3c162..0000000000 --- a/pkg/nuclide-objc/spec/ObjectiveCColonIndenter-spec.js +++ /dev/null @@ -1,160 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import {Point, TextBuffer} from 'atom'; - -import ObjectiveCColonIndenter from '../lib/ObjectiveCColonIndenter'; -const {getIndentedColonColumn} = ObjectiveCColonIndenter; - -describe('ObjectiveCColonIndenter', () => { - describe('getIndentedColonColumn', () => { - it('returns null if no colons are found for a method declaration', () => { - expect( - getIndentedColonColumn( - new TextBuffer( - ` - + (Type *)arg - arg:`, - ), - Point.fromObject([2, 17]), - ), - ).toBeNull(); - }); - - it('works on class method declarations', () => { - expect( - getIndentedColonColumn( - new TextBuffer( - ` - + (Type *)arg:(Type *)value - arg:`, - ), - Point.fromObject([2, 17]), - ), - ).toEqual(27); - }); - - it('works on instance method declarations', () => { - expect( - getIndentedColonColumn( - new TextBuffer( - ` - - (Type *)arg:(Type *)value - arg:`, - ), - Point.fromObject([2, 17]), - ), - ).toEqual(27); - }); - - it('returns null for single-line method calls', () => { - expect( - getIndentedColonColumn( - new TextBuffer('[obj arg:value :'), - Point.fromObject([0, 15]), - ), - ).toBeNull(); - }); - - it('works on multi-line method calls', () => { - expect( - getIndentedColonColumn( - new TextBuffer( - ` - [obj arg:value - arg:value - arg:`, - ), - Point.fromObject([3, 17]), - ), - ).toEqual(22); - }); - - it('returns null if no colons are found for a method call', () => { - expect( - getIndentedColonColumn( - new TextBuffer( - ` - [obj arg - arg:`, - ), - Point.fromObject([2, 17]), - ), - ).toBeNull(); - }); - - it('returns null if no key characters are found', () => { - expect( - getIndentedColonColumn( - new TextBuffer( - ` - obj arg - arg:`, - ), - Point.fromObject([2, 17]), - ), - ).toBeNull(); - }); - - it('works when the first line of the method has multiple colons', () => { - expect( - getIndentedColonColumn( - new TextBuffer( - ` - [obj arg:value arg:value - arg:`, - ), - Point.fromObject([2, 17]), - ), - ).toEqual(22); - }); - - it('works when the previous line is not indented properly', () => { - expect( - getIndentedColonColumn( - new TextBuffer( - ` - [obj arg:value - arg:value - arg:`, - ), - Point.fromObject([3, 17]), - ), - ).toEqual(22); - }); - - it('works when the method is nested and on the same line as the outer method', () => { - expect( - getIndentedColonColumn( - new TextBuffer( - ` - [obj arg:[obj value: - arg:`, - ), - Point.fromObject([2, 17]), - ), - ).toEqual(33); - }); - - it('works when a previous argument is a nested method', () => { - expect( - getIndentedColonColumn( - new TextBuffer( - ` - [obj arg:[obj arg:value] - arg:`, - ), - Point.fromObject([2, 17]), - ), - ).toEqual(22); - }); - }); -}); diff --git a/pkg/nuclide-ocaml/lib/CodeLensListener.js b/pkg/nuclide-ocaml/lib/CodeLensListener.js index 75c3e8bb1e..e9e8325c68 100644 --- a/pkg/nuclide-ocaml/lib/CodeLensListener.js +++ b/pkg/nuclide-ocaml/lib/CodeLensListener.js @@ -1,53 +1,70 @@ -/** - * 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 - */ - -import type {AtomLanguageService} from '../../nuclide-language-service'; -import type { - LanguageService, - CodeLensData, -} from '../../nuclide-language-service/lib/LanguageService'; -import type {FileVersion} from '../../nuclide-open-files-rpc/lib/rpc-types'; - -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {observeEditorDestroy} from 'nuclide-commons-atom/text-editor'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import {microtask} from 'nuclide-commons/observable'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Observable} from 'rxjs'; -import {getFileVersionOfEditor} from '../../nuclide-open-files'; -import createDOMPurify from 'dompurify'; - -const domPurify = createDOMPurify(); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.observeForCodeLens = observeForCodeLens; + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _textEditor; + +function _load_textEditor() { + return _textEditor = require('../../../modules/nuclide-commons-atom/text-editor'); +} + +var _event; + +function _load_event() { + return _event = require('../../../modules/nuclide-commons/event'); +} + +var _observable; + +function _load_observable() { + return _observable = require('../../../modules/nuclide-commons/observable'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideOpenFiles; + +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} + +var _dompurify; + +function _load_dompurify() { + return _dompurify = _interopRequireDefault(require('dompurify')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const domPurify = (0, (_dompurify || _load_dompurify()).default)(); /** + * 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. + * + * + * @format + */ const RETRIES = 3; -type ResolvableLens = { - lens: CodeLensData, - element: HTMLElement, - resolved: boolean, - retries: number, -}; - -type ResolveInfo = { - editor: atom$TextEditor, - fileVersion: FileVersion, - languageService: LanguageService, - lenses: Array, -}; - -function makeResolvableLens( - editor: atom$TextEditor, - markerLayer: atom$DisplayMarkerLayer, - lens: CodeLensData, -): ResolvableLens { +function makeResolvableLens(editor, markerLayer, lens) { const marker = markerLayer.markBufferPosition(lens.range.start); const element = document.createElement('span'); @@ -58,15 +75,12 @@ function makeResolvableLens( // editor down as we resolve code lenses. element.innerHTML = '\xa0'; const listener = () => { - if ( - element.innerText != null && - featureConfig.get('nuclide-ocaml.codeLensCopy') - ) { + if (element.innerText != null && (_featureConfig || _load_featureConfig()).default.get('nuclide-ocaml.codeLensCopy')) { atom.clipboard.write(element.innerText); const tooltipDispose = atom.tooltips.add(element, { title: 'Copied code lens to clipboard.', placement: 'auto', - trigger: 'manual', + trigger: 'manual' }); setTimeout(() => tooltipDispose.dispose(), 3000); } @@ -88,77 +102,53 @@ function makeResolvableLens( editor.decorateMarker(marker, { type: 'block', position: 'before', - item: containingElement, + item: containingElement }); - return {lens, element, marker, resolved: false, retries: 0}; + return { lens, element, marker, resolved: false, retries: 0 }; } -function getCodeLensPositions( - atomLanguageService: AtomLanguageService, - logger: log4js$Logger, - editor: atom$TextEditor, -): Observable, -}> { +function getCodeLensPositions(atomLanguageService, logger, editor) { const uri = editor.getPath(); - return Observable.defer(() => - atomLanguageService.getLanguageServiceForUri(uri), - ).switchMap(languageService => { + return _rxjsBundlesRxMinJs.Observable.defer(() => atomLanguageService.getLanguageServiceForUri(uri)).switchMap(languageService => { if (languageService == null) { - return Observable.of(null); + return _rxjsBundlesRxMinJs.Observable.of(null); } - return Observable.defer(() => getFileVersionOfEditor(editor)).switchMap( - fileVersion => { - if (fileVersion == null) { - return Observable.of(null); + return _rxjsBundlesRxMinJs.Observable.defer(() => (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getFileVersionOfEditor)(editor)).switchMap(fileVersion => { + if (fileVersion == null) { + return _rxjsBundlesRxMinJs.Observable.of(null); + } + return _rxjsBundlesRxMinJs.Observable.defer(async () => { + const codeLens = await languageService.getCodeLens(fileVersion); + if (codeLens == null) { + throw new Error('Could not retrieve code lenses.'); } - return Observable.defer(async () => { - const codeLens = await languageService.getCodeLens(fileVersion); - if (codeLens == null) { - throw new Error('Could not retrieve code lenses.'); - } - return {languageService, fileVersion, codeLens}; - }) - .retryWhen(errs => - errs.zip(Observable.range(1, RETRIES)).flatMap((_, retryCount) => { - return Observable.timer(retryCount * 1000); - }), - ) - .defaultIfEmpty(null); - }, - ); + return { languageService, fileVersion, codeLens }; + }).retryWhen(errs => errs.zip(_rxjsBundlesRxMinJs.Observable.range(1, RETRIES)).flatMap((_, retryCount) => { + return _rxjsBundlesRxMinJs.Observable.timer(retryCount * 1000); + })).defaultIfEmpty(null); + }); }); } -function markCodeLensPositions( - languageService: LanguageService, - editor: atom$TextEditor, - markerLayer: atom$DisplayMarkerLayer, - fileVersion: FileVersion, - codeLens: Array, -): ResolveInfo { +function markCodeLensPositions(languageService, editor, markerLayer, fileVersion, codeLens) { // Sort code lenses based on their row numbers from top to bottom, so // later their resolution can start in the same order. return { editor, fileVersion, languageService, - lenses: codeLens - .sort((lens1, lens2) => lens1.range.start.row - lens2.range.start.row) - .map(lens => makeResolvableLens(editor, markerLayer, lens)), + lenses: codeLens.sort((lens1, lens2) => lens1.range.start.row - lens2.range.start.row).map(lens => makeResolvableLens(editor, markerLayer, lens)) }; } -function resolveVisible(resolveInfo: ResolveInfo): Observable { +function resolveVisible(resolveInfo) { const editor = resolveInfo.editor; // Currently undocumented, but there's an open PR to add these to the public // API: https://github.com/atom/atom/issues/15559 - const firstLine = (editor: any).element.getFirstVisibleScreenRow(); - const lastLine = (editor: any).element.getLastVisibleScreenRow() + 1; + const firstLine = editor.element.getFirstVisibleScreenRow(); + const lastLine = editor.element.getLastVisibleScreenRow() + 1; const firstBufferLine = editor.bufferRowForScreenRow(firstLine); const lastBufferLine = editor.bufferRowForScreenRow(lastLine); @@ -170,27 +160,19 @@ function resolveVisible(resolveInfo: ResolveInfo): Observable { // going over the network and resolving the code lenses is several orders of // magnitude more than looping over a small array and doing simple numerical // comparisons. - const resolvableLenses = resolveInfo.lenses.filter( - lensInfo => - lensInfo.lens.range.start.row >= firstBufferLine && - lensInfo.lens.range.start.row <= lastBufferLine, - ); - - return Observable.from(resolvableLenses).mergeMap(lensInfo => { - const isFolded = () => - editor.isFoldedAtBufferRow(lensInfo.lens.range.start.row); - return Observable.defer(() => { + const resolvableLenses = resolveInfo.lenses.filter(lensInfo => lensInfo.lens.range.start.row >= firstBufferLine && lensInfo.lens.range.start.row <= lastBufferLine); + + return _rxjsBundlesRxMinJs.Observable.from(resolvableLenses).mergeMap(lensInfo => { + const isFolded = () => editor.isFoldedAtBufferRow(lensInfo.lens.range.start.row); + return _rxjsBundlesRxMinJs.Observable.defer(() => { if (lensInfo.resolved || isFolded()) { return Promise.resolve(lensInfo.lens); } // Set this *before* we get the data so we don't send duplicate requests. lensInfo.resolved = true; - return resolveInfo.languageService.resolveCodeLens( - resolveInfo.fileVersion.filePath, - lensInfo.lens, - ); - }).do((lens: ?CodeLensData) => { + return resolveInfo.languageService.resolveCodeLens(resolveInfo.fileVersion.filePath, lensInfo.lens); + }).do(lens => { lensInfo.element.classList.toggle('folded', isFolded()); if (!lensInfo.resolved) { @@ -200,7 +182,7 @@ function resolveVisible(resolveInfo: ResolveInfo): Observable { if (lens != null && lens.command != null) { const text = domPurify.sanitize(lens.command.title, { - ALLOWED_TAGS: [], + ALLOWED_TAGS: [] }); lensInfo.element.innerHTML = text; } else if (lensInfo.retries < RETRIES) { @@ -211,62 +193,26 @@ function resolveVisible(resolveInfo: ResolveInfo): Observable { }); } -export function observeForCodeLens( - atomLanguageService: AtomLanguageService, - logger: log4js$Logger, -): IDisposable { - return new UniversalDisposable( - observableFromSubscribeFunction( - atom.workspace.observeTextEditors.bind(atom.workspace), - ) - // If the editor is already open when the user launches Atom, then *two* - // events will be fired from observeTextEditors, so group by the editor ID - // and then only take the first in order to avoid the second event. - // The cause for this is: - // 1. Atom loads the text editor and adds it to the registry - // 2. Atom loads the grammar and then loads the OCaml package (because it - // only activates when an OCaml file is opened). At this point it's - // able to get the list of editors, and it fires observeTextEditors. - // 3. did-add-text-editor is fired, causing the duplicated event. - // TODO(wipi): remove once https://github.com/atom/atom/pull/17299 is - // released. - .distinct(editor => editor.id) - .mergeMap(editor => { - const markerLayer = editor.addMarkerLayer(); - return ( - observableFromSubscribeFunction(editor.onDidSave.bind(editor)) - // Add an additional event into the stream so that we don't need to - // save the file in order to get the first set of code lenses. - .startWith(null) - .switchMap(evt => - getCodeLensPositions(atomLanguageService, logger, editor), - ) - .do(() => markerLayer.clear()) - .filter(Boolean) - .map(positions => - markCodeLensPositions( - positions.languageService, - editor, - markerLayer, - positions.fileVersion, - positions.codeLens, - ), - ) - .switchMap((resolveInfo, iteration) => - Observable.merge( - iteration === 0 - ? microtask.do(() => { - editor.scrollToCursorPosition({center: true}); - }) - : Observable.empty(), - Observable.timer(0, 1000).concatMap(() => - resolveVisible(resolveInfo), - ), - ), - ) - .takeUntil(observeEditorDestroy(editor)) - ); - }) - .subscribe(), - ); -} +function observeForCodeLens(atomLanguageService, logger) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default((0, (_event || _load_event()).observableFromSubscribeFunction)(atom.workspace.observeTextEditors.bind(atom.workspace)) + // If the editor is already open when the user launches Atom, then *two* + // events will be fired from observeTextEditors, so group by the editor ID + // and then only take the first in order to avoid the second event. + // The cause for this is: + // 1. Atom loads the text editor and adds it to the registry + // 2. Atom loads the grammar and then loads the OCaml package (because it + // only activates when an OCaml file is opened). At this point it's + // able to get the list of editors, and it fires observeTextEditors. + // 3. did-add-text-editor is fired, causing the duplicated event. + // TODO(wipi): remove once https://github.com/atom/atom/pull/17299 is + // released. + .distinct(editor => editor.id).mergeMap(editor => { + const markerLayer = editor.addMarkerLayer(); + return (0, (_event || _load_event()).observableFromSubscribeFunction)(editor.onDidSave.bind(editor)) + // Add an additional event into the stream so that we don't need to + // save the file in order to get the first set of code lenses. + .startWith(null).switchMap(evt => getCodeLensPositions(atomLanguageService, logger, editor)).do(() => markerLayer.clear()).filter(Boolean).map(positions => markCodeLensPositions(positions.languageService, editor, markerLayer, positions.fileVersion, positions.codeLens)).switchMap((resolveInfo, iteration) => _rxjsBundlesRxMinJs.Observable.merge(iteration === 0 ? (_observable || _load_observable()).microtask.do(() => { + editor.scrollToCursorPosition({ center: true }); + }) : _rxjsBundlesRxMinJs.Observable.empty(), _rxjsBundlesRxMinJs.Observable.timer(0, 1000).concatMap(() => resolveVisible(resolveInfo)))).takeUntil((0, (_textEditor || _load_textEditor()).observeEditorDestroy)(editor)); + }).subscribe()); +} \ No newline at end of file diff --git a/pkg/nuclide-ocaml/lib/OCamlLanguage.js b/pkg/nuclide-ocaml/lib/OCamlLanguage.js index a5a15d7333..7077a7293d 100644 --- a/pkg/nuclide-ocaml/lib/OCamlLanguage.js +++ b/pkg/nuclide-ocaml/lib/OCamlLanguage.js @@ -1,116 +1,129 @@ -/** - * 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 strict-local - * @format - */ - -import type {ServerConnection} from '../../nuclide-remote-connection'; -import type {AtomLanguageServiceConfig} from '../../nuclide-language-service/lib/AtomLanguageService'; -import type {LanguageService} from '../../nuclide-language-service/lib/LanguageService'; - -import featureConfig from 'nuclide-commons-atom/feature-config'; -import { - AtomLanguageService, - getHostServices, -} from '../../nuclide-language-service'; -import {NullLanguageService} from '../../nuclide-language-service-rpc'; -import {parseLogLevel} from '../../nuclide-logging/lib/rpc-types'; -import {getNotifierByConnection} from '../../nuclide-open-files'; -import {getVSCodeLanguageServiceByConnection} from '../../nuclide-remote-connection'; - -async function createOCamlLanguageService( - connection: ?ServerConnection, -): Promise { - const service = getVSCodeLanguageServiceByConnection(connection); - const [fileNotifier, host] = await Promise.all([ - getNotifierByConnection(connection), - getHostServices(), - ]); - - const logLevel = parseLogLevel( - featureConfig.get('nuclide-ocaml.logLevel'), - 'DEBUG', - ); - - let ocpindent = featureConfig.get('nuclide-ocaml.pathToOcpIndent'); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.createLanguageService = createLanguageService; + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _nuclideLanguageService; + +function _load_nuclideLanguageService() { + return _nuclideLanguageService = require('../../nuclide-language-service'); +} + +var _nuclideLanguageServiceRpc; + +function _load_nuclideLanguageServiceRpc() { + return _nuclideLanguageServiceRpc = require('../../nuclide-language-service-rpc'); +} + +var _rpcTypes; + +function _load_rpcTypes() { + return _rpcTypes = require('../../nuclide-logging/lib/rpc-types'); +} + +var _nuclideOpenFiles; + +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +async function createOCamlLanguageService(connection) { + const service = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getVSCodeLanguageServiceByConnection)(connection); + const [fileNotifier, host] = await Promise.all([(0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getNotifierByConnection)(connection), (0, (_nuclideLanguageService || _load_nuclideLanguageService()).getHostServices)()]); + + const logLevel = (0, (_rpcTypes || _load_rpcTypes()).parseLogLevel)((_featureConfig || _load_featureConfig()).default.get('nuclide-ocaml.logLevel'), 'DEBUG'); + + let ocpindent = (_featureConfig || _load_featureConfig()).default.get('nuclide-ocaml.pathToOcpIndent'); if (typeof ocpindent !== 'string' || ocpindent === '') { ocpindent = null; } - const lspService = await service.createMultiLspLanguageService( - 'ocaml', - 'ocaml-language-server', - ['--stdio'], - { - logCategory: 'OcamlService', - logLevel, - fileNotifier, - host, - projectFileNames: ['esy', 'esy.json', 'package.json', '.merlin'], - projectFileSearchStrategy: 'priority', - useOriginalEnvironment: true, - fileExtensions: ['.ml', '.mli', '.re', '.rei'], - additionalLogFilesRetentionPeriod: 5 * 60 * 1000, // 5 minutes - - // ocaml-language-server will use defaults for any settings that aren't - // given, so we only need to list non-defaults here. - initializationOptions: { - codelens: { - // This doesn't actually change the encoding (Nuclide/Atom can handle - // unicode just fine), but instead just disables some single-character - // substitutions that make displayed code lenses not valid OCaml. - unicode: false, - }, - format: { - width: 80, - }, - path: - ocpindent == null - ? undefined - : { - ocpindent, - }, + const lspService = await service.createMultiLspLanguageService('ocaml', 'ocaml-language-server', ['--stdio'], { + logCategory: 'OcamlService', + logLevel, + fileNotifier, + host, + projectFileNames: ['esy', 'esy.json', 'package.json', '.merlin'], + projectFileSearchStrategy: 'priority', + useOriginalEnvironment: true, + fileExtensions: ['.ml', '.mli', '.re', '.rei'], + additionalLogFilesRetentionPeriod: 5 * 60 * 1000, // 5 minutes + + // ocaml-language-server will use defaults for any settings that aren't + // given, so we only need to list non-defaults here. + initializationOptions: { + codelens: { + // This doesn't actually change the encoding (Nuclide/Atom can handle + // unicode just fine), but instead just disables some single-character + // substitutions that make displayed code lenses not valid OCaml. + unicode: false }, - }, - ); - return lspService || new NullLanguageService(); -} + format: { + width: 80 + }, + path: ocpindent == null ? undefined : { + ocpindent + } + } + }); + return lspService || new (_nuclideLanguageServiceRpc || _load_nuclideLanguageServiceRpc()).NullLanguageService(); +} /** + * 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. + * + * strict-local + * @format + */ -export function createLanguageService(): AtomLanguageService { - const atomConfig: AtomLanguageServiceConfig = { +function createLanguageService() { + const atomConfig = { name: 'OCaml', grammars: ['source.ocaml', 'source.reason'], outline: { version: '0.1.0', priority: 1, analyticsEventName: 'ocaml.outline', - updateOnEdit: false, + updateOnEdit: false }, definition: { version: '0.1.0', priority: 20, - definitionEventName: 'ocaml.getDefinition', + definitionEventName: 'ocaml.getDefinition' }, typeHint: { version: '0.0.0', priority: 1, - analyticsEventName: 'ocaml.typeHint', + analyticsEventName: 'ocaml.typeHint' }, codeFormat: { version: '0.1.0', priority: 1, analyticsEventName: 'ocaml.formatCode', canFormatRanges: true, - canFormatAtPosition: false, + canFormatAtPosition: false }, findReferences: { version: '0.1.0', - analyticsEventName: 'ocaml.findReferences', + analyticsEventName: 'ocaml.findReferences' }, autocomplete: { inclusionPriority: 1, @@ -120,16 +133,16 @@ export function createLanguageService(): AtomLanguageService { excludeLowerPriority: false, analytics: { eventName: 'nuclide-ocaml', - shouldLogInsertedSuggestion: false, + shouldLogInsertedSuggestion: false }, autocompleteCacherConfig: null, - supportsResolve: true, + supportsResolve: true }, diagnostics: { version: '0.2.0', - analyticsEventName: 'ocaml.observeDiagnostics', - }, + analyticsEventName: 'ocaml.observeDiagnostics' + } }; - return new AtomLanguageService(createOCamlLanguageService, atomConfig); -} + return new (_nuclideLanguageService || _load_nuclideLanguageService()).AtomLanguageService(createOCamlLanguageService, atomConfig); +} \ No newline at end of file diff --git a/pkg/nuclide-ocaml/lib/main.js b/pkg/nuclide-ocaml/lib/main.js index 2c2bd74dd4..785851f49e 100644 --- a/pkg/nuclide-ocaml/lib/main.js +++ b/pkg/nuclide-ocaml/lib/main.js @@ -1,35 +1,65 @@ -/** - * 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 strict-local - * @format - */ - -import {getLogger} from 'log4js'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {observeForCodeLens} from './CodeLensListener'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {createLanguageService} from './OCamlLanguage'; - -let disposables: UniversalDisposable = new UniversalDisposable(); - -export async function activate(): Promise { - const ocamlLspLanguageService = createLanguageService(); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.activate = activate; +exports.deactivate = deactivate; + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _CodeLensListener; + +function _load_CodeLensListener() { + return _CodeLensListener = require('./CodeLensListener'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _OCamlLanguage; + +function _load_OCamlLanguage() { + return _OCamlLanguage = require('./OCamlLanguage'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +let disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); /** + * 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. + * + * strict-local + * @format + */ + +async function activate() { + const ocamlLspLanguageService = (0, (_OCamlLanguage || _load_OCamlLanguage()).createLanguageService)(); ocamlLspLanguageService.activate(); disposables.add(ocamlLspLanguageService); - if (featureConfig.get('nuclide-ocaml.codeLens')) { - disposables.add( - observeForCodeLens(ocamlLspLanguageService, getLogger('OcamlService')), - ); + if ((_featureConfig || _load_featureConfig()).default.get('nuclide-ocaml.codeLens')) { + disposables.add((0, (_CodeLensListener || _load_CodeLensListener()).observeForCodeLens)(ocamlLspLanguageService, (0, (_log4js || _load_log4js()).getLogger)('OcamlService'))); } } -export async function deactivate(): Promise { +async function deactivate() { disposables.dispose(); - disposables = new UniversalDisposable(); -} + disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); +} \ No newline at end of file diff --git a/pkg/nuclide-open-filenames-provider/lib/OpenFileNameProvider.js b/pkg/nuclide-open-filenames-provider/lib/OpenFileNameProvider.js index 0e0060e1ff..53710147a5 100644 --- a/pkg/nuclide-open-filenames-provider/lib/OpenFileNameProvider.js +++ b/pkg/nuclide-open-filenames-provider/lib/OpenFileNameProvider.js @@ -1,57 +1,55 @@ -/** - * 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 strict-local - * @format - */ - -import type {FileResult, Provider} from '../../nuclide-quick-open/lib/types'; - -import {arrayCompact} from 'nuclide-commons/collection'; -import {Matcher} from '../../nuclide-fuzzy-native'; +'use strict'; + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _nuclideFuzzyNative; + +function _load_nuclideFuzzyNative() { + return _nuclideFuzzyNative = require('../../nuclide-fuzzy-native'); +} // Returns paths of currently opened editor tabs. -function getOpenTabsMatching(query: string): Array { - const matcher = new Matcher( - arrayCompact( - atom.workspace.getTextEditors().map(editor => editor.getPath()), - ), - ); - return matcher.match(query, {recordMatchIndexes: true}).map(result => ({ +function getOpenTabsMatching(query) { + const matcher = new (_nuclideFuzzyNative || _load_nuclideFuzzyNative()).Matcher((0, (_collection || _load_collection()).arrayCompact)(atom.workspace.getTextEditors().map(editor => editor.getPath()))); + return matcher.match(query, { recordMatchIndexes: true }).map(result => ({ resultType: 'FILE', path: result.value, score: result.score, - matchIndexes: result.matchIndexes, + matchIndexes: result.matchIndexes })); -} +} /** + * 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. + * + * strict-local + * @format + */ -const OpenFileListProvider: Provider = { +const OpenFileListProvider = { providerType: 'GLOBAL', name: 'OpenFileListProvider', debounceDelay: 0, display: { title: 'Open Files', prompt: 'Search open filenames...', - action: 'nuclide-open-filenames-provider:toggle-provider', + action: 'nuclide-open-filenames-provider:toggle-provider' }, - isEligibleForDirectories( - directories: Array, - ): Promise { + isEligibleForDirectories(directories) { return Promise.resolve(true); }, - executeQuery( - query: string, - directories: Array, - ): Promise> { + executeQuery(query, directories) { return Promise.resolve(getOpenTabsMatching(query)); - }, + } }; // eslint-disable-next-line nuclide-internal/no-commonjs -module.exports = OpenFileListProvider; +module.exports = OpenFileListProvider; \ No newline at end of file diff --git a/pkg/nuclide-open-filenames-provider/lib/main.js b/pkg/nuclide-open-filenames-provider/lib/main.js index 5905138181..0371552c7d 100644 --- a/pkg/nuclide-open-filenames-provider/lib/main.js +++ b/pkg/nuclide-open-filenames-provider/lib/main.js @@ -1,3 +1,18 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.registerProvider = registerProvider; + +var _OpenFileNameProvider; + +function _load_OpenFileNameProvider() { + return _OpenFileNameProvider = _interopRequireDefault(require('./OpenFileNameProvider')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,14 +20,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {FileResult, Provider} from '../../nuclide-quick-open/lib/types'; - -import OpenFileNameProvider from './OpenFileNameProvider'; - -export function registerProvider(): Provider { - return OpenFileNameProvider; -} +function registerProvider() { + return (_OpenFileNameProvider || _load_OpenFileNameProvider()).default; +} \ No newline at end of file diff --git a/pkg/nuclide-open-files-rpc/__tests__/ConfigObserver-test.js b/pkg/nuclide-open-files-rpc/__tests__/ConfigObserver-test.js index 7f46dcc312..afccb6d080 100644 --- a/pkg/nuclide-open-files-rpc/__tests__/ConfigObserver-test.js +++ b/pkg/nuclide-open-files-rpc/__tests__/ConfigObserver-test.js @@ -1,3 +1,25 @@ +'use strict'; + +var _FileCache; + +function _load_FileCache() { + return _FileCache = require('../lib/FileCache'); +} + +var _ConfigObserver; + +function _load_ConfigObserver() { + return _ConfigObserver = require('../lib/ConfigObserver'); +} + +var _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../../../jest/waits_for')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,31 +27,25 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import {FileCache} from '../lib/FileCache'; -import {ConfigObserver} from '../lib/ConfigObserver'; -import waitsFor from '../../../jest/waits_for'; - describe('ConfigObserver', () => { - let cache: FileCache = (null: any); + let cache = null; let eventCount = 0; - let events: Promise>> = (null: any); - let findNearestFile: (path: NuclideUri) => Promise = (null: any); + let events = null; + let findNearestFile = null; const createOpen = filePath => ({ kind: 'open', fileVersion: { notifier: cache, filePath, - version: 1, + version: 1 }, contents: 'contents1', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); const createClose = filePath => ({ @@ -37,94 +53,82 @@ describe('ConfigObserver', () => { fileVersion: { notifier: cache, filePath, - version: 1, - }, + version: 1 + } }); beforeEach(() => { - cache = new FileCache(); - const observer = new ConfigObserver(cache, ['.php'], path => - findNearestFile(path), - ); + cache = new (_FileCache || _load_FileCache()).FileCache(); + const observer = new (_ConfigObserver || _load_ConfigObserver()).ConfigObserver(cache, ['.php'], path => findNearestFile(path)); eventCount = 0; - events = observer - .observeConfigs() - .map(config => Array.from(config)) - .do(() => { - eventCount++; - }) - .toArray() - .toPromise(); + events = observer.observeConfigs().map(config => Array.from(config)).do(() => { + eventCount++; + }).toArray().toPromise(); }); it('root project', async () => { findNearestFile = path => Promise.resolve(path); cache.onDirectoriesChanged(new Set(['/some/path'])); - await waitsFor(() => eventCount >= 2); + await (0, (_waits_for || _load_waits_for()).default)(() => eventCount >= 2); cache.onDirectoriesChanged(new Set()); - await waitsFor(() => eventCount >= 3); + await (0, (_waits_for || _load_waits_for()).default)(() => eventCount >= 3); // completes the observables. cache.dispose(); // observer.dispose(); - expect(await events).toEqual([[], ['/some/path'], []]); + expect((await events)).toEqual([[], ['/some/path'], []]); }); it('multiple root projects', async () => { findNearestFile = path => Promise.resolve(path); cache.onDirectoriesChanged(new Set(['/some/path', '/some/path2'])); - await waitsFor(() => eventCount >= 2); + await (0, (_waits_for || _load_waits_for()).default)(() => eventCount >= 2); cache.onDirectoriesChanged(new Set(['/some/path2'])); - await waitsFor(() => eventCount >= 3); + await (0, (_waits_for || _load_waits_for()).default)(() => eventCount >= 3); cache.onDirectoriesChanged(new Set()); - await waitsFor(() => eventCount >= 4); + await (0, (_waits_for || _load_waits_for()).default)(() => eventCount >= 4); // completes the observables. cache.dispose(); // observer.dispose(); - expect(await events).toEqual([ - [], - ['/some/path', '/some/path2'], - ['/some/path2'], - [], - ]); + expect((await events)).toEqual([[], ['/some/path', '/some/path2'], ['/some/path2'], []]); }); it('opening a file in a root project', async () => { findNearestFile = path => Promise.resolve('/some/path'); cache.onDirectoriesChanged(new Set(['/some/path'])); - await waitsFor(() => eventCount >= 2); + await (0, (_waits_for || _load_waits_for()).default)(() => eventCount >= 2); cache.onFileEvent(createOpen('/some/path/file1.php')); cache.onFileEvent(createClose('/some/path/file1.php')); cache.onDirectoriesChanged(new Set()); - await waitsFor(() => eventCount >= 3); + await (0, (_waits_for || _load_waits_for()).default)(() => eventCount >= 3); // completes the observables. cache.dispose(); // observer.dispose(); - expect(await events).toEqual([[], ['/some/path'], []]); + expect((await events)).toEqual([[], ['/some/path'], []]); }); it('opening a file without a project', async () => { findNearestFile = path => Promise.resolve('/some/path'); cache.onFileEvent(createOpen('/some/path/file1.php')); - await waitsFor(() => eventCount >= 2); + await (0, (_waits_for || _load_waits_for()).default)(() => eventCount >= 2); cache.onFileEvent(createClose('/some/path/file1.php')); - await waitsFor(() => eventCount >= 3); + await (0, (_waits_for || _load_waits_for()).default)(() => eventCount >= 3); // completes the observables. cache.dispose(); // observer.dispose(); - expect(await events).toEqual([[], ['/some/path'], []]); + expect((await events)).toEqual([[], ['/some/path'], []]); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-open-files-rpc/__tests__/FileCache-test.js b/pkg/nuclide-open-files-rpc/__tests__/FileCache-test.js index c0be3e8ca7..5809f2fbf5 100644 --- a/pkg/nuclide-open-files-rpc/__tests__/FileCache-test.js +++ b/pkg/nuclide-open-files-rpc/__tests__/FileCache-test.js @@ -1,32 +1,39 @@ -/** - * 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 - */ +'use strict'; -import {Subject} from 'rxjs'; -import {FileCache} from '../lib/FileCache'; -import {Point as ServerPoint, Range as ServerRange} from 'simple-text-buffer'; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); -function fileInfoToObject(fileInfo: { - buffer: simpleTextBuffer$TextBuffer, - languageId: string, -}): Object { +var _FileCache; + +function _load_FileCache() { + return _FileCache = require('../lib/FileCache'); +} + +var _simpleTextBuffer; + +function _load_simpleTextBuffer() { + return _simpleTextBuffer = require('simple-text-buffer'); +} + +function fileInfoToObject(fileInfo) { return { buffer: { text: fileInfo.buffer.getText(), - changeCount: fileInfo.buffer.changeCount, + changeCount: fileInfo.buffer.changeCount }, - languageId: fileInfo.languageId, + languageId: fileInfo.languageId }; -} +} /** + * 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. + * + * + * @format + */ -function cacheToObject(cache: FileCache): Object { +function cacheToObject(cache) { const result = {}; cache._buffers.forEach((fileInfo, filePath) => { result[filePath] = fileInfoToObject(fileInfo); @@ -35,18 +42,13 @@ function cacheToObject(cache: FileCache): Object { } describe('FileCache', () => { - let cache: FileCache = (null: any); + let cache = null; // Initialize with a placeholder - let finishEvents: () => Promise> = async () => []; - let finishDirEvents: () => Promise>> = async () => []; + let finishEvents = async () => []; + let finishDirEvents = async () => []; - async function getFileContentsByVersion( - filePath, - changeCount, - ): Promise { - const buffer = await cache.getBufferAtVersion( - cache.createFileVersion(filePath, changeCount), - ); + async function getFileContentsByVersion(filePath, changeCount) { + const buffer = await cache.getBufferAtVersion(cache.createFileVersion(filePath, changeCount)); if (buffer == null) { return null; } @@ -54,34 +56,23 @@ describe('FileCache', () => { } beforeEach(() => { - cache = new FileCache(); + cache = new (_FileCache || _load_FileCache()).FileCache(); - const done = new Subject(); - const events = cache - .observeFileEvents() - .takeUntil(done) - .map(event => { - const result = { - ...event, - filePath: event.fileVersion.filePath, - changeCount: event.fileVersion.version, - }; - delete result.fileVersion; - return result; - }) - .toArray() - .toPromise(); + const done = new _rxjsBundlesRxMinJs.Subject(); + const events = cache.observeFileEvents().takeUntil(done).map(event => { + const result = Object.assign({}, event, { + filePath: event.fileVersion.filePath, + changeCount: event.fileVersion.version + }); + delete result.fileVersion; + return result; + }).toArray().toPromise(); finishEvents = () => { done.next(); done.complete(); return events; }; - const dirEvents = cache - .observeDirectoryEvents() - .takeUntil(done) - .map(dirs => Array.from(dirs)) - .toArray() - .toPromise(); + const dirEvents = cache.observeDirectoryEvents().takeUntil(done).map(dirs => Array.from(dirs)).toArray().toPromise(); finishDirEvents = () => { done.next(); done.complete(); @@ -96,29 +87,27 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 3, + version: 3 }, contents: 'contents1', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); expect(cacheToObject(cache)).toEqual({ f1: { buffer: { text: 'contents1', - changeCount: 3, + changeCount: 3 }, - languageId: 'Babel ES6 JavaScript', - }, + languageId: 'Babel ES6 JavaScript' + } }); - expect(await finishEvents()).toEqual([ - { - kind: 'open', - filePath: 'f1', - changeCount: 3, - contents: 'contents1', - languageId: 'Babel ES6 JavaScript', - }, - ]); + expect((await finishEvents())).toEqual([{ + kind: 'open', + filePath: 'f1', + changeCount: 3, + contents: 'contents1', + languageId: 'Babel ES6 JavaScript' + }]); })(); }); it('open/close', async () => { @@ -128,34 +117,31 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 3, + version: 3 }, contents: 'contents1', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); cache.onFileEvent({ kind: 'close', fileVersion: { notifier: cache, filePath: 'f1', - version: 3, - }, + version: 3 + } }); expect(cacheToObject(cache)).toEqual({}); - expect(await finishEvents()).toEqual([ - { - kind: 'open', - filePath: 'f1', - changeCount: 3, - contents: 'contents1', - languageId: 'Babel ES6 JavaScript', - }, - { - kind: 'close', - filePath: 'f1', - changeCount: 3, - }, - ]); + expect((await finishEvents())).toEqual([{ + kind: 'open', + filePath: 'f1', + changeCount: 3, + contents: 'contents1', + languageId: 'Babel ES6 JavaScript' + }, { + kind: 'close', + filePath: 'f1', + changeCount: 3 + }]); })(); }); it('edit', async () => { @@ -164,24 +150,24 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 3, + version: 3 }, contents: 'contents1', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); cache.onFileEvent({ kind: 'edit', fileVersion: { notifier: cache, filePath: 'f1', - version: 4, + version: 4 }, - oldRange: new ServerRange(new ServerPoint(0, 3), new ServerPoint(0, 6)), + oldRange: new (_simpleTextBuffer || _load_simpleTextBuffer()).Range(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 3), new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 6)), oldText: 'ten', - newRange: new ServerRange(new ServerPoint(0, 3), new ServerPoint(0, 9)), - newText: 'eleven', + newRange: new (_simpleTextBuffer || _load_simpleTextBuffer()).Range(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 3), new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 9)), + newText: 'eleven' }); - expect(await finishEvents()).toMatchSnapshot(); + expect((await finishEvents())).toMatchSnapshot(); }); it('sync closed file', async () => { cache.onFileEvent({ @@ -189,29 +175,27 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f2', - version: 4, + version: 4 }, contents: 'contents12', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); expect(cacheToObject(cache)).toEqual({ f2: { buffer: { text: 'contents12', - changeCount: 4, + changeCount: 4 }, - languageId: 'Babel ES6 JavaScript', - }, + languageId: 'Babel ES6 JavaScript' + } }); - expect(await finishEvents()).toEqual([ - { - kind: 'open', - filePath: 'f2', - changeCount: 4, - contents: 'contents12', - languageId: 'Babel ES6 JavaScript', - }, - ]); + expect((await finishEvents())).toEqual([{ + kind: 'open', + filePath: 'f2', + changeCount: 4, + contents: 'contents12', + languageId: 'Babel ES6 JavaScript' + }]); }); it('sync opened file', async () => { cache.onFileEvent({ @@ -219,56 +203,51 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f2', - version: 4, + version: 4 }, contents: 'blip', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); cache.onFileEvent({ kind: 'sync', fileVersion: { notifier: cache, filePath: 'f2', - version: 42, + version: 42 }, contents: 'contents12', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); expect(cacheToObject(cache)).toEqual({ f2: { buffer: { text: 'contents12', - changeCount: 42, + changeCount: 42 }, - languageId: 'Babel ES6 JavaScript', - }, + languageId: 'Babel ES6 JavaScript' + } }); - expect(JSON.stringify(await finishEvents())).toEqual( - JSON.stringify([ - { - kind: 'open', - contents: 'blip', - languageId: 'Babel ES6 JavaScript', - filePath: 'f2', - changeCount: 4, - }, - { - kind: 'edit', - oldRange: { - start: {row: 0, column: 0}, - end: {row: 0, column: 4}, - }, - oldText: 'blip', - newRange: { - start: {row: 0, column: 0}, - end: {row: 0, column: 10}, - }, - newText: 'contents12', - filePath: 'f2', - changeCount: 42, - }, - ]), - ); + expect(JSON.stringify((await finishEvents()))).toEqual(JSON.stringify([{ + kind: 'open', + contents: 'blip', + languageId: 'Babel ES6 JavaScript', + filePath: 'f2', + changeCount: 4 + }, { + kind: 'edit', + oldRange: { + start: { row: 0, column: 0 }, + end: { row: 0, column: 4 } + }, + oldText: 'blip', + newRange: { + start: { row: 0, column: 0 }, + end: { row: 0, column: 10 } + }, + newText: 'contents12', + filePath: 'f2', + changeCount: 42 + }])); }); it('out of date sync', async () => { cache.onFileEvent({ @@ -276,31 +255,31 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f2', - version: 42, + version: 42 }, contents: 'blip', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); cache.onFileEvent({ kind: 'sync', fileVersion: { notifier: cache, filePath: 'f2', - version: 4, + version: 4 }, contents: 'contents12', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); expect(cacheToObject(cache)).toEqual({ f2: { buffer: { text: 'blip', - changeCount: 42, + changeCount: 42 }, - languageId: 'Babel ES6 JavaScript', - }, + languageId: 'Babel ES6 JavaScript' + } }); - expect(JSON.stringify(await finishEvents())).toMatchSnapshot(); + expect(JSON.stringify((await finishEvents()))).toMatchSnapshot(); }); // Unexpected Operations Should Throw @@ -311,10 +290,10 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 3, + version: 3 }, contents: 'contents1', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); expect(() => { cache.onFileEvent({ @@ -322,21 +301,19 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 3, + version: 3 }, contents: 'contents1', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); }).toThrow(); - expect(await finishEvents()).toEqual([ - { - kind: 'open', - filePath: 'f1', - changeCount: 3, - contents: 'contents1', - languageId: 'Babel ES6 JavaScript', - }, - ]); + expect((await finishEvents())).toEqual([{ + kind: 'open', + filePath: 'f1', + changeCount: 3, + contents: 'contents1', + languageId: 'Babel ES6 JavaScript' + }]); })(); }); it('close non-existing file', async () => { @@ -346,11 +323,11 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 3, - }, + version: 3 + } }); }).not.toThrow(); - expect(await finishEvents()).toEqual([]); + expect((await finishEvents())).toEqual([]); }); it('edit closed file', async () => { expect(() => { @@ -359,15 +336,15 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 4, + version: 4 }, - oldRange: new ServerRange(new ServerPoint(0, 3), new ServerPoint(0, 6)), + oldRange: new (_simpleTextBuffer || _load_simpleTextBuffer()).Range(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 3), new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 6)), oldText: 'ten', - newRange: new ServerRange(new ServerPoint(0, 3), new ServerPoint(0, 9)), - newText: 'eleven', + newRange: new (_simpleTextBuffer || _load_simpleTextBuffer()).Range(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 3), new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 9)), + newText: 'eleven' }); }).toThrow(); - expect(await finishEvents()).toEqual([]); + expect((await finishEvents())).toEqual([]); }); it('edit with non-sequential version', async () => { cache.onFileEvent({ @@ -375,14 +352,14 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 3, + version: 3 }, oldRange: { - start: {row: 0, column: 3}, - end: {row: 0, column: 6}, + start: { row: 0, column: 3 }, + end: { row: 0, column: 6 } }, contents: 'contents1', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); expect(() => { cache.onFileEvent({ @@ -390,23 +367,21 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 5, + version: 5 }, - oldRange: new ServerRange(new ServerPoint(0, 3), new ServerPoint(0, 6)), + oldRange: new (_simpleTextBuffer || _load_simpleTextBuffer()).Range(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 3), new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 6)), oldText: 'ten', - newRange: new ServerRange(new ServerPoint(0, 3), new ServerPoint(0, 9)), - newText: 'eleven', + newRange: new (_simpleTextBuffer || _load_simpleTextBuffer()).Range(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 3), new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 9)), + newText: 'eleven' }); }).toThrow(); - expect(await finishEvents()).toEqual([ - { - kind: 'open', - languageId: 'Babel ES6 JavaScript', - filePath: 'f1', - changeCount: 3, - contents: 'contents1', - }, - ]); + expect((await finishEvents())).toEqual([{ + kind: 'open', + languageId: 'Babel ES6 JavaScript', + filePath: 'f1', + changeCount: 3, + contents: 'contents1' + }]); }); it('edit with incorrect oldText', async () => { await (async () => { @@ -415,10 +390,10 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 3, + version: 3 }, contents: 'contents1', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); expect(() => { cache.onFileEvent({ @@ -426,29 +401,21 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 4, + version: 4 }, - oldRange: new ServerRange( - new ServerPoint(0, 3), - new ServerPoint(0, 6), - ), + oldRange: new (_simpleTextBuffer || _load_simpleTextBuffer()).Range(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 3), new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 6)), oldText: 'one', - newRange: new ServerRange( - new ServerPoint(0, 3), - new ServerPoint(0, 9), - ), - newText: 'eleven', + newRange: new (_simpleTextBuffer || _load_simpleTextBuffer()).Range(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 3), new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 9)), + newText: 'eleven' }); }).toThrow(); - expect(await finishEvents()).toEqual([ - { - kind: 'open', - filePath: 'f1', - changeCount: 3, - contents: 'contents1', - languageId: 'Babel ES6 JavaScript', - }, - ]); + expect((await finishEvents())).toEqual([{ + kind: 'open', + filePath: 'f1', + changeCount: 3, + contents: 'contents1', + languageId: 'Babel ES6 JavaScript' + }]); })(); }); @@ -460,10 +427,10 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 3, + version: 3 }, contents: 'contents1', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); const result = await getFileContentsByVersion('f1', 3); expect(result).toBe('contents1'); @@ -476,10 +443,10 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 3, + version: 3 }, contents: 'contents1', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); const value = await getFileContentsByVersion('f1', 2); expect(value).toBe(null); @@ -492,10 +459,10 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 3, + version: 3 }, contents: 'contents1', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); const result = getFileContentsByVersion('f1', 4); cache.onFileEvent({ @@ -503,12 +470,12 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 4, + version: 4 }, - oldRange: new ServerRange(new ServerPoint(0, 3), new ServerPoint(0, 6)), + oldRange: new (_simpleTextBuffer || _load_simpleTextBuffer()).Range(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 3), new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 6)), oldText: 'ten', - newRange: new ServerRange(new ServerPoint(0, 3), new ServerPoint(0, 9)), - newText: 'eleven', + newRange: new (_simpleTextBuffer || _load_simpleTextBuffer()).Range(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 3), new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(0, 9)), + newText: 'eleven' }); const value = await result; expect(value).toBe('conelevents1'); @@ -522,10 +489,10 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 3, + version: 3 }, contents: 'contents1', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); const value = await result; expect(value).toBe('contents1'); @@ -539,12 +506,12 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 3, + version: 3 }, contents: 'contents1', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); - expect(await result).toBe(null); + expect((await result)).toBe(null); })(); }); it('getBufferAtVersion on sync open', async () => { @@ -555,10 +522,10 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 3, + version: 3 }, contents: 'contents1', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); const value = await result; expect(value).toBe('contents1'); @@ -572,20 +539,20 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 3, + version: 3 }, contents: 'contents1', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); cache.onFileEvent({ kind: 'sync', fileVersion: { notifier: cache, filePath: 'f1', - version: 6, + version: 6 }, contents: 'contents6', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); const value = await result; expect(value).toBe('contents6'); @@ -599,19 +566,19 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 3, + version: 3 }, contents: 'contents1', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); - expect(await result1).toBe('contents1'); + expect((await result1)).toBe('contents1'); cache.onFileEvent({ kind: 'close', fileVersion: { notifier: cache, filePath: 'f1', - version: 4, - }, + version: 4 + } }); const result2 = getFileContentsByVersion('f1', 4); @@ -620,28 +587,28 @@ describe('FileCache', () => { fileVersion: { notifier: cache, filePath: 'f1', - version: 4, + version: 4 }, contents: 'contents-reopened', - languageId: 'Babel ES6 JavaScript', + languageId: 'Babel ES6 JavaScript' }); - expect(await result2).toBe('contents-reopened'); + expect((await result2)).toBe('contents-reopened'); })(); }); it('Initial dirs', async () => { await (async () => { - expect(await finishDirEvents()).toEqual([[]]); + expect((await finishDirEvents())).toEqual([[]]); })(); }); it('Single dir', async () => { await (async () => { cache.onDirectoriesChanged(new Set(['abc'])); - expect(await finishDirEvents()).toEqual([[], ['abc']]); + expect((await finishDirEvents())).toEqual([[], ['abc']]); })(); }); afterEach(() => { cache.dispose(); - cache = (null: any); + cache = null; }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-open-files-rpc/lib/ConfigObserver.js b/pkg/nuclide-open-files-rpc/lib/ConfigObserver.js index 1f01253206..5b4eb59e93 100644 --- a/pkg/nuclide-open-files-rpc/lib/ConfigObserver.js +++ b/pkg/nuclide-open-files-rpc/lib/ConfigObserver.js @@ -1,3 +1,38 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ConfigObserver = undefined; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _constants; + +function _load_constants() { + return _constants = require('./constants'); +} + +var _FileCache; + +function _load_FileCache() { + return _FileCache = require('./FileCache'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,75 +40,43 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import {BehaviorSubject, Observable} from 'rxjs'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {areSetsEqual} from 'nuclide-commons/collection'; -import {FileEventKind} from './constants'; -import {FileCache} from './FileCache'; - -export class ConfigObserver { - _fileExtensions: Array; - _fileCache: FileCache; - _currentConfigs: BehaviorSubject>; - _subscription: rxjs$ISubscription; - _findConfigDir: (path: NuclideUri) => Promise; - - constructor( - cache: FileCache, - fileExtensions: Array, - findConfigDir: (path: NuclideUri) => Promise, - ) { +class ConfigObserver { + + constructor(cache, fileExtensions, findConfigDir) { this._fileCache = cache; this._fileExtensions = fileExtensions; this._findConfigDir = findConfigDir; - this._currentConfigs = new BehaviorSubject(new Set()); + this._currentConfigs = new _rxjsBundlesRxMinJs.BehaviorSubject(new Set()); // TODO: Consider incrementally updating, rather than recomputing on each event. - this._subscription = cache - .observeFileEvents() - .filter(fileEvent => fileEvent.kind !== FileEventKind.EDIT) - .mapTo(undefined) - .merge(cache.observeDirectoryEvents().mapTo(undefined)) - .switchMap(() => Observable.fromPromise(this._computeOpenConfigs())) - .distinctUntilChanged(areSetsEqual) - // Filter out initial empty set, which duplicates the initial value of the BehaviorSubject - .skipWhile(dirs => dirs.size === 0) - .subscribe(this._currentConfigs); + this._subscription = cache.observeFileEvents().filter(fileEvent => fileEvent.kind !== (_constants || _load_constants()).FileEventKind.EDIT).mapTo(undefined).merge(cache.observeDirectoryEvents().mapTo(undefined)).switchMap(() => _rxjsBundlesRxMinJs.Observable.fromPromise(this._computeOpenConfigs())).distinctUntilChanged((_collection || _load_collection()).areSetsEqual) + // Filter out initial empty set, which duplicates the initial value of the BehaviorSubject + .skipWhile(dirs => dirs.size === 0).subscribe(this._currentConfigs); } - async _computeOpenConfigs(): Promise> { - const paths = Array.from(this._fileCache.getOpenDirectories()).concat( - Array.from(this._fileCache.getOpenFiles()).filter( - filePath => - this._fileExtensions.indexOf(nuclideUri.extname(filePath)) !== -1, - ), - ); - - const result = new Set( - (await Promise.all(paths.map(path => this._findConfigDir(path)))).filter( - path => path != null, - ), - ); + async _computeOpenConfigs() { + const paths = Array.from(this._fileCache.getOpenDirectories()).concat(Array.from(this._fileCache.getOpenFiles()).filter(filePath => this._fileExtensions.indexOf((_nuclideUri || _load_nuclideUri()).default.extname(filePath)) !== -1)); + + const result = new Set((await Promise.all(paths.map(path => this._findConfigDir(path)))).filter(path => path != null)); // $FlowIssue Flow doesn't understand filter - return (result: Set); + return result; } - observeConfigs(): Observable> { + observeConfigs() { return this._currentConfigs.asObservable(); } - getOpenConfigs(): Set { + getOpenConfigs() { return this._currentConfigs.getValue(); } - dispose(): void { + dispose() { this._subscription.unsubscribe(); this._currentConfigs.complete(); this._currentConfigs.unsubscribe(); } } +exports.ConfigObserver = ConfigObserver; \ No newline at end of file diff --git a/pkg/nuclide-open-files-rpc/lib/FileCache.js b/pkg/nuclide-open-files-rpc/lib/FileCache.js index 81015dbce7..e11c7dae4f 100644 --- a/pkg/nuclide-open-files-rpc/lib/FileCache.js +++ b/pkg/nuclide-open-files-rpc/lib/FileCache.js @@ -1,3 +1,48 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.FileCache = undefined; + +var _simpleTextBuffer; + +function _load_simpleTextBuffer() { + return _simpleTextBuffer = _interopRequireDefault(require('simple-text-buffer')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _FileVersionNotifier; + +function _load_FileVersionNotifier() { + return _FileVersionNotifier = require('./FileVersionNotifier'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _constants; + +function _load_constants() { + return _constants = require('./constants'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * NB: although it is possible to change the language ID after the file has + * already been opened, the file cache will not update to reflect that. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,101 +50,86 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - FileOpenEvent, - FileCloseEvent, - FileEditEvent, - FileSaveEvent, - FileEvent, - FileVersion, - LocalFileEvent, -} from './rpc-types'; - -import TextBuffer from 'simple-text-buffer'; -import invariant from 'assert'; -import {BehaviorSubject, Subject, Observable} from 'rxjs'; -import {FileVersionNotifier} from './FileVersionNotifier'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - -import {FileEventKind} from './constants'; - -/** - * NB: although it is possible to change the language ID after the file has - * already been opened, the file cache will not update to reflect that. - */ -export class FileCache { - _buffers: Map< - NuclideUri, - {buffer: simpleTextBuffer$TextBuffer, languageId: string}, - >; - - _requests: FileVersionNotifier; - _fileEvents: Subject; +class FileCache { // Care! update() is the only way you're allowed to update _buffers or _requests // or to fire a _fileEvents.next() event. That's to ensure that the three things // stay in sync. - _directoryEvents: BehaviorSubject>; - _resources: UniversalDisposable; - constructor() { this._buffers = new Map(); - this._fileEvents = new Subject(); - this._directoryEvents = new BehaviorSubject(new Set()); - this._requests = new FileVersionNotifier(); + this._fileEvents = new _rxjsBundlesRxMinJs.Subject(); + this._directoryEvents = new _rxjsBundlesRxMinJs.BehaviorSubject(new Set()); + this._requests = new (_FileVersionNotifier || _load_FileVersionNotifier()).FileVersionNotifier(); - this._resources = new UniversalDisposable(); + this._resources = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._resources.add(this._requests); } - update(updateBufferAndMakeEventFunc: () => LocalFileEvent) { + update(updateBufferAndMakeEventFunc) { const event = updateBufferAndMakeEventFunc(); this._requests.onEvent(event); // invariant: because the above two lines have updated both _buffers and _requests, // then getBufferAtVersion will necessarily return immediately and successfully. // And getBufferForFileEvent will also succeed. - invariant(event.kind !== 'edit' || this.getBufferForFileEvent(event)); + + if (!(event.kind !== 'edit' || this.getBufferForFileEvent(event))) { + throw new Error('Invariant violation: "event.kind !== \'edit\' || this.getBufferForFileEvent(event)"'); + } this._fileEvents.next(event); } // If any out of sync state is detected then an Error is thrown. // This will force the client to send a 'sync' event to get back on track. - onFileEvent(event: FileEvent): Promise { + onFileEvent(event) { const filePath = event.fileVersion.filePath; const changeCount = event.fileVersion.version; const fileInfo = this._buffers.get(filePath); const buffer = fileInfo != null ? fileInfo.buffer : null; switch (event.kind) { - case FileEventKind.OPEN: - invariant(buffer == null); + case (_constants || _load_constants()).FileEventKind.OPEN: + if (!(buffer == null)) { + throw new Error('Invariant violation: "buffer == null"'); + } + this._open(filePath, event.contents, changeCount, event.languageId); break; - case FileEventKind.CLOSE: + case (_constants || _load_constants()).FileEventKind.CLOSE: if (buffer != null) { this._close(filePath, buffer); } break; - case FileEventKind.EDIT: - invariant(buffer != null); - invariant(buffer.changeCount === changeCount - 1); - invariant(buffer.getTextInRange(event.oldRange) === event.oldText); + case (_constants || _load_constants()).FileEventKind.EDIT: + if (!(buffer != null)) { + throw new Error('Invariant violation: "buffer != null"'); + } + + if (!(buffer.changeCount === changeCount - 1)) { + throw new Error('Invariant violation: "buffer.changeCount === changeCount - 1"'); + } + + if (!(buffer.getTextInRange(event.oldRange) === event.oldText)) { + throw new Error('Invariant violation: "buffer.getTextInRange(event.oldRange) === event.oldText"'); + } + this.update(() => { buffer.setTextInRange(event.oldRange, event.newText); - invariant(buffer.changeCount === changeCount); + + if (!(buffer.changeCount === changeCount)) { + throw new Error('Invariant violation: "buffer.changeCount === changeCount"'); + } + return event; }); break; - case FileEventKind.SAVE: + case (_constants || _load_constants()).FileEventKind.SAVE: this._save(filePath, changeCount); break; - case FileEventKind.SYNC: + case (_constants || _load_constants()).FileEventKind.SYNC: if (buffer == null) { this._open(filePath, event.contents, changeCount, event.languageId); } else { @@ -107,22 +137,17 @@ export class FileCache { } break; default: - (event.kind: empty); + event.kind; throw new Error(`Unexpected FileEvent.kind: ${event.kind}`); } return Promise.resolve(undefined); } - async onDirectoriesChanged(openDirectories: Set): Promise { + async onDirectoriesChanged(openDirectories) { this._directoryEvents.next(openDirectories); } - _syncEdit( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - contents: string, - changeCount: number, - ): void { + _syncEdit(filePath, buffer, contents, changeCount) { // messages are out of order if (changeCount < buffer.changeCount) { return; @@ -134,66 +159,52 @@ export class FileCache { buffer.setText(contents); const newRange = buffer.getRange(); buffer.changeCount = changeCount; - return createEditEvent( - this.createFileVersion(filePath, changeCount), - oldRange, - oldText, - newRange, - buffer.getText(), - ); + return createEditEvent(this.createFileVersion(filePath, changeCount), oldRange, oldText, newRange, buffer.getText()); }); } - _open( - filePath: NuclideUri, - contents: string, - changeCount: number, - languageId: string, - ): void { + _open(filePath, contents, changeCount, languageId) { // We never call setPath on these TextBuffers as that will // start the TextBuffer attempting to sync with the file system. - const newBuffer = new TextBuffer(contents); + const newBuffer = new (_simpleTextBuffer || _load_simpleTextBuffer()).default(contents); newBuffer.changeCount = changeCount; this.update(() => { - this._buffers.set(filePath, {buffer: newBuffer, languageId}); - return createOpenEvent( - this.createFileVersion(filePath, changeCount), - contents, - languageId, - ); + this._buffers.set(filePath, { buffer: newBuffer, languageId }); + return createOpenEvent(this.createFileVersion(filePath, changeCount), contents, languageId); }); } - _close(filePath: NuclideUri, buffer: simpleTextBuffer$TextBuffer): void { + _close(filePath, buffer) { this.update(() => { this._buffers.delete(filePath); - return createCloseEvent( - this.createFileVersion(filePath, buffer.changeCount), - ); + return createCloseEvent(this.createFileVersion(filePath, buffer.changeCount)); }); buffer.destroy(); } - _save(filePath: NuclideUri, changeCount: number): void { + _save(filePath, changeCount) { this.update(() => { return createSaveEvent(this.createFileVersion(filePath, changeCount)); }); } - dispose(): void { + dispose() { // The _close routine will delete elements from the _buffers map. - // Per ES6 this is safe to do even while iterating. - for (const [filePath, {buffer}] of this._buffers.entries()) { + for (const [filePath, { buffer }] of this._buffers.entries()) { this._close(filePath, buffer); } - invariant(this._buffers.size === 0); + + if (!(this._buffers.size === 0)) { + throw new Error('Invariant violation: "this._buffers.size === 0"'); + } + this._resources.dispose(); this._fileEvents.complete(); this._directoryEvents.complete(); } // getBuffer: returns whatever is the current version of the buffer. - getBuffer(filePath: NuclideUri): ?simpleTextBuffer$TextBuffer { + getBuffer(filePath) { // TODO: change this to return a string, to ensure that no caller will ever mutate // the buffer contents (and hence its changeCount). The only modifications allowed // are those that come from the editor inside this.onFileEvent. @@ -206,33 +217,37 @@ export class FileCache { // But if for whatever reason the stream of onFileEvent won't hit that precise version // then returns null. See comments in _requests.waitForBufferAtVersion for // the subtle scenarios where it might return null. - async getBufferAtVersion( - fileVersion: FileVersion, - ): Promise { + async getBufferAtVersion(fileVersion) { // TODO: change this to return a string, like getBuffer() above. if (!(await this._requests.waitForBufferAtVersion(fileVersion))) { return null; } const buffer = this.getBuffer(fileVersion.filePath); - return buffer != null && buffer.changeCount === fileVersion.version - ? buffer - : null; + return buffer != null && buffer.changeCount === fileVersion.version ? buffer : null; } // getBufferForFileEvent - this function may be called immediately when an edit or save // event happens, before any awaits. At that time the buffer is guaranteed to be // available. If called at any other time, the buffer may no longer be available, // in which case it may throw. - getBufferForFileEvent(fileEvent: FileEvent): simpleTextBuffer$TextBuffer { + getBufferForFileEvent(fileEvent) { // TODO: change this to return a string, like getBuffer() above. const fileVersion = fileEvent.fileVersion; - invariant(this._requests.isBufferAtVersion(fileVersion)); + + if (!this._requests.isBufferAtVersion(fileVersion)) { + throw new Error('Invariant violation: "this._requests.isBufferAtVersion(fileVersion)"'); + } + const buffer = this.getBuffer(fileVersion.filePath); - invariant(buffer != null && buffer.changeCount === fileVersion.version); + + if (!(buffer != null && buffer.changeCount === fileVersion.version)) { + throw new Error('Invariant violation: "buffer != null && buffer.changeCount === fileVersion.version"'); + } + return buffer; } - getOpenDirectories(): Set { + getOpenDirectories() { return this._directoryEvents.getValue(); } @@ -240,88 +255,77 @@ export class FileCache { // Remote equivalent of atom.project.relativizePath()[1] // TODO: Return the most nested open directory. // Note that Atom doesn't do this, though it should. - getContainingDirectory(filePath: NuclideUri): ?NuclideUri { + getContainingDirectory(filePath) { for (const dir of this.getOpenDirectories()) { - if (nuclideUri.contains(dir, filePath)) { + if ((_nuclideUri || _load_nuclideUri()).default.contains(dir, filePath)) { return dir; } } return null; } - getOpenFiles(): Iterator { + getOpenFiles() { return this._buffers.keys(); } - observeFileEvents(): Observable { - return Observable.from( - Array.from(this._buffers.entries()).map( - ([filePath, {buffer, languageId}]) => { - invariant(buffer != null); - invariant(languageId != null); - return createOpenEvent( - this.createFileVersion(filePath, buffer.changeCount), - buffer.getText(), - languageId, - ); - }, - ), - ).concat(this._fileEvents); + observeFileEvents() { + return _rxjsBundlesRxMinJs.Observable.from(Array.from(this._buffers.entries()).map(([filePath, { buffer, languageId }]) => { + if (!(buffer != null)) { + throw new Error('Invariant violation: "buffer != null"'); + } + + if (!(languageId != null)) { + throw new Error('Invariant violation: "languageId != null"'); + } + + return createOpenEvent(this.createFileVersion(filePath, buffer.changeCount), buffer.getText(), languageId); + })).concat(this._fileEvents); } - observeDirectoryEvents(): Observable> { + observeDirectoryEvents() { return this._directoryEvents; } - createFileVersion(filePath: NuclideUri, version: number): FileVersion { + createFileVersion(filePath, version) { return { notifier: this, filePath, - version, + version }; } } -function createOpenEvent( - fileVersion: FileVersion, - contents: string, - languageId: string, -): FileOpenEvent { +exports.FileCache = FileCache; +function createOpenEvent(fileVersion, contents, languageId) { return { - kind: FileEventKind.OPEN, + kind: (_constants || _load_constants()).FileEventKind.OPEN, fileVersion, contents, - languageId, + languageId }; } -function createCloseEvent(fileVersion: FileVersion): FileCloseEvent { +function createCloseEvent(fileVersion) { return { - kind: FileEventKind.CLOSE, - fileVersion, + kind: (_constants || _load_constants()).FileEventKind.CLOSE, + fileVersion }; } -function createSaveEvent(fileVersion: FileVersion): FileSaveEvent { +function createSaveEvent(fileVersion) { return { - kind: FileEventKind.SAVE, - fileVersion, + kind: (_constants || _load_constants()).FileEventKind.SAVE, + fileVersion }; } -function createEditEvent( - fileVersion: FileVersion, - oldRange: atom$Range, - oldText: string, - newRange: atom$Range, - newText: string, -): FileEditEvent { +function createEditEvent(fileVersion, oldRange, oldText, newRange, newText) { return { - kind: FileEventKind.EDIT, + kind: (_constants || _load_constants()).FileEventKind.EDIT, fileVersion, oldRange, oldText, newRange, - newText, + newText }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-open-files-rpc/lib/FileVersionNotifier.js b/pkg/nuclide-open-files-rpc/lib/FileVersionNotifier.js index 81a80b9b7c..d75eb025f3 100644 --- a/pkg/nuclide-open-files-rpc/lib/FileVersionNotifier.js +++ b/pkg/nuclide-open-files-rpc/lib/FileVersionNotifier.js @@ -1,65 +1,70 @@ -/** - * 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 - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {LocalFileEvent, FileVersion} from './rpc-types'; - -import {FileEventKind} from './constants'; -import {Deferred} from 'nuclide-commons/promise'; -import {MultiMap} from 'nuclide-commons/collection'; - -export class FileVersionNotifier { - _versions: Map; - _requests: MultiMap; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.FileVersionNotifier = undefined; + +var _constants; + +function _load_constants() { + return _constants = require('./constants'); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +class FileVersionNotifier { constructor() { this._versions = new Map(); - this._requests = new MultiMap(); + this._requests = new (_collection || _load_collection()).MultiMap(); } // If any out of sync state is detected then an Error is thrown. // This will force the client to send a 'sync' event to get back on track. - onEvent(event: LocalFileEvent): void { + onEvent(event) { const filePath = event.fileVersion.filePath; const changeCount = event.fileVersion.version; switch (event.kind) { - case FileEventKind.OPEN: + case (_constants || _load_constants()).FileEventKind.OPEN: this._versions.set(filePath, changeCount); break; - case FileEventKind.CLOSE: + case (_constants || _load_constants()).FileEventKind.CLOSE: this._versions.delete(filePath); break; - case FileEventKind.EDIT: + case (_constants || _load_constants()).FileEventKind.EDIT: this._versions.set(filePath, changeCount); break; - case FileEventKind.SAVE: + case (_constants || _load_constants()).FileEventKind.SAVE: break; default: - (event.kind: empty); + event.kind; throw new Error(`Unexpected LocalFileEvent.kind: ${event.kind}`); } this._checkRequests(filePath); } - dispose(): void { + dispose() { for (const request of this._requests.values()) { request.reject(createRejectError()); } } - getVersion(filePath: NuclideUri): ?number { + getVersion(filePath) { return this._versions.get(filePath); } - isBufferAtVersion(fileVersion: FileVersion): boolean { + isBufferAtVersion(fileVersion) { const filePath = fileVersion.filePath; const version = fileVersion.version; const currentVersion = this._versions.get(filePath); @@ -86,7 +91,7 @@ export class FileVersionNotifier { // (4) Network goes back up // (5) User types to version N+2 which invokes onEvent for N+2 // At step 5 we know we will never be able to deliver buffer at version N+1, so we return false. - waitForBufferAtVersion(fileVersion: FileVersion): Promise { + waitForBufferAtVersion(fileVersion) { const filePath = fileVersion.filePath; const version = fileVersion.version; const currentVersion = this._versions.get(filePath); @@ -100,22 +105,16 @@ export class FileVersionNotifier { return request.promise; } - _checkRequests(filePath: NuclideUri): void { + _checkRequests(filePath) { const currentVersion = this._versions.get(filePath); if (currentVersion == null) { return; } const requests = Array.from(this._requests.get(filePath)); - const resolves = requests.filter( - request => request.changeCount === currentVersion, - ); - const rejects = requests.filter( - request => request.changeCount < currentVersion, - ); - const remaining = requests.filter( - request => request.changeCount > currentVersion, - ); + const resolves = requests.filter(request => request.changeCount === currentVersion); + const rejects = requests.filter(request => request.changeCount < currentVersion); + const remaining = requests.filter(request => request.changeCount > currentVersion); this._requests.set(filePath, remaining); resolves.forEach(request => request.resolve(true)); @@ -123,18 +122,27 @@ export class FileVersionNotifier { } } -function createRejectError(): Error { +exports.FileVersionNotifier = FileVersionNotifier; /** + * 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. + * + * + * @format + */ + +function createRejectError() { return new Error('File modified past requested change'); } -class Request extends Deferred { - filePath: NuclideUri; - changeCount: number; +class Request extends (_promise || _load_promise()).Deferred { - constructor(filePath: NuclideUri, changeCount: number) { + constructor(filePath, changeCount) { super(); this.filePath = filePath; this.changeCount = changeCount; } -} +} \ No newline at end of file diff --git a/pkg/nuclide-open-files-rpc/lib/OpenFilesService.js b/pkg/nuclide-open-files-rpc/lib/OpenFilesService.js index f5566ae322..9e08e45820 100644 --- a/pkg/nuclide-open-files-rpc/lib/OpenFilesService.js +++ b/pkg/nuclide-open-files-rpc/lib/OpenFilesService.js @@ -1,3 +1,16 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.initialize = initialize; + +var _FileCache; + +function _load_FileCache() { + return _FileCache = require('./FileCache'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,14 +18,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {FileNotifier} from './rpc-types'; - -import {FileCache} from './FileCache'; - -export async function initialize(): Promise { - return new FileCache(); -} +async function initialize() { + return new (_FileCache || _load_FileCache()).FileCache(); +} \ No newline at end of file diff --git a/pkg/nuclide-open-files-rpc/lib/OpenFilesServiceProxy.js b/pkg/nuclide-open-files-rpc/lib/OpenFilesServiceProxy.js new file mode 100644 index 0000000000..095cf32c68 --- /dev/null +++ b/pkg/nuclide-open-files-rpc/lib/OpenFilesServiceProxy.js @@ -0,0 +1,595 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + remoteModule.FileNotifier = class { + constructor() { + throw Error("constructors are not supported for remote objects"); + } + + onFileEvent(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 62 + }, + name: "FileNotifier" + }), "onFileEvent", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "event", + type: { + kind: "named", + name: "FileEvent" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + } + + onDirectoriesChanged(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 62 + }, + name: "FileNotifier" + }), "onDirectoriesChanged", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "openDirectories", + type: { + kind: "set", + type: { + kind: "named", + name: "NuclideUri" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + } + + dispose() { + return _client.disposeRemoteObject(this); + } + + }; + + remoteModule.initialize = function () { + return _client.callRemoteFunction("OpenFilesService/initialize", "promise", _client.marshalArguments(Array.from(arguments), [])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "FileNotifier" + }); + }); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + FileVersion: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 68 + }, + name: "FileVersion", + definition: { + kind: "object", + fields: [{ + name: "notifier", + type: { + kind: "named", + name: "FileNotifier" + }, + optional: false + }, { + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "version", + type: { + kind: "number" + }, + optional: false + }] + } + }, + FileOpenEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 14 + }, + name: "FileOpenEvent", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "open" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "contents", + type: { + kind: "string" + }, + optional: false + }, { + name: "languageId", + type: { + kind: "string" + }, + optional: false + }] + } + }, + FileCloseEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 29 + }, + name: "FileCloseEvent", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "close" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }] + } + }, + FileEditEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 34 + }, + name: "FileEditEvent", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "edit" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "oldRange", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }, { + name: "newRange", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }, { + name: "oldText", + type: { + kind: "string" + }, + optional: false + }, { + name: "newText", + type: { + kind: "string" + }, + optional: false + }] + } + }, + FileSaveEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 43 + }, + name: "FileSaveEvent", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "save" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }] + } + }, + FileSyncEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 22 + }, + name: "FileSyncEvent", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "sync" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "contents", + type: { + kind: "string" + }, + optional: false + }, { + name: "languageId", + type: { + kind: "string" + }, + optional: false + }] + } + }, + FileEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 49 + }, + name: "FileEvent", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "open" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "contents", + type: { + kind: "string" + }, + optional: false + }, { + name: "languageId", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "close" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "edit" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "oldRange", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }, { + name: "newRange", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }, { + name: "oldText", + type: { + kind: "string" + }, + optional: false + }, { + name: "newText", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "save" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "sync" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "contents", + type: { + kind: "string" + }, + optional: false + }, { + name: "languageId", + type: { + kind: "string" + }, + optional: false + }] + }], + discriminantField: "kind" + } + }, + FileNotifier: { + kind: "interface", + name: "FileNotifier", + location: { + type: "source", + fileName: "rpc-types.js", + line: 62 + }, + staticMethods: {}, + instanceMethods: { + onFileEvent: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 63 + }, + kind: "function", + argumentTypes: [{ + name: "event", + type: { + kind: "named", + name: "FileEvent" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + }, + onDirectoriesChanged: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 64 + }, + kind: "function", + argumentTypes: [{ + name: "openDirectories", + type: { + kind: "set", + type: { + kind: "named", + name: "NuclideUri" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + }, + dispose: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 65 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "void" + } + } + } + }, + initialize: { + kind: "function", + name: "initialize", + location: { + type: "source", + fileName: "OpenFilesService.js", + line: 16 + }, + type: { + location: { + type: "source", + fileName: "OpenFilesService.js", + line: 16 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "FileNotifier" + } + } + } + } + } +}); \ No newline at end of file diff --git a/pkg/nuclide-open-files-rpc/lib/constants.js b/pkg/nuclide-open-files-rpc/lib/constants.js index 1906facc0a..5312bf1837 100644 --- a/pkg/nuclide-open-files-rpc/lib/constants.js +++ b/pkg/nuclide-open-files-rpc/lib/constants.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,14 +10,14 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -export const FileEventKind = Object.freeze({ +const FileEventKind = exports.FileEventKind = Object.freeze({ OPEN: 'open', SYNC: 'sync', CLOSE: 'close', EDIT: 'edit', - SAVE: 'save', -}); + SAVE: 'save' +}); \ No newline at end of file diff --git a/pkg/nuclide-open-files-rpc/lib/main.js b/pkg/nuclide-open-files-rpc/lib/main.js index dc7a346027..c2b4031164 100644 --- a/pkg/nuclide-open-files-rpc/lib/main.js +++ b/pkg/nuclide-open-files-rpc/lib/main.js @@ -1,33 +1,67 @@ -/** - * 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 strict-local - * @format - */ - -import type {FileVersion} from './rpc-types'; - -import {FileCache} from './FileCache'; -import {FileVersionNotifier} from './FileVersionNotifier'; - -export {FileCache, FileVersionNotifier}; -export {FileEventKind} from './constants'; -export {ConfigObserver} from './ConfigObserver'; - -import invariant from 'assert'; - -export const OPEN_FILES_SERVICE = 'OpenFilesService'; - -export function getBufferAtVersion( - fileVersion: FileVersion, -): Promise { - invariant( - fileVersion.notifier instanceof FileCache, - "Don't call this from the Atom process", - ); - return (fileVersion.notifier: FileCache).getBufferAtVersion(fileVersion); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.OPEN_FILES_SERVICE = exports.ConfigObserver = exports.FileEventKind = exports.FileVersionNotifier = exports.FileCache = undefined; + +var _constants; + +function _load_constants() { + return _constants = require('./constants'); +} + +Object.defineProperty(exports, 'FileEventKind', { + enumerable: true, + get: function () { + return (_constants || _load_constants()).FileEventKind; + } +}); + +var _ConfigObserver; + +function _load_ConfigObserver() { + return _ConfigObserver = require('./ConfigObserver'); +} + +Object.defineProperty(exports, 'ConfigObserver', { + enumerable: true, + get: function () { + return (_ConfigObserver || _load_ConfigObserver()).ConfigObserver; + } +}); +exports.getBufferAtVersion = getBufferAtVersion; + +var _FileCache; + +function _load_FileCache() { + return _FileCache = require('./FileCache'); +} + +var _FileVersionNotifier; + +function _load_FileVersionNotifier() { + return _FileVersionNotifier = require('./FileVersionNotifier'); } + +exports.FileCache = (_FileCache || _load_FileCache()).FileCache; +exports.FileVersionNotifier = (_FileVersionNotifier || _load_FileVersionNotifier()).FileVersionNotifier; /** + * 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. + * + * strict-local + * @format + */ + +const OPEN_FILES_SERVICE = exports.OPEN_FILES_SERVICE = 'OpenFilesService'; + +function getBufferAtVersion(fileVersion) { + if (!(fileVersion.notifier instanceof (_FileCache || _load_FileCache()).FileCache)) { + throw new Error("Don't call this from the Atom process"); + } + + return fileVersion.notifier.getBufferAtVersion(fileVersion); +} \ No newline at end of file diff --git a/pkg/nuclide-open-files-rpc/lib/rpc-types.js b/pkg/nuclide-open-files-rpc/lib/rpc-types.js index 7e65a200d7..a726efc43f 100644 --- a/pkg/nuclide-open-files-rpc/lib/rpc-types.js +++ b/pkg/nuclide-open-files-rpc/lib/rpc-types.js @@ -1,72 +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 - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -export type FileOpenEvent = { - kind: 'open', - fileVersion: FileVersion, - contents: string, - languageId: string, -}; - -// Used in debugging to verify that the server contents match the client -export type FileSyncEvent = { - kind: 'sync', - fileVersion: FileVersion, - contents: string, - languageId: string, -}; - -export type FileCloseEvent = { - kind: 'close', - fileVersion: FileVersion, -}; - -export type FileEditEvent = { - kind: 'edit', - fileVersion: FileVersion, - oldRange: atom$Range, - newRange: atom$Range, - oldText: string, - newText: string, -}; - -export type FileSaveEvent = { - kind: 'save', - fileVersion: FileVersion, -}; - -// TODO: Save Events? -export type FileEvent = - | FileOpenEvent - | FileCloseEvent - | FileEditEvent - | FileSaveEvent - | FileSyncEvent; - -export type LocalFileEvent = - | FileOpenEvent - | FileCloseEvent - | FileEditEvent - | FileSaveEvent; - -export interface FileNotifier { - onFileEvent(event: FileEvent): Promise; - onDirectoriesChanged(openDirectories: Set): Promise; - dispose(): void; -} - -export type FileVersion = { - notifier: FileNotifier, - filePath: NuclideUri, - version: number, -}; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-open-files/__atom_tests__/main-test.js b/pkg/nuclide-open-files/__atom_tests__/main-test.js index 8680ee0f34..900a9b1f5f 100644 --- a/pkg/nuclide-open-files/__atom_tests__/main-test.js +++ b/pkg/nuclide-open-files/__atom_tests__/main-test.js @@ -1,3 +1,29 @@ +'use strict'; + +var _os = _interopRequireDefault(require('os')); + +var _FileCache; + +function _load_FileCache() { + return _FileCache = require('../../nuclide-open-files-rpc/lib/FileCache'); +} + +var _main; + +function _load_main() { + return _main = require('../lib/main'); +} + +var _atom = require('atom'); + +var _nuclideOpenFilesRpc; + +function _load_nuclideOpenFilesRpc() { + return _nuclideOpenFilesRpc = require('../../nuclide-open-files-rpc'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,58 +31,45 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {Observable} from 'rxjs'; +describe('nuclide-open-files', () => { + let notifier = null; -import os from 'os'; -import invariant from 'assert'; -import {FileCache} from '../../nuclide-open-files-rpc/lib/FileCache'; -import { - reset, - getFileVersionOfBuffer, - getNotifierByConnection, -} from '../lib/main'; -import {Point, TextBuffer} from 'atom'; -import {getBufferAtVersion} from '../../nuclide-open-files-rpc'; + async function getFileCache() { + const cache = await (0, (_main || _load_main()).getNotifierByConnection)(null); -describe('nuclide-open-files', () => { - let notifier: FileCache = (null: any); + if (!(cache != null)) { + throw new Error('Invariant violation: "cache != null"'); + } - async function getFileCache(): Promise { - const cache = await getNotifierByConnection(null); - invariant(cache != null); - return (cache: any); + return cache; } describe('observeFileEvents', () => { beforeEach(async () => { - reset(); + (0, (_main || _load_main()).reset)(); notifier = await getFileCache(); }); - let events: Observable = (null: any); + let events = null; beforeEach(async () => { events = (await getFileCache()).observeFileEvents().map(event => { - const result = { - ...event, + const result = Object.assign({}, event, { filePath: event.fileVersion.filePath, - changeCount: event.fileVersion.version, - }; + changeCount: event.fileVersion.version + }); delete result.fileVersion; return result; }); }); it('open/close', async () => { - const actual = events - .take(2) - .toArray() - .toPromise(); - const buffer = new TextBuffer({filePath: 'f1', text: 'contents1'}); + const actual = events.take(2).toArray().toPromise(); + const buffer = new _atom.TextBuffer({ filePath: 'f1', text: 'contents1' }); // simulates an open atom.project.addBuffer(buffer); // Wait one turn before destroying the text buffer, which calls `setText('')`. @@ -64,28 +77,22 @@ describe('nuclide-open-files', () => { // close buffer.destroy(); - expect(await actual).toEqual([ - { - kind: 'open', - filePath: 'f1', - changeCount: 1, - contents: 'contents1', - languageId: 'text.plain.null-grammar', - }, - { - kind: 'close', - filePath: 'f1', - changeCount: 1, - }, - ]); + expect((await actual)).toEqual([{ + kind: 'open', + filePath: 'f1', + changeCount: 1, + contents: 'contents1', + languageId: 'text.plain.null-grammar' + }, { + kind: 'close', + filePath: 'f1', + changeCount: 1 + }]); }); it('open with delayed load sends initial open event after load', async () => { - const actual = events - .take(2) - .toArray() - .toPromise(); - const buffer = new TextBuffer({filePath: 'f1'}); + const actual = events.take(2).toArray().toPromise(); + const buffer = new _atom.TextBuffer({ filePath: 'f1' }); // simulates an open atom.project.addBuffer(buffer); @@ -98,188 +105,145 @@ describe('nuclide-open-files', () => { // close buffer.destroy(); - expect(await actual).toEqual([ - { - kind: 'open', - filePath: 'f1', - changeCount: 2, - contents: 'contents1', - languageId: 'text.plain.null-grammar', - }, - { - kind: 'close', - filePath: 'f1', - changeCount: 2, - }, - ]); + expect((await actual)).toEqual([{ + kind: 'open', + filePath: 'f1', + changeCount: 2, + contents: 'contents1', + languageId: 'text.plain.null-grammar' + }, { + kind: 'close', + filePath: 'f1', + changeCount: 2 + }]); }); it('edit', async () => { - const buffer = new TextBuffer({filePath: 'f1', text: 'contents1'}); + const buffer = new _atom.TextBuffer({ filePath: 'f1', text: 'contents1' }); atom.project.addBuffer(buffer); - const firstEvents = await events - .take(1) - .toArray() - .toPromise(); + const firstEvents = await events.take(1).toArray().toPromise(); buffer.append('42'); buffer.destroy(); - const secondEvents = await events - .take(2) - .toArray() - .toPromise(); - - expect([...firstEvents, ...secondEvents]).toEqual([ - { - kind: 'open', - filePath: 'f1', - changeCount: 1, - contents: 'contents1', - languageId: 'text.plain.null-grammar', - }, - { - kind: 'edit', - filePath: 'f1', - changeCount: 2, - oldRange: { - start: {row: 0, column: 9}, - end: {row: 0, column: 9}, - }, - oldText: '', - newRange: { - start: {row: 0, column: 9}, - end: {row: 0, column: 11}, - }, - newText: '42', + const secondEvents = await events.take(2).toArray().toPromise(); + + expect([...firstEvents, ...secondEvents]).toEqual([{ + kind: 'open', + filePath: 'f1', + changeCount: 1, + contents: 'contents1', + languageId: 'text.plain.null-grammar' + }, { + kind: 'edit', + filePath: 'f1', + changeCount: 2, + oldRange: { + start: { row: 0, column: 9 }, + end: { row: 0, column: 9 } }, - { - kind: 'close', - filePath: 'f1', - changeCount: 2, + oldText: '', + newRange: { + start: { row: 0, column: 9 }, + end: { row: 0, column: 11 } }, - ]); + newText: '42' + }, { + kind: 'close', + filePath: 'f1', + changeCount: 2 + }]); }); it('edit with multiple edits', async () => { - const buffer = new TextBuffer({filePath: 'f1', text: 'contents1'}); + const buffer = new _atom.TextBuffer({ filePath: 'f1', text: 'contents1' }); atom.project.addBuffer(buffer); - const firstEvents = await events - .take(1) - .toArray() - .toPromise(); + const firstEvents = await events.take(1).toArray().toPromise(); buffer.transact(() => { - buffer.insert(new Point(0, 0), 'a'); + buffer.insert(new _atom.Point(0, 0), 'a'); buffer.append('b'); }); buffer.destroy(); - const secondEvents = await events - .take(3) - .toArray() - .toPromise(); - - expect([...firstEvents, ...secondEvents]).toEqual([ - { - kind: 'open', - filePath: 'f1', - changeCount: 1, - contents: 'contents1', - languageId: 'text.plain.null-grammar', + const secondEvents = await events.take(3).toArray().toPromise(); + + expect([...firstEvents, ...secondEvents]).toEqual([{ + kind: 'open', + filePath: 'f1', + changeCount: 1, + contents: 'contents1', + languageId: 'text.plain.null-grammar' + }, { + kind: 'edit', + filePath: 'f1', + changeCount: 2, + oldRange: { + start: { row: 0, column: 9 }, + end: { row: 0, column: 9 } }, - { - kind: 'edit', - filePath: 'f1', - changeCount: 2, - oldRange: { - start: {row: 0, column: 9}, - end: {row: 0, column: 9}, - }, - oldText: '', - newRange: { - start: {row: 0, column: 10}, - end: {row: 0, column: 11}, - }, - newText: 'b', + oldText: '', + newRange: { + start: { row: 0, column: 10 }, + end: { row: 0, column: 11 } }, - { - kind: 'edit', - filePath: 'f1', - changeCount: 3, - oldRange: { - start: {row: 0, column: 0}, - end: {row: 0, column: 0}, - }, - oldText: '', - newRange: { - start: {row: 0, column: 0}, - end: {row: 0, column: 1}, - }, - newText: 'a', + newText: 'b' + }, { + kind: 'edit', + filePath: 'f1', + changeCount: 3, + oldRange: { + start: { row: 0, column: 0 }, + end: { row: 0, column: 0 } }, - { - kind: 'close', - filePath: 'f1', - changeCount: 3, + oldText: '', + newRange: { + start: { row: 0, column: 0 }, + end: { row: 0, column: 1 } }, - ]); + newText: 'a' + }, { + kind: 'close', + filePath: 'f1', + changeCount: 3 + }]); }); it('save', async () => { - const buffer = new TextBuffer({filePath: 'f1', text: 'contents1'}); + const buffer = new _atom.TextBuffer({ filePath: 'f1', text: 'contents1' }); atom.project.addBuffer(buffer); - const firstEvents = await events - .take(1) - .toArray() - .toPromise(); + const firstEvents = await events.take(1).toArray().toPromise(); buffer.save(); - const secondEvents = await events - .take(1) - .toArray() - .toPromise(); + const secondEvents = await events.take(1).toArray().toPromise(); buffer.destroy(); - const thirdEvents = await events - .take(1) - .toArray() - .toPromise(); - - expect([...firstEvents, ...secondEvents, ...thirdEvents]).toEqual([ - { - kind: 'open', - filePath: 'f1', - changeCount: 1, - contents: 'contents1', - languageId: 'text.plain.null-grammar', - }, - { - kind: 'save', - filePath: 'f1', - changeCount: 1, - }, - { - kind: 'close', - filePath: 'f1', - changeCount: 1, - }, - ]); + const thirdEvents = await events.take(1).toArray().toPromise(); + + expect([...firstEvents, ...secondEvents, ...thirdEvents]).toEqual([{ + kind: 'open', + filePath: 'f1', + changeCount: 1, + contents: 'contents1', + languageId: 'text.plain.null-grammar' + }, { + kind: 'save', + filePath: 'f1', + changeCount: 1 + }, { + kind: 'close', + filePath: 'f1', + changeCount: 1 + }]); }); it('rename', async () => { - const buffer = new TextBuffer({filePath: 'f1', text: 'contents1'}); + const buffer = new _atom.TextBuffer({ filePath: 'f1', text: 'contents1' }); atom.project.addBuffer(buffer); - const firstEvents = await events - .take(1) - .toArray() - .toPromise(); + const firstEvents = await events.take(1).toArray().toPromise(); // $FlowIgnore: spec buffer.setPath('f2'); - const secondEventsPromise = events - .take(3) - .toArray() - .toPromise(); + const secondEventsPromise = events.take(3).toArray().toPromise(); // Wait one turn before destroying the text buffer, which calls `setText('')`. await Promise.resolve(); @@ -287,209 +251,216 @@ describe('nuclide-open-files', () => { buffer.destroy(); const secondEvents = await secondEventsPromise; - expect([...firstEvents, ...secondEvents]).toEqual([ - { - kind: 'open', - filePath: 'f1', - changeCount: 1, - contents: 'contents1', - languageId: 'text.plain.null-grammar', - }, - { - kind: 'close', - filePath: 'f1', - changeCount: 1, - }, - { - kind: 'open', - filePath: 'f2', - changeCount: 1, - contents: 'contents1', - languageId: 'text.plain.null-grammar', - }, - { - kind: 'close', - filePath: 'f2', - changeCount: 1, - }, - ]); + expect([...firstEvents, ...secondEvents]).toEqual([{ + kind: 'open', + filePath: 'f1', + changeCount: 1, + contents: 'contents1', + languageId: 'text.plain.null-grammar' + }, { + kind: 'close', + filePath: 'f1', + changeCount: 1 + }, { + kind: 'open', + filePath: 'f2', + changeCount: 1, + contents: 'contents1', + languageId: 'text.plain.null-grammar' + }, { + kind: 'close', + filePath: 'f2', + changeCount: 1 + }]); }); it('rename new file', async () => { - const buffer = new TextBuffer('contents1'); + const buffer = new _atom.TextBuffer('contents1'); atom.project.addBuffer(buffer); // $FlowIgnore: spec buffer.setPath('f2'); - const eventsPromise = events - .take(2) - .toArray() - .toPromise(); + const eventsPromise = events.take(2).toArray().toPromise(); // Wait one turn before destroying the text buffer, which calls `setText('')`. await Promise.resolve(); buffer.destroy(); - expect(await eventsPromise).toEqual([ - { - kind: 'open', - filePath: 'f2', - changeCount: 1, - contents: 'contents1', - languageId: 'text.plain.null-grammar', - }, - { - kind: 'close', - filePath: 'f2', - changeCount: 1, - }, - ]); + expect((await eventsPromise)).toEqual([{ + kind: 'open', + filePath: 'f2', + changeCount: 1, + contents: 'contents1', + languageId: 'text.plain.null-grammar' + }, { + kind: 'close', + filePath: 'f2', + changeCount: 1 + }]); }); }); describe('observeDirectoryEvents', () => { beforeEach(async () => { - reset(); + (0, (_main || _load_main()).reset)(); notifier = await getFileCache(); }); - let evts: Observable>; + let evts; beforeEach(async () => { - evts = (await getFileCache()).observeDirectoryEvents().map(dirs => - Array.from(dirs).filter( - dir => - !dir.includes( - // apm test adds a project using os.tempdir() as the path. - // Exclude all directories rooted in the OS's default tmp dir. - // https://github.com/atom/atom/pull/15990/files - os.tmpdir(), - ), - ), - ); + evts = (await getFileCache()).observeDirectoryEvents().map(dirs => Array.from(dirs).filter(dir => !dir.includes( + // apm test adds a project using os.tempdir() as the path. + // Exclude all directories rooted in the OS's default tmp dir. + // https://github.com/atom/atom/pull/15990/files + _os.default.tmpdir()))); }); it('Initially', async () => { - const events = evts - .take(1) - .toArray() - .toPromise(); + const events = evts.take(1).toArray().toPromise(); - expect(await events).toEqual([[]]); + expect((await events)).toEqual([[]]); }); it('open a dir', async () => { const dir = __dirname; - const events = evts - .take(2) - .toArray() - .toPromise(); + const events = evts.take(2).toArray().toPromise(); atom.project.addPath(dir); - expect(await events).toEqual([[], [dir]]); + expect((await events)).toEqual([[], [dir]]); }); }); describe('getBufferAtVersion', () => { beforeEach(async () => { - reset(); + (0, (_main || _load_main()).reset)(); notifier = await getFileCache(); }); it('get current version', async () => { - const buffer = new TextBuffer({ + const buffer = new _atom.TextBuffer({ notifier, filePath: 'f1', - text: 'contents1', + text: 'contents1' }); atom.project.addBuffer(buffer); - const fileVersion = await getFileVersionOfBuffer(buffer); - invariant(fileVersion != null); - const serverBuffer = await getBufferAtVersion(fileVersion); - invariant(serverBuffer != null); + const fileVersion = await (0, (_main || _load_main()).getFileVersionOfBuffer)(buffer); + + if (!(fileVersion != null)) { + throw new Error('Invariant violation: "fileVersion != null"'); + } + + const serverBuffer = await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion); + + if (!(serverBuffer != null)) { + throw new Error('Invariant violation: "serverBuffer != null"'); + } + expect(serverBuffer.getText()).toEqual('contents1'); buffer.destroy(); }); it('safely handles destroyed buffers', async () => { - const buffer = new TextBuffer({ + const buffer = new _atom.TextBuffer({ notifier, filePath: 'f1', - text: 'contents1', + text: 'contents1' }); atom.project.addBuffer(buffer); atom.project.removeBuffer(buffer); - const fileVersion = await getFileVersionOfBuffer(buffer); + const fileVersion = await (0, (_main || _load_main()).getFileVersionOfBuffer)(buffer); expect(fileVersion).toBe(null); }); it('get next version', async () => { - const buffer = new TextBuffer({filePath: 'f1', text: 'contents1'}); + const buffer = new _atom.TextBuffer({ filePath: 'f1', text: 'contents1' }); atom.project.addBuffer(buffer); - const fileVersion = await getFileVersionOfBuffer(buffer); - invariant(fileVersion != null); + const fileVersion = await (0, (_main || _load_main()).getFileVersionOfBuffer)(buffer); + + if (!(fileVersion != null)) { + throw new Error('Invariant violation: "fileVersion != null"'); + } + fileVersion.version++; - const serverBufferPromise = getBufferAtVersion(fileVersion); + const serverBufferPromise = (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion); buffer.append('42'); - invariant(serverBufferPromise != null); + if (!(serverBufferPromise != null)) { + throw new Error('Invariant violation: "serverBufferPromise != null"'); + } + const serverBuffer = await serverBufferPromise; - invariant(serverBuffer != null); + + if (!(serverBuffer != null)) { + throw new Error('Invariant violation: "serverBuffer != null"'); + } + expect(serverBuffer.getText()).toEqual('contents142'); buffer.destroy(); }); it('get out of date version', async () => { - const buffer = new TextBuffer({filePath: 'f1', text: 'contents1'}); + const buffer = new _atom.TextBuffer({ filePath: 'f1', text: 'contents1' }); atom.project.addBuffer(buffer); - const outdatedFileVersion = await getFileVersionOfBuffer(buffer); - invariant(outdatedFileVersion != null); + const outdatedFileVersion = await (0, (_main || _load_main()).getFileVersionOfBuffer)(buffer); + + if (!(outdatedFileVersion != null)) { + throw new Error('Invariant violation: "outdatedFileVersion != null"'); + } buffer.append('42'); - const fileVersion = await getFileVersionOfBuffer(buffer); - invariant(fileVersion != null); - await getBufferAtVersion(fileVersion); + const fileVersion = await (0, (_main || _load_main()).getFileVersionOfBuffer)(buffer); - const result = await getBufferAtVersion(outdatedFileVersion); + if (!(fileVersion != null)) { + throw new Error('Invariant violation: "fileVersion != null"'); + } + + await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion); + + const result = await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(outdatedFileVersion); expect(result).toBe(null); buffer.destroy(); }); it('get version before file opens', async () => { - const serverBufferPromise = getBufferAtVersion({ + const serverBufferPromise = (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)({ notifier, filePath: 'f3', - version: 1, + version: 1 }); - const buffer = new TextBuffer({filePath: 'f3', text: 'contents3'}); + const buffer = new _atom.TextBuffer({ filePath: 'f3', text: 'contents3' }); atom.project.addBuffer(buffer); const serverBuffer = await serverBufferPromise; - invariant(serverBuffer != null); + + if (!(serverBuffer != null)) { + throw new Error('Invariant violation: "serverBuffer != null"'); + } + expect(serverBuffer.getText()).toEqual('contents3'); buffer.destroy(); }); it('get out of date version on open', async () => { - const serverBuffer = getBufferAtVersion({ + const serverBuffer = (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)({ notifier, filePath: 'f3', - version: 0, + version: 0 }); - const buffer = new TextBuffer({filePath: 'f3', text: 'contents1'}); + const buffer = new _atom.TextBuffer({ filePath: 'f3', text: 'contents1' }); atom.project.addBuffer(buffer); const result = await serverBuffer; @@ -500,33 +471,44 @@ describe('nuclide-open-files', () => { }); it('get reopened file', async () => { - const buffer = new TextBuffer({filePath: 'f3', text: 'contents3'}); + const buffer = new _atom.TextBuffer({ filePath: 'f3', text: 'contents3' }); atom.project.addBuffer(buffer); - const fileVersion = await getFileVersionOfBuffer(buffer); - invariant(fileVersion != null); - const serverBuffer = await getBufferAtVersion(fileVersion); - invariant(serverBuffer != null); + const fileVersion = await (0, (_main || _load_main()).getFileVersionOfBuffer)(buffer); + + if (!(fileVersion != null)) { + throw new Error('Invariant violation: "fileVersion != null"'); + } + + const serverBuffer = await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion); + + if (!(serverBuffer != null)) { + throw new Error('Invariant violation: "serverBuffer != null"'); + } + expect(serverBuffer.getText()).toEqual('contents3'); - const receivedClose = (await getFileCache()) - .observeFileEvents() - .filter(event => event.kind === 'close') - .take(1) - .toArray() - .toPromise(); + const receivedClose = (await getFileCache()).observeFileEvents().filter(event => event.kind === 'close').take(1).toArray().toPromise(); buffer.destroy(); await receivedClose; - const buffer2 = new TextBuffer({filePath: 'f3', text: 'contents4'}); + const buffer2 = new _atom.TextBuffer({ filePath: 'f3', text: 'contents4' }); atom.project.addBuffer(buffer2); - const fileVersion2 = await getFileVersionOfBuffer(buffer2); - invariant(fileVersion2 != null); - const serverBuffer2 = await getBufferAtVersion(fileVersion2); - invariant(serverBuffer2 != null); + const fileVersion2 = await (0, (_main || _load_main()).getFileVersionOfBuffer)(buffer2); + + if (!(fileVersion2 != null)) { + throw new Error('Invariant violation: "fileVersion2 != null"'); + } + + const serverBuffer2 = await (0, (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).getBufferAtVersion)(fileVersion2); + + if (!(serverBuffer2 != null)) { + throw new Error('Invariant violation: "serverBuffer2 != null"'); + } + expect(serverBuffer2.getText()).toEqual('contents4'); buffer2.destroy(); }); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-open-files/lib/BufferSubscription.js b/pkg/nuclide-open-files/lib/BufferSubscription.js index 6dce8f6e68..acda158ad7 100644 --- a/pkg/nuclide-open-files/lib/BufferSubscription.js +++ b/pkg/nuclide-open-files/lib/BufferSubscription.js @@ -1,29 +1,40 @@ -/** - * 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 - */ - -import type { - FileNotifier, - LocalFileEvent, - FileSyncEvent, - FileEvent, -} from '../../nuclide-open-files-rpc/lib/rpc-types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {NotifiersByConnection} from './NotifiersByConnection'; - -import invariant from 'assert'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {getLogger} from 'log4js'; -import {FileEventKind} from '../../nuclide-open-files-rpc'; - -const logger = getLogger('nuclide-open-files'); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.BufferSubscription = undefined; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _nuclideOpenFilesRpc; + +function _load_nuclideOpenFilesRpc() { + return _nuclideOpenFilesRpc = require('../../nuclide-open-files-rpc'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-open-files'); /** + * 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. + * + * + * @format + */ const RESYNC_TIMEOUT_MS = 2000; @@ -39,18 +50,9 @@ const RESYNC_TIMEOUT_MS = 2000; // renamed or destroyed, so rather than keep the per-buffer info around after // a buffer is destroyed, the outstanding close messages are kept with the // per-connection info in NotifiersByConnection. -export class BufferSubscription { - _oldPath: ?NuclideUri; - _notifiers: NotifiersByConnection; - _buffer: atom$TextBuffer; - _notifier: ?Promise; - _subscriptions: UniversalDisposable; - _serverVersion: number; - _lastAttemptedSync: number; - _changeCount: number; - _sentOpen: boolean; - - constructor(notifiers: NotifiersByConnection, buffer: atom$TextBuffer) { +class BufferSubscription { + + constructor(notifiers, buffer) { this._notifiers = notifiers; this._buffer = buffer; this._notifier = null; @@ -59,75 +61,84 @@ export class BufferSubscription { this._changeCount = 1; this._sentOpen = false; - const subscriptions = new UniversalDisposable(); + const subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); - subscriptions.add( - buffer.onDidChangeText(async (event: atom$AggregatedTextEditEvent) => { - // It's important that we increment the change count *before* waiting on the notifier. - // This makes sure that any users who use `getVersion` in between obtain the correct version. - this._changeCount += event.changes.length; - if (this._notifier == null) { - return; - } + subscriptions.add(buffer.onDidChangeText(async event => { + // It's important that we increment the change count *before* waiting on the notifier. + // This makes sure that any users who use `getVersion` in between obtain the correct version. + this._changeCount += event.changes.length; + if (this._notifier == null) { + return; + } - // Must inspect the buffer before awaiting on the notifier - // to avoid race conditions - const filePath = this._buffer.getPath(); - invariant(filePath != null); - const version = this._changeCount; + // Must inspect the buffer before awaiting on the notifier + // to avoid race conditions + const filePath = this._buffer.getPath(); - invariant(this._notifier != null); - const notifier = await this._notifier; - if (this._sentOpen) { - // Changes must be sent in reverse order to ensure that they are applied cleanly. - // (Atom ensures that they are sent over in increasing lexicographic order). - for (let i = event.changes.length - 1; i >= 0; i--) { - const edit = event.changes[i]; - this.sendEvent({ - kind: FileEventKind.EDIT, - fileVersion: { - notifier, - filePath, - version: version - i, - }, - oldRange: edit.oldRange, - newRange: edit.newRange, - oldText: edit.oldText, - newText: edit.newText, - }); - } - } else { - this._sendOpenByNotifier(notifier, version); - } - }), - ); + if (!(filePath != null)) { + throw new Error('Invariant violation: "filePath != null"'); + } - subscriptions.add( - buffer.onDidSave(async () => { - if (this._notifier == null) { - return; - } + const version = this._changeCount; - const filePath = this._buffer.getPath(); - invariant(filePath != null); + if (!(this._notifier != null)) { + throw new Error('Invariant violation: "this._notifier != null"'); + } - invariant(this._notifier != null); - const notifier = await this._notifier; - const version = this._changeCount; - if (this._sentOpen) { + const notifier = await this._notifier; + if (this._sentOpen) { + // Changes must be sent in reverse order to ensure that they are applied cleanly. + // (Atom ensures that they are sent over in increasing lexicographic order). + for (let i = event.changes.length - 1; i >= 0; i--) { + const edit = event.changes[i]; this.sendEvent({ - kind: FileEventKind.SAVE, + kind: (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).FileEventKind.EDIT, fileVersion: { notifier, filePath, - version, + version: version - i }, + oldRange: edit.oldRange, + newRange: edit.newRange, + oldText: edit.oldText, + newText: edit.newText }); - } else { - this._sendOpenByNotifier(notifier, version); } - }), - ); + } else { + this._sendOpenByNotifier(notifier, version); + } + })); + + subscriptions.add(buffer.onDidSave(async () => { + if (this._notifier == null) { + return; + } + + const filePath = this._buffer.getPath(); + + if (!(filePath != null)) { + throw new Error('Invariant violation: "filePath != null"'); + } + + if (!(this._notifier != null)) { + throw new Error('Invariant violation: "this._notifier != null"'); + } + + const notifier = await this._notifier; + const version = this._changeCount; + if (this._sentOpen) { + this.sendEvent({ + kind: (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).FileEventKind.SAVE, + fileVersion: { + notifier, + filePath, + version + } + }); + } else { + this._sendOpenByNotifier(notifier, version); + } + })); this._subscriptions = subscriptions; @@ -143,41 +154,50 @@ export class BufferSubscription { } } - async _sendOpen(version: number): Promise { - invariant(this._notifier != null); + async _sendOpen(version) { + if (!(this._notifier != null)) { + throw new Error('Invariant violation: "this._notifier != null"'); + } + const notifier = await this._notifier; this._sendOpenByNotifier(notifier, version); } - _sendOpenByNotifier(notifier: FileNotifier, version: number): void { + _sendOpenByNotifier(notifier, version) { const filePath = this._buffer.getPath(); - invariant(filePath != null); + + if (!(filePath != null)) { + throw new Error('Invariant violation: "filePath != null"'); + } const contents = this._buffer.getText(); const languageId = this._getLanguageId(filePath, contents); this._sentOpen = true; this.sendEvent({ - kind: FileEventKind.OPEN, + kind: (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).FileEventKind.OPEN, fileVersion: { notifier, filePath, - version, + version }, contents, - languageId, + languageId }); } - _getLanguageId(filePath: string, contents: string): string { + _getLanguageId(filePath, contents) { return this._buffer.getLanguageMode().getLanguageId(); } - getVersion(): number { + getVersion() { return this._changeCount; } - async sendEvent(event: LocalFileEvent) { - invariant(event.kind !== FileEventKind.SYNC); + async sendEvent(event) { + if (!(event.kind !== (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).FileEventKind.SYNC)) { + throw new Error('Invariant violation: "event.kind !== FileEventKind.SYNC"'); + } + try { await event.fileVersion.notifier.onFileEvent(event); this.updateServerVersion(event.fileVersion.version); @@ -193,7 +213,7 @@ export class BufferSubscription { } } - updateServerVersion(sentVersion: number): void { + updateServerVersion(sentVersion) { this._serverVersion = Math.max(this._serverVersion, sentVersion); this._lastAttemptedSync = Math.max(this._lastAttemptedSync, sentVersion); } @@ -216,7 +236,11 @@ export class BufferSubscription { logger.error('Resync preempted by remote connection closed'); return; } - invariant(filePath != null); + + if (!(filePath != null)) { + throw new Error('Invariant violation: "filePath != null"'); + } + const notifier = await this._notifier; if (this._buffer.isDestroyed()) { logger.error('Resync preempted by later event'); @@ -230,28 +254,23 @@ export class BufferSubscription { const contents = this._buffer.getText(); const languageId = this._getLanguageId(filePath, contents); - const syncEvent: FileSyncEvent = { - kind: FileEventKind.SYNC, + const syncEvent = { + kind: (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).FileEventKind.SYNC, fileVersion: { notifier, filePath, - version: resyncVersion, + version: resyncVersion }, contents, - languageId, + languageId }; try { await notifier.onFileEvent(syncEvent); this.updateServerVersion(resyncVersion); - logger.error( - `Successful resync event: ${eventToString(syncEvent)}`, - ); + logger.error(`Successful resync event: ${eventToString(syncEvent)}`); } catch (syncError) { - logger.error( - `Error sending file sync event: ${eventToString(syncEvent)}`, - syncError, - ); + logger.error(`Error sending file sync event: ${eventToString(syncEvent)}`, syncError); // continue trying until either the file is closed, // or a resync to a later edit is attempted @@ -281,9 +300,10 @@ export class BufferSubscription { } } -function eventToString(event: FileEvent): string { - const jsonable = {...event}; - jsonable.fileVersion = {...event.fileVersion}; +exports.BufferSubscription = BufferSubscription; +function eventToString(event) { + const jsonable = Object.assign({}, event); + jsonable.fileVersion = Object.assign({}, event.fileVersion); jsonable.fileVersion.notifier = null; return JSON.stringify(jsonable); -} +} \ No newline at end of file diff --git a/pkg/nuclide-open-files/lib/NotifiersByConnection.js b/pkg/nuclide-open-files/lib/NotifiersByConnection.js index 10874daa35..4625382b88 100644 --- a/pkg/nuclide-open-files/lib/NotifiersByConnection.js +++ b/pkg/nuclide-open-files/lib/NotifiersByConnection.js @@ -1,48 +1,76 @@ -/** - * 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 - */ - -import typeof * as OpenFilesService from '../../nuclide-open-files-rpc/lib/OpenFilesService'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {FileNotifier} from '../../nuclide-open-files-rpc/lib/rpc-types'; - -import { - getServiceByConnection, - ServerConnection, - ConnectionCache, -} from '../../nuclide-remote-connection'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {OPEN_FILES_SERVICE} from '../../nuclide-open-files-rpc'; -import {getLogger} from 'log4js'; -import {FileEventKind} from '../../nuclide-open-files-rpc'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import {areSetsEqual} from 'nuclide-commons/collection'; - -const logger = getLogger('nuclide-open-files'); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.NotifiersByConnection = undefined; + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _nuclideOpenFilesRpc; + +function _load_nuclideOpenFilesRpc() { + return _nuclideOpenFilesRpc = require('../../nuclide-open-files-rpc'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _event; + +function _load_event() { + return _event = require('../../../modules/nuclide-commons/event'); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-open-files'); /** + * 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. + * + * + * @format + */ const RESYNC_TIMEOUT_MS = 2000; -function getOpenFilesService(connection: ?ServerConnection): OpenFilesService { - return getServiceByConnection(OPEN_FILES_SERVICE, connection); +function getOpenFilesService(connection) { + return (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getServiceByConnection)((_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).OPEN_FILES_SERVICE, connection); } -function uriMatchesConnection( - uri: NuclideUri, - connection: ?ServerConnection, -): boolean { +function uriMatchesConnection(uri, connection) { if (connection == null) { - return nuclideUri.isLocal(uri); + return (_nuclideUri || _load_nuclideUri()).default.isLocal(uri); } else { - return connection.getRemoteHostname() === nuclideUri.getHostnameOpt(uri); + return connection.getRemoteHostname() === (_nuclideUri || _load_nuclideUri()).default.getHostnameOpt(uri); } } @@ -51,20 +79,12 @@ function uriMatchesConnection( // Also handles sending 'close' events to the FileNotifier so that // the per-Buffer BufferSubscription does not need to live past // the buffer being destroyed. -export class NotifiersByConnection { - _notifiers: ConnectionCache; - _subscriptions: ConnectionCache; - _getService: (connection: ?ServerConnection) => OpenFilesService; - - constructor( - getService: ( - connection: ?ServerConnection, - ) => OpenFilesService = getOpenFilesService, - ) { +class NotifiersByConnection { + + constructor(getService = getOpenFilesService) { this._getService = getService; - const filterByConnection = (connection, dirs) => - new Set(dirs.filter(dir => uriMatchesConnection(dir, connection))); - this._notifiers = new ConnectionCache(connection => { + const filterByConnection = (connection, dirs) => new Set(dirs.filter(dir => uriMatchesConnection(dir, connection))); + this._notifiers = new (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).ConnectionCache(connection => { const result = this._getService(connection).initialize(); // NOTE: It's important to use `await` here rather than .then. // v8's native async/await implementation treats .then and await differently. @@ -77,19 +97,12 @@ export class NotifiersByConnection { onDirectoriesChanged(); return result; }); - this._subscriptions = new ConnectionCache(connection => { - const subscription = observableFromSubscribeFunction(cb => - atom.project.onDidChangePaths(cb), - ) - .map(dirs => filterByConnection(connection, dirs)) - .distinctUntilChanged(areSetsEqual) - .subscribe(async dirs => { - const notifier = await this._notifiers.get(connection); - notifier.onDirectoriesChanged(dirs); - }); - return Promise.resolve( - new UniversalDisposable(() => subscription.unsubscribe()), - ); + this._subscriptions = new (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).ConnectionCache(connection => { + const subscription = (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => atom.project.onDidChangePaths(cb)).map(dirs => filterByConnection(connection, dirs)).distinctUntilChanged((_collection || _load_collection()).areSetsEqual).subscribe(async dirs => { + const notifier = await this._notifiers.get(connection); + notifier.onDirectoriesChanged(dirs); + }); + return Promise.resolve(new (_UniversalDisposable || _load_UniversalDisposable()).default(() => subscription.unsubscribe())); }); } @@ -100,24 +113,24 @@ export class NotifiersByConnection { // Returns null for a buffer to a file on a closed remote connection // or a new buffer which has not been saved. - get(buffer: atom$TextBuffer): ?Promise { + get(buffer) { return this.getForUri(buffer.getPath()); } - getForConnection(connection: ?ServerConnection): Promise { + getForConnection(connection) { return this._notifiers.get(connection); } // Returns null for a buffer to a file on a closed remote connection // or a new buffer which has not been saved. - getForUri(path: ?NuclideUri): ?Promise { + getForUri(path) { return this._notifiers.getForUri(path); } // Sends the close message to the appropriate FileNotifier. // Will keep trying to send until the send succeeds or // the corresponding ServerConnection is closed. - sendClose(filePath: NuclideUri, version: number): void { + sendClose(filePath, version) { if (filePath === '') { return; } @@ -130,20 +143,17 @@ export class NotifiersByConnection { try { const n = await notifier; const message = { - kind: FileEventKind.CLOSE, + kind: (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).FileEventKind.CLOSE, fileVersion: { notifier: n, filePath, - version, - }, + version + } }; await message.fileVersion.notifier.onFileEvent(message); } catch (e) { - logger.error( - `Error sending file close event: ${filePath} ${version}`, - e, - ); + logger.error(`Error sending file close event: ${filePath} ${version}`, e); setTimeout(sendMessage, RESYNC_TIMEOUT_MS); } } @@ -152,3 +162,4 @@ export class NotifiersByConnection { sendMessage(); } } +exports.NotifiersByConnection = NotifiersByConnection; \ No newline at end of file diff --git a/pkg/nuclide-open-files/lib/main.js b/pkg/nuclide-open-files/lib/main.js index cdfe8cba61..2283ded762 100644 --- a/pkg/nuclide-open-files/lib/main.js +++ b/pkg/nuclide-open-files/lib/main.js @@ -1,83 +1,94 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Activation = undefined; +exports.reset = reset; +exports.getNotifierByConnection = getNotifierByConnection; +exports.getFileVersionOfBuffer = getFileVersionOfBuffer; +exports.getFileVersionOfEditor = getFileVersionOfEditor; + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _textBuffer; + +function _load_textBuffer() { + return _textBuffer = require('../../commons-atom/text-buffer'); +} + +var _NotifiersByConnection; + +function _load_NotifiersByConnection() { + return _NotifiersByConnection = require('./NotifiersByConnection'); +} -import type {FileVersion} from '../../nuclide-open-files-rpc/lib/rpc-types'; -import type {ServerConnection} from '../../nuclide-remote-connection'; -import type {FileNotifier} from '../../nuclide-open-files-rpc/lib/rpc-types'; - -import invariant from 'assert'; -import {getLogger} from 'log4js'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import { - observeBufferOpen, - observeBufferCloseOrRename, -} from '../../commons-atom/text-buffer'; -import {NotifiersByConnection} from './NotifiersByConnection'; -import {BufferSubscription} from './BufferSubscription'; - -export class Activation { - _disposables: UniversalDisposable; - _bufferSubscriptions: Map; - notifiers: NotifiersByConnection; - - constructor(state: ?Object) { - this._disposables = new UniversalDisposable(); +var _BufferSubscription; + +function _load_BufferSubscription() { + return _BufferSubscription = require('./BufferSubscription'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Activation { + + constructor(state) { + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._bufferSubscriptions = new Map(); - const notifiers = new NotifiersByConnection(); + const notifiers = new (_NotifiersByConnection || _load_NotifiersByConnection()).NotifiersByConnection(); this.notifiers = notifiers; this._disposables.add(notifiers); - this._disposables.add( - observeBufferOpen().subscribe(buffer => { - const path = buffer.getPath(); - // Empty files don't need to be monitored. - if (path == null || this._bufferSubscriptions.has(path)) { - return; - } - this._createBufferSubscription(path, buffer); - }), - ); + this._disposables.add((0, (_textBuffer || _load_textBuffer()).observeBufferOpen)().subscribe(buffer => { + const path = buffer.getPath(); + // Empty files don't need to be monitored. + if (path == null || this._bufferSubscriptions.has(path)) { + return; + } + this._createBufferSubscription(path, buffer); + })); } - _createBufferSubscription( - path: string, - buffer: atom$TextBuffer, - ): BufferSubscription { - const bufferSubscription = new BufferSubscription(this.notifiers, buffer); + _createBufferSubscription(path, buffer) { + const bufferSubscription = new (_BufferSubscription || _load_BufferSubscription()).BufferSubscription(this.notifiers, buffer); this._bufferSubscriptions.set(path, bufferSubscription); - const subscriptions = new UniversalDisposable(bufferSubscription); - subscriptions.add( - observeBufferCloseOrRename(buffer).subscribe(closeEvent => { - this._bufferSubscriptions.delete(path); - this._disposables.remove(subscriptions); - subscriptions.dispose(); - }), - ); + const subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(bufferSubscription); + subscriptions.add((0, (_textBuffer || _load_textBuffer()).observeBufferCloseOrRename)(buffer).subscribe(closeEvent => { + this._bufferSubscriptions.delete(path); + this._disposables.remove(subscriptions); + subscriptions.dispose(); + })); this._disposables.add(subscriptions); return bufferSubscription; } - getVersion(buffer: atom$TextBuffer): number { + getVersion(buffer) { const path = buffer.getPath(); - invariant(path != null); // Guaranteed when called below. + + if (!(path != null)) { + throw new Error('Invariant violation: "path != null"'); + } // Guaranteed when called below. + + let bufferSubscription = this._bufferSubscriptions.get(path); if (bufferSubscription == null) { // In rare situations, the buffer subscription may not have been created // when initially opened above (e.g. exceptions). // It's fine to just create the subscription at this point. bufferSubscription = this._createBufferSubscription(path, buffer); - getLogger('nuclide-open-files').warn( - `Did not register open event for buffer ${path}. Manually creating subscription`, - ); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-open-files').warn(`Did not register open event for buffer ${path}. Manually creating subscription`); } return bufferSubscription.getVersion(); } @@ -88,11 +99,22 @@ export class Activation { } } -// Mutable for testing. -let activation: ?Activation = new Activation(); +exports.Activation = Activation; // Mutable for testing. +/** + * 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. + * + * + * @format + */ + +let activation = new Activation(); // exported for testing -export function reset(): void { +function reset() { if (activation != null) { activation.dispose(); } @@ -106,30 +128,28 @@ function getActivation() { return activation; } -export function getNotifierByConnection( - connection: ?ServerConnection, -): Promise { +function getNotifierByConnection(connection) { return getActivation().notifiers.getForConnection(connection); } -export async function getFileVersionOfBuffer( - buffer: atom$TextBuffer, -): Promise { +async function getFileVersionOfBuffer(buffer) { const filePath = buffer.getPath(); const notifier = await getActivation().notifiers.getForUri(filePath); if (notifier == null || buffer.isDestroyed()) { return null; } - invariant(filePath != null); + + if (!(filePath != null)) { + throw new Error('Invariant violation: "filePath != null"'); + } + return { notifier, filePath, - version: getActivation().getVersion(buffer), + version: getActivation().getVersion(buffer) }; } -export function getFileVersionOfEditor( - editor: atom$TextEditor, -): Promise { +function getFileVersionOfEditor(editor) { return getFileVersionOfBuffer(editor.getBuffer()); -} +} \ No newline at end of file diff --git a/pkg/nuclide-outline-view-extras/lib/main.js b/pkg/nuclide-outline-view-extras/lib/main.js index e42bdf193f..13b1c506fa 100644 --- a/pkg/nuclide-outline-view-extras/lib/main.js +++ b/pkg/nuclide-outline-view-extras/lib/main.js @@ -1,67 +1,80 @@ -/** - * 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 strict-local - * @format - */ - -import type {HomeFragments} from '../../nuclide-home/lib/types'; -import type {NuxTourModel} from '../../nuclide-nux/lib/NuxModel'; -import type {RegisterNux} from '../../nuclide-nux/lib/main'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -import {WORKSPACE_VIEW_URI} from 'atom-ide-ui/pkg/atom-ide-outline-view/lib/OutlineViewPanel'; -import {makeToolbarButtonSpec} from 'nuclide-commons-ui/ToolbarUtils'; - -const NUX_OUTLINE_VIEW_TOUR = 'nuclide_outline_view_nux'; +'use strict'; + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _OutlineViewPanel; + +function _load_OutlineViewPanel() { + return _OutlineViewPanel = require('../../../modules/atom-ide-ui/pkg/atom-ide-outline-view/lib/OutlineViewPanel'); +} + +var _ToolbarUtils; + +function _load_ToolbarUtils() { + return _ToolbarUtils = require('../../../modules/nuclide-commons-ui/ToolbarUtils'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const NUX_OUTLINE_VIEW_TOUR = 'nuclide_outline_view_nux'; /** + * 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. + * + * strict-local + * @format + */ + const NUX_OUTLINE_VIEW_ID = 4342; const GK_NUX_OUTLINE_VIEW = 'mp_nuclide_outline_view_nux'; class Activation { - _disposables: UniversalDisposable; constructor() { - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - consumeToolBar(getToolBar: toolbar$GetToolbar): IDisposable { + consumeToolBar(getToolBar) { const toolBar = getToolBar('outline-view'); - const {element} = toolBar.addButton( - makeToolbarButtonSpec({ - icon: 'list-unordered', - callback: 'outline-view:toggle', - tooltip: 'Toggle Outline', - priority: 200, - }), - ); + const { element } = toolBar.addButton((0, (_ToolbarUtils || _load_ToolbarUtils()).makeToolbarButtonSpec)({ + icon: 'list-unordered', + callback: 'outline-view:toggle', + tooltip: 'Toggle Outline', + priority: 200 + })); // Class added is not defined elsewhere, and is just used to mark the toolbar button element.classList.add('outline-view-toolbar-button'); - const disposable = new UniversalDisposable(() => { + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { toolBar.removeItems(); }); this._disposables.add(disposable); return disposable; } - _createOutlineViewNuxTourModel(): NuxTourModel { + _createOutlineViewNuxTourModel() { const outlineViewToolbarIconNux = { content: 'Check out the new Outline!', selector: '.outline-view-toolbar-button', position: 'auto', - completionPredicate: () => - document.querySelector('div.outline-view') != null, + completionPredicate: () => document.querySelector('div.outline-view') != null }; const outlineViewPanelNux = { content: 'Click on a symbol to jump to its definition.', selector: 'div.outline-view', - position: 'left', + position: 'left' }; const isValidFileTypeForNux = editor => { @@ -75,14 +88,12 @@ class Activation { return path.endsWith('.js') || path.endsWith('.php'); }; - const isOutlineViewClosed = () => - document.querySelector('div.outline-view') == null; - const triggerCallback = editor => - isOutlineViewClosed() && isValidFileTypeForNux(editor); + const isOutlineViewClosed = () => document.querySelector('div.outline-view') == null; + const triggerCallback = editor => isOutlineViewClosed() && isValidFileTypeForNux(editor); const nuxTriggerModel = { triggerType: 'editor', - triggerCallback, + triggerCallback }; const outlineViewNuxTour = { @@ -90,33 +101,32 @@ class Activation { name: NUX_OUTLINE_VIEW_TOUR, nuxList: [outlineViewToolbarIconNux, outlineViewPanelNux], trigger: nuxTriggerModel, - gatekeeperID: GK_NUX_OUTLINE_VIEW, + gatekeeperID: GK_NUX_OUTLINE_VIEW }; return outlineViewNuxTour; } - consumeRegisterNuxService(addNewNux: RegisterNux): IDisposable { + consumeRegisterNuxService(addNewNux) { const disposable = addNewNux(this._createOutlineViewNuxTourModel()); this._disposables.add(disposable); return disposable; } - getHomeFragments(): HomeFragments { + getHomeFragments() { return { feature: { title: 'Outline', icon: 'list-unordered', - description: - 'Displays major components of the current file (classes, methods, etc.)', + description: 'Displays major components of the current file (classes, methods, etc.)', command: () => { // eslint-disable-next-line nuclide-internal/atom-apis - atom.workspace.open(WORKSPACE_VIEW_URI, {searchAllPanes: true}); - }, + atom.workspace.open((_OutlineViewPanel || _load_OutlineViewPanel()).WORKSPACE_VIEW_URI, { searchAllPanes: true }); + } }, - priority: 2.5, // Between diff view and test runner + priority: 2.5 // Between diff view and test runner }; } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-project/lib/main.js b/pkg/nuclide-project/lib/main.js index 00fbad0eaa..a91bce69dd 100644 --- a/pkg/nuclide-project/lib/main.js +++ b/pkg/nuclide-project/lib/main.js @@ -1,49 +1,65 @@ -/** - * 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 - */ - -import createPackage from 'nuclide-commons-atom/createPackage'; -import {observeProjectPaths} from 'nuclide-commons-atom/projects'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; +'use strict'; + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _projects; + +function _load_projects() { + return _projects = require('../../../modules/nuclide-commons-atom/projects'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class Activation { - _disposables: UniversalDisposable; - - constructor(state: ?mixed) { - this._disposables = new UniversalDisposable( - observeProjectPaths(async projectPath => { - if (nuclideUri.isRemote(projectPath)) { - return; - } - const realPath = await fsPromise.realpath(projectPath); - if (realPath !== projectPath) { - atom.notifications.addWarning( - 'You have mounted a non-canonical project path. ' + - 'Nuclide only supports mounting canonical paths as local projects.
    ' + - 'Some Nuclide features such as Flow might not work properly.', - { - detail: - `Mounted path: ${projectPath}\n \n ` + - `Try re-mounting the canonical project path instead:\n${realPath}`, - }, - ); - } - }), - ); + + constructor(state) { + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default((0, (_projects || _load_projects()).observeProjectPaths)(async projectPath => { + if ((_nuclideUri || _load_nuclideUri()).default.isRemote(projectPath)) { + return; + } + const realPath = await (_fsPromise || _load_fsPromise()).default.realpath(projectPath); + if (realPath !== projectPath) { + atom.notifications.addWarning('You have mounted a non-canonical project path. ' + 'Nuclide only supports mounting canonical paths as local projects.
    ' + 'Some Nuclide features such as Flow might not work properly.', { + detail: `Mounted path: ${projectPath}\n \n ` + `Try re-mounting the canonical project path instead:\n${realPath}` + }); + } + })); } - dispose(): void { + dispose() { this._disposables.dispose(); } -} +} /** + * 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. + * + * + * @format + */ -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-projectionist/__tests__/main-test.js b/pkg/nuclide-projectionist/__tests__/main-test.js index b563f9c691..ec73fc473d 100644 --- a/pkg/nuclide-projectionist/__tests__/main-test.js +++ b/pkg/nuclide-projectionist/__tests__/main-test.js @@ -1,153 +1,130 @@ -/** - * 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 - */ - -import Projectionist from '../lib/main'; +'use strict'; + +var _main; + +function _load_main() { + return _main = _interopRequireDefault(require('../lib/main')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } describe('Projectionist', () => { describe('getAlternates', () => { it('returns an empty list when nothing matches', () => { - const projectionist = new Projectionist({ + const projectionist = new (_main || _load_main()).default({ 'src/main/java/*.java': { - alternate: 'src/test/java/{}.java', - }, + alternate: 'src/test/java/{}.java' + } }); - expect( - projectionist.getAlternates( - 'src/main/does-not-exist/java/FooAbstractServiceFactoryImpl.java', - ), - ).toEqual([]); + expect(projectionist.getAlternates('src/main/does-not-exist/java/FooAbstractServiceFactoryImpl.java')).toEqual([]); }); it('returns an empty list when it matches but there arent alternates', () => { - const projectionist = new Projectionist({ + const projectionist = new (_main || _load_main()).default({ 'src/main/java/*.java': { - make: 'build', - }, + make: 'build' + } }); - expect( - projectionist.getAlternates( - 'src/main/does-not-exist/java/FooAbstractServiceFactoryImpl.java', - ), - ).toEqual([]); + expect(projectionist.getAlternates('src/main/does-not-exist/java/FooAbstractServiceFactoryImpl.java')).toEqual([]); }); it('treats * as a generous glob', () => { - const projectionist = new Projectionist({ + const projectionist = new (_main || _load_main()).default({ 'pkg/*/*.js': { - alternate: 'pkg/{}/spec/{}-spec.js', - }, + alternate: 'pkg/{}/spec/{}-spec.js' + } }); - expect( - projectionist.getAlternates('pkg/commons-node/foo/bar/baz/cache.js'), - ).toEqual(['pkg/commons-node/spec/foo/bar/baz/cache-spec.js']); + expect(projectionist.getAlternates('pkg/commons-node/foo/bar/baz/cache.js')).toEqual(['pkg/commons-node/spec/foo/bar/baz/cache-spec.js']); }); it('returns a single matching alternate', () => { - const projectionist = new Projectionist({ + const projectionist = new (_main || _load_main()).default({ 'pkg/*/*.js': { - alternate: 'pkg/{}/spec/{}-spec.js', - }, + alternate: 'pkg/{}/spec/{}-spec.js' + } }); - expect(projectionist.getAlternates('pkg/commons-node/cache.js')).toEqual([ - 'pkg/commons-node/spec/cache-spec.js', - ]); + expect(projectionist.getAlternates('pkg/commons-node/cache.js')).toEqual(['pkg/commons-node/spec/cache-spec.js']); }); it('recurses with a global glob', () => { - const projectionist = new Projectionist({ + const projectionist = new (_main || _load_main()).default({ '*': { '*.c': { alternate: '{}.h', - type: 'source', - }, - }, + type: 'source' + } + } }); - expect(projectionist.getAlternates('/foo/bar/baz.c')).toEqual([ - '/foo/bar/baz.h', - ]); + expect(projectionist.getAlternates('/foo/bar/baz.c')).toEqual(['/foo/bar/baz.h']); }); it('recurses with a directory glob', () => { - const projectionist = new Projectionist({ + const projectionist = new (_main || _load_main()).default({ 'bin/scripts/': { 'bin/scripts/*.js': { - alternate: 'bin/scripts/{}-test.js', - }, - }, + alternate: 'bin/scripts/{}-test.js' + } + } }); - expect(projectionist.getAlternates('bin/scripts/foo.js')).toEqual([ - 'bin/scripts/foo-test.js', - ]); + expect(projectionist.getAlternates('bin/scripts/foo.js')).toEqual(['bin/scripts/foo-test.js']); }); it('returns all possible alternates', () => { - const projectionist = new Projectionist({ + const projectionist = new (_main || _load_main()).default({ 'pkg/*/spec/*-spec.js': { alternate: 'pkg/{}/lib/{}.js', - type: 'test', + type: 'test' }, 'pkg/*/*.js': { - alternate: 'pkg/{}/spec/{}-spec.js', - }, + alternate: 'pkg/{}/spec/{}-spec.js' + } }); - expect(projectionist.getAlternates('pkg/foo/spec/bar-spec.js')).toEqual([ - 'pkg/foo/lib/bar.js', - 'pkg/foo/spec/spec/bar-spec-spec.js', - ]); + expect(projectionist.getAlternates('pkg/foo/spec/bar-spec.js')).toEqual(['pkg/foo/lib/bar.js', 'pkg/foo/spec/spec/bar-spec-spec.js']); }); it('expands dirname and basename', () => { - const projectionist = new Projectionist({ + const projectionist = new (_main || _load_main()).default({ '**/__tests__/*-test.js': { alternate: '{dirname}/{basename}.js', - type: 'test', - }, + type: 'test' + } }); - expect( - projectionist.getAlternates('bin/scripts/__tests__/foo-test.js'), - ).toEqual(['bin/scripts/foo.js']); + expect(projectionist.getAlternates('bin/scripts/__tests__/foo-test.js')).toEqual(['bin/scripts/foo.js']); }); it('expands many dirname and basename', () => { - const projectionist = new Projectionist({ + const projectionist = new (_main || _load_main()).default({ '*.js': { - alternate: [ - '{dirname}/{basename}.test.js', - '{dirname}/__tests__/{basename}-test.js', - '{dirname}/__tests__/{basename}-mocha.js', - ], - type: 'source', - }, + alternate: ['{dirname}/{basename}.test.js', '{dirname}/__tests__/{basename}-test.js', '{dirname}/__tests__/{basename}-mocha.js'], + type: 'source' + } }); - expect(projectionist.getAlternates('bin/scripts/foo.js')).toEqual([ - 'bin/scripts/foo.test.js', - 'bin/scripts/__tests__/foo-test.js', - 'bin/scripts/__tests__/foo-mocha.js', - ]); + expect(projectionist.getAlternates('bin/scripts/foo.js')).toEqual(['bin/scripts/foo.test.js', 'bin/scripts/__tests__/foo-test.js', 'bin/scripts/__tests__/foo-mocha.js']); }); }); describe('getType', () => { it('returns the type of a given file', () => { - const projectionist = new Projectionist({ + const projectionist = new (_main || _load_main()).default({ 'bin/scripts/': { 'bin/scripts/*.js': { - type: 'script', - }, - }, + type: 'script' + } + } }); expect(projectionist.getType('bin/scripts/foo.js')).toEqual('script'); }); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-projectionist/lib/main.js b/pkg/nuclide-projectionist/lib/main.js index 9ab9ec0a49..d0d589ced0 100644 --- a/pkg/nuclide-projectionist/lib/main.js +++ b/pkg/nuclide-projectionist/lib/main.js @@ -1,3 +1,26 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _micromatch; + +function _load_micromatch() { + return _micromatch = _interopRequireDefault(require('micromatch')); +} + +var _path = _interopRequireDefault(require('path')); + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// eslint-disable-next-line nuclide-internal/prefer-nuclide-uri /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,115 +28,77 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {ProjectionistRules, Projection} from './types'; - -import micromatch from 'micromatch'; -// eslint-disable-next-line nuclide-internal/prefer-nuclide-uri -import path from 'path'; -import { - arrayFlatten, - arrayUnique, - arrayCompact, -} from 'nuclide-commons/collection'; - -export default class Projectionist { - rules: ProjectionistRules; +class Projectionist { - constructor(rules: ProjectionistRules) { + constructor(rules) { this.rules = rules; } - getAlternates(projectRelativePath: string): Array { - return mapProjections( - this.rules, - projectRelativePath, - (projection, matches) => { - const alternate = projection.alternate; - if (alternate == null) { - return []; - } - - const alternates = - typeof alternate === 'string' ? [alternate] : alternate; - - return alternates.map(alt => - replaceTargetsWithMatches(alt, matches, projectRelativePath), - ); - }, - ); + getAlternates(projectRelativePath) { + return mapProjections(this.rules, projectRelativePath, (projection, matches) => { + const alternate = projection.alternate; + if (alternate == null) { + return []; + } + + const alternates = typeof alternate === 'string' ? [alternate] : alternate; + + return alternates.map(alt => replaceTargetsWithMatches(alt, matches, projectRelativePath)); + }); } - getType(projectRelativePath: string): ?string { - return arrayCompact( - mapProjections(this.rules, projectRelativePath, projection => [ - projection.type, - ]), - )[0]; + getType(projectRelativePath) { + return (0, (_collection || _load_collection()).arrayCompact)(mapProjections(this.rules, projectRelativePath, projection => [projection.type]))[0]; } } -function mapProjections( - rules: ProjectionistRules, - projectRelativePath: string, - mapFn: (projection: Projection, matches: null | Array) => Array, -): Array { +exports.default = Projectionist; +function mapProjections(rules, projectRelativePath, mapFn) { const toFlatten = Object.keys(rules).map(pattern => { const value = rules[pattern]; if (isProjection(value)) { - const innerRules = ((value: any): ProjectionistRules); + const innerRules = value; return mapProjections(innerRules, projectRelativePath, mapFn); } else { - const projection = ((value: any): Projection); + const projection = value; - const matches = micromatch.capture( - normalizePattern(pattern), - projectRelativePath, - ); + const matches = (_micromatch || _load_micromatch()).default.capture(normalizePattern(pattern), projectRelativePath); - const matchesBaseName = micromatch.isMatch(projectRelativePath, pattern, { - matchBase: true, + const matchesBaseName = (_micromatch || _load_micromatch()).default.isMatch(projectRelativePath, pattern, { + matchBase: true }); - if ( - matches != null || - // basename matches ('*.c' to glob any c file) are treated specially - matchesBaseName || - // an exact prefix match is okay too - projectRelativePath.startsWith(pattern) - ) { + if (matches != null || + // basename matches ('*.c' to glob any c file) are treated specially + matchesBaseName || + // an exact prefix match is okay too + projectRelativePath.startsWith(pattern)) { return mapFn(projection, matches); } } }); - return arrayUnique(arrayFlatten(arrayCompact(toFlatten))); + return (0, (_collection || _load_collection()).arrayUnique)((0, (_collection || _load_collection()).arrayFlatten)((0, (_collection || _load_collection()).arrayCompact)(toFlatten))); } const RULES_KEY_RE = /\*|\//; -function isProjection(maybeProjection: Object): boolean { +function isProjection(maybeProjection) { return Object.keys(maybeProjection).some(key => key.match(RULES_KEY_RE)); } const keywordReplacements = { '{}': match => match, '{basename}': match => basenameWithoutExtension(match), - '{dirname}': match => match, + '{dirname}': match => match }; -function replaceTargetsWithMatches( - stringWithTargets: string, - matches: null | Array, - projectRelativePath: string, -) { +function replaceTargetsWithMatches(stringWithTargets, matches, projectRelativePath) { if (matches == null) { - return path.join( - path.dirname(projectRelativePath), - stringWithTargets.replace('{}', basenameWithoutExtension), - ); + return _path.default.join(_path.default.dirname(projectRelativePath), stringWithTargets.replace('{}', basenameWithoutExtension)); } const targets = stringWithTargets.match(/({.*?})/g); @@ -125,31 +110,23 @@ function replaceTargetsWithMatches( for (let i = 0; i < targets.length; i++) { const target = targets[i]; if (i === targets.length - 1 && targets.length < matches.length) { - replaced = replaced.replace( - target, - keywordReplacements[target](path.join(...matches.slice(i))), - ); + replaced = replaced.replace(target, keywordReplacements[target](_path.default.join(...matches.slice(i)))); } else { - replaced = replaced.replace( - target, - keywordReplacements[target](matches[i]), - ); + replaced = replaced.replace(target, keywordReplacements[target](matches[i])); } } return replaced; } // vim-projectionist seems to treat the last star as **/* rather than * -function normalizePattern(pattern: string) { +function normalizePattern(pattern) { const lastStarIndex = pattern.lastIndexOf('*'); if (lastStarIndex === -1) { return pattern; } - return ( - pattern.slice(0, lastStarIndex) + '**/*' + pattern.slice(lastStarIndex + 1) - ); + return pattern.slice(0, lastStarIndex) + '**/*' + pattern.slice(lastStarIndex + 1); } function basenameWithoutExtension(pathString) { - return path.basename(pathString, path.extname(pathString)); -} + return _path.default.basename(pathString, _path.default.extname(pathString)); +} \ No newline at end of file diff --git a/pkg/nuclide-projectionist/lib/types.js b/pkg/nuclide-projectionist/lib/types.js index 943214f067..9a390c31f7 100644 --- a/pkg/nuclide-projectionist/lib/types.js +++ b/pkg/nuclide-projectionist/lib/types.js @@ -1,26 +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 strict - * @format - */ - -export type ProjectionistRules = { - [fileGlob: string]: Projection | ProjectionistRules, -}; - -export type Projection = { - alternate?: string | Array, - console?: string, - dispatch?: string, - make?: string, - path?: string, - start?: string, - template?: string, - type?: string, - [string]: string, -}; +"use strict"; \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/__tests__/JediServerManager-test.js b/pkg/nuclide-python-rpc/__tests__/JediServerManager-test.js index e7ab38f163..d5e08691e2 100644 --- a/pkg/nuclide-python-rpc/__tests__/JediServerManager-test.js +++ b/pkg/nuclide-python-rpc/__tests__/JediServerManager-test.js @@ -1,30 +1,35 @@ -/** - * 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 - */ - -import fsPromise from 'nuclide-commons/fsPromise'; -import JediServerManager from '../lib/JediServerManager'; -import waitsFor from '../../../jest/waits_for'; +'use strict'; + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _JediServerManager; + +function _load_JediServerManager() { + return _JediServerManager = _interopRequireDefault(require('../lib/JediServerManager')); +} + +var _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../../../jest/waits_for')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } describe('JediServerManager', () => { let jediServerManager; beforeEach(() => { - jediServerManager = new JediServerManager(); + jediServerManager = new (_JediServerManager || _load_JediServerManager()).default(); }); it('caches syspaths by file name', async () => { const mockPath = '/a/b/c'; - const spy = jest - .spyOn(fsPromise, 'findFurthestFile') - .mockReturnValue(Promise.resolve(mockPath)); + const spy = jest.spyOn((_fsPromise || _load_fsPromise()).default, 'findFurthestFile').mockReturnValue(Promise.resolve(mockPath)); const sysPath = jediServerManager.getSysPath('/test/file.txt'); expect(sysPath).toEqual([]); @@ -32,11 +37,18 @@ describe('JediServerManager', () => { // Second call with the same source path should retrieve top-level module path // directly from cache. - (fsPromise.findFurthestFile: any).mockReset(); + (_fsPromise || _load_fsPromise()).default.findFurthestFile.mockReset(); expect(spy).not.toHaveBeenCalled(); - await waitsFor(() => - jediServerManager.getSysPath('/test/file.txt').includes(mockPath), - ); + await (0, (_waits_for || _load_waits_for()).default)(() => jediServerManager.getSysPath('/test/file.txt').includes(mockPath)); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/__tests__/LinkTreeManager-resolve-link-tree-path-test.js b/pkg/nuclide-python-rpc/__tests__/LinkTreeManager-resolve-link-tree-path-test.js index 5c22084b40..3eceef6044 100644 --- a/pkg/nuclide-python-rpc/__tests__/LinkTreeManager-resolve-link-tree-path-test.js +++ b/pkg/nuclide-python-rpc/__tests__/LinkTreeManager-resolve-link-tree-path-test.js @@ -1,3 +1,38 @@ +'use strict'; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _nuclideBuckRpc; + +function _load_nuclideBuckRpc() { + return _nuclideBuckRpc = _interopRequireWildcard(require('../../nuclide-buck-rpc')); +} + +var _LinkTreeManager; + +function _load_LinkTreeManager() { + return _LinkTreeManager = _interopRequireDefault(require('../lib/LinkTreeManager')); +} + +var _nuclideTestHelpers; + +function _load_nuclideTestHelpers() { + return _nuclideTestHelpers = require('../../nuclide-test-helpers'); +} + +var _path = _interopRequireDefault(require('path')); + +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 }; } + +jest.setTimeout(60000); + +// Disable buckd so it doesn't linger around after the test. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,24 +40,15 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import nuclideUri from 'nuclide-commons/nuclideUri'; -import * as BuckService from '../../nuclide-buck-rpc'; -import LinkTreeManager from '../lib/LinkTreeManager'; -import {copyBuildFixture} from '../../nuclide-test-helpers'; -import path from 'path'; - -jest.setTimeout(60000); - -// Disable buckd so it doesn't linger around after the test. process.env.NO_BUCKD = '1'; describe('LinkTreeManager', () => { - let linkTreeManager: LinkTreeManager = (null: any); - let projectDir: string = (null: any); + let linkTreeManager = null; + let projectDir = null; beforeEach(async () => { global.performance.mark = jest.fn(); @@ -31,20 +57,15 @@ describe('LinkTreeManager', () => { global.performance.clearMeasures = jest.fn(); if (projectDir == null) { - projectDir = await copyBuildFixture( - 'test-buck-project', - path.resolve(__dirname, '../__mocks__'), - ); + projectDir = await (0, (_nuclideTestHelpers || _load_nuclideTestHelpers()).copyBuildFixture)('test-buck-project', _path.default.resolve(__dirname, '../__mocks__')); } - linkTreeManager = new LinkTreeManager(); + linkTreeManager = new (_LinkTreeManager || _load_LinkTreeManager()).default(); }); // this test is very slow because it runs buck under the hood it("resolves a link tree path with a buck project's source file", async () => { - const srcPath = nuclideUri.join(projectDir, 'test1/test1.py'); + const srcPath = (_nuclideUri || _load_nuclideUri()).default.join(projectDir, 'test1/test1.py'); const linkTreePaths = await linkTreeManager.getLinkTreePaths(srcPath); - expect(linkTreePaths).toEqual([ - nuclideUri.join(projectDir, 'buck-out/gen/test1/testbin1#link-tree'), - ]); + expect(linkTreePaths).toEqual([(_nuclideUri || _load_nuclideUri()).default.join(projectDir, 'buck-out/gen/test1/testbin1#link-tree')]); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/__tests__/LinkTreeManager-test.js b/pkg/nuclide-python-rpc/__tests__/LinkTreeManager-test.js index e32baafe63..5044106eec 100644 --- a/pkg/nuclide-python-rpc/__tests__/LinkTreeManager-test.js +++ b/pkg/nuclide-python-rpc/__tests__/LinkTreeManager-test.js @@ -1,3 +1,38 @@ +'use strict'; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _nuclideBuckRpc; + +function _load_nuclideBuckRpc() { + return _nuclideBuckRpc = _interopRequireWildcard(require('../../nuclide-buck-rpc')); +} + +var _LinkTreeManager; + +function _load_LinkTreeManager() { + return _LinkTreeManager = _interopRequireDefault(require('../lib/LinkTreeManager')); +} + +var _nuclideTestHelpers; + +function _load_nuclideTestHelpers() { + return _nuclideTestHelpers = require('../../nuclide-test-helpers'); +} + +var _path = _interopRequireDefault(require('path')); + +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 }; } + +jest.setTimeout(35000); + +// Disable buckd so it doesn't linger around after the test. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,24 +40,15 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import nuclideUri from 'nuclide-commons/nuclideUri'; -import * as BuckService from '../../nuclide-buck-rpc'; -import LinkTreeManager from '../lib/LinkTreeManager'; -import {copyBuildFixture} from '../../nuclide-test-helpers'; -import path from 'path'; - -jest.setTimeout(35000); - -// Disable buckd so it doesn't linger around after the test. process.env.NO_BUCKD = '1'; describe('LinkTreeManager', () => { - let linkTreeManager: LinkTreeManager = (null: any); - let projectDir: string = (null: any); + let linkTreeManager = null; + let projectDir = null; beforeEach(async () => { global.performance.mark = jest.fn(); @@ -31,50 +57,38 @@ describe('LinkTreeManager', () => { global.performance.clearMeasures = jest.fn(); if (projectDir == null) { - projectDir = await copyBuildFixture( - 'test-buck-project', - path.resolve(__dirname, '../__mocks__'), - ); + projectDir = await (0, (_nuclideTestHelpers || _load_nuclideTestHelpers()).copyBuildFixture)('test-buck-project', _path.default.resolve(__dirname, '../__mocks__')); } - linkTreeManager = new LinkTreeManager(); + linkTreeManager = new (_LinkTreeManager || _load_LinkTreeManager()).default(); }); it('correctly builds a link tree path given a source file path (mocked project)', async () => { - jest - .spyOn(BuckService, 'getOwners') - .mockReturnValue(Promise.resolve(['//test:a', '//test2:a'])); - const spy = jest.spyOn(BuckService, 'queryWithAttributes').mockReturnValue({ + jest.spyOn(_nuclideBuckRpc || _load_nuclideBuckRpc(), 'getOwners').mockReturnValue(Promise.resolve(['//test:a', '//test2:a'])); + const spy = jest.spyOn(_nuclideBuckRpc || _load_nuclideBuckRpc(), 'queryWithAttributes').mockReturnValue({ '//test:x': { - 'buck.type': 'python_binary', + 'buck.type': 'python_binary' }, '//test:y': { - 'buck.type': 'python_test', - }, + 'buck.type': 'python_test' + } }); - const srcPath = nuclideUri.join(projectDir, 'test1/test1.py'); - const expectedPaths = [ - nuclideUri.join(projectDir, 'buck-out/gen/test/x#link-tree'), - nuclideUri.join(projectDir, 'buck-out/gen/test/y#binary,link-tree'), - ]; + const srcPath = (_nuclideUri || _load_nuclideUri()).default.join(projectDir, 'test1/test1.py'); + const expectedPaths = [(_nuclideUri || _load_nuclideUri()).default.join(projectDir, 'buck-out/gen/test/x#link-tree'), (_nuclideUri || _load_nuclideUri()).default.join(projectDir, 'buck-out/gen/test/y#binary,link-tree')]; const linkTreePaths = await linkTreeManager.getLinkTreePaths(srcPath); // rdeps query should be executed with the first owner found, and scoped to // the target's immediate neighbors. - expect(spy).toHaveBeenCalledWith( - projectDir, - 'kind("python_binary|python_test", rdeps(//test/..., //test:a))', - ['buck.type', 'deps'], - ); + expect(spy).toHaveBeenCalledWith(projectDir, 'kind("python_binary|python_test", rdeps(//test/..., //test:a))', ['buck.type', 'deps']); // Properly resolve a link-tree path based on the source's firstly found // binary dependency. expect(linkTreePaths).toEqual(expectedPaths); }); it('ignores TARGETS files', async () => { - jest.spyOn(BuckService, 'getOwners').mockImplementation(() => { + jest.spyOn(_nuclideBuckRpc || _load_nuclideBuckRpc(), 'getOwners').mockImplementation(() => { throw new Error('test'); }); - const srcPath = nuclideUri.join(projectDir, 'test1/TARGETS'); - expect(await linkTreeManager.getLinkTreePaths(srcPath)).toEqual([]); + const srcPath = (_nuclideUri || _load_nuclideUri()).default.join(projectDir, 'test1/TARGETS'); + expect((await linkTreeManager.getLinkTreePaths(srcPath))).toEqual([]); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/__tests__/PythonService-signature-test.js b/pkg/nuclide-python-rpc/__tests__/PythonService-signature-test.js index 86def6ccca..e15a1d7972 100644 --- a/pkg/nuclide-python-rpc/__tests__/PythonService-signature-test.js +++ b/pkg/nuclide-python-rpc/__tests__/PythonService-signature-test.js @@ -1,28 +1,41 @@ -/** - * 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 - */ - -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import JediServerManager from '../lib/JediServerManager'; - -const FIXTURE = nuclideUri.join( - __dirname, - '../__mocks__/fixtures/signature_help.py', -); +'use strict'; + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _JediServerManager; + +function _load_JediServerManager() { + return _JediServerManager = _interopRequireDefault(require('../lib/JediServerManager')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const FIXTURE = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures/signature_help.py'); /** + * 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. + * + * + * @format + */ describe('PythonService', () => { - let serverManager: JediServerManager = (null: any); + let serverManager = null; beforeEach(() => { - serverManager = new JediServerManager(); + serverManager = new (_JediServerManager || _load_JediServerManager()).default(); // Don't try to retrieve additional paths from Buck/etc. jest.spyOn(serverManager, 'getSysPath').mockReturnValue([]); }); @@ -33,86 +46,57 @@ describe('PythonService', () => { it('Returns signatures', async () => { await (async () => { - const contents = await fsPromise.readFile(FIXTURE, 'utf8'); + const contents = await (_fsPromise || _load_fsPromise()).default.readFile(FIXTURE, 'utf8'); const jediService = await serverManager.getJediService(); - expect( - await jediService.get_signature_help(FIXTURE, contents, [], 13, 0), - ).toBe(null); + expect((await jediService.get_signature_help(FIXTURE, contents, [], 13, 0))).toBe(null); // main() - expect( - await jediService.get_signature_help(FIXTURE, contents, [], 13, 5), - ).toEqual({ - signatures: [ - { - label: 'main(param1, param2)', - documentation: 'Main docstring', - parameters: [ - {label: 'param1', documentation: ''}, - {label: 'param2', documentation: ''}, - ], - }, - ], + expect((await jediService.get_signature_help(FIXTURE, contents, [], 13, 5))).toEqual({ + signatures: [{ + label: 'main(param1, param2)', + documentation: 'Main docstring', + parameters: [{ label: 'param1', documentation: '' }, { label: 'param2', documentation: '' }] + }], activeSignature: 0, - activeParameter: 0, + activeParameter: 0 }); // isinstance(obj) - expect( - await jediService.get_signature_help(FIXTURE, contents, [], 12, 11), - ).toEqual({ - signatures: [ - { - label: 'isinstance(obj, class_or_tuple)', - documentation: jasmine.any(String), - parameters: [ - {label: 'obj', documentation: ''}, - {label: 'class_or_tuple', documentation: ''}, - ], - }, - ], + expect((await jediService.get_signature_help(FIXTURE, contents, [], 12, 11))).toEqual({ + signatures: [{ + label: 'isinstance(obj, class_or_tuple)', + documentation: jasmine.any(String), + parameters: [{ label: 'obj', documentation: '' }, { label: 'class_or_tuple', documentation: '' }] + }], activeSignature: 0, - activeParameter: 0, + activeParameter: 0 }); // isinstance(obj, class) - expect( - await jediService.get_signature_help(FIXTURE, contents, [], 12, 18), - ).toEqual({ - signatures: [ - { - label: 'isinstance(obj, class_or_tuple)', - documentation: jasmine.any(String), - parameters: [ - {label: 'obj', documentation: ''}, - {label: 'class_or_tuple', documentation: ''}, - ], - }, - ], + expect((await jediService.get_signature_help(FIXTURE, contents, [], 12, 18))).toEqual({ + signatures: [{ + label: 'isinstance(obj, class_or_tuple)', + documentation: jasmine.any(String), + parameters: [{ label: 'obj', documentation: '' }, { label: 'class_or_tuple', documentation: '' }] + }], activeSignature: 0, - activeParameter: 1, + activeParameter: 1 }); // Don't return anything if we're inside the string. - expect( - await jediService.get_signature_help(FIXTURE, contents, [], 12, 13), - ).toEqual(null); + expect((await jediService.get_signature_help(FIXTURE, contents, [], 12, 13))).toEqual(null); // len() - expect( - await jediService.get_signature_help(FIXTURE, contents, [], 11, 4), - ).toEqual({ - signatures: [ - { - label: 'len(obj)', - documentation: 'Return the number of items in a container.', - parameters: [{label: 'obj', documentation: ''}], - }, - ], + expect((await jediService.get_signature_help(FIXTURE, contents, [], 11, 4))).toEqual({ + signatures: [{ + label: 'len(obj)', + documentation: 'Return the number of items in a container.', + parameters: [{ label: 'obj', documentation: '' }] + }], activeSignature: 0, - activeParameter: 0, + activeParameter: 0 }); })(); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/__tests__/PythonService-test.js b/pkg/nuclide-python-rpc/__tests__/PythonService-test.js index 51caed613b..3583d97519 100644 --- a/pkg/nuclide-python-rpc/__tests__/PythonService-test.js +++ b/pkg/nuclide-python-rpc/__tests__/PythonService-test.js @@ -1,3 +1,55 @@ +'use strict'; + +var _fs = _interopRequireDefault(require('fs')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _PythonService; + +function _load_PythonService() { + return _PythonService = require('../lib/PythonService'); +} + +var _DefinitionHelpers; + +function _load_DefinitionHelpers() { + return _DefinitionHelpers = require('../lib/DefinitionHelpers'); +} + +var _AutocompleteHelpers; + +function _load_AutocompleteHelpers() { + return _AutocompleteHelpers = require('../lib/AutocompleteHelpers'); +} + +var _JediServerManager; + +function _load_JediServerManager() { + return _JediServerManager = _interopRequireDefault(require('../lib/JediServerManager')); +} + +var _simpleTextBuffer; + +function _load_simpleTextBuffer() { + return _simpleTextBuffer = _interopRequireDefault(require('simple-text-buffer')); +} + +var _simpleTextBuffer2; + +function _load_simpleTextBuffer2() { + return _simpleTextBuffer2 = require('simple-text-buffer'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// make sure we don't save absolute paths in snapshots +const replacePath = str => str.replace(/.*__mocks__/, '/__mocks__'); + +// Test python file located at fixtures/serverdummy.py /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,52 +57,34 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import invariant from 'assert'; -import fs from 'fs'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {_getReferences} from '../lib/PythonService'; -import {getDefinition} from '../lib/DefinitionHelpers'; -import {getCompletions} from '../lib/AutocompleteHelpers'; -import JediServerManager from '../lib/JediServerManager'; -import TextBuffer from 'simple-text-buffer'; -import {Point} from 'simple-text-buffer'; - -// make sure we don't save absolute paths in snapshots -const replacePath = str => str.replace(/.*__mocks__/, '/__mocks__'); - -// Test python file located at fixtures/serverdummy.py -const TEST_FILE = nuclideUri.join( - __dirname, - '../__mocks__/fixtures', - 'serverdummy.py', -); -const FILE_CONTENTS = fs.readFileSync(TEST_FILE).toString('utf8'); +const TEST_FILE = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures', 'serverdummy.py'); +const FILE_CONTENTS = _fs.default.readFileSync(TEST_FILE).toString('utf8'); // Disable buckd so it doesn't linger around after the test. process.env.NO_BUCKD = '1'; -function bufferOfContents(contents: string): simpleTextBuffer$TextBuffer { - return new TextBuffer(contents); +function bufferOfContents(contents) { + return new (_simpleTextBuffer || _load_simpleTextBuffer()).default(contents); } // Line/column actual offsets are 0-indexed in this test, similar to what atom // provides as input. describe('PythonService', () => { - let serverManager: JediServerManager = (null: any); + let serverManager = null; - beforeEach(function() { - serverManager = new JediServerManager(); + beforeEach(function () { + serverManager = new (_JediServerManager || _load_JediServerManager()).default(); // Don't try to retrieve additional paths from Buck/etc. jest.spyOn(serverManager, 'getSysPath').mockReturnValue([]); }); afterEach(() => { serverManager.reset(); - serverManager = (null: any); + serverManager = null; }); describe('Completions', () => { @@ -58,9 +92,12 @@ describe('PythonService', () => { await (async () => { // Basically everything is wrong here, but politely reject the promise. try { - await getCompletions(serverManager, 'potato', 'tomato', 6, 15); + await (0, (_AutocompleteHelpers || _load_AutocompleteHelpers()).getCompletions)(serverManager, 'potato', 'tomato', 6, 15); // Fail - this line should not be reachable. - invariant(false); + + if (!false) { + throw new Error('Invariant violation: "false"'); + } } catch (e) { // Python process should respond with a Traceback for what went wrong while // processing the request. @@ -72,14 +109,12 @@ describe('PythonService', () => { it('can make completion suggestions for imported module member functions', async () => { await (async () => { // line 12: def hello = os.path.isab - const response = await getCompletions( - serverManager, - TEST_FILE, - FILE_CONTENTS, - 11, - 20, - ); - invariant(response); + const response = await (0, (_AutocompleteHelpers || _load_AutocompleteHelpers()).getCompletions)(serverManager, TEST_FILE, FILE_CONTENTS, 11, 20); + + if (!response) { + throw new Error('Invariant violation: "response"'); + } + expect(response.length).toBeGreaterThan(0); const completion = response[0]; @@ -93,14 +128,12 @@ describe('PythonService', () => { it('can make completion suggestions for locally defined variables', async () => { await (async () => { // line 14: potato2 = po - const response = await getCompletions( - serverManager, - TEST_FILE, - FILE_CONTENTS, - 13, - 12, - ); - invariant(response); + const response = await (0, (_AutocompleteHelpers || _load_AutocompleteHelpers()).getCompletions)(serverManager, TEST_FILE, FILE_CONTENTS, 13, 12); + + if (!response) { + throw new Error('Invariant violation: "response"'); + } + expect(response.length).toBeGreaterThan(0); const completion = response[0]; @@ -112,14 +145,12 @@ describe('PythonService', () => { it('does not return params for @property methods', async () => { await (async () => { // line 18: a.t - const response = await getCompletions( - serverManager, - TEST_FILE, - FILE_CONTENTS, - 17, - 3, - ); - invariant(response); + const response = await (0, (_AutocompleteHelpers || _load_AutocompleteHelpers()).getCompletions)(serverManager, TEST_FILE, FILE_CONTENTS, 17, 3); + + if (!response) { + throw new Error('Invariant violation: "response"'); + } + expect(response.length).toBeGreaterThan(0); const completion = response[0]; @@ -132,14 +163,12 @@ describe('PythonService', () => { it('includes parameters for assignment completions', async () => { await (async () => { // line 26: a = Tes - const response = await getCompletions( - serverManager, - TEST_FILE, - FILE_CONTENTS, - 25, - 7, - ); - invariant(response); + const response = await (0, (_AutocompleteHelpers || _load_AutocompleteHelpers()).getCompletions)(serverManager, TEST_FILE, FILE_CONTENTS, 25, 7); + + if (!response) { + throw new Error('Invariant violation: "response"'); + } + expect(response.length).toBeGreaterThan(0); const completion = response[0]; @@ -152,14 +181,12 @@ describe('PythonService', () => { it('does not include parameters for import statement completions', async () => { await (async () => { // line 9: from decorated import Test - const response = await getCompletions( - serverManager, - TEST_FILE, - FILE_CONTENTS, - 8, - 26, - ); - invariant(response); + const response = await (0, (_AutocompleteHelpers || _load_AutocompleteHelpers()).getCompletions)(serverManager, TEST_FILE, FILE_CONTENTS, 8, 26); + + if (!response) { + throw new Error('Invariant violation: "response"'); + } + expect(response.length).toBeGreaterThan(0); const completion = response[0]; @@ -178,7 +205,10 @@ describe('PythonService', () => { const service = await serverManager.getJediService(); await service.get_definitions('potato', 'tomato', [], 6, 15); // Fail - this line should not be reachable. - invariant(false); + + if (!false) { + throw new Error('Invariant violation: "false"'); + } } catch (e) { // Python process should respond with a Traceback for what went wrong while // processing the request. @@ -190,13 +220,12 @@ describe('PythonService', () => { it('can find definitions for imported modules', async () => { await (async () => { // line 9: import os - const response = await getDefinition( - serverManager, - TEST_FILE, - bufferOfContents(FILE_CONTENTS), - new Point(7, 8), - ); - invariant(response != null); + const response = await (0, (_DefinitionHelpers || _load_DefinitionHelpers()).getDefinition)(serverManager, TEST_FILE, bufferOfContents(FILE_CONTENTS), new (_simpleTextBuffer2 || _load_simpleTextBuffer2()).Point(7, 8)); + + if (!(response != null)) { + throw new Error('Invariant violation: "response != null"'); + } + expect(response.definitions.length).toBeGreaterThan(0); const definition = response.definitions[0]; @@ -209,13 +238,12 @@ describe('PythonService', () => { it('follows imports until a non-import definition when possible', async () => { await (async () => { // line 17: a = Test() - const response = await getDefinition( - serverManager, - TEST_FILE, - bufferOfContents(FILE_CONTENTS), - new Point(16, 7), - ); - invariant(response != null); + const response = await (0, (_DefinitionHelpers || _load_DefinitionHelpers()).getDefinition)(serverManager, TEST_FILE, bufferOfContents(FILE_CONTENTS), new (_simpleTextBuffer2 || _load_simpleTextBuffer2()).Point(16, 7)); + + if (!(response != null)) { + throw new Error('Invariant violation: "response != null"'); + } + expect(response.definitions.length).toBeGreaterThan(0); const definition = response.definitions[0]; @@ -230,12 +258,7 @@ describe('PythonService', () => { it('does not follow unresolvable imports', async () => { await (async () => { // line 27: b = Test2() - const response = await getDefinition( - serverManager, - TEST_FILE, - bufferOfContents(FILE_CONTENTS), - new Point(26, 7), - ); + const response = await (0, (_DefinitionHelpers || _load_DefinitionHelpers()).getDefinition)(serverManager, TEST_FILE, bufferOfContents(FILE_CONTENTS), new (_simpleTextBuffer2 || _load_simpleTextBuffer2()).Point(26, 7)); expect(response).toBe(null); })(); }); @@ -243,13 +266,12 @@ describe('PythonService', () => { it('can find the definitions of locally defined variables', async () => { await (async () => { // line 15: potato3 = potato - const response = await getDefinition( - serverManager, - TEST_FILE, - bufferOfContents(FILE_CONTENTS), - new Point(14, 12), - ); - invariant(response != null); + const response = await (0, (_DefinitionHelpers || _load_DefinitionHelpers()).getDefinition)(serverManager, TEST_FILE, bufferOfContents(FILE_CONTENTS), new (_simpleTextBuffer2 || _load_simpleTextBuffer2()).Point(14, 12)); + + if (!(response != null)) { + throw new Error('Invariant violation: "response != null"'); + } + expect(response.definitions.length).toBeGreaterThan(0); const definition = response.definitions[0]; @@ -265,70 +287,54 @@ describe('PythonService', () => { it('can find the references of locally defined variables', async () => { await (async () => { // line 13: potato = 5 - const response = await _getReferences( - serverManager, - TEST_FILE, - FILE_CONTENTS, - 12, - 2, - ); - invariant(response); - - expect(response).toEqual([ - { - type: 'statement', - text: 'potato', - file: TEST_FILE, - line: 12, - column: 0, - }, - { - type: 'statement', - text: 'potato', - file: TEST_FILE, - line: 14, - column: 10, - }, - ]); + const response = await (0, (_PythonService || _load_PythonService())._getReferences)(serverManager, TEST_FILE, FILE_CONTENTS, 12, 2); + + if (!response) { + throw new Error('Invariant violation: "response"'); + } + + expect(response).toEqual([{ + type: 'statement', + text: 'potato', + file: TEST_FILE, + line: 12, + column: 0 + }, { + type: 'statement', + text: 'potato', + file: TEST_FILE, + line: 14, + column: 10 + }]); })(); }); it('can find the references of imported modules', async () => { // line 29: import decorated - const response = await _getReferences( - serverManager, - TEST_FILE, - FILE_CONTENTS, - 28, - 8, - ); - invariant(response); - - expect( - response.map(o => { - o.file = replacePath(o.file); - return o; - }), - ).toMatchSnapshot(); + const response = await (0, (_PythonService || _load_PythonService())._getReferences)(serverManager, TEST_FILE, FILE_CONTENTS, 28, 8); + + if (!response) { + throw new Error('Invariant violation: "response"'); + } + + expect(response.map(o => { + o.file = replacePath(o.file); + return o; + })).toMatchSnapshot(); }); it('displays the caller name for references within functions', async () => { // line 13: potato = 5 - const response = await _getReferences( - serverManager, - TEST_FILE, - FILE_CONTENTS, - 19, - 2, - ); - invariant(response); - - expect( - response.map(o => { - o.file = replacePath(o.file); - return o; - }), - ).toMatchSnapshot(); + const response = await (0, (_PythonService || _load_PythonService())._getReferences)(serverManager, TEST_FILE, FILE_CONTENTS, 19, 2); + + if (!response) { + throw new Error('Invariant violation: "response"'); + } + + expect(response.map(o => { + o.file = replacePath(o.file); + return o; + })).toMatchSnapshot(); }); }); @@ -338,15 +344,11 @@ describe('PythonService', () => { return service.get_outline(src, contents); } - async function checkOutlineTree(testName: string) { - const dirName = nuclideUri.join( - __dirname, - '../__mocks__/fixtures', - 'outline-tests', - ); + async function checkOutlineTree(testName) { + const dirName = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures', 'outline-tests'); - const srcPath = nuclideUri.join(dirName, testName + '.py'); - const srcContents = fs.readFileSync(srcPath).toString('utf8'); + const srcPath = (_nuclideUri || _load_nuclideUri()).default.join(dirName, testName + '.py'); + const srcContents = _fs.default.readFileSync(srcPath).toString('utf8'); const response = await getOutline(srcPath, srcContents); expect(response).toMatchSnapshot(); @@ -375,11 +377,8 @@ describe('PythonService', () => { describe('Module Resolution', () => { it('can resolve imports that are relative to the top-level module', async () => { - const projectFile = nuclideUri.join( - __dirname, - '../__mocks__/fixtures/test-project/testdir/lib/test2.py', - ); - const src = fs.readFileSync(projectFile).toString('utf8'); + const projectFile = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures/test-project/testdir/lib/test2.py'); + const src = _fs.default.readFileSync(projectFile).toString('utf8'); // Test completion of a module name relative to the tlm. let response; @@ -388,10 +387,13 @@ describe('PythonService', () => { while (response == null || response.length === 0) { // line 7: from potato import h // eslint-disable-next-line no-await-in-loop - response = await getCompletions(serverManager, projectFile, src, 6, 28); + response = await (0, (_AutocompleteHelpers || _load_AutocompleteHelpers()).getCompletions)(serverManager, projectFile, src, 6, 28); + } + + if (!response) { + throw new Error('Invariant violation: "response"'); } - invariant(response); const completion = response[0]; expect(completion.text).toEqual('hello_world'); expect(completion.type).toEqual('function'); @@ -402,17 +404,14 @@ describe('PythonService', () => { it('displays the docblock for a definition', async () => { await (async () => { const service = await serverManager.getJediService(); - const response = await service.get_hover( - TEST_FILE, - FILE_CONTENTS, - [], - 'Test', - 30, - 16, - ); - invariant(response != null); + const response = await service.get_hover(TEST_FILE, FILE_CONTENTS, [], 'Test', 30, 16); + + if (!(response != null)) { + throw new Error('Invariant violation: "response != null"'); + } + expect(response).toBe('This is a \\*test class.'); })(); }); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/__tests__/outline-test.js b/pkg/nuclide-python-rpc/__tests__/outline-test.js index 91bd9878c4..124239ea09 100644 --- a/pkg/nuclide-python-rpc/__tests__/outline-test.js +++ b/pkg/nuclide-python-rpc/__tests__/outline-test.js @@ -1,3 +1,27 @@ +'use strict'; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _fs = _interopRequireDefault(require('fs')); + +var _outline; + +function _load_outline() { + return _outline = require('../lib/outline'); +} + +var _nuclideTestHelpers; + +function _load_nuclideTestHelpers() { + return _nuclideTestHelpers = require('../../nuclide-test-helpers'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,33 +29,22 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import nuclideUri from 'nuclide-commons/nuclideUri'; -import fs from 'fs'; -import {itemsToOutline} from '../lib/outline'; -import {addMatchers} from '../../nuclide-test-helpers'; - describe('Python outline', () => { it('converts from JSON to outline', () => { // Test using a fixture file containing the json representation of // the PythonService.getOutline result. We're only testing the conversion // of the raw outline to an OutlineTree, without calling the service. - const outlinePath = nuclideUri.join( - __dirname, - '../__mocks__/fixtures/t.json', - ); - const resultPath = nuclideUri.join( - __dirname, - '../__mocks__/fixtures/t_expected_result.json', - ); - - const outlineItems = JSON.parse(fs.readFileSync(outlinePath, 'utf8')); - const expectedResult = JSON.parse(fs.readFileSync(resultPath, 'utf8')); - - const result = itemsToOutline('all' /* mode */, outlineItems); + const outlinePath = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures/t.json'); + const resultPath = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures/t_expected_result.json'); + + const outlineItems = JSON.parse(_fs.default.readFileSync(outlinePath, 'utf8')); + const expectedResult = JSON.parse(_fs.default.readFileSync(resultPath, 'utf8')); + + const result = (0, (_outline || _load_outline()).itemsToOutline)('all' /* mode */, outlineItems); expect(result).toEqual(expectedResult); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/lib/AutocompleteHelpers.js b/pkg/nuclide-python-rpc/lib/AutocompleteHelpers.js index 9199a1faa5..0b4447c6b8 100644 --- a/pkg/nuclide-python-rpc/lib/AutocompleteHelpers.js +++ b/pkg/nuclide-python-rpc/lib/AutocompleteHelpers.js @@ -1,20 +1,16 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {PythonCompletion} from './PythonService'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {AutocompleteResult} from '../../nuclide-language-service/lib/LanguageService'; -import type JediServerManager from './JediServerManager'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getAutocompleteSuggestions = getAutocompleteSuggestions; +exports.getCompletions = getCompletions; -import {matchRegexEndingAt} from 'nuclide-commons/range'; +var _range; + +function _load_range() { + return _range = require('../../../modules/nuclide-commons/range'); +} // Type mappings between Jedi types and autocomplete-plus types used for styling. const TYPES = { @@ -26,8 +22,17 @@ const TYPES = { statement: 'variable', import: 'import', param: 'variable', - property: 'property', -}; + property: 'property' +}; /** + * 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. + * + * strict-local + * @format + */ const TRIGGER_REGEX = /(\.|[a-zA-Z_][a-zA-Z0-9_]*)$/; @@ -41,17 +46,9 @@ const TRIGGER_REGEX = /(\.|[a-zA-Z_][a-zA-Z0-9_]*)$/; * instead of plain text. * @return string Textual representation of the completion. */ -function getText( - completion: PythonCompletion, - includeOptionalArgs: boolean = true, - createPlaceholders: boolean = false, -): string { +function getText(completion, includeOptionalArgs = true, createPlaceholders = false) { if (completion.params) { - const params = includeOptionalArgs - ? completion.params - : completion.params.filter( - param => param.indexOf('=') < 0 && param.indexOf('*') < 0, - ); + const params = includeOptionalArgs ? completion.params : completion.params.filter(param => param.indexOf('=') < 0 && param.indexOf('*') < 0); const paramTexts = params.map((param, index) => { return createPlaceholders ? `\${${index + 1}:${param}}` : param; @@ -62,70 +59,36 @@ function getText( return completion.text; } -export async function getAutocompleteSuggestions( - serverManager: JediServerManager, - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, - activatedManually: boolean, - autocompleteArguments: boolean, - includeOptionalArguments: boolean, -): Promise { - if ( - !activatedManually && - matchRegexEndingAt(buffer, position, TRIGGER_REGEX) == null - ) { - return {isIncomplete: false, items: []}; +async function getAutocompleteSuggestions(serverManager, filePath, buffer, position, activatedManually, autocompleteArguments, includeOptionalArguments) { + if (!activatedManually && (0, (_range || _load_range()).matchRegexEndingAt)(buffer, position, TRIGGER_REGEX) == null) { + return { isIncomplete: false, items: [] }; } - const results = await getCompletions( - serverManager, - filePath, - buffer.getText(), - position.row, - position.column, - ); + const results = await getCompletions(serverManager, filePath, buffer.getText(), position.row, position.column); if (results == null) { - return {isIncomplete: false, items: []}; + return { isIncomplete: false, items: [] }; } const items = results.map(completion => { // Always display optional arguments in the UI. const displayText = getText(completion); // Only autocomplete arguments if the include optional arguments setting is on. - const snippet = autocompleteArguments - ? getText( - completion, - includeOptionalArguments, - true /* createPlaceholders */, - ) - : completion.text; + const snippet = autocompleteArguments ? getText(completion, includeOptionalArguments, true /* createPlaceholders */ + ) : completion.text; return { displayText, snippet, type: TYPES[completion.type], - description: completion.description, + description: completion.description }; }); return { isIncomplete: false, - items, + items }; } -export async function getCompletions( - serverManager: JediServerManager, - src: NuclideUri, - contents: string, - line: number, - column: number, -): Promise> { +async function getCompletions(serverManager, src, contents, line, column) { const service = await serverManager.getJediService(); - return service.get_completions( - src, - contents, - serverManager.getSysPath(src), - line, - column, - ); -} + return service.get_completions(src, contents, serverManager.getSysPath(src), line, column); +} \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/lib/DefinitionHelpers.js b/pkg/nuclide-python-rpc/lib/DefinitionHelpers.js index 282fb321f7..ae5d50c0d4 100644 --- a/pkg/nuclide-python-rpc/lib/DefinitionHelpers.js +++ b/pkg/nuclide-python-rpc/lib/DefinitionHelpers.js @@ -1,3 +1,28 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getDefinition = getDefinition; + +var _simpleTextBuffer; + +function _load_simpleTextBuffer() { + return _simpleTextBuffer = require('simple-text-buffer'); +} + +var _range; + +function _load_range() { + return _range = require('../../../modules/nuclide-commons/range'); +} + +var _constants; + +function _load_constants() { + return _constants = require('./constants'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,61 +30,38 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {DefinitionQueryResult} from 'atom-ide-ui'; -import type JediServerManager from '../lib/JediServerManager'; - -import {Point} from 'simple-text-buffer'; -import {wordAtPositionFromBuffer} from 'nuclide-commons/range'; -import {IDENTIFIER_REGEXP} from './constants'; - -export async function getDefinition( - serverManager: JediServerManager, - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, -): Promise { - const wordMatch = wordAtPositionFromBuffer( - buffer, - position, - IDENTIFIER_REGEXP, - ); +async function getDefinition(serverManager, filePath, buffer, position) { + const wordMatch = (0, (_range || _load_range()).wordAtPositionFromBuffer)(buffer, position, (_constants || _load_constants()).IDENTIFIER_REGEXP); if (wordMatch == null) { return null; } - const {range} = wordMatch; + const { range } = wordMatch; const line = position.row; const column = position.column; const contents = buffer.getText(); const service = await serverManager.getJediService(); - const result = await service.get_definitions( - filePath, - contents, - serverManager.getSysPath(filePath), - line, - column, - ); + const result = await service.get_definitions(filePath, contents, serverManager.getSysPath(filePath), line, column); if (result == null || result.length === 0) { return null; } const definitions = result.map(definition => ({ path: definition.file, - position: new Point(definition.line, definition.column), + position: new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(definition.line, definition.column), id: definition.text, name: definition.text, - language: 'python', + language: 'python' })); return { queryRange: [range], - definitions, + definitions }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/lib/JediServer.js b/pkg/nuclide-python-rpc/lib/JediServer.js index 7f0df0e2cb..47fec90bde 100644 --- a/pkg/nuclide-python-rpc/lib/JediServer.js +++ b/pkg/nuclide-python-rpc/lib/JediServer.js @@ -1,44 +1,68 @@ -/** - * 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 strict-local - * @format - */ - -import typeof * as JediService from './JediService'; - -import invariant from 'assert'; -import {Observable} from 'rxjs'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {getOriginalEnvironment, spawn} from 'nuclide-commons/process'; -import which from 'nuclide-commons/which'; -import {RpcProcess} from '../../nuclide-rpc'; -import {ServiceRegistry, loadServicesConfig} from '../../nuclide-rpc'; -import {localNuclideUriMarshalers} from '../../nuclide-marshalers-common'; - -const LIB_PATH = nuclideUri.join(__dirname, '../VendorLib'); -const PROCESS_PATH = nuclideUri.join(__dirname, '../python/jediserver.py'); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _which; + +function _load_which() { + return _which = _interopRequireDefault(require('../../../modules/nuclide-commons/which')); +} + +var _nuclideRpc; + +function _load_nuclideRpc() { + return _nuclideRpc = require('../../nuclide-rpc'); +} + +var _nuclideMarshalersCommon; + +function _load_nuclideMarshalersCommon() { + return _nuclideMarshalersCommon = require('../../nuclide-marshalers-common'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const LIB_PATH = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../VendorLib'); /** + * 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. + * + * strict-local + * @format + */ + +const PROCESS_PATH = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../python/jediserver.py'); const OPTS = { - cwd: nuclideUri.dirname(PROCESS_PATH), + cwd: (_nuclideUri || _load_nuclideUri()).default.dirname(PROCESS_PATH), stdio: 'pipe', detached: false, // When Atom is killed, server process should be killed. - env: {...process.env, PYTHONPATH: LIB_PATH}, - /* TODO(T17353599) */ isExitError: () => false, + env: Object.assign({}, process.env, { PYTHONPATH: LIB_PATH }), + /* TODO(T17353599) */isExitError: () => false }; -let serviceRegistry: ?ServiceRegistry = null; +let serviceRegistry = null; -function getServiceRegistry(): ServiceRegistry { +function getServiceRegistry() { if (serviceRegistry == null) { - serviceRegistry = new ServiceRegistry( - [localNuclideUriMarshalers], - loadServicesConfig(nuclideUri.join(__dirname, '..')), - 'python_language_service', - ); + serviceRegistry = new (_nuclideRpc || _load_nuclideRpc()).ServiceRegistry([(_nuclideMarshalersCommon || _load_nuclideMarshalersCommon()).localNuclideUriMarshalers], (0, (_nuclideRpc || _load_nuclideRpc()).loadServicesConfig)((_nuclideUri || _load_nuclideUri()).default.join(__dirname, '..')), 'python_language_service'); } return serviceRegistry; } @@ -51,70 +75,63 @@ async function getServerArgs() { // $FlowFB const findJediServerArgs = require('./fb/find-jedi-server-args').default; overrides = await findJediServerArgs(); - } catch (e) { - // Ignore. - } + } catch (e) {} + // Ignore. + // Append the user's PYTHONPATH if it exists. - const {PYTHONPATH} = await getOriginalEnvironment(); + const { PYTHONPATH } = await (0, (_process || _load_process()).getOriginalEnvironment)(); if (PYTHONPATH != null && PYTHONPATH.trim() !== '') { - overrides.paths = (overrides.paths || []).concat( - nuclideUri.splitPathList(PYTHONPATH), - ); + overrides.paths = (overrides.paths || []).concat((_nuclideUri || _load_nuclideUri()).default.splitPathList(PYTHONPATH)); } // Jedi only parses Python3 files if we start with Python3. // It's not the end of the world if Python3 isn't available, though. let pythonPath = 'python'; if (overrides.pythonPath == null) { - const python3Path = await which('python3'); + const python3Path = await (0, (_which || _load_which()).default)('python3'); if (python3Path != null) { pythonPath = python3Path; } } - return { + return Object.assign({ // Default to assuming that python is in system PATH. pythonPath, - paths: [], - ...overrides, - }; + paths: [] + }, overrides); } -export default class JediServer { - _process: RpcProcess; - _isDisposed: boolean; +class JediServer { constructor() { - const processStream = Observable.fromPromise(getServerArgs()).switchMap( - ({pythonPath, paths}) => { - let args = [PROCESS_PATH]; - if (paths.length > 0) { - args.push('-p'); - args = args.concat(paths); - } - return spawn(pythonPath, args, OPTS); - }, - ); - this._process = new RpcProcess( - 'JediServer', - getServiceRegistry(), - processStream, - ); + const processStream = _rxjsBundlesRxMinJs.Observable.fromPromise(getServerArgs()).switchMap(({ pythonPath, paths }) => { + let args = [PROCESS_PATH]; + if (paths.length > 0) { + args.push('-p'); + args = args.concat(paths); + } + return (0, (_process || _load_process()).spawn)(pythonPath, args, OPTS); + }); + this._process = new (_nuclideRpc || _load_nuclideRpc()).RpcProcess('JediServer', getServiceRegistry(), processStream); this._isDisposed = false; } - getService(): Promise { - invariant(!this._isDisposed, 'getService called on disposed JediServer'); + getService() { + if (!!this._isDisposed) { + throw new Error('getService called on disposed JediServer'); + } + return this._process.getService('JediService'); } - isDisposed(): boolean { + isDisposed() { return this._isDisposed; } - dispose(): void { + dispose() { this._isDisposed = true; this._process.dispose(); } } +exports.default = JediServer; \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/lib/JediServerManager.js b/pkg/nuclide-python-rpc/lib/JediServerManager.js index fcdef07bc4..abf10ea8ee 100644 --- a/pkg/nuclide-python-rpc/lib/JediServerManager.js +++ b/pkg/nuclide-python-rpc/lib/JediServerManager.js @@ -1,34 +1,45 @@ -/** - * 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 - */ - -import typeof * as JediService from './JediService'; - -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import JediServer from './JediServer'; -import LinkTreeManager from './LinkTreeManager'; - -export default class JediServerManager { - _linkTreeManager: LinkTreeManager; - _sysPathMap: Map>; - _server: ?JediServer; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _JediServer; + +function _load_JediServer() { + return _JediServer = _interopRequireDefault(require('./JediServer')); +} + +var _LinkTreeManager; + +function _load_LinkTreeManager() { + return _LinkTreeManager = _interopRequireDefault(require('./LinkTreeManager')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class JediServerManager { constructor() { - this._linkTreeManager = new LinkTreeManager(); + this._linkTreeManager = new (_LinkTreeManager || _load_LinkTreeManager()).default(); this._sysPathMap = new Map(); } - getJediService(): Promise { + getJediService() { if (this._server == null) { - this._server = new JediServer(); + this._server = new (_JediServer || _load_JediServer()).default(); } return this._server.getService(); } @@ -37,7 +48,7 @@ export default class JediServerManager { * It's fine if the syspath changes over time. * We'll return partial results while we fetch the actual values. */ - getSysPath(src: string): Array { + getSysPath(src) { const cachedSysPath = this._sysPathMap.get(src); if (cachedSysPath == null) { const sysPath = []; @@ -58,25 +69,33 @@ export default class JediServerManager { return cachedSysPath; } - reset(): void { + reset() { if (this._server != null) { this._server.dispose(); this._server = null; } this._sysPathMap.clear(); - this._linkTreeManager = new LinkTreeManager(); + this._linkTreeManager = new (_LinkTreeManager || _load_LinkTreeManager()).default(); } } -function getTopLevelModulePath(src: string): Promise { - return fsPromise.findFurthestFile( - '__init__.py', - nuclideUri.dirname(src), - true /* stopOnMissing */, +exports.default = JediServerManager; /** + * 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. + * + * + * @format + */ + +function getTopLevelModulePath(src) { + return (_fsPromise || _load_fsPromise()).default.findFurthestFile('__init__.py', (_nuclideUri || _load_nuclideUri()).default.dirname(src), true /* stopOnMissing */ ); } -async function getCustomSysPath(src: string): Promise> { +async function getCustomSysPath(src) { try { // $FlowFB const fbCustomSysPath = require('./fb/custom-sys-path').default; @@ -85,4 +104,4 @@ async function getCustomSysPath(src: string): Promise> { // Ignore. } return []; -} +} \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/lib/JediService.js b/pkg/nuclide-python-rpc/lib/JediService.js index 7d0c43089d..ba359874eb 100644 --- a/pkg/nuclide-python-rpc/lib/JediService.js +++ b/pkg/nuclide-python-rpc/lib/JediService.js @@ -1,3 +1,18 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.get_completions = get_completions; +exports.get_definitions = get_definitions; +exports.get_references = get_references; +exports.get_hover = get_hover; +exports.get_outline = get_outline; +exports.get_signature_help = get_signature_help; + + +// This file contains RPC definitions for jediserver.py. + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,133 +20,32 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {SignatureHelp} from 'atom-ide-ui'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -// This file contains RPC definitions for jediserver.py. - -export type JediCompletion = { - type: string, - text: string, - description?: string, - params: ?Array, -}; - -export type JediDefinition = { - type: string, - text: string, - file: NuclideUri, - line: number, - column: number, -}; - -export type JediReference = { - type: string, - text: string, - file: NuclideUri, - line: number, - column: number, - parentName?: string, -}; - -export type Position = { - line: number, - column: number, -}; - -export type JediFunctionItem = { - kind: 'function', - name: string, - start: Position, - end: Position, - children?: Array, - docblock?: string, - params?: Array, -}; - -export type JediClassItem = { - kind: 'class', - name: string, - start: Position, - end: Position, - children?: Array, - docblock?: string, - // Class params, i.e. superclasses. - params?: Array, -}; - -export type JediStatementItem = { - kind: 'statement', - name: string, - start: Position, - end: Position, - docblock?: string, -}; - -export type JediOutlineItem = - | JediFunctionItem - | JediClassItem - | JediStatementItem; - -export async function get_completions( - src: NuclideUri, - contents: string, - sysPath: Array, - line: number, - column: number, -): Promise> { +async function get_completions(src, contents, sysPath, line, column) { throw new Error('RPC Stub'); } -export async function get_definitions( - src: NuclideUri, - contents: string, - sysPath: Array, - line: number, - column: number, -): Promise> { +async function get_definitions(src, contents, sysPath, line, column) { throw new Error('RPC Stub'); } -export async function get_references( - src: NuclideUri, - contents: string, - sysPath: Array, - line: number, - column: number, -): Promise> { +async function get_references(src, contents, sysPath, line, column) { throw new Error('RPC Stub'); } -export async function get_hover( - src: NuclideUri, - contents: string, - sysPath: Array, - // It's much easier to get the current word from JavaScript. - word: string, - line: number, - column: number, -): Promise { +async function get_hover(src, contents, sysPath, +// It's much easier to get the current word from JavaScript. +word, line, column) { throw new Error('RPC Stub'); } -export function get_outline( - src: NuclideUri, - contents: string, -): Promise> { +function get_outline(src, contents) { throw new Error('RPC Stub'); } -export function get_signature_help( - src: NuclideUri, - contents: string, - sysPath: Array, - line: number, - column: number, -): Promise { +function get_signature_help(src, contents, sysPath, line, column) { throw new Error('RPC Stub'); -} +} \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/lib/JediServiceProxy.js b/pkg/nuclide-python-rpc/lib/JediServiceProxy.js new file mode 100644 index 0000000000..46edaa71ea --- /dev/null +++ b/pkg/nuclide-python-rpc/lib/JediServiceProxy.js @@ -0,0 +1,1245 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + + remoteModule.get_completions = function (arg0, arg1, arg2, arg3, arg4) { + return _client.callRemoteFunction("get_completions", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "contents", + type: { + kind: "string" + } + }, { + name: "sysPath", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "JediCompletion" + } + } + }); + }); + }; + + remoteModule.get_definitions = function (arg0, arg1, arg2, arg3, arg4) { + return _client.callRemoteFunction("get_definitions", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "contents", + type: { + kind: "string" + } + }, { + name: "sysPath", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "JediDefinition" + } + } + }); + }); + }; + + remoteModule.get_references = function (arg0, arg1, arg2, arg3, arg4) { + return _client.callRemoteFunction("get_references", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "contents", + type: { + kind: "string" + } + }, { + name: "sysPath", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "JediReference" + } + } + }); + }); + }; + + remoteModule.get_hover = function (arg0, arg1, arg2, arg3, arg4, arg5) { + return _client.callRemoteFunction("get_hover", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "contents", + type: { + kind: "string" + } + }, { + name: "sysPath", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "word", + type: { + kind: "string" + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "string" + } + }); + }); + }; + + remoteModule.get_outline = function (arg0, arg1) { + return _client.callRemoteFunction("get_outline", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "contents", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "JediOutlineItem" + } + } + }); + }); + }; + + remoteModule.get_signature_help = function (arg0, arg1, arg2, arg3, arg4) { + return _client.callRemoteFunction("get_signature_help", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "contents", + type: { + kind: "string" + } + }, { + name: "sysPath", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "SignatureHelp" + } + }); + }); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + JediCompletion: { + kind: "alias", + location: { + type: "source", + fileName: "JediService.js", + line: 17 + }, + name: "JediCompletion", + definition: { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string" + }, + optional: false + }, { + name: "text", + type: { + kind: "string" + }, + optional: false + }, { + name: "description", + type: { + kind: "string" + }, + optional: true + }, { + name: "params", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, + optional: false + }] + } + }, + JediDefinition: { + kind: "alias", + location: { + type: "source", + fileName: "JediService.js", + line: 24 + }, + name: "JediDefinition", + definition: { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string" + }, + optional: false + }, { + name: "text", + type: { + kind: "string" + }, + optional: false + }, { + name: "file", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "line", + type: { + kind: "number" + }, + optional: false + }, { + name: "column", + type: { + kind: "number" + }, + optional: false + }] + } + }, + JediReference: { + kind: "alias", + location: { + type: "source", + fileName: "JediService.js", + line: 32 + }, + name: "JediReference", + definition: { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string" + }, + optional: false + }, { + name: "text", + type: { + kind: "string" + }, + optional: false + }, { + name: "file", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "line", + type: { + kind: "number" + }, + optional: false + }, { + name: "column", + type: { + kind: "number" + }, + optional: false + }, { + name: "parentName", + type: { + kind: "string" + }, + optional: true + }] + } + }, + Position: { + kind: "alias", + location: { + type: "source", + fileName: "JediService.js", + line: 41 + }, + name: "Position", + definition: { + kind: "object", + fields: [{ + name: "line", + type: { + kind: "number" + }, + optional: false + }, { + name: "column", + type: { + kind: "number" + }, + optional: false + }] + } + }, + JediClassItem: { + kind: "alias", + location: { + type: "source", + fileName: "JediService.js", + line: 56 + }, + name: "JediClassItem", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "class" + }, + optional: false + }, { + name: "name", + type: { + kind: "string" + }, + optional: false + }, { + name: "start", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "end", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "children", + type: { + kind: "array", + type: { + kind: "named", + name: "JediOutlineItem" + } + }, + optional: true + }, { + name: "docblock", + type: { + kind: "string" + }, + optional: true + }, { + name: "params", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: true + }] + } + }, + JediStatementItem: { + kind: "alias", + location: { + type: "source", + fileName: "JediService.js", + line: 67 + }, + name: "JediStatementItem", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "statement" + }, + optional: false + }, { + name: "name", + type: { + kind: "string" + }, + optional: false + }, { + name: "start", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "end", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "docblock", + type: { + kind: "string" + }, + optional: true + }] + } + }, + JediOutlineItem: { + kind: "alias", + location: { + type: "source", + fileName: "JediService.js", + line: 75 + }, + name: "JediOutlineItem", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "function" + }, + optional: false + }, { + name: "name", + type: { + kind: "string" + }, + optional: false + }, { + name: "start", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "end", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "children", + type: { + kind: "array", + type: { + kind: "named", + name: "JediOutlineItem" + } + }, + optional: true + }, { + name: "docblock", + type: { + kind: "string" + }, + optional: true + }, { + name: "params", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: true + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "class" + }, + optional: false + }, { + name: "name", + type: { + kind: "string" + }, + optional: false + }, { + name: "start", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "end", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "children", + type: { + kind: "array", + type: { + kind: "named", + name: "JediOutlineItem" + } + }, + optional: true + }, { + name: "docblock", + type: { + kind: "string" + }, + optional: true + }, { + name: "params", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: true + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "statement" + }, + optional: false + }, { + name: "name", + type: { + kind: "string" + }, + optional: false + }, { + name: "start", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "end", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "docblock", + type: { + kind: "string" + }, + optional: true + }] + }], + discriminantField: "kind" + } + }, + JediFunctionItem: { + kind: "alias", + location: { + type: "source", + fileName: "JediService.js", + line: 46 + }, + name: "JediFunctionItem", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "function" + }, + optional: false + }, { + name: "name", + type: { + kind: "string" + }, + optional: false + }, { + name: "start", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "end", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "children", + type: { + kind: "array", + type: { + kind: "named", + name: "JediOutlineItem" + } + }, + optional: true + }, { + name: "docblock", + type: { + kind: "string" + }, + optional: true + }, { + name: "params", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: true + }] + } + }, + get_completions: { + kind: "function", + name: "get_completions", + location: { + type: "source", + fileName: "JediService.js", + line: 80 + }, + type: { + location: { + type: "source", + fileName: "JediService.js", + line: 80 + }, + kind: "function", + argumentTypes: [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "contents", + type: { + kind: "string" + } + }, { + name: "sysPath", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "JediCompletion" + } + } + } + } + } + }, + get_definitions: { + kind: "function", + name: "get_definitions", + location: { + type: "source", + fileName: "JediService.js", + line: 90 + }, + type: { + location: { + type: "source", + fileName: "JediService.js", + line: 90 + }, + kind: "function", + argumentTypes: [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "contents", + type: { + kind: "string" + } + }, { + name: "sysPath", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "JediDefinition" + } + } + } + } + } + }, + get_references: { + kind: "function", + name: "get_references", + location: { + type: "source", + fileName: "JediService.js", + line: 100 + }, + type: { + location: { + type: "source", + fileName: "JediService.js", + line: 100 + }, + kind: "function", + argumentTypes: [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "contents", + type: { + kind: "string" + } + }, { + name: "sysPath", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "JediReference" + } + } + } + } + } + }, + get_hover: { + kind: "function", + name: "get_hover", + location: { + type: "source", + fileName: "JediService.js", + line: 110 + }, + type: { + location: { + type: "source", + fileName: "JediService.js", + line: 110 + }, + kind: "function", + argumentTypes: [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "contents", + type: { + kind: "string" + } + }, { + name: "sysPath", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "word", + type: { + kind: "string" + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + } + } + }, + get_outline: { + kind: "function", + name: "get_outline", + location: { + type: "source", + fileName: "JediService.js", + line: 122 + }, + type: { + location: { + type: "source", + fileName: "JediService.js", + line: 122 + }, + kind: "function", + argumentTypes: [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "contents", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "JediOutlineItem" + } + } + } + } + } + }, + SignatureParameter: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 56 + }, + name: "SignatureParameter", + definition: { + kind: "object", + fields: [{ + name: "label", + type: { + kind: "string" + }, + optional: false + }, { + name: "documentation", + type: { + kind: "string" + }, + optional: true + }] + } + }, + Signature: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 50 + }, + name: "Signature", + definition: { + kind: "object", + fields: [{ + name: "label", + type: { + kind: "string" + }, + optional: false + }, { + name: "documentation", + type: { + kind: "string" + }, + optional: true + }, { + name: "parameters", + type: { + kind: "array", + type: { + kind: "named", + name: "SignatureParameter" + } + }, + optional: true + }] + } + }, + SignatureHelp: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 44 + }, + name: "SignatureHelp", + definition: { + kind: "object", + fields: [{ + name: "signatures", + type: { + kind: "array", + type: { + kind: "named", + name: "Signature" + } + }, + optional: false + }, { + name: "activeSignature", + type: { + kind: "number" + }, + optional: true + }, { + name: "activeParameter", + type: { + kind: "number" + }, + optional: true + }] + } + }, + get_signature_help: { + kind: "function", + name: "get_signature_help", + location: { + type: "source", + fileName: "JediService.js", + line: 129 + }, + type: { + location: { + type: "source", + fileName: "JediService.js", + line: 129 + }, + kind: "function", + argumentTypes: [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "contents", + type: { + kind: "string" + } + }, { + name: "sysPath", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "SignatureHelp" + } + } + } + } + } + } +}); \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/lib/LinkTreeManager.js b/pkg/nuclide-python-rpc/lib/LinkTreeManager.js index f9e0fc82ec..30268bf226 100644 --- a/pkg/nuclide-python-rpc/lib/LinkTreeManager.js +++ b/pkg/nuclide-python-rpc/lib/LinkTreeManager.js @@ -1,118 +1,131 @@ -/** - * 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 strict-local - * @format - */ - -import invariant from 'assert'; -import {memoize} from 'lodash'; -import {getLogger} from 'log4js'; -import {objectEntries, objectValues} from 'nuclide-commons/collection'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {trackTiming} from '../../nuclide-analytics'; -import * as BuckService from '../../nuclide-buck-rpc'; - -const BUCK_GEN_PATH = 'buck-out/gen'; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _memoize2; + +function _load_memoize() { + return _memoize2 = _interopRequireDefault(require('lodash/memoize')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _nuclideBuckRpc; + +function _load_nuclideBuckRpc() { + return _nuclideBuckRpc = _interopRequireWildcard(require('../../nuclide-buck-rpc')); +} + +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 BUCK_GEN_PATH = 'buck-out/gen'; /** + * 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. + * + * strict-local + * @format + */ + const FILENAME_BLACKLIST = [ - // These are treated as Python files but obviously they don't have linktrees. - 'BUCK', - 'TARGETS', -]; +// These are treated as Python files but obviously they don't have linktrees. +'BUCK', 'TARGETS']; const LINK_TREE_SUFFIXES = Object.freeze({ python_binary: '#link-tree', - python_test: '#binary,link-tree', + python_test: '#binary,link-tree' }); -const logger = getLogger('LinkTreeManager'); +const logger = (0, (_log4js || _load_log4js()).getLogger)('LinkTreeManager'); -export default class LinkTreeManager { - getBuckRoot = memoize( - (src: string): Promise => { - return BuckService.getRootForPath(src); - }, - ); - - getOwner = memoize( - async (src: string): Promise => { +class LinkTreeManager { + constructor() { + this.getBuckRoot = (0, (_memoize2 || _load_memoize()).default)(src => { + return (_nuclideBuckRpc || _load_nuclideBuckRpc()).getRootForPath(src); + }); + this.getOwner = (0, (_memoize2 || _load_memoize()).default)(async src => { const buckRoot = await this.getBuckRoot(src); if (buckRoot == null) { return null; } - const owners = await BuckService.getOwners(buckRoot, src, []).catch( - err => { - logger.error(`Failed to get Buck owner for ${src}`, err); - return []; - }, - ); + const owners = await (_nuclideBuckRpc || _load_nuclideBuckRpc()).getOwners(buckRoot, src, []).catch(err => { + logger.error(`Failed to get Buck owner for ${src}`, err); + return []; + }); return owners.length > 0 ? owners[0] : null; - }, - ); + }); + this.getDependents = (0, (_memoize2 || _load_memoize()).default)(async (buckRoot, target) => { + try { + /** + * Buck 'rdeps' has a pretty slow implementation: + * it crawls all transitive deps of the first argument looking for the second. + * Without a more efficient solution we'll just crawl the surrounding targets. + * e.g. the universe for //a:b will just be //a/... + */ + const targetDir = target.substr(0, target.indexOf(':')); + const universe = targetDir + '/...'; + // Quote kinds - the kind() operator takes a string. + const kinds = JSON.stringify(Object.keys(LINK_TREE_SUFFIXES).join('|')); + const dependents = await (_nuclideBuckRpc || _load_nuclideBuckRpc()).queryWithAttributes(buckRoot, `kind(${kinds}, rdeps(${universe}, ${target}))`, ['buck.type', 'deps']); + // Python binaries/unit tests often come with many 'helper targets'. + // (e.g. a binary might have a version built for ipython use). + // We'll restrict ourselves to only using the top level targets. + const nonToplevel = new Set(); + (0, (_collection || _load_collection()).objectValues)(dependents).forEach(attrs => { + if (Array.isArray(attrs.deps)) { + attrs.deps.forEach(dep => { + if (typeof dep !== 'string') { + return; + } + // Resolve relative dependencies, e.g. :dep + const resolvedDep = dep.startsWith(':') ? targetDir + dep : dep; + nonToplevel.add(resolvedDep); + }); + } + }); + return new Map((0, (_collection || _load_collection()).objectEntries)(dependents).filter(([dep]) => !nonToplevel.has(dep)).map(([dep, attrs]) => { + const buckType = String(attrs['buck.type']); - /** - * For a given file, attempts to find python_binary/python_unittest dependents. - * Returns a mapping of target -> target type. - */ - getDependents = memoize(async (buckRoot: string, target: string): Promise< - Map, - > => { - try { - /** - * Buck 'rdeps' has a pretty slow implementation: - * it crawls all transitive deps of the first argument looking for the second. - * Without a more efficient solution we'll just crawl the surrounding targets. - * e.g. the universe for //a:b will just be //a/... - */ - const targetDir = target.substr(0, target.indexOf(':')); - const universe = targetDir + '/...'; - // Quote kinds - the kind() operator takes a string. - const kinds = JSON.stringify(Object.keys(LINK_TREE_SUFFIXES).join('|')); - const dependents = await BuckService.queryWithAttributes( - buckRoot, - `kind(${kinds}, rdeps(${universe}, ${target}))`, - ['buck.type', 'deps'], - ); - // Python binaries/unit tests often come with many 'helper targets'. - // (e.g. a binary might have a version built for ipython use). - // We'll restrict ourselves to only using the top level targets. - const nonToplevel = new Set(); - objectValues(dependents).forEach(attrs => { - if (Array.isArray(attrs.deps)) { - attrs.deps.forEach(dep => { - if (typeof dep !== 'string') { - return; - } - // Resolve relative dependencies, e.g. :dep - const resolvedDep = dep.startsWith(':') ? targetDir + dep : dep; - nonToplevel.add(resolvedDep); - }); - } - }); - return new Map( - objectEntries(dependents) - .filter(([dep]) => !nonToplevel.has(dep)) - .map(([dep, attrs]) => { - const buckType = String(attrs['buck.type']); - invariant( - LINK_TREE_SUFFIXES.hasOwnProperty(buckType), - 'got invalid buck.type', - ); - return [dep, buckType]; - }), - ); - } catch (err) { - logger.error(`Failed to get dependents of target ${target}`, err); - return new Map(); - } - }, (buckRoot, target) => `${buckRoot}/${target}`); - - getLinkTreePaths = memoize( - async (src: string): Promise> => { - const basename = nuclideUri.basename(src); + if (!LINK_TREE_SUFFIXES.hasOwnProperty(buckType)) { + throw new Error('got invalid buck.type'); + } + + return [dep, buckType]; + })); + } catch (err) { + logger.error(`Failed to get dependents of target ${target}`, err); + return new Map(); + } + }, (buckRoot, target) => `${buckRoot}/${target}`); + this.getLinkTreePaths = (0, (_memoize2 || _load_memoize()).default)(async src => { + const basename = (_nuclideUri || _load_nuclideUri()).default.basename(src); if (FILENAME_BLACKLIST.includes(basename)) { return []; } @@ -122,29 +135,29 @@ export default class LinkTreeManager { return []; } - return trackTiming( - 'python.link-tree', - async () => { - const owner = await this.getOwner(src); - if (owner == null) { - return []; - } - const dependents = await this.getDependents(buckRoot, owner); - const paths = Array.from(dependents).map(([target, kind]) => { - const linkTreeSuffix = LINK_TREE_SUFFIXES[kind]; - // Turn //test/target:a into test/target/a. - const binPath = target.substr(2).replace(':', '/'); - return nuclideUri.join( - buckRoot, - BUCK_GEN_PATH, - binPath + linkTreeSuffix, - ); - }); - logger.info(`Resolved link trees for ${src}`, paths); - return paths; - }, - {src}, - ); - }, - ); + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)('python.link-tree', async () => { + const owner = await this.getOwner(src); + if (owner == null) { + return []; + } + const dependents = await this.getDependents(buckRoot, owner); + const paths = Array.from(dependents).map(([target, kind]) => { + const linkTreeSuffix = LINK_TREE_SUFFIXES[kind]; + // Turn //test/target:a into test/target/a. + const binPath = target.substr(2).replace(':', '/'); + return (_nuclideUri || _load_nuclideUri()).default.join(buckRoot, BUCK_GEN_PATH, binPath + linkTreeSuffix); + }); + logger.info(`Resolved link trees for ${src}`, paths); + return paths; + }, { src }); + }); + } + + /** + * For a given file, attempts to find python_binary/python_unittest dependents. + * Returns a mapping of target -> target type. + */ + + } +exports.default = LinkTreeManager; \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/lib/PythonService.js b/pkg/nuclide-python-rpc/lib/PythonService.js index 99f7d2fee8..b5ef6861ac 100644 --- a/pkg/nuclide-python-rpc/lib/PythonService.js +++ b/pkg/nuclide-python-rpc/lib/PythonService.js @@ -1,234 +1,175 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.initialize = initialize; +exports._getReferences = _getReferences; +exports.getDiagnostics = getDiagnostics; +exports.getBuildableTargets = getBuildableTargets; +exports.reset = reset; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _range; + +function _load_range() { + return _range = require('../../../modules/nuclide-commons/range'); +} + +var _string; + +function _load_string() { + return _string = require('../../../modules/nuclide-commons/string'); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _once; + +function _load_once() { + return _once = _interopRequireDefault(require('../../commons-node/once')); +} + +var _constants; + +function _load_constants() { + return _constants = require('./constants'); +} -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - LanguageService, - Completion, -} from '../../nuclide-language-service/lib/LanguageService'; -import type {FileNotifier} from '../../nuclide-open-files-rpc/lib/rpc-types'; -import type {TextEdit} from 'nuclide-commons-atom/text-edit'; -import type {TypeHint} from '../../nuclide-type-hint/lib/rpc-types'; -import type {CoverageResult} from '../../nuclide-type-coverage/lib/rpc-types'; -import type { - DefinitionQueryResult, - DiagnosticMessageType, - FindReferencesReturn, - Outline, - CodeAction, - SignatureHelp, -} from 'atom-ide-ui'; -import type { - AutocompleteResult, - FileDiagnosticMap, - FileDiagnosticMessage, -} from '../../nuclide-language-service/lib/LanguageService'; -import type {ConnectableObservable} from 'rxjs'; - -import invariant from 'assert'; -import {Observable} from 'rxjs'; -import {runCommand, ProcessExitError} from 'nuclide-commons/process'; -import {asyncSome} from 'nuclide-commons/promise'; -import {wordAtPositionFromBuffer} from 'nuclide-commons/range'; -import {maybeToString} from 'nuclide-commons/string'; -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import once from '../../commons-node/once'; -import {IDENTIFIER_REGEXP} from './constants'; -import JediServerManager from './JediServerManager'; -import {parseFlake8Output} from './flake8'; -import {ServerLanguageService} from '../../nuclide-language-service-rpc'; -import {itemsToOutline} from './outline'; -import {Point, Range} from 'simple-text-buffer'; -import {FileCache} from '../../nuclide-open-files-rpc'; -import {getAutocompleteSuggestions} from './AutocompleteHelpers'; -import {getDefinition} from './DefinitionHelpers'; - -export type PythonCompletion = { - type: string, - text: string, - description?: string, - params: ?Array, -}; - -export type PythonDefinition = { - type: string, - text: string, - file: NuclideUri, - line: number, - column: number, -}; - -export type PythonReference = { - type: string, - text: string, - file: NuclideUri, - line: number, - column: number, - parentName?: string, -}; - -export type Position = { - line: number, - column: number, -}; - -export type PythonFunctionItem = { - kind: 'function', - name: string, - start: Position, - end: Position, - children?: Array, - docblock?: string, - params?: Array, -}; - -export type PythonClassItem = { - kind: 'class', - name: string, - start: Position, - end: Position, - children?: Array, - docblock?: string, - // Class params, i.e. superclasses. - params?: Array, -}; - -export type PythonStatementItem = { - kind: 'statement', - name: string, - start: Position, - end: Position, - docblock?: string, -}; - -export type PythonOutlineItem = - | PythonFunctionItem - | PythonClassItem - | PythonStatementItem; - -export type PythonDiagnostic = { - file: NuclideUri, - code: string, - message: string, - type: DiagnosticMessageType, - line: number, - column: number, -}; - -export type PythonServiceConfig = { - showGlobalVariables: boolean, - autocompleteArguments: boolean, - includeOptionalArguments: boolean, -}; - -const serverManager = new JediServerManager(); - -export async function initialize( - fileNotifier: FileNotifier, - config: PythonServiceConfig, -): Promise { - return new ServerLanguageService( - fileNotifier, - new PythonSingleFileLanguageService(fileNotifier, config), - ); +var _JediServerManager; + +function _load_JediServerManager() { + return _JediServerManager = _interopRequireDefault(require('./JediServerManager')); +} + +var _flake; + +function _load_flake() { + return _flake = require('./flake8'); +} + +var _nuclideLanguageServiceRpc; + +function _load_nuclideLanguageServiceRpc() { + return _nuclideLanguageServiceRpc = require('../../nuclide-language-service-rpc'); +} + +var _outline; + +function _load_outline() { + return _outline = require('./outline'); +} + +var _simpleTextBuffer; + +function _load_simpleTextBuffer() { + return _simpleTextBuffer = require('simple-text-buffer'); +} + +var _nuclideOpenFilesRpc; + +function _load_nuclideOpenFilesRpc() { + return _nuclideOpenFilesRpc = require('../../nuclide-open-files-rpc'); +} + +var _AutocompleteHelpers; + +function _load_AutocompleteHelpers() { + return _AutocompleteHelpers = require('./AutocompleteHelpers'); +} + +var _DefinitionHelpers; + +function _load_DefinitionHelpers() { + return _DefinitionHelpers = require('./DefinitionHelpers'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const serverManager = new (_JediServerManager || _load_JediServerManager()).default(); /** + * 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. + * + * strict-local + * @format + */ + +async function initialize(fileNotifier, config) { + return new (_nuclideLanguageServiceRpc || _load_nuclideLanguageServiceRpc()).ServerLanguageService(fileNotifier, new PythonSingleFileLanguageService(fileNotifier, config)); } class PythonSingleFileLanguageService { - _fileCache: FileCache; - _showGlobalVariables: boolean; - _autocompleteArguments: boolean; - _includeOptionalArguments: boolean; - constructor(fileNotifier: FileNotifier, config: PythonServiceConfig) { - invariant(fileNotifier instanceof FileCache); + constructor(fileNotifier, config) { + if (!(fileNotifier instanceof (_nuclideOpenFilesRpc || _load_nuclideOpenFilesRpc()).FileCache)) { + throw new Error('Invariant violation: "fileNotifier instanceof FileCache"'); + } + this._fileCache = fileNotifier; this._showGlobalVariables = config.showGlobalVariables; this._autocompleteArguments = config.autocompleteArguments; this._includeOptionalArguments = config.includeOptionalArguments; } - async getCodeActions( - filePath: NuclideUri, - range: atom$Range, - diagnostics: Array, - ): Promise> { + async getCodeActions(filePath, range, diagnostics) { throw new Error('Not implemented'); } - getDiagnostics( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - ): Promise { + getDiagnostics(filePath, buffer) { throw new Error('Not Yet Implemented'); } - observeDiagnostics(): ConnectableObservable { + observeDiagnostics() { throw new Error('Not Yet Implemented'); } - getAutocompleteSuggestions( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, - activatedManually: boolean, - ): Promise { - return getAutocompleteSuggestions( - serverManager, - filePath, - buffer, - position, - activatedManually, - this._autocompleteArguments, - this._includeOptionalArguments, - ); + getAutocompleteSuggestions(filePath, buffer, position, activatedManually) { + return (0, (_AutocompleteHelpers || _load_AutocompleteHelpers()).getAutocompleteSuggestions)(serverManager, filePath, buffer, position, activatedManually, this._autocompleteArguments, this._includeOptionalArguments); } - resolveAutocompleteSuggestion(suggestion: Completion): Promise { + resolveAutocompleteSuggestion(suggestion) { return Promise.resolve(null); } - getDefinition( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, - ): Promise { - return getDefinition(serverManager, filePath, buffer, position); + getDefinition(filePath, buffer, position) { + return (0, (_DefinitionHelpers || _load_DefinitionHelpers()).getDefinition)(serverManager, filePath, buffer, position); } - findReferences( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, - ): Observable { - return Observable.fromPromise( - this._findReferences(filePath, buffer, position), - ); + findReferences(filePath, buffer, position) { + return _rxjsBundlesRxMinJs.Observable.fromPromise(this._findReferences(filePath, buffer, position)); } - async _findReferences( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, - ): Promise { - const result = await _getReferences( - serverManager, - filePath, - buffer.getText(), - position.row, - position.column, - ); + async _findReferences(filePath, buffer, position) { + const result = await _getReferences(serverManager, filePath, buffer.getText(), position.row, position.column); if (!result || result.length === 0) { - return {type: 'error', message: 'No usages were found.'}; + return { type: 'error', message: 'No usages were found.' }; } const symbolName = result[0].text; @@ -238,35 +179,27 @@ class PythonSingleFileLanguageService { return { uri: ref.file, name: ref.parentName, - range: new Range( - new Point(ref.line, ref.column), - new Point(ref.line, ref.column + ref.text.length), - ), + range: new (_simpleTextBuffer || _load_simpleTextBuffer()).Range(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(ref.line, ref.column), new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(ref.line, ref.column + ref.text.length)) }; }); // Choose the project root as baseUri, or if no project exists, // use the dirname of the src file. - const baseUri = - this._fileCache.getContainingDirectory(filePath) || - nuclideUri.dirname(filePath); + const baseUri = this._fileCache.getContainingDirectory(filePath) || (_nuclideUri || _load_nuclideUri()).default.dirname(filePath); return { type: 'data', baseUri, referencedSymbolName: symbolName, - references, + references }; } - getCoverage(filePath: NuclideUri): Promise { + getCoverage(filePath) { throw new Error('Not Yet Implemented'); } - async getOutline( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - ): Promise { + async getOutline(filePath, buffer) { const service = await serverManager.getJediService(); const items = await service.get_outline(filePath, buffer.getText()); @@ -276,77 +209,49 @@ class PythonSingleFileLanguageService { const mode = this._showGlobalVariables ? 'all' : 'constants'; return { - outlineTrees: itemsToOutline(mode, items), + outlineTrees: (0, (_outline || _load_outline()).itemsToOutline)(mode, items) }; } - async typeHint( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, - ): Promise { - const word = wordAtPositionFromBuffer(buffer, position, IDENTIFIER_REGEXP); + async typeHint(filePath, buffer, position) { + const word = (0, (_range || _load_range()).wordAtPositionFromBuffer)(buffer, position, (_constants || _load_constants()).IDENTIFIER_REGEXP); if (word == null) { return null; } const service = await serverManager.getJediService(); - const result = await service.get_hover( - filePath, - buffer.getText(), - serverManager.getSysPath(filePath), - word.wordMatch[0], - position.row, - position.column, - ); + const result = await service.get_hover(filePath, buffer.getText(), serverManager.getSysPath(filePath), word.wordMatch[0], position.row, position.column); if (result == null) { return null; } return { - hint: [ - { - type: 'markdown', - value: result, - }, - ], - range: word.range, + hint: [{ + type: 'markdown', + value: result + }], + range: word.range }; } - async onToggleCoverage(set: boolean): Promise { + async onToggleCoverage(set) { return; } - highlight( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, - ): Promise> { + highlight(filePath, buffer, position) { throw new Error('Not Yet Implemented'); } - formatSource( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - range: atom$Range, - ): Promise> { + formatSource(filePath, buffer, range) { throw new Error('Not Yet Implemented'); } - async formatEntireFile( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - range: atom$Range, - ): Promise { + async formatEntireFile(filePath, buffer, range) { const contents = buffer.getText(); - const {command, args} = await getFormatterCommandImpl()(filePath, range); - const dirName = nuclideUri.dirname(nuclideUri.getPath(filePath)); + const { command, args } = await getFormatterCommandImpl()(filePath, range); + const dirName = (_nuclideUri || _load_nuclideUri()).default.dirname((_nuclideUri || _load_nuclideUri()).default.getPath(filePath)); let stdout; try { - stdout = await runCommand(command, args, { + stdout = await (0, (_process || _load_process()).runCommand)(command, args, { cwd: dirName, input: contents, // At the moment, yapf outputs 3 possible exit codes: @@ -355,7 +260,7 @@ class PythonSingleFileLanguageService { // 1 - internal failure, most likely due to syntax errors. // // See: https://github.com/google/yapf/issues/228#issuecomment-198682079 - isExitError: exit => exit.exitCode === 1, + isExitError: exit => exit.exitCode === 1 }).toPromise(); } catch (err) { throw new Error(`"${command}" failed, likely due to syntax errors.`); @@ -366,97 +271,59 @@ class PythonSingleFileLanguageService { throw new Error('Empty output received from yapf.'); } - return {formatted: stdout}; + return { formatted: stdout }; } - formatAtPosition( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, - triggerCharacter: string, - ): Promise> { + formatAtPosition(filePath, buffer, position, triggerCharacter) { throw new Error('Not Yet Implemented'); } - async signatureHelp( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - position: atom$Point, - ): Promise { + async signatureHelp(filePath, buffer, position) { const service = await serverManager.getJediService(); - return service.get_signature_help( - filePath, - buffer.getText(), - serverManager.getSysPath(filePath), - position.row, - position.column, - ); + return service.get_signature_help(filePath, buffer.getText(), serverManager.getSysPath(filePath), position.row, position.column); } - getProjectRoot(fileUri: NuclideUri): Promise { + getProjectRoot(fileUri) { throw new Error('Not Yet Implemented'); } - isFileInProject(fileUri: NuclideUri): Promise { + isFileInProject(fileUri) { throw new Error('Not Yet Implemented'); } - getExpandedSelectionRange( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - currentSelection: atom$Range, - ): Promise { + getExpandedSelectionRange(filePath, buffer, currentSelection) { throw new Error('Not Yet Implemented'); } - getCollapsedSelectionRange( - filePath: NuclideUri, - buffer: simpleTextBuffer$TextBuffer, - currentSelection: atom$Range, - originalCursorPosition: atom$Point, - ): Promise { + getCollapsedSelectionRange(filePath, buffer, currentSelection, originalCursorPosition) { throw new Error('Not Yet Implemented'); } - dispose(): void {} + dispose() {} } -const getFormatterCommandImpl = once(() => { +const getFormatterCommandImpl = (0, (_once || _load_once()).default)(() => { try { // $FlowFB return require('./fb/get-formatter-command').default; } catch (e) { return (filePath, range) => ({ command: 'yapf', - args: ['--lines', `${range.start.row + 1}-${range.end.row + 1}`], + args: ['--lines', `${range.start.row + 1}-${range.end.row + 1}`] }); } }); // Exported for testing. -export async function _getReferences( - manager: JediServerManager, - src: NuclideUri, - contents: string, - line: number, - column: number, -): Promise> { +async function _getReferences(manager, src, contents, line, column) { const service = await manager.getJediService(); - return service.get_references( - src, - contents, - manager.getSysPath(src), - line, - column, - ); + return service.get_references(src, contents, manager.getSysPath(src), line, column); } // Set to false if flake8 isn't found, so we don't repeatedly fail. let shouldRunFlake8 = true; -export async function getDiagnostics( - src: NuclideUri, -): Promise> { +async function getDiagnostics(src) { if (!shouldRunFlake8) { return []; } @@ -467,7 +334,7 @@ export async function getDiagnostics( } catch (err) { // A non-successful exit code can result in some cases that we want to ignore, // for example when an incorrect python version is specified for a source file. - if (err instanceof ProcessExitError) { + if (err instanceof (_process || _load_process()).ProcessExitError) { return []; } else if (err.errorCode === 'ENOENT') { // Don't throw if flake8 is not found on the user's system. @@ -475,14 +342,14 @@ export async function getDiagnostics( shouldRunFlake8 = false; return []; } - throw new Error(`flake8 failed with error: ${maybeToString(err.message)}`); + throw new Error(`flake8 failed with error: ${(0, (_string || _load_string()).maybeToString)(err.message)}`); } - return parseFlake8Output(src, result); + return (0, (_flake || _load_flake()).parseFlake8Output)(src, result); } -async function runLinterCommand(src: NuclideUri): Promise { - const dirName = nuclideUri.dirname(src); +async function runLinterCommand(src) { + const dirName = (_nuclideUri || _load_nuclideUri()).default.dirname(src); let result; let runFlake8; @@ -500,15 +367,16 @@ async function runLinterCommand(src: NuclideUri): Promise { } } - const command = - (global.atom && atom.config.get('nuclide.nuclide-python.pathToFlake8')) || - 'flake8'; + const command = global.atom && atom.config.get('nuclide.nuclide-python.pathToFlake8') || 'flake8'; - invariant(typeof command === 'string'); - return runCommand(command, [src], { + if (!(typeof command === 'string')) { + throw new Error('Invariant violation: "typeof command === \'string\'"'); + } + + return (0, (_process || _load_process()).runCommand)(command, [src], { cwd: dirName, // 1 indicates unclean lint result (i.e. has errors/warnings). - isExitError: exit => exit.exitCode == null || exit.exitCode > 1, + isExitError: exit => exit.exitCode == null || exit.exitCode > 1 }).toPromise(); } @@ -516,15 +384,13 @@ async function runLinterCommand(src: NuclideUri): Promise { * Retrieves a list of buildable targets to obtain link trees for a given file. * (This won't return anything if a link tree is already available.) */ -export async function getBuildableTargets( - src: NuclideUri, -): Promise> { +async function getBuildableTargets(src) { const linkTreeManager = serverManager._linkTreeManager; const linkTrees = await linkTreeManager.getLinkTreePaths(src); if (linkTrees.length === 0) { return []; } - if (await asyncSome(linkTrees, fsPromise.exists)) { + if (await (0, (_promise || _load_promise()).asyncSome)(linkTrees, (_fsPromise || _load_fsPromise()).default.exists)) { return []; } const buckRoot = await linkTreeManager.getBuckRoot(src); @@ -536,6 +402,6 @@ export async function getBuildableTargets( return Array.from(dependents.keys()); } -export function reset(): void { +function reset() { serverManager.reset(); -} +} \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/lib/PythonServiceProxy.js b/pkg/nuclide-python-rpc/lib/PythonServiceProxy.js new file mode 100644 index 0000000000..9c16e7a80e --- /dev/null +++ b/pkg/nuclide-python-rpc/lib/PythonServiceProxy.js @@ -0,0 +1,4639 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + remoteModule.FileNotifier = class { + constructor() { + throw Error("constructors are not supported for remote objects"); + } + + onFileEvent(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 62 + }, + name: "FileNotifier" + }), "onFileEvent", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "event", + type: { + kind: "named", + name: "FileEvent" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + } + + onDirectoriesChanged(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 62 + }, + name: "FileNotifier" + }), "onDirectoriesChanged", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "openDirectories", + type: { + kind: "set", + type: { + kind: "named", + name: "NuclideUri" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + } + + dispose() { + return _client.disposeRemoteObject(this); + } + + }; + remoteModule.CodeAction = class { + constructor() { + throw Error("constructors are not supported for remote objects"); + } + + apply() { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "types.js", + line: 15 + }, + name: "CodeAction" + }), "apply", "promise", _client.marshalArguments(Array.from(arguments), [])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + } + + getTitle() { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "types.js", + line: 15 + }, + name: "CodeAction" + }), "getTitle", "promise", _client.marshalArguments(Array.from(arguments), [])).then(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }); + } + + dispose() { + return _client.disposeRemoteObject(this); + } + + }; + remoteModule.LanguageService = class { + constructor() { + throw Error("constructors are not supported for remote objects"); + } + + getDiagnostics(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "getDiagnostics", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "FileDiagnosticMap" + } + }); + }); + } + + observeDiagnostics() { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "observeDiagnostics", "observable", _client.marshalArguments(Array.from(arguments), [])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "FileDiagnosticMap" + }); + }).publish(); + } + + observeStatus(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "observeStatus", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "StatusData" + }); + }).publish(); + } + + clickStatus(arg0, arg1, arg2) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "clickStatus", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "id", + type: { + kind: "string" + } + }, { + name: "button", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + } + + getAutocompleteSuggestions(arg0, arg1, arg2) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "getAutocompleteSuggestions", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "position", + type: { + kind: "named", + name: "atom$Point" + } + }, { + name: "request", + type: { + kind: "named", + name: "AutocompleteRequest" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "AutocompleteResult" + } + }); + }); + } + + resolveAutocompleteSuggestion(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "resolveAutocompleteSuggestion", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "suggestion", + type: { + kind: "named", + name: "Completion" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "Completion" + } + }); + }); + } + + getDefinition(arg0, arg1) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "getDefinition", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "position", + type: { + kind: "named", + name: "atom$Point" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "DefinitionQueryResult" + } + }); + }); + } + + findReferences(arg0, arg1) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "findReferences", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "position", + type: { + kind: "named", + name: "atom$Point" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "FindReferencesReturn" + } + }); + }).publish(); + } + + getCoverage(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "getCoverage", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "CoverageResult" + } + }); + }); + } + + getOutline(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "getOutline", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "Outline" + } + }); + }); + } + + getCodeLens(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "getCodeLens", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "CodeLensData" + } + } + }); + }); + } + + resolveCodeLens(arg0, arg1) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "resolveCodeLens", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "codeLens", + type: { + kind: "named", + name: "CodeLensData" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "CodeLensData" + } + }); + }); + } + + getCodeActions(arg0, arg1, arg2) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "getCodeActions", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "range", + type: { + kind: "named", + name: "atom$Range" + } + }, { + name: "diagnostics", + type: { + kind: "array", + type: { + kind: "named", + name: "FileDiagnosticMessage" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "CodeAction" + } + }); + }); + } + + typeHint(arg0, arg1) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "typeHint", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "position", + type: { + kind: "named", + name: "atom$Point" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "TypeHint" + } + }); + }); + } + + highlight(arg0, arg1) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "highlight", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "position", + type: { + kind: "named", + name: "atom$Point" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "atom$Range" + } + } + }); + }); + } + + formatSource(arg0, arg1, arg2) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "formatSource", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "range", + type: { + kind: "named", + name: "atom$Range" + } + }, { + name: "options", + type: { + kind: "named", + name: "FormatOptions" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "TextEdit" + } + } + }); + }); + } + + formatEntireFile(arg0, arg1, arg2) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "formatEntireFile", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "range", + type: { + kind: "named", + name: "atom$Range" + } + }, { + name: "options", + type: { + kind: "named", + name: "FormatOptions" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "object", + fields: [{ + name: "newCursor", + type: { + kind: "number" + }, + optional: true + }, { + name: "formatted", + type: { + kind: "string" + }, + optional: false + }] + } + }); + }); + } + + formatAtPosition(arg0, arg1, arg2, arg3) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "formatAtPosition", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "position", + type: { + kind: "named", + name: "atom$Point" + } + }, { + name: "triggerCharacter", + type: { + kind: "string" + } + }, { + name: "options", + type: { + kind: "named", + name: "FormatOptions" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "TextEdit" + } + } + }); + }); + } + + signatureHelp(arg0, arg1) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "signatureHelp", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "position", + type: { + kind: "named", + name: "atom$Point" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "SignatureHelp" + } + }); + }); + } + + onToggleCoverage(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "onToggleCoverage", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "on", + type: { + kind: "boolean" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + } + + getAdditionalLogFiles(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "getAdditionalLogFiles", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "deadline", + type: { + kind: "named", + name: "DeadlineRequest" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "AdditionalLogFile" + } + }); + }); + } + + supportsSymbolSearch(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "supportsSymbolSearch", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "directories", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "boolean" + }); + }); + } + + symbolSearch(arg0, arg1) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "symbolSearch", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "query", + type: { + kind: "string" + } + }, { + name: "directories", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "SymbolResult" + } + } + }); + }); + } + + getProjectRoot(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "getProjectRoot", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileUri", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "NuclideUri" + } + }); + }); + } + + isFileInProject(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "isFileInProject", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileUri", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "boolean" + }); + }); + } + + getExpandedSelectionRange(arg0, arg1) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "getExpandedSelectionRange", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "currentSelection", + type: { + kind: "named", + name: "atom$Range" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "atom$Range" + } + }); + }); + } + + getCollapsedSelectionRange(arg0, arg1, arg2) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + name: "LanguageService" + }), "getCollapsedSelectionRange", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "currentSelection", + type: { + kind: "named", + name: "atom$Range" + } + }, { + name: "originalCursorPosition", + type: { + kind: "named", + name: "atom$Point" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "atom$Range" + } + }); + }); + } + + dispose() { + return _client.disposeRemoteObject(this); + } + + }; + + remoteModule.initialize = function (arg0, arg1) { + return _client.callRemoteFunction("PythonService/initialize", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileNotifier", + type: { + kind: "named", + name: "FileNotifier" + } + }, { + name: "config", + type: { + kind: "named", + name: "PythonServiceConfig" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "LanguageService" + }); + }); + }; + + remoteModule.getDiagnostics = function (arg0) { + return _client.callRemoteFunction("PythonService/getDiagnostics", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "PythonDiagnostic" + } + }); + }); + }; + + remoteModule.getBuildableTargets = function (arg0) { + return _client.callRemoteFunction("PythonService/getBuildableTargets", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "string" + } + }); + }); + }; + + remoteModule.reset = function () { + return _client.callRemoteFunction("PythonService/reset", "void", _client.marshalArguments(Array.from(arguments), [])); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + PythonCompletion: { + kind: "alias", + location: { + type: "source", + fileName: "PythonService.js", + line: 55 + }, + name: "PythonCompletion", + definition: { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string" + }, + optional: false + }, { + name: "text", + type: { + kind: "string" + }, + optional: false + }, { + name: "description", + type: { + kind: "string" + }, + optional: true + }, { + name: "params", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "string" + } + } + }, + optional: false + }] + } + }, + PythonDefinition: { + kind: "alias", + location: { + type: "source", + fileName: "PythonService.js", + line: 62 + }, + name: "PythonDefinition", + definition: { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string" + }, + optional: false + }, { + name: "text", + type: { + kind: "string" + }, + optional: false + }, { + name: "file", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "line", + type: { + kind: "number" + }, + optional: false + }, { + name: "column", + type: { + kind: "number" + }, + optional: false + }] + } + }, + PythonReference: { + kind: "alias", + location: { + type: "source", + fileName: "PythonService.js", + line: 70 + }, + name: "PythonReference", + definition: { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string" + }, + optional: false + }, { + name: "text", + type: { + kind: "string" + }, + optional: false + }, { + name: "file", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "line", + type: { + kind: "number" + }, + optional: false + }, { + name: "column", + type: { + kind: "number" + }, + optional: false + }, { + name: "parentName", + type: { + kind: "string" + }, + optional: true + }] + } + }, + Position: { + kind: "alias", + location: { + type: "source", + fileName: "PythonService.js", + line: 79 + }, + name: "Position", + definition: { + kind: "object", + fields: [{ + name: "line", + type: { + kind: "number" + }, + optional: false + }, { + name: "column", + type: { + kind: "number" + }, + optional: false + }] + } + }, + PythonClassItem: { + kind: "alias", + location: { + type: "source", + fileName: "PythonService.js", + line: 94 + }, + name: "PythonClassItem", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "class" + }, + optional: false + }, { + name: "name", + type: { + kind: "string" + }, + optional: false + }, { + name: "start", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "end", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "children", + type: { + kind: "array", + type: { + kind: "named", + name: "PythonOutlineItem" + } + }, + optional: true + }, { + name: "docblock", + type: { + kind: "string" + }, + optional: true + }, { + name: "params", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: true + }] + } + }, + PythonStatementItem: { + kind: "alias", + location: { + type: "source", + fileName: "PythonService.js", + line: 105 + }, + name: "PythonStatementItem", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "statement" + }, + optional: false + }, { + name: "name", + type: { + kind: "string" + }, + optional: false + }, { + name: "start", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "end", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "docblock", + type: { + kind: "string" + }, + optional: true + }] + } + }, + PythonOutlineItem: { + kind: "alias", + location: { + type: "source", + fileName: "PythonService.js", + line: 113 + }, + name: "PythonOutlineItem", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "function" + }, + optional: false + }, { + name: "name", + type: { + kind: "string" + }, + optional: false + }, { + name: "start", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "end", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "children", + type: { + kind: "array", + type: { + kind: "named", + name: "PythonOutlineItem" + } + }, + optional: true + }, { + name: "docblock", + type: { + kind: "string" + }, + optional: true + }, { + name: "params", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: true + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "class" + }, + optional: false + }, { + name: "name", + type: { + kind: "string" + }, + optional: false + }, { + name: "start", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "end", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "children", + type: { + kind: "array", + type: { + kind: "named", + name: "PythonOutlineItem" + } + }, + optional: true + }, { + name: "docblock", + type: { + kind: "string" + }, + optional: true + }, { + name: "params", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: true + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "statement" + }, + optional: false + }, { + name: "name", + type: { + kind: "string" + }, + optional: false + }, { + name: "start", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "end", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "docblock", + type: { + kind: "string" + }, + optional: true + }] + }], + discriminantField: "kind" + } + }, + PythonFunctionItem: { + kind: "alias", + location: { + type: "source", + fileName: "PythonService.js", + line: 84 + }, + name: "PythonFunctionItem", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "function" + }, + optional: false + }, { + name: "name", + type: { + kind: "string" + }, + optional: false + }, { + name: "start", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "end", + type: { + kind: "named", + name: "Position" + }, + optional: false + }, { + name: "children", + type: { + kind: "array", + type: { + kind: "named", + name: "PythonOutlineItem" + } + }, + optional: true + }, { + name: "docblock", + type: { + kind: "string" + }, + optional: true + }, { + name: "params", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: true + }] + } + }, + DiagnosticMessageType: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 67 + }, + name: "DiagnosticMessageType", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "Error" + }, { + kind: "string-literal", + value: "Warning" + }, { + kind: "string-literal", + value: "Info" + }, { + kind: "string-literal", + value: "Hint" + }] + } + }, + PythonDiagnostic: { + kind: "alias", + location: { + type: "source", + fileName: "PythonService.js", + line: 118 + }, + name: "PythonDiagnostic", + definition: { + kind: "object", + fields: [{ + name: "file", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "code", + type: { + kind: "string" + }, + optional: false + }, { + name: "message", + type: { + kind: "string" + }, + optional: false + }, { + name: "type", + type: { + kind: "named", + name: "DiagnosticMessageType" + }, + optional: false + }, { + name: "line", + type: { + kind: "number" + }, + optional: false + }, { + name: "column", + type: { + kind: "number" + }, + optional: false + }] + } + }, + PythonServiceConfig: { + kind: "alias", + location: { + type: "source", + fileName: "PythonService.js", + line: 127 + }, + name: "PythonServiceConfig", + definition: { + kind: "object", + fields: [{ + name: "showGlobalVariables", + type: { + kind: "boolean" + }, + optional: false + }, { + name: "autocompleteArguments", + type: { + kind: "boolean" + }, + optional: false + }, { + name: "includeOptionalArguments", + type: { + kind: "boolean" + }, + optional: false + }] + } + }, + DiagnosticMessageKind: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 66 + }, + name: "DiagnosticMessageKind", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "lint" + }, { + kind: "string-literal", + value: "review" + }, { + kind: "string-literal", + value: "action" + }] + } + }, + DiagnosticTrace: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 69 + }, + name: "DiagnosticTrace", + definition: { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "Trace" + }, + optional: false + }, { + name: "text", + type: { + kind: "string" + }, + optional: true + }, { + name: "html", + type: { + kind: "string" + }, + optional: true + }, { + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: true + }, { + name: "range", + type: { + kind: "named", + name: "atom$Range" + }, + optional: true + }] + } + }, + TextEdit: { + kind: "alias", + location: { + type: "source", + fileName: "text-edit.js", + line: 21 + }, + name: "TextEdit", + definition: { + kind: "object", + fields: [{ + name: "oldRange", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }, { + name: "newText", + type: { + kind: "string" + }, + optional: false + }, { + name: "oldText", + type: { + kind: "string" + }, + optional: true + }] + } + }, + DiagnosticFix: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 78 + }, + name: "DiagnosticFix", + definition: { + kind: "intersection", + types: [{ + kind: "named", + name: "TextEdit" + }, { + kind: "object", + fields: [{ + name: "speculative", + type: { + kind: "boolean" + }, + optional: true + }, { + name: "title", + type: { + kind: "string" + }, + optional: true + }] + }], + flattened: { + kind: "object", + fields: [{ + name: "oldRange", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }, { + name: "newText", + type: { + kind: "string" + }, + optional: false + }, { + name: "oldText", + type: { + kind: "string" + }, + optional: true + }, { + name: "speculative", + type: { + kind: "boolean" + }, + optional: true + }, { + name: "title", + type: { + kind: "string" + }, + optional: true + }] + } + } + }, + FileDiagnosticMessage: { + kind: "alias", + location: { + type: "source", + fileName: "LanguageService.js", + line: 100 + }, + name: "FileDiagnosticMessage", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "named", + name: "DiagnosticMessageKind" + }, + optional: true + }, { + name: "providerName", + type: { + kind: "string" + }, + optional: false + }, { + name: "type", + type: { + kind: "named", + name: "DiagnosticMessageType" + }, + optional: false + }, { + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "text", + type: { + kind: "string" + }, + optional: true + }, { + name: "html", + type: { + kind: "string" + }, + optional: true + }, { + name: "range", + type: { + kind: "named", + name: "atom$Range" + }, + optional: true + }, { + name: "trace", + type: { + kind: "array", + type: { + kind: "named", + name: "DiagnosticTrace" + } + }, + optional: true + }, { + name: "fix", + type: { + kind: "named", + name: "DiagnosticFix" + }, + optional: true + }, { + name: "actions", + type: { + kind: "void" + }, + optional: true + }, { + name: "stale", + type: { + kind: "boolean" + }, + optional: true + }] + } + }, + FileDiagnosticMap: { + kind: "alias", + location: { + type: "source", + fileName: "LanguageService.js", + line: 123 + }, + name: "FileDiagnosticMap", + definition: { + kind: "map", + keyType: { + kind: "named", + name: "NuclideUri" + }, + valueType: { + kind: "array", + type: { + kind: "named", + name: "FileDiagnosticMessage" + } + } + } + }, + FileOpenEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 14 + }, + name: "FileOpenEvent", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "open" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "contents", + type: { + kind: "string" + }, + optional: false + }, { + name: "languageId", + type: { + kind: "string" + }, + optional: false + }] + } + }, + FileCloseEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 29 + }, + name: "FileCloseEvent", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "close" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }] + } + }, + FileEditEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 34 + }, + name: "FileEditEvent", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "edit" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "oldRange", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }, { + name: "newRange", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }, { + name: "oldText", + type: { + kind: "string" + }, + optional: false + }, { + name: "newText", + type: { + kind: "string" + }, + optional: false + }] + } + }, + FileSaveEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 43 + }, + name: "FileSaveEvent", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "save" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }] + } + }, + FileSyncEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 22 + }, + name: "FileSyncEvent", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "sync" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "contents", + type: { + kind: "string" + }, + optional: false + }, { + name: "languageId", + type: { + kind: "string" + }, + optional: false + }] + } + }, + FileEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 49 + }, + name: "FileEvent", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "open" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "contents", + type: { + kind: "string" + }, + optional: false + }, { + name: "languageId", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "close" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "edit" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "oldRange", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }, { + name: "newRange", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }, { + name: "oldText", + type: { + kind: "string" + }, + optional: false + }, { + name: "newText", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "save" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "sync" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "contents", + type: { + kind: "string" + }, + optional: false + }, { + name: "languageId", + type: { + kind: "string" + }, + optional: false + }] + }], + discriminantField: "kind" + } + }, + FileNotifier: { + kind: "interface", + name: "FileNotifier", + location: { + type: "source", + fileName: "rpc-types.js", + line: 62 + }, + staticMethods: {}, + instanceMethods: { + onFileEvent: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 63 + }, + kind: "function", + argumentTypes: [{ + name: "event", + type: { + kind: "named", + name: "FileEvent" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + }, + onDirectoriesChanged: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 64 + }, + kind: "function", + argumentTypes: [{ + name: "openDirectories", + type: { + kind: "set", + type: { + kind: "named", + name: "NuclideUri" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + }, + dispose: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 65 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "void" + } + } + } + }, + FileVersion: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 68 + }, + name: "FileVersion", + definition: { + kind: "object", + fields: [{ + name: "notifier", + type: { + kind: "named", + name: "FileNotifier" + }, + optional: false + }, { + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "version", + type: { + kind: "number" + }, + optional: false + }] + } + }, + StatusData: { + kind: "alias", + location: { + type: "source", + fileName: "LanguageService.js", + line: 135 + }, + name: "StatusData", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "null" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "green" + }, + optional: false + }, { + name: "message", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "yellow" + }, + optional: false + }, { + name: "message", + type: { + kind: "string" + }, + optional: false + }, { + name: "fraction", + type: { + kind: "number" + }, + optional: true + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "red" + }, + optional: false + }, { + name: "id", + type: { + kind: "string" + }, + optional: true + }, { + name: "message", + type: { + kind: "string" + }, + optional: false + }, { + name: "buttons", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: false + }] + }], + discriminantField: "kind" + } + }, + Completion: { + kind: "alias", + location: { + type: "source", + fileName: "LanguageService.js", + line: 37 + }, + name: "Completion", + definition: { + kind: "object", + fields: [{ + name: "text", + type: { + kind: "string" + }, + optional: true + }, { + name: "snippet", + type: { + kind: "string" + }, + optional: true + }, { + name: "displayText", + type: { + kind: "string" + }, + optional: true + }, { + name: "replacementPrefix", + type: { + kind: "string" + }, + optional: true + }, { + name: "type", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: true + }, { + name: "leftLabel", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: true + }, { + name: "leftLabelHTML", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: true + }, { + name: "rightLabel", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: true + }, { + name: "rightLabelHTML", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: true + }, { + name: "className", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: true + }, { + name: "iconHTML", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: true + }, { + name: "description", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: true + }, { + name: "descriptionMarkdown", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: true + }, { + name: "descriptionMoreURL", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: true + }, { + name: "filterText", + type: { + kind: "string" + }, + optional: true + }, { + name: "sortText", + type: { + kind: "string" + }, + optional: true + }, { + name: "extraData", + type: { + kind: "mixed" + }, + optional: true + }, { + name: "textEdits", + type: { + kind: "array", + type: { + kind: "named", + name: "TextEdit" + } + }, + optional: true + }, { + name: "remoteUri", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: true + }] + } + }, + AutocompleteResult: { + kind: "alias", + location: { + type: "source", + fileName: "LanguageService.js", + line: 73 + }, + name: "AutocompleteResult", + definition: { + kind: "object", + fields: [{ + name: "isIncomplete", + type: { + kind: "boolean" + }, + optional: false + }, { + name: "items", + type: { + kind: "array", + type: { + kind: "named", + name: "Completion" + } + }, + optional: false + }] + } + }, + AutocompleteRequest: { + kind: "alias", + location: { + type: "source", + fileName: "LanguageService.js", + line: 85 + }, + name: "AutocompleteRequest", + definition: { + kind: "object", + fields: [{ + name: "activatedManually", + type: { + kind: "boolean" + }, + optional: false + }, { + name: "triggerCharacter", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "prefix", + type: { + kind: "string" + }, + optional: false + }] + } + }, + Definition: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 15 + }, + name: "Definition", + definition: { + kind: "object", + fields: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "position", + type: { + kind: "named", + name: "atom$Point" + }, + optional: false + }, { + name: "range", + type: { + kind: "named", + name: "atom$Range" + }, + optional: true + }, { + name: "name", + type: { + kind: "string" + }, + optional: true + }, { + name: "projectRoot", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: true + }, { + name: "language", + type: { + kind: "string" + }, + optional: false + }] + } + }, + DefinitionQueryResult: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 37 + }, + name: "DefinitionQueryResult", + definition: { + kind: "object", + fields: [{ + name: "queryRange", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "atom$Range" + } + } + }, + optional: false + }, { + name: "definitions", + type: { + kind: "array", + type: { + kind: "named", + name: "Definition" + } + }, + optional: false + }] + } + }, + Reference: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 27 + }, + name: "Reference", + definition: { + kind: "object", + fields: [{ + name: "uri", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "name", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "range", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }] + } + }, + FindReferencesData: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 33 + }, + name: "FindReferencesData", + definition: { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "data" + }, + optional: false + }, { + name: "baseUri", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "referencedSymbolName", + type: { + kind: "string" + }, + optional: false + }, { + name: "references", + type: { + kind: "array", + type: { + kind: "named", + name: "Reference" + } + }, + optional: false + }, { + name: "title", + type: { + kind: "string" + }, + optional: true + }] + } + }, + FindReferencesError: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 41 + }, + name: "FindReferencesError", + definition: { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "error" + }, + optional: false + }, { + name: "message", + type: { + kind: "string" + }, + optional: false + }] + } + }, + FindReferencesReturn: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 46 + }, + name: "FindReferencesReturn", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "data" + }, + optional: false + }, { + name: "baseUri", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "referencedSymbolName", + type: { + kind: "string" + }, + optional: false + }, { + name: "references", + type: { + kind: "array", + type: { + kind: "named", + name: "Reference" + } + }, + optional: false + }, { + name: "title", + type: { + kind: "string" + }, + optional: true + }] + }, { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "error" + }, + optional: false + }, { + name: "message", + type: { + kind: "string" + }, + optional: false + }] + }], + discriminantField: "type" + } + }, + UncoveredRegion: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 12 + }, + name: "UncoveredRegion", + definition: { + kind: "object", + fields: [{ + name: "range", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }, { + name: "message", + type: { + kind: "string" + }, + optional: true + }] + } + }, + CoverageResult: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 17 + }, + name: "CoverageResult", + definition: { + kind: "object", + fields: [{ + name: "percentage", + type: { + kind: "number" + }, + optional: false + }, { + name: "uncoveredRegions", + type: { + kind: "array", + type: { + kind: "named", + name: "UncoveredRegion" + } + }, + optional: false + }] + } + }, + OutlineTreeKind: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 49 + }, + name: "OutlineTreeKind", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "file" + }, { + kind: "string-literal", + value: "module" + }, { + kind: "string-literal", + value: "namespace" + }, { + kind: "string-literal", + value: "package" + }, { + kind: "string-literal", + value: "class" + }, { + kind: "string-literal", + value: "method" + }, { + kind: "string-literal", + value: "property" + }, { + kind: "string-literal", + value: "field" + }, { + kind: "string-literal", + value: "constructor" + }, { + kind: "string-literal", + value: "enum" + }, { + kind: "string-literal", + value: "interface" + }, { + kind: "string-literal", + value: "function" + }, { + kind: "string-literal", + value: "variable" + }, { + kind: "string-literal", + value: "constant" + }, { + kind: "string-literal", + value: "string" + }, { + kind: "string-literal", + value: "number" + }, { + kind: "string-literal", + value: "boolean" + }, { + kind: "string-literal", + value: "array" + }] + } + }, + TokenKind: { + kind: "alias", + location: { + type: "source", + fileName: "tokenized-text.js", + line: 13 + }, + name: "TokenKind", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "keyword" + }, { + kind: "string-literal", + value: "class-name" + }, { + kind: "string-literal", + value: "constructor" + }, { + kind: "string-literal", + value: "method" + }, { + kind: "string-literal", + value: "param" + }, { + kind: "string-literal", + value: "string" + }, { + kind: "string-literal", + value: "whitespace" + }, { + kind: "string-literal", + value: "plain" + }, { + kind: "string-literal", + value: "type" + }] + } + }, + TextToken: { + kind: "alias", + location: { + type: "source", + fileName: "tokenized-text.js", + line: 24 + }, + name: "TextToken", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "named", + name: "TokenKind" + }, + optional: false + }, { + name: "value", + type: { + kind: "string" + }, + optional: false + }] + } + }, + TokenizedText: { + kind: "alias", + location: { + type: "source", + fileName: "tokenized-text.js", + line: 29 + }, + name: "TokenizedText", + definition: { + kind: "array", + type: { + kind: "named", + name: "TextToken" + } + } + }, + OutlineTree: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 27 + }, + name: "OutlineTree", + definition: { + kind: "object", + fields: [{ + name: "icon", + type: { + kind: "string" + }, + optional: true + }, { + name: "kind", + type: { + kind: "named", + name: "OutlineTreeKind" + }, + optional: true + }, { + name: "plainText", + type: { + kind: "string" + }, + optional: true + }, { + name: "tokenizedText", + type: { + kind: "named", + name: "TokenizedText" + }, + optional: true + }, { + name: "representativeName", + type: { + kind: "string" + }, + optional: true + }, { + name: "startPosition", + type: { + kind: "named", + name: "atom$Point" + }, + optional: false + }, { + name: "endPosition", + type: { + kind: "named", + name: "atom$Point" + }, + optional: true + }, { + name: "landingPosition", + type: { + kind: "named", + name: "atom$Point" + }, + optional: true + }, { + name: "children", + type: { + kind: "array", + type: { + kind: "named", + name: "OutlineTree" + } + }, + optional: false + }] + } + }, + Outline: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 44 + }, + name: "Outline", + definition: { + kind: "object", + fields: [{ + name: "outlineTrees", + type: { + kind: "array", + type: { + kind: "named", + name: "OutlineTree" + } + }, + optional: false + }] + } + }, + CodeLensData: { + kind: "alias", + location: { + type: "source", + fileName: "LanguageService.js", + line: 124 + }, + name: "CodeLensData", + definition: { + kind: "object", + fields: [{ + name: "range", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }, { + name: "command", + type: { + kind: "object", + fields: [{ + name: "title", + type: { + kind: "string" + }, + optional: false + }, { + name: "command", + type: { + kind: "string" + }, + optional: false + }, { + name: "arguments", + type: { + kind: "array", + type: { + kind: "any" + } + }, + optional: true + }] + }, + optional: true + }, { + name: "data", + type: { + kind: "any" + }, + optional: true + }] + } + }, + CodeAction: { + kind: "interface", + name: "CodeAction", + location: { + type: "source", + fileName: "types.js", + line: 15 + }, + staticMethods: {}, + instanceMethods: { + apply: { + location: { + type: "source", + fileName: "types.js", + line: 16 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + }, + getTitle: { + location: { + type: "source", + fileName: "types.js", + line: 17 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "string" + } + } + }, + dispose: { + location: { + type: "source", + fileName: "types.js", + line: 18 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "void" + } + } + } + }, + TypeHint: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 12 + }, + name: "TypeHint", + definition: { + kind: "object", + fields: [{ + name: "hint", + type: { + kind: "array", + type: { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "union", + types: [{ + kind: "string-literal", + value: "snippet" + }, { + kind: "string-literal", + value: "markdown" + }] + }, + optional: false + }, { + name: "value", + type: { + kind: "string" + }, + optional: false + }] + } + }, + optional: false + }, { + name: "range", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }] + } + }, + FormatOptions: { + kind: "alias", + location: { + type: "source", + fileName: "LanguageService.js", + line: 78 + }, + name: "FormatOptions", + definition: { + kind: "object", + fields: [{ + name: "tabSize", + type: { + kind: "number" + }, + optional: false + }, { + name: "insertSpaces", + type: { + kind: "boolean" + }, + optional: false + }] + } + }, + SignatureParameter: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 56 + }, + name: "SignatureParameter", + definition: { + kind: "object", + fields: [{ + name: "label", + type: { + kind: "string" + }, + optional: false + }, { + name: "documentation", + type: { + kind: "string" + }, + optional: true + }] + } + }, + Signature: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 50 + }, + name: "Signature", + definition: { + kind: "object", + fields: [{ + name: "label", + type: { + kind: "string" + }, + optional: false + }, { + name: "documentation", + type: { + kind: "string" + }, + optional: true + }, { + name: "parameters", + type: { + kind: "array", + type: { + kind: "named", + name: "SignatureParameter" + } + }, + optional: true + }] + } + }, + SignatureHelp: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 44 + }, + name: "SignatureHelp", + definition: { + kind: "object", + fields: [{ + name: "signatures", + type: { + kind: "array", + type: { + kind: "named", + name: "Signature" + } + }, + optional: false + }, { + name: "activeSignature", + type: { + kind: "number" + }, + optional: true + }, { + name: "activeParameter", + type: { + kind: "number" + }, + optional: true + }] + } + }, + AdditionalLogFile: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 31 + }, + name: "AdditionalLogFile", + definition: { + kind: "object", + fields: [{ + name: "title", + type: { + kind: "string" + }, + optional: false + }, { + name: "data", + type: { + kind: "string" + }, + optional: false + }] + } + }, + DeadlineRequest: { + kind: "alias", + location: { + type: "source", + fileName: "promise.js", + line: 210 + }, + name: "DeadlineRequest", + definition: { + kind: "number" + } + }, + SymbolResult: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 21 + }, + name: "SymbolResult", + definition: { + kind: "object", + fields: [{ + name: "resultType", + type: { + kind: "string-literal", + value: "SYMBOL" + }, + optional: false + }, { + name: "path", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "line", + type: { + kind: "number" + }, + optional: false + }, { + name: "column", + type: { + kind: "number" + }, + optional: false + }, { + name: "name", + type: { + kind: "string" + }, + optional: false + }, { + name: "containerName", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "icon", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "hoverText", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }] + } + }, + LanguageService: { + kind: "interface", + name: "LanguageService", + location: { + type: "source", + fileName: "LanguageService.js", + line: 146 + }, + staticMethods: {}, + instanceMethods: { + getDiagnostics: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 147 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "FileDiagnosticMap" + } + } + } + }, + observeDiagnostics: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 149 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "FileDiagnosticMap" + } + } + }, + observeStatus: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 151 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "StatusData" + } + } + }, + clickStatus: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 153 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "id", + type: { + kind: "string" + } + }, { + name: "button", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + }, + getAutocompleteSuggestions: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 159 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "position", + type: { + kind: "named", + name: "atom$Point" + } + }, { + name: "request", + type: { + kind: "named", + name: "AutocompleteRequest" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "AutocompleteResult" + } + } + } + }, + resolveAutocompleteSuggestion: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 165 + }, + kind: "function", + argumentTypes: [{ + name: "suggestion", + type: { + kind: "named", + name: "Completion" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "Completion" + } + } + } + }, + getDefinition: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 167 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "position", + type: { + kind: "named", + name: "atom$Point" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "DefinitionQueryResult" + } + } + } + }, + findReferences: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 172 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "position", + type: { + kind: "named", + name: "atom$Point" + } + }], + returnType: { + kind: "observable", + type: { + kind: "nullable", + type: { + kind: "named", + name: "FindReferencesReturn" + } + } + } + }, + getCoverage: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 177 + }, + kind: "function", + argumentTypes: [{ + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "CoverageResult" + } + } + } + }, + getOutline: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 179 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "Outline" + } + } + } + }, + getCodeLens: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 181 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "CodeLensData" + } + } + } + } + }, + resolveCodeLens: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 183 + }, + kind: "function", + argumentTypes: [{ + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "codeLens", + type: { + kind: "named", + name: "CodeLensData" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "CodeLensData" + } + } + } + }, + getCodeActions: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 196 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "range", + type: { + kind: "named", + name: "atom$Range" + } + }, { + name: "diagnostics", + type: { + kind: "array", + type: { + kind: "named", + name: "FileDiagnosticMessage" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "array", + type: { + kind: "named", + name: "CodeAction" + } + } + } + }, + typeHint: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 202 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "position", + type: { + kind: "named", + name: "atom$Point" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "TypeHint" + } + } + } + }, + highlight: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 204 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "position", + type: { + kind: "named", + name: "atom$Point" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "atom$Range" + } + } + } + } + }, + formatSource: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 209 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "range", + type: { + kind: "named", + name: "atom$Range" + } + }, { + name: "options", + type: { + kind: "named", + name: "FormatOptions" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "TextEdit" + } + } + } + } + }, + formatEntireFile: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 215 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "range", + type: { + kind: "named", + name: "atom$Range" + } + }, { + name: "options", + type: { + kind: "named", + name: "FormatOptions" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "object", + fields: [{ + name: "newCursor", + type: { + kind: "number" + }, + optional: true + }, { + name: "formatted", + type: { + kind: "string" + }, + optional: false + }] + } + } + } + }, + formatAtPosition: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 224 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "position", + type: { + kind: "named", + name: "atom$Point" + } + }, { + name: "triggerCharacter", + type: { + kind: "string" + } + }, { + name: "options", + type: { + kind: "named", + name: "FormatOptions" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "TextEdit" + } + } + } + } + }, + signatureHelp: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 231 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "position", + type: { + kind: "named", + name: "atom$Point" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "SignatureHelp" + } + } + } + }, + onToggleCoverage: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 236 + }, + kind: "function", + argumentTypes: [{ + name: "on", + type: { + kind: "boolean" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + }, + getAdditionalLogFiles: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 238 + }, + kind: "function", + argumentTypes: [{ + name: "deadline", + type: { + kind: "named", + name: "DeadlineRequest" + } + }], + returnType: { + kind: "promise", + type: { + kind: "array", + type: { + kind: "named", + name: "AdditionalLogFile" + } + } + } + }, + supportsSymbolSearch: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 242 + }, + kind: "function", + argumentTypes: [{ + name: "directories", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "boolean" + } + } + }, + symbolSearch: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 244 + }, + kind: "function", + argumentTypes: [{ + name: "query", + type: { + kind: "string" + } + }, { + name: "directories", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "array", + type: { + kind: "named", + name: "SymbolResult" + } + } + } + } + }, + getProjectRoot: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 249 + }, + kind: "function", + argumentTypes: [{ + name: "fileUri", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "NuclideUri" + } + } + } + }, + isFileInProject: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 251 + }, + kind: "function", + argumentTypes: [{ + name: "fileUri", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "boolean" + } + } + }, + getExpandedSelectionRange: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 253 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "currentSelection", + type: { + kind: "named", + name: "atom$Range" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "atom$Range" + } + } + } + }, + getCollapsedSelectionRange: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 258 + }, + kind: "function", + argumentTypes: [{ + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + } + }, { + name: "currentSelection", + type: { + kind: "named", + name: "atom$Range" + } + }, { + name: "originalCursorPosition", + type: { + kind: "named", + name: "atom$Point" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "atom$Range" + } + } + } + }, + dispose: { + location: { + type: "source", + fileName: "LanguageService.js", + line: 264 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "void" + } + } + } + }, + initialize: { + kind: "function", + name: "initialize", + location: { + type: "source", + fileName: "PythonService.js", + line: 135 + }, + type: { + location: { + type: "source", + fileName: "PythonService.js", + line: 135 + }, + kind: "function", + argumentTypes: [{ + name: "fileNotifier", + type: { + kind: "named", + name: "FileNotifier" + } + }, { + name: "config", + type: { + kind: "named", + name: "PythonServiceConfig" + } + }], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "LanguageService" + } + } + } + }, + getDiagnostics: { + kind: "function", + name: "getDiagnostics", + location: { + type: "source", + fileName: "PythonService.js", + line: 457 + }, + type: { + location: { + type: "source", + fileName: "PythonService.js", + line: 457 + }, + kind: "function", + argumentTypes: [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "array", + type: { + kind: "named", + name: "PythonDiagnostic" + } + } + } + } + }, + getBuildableTargets: { + kind: "function", + name: "getBuildableTargets", + location: { + type: "source", + fileName: "PythonService.js", + line: 519 + }, + type: { + location: { + type: "source", + fileName: "PythonService.js", + line: 519 + }, + kind: "function", + argumentTypes: [{ + name: "src", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "array", + type: { + kind: "string" + } + } + } + } + }, + reset: { + kind: "function", + name: "reset", + location: { + type: "source", + fileName: "PythonService.js", + line: 539 + }, + type: { + location: { + type: "source", + fileName: "PythonService.js", + line: 539 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "void" + } + } + } + } +}); \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/lib/constants.js b/pkg/nuclide-python-rpc/lib/constants.js index 270acd9339..143b765c04 100644 --- a/pkg/nuclide-python-rpc/lib/constants.js +++ b/pkg/nuclide-python-rpc/lib/constants.js @@ -1,3 +1,8 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,8 +10,8 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -export const IDENTIFIER_REGEXP = /[a-zA-Z_][a-zA-Z0-9_]*/g; +const IDENTIFIER_REGEXP = exports.IDENTIFIER_REGEXP = /[a-zA-Z_][a-zA-Z0-9_]*/g; \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/lib/flake8.js b/pkg/nuclide-python-rpc/lib/flake8.js index 7f39ad51bb..83b36204ca 100644 --- a/pkg/nuclide-python-rpc/lib/flake8.js +++ b/pkg/nuclide-python-rpc/lib/flake8.js @@ -1,26 +1,30 @@ -/** - * 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 - */ +'use strict'; -import type {DiagnosticMessageType} from 'atom-ide-ui'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.parseFlake8Output = parseFlake8Output; -function classifyCode(code: string): DiagnosticMessageType { + +function classifyCode(code) { if (/^(B9|C|E[235]|F40[135]|T400|T49)/.test(code)) { return 'Info'; } else if (/^(F|B|T484|E999)/.test(code)) { return 'Error'; } return 'Warning'; -} +} /** + * 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. + * + * + * @format + */ -export function parseFlake8Output(src: string, output: string): Array { +function parseFlake8Output(src, output) { const regex = /(\d+):(\d+):\s([A-Z]{1,2}\d{2,3})\s+(.*)/g; const results = []; @@ -36,9 +40,9 @@ export function parseFlake8Output(src: string, output: string): Array { column: parseInt(column, 10) - 1 || 0, code, type: classifyCode(code), - message, + message }); } return results; -} +} \ No newline at end of file diff --git a/pkg/nuclide-python-rpc/lib/outline.js b/pkg/nuclide-python-rpc/lib/outline.js index 6f7a4581b9..5d9965c056 100644 --- a/pkg/nuclide-python-rpc/lib/outline.js +++ b/pkg/nuclide-python-rpc/lib/outline.js @@ -1,38 +1,23 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {OutlineTree} from 'atom-ide-ui'; -import type {TextToken} from 'nuclide-commons/tokenized-text'; -import type { - PythonOutlineItem, - PythonClassItem, - PythonFunctionItem, - PythonStatementItem, -} from '../../nuclide-python-rpc'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.itemsToOutline = itemsToOutline; -import {Point} from 'simple-text-buffer'; -import { - keyword, - method, - param, - whitespace, - plain, -} from 'nuclide-commons/tokenized-text'; +var _simpleTextBuffer; -type ShowVariableMode = 'none' | 'constants' | 'all'; +function _load_simpleTextBuffer() { + return _simpleTextBuffer = require('simple-text-buffer'); +} + +var _tokenizedText; + +function _load_tokenizedText() { + return _tokenizedText = require('../../../modules/nuclide-commons/tokenized-text'); +} -function itemToOutlineTree( - mode: ShowVariableMode, - item: PythonOutlineItem, -): ?OutlineTree { +function itemToOutlineTree(mode, item) { switch (item.kind) { case 'class': return classToOutlineTree('all', item); @@ -41,40 +26,34 @@ function itemToOutlineTree( case 'statement': return statementToOutlineTree(mode, item); } -} +} /** + * 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. + * + * strict-local + * @format + */ -function classToOutlineTree( - mode: ShowVariableMode, - item: PythonClassItem, -): OutlineTree { - return { - tokenizedText: [keyword('class'), whitespace(' '), method(item.name)], +function classToOutlineTree(mode, item) { + return Object.assign({ + tokenizedText: [(0, (_tokenizedText || _load_tokenizedText()).keyword)('class'), (0, (_tokenizedText || _load_tokenizedText()).whitespace)(' '), (0, (_tokenizedText || _load_tokenizedText()).method)(item.name)], representativeName: item.name, - children: itemsToOutline(mode, item.children), - ...itemToPositions(item), - }; + children: itemsToOutline(mode, item.children) + }, itemToPositions(item)); } -function functionToOutlineTree(item: PythonFunctionItem): OutlineTree { - return { - tokenizedText: [ - keyword('def'), - whitespace(' '), - method(item.name), - plain('('), - ...argsToText(item.params || []), - plain(')'), - ], +function functionToOutlineTree(item) { + return Object.assign({ + tokenizedText: [(0, (_tokenizedText || _load_tokenizedText()).keyword)('def'), (0, (_tokenizedText || _load_tokenizedText()).whitespace)(' '), (0, (_tokenizedText || _load_tokenizedText()).method)(item.name), (0, (_tokenizedText || _load_tokenizedText()).plain)('('), ...argsToText(item.params || []), (0, (_tokenizedText || _load_tokenizedText()).plain)(')')], representativeName: item.name, - children: [], - ...itemToPositions(item), - }; + children: [] + }, itemToPositions(item)); } -function statementToOutlineTree( - mode: ShowVariableMode, - item: PythonStatementItem, -): ?OutlineTree { +function statementToOutlineTree(mode, item) { if (mode === 'none') { return null; } @@ -85,60 +64,51 @@ function statementToOutlineTree( return null; } - return { - tokenizedText: [plain(name)], + return Object.assign({ + tokenizedText: [(0, (_tokenizedText || _load_tokenizedText()).plain)(name)], representativeName: name, - children: [], - ...itemToPositions(item), - }; + children: [] + }, itemToPositions(item)); } -function argsToText(args: Array): Array { +function argsToText(args) { const result = []; function startArg() { if (result.length > 0) { - result.push(plain(',')); - result.push(whitespace(' ')); + result.push((0, (_tokenizedText || _load_tokenizedText()).plain)(',')); + result.push((0, (_tokenizedText || _load_tokenizedText()).whitespace)(' ')); } } args.forEach(arg => { startArg(); if (arg.startsWith('**')) { - result.push(plain('**')); - result.push(param(arg.slice(2))); + result.push((0, (_tokenizedText || _load_tokenizedText()).plain)('**')); + result.push((0, (_tokenizedText || _load_tokenizedText()).param)(arg.slice(2))); } else if (arg.startsWith('*')) { - result.push(plain('*')); - result.push(param(arg.slice(1))); + result.push((0, (_tokenizedText || _load_tokenizedText()).plain)('*')); + result.push((0, (_tokenizedText || _load_tokenizedText()).param)(arg.slice(1))); } else { - result.push(param(arg)); + result.push((0, (_tokenizedText || _load_tokenizedText()).param)(arg)); } }); return result; } -function itemToPositions( - item: PythonOutlineItem, -): { - startPosition: atom$Point, - endPosition: atom$Point, -} { - const {start, end} = item; +function itemToPositions(item) { + const { start, end } = item; return { - startPosition: new Point(start.line - 1, start.column), + startPosition: new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(start.line - 1, start.column), // Outline's endPosition is inclusive, while Jedi's is exclusive. // By decrementing the end column, we avoid situations where // two items are highlighted at once. End column may end up as -1, // which still has the intended effect. - endPosition: new Point(end.line - 1, end.column - 1), + endPosition: new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(end.line - 1, end.column - 1) }; } -export function itemsToOutline( - mode: ShowVariableMode, - items: ?Array, -): Array { +function itemsToOutline(mode, items) { if (!items || items.length === 0) { return []; } @@ -149,4 +119,4 @@ export function itemsToOutline( } }); return result; -} +} \ No newline at end of file diff --git a/pkg/nuclide-python/lib/LinkTreeLinter.js b/pkg/nuclide-python/lib/LinkTreeLinter.js index 4fd10b80a7..19f05b3cf5 100644 --- a/pkg/nuclide-python/lib/LinkTreeLinter.js +++ b/pkg/nuclide-python/lib/LinkTreeLinter.js @@ -1,3 +1,73 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _debounced; + +function _load_debounced() { + return _debounced = require('../../../modules/nuclide-commons-atom/debounced'); +} + +var _event; + +function _load_event() { + return _event = require('../../../modules/nuclide-commons/event'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _observable; + +function _load_observable() { + return _observable = require('../../../modules/nuclide-commons/observable'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _shallowequal; + +function _load_shallowequal() { + return _shallowequal = _interopRequireDefault(require('shallowequal')); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _constants; + +function _load_constants() { + return _constants = require('./constants'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,142 +75,98 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {LinterMessageV2} from 'atom-ide-ui'; -import type {BuckTaskRunnerService} from '../../nuclide-buck/lib/types'; -import type CwdApi from '../../nuclide-current-working-directory/lib/CwdApi'; - -import {getLogger} from 'log4js'; -import {observeActiveEditorsDebounced} from 'nuclide-commons-atom/debounced'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {compact} from 'nuclide-commons/observable'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Observable, Subject} from 'rxjs'; -import shallowEqual from 'shallowequal'; -import {track} from '../../nuclide-analytics'; -import {getPythonServiceByNuclideUri} from '../../nuclide-remote-connection'; -import {GRAMMAR_SET} from './constants'; - const DEBOUNCE_INTERVAL = 1000; // TODO(hansonw): increase when code action UI supports more const NUM_SUGGESTIONS = 3; -export default class LinkTreeLinter { - _buckTaskRunnerService: ?BuckTaskRunnerService; - _cwdApi: ?CwdApi; +class LinkTreeLinter { + constructor() { + this._disposedPaths = new Set(); + } // Once the user interacts with a diagnostic, hide it forever. - _disposedPaths: Set = new Set(); - consumeBuckTaskRunner(service: BuckTaskRunnerService): IDisposable { + + consumeBuckTaskRunner(service) { this._buckTaskRunnerService = service; - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { this._buckTaskRunnerService = null; }); } - consumeCwdApi(api: CwdApi): IDisposable { + consumeCwdApi(api) { this._cwdApi = api; - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { this._cwdApi = null; }); } - observeMessages(): Observable> { - return observeActiveEditorsDebounced(DEBOUNCE_INTERVAL) - .let(compact) - .switchMap(editor => { - const path = editor.getPath(); - if ( - path == null || - this._disposedPaths.has(path) || - !GRAMMAR_SET.has(editor.getGrammar().scopeName) - ) { - return Observable.of([]); - } - // If the CWD doesn't contain the file, Buck isn't going to work. - const cwd = this._cwdApi == null ? null : this._cwdApi.getCwd(); - if (cwd != null && !nuclideUri.contains(cwd, path)) { - return Observable.of([]); + observeMessages() { + return (0, (_debounced || _load_debounced()).observeActiveEditorsDebounced)(DEBOUNCE_INTERVAL).let((_observable || _load_observable()).compact).switchMap(editor => { + const path = editor.getPath(); + if (path == null || this._disposedPaths.has(path) || !(_constants || _load_constants()).GRAMMAR_SET.has(editor.getGrammar().scopeName)) { + return _rxjsBundlesRxMinJs.Observable.of([]); + } + // If the CWD doesn't contain the file, Buck isn't going to work. + const cwd = this._cwdApi == null ? null : this._cwdApi.getCwd(); + if (cwd != null && !(_nuclideUri || _load_nuclideUri()).default.contains(cwd, path)) { + return _rxjsBundlesRxMinJs.Observable.of([]); + } + const pythonService = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getPythonServiceByNuclideUri)(path); + return _rxjsBundlesRxMinJs.Observable.fromPromise(pythonService.getBuildableTargets(path)).filter(targets => targets.length > 0).switchMap(targets => { + const buckService = this._buckTaskRunnerService; + if (buckService == null || editor.getLineCount() === 0) { + return _rxjsBundlesRxMinJs.Observable.of([]); } - const pythonService = getPythonServiceByNuclideUri(path); - return Observable.fromPromise(pythonService.getBuildableTargets(path)) - .filter(targets => targets.length > 0) - .switchMap(targets => { - const buckService = this._buckTaskRunnerService; - if (buckService == null || editor.getLineCount() === 0) { - return Observable.of([]); - } - const position = [ - [0, 0], - [0, editor.lineTextForBufferRow(0).length], - ]; - const disposed = new Subject(); - // If the user happened to build a viable target - great! - const taskCompleted = observableFromSubscribeFunction(cb => - buckService.onDidCompleteTask(task => { - if (targets.includes(task.buildTarget)) { - cb(); - } - }), - ); - const solutions = targets.slice(0, NUM_SUGGESTIONS).map(target => ({ - title: target, - position, - apply: () => { - track('python.link-tree-built', {target, path}); - buckService.setBuildTarget(target); - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'nuclide-task-runner:toggle-buck-toolbar', - {visible: true}, - ); - // TODO: Ideally this would actually trigger the build - - // but there's no way to wait for 'build' to be enabled. - this._disposedPaths.add(path); - disposed.next(); - }, - })); - solutions.push({ - title: 'No thanks', - position, - apply: () => { - track('python.link-tree-ignored', {path}); - this._disposedPaths.add(path); - disposed.next(); - }, - }); - return Observable.of([ - { - kind: 'action', - severity: 'info', - location: { - file: path, - position, - }, - excerpt: - 'For better language services, build a binary or unittest\n' + - 'that uses this file with Buck. Suggestions:', - solutions, - }, - ]) - .concat(Observable.never()) - .takeUntil(disposed) - .takeUntil(taskCompleted); - }) - .takeUntil( - observableFromSubscribeFunction(cb => editor.onDidDestroy(cb)), - ) - .concat(Observable.of([])); - }) - .catch((err, continuation) => { - getLogger('LinkTreeLinter').error(err); - return continuation; - }) - .distinctUntilChanged(shallowEqual); + const position = [[0, 0], [0, editor.lineTextForBufferRow(0).length]]; + const disposed = new _rxjsBundlesRxMinJs.Subject(); + // If the user happened to build a viable target - great! + const taskCompleted = (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => buckService.onDidCompleteTask(task => { + if (targets.includes(task.buildTarget)) { + cb(); + } + })); + const solutions = targets.slice(0, NUM_SUGGESTIONS).map(target => ({ + title: target, + position, + apply: () => { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('python.link-tree-built', { target, path }); + buckService.setBuildTarget(target); + atom.commands.dispatch(atom.views.getView(atom.workspace), 'nuclide-task-runner:toggle-buck-toolbar', { visible: true }); + // TODO: Ideally this would actually trigger the build - + // but there's no way to wait for 'build' to be enabled. + this._disposedPaths.add(path); + disposed.next(); + } + })); + solutions.push({ + title: 'No thanks', + position, + apply: () => { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('python.link-tree-ignored', { path }); + this._disposedPaths.add(path); + disposed.next(); + } + }); + return _rxjsBundlesRxMinJs.Observable.of([{ + kind: 'action', + severity: 'info', + location: { + file: path, + position + }, + excerpt: 'For better language services, build a binary or unittest\n' + 'that uses this file with Buck. Suggestions:', + solutions + }]).concat(_rxjsBundlesRxMinJs.Observable.never()).takeUntil(disposed).takeUntil(taskCompleted); + }).takeUntil((0, (_event || _load_event()).observableFromSubscribeFunction)(cb => editor.onDidDestroy(cb))).concat(_rxjsBundlesRxMinJs.Observable.of([])); + }).catch((err, continuation) => { + (0, (_log4js || _load_log4js()).getLogger)('LinkTreeLinter').error(err); + return continuation; + }).distinctUntilChanged((_shallowequal || _load_shallowequal()).default); } } +exports.default = LinkTreeLinter; \ No newline at end of file diff --git a/pkg/nuclide-python/lib/LintHelpers.js b/pkg/nuclide-python/lib/LintHelpers.js index dc44a2dad1..39919d1124 100644 --- a/pkg/nuclide-python/lib/LintHelpers.js +++ b/pkg/nuclide-python/lib/LintHelpers.js @@ -1,3 +1,41 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _diagnosticRange; + +function _load_diagnosticRange() { + return _diagnosticRange = require('./diagnostic-range'); +} + +var _config; + +function _load_config() { + return _config = require('./config'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,31 +43,19 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {LinterMessage} from 'atom-ide-ui'; - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {getPythonServiceByNuclideUri} from '../../nuclide-remote-connection'; -import {trackTiming} from '../../nuclide-analytics'; -import {getDiagnosticRange} from './diagnostic-range'; -import {getEnableLinting, getLintExtensionBlacklist} from './config'; - -export default class LintHelpers { - static lint(editor: TextEditor): Promise> { +class LintHelpers { + static lint(editor) { const src = editor.getPath(); - if ( - src == null || - !getEnableLinting() || - getLintExtensionBlacklist().includes(nuclideUri.extname(src)) - ) { + if (src == null || !(0, (_config || _load_config()).getEnableLinting)() || (0, (_config || _load_config()).getLintExtensionBlacklist)().includes((_nuclideUri || _load_nuclideUri()).default.extname(src))) { return Promise.resolve([]); } - return trackTiming('nuclide-python.lint', async () => { - const service = getPythonServiceByNuclideUri(src); + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)('nuclide-python.lint', async () => { + const service = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getPythonServiceByNuclideUri)(src); const diagnostics = await service.getDiagnostics(src); if (editor.isDestroyed()) { return []; @@ -39,8 +65,9 @@ export default class LintHelpers { type: diagnostic.type, text: diagnostic.message, filePath: diagnostic.file, - range: getDiagnosticRange(diagnostic, editor), + range: (0, (_diagnosticRange || _load_diagnosticRange()).getDiagnosticRange)(diagnostic, editor) })); }); } } +exports.default = LintHelpers; \ No newline at end of file diff --git a/pkg/nuclide-python/lib/config.js b/pkg/nuclide-python/lib/config.js index 027354575e..e450ecf77b 100644 --- a/pkg/nuclide-python/lib/config.js +++ b/pkg/nuclide-python/lib/config.js @@ -1,40 +1,57 @@ -/** - * 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 - */ - -import featureConfig from 'nuclide-commons-atom/feature-config'; - -export function getAutocompleteArguments(): boolean { - return (featureConfig.get('nuclide-python.autocompleteArguments'): any); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getAutocompleteArguments = getAutocompleteArguments; +exports.getIncludeOptionalArguments = getIncludeOptionalArguments; +exports.getPythonPath = getPythonPath; +exports.getShowGlobalVariables = getShowGlobalVariables; +exports.getShowSignatureHelp = getShowSignatureHelp; +exports.getEnableLinting = getEnableLinting; +exports.getLintExtensionBlacklist = getLintExtensionBlacklist; + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); } -export function getIncludeOptionalArguments(): boolean { - return (featureConfig.get('nuclide-python.includeOptionalArguments'): any); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function getAutocompleteArguments() { + return (_featureConfig || _load_featureConfig()).default.get('nuclide-python.autocompleteArguments'); +} /** + * 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. + * + * + * @format + */ + +function getIncludeOptionalArguments() { + return (_featureConfig || _load_featureConfig()).default.get('nuclide-python.includeOptionalArguments'); } -export function getPythonPath(): string { - return (featureConfig.get('nuclide-python.pathToPython'): any); +function getPythonPath() { + return (_featureConfig || _load_featureConfig()).default.get('nuclide-python.pathToPython'); } -export function getShowGlobalVariables(): boolean { - return (featureConfig.get('nuclide-python.showGlobalVariables'): any); +function getShowGlobalVariables() { + return (_featureConfig || _load_featureConfig()).default.get('nuclide-python.showGlobalVariables'); } -export function getShowSignatureHelp(): boolean { - return Boolean(featureConfig.get('nuclide-python.showSignatureHelp')); +function getShowSignatureHelp() { + return Boolean((_featureConfig || _load_featureConfig()).default.get('nuclide-python.showSignatureHelp')); } -export function getEnableLinting(): boolean { - return (featureConfig.get('nuclide-python.enableLinting'): any); +function getEnableLinting() { + return (_featureConfig || _load_featureConfig()).default.get('nuclide-python.enableLinting'); } -export function getLintExtensionBlacklist(): Array { - return (featureConfig.get('nuclide-python.lintExtensionBlacklist'): any); -} +function getLintExtensionBlacklist() { + return (_featureConfig || _load_featureConfig()).default.get('nuclide-python.lintExtensionBlacklist'); +} \ No newline at end of file diff --git a/pkg/nuclide-python/lib/constants.js b/pkg/nuclide-python/lib/constants.js index b8fd8a3214..9fb3def20b 100644 --- a/pkg/nuclide-python/lib/constants.js +++ b/pkg/nuclide-python/lib/constants.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,10 +10,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -export const GRAMMARS = ['source.python', 'python']; -export const GRAMMAR_SET: Set = new Set(GRAMMARS); -export const PACKAGE_NAME = 'nuclide-python'; +const GRAMMARS = exports.GRAMMARS = ['source.python', 'python']; +const GRAMMAR_SET = exports.GRAMMAR_SET = new Set(GRAMMARS); +const PACKAGE_NAME = exports.PACKAGE_NAME = 'nuclide-python'; \ No newline at end of file diff --git a/pkg/nuclide-python/lib/diagnostic-range.js b/pkg/nuclide-python/lib/diagnostic-range.js index 006ad843c1..cf32fa49de 100644 --- a/pkg/nuclide-python/lib/diagnostic-range.js +++ b/pkg/nuclide-python/lib/diagnostic-range.js @@ -1,3 +1,24 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getDiagnosticRange = getDiagnosticRange; + +var _atom = require('atom'); + +var _range; + +function _load_range() { + return _range = require('../../../modules/nuclide-commons-atom/range'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,36 +26,27 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {PythonDiagnostic} from '../../nuclide-python-rpc'; - -import {Point, Range} from 'atom'; -import {wordAtPosition, trimRange} from 'nuclide-commons-atom/range'; -import {getLogger} from 'log4js'; - -const logger = getLogger('nuclide-python'); +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-python'); // Computes an appropriate underline range using the diagnostic type information. // Range variants include underlining the entire line, entire trimmed line, // or a word or whitespace range within the line. -export function getDiagnosticRange( - diagnostic: PythonDiagnostic, - editor: atom$TextEditor, -): Range { +function getDiagnosticRange(diagnostic, editor) { const buffer = editor.getBuffer(); // The diagnostic message's line index may be out of bounds if buffer contents // have changed. To prevent an exception, we just use the last line of the buffer if // unsafeLine is out of bounds. - const {code, line: unsafeLine, column, message} = diagnostic; + const { code, line: unsafeLine, column, message } = diagnostic; const lastRow = buffer.getLastRow(); const line = unsafeLine <= lastRow ? unsafeLine : lastRow; const lineLength = buffer.lineLengthForRow(line); - const trimmedRange = trimRange(editor, buffer.rangeForRow(line, false)); + const trimmedRange = (0, (_range || _load_range()).trimRange)(editor, buffer.rangeForRow(line, false)); const trimmedStartCol = trimmedRange.start.column; const trimmedEndCol = trimmedRange.end.column; @@ -49,24 +61,20 @@ export function getDiagnosticRange( if (code === 'E902' || message.startsWith('SyntaxError')) { break; } - return new Range([line, 0], [line, trimmedStartCol]); + return new _atom.Range([line, 0], [line, trimmedStartCol]); // pep8 - whitespace case 'E2': // '#' comment spacing if (code.startsWith('E26')) { - return new Range([line, column], [line, trimmedEndCol]); + return new _atom.Range([line, column], [line, trimmedEndCol]); } const numericCode = parseInt(code.slice(1), 10); // Missing whitespace - underline the closest symbol - if ((numericCode >= 225 && numericCode <= 231) || numericCode === 275) { - return new Range([line, column], [line, column + 1]); + if (numericCode >= 225 && numericCode <= 231 || numericCode === 275) { + return new _atom.Range([line, column], [line, column + 1]); } // Extra whitespace - underline the offending whitespace - const whitespace = wordAtPosition( - editor, - new Point(line, column), - /\s+/g, - ); + const whitespace = (0, (_range || _load_range()).wordAtPosition)(editor, new _atom.Point(line, column), /\s+/g); if (whitespace) { return whitespace.range; } @@ -75,19 +83,19 @@ export function getDiagnosticRange( // pep8 - line length case 'E3': case 'E5': - return new Range([line, 0], [line, lineLength]); + return new _atom.Range([line, 0], [line, lineLength]); // pep8 - whitespace warning case 'W2': // trailing whitespace if (code === 'W291') { - return new Range([line, trimmedEndCol], [line, lineLength]); + return new _atom.Range([line, trimmedEndCol], [line, lineLength]); } break; // pyflakes - import related messages case 'F4': if (code === 'F405') { // may be undefined, or defined from import * - const word = wordAtPosition(editor, new Point(line, column)); + const word = (0, (_range || _load_range()).wordAtPosition)(editor, new _atom.Point(line, column)); if (word) { return word.range; } @@ -100,7 +108,7 @@ export function getDiagnosticRange( if (!code.startsWith('F82')) { break; } - const word = wordAtPosition(editor, new Point(line, column)); + const word = (0, (_range || _load_range()).wordAtPosition)(editor, new _atom.Point(line, column)); if (word) { return word.range; } @@ -109,14 +117,9 @@ export function getDiagnosticRange( break; } } catch (e) { - const diagnosticAsString = `${ - diagnostic.file - }:${unsafeLine}:${column} - ${code}: ${message}`; - logger.error( - `Failed to find flake8 diagnostic range: ${diagnosticAsString}`, - e, - ); + const diagnosticAsString = `${diagnostic.file}:${unsafeLine}:${column} - ${code}: ${message}`; + logger.error(`Failed to find flake8 diagnostic range: ${diagnosticAsString}`, e); } - return new Range([line, trimmedStartCol], [line, trimmedEndCol]); -} + return new _atom.Range([line, trimmedStartCol], [line, trimmedEndCol]); +} \ No newline at end of file diff --git a/pkg/nuclide-python/lib/main.js b/pkg/nuclide-python/lib/main.js index 4029f5efa9..e601e2993f 100644 --- a/pkg/nuclide-python/lib/main.js +++ b/pkg/nuclide-python/lib/main.js @@ -1,3 +1,67 @@ +'use strict'; + +var _constants; + +function _load_constants() { + return _constants = require('./constants'); +} + +var _LinkTreeLinter; + +function _load_LinkTreeLinter() { + return _LinkTreeLinter = _interopRequireDefault(require('./LinkTreeLinter')); +} + +var _LintHelpers; + +function _load_LintHelpers() { + return _LintHelpers = _interopRequireDefault(require('./LintHelpers')); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideOpenFiles; + +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} + +var _nuclideLanguageService; + +function _load_nuclideLanguageService() { + return _nuclideLanguageService = require('../../nuclide-language-service'); +} + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _config; + +function _load_config() { + return _config = require('./config'); +} + +var _pythonPlatform; + +function _load_pythonPlatform() { + return _pythonPlatform = require('./pythonPlatform'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,73 +69,41 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {LinterProvider, RegisterIndieLinter} from 'atom-ide-ui'; -import type {BuckTaskRunnerService} from '../../nuclide-buck/lib/types'; -import type {PlatformService} from '../../nuclide-buck/lib/PlatformService'; -import type CwdApi from '../../nuclide-current-working-directory/lib/CwdApi'; -import type {AtomLanguageServiceConfig} from '../../nuclide-language-service/lib/AtomLanguageService'; -import type {LanguageService} from '../../nuclide-language-service/lib/LanguageService'; - -import {GRAMMARS, GRAMMAR_SET} from './constants'; -import LinkTreeLinter from './LinkTreeLinter'; -import LintHelpers from './LintHelpers'; -import { - getPythonServiceByConnection, - ServerConnection, -} from '../../nuclide-remote-connection'; -import {getNotifierByConnection} from '../../nuclide-open-files'; -import { - AtomLanguageService, - updateAutocompleteFirstResults, - updateAutocompleteResults, -} from '../../nuclide-language-service'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import { - getShowGlobalVariables, - getShowSignatureHelp, - getAutocompleteArguments, - getIncludeOptionalArguments, -} from './config'; -import {providePythonPlatformGroup} from './pythonPlatform'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -async function connectionToPythonService( - connection: ?ServerConnection, -): Promise { - const pythonService = getPythonServiceByConnection(connection); - const fileNotifier = await getNotifierByConnection(connection); +async function connectionToPythonService(connection) { + const pythonService = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getPythonServiceByConnection)(connection); + const fileNotifier = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getNotifierByConnection)(connection); const languageService = await pythonService.initialize(fileNotifier, { - showGlobalVariables: getShowGlobalVariables(), - autocompleteArguments: getAutocompleteArguments(), - includeOptionalArguments: getIncludeOptionalArguments(), + showGlobalVariables: (0, (_config || _load_config()).getShowGlobalVariables)(), + autocompleteArguments: (0, (_config || _load_config()).getAutocompleteArguments)(), + includeOptionalArguments: (0, (_config || _load_config()).getIncludeOptionalArguments)() }); return languageService; } -function getAtomConfig(): AtomLanguageServiceConfig { +function getAtomConfig() { return { name: 'Python', - grammars: GRAMMARS, + grammars: (_constants || _load_constants()).GRAMMARS, outline: { version: '0.1.0', priority: 1, - analyticsEventName: 'python.outline', + analyticsEventName: 'python.outline' }, codeFormat: { version: '0.1.0', priority: 1, analyticsEventName: 'python.formatCode', canFormatRanges: false, - canFormatAtPosition: false, + canFormatAtPosition: false }, findReferences: { version: '0.1.0', - analyticsEventName: 'python.get-references', + analyticsEventName: 'python.get-references' }, autocomplete: { inclusionPriority: 5, @@ -80,106 +112,84 @@ function getAtomConfig(): AtomLanguageServiceConfig { excludeLowerPriority: false, analytics: { eventName: 'nuclide-python', - shouldLogInsertedSuggestion: false, + shouldLogInsertedSuggestion: false }, autocompleteCacherConfig: { - updateResults: updateAutocompleteResults, - updateFirstResults: updateAutocompleteFirstResults, + updateResults: (_nuclideLanguageService || _load_nuclideLanguageService()).updateAutocompleteResults, + updateFirstResults: (_nuclideLanguageService || _load_nuclideLanguageService()).updateAutocompleteFirstResults }, - supportsResolve: false, + supportsResolve: false }, definition: { version: '0.1.0', priority: 20, - definitionEventName: 'python.get-definition', + definitionEventName: 'python.get-definition' }, typeHint: { version: '0.0.0', priority: 5, - analyticsEventName: 'python.hover', + analyticsEventName: 'python.hover' }, - signatureHelp: getShowSignatureHelp() - ? { - version: '0.1.0', - priority: 1, - triggerCharacters: new Set(['(', ',']), - analyticsEventName: 'python.signatureHelp', - } - : undefined, + signatureHelp: (0, (_config || _load_config()).getShowSignatureHelp)() ? { + version: '0.1.0', + priority: 1, + triggerCharacters: new Set(['(', ',']), + analyticsEventName: 'python.signatureHelp' + } : undefined }; } -function resetServices(): void { - getPythonServiceByConnection(null).reset(); - ServerConnection.getAllConnections().forEach(conn => { - getPythonServiceByConnection(conn).reset(); +function resetServices() { + (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getPythonServiceByConnection)(null).reset(); + (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).ServerConnection.getAllConnections().forEach(conn => { + (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getPythonServiceByConnection)(conn).reset(); }); } class Activation { - _pythonLanguageService: AtomLanguageService; - _linkTreeLinter: LinkTreeLinter; - _subscriptions: UniversalDisposable; - - constructor(rawState: ?Object) { - this._pythonLanguageService = new AtomLanguageService( - connectionToPythonService, - getAtomConfig(), - ); + + constructor(rawState) { + this._pythonLanguageService = new (_nuclideLanguageService || _load_nuclideLanguageService()).AtomLanguageService(connectionToPythonService, getAtomConfig()); this._pythonLanguageService.activate(); - this._linkTreeLinter = new LinkTreeLinter(); - this._subscriptions = new UniversalDisposable( - this._pythonLanguageService, - atom.commands.add( - 'atom-workspace', - 'nuclide-python:reset-language-services', - resetServices, - ), - ); + this._linkTreeLinter = new (_LinkTreeLinter || _load_LinkTreeLinter()).default(); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(this._pythonLanguageService, atom.commands.add('atom-workspace', 'nuclide-python:reset-language-services', resetServices)); } - provideLint(): LinterProvider { + provideLint() { return { - grammarScopes: Array.from(GRAMMAR_SET), + grammarScopes: Array.from((_constants || _load_constants()).GRAMMAR_SET), scope: 'file', name: 'flake8', - lint: editor => LintHelpers.lint(editor), + lint: editor => (_LintHelpers || _load_LintHelpers()).default.lint(editor) }; } - consumeLinterIndie(register: RegisterIndieLinter): IDisposable { - const linter = register({name: 'Python'}); - const disposable = new UniversalDisposable( - linter, - this._linkTreeLinter - .observeMessages() - .subscribe(messages => linter.setAllMessages(messages)), - ); + consumeLinterIndie(register) { + const linter = register({ name: 'Python' }); + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(linter, this._linkTreeLinter.observeMessages().subscribe(messages => linter.setAllMessages(messages))); this._subscriptions.add(disposable); - return new UniversalDisposable(disposable, () => - this._subscriptions.remove(disposable), - ); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(disposable, () => this._subscriptions.remove(disposable)); } - consumePlatformService(service: PlatformService): IDisposable { - const disposable = service.register(providePythonPlatformGroup); + consumePlatformService(service) { + const disposable = service.register((_pythonPlatform || _load_pythonPlatform()).providePythonPlatformGroup); this._subscriptions.add(disposable); - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { this._subscriptions.remove(disposable); }); } - consumeBuckTaskRunner(service: BuckTaskRunnerService): IDisposable { + consumeBuckTaskRunner(service) { return this._linkTreeLinter.consumeBuckTaskRunner(service); } - consumeCwdApi(api: CwdApi): IDisposable { + consumeCwdApi(api) { return this._linkTreeLinter.consumeCwdApi(api); } - dispose(): void { + dispose() { this._subscriptions.dispose(); } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-python/lib/pythonPlatform.js b/pkg/nuclide-python/lib/pythonPlatform.js index ced78274ea..846fb51dda 100644 --- a/pkg/nuclide-python/lib/pythonPlatform.js +++ b/pkg/nuclide-python/lib/pythonPlatform.js @@ -1,33 +1,27 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {PlatformGroup} from '../../nuclide-buck/lib/types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.providePythonPlatformGroup = providePythonPlatformGroup; -import {Observable} from 'rxjs'; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); -export function providePythonPlatformGroup( - buckRoot: NuclideUri, - ruleType: string, - buildTarget: string, -): Observable { +function providePythonPlatformGroup(buckRoot, ruleType, buildTarget) { try { // $FlowFB const fbPythonPlatform = require('./fb-pythonPlatform'); - return fbPythonPlatform.providePythonPlatformGroup( - buckRoot, - ruleType, - buildTarget, - ); + return fbPythonPlatform.providePythonPlatformGroup(buckRoot, ruleType, buildTarget); } catch (error) { - return Observable.of(null); + return _rxjsBundlesRxMinJs.Observable.of(null); } -} +} /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-python/spec/LinkTreeLinter-spec.js b/pkg/nuclide-python/spec/LinkTreeLinter-spec.js deleted file mode 100644 index 786497c454..0000000000 --- a/pkg/nuclide-python/spec/LinkTreeLinter-spec.js +++ /dev/null @@ -1,116 +0,0 @@ -/** - * 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 - */ - -import invariant from 'assert'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import LinkTreeLinter from '../lib/LinkTreeLinter'; - -const TEST_TARGET = '//test:target'; - -describe('LinkTreeLinter', () => { - beforeEach(() => { - jasmine.useMockClock(); - - spyOn( - require('../../nuclide-remote-connection'), - 'getPythonServiceByNuclideUri', - ).andReturn({ - async getBuildableTargets() { - return [TEST_TARGET]; - }, - }); - - // Override the grammars to include the null grammar. - (require('../lib/constants'): any).GRAMMAR_SET = new Set([ - 'text.plain.null-grammar', - ]); - }); - - it('provides diagnostics for Python files with linktrees', () => { - const linkTreeLinter = new LinkTreeLinter(); - const mockBuckTaskRunner = ({}: any); - const mockCwdApi = ({}: any); - let onDidCompleteTask; - mockBuckTaskRunner.setBuildTarget = jasmine.createSpy('setBuildTarget'); - mockBuckTaskRunner.onDidCompleteTask = jasmine - .createSpy('onDidCompleteTask') - .andCallFake(cb => { - onDidCompleteTask = cb; - return new UniversalDisposable(); - }); - mockCwdApi.getCwd = jasmine.createSpy('getCwd').andReturn(__dirname); - - linkTreeLinter.consumeBuckTaskRunner(mockBuckTaskRunner); - linkTreeLinter.consumeCwdApi(mockCwdApi); - - const file1 = nuclideUri.join(__dirname, 'fixtures', 't.py'); - const file2 = nuclideUri.join(__dirname, 'fixtures', 'bad_syntax_land.py'); - - let messages = []; - linkTreeLinter.observeMessages().subscribe(m => { - messages = m; - }); - - waitsForPromise(async () => { - await atom.workspace.open(file1); - advanceClock(1000); // debounce delay - }); - - waitsFor(() => messages.length > 0, 'a diagnostic to appear'); - - runs(() => { - expect(messages.length).toBe(1); - const message = messages[0]; - expect(message.location.file).toBe(file1); - const {solutions} = message; - invariant(solutions != null); - expect(solutions.length).toBe(2); - expect(solutions[0].title).toBe(TEST_TARGET); - - // Applying the first action should fill the Buck runner and dismiss the message. - invariant(solutions[0].replaceWith === undefined); - solutions[0].apply(); - expect(messages).toEqual([]); - expect(mockBuckTaskRunner.setBuildTarget).toHaveBeenCalledWith( - TEST_TARGET, - ); - }); - - waitsForPromise(async () => { - await atom.workspace.open(file2); - advanceClock(1000); // debounce delay - }); - - waitsFor(() => messages.length > 0, 'a diagnostic to appear'); - - runs(() => { - expect(messages.length).toBe(1); - const message = messages[0]; - expect(message.location.file).toBe(file2); - - // Finishing the Buck task should also dismiss the message. - onDidCompleteTask({buildTarget: TEST_TARGET}); - expect(messages).toEqual([]); - }); - - waitsForPromise(async () => { - mockCwdApi.getCwd.reset(); - await atom.workspace.open(file1); - advanceClock(1000); // debounce delay - }); - - runs(() => { - // file1 should be blacklisted already: don't even check the CWD. - expect(mockCwdApi.getCwd).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/pkg/nuclide-python/spec/diagnostic-range-spec.js b/pkg/nuclide-python/spec/diagnostic-range-spec.js deleted file mode 100644 index b05a02aa59..0000000000 --- a/pkg/nuclide-python/spec/diagnostic-range-spec.js +++ /dev/null @@ -1,111 +0,0 @@ -/** - * 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 - */ - -import type {PythonDiagnostic} from '../../nuclide-python-rpc'; - -import invariant from 'assert'; -import {Range} from 'atom'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {getDiagnosticRange} from '../lib/diagnostic-range'; - -describe('Diagnostic range', () => { - const fixturePath = nuclideUri.join( - __dirname, - 'fixtures', - 'bad_syntax_land.py', - ); - let editor: ?atom$TextEditor = null; - - beforeEach(() => { - waitsForPromise(async () => { - editor = await atom.workspace.open(fixturePath); - }); - }); - - function checkRange(diagnostic: PythonDiagnostic, expectedRange: atom$Range) { - invariant(editor); - const range = getDiagnosticRange(diagnostic, editor); - expect(range).toEqual(expectedRange); - } - - function makeDiagnostic( - code: string, - message: string, - line: number, - column: number, - ): PythonDiagnostic { - return { - file: fixturePath, - type: 'Warning', - code, - message, - line, - column, - }; - } - - it('Underlines leading whitespace for indentation messages', () => { - checkRange(makeDiagnostic('E116', '', 24, 0), new Range([24, 0], [24, 8])); - checkRange( - makeDiagnostic('E901', 'IndentationError: blahblah', 25, 0), - new Range([25, 0], [25, 8]), - ); - }); - - it('Underlines the entire line for line length message', () => { - checkRange( - makeDiagnostic('E501', '', 22, 0), - new Range([22, 0], [22, 117]), - ); - }); - - it('Underlines the whitespace when there is extra whitespace', () => { - checkRange( - makeDiagnostic('E202', '', 20, 10), - new Range([20, 10], [20, 11]), - ); - checkRange(makeDiagnostic('E222', '', 31, 4), new Range([31, 3], [31, 5])); - }); - - it('Underlines the whitespace when there is trailing whitespace', () => { - checkRange(makeDiagnostic('W291', '', 37, 5), new Range([37, 5], [37, 9])); - }); - - it('Underlines the comment for comment spacing issues', () => { - checkRange( - makeDiagnostic('E261', '', 27, 12), - new Range([27, 12], [27, 85]), - ); - checkRange( - makeDiagnostic('E262', '', 28, 16), - new Range([28, 16], [28, 58]), - ); - }); - - it('Underlines the word for possibly undefined references', () => { - checkRange(makeDiagnostic('F405', '', 40, 4), new Range([40, 4], [40, 14])); - }); - - it('Underlines the symbol name for undefined references', () => { - checkRange(makeDiagnostic('F821', '', 40, 4), new Range([40, 4], [40, 14])); - }); - - it('Underlines the entire non-empty line contents for unused assignments', () => { - checkRange(makeDiagnostic('F841', '', 42, 0), new Range([42, 0], [42, 9])); - }); - - it('Underlines the entire non-empty line contents for syntax errors', () => { - checkRange( - makeDiagnostic('E901', 'SyntaxError', 45, 4), - new Range([45, 4], [45, 14]), - ); - }); -}); diff --git a/pkg/nuclide-python/spec/fixtures/bad_syntax_land.py b/pkg/nuclide-python/spec/fixtures/bad_syntax_land.py deleted file mode 100644 index c8cd8b2b12..0000000000 --- a/pkg/nuclide-python/spec/fixtures/bad_syntax_land.py +++ /dev/null @@ -1,46 +0,0 @@ -# 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. - -# @nolint - -# Unused single import, underline name. -import numpy -from os.path import ( - join, - # Unused from .. import, underline name on appropriate line. - abspath, -) - -join('test', 'b') - - -# Extra whitespace before ), underline the space. -def test(a ): - # Line too long, underline entire line including leading whitespace. - os.path.join('abdfdkfdsljfksdlfjsdklfjsdkljfsdklfjskdlfjdskljfsd', 'fdsjkfdsjkfsdjkfsdjfdksfdsfdsfdfdsfsdfsdfds') - print a - # Unexpected indent, underline the leading whitespace. - print a - -print('hi') # Two blank spaces before comment, underline the comment including space. -print('hello') #One space after #, underline the comment. - -b=5 # Missing whitespace around operator, underline the operator. -b = 5 # Too much whitespace, underline the whitespace. - -# Trailing whitespace, underline the whitespace. -# NOTE: DON'T LET YOUR EDITOR TRIM THE TRAILING WHITESPACE, -# OR TESTS WILL FAIL :( -# Expected: 4 trailing spaces. -f = 5 - -# Undefined reference, underline the reference. -f = idontexist -# Unused definition, underline the entire assignment. -d = 12345 -# SyntaxError, underline entire non-whitespace line. -def a(b): - print(()!! diff --git a/pkg/nuclide-python/spec/fixtures/t.py b/pkg/nuclide-python/spec/fixtures/t.py deleted file mode 100644 index 121a880a30..0000000000 --- a/pkg/nuclide-python/spec/fixtures/t.py +++ /dev/null @@ -1,46 +0,0 @@ -# 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. - -# t.json is the outline generated by the python service for this file, which is -# what we use as a fixture in tests. This file is left here for reference only. - -import codecs -import collections - -CONST = 42 - - -def check_output(*popenargs, **kwargs): - return - - -class MyClass(object): - def __init(self): - return - - -def load_package_configs(): - package_map = {} - - # Performs a depth-first search of the project root for package.json files. - for (path, dirs, files) in os.walk(PACKAGES_PATH): - if 'package.json' in files: - # No need to explore subdirectories once package.json is found. - del dirs[:] - package_json = os.path.join(path, 'package.json') - config = create_config_for_package(package_json) - # config will be None for packages such as sample packages. - if config: - package_name = config['name'] - # Update the map now that the config is complete. - package_map[package_name] = config - - return package_map - -if __name__ == '__main__': - print json.dumps(ast_to_outline(parse(sys.stdin.read())), indent=4) - -var = 42 diff --git a/pkg/nuclide-quick-open/lib/FileResultComponent.js b/pkg/nuclide-quick-open/lib/FileResultComponent.js index 73bd3cf0b0..4f1d02685a 100644 --- a/pkg/nuclide-quick-open/lib/FileResultComponent.js +++ b/pkg/nuclide-quick-open/lib/FileResultComponent.js @@ -1,3 +1,39 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = _interopRequireWildcard(require('react')); + +var _matchIndexesToRanges; + +function _load_matchIndexesToRanges() { + return _matchIndexesToRanges = _interopRequireDefault(require('../../../modules/nuclide-commons/matchIndexesToRanges')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _HighlightedText; + +function _load_HighlightedText() { + return _HighlightedText = _interopRequireDefault(require('../../../modules/nuclide-commons-ui/HighlightedText')); +} + +var _PathWithFileIcon; + +function _load_PathWithFileIcon() { + return _PathWithFileIcon = _interopRequireDefault(require('../../nuclide-ui/PathWithFileIcon')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,41 +41,28 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {FileResult} from './types'; - -import * as React from 'react'; -import matchIndexesToRanges from 'nuclide-commons/matchIndexesToRanges'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import HighlightedText from 'nuclide-commons-ui/HighlightedText'; -import PathWithFileIcon from '../../nuclide-ui/PathWithFileIcon'; - -export default class FileResultComponent { - static getComponentForItem( - item: FileResult, - serviceName: string, - dirName: string, - ): React.Element { +class FileResultComponent { + static getComponentForItem(item, serviceName, dirName) { // Trim the `dirName` off the `filePath` since that's shown by the group let filePath = item.path; let matchIndexes = item.matchIndexes || []; if (filePath.startsWith(dirName)) { filePath = '.' + filePath.slice(dirName.length); - matchIndexes = matchIndexes - .map(i => i - (dirName.length - 1)) - .filter(i => i >= 0); + matchIndexes = matchIndexes.map(i => i - (dirName.length - 1)).filter(i => i >= 0); } - return ( - - - + return _react.createElement( + (_PathWithFileIcon || _load_PathWithFileIcon()).default, + { path: (_nuclideUri || _load_nuclideUri()).default.basename(filePath) }, + _react.createElement((_HighlightedText || _load_HighlightedText()).default, { + highlightedRanges: (0, (_matchIndexesToRanges || _load_matchIndexesToRanges()).default)(matchIndexes), + text: filePath + }) ); } } +exports.default = FileResultComponent; \ No newline at end of file diff --git a/pkg/nuclide-quick-open/lib/QuickOpenProviderRegistry.js b/pkg/nuclide-quick-open/lib/QuickOpenProviderRegistry.js index 7ac7d5d337..56be8c778c 100644 --- a/pkg/nuclide-quick-open/lib/QuickOpenProviderRegistry.js +++ b/pkg/nuclide-quick-open/lib/QuickOpenProviderRegistry.js @@ -1,99 +1,78 @@ -/** - * 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 - */ - -import type { - Provider, - ProviderResult, - DirectoryProviderType, - GlobalProviderType, -} from './types'; - -import {Emitter} from 'atom'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -export default class QuickOpenProviderRegistry { - _emitter: Emitter; - _subscriptions: UniversalDisposable; - _directoryProviders: Map>; - _globalProviders: Map>; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _atom = require('atom'); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class QuickOpenProviderRegistry { constructor() { - this._emitter = new Emitter(); - this._subscriptions = new UniversalDisposable(); + this._emitter = new _atom.Emitter(); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._directoryProviders = new Map(); this._globalProviders = new Map(); } - getProviders(): Array> { - return [ - ...this._globalProviders.values(), - ...this._directoryProviders.values(), - ]; + getProviders() { + return [...this._globalProviders.values(), ...this._directoryProviders.values()]; } - getGlobalProviders(): Array> { + getGlobalProviders() { return [...this._globalProviders.values()]; } - getDirectoryProviders(): Array> { + getDirectoryProviders() { return [...this._directoryProviders.values()]; } - getProviderByName(serviceName: string): ?Provider { - return ( - this._globalProviders.get(serviceName) || - this._directoryProviders.get(serviceName) - ); + getProviderByName(serviceName) { + return this._globalProviders.get(serviceName) || this._directoryProviders.get(serviceName); } - getGlobalProviderByName(serviceName: string): ?GlobalProviderType<*> { + getGlobalProviderByName(serviceName) { return this._globalProviders.get(serviceName); } - getDirectoryProviderByName(serviceName: string): ?DirectoryProviderType<*> { + getDirectoryProviderByName(serviceName) { return this._directoryProviders.get(serviceName); } - isProviderGlobal(serviceName: string): boolean { + isProviderGlobal(serviceName) { return this._globalProviders.has(serviceName); } - observeProviders( - callback: (service: Provider) => void, - ): IDisposable { + observeProviders(callback) { for (const provider of this.getProviders()) { callback(provider); } return this.onDidAddProvider(callback); } - onDidAddProvider( - callback: (service: Provider) => void, - ): IDisposable { + onDidAddProvider(callback) { return this._emitter.on('did-add-provider', callback); } - onDidRemoveProvider( - callback: (service: Provider) => void, - ): IDisposable { + onDidRemoveProvider(callback) { return this._emitter.on('did-remove-provider', callback); } - addProvider(service: Provider): IDisposable { + addProvider(service) { if (service.providerType === 'GLOBAL') { this._globalProviders.set(service.name, service); } else { this._directoryProviders.set(service.name, service); } - const disposable = new UniversalDisposable(() => { + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { if (service.providerType === 'GLOBAL') { this._globalProviders.delete(service.name); } else { @@ -107,8 +86,18 @@ export default class QuickOpenProviderRegistry { return disposable; } - dispose(): void { + dispose() { this._emitter.dispose(); this._subscriptions.dispose(); } } +exports.default = QuickOpenProviderRegistry; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-quick-open/lib/QuickSelectionActions.js b/pkg/nuclide-quick-open/lib/QuickSelectionActions.js index 0d46eb7d82..db9468e237 100644 --- a/pkg/nuclide-quick-open/lib/QuickSelectionActions.js +++ b/pkg/nuclide-quick-open/lib/QuickSelectionActions.js @@ -1,3 +1,15 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _QuickSelectionDispatcher; + +function _load_QuickSelectionDispatcher() { + return _QuickSelectionDispatcher = require('./QuickSelectionDispatcher'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,32 +17,28 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -import type QuickSelectionDispatcher from './QuickSelectionDispatcher'; - -import {ActionTypes} from './QuickSelectionDispatcher'; - -export default class QuickSelectionActions { - _dispatcher: QuickSelectionDispatcher; +class QuickSelectionActions { - constructor(dispatcher: QuickSelectionDispatcher) { + constructor(dispatcher) { this._dispatcher = dispatcher; } - query(query: string): void { + query(query) { this._dispatcher.dispatch({ - actionType: ActionTypes.QUERY, - query, + actionType: (_QuickSelectionDispatcher || _load_QuickSelectionDispatcher()).ActionTypes.QUERY, + query }); } - changeActiveProvider(providerName: string): void { + changeActiveProvider(providerName) { this._dispatcher.dispatch({ - actionType: ActionTypes.ACTIVE_PROVIDER_CHANGED, - providerName, + actionType: (_QuickSelectionDispatcher || _load_QuickSelectionDispatcher()).ActionTypes.ACTIVE_PROVIDER_CHANGED, + providerName }); } } +exports.default = QuickSelectionActions; \ No newline at end of file diff --git a/pkg/nuclide-quick-open/lib/QuickSelectionComponent.js b/pkg/nuclide-quick-open/lib/QuickSelectionComponent.js index cd424f4d9c..30399fd338 100644 --- a/pkg/nuclide-quick-open/lib/QuickSelectionComponent.js +++ b/pkg/nuclide-quick-open/lib/QuickSelectionComponent.js @@ -1,130 +1,231 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../../../modules/nuclide-commons-ui/AtomInput'); +} + +var _Button; + +function _load_Button() { + return _Button = require('../../../modules/nuclide-commons-ui/Button'); +} + +var _Icon; + +function _load_Icon() { + return _Icon = require('../../../modules/nuclide-commons-ui/Icon'); +} + +var _scrollIntoView; + +function _load_scrollIntoView() { + return _scrollIntoView = require('../../../modules/nuclide-commons-ui/scrollIntoView'); +} + +var _Tabs; + +function _load_Tabs() { + return _Tabs = _interopRequireDefault(require('../../../modules/nuclide-commons-ui/Tabs')); +} + +var _Badge; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {Tab} from 'nuclide-commons-ui/Tabs'; -import type QuickSelectionActions from './QuickSelectionActions'; - -import type {FileResult, ProviderResult} from './types'; -import type SearchResultManager, {ProviderSpec} from './SearchResultManager'; -import type { - ProviderResults, - GroupedResult, - GroupedResults, -} from './searchResultHelpers'; - -import nullthrows from 'nullthrows'; - -type ResultContext = { - nonEmptyResults: GroupedResults, - serviceNames: Array, - currentServiceIndex: number, - currentService: GroupedResult, - directoryNames: Array, - currentDirectoryIndex: number, - currentDirectory: ProviderResults, -}; - -export type SelectionIndex = { - selectedDirectory: string, - selectedService: string, - selectedItemIndex: number, -}; - -import {Observable, Scheduler} from 'rxjs'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {Button} from 'nuclide-commons-ui/Button'; -import {Icon} from 'nuclide-commons-ui/Icon'; -import {scrollIntoViewIfNeeded} from 'nuclide-commons-ui/scrollIntoView'; -import Tabs from 'nuclide-commons-ui/Tabs'; -import {Badge, BadgeSizes} from '../../nuclide-ui/Badge'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import humanizeKeystroke from 'nuclide-commons/humanizeKeystroke'; -import {fastDebounce, throttle, microtask} from 'nuclide-commons/observable'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import classnames from 'classnames'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import { - filterEmptyResults, - flattenResults, - getOuterResults, -} from './searchResultHelpers'; +function _load_Badge() { + return _Badge = require('../../nuclide-ui/Badge'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _event; + +function _load_event() { + return _event = require('../../../modules/nuclide-commons/event'); +} + +var _humanizeKeystroke; + +function _load_humanizeKeystroke() { + return _humanizeKeystroke = _interopRequireDefault(require('../../../modules/nuclide-commons/humanizeKeystroke')); +} + +var _observable; + +function _load_observable() { + return _observable = require('../../../modules/nuclide-commons/observable'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _reactDom = _interopRequireDefault(require('react-dom')); + +var _classnames; + +function _load_classnames() { + return _classnames = _interopRequireDefault(require('classnames')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _searchResultHelpers; + +function _load_searchResultHelpers() { + return _searchResultHelpers = require('./searchResultHelpers'); +} + +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 }; } /** * Determine what the applicable shortcut for a given action is within this component's context. * For example, this will return different keybindings on windows vs linux. */ -function _findKeybindingForAction(action: string, target: HTMLElement): string { +function _findKeybindingForAction(action, target) { const matchingKeyBindings = atom.keymaps.findKeyBindings({ command: action, - target, + target }); - const keystroke = - (matchingKeyBindings.length && matchingKeyBindings[0].keystrokes) || ''; - return humanizeKeystroke(keystroke); -} + const keystroke = matchingKeyBindings.length && matchingKeyBindings[0].keystrokes || ''; + return (0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)(keystroke); +} /** + * 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. + * + * + * @format + */ + +class QuickSelectionComponent extends _react.Component { -type Props = {| - searchResultManager: SearchResultManager, - quickSelectionActions: QuickSelectionActions, - onCancellation: () => void, - onSelection: ( - selections: Array, - providerName: string, - query: string, - ) => void, - onItemsChanged?: (newItems: GroupedResults) => void, - onSelectionChanged?: ( - selectionIndex: SelectionIndex, - providerName: string, - query: string, - ) => void, -|}; - -type State = { - activeTab: ProviderSpec, - hasUserSelection: boolean, - resultsByService: GroupedResults, - renderableProviders: Array, - selectedService: string, - selectedDirectory: string, - selectedItemIndex: number, - initialQuery: string, -}; - -export default class QuickSelectionComponent extends React.Component< - Props, - State, -> { - _modal: ?HTMLElement; - _queryInput: ?AtomInput; - _selectionList: ?HTMLElement; - _subscriptions: UniversalDisposable; - - constructor(props: Props) { + constructor(props) { super(props); - this._subscriptions = new UniversalDisposable(); + + this._handleClickOpenAll = () => { + if (this.state.activeTab.canOpenAll) { + this._openAll(); + } + }; + + this._handleKeyPress = e => { + if (e.shiftKey && e.key === 'Enter') { + if (this.state.activeTab.canOpenAll) { + this._openAll(); + } + } + }; + + this._handleMovePreviousTab = event => { + const currentProviderName = this.props.searchResultManager.getActiveProviderName(); + const currentTabIndex = this.state.renderableProviders.findIndex(tab => tab.name === currentProviderName); + const previousProvider = this.state.renderableProviders[currentTabIndex - 1] || this.state.renderableProviders[this.state.renderableProviders.length - 1]; + this.props.quickSelectionActions.changeActiveProvider(previousProvider.name); + event.stopImmediatePropagation(); + }; + + this._handleMoveNextTab = event => { + const currentProviderName = this.props.searchResultManager.getActiveProviderName(); + const currentTabIndex = this.state.renderableProviders.findIndex(tab => tab.name === currentProviderName); + const nextProvider = this.state.renderableProviders[currentTabIndex + 1] || this.state.renderableProviders[0]; + this.props.quickSelectionActions.changeActiveProvider(nextProvider.name); + event.stopImmediatePropagation(); + }; + + this._handleMoveToBottom = () => { + this._moveSelectionToBottom( /* userInitiated */true); + }; + + this._handleMoveToTop = () => { + this._moveSelectionToTop( /* userInitiated */true); + }; + + this._handleMoveDown = () => { + this._moveSelectionDown( /* userInitiated */true); + }; + + this._handleMoveUp = () => { + this._moveSelectionUp( /* userInitiated */true); + }; + + this._handleDocumentMouseDown = event => { + // If the click did not happen on the modal or on any of its descendants, + // the click was elsewhere on the document and should close the modal. + // Otherwise, refocus the input box. + if (event.target !== this._modal && !(0, (_nullthrows || _load_nullthrows()).default)(this._modal).contains(event.target)) { + this.props.onCancellation(); + } else { + process.nextTick(() => this.focus()); + } + }; + + this._handleTextInputChange = () => { + this.setState({ hasUserSelection: false }); + const query = this._getTextEditor().getText(); + this.props.quickSelectionActions.query(query); + }; + + this._handleResultsChange = () => { + this._updateResults(); + }; + + this._handleProvidersChange = () => { + this._updateResults(); + + // Execute the current query again. + // This will update any new providers. + this.props.quickSelectionActions.query(this._getTextEditor().getText()); + }; + + this._select = () => { + const selectedItem = this._getItemAtIndex(this.state.selectedService, this.state.selectedDirectory, this.state.selectedItemIndex); + if (!selectedItem) { + this.props.onCancellation(); + } else { + const providerName = this.props.searchResultManager.getActiveProviderName(); + const query = this._getTextEditor().getText(); + this.props.onSelection([selectedItem], providerName, query); + } + }; + + this._handleTabChange = newTab => { + const newProviderName = newTab.name; + const currentProviderName = this.props.searchResultManager.getActiveProviderName(); + if (newProviderName !== currentProviderName) { + this.props.quickSelectionActions.changeActiveProvider(newProviderName); + } + }; + + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); const initialProviderName = this.props.searchResultManager.getActiveProviderName(); - const initialActiveTab = this.props.searchResultManager.getProviderSpecByName( - initialProviderName, - ); + const initialActiveTab = this.props.searchResultManager.getProviderSpecByName(initialProviderName); const initialQuery = this.props.searchResultManager.getLastQuery() || ''; - const initialResults = this.props.searchResultManager.getResults( - initialQuery, - initialProviderName, - ); - const topOuterResult = getOuterResults('top', initialResults); + const initialResults = this.props.searchResultManager.getResults(initialQuery, initialProviderName); + const topOuterResult = (0, (_searchResultHelpers || _load_searchResultHelpers()).getOuterResults)('top', initialResults); this.state = { activeTab: initialActiveTab, @@ -132,36 +233,35 @@ export default class QuickSelectionComponent extends React.Component< resultsByService: initialResults, renderableProviders: this.props.searchResultManager.getRenderableProviders(), selectedService: topOuterResult != null ? topOuterResult.serviceName : '', - selectedDirectory: - topOuterResult != null ? topOuterResult.directoryName : '', + selectedDirectory: topOuterResult != null ? topOuterResult.directoryName : '', selectedItemIndex: topOuterResult != null ? 0 : -1, hasUserSelection: false, - initialQuery, + initialQuery }; } /** * Public API */ - focus(): void { + focus() { const element = this._getInputTextEditor(); if (element != null) { element.focus(); } } - selectAllText(): void { + selectAllText() { this._getTextEditor().selectAll(); } - setInputValue(value: string): void { + setInputValue(value) { this._getTextEditor().setText(value); } /** * Private API */ - componentWillReceiveProps(nextProps: Props): void { + componentWillReceiveProps(nextProps) { // Prevent clowniness: if (this.props.searchResultManager !== nextProps.searchResultManager) { throw new Error('quick-open: searchResultManager instance changed.'); @@ -170,255 +270,92 @@ export default class QuickSelectionComponent extends React.Component< const nextProviderName = this.props.searchResultManager.getActiveProviderName(); if (this.state.activeTab.name === nextProviderName) { process.nextTick(() => { - const query = nullthrows(this._queryInput).getText(); + const query = (0, (_nullthrows || _load_nullthrows()).default)(this._queryInput).getText(); this.props.quickSelectionActions.query(query); }); } else { - const activeProviderSpec = this.props.searchResultManager.getProviderSpecByName( - nextProviderName, - ); - const lastResults = this.props.searchResultManager.getResults( - nullthrows(this._queryInput).getText(), - nextProviderName, - ); + const activeProviderSpec = this.props.searchResultManager.getProviderSpecByName(nextProviderName); + const lastResults = this.props.searchResultManager.getResults((0, (_nullthrows || _load_nullthrows()).default)(this._queryInput).getText(), nextProviderName); this._getTextEditor().setPlaceholderText(activeProviderSpec.prompt); - this.setState( - { - activeTab: activeProviderSpec, - resultsByService: lastResults, - }, - () => { - process.nextTick(() => { - const query = nullthrows(this._queryInput).getText(); - this.props.quickSelectionActions.query(query); - }); - if (this.props.onItemsChanged != null) { - this.props.onItemsChanged(lastResults); - } - }, - ); + this.setState({ + activeTab: activeProviderSpec, + resultsByService: lastResults + }, () => { + process.nextTick(() => { + const query = (0, (_nullthrows || _load_nullthrows()).default)(this._queryInput).getText(); + this.props.quickSelectionActions.query(query); + }); + if (this.props.onItemsChanged != null) { + this.props.onItemsChanged(lastResults); + } + }); } } - componentDidUpdate(prevProps: Props, prevState: State): void { + componentDidUpdate(prevProps, prevState) { if (prevState.resultsByService !== this.state.resultsByService) { if (this.props.onItemsChanged != null) { this.props.onItemsChanged(this.state.resultsByService); } } - if ( - prevState.selectedItemIndex !== this.state.selectedItemIndex || - prevState.selectedService !== this.state.selectedService || - prevState.selectedDirectory !== this.state.selectedDirectory - ) { + if (prevState.selectedItemIndex !== this.state.selectedItemIndex || prevState.selectedService !== this.state.selectedService || prevState.selectedDirectory !== this.state.selectedDirectory) { this._updateScrollPosition(); } } - componentDidMount(): void { - const modalNode = ReactDOM.findDOMNode(this); - this._subscriptions.add( - atom.commands.add( - // $FlowFixMe - modalNode, - 'core:move-to-bottom', - this._handleMoveToBottom, - ), - // $FlowFixMe - atom.commands.add(modalNode, 'core:move-to-top', this._handleMoveToTop), - // $FlowFixMe - atom.commands.add(modalNode, 'core:move-down', this._handleMoveDown), - // $FlowFixMe - atom.commands.add(modalNode, 'core:move-up', this._handleMoveUp), - // $FlowFixMe - atom.commands.add(modalNode, 'core:confirm', this._select), - atom.commands.add( - // $FlowFixMe - modalNode, - 'pane:show-previous-item', - this._handleMovePreviousTab, - ), - atom.commands.add( - // $FlowFixMe - modalNode, - 'pane:show-next-item', - this._handleMoveNextTab, - ), - atom.commands.add('body', 'core:cancel', () => { - this.props.onCancellation(); - }), - Observable.fromEvent(document, 'mousedown').subscribe( - this._handleDocumentMouseDown, - ), - // The text editor often changes during dispatches, so wait until the next tick. - observableFromSubscribeFunction(cb => - nullthrows(this._queryInput).onDidChange(cb), - ) - .startWith(null) - .let(throttle(microtask, {leading: false})) - .subscribe(this._handleTextInputChange), - observableFromSubscribeFunction(cb => - this.props.searchResultManager.onProvidersChanged(cb), - ) - .debounceTime(0, Scheduler.animationFrame) - .subscribe(this._handleProvidersChange), - observableFromSubscribeFunction(cb => - this.props.searchResultManager.onResultsChanged(cb), - ) - .let(fastDebounce(50)) - // debounceTime seems to have issues canceling scheduled work. So - // schedule it after we've debounced the events. See - // https://github.com/ReactiveX/rxjs/pull/2135 - .debounceTime(0, Scheduler.animationFrame) - .subscribe(this._handleResultsChange), - ); + componentDidMount() { + const modalNode = _reactDom.default.findDOMNode(this); + this._subscriptions.add(atom.commands.add( + // $FlowFixMe + modalNode, 'core:move-to-bottom', this._handleMoveToBottom), + // $FlowFixMe + atom.commands.add(modalNode, 'core:move-to-top', this._handleMoveToTop), + // $FlowFixMe + atom.commands.add(modalNode, 'core:move-down', this._handleMoveDown), + // $FlowFixMe + atom.commands.add(modalNode, 'core:move-up', this._handleMoveUp), + // $FlowFixMe + atom.commands.add(modalNode, 'core:confirm', this._select), atom.commands.add( + // $FlowFixMe + modalNode, 'pane:show-previous-item', this._handleMovePreviousTab), atom.commands.add( + // $FlowFixMe + modalNode, 'pane:show-next-item', this._handleMoveNextTab), atom.commands.add('body', 'core:cancel', () => { + this.props.onCancellation(); + }), _rxjsBundlesRxMinJs.Observable.fromEvent(document, 'mousedown').subscribe(this._handleDocumentMouseDown), + // The text editor often changes during dispatches, so wait until the next tick. + (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => (0, (_nullthrows || _load_nullthrows()).default)(this._queryInput).onDidChange(cb)).startWith(null).let((0, (_observable || _load_observable()).throttle)((_observable || _load_observable()).microtask, { leading: false })).subscribe(this._handleTextInputChange), (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => this.props.searchResultManager.onProvidersChanged(cb)).debounceTime(0, _rxjsBundlesRxMinJs.Scheduler.animationFrame).subscribe(this._handleProvidersChange), (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => this.props.searchResultManager.onResultsChanged(cb)).let((0, (_observable || _load_observable()).fastDebounce)(50)) + // debounceTime seems to have issues canceling scheduled work. So + // schedule it after we've debounced the events. See + // https://github.com/ReactiveX/rxjs/pull/2135 + .debounceTime(0, _rxjsBundlesRxMinJs.Scheduler.animationFrame).subscribe(this._handleResultsChange)); this._getTextEditor().selectAll(); } - componentWillUnmount(): void { + componentWillUnmount() { this._subscriptions.dispose(); } - _handleClickOpenAll = (): void => { - if (this.state.activeTab.canOpenAll) { - this._openAll(); - } - }; - - _handleKeyPress = (e: SyntheticKeyboardEvent<>): void => { - if (e.shiftKey && e.key === 'Enter') { - if (this.state.activeTab.canOpenAll) { - this._openAll(); - } - } - }; - - _handleMovePreviousTab = (event: Event): void => { - const currentProviderName = this.props.searchResultManager.getActiveProviderName(); - const currentTabIndex = this.state.renderableProviders.findIndex( - tab => tab.name === currentProviderName, - ); - const previousProvider = - this.state.renderableProviders[currentTabIndex - 1] || - this.state.renderableProviders[this.state.renderableProviders.length - 1]; - this.props.quickSelectionActions.changeActiveProvider( - previousProvider.name, - ); - event.stopImmediatePropagation(); - }; - - _handleMoveNextTab = (event: Event): void => { - const currentProviderName = this.props.searchResultManager.getActiveProviderName(); - const currentTabIndex = this.state.renderableProviders.findIndex( - tab => tab.name === currentProviderName, - ); - const nextProvider = - this.state.renderableProviders[currentTabIndex + 1] || - this.state.renderableProviders[0]; - this.props.quickSelectionActions.changeActiveProvider(nextProvider.name); - event.stopImmediatePropagation(); - }; - - _handleMoveToBottom = (): void => { - this._moveSelectionToBottom(/* userInitiated */ true); - }; - - _handleMoveToTop = (): void => { - this._moveSelectionToTop(/* userInitiated */ true); - }; - - _handleMoveDown = (): void => { - this._moveSelectionDown(/* userInitiated */ true); - }; - - _handleMoveUp = (): void => { - this._moveSelectionUp(/* userInitiated */ true); - }; - - _handleDocumentMouseDown = (event: Event): void => { - // If the click did not happen on the modal or on any of its descendants, - // the click was elsewhere on the document and should close the modal. - // Otherwise, refocus the input box. - if ( - event.target !== this._modal && - !nullthrows(this._modal).contains((event.target: any)) - ) { - this.props.onCancellation(); - } else { - process.nextTick(() => this.focus()); - } - }; - - _handleTextInputChange = (): void => { - this.setState({hasUserSelection: false}); - const query = this._getTextEditor().getText(); - this.props.quickSelectionActions.query(query); - }; - - _handleResultsChange = (): void => { - this._updateResults(); - }; - - _handleProvidersChange = (): void => { - this._updateResults(); - - // Execute the current query again. - // This will update any new providers. - this.props.quickSelectionActions.query(this._getTextEditor().getText()); - }; - - _updateResults(): void { + _updateResults() { const activeProviderName = this.props.searchResultManager.getActiveProviderName(); - const updatedResults = this.props.searchResultManager.getResults( - nullthrows(this._queryInput).getText(), - activeProviderName, - ); + const updatedResults = this.props.searchResultManager.getResults((0, (_nullthrows || _load_nullthrows()).default)(this._queryInput).getText(), activeProviderName); const [topProviderName] = Object.keys(updatedResults); const renderableProviders = this.props.searchResultManager.getRenderableProviders(); - this.setState( - { - renderableProviders, - resultsByService: updatedResults, - }, - () => { - if ( - !this.state.hasUserSelection && - topProviderName != null && - this.state.resultsByService[topProviderName] != null - ) { - const topProviderResults = this.state.resultsByService[ - topProviderName - ].results; - if ( - !Object.keys(topProviderResults).some( - dirName => topProviderResults[dirName].loading, - ) - ) { - this._moveSelectionToTop(/* userInitiated */ false); - } + this.setState({ + renderableProviders, + resultsByService: updatedResults + }, () => { + if (!this.state.hasUserSelection && topProviderName != null && this.state.resultsByService[topProviderName] != null) { + const topProviderResults = this.state.resultsByService[topProviderName].results; + if (!Object.keys(topProviderResults).some(dirName => topProviderResults[dirName].loading)) { + this._moveSelectionToTop( /* userInitiated */false); } - }, - ); + } + }); } - _select = (): void => { - const selectedItem = this._getItemAtIndex( - this.state.selectedService, - this.state.selectedDirectory, - this.state.selectedItemIndex, - ); - if (!selectedItem) { - this.props.onCancellation(); - } else { - const providerName = this.props.searchResultManager.getActiveProviderName(); - const query = this._getTextEditor().getText(); - this.props.onSelection([selectedItem], providerName, query); - } - }; - - _getCurrentResultContext(): ?ResultContext { - const nonEmptyResults = filterEmptyResults(this.state.resultsByService); + _getCurrentResultContext() { + const nonEmptyResults = (0, (_searchResultHelpers || _load_searchResultHelpers()).filterEmptyResults)(this.state.resultsByService); const currentService = nonEmptyResults[this.state.selectedService]; if (!currentService) { @@ -426,15 +363,10 @@ export default class QuickSelectionComponent extends React.Component< } const serviceNames = Object.keys(nonEmptyResults); - const currentServiceIndex = serviceNames.indexOf( - this.state.selectedService, - ); + const currentServiceIndex = serviceNames.indexOf(this.state.selectedService); const directoryNames = Object.keys(currentService.results); - const currentDirectoryIndex = directoryNames.indexOf( - this.state.selectedDirectory, - ); - const currentDirectory = - currentService.results[this.state.selectedDirectory]; + const currentDirectoryIndex = directoryNames.indexOf(this.state.selectedDirectory); + const currentDirectory = currentService.results[this.state.selectedDirectory]; if (!currentDirectory || !currentDirectory.results) { return null; @@ -447,51 +379,30 @@ export default class QuickSelectionComponent extends React.Component< currentService, directoryNames, currentDirectoryIndex, - currentDirectory, + currentDirectory }; } - _moveSelectionDown(userInitiated: boolean): void { + _moveSelectionDown(userInitiated) { const context = this._getCurrentResultContext(); if (!context) { this._moveSelectionToTop(userInitiated); return; } - if ( - this.state.selectedItemIndex < - context.currentDirectory.results.length - 1 - ) { + if (this.state.selectedItemIndex < context.currentDirectory.results.length - 1) { // only bump the index if remaining in current directory - this._setSelectedIndex( - this.state.selectedService, - this.state.selectedDirectory, - this.state.selectedItemIndex + 1, - userInitiated, - ); + this._setSelectedIndex(this.state.selectedService, this.state.selectedDirectory, this.state.selectedItemIndex + 1, userInitiated); } else { // otherwise go to next directory... if (context.currentDirectoryIndex < context.directoryNames.length - 1) { - this._setSelectedIndex( - this.state.selectedService, - context.directoryNames[context.currentDirectoryIndex + 1], - 0, - userInitiated, - ); + this._setSelectedIndex(this.state.selectedService, context.directoryNames[context.currentDirectoryIndex + 1], 0, userInitiated); } else { // ...or the next service... if (context.currentServiceIndex < context.serviceNames.length - 1) { - const newServiceName = - context.serviceNames[context.currentServiceIndex + 1]; - const newDirectoryName = Object.keys( - context.nonEmptyResults[newServiceName].results, - ).shift(); - this._setSelectedIndex( - newServiceName, - newDirectoryName, - 0, - userInitiated, - ); + const newServiceName = context.serviceNames[context.currentServiceIndex + 1]; + const newDirectoryName = Object.keys(context.nonEmptyResults[newServiceName].results).shift(); + this._setSelectedIndex(newServiceName, newDirectoryName, 0, userInitiated); } else { // ...or wrap around to the very top this._moveSelectionToTop(userInitiated); @@ -500,7 +411,7 @@ export default class QuickSelectionComponent extends React.Component< } } - _moveSelectionUp(userInitiated: boolean): void { + _moveSelectionUp(userInitiated) { const context = this._getCurrentResultContext(); if (!context) { this._moveSelectionToBottom(userInitiated); @@ -509,48 +420,24 @@ export default class QuickSelectionComponent extends React.Component< if (this.state.selectedItemIndex > 0) { // only decrease the index if remaining in current directory - this._setSelectedIndex( - this.state.selectedService, - this.state.selectedDirectory, - this.state.selectedItemIndex - 1, - userInitiated, - ); + this._setSelectedIndex(this.state.selectedService, this.state.selectedDirectory, this.state.selectedItemIndex - 1, userInitiated); } else { // otherwise, go to the previous directory... if (context.currentDirectoryIndex > 0) { - this._setSelectedIndex( - this.state.selectedService, - context.directoryNames[context.currentDirectoryIndex - 1], - context.currentService.results[ - context.directoryNames[context.currentDirectoryIndex - 1] - ].results.length - 1, - userInitiated, - ); + this._setSelectedIndex(this.state.selectedService, context.directoryNames[context.currentDirectoryIndex - 1], context.currentService.results[context.directoryNames[context.currentDirectoryIndex - 1]].results.length - 1, userInitiated); } else { // ...or the previous service... if (context.currentServiceIndex > 0) { - const newServiceName = - context.serviceNames[context.currentServiceIndex - 1]; - const newDirectoryName = Object.keys( - context.nonEmptyResults[newServiceName].results, - ).pop(); + const newServiceName = context.serviceNames[context.currentServiceIndex - 1]; + const newDirectoryName = Object.keys(context.nonEmptyResults[newServiceName].results).pop(); if (newDirectoryName == null) { return; } - const resultsForDirectory = - context.nonEmptyResults[newServiceName].results[newDirectoryName]; - if ( - resultsForDirectory == null || - resultsForDirectory.results == null - ) { + const resultsForDirectory = context.nonEmptyResults[newServiceName].results[newDirectoryName]; + if (resultsForDirectory == null || resultsForDirectory.results == null) { return; } - this._setSelectedIndex( - newServiceName, - newDirectoryName, - resultsForDirectory.results.length - 1, - userInitiated, - ); + this._setSelectedIndex(newServiceName, newDirectoryName, resultsForDirectory.results.length - 1, userInitiated); } else { // ...or wrap around to the very bottom this._moveSelectionToBottom(userInitiated); @@ -560,103 +447,65 @@ export default class QuickSelectionComponent extends React.Component< } // Update the scroll position of the list view to ensure the selected item is visible. - _updateScrollPosition(): void { + _updateScrollPosition() { if (this._selectionList == null) { return; } - const listNode = nullthrows(this._selectionList); + const listNode = (0, (_nullthrows || _load_nullthrows()).default)(this._selectionList); const selectedNode = listNode.getElementsByClassName('selected')[0]; // false is passed for @centerIfNeeded parameter, which defaults to true. // Passing false causes the minimum necessary scroll to occur, so the selection sticks to the // top/bottom. if (selectedNode) { - scrollIntoViewIfNeeded(selectedNode, false); + (0, (_scrollIntoView || _load_scrollIntoView()).scrollIntoViewIfNeeded)(selectedNode, false); } } - _moveSelectionToBottom(userInitiated: boolean): void { - const bottom = getOuterResults('bottom', this.state.resultsByService); + _moveSelectionToBottom(userInitiated) { + const bottom = (0, (_searchResultHelpers || _load_searchResultHelpers()).getOuterResults)('bottom', this.state.resultsByService); if (!bottom) { return; } - this._setSelectedIndex( - bottom.serviceName, - bottom.directoryName, - bottom.results.length - 1, - userInitiated, - ); + this._setSelectedIndex(bottom.serviceName, bottom.directoryName, bottom.results.length - 1, userInitiated); } - _moveSelectionToTop(userInitiated: boolean): void { - const top = getOuterResults('top', this.state.resultsByService); + _moveSelectionToTop(userInitiated) { + const top = (0, (_searchResultHelpers || _load_searchResultHelpers()).getOuterResults)('top', this.state.resultsByService); if (!top) { return; } - this._setSelectedIndex( - top.serviceName, - top.directoryName, - 0, - userInitiated, - ); + this._setSelectedIndex(top.serviceName, top.directoryName, 0, userInitiated); } - _getItemAtIndex( - serviceName: string, - directory: string, - itemIndex: number, - ): ?ProviderResult { - if ( - itemIndex === -1 || - !this.state.resultsByService[serviceName] || - !this.state.resultsByService[serviceName].results[directory] || - !this.state.resultsByService[serviceName].results[directory].results[ - itemIndex - ] - ) { + _getItemAtIndex(serviceName, directory, itemIndex) { + if (itemIndex === -1 || !this.state.resultsByService[serviceName] || !this.state.resultsByService[serviceName].results[directory] || !this.state.resultsByService[serviceName].results[directory].results[itemIndex]) { return null; } - return this.state.resultsByService[serviceName].results[directory].results[ - itemIndex - ]; + return this.state.resultsByService[serviceName].results[directory].results[itemIndex]; } - _componentForItem( - item: ProviderResult, - serviceName: string, - dirName: string, - ): React.Element { + _componentForItem(item, serviceName, dirName) { if (item.resultType === 'FILE') { - (item: FileResult); - return this.props.searchResultManager.getRendererForProvider( - serviceName, - item, - )(item, serviceName, dirName); + item; + return this.props.searchResultManager.getRendererForProvider(serviceName, item)(item, serviceName, dirName); } - return this.props.searchResultManager.getRendererForProvider( - serviceName, - item, - )(item, serviceName, dirName); + return this.props.searchResultManager.getRendererForProvider(serviceName, item)(item, serviceName, dirName); } - _getSelectedIndex(): SelectionIndex { + _getSelectedIndex() { return { selectedDirectory: this.state.selectedDirectory, selectedService: this.state.selectedService, - selectedItemIndex: this.state.selectedItemIndex, + selectedItemIndex: this.state.selectedItemIndex }; } - _setSelectedIndex( - service: string, - directory: string, - itemIndex: number, - userInitiated: boolean, - ): void { + _setSelectedIndex(service, directory, itemIndex, userInitiated) { const newState = { selectedService: service, selectedDirectory: directory, selectedItemIndex: itemIndex, - hasUserSelection: userInitiated, + hasUserSelection: userInitiated }; this.setState(newState, () => { const selectedIndex = this._getSelectedIndex(); @@ -668,250 +517,251 @@ export default class QuickSelectionComponent extends React.Component< }); } - _getInputTextEditor(): ?atom$TextEditorElement { + _getInputTextEditor() { if (this._queryInput != null) { return this._queryInput.getTextEditor().getElement(); } return null; } - _getTextEditor(): TextEditor { - return nullthrows(this._queryInput).getTextEditor(); + _getTextEditor() { + return (0, (_nullthrows || _load_nullthrows()).default)(this._queryInput).getTextEditor(); } /** * @param newTab is actually a ProviderSpec plus the `name` and `tabContent` properties added by * _renderTabs(), which created the tab object in the first place. */ - _handleTabChange = (newTab: Tab): void => { - const newProviderName = newTab.name; - const currentProviderName = this.props.searchResultManager.getActiveProviderName(); - if (newProviderName !== currentProviderName) { - this.props.quickSelectionActions.changeActiveProvider(newProviderName); - } - }; - _renderTabs(): React.Element { + + _renderTabs() { const workspace = atom.views.getView(atom.workspace); const tabs = this.state.renderableProviders.map(tab => { let keyBinding = null; // TODO - const humanizedKeybinding = tab.action - ? _findKeybindingForAction(tab.action, workspace) - : ''; + const humanizedKeybinding = tab.action ? _findKeybindingForAction(tab.action, workspace) : ''; if (humanizedKeybinding !== '') { - keyBinding = {humanizedKeybinding}; + keyBinding = _react.createElement( + 'kbd', + { className: 'key-binding' }, + humanizedKeybinding + ); } return { name: tab.name, - tabContent: ( - - {tab.title} - {keyBinding} - - ), + tabContent: _react.createElement( + 'span', + null, + tab.title, + keyBinding + ) }; }); - return ( -
    - -
    + return _react.createElement( + 'div', + { className: 'omnisearch-tabs' }, + _react.createElement((_Tabs || _load_Tabs()).default, { + tabs: tabs, + activeTabName: this.state.activeTab.name, + onActiveTabChange: this._handleTabChange + }) ); } - _openAll(): void { - const selections = flattenResults(this.state.resultsByService); + _openAll() { + const selections = (0, (_searchResultHelpers || _load_searchResultHelpers()).flattenResults)(this.state.resultsByService); const providerName = this.props.searchResultManager.getActiveProviderName(); const query = this._getTextEditor().getText(); this.props.onSelection(selections, providerName, query); } - render(): React.Node { + render() { let numTotalResultsRendered = 0; - const isOmniSearchActive = - this.state.activeTab.name === 'OmniSearchResultProvider'; + const isOmniSearchActive = this.state.activeTab.name === 'OmniSearchResultProvider'; let numQueriesOutstanding = 0; - const services = Object.keys(this.state.resultsByService).map( - serviceName => { - let numResultsForService = 0; - const directories = this.state.resultsByService[serviceName].results; - const serviceTitle = this.state.resultsByService[serviceName].title; - const totalResults = this.state.resultsByService[serviceName] - .totalResults; - const directoryNames = Object.keys(directories); - const directoriesForService = directoryNames.map(dirName => { - const resultsForDirectory = directories[dirName]; - let message = null; - if (resultsForDirectory.loading) { - numQueriesOutstanding++; - if (!isOmniSearchActive) { - numTotalResultsRendered++; - message = ( - - - Loading... - - ); - } - } else if (resultsForDirectory.error && !isOmniSearchActive) { - message = ( - - - Error:
    {resultsForDirectory.error}
    -
    - ); - } else if ( - resultsForDirectory.results.length === 0 && - !isOmniSearchActive - ) { - message = ( - - - No results - + const services = Object.keys(this.state.resultsByService).map(serviceName => { + let numResultsForService = 0; + const directories = this.state.resultsByService[serviceName].results; + const serviceTitle = this.state.resultsByService[serviceName].title; + const totalResults = this.state.resultsByService[serviceName].totalResults; + const directoryNames = Object.keys(directories); + const directoriesForService = directoryNames.map(dirName => { + const resultsForDirectory = directories[dirName]; + let message = null; + if (resultsForDirectory.loading) { + numQueriesOutstanding++; + if (!isOmniSearchActive) { + numTotalResultsRendered++; + message = _react.createElement( + 'span', + null, + _react.createElement('span', { className: 'loading loading-spinner-tiny inline-block' }), + 'Loading...' ); } - const itemComponents = resultsForDirectory.results.map( - (item, itemIndex) => { - numResultsForService++; - numTotalResultsRendered++; - const isSelected = - serviceName === this.state.selectedService && - dirName === this.state.selectedDirectory && - itemIndex === this.state.selectedItemIndex; - return ( -
  • - {this._componentForItem(item, serviceName, dirName)} -
  • - ); - }, + } else if (resultsForDirectory.error && !isOmniSearchActive) { + message = _react.createElement( + 'span', + null, + _react.createElement('span', { className: 'icon icon-circle-slash' }), + 'Error: ', + _react.createElement( + 'pre', + null, + resultsForDirectory.error + ) ); - let directoryLabel = null; - // hide folders if only 1 level would be shown, or if no results were found - const showDirectories = - directoryNames.length > 1 && - (!isOmniSearchActive || resultsForDirectory.results.length > 0); - if (showDirectories) { - directoryLabel = ( -
    - - {nuclideUri.nuclideUriToDisplayString(dirName)} - -
    - ); - } - return ( -
  • - {directoryLabel} - {message} -
      {itemComponents}
    -
  • + } else if (resultsForDirectory.results.length === 0 && !isOmniSearchActive) { + message = _react.createElement( + 'span', + null, + _react.createElement('span', { className: 'icon icon-x' }), + 'No results' ); - }); - let serviceLabel = null; - if (isOmniSearchActive && numResultsForService > 0) { - serviceLabel = ( -
    - this.props.quickSelectionActions.changeActiveProvider( - serviceName, - ) - }> - - -
    + } + const itemComponents = resultsForDirectory.results.map((item, itemIndex) => { + numResultsForService++; + numTotalResultsRendered++; + const isSelected = serviceName === this.state.selectedService && dirName === this.state.selectedDirectory && itemIndex === this.state.selectedItemIndex; + return _react.createElement( + 'li', + { + className: (0, (_classnames || _load_classnames()).default)({ + 'quick-open-result-item': true, + 'list-item': true, + selected: isSelected + }), + key: serviceName + dirName + itemIndex, + onMouseDown: this._select, + onMouseEnter: this._setSelectedIndex.bind(this, serviceName, dirName, itemIndex, + /* userInitiated */true) }, + this._componentForItem(item, serviceName, dirName) ); - return ( -
  • - {serviceLabel} -
      {directoriesForService}
    -
  • + }); + let directoryLabel = null; + // hide folders if only 1 level would be shown, or if no results were found + const showDirectories = directoryNames.length > 1 && (!isOmniSearchActive || resultsForDirectory.results.length > 0); + if (showDirectories) { + directoryLabel = _react.createElement( + 'div', + { className: 'list-item' }, + _react.createElement( + 'span', + { className: 'icon icon-file-directory' }, + (_nuclideUri || _load_nuclideUri()).default.nuclideUriToDisplayString(dirName) + ) ); } - return directoriesForService; - }, - ); + return _react.createElement( + 'li', + { + className: (0, (_classnames || _load_classnames()).default)({ 'list-nested-item': showDirectories }), + key: dirName }, + directoryLabel, + message, + _react.createElement( + 'ul', + { className: 'list-tree' }, + itemComponents + ) + ); + }); + let serviceLabel = null; + if (isOmniSearchActive && numResultsForService > 0) { + serviceLabel = _react.createElement( + 'div', + { + className: 'quick-open-provider-item list-item', + onClick: () => this.props.quickSelectionActions.changeActiveProvider(serviceName) }, + _react.createElement((_Icon || _load_Icon()).Icon, { icon: 'gear', children: serviceTitle }), + _react.createElement((_Badge || _load_Badge()).Badge, { + size: (_Badge || _load_Badge()).BadgeSizes.small, + className: 'quick-open-provider-count-badge', + value: totalResults + }) + ); + return _react.createElement( + 'li', + { className: 'list-nested-item', key: serviceName }, + serviceLabel, + _react.createElement( + 'ul', + { className: 'list-tree' }, + directoriesForService + ) + ); + } + return directoriesForService; + }); const hasSearchResult = numTotalResultsRendered > 0; let omniSearchStatus = null; if (isOmniSearchActive && numQueriesOutstanding > 0) { - omniSearchStatus = ( - - - {'Loading...'} - + omniSearchStatus = _react.createElement( + 'span', + null, + _react.createElement('span', { className: 'loading loading-spinner-tiny inline-block' }), + 'Loading...' ); } else if (isOmniSearchActive && !hasSearchResult) { - omniSearchStatus = ( -
  • - - - No results - -
  • + omniSearchStatus = _react.createElement( + 'li', + null, + _react.createElement( + 'span', + null, + _react.createElement('span', { className: 'icon icon-x' }), + 'No results' + ) ); } const disableOpenAll = !hasSearchResult || !this.state.activeTab.canOpenAll; - return ( -
    { + return _react.createElement( + 'div', + { + className: 'select-list omnisearch-modal', + ref: el => { this._modal = el; - }} - onKeyPress={this._handleKeyPress}> -
    - { - this._queryInput = input; - }} - initialValue={this.state.initialQuery} - placeholderText={this.state.activeTab.prompt} - /> - -
    - {this._renderTabs()} -
    -
    -
      { + }, + onKeyPress: this._handleKeyPress }, + _react.createElement( + 'div', + { className: 'omnisearch-search-bar' }, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + className: 'omnisearch-pane', + ref: input => { + this._queryInput = input; + }, + initialValue: this.state.initialQuery, + placeholderText: this.state.activeTab.prompt + }), + _react.createElement( + (_Button || _load_Button()).Button, + { + className: 'omnisearch-open-all', + onClick: this._handleClickOpenAll, + disabled: disableOpenAll }, + 'Open All' + ) + ), + this._renderTabs(), + _react.createElement( + 'div', + { className: 'omnisearch-results' }, + _react.createElement( + 'div', + { className: 'omnisearch-pane' }, + _react.createElement( + 'ul', + { + className: 'list-tree', + ref: el => { this._selectionList = el; - }}> - {services} - {omniSearchStatus} -
    -
    -
    -
    + } }, + services, + omniSearchStatus + ) + ) + ) ); } } +exports.default = QuickSelectionComponent; \ No newline at end of file diff --git a/pkg/nuclide-quick-open/lib/QuickSelectionDispatcher.js b/pkg/nuclide-quick-open/lib/QuickSelectionDispatcher.js index a5f879b9fc..c6e8d9a126 100644 --- a/pkg/nuclide-quick-open/lib/QuickSelectionDispatcher.js +++ b/pkg/nuclide-quick-open/lib/QuickSelectionDispatcher.js @@ -1,3 +1,25 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ActionTypes = undefined; + +var _Dispatcher; + +function _load_Dispatcher() { + return _Dispatcher = _interopRequireDefault(require('../../commons-node/Dispatcher')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const ActionTypes = exports.ActionTypes = Object.freeze({ + ACTIVE_PROVIDER_CHANGED: 'ACTIVE_PROVIDER_CHANGED', + QUERY: 'QUERY' +}); + +// Flow hack: Every QuickSelectionAction actionType must be in ActionTypes. +// $FlowFixMe(>=0.55.0) Flow suppress /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,33 +27,11 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -import Dispatcher from '../../commons-node/Dispatcher'; - -export type QuickSelectionAction = - | { - actionType: 'ACTIVE_PROVIDER_CHANGED', - providerName: string, - } - | { - actionType: 'QUERY', - query: string, - }; - -export const ActionTypes = Object.freeze({ - ACTIVE_PROVIDER_CHANGED: 'ACTIVE_PROVIDER_CHANGED', - QUERY: 'QUERY', -}); - -// Flow hack: Every QuickSelectionAction actionType must be in ActionTypes. -// $FlowFixMe(>=0.55.0) Flow suppress -(('': $PropertyType): $Keys< - typeof ActionTypes, ->); +''; -export default class QuickSelectionDispatcher extends Dispatcher< - QuickSelectionAction, -> {} +class QuickSelectionDispatcher extends (_Dispatcher || _load_Dispatcher()).default {} +exports.default = QuickSelectionDispatcher; \ No newline at end of file diff --git a/pkg/nuclide-quick-open/lib/ResultCache.js b/pkg/nuclide-quick-open/lib/ResultCache.js index 0468ca1c4f..782af0b040 100644 --- a/pkg/nuclide-quick-open/lib/ResultCache.js +++ b/pkg/nuclide-quick-open/lib/ResultCache.js @@ -1,3 +1,21 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _debounce; + +function _load_debounce() { + return _debounce = _interopRequireDefault(require('../../../modules/nuclide-commons/debounce')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Number of elements in the cache before periodic cleanup kicks in. Includes partial query strings. + + +// TODO use maps /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,51 +23,30 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {ProviderResults} from './searchResultHelpers'; -import type {ProviderResult} from './types'; - -import invariant from 'assert'; - -import debounce from 'nuclide-commons/debounce'; - -// TODO use maps -type CachedDirectoryResults = {[query: string]: ProviderResults}; -type CachedProviderResults = {[directory: string]: CachedDirectoryResults}; -export type CachedResults = {[providerName: string]: CachedProviderResults}; - -// Number of elements in the cache before periodic cleanup kicks in. Includes partial query strings. const MAX_CACHED_QUERIES = 100; const CACHE_CLEAN_DEBOUNCE_DELAY = 5000; -export default class ResultCache { - // Cache the last query with results for each provider. - // Display cached results for the last completed query until new data arrives. - _lastCachedQuery: Map; +class ResultCache { // List of most recently used query strings, used for pruning the result cache. // Makes use of `Map`'s insertion ordering, so values are irrelevant and always set to `null`. - _queryLruQueue: Map; - _cachedResults: CachedResults; - _onResultsChanged: () => mixed; - _debouncedCleanCache: () => void; - - constructor(onResultsChanged: () => mixed) { + constructor(onResultsChanged) { this._lastCachedQuery = new Map(); this._queryLruQueue = new Map(); this._cachedResults = {}; this._onResultsChanged = onResultsChanged; - this._debouncedCleanCache = debounce( - () => this._cleanCache(), - CACHE_CLEAN_DEBOUNCE_DELAY, - /* immediate */ false, - ); + this._debouncedCleanCache = (0, (_debounce || _load_debounce()).default)(() => this._cleanCache(), CACHE_CLEAN_DEBOUNCE_DELAY, + /* immediate */false); } // Return value indicates whether there was a change - removeResultsForProvider(providerName: string): void { + + // Cache the last query with results for each provider. + // Display cached results for the last completed query until new data arrives. + removeResultsForProvider(providerName) { if (this._cachedResults[providerName]) { delete this._cachedResults[providerName]; this._onResultsChanged(); @@ -57,19 +54,12 @@ export default class ResultCache { this._lastCachedQuery.delete(providerName); } - setCacheResult( - providerName: string, - directory: string, - query: string, - results: Array, - loading: boolean = false, - error: ?Object = null, - ): void { + setCacheResult(providerName, directory, query, results, loading = false, error = null) { this._ensureCacheEntry(providerName, directory); this._cachedResults[providerName][directory][query] = { results, loading, - error, + error }; this._lastCachedQuery.set(providerName, query); // Refresh the usage for the current query. @@ -79,39 +69,30 @@ export default class ResultCache { } // Sets the cache result directly without modifying the _lastCachedQuery or _queryLruQueue. - rawSetCacheResult( - providerName: string, - directory: string, - query: string, - result: ProviderResults, - ): void { + rawSetCacheResult(providerName, directory, query, result) { this._ensureCacheEntry(providerName, directory); this._cachedResults[providerName][directory][query] = result; } - getCacheResult( - providerName: string, - directory: string, - query: string, - ): ProviderResults { + getCacheResult(providerName, directory, query) { this._ensureCacheEntry(providerName, directory); return this._cachedResults[providerName][directory][query]; } // plz don't mutate this - getAllCachedResults(): CachedResults { + getAllCachedResults() { return this._cachedResults; } - getLastCachedQuery(providerName: string): ?string { + getLastCachedQuery(providerName) { return this._lastCachedQuery.get(providerName); } - setLastCachedQuery(providerName: string, query: string): void { + setLastCachedQuery(providerName, query) { this._lastCachedQuery.set(providerName, query); } - _ensureCacheEntry(providerName: string, directory: string): void { + _ensureCacheEntry(providerName, directory) { if (!this._cachedResults[providerName]) { this._cachedResults[providerName] = {}; } @@ -124,18 +105,22 @@ export default class ResultCache { * Release the oldest cached results once the cache is full. Return value indicates whether the * cache was changed. */ - _cleanCache(): void { + _cleanCache() { const queueSize = this._queryLruQueue.size; if (queueSize <= MAX_CACHED_QUERIES) { return; } // Figure out least recently used queries, and pop them off of the `_queryLruQueue` Map. - const expiredQueries: Array = []; + const expiredQueries = []; const keyIterator = this._queryLruQueue.keys(); const entriesToRemove = queueSize - MAX_CACHED_QUERIES; for (let i = 0; i < entriesToRemove; i++) { const firstEntryKey = keyIterator.next().value; - invariant(firstEntryKey != null); + + if (!(firstEntryKey != null)) { + throw new Error('Invariant violation: "firstEntryKey != null"'); + } + expiredQueries.push(firstEntryKey); this._queryLruQueue.delete(firstEntryKey); } @@ -150,3 +135,4 @@ export default class ResultCache { this._onResultsChanged(); } } +exports.default = ResultCache; \ No newline at end of file diff --git a/pkg/nuclide-quick-open/lib/SearchResultManager.js b/pkg/nuclide-quick-open/lib/SearchResultManager.js index 8764403ecd..53267a8259 100644 --- a/pkg/nuclide-quick-open/lib/SearchResultManager.js +++ b/pkg/nuclide-quick-open/lib/SearchResultManager.js @@ -1,3 +1,74 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.__test__ = undefined; + +var _observable; + +function _load_observable() { + return _observable = require('../../../modules/nuclide-commons/observable'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _atom = require('atom'); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _debounce; + +function _load_debounce() { + return _debounce = _interopRequireDefault(require('../../../modules/nuclide-commons/debounce')); +} + +var _FileResultComponent; + +function _load_FileResultComponent() { + return _FileResultComponent = _interopRequireDefault(require('./FileResultComponent')); +} + +var _ResultCache; + +function _load_ResultCache() { + return _ResultCache = _interopRequireDefault(require('./ResultCache')); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,54 +76,12 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ /* global performance */ -import type { - ProviderResult, - Provider, - GlobalProviderType, - DirectoryProviderType, -} from './types'; -import type { - GroupedResult, - GroupedResults, - ProviderResults, -} from './searchResultHelpers'; -import type QuickOpenProviderRegistry from './QuickOpenProviderRegistry'; - -export type ProviderSpec = { - action: string, - canOpenAll: boolean, - name: string, - prompt: string, - title: string, - priority: number, -}; - -type ResultRenderer = ( - item: T, - serviceName: string, - dirName: string, -) => React.Element; - -import invariant from 'assert'; -import {fastDebounce} from 'nuclide-commons/observable'; -import {trackSampled} from '../../nuclide-analytics'; -import {getLogger} from 'log4js'; -import * as React from 'react'; -import {Subject} from 'rxjs'; -import {Emitter} from 'atom'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {triggerAfterWait} from 'nuclide-commons/promise'; -import debounce from 'nuclide-commons/debounce'; -import FileResultComponent from './FileResultComponent'; -import ResultCache from './ResultCache'; -import {arrayEqual, mapEqual, areSetsEqual} from 'nuclide-commons/collection'; - const MAX_OMNI_RESULTS_PER_SERVICE = 5; const DEFAULT_QUERY_DEBOUNCE_DELAY = 200; const LOADING_EVENT_DELAY = 200; @@ -62,43 +91,23 @@ const OMNISEARCH_PROVIDER = { name: 'OmniSearchResultProvider', prompt: 'Search for anything...', title: 'OmniSearch', - priority: 0, + priority: 0 }; const UPDATE_DIRECTORIES_DEBOUNCE_DELAY = 100; const GLOBAL_KEY = 'global'; // Quick-open generates a *ton* of queries - sample the tracking. const TRACK_SOURCE_RATE = 10; -function getQueryDebounceDelay(provider: Provider) { - return provider.debounceDelay != null - ? provider.debounceDelay - : DEFAULT_QUERY_DEBOUNCE_DELAY; +function getQueryDebounceDelay(provider) { + return provider.debounceDelay != null ? provider.debounceDelay : DEFAULT_QUERY_DEBOUNCE_DELAY; } /** * A singleton cache for search providers and results. */ -export default class SearchResultManager { - _quickOpenProviderRegistry: QuickOpenProviderRegistry; - _directoryEligibleProviders: Map< - atom$Directory, - Set>, - >; - - _globalEligibleProviders: Set>; - _providerSubscriptions: Map, IDisposable>; - _directories: Array; - _resultCache: ResultCache; - _currentWorkingRoot: ?string; - _debouncedUpdateDirectories: {(): Promise | void} & IDisposable; - _emitter: Emitter; - _subscriptions: UniversalDisposable; - _querySubscriptions: UniversalDisposable; - _activeProviderName: string; - _lastRawQuery: ?string; - _queryStream: Subject; - - constructor(quickOpenProviderRegistry: QuickOpenProviderRegistry) { +class SearchResultManager { + + constructor(quickOpenProviderRegistry) { this._activeProviderName = OMNISEARCH_PROVIDER.name; this._lastRawQuery = null; this._directoryEligibleProviders = new Map(); @@ -106,78 +115,63 @@ export default class SearchResultManager { this._providerSubscriptions = new Map(); this._directories = []; this._currentWorkingRoot = null; - this._resultCache = new ResultCache(() => { + this._resultCache = new (_ResultCache || _load_ResultCache()).default(() => { // on result changed this._emitter.emit('results-changed'); }); // `updateDirectories` joins providers and directories, which don't know anything about each // other. Debounce this call to reduce churn at startup, and when new providers get activated or // a new directory gets mounted. - this._debouncedUpdateDirectories = debounce( - this._updateDirectories.bind(this), - UPDATE_DIRECTORIES_DEBOUNCE_DELAY, - /* immediate */ false, - ); - this._emitter = new Emitter(); - this._subscriptions = new UniversalDisposable(); - this._querySubscriptions = new UniversalDisposable(); + this._debouncedUpdateDirectories = (0, (_debounce || _load_debounce()).default)(this._updateDirectories.bind(this), UPDATE_DIRECTORIES_DEBOUNCE_DELAY, + /* immediate */false); + this._emitter = new _atom.Emitter(); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._querySubscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._quickOpenProviderRegistry = quickOpenProviderRegistry; - this._queryStream = new Subject(); - this._subscriptions.add( - this._debouncedUpdateDirectories, - atom.project.onDidChangePaths(this._debouncedUpdateDirectories), - this._quickOpenProviderRegistry.observeProviders( - this._registerProvider.bind(this), - ), - this._quickOpenProviderRegistry.onDidRemoveProvider( - this._deregisterProvider.bind(this), - ), - ); + this._queryStream = new _rxjsBundlesRxMinJs.Subject(); + this._subscriptions.add(this._debouncedUpdateDirectories, atom.project.onDidChangePaths(this._debouncedUpdateDirectories), this._quickOpenProviderRegistry.observeProviders(this._registerProvider.bind(this)), this._quickOpenProviderRegistry.onDidRemoveProvider(this._deregisterProvider.bind(this))); this._debouncedUpdateDirectories(); } - executeQuery(query: string): void { + executeQuery(query) { this._lastRawQuery = query; this._queryStream.next(this._sanitizeQuery(query)); } - setActiveProvider(providerName: string): void { + setActiveProvider(providerName) { if (this._activeProviderName !== providerName) { this._activeProviderName = providerName; this._emitter.emit('providers-changed'); } } - onResultsChanged(callback: () => void): IDisposable { + onResultsChanged(callback) { return this._emitter.on('results-changed', callback); } - onProvidersChanged(callback: () => void): IDisposable { + onProvidersChanged(callback) { return this._emitter.on('providers-changed', callback); } - getActiveProviderName(): string { + getActiveProviderName() { return this._activeProviderName; } - getLastQuery(): ?string { + getLastQuery() { return this._lastRawQuery; } - getRendererForProvider( - providerName: string, - item: T, - ): ResultRenderer { + getRendererForProvider(providerName, item) { const provider = this._getProviderByName(providerName); if (provider.getComponentForItem != null) { return provider.getComponentForItem; } else if (item.resultType === 'FILE') { - return FileResultComponent.getComponentForItem; + return (_FileResultComponent || _load_FileResultComponent()).default.getComponentForItem; } throw new Error('Unable to get renderer for provider'); } - dispose(): void { + dispose() { this._emitter.dispose(); this._subscriptions.dispose(); this._providerSubscriptions.forEach(subscriptions => { @@ -189,7 +183,7 @@ export default class SearchResultManager { * Renew the cached list of directories, as well as the cached map of eligible providers * for every directory. */ - async _updateDirectories(): Promise { + async _updateDirectories() { const directories = atom.project.getDirectories(); const directoryEligibleProviders = new Map(); const globalEligibleProviders = new Set(); @@ -199,58 +193,31 @@ export default class SearchResultManager { const providersForDirectory = new Set(); directoryEligibleProviders.set(directory, providersForDirectory); for (const provider of this._quickOpenProviderRegistry.getDirectoryProviders()) { - eligibilities.push( - provider - .isEligibleForDirectory(directory) - .catch(err => { - getLogger('nuclide-quick-open').warn( - `isEligibleForDirectory failed for directory provider ${ - provider.name - }`, - err, - ); - return false; - }) - .then(isEligible => { - if (isEligible) { - providersForDirectory.add(provider); - } - }), - ); + eligibilities.push(provider.isEligibleForDirectory(directory).catch(err => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-quick-open').warn(`isEligibleForDirectory failed for directory provider ${provider.name}`, err); + return false; + }).then(isEligible => { + if (isEligible) { + providersForDirectory.add(provider); + } + })); } }); for (const provider of this._quickOpenProviderRegistry.getGlobalProviders()) { - eligibilities.push( - provider - .isEligibleForDirectories(directories) - .catch(err => { - getLogger('nuclide-quick-open').warn( - `isEligibleForDirectories failed for ${provider.name}`, - err, - ); - return false; - }) - .then(isEligible => { - if (isEligible) { - globalEligibleProviders.add(provider); - } - }), - ); + eligibilities.push(provider.isEligibleForDirectories(directories).catch(err => { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-quick-open').warn(`isEligibleForDirectories failed for ${provider.name}`, err); + return false; + }).then(isEligible => { + if (isEligible) { + globalEligibleProviders.add(provider); + } + })); } await Promise.all(eligibilities); - if ( - !( - arrayEqual(this._directories, directories) && - mapEqual( - this._directoryEligibleProviders, - directoryEligibleProviders, - ) && - areSetsEqual(this._globalEligibleProviders, globalEligibleProviders) - ) - ) { + if (!((0, (_collection || _load_collection()).arrayEqual)(this._directories, directories) && (0, (_collection || _load_collection()).mapEqual)(this._directoryEligibleProviders, directoryEligibleProviders) && (0, (_collection || _load_collection()).areSetsEqual)(this._globalEligibleProviders, globalEligibleProviders))) { this._directories = directories; this._directoryEligibleProviders = directoryEligibleProviders; this._globalEligibleProviders = globalEligibleProviders; @@ -259,33 +226,23 @@ export default class SearchResultManager { // Providers can have a very wide range of debounce delays. // Debounce queries on a per-provider basis to ensure that the default Cmd-T is snappy. this._querySubscriptions.dispose(); - this._querySubscriptions = new UniversalDisposable(); + this._querySubscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); for (const [directory, providers] of this._directoryEligibleProviders) { for (const provider of providers) { - this._querySubscriptions.add( - this._queryStream - .let(fastDebounce(getQueryDebounceDelay(provider))) - .subscribe(query => - this._executeDirectoryQuery(directory, provider, query), - ), - ); + this._querySubscriptions.add(this._queryStream.let((0, (_observable || _load_observable()).fastDebounce)(getQueryDebounceDelay(provider))).subscribe(query => this._executeDirectoryQuery(directory, provider, query))); } } for (const provider of this._globalEligibleProviders) { - this._querySubscriptions.add( - this._queryStream - .let(fastDebounce(getQueryDebounceDelay(provider))) - .subscribe(query => this._executeGlobalQuery(provider, query)), - ); + this._querySubscriptions.add(this._queryStream.let((0, (_observable || _load_observable()).fastDebounce)(getQueryDebounceDelay(provider))).subscribe(query => this._executeGlobalQuery(provider, query))); } } } - setCurrentWorkingRoot(newRoot: ?string): void { + setCurrentWorkingRoot(newRoot) { this._currentWorkingRoot = newRoot; } - _sortDirectories(): Array { + _sortDirectories() { const currentWorkingRoot = this._currentWorkingRoot; if (currentWorkingRoot == null) { // Don't sort @@ -319,18 +276,18 @@ export default class SearchResultManager { return directories; } - _registerProvider(service: Provider): void { + _registerProvider(service) { if (this._providerSubscriptions.get(service)) { throw new Error(`${service.name} has already been registered.`); } - const subscriptions = new UniversalDisposable(); + const subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._providerSubscriptions.set(service, subscriptions); this._debouncedUpdateDirectories(); } - _deregisterProvider(service: Provider): void { + _deregisterProvider(service) { const subscriptions = this._providerSubscriptions.get(service); if (subscriptions == null) { throw new Error(`${service.name} has already been deregistered.`); @@ -355,122 +312,79 @@ export default class SearchResultManager { this._emitter.emit('providers-changed'); } - _cacheResult( - query: string, - result: Array, - directory: string, - provider: Provider, - ): void { - this._resultCache.setCacheResult( - provider.name, - directory, - query, - result, - false, - null, - ); + _cacheResult(query, result, directory, provider) { + this._resultCache.setCacheResult(provider.name, directory, query, result, false, null); } - _setLoading( - query: string, - directory: string, - provider: Provider, - ): void { - const previousResult = this._resultCache.getCacheResult( - provider.name, - directory, - query, - ); + _setLoading(query, directory, provider) { + const previousResult = this._resultCache.getCacheResult(provider.name, directory, query); if (!previousResult) { this._resultCache.rawSetCacheResult(provider.name, directory, query, { results: [], error: null, - loading: true, + loading: true }); } } - _processResult( - query: string, - result: Array, - directory: string, - provider: Provider, - ): void { + _processResult(query, result, directory, provider) { this._cacheResult(query, result, directory, provider); this._emitter.emit('results-changed'); } - _sanitizeQuery(query: string): string { + _sanitizeQuery(query) { return query.trim(); } - _executeGlobalQuery(provider: GlobalProviderType<*>, query: string): void { + _executeGlobalQuery(provider, query) { const startTime = performance.now(); const loadingFn = () => { this._setLoading(query, GLOBAL_KEY, provider); this._emitter.emit('results-changed'); }; - triggerAfterWait( - provider.executeQuery(query, this._directories), - LOADING_EVENT_DELAY, - loadingFn, - ).then(result => { - trackSampled('quickopen-query-source-provider', TRACK_SOURCE_RATE, { + (0, (_promise || _load_promise()).triggerAfterWait)(provider.executeQuery(query, this._directories), LOADING_EVENT_DELAY, loadingFn).then(result => { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackSampled)('quickopen-query-source-provider', TRACK_SOURCE_RATE, { 'quickopen-source-provider': provider.name, 'quickopen-query-duration': (performance.now() - startTime).toString(), - 'quickopen-result-count': result.length.toString(), + 'quickopen-result-count': result.length.toString() }); this._processResult(query, result, GLOBAL_KEY, provider); }); } - _executeDirectoryQuery( - directory: atom$Directory, - provider: DirectoryProviderType<*>, - query: string, - ) { + _executeDirectoryQuery(directory, provider, query) { const path = directory.getPath(); const startTime = performance.now(); const loadingFn = () => { this._setLoading(query, path, provider); this._emitter.emit('results-changed'); }; - triggerAfterWait( - provider.executeQuery(query, directory), - LOADING_EVENT_DELAY, - loadingFn, - ).then(result => { - trackSampled('quickopen-query-source-provider', TRACK_SOURCE_RATE, { + (0, (_promise || _load_promise()).triggerAfterWait)(provider.executeQuery(query, directory), LOADING_EVENT_DELAY, loadingFn).then(result => { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackSampled)('quickopen-query-source-provider', TRACK_SOURCE_RATE, { 'quickopen-source-provider': provider.name, 'quickopen-query-duration': (performance.now() - startTime).toString(), - 'quickopen-result-count': result.length.toString(), + 'quickopen-result-count': result.length.toString() }); this._processResult(query, result, path, provider); }); } - _getProviderByName(providerName: string): Provider { - const provider = this._quickOpenProviderRegistry.getProviderByName( - providerName, - ); - invariant( - provider != null, - `Provider ${providerName} is not registered with quick-open.`, - ); + _getProviderByName(providerName) { + const provider = this._quickOpenProviderRegistry.getProviderByName(providerName); + + if (!(provider != null)) { + throw new Error(`Provider ${providerName} is not registered with quick-open.`); + } + return provider; } - _getResultsForProvider(query: string, providerName: string): GroupedResult { + _getResultsForProvider(query, providerName) { let providerPaths; if (this._quickOpenProviderRegistry.isProviderGlobal(providerName)) { - const provider = this._quickOpenProviderRegistry.getGlobalProviderByName( - providerName, - ); - providerPaths = - provider && this._globalEligibleProviders.has(provider) - ? [GLOBAL_KEY] - : []; + const provider = this._quickOpenProviderRegistry.getGlobalProviderByName(providerName); + providerPaths = provider && this._globalEligibleProviders.has(provider) ? [GLOBAL_KEY] : []; } else { providerPaths = this._sortDirectories().map(d => d.getPath()); } @@ -481,9 +395,7 @@ export default class SearchResultManager { title: providerSpec.title, results: providerPaths.reduce((results, path) => { let cachedResult = {}; - const cachedPaths = this._resultCache.getAllCachedResults()[ - providerName - ]; + const cachedPaths = this._resultCache.getAllCachedResults()[providerName]; if (cachedPaths) { const cachedQueries = cachedPaths[path]; if (cachedQueries) { @@ -495,78 +407,59 @@ export default class SearchResultManager { // We need to ensure that "abce" displays the results for "abc" // while loading rather than the results for "abcd". this._resultCache.setLastCachedQuery(providerName, query); - } else if ( - lastCachedQuery != null && - cachedQueries[lastCachedQuery] - ) { + } else if (lastCachedQuery != null && cachedQueries[lastCachedQuery]) { cachedResult = cachedQueries[lastCachedQuery]; } } } - const defaultResult: ProviderResults = { + const defaultResult = { error: null, loading: false, - results: [], + results: [] }; const resultList = cachedResult.results || defaultResult.results; results[path] = { results: resultList.map(result => - // $FlowFixMe (v0.54.1 <) - ({ - ...result, - sourceProvider: providerName, - }), - ), + // $FlowFixMe (v0.54.1 <) + Object.assign({}, result, { + sourceProvider: providerName + })), loading: cachedResult.loading || defaultResult.loading, - error: cachedResult.error || defaultResult.error, + error: cachedResult.error || defaultResult.error }; return results; }, {}), - totalResults: 0, + totalResults: 0 }; } - getResults(query: string, activeProviderName: string): GroupedResults { + getResults(query, activeProviderName) { const sanitizedQuery = this._sanitizeQuery(query); if (activeProviderName === OMNISEARCH_PROVIDER.name) { const omniSearchResults = {}; - Object.keys(this._resultCache.getAllCachedResults()) - .map(providerName => { - const resultForProvider = this._getResultsForProvider( - sanitizedQuery, - providerName, - ); - // TODO replace this with a ranking algorithm. - for (const dir in resultForProvider.results) { - resultForProvider.totalResults += - resultForProvider.results[dir].results.length; - resultForProvider.results[dir].results = resultForProvider.results[ - dir - ].results.slice(0, MAX_OMNI_RESULTS_PER_SERVICE); - } - return [providerName, resultForProvider]; - }) - .sort(([name1, result1], [name2, result2]) => { - return result1.priority === result2.priority - ? name1.localeCompare(name2) - : result1.priority - result2.priority; - }) - .forEach(([providerName, resultForProvider]) => { - omniSearchResults[providerName] = resultForProvider; - }); + Object.keys(this._resultCache.getAllCachedResults()).map(providerName => { + const resultForProvider = this._getResultsForProvider(sanitizedQuery, providerName); + // TODO replace this with a ranking algorithm. + for (const dir in resultForProvider.results) { + resultForProvider.totalResults += resultForProvider.results[dir].results.length; + resultForProvider.results[dir].results = resultForProvider.results[dir].results.slice(0, MAX_OMNI_RESULTS_PER_SERVICE); + } + return [providerName, resultForProvider]; + }).sort(([name1, result1], [name2, result2]) => { + return result1.priority === result2.priority ? name1.localeCompare(name2) : result1.priority - result2.priority; + }).forEach(([providerName, resultForProvider]) => { + omniSearchResults[providerName] = resultForProvider; + }); return omniSearchResults; } else { - const resultForProvider = this._getResultsForProvider( - sanitizedQuery, - activeProviderName, - ); - return {[activeProviderName]: resultForProvider}; + const resultForProvider = this._getResultsForProvider(sanitizedQuery, activeProviderName); + return { [activeProviderName]: resultForProvider }; } } - getProviderSpecByName(providerName: string): ProviderSpec { + getProviderSpecByName(providerName) { if (providerName === OMNISEARCH_PROVIDER.name) { - return {...OMNISEARCH_PROVIDER}; + return Object.assign({}, OMNISEARCH_PROVIDER); } return this._bakeProvider(this._getProviderByName(providerName)); } @@ -574,51 +467,39 @@ export default class SearchResultManager { /** * Turn a Provider into a plain "spec" object consumed by QuickSelectionComponent. */ - _bakeProvider(provider: Provider): ProviderSpec { - const {display} = provider; + _bakeProvider(provider) { + const { display } = provider; const providerSpec = { name: provider.name, debounceDelay: getQueryDebounceDelay(provider), title: display != null ? display.title : provider.name, prompt: display != null ? display.prompt : `Search ${provider.name}`, action: display != null && display.action != null ? display.action : '', - canOpenAll: - display != null && display.canOpenAll != null - ? display.canOpenAll - : true, - priority: - provider.priority != null - ? provider.priority - : Number.POSITIVE_INFINITY, + canOpenAll: display != null && display.canOpenAll != null ? display.canOpenAll : true, + priority: provider.priority != null ? provider.priority : Number.POSITIVE_INFINITY }; return providerSpec; } - getRenderableProviders(): Array { + getRenderableProviders() { // Only render tabs for providers that are eligible for at least one directory. - const eligibleDirectoryProviders = this._quickOpenProviderRegistry - .getDirectoryProviders() - .filter(directoryProvider => { - for (const [, directoryEligibleProviders] of this - ._directoryEligibleProviders) { - if (directoryEligibleProviders.has(directoryProvider)) { - return true; - } + const eligibleDirectoryProviders = this._quickOpenProviderRegistry.getDirectoryProviders().filter(directoryProvider => { + for (const [, directoryEligibleProviders] of this._directoryEligibleProviders) { + if (directoryEligibleProviders.has(directoryProvider)) { + return true; } - return false; - }); - const tabs = Array.from(this._globalEligibleProviders) - .concat(eligibleDirectoryProviders) - .filter(provider => provider.display != null) - .map(provider => this._bakeProvider(provider)) - .sort((p1, p2) => p1.name.localeCompare(p2.name)); + } + return false; + }); + const tabs = Array.from(this._globalEligibleProviders).concat(eligibleDirectoryProviders).filter(provider => provider.display != null).map(provider => this._bakeProvider(provider)).sort((p1, p2) => p1.name.localeCompare(p2.name)); tabs.unshift(OMNISEARCH_PROVIDER); return tabs; } } -export const __test__ = { - _getOmniSearchProviderSpec(): ProviderSpec { +exports.default = SearchResultManager; +const __test__ = exports.__test__ = { + _getOmniSearchProviderSpec() { return OMNISEARCH_PROVIDER; - }, -}; + } +}; \ No newline at end of file diff --git a/pkg/nuclide-quick-open/lib/main.js b/pkg/nuclide-quick-open/lib/main.js index 041ebcd372..74c92cbef9 100644 --- a/pkg/nuclide-quick-open/lib/main.js +++ b/pkg/nuclide-quick-open/lib/main.js @@ -1,107 +1,139 @@ -/** - * 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 - */ - -import type {ProviderResult, Provider} from './types'; -import type {HomeFragments} from '../../nuclide-home/lib/types'; -import type CwdApi from '../../nuclide-current-working-directory/lib/CwdApi'; -import type { - DeepLinkService, - DeepLinkParams, -} from '../../nuclide-deep-link/lib/types'; -import type {QuickSelectionAction} from './QuickSelectionDispatcher'; -import type {SelectionIndex} from './QuickSelectionComponent'; - -import invariant from 'assert'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import QuickSelectionComponent from './QuickSelectionComponent'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {goToLocation} from 'nuclide-commons-atom/go-to-location'; -import {track} from '../../nuclide-analytics'; -import debounce from 'nuclide-commons/debounce'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import SearchResultManager from './SearchResultManager'; -import QuickOpenProviderRegistry from './QuickOpenProviderRegistry'; -import QuickSelectionActions from './QuickSelectionActions'; -import QuickSelectionDispatcher, { - ActionTypes, -} from './QuickSelectionDispatcher'; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.activate = activate; +exports.deactivate = deactivate; +exports.registerProvider = registerProvider; +exports.consumeCWD = consumeCWD; +exports.consumeDeepLinkService = consumeDeepLinkService; +exports.getHomeFragments = getHomeFragments; + +var _react = _interopRequireWildcard(require('react')); + +var _reactDom = _interopRequireDefault(require('react-dom')); + +var _QuickSelectionComponent; + +function _load_QuickSelectionComponent() { + return _QuickSelectionComponent = _interopRequireDefault(require('./QuickSelectionComponent')); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _goToLocation; + +function _load_goToLocation() { + return _goToLocation = require('../../../modules/nuclide-commons-atom/go-to-location'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _debounce; + +function _load_debounce() { + return _debounce = _interopRequireDefault(require('../../../modules/nuclide-commons/debounce')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _SearchResultManager; + +function _load_SearchResultManager() { + return _SearchResultManager = _interopRequireDefault(require('./SearchResultManager')); +} + +var _QuickOpenProviderRegistry; + +function _load_QuickOpenProviderRegistry() { + return _QuickOpenProviderRegistry = _interopRequireDefault(require('./QuickOpenProviderRegistry')); +} + +var _QuickSelectionActions; + +function _load_QuickSelectionActions() { + return _QuickSelectionActions = _interopRequireDefault(require('./QuickSelectionActions')); +} + +var _QuickSelectionDispatcher; + +function _load_QuickSelectionDispatcher() { + return _QuickSelectionDispatcher = _interopRequireDefault(require('./QuickSelectionDispatcher')); +} + +var _QuickSelectionDispatcher2; + +function _load_QuickSelectionDispatcher2() { + return _QuickSelectionDispatcher2 = require('./QuickSelectionDispatcher'); +} + +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; } } // Don't pre-fill search input if selection is longer than this: -const MAX_SELECTION_LENGTH = 1000; +const MAX_SELECTION_LENGTH = 1000; /** + * 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. + * + * + * @format + */ + const ANALYTICS_CHANGE_SELECTION_DEBOUCE = 100; class Activation { - _analyticsSessionId: ?string; - _dispatcherToken: string; - _previousFocus: ?HTMLElement; - _searchComponent: ?QuickSelectionComponent; - _searchPanel: ?atom$Panel; - _subscriptions: UniversalDisposable; - _searchResultManager: SearchResultManager; - _quickOpenProviderRegistry: QuickOpenProviderRegistry; - _quickSelectionActions: QuickSelectionActions; - _quickSelectionDispatcher: QuickSelectionDispatcher; constructor() { this._analyticsSessionId = null; this._previousFocus = null; this._searchComponent = null; this._searchPanel = null; - this._quickOpenProviderRegistry = new QuickOpenProviderRegistry(); - this._quickSelectionDispatcher = new QuickSelectionDispatcher(); - this._quickSelectionActions = new QuickSelectionActions( - this._quickSelectionDispatcher, - ); - this._searchResultManager = new SearchResultManager( - this._quickOpenProviderRegistry, - ); - this._dispatcherToken = this._quickSelectionDispatcher.register( - this._handleActions.bind(this), - ); - this._subscriptions = new UniversalDisposable( - atom.commands.add('atom-workspace', { - 'nuclide-quick-open:find-anything-via-omni-search': () => { - this._quickSelectionActions.changeActiveProvider( - 'OmniSearchResultProvider', - ); - }, - }), - ); - - (this: any)._handleSelectionChanged = debounce( - this._handleSelectionChanged.bind(this), - ANALYTICS_CHANGE_SELECTION_DEBOUCE, - ); - - (this: any)._handleSelection = (this: any)._handleSelection.bind(this); - (this: any)._closeSearchPanel = (this: any)._closeSearchPanel.bind(this); + this._quickOpenProviderRegistry = new (_QuickOpenProviderRegistry || _load_QuickOpenProviderRegistry()).default(); + this._quickSelectionDispatcher = new (_QuickSelectionDispatcher || _load_QuickSelectionDispatcher()).default(); + this._quickSelectionActions = new (_QuickSelectionActions || _load_QuickSelectionActions()).default(this._quickSelectionDispatcher); + this._searchResultManager = new (_SearchResultManager || _load_SearchResultManager()).default(this._quickOpenProviderRegistry); + this._dispatcherToken = this._quickSelectionDispatcher.register(this._handleActions.bind(this)); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(atom.commands.add('atom-workspace', { + 'nuclide-quick-open:find-anything-via-omni-search': () => { + this._quickSelectionActions.changeActiveProvider('OmniSearchResultProvider'); + } + })); + + this._handleSelectionChanged = (0, (_debounce || _load_debounce()).default)(this._handleSelectionChanged.bind(this), ANALYTICS_CHANGE_SELECTION_DEBOUCE); + + this._handleSelection = this._handleSelection.bind(this); + this._closeSearchPanel = this._closeSearchPanel.bind(this); } - _handleActions(action: QuickSelectionAction): void { + _handleActions(action) { switch (action.actionType) { - case ActionTypes.ACTIVE_PROVIDER_CHANGED: + case (_QuickSelectionDispatcher2 || _load_QuickSelectionDispatcher2()).ActionTypes.ACTIVE_PROVIDER_CHANGED: this._handleActiveProviderChange(action.providerName); break; - case ActionTypes.QUERY: + case (_QuickSelectionDispatcher2 || _load_QuickSelectionDispatcher2()).ActionTypes.QUERY: this._searchResultManager.executeQuery(action.query); break; } } - _handleSelection( - selections: Array, - providerName: string, - query: string, - ): void { + _handleSelection(selections, providerName, query) { for (let i = 0; i < selections.length; i++) { const selection = selections[i]; // TODO: Having a callback to call shouldn't necessarily preclude @@ -110,21 +142,15 @@ class Activation { // Can possibly be resolved with a first-class "LINK" or similar resultType if (typeof selection.callback === 'function') { selection.callback(); - } else if ( - selection.resultType === 'FILE' || - selection.resultType === 'SYMBOL' - ) { - goToLocation(selection.path, { + } else if (selection.resultType === 'FILE' || selection.resultType === 'SYMBOL') { + (0, (_goToLocation || _load_goToLocation()).goToLocation)(selection.path, { line: selection.line, - column: selection.column, + column: selection.column }); } - if ( - selection.resultType === 'FILE' || - selection.resultType === 'SYMBOL' - ) { - track('quickopen-select-file', { + if (selection.resultType === 'FILE' || selection.resultType === 'SYMBOL') { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('quickopen-select-file', { 'quickopen-filepath': selection.path, 'quickopen-query': query, // The currently open "tab". @@ -132,49 +158,44 @@ class Activation { 'quickopen-session': this._analyticsSessionId || '', // Because the `provider` is usually OmniSearch, also track the original provider. // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - 'quickopen-provider-source': selection.sourceProvider || '', + 'quickopen-provider-source': selection.sourceProvider || '' }); } } this._closeSearchPanel(); } - _handleSelectionChanged( - selectionIndex: SelectionIndex, - providerName: string, - query: string, - ): void { + _handleSelectionChanged(selectionIndex, providerName, query) { // Only track user-initiated selection-change events. if (this._analyticsSessionId != null) { - track('quickopen-change-selection', { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('quickopen-change-selection', { 'quickopen-selected-index': selectionIndex.selectedItemIndex.toString(), 'quickopen-selected-service': selectionIndex.selectedService, 'quickopen-selected-directory': selectionIndex.selectedDirectory, - 'quickopen-session': this._analyticsSessionId, + 'quickopen-session': this._analyticsSessionId }); } } - _handleActiveProviderChange(newProviderName: string): void { + _handleActiveProviderChange(newProviderName) { /** * A "session" for the purpose of analytics. It exists from the moment the * quick-open UI becomes visible until it gets closed, either via file * selection or cancellation. */ this._analyticsSessionId = - // flowlint-next-line sketchy-null-string:off - this._analyticsSessionId || Date.now().toString(); - track('quickopen-change-tab', { + // flowlint-next-line sketchy-null-string:off + this._analyticsSessionId || Date.now().toString(); + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('quickopen-change-tab', { 'quickopen-provider': newProviderName, - 'quickopen-session': this._analyticsSessionId, + 'quickopen-session': this._analyticsSessionId }); - if ( - this._searchPanel != null && - this._searchPanel.isVisible() && - this._searchResultManager.getActiveProviderName() === newProviderName - ) { + if (this._searchPanel != null && this._searchPanel.isVisible() && this._searchResultManager.getActiveProviderName() === newProviderName) { // Search panel is already open. Just focus on the query textbox. - invariant(this._searchComponent != null); + if (!(this._searchComponent != null)) { + throw new Error('Invariant violation: "this._searchComponent != null"'); + } + this._searchComponent.selectAllText(); } else { this._searchResultManager.setActiveProvider(newProviderName); @@ -182,41 +203,39 @@ class Activation { } } - _showSearchPanel(initialQuery?: string): void { + _showSearchPanel(initialQuery) { if (this._searchPanel == null) { this._searchPanel = atom.workspace.addModalPanel({ item: document.createElement('div'), visible: false, - className: 'nuclide-quick-open', + className: 'nuclide-quick-open' }); } const searchPanel = this._searchPanel; - invariant(searchPanel != null); - - const searchComponent = ReactDOM.render( - , - searchPanel.getItem(), - ); - invariant(searchComponent instanceof QuickSelectionComponent); - - if ( - this._searchComponent != null && - this._searchComponent !== searchComponent - ) { - throw new Error( - 'Only one QuickSelectionComponent can be rendered at a time.', - ); + + if (!(searchPanel != null)) { + throw new Error('Invariant violation: "searchPanel != null"'); + } + + const searchComponent = _reactDom.default.render(_react.createElement((_QuickSelectionComponent || _load_QuickSelectionComponent()).default, { + quickSelectionActions: this._quickSelectionActions, + searchResultManager: this._searchResultManager, + onSelection: this._handleSelection, + onCancellation: this._closeSearchPanel + }), searchPanel.getItem()); + + if (!(searchComponent instanceof (_QuickSelectionComponent || _load_QuickSelectionComponent()).default)) { + throw new Error('Invariant violation: "searchComponent instanceof QuickSelectionComponent"'); + } + + if (this._searchComponent != null && this._searchComponent !== searchComponent) { + throw new Error('Only one QuickSelectionComponent can be rendered at a time.'); } // Start a new search "session" for analytics purposes. - track('quickopen-open-panel', { - 'quickopen-session': this._analyticsSessionId || '', + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('quickopen-open-panel', { + 'quickopen-session': this._analyticsSessionId || '' }); if (this._searchComponent == null) { @@ -226,14 +245,10 @@ class Activation { if (initialQuery != null) { searchComponent.setInputValue(initialQuery); - } else if ( - !searchPanel.isVisible() && - featureConfig.get('nuclide-quick-open.useSelection') - ) { + } else if (!searchPanel.isVisible() && (_featureConfig || _load_featureConfig()).default.get('nuclide-quick-open.useSelection')) { // Only on initial render should you use the current selection as a query. const editor = atom.workspace.getActiveTextEditor(); - const selectedText = - editor != null && editor.getSelections()[0].getText(); + const selectedText = editor != null && editor.getSelections()[0].getText(); if (selectedText && selectedText.length <= MAX_SELECTION_LENGTH) { searchComponent.setInputValue(selectedText.split('\n')[0]); } @@ -245,13 +260,16 @@ class Activation { } } - _closeSearchPanel(): void { + _closeSearchPanel() { if (this._searchComponent != null) { - invariant(this._searchPanel != null); - ReactDOM.unmountComponentAtNode(this._searchPanel.getItem()); + if (!(this._searchPanel != null)) { + throw new Error('Invariant violation: "this._searchPanel != null"'); + } + + _reactDom.default.unmountComponentAtNode(this._searchPanel.getItem()); this._searchComponent = null; - track('quickopen-close-panel', { - 'quickopen-session': this._analyticsSessionId || '', + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('quickopen-close-panel', { + 'quickopen-session': this._analyticsSessionId || '' }); this._analyticsSessionId = null; } @@ -266,27 +284,23 @@ class Activation { } } - registerProvider(service: Provider): IDisposable { - const subscriptions = new UniversalDisposable( - this._quickOpenProviderRegistry.addProvider(service), - ); + registerProvider(service) { + const subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(this._quickOpenProviderRegistry.addProvider(service)); // If the provider is renderable and specifies a keybinding, wire it up with // the toggle command. if (service.display != null && service.display.action != null) { - subscriptions.add( - atom.commands.add('atom-workspace', { - [service.display.action]: () => { - this._quickSelectionActions.changeActiveProvider(service.name); - }, - }), - ); + subscriptions.add(atom.commands.add('atom-workspace', { + [service.display.action]: () => { + this._quickSelectionActions.changeActiveProvider(service.name); + } + })); } return subscriptions; } - consumeCWDService(service: CwdApi): IDisposable { + consumeCWDService(service) { const disposable = service.observeCwd(dir => { this._searchResultManager.setCurrentWorkingRoot(dir); }); @@ -294,21 +308,18 @@ class Activation { return disposable; } - consumeDeepLinkService(service: DeepLinkService): IDisposable { - const disposable = service.subscribeToPath( - 'quick-open-query', - (params: DeepLinkParams): void => { - const {query} = params; - if (typeof query === 'string') { - this._showSearchPanel(query); - } - }, - ); + consumeDeepLinkService(service) { + const disposable = service.subscribeToPath('quick-open-query', params => { + const { query } = params; + if (typeof query === 'string') { + this._showSearchPanel(query); + } + }); this._subscriptions.add(disposable); return disposable; } - dispose(): void { + dispose() { this._subscriptions.dispose(); this._quickSelectionDispatcher.unregister(this._dispatcherToken); this._closeSearchPanel(); @@ -322,44 +333,53 @@ class Activation { } } -let activation: ?Activation = null; +let activation = null; -export function activate(): void { +function activate() { activation = new Activation(); } -export function deactivate(): void { - invariant(activation != null); +function deactivate() { + if (!(activation != null)) { + throw new Error('Invariant violation: "activation != null"'); + } + activation.dispose(); activation = null; } -export function registerProvider( - service: Provider, -): IDisposable { - invariant(activation != null); +function registerProvider(service) { + if (!(activation != null)) { + throw new Error('Invariant violation: "activation != null"'); + } + return activation.registerProvider(service); } -export function consumeCWD(cwd: CwdApi): IDisposable { - invariant(activation != null); +function consumeCWD(cwd) { + if (!(activation != null)) { + throw new Error('Invariant violation: "activation != null"'); + } + return activation.consumeCWDService(cwd); } -export function consumeDeepLinkService(service: DeepLinkService): IDisposable { - invariant(activation != null); +function consumeDeepLinkService(service) { + if (!(activation != null)) { + throw new Error('Invariant violation: "activation != null"'); + } + return activation.consumeDeepLinkService(service); } -export function getHomeFragments(): HomeFragments { +function getHomeFragments() { return { feature: { title: 'Quick Open', icon: 'search', - description: - 'A powerful search box to quickly find local and remote files and content.', - command: 'nuclide-quick-open:find-anything-via-omni-search', + description: 'A powerful search box to quickly find local and remote files and content.', + command: 'nuclide-quick-open:find-anything-via-omni-search' }, - priority: 10, + priority: 10 }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-quick-open/lib/searchResultHelpers.js b/pkg/nuclide-quick-open/lib/searchResultHelpers.js index 27865fcc64..4efa5432fd 100644 --- a/pkg/nuclide-quick-open/lib/searchResultHelpers.js +++ b/pkg/nuclide-quick-open/lib/searchResultHelpers.js @@ -1,45 +1,19 @@ -/** - * 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 - */ +'use strict'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {ProviderResult} from './types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.filterEmptyResults = filterEmptyResults; +exports.flattenResults = flattenResults; +exports.getOuterResults = getOuterResults; -export type ProviderResults = { - error: ?Object, - loading: boolean, - results: Array, -}; +var _collection; -export type OuterResults = { - serviceName: string, - directoryName: NuclideUri, - results: Array, -}; - -export type GroupedResult = { - priority: number, - results: {[key: NuclideUri]: ProviderResults}, - title: string, - totalResults: number, -}; - -export type GroupedResults = { - [key: string]: GroupedResult, -}; - -import {isEmpty} from 'nuclide-commons/collection'; +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} -export function filterEmptyResults( - resultsGroupedByService: GroupedResults, -): GroupedResults { +function filterEmptyResults(resultsGroupedByService) { const filteredTree = {}; for (const serviceName in resultsGroupedByService) { const directories = resultsGroupedByService[serviceName].results; @@ -49,16 +23,23 @@ export function filterEmptyResults( nonEmptyDirectories[dirName] = directories[dirName]; } } - if (!isEmpty(nonEmptyDirectories)) { - filteredTree[serviceName] = {results: nonEmptyDirectories}; + if (!(0, (_collection || _load_collection()).isEmpty)(nonEmptyDirectories)) { + filteredTree[serviceName] = { results: nonEmptyDirectories }; } } return filteredTree; -} +} /** + * 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. + * + * + * @format + */ -export function flattenResults( - resultsGroupedByService: GroupedResults, -): Array { +function flattenResults(resultsGroupedByService) { const items = []; for (const serviceName in resultsGroupedByService) { for (const dirName in resultsGroupedByService[serviceName].results) { @@ -68,28 +49,19 @@ export function flattenResults( return Array.prototype.concat.apply([], items); } -export function getOuterResults( - location: 'top' | 'bottom', - resultsByService: GroupedResults, -): ?OuterResults { +function getOuterResults(location, resultsByService) { const nonEmptyResults = filterEmptyResults(resultsByService); const serviceNames = Object.keys(nonEmptyResults); - const serviceName = - location === 'top' - ? serviceNames[0] - : serviceNames[serviceNames.length - 1]; + const serviceName = location === 'top' ? serviceNames[0] : serviceNames[serviceNames.length - 1]; if (serviceName == null) { return null; } const directoryNames = Object.keys(nonEmptyResults[serviceName].results); - const directoryName = - location === 'top' - ? directoryNames[0] - : directoryNames[directoryNames.length - 1]; + const directoryName = location === 'top' ? directoryNames[0] : directoryNames[directoryNames.length - 1]; const results = nonEmptyResults[serviceName].results[directoryName].results; return { serviceName, directoryName, - results, + results }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-quick-open/lib/types.js b/pkg/nuclide-quick-open/lib/types.js index 462f62aaa3..e043c78f40 100644 --- a/pkg/nuclide-quick-open/lib/types.js +++ b/pkg/nuclide-quick-open/lib/types.js @@ -1,89 +1,5 @@ -/** - * 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 - */ +'use strict'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; +var _react = _interopRequireWildcard(require('react')); -import * as React from 'react'; - -export type CommandResult = { - resultType: 'COMMAND', - callback?: () => mixed, -}; - -export type SymbolResult = { - resultType: 'SYMBOL', - path: NuclideUri, - line: number, - column: number, - name: string, - containerName: ?string, - icon: ?string, // from https://github.com/atom/atom/blob/master/static/octicons.less - hoverText: ?string, // sometimes used to explain the icon in words -}; - -export type FileResult = { - resultType: 'FILE', - path: NuclideUri, - matchIndexes?: Array, - score?: number, - // The original query that prompted this result, e.g. to highlight it in the UI. - query?: string, - context?: string, - timestamp?: number, - // Jump to line/column if provided. - line?: number, - column?: number, - // A custom callback to perform upon selection. - callback?: () => mixed, -}; - -export type ProviderResult = CommandResult | FileResult | SymbolResult; - -export type DirectoryProviderType = { - providerType: 'DIRECTORY', - name: string, - +debounceDelay?: number, - +display?: { - title: string, - prompt: string, - action?: string, - canOpenAll?: boolean, - }, - +priority?: number, - isEligibleForDirectory(directory: atom$Directory): Promise, - executeQuery(query: string, directory: atom$Directory): Promise>, - +getComponentForItem?: (item: T) => React.Element, -}; - -export type GlobalProviderType = { - providerType: 'GLOBAL', - name: string, - +debounceDelay?: number, - +display?: { - title: string, - prompt: string, - action?: string, - canOpenAll?: boolean, - }, - +priority?: number, - isEligibleForDirectories( - directories: Array, - ): Promise, - executeQuery( - query: string, - directories: Array, - ): Promise>, - +getComponentForItem?: (item: T) => React.Element, -}; - -export type Provider = - | DirectoryProviderType - | GlobalProviderType; +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/pkg/nuclide-quick-open/spec/SearchResultManager-spec.js b/pkg/nuclide-quick-open/spec/SearchResultManager-spec.js deleted file mode 100644 index 0251d45da7..0000000000 --- a/pkg/nuclide-quick-open/spec/SearchResultManager-spec.js +++ /dev/null @@ -1,368 +0,0 @@ -/** - * 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 - */ - -import type {GlobalProviderType, FileResult, Provider} from '../lib/types'; -import type {ProviderSpec} from '../lib/SearchResultManager'; -import type { - ProviderResults, - GroupedResult, - GroupedResults, -} from '../lib/searchResultHelpers'; - -import nuclideUri from 'nuclide-commons/nuclideUri'; - -import SearchResultManager from '../lib/SearchResultManager'; -import QuickOpenProviderRegistry from '../lib/QuickOpenProviderRegistry'; - -import {__test__} from '../lib/SearchResultManager'; -const {_getOmniSearchProviderSpec} = __test__; - -const PROJECT_ROOT1 = nuclideUri.join(__dirname, 'fixtures/root1'); -const PROJECT_ROOT2 = nuclideUri.join(__dirname, 'fixtures/root2'); -const PROJECT_ROOT3 = nuclideUri.join(__dirname, 'fixtures/root3'); - -const FakeProvider: GlobalProviderType = { - providerType: 'GLOBAL', - name: 'FakeProvider', - display: { - title: 'Fake', - prompt: 'Search FakeProvider', - canOpenAll: false, - }, - isEligibleForDirectories: directories => Promise.resolve(true), - executeQuery: (query, directories) => Promise.resolve([]), -}; - -const FakeProviderSpec: ProviderSpec = Object.freeze({ - action: '', - canOpenAll: false, - debounceDelay: 200, - name: 'FakeProvider', - prompt: 'Search FakeProvider', - title: 'Fake', - priority: Number.POSITIVE_INFINITY, -}); - -const TEST_STRINGS = ['yolo', 'foo', 'bar']; -const ExactStringMatchProvider: Provider = Object.freeze({ - providerType: 'GLOBAL', - name: 'ExactStringMatchProvider', - display: { - title: 'ExactString', - prompt: 'Nothing to see here', - }, - isEligibleForDirectories: directories => Promise.resolve(true), - executeQuery: (query, directories) => - Promise.resolve( - TEST_STRINGS.filter(s => s === query).map(s => ({ - resultType: 'FILE', - path: s, - })), - ), -}); - -// Promise-ify the flux cycle around SearchResultManager::executeQuery. -function querySingleProvider( - searchResultManager: SearchResultManager, - query: string, - providerName: string, -): Promise { - return new Promise((resolve, reject) => { - searchResultManager.onResultsChanged(() => { - resolve(searchResultManager.getResults(query, providerName)); - }); - searchResultManager.executeQuery(query); - }); -} - -function queryOmniSearchProvider( - quickOpenProviderRegistry: QuickOpenProviderRegistry, - searchResultManager: SearchResultManager, - query: string, -): Promise { - return new Promise((resolve, reject) => { - let pendingUpdates = quickOpenProviderRegistry.getProviders().length; - searchResultManager.onResultsChanged(() => { - if (--pendingUpdates === 0) { - resolve( - searchResultManager.getResults(query, 'OmniSearchResultProvider'), - ); - } - }); - searchResultManager.executeQuery(query); - }); -} - -// Helper to construct expected result objects for a global provider. -function constructSingleProviderResult( - provider: Provider, - result: ProviderResults, -): GroupedResults { - const groupResult: GroupedResult = { - priority: - provider.priority != null ? provider.priority : Number.POSITIVE_INFINITY, - title: provider.display != null ? provider.display.title : provider.name, - results: { - global: {...result}, - }, - totalResults: 0, - }; - return {[provider.name]: groupResult}; -} - -describe('SearchResultManager', () => { - let searchResultManager: SearchResultManager = (null: any); - let quickOpenProviderRegistry: QuickOpenProviderRegistry = (null: any); - let providersChanged: Promise; - - beforeEach(() => { - jasmine.useRealClock(); - quickOpenProviderRegistry = new QuickOpenProviderRegistry(); - searchResultManager = new SearchResultManager(quickOpenProviderRegistry); - providersChanged = new Promise(resolve => { - return searchResultManager.onProvidersChanged(resolve); - }); - }); - - afterEach(() => { - searchResultManager.dispose(); - }); - - describe('getLastQuery', () => { - it('should store the raw query', () => { - expect(searchResultManager.getLastQuery()).toBe(null); - searchResultManager.executeQuery('aaa'); - expect(searchResultManager.getLastQuery()).toBe('aaa'); - searchResultManager.executeQuery(' aaa '); - expect(searchResultManager.getLastQuery()).toBe(' aaa '); - }); - }); - - describe('getRenderableProviders', () => { - it('Should return OmniSearchProvider even if no actual providers are available.', () => { - const renderableProviders = searchResultManager.getRenderableProviders(); - expect(renderableProviders).toEqual([_getOmniSearchProviderSpec()]); - }); - }); - - describe('provider/directory cache', () => { - it('updates the cache when providers become (un)available', () => { - waitsForPromise(async () => { - let providersChangedCallCount = 0; - searchResultManager.onProvidersChanged(() => { - providersChangedCallCount++; - }); - - const fakeProviderDisposable = quickOpenProviderRegistry.addProvider( - FakeProvider, - ); - - // We want to await until updateDirectories has finished, but we don't - // have access to its returned Promise. So instead we'll await until - // it finally emits 'providers-changed'. - await providersChanged; - - let renderableProviders = searchResultManager.getRenderableProviders(); - expect(renderableProviders.length).toEqual(2); - expect(renderableProviders[1]).toEqual(FakeProviderSpec); - expect(providersChangedCallCount).toEqual(1); - - // Simulate deactivation of FakeProvider - // The dispose method has immediate effect: no debouncing, no need to await. - fakeProviderDisposable.dispose(); - renderableProviders = searchResultManager.getRenderableProviders(); - expect(renderableProviders.length).toEqual(1); - expect(providersChangedCallCount).toEqual(2); - }); - }); - }); - - describe('querying providers', () => { - it('queries providers asynchronously, emits change events and returns filtered results', () => { - waitsForPromise(async () => { - quickOpenProviderRegistry.addProvider(ExactStringMatchProvider); - await providersChanged; - expect( - await querySingleProvider( - searchResultManager, - 'yolo', - 'ExactStringMatchProvider', - ), - ).toEqual( - constructSingleProviderResult(ExactStringMatchProvider, { - results: [ - { - resultType: 'FILE', - path: 'yolo', - sourceProvider: 'ExactStringMatchProvider', - }, - ], - loading: false, - error: null, - }), - ); - }); - }); - - it('ignores trailing whitespace in querystring.', () => { - waitsForPromise(async () => { - quickOpenProviderRegistry.addProvider(ExactStringMatchProvider); - await providersChanged; - await Promise.all( - [' yolo', 'yolo ', ' yolo \n '].map(async query => { - expect( - await querySingleProvider( - searchResultManager, - query, - 'ExactStringMatchProvider', - ), - ).toEqual( - constructSingleProviderResult(ExactStringMatchProvider, { - results: [ - { - resultType: 'FILE', - path: query.trim(), - sourceProvider: 'ExactStringMatchProvider', - }, - ], - loading: false, - error: null, - }), - ); - }), - ); - }); - }); - }); - - describe('OmniSearch provider sorting', () => { - const FirstProvider: Provider = { - providerType: 'GLOBAL', - name: 'FirstProvider', - priority: 1, - isEligibleForDirectories: directories => Promise.resolve(true), - executeQuery: (query, directories) => Promise.resolve([]), - }; - const SecondProvider: Provider = { - providerType: 'GLOBAL', - name: 'SecondProvider', - priority: 2, - isEligibleForDirectories: directories => Promise.resolve(true), - executeQuery: (query, directories) => Promise.resolve([]), - }; - const ThirdProvider: Provider = { - providerType: 'GLOBAL', - name: 'ThirdProvider', - priority: 3, - isEligibleForDirectories: directories => Promise.resolve(true), - executeQuery: (query, directories) => Promise.resolve([]), - }; - const allResults: GroupedResults = { - FirstProvider: { - title: 'FirstProvider', - priority: 1, - results: {global: {results: [], loading: false, error: null}}, - totalResults: 0, - }, - SecondProvider: { - title: 'SecondProvider', - priority: 2, - results: {global: {results: [], loading: false, error: null}}, - totalResults: 0, - }, - ThirdProvider: { - title: 'ThirdProvider', - priority: 3, - results: {global: {results: [], loading: false, error: null}}, - totalResults: 0, - }, - }; - - it('returns results sorted by priority (1, 3, 2)', () => { - quickOpenProviderRegistry.addProvider(FirstProvider); - quickOpenProviderRegistry.addProvider(ThirdProvider); - quickOpenProviderRegistry.addProvider(SecondProvider); - waitsForPromise(async () => { - await providersChanged; - expect( - await queryOmniSearchProvider( - quickOpenProviderRegistry, - searchResultManager, - '', - ), - ).toEqual(allResults); - }); - }); - - it('returns results sorted by priority (3, 2, 1)', () => { - quickOpenProviderRegistry.addProvider(ThirdProvider); - quickOpenProviderRegistry.addProvider(SecondProvider); - quickOpenProviderRegistry.addProvider(FirstProvider); - waitsForPromise(async () => { - await providersChanged; - expect( - await queryOmniSearchProvider( - quickOpenProviderRegistry, - searchResultManager, - '', - ), - ).toEqual(allResults); - }); - }); - }); - - describe('directory sorting', () => { - beforeEach(() => { - waitsForPromise(async () => { - // Something adds paths automatically. I've seen both the `fixtures` directory and the - // `spec` directory. Remove them here so they don't pollute the tests below. - atom.project.getPaths().forEach(path => atom.project.removePath(path)); - - atom.project.addPath(PROJECT_ROOT1); - atom.project.addPath(PROJECT_ROOT2); - atom.project.addPath(PROJECT_ROOT3); - - await providersChanged; - }); - }); - - describe('with no current working root', () => { - it('should return the same order as Atom', () => { - const sortedPaths = searchResultManager - ._sortDirectories() - .map(dir => dir.getPath()); - expect(sortedPaths).toEqual([ - PROJECT_ROOT1, - PROJECT_ROOT2, - PROJECT_ROOT3, - ]); - }); - }); - - describe('with a current working root', () => { - beforeEach(() => { - // mocking the directory -- if this becomes a problem it shouldn't be too hard to get the - // actual Directory object from Atom - searchResultManager.setCurrentWorkingRoot(PROJECT_ROOT3); - }); - it('should put that root first, without disturbing the relative order of other roots', () => { - const sortedPaths = searchResultManager - ._sortDirectories() - .map(dir => dir.getPath()); - expect(sortedPaths).toEqual([ - PROJECT_ROOT3, - PROJECT_ROOT1, - PROJECT_ROOT2, - ]); - }); - }); - }); -}); diff --git a/pkg/nuclide-quick-open/spec/fixtures/root1/empty.txt b/pkg/nuclide-quick-open/spec/fixtures/root1/empty.txt deleted file mode 100644 index 3d2db15498..0000000000 --- a/pkg/nuclide-quick-open/spec/fixtures/root1/empty.txt +++ /dev/null @@ -1 +0,0 @@ -Just here to make sure the folder is recorded in version control diff --git a/pkg/nuclide-quick-open/spec/fixtures/root2/empty.txt b/pkg/nuclide-quick-open/spec/fixtures/root2/empty.txt deleted file mode 100644 index 3d2db15498..0000000000 --- a/pkg/nuclide-quick-open/spec/fixtures/root2/empty.txt +++ /dev/null @@ -1 +0,0 @@ -Just here to make sure the folder is recorded in version control diff --git a/pkg/nuclide-quick-open/spec/fixtures/root3/empty.txt b/pkg/nuclide-quick-open/spec/fixtures/root3/empty.txt deleted file mode 100644 index 3d2db15498..0000000000 --- a/pkg/nuclide-quick-open/spec/fixtures/root3/empty.txt +++ /dev/null @@ -1 +0,0 @@ -Just here to make sure the folder is recorded in version control diff --git a/pkg/nuclide-quick-open/spec/searchResultHelpers-spec.js b/pkg/nuclide-quick-open/spec/searchResultHelpers-spec.js deleted file mode 100644 index ee31c614f0..0000000000 --- a/pkg/nuclide-quick-open/spec/searchResultHelpers-spec.js +++ /dev/null @@ -1,161 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import type {GroupedResults} from '../lib/searchResultHelpers'; - -import { - filterEmptyResults, - flattenResults, - getOuterResults, -} from '../lib/searchResultHelpers'; - -const SEARCH_RESULTS_FIXTURE: GroupedResults = { - searchService: { - results: { - shouldNotAppearInOutputFolder: { - results: [], - loading: false, - error: null, - }, - folderB: { - results: [ - { - resultType: 'FILE', - path: 'foo', - }, - ], - loading: false, - error: null, - }, - }, - title: 'searchService', - priority: 0, - totalResults: 1, - }, - symbolService: { - results: { - folderA: { - results: [ - { - resultType: 'FILE', - path: 'bar', - }, - ], - loading: false, - error: null, - }, - shouldNotAppearInOutputFolder: { - results: [], - loading: false, - error: null, - }, - }, - title: 'symbolService', - priority: 0, - totalResults: 1, - }, - shouldNotAppearInOutputService: { - results: { - folderA: { - results: [], - loading: false, - error: null, - }, - folderB: { - results: [], - loading: false, - error: null, - }, - }, - title: 'shouldNotAppearInOutputService', - priority: 0, - totalResults: 0, - }, -}; - -describe('searchResultHelper', () => { - describe('emptyResults', () => { - it('does not include empty folders', () => { - const filteredResults: GroupedResults = filterEmptyResults( - SEARCH_RESULTS_FIXTURE, - ); - expect(filteredResults).toEqual({ - searchService: { - results: { - folderB: { - results: [ - { - resultType: 'FILE', - path: 'foo', - }, - ], - loading: false, - error: null, - }, - }, - }, - symbolService: { - results: { - folderA: { - results: [ - { - resultType: 'FILE', - path: 'bar', - }, - ], - loading: false, - error: null, - }, - }, - }, - }); - }); - }); - - describe('flattenResults', () => { - it('returns an array of flattened results', () => { - expect(flattenResults(SEARCH_RESULTS_FIXTURE)).toEqual([ - {resultType: 'FILE', path: 'foo'}, - {resultType: 'FILE', path: 'bar'}, - ]); - }); - }); - - describe('getOuterResults', () => { - it('works with top', () => { - const topOuterResults = getOuterResults('top', SEARCH_RESULTS_FIXTURE); - expect(topOuterResults).toEqual({ - serviceName: 'searchService', - directoryName: 'folderB', - results: [ - { - resultType: 'FILE', - path: 'foo', - }, - ], - }); - }); - - it('works with bottom', () => { - const topOuterResults = getOuterResults('bottom', SEARCH_RESULTS_FIXTURE); - expect(topOuterResults).toEqual({ - serviceName: 'symbolService', - directoryName: 'folderA', - results: [ - { - resultType: 'FILE', - path: 'bar', - }, - ], - }); - }); - }); -}); diff --git a/pkg/nuclide-react-inspector/lib/main.js b/pkg/nuclide-react-inspector/lib/main.js index 3d52634253..e62fd4ea36 100644 --- a/pkg/nuclide-react-inspector/lib/main.js +++ b/pkg/nuclide-react-inspector/lib/main.js @@ -1,47 +1,77 @@ -/** - * 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 strict-local - * @format - */ - -import {viewableFromReactElement} from '../../commons-atom/viewableFromReactElement'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import Inspector, {WORKSPACE_VIEW_URI} from './ui/Inspector'; -import invariant from 'assert'; -import * as React from 'react'; -import {destroyItemWhere} from 'nuclide-commons-atom/destroyItemWhere'; - -let disposables: ?UniversalDisposable = null; - -export function activate(): void { - disposables = new UniversalDisposable(registerCommandAndOpener()); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.activate = activate; +exports.deactivate = deactivate; + +var _viewableFromReactElement; + +function _load_viewableFromReactElement() { + return _viewableFromReactElement = require('../../commons-atom/viewableFromReactElement'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _Inspector; + +function _load_Inspector() { + return _Inspector = _interopRequireDefault(require('./ui/Inspector')); +} + +var _Inspector2; + +function _load_Inspector2() { + return _Inspector2 = require('./ui/Inspector'); } -export function deactivate(): void { - invariant(disposables != null); +var _react = _interopRequireWildcard(require('react')); + +var _destroyItemWhere; + +function _load_destroyItemWhere() { + return _destroyItemWhere = require('../../../modules/nuclide-commons-atom/destroyItemWhere'); +} + +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 disposables = null; /** + * 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. + * + * strict-local + * @format + */ + +function activate() { + disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(registerCommandAndOpener()); +} + +function deactivate() { + if (!(disposables != null)) { + throw new Error('Invariant violation: "disposables != null"'); + } + disposables.dispose(); disposables = null; } -function registerCommandAndOpener(): UniversalDisposable { - return new UniversalDisposable( - atom.workspace.addOpener(uri => { - if (uri === WORKSPACE_VIEW_URI) { - return viewableFromReactElement(); - } - }), - () => destroyItemWhere(item => item instanceof Inspector), - atom.commands.add( - 'atom-workspace', - 'nuclide-react-inspector:toggle', - () => { - atom.workspace.toggle(WORKSPACE_VIEW_URI); - }, - ), - ); -} +function registerCommandAndOpener() { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(atom.workspace.addOpener(uri => { + if (uri === (_Inspector2 || _load_Inspector2()).WORKSPACE_VIEW_URI) { + return (0, (_viewableFromReactElement || _load_viewableFromReactElement()).viewableFromReactElement)(_react.createElement((_Inspector || _load_Inspector()).default, null)); + } + }), () => (0, (_destroyItemWhere || _load_destroyItemWhere()).destroyItemWhere)(item => item instanceof (_Inspector || _load_Inspector()).default), atom.commands.add('atom-workspace', 'nuclide-react-inspector:toggle', () => { + atom.workspace.toggle((_Inspector2 || _load_Inspector2()).WORKSPACE_VIEW_URI); + })); +} \ No newline at end of file diff --git a/pkg/nuclide-react-inspector/lib/ui/Inspector.js b/pkg/nuclide-react-inspector/lib/ui/Inspector.js index 83d17fa504..3d3dfeb5a3 100644 --- a/pkg/nuclide-react-inspector/lib/ui/Inspector.js +++ b/pkg/nuclide-react-inspector/lib/ui/Inspector.js @@ -1,3 +1,20 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.WORKSPACE_VIEW_URI = undefined; + +var _react = _interopRequireWildcard(require('react')); + +var _Webview; + +function _load_Webview() { + return _Webview = require('../../../nuclide-ui/Webview'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,62 +22,59 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import * as React from 'react'; -import {Webview} from '../../../nuclide-ui/Webview'; +const WORKSPACE_VIEW_URI = exports.WORKSPACE_VIEW_URI = 'atom://nuclide/react-inspector'; + +class Inspector extends _react.Component { + constructor(...args) { + var _temp; + + return _temp = super(...args), this._handleDidFinishLoad = event => { + const themes = atom.config.get('core.themes'); + + let theme = ''; -export const WORKSPACE_VIEW_URI = 'atom://nuclide/react-inspector'; + // Atom has 2 theme settings: UI and Syntax. + // DevTools matches the Syntax theme, which is the 2nd in the array. + if (Array.isArray(themes) && themes.length > 1) { + theme = themes[1]; + } -type Props = {||}; + const element = event.target; + const requirePaths = require.cache[__filename].paths; + const inspectorDevTools = require.resolve('react-devtools-core/standalone'); + element.executeJavaScript(`initializeElementInspector( + ${JSON.stringify(inspectorDevTools)}, + ${JSON.stringify(requirePaths)}, + ${JSON.stringify(theme)} + );`); + }, _temp; + } -export default class Inspector extends React.Component { - getTitle(): string { + getTitle() { return 'React Inspector'; } - getDefaultLocation(): string { + getDefaultLocation() { return 'center'; } - getURI(): string { + getURI() { return WORKSPACE_VIEW_URI; } - render(): React.Node { - return ( - - ); + render() { + return _react.createElement((_Webview || _load_Webview()).Webview, { + style: { width: '100%', height: '100%' }, + nodeintegration: true, + className: 'native-key-bindings', + onDidFinishLoad: this._handleDidFinishLoad, + src: 'atom://nuclide/pkg/nuclide-react-inspector/lib/ui/inspector.html' + }); } - _handleDidFinishLoad = (event: Event) => { - const themes = atom.config.get('core.themes'); - - let theme = ''; - - // Atom has 2 theme settings: UI and Syntax. - // DevTools matches the Syntax theme, which is the 2nd in the array. - if (Array.isArray(themes) && themes.length > 1) { - theme = themes[1]; - } - - const element = ((event.target: any): WebviewElement); - const requirePaths = require.cache[__filename].paths; - const inspectorDevTools = require.resolve('react-devtools-core/standalone'); - element.executeJavaScript( - `initializeElementInspector( - ${JSON.stringify(inspectorDevTools)}, - ${JSON.stringify(requirePaths)}, - ${JSON.stringify(theme)} - );`, - ); - }; } +exports.default = Inspector; \ No newline at end of file diff --git a/pkg/nuclide-recent-files-provider/lib/RecentFilesProvider.js b/pkg/nuclide-recent-files-provider/lib/RecentFilesProvider.js index 2f7311e505..cb434dbfc4 100644 --- a/pkg/nuclide-recent-files-provider/lib/RecentFilesProvider.js +++ b/pkg/nuclide-recent-files-provider/lib/RecentFilesProvider.js @@ -1,3 +1,48 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RecentFilesProvider = undefined; +exports.setRecentFilesService = setRecentFilesService; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _string; + +function _load_string() { + return _string = require('../../../modules/nuclide-commons/string'); +} + +var _nuclideFuzzyNative; + +function _load_nuclideFuzzyNative() { + return _nuclideFuzzyNative = require('../../nuclide-fuzzy-native'); +} + +var _PathWithFileIcon; + +function _load_PathWithFileIcon() { + return _PathWithFileIcon = _interopRequireDefault(require('../../nuclide-ui/PathWithFileIcon')); +} + +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 }; } + +// Imported from nuclide-files-service, which is an apm package, preventing a direct import. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,70 +50,33 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import nuclideUri from 'nuclide-commons/nuclideUri'; -import * as React from 'react'; - -import type {FileResult, Provider} from '../../nuclide-quick-open/lib/types'; - -import {arrayCompact} from 'nuclide-commons/collection'; -import {relativeDate} from 'nuclide-commons/string'; -import {Matcher} from '../../nuclide-fuzzy-native'; -import PathWithFileIcon from '../../nuclide-ui/PathWithFileIcon'; - -// Imported from nuclide-files-service, which is an apm package, preventing a direct import. -type FilePath = string; -type TimeStamp = number; -type FileList = Array<{path: FilePath, timestamp: TimeStamp}>; -type RecentFilesService = { - getRecentFiles(): FileList, - touchFile(path: string): void, -}; - -let _recentFilesService: ?RecentFilesService = null; +let _recentFilesService = null; -function getRecentFilesMatching(query: string): Array { +function getRecentFilesMatching(query) { if (_recentFilesService == null) { return []; } const projectPaths = atom.project.getPaths(); - const openFiles = new Set( - arrayCompact( - atom.workspace.getTextEditors().map(editor => editor.getPath()), - ), - ); - const validRecentFiles = _recentFilesService - .getRecentFiles() - .filter( - result => - !openFiles.has(result.path) && - projectPaths.some( - projectPath => result.path.indexOf(projectPath) !== -1, - ), - ); - const timestamps: Map = new Map(); - const matcher = new Matcher( - validRecentFiles.map(recentFile => { - timestamps.set(recentFile.path, recentFile.timestamp); - return recentFile.path; - }), - ); - return ( - matcher - .match(query, {recordMatchIndexes: true}) - .map(result => ({ - resultType: 'FILE', - path: result.value, - score: result.score, - matchIndexes: result.matchIndexes, - timestamp: timestamps.get(result.value) || 0, - })) - // $FlowIssue Flow seems to type the arguments to `sort` as `FileResult` without `timestamp`. - .sort((a, b) => b.timestamp - a.timestamp) - ); + const openFiles = new Set((0, (_collection || _load_collection()).arrayCompact)(atom.workspace.getTextEditors().map(editor => editor.getPath()))); + const validRecentFiles = _recentFilesService.getRecentFiles().filter(result => !openFiles.has(result.path) && projectPaths.some(projectPath => result.path.indexOf(projectPath) !== -1)); + const timestamps = new Map(); + const matcher = new (_nuclideFuzzyNative || _load_nuclideFuzzyNative()).Matcher(validRecentFiles.map(recentFile => { + timestamps.set(recentFile.path, recentFile.timestamp); + return recentFile.path; + })); + return matcher.match(query, { recordMatchIndexes: true }).map(result => ({ + resultType: 'FILE', + path: result.value, + score: result.score, + matchIndexes: result.matchIndexes, + timestamp: timestamps.get(result.value) || 0 + })) + // $FlowIssue Flow seems to type the arguments to `sort` as `FileResult` without `timestamp`. + .sort((a, b) => b.timestamp - a.timestamp); } const MS_PER_HOUR = 60 * 60 * 1000; @@ -92,70 +100,71 @@ const FALLOFF = 1.1; * | ########################## ] * +----------Time--------------> */ -function opacityForTimestamp(timestamp: number): number { +function opacityForTimestamp(timestamp) { const ageInMS = Date.now() - timestamp; - return Math.min( - 1, - Math.max( - 1 - FALLOFF * Math.log10((ageInMS - SHELF) / MS_PER_DAY + 1), - MIN_OPACITY, - ), - ); + return Math.min(1, Math.max(1 - FALLOFF * Math.log10((ageInMS - SHELF) / MS_PER_DAY + 1), MIN_OPACITY)); } -export const RecentFilesProvider: Provider = { +const RecentFilesProvider = exports.RecentFilesProvider = { providerType: 'GLOBAL', name: 'RecentFilesProvider', debounceDelay: 0, display: { title: 'Recent Files', prompt: 'Search recently opened filenames...', - action: 'nuclide-recent-files-provider:toggle-provider', + action: 'nuclide-recent-files-provider:toggle-provider' }, - async isEligibleForDirectories( - directories: Array, - ): Promise { + async isEligibleForDirectories(directories) { return true; }, - executeQuery( - query: string, - directories: Array, - ): Promise> { + executeQuery(query, directories) { return Promise.resolve(getRecentFilesMatching(query)); }, - getComponentForItem(item: FileResult): React.Element { - const filename = nuclideUri.basename(item.path); + getComponentForItem(item) { + const filename = (_nuclideUri || _load_nuclideUri()).default.basename(item.path); const filePath = item.path.substring(0, item.path.lastIndexOf(filename)); const date = item.timestamp == null ? null : new Date(item.timestamp); // eslint-disable-next-line eqeqeq const datetime = date === null ? '' : date.toLocaleString(); - return ( -
    -
    - - {filePath} - - {filename} -
    -
    - - {date == null ? 'At some point' : relativeDate(date)} - -
    -
    + , style: { opacity: opacityForTimestamp(item.timestamp || Date.now()) }, + title: datetime }, + _react.createElement( + 'div', + { className: 'recent-files-provider-filepath-container' }, + _react.createElement( + (_PathWithFileIcon || _load_PathWithFileIcon()).default, + { + className: 'recent-files-provider-file-path', + path: filename }, + filePath + ), + _react.createElement( + 'span', + { className: 'recent-files-provider-file-name' }, + filename + ) + ), + _react.createElement( + 'div', + { className: 'recent-files-provider-datetime-container' }, + _react.createElement( + 'span', + { className: 'recent-files-provider-datetime-label' }, + date == null ? 'At some point' : (0, (_string || _load_string()).relativeDate)(date) + ) + ) ); - }, + } }; -export function setRecentFilesService(service: RecentFilesService): void { +function setRecentFilesService(service) { _recentFilesService = service; -} +} \ No newline at end of file diff --git a/pkg/nuclide-recent-files-provider/lib/main.js b/pkg/nuclide-recent-files-provider/lib/main.js index aed0c2bfe6..aeeb9ed6ed 100644 --- a/pkg/nuclide-recent-files-provider/lib/main.js +++ b/pkg/nuclide-recent-files-provider/lib/main.js @@ -1,26 +1,30 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {FileResult, Provider} from '../../nuclide-quick-open/lib/types'; -import type RecentFilesService from '../../nuclide-recent-files-service/lib/RecentFilesService'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.registerProvider = registerProvider; +exports.consumeRecentFilesService = consumeRecentFilesService; -import { - RecentFilesProvider, - setRecentFilesService, -} from './RecentFilesProvider'; +var _RecentFilesProvider; -export function registerProvider(): Provider { - return RecentFilesProvider; +function _load_RecentFilesProvider() { + return _RecentFilesProvider = require('./RecentFilesProvider'); } -export function consumeRecentFilesService(service: RecentFilesService): void { - setRecentFilesService(service); -} +function registerProvider() { + return (_RecentFilesProvider || _load_RecentFilesProvider()).RecentFilesProvider; +} /** + * 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. + * + * strict-local + * @format + */ + +function consumeRecentFilesService(service) { + (0, (_RecentFilesProvider || _load_RecentFilesProvider()).setRecentFilesService)(service); +} \ No newline at end of file diff --git a/pkg/nuclide-recent-files-provider/spec/RecentFilesProvider-spec.js b/pkg/nuclide-recent-files-provider/spec/RecentFilesProvider-spec.js deleted file mode 100644 index d218fa5660..0000000000 --- a/pkg/nuclide-recent-files-provider/spec/RecentFilesProvider-spec.js +++ /dev/null @@ -1,212 +0,0 @@ -/** - * 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 - */ - -import type {FileResult, Provider} from '../../nuclide-quick-open/lib/types'; - -import invariant from 'assert'; -import { - RecentFilesProvider, - setRecentFilesService, -} from '../lib/RecentFilesProvider'; -import * as React from 'react'; -import TestUtils from 'react-dom/test-utils'; - -let provider: ?Provider = null; - -const PROJECT_PATH = '/Users/testuser/'; -const PROJECT_PATH2 = '/Users/something_else/'; - -const FILE_PATHS = [ - PROJECT_PATH + 'foo/bla/foo.js', - PROJECT_PATH + 'foo/bla/bar.js', - PROJECT_PATH + 'foo/bla/baz.js', -]; - -const FAKE_RECENT_FILES = FILE_PATHS.map((path, i) => ({ - resultType: 'FILE', - path, - timestamp: 1e8 - i * 1000, - matchIndexes: [], - score: 1, -})); - -const FakeRecentFilesService = { - getRecentFiles: () => FAKE_RECENT_FILES, - touchFile: (path: string) => {}, -}; - -let fakeGetProjectPathsImpl = () => []; -const fakeGetProjectPaths = () => fakeGetProjectPathsImpl(); - -// Per https://github.com/facebook/react/issues/4692#issuecomment-163029873 -class Wrapper extends React.Component<{ - children?: any, -}> { - render(): React.Node { - return
    {this.props.children}
    ; - } -} - -describe('RecentFilesProvider', () => { - beforeEach(() => { - // $FlowIssue - provider = {...RecentFilesProvider}; - setRecentFilesService(FakeRecentFilesService); - spyOn(atom.project, 'getPaths').andCallFake(fakeGetProjectPaths); - }); - - describe('getRecentFiles', () => { - it('returns all recently opened files for currently mounted project directories', () => { - waitsForPromise(async () => { - invariant(provider != null); - fakeGetProjectPathsImpl = () => [PROJECT_PATH]; - invariant(provider.providerType === 'GLOBAL'); - expect(await provider.executeQuery('', [])).toEqual(FAKE_RECENT_FILES); - invariant(provider.providerType === 'GLOBAL'); - fakeGetProjectPathsImpl = () => [PROJECT_PATH, PROJECT_PATH2]; - expect(await provider.executeQuery('', [])).toEqual(FAKE_RECENT_FILES); - }); - }); - - it('does not return files for project directories that are not currently mounted', () => { - waitsForPromise(async () => { - invariant(provider != null); - fakeGetProjectPathsImpl = () => [PROJECT_PATH2]; - invariant(provider.providerType === 'GLOBAL'); - expect(await provider.executeQuery('', [])).toEqual([]); - - fakeGetProjectPathsImpl = () => []; - invariant(provider.providerType === 'GLOBAL'); - expect(await provider.executeQuery('', [])).toEqual([]); - }); - }); - - it('does not return files that are currently open in Atom', () => { - waitsForPromise(async () => { - invariant(provider != null); - fakeGetProjectPathsImpl = () => [PROJECT_PATH]; - const textEditor = await atom.workspace.open(FILE_PATHS[0]); - invariant(provider.providerType === 'GLOBAL'); - expect(await provider.executeQuery('', [])).toEqual([ - FAKE_RECENT_FILES[1], - FAKE_RECENT_FILES[2], - ]); - textEditor.destroy(); - invariant(provider.providerType === 'GLOBAL'); - expect(await provider.executeQuery('', [])).toEqual(FAKE_RECENT_FILES); - }); - }); - - it('filters results according to the query string', () => { - waitsForPromise(async () => { - invariant(provider != null); - fakeGetProjectPathsImpl = () => [PROJECT_PATH]; - // 'foo/bla/foo.js' does not match 'bba', but `bar.js` and `baz.js` do. - invariant(provider.providerType === 'GLOBAL'); - const results = await provider.executeQuery('bba', []); - // Do not cement exact scores or match indices in this test, since they are determined by - // Fuzzy-native. Jasmine 1.3 does not support `jasmine.objectContaining`, - // so we need to check the results manually: - expect(results.length).toEqual(2); - - expect(results[0].path).toEqual(FAKE_RECENT_FILES[1].path); - expect(results[0].timestamp).toEqual(FAKE_RECENT_FILES[1].timestamp); - expect(results[0].matchIndexes).toBeDefined(); - expect(results[0].score).toBeGreaterThan(0); - - expect(results[1].path).toEqual(FAKE_RECENT_FILES[2].path); - expect(results[1].timestamp).toEqual(FAKE_RECENT_FILES[2].timestamp); - expect(results[1].matchIndexes).toBeDefined(); - expect(results[1].score).toBeGreaterThan(0); - }); - }); - }); - - describe('Result rendering', () => { - it('should render complete results', () => { - const timestamp = Date.now(); - const mockResult = { - resultType: 'FILE', - path: '/some/arbitrary/path', - timestamp, - }; - invariant(provider != null); - invariant(provider.getComponentForItem != null); - const reactElement = provider.getComponentForItem(mockResult); - expect(reactElement.props.title).toEqual( - new Date(mockResult.timestamp).toLocaleString(), - ); - const renderedComponent = TestUtils.renderIntoDocument( - {reactElement}, - ); - expect( - TestUtils.scryRenderedDOMComponentsWithClass( - renderedComponent, - 'recent-files-provider-file-name', - ).length, - ).toBe(1); - expect( - TestUtils.scryRenderedDOMComponentsWithClass( - renderedComponent, - 'recent-files-provider-file-path', - ).length, - ).toBe(1); - const datetimeLabels = TestUtils.scryRenderedDOMComponentsWithClass( - renderedComponent, - 'recent-files-provider-datetime-label', - ); - expect(datetimeLabels.length).toBe(1); - }); - - it('should render results with opacity according to their timestamp', () => { - const now = Date.now(); - const HOURS = 60 * 60 * 1000; - const DAYS = 24 * HOURS; - - invariant(provider != null); - invariant(provider.getComponentForItem != null); - expect( - provider.getComponentForItem({ - resultType: 'FILE', - path: '/some/arbitrary/path', - timestamp: now, - }).props.style.opacity, - ).toEqual(1); - - invariant(provider.getComponentForItem != null); - expect( - provider.getComponentForItem({ - resultType: 'FILE', - path: '/some/arbitrary/path', - timestamp: now - 7 * HOURS, - }).props.style.opacity, - ).toEqual(1); - - invariant(provider.getComponentForItem != null); - expect( - provider.getComponentForItem({ - resultType: 'FILE', - path: '/some/arbitrary/path', - timestamp: now - 8 * HOURS, - }).props.style.opacity, - ).not.toBeGreaterThan(1); - - invariant(provider.getComponentForItem != null); - expect( - provider.getComponentForItem({ - resultType: 'FILE', - path: '/some/arbitrary/path', - timestamp: now - 10 * DAYS, - }).props.style.opacity, - ).toEqual(0.6); - }); - }); -}); diff --git a/pkg/nuclide-recent-files-service/lib/RecentFilesService.js b/pkg/nuclide-recent-files-service/lib/RecentFilesService.js index 99f9e53663..ca7cccfa3c 100644 --- a/pkg/nuclide-recent-files-service/lib/RecentFilesService.js +++ b/pkg/nuclide-recent-files-service/lib/RecentFilesService.js @@ -1,3 +1,23 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _lruCache; + +function _load_lruCache() { + return _lruCache = _interopRequireDefault(require('lru-cache')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,62 +25,46 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type { - FileList, - FilePath, - TimeStamp, - RecentFilesSerializedState, -} from '..'; -import type {LRUCache} from 'lru-cache'; - -import LRU from 'lru-cache'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -export default class RecentFilesService { +class RecentFilesService { // Map uses `Map`'s insertion ordering to keep files in order. - _fileList: LRUCache; - _subscriptions: UniversalDisposable; - - constructor(state: ?RecentFilesSerializedState) { - this._fileList = LRU({max: 100}); + constructor(state) { + this._fileList = (0, (_lruCache || _load_lruCache()).default)({ max: 100 }); if (state != null && state.filelist != null) { // Serialized state is in reverse chronological order. Reverse it to insert items correctly. state.filelist.reduceRight((_, fileItem) => { this._fileList.set(fileItem.path, fileItem.timestamp); }, null); } - this._subscriptions = new UniversalDisposable(); - this._subscriptions.add( - atom.workspace.onDidChangeActivePaneItem((item: ?mixed) => { - // Not all `item`s are instances of TextEditor (e.g. the diff view). - // flowlint-next-line sketchy-null-mixed:off - if (!item || typeof item.getPath !== 'function') { - return; - } - const editorPath = item.getPath(); - if (editorPath != null) { - this.touchFile(editorPath); - } - }), - ); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._subscriptions.add(atom.workspace.onDidChangeActivePaneItem(item => { + // Not all `item`s are instances of TextEditor (e.g. the diff view). + // flowlint-next-line sketchy-null-mixed:off + if (!item || typeof item.getPath !== 'function') { + return; + } + const editorPath = item.getPath(); + if (editorPath != null) { + this.touchFile(editorPath); + } + })); } - touchFile(path: string): void { + touchFile(path) { this._fileList.set(path, Date.now()); } /** * Returns a reverse-chronological list of recently opened files. */ - getRecentFiles(): FileList { - return this._fileList.dump().map(({k, v}) => ({ + getRecentFiles() { + return this._fileList.dump().map(({ k, v }) => ({ resultType: 'FILE', path: k, - timestamp: v, + timestamp: v })); } @@ -68,3 +72,4 @@ export default class RecentFilesService { this._subscriptions.dispose(); } } +exports.default = RecentFilesService; \ No newline at end of file diff --git a/pkg/nuclide-recent-files-service/lib/main.js b/pkg/nuclide-recent-files-service/lib/main.js index bca5469372..dc124ba602 100644 --- a/pkg/nuclide-recent-files-service/lib/main.js +++ b/pkg/nuclide-recent-files-service/lib/main.js @@ -1,45 +1,54 @@ -/** - * 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 - */ - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import RecentFilesService from './RecentFilesService'; - -export type FilePath = string; -export type TimeStamp = number; -export type FileList = Array<{path: FilePath, timestamp: TimeStamp}>; -export type RecentFilesSerializedState = {filelist?: FileList}; +'use strict'; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _RecentFilesService; + +function _load_RecentFilesService() { + return _RecentFilesService = _interopRequireDefault(require('./RecentFilesService')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class Activation { - _subscriptions: UniversalDisposable; - _service: RecentFilesService; - constructor(state: ?RecentFilesSerializedState) { - this._service = new RecentFilesService(state); - this._subscriptions = new UniversalDisposable(this._service); + constructor(state) { + this._service = new (_RecentFilesService || _load_RecentFilesService()).default(state); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(this._service); } - provideRecentFilesService(): RecentFilesService { + provideRecentFilesService() { return this._service; } - serialize(): Object { + serialize() { return { - filelist: this._service.getRecentFiles(), + filelist: this._service.getRecentFiles() }; } dispose() { this._subscriptions.dispose(); } -} - -createPackage(module.exports, Activation); +} /** + * 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. + * + * + * @format + */ + +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-recent-files-service/spec/RecentFilesService-spec.js b/pkg/nuclide-recent-files-service/spec/RecentFilesService-spec.js deleted file mode 100644 index 90700c76fb..0000000000 --- a/pkg/nuclide-recent-files-service/spec/RecentFilesService-spec.js +++ /dev/null @@ -1,126 +0,0 @@ -/** - * 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 - */ - -import invariant from 'assert'; -import fsPromise from 'nuclide-commons/fsPromise'; - -import RecentFilesService from '../lib/RecentFilesService'; - -describe('RecentFilesService', () => { - let filePath1; - let filePath2; - let filePath3; - let recentFilesService: any; - - beforeEach(() => { - recentFilesService = new RecentFilesService(); - - waitsForPromise(async () => { - [filePath1, filePath2, filePath3] = await Promise.all([ - fsPromise.tempfile('1'), - fsPromise.tempfile('2'), - fsPromise.tempfile('3'), - ]); - }); - }); - - describe('getRecentFiles', () => { - it('returns a reverse-chronological list of recently opened files', () => { - waitsForPromise(async () => { - let mostRecentFiles; - let previousTimestamp = Date.now(); - expect(recentFilesService.getRecentFiles().length).toEqual(0); - - await atom.workspace.open(filePath1); - mostRecentFiles = recentFilesService.getRecentFiles(); - expect(mostRecentFiles.length).toEqual(1); - expect(mostRecentFiles[0].path.endsWith(filePath1)).toBe(true); - expect(mostRecentFiles[0].timestamp).toBe(previousTimestamp); - previousTimestamp = mostRecentFiles[0].timestamp; - - await atom.workspace.open(filePath2); - mostRecentFiles = recentFilesService.getRecentFiles(); - expect(mostRecentFiles.length).toEqual(2); - expect(mostRecentFiles[0].path.endsWith(filePath2)).toBe(true); - expect(mostRecentFiles[0].timestamp).toBe(previousTimestamp); - - previousTimestamp = mostRecentFiles[0].timestamp; - await atom.workspace.open(filePath3); - mostRecentFiles = recentFilesService.getRecentFiles(); - expect(mostRecentFiles.length).toEqual(3); - expect(mostRecentFiles[0].path.endsWith(filePath3)).toBe(true); - expect(mostRecentFiles[0].timestamp).toBe(previousTimestamp); - }); - }); - - it('returns paths and timestamps of recently opened files', () => { - waitsForPromise(async () => { - await atom.workspace.open(filePath1); - const recentFiles = recentFilesService.getRecentFiles(); - const mostRecentFile = recentFiles[0]; - expect(Object.keys(mostRecentFile).length).toEqual(3); - expect(typeof mostRecentFile.timestamp === 'number').toBe(true); - expect(mostRecentFile.path.endsWith(filePath1)).toBe(true); - }); - }); - - it('resets the order of previously tracked files when they are touched', () => { - waitsForPromise(async () => { - let mostRecentFiles; - expect(recentFilesService.getRecentFiles().length).toEqual(0); - - await atom.workspace.open(filePath1); - mostRecentFiles = recentFilesService.getRecentFiles(); - expect(mostRecentFiles.length).toEqual(1); - expect(mostRecentFiles[0].path.endsWith(filePath1)).toBe(true); - - await atom.workspace.open(filePath2); - mostRecentFiles = recentFilesService.getRecentFiles(); - expect(mostRecentFiles.length).toEqual(2); - expect(mostRecentFiles[0].path.endsWith(filePath2)).toBe(true); - - await atom.workspace.open(filePath1); - mostRecentFiles = recentFilesService.getRecentFiles(); - expect(mostRecentFiles.length).toEqual(2); - expect(mostRecentFiles[0].path.endsWith(filePath1)).toBe(true); - expect(mostRecentFiles[1].path.endsWith(filePath2)).toBe(true); - - await atom.workspace.open(filePath2); - mostRecentFiles = recentFilesService.getRecentFiles(); - expect(mostRecentFiles.length).toEqual(2); - expect(mostRecentFiles[0].path.endsWith(filePath2)).toBe(true); - expect(mostRecentFiles[1].path.endsWith(filePath1)).toBe(true); - }); - }); - }); - - describe('initialization and de-serialization', () => { - it('correctly restores itself from serialized state', () => { - const serializedState = { - filelist: [ - {resultType: 'FILE', path: filePath1, timestamp: 100}, - {resultType: 'FILE', path: filePath2, timestamp: 200}, - {resultType: 'FILE', path: filePath3, timestamp: 300}, - ], - }; - const restoredRecentFilesService = new RecentFilesService( - serializedState, - ); - const mostRecentFiles = restoredRecentFilesService.getRecentFiles(); - expect(mostRecentFiles).toEqual(serializedState.filelist); - }); - - it('starts out empty if no serialized state is passed to the constructor', () => { - invariant(recentFilesService); - expect(recentFilesService.getRecentFiles().length).toEqual(0); - }); - }); -}); diff --git a/pkg/nuclide-refactorizer/__atom_tests__/refactorEpics-test.js b/pkg/nuclide-refactorizer/__atom_tests__/refactorEpics-test.js index 6c2938560a..84bbb4416e 100644 --- a/pkg/nuclide-refactorizer/__atom_tests__/refactorEpics-test.js +++ b/pkg/nuclide-refactorizer/__atom_tests__/refactorEpics-test.js @@ -1,113 +1,98 @@ -/** - * 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 - */ +'use strict'; -import fs from 'fs'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {generateFixture} from 'nuclide-commons/test-helpers'; -import {applyRefactoring} from '../lib/refactorEpics'; -import path from 'path'; +var _fs = _interopRequireDefault(require('fs')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _testHelpers; + +function _load_testHelpers() { + return _testHelpers = require('../../../modules/nuclide-commons/test-helpers'); +} + +var _refactorEpics; + +function _load_refactorEpics() { + return _refactorEpics = require('../lib/refactorEpics'); +} + +var _path = _interopRequireDefault(require('path')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } describe('applyRefactoring', () => { let testDir; let testFile1; let testFile2; beforeEach(async () => { - const fixturesPath = path.resolve(__dirname, '../__mocks__/fixtures'); + const fixturesPath = _path.default.resolve(__dirname, '../__mocks__/fixtures'); atom.project.setPaths([fixturesPath]); - testDir = await generateFixture( - 'refactoring', - new Map([['test1.txt', 'abcdefghi'], ['test2.txt', '123456789']]), - ); - testFile1 = nuclideUri.join(testDir, 'test1.txt'); - testFile2 = nuclideUri.join(testDir, 'test2.txt'); + testDir = await (0, (_testHelpers || _load_testHelpers()).generateFixture)('refactoring', new Map([['test1.txt', 'abcdefghi'], ['test2.txt', '123456789']])); + testFile1 = (_nuclideUri || _load_nuclideUri()).default.join(testDir, 'test1.txt'); + testFile2 = (_nuclideUri || _load_nuclideUri()).default.join(testDir, 'test2.txt'); }); it('is able to apply refactors to external files', async () => { - const actions = await applyRefactoring({ + const actions = await (0, (_refactorEpics || _load_refactorEpics()).applyRefactoring)({ type: 'apply', payload: { response: { type: 'external-edit', - edits: new Map([ - [ - testFile1, - [ - { - startOffset: 0, - endOffset: 3, - oldText: 'abc', - newText: 'aaa', - }, - { - startOffset: 3, - endOffset: 6, - oldText: 'def', - newText: 'ddd', - }, - ], - ], - [ - testFile2, - [ - { - startOffset: 6, - endOffset: 9, - oldText: '789', - newText: '000', - }, - ], - ], - ]), - }, - }, - }) - .toArray() - .toPromise(); + edits: new Map([[testFile1, [{ + startOffset: 0, + endOffset: 3, + oldText: 'abc', + newText: 'aaa' + }, { + startOffset: 3, + endOffset: 6, + oldText: 'def', + newText: 'ddd' + }]], [testFile2, [{ + startOffset: 6, + endOffset: 9, + oldText: '789', + newText: '000' + }]]]) + } + } + }).toArray().toPromise(); const message = 'Applying edits...'; - expect(actions).toEqual([ - {type: 'progress', payload: {message, value: 0, max: 2}}, - {type: 'progress', payload: {message, value: 1, max: 2}}, - {type: 'progress', payload: {message, value: 2, max: 2}}, - {type: 'close'}, - ]); - expect(fs.readFileSync(testFile1, 'utf8')).toBe('aaadddghi'); - expect(fs.readFileSync(testFile2, 'utf8')).toBe('123456000'); + expect(actions).toEqual([{ type: 'progress', payload: { message, value: 0, max: 2 } }, { type: 'progress', payload: { message, value: 1, max: 2 } }, { type: 'progress', payload: { message, value: 2, max: 2 } }, { type: 'close' }]); + expect(_fs.default.readFileSync(testFile1, 'utf8')).toBe('aaadddghi'); + expect(_fs.default.readFileSync(testFile2, 'utf8')).toBe('123456000'); }); it('errors on mismatch', async () => { - const actions = await applyRefactoring({ + const actions = await (0, (_refactorEpics || _load_refactorEpics()).applyRefactoring)({ type: 'apply', payload: { response: { type: 'external-edit', - edits: new Map([ - [ - testFile1, - [ - { - startOffset: 0, - endOffset: 3, - oldText: 'abb', - newText: 'aaa', - }, - ], - ], - ]), - }, - }, - }) - .toPromise() - .catch(err => err); + edits: new Map([[testFile1, [{ + startOffset: 0, + endOffset: 3, + oldText: 'abb', + newText: 'aaa' + }]]]) + } + } + }).toPromise().catch(err => err); expect(actions instanceof Error).toBe(true); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-refactorizer/__atom_tests__/refactorStore-test.js b/pkg/nuclide-refactorizer/__atom_tests__/refactorStore-test.js index 545444d131..69f30fcbb9 100644 --- a/pkg/nuclide-refactorizer/__atom_tests__/refactorStore-test.js +++ b/pkg/nuclide-refactorizer/__atom_tests__/refactorStore-test.js @@ -1,3 +1,50 @@ +'use strict'; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _atom = require('atom'); + +var _ProviderRegistry; + +function _load_ProviderRegistry() { + return _ProviderRegistry = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/ProviderRegistry')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _testHelpers; + +function _load_testHelpers() { + return _testHelpers = require('../../../modules/nuclide-commons/test-helpers'); +} + +var _refactorStore; + +function _load_refactorStore() { + return _refactorStore = require('../lib/refactorStore'); +} + +var _refactorActions; + +function _load_refactorActions() { + return _refactorActions = _interopRequireWildcard(require('../lib/refactorActions')); +} + +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 }; } + +// sentinel value /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,110 +52,75 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type { - AvailableRefactoring, - FreeformRefactorRequest, - RefactorProvider, - RefactorRequest, - RefactorResponse, - RenameRefactoring, - RenameRequest, -} from '..'; -import type {Store, RefactorState} from '../lib/types'; - -import {Observable, BehaviorSubject, Subject} from 'rxjs'; -import {Range, Point} from 'atom'; -import invariant from 'assert'; - -import ProviderRegistry from 'nuclide-commons-atom/ProviderRegistry'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Deferred, nextTick} from 'nuclide-commons/promise'; -import {expectObservableToStartWith} from 'nuclide-commons/test-helpers'; - -import {getStore, getErrors} from '../lib/refactorStore'; -import * as Actions from '../lib/refactorActions'; - -// sentinel value const NO_ERROR = {}; // This tests the integration of the reducers and epics describe('refactorStore', () => { - let store: Store = (null: any); - let providers: ProviderRegistry = (null: any); - let stateStream: Observable; - let currentState: BehaviorSubject; - - let provider: RefactorProvider = (null: any); - let refactoringsAtPointReturn: Promise< - Array, - > = (null: any); - let refactorReturn: Observable = (null: any); - - let lastError: mixed = null; - function expectNoUncaughtErrors(): void { + let store = null; + let providers = null; + let stateStream; + let currentState; + + let provider = null; + let refactoringsAtPointReturn = null; + let refactorReturn = null; + + let lastError = null; + function expectNoUncaughtErrors() { // expect(lastError).toBe(NO_ERROR) results in 'obj.hasOwnProperty is not a function' in some // cases... expect(lastError === NO_ERROR).toBeTruthy(); } - let errorSubscription: rxjs$ISubscription = (null: any); + let errorSubscription = null; - const waitForPhase = (phaseType: string) => { - return currentState - .filter(s => { - return s.type === 'open' && s.phase.type === phaseType; - }) - .first() - .toPromise(); + const waitForPhase = phaseType => { + return currentState.filter(s => { + return s.type === 'open' && s.phase.type === phaseType; + }).first().toPromise(); }; const waitForClose = () => { - return currentState - .filter(s => s.type === 'closed') - .first() - .toPromise(); + return currentState.filter(s => s.type === 'closed').first().toPromise(); }; beforeEach(() => { lastError = NO_ERROR; - errorSubscription = getErrors().subscribe(error => { + errorSubscription = (0, (_refactorStore || _load_refactorStore()).getErrors)().subscribe(error => { lastError = error; }); provider = { grammarScopes: ['text.plain', 'text.plain.null-grammar'], priority: 1, - refactorings( - editor: atom$TextEditor, - range: atom$Range, - ): Promise> { + refactorings(editor, range) { return refactoringsAtPointReturn; }, - refactor(request: RefactorRequest): Observable { + refactor(request) { return refactorReturn; - }, + } }; // TODO spy on the provider and call through refactoringsAtPointReturn = Promise.resolve([]); - refactorReturn = Observable.empty(); + refactorReturn = _rxjsBundlesRxMinJs.Observable.empty(); - providers = new ProviderRegistry(); - store = getStore(providers); + providers = new (_ProviderRegistry || _load_ProviderRegistry()).default(); + store = (0, (_refactorStore || _load_refactorStore()).getStore)(providers); // $FlowIssue no symbol support - const stream: Observable = Observable.from(store); + const stream = _rxjsBundlesRxMinJs.Observable.from(store); stateStream = stream - // Filter out duplicate states. This happens during error handling, for example. - .distinctUntilChanged() - // publishReplay() and connect means it will - .publishReplay(); + // Filter out duplicate states. This happens during error handling, for example. + .distinctUntilChanged() + // publishReplay() and connect means it will + .publishReplay(); stateStream.connect(); // stateStream will replay, but it's also useful to be able to wait for particular states before // proceeding. - currentState = new BehaviorSubject(store.getState()); + currentState = new _rxjsBundlesRxMinJs.BehaviorSubject(store.getState()); stateStream.subscribe(currentState); }); @@ -117,26 +129,22 @@ describe('refactorStore', () => { }); it('starts closed', () => { - expect(store.getState()).toEqual({type: 'closed'}); + expect(store.getState()).toEqual({ type: 'closed' }); }); it('handles a missing editor', async () => { await (async () => { - store.dispatch(Actions.open('generic')); - await expectObservableToStartWith(stateStream, [ - {type: 'closed'}, - { - type: 'open', - ui: 'generic', - phase: {type: 'get-refactorings'}, - }, - {type: 'closed'}, - ]); + store.dispatch((_refactorActions || _load_refactorActions()).open('generic')); + await (0, (_testHelpers || _load_testHelpers()).expectObservableToStartWith)(stateStream, [{ type: 'closed' }, { + type: 'open', + ui: 'generic', + phase: { type: 'get-refactorings' } + }, { type: 'closed' }]); })(); }); describe('with an open text editor', () => { - let openEditor: atom$TextEditor = (null: any); + let openEditor = null; beforeEach(async () => { await (async () => { openEditor = await atom.workspace.open(TEST_FILE); @@ -144,16 +152,12 @@ describe('refactorStore', () => { }); it('handles a missing provider', async () => { await (async () => { - store.dispatch(Actions.open('generic')); - await expectObservableToStartWith(stateStream, [ - {type: 'closed'}, - { - type: 'open', - ui: 'generic', - phase: {type: 'get-refactorings'}, - }, - {type: 'closed'}, - ]); + store.dispatch((_refactorActions || _load_refactorActions()).open('generic')); + await (0, (_testHelpers || _load_testHelpers()).expectObservableToStartWith)(stateStream, [{ type: 'closed' }, { + type: 'open', + ui: 'generic', + phase: { type: 'get-refactorings' } + }, { type: 'closed' }]); })(); }); @@ -165,23 +169,23 @@ describe('refactorStore', () => { it('runs the refactor', async () => { await (async () => { refactoringsAtPointReturn = Promise.resolve([TEST_FILE_RENAME]); - refactorReturn = Observable.of({ + refactorReturn = _rxjsBundlesRxMinJs.Observable.of({ type: 'edit', - edits: new Map([[TEST_FILE, TEST_FILE_EDITS]]), + edits: new Map([[TEST_FILE, TEST_FILE_EDITS]]) }); - store.dispatch(Actions.open('generic')); + store.dispatch((_refactorActions || _load_refactorActions()).open('generic')); await waitForPhase('pick'); - store.dispatch(Actions.pickedRefactor(TEST_FILE_RENAME)); + store.dispatch((_refactorActions || _load_refactorActions()).pickedRefactor(TEST_FILE_RENAME)); await waitForPhase('rename'); - const rename: RenameRequest = { + const rename = { kind: 'rename', originalPoint: TEST_FILE_POINT, symbolAtPoint: TEST_FILE_SYMBOL_AT_POINT, editor: openEditor, - newName: 'bar', + newName: 'bar' }; - store.dispatch(Actions.execute(provider, rename)); + store.dispatch((_refactorActions || _load_refactorActions()).execute(provider, rename)); await waitForClose(); expect(openEditor.getText()).toEqual('bar\nbar\nbar\n'); })(); @@ -190,60 +194,56 @@ describe('refactorStore', () => { it('does not allow refactoring of an unsaved file', async () => { await (async () => { await atom.workspace.open(); - store.dispatch(Actions.open('generic')); - await expectObservableToStartWith(stateStream, [ - {type: 'closed'}, - { - type: 'open', - ui: 'generic', - phase: {type: 'get-refactorings'}, - }, - {type: 'closed'}, - ]); - await nextTick(); + store.dispatch((_refactorActions || _load_refactorActions()).open('generic')); + await (0, (_testHelpers || _load_testHelpers()).expectObservableToStartWith)(stateStream, [{ type: 'closed' }, { + type: 'open', + ui: 'generic', + phase: { type: 'get-refactorings' } + }, { type: 'closed' }]); + await (0, (_promise || _load_promise()).nextTick)(); expectNoUncaughtErrors(); })(); }); it('tolerates a provider returning available refactorings after a close action', async () => { await (async () => { - const deferred = new Deferred(); + const deferred = new (_promise || _load_promise()).Deferred(); refactoringsAtPointReturn = deferred.promise; - store.dispatch(Actions.open('generic')); + store.dispatch((_refactorActions || _load_refactorActions()).open('generic')); await waitForPhase('get-refactorings'); - store.dispatch(Actions.close()); + store.dispatch((_refactorActions || _load_refactorActions()).close()); await waitForClose(); deferred.resolve([]); - await nextTick(); + await (0, (_promise || _load_promise()).nextTick)(); expectNoUncaughtErrors(); })(); }); it('tolerates a provider returning refactor results after a close action', async () => { await (async () => { - const deferred = new Subject(); + const deferred = new _rxjsBundlesRxMinJs.Subject(); refactoringsAtPointReturn = Promise.resolve([TEST_FILE_RENAME]); refactorReturn = deferred; - store.dispatch(Actions.open('generic')); + store.dispatch((_refactorActions || _load_refactorActions()).open('generic')); await waitForPhase('pick'); - store.dispatch(Actions.pickedRefactor(TEST_FILE_RENAME)); + store.dispatch((_refactorActions || _load_refactorActions()).pickedRefactor(TEST_FILE_RENAME)); await waitForPhase('rename'); - const rename: RenameRequest = { + const rename = { kind: 'rename', originalPoint: TEST_FILE_POINT, symbolAtPoint: TEST_FILE_SYMBOL_AT_POINT, editor: openEditor, - newName: 'bar', + newName: 'bar' }; - store.dispatch(Actions.execute(provider, rename)); + store.dispatch((_refactorActions || _load_refactorActions()).execute(provider, rename)); await waitForPhase('execute'); - store.dispatch(Actions.close()); + store.dispatch((_refactorActions || _load_refactorActions()).close()); await waitForClose(); deferred.next({ type: 'edit', - edits: new Map([[TEST_FILE, TEST_FILE_EDITS]]), + edits: new Map([[TEST_FILE, TEST_FILE_EDITS]]) }); - await nextTick(); + await (0, (_promise || _load_promise()).nextTick)(); expectNoUncaughtErrors(); })(); }); @@ -252,10 +252,10 @@ describe('refactorStore', () => { it('tolerates a provider throwing in refactoringsAtPoint', async () => { await (async () => { refactoringsAtPointReturn = Promise.reject(new Error()); - store.dispatch(Actions.open('generic')); + store.dispatch((_refactorActions || _load_refactorActions()).open('generic')); await waitForPhase('get-refactorings'); await waitForClose(); - await nextTick(); + await (0, (_promise || _load_promise()).nextTick)(); expectNoUncaughtErrors(); })(); }); @@ -264,21 +264,21 @@ describe('refactorStore', () => { it('tolerates a provider throwing in refactor', async () => { await (async () => { refactoringsAtPointReturn = Promise.resolve([TEST_FILE_RENAME]); - refactorReturn = Observable.throw(new Error()); - store.dispatch(Actions.open('generic')); + refactorReturn = _rxjsBundlesRxMinJs.Observable.throw(new Error()); + store.dispatch((_refactorActions || _load_refactorActions()).open('generic')); await waitForPhase('pick'); - store.dispatch(Actions.pickedRefactor(TEST_FILE_RENAME)); + store.dispatch((_refactorActions || _load_refactorActions()).pickedRefactor(TEST_FILE_RENAME)); await waitForPhase('rename'); - const rename: RenameRequest = { + const rename = { kind: 'rename', originalPoint: TEST_FILE_POINT, symbolAtPoint: TEST_FILE_SYMBOL_AT_POINT, editor: openEditor, - newName: 'bar', + newName: 'bar' }; - store.dispatch(Actions.execute(provider, rename)); + store.dispatch((_refactorActions || _load_refactorActions()).execute(provider, rename)); await waitForClose(); - await nextTick(); + await (0, (_promise || _load_promise()).nextTick)(); expectNoUncaughtErrors(); })(); }); @@ -286,21 +286,21 @@ describe('refactorStore', () => { it('tolerates a provider returning empty from refactor', async () => { await (async () => { refactoringsAtPointReturn = Promise.resolve([TEST_FILE_RENAME]); - refactorReturn = Observable.empty(); - store.dispatch(Actions.open('generic')); + refactorReturn = _rxjsBundlesRxMinJs.Observable.empty(); + store.dispatch((_refactorActions || _load_refactorActions()).open('generic')); await waitForPhase('pick'); - store.dispatch(Actions.pickedRefactor(TEST_FILE_RENAME)); + store.dispatch((_refactorActions || _load_refactorActions()).pickedRefactor(TEST_FILE_RENAME)); await waitForPhase('rename'); - const rename: RenameRequest = { + const rename = { kind: 'rename', originalPoint: TEST_FILE_POINT, symbolAtPoint: TEST_FILE_SYMBOL_AT_POINT, editor: openEditor, - newName: 'bar', + newName: 'bar' }; - store.dispatch(Actions.execute(provider, rename)); + store.dispatch((_refactorActions || _load_refactorActions()).execute(provider, rename)); await waitForClose(); - await nextTick(); + await (0, (_promise || _load_promise()).nextTick)(); expectNoUncaughtErrors(); })(); }); @@ -308,32 +308,30 @@ describe('refactorStore', () => { it('fails gracefully when the edits do not apply', async () => { await (async () => { refactoringsAtPointReturn = Promise.resolve([TEST_FILE_RENAME]); - const edits = [ - { - oldRange: new Range([0, 0], [0, 3]), - // intentionally not 'foo' in order to trigger a conflict when we attempt to apply this - // edit. - oldText: 'foz', - newText: 'bar', - }, - ]; - refactorReturn = Observable.of({ + const edits = [{ + oldRange: new _atom.Range([0, 0], [0, 3]), + // intentionally not 'foo' in order to trigger a conflict when we attempt to apply this + // edit. + oldText: 'foz', + newText: 'bar' + }]; + refactorReturn = _rxjsBundlesRxMinJs.Observable.of({ type: 'edit', - edits: new Map([[TEST_FILE, edits]]), + edits: new Map([[TEST_FILE, edits]]) }); - store.dispatch(Actions.open('generic')); + store.dispatch((_refactorActions || _load_refactorActions()).open('generic')); await waitForPhase('pick'); - store.dispatch(Actions.pickedRefactor(TEST_FILE_RENAME)); + store.dispatch((_refactorActions || _load_refactorActions()).pickedRefactor(TEST_FILE_RENAME)); await waitForPhase('rename'); - const rename: RenameRequest = { + const rename = { kind: 'rename', originalPoint: TEST_FILE_POINT, symbolAtPoint: TEST_FILE_SYMBOL_AT_POINT, editor: openEditor, - newName: 'bar', + newName: 'bar' }; - store.dispatch(Actions.execute(provider, rename)); + store.dispatch((_refactorActions || _load_refactorActions()).execute(provider, rename)); // TODO should display an error somewhere await waitForClose(); expect(openEditor.getText()).toEqual('foo\nbar\nfoo\n'); @@ -342,27 +340,25 @@ describe('refactorStore', () => { // sure that we can apply the entire refactoring transactionally. this means if something // goes wrong we need to roll back the rest. - await nextTick(); + await (0, (_promise || _load_promise()).nextTick)(); expectNoUncaughtErrors(); })(); }); }); describe('with a freeform provider', () => { - const refactoring: AvailableRefactoring = { + const refactoring = { kind: 'freeform', id: 'asyncify', name: 'Asyncify', description: 'Convert this method to async', - range: new Range([0, 0], [0, 0]), - arguments: [ - { - description: 'New name for method', - name: 'new_name', - type: 'string', - default: 'genKittensAndRainbows', - }, - ], + range: new _atom.Range([0, 0], [0, 0]), + arguments: [{ + description: 'New name for method', + name: 'new_name', + type: 'string', + default: 'genKittensAndRainbows' + }] }; beforeEach(() => { @@ -372,45 +368,53 @@ describe('refactorStore', () => { async refactorings() { return [refactoring]; }, - refactor(request: RefactorRequest) { - invariant(request.kind === 'freeform'); - const edits = [ - { - oldRange: new Range([0, 0], [0, 3]), - oldText: 'foo', - newText: String(request.arguments.get('new_name')), - }, - ]; - return Observable.of({ + refactor(request) { + if (!(request.kind === 'freeform')) { + throw new Error('Invariant violation: "request.kind === \'freeform\'"'); + } + + const edits = [{ + oldRange: new _atom.Range([0, 0], [0, 3]), + oldText: 'foo', + newText: String(request.arguments.get('new_name')) + }]; + return _rxjsBundlesRxMinJs.Observable.of({ type: 'edit', - edits: new Map([[TEST_FILE, edits]]), + edits: new Map([[TEST_FILE, edits]]) }); - }, + } }; providers.addProvider(provider); }); it('runs the refactor', async () => { await (async () => { - store.dispatch(Actions.open('generic')); + store.dispatch((_refactorActions || _load_refactorActions()).open('generic')); await waitForPhase('pick'); - store.dispatch(Actions.pickedRefactor(refactoring)); + store.dispatch((_refactorActions || _load_refactorActions()).pickedRefactor(refactoring)); await waitForPhase('freeform'); const state = store.getState(); - invariant(state.type === 'open'); - invariant(state.phase.type === 'freeform'); + + if (!(state.type === 'open')) { + throw new Error('Invariant violation: "state.type === \'open\'"'); + } + + if (!(state.phase.type === 'freeform')) { + throw new Error('Invariant violation: "state.phase.type === \'freeform\'"'); + } + expect(state.phase.refactoring).toEqual(refactoring); - const asyncify: FreeformRefactorRequest = { + const asyncify = { kind: 'freeform', - originalRange: new Range(TEST_FILE_POINT, TEST_FILE_POINT), + originalRange: new _atom.Range(TEST_FILE_POINT, TEST_FILE_POINT), editor: openEditor, id: 'asyncify', - range: new Range([0, 0], [0, 0]), - arguments: new Map([['new_name', 'test']]), + range: new _atom.Range([0, 0], [0, 0]), + arguments: new Map([['new_name', 'test']]) }; - store.dispatch(Actions.execute(provider, asyncify)); + store.dispatch((_refactorActions || _load_refactorActions()).execute(provider, asyncify)); await waitForClose(); expect(openEditor.getText()).toEqual('test\nbar\nfoo\n'); })(); @@ -421,29 +425,22 @@ describe('refactorStore', () => { // This is all just dummy data, so I'm keeping it down here to avoid drawing attention to it over // the important test logic. -const TEST_FILE = nuclideUri.join( - __dirname, - '../__mocks__/fixtures', - 'refactor-fixture.txt', -); -const TEST_FILE_POINT = new Point(0, 1); +const TEST_FILE = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures', 'refactor-fixture.txt'); +const TEST_FILE_POINT = new _atom.Point(0, 1); const TEST_FILE_SYMBOL_AT_POINT = { text: 'foo', - range: new Range([0, 0], [0, 3]), + range: new _atom.Range([0, 0], [0, 3]) }; -const TEST_FILE_RENAME: RenameRefactoring = { +const TEST_FILE_RENAME = { kind: 'rename', - symbolAtPoint: TEST_FILE_SYMBOL_AT_POINT, + symbolAtPoint: TEST_FILE_SYMBOL_AT_POINT }; -const TEST_FILE_EDITS = [ - { - oldRange: new Range([0, 0], [0, 3]), - oldText: 'foo', - newText: 'bar', - }, - { - oldRange: new Range([2, 0], [2, 3]), - oldText: 'foo', - newText: 'bar', - }, -]; +const TEST_FILE_EDITS = [{ + oldRange: new _atom.Range([0, 0], [0, 3]), + oldText: 'foo', + newText: 'bar' +}, { + oldRange: new _atom.Range([2, 0], [2, 3]), + oldText: 'foo', + newText: 'bar' +}]; \ No newline at end of file diff --git a/pkg/nuclide-refactorizer/lib/components/ConfirmRefactorComponent.js b/pkg/nuclide-refactorizer/lib/components/ConfirmRefactorComponent.js index 479461c604..6c49fcf027 100644 --- a/pkg/nuclide-refactorizer/lib/components/ConfirmRefactorComponent.js +++ b/pkg/nuclide-refactorizer/lib/components/ConfirmRefactorComponent.js @@ -1,90 +1,143 @@ -/** - * 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 strict-local - * @format - */ - -import type {Store, ConfirmPhase} from '../types'; -import type {RefactorEditResponse} from '../rpc-types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import * as React from 'react'; - -import {getAtomProjectRelativePath} from 'nuclide-commons-atom/projects'; -import {pluralize} from 'nuclide-commons/string'; -import {Button, ButtonTypes} from 'nuclide-commons-ui/Button'; -import {Icon} from 'nuclide-commons-ui/Icon'; -import {TreeList, TreeItem} from 'nuclide-commons-ui/Tree'; -import PathWithFileIcon from '../../../nuclide-ui/PathWithFileIcon'; - -import * as Actions from '../refactorActions'; - -type Props = { - phase: ConfirmPhase, - store: Store, -}; - -export class ConfirmRefactorComponent extends React.PureComponent { - _execute = () => { - this.props.store.dispatch(Actions.apply(this.props.phase.response)); - }; - - _diffPreview = (uri: NuclideUri, response: RefactorEditResponse) => { - this.props.store.dispatch( - Actions.loadDiffPreview(this.props.phase, uri, response), - ); - }; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ConfirmRefactorComponent = undefined; + +var _react = _interopRequireWildcard(require('react')); + +var _projects; + +function _load_projects() { + return _projects = require('../../../../modules/nuclide-commons-atom/projects'); +} + +var _string; + +function _load_string() { + return _string = require('../../../../modules/nuclide-commons/string'); +} + +var _Button; + +function _load_Button() { + return _Button = require('../../../../modules/nuclide-commons-ui/Button'); +} + +var _Icon; + +function _load_Icon() { + return _Icon = require('../../../../modules/nuclide-commons-ui/Icon'); +} + +var _Tree; + +function _load_Tree() { + return _Tree = require('../../../../modules/nuclide-commons-ui/Tree'); +} + +var _PathWithFileIcon; + +function _load_PathWithFileIcon() { + return _PathWithFileIcon = _interopRequireDefault(require('../../../nuclide-ui/PathWithFileIcon')); +} + +var _refactorActions; + +function _load_refactorActions() { + return _refactorActions = _interopRequireWildcard(require('../refactorActions')); +} + +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 ConfirmRefactorComponent extends _react.PureComponent { + constructor(...args) { + var _temp; + + return _temp = super(...args), this._execute = () => { + this.props.store.dispatch((_refactorActions || _load_refactorActions()).apply(this.props.phase.response)); + }, this._diffPreview = (uri, response) => { + this.props.store.dispatch((_refactorActions || _load_refactorActions()).loadDiffPreview(this.props.phase, uri, response)); + }, _temp; + } - render(): React.Node { - const {response} = this.props.phase; + render() { + const { response } = this.props.phase; const editCount = new Map(); for (const [path, edits] of response.edits) { editCount.set(path, (editCount.get(path) || 0) + edits.length); } // TODO: display actual diff output here. - return ( -
    - This refactoring will affect {editCount.size} files. Confirm? -
    - - {Array.from(editCount).map(([path, count]) => ( - - - { - this._diffPreview(path, response); - }} - icon="diff" - /> - - {getAtomProjectRelativePath(path)} - {' '} - ({count} {pluralize('change', count)}) - - - ))} - -
    -
    - -
    -
    + className: 'nuclide-refactorizer-confirm-list native-key-bindings', + tabIndex: -1 }, + _react.createElement( + (_Tree || _load_Tree()).TreeList, + null, + Array.from(editCount).map(([path, count]) => _react.createElement( + (_Tree || _load_Tree()).TreeItem, + { key: path }, + _react.createElement( + (_PathWithFileIcon || _load_PathWithFileIcon()).default, + { + className: 'nuclide-refactorizer-confirm-list-item', + path: path }, + _react.createElement((_Icon || _load_Icon()).Icon, { + className: 'nuclide-refactorizer-diff-preview-icon', + onClick: () => { + this._diffPreview(path, response); + }, + icon: 'diff' + }), + _react.createElement( + 'span', + { className: 'nuclide-refactorizer-confirm-list-path' }, + (0, (_projects || _load_projects()).getAtomProjectRelativePath)(path) + ), + ' ', + '(', + count, + ' ', + (0, (_string || _load_string()).pluralize)('change', count), + ')' + ) + )) + ) + ), + _react.createElement( + 'div', + { style: { display: 'flex', justifyContent: 'flex-end' } }, + _react.createElement( + (_Button || _load_Button()).Button, + { + buttonType: (_Button || _load_Button()).ButtonTypes.PRIMARY, + onClick: this._execute, + autoFocus: true }, + 'Confirm' + ) + ) ); } } +exports.ConfirmRefactorComponent = ConfirmRefactorComponent; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-refactorizer/lib/components/DiffPreviewComponent.js b/pkg/nuclide-refactorizer/lib/components/DiffPreviewComponent.js index b688f56741..07f4484774 100644 --- a/pkg/nuclide-refactorizer/lib/components/DiffPreviewComponent.js +++ b/pkg/nuclide-refactorizer/lib/components/DiffPreviewComponent.js @@ -1,28 +1,39 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {DiffPreviewPhase} from '../types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DiffPreviewComponent = undefined; -import FileChanges from '../../../nuclide-ui/FileChanges'; -import * as React from 'react'; +var _FileChanges; -type Props = { - phase: DiffPreviewPhase, -}; +function _load_FileChanges() { + return _FileChanges = _interopRequireDefault(require('../../../nuclide-ui/FileChanges')); +} + +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 }; } -export class DiffPreviewComponent extends React.Component { - render(): React.Node { - const {diffs} = this.props.phase; - return ( -
    {diffs.map((diff, i) => )}
    +class DiffPreviewComponent extends _react.Component { + render() { + const { diffs } = this.props.phase; + return _react.createElement( + 'div', + null, + diffs.map((diff, i) => _react.createElement((_FileChanges || _load_FileChanges()).default, { key: i, diff: diff })) ); } } +exports.DiffPreviewComponent = DiffPreviewComponent; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-refactorizer/lib/components/FreeformRefactorComponent.js b/pkg/nuclide-refactorizer/lib/components/FreeformRefactorComponent.js index fe3833a3bb..b3041965b3 100644 --- a/pkg/nuclide-refactorizer/lib/components/FreeformRefactorComponent.js +++ b/pkg/nuclide-refactorizer/lib/components/FreeformRefactorComponent.js @@ -1,3 +1,44 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.FreeformRefactorComponent = undefined; + +var _react = _interopRequireWildcard(require('react')); + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../../../../modules/nuclide-commons-ui/AtomInput'); +} + +var _Button; + +function _load_Button() { + return _Button = require('../../../../modules/nuclide-commons-ui/Button'); +} + +var _Checkbox; + +function _load_Checkbox() { + return _Checkbox = require('../../../../modules/nuclide-commons-ui/Checkbox'); +} + +var _Dropdown; + +function _load_Dropdown() { + return _Dropdown = require('../../../../modules/nuclide-commons-ui/Dropdown'); +} + +var _refactorActions; + +function _load_refactorActions() { + return _refactorActions = _interopRequireWildcard(require('../refactorActions')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,32 +46,11 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {FreeformRefactoringArgument} from '../..'; -import type {Store, FreeformPhase} from '../types'; - -import * as React from 'react'; - -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {Button, ButtonTypes} from 'nuclide-commons-ui/Button'; -import {Checkbox} from 'nuclide-commons-ui/Checkbox'; -import {Dropdown} from 'nuclide-commons-ui/Dropdown'; - -import * as Actions from '../refactorActions'; - -type Props = { - phase: FreeformPhase, - store: Store, -}; - -type State = { - args: Map, -}; - -function getDefault(arg: FreeformRefactoringArgument): string | boolean { +function getDefault(arg) { if (arg.default != null) { return arg.default; } @@ -47,103 +67,100 @@ function getDefault(arg: FreeformRefactoringArgument): string | boolean { throw new Error('unreachable'); } -export class FreeformRefactorComponent extends React.Component { - constructor(props: Props) { +class FreeformRefactorComponent extends _react.Component { + constructor(props) { super(props); - const defaultArgs = new Map( - props.phase.refactoring.arguments.map(arg => [arg.name, getDefault(arg)]), - ); + + this._execute = () => { + const { editor, originalRange, refactoring } = this.props.phase; + this.props.store.dispatch((_refactorActions || _load_refactorActions()).execute(this.props.phase.provider, { + kind: 'freeform', + editor, + originalRange, + id: refactoring.id, + range: refactoring.range, + arguments: this.state.args + })); + }; + + const defaultArgs = new Map(props.phase.refactoring.arguments.map(arg => [arg.name, getDefault(arg)])); this.state = { - args: defaultArgs, + args: defaultArgs }; } - render(): React.Node { - return ( -
    - {this._getControls()} -
    - -
    -
    + render() { + return _react.createElement( + 'div', + null, + this._getControls(), + _react.createElement( + 'div', + { style: { display: 'flex', justifyContent: 'flex-end' } }, + _react.createElement( + (_Button || _load_Button()).Button, + { + className: 'nuclide-refactorizer-execute-button', + buttonType: (_Button || _load_Button()).ButtonTypes.PRIMARY, + onClick: this._execute }, + 'Execute' + ) + ) ); } _getControls() { - return this.props.phase.refactoring.arguments - .map((arg, index) => { - switch (arg.type) { - case 'string': - return [ -
    - {arg.description} -
    , - this._updateArg(arg.name, text)} - onConfirm={this._execute} - />, - ]; - case 'boolean': - return ( - this._updateArg(arg.name, checked)} - /> - ); - case 'enum': - return [ -
    - {arg.description} -
    , - ({ - value: val.value, - label: val.description, - }))} - onChange={value => this._updateArg(arg.name, value)} - />, - ]; - } - }) - .map((elem, index) => { - return ( -
    - {elem} -
    - ); - }); + return this.props.phase.refactoring.arguments.map((arg, index) => { + switch (arg.type) { + case 'string': + return [_react.createElement( + 'div', + { key: 'label', className: 'nuclide-refactorizer-freeform-label' }, + arg.description + ), _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + key: 'input', + autofocus: index === 0, + startSelected: index === 0, + className: 'nuclide-refactorizer-freeform-editor', + value: String(this.state.args.get(arg.name)), + onDidChange: text => this._updateArg(arg.name, text), + onConfirm: this._execute + })]; + case 'boolean': + return _react.createElement((_Checkbox || _load_Checkbox()).Checkbox, { + label: arg.description, + checked: Boolean(this.state.args.get(arg.name)), + onChange: checked => this._updateArg(arg.name, checked) + }); + case 'enum': + return [_react.createElement( + 'div', + { key: 'label', className: 'nuclide-refactorizer-freeform-label' }, + arg.description + ), _react.createElement((_Dropdown || _load_Dropdown()).Dropdown, { + key: 'dropdown', + value: this.state.args.get(arg.name) || arg.options[0], + options: arg.options.map(val => ({ + value: val.value, + label: val.description + })), + onChange: value => this._updateArg(arg.name, value) + })]; + } + }).map((elem, index) => { + return _react.createElement( + 'div', + { key: index, className: 'nuclide-refactorizer-freeform-group' }, + elem + ); + }); } - _updateArg(name: string, value: mixed) { + _updateArg(name, value) { // A bit hacky, but immutability isn't a requirement here. this.state.args.set(name, value); this.forceUpdate(); } - _execute = () => { - const {editor, originalRange, refactoring} = this.props.phase; - this.props.store.dispatch( - Actions.execute(this.props.phase.provider, { - kind: 'freeform', - editor, - originalRange, - id: refactoring.id, - range: refactoring.range, - arguments: this.state.args, - }), - ); - }; } +exports.FreeformRefactorComponent = FreeformRefactorComponent; \ No newline at end of file diff --git a/pkg/nuclide-refactorizer/lib/components/MainRefactorComponent.js b/pkg/nuclide-refactorizer/lib/components/MainRefactorComponent.js index 1c01d889ae..29a7c1710f 100644 --- a/pkg/nuclide-refactorizer/lib/components/MainRefactorComponent.js +++ b/pkg/nuclide-refactorizer/lib/components/MainRefactorComponent.js @@ -1,37 +1,70 @@ -/** - * 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 - */ - -import type {Store, RefactorState} from '../types'; - -import * as React from 'react'; -import invariant from 'assert'; - -import {Button} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; - -import {ConfirmRefactorComponent} from './ConfirmRefactorComponent'; -import {DiffPreviewComponent} from './DiffPreviewComponent'; -import {FreeformRefactorComponent} from './FreeformRefactorComponent'; -import {PickRefactorComponent} from './PickRefactorComponent'; -import {ProgressComponent} from './ProgressComponent'; -import {RenameComponent} from './RenameComponent'; -import * as Actions from '../refactorActions'; - -type Props = { - appState: RefactorState, - store: Store, -}; - -export class MainRefactorComponent extends React.Component { - render(): React.Element | null { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.MainRefactorComponent = undefined; + +var _react = _interopRequireWildcard(require('react')); + +var _Button; + +function _load_Button() { + return _Button = require('../../../../modules/nuclide-commons-ui/Button'); +} + +var _ButtonGroup; + +function _load_ButtonGroup() { + return _ButtonGroup = require('../../../../modules/nuclide-commons-ui/ButtonGroup'); +} + +var _ConfirmRefactorComponent; + +function _load_ConfirmRefactorComponent() { + return _ConfirmRefactorComponent = require('./ConfirmRefactorComponent'); +} + +var _DiffPreviewComponent; + +function _load_DiffPreviewComponent() { + return _DiffPreviewComponent = require('./DiffPreviewComponent'); +} + +var _FreeformRefactorComponent; + +function _load_FreeformRefactorComponent() { + return _FreeformRefactorComponent = require('./FreeformRefactorComponent'); +} + +var _PickRefactorComponent; + +function _load_PickRefactorComponent() { + return _PickRefactorComponent = require('./PickRefactorComponent'); +} + +var _ProgressComponent; + +function _load_ProgressComponent() { + return _ProgressComponent = require('./ProgressComponent'); +} + +var _RenameComponent; + +function _load_RenameComponent() { + return _RenameComponent = require('./RenameComponent'); +} + +var _refactorActions; + +function _load_refactorActions() { + return _refactorActions = _interopRequireWildcard(require('../refactorActions')); +} + +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 MainRefactorComponent extends _react.Component { + render() { if (this.props.appState.type === 'closed') { return null; } else { @@ -41,75 +74,100 @@ export class MainRefactorComponent extends React.Component { } } - _render(): React.Element { - return ( -
    - {this.getHeaderElement()} - {this.getInnerElement()} -
    + _render() { + return _react.createElement( + 'div', + null, + this.getHeaderElement(), + this.getInnerElement() ); } - _getBackButton(): React.Node { + _getBackButton() { const appState = this.props.appState; - const previousPhase = - (appState.phase && appState.phase.previousPhase) || null; - return previousPhase ? ( - + const previousPhase = appState.phase && appState.phase.previousPhase || null; + return previousPhase ? _react.createElement( + (_Button || _load_Button()).Button, + { + onClick: () => this.props.store.dispatch((_refactorActions || _load_refactorActions()).backFromDiffPreview(previousPhase)) }, + 'Back' ) : null; } - getHeaderElement(): React.Element { + getHeaderElement() { const appState = this.props.appState; - invariant(appState.type === 'open'); - return ( -
    - Refactor - - {this._getBackButton()} - - -
    + + if (!(appState.type === 'open')) { + throw new Error('Invariant violation: "appState.type === \'open\'"'); + } + + return _react.createElement( + 'div', + { className: 'nuclide-refactorizer-header' }, + _react.createElement( + 'span', + null, + 'Refactor' + ), + _react.createElement( + (_ButtonGroup || _load_ButtonGroup()).ButtonGroup, + null, + this._getBackButton(), + _react.createElement( + (_Button || _load_Button()).Button, + { onClick: () => this.props.store.dispatch((_refactorActions || _load_refactorActions()).close()) }, + 'Close' + ) + ) ); } - getInnerElement(): React.Element { + getInnerElement() { const appState = this.props.appState; - invariant(appState.type === 'open'); + + if (!(appState.type === 'open')) { + throw new Error('Invariant violation: "appState.type === \'open\'"'); + } + const phase = appState.phase; switch (phase.type) { case 'get-refactorings': - return
    Waiting for refactorings...
    ; - case 'pick': - return ( - + return _react.createElement( + 'div', + null, + 'Waiting for refactorings...' ); + case 'pick': + return _react.createElement((_PickRefactorComponent || _load_PickRefactorComponent()).PickRefactorComponent, { pickPhase: phase, store: this.props.store }); case 'rename': - return ; + return _react.createElement((_RenameComponent || _load_RenameComponent()).RenameComponent, { phase: phase, store: this.props.store }); case 'freeform': - return ( - - ); + return _react.createElement((_FreeformRefactorComponent || _load_FreeformRefactorComponent()).FreeformRefactorComponent, { phase: phase, store: this.props.store }); case 'execute': - return
    Executing refactoring...
    ; - case 'confirm': - return ( - + return _react.createElement( + 'div', + null, + 'Executing refactoring...' ); + case 'confirm': + return _react.createElement((_ConfirmRefactorComponent || _load_ConfirmRefactorComponent()).ConfirmRefactorComponent, { phase: phase, store: this.props.store }); case 'progress': - return ; + return _react.createElement((_ProgressComponent || _load_ProgressComponent()).ProgressComponent, { phase: phase }); case 'diff-preview': - return ; + return _react.createElement((_DiffPreviewComponent || _load_DiffPreviewComponent()).DiffPreviewComponent, { phase: phase }); default: - (phase: empty); - return
    ; + phase; + return _react.createElement('div', null); } } } +exports.MainRefactorComponent = MainRefactorComponent; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-refactorizer/lib/components/PickRefactorComponent.js b/pkg/nuclide-refactorizer/lib/components/PickRefactorComponent.js index a75b07ee17..5af0961c8f 100644 --- a/pkg/nuclide-refactorizer/lib/components/PickRefactorComponent.js +++ b/pkg/nuclide-refactorizer/lib/components/PickRefactorComponent.js @@ -1,3 +1,34 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PickRefactorComponent = undefined; + +var _react = _interopRequireWildcard(require('react')); + +var _refactorActions; + +function _load_refactorActions() { + return _refactorActions = _interopRequireWildcard(require('../refactorActions')); +} + +var _Button; + +function _load_Button() { + return _Button = require('../../../../modules/nuclide-commons-ui/Button'); +} + +var _classnames; + +function _load_classnames() { + return _classnames = _interopRequireDefault(require('classnames')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,97 +36,88 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {Store, PickPhase} from '../types'; -import type {AvailableRefactoring} from '../..'; - -import * as React from 'react'; -import * as Actions from '../refactorActions'; -import {Button} from 'nuclide-commons-ui/Button'; -import classNames from 'classnames'; - -type State = { - selectedRefactoring: ?AvailableRefactoring, -}; - -export class PickRefactorComponent extends React.Component< - { - pickPhase: PickPhase, - store: Store, - }, - State, -> { - state: State = { - selectedRefactoring: null, - }; - - render(): React.Node { - const {availableRefactorings} = this.props.pickPhase; +class PickRefactorComponent extends _react.Component { + constructor(...args) { + var _temp; + + return _temp = super(...args), this.state = { + selectedRefactoring: null + }, _temp; + } + + render() { + const { availableRefactorings } = this.props.pickPhase; if (availableRefactorings.length === 0) { - return
    No refactorings available at this location
    ; + return _react.createElement( + 'div', + null, + 'No refactorings available at this location' + ); } - const elements = availableRefactorings.map(r => - this._renderRefactorOption(r), - ); + const elements = availableRefactorings.map(r => this._renderRefactorOption(r)); - return ( -
    -
      {elements}
    -
    + return _react.createElement( + 'div', + { className: 'select-list nuclide-refactorizer-pick-refactor' }, + _react.createElement( + 'ol', + { className: 'list-group' }, + elements + ) ); } - _pickRefactor(refactoring: AvailableRefactoring): void { + _pickRefactor(refactoring) { if (refactoring.kind === 'freeform' && refactoring.arguments.length === 0) { - this.props.store.dispatch( - Actions.execute(this.props.pickPhase.provider, { - kind: 'freeform', - editor: this.props.pickPhase.editor, - originalRange: this.props.pickPhase.originalRange, - id: refactoring.id, - range: refactoring.range, - arguments: new Map(), - }), - ); + this.props.store.dispatch((_refactorActions || _load_refactorActions()).execute(this.props.pickPhase.provider, { + kind: 'freeform', + editor: this.props.pickPhase.editor, + originalRange: this.props.pickPhase.originalRange, + id: refactoring.id, + range: refactoring.range, + arguments: new Map() + })); return; } - this.props.store.dispatch(Actions.pickedRefactor(refactoring)); + this.props.store.dispatch((_refactorActions || _load_refactorActions()).pickedRefactor(refactoring)); } - _select(selectedRefactoring: AvailableRefactoring): void { + _select(selectedRefactoring) { this.setState({ - selectedRefactoring, + selectedRefactoring }); } - _renderRefactorOption(refactoring: AvailableRefactoring): React.Node { + _renderRefactorOption(refactoring) { switch (refactoring.kind) { case 'rename': - return ( -
  • - -
  • + } }, + 'Rename' + ) ); case 'freeform': const selectable = !refactoring.disabled; - const selected = - selectable && refactoring === this.state.selectedRefactoring; + const selected = selectable && refactoring === this.state.selectedRefactoring; const props = {}; - props.className = classNames('two-lines', { + props.className = (0, (_classnames || _load_classnames()).default)('two-lines', { 'nuclide-refactorizer-selectable': selectable, 'nuclide-refactorizer-selected': selected, - 'nuclide-refactorizer-unselectable': !selectable, + 'nuclide-refactorizer-unselectable': !selectable }); props.onMouseEnter = () => this._select(refactoring); if (!refactoring.disabled) { @@ -103,30 +125,35 @@ export class PickRefactorComponent extends React.Component< this._pickRefactor(refactoring); }; } - const refactoringOption = ( -
  • -
    - {refactoring.name} -
    -
    - {refactoring.description} -
    -
  • + 'nuclide-refactorizer-unselectable-text': !selectable + }) }, + refactoring.description + ) ); return refactoringOption; default: - (refactoring.kind: empty); + refactoring.kind; throw new Error(`Unknown refactoring kind ${refactoring.kind}`); } } } +exports.PickRefactorComponent = PickRefactorComponent; \ No newline at end of file diff --git a/pkg/nuclide-refactorizer/lib/components/ProgressComponent.js b/pkg/nuclide-refactorizer/lib/components/ProgressComponent.js index 7b067cd40b..07da1c0966 100644 --- a/pkg/nuclide-refactorizer/lib/components/ProgressComponent.js +++ b/pkg/nuclide-refactorizer/lib/components/ProgressComponent.js @@ -1,34 +1,47 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {ProgressPhase} from '../types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ProgressComponent = undefined; -import * as React from 'react'; +var _react = _interopRequireWildcard(require('react')); -import {ProgressBar} from 'nuclide-commons-ui/ProgressBar'; +var _ProgressBar; -type Props = { - phase: ProgressPhase, -}; +function _load_ProgressBar() { + return _ProgressBar = require('../../../../modules/nuclide-commons-ui/ProgressBar'); +} + +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; } } -export class ProgressComponent extends React.Component { - render(): React.Node { - const {message, value, max} = this.props.phase; - return ( -
    - {message} ({value} / {max}) -
    - -
    -
    +class ProgressComponent extends _react.Component { + render() { + const { message, value, max } = this.props.phase; + return _react.createElement( + 'div', + null, + message, + ' (', + value, + ' / ', + max, + ')', + _react.createElement( + 'div', + { className: 'nuclide-refactorizer-progress' }, + _react.createElement((_ProgressBar || _load_ProgressBar()).ProgressBar, { value: value, max: max }) + ) ); } } +exports.ProgressComponent = ProgressComponent; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-refactorizer/lib/components/RenameComponent.js b/pkg/nuclide-refactorizer/lib/components/RenameComponent.js index a8319b0a22..724c9be8cf 100644 --- a/pkg/nuclide-refactorizer/lib/components/RenameComponent.js +++ b/pkg/nuclide-refactorizer/lib/components/RenameComponent.js @@ -1,73 +1,83 @@ -/** - * 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 - */ +'use strict'; -import type {Store, RenamePhase} from '../types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RenameComponent = undefined; -import * as React from 'react'; +var _react = _interopRequireWildcard(require('react')); -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {Button} from 'nuclide-commons-ui/Button'; +var _AtomInput; -import * as Actions from '../refactorActions'; +function _load_AtomInput() { + return _AtomInput = require('../../../../modules/nuclide-commons-ui/AtomInput'); +} + +var _Button; -type Props = { - phase: RenamePhase, - store: Store, -}; +function _load_Button() { + return _Button = require('../../../../modules/nuclide-commons-ui/Button'); +} -type State = { - newName: string, -}; +var _refactorActions; -export class RenameComponent extends React.Component { - constructor(props: Props) { +function _load_refactorActions() { + return _refactorActions = _interopRequireWildcard(require('../refactorActions')); +} + +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 RenameComponent extends _react.Component { + constructor(props) { super(props); this.state = { - newName: this.props.phase.symbolAtPoint.text, + newName: this.props.phase.symbolAtPoint.text }; } - render(): React.Node { - return ( -
    - this.setState({newName: text})} - onConfirm={() => this._runRename()} - /> - -
    + render() { + return _react.createElement( + 'div', + null, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + autofocus: true, + startSelected: true, + className: 'nuclide-refactorizer-rename-editor', + initialValue: this.props.phase.symbolAtPoint.text, + onDidChange: text => this.setState({ newName: text }), + onConfirm: () => this._runRename() + }), + _react.createElement( + (_Button || _load_Button()).Button + // Used to identify this element in integration tests + , + { className: 'nuclide-refactorizer-execute-button', + onClick: () => this._runRename() }, + 'Execute' + ) ); } - _runRename(): void { - const {newName} = this.state; - const {symbolAtPoint, editor, originalPoint} = this.props.phase; + _runRename() { + const { newName } = this.state; + const { symbolAtPoint, editor, originalPoint } = this.props.phase; const refactoring = { kind: 'rename', newName, originalPoint, symbolAtPoint, - editor, + editor }; - this.props.store.dispatch( - Actions.execute(this.props.phase.provider, refactoring), - ); + this.props.store.dispatch((_refactorActions || _load_refactorActions()).execute(this.props.phase.provider, refactoring)); } } +exports.RenameComponent = RenameComponent; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-refactorizer/lib/main.js b/pkg/nuclide-refactorizer/lib/main.js index 8d2017b226..56e823e1c5 100644 --- a/pkg/nuclide-refactorizer/lib/main.js +++ b/pkg/nuclide-refactorizer/lib/main.js @@ -1,3 +1,63 @@ +'use strict'; + +var _ProviderRegistry; + +function _load_ProviderRegistry() { + return _ProviderRegistry = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/ProviderRegistry')); +} + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _observeGrammarForTextEditors; + +function _load_observeGrammarForTextEditors() { + return _observeGrammarForTextEditors = _interopRequireDefault(require('../../commons-atom/observe-grammar-for-text-editors')); +} + +var _mouseToPosition; + +function _load_mouseToPosition() { + return _mouseToPosition = require('../../../modules/nuclide-commons-atom/mouse-to-position'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _passesGK; + +function _load_passesGK() { + return _passesGK = _interopRequireDefault(require('../../commons-node/passesGK')); +} + +var _refactorActions; + +function _load_refactorActions() { + return _refactorActions = _interopRequireWildcard(require('./refactorActions')); +} + +var _refactorStore; + +function _load_refactorStore() { + return _refactorStore = require('./refactorStore'); +} + +var _refactorUIs; + +function _load_refactorUIs() { + return _refactorUIs = require('./refactorUIs'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +65,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ @@ -13,160 +73,62 @@ * WARNING: This package is still experimental and in early development. Use it at your own risk. */ -import type {Observable} from 'rxjs'; -import type {CodeActionProvider} from 'atom-ide-ui'; -import type { - AvailableRefactoring, - FreeformRefactoring, - FreeformRefactoringArgument, - RefactorResponse, - RenameRefactoring, -} from './rpc-types'; - -import type {Store} from './types'; - -import invariant from 'assert'; - -import ProviderRegistry from 'nuclide-commons-atom/ProviderRegistry'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import observeGrammarForTextEditors from '../../commons-atom/observe-grammar-for-text-editors'; -import {bufferPositionForMouseEvent} from 'nuclide-commons-atom/mouse-to-position'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import passesGK from '../../commons-node/passesGK'; - -import * as Actions from './refactorActions'; -import {getStore} from './refactorStore'; -import {initRefactorUIs} from './refactorUIs'; - -export type { - AvailableRefactoring, - FreeformRefactoring, - FreeformRefactoringArgument, - RefactorResponse, - RenameRefactoring, -}; - -export type RenameRefactorKind = 'rename'; -export type FreeformRefactorKind = 'freeform'; - -export type RefactorKind = RenameRefactorKind | FreeformRefactorKind; - -export type RenameRequest = { - kind: RenameRefactorKind, - editor: atom$TextEditor, - originalPoint: atom$Point, - symbolAtPoint: { - text: string, - range: atom$Range, - }, - newName: string, -}; - -export type FreeformRefactorRequest = {| - kind: FreeformRefactorKind, - editor: atom$TextEditor, - originalRange: atom$Range, - // Echoes FreeformRefactoring.id. - id: string, - // Echoes FreeformRefactoring.range. - range: atom$Range, - // Arguments provided by the user. - arguments: Map, -|}; - -export type RefactorRequest = RenameRequest | FreeformRefactorRequest; - -export type RefactorProvider = { - priority: number, - grammarScopes: Array, - - refactorings( - editor: atom$TextEditor, - range: atom$Range, - ): Promise>, - - // Providers may stream back progress responses. - // Note that the stream will terminate once an edit response is received. - // If no edit response is received, an error will be raised. - refactor(request: RefactorRequest): Observable, -}; - const CONTEXT_MENU_CLASS = 'enable-nuclide-refactorizer'; class Activation { - _disposables: UniversalDisposable; - _store: Store; - _providerRegistry: ProviderRegistry; constructor() { - this._providerRegistry = new ProviderRegistry(); + this._providerRegistry = new (_ProviderRegistry || _load_ProviderRegistry()).default(); - this._store = getStore(this._providerRegistry); + this._store = (0, (_refactorStore || _load_refactorStore()).getStore)(this._providerRegistry); let lastMouseEvent = null; - this._disposables = new UniversalDisposable( - initRefactorUIs(this._store), - atom.commands.add( - 'atom-workspace', - 'nuclide-refactorizer:refactorize', - () => { - this._store.dispatch(Actions.open('generic')); - }, - ), - atom.commands.add( - 'atom-text-editor', - // We don't actually want people calling this directly. - // eslint-disable-next-line nuclide-internal/atom-commands - 'nuclide-refactorizer:refactorize-from-context-menu', - () => { - const mouseEvent = lastMouseEvent; - lastMouseEvent = null; - invariant( - mouseEvent != null, - 'No mouse event found. Do not invoke this command directly. ' + - 'If you did use the context menu, please report this issue.', - ); - const editor = atom.workspace.getActiveTextEditor(); - invariant(editor != null); - const bufferPosition = bufferPositionForMouseEvent( - mouseEvent, - editor, - ); - // If the user selected some text and clicked within it, - // we'll treat it as a 'range refactor'. - const currentSelection = editor.getSelectedBufferRange(); - if (!currentSelection.containsPoint(bufferPosition)) { - editor.setCursorBufferPosition(bufferPosition); - } - - this._store.dispatch(Actions.open('generic')); - }, - ), - atom.contextMenu.add({ - 'atom-text-editor:not(.mini).enable-nuclide-refactorizer': [ - { - label: 'Refactor', - command: 'nuclide-refactorizer:refactorize-from-context-menu', - created: event => { - lastMouseEvent = event; - }, - }, - ], - }), - atom.commands.add('atom-workspace', 'nuclide-refactorizer:rename', () => { - this._store.dispatch(Actions.open('rename')); - }), - observeGrammarForTextEditors(editor => - this._addContextMenuIfEligible(editor), - ), - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default((0, (_refactorUIs || _load_refactorUIs()).initRefactorUIs)(this._store), atom.commands.add('atom-workspace', 'nuclide-refactorizer:refactorize', () => { + this._store.dispatch((_refactorActions || _load_refactorActions()).open('generic')); + }), atom.commands.add('atom-text-editor', + // We don't actually want people calling this directly. + // eslint-disable-next-line nuclide-internal/atom-commands + 'nuclide-refactorizer:refactorize-from-context-menu', () => { + const mouseEvent = lastMouseEvent; + lastMouseEvent = null; + + if (!(mouseEvent != null)) { + throw new Error('No mouse event found. Do not invoke this command directly. ' + 'If you did use the context menu, please report this issue.'); + } + + const editor = atom.workspace.getActiveTextEditor(); + + if (!(editor != null)) { + throw new Error('Invariant violation: "editor != null"'); + } + + const bufferPosition = (0, (_mouseToPosition || _load_mouseToPosition()).bufferPositionForMouseEvent)(mouseEvent, editor); + // If the user selected some text and clicked within it, + // we'll treat it as a 'range refactor'. + const currentSelection = editor.getSelectedBufferRange(); + if (!currentSelection.containsPoint(bufferPosition)) { + editor.setCursorBufferPosition(bufferPosition); + } + + this._store.dispatch((_refactorActions || _load_refactorActions()).open('generic')); + }), atom.contextMenu.add({ + 'atom-text-editor:not(.mini).enable-nuclide-refactorizer': [{ + label: 'Refactor', + command: 'nuclide-refactorizer:refactorize-from-context-menu', + created: event => { + lastMouseEvent = event; + } + }] + }), atom.commands.add('atom-workspace', 'nuclide-refactorizer:rename', () => { + this._store.dispatch((_refactorActions || _load_refactorActions()).open('rename')); + }), (0, (_observeGrammarForTextEditors || _load_observeGrammarForTextEditors()).default)(editor => this._addContextMenuIfEligible(editor))); } dispose() { this._disposables.dispose(); } - _addContextMenuIfEligible(editor: atom$TextEditor): void { + _addContextMenuIfEligible(editor) { const element = atom.views.getView(editor); if (this._providerRegistry.getProviderForEditor(editor) != null) { element.classList.add(CONTEXT_MENU_CLASS); @@ -175,64 +137,52 @@ class Activation { } } - _checkAllEditorContextMenus(): void { - atom.workspace - .getTextEditors() - .forEach(editor => this._addContextMenuIfEligible(editor)); + _checkAllEditorContextMenus() { + atom.workspace.getTextEditors().forEach(editor => this._addContextMenuIfEligible(editor)); } - consumeRefactorProvider(provider: RefactorProvider): IDisposable { + consumeRefactorProvider(provider) { this._providerRegistry.addProvider(provider); this._checkAllEditorContextMenus(); - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { this._providerRegistry.removeProvider(provider); this._checkAllEditorContextMenus(); }); } - provideCodeActions(): CodeActionProvider { + provideCodeActions() { const store = this._store; const providerRegistry = this._providerRegistry; return { priority: 1, async getCodeActions(editor, range, diagnostics) { const provider = providerRegistry.getProviderForEditor(editor); - if ( - provider == null || - diagnostics.length > 0 || - !(await passesGK('nuclide_refactorizer_code_actions')) - ) { + if (provider == null || diagnostics.length > 0 || !(await (0, (_passesGK || _load_passesGK()).default)('nuclide_refactorizer_code_actions'))) { return []; } const refactors = await provider.refactorings(editor, range); - return refactors - .filter(refactor => { - return refactor.kind === 'freeform' && !refactor.disabled; - }) - .map(refactor => { - invariant(refactor.kind === 'freeform'); - return { - async apply() { - return store.dispatch( - Actions.inlinePickedRefactor( - editor, - range, - provider, - refactor, - ), - ); - }, - async getTitle() { - return refactor.name; - }, - dispose() {}, - }; - }); - }, + return refactors.filter(refactor => { + return refactor.kind === 'freeform' && !refactor.disabled; + }).map(refactor => { + if (!(refactor.kind === 'freeform')) { + throw new Error('Invariant violation: "refactor.kind === \'freeform\'"'); + } + + return { + async apply() { + return store.dispatch((_refactorActions || _load_refactorActions()).inlinePickedRefactor(editor, range, provider, refactor)); + }, + async getTitle() { + return refactor.name; + }, + dispose() {} + }; + }); + } }; } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-refactorizer/lib/refactorActions.js b/pkg/nuclide-refactorizer/lib/refactorActions.js index d8ea319aba..0b055d6fad 100644 --- a/pkg/nuclide-refactorizer/lib/refactorActions.js +++ b/pkg/nuclide-refactorizer/lib/refactorActions.js @@ -1,3 +1,21 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.open = open; +exports.gotRefactorings = gotRefactorings; +exports.error = error; +exports.backFromDiffPreview = backFromDiffPreview; +exports.pickedRefactor = pickedRefactor; +exports.inlinePickedRefactor = inlinePickedRefactor; +exports.execute = execute; +exports.confirm = confirm; +exports.loadDiffPreview = loadDiffPreview; +exports.displayDiffPreview = displayDiffPreview; +exports.apply = apply; +exports.progress = progress; +exports.close = close; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,169 +23,120 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {AvailableRefactoring, RefactorRequest, RefactorProvider} from '..'; - -import type { - ApplyAction, - BackFromDiffPreviewAction, - CloseAction, - ConfirmAction, - DisplayDiffPreviewAction, - ErrorAction, - ErrorSource, - ExecuteAction, - GotRefactoringsAction, - InlinePickedRefactorAction, - OpenAction, - Phase, - ProgressAction, - PickedRefactorAction, - RefactorUI, - LoadDiffPreviewAction, -} from './types'; - -import type {RefactorEditResponse} from './rpc-types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -export function open(ui: RefactorUI): OpenAction { +function open(ui) { return { type: 'open', - ui, + ui }; } -export function gotRefactorings( - editor: atom$TextEditor, - originalRange: atom$Range, - provider: RefactorProvider, - availableRefactorings: Array, -): GotRefactoringsAction { +function gotRefactorings(editor, originalRange, provider, availableRefactorings) { return { type: 'got-refactorings', payload: { editor, originalRange, provider, - availableRefactorings, - }, + availableRefactorings + } }; } -export function error(source: ErrorSource, err: Error): ErrorAction { +function error(source, err) { return { type: 'error', payload: { source, - error: err, - }, + error: err + } }; } -export function backFromDiffPreview(phase: Phase): BackFromDiffPreviewAction { +function backFromDiffPreview(phase) { return { type: 'back-from-diff-preview', payload: { - phase, - }, + phase + } }; } -export function pickedRefactor( - refactoring: AvailableRefactoring, -): PickedRefactorAction { +function pickedRefactor(refactoring) { return { type: 'picked-refactor', payload: { - refactoring, - }, + refactoring + } }; } -export function inlinePickedRefactor( - editor: atom$TextEditor, - originalRange: atom$Range, - provider: RefactorProvider, - refactoring: AvailableRefactoring, -): InlinePickedRefactorAction { +function inlinePickedRefactor(editor, originalRange, provider, refactoring) { return { type: 'inline-picked-refactor', payload: { originalRange, editor, provider, - refactoring, - }, + refactoring + } }; } -export function execute( - provider: RefactorProvider, - refactoring: RefactorRequest, -): ExecuteAction { +function execute(provider, refactoring) { return { type: 'execute', payload: { provider, - refactoring, - }, + refactoring + } }; } -export function confirm(response: RefactorEditResponse): ConfirmAction { +function confirm(response) { return { type: 'confirm', - payload: {response}, + payload: { response } }; } -export function loadDiffPreview( - previousPhase: Phase, - uri: NuclideUri, - response: RefactorEditResponse, -): LoadDiffPreviewAction { +function loadDiffPreview(previousPhase, uri, response) { return { type: 'load-diff-preview', payload: { previousPhase, uri, - response, - }, + response + } }; } -export function displayDiffPreview( - diffs: Array, -): DisplayDiffPreviewAction { +function displayDiffPreview(diffs) { return { type: 'display-diff-preview', - payload: {diffs}, + payload: { diffs } }; } -export function apply(response: RefactorEditResponse): ApplyAction { +function apply(response) { return { type: 'apply', - payload: {response}, + payload: { response } }; } -export function progress( - message: string, - value: number, - max: number, -): ProgressAction { +function progress(message, value, max) { return { type: 'progress', - payload: {message, value, max}, + payload: { message, value, max } }; } -export function close(): CloseAction { +function close() { return { - type: 'close', + type: 'close' }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-refactorizer/lib/refactorEpics.js b/pkg/nuclide-refactorizer/lib/refactorEpics.js index 029cd9b518..1193956c26 100644 --- a/pkg/nuclide-refactorizer/lib/refactorEpics.js +++ b/pkg/nuclide-refactorizer/lib/refactorEpics.js @@ -1,260 +1,225 @@ -/** - * 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 - */ - -import type {ActionsObservable, Epic} from 'nuclide-commons/redux-observable'; -import type ProviderRegistry from 'nuclide-commons-atom/ProviderRegistry'; -import {getFileForPath} from 'nuclide-commons-atom/projects'; -import type {TextEdit} from 'nuclide-commons-atom/text-edit'; -import type { - ApplyAction, - RefactorAction, - RefactorState, - ExecuteAction, -} from './types'; -import type {ExternalTextEdit, RefactorEditResponse} from './rpc-types'; -import type {RefactorProvider} from '..'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import invariant from 'assert'; -import {Observable} from 'rxjs'; -import {Range, TextBuffer} from 'atom'; - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import parse from 'diffparser'; -import {applyTextEditsToBuffer} from 'nuclide-commons-atom/text-edit'; -import {toUnifiedDiff} from 'nuclide-commons-atom/text-edit-diff'; -import {existingEditorForUri} from 'nuclide-commons-atom/text-editor'; -import {getLogger} from 'log4js'; -import {track} from '../../nuclide-analytics'; - -import * as Actions from './refactorActions'; - -export function getEpics( - providers: ProviderRegistry, -): Array> { - return [ - function getRefactoringsEpic( - actions: ActionsObservable, - ): Observable { - return actions.ofType('open').switchMap(() => { - return Observable.fromPromise(getRefactorings(providers)).takeUntil( - actions, - ); - }); - }, - - function executeRefactoringEpic( - actions: ActionsObservable, - ): Observable { - return actions.ofType('execute').switchMap(action => { - // Flow doesn't understand the implications of ofType :( - invariant(action.type === 'execute'); - return executeRefactoring(action) - .concat( - // Default handler if we don't get a result. - Observable.of( - Actions.error('execute', Error('Could not refactor.')), - ), - ) - .takeUntil(actions.filter(x => x.type !== 'progress')); - }); - }, - - function applyRefactoringEpic( - actions: ActionsObservable, - ): Observable { - return actions.ofType('apply').switchMap(action => { - invariant(action.type === 'apply'); - return applyRefactoring(action).takeUntil(actions.ofType('close')); - }); - }, - - function loadDiffPreviewEpic( - actions: ActionsObservable, - ): Observable { - return actions.ofType('load-diff-preview').switchMap(action => { - invariant(action.type === 'load-diff-preview'); - return Observable.fromPromise( - loadDiffPreview(action.payload.uri, action.payload.response), - ); - }); - }, - - function handleErrors( - actions: ActionsObservable, - ): Observable { - return actions.ofType('error').map(action => { - invariant(action.type === 'error'); - const {source, error} = action.payload; - const sourceName = - source === 'got-refactorings' - ? 'getting refactors' - : 'executing refactor'; - getLogger('nuclide-refactorizer').error(`Error ${sourceName}:`, error); - atom.notifications.addError(`Error ${sourceName}`, { - description: error.message, - dismissable: true, - }); - return Actions.close(); - }); - }, - ]; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getEpics = getEpics; +exports.applyRefactoring = applyRefactoring; + +var _projects; + +function _load_projects() { + return _projects = require('../../../modules/nuclide-commons-atom/projects'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _atom = require('atom'); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); } -async function getRefactorings( - providers: ProviderRegistry, -): Promise { - track('nuclide-refactorizer:get-refactorings'); +var _diffparser; + +function _load_diffparser() { + return _diffparser = _interopRequireDefault(require('diffparser')); +} + +var _textEdit; + +function _load_textEdit() { + return _textEdit = require('../../../modules/nuclide-commons-atom/text-edit'); +} + +var _textEditDiff; + +function _load_textEditDiff() { + return _textEditDiff = require('../../../modules/nuclide-commons-atom/text-edit-diff'); +} + +var _textEditor; + +function _load_textEditor() { + return _textEditor = require('../../../modules/nuclide-commons-atom/text-editor'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _refactorActions; + +function _load_refactorActions() { + return _refactorActions = _interopRequireWildcard(require('./refactorActions')); +} + +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 getEpics(providers) { + return [function getRefactoringsEpic(actions) { + return actions.ofType('open').switchMap(() => { + return _rxjsBundlesRxMinJs.Observable.fromPromise(getRefactorings(providers)).takeUntil(actions); + }); + }, function executeRefactoringEpic(actions) { + return actions.ofType('execute').switchMap(action => { + // Flow doesn't understand the implications of ofType :( + if (!(action.type === 'execute')) { + throw new Error('Invariant violation: "action.type === \'execute\'"'); + } + + return executeRefactoring(action).concat( + // Default handler if we don't get a result. + _rxjsBundlesRxMinJs.Observable.of((_refactorActions || _load_refactorActions()).error('execute', Error('Could not refactor.')))).takeUntil(actions.filter(x => x.type !== 'progress')); + }); + }, function applyRefactoringEpic(actions) { + return actions.ofType('apply').switchMap(action => { + if (!(action.type === 'apply')) { + throw new Error('Invariant violation: "action.type === \'apply\'"'); + } + + return applyRefactoring(action).takeUntil(actions.ofType('close')); + }); + }, function loadDiffPreviewEpic(actions) { + return actions.ofType('load-diff-preview').switchMap(action => { + if (!(action.type === 'load-diff-preview')) { + throw new Error('Invariant violation: "action.type === \'load-diff-preview\'"'); + } + + return _rxjsBundlesRxMinJs.Observable.fromPromise(loadDiffPreview(action.payload.uri, action.payload.response)); + }); + }, function handleErrors(actions) { + return actions.ofType('error').map(action => { + if (!(action.type === 'error')) { + throw new Error('Invariant violation: "action.type === \'error\'"'); + } + + const { source, error } = action.payload; + const sourceName = source === 'got-refactorings' ? 'getting refactors' : 'executing refactor'; + (0, (_log4js || _load_log4js()).getLogger)('nuclide-refactorizer').error(`Error ${sourceName}:`, error); + atom.notifications.addError(`Error ${sourceName}`, { + description: error.message, + dismissable: true + }); + return (_refactorActions || _load_refactorActions()).close(); + }); + }]; +} /** + * 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. + * + * + * @format + */ + +async function getRefactorings(providers) { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('nuclide-refactorizer:get-refactorings'); const editor = atom.workspace.getActiveTextEditor(); if (editor == null || editor.getPath() == null) { - return Actions.error( - 'get-refactorings', - Error('Must be run from a saved file.'), - ); + return (_refactorActions || _load_refactorActions()).error('get-refactorings', Error('Must be run from a saved file.')); } const provider = providers.getProviderForEditor(editor); if (provider == null) { - return Actions.error('get-refactorings', Error('No providers found.')); + return (_refactorActions || _load_refactorActions()).error('get-refactorings', Error('No providers found.')); } try { const selectedRange = editor.getSelectedBufferRange(); - const availableRefactorings = await provider.refactorings( - editor, - selectedRange, - ); - availableRefactorings.sort( - (x, y) => (x.disabled === true ? 1 : 0) - (y.disabled === true ? 1 : 0), - ); - return Actions.gotRefactorings( - editor, - selectedRange, - provider, - availableRefactorings, - ); + const availableRefactorings = await provider.refactorings(editor, selectedRange); + availableRefactorings.sort((x, y) => (x.disabled === true ? 1 : 0) - (y.disabled === true ? 1 : 0)); + return (_refactorActions || _load_refactorActions()).gotRefactorings(editor, selectedRange, provider, availableRefactorings); } catch (e) { - return Actions.error('get-refactorings', e); + return (_refactorActions || _load_refactorActions()).error('get-refactorings', e); } } -function executeRefactoring(action: ExecuteAction): Observable { - const {refactoring, provider} = action.payload; - return provider - .refactor(refactoring) - .map(response => { - switch (response.type) { - case 'progress': - return Actions.progress( - response.message, - response.value, - response.max, - ); - case 'edit': - case 'external-edit': - if (response.edits.size <= 1) { - return Actions.apply(response); - } - return Actions.confirm(response); - default: - (response: empty); - throw new Error(); - } - }) - .catch(e => Observable.of(Actions.error('execute', e))); +function executeRefactoring(action) { + const { refactoring, provider } = action.payload; + return provider.refactor(refactoring).map(response => { + switch (response.type) { + case 'progress': + return (_refactorActions || _load_refactorActions()).progress(response.message, response.value, response.max); + case 'edit': + case 'external-edit': + if (response.edits.size <= 1) { + return (_refactorActions || _load_refactorActions()).apply(response); + } + return (_refactorActions || _load_refactorActions()).confirm(response); + default: + response; + throw new Error(); + } + }).catch(e => _rxjsBundlesRxMinJs.Observable.of((_refactorActions || _load_refactorActions()).error('execute', e))); } const FILE_IO_CONCURRENCY = 4; -export function applyRefactoring( - action: ApplyAction, -): Observable { - return Observable.defer(() => { - const {response} = action.payload; - let editStream = Observable.empty(); +function applyRefactoring(action) { + return _rxjsBundlesRxMinJs.Observable.defer(() => { + const { response } = action.payload; + let editStream = _rxjsBundlesRxMinJs.Observable.empty(); if (response.type === 'edit') { // Regular edits are applied directly to open buffers. - // Note that all files must actually be open. for (const [path, edits] of response.edits) { - const editor = existingEditorForUri(path); + const editor = (0, (_textEditor || _load_textEditor()).existingEditorForUri)(path); if (editor != null) { - applyTextEditsToBuffer(editor.getBuffer(), edits); + (0, (_textEdit || _load_textEdit()).applyTextEditsToBuffer)(editor.getBuffer(), edits); } else { - return Observable.of( - Actions.error( - 'execute', - Error(`Expected file ${path} to be open.`), - ), - ); + return _rxjsBundlesRxMinJs.Observable.of((_refactorActions || _load_refactorActions()).error('execute', Error(`Expected file ${path} to be open.`))); } } } else { // External edits are applied directly to disk. - editStream = Observable.from(response.edits) - .mergeMap(async ([path, edits]) => { - const file = getFileForPath(path); - if (file == null) { - throw new Error(`Could not read file ${path}`); - } - let data = await file.read(); - edits.sort((a, b) => a.startOffset - b.startOffset); - edits.reverse().forEach(edit => { - if (edit.oldText != null) { - const oldText = data.substring(edit.startOffset, edit.endOffset); - if (oldText !== edit.oldText) { - throw new Error( - `Cannot apply refactor: file contents of ${path} have changed!`, - ); - } + editStream = _rxjsBundlesRxMinJs.Observable.from(response.edits).mergeMap(async ([path, edits]) => { + const file = (0, (_projects || _load_projects()).getFileForPath)(path); + if (file == null) { + throw new Error(`Could not read file ${path}`); + } + let data = await file.read(); + edits.sort((a, b) => a.startOffset - b.startOffset); + edits.reverse().forEach(edit => { + if (edit.oldText != null) { + const oldText = data.substring(edit.startOffset, edit.endOffset); + if (oldText !== edit.oldText) { + throw new Error(`Cannot apply refactor: file contents of ${path} have changed!`); } - data = - data.slice(0, edit.startOffset) + - edit.newText + - data.slice(edit.endOffset); - }); - await file.write(data); - }, FILE_IO_CONCURRENCY) - .scan((done, _) => done + 1, 0) - .startWith(0) - .map(done => - Actions.progress('Applying edits...', done, response.edits.size), - ); + } + data = data.slice(0, edit.startOffset) + edit.newText + data.slice(edit.endOffset); + }); + await file.write(data); + }, FILE_IO_CONCURRENCY).scan((done, _) => done + 1, 0).startWith(0).map(done => (_refactorActions || _load_refactorActions()).progress('Applying edits...', done, response.edits.size)); } - return Observable.concat( - editStream, - Observable.of(Actions.close()).do(() => - track('nuclide-refactorizer:success'), - ), - ); + return _rxjsBundlesRxMinJs.Observable.concat(editStream, _rxjsBundlesRxMinJs.Observable.of((_refactorActions || _load_refactorActions()).close()).do(() => (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('nuclide-refactorizer:success'))); }); } -async function loadDiffPreview( - uri: NuclideUri, - response: RefactorEditResponse, -): Promise { - const file = getFileForPath(uri); +async function loadDiffPreview(uri, response) { + const file = (0, (_projects || _load_projects()).getFileForPath)(uri); if (file == null) { throw new Error(`Could not read file ${uri}`); } - const buffer = new TextBuffer(await file.read()); + const buffer = new _atom.TextBuffer((await file.read())); const edits = getEdits(uri, buffer, response); - const diffString = toUnifiedDiff(nuclideUri.basename(uri), buffer, edits); + const diffString = (0, (_textEditDiff || _load_textEditDiff()).toUnifiedDiff)((_nuclideUri || _load_nuclideUri()).default.basename(uri), buffer, edits); - return Actions.displayDiffPreview(parse(diffString)); + return (_refactorActions || _load_refactorActions()).displayDiffPreview((0, (_diffparser || _load_diffparser()).default)(diffString)); } -function getEdits( - uri: NuclideUri, - buffer: atom$TextBuffer, - response: RefactorEditResponse, -): Array { +function getEdits(uri, buffer, response) { switch (response.type) { case 'edit': return response.edits.get(uri) || []; @@ -265,13 +230,10 @@ function getEdits( } } -function toTextEdit(buffer: atom$TextBuffer, edit: ExternalTextEdit): TextEdit { +function toTextEdit(buffer, edit) { return { - oldRange: new Range( - buffer.positionForCharacterIndex(edit.startOffset), - buffer.positionForCharacterIndex(edit.endOffset), - ), + oldRange: new _atom.Range(buffer.positionForCharacterIndex(edit.startOffset), buffer.positionForCharacterIndex(edit.endOffset)), oldText: edit.oldText, - newText: edit.newText, + newText: edit.newText }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-refactorizer/lib/refactorReducers.js b/pkg/nuclide-refactorizer/lib/refactorReducers.js index 6926314ea5..21ea5dce88 100644 --- a/pkg/nuclide-refactorizer/lib/refactorReducers.js +++ b/pkg/nuclide-refactorizer/lib/refactorReducers.js @@ -1,41 +1,13 @@ -/** - * 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 strict-local - * @format - */ - -import type {AvailableRefactoring, RefactorProvider} from '..'; - -import type { - BackFromDiffPreviewAction, - ConfirmAction, - DisplayDiffPreviewAction, - ExecuteAction, - GotRefactoringsAction, - LoadDiffPreviewAction, - OpenAction, - PickedRefactorAction, - InlinePickedRefactorAction, - ProgressAction, - RefactorAction, - RefactoringPhase, - RefactorState, -} from './types'; - -import invariant from 'assert'; - -export default function refactorReducers( - state_: ?RefactorState, - action: RefactorAction, -): RefactorState { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = refactorReducers; +function refactorReducers(state_, action) { let state = state_; if (state == null) { - state = {type: 'closed'}; + state = { type: 'closed' }; } // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) @@ -71,28 +43,41 @@ export default function refactorReducers( default: return state; } -} - -function open(state: RefactorState, action: OpenAction): RefactorState { - invariant(state.type === 'closed'); +} /** + * 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. + * + * strict-local + * @format + */ + +function open(state, action) { + if (!(state.type === 'closed')) { + throw new Error('Invariant violation: "state.type === \'closed\'"'); + } return { type: 'open', ui: action.ui, phase: { - type: 'get-refactorings', - }, + type: 'get-refactorings' + } }; } -function gotRefactorings( - state: RefactorState, - action: GotRefactoringsAction, -): RefactorState { - invariant(state.type === 'open'); - invariant(state.phase.type === 'get-refactorings'); +function gotRefactorings(state, action) { + if (!(state.type === 'open')) { + throw new Error('Invariant violation: "state.type === \'open\'"'); + } - const {editor, originalRange} = action.payload; + if (!(state.phase.type === 'get-refactorings')) { + throw new Error('Invariant violation: "state.phase.type === \'get-refactorings\'"'); + } + + const { editor, originalRange } = action.payload; return { type: 'open', @@ -102,69 +87,69 @@ function gotRefactorings( provider: action.payload.provider, editor, originalRange, - availableRefactorings: action.payload.availableRefactorings, - }, + availableRefactorings: action.payload.availableRefactorings + } }; } -function close(state: RefactorState): RefactorState { - invariant(state.type === 'open'); +function close(state) { + if (!(state.type === 'open')) { + throw new Error('Invariant violation: "state.type === \'open\'"'); + } + return { - type: 'closed', + type: 'closed' }; } -function backFromDiffPreview( - state: RefactorState, - action: BackFromDiffPreviewAction, -): RefactorState { - invariant(state.type === 'open'); +function backFromDiffPreview(state, action) { + if (!(state.type === 'open')) { + throw new Error('Invariant violation: "state.type === \'open\'"'); + } - return { - ...state, - phase: action.payload.phase, - }; + return Object.assign({}, state, { + phase: action.payload.phase + }); } -function pickedRefactor( - state: RefactorState, - action: PickedRefactorAction, -): RefactorState { - invariant(state.type === 'open'); - invariant(state.phase.type === 'pick'); +function pickedRefactor(state, action) { + if (!(state.type === 'open')) { + throw new Error('Invariant violation: "state.type === \'open\'"'); + } - const {refactoring} = action.payload; - const {provider, editor, originalRange} = state.phase; + if (!(state.phase.type === 'pick')) { + throw new Error('Invariant violation: "state.phase.type === \'pick\'"'); + } + + const { refactoring } = action.payload; + const { provider, editor, originalRange } = state.phase; return { type: 'open', ui: state.ui, - phase: getRefactoringPhase(refactoring, provider, editor, originalRange), + phase: getRefactoringPhase(refactoring, provider, editor, originalRange) }; } -function inlinePickedRefactor( - state: RefactorState, - action: InlinePickedRefactorAction, -): RefactorState { - const {provider, editor, originalRange, refactoring} = action.payload; +function inlinePickedRefactor(state, action) { + const { provider, editor, originalRange, refactoring } = action.payload; + + if (!(state.type === 'closed')) { + throw new Error('Invariant violation: "state.type === \'closed\'"'); + } - invariant(state.type === 'closed'); - invariant(refactoring.kind === 'freeform'); + if (!(refactoring.kind === 'freeform')) { + throw new Error('Invariant violation: "refactoring.kind === \'freeform\'"'); + } return { type: 'open', ui: 'generic', - phase: getRefactoringPhase(refactoring, provider, editor, originalRange), + phase: getRefactoringPhase(refactoring, provider, editor, originalRange) }; } -function getRefactoringPhase( - refactoring: AvailableRefactoring, - provider: RefactorProvider, - editor: atom$TextEditor, - originalRange: atom$Range, -): RefactoringPhase { +function getRefactoringPhase(refactoring, provider, editor, originalRange) { switch (refactoring.kind) { case 'rename': return { @@ -172,7 +157,7 @@ function getRefactoringPhase( provider, editor, originalPoint: originalRange.start, - symbolAtPoint: refactoring.symbolAtPoint, + symbolAtPoint: refactoring.symbolAtPoint }; case 'freeform': return { @@ -180,84 +165,87 @@ function getRefactoringPhase( provider, editor, originalRange, - refactoring, + refactoring }; default: - invariant(false, `Unexpected refactoring kind ${refactoring.kind}`); + if (!false) { + throw new Error(`Unexpected refactoring kind ${refactoring.kind}`); + } + } } -function executeRefactor( - state: RefactorState, - action: ExecuteAction, -): RefactorState { - invariant(state.type === 'open'); +function executeRefactor(state, action) { + if (!(state.type === 'open')) { + throw new Error('Invariant violation: "state.type === \'open\'"'); + } + return { type: 'open', ui: state.ui, phase: { - type: 'execute', - }, + type: 'execute' + } }; } -function confirmRefactor( - state: RefactorState, - action: ConfirmAction, -): RefactorState { - invariant(state.type === 'open'); +function confirmRefactor(state, action) { + if (!(state.type === 'open')) { + throw new Error('Invariant violation: "state.type === \'open\'"'); + } + return { type: 'open', ui: state.ui, phase: { type: 'confirm', - response: action.payload.response, - }, + response: action.payload.response + } }; } -function loadDiffPreview( - state: RefactorState, - action: LoadDiffPreviewAction, -): RefactorState { - invariant(state.type === 'open'); +function loadDiffPreview(state, action) { + if (!(state.type === 'open')) { + throw new Error('Invariant violation: "state.type === \'open\'"'); + } - return { - ...state, + return Object.assign({}, state, { phase: { type: 'diff-preview', loading: true, diffs: [], - previousPhase: action.payload.previousPhase, - }, - }; + previousPhase: action.payload.previousPhase + } + }); } -function displayDiffPreview( - state: RefactorState, - action: DisplayDiffPreviewAction, -): RefactorState { - invariant(state.type === 'open'); - invariant(state.phase.type === 'diff-preview'); +function displayDiffPreview(state, action) { + if (!(state.type === 'open')) { + throw new Error('Invariant violation: "state.type === \'open\'"'); + } + + if (!(state.phase.type === 'diff-preview')) { + throw new Error('Invariant violation: "state.phase.type === \'diff-preview\'"'); + } - return { - ...state, - phase: { - ...state.phase, + return Object.assign({}, state, { + phase: Object.assign({}, state.phase, { loading: false, - diffs: action.payload.diffs, - }, - }; + diffs: action.payload.diffs + }) + }); } -function progress(state: RefactorState, action: ProgressAction): RefactorState { - invariant(state.type === 'open'); +function progress(state, action) { + if (!(state.type === 'open')) { + throw new Error('Invariant violation: "state.type === \'open\'"'); + } + return { type: 'open', ui: state.ui, - phase: { - type: 'progress', - ...action.payload, - }, + phase: Object.assign({ + type: 'progress' + }, action.payload) }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-refactorizer/lib/refactorStore.js b/pkg/nuclide-refactorizer/lib/refactorStore.js index 6bae6caad7..21ed4370bb 100644 --- a/pkg/nuclide-refactorizer/lib/refactorStore.js +++ b/pkg/nuclide-refactorizer/lib/refactorStore.js @@ -1,51 +1,68 @@ -/** - * 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 - */ - -import type {RefactorProvider} from '..'; -import type {Observable} from 'rxjs'; - -import type {Store} from './types'; - -import {createStore, applyMiddleware} from 'redux'; -import {Subject} from 'rxjs'; - -import type ProviderRegistry from 'nuclide-commons-atom/ProviderRegistry'; -import { - createEpicMiddleware, - combineEpics, -} from 'nuclide-commons/redux-observable'; -import {getLogger} from 'log4js'; - -import refactorReducers from './refactorReducers'; -import {getEpics} from './refactorEpics'; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getStore = getStore; +exports.getErrors = getErrors; + +var _reduxMin; + +function _load_reduxMin() { + return _reduxMin = require('redux/dist/redux.min.js'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _reduxObservable; + +function _load_reduxObservable() { + return _reduxObservable = require('../../../modules/nuclide-commons/redux-observable'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _refactorReducers; + +function _load_refactorReducers() { + return _refactorReducers = _interopRequireDefault(require('./refactorReducers')); +} + +var _refactorEpics; + +function _load_refactorEpics() { + return _refactorEpics = require('./refactorEpics'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // TODO create this lazily -const errors: Subject = new Subject(); +const errors = new _rxjsBundlesRxMinJs.Subject(); /** + * 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. + * + * + * @format + */ -function handleError(error: mixed): void { - getLogger('nuclide-refactorizer').error( - 'Uncaught exception in refactoring:', - error, - ); +function handleError(error) { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-refactorizer').error('Uncaught exception in refactoring:', error); errors.next(error); } -export function getStore(providers: ProviderRegistry): Store { +function getStore(providers) { const rootEpic = (actions, store) => { - return combineEpics(...getEpics(providers))(actions, store).catch( - (error, stream) => { - handleError(error); - return stream; - }, - ); + return (0, (_reduxObservable || _load_reduxObservable()).combineEpics)(...(0, (_refactorEpics || _load_refactorEpics()).getEpics)(providers))(actions, store).catch((error, stream) => { + handleError(error); + return stream; + }); }; const exceptionHandler = store => next => action => { try { @@ -54,12 +71,9 @@ export function getStore(providers: ProviderRegistry): Store { handleError(e); } }; - return createStore( - refactorReducers, - applyMiddleware(exceptionHandler, createEpicMiddleware(rootEpic)), - ); + return (0, (_reduxMin || _load_reduxMin()).createStore)((_refactorReducers || _load_refactorReducers()).default, (0, (_reduxMin || _load_reduxMin()).applyMiddleware)(exceptionHandler, (0, (_reduxObservable || _load_reduxObservable()).createEpicMiddleware)(rootEpic))); } -export function getErrors(): Observable { +function getErrors() { return errors.asObservable(); -} +} \ No newline at end of file diff --git a/pkg/nuclide-refactorizer/lib/refactorUIs.js b/pkg/nuclide-refactorizer/lib/refactorUIs.js index 18d398eb7c..5f5c85e9ed 100644 --- a/pkg/nuclide-refactorizer/lib/refactorUIs.js +++ b/pkg/nuclide-refactorizer/lib/refactorUIs.js @@ -1,3 +1,36 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.initRefactorUIs = initRefactorUIs; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _reactDom = _interopRequireDefault(require('react-dom')); + +var _MainRefactorComponent; + +function _load_MainRefactorComponent() { + return _MainRefactorComponent = require('./components/MainRefactorComponent'); +} + +var _refactorActions; + +function _load_refactorActions() { + return _refactorActions = _interopRequireWildcard(require('./refactorActions')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,151 +38,118 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {RefactorUIFactory, Store, RefactorState} from './types'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import invariant from 'assert'; - -import {MainRefactorComponent} from './components/MainRefactorComponent'; -import * as Actions from './refactorActions'; +const refactorUIFactories = [genericRefactorUI, closeOnEscape, focusEditorOnClose, renameShortcut]; -const refactorUIFactories: Array = [ - genericRefactorUI, - closeOnEscape, - focusEditorOnClose, - renameShortcut, -]; - -export function initRefactorUIs(store: Store): IDisposable { +function initRefactorUIs(store) { const disposables = refactorUIFactories.map(uiFn => uiFn(store)); - return new UniversalDisposable(...disposables); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(...disposables); } -function genericRefactorUI(store: Store): IDisposable { - const renderer: GenericUIRenderer = new GenericUIRenderer(store); - const disposeFn: () => void = store.subscribe(() => { +function genericRefactorUI(store) { + const renderer = new GenericUIRenderer(store); + const disposeFn = store.subscribe(() => { const state = store.getState(); - if ( - state.type === 'closed' || - (state.type === 'open' && state.ui === 'generic') - ) { + if (state.type === 'closed' || state.type === 'open' && state.ui === 'generic') { renderer.renderState(state); } }); - return new UniversalDisposable(disposeFn); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(disposeFn); } -function closeOnEscape(store: Store): IDisposable { - let escapeSubscription: ?IDisposable = null; - return new UniversalDisposable( - store.subscribe(() => { - const state = store.getState(); - if (state.type === 'open' && escapeSubscription == null) { - escapeSubscription = atom.commands.add('body', 'core:cancel', () => { - store.dispatch(Actions.close()); - }); - } else if (state.type === 'closed') { - invariant(escapeSubscription != null); - escapeSubscription.dispose(); - escapeSubscription = null; +function closeOnEscape(store) { + let escapeSubscription = null; + return new (_UniversalDisposable || _load_UniversalDisposable()).default(store.subscribe(() => { + const state = store.getState(); + if (state.type === 'open' && escapeSubscription == null) { + escapeSubscription = atom.commands.add('body', 'core:cancel', () => { + store.dispatch((_refactorActions || _load_refactorActions()).close()); + }); + } else if (state.type === 'closed') { + if (!(escapeSubscription != null)) { + throw new Error('Invariant violation: "escapeSubscription != null"'); } - }), - ); -} -function focusEditorOnClose(store: Store): IDisposable { - return new UniversalDisposable( - store.subscribe(() => { - const state = store.getState(); - if (state.type === 'closed') { - const editor = atom.workspace.getActiveTextEditor(); - if (editor == null) { - return; - } - const pane = atom.workspace.paneForItem(editor); - if (pane == null) { - return; - } - pane.activate(); - pane.activateItem(editor); - } - }), - ); + escapeSubscription.dispose(); + escapeSubscription = null; + } + })); } -function renameShortcut(store: Store): IDisposable { - const renderer: GenericUIRenderer = new GenericUIRenderer(store); - return new UniversalDisposable( - store.subscribe(() => { - const state = store.getState(); - if (state.type === 'closed') { - renderer.renderState(state); +function focusEditorOnClose(store) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(store.subscribe(() => { + const state = store.getState(); + if (state.type === 'closed') { + const editor = atom.workspace.getActiveTextEditor(); + if (editor == null) { return; } - if (state.ui === 'rename') { - const {phase} = state; - switch (phase.type) { - case 'pick': - let renameRefactoring = null; - for (const refactoring of phase.availableRefactorings) { - if ( - refactoring.kind === 'rename' || - (refactoring.kind === 'freeform' && - refactoring.disabled !== false && - refactoring.name.match(/rename/i)) - ) { - renameRefactoring = refactoring; - break; - } - } - if (renameRefactoring == null) { - atom.notifications.addWarning( - 'Unable to rename at this location', - ); - store.dispatch(Actions.close()); - } else { - store.dispatch(Actions.pickedRefactor(renameRefactoring)); + const pane = atom.workspace.paneForItem(editor); + if (pane == null) { + return; + } + pane.activate(); + pane.activateItem(editor); + } + })); +} + +function renameShortcut(store) { + const renderer = new GenericUIRenderer(store); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(store.subscribe(() => { + const state = store.getState(); + if (state.type === 'closed') { + renderer.renderState(state); + return; + } + if (state.ui === 'rename') { + const { phase } = state; + switch (phase.type) { + case 'pick': + let renameRefactoring = null; + for (const refactoring of phase.availableRefactorings) { + if (refactoring.kind === 'rename' || refactoring.kind === 'freeform' && refactoring.disabled !== false && refactoring.name.match(/rename/i)) { + renameRefactoring = refactoring; + break; } - break; - default: - renderer.renderState(state); - } + } + if (renameRefactoring == null) { + atom.notifications.addWarning('Unable to rename at this location'); + store.dispatch((_refactorActions || _load_refactorActions()).close()); + } else { + store.dispatch((_refactorActions || _load_refactorActions()).pickedRefactor(renameRefactoring)); + } + break; + default: + renderer.renderState(state); } - }), - ); + } + })); } class GenericUIRenderer { - _panel: ?atom$Panel; - _store: Store; - constructor(store: Store) { + constructor(store) { this._store = store; } - renderState(state: RefactorState) { + renderState(state) { if (state.type === 'open') { if (this._panel == null) { const element = document.createElement('div'); - this._panel = atom.workspace.addModalPanel({item: element}); + this._panel = atom.workspace.addModalPanel({ item: element }); } - ReactDOM.render( - , - this._panel.getItem(), - ); + _reactDom.default.render(_react.createElement((_MainRefactorComponent || _load_MainRefactorComponent()).MainRefactorComponent, { appState: state, store: this._store }), this._panel.getItem()); } else { if (this._panel != null) { const panel = this._panel; - ReactDOM.unmountComponentAtNode(panel.getItem()); + _reactDom.default.unmountComponentAtNode(panel.getItem()); panel.destroy(); this._panel = null; } } } -} +} \ No newline at end of file diff --git a/pkg/nuclide-refactorizer/lib/rpc-types.js b/pkg/nuclide-refactorizer/lib/rpc-types.js index 26739efff4..a726efc43f 100644 --- a/pkg/nuclide-refactorizer/lib/rpc-types.js +++ b/pkg/nuclide-refactorizer/lib/rpc-types.js @@ -1,108 +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 - */ - -import type {TextEdit} from 'nuclide-commons-atom/text-edit'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -export type RenameRefactoring = { - kind: 'rename', - symbolAtPoint: { - text: string, - range: atom$Range, - }, -}; - -export type FreeformEnumValue = { - value: string, - description: string, -}; - -// Factoring out `description` confuses Flow when filtering on the type. -export type FreeformRefactoringArgument = - | { - type: 'string', - name: string, - description: string, - default?: string, - } - | { - type: 'boolean', - name: string, - description: string, - default?: boolean, - } - | { - type: 'enum', - name: string, - description: string, - options: Array, - default?: string, - }; - -// A freeform refactoring type. -// This allows providers to define completely new refactoring commands, -// as well as ask for arbitrary arguments to the refactoring command. -export type FreeformRefactoring = { - kind: 'freeform', - // Unique identifier which will be used in the request. - id: string, - // Display name of the refactoring. - name: string, - // User-friendly description of what the refactoring does. - description: string, - // Full affected range of the refactoring. - range: atom$Range, - // Additional arguments to be requested from the user. - // The `name`s should be unique identifiers, which will be used in the request. - arguments: Array, - // Providers can return disabled refactorings to improve discoverability. - disabled?: boolean, -}; - -export type AvailableRefactoring = RenameRefactoring | FreeformRefactoring; - -// For edits outside of Atom editors, it's easier and more efficient to use -// absolute character offsets rather than line/column ranges. -export type ExternalTextEdit = { - startOffset: number, - endOffset: number, - newText: string, - // If included, this will be used to verify that the edit still applies cleanly. - oldText?: string, -}; - -// Regular "edits" are intended for changes inside open files. -// These will be applied to the buffer and will not be immediately saved. -// This is appropriate for small-scale changes to a set of files. -export type EditResponse = { - type: 'edit', - edits: Map>, -}; - -// "externalEdits" are intended for changes that include unopened files. -// External edits will be directly written to files on disk, bypassing Atom. -// They also have a slightly different format for efficiency purposes. -export type ExternalEditResponse = { - type: 'external-edit', - edits: Map>, -}; - -// An intermediate response to display progress in the UI. -export type ProgressResponse = { - type: 'progress', - message: string, - value: number, - max: number, -}; - -export type RefactorEditResponse = EditResponse | ExternalEditResponse; - -export type RefactorResponse = RefactorEditResponse | ProgressResponse; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-refactorizer/lib/types.js b/pkg/nuclide-refactorizer/lib/types.js index 99c2e37dc1..a726efc43f 100644 --- a/pkg/nuclide-refactorizer/lib/types.js +++ b/pkg/nuclide-refactorizer/lib/types.js @@ -1,234 +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 - */ - -/* - * This file houses types that are internal to this package. Types that are part of its public - * interface are exported from main.js - */ - -import type { - AvailableRefactoring, - FreeformRefactoring, - RefactorRequest, - RefactorProvider, -} from '..'; - -import type {RefactorEditResponse} from './rpc-types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -export type Store = { - // Returns unsubscribe function - subscribe(fn: () => mixed): () => void, - dispatch(action: RefactorAction): void, - getState(): RefactorState, -}; - -export type RefactorUIFactory = (store: Store) => IDisposable; - -export type RefactorUI = 'generic' | 'simple-rename' | 'rename'; - -// State - -export type ClosedState = {| - type: 'closed', -|}; - -export type OpenState = {| - type: 'open', - ui: RefactorUI, - phase: Phase, -|}; - -export type RefactorState = ClosedState | OpenState; - -export type GetRefactoringsPhase = {| - type: 'get-refactorings', -|}; - -export type PickPhase = {| - type: 'pick', - provider: RefactorProvider, - originalRange: atom$Range, - editor: atom$TextEditor, - availableRefactorings: Array, -|}; - -export type RenamePhase = {| - type: 'rename', - provider: RefactorProvider, - editor: atom$TextEditor, - originalPoint: atom$Point, - symbolAtPoint: { - text: string, - range: atom$Range, - }, -|}; - -export type FreeformPhase = {| - type: 'freeform', - provider: RefactorProvider, - editor: atom$TextEditor, - originalRange: atom$Range, - refactoring: FreeformRefactoring, -|}; - -export type ExecutePhase = {| - type: 'execute', -|}; - -// For multi-file changes, add a confirmation step. -export type ConfirmPhase = {| - type: 'confirm', - response: RefactorEditResponse, -|}; - -export type DiffPreviewPhase = {| - type: 'diff-preview', - loading: boolean, - diffs: Array, - previousPhase: Phase, -|}; - -export type ProgressPhase = {| - type: 'progress', - message: string, - value: number, - max: number, -|}; - -export type Phase = - | GetRefactoringsPhase - | PickPhase - | RenamePhase - | FreeformPhase - | ExecutePhase - | ConfirmPhase - | DiffPreviewPhase - | ProgressPhase; - -export type RefactoringPhase = RenamePhase | FreeformPhase; - -// Actions - -export type OpenAction = {| - type: 'open', - ui: RefactorUI, -|}; - -export type BackFromDiffPreviewAction = {| - type: 'back-from-diff-preview', - payload: { - phase: Phase, - }, -|}; - -export type GotRefactoringsAction = {| - type: 'got-refactorings', - payload: { - originalRange: atom$Range, - editor: atom$TextEditor, - provider: RefactorProvider, - availableRefactorings: Array, - }, -|}; - -export type ErrorSource = 'get-refactorings' | 'execute'; - -export type ErrorAction = {| - type: 'error', - payload: { - source: ErrorSource, - error: Error, - }, -|}; - -export type CloseAction = {| - type: 'close', -|}; - -export type PickedRefactorAction = {| - type: 'picked-refactor', - payload: { - refactoring: AvailableRefactoring, - }, -|}; - -export type InlinePickedRefactorAction = {| - type: 'inline-picked-refactor', - payload: { - originalRange: atom$Range, - editor: atom$TextEditor, - provider: RefactorProvider, - refactoring: AvailableRefactoring, - }, -|}; - -export type ExecuteAction = {| - type: 'execute', - payload: { - provider: RefactorProvider, - refactoring: RefactorRequest, - }, -|}; - -export type ConfirmAction = {| - type: 'confirm', - payload: { - response: RefactorEditResponse, - }, -|}; - -export type LoadDiffPreviewAction = {| - type: 'load-diff-preview', - payload: { - previousPhase: Phase, - uri: NuclideUri, - response: RefactorEditResponse, - }, -|}; - -export type DisplayDiffPreviewAction = {| - type: 'display-diff-preview', - payload: { - diffs: Array, - }, -|}; - -export type ApplyAction = {| - type: 'apply', - payload: { - response: RefactorEditResponse, - }, -|}; - -export type ProgressAction = {| - type: 'progress', - payload: { - message: string, - value: number, - max: number, - }, -|}; - -export type RefactorAction = - | OpenAction - | CloseAction - | BackFromDiffPreviewAction - | PickedRefactorAction - | InlinePickedRefactorAction - | GotRefactoringsAction - | ErrorAction - | ExecuteAction - | ConfirmAction - | LoadDiffPreviewAction - | DisplayDiffPreviewAction - | ApplyAction - | ProgressAction; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-related-files/lib/JumpToRelatedFile.js b/pkg/nuclide-related-files/lib/JumpToRelatedFile.js index a6c647d4e5..bcf92e6108 100644 --- a/pkg/nuclide-related-files/lib/JumpToRelatedFile.js +++ b/pkg/nuclide-related-files/lib/JumpToRelatedFile.js @@ -1,3 +1,40 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _RelatedFileFinder; + +function _load_RelatedFileFinder() { + return _RelatedFileFinder = _interopRequireDefault(require('./RelatedFileFinder')); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _goToLocation; + +function _load_goToLocation() { + return _goToLocation = require('../../../modules/nuclide-commons-atom/go-to-location'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Sets up listeners so the user can jump to related files. + * + * Clients must call `dispose()` once they're done with an instance. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,22 +42,11 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import RelatedFileFinder from './RelatedFileFinder'; -import {trackTiming} from '../../nuclide-analytics'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {goToLocation} from 'nuclide-commons-atom/go-to-location'; - -/** - * Sets up listeners so the user can jump to related files. - * - * Clients must call `dispose()` once they're done with an instance. - */ -export default class JumpToRelatedFile { - _subscription: IDisposable; +class JumpToRelatedFile { constructor() { this._subscription = atom.commands.add('atom-workspace', { @@ -32,10 +58,7 @@ export default class JumpToRelatedFile { const path = editor.getPath(); // flowlint-next-line sketchy-null-string:off if (path) { - trackTiming( - 'nuclide-related-files:switch-between-header-source', - async () => this._open(await this.getNextRelatedFile(path)), - ); + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)('nuclide-related-files:switch-between-header-source', async () => this._open((await this.getNextRelatedFile(path)))); } }, 'nuclide-related-files:jump-to-next-related-file': () => { @@ -46,10 +69,7 @@ export default class JumpToRelatedFile { const path = editor.getPath(); // flowlint-next-line sketchy-null-string:off if (path) { - trackTiming( - 'nuclide-related-files:jump-to-next-related-file', - async () => this._open(await this.getNextRelatedFile(path)), - ); + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)('nuclide-related-files:jump-to-next-related-file', async () => this._open((await this.getNextRelatedFile(path)))); } }, 'nuclide-related-files:jump-to-previous-related-file': () => { @@ -60,16 +80,13 @@ export default class JumpToRelatedFile { const path = editor.getPath(); // flowlint-next-line sketchy-null-string:off if (path) { - trackTiming( - 'nuclide-related-files:jump-to-previous-related-file', - async () => this._open(await this.getPreviousRelatedFile(path)), - ); + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)('nuclide-related-files:jump-to-previous-related-file', async () => this._open((await this.getPreviousRelatedFile(path)))); } - }, + } }); } - dispose(): void { + dispose() { this._subscription.dispose(); } @@ -77,45 +94,36 @@ export default class JumpToRelatedFile { * Gets the next related file, which Xcode defines as the one that comes * before the current one alphabetically. */ - async getNextRelatedFile(path: string): Promise { - const {relatedFiles, index} = await RelatedFileFinder.find( - path, - this._getFileTypeWhitelist(), - ); + async getNextRelatedFile(path) { + const { relatedFiles, index } = await (_RelatedFileFinder || _load_RelatedFileFinder()).default.find(path, this._getFileTypeWhitelist()); if (index === -1) { return path; } - return relatedFiles[ - (relatedFiles.length + index - 1) % relatedFiles.length - ]; + return relatedFiles[(relatedFiles.length + index - 1) % relatedFiles.length]; } /** * Gets the previous related file, which Xcode defines as the one that comes * after the current one alphabetically. */ - async getPreviousRelatedFile(path: string): Promise { - const {relatedFiles, index} = await RelatedFileFinder.find( - path, - this._getFileTypeWhitelist(), - ); + async getPreviousRelatedFile(path) { + const { relatedFiles, index } = await (_RelatedFileFinder || _load_RelatedFileFinder()).default.find(path, this._getFileTypeWhitelist()); if (index === -1) { return path; } return relatedFiles[(index + 1) % relatedFiles.length]; } - _getFileTypeWhitelist(): Set { - const fileTypeWhitelist: Array = (featureConfig.get( - 'nuclide-related-files.fileTypeWhitelist', - ): any); + _getFileTypeWhitelist() { + const fileTypeWhitelist = (_featureConfig || _load_featureConfig()).default.get('nuclide-related-files.fileTypeWhitelist'); return new Set(fileTypeWhitelist); } - _open(path: string) { - if (featureConfig.get('nuclide-related-files.openInNextPane')) { + _open(path) { + if ((_featureConfig || _load_featureConfig()).default.get('nuclide-related-files.openInNextPane')) { atom.workspace.activateNextPane(); } - goToLocation(path); + (0, (_goToLocation || _load_goToLocation()).goToLocation)(path); } } +exports.default = JumpToRelatedFile; \ No newline at end of file diff --git a/pkg/nuclide-related-files/lib/RelatedFileFinder.js b/pkg/nuclide-related-files/lib/RelatedFileFinder.js index 932fa813a9..1bf7bad9d4 100644 --- a/pkg/nuclide-related-files/lib/RelatedFileFinder.js +++ b/pkg/nuclide-related-files/lib/RelatedFileFinder.js @@ -1,3 +1,35 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,19 +37,11 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {RelatedFilesProvider} from './types'; - -import {getFileSystemServiceByNuclideUri} from '../../nuclide-remote-connection'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {timeoutPromise} from 'nuclide-commons/promise'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -const relatedFilesProviders: Set = new Set(); +const relatedFilesProviders = new Set(); /** * Finds related files, to be used in `JumpToRelatedFile`. @@ -28,31 +52,21 @@ const relatedFilesProviders: Set = new Set(); * * For now, we only search in the given path's directory for related files. */ -export default class RelatedFileFinder { - static registerRelatedFilesProvider( - provider: RelatedFilesProvider, - ): IDisposable { +class RelatedFileFinder { + static registerRelatedFilesProvider(provider) { relatedFilesProviders.add(provider); - return new UniversalDisposable(() => - relatedFilesProviders.delete(provider), - ); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => relatedFilesProviders.delete(provider)); } - static getRelatedFilesProvidersDisposable(): IDisposable { - return new UniversalDisposable(() => relatedFilesProviders.clear()); + static getRelatedFilesProvidersDisposable() { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => relatedFilesProviders.clear()); } - static async _findRelatedFilesFromProviders( - path: NuclideUri, - ): Promise> { - const relatedLists = await Promise.all( - Array.from(relatedFilesProviders.values()).map(provider => - timeoutPromise(provider.getRelatedFiles(path), 1000).catch(error => { - // silently catch the error and return an empty result - return []; - }), - ), - ); + static async _findRelatedFilesFromProviders(path) { + const relatedLists = await Promise.all(Array.from(relatedFilesProviders.values()).map(provider => (0, (_promise || _load_promise()).timeoutPromise)(provider.getRelatedFiles(path), 1000).catch(error => { + // silently catch the error and return an empty result + return []; + }))); const relatedFiles = new Set(); for (const relatedList of relatedLists) { for (const relatedFile of relatedList) { @@ -71,33 +85,24 @@ export default class RelatedFileFinder { * filePath should always be in the result * @return The related files and the given path's index into it. */ - static async find( - filePath: NuclideUri, - fileTypeWhitelist?: Set = new Set(), - ): Promise<{relatedFiles: Array, index: number}> { - const dirName = nuclideUri.dirname(filePath); + static async find(filePath, fileTypeWhitelist = new Set()) { + const dirName = (_nuclideUri || _load_nuclideUri()).default.dirname(filePath); const prefix = getPrefix(filePath); - const service = getFileSystemServiceByNuclideUri(filePath); + const service = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getFileSystemServiceByNuclideUri)(filePath); const listing = await service.readdir(dirName); // Here the filtering logic: // first get all files with the same prefix -> filelist, // add the related files from external providers // get all the files that matches the whitelist -> wlFilelist; // check the wlFilelist: if empty, use filelist - const filelist = listing - .filter(entry => { - const [name, isFile] = entry; - return isFile && !name.endsWith('~') && getPrefix(name) === prefix; - }) - .map(entry => nuclideUri.join(dirName, entry[0])) - .concat(await RelatedFileFinder._findRelatedFilesFromProviders(filePath)); - - let wlFilelist = - fileTypeWhitelist.size <= 0 - ? filelist - : filelist.filter(otherFilePath => { - return fileTypeWhitelist.has(nuclideUri.extname(otherFilePath)); - }); + const filelist = listing.filter(entry => { + const [name, isFile] = entry; + return isFile && !name.endsWith('~') && getPrefix(name) === prefix; + }).map(entry => (_nuclideUri || _load_nuclideUri()).default.join(dirName, entry[0])).concat((await RelatedFileFinder._findRelatedFilesFromProviders(filePath))); + + let wlFilelist = fileTypeWhitelist.size <= 0 ? filelist : filelist.filter(otherFilePath => { + return fileTypeWhitelist.has((_nuclideUri || _load_nuclideUri()).default.extname(otherFilePath)); + }); if (wlFilelist.length <= 0) { // no files in white list wlFilelist = filelist; @@ -112,13 +117,14 @@ export default class RelatedFileFinder { return { relatedFiles, - index: relatedFiles.indexOf(filePath), + index: relatedFiles.indexOf(filePath) }; } } -function getPrefix(filePath: NuclideUri): string { - let base = nuclideUri.basename(filePath); +exports.default = RelatedFileFinder; +function getPrefix(filePath) { + let base = (_nuclideUri || _load_nuclideUri()).default.basename(filePath); // Strip off the extension. const pos = base.lastIndexOf('.'); if (pos !== -1) { @@ -127,4 +133,4 @@ function getPrefix(filePath: NuclideUri): string { // In Objective-C we often have the X + XInternal.h for implementation methods. // Similarly, C++ users often use X.h + X-inl.h. return base.replace(/(Internal|-inl)$/, ''); -} +} \ No newline at end of file diff --git a/pkg/nuclide-related-files/lib/main.js b/pkg/nuclide-related-files/lib/main.js index 2797674d15..25984b15aa 100644 --- a/pkg/nuclide-related-files/lib/main.js +++ b/pkg/nuclide-related-files/lib/main.js @@ -1,3 +1,32 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.activate = activate; +exports.consumeRelatedFilesProvider = consumeRelatedFilesProvider; +exports.deactivate = deactivate; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _JumpToRelatedFile; + +function _load_JumpToRelatedFile() { + return _JumpToRelatedFile = _interopRequireDefault(require('./JumpToRelatedFile')); +} + +var _RelatedFileFinder; + +function _load_RelatedFileFinder() { + return _RelatedFileFinder = _interopRequireDefault(require('./RelatedFileFinder')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,59 +34,35 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {RelatedFilesProvider} from './types'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import JumpToRelatedFile from './JumpToRelatedFile'; -import RelatedFileFinder from './RelatedFileFinder'; - -let subscriptions: ?UniversalDisposable = null; +let subscriptions = null; // Only expose a context menu for files in languages that have header files. -const GRAMMARS_WITH_HEADER_FILES = new Set([ - 'source.c', - 'source.cpp', - 'source.objc', - 'source.objcpp', - 'source.ocaml', -]); - -export function activate() { - subscriptions = new UniversalDisposable( - new JumpToRelatedFile(), - atom.contextMenu.add({ - 'atom-text-editor': [ - { - label: 'Switch Between Header/Source', - command: 'nuclide-related-files:jump-to-next-related-file', - shouldDisplay() { - const editor = atom.workspace.getActiveTextEditor(); - return ( - editor != null && - GRAMMARS_WITH_HEADER_FILES.has(editor.getGrammar().scopeName) - ); - }, - }, - {type: 'separator'}, - ], - }), - RelatedFileFinder.getRelatedFilesProvidersDisposable(), - ); +const GRAMMARS_WITH_HEADER_FILES = new Set(['source.c', 'source.cpp', 'source.objc', 'source.objcpp', 'source.ocaml']); + +function activate() { + subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(new (_JumpToRelatedFile || _load_JumpToRelatedFile()).default(), atom.contextMenu.add({ + 'atom-text-editor': [{ + label: 'Switch Between Header/Source', + command: 'nuclide-related-files:jump-to-next-related-file', + shouldDisplay() { + const editor = atom.workspace.getActiveTextEditor(); + return editor != null && GRAMMARS_WITH_HEADER_FILES.has(editor.getGrammar().scopeName); + } + }, { type: 'separator' }] + }), (_RelatedFileFinder || _load_RelatedFileFinder()).default.getRelatedFilesProvidersDisposable()); } -export function consumeRelatedFilesProvider( - provider: RelatedFilesProvider, -): IDisposable { - return RelatedFileFinder.registerRelatedFilesProvider(provider); +function consumeRelatedFilesProvider(provider) { + return (_RelatedFileFinder || _load_RelatedFileFinder()).default.registerRelatedFilesProvider(provider); } -export function deactivate() { +function deactivate() { if (subscriptions != null) { subscriptions.dispose(); subscriptions = null; } -} +} \ No newline at end of file diff --git a/pkg/nuclide-related-files/lib/types.js b/pkg/nuclide-related-files/lib/types.js index 0bfc0a78c0..a726efc43f 100644 --- a/pkg/nuclide-related-files/lib/types.js +++ b/pkg/nuclide-related-files/lib/types.js @@ -1,16 +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 - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -export type RelatedFilesProvider = { - getRelatedFiles: (path: NuclideUri) => Promise>, -}; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-related-files/spec/JumpToRelatedFile-spec.js b/pkg/nuclide-related-files/spec/JumpToRelatedFile-spec.js deleted file mode 100644 index fd55d7c521..0000000000 --- a/pkg/nuclide-related-files/spec/JumpToRelatedFile-spec.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import JumpToRelatedFile from '../lib/JumpToRelatedFile'; -import RelatedFileFinder from '../lib/RelatedFileFinder'; - -describe('JumpToRelatedFile', () => { - const relatedFiles = ['dir/Test.h', 'dir/Test.m', 'dir/TestInternal.h']; - let currentFile = ''; - - beforeEach(() => { - spyOn(RelatedFileFinder, 'find').andCallFake(() => { - return {relatedFiles, index: relatedFiles.indexOf(currentFile)}; - }); - }); - - describe('@getNextRelatedFile_', () => { - it('gets next related file at the start of the sequence', () => { - waitsForPromise(async () => { - currentFile = 'dir/Test.h'; - - const jumpToRelatedFile = new JumpToRelatedFile(); - expect(await jumpToRelatedFile.getNextRelatedFile(currentFile)).toEqual( - 'dir/TestInternal.h', - ); - }); - }); - - it('gets next related file in the middle of the sequence', () => { - waitsForPromise(async () => { - currentFile = 'dir/Test.m'; - - const jumpToRelatedFile = new JumpToRelatedFile(); - expect(await jumpToRelatedFile.getNextRelatedFile(currentFile)).toEqual( - 'dir/Test.h', - ); - }); - }); - - it('gets next related file at the end of the sequence', () => { - waitsForPromise(async () => { - currentFile = 'dir/TestInternal.h'; - - const jumpToRelatedFile = new JumpToRelatedFile(); - expect(await jumpToRelatedFile.getNextRelatedFile(currentFile)).toEqual( - 'dir/Test.m', - ); - }); - }); - }); - - describe('@getPreviousRelatedFile_', () => { - it('gets previous related file at the start of the sequence', () => { - waitsForPromise(async () => { - currentFile = 'dir/Test.h'; - - const jumpToRelatedFile = new JumpToRelatedFile(); - expect( - await jumpToRelatedFile.getPreviousRelatedFile(currentFile), - ).toEqual('dir/Test.m'); - }); - }); - - it('gets previous related file in the middle of the sequence', () => { - waitsForPromise(async () => { - currentFile = 'dir/Test.m'; - - const jumpToRelatedFile = new JumpToRelatedFile(); - expect( - await jumpToRelatedFile.getPreviousRelatedFile(currentFile), - ).toEqual('dir/TestInternal.h'); - }); - }); - - it('gets previous related file at the end of the sequence', () => { - waitsForPromise(async () => { - currentFile = 'dir/TestInternal.h'; - - const jumpToRelatedFile = new JumpToRelatedFile(); - expect( - await jumpToRelatedFile.getPreviousRelatedFile(currentFile), - ).toEqual('dir/Test.h'); - }); - }); - - it('does nothing for missing files', () => { - waitsForPromise(async () => { - currentFile = 'dir/Test.h~'; - - const jumpToRelatedFile = new JumpToRelatedFile(); - expect( - await jumpToRelatedFile.getPreviousRelatedFile(currentFile), - ).toEqual('dir/Test.h~'); - }); - }); - }); -}); diff --git a/pkg/nuclide-related-files/spec/RelatedFileFinder-spec.js b/pkg/nuclide-related-files/spec/RelatedFileFinder-spec.js deleted file mode 100644 index 5e69c4124a..0000000000 --- a/pkg/nuclide-related-files/spec/RelatedFileFinder-spec.js +++ /dev/null @@ -1,141 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import RelatedFileFinder from '../lib/RelatedFileFinder'; - -function mockFiles(files: Array) { - spyOn( - require('../../nuclide-remote-connection'), - 'getFileSystemServiceByNuclideUri', - ).andReturn({ - readdir: async () => { - return files.map(name => { - return [name, true, false]; - }); - }, - }); -} - -describe('RelatedFileFinder', () => { - describe('@find', () => { - it('finds related file with a different extension', () => { - waitsForPromise(async () => { - mockFiles(['Test.h', 'Test.m', 'Test.m~']); - expect(await RelatedFileFinder.find('dir/Test.m')).toEqual({ - relatedFiles: ['dir/Test.h', 'dir/Test.m'], - index: 1, - }); - }); - }); - - it('finds related file whose name ends with `Internal`', () => { - waitsForPromise(async () => { - mockFiles(['Test.m', 'TestInternal.h']); - expect(await RelatedFileFinder.find('dir/Test.m')).toEqual({ - relatedFiles: ['dir/Test.m', 'dir/TestInternal.h'], - index: 0, - }); - }); - }); - - it('finds related file whose name ends with `-inl`', () => { - waitsForPromise(async () => { - mockFiles(['Test.h', 'Test-inl.h']); - expect(await RelatedFileFinder.find('dir/Test.h')).toEqual({ - relatedFiles: ['dir/Test-inl.h', 'dir/Test.h'], - index: 1, - }); - }); - }); - - it('does not find related file whose name starts with `Internal`', () => { - waitsForPromise(async () => { - mockFiles(['Test.m', 'InternalTest.h']); - expect(await RelatedFileFinder.find('dir/Test.m')).toEqual({ - relatedFiles: ['dir/Test.m'], - index: 0, - }); - }); - }); - - it('finds related file whose name ends with `t` and itself', () => { - waitsForPromise(async () => { - mockFiles(['Test.m', 'Test.v', 'Test.t']); - expect( - await RelatedFileFinder.find('dir/Test.m', new Set(['.t'])), - ).toEqual({ - relatedFiles: ['dir/Test.m', 'dir/Test.t'], - index: 0, - }); - }); - }); - - it('finds related file but nothing and then return all', () => { - waitsForPromise(async () => { - mockFiles(['Test.m', 'Test.v', 'Test.t']); - expect( - await RelatedFileFinder.find('dir/Test.m', new Set(['.o'])), - ).toEqual({ - relatedFiles: ['dir/Test.m', 'dir/Test.t', 'dir/Test.v'], - index: 0, - }); - }); - }); - - it('finds related file but only itself', () => { - waitsForPromise(async () => { - mockFiles(['Test.m', 'Test.v', 'Test.t']); - expect( - await RelatedFileFinder.find('dir/Test.m', new Set(['.m'])), - ).toEqual({ - relatedFiles: ['dir/Test.m'], - index: 0, - }); - }); - }); - - it('finds related file from a provider', () => { - waitsForPromise(async () => { - RelatedFileFinder.registerRelatedFilesProvider({ - getRelatedFiles(path: string): Promise> { - return Promise.resolve(['dir/Related.h']); - }, - }); - mockFiles(['Test.m', 'Related.h', 'Test.h']); - expect(await RelatedFileFinder.find('dir/Test.m')).toEqual({ - relatedFiles: ['dir/Related.h', 'dir/Test.h', 'dir/Test.m'], - index: 2, - }); - }); - }); - - it('returns result even with bad provider', () => { - // relies on the 1 second timeout in RFF._findRelatedFilesFromProviders - jasmine.useRealClock(); - waitsForPromise({timeout: 2000}, async () => { - RelatedFileFinder.registerRelatedFilesProvider({ - getRelatedFiles(path: string): Promise> { - // return a promise that never calls resolve. - return new Promise(resolve => {}); - }, - }); - // copy an earlier test - mockFiles(['Test.m', 'Test.v', 'Test.t']); - expect( - await RelatedFileFinder.find('dir/Test.m', new Set(['.t'])), - ).toEqual({ - relatedFiles: ['dir/Test.m', 'dir/Test.t'], - index: 0, - }); - }); - }); - }); -}); diff --git a/pkg/nuclide-remote-atom-rpc/bin/CommandClient.js b/pkg/nuclide-remote-atom-rpc/bin/CommandClient.js index 1e7ad55d74..444f693b61 100644 --- a/pkg/nuclide-remote-atom-rpc/bin/CommandClient.js +++ b/pkg/nuclide-remote-atom-rpc/bin/CommandClient.js @@ -1,3 +1,44 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getCommands = getCommands; + +var _ConfigDirectory; + +function _load_ConfigDirectory() { + return _ConfigDirectory = require('../shared/ConfigDirectory'); +} + +var _net = _interopRequireDefault(require('net')); + +var _nuclideRpc; + +function _load_nuclideRpc() { + return _nuclideRpc = require('../../nuclide-rpc'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _nuclideMarshalersCommon; + +function _load_nuclideMarshalersCommon() { + return _nuclideMarshalersCommon = require('../../nuclide-marshalers-common'); +} + +var _errors; + +function _load_errors() { + return _errors = require('./errors'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,26 +46,11 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import typeof * as CommandService from '../lib/CommandService'; -import type {MultiConnectionAtomCommands} from '../lib/rpc-types'; - -import {getServer, RPC_PROTOCOL} from '../shared/ConfigDirectory'; -import net from 'net'; -import { - loadServicesConfig, - RpcConnection, - SocketTransport, -} from '../../nuclide-rpc'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {localNuclideUriMarshalers} from '../../nuclide-marshalers-common'; -import {FailedConnectionError} from './errors'; -import invariant from 'assert'; - -function convertStringFamilyToNumberFamily(family: string): number { +function convertStringFamilyToNumberFamily(family) { switch (family) { case 'IPv4': return 4; @@ -35,66 +61,49 @@ function convertStringFamilyToNumberFamily(family: string): number { } } -export async function getCommands( - argv: {port: ?number, family: ?string}, - rejectIfZeroConnections: boolean, -): Promise { - const commands = - argv.port != null && argv.family != null - ? await startCommands(argv.port, argv.family) - : await findExistingCommands(); +async function getCommands(argv, rejectIfZeroConnections) { + const commands = argv.port != null && argv.family != null ? await startCommands(argv.port, argv.family) : await findExistingCommands(); if ((await commands.getConnectionCount()) === 0 && rejectIfZeroConnections) { - throw new FailedConnectionError( - 'Nuclide server is running but no Atom process with Nuclide is connected.', - ); + throw new (_errors || _load_errors()).FailedConnectionError('Nuclide server is running but no Atom process with Nuclide is connected.'); } return commands; } -async function findExistingCommands(): Promise { +async function findExistingCommands() { // Get the RPC connection info for the filesystem. - const serverInfo = await getServer(); + const serverInfo = await (0, (_ConfigDirectory || _load_ConfigDirectory()).getServer)(); if (serverInfo == null) { - throw new FailedConnectionError( - 'Could not find a nuclide-server with a connected Atom', - ); + throw new (_errors || _load_errors()).FailedConnectionError('Could not find a nuclide-server with a connected Atom'); + } + + if (!(serverInfo != null)) { + throw new Error('Invariant violation: "serverInfo != null"'); } - invariant(serverInfo != null); - const {commandPort, family} = serverInfo; + + const { commandPort, family } = serverInfo; return startCommands(commandPort, family); } -async function startCommands( - commandPort: number, - family: string, -): Promise { +async function startCommands(commandPort, family) { // Setup the RPC connection to the NuclideServer process. - const services = loadServicesConfig(nuclideUri.join(__dirname, '..')); - const socket = net.connect({ + const services = (0, (_nuclideRpc || _load_nuclideRpc()).loadServicesConfig)((_nuclideUri || _load_nuclideUri()).default.join(__dirname, '..')); + const socket = _net.default.connect({ port: commandPort, - family: convertStringFamilyToNumberFamily(family), + family: convertStringFamilyToNumberFamily(family) }); - const transport = new SocketTransport(socket); + const transport = new (_nuclideRpc || _load_nuclideRpc()).SocketTransport(socket); try { await transport.onConnected(); } catch (e) { // This is usually ECONNREFUSED ... // ... indicating that there was a nuclide-server but it is now shutdown. - throw new FailedConnectionError( - 'Could not find a nuclide-server with a connected Atom ' + - '("Nuclide/Kill Nuclide Server and Restart" will likely help)', - ); + throw new (_errors || _load_errors()).FailedConnectionError('Could not find a nuclide-server with a connected Atom ' + '("Nuclide/Kill Nuclide Server and Restart" will likely help)'); } - const connection = RpcConnection.createLocal( - transport, - [localNuclideUriMarshalers], - services, - RPC_PROTOCOL, - ); + const connection = (_nuclideRpc || _load_nuclideRpc()).RpcConnection.createLocal(transport, [(_nuclideMarshalersCommon || _load_nuclideMarshalersCommon()).localNuclideUriMarshalers], services, (_ConfigDirectory || _load_ConfigDirectory()).RPC_PROTOCOL); // Get the command interface - const service: CommandService = connection.getService('CommandService'); + const service = connection.getService('CommandService'); return service.getAtomCommands(); -} +} \ No newline at end of file diff --git a/pkg/nuclide-remote-atom-rpc/bin/atom-notify-node.js b/pkg/nuclide-remote-atom-rpc/bin/atom-notify-node.js index d18c49a2e0..ed20387e0d 100644 --- a/pkg/nuclide-remote-atom-rpc/bin/atom-notify-node.js +++ b/pkg/nuclide-remote-atom-rpc/bin/atom-notify-node.js @@ -1,24 +1,24 @@ -/** - * 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 - */ +'use strict'; -import yargs from 'yargs'; -import {getCommands} from './CommandClient'; -import { - reportConnectionErrorAndExit, - setupErrorHandling, - setupLogging, - EXIT_CODE_INVALID_ARGUMENTS, - EXIT_CODE_SUCCESS, - FailedConnectionError, -} from './errors'; +var _yargs; + +function _load_yargs() { + return _yargs = _interopRequireDefault(require('yargs')); +} + +var _CommandClient; + +function _load_CommandClient() { + return _CommandClient = require('./CommandClient'); +} + +var _errors; + +function _load_errors() { + return _errors = require('./errors'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Command-line tool that allows you to send a message that gets displayed as @@ -30,20 +30,20 @@ import { * https://www.gsp.com/cgi-bin/man.cgi?section=1&topic=zwrite. */ -async function main(argv): Promise { - setupLogging(); - setupErrorHandling(); +async function main(argv) { + (0, (_errors || _load_errors()).setupLogging)(); + (0, (_errors || _load_errors()).setupErrorHandling)(); // Connect to the Nuclide server running on this host, if it exists. let commands = null; try { - commands = await getCommands(argv, /* rejectIfZeroConnections */ true); + commands = await (0, (_CommandClient || _load_CommandClient()).getCommands)(argv, /* rejectIfZeroConnections */true); } catch (error) { - if (error instanceof FailedConnectionError) { + if (error instanceof (_errors || _load_errors()).FailedConnectionError) { // Note this does not throw: reportConnectionErrorAndExit() // does not return. However, we use throw to convince Flow // that any code after this is unreachable. - throw reportConnectionErrorAndExit(error); + throw (0, (_errors || _load_errors()).reportConnectionErrorAndExit)(error); } else { throw error; } @@ -53,7 +53,7 @@ async function main(argv): Promise { if (message === '') { // eslint-disable-next-line no-console console.error('Cowardly refusing to send an empty message.'); // HT tar - return EXIT_CODE_INVALID_ARGUMENTS; + return (_errors || _load_errors()).EXIT_CODE_INVALID_ARGUMENTS; } let type = 'info'; @@ -71,56 +71,55 @@ async function main(argv): Promise { // Counterintuitively, by setting dismissable to true, it makes it sticky // because in Atom, "dismissable" means "has a close box", which means // it does not go away until the user clicks on the X. - dismissable: argv.sticky, + dismissable: argv.sticky }; await commands.addNotification(notification); - return EXIT_CODE_SUCCESS; -} + return (_errors || _load_errors()).EXIT_CODE_SUCCESS; +} /** + * 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. + * + * + * @format + */ + +async function run() { + const { argv } = (_yargs || _load_yargs()).default.usage('Usage: atom-notify').help('h').alias('h', 'help').option('p', { + alias: 'port', + describe: 'Port for connecting to nuclide', + type: 'number' + }).option('f', { + alias: 'family', + describe: 'Address family for connecting to nuclide. Either "IPv4" or "IPv6".', + type: 'string' + }).option('s', { + alias: 'sticky', + describe: 'Requires user to explicitly dismiss the notification.', + type: 'boolean' + }) -async function run(): Promise { - const {argv} = yargs - .usage('Usage: atom-notify') - .help('h') - .alias('h', 'help') - .option('p', { - alias: 'port', - describe: 'Port for connecting to nuclide', - type: 'number', - }) - .option('f', { - alias: 'family', - describe: - 'Address family for connecting to nuclide. Either "IPv4" or "IPv6".', - type: 'string', - }) - .option('s', { - alias: 'sticky', - describe: 'Requires user to explicitly dismiss the notification.', - type: 'boolean', - }) - - // Note that we do not support 'fatal' from the CLI because that tells - // the user that "This is likely a bug in Atom", which is misleading. - .option('success', { - describe: 'Display as success.', - type: 'boolean', - }) - .option('info', { - describe: 'Display as info.', - type: 'boolean', - }) - .option('warning', { - describe: 'Display as warning.', - type: 'boolean', - }) - .option('error', { - describe: 'Display as error.', - type: 'boolean', - }); + // Note that we do not support 'fatal' from the CLI because that tells + // the user that "This is likely a bug in Atom", which is misleading. + .option('success', { + describe: 'Display as success.', + type: 'boolean' + }).option('info', { + describe: 'Display as info.', + type: 'boolean' + }).option('warning', { + describe: 'Display as warning.', + type: 'boolean' + }).option('error', { + describe: 'Display as error.', + type: 'boolean' + }); const exitCode = await main(argv); process.exit(exitCode); } -run(); +run(); \ No newline at end of file diff --git a/pkg/nuclide-remote-atom-rpc/bin/errors.js b/pkg/nuclide-remote-atom-rpc/bin/errors.js index 3505837a0c..7c3ceb2944 100644 --- a/pkg/nuclide-remote-atom-rpc/bin/errors.js +++ b/pkg/nuclide-remote-atom-rpc/bin/errors.js @@ -1,33 +1,50 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import log4js from 'log4js'; -import os from 'os'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.FailedConnectionError = exports.EXIT_CODE_INVALID_ARGUMENTS = exports.EXIT_CODE_CONNECTION_ERROR = exports.EXIT_CODE_APPLICATION_ERROR = exports.EXIT_CODE_UNKNOWN_ERROR = exports.EXIT_CODE_SUCCESS = undefined; +exports.setupErrorHandling = setupErrorHandling; +exports.setupLogging = setupLogging; +exports.reportConnectionErrorAndExit = reportConnectionErrorAndExit; +exports.reportErrorAndExit = reportErrorAndExit; -import {initializeLogging} from '../../nuclide-logging'; +var _log4js; -const logger = log4js.getLogger('nuclide-remote-atom-rpc'); +function _load_log4js() { + return _log4js = _interopRequireDefault(require('log4js')); +} + +var _os = _interopRequireDefault(require('os')); + +var _nuclideLogging; + +function _load_nuclideLogging() { + return _nuclideLogging = require('../../nuclide-logging'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const logger = (_log4js || _load_log4js()).default.getLogger('nuclide-remote-atom-rpc'); /** + * 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. + * + * strict-local + * @format + */ -export const EXIT_CODE_SUCCESS = 0; -export const EXIT_CODE_UNKNOWN_ERROR = 1; -export const EXIT_CODE_APPLICATION_ERROR = 2; -export const EXIT_CODE_CONNECTION_ERROR = 3; -export const EXIT_CODE_INVALID_ARGUMENTS = 4; +const EXIT_CODE_SUCCESS = exports.EXIT_CODE_SUCCESS = 0; +const EXIT_CODE_UNKNOWN_ERROR = exports.EXIT_CODE_UNKNOWN_ERROR = 1; +const EXIT_CODE_APPLICATION_ERROR = exports.EXIT_CODE_APPLICATION_ERROR = 2; +const EXIT_CODE_CONNECTION_ERROR = exports.EXIT_CODE_CONNECTION_ERROR = 3; +const EXIT_CODE_INVALID_ARGUMENTS = exports.EXIT_CODE_INVALID_ARGUMENTS = 4; -export function setupErrorHandling() { +function setupErrorHandling() { process.on('uncaughtException', event => { - logger.error( - `Caught unhandled exception: ${event.message}`, - event.originalError, - ); + logger.error(`Caught unhandled exception: ${event.message}`, event.originalError); process.stderr.write(`Unhandled exception: ${event.message}\n`); process.exit(EXIT_CODE_UNKNOWN_ERROR); }); @@ -39,27 +56,19 @@ export function setupErrorHandling() { }); } -export function setupLogging() { - initializeLogging(); +function setupLogging() { + (0, (_nuclideLogging || _load_nuclideLogging()).initializeLogging)(); } -export function reportConnectionErrorAndExit( - error: FailedConnectionError, -): void { +function reportConnectionErrorAndExit(error) { const detailMessage = error.message; - process.stderr.write( - `Error connecting to nuclide-server on ${os.hostname()}:\n`, - ); + process.stderr.write(`Error connecting to nuclide-server on ${_os.default.hostname()}:\n`); process.stderr.write(` ${detailMessage}.\n`); process.stderr.write('\n'); process.stderr.write('Potential fixes:\n'); process.stderr.write('* Ensure Atom with Nuclide is open.\n'); - process.stderr.write( - `* Verify Nuclide's current directory located on ${os.hostname()}\n`, - ); - process.stderr.write( - '* Click the menu item "Nuclide/Kill Nuclide Server and Restart"\n', - ); + process.stderr.write(`* Verify Nuclide's current directory located on ${_os.default.hostname()}\n`); + process.stderr.write('* Click the menu item "Nuclide/Kill Nuclide Server and Restart"\n'); process.stderr.write('\n'); process.stderr.write('Callstack:\n'); process.stderr.write(new Error().stack); @@ -67,10 +76,11 @@ export function reportConnectionErrorAndExit( process.exit(EXIT_CODE_CONNECTION_ERROR); } -export function reportErrorAndExit(error: Error, exitCode: number): void { +function reportErrorAndExit(error, exitCode) { process.stderr.write(error.stack); process.stderr.write('\n'); process.exit(exitCode); } -export class FailedConnectionError extends Error {} +class FailedConnectionError extends Error {} +exports.FailedConnectionError = FailedConnectionError; \ No newline at end of file diff --git a/pkg/nuclide-remote-atom-rpc/bin/main.js b/pkg/nuclide-remote-atom-rpc/bin/main.js index 1b00eb3116..b84f117ee8 100644 --- a/pkg/nuclide-remote-atom-rpc/bin/main.js +++ b/pkg/nuclide-remote-atom-rpc/bin/main.js @@ -1,48 +1,63 @@ -/** - * 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 - */ +'use strict'; + +var _CommandClient; + +function _load_CommandClient() { + return _CommandClient = require('./CommandClient'); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _errors; + +function _load_errors() { + return _errors = require('./errors'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _yargs; + +function _load_yargs() { + return _yargs = _interopRequireDefault(require('yargs')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import {getCommands} from './CommandClient'; -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import { - setupErrorHandling, - setupLogging, - reportErrorAndExit, - reportConnectionErrorAndExit, - EXIT_CODE_SUCCESS, - EXIT_CODE_APPLICATION_ERROR, - EXIT_CODE_INVALID_ARGUMENTS, - FailedConnectionError, -} from './errors'; -import {getLogger} from 'log4js'; -import yargs from 'yargs'; - -const logger = getLogger('nuclide-remote-atom-rpc'); - -type FileLocation = { - filePath: string, - line: number, - column: number, -}; +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-remote-atom-rpc'); /** + * 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. + * + * + * @format + */ const LocationSuffixRegExp = /(:\d+)(:\d+)?$/; // This code is coped from Atom: src/main-process/atom-application.coffee -function parseLocationParameter(value: string): FileLocation { - let filePath: string = value.replace(/[:\s]+$/, ''); +function parseLocationParameter(value) { + let filePath = value.replace(/[:\s]+$/, ''); const match = filePath.match(LocationSuffixRegExp); - let line: number = 0; - let column: number = 0; + let line = 0; + let column = 0; if (match) { filePath = filePath.slice(0, -match[0].length); if (match[1]) { @@ -55,7 +70,7 @@ function parseLocationParameter(value: string): FileLocation { return { filePath, line, - column, + column }; } @@ -64,40 +79,40 @@ function parseLocationParameter(value: string): FileLocation { * Sometimes filePath may not exist yet, in which case we need to look upwards * for the first prefix that actually does exist. */ -async function getRealPath(filePath: NuclideUri): Promise { - if (nuclideUri.isRemote(filePath)) { +async function getRealPath(filePath) { + if ((_nuclideUri || _load_nuclideUri()).default.isRemote(filePath)) { return filePath; } - const resolved = nuclideUri.resolve(filePath); + const resolved = (_nuclideUri || _load_nuclideUri()).default.resolve(filePath); let prefix = resolved; let suffix = null; while (true) { try { // eslint-disable-next-line no-await-in-loop - const realpath = await fsPromise.realpath(prefix); - return suffix == null ? realpath : nuclideUri.join(realpath, suffix); + const realpath = await (_fsPromise || _load_fsPromise()).default.realpath(prefix); + return suffix == null ? realpath : (_nuclideUri || _load_nuclideUri()).default.join(realpath, suffix); } catch (err) { if (err.code !== 'ENOENT') { throw err; } - const basename = nuclideUri.basename(prefix); + const basename = (_nuclideUri || _load_nuclideUri()).default.basename(prefix); if (basename === '') { // We've reached the filesystem root. break; } - suffix = suffix == null ? basename : nuclideUri.join(basename, suffix); - prefix = nuclideUri.dirname(prefix); + suffix = suffix == null ? basename : (_nuclideUri || _load_nuclideUri()).default.join(basename, suffix); + prefix = (_nuclideUri || _load_nuclideUri()).default.dirname(prefix); } } return resolved; } -async function getIsDirectory(filePath: NuclideUri): Promise { +async function getIsDirectory(filePath) { try { - if (nuclideUri.isRemote(filePath)) { + if ((_nuclideUri || _load_nuclideUri()).default.isRemote(filePath)) { return false; } else { - const stats = await fsPromise.stat(filePath); + const stats = await (_fsPromise || _load_fsPromise()).default.stat(filePath); return stats.isDirectory(); } } catch (e) { @@ -105,9 +120,9 @@ async function getIsDirectory(filePath: NuclideUri): Promise { } } -async function main(argv): Promise { - setupLogging(); - setupErrorHandling(); +async function main(argv) { + (0, (_errors || _load_errors()).setupLogging)(); + (0, (_errors || _load_errors()).setupErrorHandling)(); logger.debug(`nuclide-remote-atom with arguments: ${argv._}`); @@ -115,37 +130,33 @@ async function main(argv): Promise { if (argv._ != null && argv._.length > 0) { let commands; try { - commands = await getCommands(argv, /* rejectIfZeroConnections */ true); + commands = await (0, (_CommandClient || _load_CommandClient()).getCommands)(argv, /* rejectIfZeroConnections */true); } catch (error) { - if (error instanceof FailedConnectionError) { + if (error instanceof (_errors || _load_errors()).FailedConnectionError) { // Note this does not throw: reportConnectionErrorAndExit() // does not return. However, we use throw to convince Flow // that any code after this is unreachable. - throw reportConnectionErrorAndExit(error); + throw (0, (_errors || _load_errors()).reportConnectionErrorAndExit)(error); } else { throw error; } } for (const arg of argv._) { - const {filePath, line, column} = parseLocationParameter(arg); + const { filePath, line, column } = parseLocationParameter(arg); // eslint-disable-next-line no-await-in-loop const realpath = await getRealPath(filePath); // eslint-disable-next-line no-await-in-loop const isDirectory = await getIsDirectory(realpath); try { - if (nuclideUri.isRemote(realpath)) { + if ((_nuclideUri || _load_nuclideUri()).default.isRemote(realpath)) { if (argv.newWindow) { // TODO(mbolin): Support --new-window for nuclide:// arguments. - process.stderr.write( - '--new-window is not currently supported for remote NuclideUris.\n', - ); - return EXIT_CODE_INVALID_ARGUMENTS; + process.stderr.write('--new-window is not currently supported for remote NuclideUris.\n'); + return (_errors || _load_errors()).EXIT_CODE_INVALID_ARGUMENTS; } - const result = commands - .openRemoteFile(realpath, line, column, Boolean(argv.wait)) - .refCount(); + const result = commands.openRemoteFile(realpath, line, column, Boolean(argv.wait)).refCount(); if (argv.wait) { // eslint-disable-next-line no-await-in-loop await result.toPromise(); @@ -166,15 +177,11 @@ async function main(argv): Promise { // makes it difficult to implement a faithful // ConnectableObservable (particularly if --wait is // specified). - process.stderr.write( - '--new-window is not currently supported for files.\n', - ); - return EXIT_CODE_INVALID_ARGUMENTS; + process.stderr.write('--new-window is not currently supported for files.\n'); + return (_errors || _load_errors()).EXIT_CODE_INVALID_ARGUMENTS; } - const result = commands - .openFile(realpath, line, column, Boolean(argv.wait)) - .refCount(); + const result = commands.openFile(realpath, line, column, Boolean(argv.wait)).refCount(); if (argv.wait) { // eslint-disable-next-line no-await-in-loop await result.toPromise(); @@ -184,55 +191,41 @@ async function main(argv): Promise { } } } catch (e) { - reportErrorAndExit(e, EXIT_CODE_APPLICATION_ERROR); + (0, (_errors || _load_errors()).reportErrorAndExit)(e, (_errors || _load_errors()).EXIT_CODE_APPLICATION_ERROR); } } } - return EXIT_CODE_SUCCESS; + return (_errors || _load_errors()).EXIT_CODE_SUCCESS; } async function run() { - const {argv} = yargs - .usage('Usage: atom ') - .help('h') - .alias('h', 'help') - .demand(1, 'At least one file name is required.') - .option('a', { - alias: 'add', - describe: - 'Ignored, as --add as always implied. ' + - 'Included for compatibility with atom CLI.', - type: 'boolean', - }) - .option('n', { - alias: 'new-window', - describe: 'Open a new window.', - type: 'boolean', - }) - .option('w', { - alias: 'wait', - describe: 'Wait for the opened file to be closed in Atom before exiting', - type: 'boolean', - }) - .option('p', { - alias: 'port', - describe: 'Port for connecting to nuclide', - type: 'number', - }) - .option('f', { - alias: 'family', - describe: - 'Address family for connecting to nuclide. Either "IPv4" or "IPv6".', - type: 'string', - }); - if ((argv.port == null) !== (argv.family == null)) { - process.stderr.write( - 'Invalid options. Both port and family must be specified.\n', - ); - process.exit(EXIT_CODE_INVALID_ARGUMENTS); + const { argv } = (_yargs || _load_yargs()).default.usage('Usage: atom ').help('h').alias('h', 'help').demand(1, 'At least one file name is required.').option('a', { + alias: 'add', + describe: 'Ignored, as --add as always implied. ' + 'Included for compatibility with atom CLI.', + type: 'boolean' + }).option('n', { + alias: 'new-window', + describe: 'Open a new window.', + type: 'boolean' + }).option('w', { + alias: 'wait', + describe: 'Wait for the opened file to be closed in Atom before exiting', + type: 'boolean' + }).option('p', { + alias: 'port', + describe: 'Port for connecting to nuclide', + type: 'number' + }).option('f', { + alias: 'family', + describe: 'Address family for connecting to nuclide. Either "IPv4" or "IPv6".', + type: 'string' + }); + if (argv.port == null !== (argv.family == null)) { + process.stderr.write('Invalid options. Both port and family must be specified.\n'); + process.exit((_errors || _load_errors()).EXIT_CODE_INVALID_ARGUMENTS); } const exitCode = await main(argv); process.exit(exitCode); } -run(); +run(); \ No newline at end of file diff --git a/pkg/nuclide-remote-atom-rpc/bin/nuclide-connections-node.js b/pkg/nuclide-remote-atom-rpc/bin/nuclide-connections-node.js index 38ba227cda..b1046fbddc 100644 --- a/pkg/nuclide-remote-atom-rpc/bin/nuclide-connections-node.js +++ b/pkg/nuclide-remote-atom-rpc/bin/nuclide-connections-node.js @@ -1,3 +1,46 @@ +'use strict'; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _os = _interopRequireDefault(require('os')); + +var _yargs; + +function _load_yargs() { + return _yargs = _interopRequireDefault(require('yargs')); +} + +var _CommandClient; + +function _load_CommandClient() { + return _CommandClient = require('./CommandClient'); +} + +var _errors; + +function _load_errors() { + return _errors = require('./errors'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/* + * CLI for printing information about the Atom clients connected to the Nuclide + * server running on this machine. By default, it lists the remote root folders + * in the Atom clients that correspond to this host. The list is written to + * stdout as JSON. + */ + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,42 +48,22 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {runCommand} from 'nuclide-commons/process'; -import os from 'os'; -import yargs from 'yargs'; -import {getCommands} from './CommandClient'; -import { - setupErrorHandling, - setupLogging, - EXIT_CODE_CONNECTION_ERROR, - EXIT_CODE_SUCCESS, - FailedConnectionError, -} from './errors'; - -/* - * CLI for printing information about the Atom clients connected to the Nuclide - * server running on this machine. By default, it lists the remote root folders - * in the Atom clients that correspond to this host. The list is written to - * stdout as JSON. - */ - -async function main(argv): Promise { - setupLogging(); - setupErrorHandling(); +async function main(argv) { + (0, (_errors || _load_errors()).setupLogging)(); + (0, (_errors || _load_errors()).setupErrorHandling)(); // Connect to the Nuclide server running on this host, if it exists. let commands = null; try { - commands = await getCommands(argv, /* rejectIfZeroConnections */ false); + commands = await (0, (_CommandClient || _load_CommandClient()).getCommands)(argv, /* rejectIfZeroConnections */false); } catch (e) { // Only a FailedConnectionError is expected. - if (!(e instanceof FailedConnectionError)) { - return EXIT_CODE_CONNECTION_ERROR; + if (!(e instanceof (_errors || _load_errors()).FailedConnectionError)) { + return (_errors || _load_errors()).EXIT_CODE_CONNECTION_ERROR; } } @@ -50,8 +73,8 @@ async function main(argv): Promise { // We should print an empty array without any ceremony in this case. foldersArray = []; } else { - const hostname = os.hostname(); - const isAliasForHostname = async function(alias: string): Promise { + const hostname = _os.default.hostname(); + const isAliasForHostname = async function (alias) { if (hostname === alias) { return true; } else { @@ -66,11 +89,11 @@ async function main(argv): Promise { const rootFolders = new Set(); for (const projectState of projectStates) { for (const rootFolder of projectState.rootFolders) { - if (nuclideUri.isRemote(rootFolder)) { - const alias = nuclideUri.getHostname(rootFolder); + if ((_nuclideUri || _load_nuclideUri()).default.isRemote(rootFolder)) { + const alias = (_nuclideUri || _load_nuclideUri()).default.getHostname(rootFolder); // eslint-disable-next-line no-await-in-loop if (await isAliasForHostname(alias)) { - const path = nuclideUri.getPath(rootFolder); + const path = (_nuclideUri || _load_nuclideUri()).default.getPath(rootFolder); rootFolders.add(path); } } @@ -82,13 +105,13 @@ async function main(argv): Promise { foldersArray.sort(); // eslint-disable-next-line no-console console.log(JSON.stringify(foldersArray, null, 2)); - return EXIT_CODE_SUCCESS; + return (_errors || _load_errors()).EXIT_CODE_SUCCESS; } -async function resolveAlias(alias: string): Promise { +async function resolveAlias(alias) { let stdout; try { - stdout = await runCommand('dig', ['+short', 'cname', alias]).toPromise(); + stdout = await (0, (_process || _load_process()).runCommand)('dig', ['+short', 'cname', alias]).toPromise(); } catch (e) { // Defend against the case where `dig` is not installed. return null; @@ -111,25 +134,19 @@ async function resolveAlias(alias: string): Promise { return stdout; } -async function run(): Promise { - const {argv} = yargs - .usage('Usage: nuclide-connections') - .help('h') - .alias('h', 'help') - .option('p', { - alias: 'port', - describe: 'Port for connecting to nuclide', - type: 'number', - }) - .option('f', { - alias: 'family', - describe: - 'Address family for connecting to nuclide. Either "IPv4" or "IPv6".', - type: 'string', - }); +async function run() { + const { argv } = (_yargs || _load_yargs()).default.usage('Usage: nuclide-connections').help('h').alias('h', 'help').option('p', { + alias: 'port', + describe: 'Port for connecting to nuclide', + type: 'number' + }).option('f', { + alias: 'family', + describe: 'Address family for connecting to nuclide. Either "IPv4" or "IPv6".', + type: 'string' + }); const exitCode = await main(argv); process.exit(exitCode); } -run(); +run(); \ No newline at end of file diff --git a/pkg/nuclide-remote-atom-rpc/lib/CommandServer.js b/pkg/nuclide-remote-atom-rpc/lib/CommandServer.js index 040f9e291b..50c191a1f4 100644 --- a/pkg/nuclide-remote-atom-rpc/lib/CommandServer.js +++ b/pkg/nuclide-remote-atom-rpc/lib/CommandServer.js @@ -1,35 +1,59 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.CommandServer = undefined; + +var _CommandServerConnection; + +function _load_CommandServerConnection() { + return _CommandServerConnection = require('./CommandServerConnection'); +} + +var _RoutingAtomCommands; + +function _load_RoutingAtomCommands() { + return _RoutingAtomCommands = require('./RoutingAtomCommands'); +} -import type { - AtomCommands, - ConnectionDetails, - MultiConnectionAtomCommands, -} from './rpc-types'; -import type {FileCache} from '../../nuclide-open-files-rpc/lib/FileCache'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import {CommandServerConnection} from './CommandServerConnection'; -import {RoutingAtomCommands} from './RoutingAtomCommands'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import invariant from 'assert'; -import { - loadServicesConfig, - ServiceRegistry, - SocketServer, -} from '../../nuclide-rpc'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {createNewEntry, RPC_PROTOCOL} from '../shared/ConfigDirectory'; -import {localNuclideUriMarshalers} from '../../nuclide-marshalers-common'; -import {firstOfIterable, concatIterators} from 'nuclide-commons/collection'; +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _nuclideRpc; + +function _load_nuclideRpc() { + return _nuclideRpc = require('../../nuclide-rpc'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _ConfigDirectory; + +function _load_ConfigDirectory() { + return _ConfigDirectory = require('../shared/ConfigDirectory'); +} + +var _nuclideMarshalersCommon; + +function _load_nuclideMarshalersCommon() { + return _nuclideMarshalersCommon = require('../../nuclide-marshalers-common'); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A singleton instance of this class should exist in a Nuclide server. @@ -43,98 +67,98 @@ import {firstOfIterable, concatIterators} from 'nuclide-commons/collection'; * it can check the hasOpenPath() for each CommandServerConnection until * it finds the appropriate connection, if any. */ -export class CommandServer { - // The list of connected AtomCommands, most recent connection last. - // We have no way of detecting a traumatic termination of an Atom - // process, so the most recent connection is likely the healthiest - // connection. - _connections: Array = []; - _server: ?SocketServer = null; - _multiConnectionAtomCommands: MultiConnectionAtomCommands; +class CommandServer { /** * In general, this constructor should not be invoked directly. * Prefer getCommandServer() in ./command-server-singleton.js. */ constructor() { - this._multiConnectionAtomCommands = new RoutingAtomCommands(this); + this._connections = []; + this._server = null; + + this._multiConnectionAtomCommands = new (_RoutingAtomCommands || _load_RoutingAtomCommands()).RoutingAtomCommands(this); } + // The list of connected AtomCommands, most recent connection last. + // We have no way of detecting a traumatic termination of an Atom + // process, so the most recent connection is likely the healthiest + // connection. + - getConnectionCount(): number { + getConnectionCount() { return this._connections.length; } - getConnections(): Iterable { + getConnections() { return this._connections; } - async _ensureServer(): Promise { + async _ensureServer() { if (this._server != null) { return this._server; } - const services = loadServicesConfig(nuclideUri.join(__dirname, '..')); - const registry = new ServiceRegistry( - [localNuclideUriMarshalers], - services, - RPC_PROTOCOL, - ); - const result = new SocketServer(registry); + const services = (0, (_nuclideRpc || _load_nuclideRpc()).loadServicesConfig)((_nuclideUri || _load_nuclideUri()).default.join(__dirname, '..')); + const registry = new (_nuclideRpc || _load_nuclideRpc()).ServiceRegistry([(_nuclideMarshalersCommon || _load_nuclideMarshalersCommon()).localNuclideUriMarshalers], services, (_ConfigDirectory || _load_ConfigDirectory()).RPC_PROTOCOL); + const result = new (_nuclideRpc || _load_nuclideRpc()).SocketServer(registry); this._server = result; const address = await result.getAddress(); - await createNewEntry(address.port, address.family); + await (0, (_ConfigDirectory || _load_ConfigDirectory()).createNewEntry)(address.port, address.family); return result; } - async getConnectionDetails(): Promise { + async getConnectionDetails() { const server = this.getCurrentServer(); return server == null ? null : (await this._ensureServer()).getAddress(); } - async register( - fileCache: FileCache, - atomCommands: AtomCommands, - ): Promise { + async register(fileCache, atomCommands) { await this._ensureServer(); - const connection = new CommandServerConnection(fileCache, atomCommands); + const connection = new (_CommandServerConnection || _load_CommandServerConnection()).CommandServerConnection(fileCache, atomCommands); this._connections.push(connection); - return new UniversalDisposable(() => this._removeConnection(connection)); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => this._removeConnection(connection)); } - _removeConnection(connection: CommandServerConnection) { - invariant(this._connections.includes(connection)); + _removeConnection(connection) { + if (!this._connections.includes(connection)) { + throw new Error('Invariant violation: "this._connections.includes(connection)"'); + } + this._connections.splice(this._connections.indexOf(connection), 1); } - getCurrentServer(): ?CommandServerConnection { + getCurrentServer() { if (this._connections.length === 0) { return null; } return this._connections[this._connections.length - 1]; } - getDefaultAtomCommands(): ?AtomCommands { + getDefaultAtomCommands() { const server = this.getCurrentServer(); return server == null ? null : server.getAtomCommands(); } - _getConnectionByPath(filePath: NuclideUri): ?CommandServerConnection { - return firstOfIterable( - concatIterators( - this._connections.filter(connection => - connection.hasOpenPath(filePath), - ), - [this.getCurrentServer()].filter(server => server != null), - ), - ); + _getConnectionByPath(filePath) { + return (0, (_collection || _load_collection()).firstOfIterable)((0, (_collection || _load_collection()).concatIterators)(this._connections.filter(connection => connection.hasOpenPath(filePath)), [this.getCurrentServer()].filter(server => server != null))); } - getAtomCommandsByPath(filePath: NuclideUri): ?AtomCommands { + getAtomCommandsByPath(filePath) { const server = this._getConnectionByPath(filePath); return server == null ? null : server.getAtomCommands(); } - getMultiConnectionAtomCommands(): MultiConnectionAtomCommands { + getMultiConnectionAtomCommands() { return this._multiConnectionAtomCommands; } } +exports.CommandServer = CommandServer; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-remote-atom-rpc/lib/CommandServerConnection.js b/pkg/nuclide-remote-atom-rpc/lib/CommandServerConnection.js index 6915354eef..fcdb341f9a 100644 --- a/pkg/nuclide-remote-atom-rpc/lib/CommandServerConnection.js +++ b/pkg/nuclide-remote-atom-rpc/lib/CommandServerConnection.js @@ -1,45 +1,46 @@ -/** - * 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 - */ - -import type {AtomCommands} from './rpc-types'; -import type {FileCache} from '../../nuclide-open-files-rpc/lib/FileCache'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import { - iterableIsEmpty, - filterIterable, - iterableContains, -} from 'nuclide-commons/collection'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - -export class CommandServerConnection { - _atomCommands: AtomCommands; - _fileCache: FileCache; - - constructor(fileCache: FileCache, atomCommands: AtomCommands) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.CommandServerConnection = undefined; + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class CommandServerConnection { + + constructor(fileCache, atomCommands) { this._atomCommands = atomCommands; this._fileCache = fileCache; } - getAtomCommands(): AtomCommands { + getAtomCommands() { return this._atomCommands; } - hasOpenPath(filePath: NuclideUri): boolean { - return ( - !iterableIsEmpty( - filterIterable(this._fileCache.getOpenDirectories(), dir => - nuclideUri.contains(dir, filePath), - ), - ) || iterableContains(this._fileCache.getOpenFiles(), filePath) - ); + hasOpenPath(filePath) { + return !(0, (_collection || _load_collection()).iterableIsEmpty)((0, (_collection || _load_collection()).filterIterable)(this._fileCache.getOpenDirectories(), dir => (_nuclideUri || _load_nuclideUri()).default.contains(dir, filePath))) || (0, (_collection || _load_collection()).iterableContains)(this._fileCache.getOpenFiles(), filePath); } } +exports.CommandServerConnection = CommandServerConnection; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-remote-atom-rpc/lib/CommandService.js b/pkg/nuclide-remote-atom-rpc/lib/CommandService.js index 6eecf0aac6..a475be9fa7 100644 --- a/pkg/nuclide-remote-atom-rpc/lib/CommandService.js +++ b/pkg/nuclide-remote-atom-rpc/lib/CommandService.js @@ -1,3 +1,22 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getAtomCommands = getAtomCommands; +exports.getConnectionDetails = getConnectionDetails; + +var _commandServerSingleton; + +function _load_commandServerSingleton() { + return _commandServerSingleton = require('./command-server-singleton'); +} + +// This file defines a service that is expected to be used by +// command-line tools that run local to a Nuclide server. +// To that end, it is defined in ../services-3.json, which can +// be loaded via the Nuclide-RPC framework. + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,23 +24,14 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {ConnectionDetails, MultiConnectionAtomCommands} from './rpc-types'; - -import {getCommandServer} from './command-server-singleton'; - -// This file defines a service that is expected to be used by -// command-line tools that run local to a Nuclide server. -// To that end, it is defined in ../services-3.json, which can -// be loaded via the Nuclide-RPC framework. - -export function getAtomCommands(): Promise { - return Promise.resolve(getCommandServer().getMultiConnectionAtomCommands()); +function getAtomCommands() { + return Promise.resolve((0, (_commandServerSingleton || _load_commandServerSingleton()).getCommandServer)().getMultiConnectionAtomCommands()); } -export function getConnectionDetails(): Promise { - return getCommandServer().getConnectionDetails(); -} +function getConnectionDetails() { + return (0, (_commandServerSingleton || _load_commandServerSingleton()).getCommandServer)().getConnectionDetails(); +} \ No newline at end of file diff --git a/pkg/nuclide-remote-atom-rpc/lib/CommandServiceProxy.js b/pkg/nuclide-remote-atom-rpc/lib/CommandServiceProxy.js new file mode 100644 index 0000000000..358e68f3a3 --- /dev/null +++ b/pkg/nuclide-remote-atom-rpc/lib/CommandServiceProxy.js @@ -0,0 +1,634 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + remoteModule.MultiConnectionAtomCommands = class { + constructor() { + throw Error("constructors are not supported for remote objects"); + } + + getConnectionCount() { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 87 + }, + name: "MultiConnectionAtomCommands" + }), "getConnectionCount", "promise", _client.marshalArguments(Array.from(arguments), [])).then(value => { + return _client.unmarshal(value, { + kind: "number" + }); + }); + } + + openFile(arg0, arg1, arg2, arg3) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 87 + }, + name: "MultiConnectionAtomCommands" + }), "openFile", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }, { + name: "isWaiting", + type: { + kind: "boolean" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "AtomFileEvent" + }); + }).publish(); + } + + openRemoteFile(arg0, arg1, arg2, arg3) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 87 + }, + name: "MultiConnectionAtomCommands" + }), "openRemoteFile", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "uri", + type: { + kind: "string" + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }, { + name: "isWaiting", + type: { + kind: "boolean" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "AtomFileEvent" + }); + }).publish(); + } + + addProject(arg0, arg1) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 87 + }, + name: "MultiConnectionAtomCommands" + }), "addProject", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "projectPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "newWindow", + type: { + kind: "boolean" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + } + + getProjectStates() { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 87 + }, + name: "MultiConnectionAtomCommands" + }), "getProjectStates", "promise", _client.marshalArguments(Array.from(arguments), [])).then(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "ProjectState" + } + }); + }); + } + + addNotification(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 87 + }, + name: "MultiConnectionAtomCommands" + }), "addNotification", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "notification", + type: { + kind: "named", + name: "AtomNotification" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + } + + dispose() { + return _client.disposeRemoteObject(this); + } + + }; + + remoteModule.getAtomCommands = function () { + return _client.callRemoteFunction("CommandService/getAtomCommands", "promise", _client.marshalArguments(Array.from(arguments), [])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "MultiConnectionAtomCommands" + }); + }); + }; + + remoteModule.getConnectionDetails = function () { + return _client.callRemoteFunction("CommandService/getConnectionDetails", "promise", _client.marshalArguments(Array.from(arguments), [])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "ConnectionDetails" + } + }); + }); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + AtomFileEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 24 + }, + name: "AtomFileEvent", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "open" + }, { + kind: "string-literal", + value: "close" + }] + } + }, + ProjectState: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 15 + }, + name: "ProjectState", + definition: { + kind: "object", + fields: [{ + name: "rootFolders", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: false + }] + } + }, + AtomNotificationType: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 26 + }, + name: "AtomNotificationType", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "success" + }, { + kind: "string-literal", + value: "info" + }, { + kind: "string-literal", + value: "warning" + }, { + kind: "string-literal", + value: "error" + }, { + kind: "string-literal", + value: "fatal" + }] + } + }, + AtomNotification: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 33 + }, + name: "AtomNotification", + definition: { + kind: "object", + fields: [{ + name: "message", + type: { + kind: "string" + }, + optional: false + }, { + name: "type", + type: { + kind: "named", + name: "AtomNotificationType" + }, + optional: false + }, { + name: "description", + type: { + kind: "string" + }, + optional: true + }, { + name: "detail", + type: { + kind: "string" + }, + optional: true + }, { + name: "icon", + type: { + kind: "string" + }, + optional: true + }, { + name: "dismissable", + type: { + kind: "boolean" + }, + optional: true + }] + } + }, + MultiConnectionAtomCommands: { + kind: "interface", + name: "MultiConnectionAtomCommands", + location: { + type: "source", + fileName: "rpc-types.js", + line: 87 + }, + staticMethods: {}, + instanceMethods: { + getConnectionCount: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 89 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "number" + } + } + }, + openFile: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 95 + }, + kind: "function", + argumentTypes: [{ + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }, { + name: "isWaiting", + type: { + kind: "boolean" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "AtomFileEvent" + } + } + }, + openRemoteFile: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 107 + }, + kind: "function", + argumentTypes: [{ + name: "uri", + type: { + kind: "string" + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }, { + name: "isWaiting", + type: { + kind: "boolean" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "AtomFileEvent" + } + } + }, + addProject: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 123 + }, + kind: "function", + argumentTypes: [{ + name: "projectPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "newWindow", + type: { + kind: "boolean" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + }, + getProjectStates: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 129 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "array", + type: { + kind: "named", + name: "ProjectState" + } + } + } + }, + addNotification: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 134 + }, + kind: "function", + argumentTypes: [{ + name: "notification", + type: { + kind: "named", + name: "AtomNotification" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + }, + dispose: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 136 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "void" + } + } + } + }, + getAtomCommands: { + kind: "function", + name: "getAtomCommands", + location: { + type: "source", + fileName: "CommandService.js", + line: 21 + }, + type: { + location: { + type: "source", + fileName: "CommandService.js", + line: 21 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "MultiConnectionAtomCommands" + } + } + } + }, + ConnectionDetails: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 139 + }, + name: "ConnectionDetails", + definition: { + kind: "object", + fields: [{ + name: "port", + type: { + kind: "number" + }, + optional: false + }, { + name: "family", + type: { + kind: "string" + }, + optional: false + }] + } + }, + getConnectionDetails: { + kind: "function", + name: "getConnectionDetails", + location: { + type: "source", + fileName: "CommandService.js", + line: 25 + }, + type: { + location: { + type: "source", + fileName: "CommandService.js", + line: 25 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "ConnectionDetails" + } + } + } + } + } + } +}); \ No newline at end of file diff --git a/pkg/nuclide-remote-atom-rpc/lib/RemoteCommandService.js b/pkg/nuclide-remote-atom-rpc/lib/RemoteCommandService.js index b3b1751418..47203ceb88 100644 --- a/pkg/nuclide-remote-atom-rpc/lib/RemoteCommandService.js +++ b/pkg/nuclide-remote-atom-rpc/lib/RemoteCommandService.js @@ -1,41 +1,56 @@ -/** - * 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 - */ +'use strict'; -import type {AtomCommands} from './rpc-types'; -import type {FileNotifier} from '../../nuclide-open-files-rpc/lib/rpc-types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.registerAtomCommands = registerAtomCommands; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {FileCache} from '../../nuclide-open-files-rpc/lib/FileCache'; -import {getCommandServer} from './command-server-singleton'; -import invariant from 'assert'; +var _UniversalDisposable; -// This interface is exposed by the nuclide server process to the client side -// Atom process. +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} -/** Dummy alias for IDisposable to satisfy Nuclide-RPC. */ -export interface Unregister { - dispose(): void; +var _FileCache; + +function _load_FileCache() { + return _FileCache = require('../../nuclide-open-files-rpc/lib/FileCache'); +} + +var _commandServerSingleton; + +function _load_commandServerSingleton() { + return _commandServerSingleton = require('./command-server-singleton'); } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Called by Atom once for each new remote connection. */ -export async function registerAtomCommands( - fileNotifier: FileNotifier, - atomCommands: AtomCommands, -): Promise { - invariant(fileNotifier instanceof FileCache); + + +// This interface is exposed by the nuclide server process to the client side +// Atom process. + +/** Dummy alias for IDisposable to satisfy Nuclide-RPC. */ +async function registerAtomCommands(fileNotifier, atomCommands) { + if (!(fileNotifier instanceof (_FileCache || _load_FileCache()).FileCache)) { + throw new Error('Invariant violation: "fileNotifier instanceof FileCache"'); + } + const fileCache = fileNotifier; - const disposables = new UniversalDisposable(); - disposables.add(await getCommandServer().register(fileCache, atomCommands)); + const disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + disposables.add((await (0, (_commandServerSingleton || _load_commandServerSingleton()).getCommandServer)().register(fileCache, atomCommands))); return disposables; -} +} /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-remote-atom-rpc/lib/RemoteCommandServiceProxy.js b/pkg/nuclide-remote-atom-rpc/lib/RemoteCommandServiceProxy.js new file mode 100644 index 0000000000..8a2a46a17c --- /dev/null +++ b/pkg/nuclide-remote-atom-rpc/lib/RemoteCommandServiceProxy.js @@ -0,0 +1,1083 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + remoteModule.Unregister = class { + constructor() { + throw Error("constructors are not supported for remote objects"); + } + + dispose() { + return _client.disposeRemoteObject(this); + } + + }; + remoteModule.FileNotifier = class { + constructor() { + throw Error("constructors are not supported for remote objects"); + } + + onFileEvent(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 62 + }, + name: "FileNotifier" + }), "onFileEvent", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "event", + type: { + kind: "named", + name: "FileEvent" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + } + + onDirectoriesChanged(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 62 + }, + name: "FileNotifier" + }), "onDirectoriesChanged", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "openDirectories", + type: { + kind: "set", + type: { + kind: "named", + name: "NuclideUri" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + } + + dispose() { + return _client.disposeRemoteObject(this); + } + + }; + remoteModule.AtomCommands = class { + constructor() { + throw Error("constructors are not supported for remote objects"); + } + + openFile(arg0, arg1, arg2, arg3) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 47 + }, + name: "AtomCommands" + }), "openFile", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }, { + name: "isWaiting", + type: { + kind: "boolean" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "AtomFileEvent" + }); + }).publish(); + } + + openRemoteFile(arg0, arg1, arg2, arg3) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 47 + }, + name: "AtomCommands" + }), "openRemoteFile", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "uri", + type: { + kind: "string" + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }, { + name: "isWaiting", + type: { + kind: "boolean" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "AtomFileEvent" + }); + }).publish(); + } + + addProject(arg0, arg1) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 47 + }, + name: "AtomCommands" + }), "addProject", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "projectPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "newWindow", + type: { + kind: "boolean" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + } + + getProjectState() { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 47 + }, + name: "AtomCommands" + }), "getProjectState", "promise", _client.marshalArguments(Array.from(arguments), [])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "ProjectState" + }); + }); + } + + addNotification(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "rpc-types.js", + line: 47 + }, + name: "AtomCommands" + }), "addNotification", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "notification", + type: { + kind: "named", + name: "AtomNotification" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + } + + dispose() { + return _client.disposeRemoteObject(this); + } + + }; + + remoteModule.registerAtomCommands = function (arg0, arg1) { + return _client.callRemoteFunction("RemoteCommandService/registerAtomCommands", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileNotifier", + type: { + kind: "named", + name: "FileNotifier" + } + }, { + name: "atomCommands", + type: { + kind: "named", + name: "AtomCommands" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "Unregister" + }); + }); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + Unregister: { + kind: "interface", + name: "Unregister", + location: { + type: "source", + fileName: "RemoteCommandService.js", + line: 24 + }, + staticMethods: {}, + instanceMethods: { + dispose: { + location: { + type: "source", + fileName: "RemoteCommandService.js", + line: 25 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "void" + } + } + } + }, + FileVersion: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 68 + }, + name: "FileVersion", + definition: { + kind: "object", + fields: [{ + name: "notifier", + type: { + kind: "named", + name: "FileNotifier" + }, + optional: false + }, { + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + name: "version", + type: { + kind: "number" + }, + optional: false + }] + } + }, + FileOpenEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 14 + }, + name: "FileOpenEvent", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "open" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "contents", + type: { + kind: "string" + }, + optional: false + }, { + name: "languageId", + type: { + kind: "string" + }, + optional: false + }] + } + }, + FileCloseEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 29 + }, + name: "FileCloseEvent", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "close" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }] + } + }, + FileEditEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 34 + }, + name: "FileEditEvent", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "edit" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "oldRange", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }, { + name: "newRange", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }, { + name: "oldText", + type: { + kind: "string" + }, + optional: false + }, { + name: "newText", + type: { + kind: "string" + }, + optional: false + }] + } + }, + FileSaveEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 43 + }, + name: "FileSaveEvent", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "save" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }] + } + }, + FileSyncEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 22 + }, + name: "FileSyncEvent", + definition: { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "sync" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "contents", + type: { + kind: "string" + }, + optional: false + }, { + name: "languageId", + type: { + kind: "string" + }, + optional: false + }] + } + }, + FileEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 49 + }, + name: "FileEvent", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "open" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "contents", + type: { + kind: "string" + }, + optional: false + }, { + name: "languageId", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "close" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "edit" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "oldRange", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }, { + name: "newRange", + type: { + kind: "named", + name: "atom$Range" + }, + optional: false + }, { + name: "oldText", + type: { + kind: "string" + }, + optional: false + }, { + name: "newText", + type: { + kind: "string" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "save" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "kind", + type: { + kind: "string-literal", + value: "sync" + }, + optional: false + }, { + name: "fileVersion", + type: { + kind: "named", + name: "FileVersion" + }, + optional: false + }, { + name: "contents", + type: { + kind: "string" + }, + optional: false + }, { + name: "languageId", + type: { + kind: "string" + }, + optional: false + }] + }], + discriminantField: "kind" + } + }, + FileNotifier: { + kind: "interface", + name: "FileNotifier", + location: { + type: "source", + fileName: "rpc-types.js", + line: 62 + }, + staticMethods: {}, + instanceMethods: { + onFileEvent: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 63 + }, + kind: "function", + argumentTypes: [{ + name: "event", + type: { + kind: "named", + name: "FileEvent" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + }, + onDirectoriesChanged: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 64 + }, + kind: "function", + argumentTypes: [{ + name: "openDirectories", + type: { + kind: "set", + type: { + kind: "named", + name: "NuclideUri" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + }, + dispose: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 65 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "void" + } + } + } + }, + AtomFileEvent: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 24 + }, + name: "AtomFileEvent", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "open" + }, { + kind: "string-literal", + value: "close" + }] + } + }, + ProjectState: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 15 + }, + name: "ProjectState", + definition: { + kind: "object", + fields: [{ + name: "rootFolders", + type: { + kind: "array", + type: { + kind: "string" + } + }, + optional: false + }] + } + }, + AtomNotificationType: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 26 + }, + name: "AtomNotificationType", + definition: { + kind: "union", + types: [{ + kind: "string-literal", + value: "success" + }, { + kind: "string-literal", + value: "info" + }, { + kind: "string-literal", + value: "warning" + }, { + kind: "string-literal", + value: "error" + }, { + kind: "string-literal", + value: "fatal" + }] + } + }, + AtomNotification: { + kind: "alias", + location: { + type: "source", + fileName: "rpc-types.js", + line: 33 + }, + name: "AtomNotification", + definition: { + kind: "object", + fields: [{ + name: "message", + type: { + kind: "string" + }, + optional: false + }, { + name: "type", + type: { + kind: "named", + name: "AtomNotificationType" + }, + optional: false + }, { + name: "description", + type: { + kind: "string" + }, + optional: true + }, { + name: "detail", + type: { + kind: "string" + }, + optional: true + }, { + name: "icon", + type: { + kind: "string" + }, + optional: true + }, { + name: "dismissable", + type: { + kind: "boolean" + }, + optional: true + }] + } + }, + AtomCommands: { + kind: "interface", + name: "AtomCommands", + location: { + type: "source", + fileName: "rpc-types.js", + line: 47 + }, + staticMethods: {}, + instanceMethods: { + openFile: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 48 + }, + kind: "function", + argumentTypes: [{ + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }, { + name: "isWaiting", + type: { + kind: "boolean" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "AtomFileEvent" + } + } + }, + openRemoteFile: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 55 + }, + kind: "function", + argumentTypes: [{ + name: "uri", + type: { + kind: "string" + } + }, { + name: "line", + type: { + kind: "number" + } + }, { + name: "column", + type: { + kind: "number" + } + }, { + name: "isWaiting", + type: { + kind: "boolean" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "AtomFileEvent" + } + } + }, + addProject: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 68 + }, + kind: "function", + argumentTypes: [{ + name: "projectPath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "newWindow", + type: { + kind: "boolean" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + }, + getProjectState: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 74 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "ProjectState" + } + } + }, + addNotification: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 76 + }, + kind: "function", + argumentTypes: [{ + name: "notification", + type: { + kind: "named", + name: "AtomNotification" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + }, + dispose: { + location: { + type: "source", + fileName: "rpc-types.js", + line: 78 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "void" + } + } + } + }, + registerAtomCommands: { + kind: "function", + name: "registerAtomCommands", + location: { + type: "source", + fileName: "RemoteCommandService.js", + line: 31 + }, + type: { + location: { + type: "source", + fileName: "RemoteCommandService.js", + line: 31 + }, + kind: "function", + argumentTypes: [{ + name: "fileNotifier", + type: { + kind: "named", + name: "FileNotifier" + } + }, { + name: "atomCommands", + type: { + kind: "named", + name: "AtomCommands" + } + }], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "Unregister" + } + } + } + } + } +}); \ No newline at end of file diff --git a/pkg/nuclide-remote-atom-rpc/lib/RoutingAtomCommands.js b/pkg/nuclide-remote-atom-rpc/lib/RoutingAtomCommands.js index ac0d08ec58..0c60002a7e 100644 --- a/pkg/nuclide-remote-atom-rpc/lib/RoutingAtomCommands.js +++ b/pkg/nuclide-remote-atom-rpc/lib/RoutingAtomCommands.js @@ -1,3 +1,22 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RoutingAtomCommands = undefined; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +/** + * Timeout to use when making a getProjectState() RPC. + * Note this is less than the server's default timeout of 60s. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,73 +24,45 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type { - AtomFileEvent, - AtomNotification, - MultiConnectionAtomCommands, - ProjectState, -} from './rpc-types'; -import type {CommandServer} from './CommandServer'; -import type {ConnectableObservable} from 'rxjs'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import {Observable} from 'rxjs'; -import {timeoutPromise} from 'nuclide-commons/promise'; - -/** - * Timeout to use when making a getProjectState() RPC. - * Note this is less than the server's default timeout of 60s. - */ const GET_PROJECT_STATES_TIMEOUT_MS = 10 * 1000; /** * Implementation of MultiConnectionAtomCommands that routes requests * to the appropriate connection from the underlying CommandServer. */ -export class RoutingAtomCommands implements MultiConnectionAtomCommands { - _server: CommandServer; +class RoutingAtomCommands { - constructor(server: CommandServer) { + constructor(server) { this._server = server; } - getConnectionCount(): Promise { + getConnectionCount() { return Promise.resolve(this._server.getConnectionCount()); } - openFile( - filePath: NuclideUri, - line: number, - column: number, - isWaiting: boolean, - ): ConnectableObservable { + openFile(filePath, line, column, isWaiting) { const commands = this._server.getAtomCommandsByPath(filePath); if (commands != null) { return commands.openFile(filePath, line, column, isWaiting); } else { - return Observable.throw(Error('No connected Atom windows')).publish(); + return _rxjsBundlesRxMinJs.Observable.throw(Error('No connected Atom windows')).publish(); } } - openRemoteFile( - uri: string, - line: number, - column: number, - isWaiting: boolean, - ): ConnectableObservable { + openRemoteFile(uri, line, column, isWaiting) { const commands = this._server.getAtomCommandsByPath(uri); if (commands != null) { return commands.openRemoteFile(uri, line, column, isWaiting); } else { - return Observable.throw(Error('No connected Atom windows')).publish(); + return _rxjsBundlesRxMinJs.Observable.throw(Error('No connected Atom windows')).publish(); } } - addProject(projectPath: NuclideUri, newWindow: boolean): Promise { + addProject(projectPath, newWindow) { const commands = this._server.getAtomCommandsByPath(projectPath); if (commands != null) { return commands.addProject(projectPath, newWindow); @@ -80,26 +71,21 @@ export class RoutingAtomCommands implements MultiConnectionAtomCommands { } } - async getProjectStates(): Promise> { + async getProjectStates() { const projectStates = []; for (const connection of this._server.getConnections()) { // Just in case the connection is no longer valid, we wrap it with a // timeout less than Nuclide RPC's default of 60s. We swallow any // errors and return an empty ProjectState if this happens. - projectStates.push( - timeoutPromise( - connection.getAtomCommands().getProjectState(), - GET_PROJECT_STATES_TIMEOUT_MS, - ).catch(error => ({ - rootFolders: [], - })), - ); + projectStates.push((0, (_promise || _load_promise()).timeoutPromise)(connection.getAtomCommands().getProjectState(), GET_PROJECT_STATES_TIMEOUT_MS).catch(error => ({ + rootFolders: [] + }))); } const resolvedProjectStates = await Promise.all(projectStates); return [].concat(...resolvedProjectStates); } - async addNotification(notification: AtomNotification): Promise { + async addNotification(notification) { const promises = []; for (const connection of this._server.getConnections()) { promises.push(connection.getAtomCommands().addNotification(notification)); @@ -109,3 +95,4 @@ export class RoutingAtomCommands implements MultiConnectionAtomCommands { dispose() {} } +exports.RoutingAtomCommands = RoutingAtomCommands; \ No newline at end of file diff --git a/pkg/nuclide-remote-atom-rpc/lib/command-server-singleton.js b/pkg/nuclide-remote-atom-rpc/lib/command-server-singleton.js index 773ba1b7d2..592c42daa0 100644 --- a/pkg/nuclide-remote-atom-rpc/lib/command-server-singleton.js +++ b/pkg/nuclide-remote-atom-rpc/lib/command-server-singleton.js @@ -1,3 +1,19 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getCommandServer = getCommandServer; + +var _CommandServer; + +function _load_CommandServer() { + return _CommandServer = require('./CommandServer'); +} + +const commandServerInstance = new (_CommandServer || _load_CommandServer()).CommandServer(); + +/** @return singleton instance of CommandServer. */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,15 +21,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import {CommandServer} from './CommandServer'; - -const commandServerInstance = new CommandServer(); - -/** @return singleton instance of CommandServer. */ -export function getCommandServer(): CommandServer { +function getCommandServer() { return commandServerInstance; -} +} \ No newline at end of file diff --git a/pkg/nuclide-remote-atom-rpc/lib/rpc-types.js b/pkg/nuclide-remote-atom-rpc/lib/rpc-types.js index d7e12195e7..a726efc43f 100644 --- a/pkg/nuclide-remote-atom-rpc/lib/rpc-types.js +++ b/pkg/nuclide-remote-atom-rpc/lib/rpc-types.js @@ -1,142 +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 - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {ConnectableObservable} from 'rxjs'; - -export type ProjectState = { - /** - * This is the raw value of atom.project.getPaths(). It can - * contain a mix of absolute paths that are local to the machine - * where Atom is running in addition to nuclide:// URIs. - */ - rootFolders: Array, -}; - -export type AtomFileEvent = 'open' | 'close'; - -export type AtomNotificationType = - | 'success' - | 'info' - | 'warning' - | 'error' - | 'fatal'; - -export type AtomNotification = { - message: string, - type: AtomNotificationType, - description?: string, - detail?: string, - icon?: string, - dismissable?: boolean, -}; - -/** - * Collection of client-side actions in Atom that can be invoked from - * a Nuclide server. Each Atom window will register its own instance - * of AtomCommands that it implements. - */ -export interface AtomCommands { - openFile( - // Path local to the machine that made the call to openFile(). - filePath: NuclideUri, - line: number, - column: number, - isWaiting: boolean, - ): ConnectableObservable; - openRemoteFile( - // This is a remote NuclideUri. It is typed as a string so that it does not - // get converted as part of Nuclide-RPC. - uri: string, - line: number, - column: number, - isWaiting: boolean, - ): ConnectableObservable; - - /** - * The returned Promise may resolve before the project is added to Atom if - * newWindow is true. - */ - addProject(projectPath: NuclideUri, newWindow: boolean): Promise; - - /** - * Returns information about the Atom windows that have a Nuclide server - * connection to this AtomCommands. - */ - getProjectState(): Promise; - - addNotification(notification: AtomNotification): Promise; - - dispose(): void; -} - -/** - * Router that forwards requests to the appropriate AtomCommands object, if - * any. Some methods, like openFile(), can be mapped to an AtomCommands based - * on a NuclideUri parameter. Other methods, like getClientConnections(), - * require consulting multiple AtomCommands objects. - */ -export interface MultiConnectionAtomCommands { - /** @return the number of AtomCommands registered with this object. */ - getConnectionCount(): Promise; - - /** - * The ConnectableObservable will throw if there are no connected Atom - * windows where the file can be opened. - */ - openFile( - // Path local to the machine that made the call to openFile(). - filePath: NuclideUri, - line: number, - column: number, - isWaiting: boolean, - ): ConnectableObservable; - - /** - * The ConnectableObservable will throw if there are no connected Atom - * windows where the file can be opened. - */ - openRemoteFile( - // This is a remote NuclideUri. It is typed as a string so that it does not - // get converted as part of Nuclide-RPC. - uri: string, - line: number, - column: number, - isWaiting: boolean, - ): ConnectableObservable; - - /** - * The returned Promise may resolve before the project is added to Atom if - * newWindow is true. - * - * The Promise will reject if there are no connected Atom clients where - * project can be added. - */ - addProject(projectPath: NuclideUri, newWindow: boolean): Promise; - - /** - * Returns information about each Atom window that has a connection to this - * Nuclide server. - */ - getProjectStates(): Promise>; - - /** - * Sends the specified notification to all connected windows. - */ - addNotification(notification: AtomNotification): Promise; - - dispose(): void; -} - -export type ConnectionDetails = { - port: number, - family: string, -}; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-remote-atom-rpc/shared/ConfigDirectory.js b/pkg/nuclide-remote-atom-rpc/shared/ConfigDirectory.js index fa3b8aaa92..db6ca050c0 100644 --- a/pkg/nuclide-remote-atom-rpc/shared/ConfigDirectory.js +++ b/pkg/nuclide-remote-atom-rpc/shared/ConfigDirectory.js @@ -1,40 +1,65 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RPC_PROTOCOL = undefined; +exports.createNewEntry = createNewEntry; +exports.getServer = getServer; + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _fsPromise; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} -import {arrayCompact} from 'nuclide-commons/collection'; -import fs from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {getLogger} from 'log4js'; -import {asyncFind} from 'nuclide-commons/promise'; -import os from 'os'; +var _nuclideUri; -const logger = getLogger('nuclide-remote-atom-rpc'); +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} -export const RPC_PROTOCOL = 'atom_rpc_protocol'; +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _os = _interopRequireDefault(require('os')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-remote-atom-rpc'); /** + * 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. + * + * + * @format + */ + +const RPC_PROTOCOL = exports.RPC_PROTOCOL = 'atom_rpc_protocol'; const NUCLIDE_DIR = '.nuclide'; const NUCLIDE_SERVER_INFO_DIR = 'command-server'; const SERVER_INFO_FILE = 'serverInfo.json'; -export type ServerInfo = { - // Port for local command scripts to connect to the nuclide-server. - commandPort: number, - // address family - family: string, -}; - -function getConfigDirectory(directory: NuclideUri): NuclideUri { - return nuclideUri.join(directory, NUCLIDE_DIR, NUCLIDE_SERVER_INFO_DIR); +function getConfigDirectory(directory) { + return (_nuclideUri || _load_nuclideUri()).default.join(directory, NUCLIDE_DIR, NUCLIDE_SERVER_INFO_DIR); } /** @@ -48,26 +73,22 @@ function getConfigDirectory(directory: NuclideUri): NuclideUri { * Code in this file is used by the NuclideServer process as well as the atom * command line process on the server. */ -async function createConfigDirectory( - clearDirectory: boolean, -): Promise { +async function createConfigDirectory(clearDirectory) { // Try some candidate directories. We exclude the directory if it is on NFS // because nuclide-server is local, so it should only write out its state to // a local directory. - return asyncFind(getCandidateDirectories(), async directory => { - if (await fs.isNonNfsDirectory(directory)) { + return (0, (_promise || _load_promise()).asyncFind)(getCandidateDirectories(), async directory => { + if (await (_fsPromise || _load_fsPromise()).default.isNonNfsDirectory(directory)) { const configDirPath = getConfigDirectory(directory); if (clearDirectory) { // When starting up a new server, we remove any connection configs leftover // from previous runs. - await fs.rimraf(configDirPath); - if (await fs.exists(configDirPath)) { - throw new Error( - 'createConfigDirectory: Failed to remove' + configDirPath, - ); + await (_fsPromise || _load_fsPromise()).default.rimraf(configDirPath); + if (await (_fsPromise || _load_fsPromise()).default.exists(configDirPath)) { + throw new Error('createConfigDirectory: Failed to remove' + configDirPath); } } - await fs.mkdirp(configDirPath); + await (_fsPromise || _load_fsPromise()).default.mkdirp(configDirPath); return configDirPath; } else { return null; @@ -75,10 +96,7 @@ async function createConfigDirectory( }); } -export async function createNewEntry( - commandPort: number, - family: string, -): Promise { +async function createNewEntry(commandPort, family) { const clearDirectory = true; const configDirectory = await createConfigDirectory(clearDirectory); if (configDirectory == null) { @@ -87,27 +105,22 @@ export async function createNewEntry( // TODO: Instead of using this dummy '0' port, will need to figure out // a directory structure which can handle multiple registered servers on the client side. - const subdir = nuclideUri.join(configDirectory, String(0)); - await fs.rimraf(subdir); - if (await fs.exists(subdir)) { + const subdir = (_nuclideUri || _load_nuclideUri()).default.join(configDirectory, String(0)); + await (_fsPromise || _load_fsPromise()).default.rimraf(subdir); + if (await (_fsPromise || _load_fsPromise()).default.exists(subdir)) { throw new Error('createNewEntry: Failed to delete: ' + subdir); } const info = { commandPort, - family, + family }; - await fs.mkdir(subdir); - await fs.writeFile( - nuclideUri.join(subdir, SERVER_INFO_FILE), - JSON.stringify(info), - ); - - logger.debug( - `Created new remote atom config at ${subdir} for port ${commandPort} family ${family}`, - ); + await (_fsPromise || _load_fsPromise()).default.mkdir(subdir); + await (_fsPromise || _load_fsPromise()).default.writeFile((_nuclideUri || _load_nuclideUri()).default.join(subdir, SERVER_INFO_FILE), JSON.stringify(info)); + + logger.debug(`Created new remote atom config at ${subdir} for port ${commandPort} family ${family}`); } -export async function getServer(): Promise { +async function getServer() { const configDirectory = await findPathToConfigDirectory(); if (configDirectory == null) { return null; @@ -119,53 +132,43 @@ export async function getServer(): Promise { // In the future, we may use the serverMetadata to determine which server // to use. if (serverInfos.length > 0) { - const {commandPort, family} = serverInfos[0]; - logger.debug( - `Read remote atom config at ${configDirectory} for port ${commandPort} family ${family}`, - ); + const { commandPort, family } = serverInfos[0]; + logger.debug(`Read remote atom config at ${configDirectory} for port ${commandPort} family ${family}`); return serverInfos[0]; } else { return null; } } -async function getServerInfos( - configDirectory: NuclideUri, -): Promise> { - const entries = await fs.readdir(configDirectory); - return arrayCompact( - // $FlowFixMe - await Promise.all( - entries.map(async entry => { - const subdir = nuclideUri.join(configDirectory, entry); - const info = JSON.parse( - await fs.readFile(nuclideUri.join(subdir, SERVER_INFO_FILE), 'utf8'), - ); - if (info.commandPort != null && info.family != null) { - return info; - } else { - return null; - } - }), - ), - ); +async function getServerInfos(configDirectory) { + const entries = await (_fsPromise || _load_fsPromise()).default.readdir(configDirectory); + return (0, (_collection || _load_collection()).arrayCompact)(( + // $FlowFixMe + await Promise.all(entries.map(async entry => { + const subdir = (_nuclideUri || _load_nuclideUri()).default.join(configDirectory, entry); + const info = JSON.parse((await (_fsPromise || _load_fsPromise()).default.readFile((_nuclideUri || _load_nuclideUri()).default.join(subdir, SERVER_INFO_FILE), 'utf8'))); + if (info.commandPort != null && info.family != null) { + return info; + } else { + return null; + } + })))); } -function findPathToConfigDirectory(): Promise { - return asyncFind(getCandidateDirectories(), async directory => { +function findPathToConfigDirectory() { + return (0, (_promise || _load_promise()).asyncFind)(getCandidateDirectories(), async directory => { const configDir = getConfigDirectory(directory); - return (await fs.exists(configDir)) ? configDir : null; + return (await (_fsPromise || _load_fsPromise()).default.exists(configDir)) ? configDir : null; }); } -function getCandidateDirectories(): Array { - const {homedir} = os.userInfo(); +function getCandidateDirectories() { + const { homedir } = _os.default.userInfo(); return [ - // Try the ~/local directory (if it exists) to avoid directly polluting homedirs. - nuclideUri.resolve(nuclideUri.join(homedir, 'local')), - // Then try the OS temporary directory... - os.tmpdir(), - // And fall back to the home directory as a last resort. - homedir, - ]; -} + // Try the ~/local directory (if it exists) to avoid directly polluting homedirs. + (_nuclideUri || _load_nuclideUri()).default.resolve((_nuclideUri || _load_nuclideUri()).default.join(homedir, 'local')), + // Then try the OS temporary directory... + _os.default.tmpdir(), + // And fall back to the home directory as a last resort. + homedir]; +} \ No newline at end of file diff --git a/pkg/nuclide-remote-atom/lib/main.js b/pkg/nuclide-remote-atom/lib/main.js index e8089e8a12..5f09e069ad 100644 --- a/pkg/nuclide-remote-atom/lib/main.js +++ b/pkg/nuclide-remote-atom/lib/main.js @@ -1,3 +1,67 @@ +'use strict'; + +var _querystring = _interopRequireDefault(require('querystring')); + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _goToLocation; + +function _load_goToLocation() { + return _goToLocation = require('../../../modules/nuclide-commons-atom/go-to-location'); +} + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _textEditor; + +function _load_textEditor() { + return _textEditor = require('../../../modules/nuclide-commons-atom/text-editor'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _nuclideOpenFiles; + +function _load_nuclideOpenFiles() { + return _nuclideOpenFiles = require('../../nuclide-open-files'); +} + +var _electron = require('electron'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,237 +69,151 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import typeof * as RemoteCommandServiceType from '../../nuclide-remote-atom-rpc/lib/RemoteCommandService'; -import type { - AtomCommands, - AtomFileEvent, - AtomNotification, - ProjectState, -} from '../../nuclide-remote-atom-rpc/lib/rpc-types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {ConnectableObservable} from 'rxjs'; -import type {DeepLinkService} from '../../nuclide-deep-link/lib/types'; -import type {RemoteProjectsService} from '../../nuclide-remote-projects'; - -import invariant from 'assert'; -import querystring from 'querystring'; -import { - getServiceByConnection, - ConnectionCache, -} from '../../nuclide-remote-connection'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {goToLocation} from 'nuclide-commons-atom/go-to-location'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {getLogger} from 'log4js'; -import {observeEditorDestroy} from 'nuclide-commons-atom/text-editor'; -import {Observable} from 'rxjs'; -import {ServerConnection} from '../../nuclide-remote-connection'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {getNotifierByConnection} from '../../nuclide-open-files'; -import {shell} from 'electron'; - const REMOTE_COMMAND_SERVICE = 'RemoteCommandService'; const ATOM_URI_ADD_PATH = 'add-path'; class Activation { - _disposables: UniversalDisposable; - _commands: AtomCommands; - _remoteProjectsService: ?RemoteProjectsService; constructor() { - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._commands = { - openFile( - uri: NuclideUri, - line: number, - column: number, - isWaiting: boolean, - ): ConnectableObservable { + openFile(uri, line, column, isWaiting) { return openFile(uri, line, column, isWaiting); }, - openRemoteFile( - uri: NuclideUri, - line: number, - column: number, - isWaiting: boolean, - ): ConnectableObservable { - if (ServerConnection.getForUri(uri) == null) { - return Observable.throw( - new Error(`Atom is not connected to host for ${uri}`), - ).publish(); + openRemoteFile(uri, line, column, isWaiting) { + if ((_nuclideRemoteConnection || _load_nuclideRemoteConnection()).ServerConnection.getForUri(uri) == null) { + return _rxjsBundlesRxMinJs.Observable.throw(new Error(`Atom is not connected to host for ${uri}`)).publish(); } return openFile(uri, line, column, isWaiting); }, - async addProject( - projectPath: NuclideUri, - newWindow: boolean, - ): Promise { - if (nuclideUri.isLocal(projectPath)) { + async addProject(projectPath, newWindow) { + if ((_nuclideUri || _load_nuclideUri()).default.isLocal(projectPath)) { atom.applicationDelegate.open({ pathsToOpen: [projectPath], newWindow, devMode: atom.devMode, - safeMode: atom.inSafeMode(), + safeMode: atom.inSafeMode() }); } else { let queryParams = { - path: projectPath, + path: projectPath }; if (newWindow) { - queryParams = {...queryParams, target: '_blank'}; + queryParams = Object.assign({}, queryParams, { target: '_blank' }); } - const url = - `atom://nuclide/${ATOM_URI_ADD_PATH}?` + - querystring.stringify(queryParams); - shell.openExternal(url); + const url = `atom://nuclide/${ATOM_URI_ADD_PATH}?` + _querystring.default.stringify(queryParams); + _electron.shell.openExternal(url); } }, - async getProjectState(): Promise { + async getProjectState() { return { - rootFolders: atom.project.getPaths(), + rootFolders: atom.project.getPaths() }; }, - addNotification(notification: AtomNotification): Promise { - const {type, message} = notification; - const {description, detail, icon, dismissable} = notification; - const options = {description, detail, icon, dismissable}; + addNotification(notification) { + const { type, message } = notification; + const { description, detail, icon, dismissable } = notification; + const options = { description, detail, icon, dismissable }; atom.notifications.add(type, message, options); return Promise.resolve(); }, - dispose(): void {}, + dispose() {} }; - this._disposables.add( - new ConnectionCache(async connection => { - // If connection is null, this indicates a local connection. Because usage - // of the local command server is low and it introduces the cost of - // starting an extra process when Atom starts up, only enable it if the - // user has explicitly opted-in. - if ( - connection == null && - !featureConfig.get('nuclide-remote-atom.enableLocalCommandService') - ) { - return {dispose: () => {}}; - } + this._disposables.add(new (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).ConnectionCache(async connection => { + // If connection is null, this indicates a local connection. Because usage + // of the local command server is low and it introduces the cost of + // starting an extra process when Atom starts up, only enable it if the + // user has explicitly opted-in. + if (connection == null && !(_featureConfig || _load_featureConfig()).default.get('nuclide-remote-atom.enableLocalCommandService')) { + return { dispose: () => {} }; + } - const service: RemoteCommandServiceType = getServiceByConnection( - REMOTE_COMMAND_SERVICE, - connection, - ); - const fileNotifier = await getNotifierByConnection(connection); - return service.registerAtomCommands(fileNotifier, this._commands); - }), - ); + const service = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getServiceByConnection)(REMOTE_COMMAND_SERVICE, connection); + const fileNotifier = await (0, (_nuclideOpenFiles || _load_nuclideOpenFiles()).getNotifierByConnection)(connection); + return service.registerAtomCommands(fileNotifier, this._commands); + })); } - consumeRemoteProjectsService(service: RemoteProjectsService): IDisposable { + consumeRemoteProjectsService(service) { this._remoteProjectsService = service; - const disposable = new UniversalDisposable(() => { + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { this._remoteProjectsService = null; }); this._disposables.add(disposable); return disposable; } - consumeDeepLinkService(service: DeepLinkService): IDisposable { - const disposable = service.subscribeToPath( - ATOM_URI_ADD_PATH, - async params => { - const {path: projectPath} = params; - invariant(typeof projectPath === 'string'); - if (!nuclideUri.isRemote(projectPath)) { - getLogger(`Expected remote Nuclide URI but got ${projectPath}.`); - return; - } + consumeDeepLinkService(service) { + const disposable = service.subscribeToPath(ATOM_URI_ADD_PATH, async params => { + const { path: projectPath } = params; - const remoteProjectsService = this._remoteProjectsService; - if (remoteProjectsService == null) { - getLogger('No provider for nuclide-remote-projects was found.'); - return; - } + if (!(typeof projectPath === 'string')) { + throw new Error('Invariant violation: "typeof projectPath === \'string\'"'); + } - getLogger().info(`Attempting to addProject(${projectPath}).`); - const hostname = nuclideUri.getHostname(projectPath); - await remoteProjectsService.createRemoteConnection({ - host: hostname, - path: nuclideUri.getPath(projectPath), - displayTitle: hostname, - }); - }, - ); + if (!(_nuclideUri || _load_nuclideUri()).default.isRemote(projectPath)) { + (0, (_log4js || _load_log4js()).getLogger)(`Expected remote Nuclide URI but got ${projectPath}.`); + return; + } + + const remoteProjectsService = this._remoteProjectsService; + if (remoteProjectsService == null) { + (0, (_log4js || _load_log4js()).getLogger)('No provider for nuclide-remote-projects was found.'); + return; + } + + (0, (_log4js || _load_log4js()).getLogger)().info(`Attempting to addProject(${projectPath}).`); + const hostname = (_nuclideUri || _load_nuclideUri()).default.getHostname(projectPath); + await remoteProjectsService.createRemoteConnection({ + host: hostname, + path: (_nuclideUri || _load_nuclideUri()).default.getPath(projectPath), + displayTitle: hostname + }); + }); this._disposables.add(disposable); return disposable; } - dispose(): void { + dispose() { this._disposables.dispose(); } } -function openFile( - uri: NuclideUri, - line: number, - column: number, - isWaiting: boolean, -): ConnectableObservable { - return Observable.fromPromise( - goToLocation(uri, {line, column}).then(editor => { - atom.applicationDelegate.focusWindow(); - - if ( - isWaiting && - featureConfig.get( - 'nuclide-remote-atom.shouldNotifyWhenCommandLineIsWaitingOnFile', - ) - ) { - const notification = atom.notifications.addInfo( - `The command line has opened \`${nuclideUri.getPath(uri)}\`` + - ' and is waiting for it to be closed.', - { - dismissable: true, - buttons: [ - { - onDidClick: () => { - featureConfig.set( - 'nuclide-remote-atom.shouldNotifyWhenCommandLineIsWaitingOnFile', - false, - ); - notification.dismiss(); - }, - text: "Don't show again", - }, - { - onDidClick: () => { - editor.destroy(); - }, - text: 'Close file', - }, - ], +function openFile(uri, line, column, isWaiting) { + return _rxjsBundlesRxMinJs.Observable.fromPromise((0, (_goToLocation || _load_goToLocation()).goToLocation)(uri, { line, column }).then(editor => { + atom.applicationDelegate.focusWindow(); + + if (isWaiting && (_featureConfig || _load_featureConfig()).default.get('nuclide-remote-atom.shouldNotifyWhenCommandLineIsWaitingOnFile')) { + const notification = atom.notifications.addInfo(`The command line has opened \`${(_nuclideUri || _load_nuclideUri()).default.getPath(uri)}\`` + ' and is waiting for it to be closed.', { + dismissable: true, + buttons: [{ + onDidClick: () => { + (_featureConfig || _load_featureConfig()).default.set('nuclide-remote-atom.shouldNotifyWhenCommandLineIsWaitingOnFile', false); + notification.dismiss(); }, - ); - editor.onDidDestroy(() => { - notification.dismiss(); - }); - } - - return editor; - }), - ) - .switchMap(editor => - Observable.merge( - Observable.of('open'), - observeEditorDestroy(editor).map(value => 'close'), - ), - ) - .publish(); + text: "Don't show again" + }, { + onDidClick: () => { + editor.destroy(); + }, + text: 'Close file' + }] + }); + editor.onDidDestroy(() => { + notification.dismiss(); + }); + } + + return editor; + })).switchMap(editor => _rxjsBundlesRxMinJs.Observable.merge(_rxjsBundlesRxMinJs.Observable.of('open'), (0, (_textEditor || _load_textEditor()).observeEditorDestroy)(editor).map(value => 'close'))).publish(); } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/__atom_tests__/RemoteConnection-test.js b/pkg/nuclide-remote-connection/__atom_tests__/RemoteConnection-test.js index bf688c544b..5412e79f8f 100644 --- a/pkg/nuclide-remote-connection/__atom_tests__/RemoteConnection-test.js +++ b/pkg/nuclide-remote-connection/__atom_tests__/RemoteConnection-test.js @@ -1,3 +1,27 @@ +'use strict'; + +var _fs = _interopRequireDefault(require('fs')); + +var _RemoteConnection; + +function _load_RemoteConnection() { + return _RemoteConnection = require('../lib/RemoteConnection'); +} + +var _ServerConnection; + +function _load_ServerConnection() { + return _ServerConnection = require('../lib/ServerConnection'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,102 +29,77 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import fs from 'fs'; -import {RemoteConnection} from '../lib/RemoteConnection'; -import {ServerConnection, __test__} from '../lib/ServerConnection'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - -const pathToFakePk = nuclideUri.join(__dirname, 'fakepk'); +const pathToFakePk = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, 'fakepk'); describe('RemoteConnection', () => { - const testConnections = __test__.connections; + const testConnections = (_ServerConnection || _load_ServerConnection()).__test__.connections; let testConnection; const testHostname = 'foo.nuclide.com'; const testPath = '/home/foo/test'; beforeEach(() => { - fs.writeFileSync(pathToFakePk, ''); - const server = new ServerConnection({ + _fs.default.writeFileSync(pathToFakePk, ''); + const server = new (_ServerConnection || _load_ServerConnection()).ServerConnection({ host: testHostname, - port: 8192, + port: 8192 }); testConnections.set(testHostname, server); - testConnection = new RemoteConnection(server, testPath, '', true); + testConnection = new (_RemoteConnection || _load_RemoteConnection()).RemoteConnection(server, testPath, '', true); server.addConnection(testConnection); }); afterEach(() => { testConnections.delete(testHostname); - if (fs.existsSync(pathToFakePk)) { - fs.unlinkSync(pathToFakePk); + if (_fs.default.existsSync(pathToFakePk)) { + _fs.default.unlinkSync(pathToFakePk); } }); describe('getByHostnameAndPath()', () => { it('gets a connection if the hostname and path matches', () => { - const conn = RemoteConnection.getByHostnameAndPath( - testHostname, - testPath, - ); + const conn = (_RemoteConnection || _load_RemoteConnection()).RemoteConnection.getByHostnameAndPath(testHostname, testPath); expect(conn).toBe(testConnection); }); it('returns undefined if the path is not matching', () => { - const conn = RemoteConnection.getByHostnameAndPath( - testHostname, - '/home/bar/test', - ); + const conn = (_RemoteConnection || _load_RemoteConnection()).RemoteConnection.getByHostnameAndPath(testHostname, '/home/bar/test'); expect(conn).toBeUndefined(); }); it('returns undefined if the hostname is not matching', () => { - const conn = RemoteConnection.getByHostnameAndPath( - 'bar.nuclide.com', - testPath, - ); + const conn = (_RemoteConnection || _load_RemoteConnection()).RemoteConnection.getByHostnameAndPath('bar.nuclide.com', testPath); expect(conn).toBeUndefined(); }); it('returns a connection if given a file path deep into the directory path', () => { - const conn = RemoteConnection.getByHostnameAndPath( - testHostname, - testPath + '/def/abc.txt', - ); + const conn = (_RemoteConnection || _load_RemoteConnection()).RemoteConnection.getByHostnameAndPath(testHostname, testPath + '/def/abc.txt'); expect(conn).toBe(testConnection); }); }); describe('getForUri()', () => { it('gets a connection if the hostname and path matches', () => { - const conn = RemoteConnection.getForUri( - `nuclide://${testHostname}${testPath}`, - ); + const conn = (_RemoteConnection || _load_RemoteConnection()).RemoteConnection.getForUri(`nuclide://${testHostname}${testPath}`); expect(conn).toBe(testConnection); }); it('returns undefined if the path is not matching', () => { - const conn = RemoteConnection.getForUri( - `nuclide://${testHostname}$/home/bar/test`, - ); + const conn = (_RemoteConnection || _load_RemoteConnection()).RemoteConnection.getForUri(`nuclide://${testHostname}$/home/bar/test`); expect(conn).toBeUndefined(); }); it('returns undefined if the hostname is not matching', () => { - const conn = RemoteConnection.getForUri( - `nuclide://bar.nuclide.com${testPath}`, - ); + const conn = (_RemoteConnection || _load_RemoteConnection()).RemoteConnection.getForUri(`nuclide://bar.nuclide.com${testPath}`); expect(conn).toBeUndefined(); }); it('returns a connection if given a file path deep into the directory path', () => { - const conn = RemoteConnection.getForUri( - `nuclide://${testHostname}${testPath}/def/abc.txt`, - ); + const conn = (_RemoteConnection || _load_RemoteConnection()).RemoteConnection.getForUri(`nuclide://${testHostname}${testPath}/def/abc.txt`); expect(conn).toBe(testConnection); }); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/__atom_tests__/RemoteConnectionConfigurationManager-test.js b/pkg/nuclide-remote-connection/__atom_tests__/RemoteConnectionConfigurationManager-test.js index 55be57a875..e463d52b03 100644 --- a/pkg/nuclide-remote-connection/__atom_tests__/RemoteConnectionConfigurationManager-test.js +++ b/pkg/nuclide-remote-connection/__atom_tests__/RemoteConnectionConfigurationManager-test.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,13 +7,13 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ const { encryptString, - decryptString, + decryptString // eslint-disable-next-line nuclide-internal/no-commonjs } = require('../lib/RemoteConnectionConfigurationManager').__test__; @@ -19,10 +21,10 @@ describe('RemoteConnectionConfigurationManager', () => { describe('encryptString and decryptString', () => { it('can encrypt and dycrypt strings', () => { const text = 'This little piggy went to market'; - const {password, salt, encryptedString} = encryptString(text); + const { password, salt, encryptedString } = encryptString(text); expect(encryptedString).not.toEqual(text); expect(decryptString(encryptedString, password, salt)).toEqual(text); }); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/__atom_tests__/RemoteDirectory-test.js b/pkg/nuclide-remote-connection/__atom_tests__/RemoteDirectory-test.js index 272789d2ca..9177d1ffb2 100644 --- a/pkg/nuclide-remote-connection/__atom_tests__/RemoteDirectory-test.js +++ b/pkg/nuclide-remote-connection/__atom_tests__/RemoteDirectory-test.js @@ -1,3 +1,41 @@ +'use strict'; + +var _fs = _interopRequireDefault(require('fs')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _atom = require('atom'); + +var _RemoteDirectory; + +function _load_RemoteDirectory() { + return _RemoteDirectory = require('../lib/RemoteDirectory'); +} + +var _connection_mock; + +function _load_connection_mock() { + return _connection_mock = _interopRequireDefault(require('../__mocks__/connection_mock')); +} + +var _temp; + +function _load_temp() { + return _temp = _interopRequireDefault(require('temp')); +} + +var _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../../../jest/waits_for')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,109 +43,68 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import invariant from 'assert'; -import fs from 'fs'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Directory} from 'atom'; -import {RemoteDirectory} from '../lib/RemoteDirectory'; -import connectionMock from '../__mocks__/connection_mock'; -import temp from 'temp'; -import waitsFor from '../../../jest/waits_for'; - -temp.track(); +(_temp || _load_temp()).default.track(); const FILE_MODE = 33188; describe('RemoteDirectory', () => { it('does have a existsSync() method', () => { - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/', - ); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/'); expect(remoteDirectory.existsSync()).toBe(true); }); - it( - 'does not list the property used to mark the directory as remote as one of its enumerable' + - ' properties.', - () => { - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/', - ); - for (const property in remoteDirectory) { - expect(property).not.toBe('__nuclide_remote_directory__'); - } - }, - ); + it('does not list the property used to mark the directory as remote as one of its enumerable' + ' properties.', () => { + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/'); + for (const property in remoteDirectory) { + expect(property).not.toBe('__nuclide_remote_directory__'); + } + }); describe('::isRemoteDirectory', () => { it('distinguishes a RemoteDirectory from a Directory.', () => { - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/', - ); - expect(RemoteDirectory.isRemoteDirectory(remoteDirectory)).toBe(true); - - const localDirectory = new Directory('/Test/Path'); - expect(RemoteDirectory.isRemoteDirectory(localDirectory)).toBe(false); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/'); + expect((_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory.isRemoteDirectory(remoteDirectory)).toBe(true); + + const localDirectory = new _atom.Directory('/Test/Path'); + expect((_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory.isRemoteDirectory(localDirectory)).toBe(false); }); }); }); describe('RemoteDirectory::isRoot()', () => { it('nuclide://example.com/ is a root', () => { - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/', - ); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/'); expect(remoteDirectory.isRoot()).toBe(true); }); it('nuclide://example.com/path/to/directory is not a root', () => { - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/path/to/directory', - ); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/path/to/directory'); expect(remoteDirectory.isRoot()).toBe(false); }); }); describe('RemoteDirectory::getBaseName()', () => { it('to handle a root path', () => { - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/', - ); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/'); expect(remoteDirectory.getBaseName()).toBe(''); }); it('to handle a non-root path', () => { - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/path/to/directory', - ); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/path/to/directory'); expect(remoteDirectory.getBaseName()).toBe('directory'); }); }); describe('RemoteDirectory::relativize()', () => { it('to relativize a file against a root path', () => { - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/', - ); - expect(remoteDirectory.relativize('nuclide://example.com/foo/bar')).toBe( - 'foo/bar', - ); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/'); + expect(remoteDirectory.relativize('nuclide://example.com/foo/bar')).toBe('foo/bar'); // Should not relativize paths from other hosts. - expect(remoteDirectory.relativize('nuclide://example2.com/foo/bar')).toBe( - 'nuclide://example2.com/foo/bar', - ); + expect(remoteDirectory.relativize('nuclide://example2.com/foo/bar')).toBe('nuclide://example2.com/foo/bar'); }); }); @@ -116,43 +113,32 @@ describe('RemoteDirectory::getEntries()', () => { let complete = false; // Directories should sort first, then files, and case should be ignored - jest - .spyOn(connectionMock.getFsService(), 'readdir') - .mockReturnValue([ - ['Aa', true], - ['a', true], - ['Bb', false], - ['b', false], - ]); - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/', - ); + jest.spyOn((_connection_mock || _load_connection_mock()).default.getFsService(), 'readdir').mockReturnValue([['Aa', true], ['a', true], ['Bb', false], ['b', false]]); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/'); remoteDirectory.getEntries((err, entries) => { expect(err).toBe(null); - invariant(entries); + + if (!entries) { + throw new Error('Invariant violation: "entries"'); + } + const sortedEntries = entries.map(entry => entry.getBaseName()); expect(sortedEntries).toEqual(['b', 'Bb', 'a', 'Aa']); complete = true; }); - waitsFor(() => complete); + (0, (_waits_for || _load_waits_for()).default)(() => complete); }); it("calls the given callback with an error on failure to match node-path-watcher's API", async () => { let complete = false; - jest - .spyOn(connectionMock.getFsService(), 'readdir') - .mockImplementation(() => { - throw new Error('ENOENT'); - }); + jest.spyOn((_connection_mock || _load_connection_mock()).default.getFsService(), 'readdir').mockImplementation(() => { + throw new Error('ENOENT'); + }); - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/', - ); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/'); remoteDirectory.getEntries((err, entries) => { expect(err).not.toBe(null); @@ -160,104 +146,66 @@ describe('RemoteDirectory::getEntries()', () => { complete = true; }); - await waitsFor(() => complete); + await (0, (_waits_for || _load_waits_for()).default)(() => complete); }); }); describe('RemoteDirectory::getParent()', () => { it('a root is its own parent', () => { - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/', - ); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/'); expect(remoteDirectory.getParent()).toBe(remoteDirectory); }); it('a non-root has the expected parent', () => { const parentDirectory = jest.fn(); - jest - .spyOn(connectionMock, 'createDirectory') - .mockReturnValue(parentDirectory); - - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/path/to/directory', - ); + jest.spyOn((_connection_mock || _load_connection_mock()).default, 'createDirectory').mockReturnValue(parentDirectory); + + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/path/to/directory'); expect(remoteDirectory.getParent()).toBe(parentDirectory); - expect(connectionMock.createDirectory).toHaveBeenCalledWith( - 'nuclide://example.com/path/to', - null, - ); + expect((_connection_mock || _load_connection_mock()).default.createDirectory).toHaveBeenCalledWith('nuclide://example.com/path/to', null); }); }); describe('RemoteDirectory::contains()', () => { it('returns false when passed undefined path', () => { - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/', - ); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/'); expect(remoteDirectory.contains(undefined)).toBe(false); }); it('returns false when passed null path', () => { - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/', - ); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/'); expect(remoteDirectory.contains(null)).toBe(false); }); it('returns false when passed empty path', () => { - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/', - ); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/'); expect(remoteDirectory.contains('')).toBe(false); }); it('returns true when passed sub directory', () => { - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/', - ); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/'); expect(remoteDirectory.contains('nuclide://example.com/asdf')).toBe(true); }); it('returns false when passed dir at same level with similar name', () => { - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/www', - ); - expect(remoteDirectory.contains('nuclide://example.com/www-base')).toBe( - false, - ); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/www'); + expect(remoteDirectory.contains('nuclide://example.com/www-base')).toBe(false); }); it('returns false when has slash and passed dir with similar name', () => { - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/www/', - ); - expect(remoteDirectory.contains('nuclide://example.com/www-base')).toBe( - false, - ); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/www/'); + expect(remoteDirectory.contains('nuclide://example.com/www-base')).toBe(false); }); }); describe('RemoteDirectory::getFile()', () => { it('returns a RemoteFile under the directory', () => { const remoteFile = jest.fn(); - jest.spyOn(connectionMock, 'createFile').mockReturnValue(remoteFile); + jest.spyOn((_connection_mock || _load_connection_mock()).default, 'createFile').mockReturnValue(remoteFile); - const remoteDirectory = new RemoteDirectory( - connectionMock, - 'nuclide://example.com/path/to/directory', - ); + const remoteDirectory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, 'nuclide://example.com/path/to/directory'); expect(remoteDirectory.getFile('foo.txt')).toBe(remoteFile); - expect(connectionMock.createFile).toHaveBeenCalledWith( - 'nuclide://example.com/path/to/directory/foo.txt', - ); + expect((_connection_mock || _load_connection_mock()).default.createFile).toHaveBeenCalledWith('nuclide://example.com/path/to/directory/foo.txt'); }); }); @@ -265,33 +213,27 @@ describe('RemoteDirectory::delete()', () => { let tempDir; beforeEach(() => { - tempDir = temp.mkdirSync('delete_test'); + tempDir = (_temp || _load_temp()).default.mkdirSync('delete_test'); }); it('deletes the existing directory', async () => { await (async () => { - const directoryPath = nuclideUri.join(tempDir, 'directory_to_delete'); - fs.mkdirSync(directoryPath); - fs.mkdirSync(nuclideUri.join(directoryPath, 'subdir')); - const directory = new RemoteDirectory( - connectionMock, - `nuclide://host13${directoryPath}`, - ); - expect(fs.existsSync(directoryPath)).toBe(true); + const directoryPath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'directory_to_delete'); + _fs.default.mkdirSync(directoryPath); + _fs.default.mkdirSync((_nuclideUri || _load_nuclideUri()).default.join(directoryPath, 'subdir')); + const directory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, `nuclide://host13${directoryPath}`); + expect(_fs.default.existsSync(directoryPath)).toBe(true); await directory.delete(); - expect(fs.existsSync(directoryPath)).toBe(false); + expect(_fs.default.existsSync(directoryPath)).toBe(false); })(); }); it('deletes the non-existent directory', async () => { await (async () => { - const directoryPath = nuclideUri.join(tempDir, 'directory_to_delete'); - const directory = new RemoteDirectory( - connectionMock, - `nuclide://host13${directoryPath}`, - ); + const directoryPath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'directory_to_delete'); + const directory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, `nuclide://host13${directoryPath}`); await directory.delete(); - expect(fs.existsSync(directoryPath)).toBe(false); + expect(_fs.default.existsSync(directoryPath)).toBe(false); })(); }); }); @@ -299,13 +241,10 @@ describe('RemoteDirectory::delete()', () => { describe('RemoteDirectory::exists()', () => { it('verifies existence', async () => { await (async () => { - const directoryPath = temp.mkdirSync('exists_test'); - expect(fs.existsSync(directoryPath)).toBe(true); + const directoryPath = (_temp || _load_temp()).default.mkdirSync('exists_test'); + expect(_fs.default.existsSync(directoryPath)).toBe(true); - const directory = new RemoteDirectory( - connectionMock, - `nuclide://host13${directoryPath}`, - ); + const directory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, `nuclide://host13${directoryPath}`); const exists = await directory.exists(); expect(exists).toBe(true); })(); @@ -313,17 +252,11 @@ describe('RemoteDirectory::exists()', () => { it('verifies non-existence', async () => { await (async () => { - const tempDir = temp.mkdirSync('exists_test'); - const directoryPath = nuclideUri.join( - tempDir, - '/directory_that_doesnt_exist', - ); - expect(fs.existsSync(directoryPath)).toBe(false); - - const directory = new RemoteDirectory( - connectionMock, - `nuclide://host13${directoryPath}`, - ); + const tempDir = (_temp || _load_temp()).default.mkdirSync('exists_test'); + const directoryPath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, '/directory_that_doesnt_exist'); + expect(_fs.default.existsSync(directoryPath)).toBe(false); + + const directory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, `nuclide://host13${directoryPath}`); const exists = await directory.exists(); expect(exists).toBe(false); })(); @@ -334,35 +267,27 @@ describe('RemoteDirectory::isSymbolicLink()', () => { let tempDir; beforeEach(() => { - tempDir = temp.mkdirSync('rename_test'); + tempDir = (_temp || _load_temp()).default.mkdirSync('rename_test'); }); it('verifies symlink', () => { - const targetDirectoryPath = nuclideUri.join(tempDir, 'target'); - const symLinkedDirectoryPath = nuclideUri.join(tempDir, 'linked'); - fs.mkdirSync(targetDirectoryPath); - fs.symlinkSync(targetDirectoryPath, symLinkedDirectoryPath, 'dir'); - expect(fs.lstatSync(symLinkedDirectoryPath).isSymbolicLink()).toBe(true); - - const directory = new RemoteDirectory( - connectionMock, - `nuclide://host13${symLinkedDirectoryPath}`, - true, - ); + const targetDirectoryPath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'target'); + const symLinkedDirectoryPath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'linked'); + _fs.default.mkdirSync(targetDirectoryPath); + _fs.default.symlinkSync(targetDirectoryPath, symLinkedDirectoryPath, 'dir'); + expect(_fs.default.lstatSync(symLinkedDirectoryPath).isSymbolicLink()).toBe(true); + + const directory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, `nuclide://host13${symLinkedDirectoryPath}`, true); const symlink = directory.isSymbolicLink(); expect(symlink).toBe(true); }); it('verifies non-symlink', () => { - const notLinkedDirectoryPath = nuclideUri.join(tempDir, 'not_linked'); - fs.mkdirSync(notLinkedDirectoryPath); - expect(fs.lstatSync(notLinkedDirectoryPath).isSymbolicLink()).toBe(false); - - const directory = new RemoteDirectory( - connectionMock, - `nuclide://host13${notLinkedDirectoryPath}`, - false, - ); + const notLinkedDirectoryPath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'not_linked'); + _fs.default.mkdirSync(notLinkedDirectoryPath); + expect(_fs.default.lstatSync(notLinkedDirectoryPath).isSymbolicLink()).toBe(false); + + const directory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, `nuclide://host13${notLinkedDirectoryPath}`, false); const symlink = directory.isSymbolicLink(); expect(symlink).toBe(false); }); @@ -377,96 +302,74 @@ xdescribe('RemoteDirectory::onDidChange()', () => { beforeEach(async () => { jasmine.getEnv().defaultTimeoutInterval = 10000; - directoryPath = temp.mkdirSync('on_did_change_test'); - filePath = nuclideUri.join(directoryPath, 'sample_file.txt'); - fs.writeFileSync(filePath, 'sample contents!'); - await (() => - connectionMock.getFsService().watchDirectoryRecursive(directoryPath))(); + directoryPath = (_temp || _load_temp()).default.mkdirSync('on_did_change_test'); + filePath = (_nuclideUri || _load_nuclideUri()).default.join(directoryPath, 'sample_file.txt'); + _fs.default.writeFileSync(filePath, 'sample contents!'); + await (() => (_connection_mock || _load_connection_mock()).default.getFsService().watchDirectoryRecursive(directoryPath))(); // wait for the watchman to settle on the created directory and file. - waits(WATCHMAN_SETTLE_TIME_MS + /* buffer */ 10); + waits(WATCHMAN_SETTLE_TIME_MS + /* buffer */10); }); afterEach(async () => { - await (() => - connectionMock.getFsService().unwatchDirectoryRecursive(directoryPath))(); + await (() => (_connection_mock || _load_connection_mock()).default.getFsService().unwatchDirectoryRecursive(directoryPath))(); }); it('notifies onDidChange observers when a new file is added to the directory', () => { - const directory = new RemoteDirectory(connectionMock, directoryPath); + const directory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, directoryPath); const changeHandler = jest.fn(); directory.onDidChange(changeHandler); - runs(() => - fs.writeFileSync( - nuclideUri.join(directoryPath, 'new_file.txt'), - 'new contents!', - ), - ); - waitsFor(() => changeHandler.mock.calls.length > 0); + runs(() => _fs.default.writeFileSync((_nuclideUri || _load_nuclideUri()).default.join(directoryPath, 'new_file.txt'), 'new contents!')); + (0, (_waits_for || _load_waits_for()).default)(() => changeHandler.mock.calls.length > 0); runs(() => { expect(changeHandler.mock.calls.length).toBe(1); - expect(changeHandler.mock.calls[0][0]).toEqual([ - { - name: 'new_file.txt', - mode: FILE_MODE, - exists: true, - new: true, - }, - ]); + expect(changeHandler.mock.calls[0][0]).toEqual([{ + name: 'new_file.txt', + mode: FILE_MODE, + exists: true, + new: true + }]); }); }); it('notifies onDidChange observers when a file is removed from the directory', () => { - const directory = new RemoteDirectory(connectionMock, directoryPath); + const directory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, directoryPath); const changeHandler = jest.fn(); directory.onDidChange(changeHandler); - runs(() => fs.unlinkSync(filePath)); - waitsFor(() => changeHandler.mock.calls.length > 0); + runs(() => _fs.default.unlinkSync(filePath)); + (0, (_waits_for || _load_waits_for()).default)(() => changeHandler.mock.calls.length > 0); runs(() => { expect(changeHandler.mock.calls.length).toBe(1); - expect(changeHandler.mock.calls[0][0]).toEqual([ - { - name: nuclideUri.basename(filePath), - mode: FILE_MODE, - exists: false, - new: false, - }, - ]); + expect(changeHandler.mock.calls[0][0]).toEqual([{ + name: (_nuclideUri || _load_nuclideUri()).default.basename(filePath), + mode: FILE_MODE, + exists: false, + new: false + }]); }); }); it("Doesn't notify observers when a file is changed contents inside the the directory", () => { - const directory = new RemoteDirectory(connectionMock, directoryPath); + const directory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, directoryPath); const changeHandler = jest.fn(); directory.onDidChange(changeHandler); - fs.writeFileSync(filePath, 'new contents!'); + _fs.default.writeFileSync(filePath, 'new contents!'); waits(1000); runs(() => expect(changeHandler.mock.calls.length).toBe(0)); }); it('batches change events into a single call', () => { - const directory = new RemoteDirectory(connectionMock, directoryPath); + const directory = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, directoryPath); const changeHandler = jest.fn(); directory.onDidChange(changeHandler); runs(() => { - fs.writeFileSync( - nuclideUri.join(directoryPath, 'new_file_1.txt'), - 'new contents 1!', - ); - fs.writeFileSync( - nuclideUri.join(directoryPath, 'new_file_2.txt'), - 'new contents 2!', - ); + _fs.default.writeFileSync((_nuclideUri || _load_nuclideUri()).default.join(directoryPath, 'new_file_1.txt'), 'new contents 1!'); + _fs.default.writeFileSync((_nuclideUri || _load_nuclideUri()).default.join(directoryPath, 'new_file_2.txt'), 'new contents 2!'); }); - waitsFor(() => changeHandler.mock.calls.length > 0); + (0, (_waits_for || _load_waits_for()).default)(() => changeHandler.mock.calls.length > 0); runs(() => { expect(changeHandler.mock.calls.length).toBe(1); - const sortedChange = changeHandler.mock.calls[0][0].sort( - (a, b) => a.name > b.name, - ); - expect(sortedChange).toEqual([ - {name: 'new_file_1.txt', exists: true, mode: FILE_MODE, new: true}, - {name: 'new_file_2.txt', exists: true, mode: FILE_MODE, new: true}, - ]); + const sortedChange = changeHandler.mock.calls[0][0].sort((a, b) => a.name > b.name); + expect(sortedChange).toEqual([{ name: 'new_file_1.txt', exists: true, mode: FILE_MODE, new: true }, { name: 'new_file_2.txt', exists: true, mode: FILE_MODE, new: true }]); }); }); }); @@ -475,20 +378,17 @@ describe('RemoteDirectory::onDidDelete()', () => { let tempDir; beforeEach(() => { - tempDir = temp.mkdirSync('on_did_delete'); + tempDir = (_temp || _load_temp()).default.mkdirSync('on_did_delete'); }); it('calls on delete', async () => { await (async () => { - const dirPath = nuclideUri.join(tempDir, 'dir_to_delete'); - const dir = new RemoteDirectory( - connectionMock, - `nuclide://host13${dirPath}`, - ); + const dirPath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'dir_to_delete'); + const dir = new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory((_connection_mock || _load_connection_mock()).default, `nuclide://host13${dirPath}`); const callbackSpy = jest.fn(); dir.onDidDelete(callbackSpy); await dir.delete(); expect(callbackSpy.mock.calls.length).toBe(1); })(); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/__atom_tests__/RemoteFile-test.js b/pkg/nuclide-remote-connection/__atom_tests__/RemoteFile-test.js index de2c0a46f9..3b29bb7ed0 100644 --- a/pkg/nuclide-remote-connection/__atom_tests__/RemoteFile-test.js +++ b/pkg/nuclide-remote-connection/__atom_tests__/RemoteFile-test.js @@ -1,33 +1,68 @@ -/** - * 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 - */ - -import type {ServerConnection} from '..'; - -import invariant from 'assert'; -import fs from 'fs'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {observeStream} from 'nuclide-commons/stream'; -import crypto from 'crypto'; -import {Subject} from 'rxjs'; -import temp from 'temp'; -import connectionMock from '../__mocks__/connection_mock'; -import {RemoteFile} from '../lib/RemoteFile'; -import waitsFor from '../../../jest/waits_for'; - -temp.track(); +'use strict'; + +var _fs = _interopRequireDefault(require('fs')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _stream; + +function _load_stream() { + return _stream = require('../../../modules/nuclide-commons/stream'); +} + +var _crypto = _interopRequireDefault(require('crypto')); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _temp; + +function _load_temp() { + return _temp = _interopRequireDefault(require('temp')); +} + +var _connection_mock; + +function _load_connection_mock() { + return _connection_mock = _interopRequireDefault(require('../__mocks__/connection_mock')); +} + +var _RemoteFile; + +function _load_RemoteFile() { + return _RemoteFile = require('../lib/RemoteFile'); +} + +var _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../../../jest/waits_for')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +(_temp || _load_temp()).default.track(); /** + * 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. + * + * + * @format + */ describe('RemoteFile', () => { const computeDigest = contents => { - const hash = crypto.createHash('sha1').update(contents || ''); - invariant(hash); + const hash = _crypto.default.createHash('sha1').update(contents || ''); + + if (!hash) { + throw new Error('Invariant violation: "hash"'); + } + return hash.digest('hex'); }; @@ -36,25 +71,25 @@ describe('RemoteFile', () => { let symlinkedFilePath; beforeEach(() => { - const tempDir = temp.mkdirSync('realpath_test'); - filePath = nuclideUri.join(tempDir, 'file.txt'); - fs.writeFileSync(filePath, 'some contents'); - filePath = fs.realpathSync(filePath); + const tempDir = (_temp || _load_temp()).default.mkdirSync('realpath_test'); + filePath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'file.txt'); + _fs.default.writeFileSync(filePath, 'some contents'); + filePath = _fs.default.realpathSync(filePath); symlinkedFilePath = filePath + '.sym'; - fs.symlinkSync(filePath, symlinkedFilePath, 'file'); + _fs.default.symlinkSync(filePath, symlinkedFilePath, 'file'); }); it('gets realpath of a file', async () => { await (async () => { - const file = new RemoteFile(connectionMock, symlinkedFilePath); + const file = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, symlinkedFilePath); const realpath = await file.getRealPath(); - expect(realpath).toBe(fs.realpathSync(symlinkedFilePath)); + expect(realpath).toBe(_fs.default.realpathSync(symlinkedFilePath)); })(); }); it('caches the getRealPath result', async () => { await (async () => { - const file = new RemoteFile(connectionMock, symlinkedFilePath); + const file = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, symlinkedFilePath); expect(file.getRealPathSync()).toBe(symlinkedFilePath); await file.getRealPath(); expect(file.getRealPathSync()).toBe(filePath); @@ -66,26 +101,26 @@ describe('RemoteFile', () => { let tempDir; beforeEach(() => { - tempDir = temp.mkdirSync('delete_test'); + tempDir = (_temp || _load_temp()).default.mkdirSync('delete_test'); }); it('deletes the existing file', async () => { await (async () => { - const filePath = nuclideUri.join(tempDir, 'file_to_delete'); - fs.writeFileSync(filePath, ''); - const file = new RemoteFile(connectionMock, filePath); - expect(fs.existsSync(filePath)).toBe(true); + const filePath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'file_to_delete'); + _fs.default.writeFileSync(filePath, ''); + const file = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, filePath); + expect(_fs.default.existsSync(filePath)).toBe(true); await file.delete(); - expect(fs.existsSync(filePath)).toBe(false); + expect(_fs.default.existsSync(filePath)).toBe(false); })(); }); it('deletes the non-existent file', async () => { await (async () => { - const filePath = nuclideUri.join(tempDir, 'file_to_delete'); - const file = new RemoteFile(connectionMock, filePath); + const filePath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'file_to_delete'); + const file = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, filePath); await file.delete(); - expect(fs.existsSync(filePath)).toBe(false); + expect(_fs.default.existsSync(filePath)).toBe(false); })(); }); }); @@ -94,18 +129,18 @@ describe('RemoteFile', () => { let tempDir; beforeEach(() => { - tempDir = temp.mkdirSync('on_did_create_and_delete_test'); + tempDir = (_temp || _load_temp()).default.mkdirSync('on_did_create_and_delete_test'); }); it('calls on delete', async () => { - const filePath = nuclideUri.join(tempDir, 'file_to_delete'); - fs.writeFileSync(filePath, ''); - const file = new RemoteFile(connectionMock, filePath); + const filePath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'file_to_delete'); + _fs.default.writeFileSync(filePath, ''); + const file = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, filePath); const callbackSpy = jest.fn(); jest.spyOn(file, '_willAddSubscription').mockReturnValue(null); file.onDidDelete(callbackSpy); file.delete(); - await waitsFor(() => callbackSpy.mock.calls.length > 0); + await (0, (_waits_for || _load_waits_for()).default)(() => callbackSpy.mock.calls.length > 0); expect(callbackSpy.mock.calls.length).toBe(1); expect(file._willAddSubscription).toHaveBeenCalled(); }); @@ -115,35 +150,27 @@ describe('RemoteFile', () => { let tempDir; beforeEach(() => { - tempDir = temp.mkdirSync('rename_test'); + tempDir = (_temp || _load_temp()).default.mkdirSync('rename_test'); }); it('verifies symlink', () => { - const targetFilePath = nuclideUri.join(tempDir, 'target'); - const symLinkedFilePath = nuclideUri.join(tempDir, 'linked'); - fs.writeFileSync(targetFilePath, ''); - fs.symlinkSync(targetFilePath, symLinkedFilePath, 'file'); - expect(fs.lstatSync(symLinkedFilePath).isSymbolicLink()).toBe(true); - - const file = new RemoteFile( - connectionMock, - `nuclide://host13${symLinkedFilePath}`, - true, - ); + const targetFilePath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'target'); + const symLinkedFilePath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'linked'); + _fs.default.writeFileSync(targetFilePath, ''); + _fs.default.symlinkSync(targetFilePath, symLinkedFilePath, 'file'); + expect(_fs.default.lstatSync(symLinkedFilePath).isSymbolicLink()).toBe(true); + + const file = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, `nuclide://host13${symLinkedFilePath}`, true); const symlink = file.isSymbolicLink(); expect(symlink).toBe(true); }); it('verifies non-symlink', () => { - const notLinkedFilePath = nuclideUri.join(tempDir, 'not_linked'); - fs.writeFileSync(notLinkedFilePath, ''); - expect(fs.lstatSync(notLinkedFilePath).isSymbolicLink()).toBe(false); - - const file = new RemoteFile( - connectionMock, - `nuclide://host13${notLinkedFilePath}`, - false, - ); + const notLinkedFilePath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'not_linked'); + _fs.default.writeFileSync(notLinkedFilePath, ''); + expect(_fs.default.lstatSync(notLinkedFilePath).isSymbolicLink()).toBe(false); + + const file = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, `nuclide://host13${notLinkedFilePath}`, false); const symlink = file.isSymbolicLink(); expect(symlink).toBe(false); }); @@ -153,7 +180,7 @@ describe('RemoteFile', () => { let tempDir; beforeEach(() => { - tempDir = temp.mkdirSync('copy_test'); + tempDir = (_temp || _load_temp()).default.mkdirSync('copy_test'); }); // We only do this simple test to make sure it's delegating to the connection. @@ -161,22 +188,20 @@ describe('RemoteFile', () => { // delegating to `fsPromise` here. it('copying existing files', async () => { await (async () => { - const filePath = nuclideUri.join(tempDir, 'file_to_copy'); + const filePath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'file_to_copy'); const fileContents = 'copy me!'; - fs.writeFileSync(filePath, fileContents); - const newFilePath = nuclideUri.join(tempDir, 'copied_file'); - expect(fs.existsSync(filePath)).toBe(true); - expect(fs.existsSync(newFilePath)).toBe(false); - - const file = new RemoteFile(connectionMock, filePath); - jest - .spyOn(file, '_subscribeToNativeChangeEvents') - .mockReturnValue(null); + _fs.default.writeFileSync(filePath, fileContents); + const newFilePath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'copied_file'); + expect(_fs.default.existsSync(filePath)).toBe(true); + expect(_fs.default.existsSync(newFilePath)).toBe(false); + + const file = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, filePath); + jest.spyOn(file, '_subscribeToNativeChangeEvents').mockReturnValue(null); const result = await file.copy(newFilePath); - const newFile = new RemoteFile(connectionMock, newFilePath); + const newFile = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, newFilePath); const digest = await newFile.getDigest(); expect(result).toBe(true); - expect(fs.existsSync(newFilePath)).toBe(true); + expect(_fs.default.existsSync(newFilePath)).toBe(true); expect(digest).toBe(computeDigest(fileContents)); })(); }); @@ -192,21 +217,20 @@ describe('RemoteFile', () => { beforeEach(async () => { jasmine.getEnv().defaultTimeoutInterval = 10000; - tempDir = temp.mkdirSync('on_did_change_test'); - filePath = nuclideUri.join(tempDir, 'file.txt'); - file = new RemoteFile(connectionMock, filePath); - fs.writeFileSync(filePath, 'sample contents'); + tempDir = (_temp || _load_temp()).default.mkdirSync('on_did_change_test'); + filePath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'file.txt'); + file = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, filePath); + _fs.default.writeFileSync(filePath, 'sample contents'); // Ask watchman to watch the directory. - await (() => - connectionMock.getFsService().watchDirectoryRecursive(tempDir))(); + await (() => (_connection_mock || _load_connection_mock()).default.getFsService().watchDirectoryRecursive(tempDir))(); // wait for the watchman to settle on the created directory and file. - waits(WATCHMAN_SETTLE_TIME_MS + /* buffer */ 10); + waits(WATCHMAN_SETTLE_TIME_MS + /* buffer */10); }); afterEach(async () => { await (async () => { await file._unsubscribeFromNativeChangeEvents(); - await connectionMock.getFsService().unwatchDirectoryRecursive(tempDir); + await (_connection_mock || _load_connection_mock()).default.getFsService().unwatchDirectoryRecursive(tempDir); })(); }); @@ -214,8 +238,8 @@ describe('RemoteFile', () => { it('notifies ::onDidChange observers', () => { const changeHandler = jest.fn(); file.onDidChange(changeHandler); - runs(() => fs.writeFileSync(filePath, 'this is new!')); - waitsFor(() => changeHandler.mock.calls.length > 0); + runs(() => _fs.default.writeFileSync(filePath, 'this is new!')); + (0, (_waits_for || _load_waits_for()).default)(() => changeHandler.mock.calls.length > 0); runs(() => expect(changeHandler.mock.calls.length).toBe(1)); }); }); @@ -224,8 +248,8 @@ describe('RemoteFile', () => { it('notifies ::onDidDelete observers', () => { const deletionHandler = jest.fn(); file.onDidDelete(deletionHandler); - runs(() => fs.unlinkSync(filePath)); - waitsFor(() => deletionHandler.mock.calls.length > 0); + runs(() => _fs.default.unlinkSync(filePath)); + (0, (_waits_for || _load_waits_for()).default)(() => deletionHandler.mock.calls.length > 0); runs(() => expect(deletionHandler.mock.calls.length).toBe(1)); }); }); @@ -236,29 +260,24 @@ describe('RemoteFile', () => { it('notifies ::onDidRename observers', () => { const renameHandler = jest.fn(); file.onDidRename(renameHandler); - runs(() => fs.renameSync(filePath, filePath + '_moved')); + runs(() => _fs.default.renameSync(filePath, filePath + '_moved')); waits(500); // wait for the rename event to emit. runs(() => advanceClock(150)); // pass the rename timeout. - waitsFor(() => renameHandler.mock.calls.length > 0); + (0, (_waits_for || _load_waits_for()).default)(() => renameHandler.mock.calls.length > 0); runs(() => { expect(renameHandler.mock.calls.length).toBe(1); - expect(renameHandler.mock.calls[0][0]).toBe( - nuclideUri.basename(filePath + '_moved'), - ); + expect(renameHandler.mock.calls[0][0]).toBe((_nuclideUri || _load_nuclideUri()).default.basename(filePath + '_moved')); }); }); }); describe('when a watch handling error happens', () => { it('notifies ::onWillThrowWatchError observers', async () => { - const notExistingFile = new RemoteFile( - connectionMock, - nuclideUri.join(tempDir, 'no_existing.txt'), - ); + const notExistingFile = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'no_existing.txt')); let skippedError; let handleError; notExistingFile.onWillThrowWatchError(watchError => { - const {error, handle} = watchError; + const { error, handle } = watchError; skippedError = error; handle(); }); @@ -270,7 +289,7 @@ describe('RemoteFile', () => { handleError = error; } })(); - waitsFor(() => skippedError); + (0, (_waits_for || _load_waits_for()).default)(() => skippedError); runs(() => { expect(skippedError.code).toBe('ENOENT'); expect(handleError).not.toBeDefined(); @@ -283,13 +302,13 @@ describe('RemoteFile', () => { let tempDir; beforeEach(() => { - tempDir = temp.mkdirSync('create_test'); + tempDir = (_temp || _load_temp()).default.mkdirSync('create_test'); }); it('returns true when file creation is successful', async () => { await (async () => { - const filePath = nuclideUri.join(tempDir, 'create.txt'); - const remoteFile = new RemoteFile(connectionMock, filePath); + const filePath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'create.txt'); + const remoteFile = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, filePath); const wasCreated = await remoteFile.create(); expect(wasCreated).toBe(true); })(); @@ -300,14 +319,14 @@ describe('RemoteFile', () => { let tempDir; beforeEach(() => { - tempDir = temp.mkdirSync('on_did_change_test'); + tempDir = (_temp || _load_temp()).default.mkdirSync('on_did_change_test'); }); it('exists resolves to true when the file exists', async () => { await (async () => { - const filePath = nuclideUri.join(tempDir, 'file.txt'); - fs.writeFileSync(filePath, 'sample contents'); - const existingFile = new RemoteFile(connectionMock, filePath); + const filePath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'file.txt'); + _fs.default.writeFileSync(filePath, 'sample contents'); + const existingFile = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, filePath); const exists = await existingFile.exists(); expect(exists).toBe(true); })(); @@ -315,10 +334,7 @@ describe('RemoteFile', () => { it('exists resolves to false when the file does not exist', async () => { await (async () => { - const notExistingFile = new RemoteFile( - connectionMock, - nuclideUri.join(tempDir, 'no_existing.txt'), - ); + const notExistingFile = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'no_existing.txt')); const exists = await notExistingFile.exists(); expect(exists).toBe(false); })(); @@ -332,11 +348,11 @@ describe('RemoteFile', () => { let fileContents; beforeEach(() => { - tempDir = temp.mkdirSync('on_did_change_test'); - filePath = nuclideUri.join(tempDir, 'file.txt'); + tempDir = (_temp || _load_temp()).default.mkdirSync('on_did_change_test'); + filePath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'file.txt'); fileContents = 'sample contents!'; - fs.writeFileSync(filePath, fileContents); - file = new RemoteFile(connectionMock, filePath); + _fs.default.writeFileSync(filePath, fileContents); + file = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, filePath); }); it('getDigest even if the file was not read before', async () => { @@ -377,13 +393,13 @@ describe('RemoteFile', () => { }); describe('RemoteFile::getParent()', () => { - let server: ServerConnection = (null: any); + let server = null; beforeEach(() => { - server = ({ + server = { createDirectory: () => {}, - getRemoteConnectionForUri: () => null, - }: any); + getRemoteConnectionForUri: () => null + }; }); it('gets the parent directory for a file in a root directory', () => { @@ -391,12 +407,9 @@ describe('RemoteFile', () => { jest.spyOn(server, 'createDirectory').mockReturnValue(parentDirectory); const filePath = 'nuclide://foo.bar.com/foo.txt'; - const file = new RemoteFile(server, filePath); + const file = new (_RemoteFile || _load_RemoteFile()).RemoteFile(server, filePath); expect(file.getParent()).toBe(parentDirectory); - expect(server.createDirectory).toHaveBeenCalledWith( - 'nuclide://foo.bar.com/', - null, - ); + expect(server.createDirectory).toHaveBeenCalledWith('nuclide://foo.bar.com/', null); }); it('gets the parent directory for a file in a non-root directory', () => { @@ -404,12 +417,9 @@ describe('RemoteFile', () => { jest.spyOn(server, 'createDirectory').mockReturnValue(parentDirectory); const filePath = 'nuclide://foo.bar.com/a/foo.txt'; - const file = new RemoteFile(server, filePath); + const file = new (_RemoteFile || _load_RemoteFile()).RemoteFile(server, filePath); expect(file.getParent()).toBe(parentDirectory); - expect(server.createDirectory).toHaveBeenCalledWith( - 'nuclide://foo.bar.com/a', - null, - ); + expect(server.createDirectory).toHaveBeenCalledWith('nuclide://foo.bar.com/a', null); }); }); @@ -417,9 +427,9 @@ describe('RemoteFile', () => { it('resubscribes after a rename', () => { const changeHandler = jest.fn(); const deletionHandler = jest.fn(); - const mockWatch = new Subject(); - jest.spyOn(connectionMock, 'getFileWatch').mockReturnValue(mockWatch); - const file = new RemoteFile(connectionMock, 'test'); + const mockWatch = new _rxjsBundlesRxMinJs.Subject(); + jest.spyOn((_connection_mock || _load_connection_mock()).default, 'getFileWatch').mockReturnValue(mockWatch); + const file = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, 'test'); file.onDidChange(changeHandler); file.onDidDelete(deletionHandler); @@ -428,8 +438,8 @@ describe('RemoteFile', () => { file.setPath('test2'); // Simulate a Watchman rename (delete + change) - mockWatch.next({type: 'delete', path: 'test'}); - mockWatch.next({type: 'change', path: 'test2'}); + mockWatch.next({ type: 'delete', path: 'test' }); + mockWatch.next({ type: 'change', path: 'test2' }); expect(deletionHandler).not.toHaveBeenCalled(); expect(changeHandler).toHaveBeenCalled(); }); @@ -438,27 +448,22 @@ describe('RemoteFile', () => { describe('RemoteFile::createReadStream()', () => { it('is able to read file contents', async () => { await (async () => { - const tempDir = temp.mkdirSync('stream_test'); - const filePath = nuclideUri.join(tempDir, 'file.txt'); - fs.writeFileSync(filePath, 'test1234'); + const tempDir = (_temp || _load_temp()).default.mkdirSync('stream_test'); + const filePath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'file.txt'); + _fs.default.writeFileSync(filePath, 'test1234'); - const file = new RemoteFile(connectionMock, filePath); + const file = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, filePath); const readStream = file.createReadStream(); - const data = await observeStream(readStream) - .toArray() - .toPromise(); + const data = await (0, (_stream || _load_stream()).observeStream)(readStream).toArray().toPromise(); expect(data).toEqual(['test1234']); })(); }); it('handles errors', async () => { await (async () => { - const file = new RemoteFile(connectionMock, 'test'); + const file = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, 'test'); const readStream = file.createReadStream(); - const data = await observeStream(readStream) - .toArray() - .toPromise() - .catch(e => e); + const data = await (0, (_stream || _load_stream()).observeStream)(readStream).toArray().toPromise().catch(e => e); expect(data instanceof Error).toBe(true); })(); }); @@ -467,26 +472,26 @@ describe('RemoteFile', () => { describe('RemoteFile::createWriteStream()', () => { it('is able to write file contents', async () => { await (async () => { - const tempDir = temp.mkdirSync('stream_test'); - const filePath = nuclideUri.join(tempDir, 'file.txt'); - const file = new RemoteFile(connectionMock, filePath); + const tempDir = (_temp || _load_temp()).default.mkdirSync('stream_test'); + const filePath = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'file.txt'); + const file = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, filePath); const writeStream = file.createWriteStream(); writeStream.write('test1234'); await new Promise(resolve => writeStream.end(resolve)); - expect(fs.readFileSync(filePath, 'utf8')).toBe('test1234'); + expect(_fs.default.readFileSync(filePath, 'utf8')).toBe('test1234'); })(); }); it('handles errors', async () => { await (async () => { - const file = new RemoteFile(connectionMock, 'a/'); + const file = new (_RemoteFile || _load_RemoteFile()).RemoteFile((_connection_mock || _load_connection_mock()).default, 'a/'); const writeStream = file.createWriteStream(); writeStream.write('test1234'); - let error: ?Error = null; - writeStream.on('error', e => (error = e)); + let error = null; + writeStream.on('error', e => error = e); await new Promise(resolve => writeStream.end(resolve)); expect(error).not.toBeNull(); })(); }); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/__atom_tests__/service-manager-test.js b/pkg/nuclide-remote-connection/__atom_tests__/service-manager-test.js index 885bef7ec8..0593670115 100644 --- a/pkg/nuclide-remote-connection/__atom_tests__/service-manager-test.js +++ b/pkg/nuclide-remote-connection/__atom_tests__/service-manager-test.js @@ -1,3 +1,17 @@ +'use strict'; + +var _nuclideVersion; + +function _load_nuclideVersion() { + return _nuclideVersion = require('../../nuclide-version'); +} + +var _; + +function _load_() { + return _ = require('..'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,19 +19,16 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import {getVersion} from '../../nuclide-version'; -import {getInfoServiceByNuclideUri} from '..'; - describe('setUseLocalRpc', () => { it('successfully starts up a local RPC server', async () => { await (async () => { - const infoService = getInfoServiceByNuclideUri(''); + const infoService = (0, (_ || _load_()).getInfoServiceByNuclideUri)(''); const version = await infoService.getServerVersion(); - expect(version).toBe(getVersion()); + expect(version).toBe((0, (_nuclideVersion || _load_nuclideVersion()).getVersion)()); })(); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/__atom_tests__/text-buffer-test.js b/pkg/nuclide-remote-connection/__atom_tests__/text-buffer-test.js index b3262d3b03..510d986859 100644 --- a/pkg/nuclide-remote-connection/__atom_tests__/text-buffer-test.js +++ b/pkg/nuclide-remote-connection/__atom_tests__/text-buffer-test.js @@ -1,39 +1,43 @@ -/** - * 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 - */ - -import {existingBufferForUri, bufferForUri} from '../lib/remote-text-buffer'; +'use strict'; + +var _remoteTextBuffer; + +function _load_remoteTextBuffer() { + return _remoteTextBuffer = require('../lib/remote-text-buffer'); +} describe('existingBufferForUri', () => { const file1 = '/tmp/file1.txt'; it('should open an editor with the same buffer, if previously cached', async () => { - const existingBuffer = existingBufferForUri(file1); + const existingBuffer = (0, (_remoteTextBuffer || _load_remoteTextBuffer()).existingBufferForUri)(file1); expect(existingBuffer).toBeUndefined(); await (async () => { const secondFile1Buffer = (await atom.workspace.open(file1)).getBuffer(); expect(secondFile1Buffer).toBeDefined(); - const bufferAfterCreation = existingBufferForUri(file1); + const bufferAfterCreation = (0, (_remoteTextBuffer || _load_remoteTextBuffer()).existingBufferForUri)(file1); expect(bufferAfterCreation).toBeDefined(); })(); }); -}); +}); /** + * 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. + * + * + * @format + */ describe('bufferForUri', () => { const file1 = '/tmp/file1.txt'; const file2 = '/tmp/file2.txt'; - let file1Buffer: atom$TextBuffer = (null: any); + let file1Buffer = null; beforeEach(() => { - file1Buffer = bufferForUri(file1); + file1Buffer = (0, (_remoteTextBuffer || _load_remoteTextBuffer()).bufferForUri)(file1); }); it('should open an editor with the same buffer, if previously cached', async () => { @@ -46,14 +50,12 @@ describe('bufferForUri', () => { it('should return the same buffer after creating an editor for it', async () => { await (async () => { const file2Buffer = (await atom.workspace.open(file2)).getBuffer(); - expect(bufferForUri(file2)).toBe(file2Buffer); + expect((0, (_remoteTextBuffer || _load_remoteTextBuffer()).bufferForUri)(file2)).toBe(file2Buffer); })(); }); it('should throw an error if remote connection not found', () => { const uri = 'nuclide://host/abc.txt'; - expect(() => bufferForUri(uri)).toThrow( - `ServerConnection cannot be found for uri: ${uri}`, - ); + expect(() => (0, (_remoteTextBuffer || _load_remoteTextBuffer()).bufferForUri)(uri)).toThrow(`ServerConnection cannot be found for uri: ${uri}`); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/__mocks__/connection_mock.js b/pkg/nuclide-remote-connection/__mocks__/connection_mock.js index e0f6b0d8e9..6d2740ed99 100644 --- a/pkg/nuclide-remote-connection/__mocks__/connection_mock.js +++ b/pkg/nuclide-remote-connection/__mocks__/connection_mock.js @@ -1,47 +1,65 @@ -/** - * 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 - */ - -import type {ServerConnection} from '..'; - -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {RemoteDirectory} from '../lib/RemoteDirectory'; -import {RemoteFile} from '../lib/RemoteFile'; - -const fsService = { - ...fsPromise, +'use strict'; + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _RemoteDirectory; + +function _load_RemoteDirectory() { + return _RemoteDirectory = require('../lib/RemoteDirectory'); +} + +var _RemoteFile; + +function _load_RemoteFile() { + return _RemoteFile = require('../lib/RemoteFile'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const fsService = Object.assign({}, (_fsPromise || _load_fsPromise()).default, { async newFile(path) { return true; }, async copy(src, dst) { - await fsPromise.copy(src, dst); + await (_fsPromise || _load_fsPromise()).default.copy(src, dst); return true; }, rmdir(uri) { - return fsPromise.rimraf(nuclideUri.getPath(uri)); + return (_fsPromise || _load_fsPromise()).default.rimraf((_nuclideUri || _load_nuclideUri()).default.getPath(uri)); }, exists(uri) { - return fsPromise.exists(nuclideUri.getPath(uri)); + return (_fsPromise || _load_fsPromise()).default.exists((_nuclideUri || _load_nuclideUri()).default.getPath(uri)); }, writeFileBuffer(path, buffer, options) { - return fsPromise.writeFile(path, buffer, options); - }, -}; + return (_fsPromise || _load_fsPromise()).default.writeFile(path, buffer, options); + } +}); /** + * 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. + * + * + * @format + */ -const connectionMock: ServerConnection & {getFsService(): Object} = ({ +const connectionMock = { getFsService: () => fsService, - createDirectory: uri => new RemoteDirectory(connectionMock, uri), - createFile: uri => new RemoteFile(connectionMock, uri), + createDirectory: uri => new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory(connectionMock, uri), + createFile: uri => new (_RemoteFile || _load_RemoteFile()).RemoteFile(connectionMock, uri), getRemoteConnectionForUri: () => null, - getService: (serviceName: string) => { + getService: serviceName => { if (serviceName === 'FileSystemService') { return fsService; } else { @@ -53,8 +71,8 @@ const connectionMock: ServerConnection & {getFsService(): Object} = ({ }, getDirectoryWatch: () => { throw new Error('mock me'); - }, -}: any); + } +}; // eslint-disable-next-line nuclide-internal/no-commonjs -module.exports = connectionMock; +module.exports = connectionMock; \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/__mocks__/ipc_echo_process.js b/pkg/nuclide-remote-connection/__mocks__/ipc_echo_process.js index d2f6c2c90f..143edba6a0 100644 --- a/pkg/nuclide-remote-connection/__mocks__/ipc_echo_process.js +++ b/pkg/nuclide-remote-connection/__mocks__/ipc_echo_process.js @@ -1,3 +1,11 @@ +'use strict'; + +var _IpcTransports; + +function _load_IpcTransports() { + return _IpcTransports = require('../lib/IpcTransports'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,15 +13,15 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import invariant from 'assert'; -import {IpcServerTransport} from '../lib/IpcTransports'; +const transport = new (_IpcTransports || _load_IpcTransports()).IpcServerTransport(); -const transport = new IpcServerTransport(); -invariant(!transport.isClosed()); +if (!!transport.isClosed()) { + throw new Error('Invariant violation: "!transport.isClosed()"'); +} transport.onMessage().subscribe(message => { if (message === 'exit') { @@ -21,4 +29,4 @@ transport.onMessage().subscribe(message => { } else { transport.send(message.toUpperCase()); } -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/__tests__/IpcTransports-test.js b/pkg/nuclide-remote-connection/__tests__/IpcTransports-test.js index e51561579a..59c58766b3 100644 --- a/pkg/nuclide-remote-connection/__tests__/IpcTransports-test.js +++ b/pkg/nuclide-remote-connection/__tests__/IpcTransports-test.js @@ -1,59 +1,60 @@ -/** - * 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 strict-local - * @format - */ - -import {fork} from 'nuclide-commons/process'; -import {IpcClientTransport} from '../lib/IpcTransports'; -import waitsFor from '../../../jest/waits_for'; +'use strict'; + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _IpcTransports; + +function _load_IpcTransports() { + return _IpcTransports = require('../lib/IpcTransports'); +} + +var _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../../../jest/waits_for')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } describe('IpcTransports', () => { let processStream; beforeEach(() => { - processStream = fork( - '--require', - [ - require.resolve('../../commons-node/load-transpiler'), - require.resolve('../__mocks__/ipc_echo_process'), - ], - { - stdio: ['pipe', 'pipe', 'pipe', 'pipe', 'ipc'], - }, - ); + processStream = (0, (_process || _load_process()).fork)('--require', [require.resolve('../../commons-node/load-transpiler'), require.resolve('../__mocks__/ipc_echo_process')], { + stdio: ['pipe', 'pipe', 'pipe', 'pipe', 'ipc'] + }); }); it('is able to communicate with a child process', async () => { - const transport = new IpcClientTransport(processStream); + const transport = new (_IpcTransports || _load_IpcTransports()).IpcClientTransport(processStream); const messageSpy = jest.fn(); transport.onMessage().subscribe(msg => messageSpy(msg)); expect(!transport.isClosed()); transport.send('hello'); - await waitsFor( - () => messageSpy.mock.calls.length === 1, - 'a reply from the local server', - 10000, - ); + await (0, (_waits_for || _load_waits_for()).default)(() => messageSpy.mock.calls.length === 1, 'a reply from the local server', 10000); expect(messageSpy).toHaveBeenCalledWith('HELLO'); transport.send('a'.repeat(99999)); - await waitsFor( - () => messageSpy.mock.calls.length === 2, - 'another reply from the local server', - 10000, - ); + await (0, (_waits_for || _load_waits_for()).default)(() => messageSpy.mock.calls.length === 2, 'another reply from the local server', 10000); expect(messageSpy).toHaveBeenCalledWith('A'.repeat(99999)); transport.send('exit'); - await waitsFor(() => transport.isClosed()); + await (0, (_waits_for || _load_waits_for()).default)(() => transport.isClosed()); }); -}); +}); /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/__tests__/SshHandshake-test.js b/pkg/nuclide-remote-connection/__tests__/SshHandshake-test.js index 769add2529..cc47bbd71e 100644 --- a/pkg/nuclide-remote-connection/__tests__/SshHandshake-test.js +++ b/pkg/nuclide-remote-connection/__tests__/SshHandshake-test.js @@ -1,3 +1,33 @@ +'use strict'; + +var _events = _interopRequireDefault(require('events')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _testHelpers; + +function _load_testHelpers() { + return _testHelpers = require('../../../modules/nuclide-commons/test-helpers'); +} + +var _SshHandshake; + +function _load_SshHandshake() { + return _SshHandshake = require('../lib/SshHandshake'); +} + +var _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../../../jest/waits_for')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,120 +35,94 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {SshConnectionConfiguration} from '../lib/SshHandshake'; - -import EventEmitter from 'events'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {clearRequireCache, uncachedRequire} from 'nuclide-commons/test-helpers'; -import {SshHandshake} from '../lib/SshHandshake'; -import type {ExecOptions, SFTPWrapper, ClientChannel} from 'ssh2'; -import waitsFor from '../../../jest/waits_for'; - -const pathToFakePk = nuclideUri.join(__dirname, 'fakepk'); +const pathToFakePk = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, 'fakepk'); describe('SshHandshake', () => { - class MockSshConnection extends EventEmitter { + class MockSshConnection extends _events.default { connect(config) {} end() {} - exec( - command: string, - options?: ExecOptions, - callback: (err: Error, channel: ClientChannel) => void | Promise, - ): boolean { + exec(command, options, callback) { return false; } - sftp( - callback: (err: Error, sftp: SFTPWrapper) => void | Promise, - ): boolean { + sftp(callback) { return false; } - forwardOut( - srcIP: string, - srcPort: number, - dstIP: string, - dstPort: number, - callback: (err: Error, channel: ClientChannel) => void | Promise, - ): boolean { + forwardOut(srcIP, srcPort, dstIP, dstPort, callback) { return false; } } let dns; - let handshakeDelegate: any; + let handshakeDelegate; beforeEach(() => { - dns = uncachedRequire(require, 'dns'); - jest - .spyOn(((dns: any): Object), 'lookup') - .mockImplementation((host, family, callback) => { - process.nextTick(() => { - callback( - /* error */ null, - /* address */ 'example.com', - /* family */ 4, - ); - }); + dns = (0, (_testHelpers || _load_testHelpers()).uncachedRequire)(require, 'dns'); + jest.spyOn(dns, 'lookup').mockImplementation((host, family, callback) => { + process.nextTick(() => { + callback( + /* error */null, + /* address */'example.com', + /* family */4); }); + }); handshakeDelegate = { onKeyboardInteractive: jest.fn(), onWillConnect: jest.fn(), onDidConnect: jest.fn(), - onError: jest.fn(), + onError: jest.fn() }; }); afterEach(() => { - clearRequireCache(require, 'dns'); + (0, (_testHelpers || _load_testHelpers()).clearRequireCache)(require, 'dns'); }); describe('connect()', () => { it('calls delegates onError when ssh connection fails', () => { const mockError = new Error('mock error'); - const sshConnection: any = new MockSshConnection(); - const sshHandshake = new SshHandshake(handshakeDelegate, sshConnection); - const config: SshConnectionConfiguration = ({ + const sshConnection = new MockSshConnection(); + const sshHandshake = new (_SshHandshake || _load_SshHandshake()).SshHandshake(handshakeDelegate, sshConnection); + const config = { pathToPrivateKey: pathToFakePk, - authMethod: 'PRIVATE_KEY', - }: any); + authMethod: 'PRIVATE_KEY' + }; sshHandshake.connect(config); sshConnection.emit('error', mockError); expect(handshakeDelegate.onWillConnect.mock.calls.length).toBe(1); expect(handshakeDelegate.onError.mock.calls.length).toBe(1); - expect(handshakeDelegate.onError.mock.calls[0][0]).toBe( - SshHandshake.ErrorType.UNKNOWN, - ); + expect(handshakeDelegate.onError.mock.calls[0][0]).toBe((_SshHandshake || _load_SshHandshake()).SshHandshake.ErrorType.UNKNOWN); expect(handshakeDelegate.onError.mock.calls[0][1]).toBe(mockError); expect(handshakeDelegate.onError.mock.calls[0][2]).toBe(config); }); it('calls delegates onError when private key does not exist', async () => { - const sshConnection: any = new MockSshConnection(); - const sshHandshake = new SshHandshake(handshakeDelegate, sshConnection); - const config: SshConnectionConfiguration = ({ + const sshConnection = new MockSshConnection(); + const sshHandshake = new (_SshHandshake || _load_SshHandshake()).SshHandshake(handshakeDelegate, sshConnection); + const config = { pathToPrivateKey: pathToFakePk + '.oops', - authMethod: 'PRIVATE_KEY', - }: any); + authMethod: 'PRIVATE_KEY' + }; sshHandshake.connect(config); let onErrorCalled = false; handshakeDelegate.onError.mockImplementation((errorType, e, _config) => { - expect(errorType).toBe(SshHandshake.ErrorType.CANT_READ_PRIVATE_KEY); + expect(errorType).toBe((_SshHandshake || _load_SshHandshake()).SshHandshake.ErrorType.CANT_READ_PRIVATE_KEY); expect(e.code).toBe('ENOENT'); expect(_config).toBe(config); onErrorCalled = true; }); - await waitsFor(() => { + await (0, (_waits_for || _load_waits_for()).default)(() => { return onErrorCalled; }); @@ -127,14 +131,14 @@ describe('SshHandshake', () => { it('retries with a password when authentication fails', () => { const mockError = new Error(); - (mockError: any).level = 'client-authentication'; - const sshConnection: any = new MockSshConnection(); - const sshHandshake = new SshHandshake(handshakeDelegate, sshConnection); - const config: SshConnectionConfiguration = ({ + mockError.level = 'client-authentication'; + const sshConnection = new MockSshConnection(); + const sshHandshake = new (_SshHandshake || _load_SshHandshake()).SshHandshake(handshakeDelegate, sshConnection); + const config = { host: 'testhost', password: 'test', - authMethod: 'PASSWORD', - }: any); + authMethod: 'PASSWORD' + }; sshHandshake.connect(config); sshConnection.config = config; @@ -163,11 +167,11 @@ describe('SshHandshake', () => { describe('cancel()', () => { it('calls SshConnection.end()', () => { - const sshConnection: any = new MockSshConnection(); - const sshHandshake = new SshHandshake(handshakeDelegate, sshConnection); - const config: SshConnectionConfiguration = ({ - pathToPrivateKey: pathToFakePk, - }: any); + const sshConnection = new MockSshConnection(); + const sshHandshake = new (_SshHandshake || _load_SshHandshake()).SshHandshake(handshakeDelegate, sshConnection); + const config = { + pathToPrivateKey: pathToFakePk + }; jest.spyOn(sshConnection, 'end').mockImplementation(() => {}); @@ -177,4 +181,4 @@ describe('SshHandshake', () => { expect(sshConnection.end.mock.calls.length).toBe(1); }); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/ConnectionCache.js b/pkg/nuclide-remote-connection/lib/ConnectionCache.js index abae7e21d4..0c6d323d72 100644 --- a/pkg/nuclide-remote-connection/lib/ConnectionCache.js +++ b/pkg/nuclide-remote-connection/lib/ConnectionCache.js @@ -1,60 +1,64 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ConnectionCache = undefined; + +var _ServerConnection; + +function _load_ServerConnection() { + return _ServerConnection = require('./ServerConnection'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; +var _nuclideUri; -import {ServerConnection} from './ServerConnection'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Cache} from 'nuclide-commons/cache'; +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _cache; + +function _load_cache() { + return _cache = require('../../../modules/nuclide-commons/cache'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // A cache of values by ServerConnection. // Will lazily create the values when requested for each connection. // Note that an entry is added for local with connection == null. -export class ConnectionCache extends Cache< - ?ServerConnection, - Promise, -> { - _subscriptions: UniversalDisposable; +class ConnectionCache extends (_cache || _load_cache()).Cache { // If lazy is true, then entries will only be created when get() is called. // Otherwise, entries will be created as soon as ServerConnection's are // established. - constructor( - factory: (connection: ?ServerConnection) => Promise, - lazy: boolean = false, - ) { + constructor(factory, lazy = false) { super(factory, valuePromise => valuePromise.then(value => value.dispose())); - this._subscriptions = new UniversalDisposable(); - this._subscriptions.add( - ServerConnection.onDidCloseServerConnection(connection => { - if (this.has(connection)) { - const value = this.get(connection); - this.delete(connection); - value.then(element => element.dispose()); - } - }), - ); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._subscriptions.add((_ServerConnection || _load_ServerConnection()).ServerConnection.onDidCloseServerConnection(connection => { + if (this.has(connection)) { + const value = this.get(connection); + this.delete(connection); + value.then(element => element.dispose()); + } + })); if (!lazy) { this.get(null); - this._subscriptions.add( - ServerConnection.observeConnections(connection => { - this.get(connection); - }), - ); + this._subscriptions.add((_ServerConnection || _load_ServerConnection()).ServerConnection.observeConnections(connection => { + this.get(connection); + })); } } - getForUri(filePath: ?NuclideUri): ?Promise { + getForUri(filePath) { const connection = connectionOfUri(filePath); if (connection == null) { return null; @@ -62,38 +66,45 @@ export class ConnectionCache extends Cache< return this.get(connection.connection); } - getExistingForUri(filePath: ?NuclideUri): ?Promise { + getExistingForUri(filePath) { const connection = connectionOfUri(filePath); if (connection == null) { return null; } - return this.has(connection.connection) - ? this.get(connection.connection) - : null; + return this.has(connection.connection) ? this.get(connection.connection) : null; } - dispose(): void { + dispose() { super.dispose(); this._subscriptions.dispose(); } } -// Returns null if there's no valid connection for the given filePath +exports.ConnectionCache = ConnectionCache; // Returns null if there's no valid connection for the given filePath // Returns {connection: null} for a valid local filePath. // Returns {connection: non-null} for a valid remote filePath. -function connectionOfUri( - filePath: ?NuclideUri, -): ?{connection: ?ServerConnection} { +/** + * 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. + * + * strict-local + * @format + */ + +function connectionOfUri(filePath) { if (filePath == null) { return null; } - const connection = ServerConnection.getForUri(filePath); + const connection = (_ServerConnection || _load_ServerConnection()).ServerConnection.getForUri(filePath); // During startup & shutdown of connections we can have a remote uri // without the corresponding connection. - if (connection == null && nuclideUri.isRemote(filePath)) { + if (connection == null && (_nuclideUri || _load_nuclideUri()).default.isRemote(filePath)) { return null; } - return {connection}; -} + return { connection }; +} \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/ConnectionHealthNotifier.js b/pkg/nuclide-remote-connection/lib/ConnectionHealthNotifier.js index 85cd6278b6..2657d444ea 100644 --- a/pkg/nuclide-remote-connection/lib/ConnectionHealthNotifier.js +++ b/pkg/nuclide-remote-connection/lib/ConnectionHealthNotifier.js @@ -1,43 +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 - * @format - */ - -import type {XhrConnectionHeartbeat} from 'big-dig/src/client/XhrConnectionHeartbeat'; - -import invariant from 'assert'; -import {trackEvent} from '../../nuclide-analytics'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {getLogger} from 'log4js'; - -const logger = getLogger('nuclide-remote-connection'); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ConnectionHealthNotifier = undefined; + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-remote-connection'); /** + * 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. + * + * + * @format + */ const HEARTBEAT_AWAY_REPORT_COUNT = 3; const HEARTBEAT_NOTIFICATION_ERROR = 1; const HEARTBEAT_NOTIFICATION_WARNING = 2; -type HeartbeatNotification = { - notification: atom$Notification, - code: string, -}; - // Returning true short-circuits the default error handling in onHeartbeatError() -export type OnHeartbeatErrorCallback = (errorCode: string) => boolean; + // Provides feedback to the user of the health of a ReliableSocket. -export class ConnectionHealthNotifier { - _heartbeatNetworkAwayCount: number; - _lastHeartbeatNotification: ?HeartbeatNotification; - _subscription: IDisposable; - _onHeartbeatError: ?OnHeartbeatErrorCallback; +class ConnectionHealthNotifier { - constructor(host: string, port: number, heartbeat: XhrConnectionHeartbeat) { + constructor(host, port, heartbeat) { this._heartbeatNetworkAwayCount = 0; this._lastHeartbeatNotification = null; @@ -48,28 +57,21 @@ export class ConnectionHealthNotifier { * The function makes sure not to add many notifications for the same event and prioritize * new events. */ - const addHeartbeatNotification = ( - type: number, - errorCode: string, - message: string, - dismissable: boolean, - askToReload: boolean, - ) => { - const {code, notification: existingNotification} = - this._lastHeartbeatNotification || {}; + const addHeartbeatNotification = (type, errorCode, message, dismissable, askToReload) => { + const { code, notification: existingNotification } = this._lastHeartbeatNotification || {}; if (code && code === errorCode && dismissable) { // A dismissable heartbeat notification with this code is already active. return; } let notification = null; - const options = {dismissable, buttons: []}; + const options = { dismissable, buttons: [] }; if (askToReload) { options.buttons.push({ className: 'icon icon-zap', onDidClick() { atom.reload(); }, - text: 'Reload Atom', + text: 'Reload Atom' }); } switch (type) { @@ -85,10 +87,14 @@ export class ConnectionHealthNotifier { if (existingNotification) { existingNotification.dismiss(); } - invariant(notification); + + if (!notification) { + throw new Error('Invariant violation: "notification"'); + } + this._lastHeartbeatNotification = { notification, - code: errorCode, + code: errorCode }; }; @@ -97,45 +103,35 @@ export class ConnectionHealthNotifier { // If there has been existing heartbeat error/warning, // that means connection has been lost and we shall show a message about connection // being restored without a reconnect prompt. - const {notification} = this._lastHeartbeatNotification; + const { notification } = this._lastHeartbeatNotification; notification.dismiss(); - atom.notifications.addSuccess( - 'Connection restored to Nuclide Server at: ' + uri, - ); + atom.notifications.addSuccess('Connection restored to Nuclide Server at: ' + uri); this._heartbeatNetworkAwayCount = 0; this._lastHeartbeatNotification = null; } }; - const notifyNetworkAway = (code: string) => { + const notifyNetworkAway = code => { this._heartbeatNetworkAwayCount++; if (this._heartbeatNetworkAwayCount >= HEARTBEAT_AWAY_REPORT_COUNT) { - addHeartbeatNotification( - HEARTBEAT_NOTIFICATION_WARNING, - code, - `Nuclide server cannot be reached at "${uri}".
    ` + - 'Nuclide will reconnect when the network is restored.', - /* dismissable */ true, - /* askToReload */ false, - ); + addHeartbeatNotification(HEARTBEAT_NOTIFICATION_WARNING, code, `Nuclide server cannot be reached at "${uri}".
    ` + 'Nuclide will reconnect when the network is restored.', + /* dismissable */true, + /* askToReload */false); } }; - const onHeartbeatError = (error: any) => { - const {code, message, originalCode} = error; + const onHeartbeatError = error => { + const { code, message, originalCode } = error; // Don't keep tracking consecutive NETWORK_AWAY events: // the user's probably offline anyway so analytics events just pile up. - if ( - code !== 'NETWORK_AWAY' || - this._heartbeatNetworkAwayCount < HEARTBEAT_AWAY_REPORT_COUNT - ) { - trackEvent({ + if (code !== 'NETWORK_AWAY' || this._heartbeatNetworkAwayCount < HEARTBEAT_AWAY_REPORT_COUNT) { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackEvent)({ type: 'heartbeat-error', data: { code: code || '', message: message || '', - host, - }, + host + } }); } logger.info('Heartbeat network error:', code, originalCode, message); @@ -153,43 +149,25 @@ export class ConnectionHealthNotifier { case 'SERVER_CRASHED': // Server shut down or port no longer accessible. // Notify the server was there, but now gone. - addHeartbeatNotification( - HEARTBEAT_NOTIFICATION_ERROR, - code, - '**Nuclide Server Crashed**
    ' + - 'Please reload Atom to restore your remote project connection.', - /* dismissable */ true, - /* askToReload */ true, - ); + addHeartbeatNotification(HEARTBEAT_NOTIFICATION_ERROR, code, '**Nuclide Server Crashed**
    ' + 'Please reload Atom to restore your remote project connection.', + /* dismissable */true, + /* askToReload */true); break; case 'PORT_NOT_ACCESSIBLE': // Notify never heard a heartbeat from the server. - addHeartbeatNotification( - HEARTBEAT_NOTIFICATION_ERROR, - code, - '**Nuclide Server Is Not Reachable**
    ' + - `It could be running on a port that is not accessible: ${String( - port, - )}.`, - /* dismissable */ true, - /* askToReload */ false, - ); + addHeartbeatNotification(HEARTBEAT_NOTIFICATION_ERROR, code, '**Nuclide Server Is Not Reachable**
    ' + `It could be running on a port that is not accessible: ${String(port)}.`, + /* dismissable */true, + /* askToReload */false); break; case 'INVALID_CERTIFICATE': // Notify the client certificate is not accepted by nuclide server // (certificate mismatch). - addHeartbeatNotification( - HEARTBEAT_NOTIFICATION_ERROR, - code, - '**Certificate Expired**
    ' + - // The expiration date should be synced with - // nuclide-server/scripts/nuclide_server_manager.py. - 'The Nuclide server certificate has most likely expired.
    ' + - 'For your security, certificates automatically expire after 14 days.
    ' + - 'Please reload Atom to restore your remote project connection.', - /* dismissable */ true, - /* askToReload */ true, - ); + addHeartbeatNotification(HEARTBEAT_NOTIFICATION_ERROR, code, '**Certificate Expired**
    ' + + // The expiration date should be synced with + // nuclide-server/scripts/nuclide_server_manager.py. + 'The Nuclide server certificate has most likely expired.
    ' + 'For your security, certificates automatically expire after 14 days.
    ' + 'Please reload Atom to restore your remote project connection.', + /* dismissable */true, + /* askToReload */true); break; default: notifyNetworkAway(code); @@ -197,19 +175,17 @@ export class ConnectionHealthNotifier { break; } }; - this._subscription = new UniversalDisposable( - heartbeat.onHeartbeat(onHeartbeat), - heartbeat.onHeartbeatError(onHeartbeatError), - ); + this._subscription = new (_UniversalDisposable || _load_UniversalDisposable()).default(heartbeat.onHeartbeat(onHeartbeat), heartbeat.onHeartbeatError(onHeartbeatError)); } // Sets function to be called on Heartbeat error. // Function should return true to short-circuit the rest of the error logic. - setOnHeartbeatError(onHeartbeatError: ?OnHeartbeatErrorCallback): void { + setOnHeartbeatError(onHeartbeatError) { this._onHeartbeatError = onHeartbeatError; } - dispose(): void { + dispose() { this._subscription.dispose(); } } +exports.ConnectionHealthNotifier = ConnectionHealthNotifier; \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/ConnectionTracker.js b/pkg/nuclide-remote-connection/lib/ConnectionTracker.js index 988ea3b8f2..a09a488f16 100644 --- a/pkg/nuclide-remote-connection/lib/ConnectionTracker.js +++ b/pkg/nuclide-remote-connection/lib/ConnectionTracker.js @@ -1,33 +1,41 @@ -/** - * 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 strict-local - * @format - */ - -import {stringifyError} from 'nuclide-commons/string'; -import {isGkEnabled} from '../../commons-node/passesGK'; -import {track} from '../../nuclide-analytics'; - -import type { - SshConnectionConfiguration, - SshHandshakeErrorType, -} from './SshHandshake'; - -const CONNECTION_EVENT = 'nuclide-remote-connection'; - -export default class ConnectionTracker { - _config: SshConnectionConfiguration; - _connectionStartTime: number; - _promptYubikeyTime: number; - _finishYubikeyTime: number; - _expired: boolean; - - constructor(config: SshConnectionConfiguration) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _string; + +function _load_string() { + return _string = require('../../../modules/nuclide-commons/string'); +} + +var _passesGK; + +function _load_passesGK() { + return _passesGK = require('../../commons-node/passesGK'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +const CONNECTION_EVENT = 'nuclide-remote-connection'; /** + * 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. + * + * strict-local + * @format + */ + +class ConnectionTracker { + + constructor(config) { this._config = config; this._expired = false; this._connectionStartTime = Date.now(); @@ -35,46 +43,35 @@ export default class ConnectionTracker { this._finishYubikeyTime = 0; } - trackPromptYubikeyInput(): void { + trackPromptYubikeyInput() { this._promptYubikeyTime = Date.now(); } - trackFinishYubikeyInput(): void { + trackFinishYubikeyInput() { this._finishYubikeyTime = Date.now(); } - trackSuccess(): void { + trackSuccess() { this._trackConnectionResult(true); } - trackFailure(errorType: SshHandshakeErrorType, e: Error): void { + trackFailure(errorType, e) { this._trackConnectionResult(false, errorType, e); } - _trackConnectionResult( - succeed: boolean, - errorType?: SshHandshakeErrorType, - e?: Error, - ): void { + _trackConnectionResult(succeed, errorType, e) { if (this._expired) { return; } - const preYubikeyDuration = - this._promptYubikeyTime > 0 - ? this._promptYubikeyTime - this._connectionStartTime - : 0; - const postYubikeyDuration = - this._finishYubikeyTime > 0 ? Date.now() - this._finishYubikeyTime : 0; - const realDuration = - preYubikeyDuration > 0 && postYubikeyDuration > 0 - ? preYubikeyDuration + postYubikeyDuration - : 0; - - track(CONNECTION_EVENT, { + const preYubikeyDuration = this._promptYubikeyTime > 0 ? this._promptYubikeyTime - this._connectionStartTime : 0; + const postYubikeyDuration = this._finishYubikeyTime > 0 ? Date.now() - this._finishYubikeyTime : 0; + const realDuration = preYubikeyDuration > 0 && postYubikeyDuration > 0 ? preYubikeyDuration + postYubikeyDuration : 0; + + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)(CONNECTION_EVENT, { error: succeed ? '0' : '1', errorType: errorType || '', - exception: e ? stringifyError(e) : '', + exception: e ? (0, (_string || _load_string()).stringifyError)(e) : '', duration: (Date.now() - this._connectionStartTime).toString(), preYubikeyDuration: preYubikeyDuration.toString(), postYubikeyDuration: postYubikeyDuration.toString(), @@ -86,9 +83,10 @@ export default class ConnectionTracker { cwd: this._config.cwd, authMethod: this._config.authMethod, // We already checked this GK to get here, so no need to await. - isBigDig: isGkEnabled('nuclide_big_dig'), + isBigDig: (0, (_passesGK || _load_passesGK()).isGkEnabled)('nuclide_big_dig') }); this._expired = true; } } +exports.default = ConnectionTracker; \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/IpcTransports.js b/pkg/nuclide-remote-connection/lib/IpcTransports.js index 88f64d0f61..945759c05f 100644 --- a/pkg/nuclide-remote-connection/lib/IpcTransports.js +++ b/pkg/nuclide-remote-connection/lib/IpcTransports.js @@ -1,103 +1,111 @@ -/** - * 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 strict-local - * @format - */ - -import invariant from 'assert'; -import fs from 'fs'; -import {getLogger} from 'log4js'; -import {Deferred} from 'nuclide-commons/promise'; -import {getOutputStream, ProcessExitError} from 'nuclide-commons/process'; -import {Observable} from 'rxjs'; -import {StreamTransport} from '../../nuclide-rpc'; - -const PIPE_FD = 3; - -export class IpcServerTransport { - _transport: StreamTransport; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.IpcClientTransport = exports.IpcServerTransport = undefined; + +var _fs = _interopRequireDefault(require('fs')); + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideRpc; + +function _load_nuclideRpc() { + return _nuclideRpc = require('../../nuclide-rpc'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const PIPE_FD = 3; /** + * 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. + * + * strict-local + * @format + */ + +class IpcServerTransport { constructor() { - this._transport = new StreamTransport( - fs.createWriteStream('', {fd: PIPE_FD}), - fs.createReadStream('', {fd: PIPE_FD}), - ); + this._transport = new (_nuclideRpc || _load_nuclideRpc()).StreamTransport(_fs.default.createWriteStream('', { fd: PIPE_FD }), _fs.default.createReadStream('', { fd: PIPE_FD })); } - send(message: string): void { + send(message) { this._transport.send(message); } - onMessage(): Observable { + onMessage() { return this._transport.onMessage(); } - close(): void { + close() { this._transport.close(); } - isClosed(): boolean { + isClosed() { return this._transport.isClosed(); } } -export class IpcClientTransport { - _transport: Deferred; - _subscription: rxjs$Subscription; - - constructor(processStream: Observable) { - this._transport = new Deferred(); - this._subscription = processStream - .do(process => - this._transport.resolve( - new StreamTransport(process.stdio[PIPE_FD], process.stdio[PIPE_FD]), - ), - ) - .switchMap(process => getOutputStream(process)) - .subscribe({ - error: err => { - this._handleError(err); - }, - }); +exports.IpcServerTransport = IpcServerTransport; +class IpcClientTransport { + + constructor(processStream) { + this._transport = new (_promise || _load_promise()).Deferred(); + this._subscription = processStream.do(process => this._transport.resolve(new (_nuclideRpc || _load_nuclideRpc()).StreamTransport(process.stdio[PIPE_FD], process.stdio[PIPE_FD]))).switchMap(process => (0, (_process || _load_process()).getOutputStream)(process)).subscribe({ + error: err => { + this._handleError(err); + } + }); } - _handleError(err: Error) { + _handleError(err) { this._transport.reject(err); - getLogger().fatal('Nuclide RPC process crashed', err); - const buttons = [ - { - text: 'Reload Atom', - className: 'icon icon-zap', - onDidClick() { - atom.reload(); - }, - }, - ]; + (0, (_log4js || _load_log4js()).getLogger)().fatal('Nuclide RPC process crashed', err); + const buttons = [{ + text: 'Reload Atom', + className: 'icon icon-zap', + onDidClick() { + atom.reload(); + } + }]; if (atom.packages.isPackageLoaded('fb-file-a-bug')) { buttons.push({ text: 'File a bug', className: 'icon icon-nuclicon-bug', onDidClick() { - atom.commands.dispatch( - atom.workspace.getElement(), - 'fb-file-a-bug:file', - ); - }, + atom.commands.dispatch(atom.workspace.getElement(), 'fb-file-a-bug:file'); + } }); } let detail; - if (err instanceof ProcessExitError) { - let {stderr} = err; + if (err instanceof (_process || _load_process()).ProcessExitError) { + let { stderr } = err; if (stderr != null) { const lines = stderr.split('\n'); - const startIndex = lines.findIndex(line => - line.includes('chrome-devtools://'), - ); + const startIndex = lines.findIndex(line => line.includes('chrome-devtools://')); if (startIndex !== -1) { stderr = lines.slice(startIndex + 1).join('\n'); } @@ -107,25 +115,25 @@ export class IpcClientTransport { detail = String(err); } atom.notifications.addError('Local RPC process crashed!', { - description: - 'The local Nuclide RPC process crashed. Please reload Atom to continue.', + description: 'The local Nuclide RPC process crashed. Please reload Atom to continue.', detail, dismissable: true, - buttons, + buttons }); } - send(message: string): void { - invariant(!this.isClosed(), 'Transport unexpectedly closed'); + send(message) { + if (!!this.isClosed()) { + throw new Error('Transport unexpectedly closed'); + } + this._transport.promise.then(transport => { transport.send(message); }); } - onMessage(): Observable { - return Observable.fromPromise(this._transport.promise).switchMap( - transport => transport.onMessage(), - ); + onMessage() { + return _rxjsBundlesRxMinJs.Observable.fromPromise(this._transport.promise).switchMap(transport => transport.onMessage()); } close() { @@ -133,8 +141,9 @@ export class IpcClientTransport { this._transport.reject(Error('Transport closed')); } - isClosed(): boolean { + isClosed() { // $FlowFixMe: Add to rxjs defs return this._subscription.closed; } } +exports.IpcClientTransport = IpcClientTransport; \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/LocalRpcServer.js b/pkg/nuclide-remote-connection/lib/LocalRpcServer.js index 93816915cb..e7ded72b08 100644 --- a/pkg/nuclide-remote-connection/lib/LocalRpcServer.js +++ b/pkg/nuclide-remote-connection/lib/LocalRpcServer.js @@ -1,3 +1,51 @@ +'use strict'; + +var _child_process = _interopRequireDefault(require('child_process')); + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _nuclideMarshalersCommon; + +function _load_nuclideMarshalersCommon() { + return _nuclideMarshalersCommon = require('../../nuclide-marshalers-common'); +} + +var _servicesConfig; + +function _load_servicesConfig() { + return _servicesConfig = _interopRequireDefault(require('../../nuclide-server/lib/servicesConfig')); +} + +var _nuclideRpc; + +function _load_nuclideRpc() { + return _nuclideRpc = require('../../nuclide-rpc'); +} + +var _nuclideLogging; + +function _load_nuclideLogging() { + return _nuclideLogging = require('../../nuclide-logging'); +} + +var _IpcTransports; + +function _load_IpcTransports() { + return _IpcTransports = require('./IpcTransports'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,27 +53,18 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import child_process from 'child_process'; -import {getLogger} from 'log4js'; -import {track} from '../../nuclide-analytics'; -import {getServerSideMarshalers} from '../../nuclide-marshalers-common'; -import servicesConfig from '../../nuclide-server/lib/servicesConfig'; -import {RpcConnection, ServiceRegistry} from '../../nuclide-rpc'; -import {initializeLogging, flushLogsAndAbort} from '../../nuclide-logging'; -import {IpcServerTransport} from './IpcTransports'; - -initializeLogging(); +(0, (_nuclideLogging || _load_nuclideLogging()).initializeLogging)(); -const logger = getLogger('LocalRpcServer'); +const logger = (0, (_log4js || _load_log4js()).getLogger)('LocalRpcServer'); process.on('uncaughtException', err => { // Log the error and continue the server crash. logger.fatal('Uncaught exception in LocalRpcServer', err); - flushLogsAndAbort(); + (0, (_nuclideLogging || _load_nuclideLogging()).flushLogsAndAbort)(); }); process.on('unhandledRejection', (error, promise) => { @@ -41,7 +80,7 @@ process.on('disconnect', () => { process.on('exit', () => { // $FlowIgnore: Private method. process._getActiveHandles().forEach(handle => { - if (handle instanceof child_process.ChildProcess) { + if (handle instanceof _child_process.default.ChildProcess) { handle.kill(); } }); @@ -49,19 +88,13 @@ process.on('exit', () => { // If we started this with --inspect, don't pass that on to the children. // Can be removed once --inspect=0 is usable. -if ( - process.execArgv.length > 0 && - process.execArgv[0].startsWith('--inspect') -) { +if (process.execArgv.length > 0 && process.execArgv[0].startsWith('--inspect')) { process.execArgv.splice(0, 1); } -const serviceRegistry = new ServiceRegistry( - getServerSideMarshalers, - servicesConfig, -); -const serverTransport = new IpcServerTransport(); -RpcConnection.createServer(serviceRegistry, serverTransport); +const serviceRegistry = new (_nuclideRpc || _load_nuclideRpc()).ServiceRegistry((_nuclideMarshalersCommon || _load_nuclideMarshalersCommon()).getServerSideMarshalers, (_servicesConfig || _load_servicesConfig()).default); +const serverTransport = new (_IpcTransports || _load_IpcTransports()).IpcServerTransport(); +(_nuclideRpc || _load_nuclideRpc()).RpcConnection.createServer(serviceRegistry, serverTransport); logger.info('Started local RPC server.'); @@ -73,13 +106,12 @@ let lastCpuUsage = process.cpuUsage(); setInterval(() => { // $FlowIssue: process.cpuUsage doesn't exist const cpuUsage = process.cpuUsage(); - track('local-rpc-health', { - ...process.memoryUsage(), + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('local-rpc-health', Object.assign({}, process.memoryUsage(), { // 1) CPU stats are in microseconds. Seconds are more convenient. // 2) CPU stats are cumulative, so take the delta. The API is supposed to provide // a diff if given the previous value, but this doesn't work correctly in practice. cpuUser: (cpuUsage.user - lastCpuUsage.user) / 1e6, - cpuSystem: (cpuUsage.system - lastCpuUsage.system) / 1e6, - }); + cpuSystem: (cpuUsage.system - lastCpuUsage.system) / 1e6 + })); lastCpuUsage = cpuUsage; -}, HEALTH_INTERVAL); +}, HEALTH_INTERVAL); \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/RemoteCommand.js b/pkg/nuclide-remote-connection/lib/RemoteCommand.js index 284eba987f..0aa847548e 100644 --- a/pkg/nuclide-remote-connection/lib/RemoteCommand.js +++ b/pkg/nuclide-remote-connection/lib/RemoteCommand.js @@ -1,35 +1,25 @@ -/** - * 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 strict - * @format - */ +'use strict'; -import {Client as SshConnection} from 'ssh2'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.readFile = readFile; -type ReadFileResult = - | {|+type: 'success', +data: Buffer|} - | {|+type: 'timeout'|} - | {|+type: 'fail-to-start-connection', +error: Error|} - | {|+type: 'fail-to-transfer-data', +error: Error|}; +var _ssh; + +function _load_ssh() { + return _ssh = require('ssh2'); +} /** * This function receives a connection, timeout and a file path and returns the * remote file's content. */ -export async function readFile( - connection: SshConnection, - timeout: number, - filePath: string, -): Promise { +async function readFile(connection, timeout, filePath) { return new Promise((resolve, reject) => { let sftpTimer = setTimeout(() => { sftpTimer = null; - resolve({type: 'timeout'}); + resolve({ type: 'timeout' }); }, timeout); connection.sftp((error, sftp) => { @@ -39,18 +29,27 @@ export async function readFile( } clearTimeout(sftpTimer); if (error) { - resolve({type: 'fail-to-start-connection', error}); + resolve({ type: 'fail-to-start-connection', error }); return; } sftp.readFile(filePath, (sftpError, data) => { sftp.end(); if (sftpError) { - resolve({type: 'fail-to-transfer-data', error: sftpError}); + resolve({ type: 'fail-to-transfer-data', error: sftpError }); return; } - resolve({type: 'success', data}); + resolve({ type: 'success', data }); return; }); }); }); -} +} /** + * 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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/RemoteConnection.js b/pkg/nuclide-remote-connection/lib/RemoteConnection.js index 3a207f285e..b2e6abbbd0 100644 --- a/pkg/nuclide-remote-connection/lib/RemoteConnection.js +++ b/pkg/nuclide-remote-connection/lib/RemoteConnection.js @@ -1,3 +1,60 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RemoteConnection = undefined; + +var _ProjectManager; + +function _load_ProjectManager() { + return _ProjectManager = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/ProjectManager')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _lookupPreferIpV; + +function _load_lookupPreferIpV() { + return _lookupPreferIpV = _interopRequireDefault(require('./lookup-prefer-ip-v6')); +} + +var _ServerConnection; + +function _load_ServerConnection() { + return _ServerConnection = require('./ServerConnection'); +} + +var _eventKit; + +function _load_eventKit() { + return _eventKit = require('event-kit'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _RemoteConnectionConfigurationManager; + +function _load_RemoteConnectionConfigurationManager() { + return _RemoteConnectionConfigurationManager = require('./RemoteConnectionConfigurationManager'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,92 +62,40 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {HgRepositoryDescription} from '../../nuclide-source-control-helpers'; - -import ProjectManager from 'nuclide-commons-atom/ProjectManager'; -import typeof * as FileWatcherServiceType from '../../nuclide-filewatcher-rpc'; -import typeof * as FileSystemServiceType from '../../nuclide-server/lib/services/FileSystemService'; -import typeof * as SourceControlService from '../../nuclide-server/lib/services/SourceControlService'; -import type {RemoteDirectory} from './RemoteDirectory'; -import type {ServerConnectionVersion} from './ServerConnection'; - -import invariant from 'assert'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import lookupPreferIpv6 from './lookup-prefer-ip-v6'; -import {ServerConnection} from './ServerConnection'; -import {Emitter} from 'event-kit'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {getConnectionConfig} from './RemoteConnectionConfigurationManager'; -import {getLogger} from 'log4js'; - -const logger = getLogger('nuclide-remote-connection'); +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-remote-connection'); const FILE_WATCHER_SERVICE = 'FileWatcherService'; const FILE_SYSTEM_SERVICE = 'FileSystemService'; -export type RemoteConnectionConfiguration = { - host: string, // host nuclide server is running on. - port: number, // port to connect to. - family?: 4 | 6, // ipv4 or ipv6? - certificateAuthorityCertificate?: Buffer, // certificate of certificate authority. - clientCertificate?: Buffer, // client certificate for https connection. - clientKey?: Buffer, // key for https connection. - version?: ServerConnectionVersion, - - // Stuff specific to RemoteConnectionConfiguration (e.g. not in ServerConnectionConfiguration) - path: string, // Path to remote directory user should start in upon connection. - displayTitle: string, // Name of the saved connection profile. - promptReconnectOnFailure?: boolean, // open a connection dialog prompt if the reconnect fails -}; - // A RemoteConnection represents a directory which has been opened in Nuclide on a remote machine. // This corresponds to what atom calls a 'root path' in a project. // // TODO: The _entries and _hgRepositoryDescription should not be here. // Nuclide behaves badly when remote directories are opened which are parent/child of each other. // And there needn't be a 1:1 relationship between RemoteConnections and hg repos. -export class RemoteConnection { - _path: string; // Path to remote directory user should start in upon connection. - _subscriptions: UniversalDisposable; - _hgRepositoryDescription: ?HgRepositoryDescription; - _connection: ServerConnection; - _displayTitle: string; - _alwaysShutdownIfLast: boolean; - _promptReconnectOnFailure: boolean; - - static _emitter = new Emitter(); - - static async findOrCreate( - config: RemoteConnectionConfiguration, - ): Promise { - const serverConnection = await ServerConnection.getOrCreate(config); - const {path, displayTitle, promptReconnectOnFailure} = config; +class RemoteConnection { + + static async findOrCreate(config) { + const serverConnection = await (_ServerConnection || _load_ServerConnection()).ServerConnection.getOrCreate(config); + const { path, displayTitle, promptReconnectOnFailure } = config; let roots; try { - const fsService: FileSystemServiceType = serverConnection.getService( - FILE_SYSTEM_SERVICE, - ); + const fsService = serverConnection.getService(FILE_SYSTEM_SERVICE); const realPath = await fsService.resolveRealPath(path); if (hasAtomProjectFormat(path)) { - await ProjectManager.open( - serverConnection.getUriOfRemotePath(realPath), - ); + await (_ProjectManager || _load_ProjectManager()).default.open(serverConnection.getUriOfRemotePath(realPath)); // $FlowFixMe: Upstream this and add to our type defs roots = atom.project.getSpecification().paths; } else { // Now that we know the real path, it's possible this collides with an existing connection. - if (realPath !== path && nuclideUri.isRemote(path)) { - const existingConnection = this.getByHostnameAndPath( - nuclideUri.getHostname(path), - realPath, - ); + if (realPath !== path && (_nuclideUri || _load_nuclideUri()).default.isRemote(path)) { + const existingConnection = this.getByHostnameAndPath((_nuclideUri || _load_nuclideUri()).default.getHostname(path), realPath); if (existingConnection != null) { return existingConnection; } @@ -106,31 +111,20 @@ export class RemoteConnection { } throw err; } - const connections = await Promise.all( - roots.map((dir, i) => { - const connection = new RemoteConnection( - serverConnection, - dir, - i === 0 ? displayTitle : '', - promptReconnectOnFailure !== false, // default: true - ); - return connection._initialize(); - }), - ); + const connections = await Promise.all(roots.map((dir, i) => { + const connection = new RemoteConnection(serverConnection, dir, i === 0 ? displayTitle : '', promptReconnectOnFailure !== false); + return connection._initialize(); + })); // We need to return one connection from this function, // even though many connections are being created to support projects. return connections[0]; } // Do NOT call this directly. Use findOrCreate instead. - constructor( - connection: ServerConnection, - path: string, - displayTitle: string, - promptReconnectOnFailure: boolean, - ) { + // Path to remote directory user should start in upon connection. + constructor(connection, path, displayTitle, promptReconnectOnFailure) { this._path = path; - this._subscriptions = new UniversalDisposable(); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._hgRepositoryDescription = null; this._connection = connection; this._displayTitle = displayTitle; @@ -138,15 +132,12 @@ export class RemoteConnection { this._promptReconnectOnFailure = promptReconnectOnFailure; } - static _createInsecureConnectionForTesting( - path: string, - port: number, - ): Promise { + static _createInsecureConnectionForTesting(path, port) { const config = { host: 'localhost', port, path, - displayTitle: '', + displayTitle: '' }; return RemoteConnection.findOrCreate(config); } @@ -157,23 +148,17 @@ export class RemoteConnection { * connection, null (resolved by promise) is returned. * Configurations may also be retrieved by IP address. */ - static async _createConnectionBySavedConfig( - host: string, - path: string, - displayTitle: string, - promptReconnectOnFailure: boolean = true, - ): Promise { - const connectionConfig = await getConnectionConfig(host); + static async _createConnectionBySavedConfig(host, path, displayTitle, promptReconnectOnFailure = true) { + const connectionConfig = await (0, (_RemoteConnectionConfigurationManager || _load_RemoteConnectionConfigurationManager()).getConnectionConfig)(host); if (!connectionConfig) { return null; } try { - const config = { - ...connectionConfig, + const config = Object.assign({}, connectionConfig, { path, displayTitle, - promptReconnectOnFailure, - }; + promptReconnectOnFailure + }); return await RemoteConnection.findOrCreate(config); } catch (e) { // Returning null from this method signals that we should @@ -185,10 +170,7 @@ export class RemoteConnection { throw e; } - const log = - e.name === 'VersionMismatchError' - ? logger.warn.bind(logger) - : logger.error.bind(logger); + const log = e.name === 'VersionMismatchError' ? logger.warn.bind(logger) : logger.error.bind(logger); log(`Failed to reuse connectionConfiguration for ${host}`, e); return null; @@ -198,17 +180,12 @@ export class RemoteConnection { /** * Attempts to connect to an open or previously open remote connection. */ - static async reconnect( - host: string, - path: string, - displayTitle: string, - promptReconnectOnFailure: boolean = true, - ): Promise { + static async reconnect(host, path, displayTitle, promptReconnectOnFailure = true) { logger.info('Attempting to reconnect', { host, path, displayTitle, - promptReconnectOnFailure, + promptReconnectOnFailure }); if (!hasAtomProjectFormat(path)) { @@ -219,22 +196,12 @@ export class RemoteConnection { } } - let connection = await RemoteConnection._createConnectionBySavedConfig( - host, - path, - displayTitle, - promptReconnectOnFailure, - ); + let connection = await RemoteConnection._createConnectionBySavedConfig(host, path, displayTitle, promptReconnectOnFailure); if (connection == null) { try { // Connection configs are also stored by IP address to share between hostnames. - const {address} = await lookupPreferIpv6(host); - connection = await RemoteConnection._createConnectionBySavedConfig( - address, - path, - displayTitle, - promptReconnectOnFailure, - ); + const { address } = await (0, (_lookupPreferIpV || _load_lookupPreferIpV()).default)(host); + connection = await RemoteConnection._createConnectionBySavedConfig(address, path, displayTitle, promptReconnectOnFailure); } catch (err) { // It's OK if the backup IP check fails. } @@ -245,34 +212,26 @@ export class RemoteConnection { // A workaround before Atom 2.0: Atom's Project::setPaths currently uses // ::repositoryForDirectorySync, so we need the repo information to already be // available when the new path is added. t6913624 tracks cleanup of this. - async _setHgRepoInfo(): Promise { + async _setHgRepoInfo() { const remotePath = this.getPath(); - const {getHgRepository} = (this.getConnection().getService( - 'SourceControlService', - ): SourceControlService); - this._setHgRepositoryDescription(await getHgRepository(remotePath)); + const { getHgRepository } = this.getConnection().getService('SourceControlService'); + this._setHgRepositoryDescription((await getHgRepository(remotePath))); } - createDirectory(uri: string, symlink: boolean = false): RemoteDirectory { - return this._connection.createDirectory( - uri, - this._hgRepositoryDescription, - symlink, - ); + createDirectory(uri, symlink = false) { + return this._connection.createDirectory(uri, this._hgRepositoryDescription, symlink); } // A workaround before Atom 2.0: see ::getHgRepoInfo of main.js. - _setHgRepositoryDescription( - hgRepositoryDescription: ?HgRepositoryDescription, - ): void { + _setHgRepositoryDescription(hgRepositoryDescription) { this._hgRepositoryDescription = hgRepositoryDescription; } - getHgRepositoryDescription(): ?HgRepositoryDescription { + getHgRepositoryDescription() { return this._hgRepositoryDescription; } - async _initialize(): Promise { + async _initialize() { const attemptShutdown = false; // Must add first to prevent the ServerConnection from going away // in a possible race. @@ -290,123 +249,95 @@ export class RemoteConnection { return this; } - _watchRootProjectDirectory(): void { + _watchRootProjectDirectory() { const rootDirectoryUri = this.getUri(); const rootDirectoryPath = this.getPath(); - const FileWatcherService: FileWatcherServiceType = this.getConnection().getService( - FILE_WATCHER_SERVICE, - ); - invariant(FileWatcherService); - const {watchDirectoryRecursive} = FileWatcherService; + const FileWatcherService = this.getConnection().getService(FILE_WATCHER_SERVICE); + + if (!FileWatcherService) { + throw new Error('Invariant violation: "FileWatcherService"'); + } + + const { watchDirectoryRecursive } = FileWatcherService; // Start watching the project for changes and initialize the root watcher // for next calls to `watchFile` and `watchDirectory`. const watchStream = watchDirectoryRecursive(rootDirectoryUri).refCount(); - const subscription = watchStream.subscribe( - watchUpdate => { - // Nothing needs to be done if the root directory was watched correctly. - // Let's just console log it anyway. - logger.info( - `Watcher Features Initialized for project: ${rootDirectoryUri}`, - watchUpdate, - ); - }, - async error => { - let warningMessageToUser = ''; - let detail; - const fileSystemService: FileSystemServiceType = this.getConnection().getService( - FILE_SYSTEM_SERVICE, - ); - if (await fileSystemService.isNfs(rootDirectoryUri)) { - warningMessageToUser += - `This project directory: \`${rootDirectoryPath}\` is on \`NFS\` filesystem. ` + - 'Nuclide works best with local (non-NFS) root directory.' + - 'e.g. `/data/users/$USER`' + - 'features such as synced remote file editing, file search, ' + - 'and Mercurial-related updates will not work.
    '; - } else { - warningMessageToUser += - 'You just connected to a remote project ' + - `\`${rootDirectoryPath}\` without Watchman support, which means that ` + - 'crucial features such as synced remote file editing, file search, ' + - 'and Mercurial-related updates will not work.'; - - const watchmanConfig = await fileSystemService - .findNearestAncestorNamed('.watchmanconfig', rootDirectoryUri) - .catch(() => null); - if (watchmanConfig == null) { - warningMessageToUser += - '

    A possible workaround is to create an empty `.watchmanconfig` file ' + - 'in the remote folder, which will enable Watchman if you have it installed.'; - } - detail = error.message || error; - logger.error( - 'Watchman failed to start - watcher features disabled!', - error, - ); + const subscription = watchStream.subscribe(watchUpdate => { + // Nothing needs to be done if the root directory was watched correctly. + // Let's just console log it anyway. + logger.info(`Watcher Features Initialized for project: ${rootDirectoryUri}`, watchUpdate); + }, async error => { + let warningMessageToUser = ''; + let detail; + const fileSystemService = this.getConnection().getService(FILE_SYSTEM_SERVICE); + if (await fileSystemService.isNfs(rootDirectoryUri)) { + warningMessageToUser += `This project directory: \`${rootDirectoryPath}\` is on \`NFS\` filesystem. ` + 'Nuclide works best with local (non-NFS) root directory.' + 'e.g. `/data/users/$USER`' + 'features such as synced remote file editing, file search, ' + 'and Mercurial-related updates will not work.
    '; + } else { + warningMessageToUser += 'You just connected to a remote project ' + `\`${rootDirectoryPath}\` without Watchman support, which means that ` + 'crucial features such as synced remote file editing, file search, ' + 'and Mercurial-related updates will not work.'; + + const watchmanConfig = await fileSystemService.findNearestAncestorNamed('.watchmanconfig', rootDirectoryUri).catch(() => null); + if (watchmanConfig == null) { + warningMessageToUser += '

    A possible workaround is to create an empty `.watchmanconfig` file ' + 'in the remote folder, which will enable Watchman if you have it installed.'; } - // Add a persistent warning message to make sure the user sees it before dismissing. - atom.notifications.addWarning(warningMessageToUser, { - dismissable: true, - detail, - }); - }, - () => { - // Nothing needs to be done if the root directory watch has ended. - logger.info(`Watcher Features Ended for project: ${rootDirectoryUri}`); - }, - ); + detail = error.message || error; + logger.error('Watchman failed to start - watcher features disabled!', error); + } + // Add a persistent warning message to make sure the user sees it before dismissing. + atom.notifications.addWarning(warningMessageToUser, { + dismissable: true, + detail + }); + }, () => { + // Nothing needs to be done if the root directory watch has ended. + logger.info(`Watcher Features Ended for project: ${rootDirectoryUri}`); + }); this._subscriptions.add(subscription); } - async close(shutdownIfLast: boolean): Promise { + async close(shutdownIfLast) { logger.info('Received close command!', { shutdownIfLast, - stack: Error('stack').stack, + stack: Error('stack').stack }); this._subscriptions.dispose(); await this._connection.removeConnection(this, shutdownIfLast); RemoteConnection._emitter.emit('did-close', this); } - getConnection(): ServerConnection { + getConnection() { return this._connection; } - getDisplayTitle(): string { + getDisplayTitle() { return this._displayTitle; } - getUri(): string { + getUri() { return this.getConnection().getUriOfRemotePath(this.getPath()); } - getPath(): string { + getPath() { return this._path; } - getConfig(): RemoteConnectionConfiguration { - return { - ...this._connection.getConfig(), + getConfig() { + return Object.assign({}, this._connection.getConfig(), { path: this._path, displayTitle: this._displayTitle, - promptReconnectOnFailure: this._promptReconnectOnFailure, - }; + promptReconnectOnFailure: this._promptReconnectOnFailure + }); } - static onDidAddRemoteConnection( - handler: (connection: RemoteConnection) => void, - ): IDisposable { + static onDidAddRemoteConnection(handler) { return RemoteConnection._emitter.on('did-add', handler); } - static onDidCloseRemoteConnection( - handler: (connection: RemoteConnection) => void, - ): IDisposable { + static onDidCloseRemoteConnection(handler) { return RemoteConnection._emitter.on('did-close', handler); } - static getForUri(uri: NuclideUri): ?RemoteConnection { - const {hostname, path} = nuclideUri.parse(uri); + static getForUri(uri) { + const { hostname, path } = (_nuclideUri || _load_nuclideUri()).default.parse(uri); if (hostname == null) { return null; } @@ -420,30 +351,29 @@ export class RemoteConnection { * If path is null, empty or undefined, then return the connection which matches * the hostname and ignore the initial working directory. */ - static getByHostnameAndPath( - hostname: string, - path: string, - ): ?RemoteConnection { + static getByHostnameAndPath(hostname, path) { return RemoteConnection.getByHostname(hostname).filter(connection => { return path.startsWith(connection.getPath()); })[0]; } - static getByHostname(hostname: string): Array { - const server = ServerConnection.getByHostname(hostname); + static getByHostname(hostname) { + const server = (_ServerConnection || _load_ServerConnection()).ServerConnection.getByHostname(hostname); return server == null ? [] : server.getConnections(); } - setAlwaysShutdownIfLast(alwaysShutdownIfLast: boolean): void { + setAlwaysShutdownIfLast(alwaysShutdownIfLast) { this._alwaysShutdownIfLast = alwaysShutdownIfLast; } - alwaysShutdownIfLast(): boolean { + alwaysShutdownIfLast() { return this._alwaysShutdownIfLast; } } +exports.RemoteConnection = RemoteConnection; +RemoteConnection._emitter = new (_eventKit || _load_eventKit()).Emitter(); function hasAtomProjectFormat(filepath) { - const ext = nuclideUri.extname(filepath); + const ext = (_nuclideUri || _load_nuclideUri()).default.extname(filepath); return ext === '.json' || ext === '.cson' || ext === '.toml'; -} +} \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/RemoteConnectionConfigurationManager.js b/pkg/nuclide-remote-connection/lib/RemoteConnectionConfigurationManager.js index 3b0a22fa70..d18bf76e6c 100644 --- a/pkg/nuclide-remote-connection/lib/RemoteConnectionConfigurationManager.js +++ b/pkg/nuclide-remote-connection/lib/RemoteConnectionConfigurationManager.js @@ -1,72 +1,77 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -/* global localStorage */ +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.__test__ = exports.SERVER_CONFIG_REQUEST_EVENT = exports.SERVER_CONFIG_RESPONSE_EVENT = undefined; +exports.getConnectionConfig = getConnectionConfig; +exports.setConnectionConfig = setConnectionConfig; +exports.clearConnectionConfig = clearConnectionConfig; + +var _crypto = _interopRequireDefault(require('crypto')); + +var _log4js; -import type { - ServerConnectionConfiguration, - ServerConnectionVersion, -} from './ServerConnection'; +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _keytarWrapper; -import crypto from 'crypto'; -import invariant from 'assert'; -import {getLogger} from 'log4js'; -import keytarWrapper from '../../commons-node/keytarWrapper'; -import electron from 'electron'; +function _load_keytarWrapper() { + return _keytarWrapper = _interopRequireDefault(require('../../commons-node/keytarWrapper')); +} -const CONFIG_DIR = 'nuclide-connections'; -const logger = getLogger('nuclide-remote-connection'); -const remote = electron.remote; -const ipc = electron.ipcRenderer; +var _electron = _interopRequireDefault(require('electron')); -invariant(remote); -invariant(ipc); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -export const SERVER_CONFIG_RESPONSE_EVENT = 'server-config-response'; -export const SERVER_CONFIG_REQUEST_EVENT = 'server-config-request'; +const CONFIG_DIR = 'nuclide-connections'; /** + * 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. + * + * strict-local + * @format + */ + +/* global localStorage */ + +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-remote-connection'); +const remote = _electron.default.remote; +const ipc = _electron.default.ipcRenderer; + +if (!remote) { + throw new Error('Invariant violation: "remote"'); +} + +if (!ipc) { + throw new Error('Invariant violation: "ipc"'); +} + +const SERVER_CONFIG_RESPONSE_EVENT = exports.SERVER_CONFIG_RESPONSE_EVENT = 'server-config-response'; +const SERVER_CONFIG_REQUEST_EVENT = exports.SERVER_CONFIG_REQUEST_EVENT = 'server-config-request'; /** * Version of ServerConnectionConfiguration that uses string instead of Buffer for fields so it can * be translated directly to/from JSON. */ -type SerializableServerConnectionConfiguration = { - host: string, - port: number, - family?: 4 | 6, - certificateAuthorityCertificate?: string, - clientCertificate?: string, - clientKey?: string, - version?: ServerConnectionVersion, -}; + // Insecure configs are used for testing only. -function isInsecure(config: ServerConnectionConfiguration): boolean { - return ( - config.clientKey == null && - config.clientCertificate == null && - config.certificateAuthorityCertificate == null - ); +function isInsecure(config) { + return config.clientKey == null && config.clientCertificate == null && config.certificateAuthorityCertificate == null; } -function getStorageKey(host: string): string { +function getStorageKey(host) { return `${CONFIG_DIR}:${host}`; } -async function getConnectionConfigViaIPC( - host: string, -): Promise { +async function getConnectionConfigViaIPC(host) { const thisWindowsId = remote.getCurrentWindow().id; - const otherWindows = remote.BrowserWindow.getAllWindows().filter( - win => win.isVisible() && win.id !== thisWindowsId, - ); + const otherWindows = remote.BrowserWindow.getAllWindows().filter(win => win.isVisible() && win.id !== thisWindowsId); const timeoutInMilliseconds = 5000; return new Promise(resolve => { @@ -85,21 +90,18 @@ async function getConnectionConfigViaIPC( ipc.removeAllListeners(SERVER_CONFIG_RESPONSE_EVENT); }, timeoutInMilliseconds); - ipc.on( - SERVER_CONFIG_RESPONSE_EVENT, - (event, config: ?ServerConnectionConfiguration) => { - responseCount++; - - if (config != null || responseCount === otherWindows.length) { - if (config != null) { - logger.info('received the config! removing other listeners'); - } - resolve(config); - clearTimeout(timeout); - ipc.removeAllListeners(SERVER_CONFIG_RESPONSE_EVENT); + ipc.on(SERVER_CONFIG_RESPONSE_EVENT, (event, config) => { + responseCount++; + + if (config != null || responseCount === otherWindows.length) { + if (config != null) { + logger.info('received the config! removing other listeners'); } - }, - ); + resolve(config); + clearTimeout(timeout); + ipc.removeAllListeners(SERVER_CONFIG_RESPONSE_EVENT); + } + }); otherWindows.forEach(window => { logger.info(`requesting config from window ${window.id}`); @@ -112,9 +114,7 @@ async function getConnectionConfigViaIPC( }); } -export async function getConnectionConfig( - host: string, -): Promise { +async function getConnectionConfig(host) { const storedConfig = localStorage.getItem(getStorageKey(host)); if (storedConfig == null) { return null; @@ -131,10 +131,7 @@ export async function getConnectionConfig( } } -export async function setConnectionConfig( - config: ServerConnectionConfiguration, - ipAddress: string, -): Promise { +async function setConnectionConfig(config, ipAddress) { // Don't attempt to store insecure connections. // Insecure connections are used for testing and will fail the encryption call below. if (isInsecure(config)) { @@ -142,7 +139,7 @@ export async function setConnectionConfig( } try { - const encrypted = JSON.stringify(await encryptConfig(config)); + const encrypted = JSON.stringify((await encryptConfig(config))); localStorage.setItem(getStorageKey(config.host), encrypted); // Store configurations by their IP address as well. // This way, multiple aliases for the same hostname can reuse a single connection. @@ -152,7 +149,7 @@ export async function setConnectionConfig( } } -export async function clearConnectionConfig(host: string): Promise { +async function clearConnectionConfig(host) { try { localStorage.removeItem(getStorageKey(host)); } catch (e) { @@ -165,31 +162,34 @@ export async function clearConnectionConfig(host: string): Promise { * @param remoteProjectConfig - The config with the clientKey we want encrypted. * @return returns the passed in config with the clientKey encrypted. */ -async function encryptConfig( - remoteProjectConfig: ServerConnectionConfiguration, -): Promise { - const sha1 = crypto.createHash('sha1'); +async function encryptConfig(remoteProjectConfig) { + const sha1 = _crypto.default.createHash('sha1'); sha1.update(`${remoteProjectConfig.host}:${remoteProjectConfig.port}`); const sha1sum = sha1.digest('hex'); const { certificateAuthorityCertificate, clientCertificate, - clientKey, + clientKey } = remoteProjectConfig; - invariant(clientKey); + + if (!clientKey) { + throw new Error('Invariant violation: "clientKey"'); + } + const realClientKey = clientKey.toString(); // Convert from Buffer to string. - const {salt, password, encryptedString} = encryptString(realClientKey); - await keytarWrapper.replacePassword( - 'nuclide.remoteProjectConfig', - sha1sum, - password, - ); + const { salt, password, encryptedString } = encryptString(realClientKey); + await (_keytarWrapper || _load_keytarWrapper()).default.replacePassword('nuclide.remoteProjectConfig', sha1sum, password); const clientKeyWithSalt = encryptedString + '.' + salt; - invariant(certificateAuthorityCertificate); - invariant(clientCertificate); + if (!certificateAuthorityCertificate) { + throw new Error('Invariant violation: "certificateAuthorityCertificate"'); + } + + if (!clientCertificate) { + throw new Error('Invariant violation: "clientCertificate"'); + } return { host: remoteProjectConfig.host, @@ -198,7 +198,7 @@ async function encryptConfig( certificateAuthorityCertificate: certificateAuthorityCertificate.toString(), clientCertificate: clientCertificate.toString(), clientKey: clientKeyWithSalt, - version: remoteProjectConfig.version, + version: remoteProjectConfig.version }; } @@ -207,17 +207,12 @@ async function encryptConfig( * @param remoteProjectConfig - The config with the clientKey we want encrypted. * @return returns the passed in config with the clientKey encrypted. */ -async function decryptConfig( - remoteProjectConfig: SerializableServerConnectionConfiguration, -): Promise { - const sha1 = crypto.createHash('sha1'); +async function decryptConfig(remoteProjectConfig) { + const sha1 = _crypto.default.createHash('sha1'); sha1.update(`${remoteProjectConfig.host}:${remoteProjectConfig.port}`); const sha1sum = sha1.digest('hex'); - const password = await keytarWrapper.getPassword( - 'nuclide.remoteProjectConfig', - sha1sum, - ); + const password = await (_keytarWrapper || _load_keytarWrapper()).default.getPassword('nuclide.remoteProjectConfig', sha1sum); if (password == null) { throw new Error('Cannot find password for encrypted client key'); @@ -226,10 +221,14 @@ async function decryptConfig( const { certificateAuthorityCertificate, clientCertificate, - clientKey, + clientKey } = remoteProjectConfig; // flowlint-next-line sketchy-null-string:off - invariant(clientKey); + + if (!clientKey) { + throw new Error('Invariant violation: "clientKey"'); + } + const [encryptedString, salt] = clientKey.split('.'); if (!encryptedString || !salt) { @@ -238,37 +237,36 @@ async function decryptConfig( const restoredClientKey = decryptString(encryptedString, password, salt); if ( - // @lint-ignore PRIVATEKEY1 - !restoredClientKey.startsWith('-----BEGIN RSA PRIVATE KEY-----') - ) { - getLogger('nuclide-remote-connection').error( - `decrypted client key did not start with expected header: ${restoredClientKey}`, - ); + // @lint-ignore PRIVATEKEY1 + !restoredClientKey.startsWith('-----BEGIN RSA PRIVATE KEY-----')) { + (0, (_log4js || _load_log4js()).getLogger)('nuclide-remote-connection').error(`decrypted client key did not start with expected header: ${restoredClientKey}`); } // flowlint-next-line sketchy-null-string:off - invariant(certificateAuthorityCertificate); + + if (!certificateAuthorityCertificate) { + throw new Error('Invariant violation: "certificateAuthorityCertificate"'); + } // flowlint-next-line sketchy-null-string:off - invariant(clientCertificate); + + + if (!clientCertificate) { + throw new Error('Invariant violation: "clientCertificate"'); + } + return { host: remoteProjectConfig.host, port: remoteProjectConfig.port, family: remoteProjectConfig.family, - certificateAuthorityCertificate: new Buffer( - certificateAuthorityCertificate, - ), + certificateAuthorityCertificate: new Buffer(certificateAuthorityCertificate), clientCertificate: new Buffer(clientCertificate), clientKey: new Buffer(restoredClientKey), - version: remoteProjectConfig.version, + version: remoteProjectConfig.version }; } -function decryptString(text: string, password: string, salt: string): string { - const decipher = crypto.createDecipheriv( - 'aes-128-cbc', - new Buffer(password, 'base64'), - new Buffer(salt, 'base64'), - ); +function decryptString(text, password, salt) { + const decipher = _crypto.default.createDecipheriv('aes-128-cbc', new Buffer(password, 'base64'), new Buffer(salt, 'base64')); let decryptedString = decipher.update(text, 'base64', 'utf8'); decryptedString += decipher.final('utf8'); @@ -276,33 +274,25 @@ function decryptString(text: string, password: string, salt: string): string { return decryptedString; } -function encryptString( - text: string, -): {password: string, salt: string, encryptedString: string} { - const password = crypto.randomBytes(16).toString('base64'); - const salt = crypto.randomBytes(16).toString('base64'); - - const cipher = crypto.createCipheriv( - 'aes-128-cbc', - new Buffer(password, 'base64'), - new Buffer(salt, 'base64'), - ); - - let encryptedString = cipher.update( - text, - /* input_encoding */ 'utf8', - /* output_encoding */ 'base64', - ); +function encryptString(text) { + const password = _crypto.default.randomBytes(16).toString('base64'); + const salt = _crypto.default.randomBytes(16).toString('base64'); + + const cipher = _crypto.default.createCipheriv('aes-128-cbc', new Buffer(password, 'base64'), new Buffer(salt, 'base64')); + + let encryptedString = cipher.update(text, + /* input_encoding */'utf8', + /* output_encoding */'base64'); encryptedString += cipher.final('base64'); return { password, salt, - encryptedString, + encryptedString }; } -export const __test__ = { +const __test__ = exports.__test__ = { decryptString, - encryptString, -}; + encryptString +}; \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/RemoteDirectory.js b/pkg/nuclide-remote-connection/lib/RemoteDirectory.js index 848abb43a9..83fb8bcc3e 100644 --- a/pkg/nuclide-remote-connection/lib/RemoteDirectory.js +++ b/pkg/nuclide-remote-connection/lib/RemoteDirectory.js @@ -1,78 +1,81 @@ -/** - * 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 - */ - -import typeof * as FileSystemService from '../../nuclide-server/lib/services/FileSystemService'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import type {ServerConnection} from './ServerConnection'; -import type {HgRepositoryDescription} from '../../nuclide-source-control-helpers'; -import type {RemoteFile} from './RemoteFile'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import invariant from 'assert'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Emitter} from 'event-kit'; -import {getLogger} from 'log4js'; - -const logger = getLogger('nuclide-remote-connection'); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RemoteDirectory = undefined; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _eventKit; + +function _load_eventKit() { + return _eventKit = require('event-kit'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-remote-connection'); /** + * 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. + * + * + * @format + */ const MARKER_PROPERTY_FOR_REMOTE_DIRECTORY = '__nuclide_remote_directory__'; /* Mostly implements https://atom.io/docs/api/latest/Directory */ -export class RemoteDirectory { - static isRemoteDirectory( - directory: atom$Directory | RemoteDirectory, - ): boolean { +class RemoteDirectory { + static isRemoteDirectory(directory) { /* $FlowFixMe */ return directory[MARKER_PROPERTY_FOR_REMOTE_DIRECTORY] === true; } - _watchSubscription: ?rxjs$ISubscription; - _server: ServerConnection; - _uri: NuclideUri; - _emitter: atom$Emitter; - _subscriptionCount: number; - _host: string; - _localPath: string; - _hgRepositoryDescription: ?HgRepositoryDescription; - _symlink: boolean; - _deleted: boolean; - _isArchive: boolean; - /** * @param uri should be of the form "nuclide://example.com/path/to/directory". */ - constructor( - server: ServerConnection, - uri: string, - symlink: boolean = false, - options: ?any, - ) { + constructor(server, uri, symlink = false, options) { Object.defineProperty(this, MARKER_PROPERTY_FOR_REMOTE_DIRECTORY, { - value: true, + value: true }); this._server = server; this._uri = uri; - this._emitter = new Emitter(); + this._emitter = new (_eventKit || _load_eventKit()).Emitter(); this._subscriptionCount = 0; this._symlink = symlink; - const {path: directoryPath, hostname} = nuclideUri.parse(uri); - invariant(hostname != null); + const { path: directoryPath, hostname } = (_nuclideUri || _load_nuclideUri()).default.parse(uri); + + if (!(hostname != null)) { + throw new Error('Invariant violation: "hostname != null"'); + } /** In the example, this would be "nuclide://example.com". */ + + this._host = hostname; /** In the example, this would be "/path/to/directory". */ this._localPath = directoryPath; // A workaround before Atom 2.0: see ::getHgRepoInfo of main.js. - this._hgRepositoryDescription = options - ? options.hgRepositoryDescription - : null; + this._hgRepositoryDescription = options ? options.hgRepositoryDescription : null; this._isArchive = options != null && Boolean(options.isArchive); this._deleted = false; } @@ -82,12 +85,12 @@ export class RemoteDirectory { this._unsubscribeFromNativeChangeEvents(); } - onDidChange(callback: () => any): IDisposable { + onDidChange(callback) { this._willAddSubscription(); return this._trackUnsubscription(this._emitter.on('did-change', callback)); } - onDidDelete(callback: () => any): IDisposable { + onDidDelete(callback) { this._willAddSubscription(); return this._trackUnsubscription(this._emitter.on('did-delete', callback)); } @@ -96,57 +99,47 @@ export class RemoteDirectory { * We may want to provide an implementation for this at some point. * However, for the time being, we don't get any benefits from doing so. */ - onDidChangeFiles(callback: () => mixed): IDisposable { - return new UniversalDisposable(); + onDidChangeFiles(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - _willAddSubscription(): void { + _willAddSubscription() { this._subscriptionCount++; try { this._subscribeToNativeChangeEvents(); } catch (err) { - logger.error( - 'Failed to subscribe RemoteDirectory:', - this._localPath, - err, - ); + logger.error('Failed to subscribe RemoteDirectory:', this._localPath, err); } } - _subscribeToNativeChangeEvents(): void { + _subscribeToNativeChangeEvents() { if (this._watchSubscription) { return; } - const watchStream = nuclideUri.isInArchive(this._uri) - ? this._server.getFileWatch(nuclideUri.ancestorOutsideArchive(this._uri)) - : this._server.getDirectoryWatch(this._uri); - this._watchSubscription = watchStream.subscribe( - watchUpdate => { - logger.debug('watchDirectory update:', watchUpdate); - switch (watchUpdate.type) { - case 'change': - return this._handleNativeChangeEvent(); - case 'delete': - return this._handleNativeDeleteEvent(); - } - }, - error => { - logger.error('Failed to subscribe RemoteDirectory:', this._uri, error); - this._watchSubscription = null; - }, - () => { - // Nothing needs to be done if the root directory watch has ended. - logger.debug(`watchDirectory ended: ${this._uri}`); - this._watchSubscription = null; - }, - ); - } - - _handleNativeChangeEvent(): void { + const watchStream = (_nuclideUri || _load_nuclideUri()).default.isInArchive(this._uri) ? this._server.getFileWatch((_nuclideUri || _load_nuclideUri()).default.ancestorOutsideArchive(this._uri)) : this._server.getDirectoryWatch(this._uri); + this._watchSubscription = watchStream.subscribe(watchUpdate => { + logger.debug('watchDirectory update:', watchUpdate); + switch (watchUpdate.type) { + case 'change': + return this._handleNativeChangeEvent(); + case 'delete': + return this._handleNativeDeleteEvent(); + } + }, error => { + logger.error('Failed to subscribe RemoteDirectory:', this._uri, error); + this._watchSubscription = null; + }, () => { + // Nothing needs to be done if the root directory watch has ended. + logger.debug(`watchDirectory ended: ${this._uri}`); + this._watchSubscription = null; + }); + } + + _handleNativeChangeEvent() { this._emitter.emit('did-change'); } - _handleNativeDeleteEvent(): void { + _handleNativeDeleteEvent() { this._unsubscribeFromNativeChangeEvents(); if (!this._deleted) { this._deleted = true; @@ -154,128 +147,116 @@ export class RemoteDirectory { } } - _trackUnsubscription(subscription: IDisposable): IDisposable { - return new UniversalDisposable(() => { + _trackUnsubscription(subscription) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { subscription.dispose(); this._didRemoveSubscription(); }); } - _didRemoveSubscription(): void { + _didRemoveSubscription() { this._subscriptionCount--; if (this._subscriptionCount === 0) { return this._unsubscribeFromNativeChangeEvents(); } } - _unsubscribeFromNativeChangeEvents(): void { + _unsubscribeFromNativeChangeEvents() { if (this._watchSubscription) { try { this._watchSubscription.unsubscribe(); } catch (error) { - logger.warn( - 'RemoteDirectory failed to unsubscribe from native events:', - this._uri, - error.message, - ); + logger.warn('RemoteDirectory failed to unsubscribe from native events:', this._uri, error.message); } this._watchSubscription = null; } } - _joinLocalPath(name: string): string { - return this._isArchive - ? nuclideUri.archiveJoin(this._localPath, name) - : nuclideUri.join(this._localPath, name); + _joinLocalPath(name) { + return this._isArchive ? (_nuclideUri || _load_nuclideUri()).default.archiveJoin(this._localPath, name) : (_nuclideUri || _load_nuclideUri()).default.join(this._localPath, name); } - isFile(): boolean { + isFile() { return false; } - isDirectory(): boolean { + isDirectory() { return true; } - isRoot(): boolean { + isRoot() { return this._isRoot(this._localPath); } - exists(): Promise { + exists() { return this._getFileSystemService().exists(this._uri); } - existsSync(): boolean { + existsSync() { // As of Atom 1.12, `atom.project.addPath` checks for project existence. // We must return true to have our remote directories be addable. return true; } - _isRoot(filePath_: string): boolean { + _isRoot(filePath_) { let filePath = filePath_; - filePath = nuclideUri.normalize(filePath); - const parts = nuclideUri.parsePath(filePath); + filePath = (_nuclideUri || _load_nuclideUri()).default.normalize(filePath); + const parts = (_nuclideUri || _load_nuclideUri()).default.parsePath(filePath); return parts.root === filePath; } - getPath(): string { + getPath() { return this._uri; } - getLocalPath(): string { + getLocalPath() { return this._localPath; } - getRealPathSync(): string { + getRealPathSync() { // Remote paths should already be resolved. return this._uri; } - getBaseName(): string { - return nuclideUri.basename(this._localPath); + getBaseName() { + return (_nuclideUri || _load_nuclideUri()).default.basename(this._localPath); } - relativize(uri: string): string { - if (!nuclideUri.isRemote(uri || '')) { + relativize(uri) { + if (!(_nuclideUri || _load_nuclideUri()).default.isRemote(uri || '')) { return uri; } - const parsedUrl = nuclideUri.parse(uri); + const parsedUrl = (_nuclideUri || _load_nuclideUri()).default.parse(uri); if (parsedUrl.hostname !== this._host) { return uri; } - return nuclideUri.relative(this._localPath, parsedUrl.path); + return (_nuclideUri || _load_nuclideUri()).default.relative(this._localPath, parsedUrl.path); } - getParent(): RemoteDirectory { + getParent() { if (this.isRoot()) { return this; } else { - const uri = nuclideUri.createRemoteUri( - this._host, - nuclideUri.dirname(this._localPath), - ); + const uri = (_nuclideUri || _load_nuclideUri()).default.createRemoteUri(this._host, (_nuclideUri || _load_nuclideUri()).default.dirname(this._localPath)); return this._server.createDirectory(uri, this._hgRepositoryDescription); } } - getFile(filename: string): RemoteFile { - const uri = nuclideUri.createRemoteUri( - this._host, - this._joinLocalPath(filename), - ); + getFile(filename) { + const uri = (_nuclideUri || _load_nuclideUri()).default.createRemoteUri(this._host, this._joinLocalPath(filename)); return this._server.createFile(uri); } - getSubdirectory(dir: string): RemoteDirectory { - const uri = nuclideUri.createRemoteUri( - this._host, - this._joinLocalPath(dir), - ); + getSubdirectory(dir) { + const uri = (_nuclideUri || _load_nuclideUri()).default.createRemoteUri(this._host, this._joinLocalPath(dir)); return this._server.createDirectory(uri, this._hgRepositoryDescription); } - async create(): Promise { - invariant(!this._deleted, 'RemoteDirectory has been deleted'); + async create() { + if (!!this._deleted) { + throw new Error('RemoteDirectory has been deleted'); + } + const created = await this._getFileSystemService().mkdirp(this._uri); if (this._subscriptionCount > 0) { this._subscribeToNativeChangeEvents(); @@ -283,12 +264,12 @@ export class RemoteDirectory { return created; } - async delete(): Promise { + async delete() { await this._getFileSystemService().rmdir(this._uri); this._handleNativeDeleteEvent(); } - getEntriesSync(): Array { + getEntriesSync() { throw new Error('not implemented'); } @@ -299,13 +280,7 @@ export class RemoteDirectory { * Note: Although this function is `async`, it never rejects. Check whether the `error` argument * passed to `callback` is `null` to determine if there was an error. */ - async getEntries( - callback: ( - error: ?atom$GetEntriesError, - // $FlowFixMe(>=0.72.0) Flow suppress (T29189893) - entries: ?Array, - ) => any, - ): Promise { + async getEntries(callback) { let entries; try { entries = await this._getFileSystemService().readdirSorted(this._uri); @@ -314,57 +289,49 @@ export class RemoteDirectory { return; } - const directories: Array = []; + const directories = []; const files = []; entries.forEach(entry => { const [name, isFile, symlink] = entry; - const uri = nuclideUri.createRemoteUri( - this._host, - this._joinLocalPath(name), - ); + const uri = (_nuclideUri || _load_nuclideUri()).default.createRemoteUri(this._host, this._joinLocalPath(name)); if (isFile) { files.push(this._server.createFile(uri, symlink)); } else { - directories.push( - this._server.createDirectory( - uri, - this._hgRepositoryDescription, - symlink, - ), - ); + directories.push(this._server.createDirectory(uri, this._hgRepositoryDescription, symlink)); } }); callback(null, directories.concat(files)); } - contains(pathToCheck: ?string): boolean { - if (!nuclideUri.isRemote(pathToCheck || '')) { + contains(pathToCheck) { + if (!(_nuclideUri || _load_nuclideUri()).default.isRemote(pathToCheck || '')) { return false; } - return nuclideUri.contains(this.getPath(), pathToCheck || ''); + return (_nuclideUri || _load_nuclideUri()).default.contains(this.getPath(), pathToCheck || ''); } - off() { - // This method is part of the EmitterMixin used by Atom's local Directory, but not documented - // as part of the API - https://atom.io/docs/api/latest/Directory, - // However, it appears to be called in project.coffee by Atom. - } + off() {} + // This method is part of the EmitterMixin used by Atom's local Directory, but not documented + // as part of the API - https://atom.io/docs/api/latest/Directory, + // However, it appears to be called in project.coffee by Atom. + // A workaround before Atom 2.0: see ::getHgRepoInfo of main.js. - getHgRepositoryDescription(): ?HgRepositoryDescription { + getHgRepositoryDescription() { return this._hgRepositoryDescription; } - isSymbolicLink(): boolean { + isSymbolicLink() { return this._symlink; } - _getFileSystemService(): FileSystemService { + _getFileSystemService() { return this._getService('FileSystemService'); } - _getService(serviceName: string): any { + _getService(serviceName) { return this._server.getService(serviceName); } } +exports.RemoteDirectory = RemoteDirectory; \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/RemoteDirectoryPlaceholder.js b/pkg/nuclide-remote-connection/lib/RemoteDirectoryPlaceholder.js index 7179b5f64b..4ed64e252b 100644 --- a/pkg/nuclide-remote-connection/lib/RemoteDirectoryPlaceholder.js +++ b/pkg/nuclide-remote-connection/lib/RemoteDirectoryPlaceholder.js @@ -1,245 +1,253 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} -import nuclideUri from 'nuclide-commons/nuclideUri'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import Stream from 'stream'; +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _stream = _interopRequireDefault(require('stream')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A Directory object that returns the bare minimum that's required by Atom. * It always exists, to satisfy Atom's existence checks. * Should be removed ASAP once the remote connection is restored. */ -export default class RemoteDirectoryPlaceholder { - symlink = false; +class RemoteDirectoryPlaceholder { - _uri: string; - _hostname: ?string; - _path: string; + constructor(uri) { + this.symlink = false; - constructor(uri: string) { this._uri = uri; - const {hostname, path} = nuclideUri.parse(uri); + const { hostname, path } = (_nuclideUri || _load_nuclideUri()).default.parse(uri); this._hostname = hostname; this._path = path; } - create(mode?: number): Promise { + create(mode) { return Promise.resolve(true); } - onDidChange(callback: () => mixed): IDisposable { - return new UniversalDisposable(); + onDidChange(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - onDidChangeFiles(callback: () => mixed): IDisposable { - return new UniversalDisposable(); + onDidChangeFiles(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - isFile(): boolean { + isFile() { return false; } - isDirectory(): boolean { + isDirectory() { return true; } - isRoot(): boolean { + isRoot() { return this._path === '/'; } - exists(): Promise { + exists() { return Promise.resolve(true); } - existsSync(): boolean { + existsSync() { return true; } - getPath(): string { + getPath() { return this._uri; } - getBaseName(): string { - return nuclideUri.basename(this._uri); + getBaseName() { + return (_nuclideUri || _load_nuclideUri()).default.basename(this._uri); } - relativize(uri: string): string { + relativize(uri) { if (!uri) { return uri; } - const parsedUrl = nuclideUri.parse(uri); + const parsedUrl = (_nuclideUri || _load_nuclideUri()).default.parse(uri); if (parsedUrl.hostname !== this._hostname) { return uri; } - return nuclideUri.relative(this._path, parsedUrl.path); + return (_nuclideUri || _load_nuclideUri()).default.relative(this._path, parsedUrl.path); } - onDidRename(callback: () => void): IDisposable { - return new UniversalDisposable(); + onDidRename(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - onDidDelete(callback: () => void): IDisposable { - return new UniversalDisposable(); + onDidDelete(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - getParent(): RemoteDirectoryPlaceholder { - return new RemoteDirectoryPlaceholder(nuclideUri.dirname(this._uri)); + getParent() { + return new RemoteDirectoryPlaceholder((_nuclideUri || _load_nuclideUri()).default.dirname(this._uri)); } - getFile(filename: string): RemoteFilePlaceholder { - return new RemoteFilePlaceholder(nuclideUri.join(this._uri, filename)); + getFile(filename) { + return new RemoteFilePlaceholder((_nuclideUri || _load_nuclideUri()).default.join(this._uri, filename)); } - getSubdirectory(dirname: string): RemoteDirectoryPlaceholder { - return new RemoteDirectoryPlaceholder(nuclideUri.join(this._uri, dirname)); + getSubdirectory(dirname) { + return new RemoteDirectoryPlaceholder((_nuclideUri || _load_nuclideUri()).default.join(this._uri, dirname)); } - getEntries( - callback: ( - error: ?atom$GetEntriesError, - // $FlowFixMe - entries: ?Array, - ) => mixed, - ): void { + getEntries(callback) { callback(null, []); } - contains(path: ?string): boolean { + contains(path) { if (path == null) { return false; } - return nuclideUri.contains(this._uri, path); + return (_nuclideUri || _load_nuclideUri()).default.contains(this._uri, path); } } +exports.default = RemoteDirectoryPlaceholder; /** + * In contrast to the directory placeholders, the file placeholders never exist. + * Atom's Git integration, for example, checks for the existence of .git files. + */ /** - * In contrast to the directory placeholders, the file placeholders never exist. - * Atom's Git integration, for example, checks for the existence of .git files. + * 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. + * + * + * @format */ -class RemoteFilePlaceholder implements atom$Fileish { - _uri: string; - constructor(uri: string) { +class RemoteFilePlaceholder { + + constructor(uri) { this._uri = uri; } - onDidChange(callback: () => mixed): IDisposable { - return new UniversalDisposable(); + onDidChange(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - onDidRename(callback: () => mixed): IDisposable { - return new UniversalDisposable(); + onDidRename(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - onDidDelete(callback: () => mixed): IDisposable { - return new UniversalDisposable(); + onDidDelete(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - onWillThrowWatchError(callback: () => mixed): IDisposable { - return new UniversalDisposable(); + onWillThrowWatchError(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - isFile(): boolean { + isFile() { return true; } - isDirectory(): boolean { + isDirectory() { return false; } - exists(): Promise { + exists() { return Promise.resolve(false); } - existsSync(): boolean { + existsSync() { return false; } - getDigestSync(): string { + getDigestSync() { return ''; } - async getDigest(): Promise { + async getDigest() { return Promise.resolve(''); } - setEncoding(encoding: string) {} + setEncoding(encoding) {} - getEncoding(): ?string { + getEncoding() { return null; } - setPath(uri: string): void { + setPath(uri) { this._uri = uri; } - getPath(): string { + getPath() { return this._uri; } - getRealPathSync(): string { + getRealPathSync() { return this._uri; } - getRealPath(): Promise { + getRealPath() { return Promise.resolve(this._uri); } - getBaseName(): string { - return nuclideUri.basename(this._uri); + getBaseName() { + return (_nuclideUri || _load_nuclideUri()).default.basename(this._uri); } - create(): Promise { + create() { return Promise.resolve(true); } - delete(): Promise { + delete() { return Promise.resolve(); } - copy(newPath: string): Promise { + copy(newPath) { return Promise.resolve(true); } - read(flushCache?: boolean): Promise { + read(flushCache) { return Promise.resolve(''); } - readSync(flushCache: boolean): string { + readSync(flushCache) { return ''; } - write(text: string): Promise { + write(text) { return Promise.resolve(); } - getParent(): RemoteDirectoryPlaceholder { - return new RemoteDirectoryPlaceholder(nuclideUri.dirname(this._uri)); + getParent() { + return new RemoteDirectoryPlaceholder((_nuclideUri || _load_nuclideUri()).default.dirname(this._uri)); } - isSymbolicLink(): boolean { + isSymbolicLink() { return false; } - createReadStream(): stream$Readable { - const stream = new Stream.Readable({ + createReadStream() { + const stream = new _stream.default.Readable({ read(size) { stream.push(null); - }, + } }); return stream; } - createWriteStream(): stream$Writable { + createWriteStream() { throw new Error('Cannot write to a RemoteFilePlaceholder'); } -} +} \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/RemoteFile.js b/pkg/nuclide-remote-connection/lib/RemoteFile.js index 72c51dfff4..22c0c26d78 100644 --- a/pkg/nuclide-remote-connection/lib/RemoteFile.js +++ b/pkg/nuclide-remote-connection/lib/RemoteFile.js @@ -1,3 +1,49 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RemoteFile = undefined; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _passesGK; + +function _load_passesGK() { + return _passesGK = _interopRequireDefault(require('../../commons-node/passesGK')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _crypto = _interopRequireDefault(require('crypto')); + +var _eventKit; + +function _load_eventKit() { + return _eventKit = require('event-kit'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _stream = _interopRequireDefault(require('stream')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-remote-connection'); + +/* Mostly implements https://atom.io/docs/api/latest/File */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,48 +51,16 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {ServerConnection} from './ServerConnection'; -import type {RemoteDirectory} from './RemoteDirectory'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import typeof * as FileSystemService from '../../nuclide-server/lib/services/FileSystemService'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import invariant from 'assert'; -import passesGK from '../../commons-node/passesGK'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import crypto from 'crypto'; -import {Emitter} from 'event-kit'; -import {getLogger} from 'log4js'; -import Stream from 'stream'; - -const logger = getLogger('nuclide-remote-connection'); +class RemoteFile { -/* Mostly implements https://atom.io/docs/api/latest/File */ -export class RemoteFile { - _deleted: boolean; - _emitter: Emitter; - _encoding: ?string; - _localPath: string; - _path: NuclideUri; - _realpath: ?string; - _server: ServerConnection; - _subscriptionCount: number; - _watchSubscription: ?rxjs$ISubscription; - _digest: ?string; - _symlink: boolean; - - constructor( - server: ServerConnection, - remotePath: NuclideUri, - symlink: boolean = false, - ) { + constructor(server, remotePath, symlink = false) { this._server = server; this.setPath(remotePath); - this._emitter = new Emitter(); + this._emitter = new (_eventKit || _load_eventKit()).Emitter(); this._subscriptionCount = 0; this._deleted = false; this._symlink = symlink; @@ -57,95 +71,81 @@ export class RemoteFile { this._unsubscribeFromNativeChangeEvents(); } - onDidChange(callback: () => mixed): IDisposable { + onDidChange(callback) { this._willAddSubscription(); return this._trackUnsubscription(this._emitter.on('did-change', callback)); } - onDidRename(callback: () => mixed): IDisposable { + onDidRename(callback) { // TODO: this is not supported by the Watchman API. - return new UniversalDisposable(); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - onDidDelete(callback: () => mixed): IDisposable { + onDidDelete(callback) { this._willAddSubscription(); return this._trackUnsubscription(this._emitter.on('did-delete', callback)); } - _willAddSubscription(): void { + _willAddSubscription() { this._subscriptionCount++; this._subscribeToNativeChangeEvents(); } - _subscribeToNativeChangeEvents(): void { + _subscribeToNativeChangeEvents() { if (this._watchSubscription) { return; } const watchStream = this._server.getFileWatch(this._path); - this._watchSubscription = watchStream.subscribe( - watchUpdate => { - // This only happens after a `setPath` and subsequent file rename. - // Getting this message signifies that the new file should be ready for watching. - if (watchUpdate.path !== this._path) { - logger.debug('watchFile renamed:', this._path); - this._unsubscribeFromNativeChangeEvents(); - this._subscribeToNativeChangeEvents(); - return; - } - logger.debug('watchFile update:', watchUpdate); - switch (watchUpdate.type) { - case 'change': - return this._handleNativeChangeEvent(); - case 'delete': - return this._handleNativeDeleteEvent(); - } - }, - error => { - // In the case of new files, it's normal for the remote file to not exist yet. - if (error.code !== 'ENOENT') { - logger.error('Failed to subscribe RemoteFile:', this._path, error); - } - this._watchSubscription = null; - }, - () => { - // Nothing needs to be done if the root directory watch has ended. - logger.debug(`watchFile ended: ${this._path}`); - this._watchSubscription = null; - }, - ); + this._watchSubscription = watchStream.subscribe(watchUpdate => { + // This only happens after a `setPath` and subsequent file rename. + // Getting this message signifies that the new file should be ready for watching. + if (watchUpdate.path !== this._path) { + logger.debug('watchFile renamed:', this._path); + this._unsubscribeFromNativeChangeEvents(); + this._subscribeToNativeChangeEvents(); + return; + } + logger.debug('watchFile update:', watchUpdate); + switch (watchUpdate.type) { + case 'change': + return this._handleNativeChangeEvent(); + case 'delete': + return this._handleNativeDeleteEvent(); + } + }, error => { + // In the case of new files, it's normal for the remote file to not exist yet. + if (error.code !== 'ENOENT') { + logger.error('Failed to subscribe RemoteFile:', this._path, error); + } + this._watchSubscription = null; + }, () => { + // Nothing needs to be done if the root directory watch has ended. + logger.debug(`watchFile ended: ${this._path}`); + this._watchSubscription = null; + }); // No need to wait for that async check. this._checkWatchOutOfOpenDirectories(); } - async _checkWatchOutOfOpenDirectories(): Promise { + async _checkWatchOutOfOpenDirectories() { const isPathInOpenDirectories = atom.project.contains(this._path); - if ( - !isPathInOpenDirectories && - (await passesGK('nuclide_watch_warn_unmanaged_file')) - ) { - atom.notifications.addWarning( - `Couldn't watch remote file \`${nuclideUri.basename( - this._path, - )}\` for changes!`, - { - detail: - "Updates to the file outside Nuclide won't reload automatically\n" + - "Please add the file's project directory to Nuclide\n", - dismissable: true, - }, - ); + if (!isPathInOpenDirectories && (await (0, (_passesGK || _load_passesGK()).default)('nuclide_watch_warn_unmanaged_file'))) { + atom.notifications.addWarning(`Couldn't watch remote file \`${(_nuclideUri || _load_nuclideUri()).default.basename(this._path)}\` for changes!`, { + detail: "Updates to the file outside Nuclide won't reload automatically\n" + "Please add the file's project directory to Nuclide\n", + dismissable: true + }); } } - _handleNativeChangeEvent(): Promise { + _handleNativeChangeEvent() { // Don't bother checking the file - this can be very expensive. this._emitter.emit('did-change'); return Promise.resolve(); } - _handleNativeDeleteEvent(): void { + _handleNativeDeleteEvent() { this._unsubscribeFromNativeChangeEvents(); if (!this._deleted) { this._deleted = true; @@ -157,50 +157,48 @@ export class RemoteFile { * Return a new Disposable that upon dispose, will remove the bound watch subscription. * When the number of subscriptions reach 0, the file is unwatched. */ - _trackUnsubscription(subscription: IDisposable): IDisposable { - return new UniversalDisposable(() => { + _trackUnsubscription(subscription) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { subscription.dispose(); this._didRemoveSubscription(); }); } - _didRemoveSubscription(): void { + _didRemoveSubscription() { this._subscriptionCount--; if (this._subscriptionCount === 0) { this._unsubscribeFromNativeChangeEvents(); } } - _unsubscribeFromNativeChangeEvents(): void { + _unsubscribeFromNativeChangeEvents() { if (this._watchSubscription) { this._watchSubscription.unsubscribe(); this._watchSubscription = null; } } - onWillThrowWatchError( - callback: (watchError: {error: Error, handle: () => void}) => mixed, - ): IDisposable { + onWillThrowWatchError(callback) { return this._emitter.on('will-throw-watch-error', callback); } - isFile(): boolean { + isFile() { return true; } - isDirectory(): boolean { + isDirectory() { return false; } - exists(): Promise { + exists() { return this._getFileSystemService().exists(this._path); } - existsSync(): boolean { + existsSync() { return true; } - getDigestSync(): string { + getDigestSync() { // flowlint-next-line sketchy-null-string:off if (!this._digest) { // File's `getDigestSync()` calls `readSync()`, which we don't implement. @@ -208,67 +206,83 @@ export class RemoteFile { this._setDigest(''); } // flowlint-next-line sketchy-null-string:off - invariant(this._digest); + + if (!this._digest) { + throw new Error('Invariant violation: "this._digest"'); + } + return this._digest; } - async getDigest(): Promise { + async getDigest() { // flowlint-next-line sketchy-null-string:off if (this._digest) { return this._digest; } await this.read(); // flowlint-next-line sketchy-null-string:off - invariant(this._digest); + + if (!this._digest) { + throw new Error('Invariant violation: "this._digest"'); + } + return this._digest; } - _setDigest(contents: string) { - const hash = crypto.createHash('sha1').update(contents || ''); - invariant(hash); + _setDigest(contents) { + const hash = _crypto.default.createHash('sha1').update(contents || ''); + + if (!hash) { + throw new Error('Invariant violation: "hash"'); + } + this._digest = hash.digest('hex'); } - setEncoding(encoding: string) { + setEncoding(encoding) { this._encoding = encoding; } - getEncoding(): ?string { + getEncoding() { return this._encoding; } - setPath(remotePath: NuclideUri): void { - const {path: localPath} = nuclideUri.parse(remotePath); + setPath(remotePath) { + const { path: localPath } = (_nuclideUri || _load_nuclideUri()).default.parse(remotePath); this._localPath = localPath; this._path = remotePath; } - getPath(): string { + getPath() { return this._path; } - getLocalPath(): string { + getLocalPath() { return this._localPath; } - getRealPathSync(): string { + getRealPathSync() { // flowlint-next-line sketchy-null-string:off return this._realpath || this._path; } - async getRealPath(): Promise { + async getRealPath() { if (this._realpath == null) { this._realpath = await this._getFileSystemService().realpath(this._path); } - invariant(this._realpath); + + if (!this._realpath) { + throw new Error('Invariant violation: "this._realpath"'); + } + return this._realpath; } - getBaseName(): string { - return nuclideUri.basename(this._path); + getBaseName() { + return (_nuclideUri || _load_nuclideUri()).default.basename(this._path); } - async create(): Promise { + async create() { const wasCreated = await this._getFileSystemService().newFile(this._path); if (this._subscriptionCount > 0) { this._subscribeToNativeChangeEvents(); @@ -276,7 +290,7 @@ export class RemoteFile { return wasCreated; } - async delete(): Promise { + async delete() { try { await this._getFileSystemService().unlink(this._path); this._handleNativeDeleteEvent(); @@ -287,16 +301,13 @@ export class RemoteFile { } } - async copy(newPath: NuclideUri): Promise { - const wasCopied = await this._getFileSystemService().copy( - this._path, - newPath, - ); + async copy(newPath) { + const wasCopied = await this._getFileSystemService().copy(this._path, newPath); this._subscribeToNativeChangeEvents(); return wasCopied; } - async read(flushCache?: boolean): Promise { + async read(flushCache) { const data = await this._getFileSystemService().readFile(this._path); const contents = data.toString(); this._setDigest(contents); @@ -304,11 +315,11 @@ export class RemoteFile { return contents; } - readSync(flushcache: boolean): Promise { + readSync(flushcache) { throw new Error('readSync is not supported in RemoteFile'); } - async write(text: string): Promise { + async write(text) { const previouslyExisted = await this.exists(); await this._getFileSystemService().writeFile(this._path, text); if (!previouslyExisted && this._subscriptionCount > 0) { @@ -316,35 +327,32 @@ export class RemoteFile { } } - async writeWithPermission(text: string, permission: number): Promise { + async writeWithPermission(text, permission) { const previouslyExisted = await this.exists(); await this._getFileSystemService().writeFile(this._path, text, { - mode: permission, + mode: permission }); if (!previouslyExisted && this._subscriptionCount > 0) { this._subscribeToNativeChangeEvents(); } } - getParent(): RemoteDirectory { - const directoryPath = nuclideUri.dirname(this._path); + getParent() { + const directoryPath = (_nuclideUri || _load_nuclideUri()).default.dirname(this._path); const remoteConnection = this._server.getRemoteConnectionForUri(this._path); - const hgRepositoryDescription = - remoteConnection != null - ? remoteConnection.getHgRepositoryDescription() - : null; + const hgRepositoryDescription = remoteConnection != null ? remoteConnection.getHgRepositoryDescription() : null; return this._server.createDirectory(directoryPath, hgRepositoryDescription); } - isSymbolicLink(): boolean { + isSymbolicLink() { return this._symlink; } - _getFileSystemService(): FileSystemService { + _getFileSystemService() { return this._getService('FileSystemService'); } - _getService(serviceName: string): any { + _getService(serviceName) { return this._server.getService(serviceName); } @@ -353,27 +361,24 @@ export class RemoteFile { * multiple RPC calls can take much longer than just fetching the entire file. * This stream just fetches the entire file contents for now. */ - createReadStream(): stream$Readable { + createReadStream() { const path = this._path; const service = this._getFileSystemService(); // push() triggers another read(), so make sure we don't read the file twice. let pushed = false; - const stream = new Stream.Readable({ + const stream = new _stream.default.Readable({ read(size) { if (pushed) { return; } - service.readFile(path).then( - buffer => { - pushed = true; - stream.push(buffer); - stream.push(null); - }, - err => { - stream.emit('error', err); - }, - ); - }, + service.readFile(path).then(buffer => { + pushed = true; + stream.push(buffer); + stream.push(null); + }, err => { + stream.emit('error', err); + }); + } }); return stream; } @@ -382,34 +387,33 @@ export class RemoteFile { * As with createReadStream, it's potentially very inefficient to write remotely in multiple * chunks. This stream just accumulates the data locally and flushes it all at once. */ - createWriteStream(): stream$Writable { + createWriteStream() { const writeData = []; let writeLength = 0; - const stream = new Stream.Writable({ + const stream = new _stream.default.Writable({ write(chunk, encoding, next) { // `chunk` may be mutated by the caller, so make sure it's copied. writeData.push(Buffer.from(chunk)); writeLength += chunk.length; next(); - }, + } }); const originalEnd = stream.end; // TODO: (hansonw) T20364274 Override final() in Node 8 and above. // For now, we'll overwrite the end function manually. // $FlowIgnore stream.end = cb => { - invariant(cb instanceof Function, 'end() called without a callback'); - this._getFileSystemService() - .writeFileBuffer(this._path, Buffer.concat(writeData, writeLength)) - .then( - () => cb(), - err => { - stream.emit('error', err); - cb(); - }, - ); + if (!(cb instanceof Function)) { + throw new Error('end() called without a callback'); + } + + this._getFileSystemService().writeFileBuffer(this._path, Buffer.concat(writeData, writeLength)).then(() => cb(), err => { + stream.emit('error', err); + cb(); + }); originalEnd.call(stream); }; return stream; } } +exports.RemoteFile = RemoteFile; \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/ServerConnection.js b/pkg/nuclide-remote-connection/lib/ServerConnection.js index c6a080e8f5..e762ca8378 100644 --- a/pkg/nuclide-remote-connection/lib/ServerConnection.js +++ b/pkg/nuclide-remote-connection/lib/ServerConnection.js @@ -1,76 +1,159 @@ -/** - * 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 - */ - -import type {XhrConnectionHeartbeat} from 'big-dig/src/client/XhrConnectionHeartbeat'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {BigDigClient} from 'big-dig/src/client'; -import type {Transport} from '../../nuclide-rpc'; -import type {RemoteConnection} from './RemoteConnection'; -import type {OnHeartbeatErrorCallback} from '../../nuclide-remote-connection/lib/ConnectionHealthNotifier.js'; -import type {HgRepositoryDescription} from '../../nuclide-source-control-helpers'; -import {SERVICE_FRAMEWORK3_PROTOCOL} from '../../nuclide-rpc/lib/config'; -import typeof * as InfoService from '../../nuclide-server/lib/services/InfoService'; -import typeof * as FileWatcherService from '../../nuclide-filewatcher-rpc'; -import type {WatchResult} from '../../nuclide-filewatcher-rpc'; - -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import invariant from 'assert'; -import {RpcConnection} from '../../nuclide-rpc'; -import {Observable} from 'rxjs'; -import servicesConfig from '../../nuclide-server/lib/servicesConfig'; -import { - setConnectionConfig, - clearConnectionConfig, - SERVER_CONFIG_REQUEST_EVENT, - SERVER_CONFIG_RESPONSE_EVENT, -} from './RemoteConnectionConfigurationManager'; -import {ConnectionHealthNotifier} from './ConnectionHealthNotifier'; -import {RemoteFile} from './RemoteFile'; -import {RemoteDirectory} from './RemoteDirectory'; -import {getAtomSideMarshalers} from '../../nuclide-marshalers-atom'; - -import {Emitter} from 'event-kit'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {timeoutPromise} from 'nuclide-commons/promise'; -import SharedObservableCache from '../../commons-node/SharedObservableCache'; - -import {ReliableSocket} from 'big-dig/src/socket/ReliableSocket'; -import {HEARTBEAT_CHANNEL} from '../../nuclide-server/lib/NuclideServer'; -import {protocolLogger} from '../../nuclide-server/lib/utils'; -import {getLogger} from 'log4js'; -import {getVersion} from '../../nuclide-version'; -import lookupPreferIpv6 from './lookup-prefer-ip-v6'; -import createBigDigRpcClient from './createBigDigRpcClient'; - -import electron from 'electron'; - -const logger = getLogger('nuclide-remote-connection'); -const remote = electron.remote; -const ipc = electron.ipcRenderer; - -invariant(remote); -invariant(ipc); - -export type ServerConnectionVersion = 1 | 2; -export const BIG_DIG_VERSION: ServerConnectionVersion = 2; - -export type ServerConnectionConfiguration = { - host: string, // host nuclide server is running on. - port: number, // port to connect to. - family?: 4 | 6, // ipv4 or ipv6? - certificateAuthorityCertificate?: Buffer, // certificate of certificate authority. - clientCertificate?: Buffer, // client certificate for https connection. - clientKey?: Buffer, // key for https connection. - version?: ServerConnectionVersion, -}; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.__test__ = exports.ServerConnection = exports.BIG_DIG_VERSION = undefined; + +var _config; + +function _load_config() { + return _config = require('../../nuclide-rpc/lib/config'); +} + +var _event; + +function _load_event() { + return _event = require('../../../modules/nuclide-commons/event'); +} + +var _nuclideRpc; + +function _load_nuclideRpc() { + return _nuclideRpc = require('../../nuclide-rpc'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _servicesConfig; + +function _load_servicesConfig() { + return _servicesConfig = _interopRequireDefault(require('../../nuclide-server/lib/servicesConfig')); +} + +var _RemoteConnectionConfigurationManager; + +function _load_RemoteConnectionConfigurationManager() { + return _RemoteConnectionConfigurationManager = require('./RemoteConnectionConfigurationManager'); +} + +var _ConnectionHealthNotifier; + +function _load_ConnectionHealthNotifier() { + return _ConnectionHealthNotifier = require('./ConnectionHealthNotifier'); +} + +var _RemoteFile; + +function _load_RemoteFile() { + return _RemoteFile = require('./RemoteFile'); +} + +var _RemoteDirectory; + +function _load_RemoteDirectory() { + return _RemoteDirectory = require('./RemoteDirectory'); +} + +var _nuclideMarshalersAtom; + +function _load_nuclideMarshalersAtom() { + return _nuclideMarshalersAtom = require('../../nuclide-marshalers-atom'); +} + +var _eventKit; + +function _load_eventKit() { + return _eventKit = require('event-kit'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _SharedObservableCache; + +function _load_SharedObservableCache() { + return _SharedObservableCache = _interopRequireDefault(require('../../commons-node/SharedObservableCache')); +} + +var _ReliableSocket; + +function _load_ReliableSocket() { + return _ReliableSocket = require('../../../modules/big-dig/src/socket/ReliableSocket'); +} + +var _NuclideServer; + +function _load_NuclideServer() { + return _NuclideServer = require('../../nuclide-server/lib/NuclideServer'); +} + +var _utils; + +function _load_utils() { + return _utils = require('../../nuclide-server/lib/utils'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _nuclideVersion; + +function _load_nuclideVersion() { + return _nuclideVersion = require('../../nuclide-version'); +} + +var _lookupPreferIpV; + +function _load_lookupPreferIpV() { + return _lookupPreferIpV = _interopRequireDefault(require('./lookup-prefer-ip-v6')); +} + +var _createBigDigRpcClient; + +function _load_createBigDigRpcClient() { + return _createBigDigRpcClient = _interopRequireDefault(require('./createBigDigRpcClient')); +} + +var _electron = _interopRequireDefault(require('electron')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-remote-connection'); /** + * 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. + * + * + * @format + */ + +const remote = _electron.default.remote; +const ipc = _electron.default.ipcRenderer; + +if (!remote) { + throw new Error('Invariant violation: "remote"'); +} + +if (!ipc) { + throw new Error('Invariant violation: "ipc"'); +} + +const BIG_DIG_VERSION = exports.BIG_DIG_VERSION = 2; // ServerConnection represents the client side of a connection to a remote machine. // There can be at most one connection to a given remote machine at a time. Clients should @@ -81,23 +164,9 @@ export type ServerConnectionConfiguration = { // // A ServerConnection keeps a list of RemoteConnections - one for each open directory on the remote // machine. Once all RemoteConnections have been closed, then the ServerConnection will close. -export class ServerConnection { - _config: ServerConnectionConfiguration; - _closed: boolean; - _healthNotifier: ?ConnectionHealthNotifier; - _heartbeat: ?XhrConnectionHeartbeat; - _client: ?RpcConnection; - _connections: Array; - _fileWatches: SharedObservableCache; - _directoryWatches: SharedObservableCache; - _bigDigClient: ?BigDigClient; - - static _connections: Map = new Map(); - static _emitter = new Emitter(); - - static async getOrCreate( - config: ServerConnectionConfiguration, - ): Promise { +class ServerConnection { + + static async getOrCreate(config) { const existingConnection = ServerConnection.getByHostname(config.host); if (existingConnection != null) { return existingConnection; @@ -113,30 +182,28 @@ export class ServerConnection { } } - static cancelConnection(hostname: string): void { + static cancelConnection(hostname) { ServerConnection._emitter.emit('did-cancel', hostname); } // WARNING: This shuts down all Nuclide servers _without_ closing their // RemoteConnections first! This is extremely unsafe and // should only be used to forcibly kill Nuclide servers before restarting. - static forceShutdownAllServers(): Promise { + static forceShutdownAllServers() { return ServerConnection.closeAll(true); } // WARNING: This shuts down all Nuclide servers _without_ closing their // RemoteConnections first! This is extremely unsafe and // should only be Called during shutdown, reload, or before autoupdate. - static async closeAll(shutdown: boolean): Promise { - await Promise.all( - Array.from(ServerConnection._connections).map(([_, connection]) => { - return connection._closeServerConnection(shutdown); - }), - ); + static async closeAll(shutdown) { + await Promise.all(Array.from(ServerConnection._connections).map(([_, connection]) => { + return connection._closeServerConnection(shutdown); + })); } // Do NOT call this from outside this class. Use ServerConnection.getOrCreate() instead. - constructor(config: ServerConnectionConfiguration) { + constructor(config) { this._config = config; this._closed = false; this._healthNotifier = null; @@ -144,45 +211,38 @@ export class ServerConnection { this._bigDigClient = null; this._heartbeat = null; this._connections = []; - this._fileWatches = new SharedObservableCache(path => { - const fileWatcherService: FileWatcherService = this.getService( - 'FileWatcherService', - ); + this._fileWatches = new (_SharedObservableCache || _load_SharedObservableCache()).default(path => { + const fileWatcherService = this.getService('FileWatcherService'); return fileWatcherService.watchFile(path).refCount(); }); - this._directoryWatches = new SharedObservableCache(path => { - const fileWatcherService: FileWatcherService = this.getService( - 'FileWatcherService', - ); + this._directoryWatches = new (_SharedObservableCache || _load_SharedObservableCache()).default(path => { + const fileWatcherService = this.getService('FileWatcherService'); return fileWatcherService.watchDirectory(path).refCount(); }); - ipc.on(SERVER_CONFIG_REQUEST_EVENT, (event, host, id) => { - logger.info( - `received request for server config for ${host} from window ${id}`, - ); + ipc.on((_RemoteConnectionConfigurationManager || _load_RemoteConnectionConfigurationManager()).SERVER_CONFIG_REQUEST_EVENT, (event, host, id) => { + logger.info(`received request for server config for ${host} from window ${id}`); let response = null; if (host === this._config.host) { logger.info(`found the server config for ${host}, sending it via ipc`); response = this._config; } - const window = remote.BrowserWindow.getAllWindows().filter( - win => win.id === id, - )[0]; - invariant(window); - window.send(SERVER_CONFIG_RESPONSE_EVENT, response); + const window = remote.BrowserWindow.getAllWindows().filter(win => win.id === id)[0]; + + if (!window) { + throw new Error('Invariant violation: "window"'); + } + + window.send((_RemoteConnectionConfigurationManager || _load_RemoteConnectionConfigurationManager()).SERVER_CONFIG_RESPONSE_EVENT, response); }); } - static async _createInsecureConnectionForTesting( - cwd: string, - port: number, - ): Promise { + static async _createInsecureConnectionForTesting(cwd, port) { const config = { host: 'localhost', port, - cwd, + cwd }; const connection = new ServerConnection(config); await connection.initialize(); @@ -190,70 +250,59 @@ export class ServerConnection { } _monitorConnectionHeartbeat() { - invariant(this._healthNotifier == null); - this._healthNotifier = new ConnectionHealthNotifier( - this._config.host, - this._config.port, - this.getHeartbeat(), - ); + if (!(this._healthNotifier == null)) { + throw new Error('Invariant violation: "this._healthNotifier == null"'); + } + + this._healthNotifier = new (_ConnectionHealthNotifier || _load_ConnectionHealthNotifier()).ConnectionHealthNotifier(this._config.host, this._config.port, this.getHeartbeat()); } - setOnHeartbeatError(onHeartbeatError: OnHeartbeatErrorCallback): void { - invariant(this._healthNotifier != null); + setOnHeartbeatError(onHeartbeatError) { + if (!(this._healthNotifier != null)) { + throw new Error('Invariant violation: "this._healthNotifier != null"'); + } + this._healthNotifier.setOnHeartbeatError(onHeartbeatError); } - getUriOfRemotePath(remotePath: string): string { + getUriOfRemotePath(remotePath) { return `nuclide://${this.getRemoteHostname()}${remotePath}`; } - createDirectory( - uri: NuclideUri, - hgRepositoryDescription: ?HgRepositoryDescription, - symlink: boolean = false, - ): RemoteDirectory { - let {path} = nuclideUri.parse(uri); - path = nuclideUri.normalize(path); - return new RemoteDirectory(this, this.getUriOfRemotePath(path), symlink, { - hgRepositoryDescription, + createDirectory(uri, hgRepositoryDescription, symlink = false) { + let { path } = (_nuclideUri || _load_nuclideUri()).default.parse(uri); + path = (_nuclideUri || _load_nuclideUri()).default.normalize(path); + return new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory(this, this.getUriOfRemotePath(path), symlink, { + hgRepositoryDescription }); } - createFile(uri: NuclideUri, symlink: boolean = false): RemoteFile { - let {path} = nuclideUri.parse(uri); - path = nuclideUri.normalize(path); - return new RemoteFile(this, this.getUriOfRemotePath(path), symlink); + createFile(uri, symlink = false) { + let { path } = (_nuclideUri || _load_nuclideUri()).default.parse(uri); + path = (_nuclideUri || _load_nuclideUri()).default.normalize(path); + return new (_RemoteFile || _load_RemoteFile()).RemoteFile(this, this.getUriOfRemotePath(path), symlink); } - createFileAsDirectory( - uri: NuclideUri, - hgRepositoryDescription: ?HgRepositoryDescription, - symlink: boolean = false, - ): RemoteDirectory { - let {path} = nuclideUri.parse(uri); - path = nuclideUri.normalize(path); - return new RemoteDirectory(this, this.getUriOfRemotePath(path), symlink, { - ...hgRepositoryDescription, - ...{isArchive: true}, - }); + createFileAsDirectory(uri, hgRepositoryDescription, symlink = false) { + let { path } = (_nuclideUri || _load_nuclideUri()).default.parse(uri); + path = (_nuclideUri || _load_nuclideUri()).default.normalize(path); + return new (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory(this, this.getUriOfRemotePath(path), symlink, Object.assign({}, hgRepositoryDescription, { isArchive: true })); } - getFileWatch(path: string): Observable { + getFileWatch(path) { return this._fileWatches.get(path); } - getDirectoryWatch(path: string): Observable { + getDirectoryWatch(path) { return this._directoryWatches.get(path); } - async initialize(): Promise { + async initialize() { await this._startRpc(); - const clientVersion = getVersion(); + const clientVersion = (0, (_nuclideVersion || _load_nuclideVersion()).getVersion)(); function throwVersionMismatch(version) { - const err = new Error( - `Version mismatch. Client at ${clientVersion} while server at ${version}.`, - ); + const err = new Error(`Version mismatch. Client at ${clientVersion} while server at ${version}.`); err.name = 'VersionMismatchError'; throw err; } @@ -270,10 +319,7 @@ export class ServerConnection { } // Do another version check over the RPC framework. - const [serverVersion, ip] = await Promise.all([ - this._getInfoService().getServerVersion(), - lookupPreferIpv6(this._config.host), - ]); + const [serverVersion, ip] = await Promise.all([this._getInfoService().getServerVersion(), (0, (_lookupPreferIpV || _load_lookupPreferIpV()).default)(this._config.host)]); if (clientVersion !== serverVersion) { throwVersionMismatch(serverVersion); } @@ -281,11 +327,11 @@ export class ServerConnection { this._monitorConnectionHeartbeat(); ServerConnection._connections.set(this.getRemoteHostname(), this); - await setConnectionConfig(this._config, ip.address); + await (0, (_RemoteConnectionConfigurationManager || _load_RemoteConnectionConfigurationManager()).setConnectionConfig)(this._config, ip.address); ServerConnection._emitter.emit('did-add', this); } - close(): void { + close() { if (this._closed) { return; } @@ -312,39 +358,36 @@ export class ServerConnection { this._healthNotifier.dispose(); } - ipc.removeAllListeners(SERVER_CONFIG_REQUEST_EVENT); + ipc.removeAllListeners((_RemoteConnectionConfigurationManager || _load_RemoteConnectionConfigurationManager()).SERVER_CONFIG_REQUEST_EVENT); } - getClient(): RpcConnection { - invariant( - !this._closed && this._client != null, - 'Server connection has been closed.', - ); + getClient() { + if (!(!this._closed && this._client != null)) { + throw new Error('Server connection has been closed.'); + } + return this._client; } - getBigDigClient(): BigDigClient { - invariant( - !this._closed && this._bigDigClient != null, - 'Server connection has been closed', - ); + getBigDigClient() { + if (!(!this._closed && this._bigDigClient != null)) { + throw new Error('Server connection has been closed'); + } return this._bigDigClient; } - getHeartbeat(): XhrConnectionHeartbeat { - invariant( - !this._closed && this._client != null && this._heartbeat != null, - 'Server connection has been closed.', - ); + getHeartbeat() { + if (!(!this._closed && this._client != null && this._heartbeat != null)) { + throw new Error('Server connection has been closed.'); + } + return this._heartbeat; } - async _startRpc(): Promise { + async _startRpc() { if (this._config.version === BIG_DIG_VERSION) { - const {bigDigClient, rpcConnection} = await createBigDigRpcClient( - this._config, - ); + const { bigDigClient, rpcConnection } = await (0, (_createBigDigRpcClient || _load_createBigDigRpcClient()).default)(this._config); this._client = rpcConnection; this._bigDigClient = bigDigClient; this._heartbeat = bigDigClient.getHeartbeat(); @@ -356,80 +399,69 @@ export class ServerConnection { // Use https if we have key, cert, and ca if (this._isSecure()) { - invariant(this._config.certificateAuthorityCertificate != null); - invariant(this._config.clientCertificate != null); - invariant(this._config.clientKey != null); - options = { - ...options, + if (!(this._config.certificateAuthorityCertificate != null)) { + throw new Error('Invariant violation: "this._config.certificateAuthorityCertificate != null"'); + } + + if (!(this._config.clientCertificate != null)) { + throw new Error('Invariant violation: "this._config.clientCertificate != null"'); + } + + if (!(this._config.clientKey != null)) { + throw new Error('Invariant violation: "this._config.clientKey != null"'); + } + + options = Object.assign({}, options, { ca: this._config.certificateAuthorityCertificate, cert: this._config.clientCertificate, key: this._config.clientKey, - family: this._config.family, - }; + family: this._config.family + }); uri = `https://${this.getRemoteHostname()}:${this.getPort()}`; } else { - options = {...options, family: this._config.family}; + options = Object.assign({}, options, { family: this._config.family }); uri = `http://${this.getRemoteHostname()}:${this.getPort()}`; } - const socket = new ReliableSocket( - uri, - HEARTBEAT_CHANNEL, - options, - protocolLogger, - ); - const client = RpcConnection.createRemote( - (socket: Transport), - getAtomSideMarshalers(this.getRemoteHostname()), - servicesConfig, - // Track calls with a sampling rate of 1/10. - {trackSampleRate: 10}, - SERVICE_FRAMEWORK3_PROTOCOL, - socket.id, - protocolLogger, - ); + const socket = new (_ReliableSocket || _load_ReliableSocket()).ReliableSocket(uri, (_NuclideServer || _load_NuclideServer()).HEARTBEAT_CHANNEL, options, (_utils || _load_utils()).protocolLogger); + const client = (_nuclideRpc || _load_nuclideRpc()).RpcConnection.createRemote(socket, (0, (_nuclideMarshalersAtom || _load_nuclideMarshalersAtom()).getAtomSideMarshalers)(this.getRemoteHostname()), (_servicesConfig || _load_servicesConfig()).default, + // Track calls with a sampling rate of 1/10. + { trackSampleRate: 10 }, (_config || _load_config()).SERVICE_FRAMEWORK3_PROTOCOL, socket.id, (_utils || _load_utils()).protocolLogger); this._client = client; this._heartbeat = socket.getHeartbeat(); } - _isSecure(): boolean { - return Boolean( - this._config.certificateAuthorityCertificate && - this._config.clientCertificate && - this._config.clientKey, - ); + _isSecure() { + return Boolean(this._config.certificateAuthorityCertificate && this._config.clientCertificate && this._config.clientKey); } - getPort(): number { + getPort() { return this._config.port; } - getRemoteHostname(): string { + getRemoteHostname() { return this._config.host; } - getConfig(): ServerConnectionConfiguration { + getConfig() { return this._config; } - addConnection(connection: RemoteConnection): void { + addConnection(connection) { this._connections.push(connection); } - async removeConnection( - connection: RemoteConnection, - shutdownIfLast: boolean, - ): Promise { - invariant( - this._connections.indexOf(connection) !== -1, - 'Attempt to remove a non-existent RemoteConnection', - ); + async removeConnection(connection, shutdownIfLast) { + if (!(this._connections.indexOf(connection) !== -1)) { + throw new Error('Attempt to remove a non-existent RemoteConnection'); + } + this._connections.splice(this._connections.indexOf(connection), 1); logger.info('Removed connection.', { cwd: connection.getUri(), title: connection.getDisplayTitle(), - remainingConnections: this._connections.length, + remainingConnections: this._connections.length }); if (this._connections.length === 0) { // The await here is subtle, it ensures that the shutdown call is sent @@ -439,131 +471,106 @@ export class ServerConnection { } } - static onDidAddServerConnection( - handler: (connection: ServerConnection) => mixed, - ): IDisposable { + static onDidAddServerConnection(handler) { return ServerConnection._emitter.on('did-add', handler); } // exposes an Observable of all the ServerConnection additions, // including those that have already connected - static connectionAdded(): Observable { - return Observable.concat( - Observable.from(ServerConnection._connections.values()), - observableFromSubscribeFunction( - ServerConnection.onDidAddServerConnection, - ), - ); - } - - static onDidCancelServerConnection( - handler: (hostname: string) => mixed, - ): IDisposable { + static connectionAdded() { + return _rxjsBundlesRxMinJs.Observable.concat(_rxjsBundlesRxMinJs.Observable.from(ServerConnection._connections.values()), (0, (_event || _load_event()).observableFromSubscribeFunction)(ServerConnection.onDidAddServerConnection)); + } + + static onDidCancelServerConnection(handler) { return ServerConnection._emitter.on('did-cancel', handler); } - static connectionAddedToHost(hostname: string): Observable { - const addEvents = ServerConnection.connectionAdded().filter( - sc => sc.getRemoteHostname() === hostname, - ); - const cancelEvents = observableFromSubscribeFunction( - ServerConnection.onDidCancelServerConnection, - ).filter(canceledHostname => canceledHostname === hostname); - return Observable.merge( - addEvents, - cancelEvents.map(x => { - throw new Error('Cancelled server connection to ' + hostname); - }), - ); - } - - static onDidCloseServerConnection( - handler: (connection: ServerConnection) => mixed, - ): IDisposable { + static connectionAddedToHost(hostname) { + const addEvents = ServerConnection.connectionAdded().filter(sc => sc.getRemoteHostname() === hostname); + const cancelEvents = (0, (_event || _load_event()).observableFromSubscribeFunction)(ServerConnection.onDidCancelServerConnection).filter(canceledHostname => canceledHostname === hostname); + return _rxjsBundlesRxMinJs.Observable.merge(addEvents, cancelEvents.map(x => { + throw new Error('Cancelled server connection to ' + hostname); + })); + } + + static onDidCloseServerConnection(handler) { return ServerConnection._emitter.on('did-close', handler); } - static getForUri(uri: NuclideUri): ?ServerConnection { - if (!nuclideUri.isRemote(uri)) { + static getForUri(uri) { + if (!(_nuclideUri || _load_nuclideUri()).default.isRemote(uri)) { return null; } - return ServerConnection.getByHostname(nuclideUri.getHostname(uri)); + return ServerConnection.getByHostname((_nuclideUri || _load_nuclideUri()).default.getHostname(uri)); } - static getByHostname(hostname: string): ?ServerConnection { + static getByHostname(hostname) { return ServerConnection._connections.get(hostname); } - static observeConnections( - handler: (connection: ServerConnection) => mixed, - ): IDisposable { + static observeConnections(handler) { ServerConnection._connections.forEach(handler); return ServerConnection.onDidAddServerConnection(handler); } - static toDebugString(connection: ?ServerConnection): string { + static toDebugString(connection) { return connection == null ? 'local' : connection.getRemoteHostname(); } - getRemoteConnectionForUri(uri: NuclideUri): ?RemoteConnection { - const {path} = nuclideUri.parse(uri); + getRemoteConnectionForUri(uri) { + const { path } = (_nuclideUri || _load_nuclideUri()).default.parse(uri); return this.getConnections().filter(connection => { return path.startsWith(connection.getPath()); })[0]; } - getConnections(): Array { + getConnections() { return this._connections; } - hasSingleMountPoint(): boolean { + hasSingleMountPoint() { return this.getConnections().length === 1; } - getService(serviceName: string): any { + getService(serviceName) { return this.getClient().getService(serviceName); } - _getInfoService(): InfoService { + _getInfoService() { return this.getService('InfoService'); } - async _closeServerConnection(shutdown: boolean): Promise { + async _closeServerConnection(shutdown) { try { // If the Nuclide server has already been shutdown or has crashed, // the closeConnection() call will attempt to disconnect from the Nuclide // server forever. This sets a 5 second timeout for it so that the rest // of this function and anything calling it can complete. - await timeoutPromise( - this._getInfoService().closeConnection(shutdown), - 5000, - ); + await (0, (_promise || _load_promise()).timeoutPromise)(this._getInfoService().closeConnection(shutdown), 5000); } catch (e) { - getLogger('nuclide-remote-connection').error( - 'Failed to close Nuclide server connection.', - ); + (0, (_log4js || _load_log4js()).getLogger)('nuclide-remote-connection').error('Failed to close Nuclide server connection.'); } finally { if (shutdown) { // Clear the saved connection config so we don't try it again at startup. - clearConnectionConfig(this._config.host); + (0, (_RemoteConnectionConfigurationManager || _load_RemoteConnectionConfigurationManager()).clearConnectionConfig)(this._config.host); } } } - static observeRemoteConnections(): Observable> { + static observeRemoteConnections() { const emitter = ServerConnection._emitter; - return Observable.merge( - observableFromSubscribeFunction(cb => emitter.on('did-add', cb)), - observableFromSubscribeFunction(cb => emitter.on('did-close', cb)), - Observable.of(null), // so subscribers get a full list immediately + return _rxjsBundlesRxMinJs.Observable.merge((0, (_event || _load_event()).observableFromSubscribeFunction)(cb => emitter.on('did-add', cb)), (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => emitter.on('did-close', cb)), _rxjsBundlesRxMinJs.Observable.of(null) // so subscribers get a full list immediately ).map(() => Array.from(ServerConnection._connections.values())); } - static getAllConnections(): Array { + static getAllConnections() { return Array.from(ServerConnection._connections.values()); } } -export const __test__ = { - connections: ServerConnection._connections, -}; +exports.ServerConnection = ServerConnection; +ServerConnection._connections = new Map(); +ServerConnection._emitter = new (_eventKit || _load_eventKit()).Emitter(); +const __test__ = exports.__test__ = { + connections: ServerConnection._connections +}; \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/SshHandshake.js b/pkg/nuclide-remote-connection/lib/SshHandshake.js index 94b6c11549..5225811888 100644 --- a/pkg/nuclide-remote-connection/lib/SshHandshake.js +++ b/pkg/nuclide-remote-connection/lib/SshHandshake.js @@ -1,3 +1,84 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SshHandshake = undefined; +exports.decorateSshConnectionDelegateWithTracking = decorateSshConnectionDelegateWithTracking; + +var _ConnectionTracker; + +function _load_ConnectionTracker() { + return _ConnectionTracker = _interopRequireDefault(require('./ConnectionTracker')); +} + +var _ssh; + +function _load_ssh() { + return _ssh = require('ssh2'); +} + +var _fsPlus; + +function _load_fsPlus() { + return _fsPlus = _interopRequireDefault(require('fs-plus')); +} + +var _net = _interopRequireDefault(require('net')); + +var _RemoteConnection; + +function _load_RemoteConnection() { + return _RemoteConnection = require('./RemoteConnection'); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _string; + +function _load_string() { + return _string = require('../../../modules/nuclide-commons/string'); +} + +var _lookupPreferIpV; + +function _load_lookupPreferIpV() { + return _lookupPreferIpV = _interopRequireDefault(require('./lookup-prefer-ip-v6')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _RemoteCommand; + +function _load_RemoteCommand() { + return _RemoteCommand = require('./RemoteCommand'); +} + +var _systemInfo; + +function _load_systemInfo() { + return _systemInfo = require('../../commons-node/system-info'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-remote-connection'); + +// Sync word and regex pattern for parsing command stdout. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,56 +86,22 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {RemoteConnectionConfiguration} from './RemoteConnection'; - -import ConnectionTracker from './ConnectionTracker'; -import {Client as SshConnection} from 'ssh2'; -import fs from 'fs-plus'; -import net from 'net'; -import invariant from 'assert'; -import {RemoteConnection} from './RemoteConnection'; -import fsPromise from 'nuclide-commons/fsPromise'; -import {sleep} from 'nuclide-commons/promise'; -import {shellQuote} from 'nuclide-commons/string'; -import lookupPreferIpv6 from './lookup-prefer-ip-v6'; -import {getLogger} from 'log4js'; -import {readFile as readRemoteFile} from './RemoteCommand'; -import {getNuclideVersion} from '../../commons-node/system-info'; - -const logger = getLogger('nuclide-remote-connection'); - -// Sync word and regex pattern for parsing command stdout. const READY_TIMEOUT_MS = 120 * 1000; const SFTP_TIMEOUT_MS = 20 * 1000; // Automatically retry with a password prompt if existing authentication methods fail. const PASSWORD_RETRIES = 3; -export type SshConnectionConfiguration = { - host: string, // host nuclide server is running on - sshPort: number, // ssh port of host nuclide server is running on - family?: 4 | 6, // ipv4 or ipv6? - username: string, // username to authenticate as - pathToPrivateKey: string, // The path to private key - remoteServerCommand: string, // Command to use to start server - cwd: string, // Path to remote directory user should start in upon connection. - authMethod: SshHandshakeAuthMethodsType, // Which of the authentication methods in `SupportedMethods` to use. - password: string, // for simple password-based authentication - displayTitle: string, // Name of the saved connection profile. -}; - const SupportedMethods = Object.freeze({ SSL_AGENT: 'SSL_AGENT', PASSWORD: 'PASSWORD', - PRIVATE_KEY: 'PRIVATE_KEY', + PRIVATE_KEY: 'PRIVATE_KEY' }); -export type SshHandshakeAuthMethodsType = $Values; - const ErrorType = Object.freeze({ UNKNOWN: 'UNKNOWN', HOST_NOT_FOUND: 'HOST_NOT_FOUND', @@ -67,31 +114,9 @@ const ErrorType = Object.freeze({ SERVER_START_FAILED: 'SERVER_START_FAILED', SERVER_CANNOT_CONNECT: 'SERVER_CANNOT_CONNECT', SFTP_TIMEOUT: 'SFTP_TIMEOUT', - USER_CANCELED: 'USER_CANCELLED', + USER_CANCELED: 'USER_CANCELLED' }); -export type SshHandshakeErrorType = - | 'UNKNOWN' - | 'HOST_NOT_FOUND' - | 'CANT_READ_PRIVATE_KEY' - | 'CERT_NOT_YET_VALID' - | 'SSH_CONNECT_TIMEOUT' - | 'SSH_CONNECT_FAILED' - | 'SSH_AUTHENTICATION' - | 'DIRECTORY_NOT_FOUND' - | 'SERVER_START_FAILED' - | 'SERVER_CANNOT_CONNECT' - | 'SFTP_TIMEOUT' - | 'USER_CANCELLED'; - -type SshConnectionErrorLevel = - | 'client-timeout' - | 'client-socket' - | 'protocal' - | 'client-authentication' - | 'agent' - | 'client-dns'; - /** * The server is asking for replies to the given prompts for * keyboard-interactive user authentication. @@ -105,130 +130,63 @@ type SshConnectionErrorLevel = * array of strings and passed to finish when you are ready to continue. Note: * It's possible for the server to come back and ask more questions. */ -export type KeyboardInteractiveCallback = ( - name: string, - instructions: string, - instructionsLang: string, - prompts: Array<{prompt: string, echo: boolean}>, - finish: (answers: Array) => void, -) => void; - -export type SshConnectionDelegate = { - /** Invoked when server requests keyboard interaction */ - onKeyboardInteractive: KeyboardInteractiveCallback, - /** Invoked when trying to connect */ - onWillConnect: (config: SshConnectionConfiguration) => void, - /** Invoked when connection is successful */ - onDidConnect: ( - connection: RemoteConnection, - config: SshConnectionConfiguration, - ) => void, - /** Invoked when connection is fails */ - onError: ( - errorType: SshHandshakeErrorType, - error: Error, - config: SshConnectionConfiguration, - ) => void, -}; - -const SshConnectionErrorLevelMap: Map< - SshConnectionErrorLevel, - SshHandshakeErrorType, -> = new Map([ - ['client-timeout', ErrorType.SSH_CONNECT_TIMEOUT], - ['client-socket', ErrorType.SSH_CONNECT_FAILED], - ['protocal', ErrorType.SSH_CONNECT_FAILED], - ['client-authentication', ErrorType.SSH_AUTHENTICATION], - ['agent', ErrorType.SSH_AUTHENTICATION], - ['client-dns', ErrorType.SSH_AUTHENTICATION], -]); - -export class SshHandshake { - static ErrorType = ErrorType; - static SupportedMethods: typeof SupportedMethods = SupportedMethods; - - _delegate: SshConnectionDelegate; - _connection: SshConnection; - _config: SshConnectionConfiguration; - _forwardingServer: net.Server; - _remoteHost: ?string; - _remotePort: number; - _certificateAuthorityCertificate: Buffer; - _clientCertificate: Buffer; - _clientKey: Buffer; - _passwordRetryCount: number; - _canceled: boolean; - - constructor(delegate: SshConnectionDelegate, connection?: SshConnection) { + + +const SshConnectionErrorLevelMap = new Map([['client-timeout', ErrorType.SSH_CONNECT_TIMEOUT], ['client-socket', ErrorType.SSH_CONNECT_FAILED], ['protocal', ErrorType.SSH_CONNECT_FAILED], ['client-authentication', ErrorType.SSH_AUTHENTICATION], ['agent', ErrorType.SSH_AUTHENTICATION], ['client-dns', ErrorType.SSH_AUTHENTICATION]]); + +class SshHandshake { + + constructor(delegate, connection) { this._canceled = false; this._delegate = delegate; - this._connection = connection ? connection : new SshConnection(); + this._connection = connection ? connection : new (_ssh || _load_ssh()).Client(); this._connection.on('ready', this._onConnect.bind(this)); this._connection.on('error', this._onSshConnectionError.bind(this)); - this._connection.on( - 'keyboard-interactive', - this._onKeyboardInteractive.bind(this), - ); + this._connection.on('keyboard-interactive', this._onKeyboardInteractive.bind(this)); } - _willConnect(): void { + _willConnect() { this._delegate.onWillConnect(this._config); } - _didConnect(connection: RemoteConnection): void { + _didConnect(connection) { this._delegate.onDidConnect(connection, this._config); } - _error( - message: string, - errorType: SshHandshakeErrorType, - error: Error, - ): void { + _error(message, errorType, error) { logger.error(`SshHandshake failed: ${errorType}, ${message}`, error); this._delegate.onError(errorType, error, this._config); } - _onSshConnectionError(error: Error): void { - const errorLevel = ((error: Object).level: SshConnectionErrorLevel); + _onSshConnectionError(error) { + const errorLevel = error.level; // Upon authentication failure, fall back to using a password. - if ( - errorLevel === 'client-authentication' && - this._passwordRetryCount < PASSWORD_RETRIES - ) { + if (errorLevel === 'client-authentication' && this._passwordRetryCount < PASSWORD_RETRIES) { const config = this._config; const retryText = this._passwordRetryCount ? ' again' : ''; - this._delegate.onKeyboardInteractive( - '', - '', - '', // ignored - [ - { - prompt: `Authentication failed. Try entering your password${retryText}:`, - echo: true, - }, - ], - ([password]) => { - this._connection.connect({ - // Use the correctly resolved hostname. - host: this._connection.config.host, - port: config.sshPort, - username: config.username, - password, - tryKeyboard: true, - readyTimeout: READY_TIMEOUT_MS, - }); - }, - ); + this._delegate.onKeyboardInteractive('', '', '', // ignored + [{ + prompt: `Authentication failed. Try entering your password${retryText}:`, + echo: true + }], ([password]) => { + this._connection.connect({ + // Use the correctly resolved hostname. + host: this._connection.config.host, + port: config.sshPort, + username: config.username, + password, + tryKeyboard: true, + readyTimeout: READY_TIMEOUT_MS + }); + }); this._passwordRetryCount++; return; } - const errorType = - SshConnectionErrorLevelMap.get(errorLevel) || - SshHandshake.ErrorType.UNKNOWN; + const errorType = SshConnectionErrorLevelMap.get(errorLevel) || SshHandshake.ErrorType.UNKNOWN; this._error('Ssh connection failed.', errorType, error); } - async connect(config: SshConnectionConfiguration): Promise { + async connect(config) { this._config = config; this._passwordRetryCount = 0; this._canceled = false; @@ -236,16 +194,12 @@ export class SshHandshake { let lookup; try { - lookup = await lookupPreferIpv6(config.host); + lookup = await (0, (_lookupPreferIpV || _load_lookupPreferIpV()).default)(config.host); } catch (e) { - return this._error( - 'Failed to resolve DNS.', - SshHandshake.ErrorType.HOST_NOT_FOUND, - e, - ); + return this._error('Failed to resolve DNS.', SshHandshake.ErrorType.HOST_NOT_FOUND, e); } - const {address, family} = lookup; + const { address, family } = lookup; this._config.family = family; if (config.authMethod === SupportedMethods.SSL_AGENT) { @@ -262,7 +216,7 @@ export class SshHandshake { username: config.username, agent, tryKeyboard: true, - readyTimeout: READY_TIMEOUT_MS, + readyTimeout: READY_TIMEOUT_MS }); } else if (config.authMethod === SupportedMethods.PASSWORD) { // The user has already entered the password once. @@ -276,27 +230,23 @@ export class SshHandshake { username: config.username, password: config.password, tryKeyboard: true, - readyTimeout: READY_TIMEOUT_MS, + readyTimeout: READY_TIMEOUT_MS }); } else if (config.authMethod === SupportedMethods.PRIVATE_KEY) { // We use fs-plus's normalize() function because it will expand the ~, if present. - const expandedPath = fs.normalize(config.pathToPrivateKey); + const expandedPath = (_fsPlus || _load_fsPlus()).default.normalize(config.pathToPrivateKey); try { - const privateKey = await fsPromise.readFile(expandedPath); + const privateKey = await (_fsPromise || _load_fsPromise()).default.readFile(expandedPath); this._connection.connect({ host: address, port: config.sshPort, username: config.username, privateKey, tryKeyboard: true, - readyTimeout: READY_TIMEOUT_MS, + readyTimeout: READY_TIMEOUT_MS }); } catch (e) { - this._error( - 'Failed to read private key', - SshHandshake.ErrorType.CANT_READ_PRIVATE_KEY, - e, - ); + this._error('Failed to read private key', SshHandshake.ErrorType.CANT_READ_PRIVATE_KEY, e); } } } @@ -306,56 +256,46 @@ export class SshHandshake { this._connection.end(); } - _onKeyboardInteractive( - name: string, - instructions: string, - instructionsLang: string, - prompts: Array<{prompt: string, echo: boolean}>, - finish: (answers: Array) => void, - ): void { - this._delegate.onKeyboardInteractive( - name, - instructions, - instructionsLang, - prompts, - finish, - ); + _onKeyboardInteractive(name, instructions, instructionsLang, prompts, finish) { + this._delegate.onKeyboardInteractive(name, instructions, instructionsLang, prompts, finish); } - _forwardSocket(socket: net.Socket): void { - invariant(socket.remoteAddress != null); - this._connection.forwardOut( - socket.remoteAddress, - socket.remotePort, - 'localhost', - this._remotePort, - (err, stream) => { - if (err) { - socket.end(); - logger.error(err); - return; - } - socket.pipe(stream); - stream.pipe(socket); - }, - ); + _forwardSocket(socket) { + if (!(socket.remoteAddress != null)) { + throw new Error('Invariant violation: "socket.remoteAddress != null"'); + } + + this._connection.forwardOut(socket.remoteAddress, socket.remotePort, 'localhost', this._remotePort, (err, stream) => { + if (err) { + socket.end(); + logger.error(err); + return; + } + socket.pipe(stream); + stream.pipe(socket); + }); } - _updateServerInfo(serverInfo: {}) { + _updateServerInfo(serverInfo) { // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - invariant(typeof serverInfo.port === 'number'); + if (!(typeof serverInfo.port === 'number')) { + throw new Error('Invariant violation: "typeof serverInfo.port === \'number\'"'); + } + this._remotePort = serverInfo.port || 0; this._remoteHost = - // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - typeof serverInfo.hostname === 'string' - ? serverInfo.hostname - : this._config.host; + // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) + typeof serverInfo.hostname === 'string' ? serverInfo.hostname : this._config.host; // Because the value for the Initial Directory that the user supplied may have // been a symlink that was resolved by the server, overwrite the original `cwd` // value with the resolved value. // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - invariant(typeof serverInfo.workspace === 'string'); + + if (!(typeof serverInfo.workspace === 'string')) { + throw new Error('Invariant violation: "typeof serverInfo.workspace === \'string\'"'); + } + this._config.cwd = serverInfo.workspace; // The following keys are optional in `RemoteConnectionConfiguration`. @@ -377,32 +317,23 @@ export class SshHandshake { } } - _isSecure(): boolean { - return Boolean( - this._certificateAuthorityCertificate && - this._clientCertificate && - this._clientKey, - ); + _isSecure() { + return Boolean(this._certificateAuthorityCertificate && this._clientCertificate && this._clientKey); } - _startRemoteServer(): Promise { + _startRemoteServer() { return new Promise((resolve, reject) => { const command = this._config.remoteServerCommand; const remoteTempFile = `/tmp/nuclide-sshhandshake-${Math.random()}`; - const flags = [ - `--workspace=${this._config.cwd}`, - `--common-name=${this._config.host}`, - `--json-output-file=${remoteTempFile}`, - '--timeout=60', - ]; + const flags = [`--workspace=${this._config.cwd}`, `--common-name=${this._config.host}`, `--json-output-file=${remoteTempFile}`, '--timeout=60']; // Append the client version if not already provided. if (!command.includes('--version=')) { - flags.push(`--version=${getNuclideVersion()}`); + flags.push(`--version=${(0, (_systemInfo || _load_systemInfo()).getNuclideVersion)()}`); } // We'll take the user-provided command literally. - const cmd = command + ' ' + shellQuote(flags); + const cmd = command + ' ' + (0, (_string || _load_string()).shellQuote)(flags); - this._connection.exec(cmd, {pty: {term: 'nuclide'}}, (err, stream) => { + this._connection.exec(cmd, { pty: { term: 'nuclide' } }, (err, stream) => { if (err) { this._onSshConnectionError(err); return resolve(false); @@ -410,65 +341,41 @@ export class SshHandshake { let stdOut = ''; // $FlowIssue - Problem with function overloads. Maybe related to #4616, #4683, #4685, and #4669 - stream - .on('close', async (exitCode, signal) => { - if (exitCode !== 0) { - if (this._canceled) { - this._error( - 'Cancelled by user', - SshHandshake.ErrorType.USER_CANCELED, - new Error(stdOut), - ); - } else { - this._error( - 'Remote shell execution failed', - SshHandshake.ErrorType.UNKNOWN, - new Error(stdOut), - ); - } - return resolve(false); + stream.on('close', async (exitCode, signal) => { + if (exitCode !== 0) { + if (this._canceled) { + this._error('Cancelled by user', SshHandshake.ErrorType.USER_CANCELED, new Error(stdOut)); + } else { + this._error('Remote shell execution failed', SshHandshake.ErrorType.UNKNOWN, new Error(stdOut)); } - - // Some servers have max channels set to 1, so add a delay to ensure - // the old channel has been cleaned up on the server. - // TODO(hansonw): Implement a proper retry mechanism. - // But first, we have to clean up this callback hell. - await sleep(100); - const result = await readRemoteFile( - this._connection, - SFTP_TIMEOUT_MS, - remoteTempFile, - ); - - switch (result.type) { - case 'success': { - let serverInfo: any = null; + return resolve(false); + } + + // Some servers have max channels set to 1, so add a delay to ensure + // the old channel has been cleaned up on the server. + // TODO(hansonw): Implement a proper retry mechanism. + // But first, we have to clean up this callback hell. + await (0, (_promise || _load_promise()).sleep)(100); + const result = await (0, (_RemoteCommand || _load_RemoteCommand()).readFile)(this._connection, SFTP_TIMEOUT_MS, remoteTempFile); + + switch (result.type) { + case 'success': + { + let serverInfo = null; try { serverInfo = JSON.parse(result.data.toString()); } catch (e) { - this._error( - 'Malformed server start information', - SshHandshake.ErrorType.SERVER_START_FAILED, - new Error(result.data), - ); + this._error('Malformed server start information', SshHandshake.ErrorType.SERVER_START_FAILED, new Error(result.data)); return resolve(false); } if (!serverInfo.success) { - this._error( - 'Remote server failed to start', - SshHandshake.ErrorType.SERVER_START_FAILED, - new Error(serverInfo.logs), - ); + this._error('Remote server failed to start', SshHandshake.ErrorType.SERVER_START_FAILED, new Error(serverInfo.logs)); return resolve(false); } if (!serverInfo.workspace) { - this._error( - 'Could not find directory', - SshHandshake.ErrorType.DIRECTORY_NOT_FOUND, - new Error(serverInfo.logs), - ); + this._error('Could not find directory', SshHandshake.ErrorType.DIRECTORY_NOT_FOUND, new Error(serverInfo.logs)); return resolve(false); } @@ -477,59 +384,40 @@ export class SshHandshake { return resolve(true); } - case 'timeout': - this._error( - 'Failed to start sftp connection', - SshHandshake.ErrorType.SFTP_TIMEOUT, - new Error(), - ); - this._connection.end(); - return resolve(false); - - case 'fail-to-start-connection': - this._error( - 'Failed to start sftp connection', - SshHandshake.ErrorType.SERVER_START_FAILED, - result.error, - ); - return resolve(false); - - case 'fail-to-transfer-data': - this._error( - 'Failed to transfer server start information', - SshHandshake.ErrorType.SERVER_START_FAILED, - result.error, - ); - return resolve(false); - - default: - (result: empty); - } - }) - .on('data', data => { - stdOut += data; - }); + case 'timeout': + this._error('Failed to start sftp connection', SshHandshake.ErrorType.SFTP_TIMEOUT, new Error()); + this._connection.end(); + return resolve(false); + + case 'fail-to-start-connection': + this._error('Failed to start sftp connection', SshHandshake.ErrorType.SERVER_START_FAILED, result.error); + return resolve(false); + + case 'fail-to-transfer-data': + this._error('Failed to transfer server start information', SshHandshake.ErrorType.SERVER_START_FAILED, result.error); + return resolve(false); + + default: + result; + } + }).on('data', data => { + stdOut += data; + }); }); }); } - async _onConnect(): Promise { + async _onConnect() { if (!(await this._startRemoteServer())) { return; } - const connect = async (config: RemoteConnectionConfiguration) => { + const connect = async config => { let connection = null; try { - connection = await RemoteConnection.findOrCreate(config); + connection = await (_RemoteConnection || _load_RemoteConnection()).RemoteConnection.findOrCreate(config); } catch (e) { - this._error( - 'Connection check failed', - e.code === 'CERT_NOT_YET_VALID' - ? SshHandshake.ErrorType.CERT_NOT_YET_VALID - : SshHandshake.ErrorType.SERVER_CANNOT_CONNECT, - e, - ); + this._error('Connection check failed', e.code === 'CERT_NOT_YET_VALID' ? SshHandshake.ErrorType.CERT_NOT_YET_VALID : SshHandshake.ErrorType.SERVER_CANNOT_CONNECT, e); } if (connection != null) { this._didConnect(connection); @@ -543,7 +431,10 @@ export class SshHandshake { // Use an ssh tunnel if server is not secure if (this._isSecure()) { // flowlint-next-line sketchy-null-string:off - invariant(this._remoteHost); + if (!this._remoteHost) { + throw new Error('Invariant violation: "this._remoteHost"'); + } + connect({ host: this._remoteHost, port: this._remotePort, @@ -552,88 +443,80 @@ export class SshHandshake { certificateAuthorityCertificate: this._certificateAuthorityCertificate, clientCertificate: this._clientCertificate, clientKey: this._clientKey, - displayTitle: this._config.displayTitle, + displayTitle: this._config.displayTitle }); } else { - this._forwardingServer = net - .createServer(sock => { - this._forwardSocket(sock); - }) - // $FlowFixMe - .listen(0, 'localhost', () => { - const localPort = this._getLocalPort(); - // flowlint-next-line sketchy-null-number:off - invariant(localPort); - connect({ - host: 'localhost', - port: localPort, - family: this._config.family, - path: this._config.cwd, - displayTitle: this._config.displayTitle, - }); + this._forwardingServer = _net.default.createServer(sock => { + this._forwardSocket(sock); + }) + // $FlowFixMe + .listen(0, 'localhost', () => { + const localPort = this._getLocalPort(); + // flowlint-next-line sketchy-null-number:off + + if (!localPort) { + throw new Error('Invariant violation: "localPort"'); + } + + connect({ + host: 'localhost', + port: localPort, + family: this._config.family, + path: this._config.cwd, + displayTitle: this._config.displayTitle }); + }); } } - _getLocalPort(): ?number { - return this._forwardingServer - ? this._forwardingServer.address().port - : null; + _getLocalPort() { + return this._forwardingServer ? this._forwardingServer.address().port : null; } - getConfig(): SshConnectionConfiguration { + getConfig() { return this._config; } } -export function decorateSshConnectionDelegateWithTracking( - delegate: SshConnectionDelegate, -): SshConnectionDelegate { +exports.SshHandshake = SshHandshake; +SshHandshake.ErrorType = ErrorType; +SshHandshake.SupportedMethods = SupportedMethods; +function decorateSshConnectionDelegateWithTracking(delegate) { let connectionTracker; return { - onKeyboardInteractive: ( - name: string, - instructions: string, - instructionsLang: string, - prompts: Array<{prompt: string, echo: boolean}>, - finish: (answers: Array) => void, - ) => { - invariant(connectionTracker); + onKeyboardInteractive: (name, instructions, instructionsLang, prompts, finish) => { + if (!connectionTracker) { + throw new Error('Invariant violation: "connectionTracker"'); + } + connectionTracker.trackPromptYubikeyInput(); - delegate.onKeyboardInteractive( - name, - instructions, - instructionsLang, - prompts, - answers => { - invariant(connectionTracker); - connectionTracker.trackFinishYubikeyInput(); - finish(answers); - }, - ); + delegate.onKeyboardInteractive(name, instructions, instructionsLang, prompts, answers => { + if (!connectionTracker) { + throw new Error('Invariant violation: "connectionTracker"'); + } + + connectionTracker.trackFinishYubikeyInput(); + finish(answers); + }); }, - onWillConnect: (config: SshConnectionConfiguration) => { - connectionTracker = new ConnectionTracker(config); + onWillConnect: config => { + connectionTracker = new (_ConnectionTracker || _load_ConnectionTracker()).default(config); delegate.onWillConnect(config); }, - onDidConnect: ( - connection: RemoteConnection, - config: SshConnectionConfiguration, - ) => { - invariant(connectionTracker); + onDidConnect: (connection, config) => { + if (!connectionTracker) { + throw new Error('Invariant violation: "connectionTracker"'); + } + connectionTracker.trackSuccess(); delegate.onDidConnect(connection, config); }, - onError: ( - errorType: SshHandshakeErrorType, - error: Error, - config: SshConnectionConfiguration, - ) => { + onError: (errorType, error, config) => { if (connectionTracker != null) { connectionTracker.trackFailure(errorType, error); } delegate.onError(errorType, error, config); - }, + } }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/createBigDigRpcClient.js b/pkg/nuclide-remote-connection/lib/createBigDigRpcClient.js index 23fd9ea137..9ce27d4027 100644 --- a/pkg/nuclide-remote-connection/lib/createBigDigRpcClient.js +++ b/pkg/nuclide-remote-connection/lib/createBigDigRpcClient.js @@ -1,3 +1,53 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _client; + +function _load_client() { + return _client = require('../../../modules/big-dig/src/client'); +} + +var _nuclideMarshalersAtom; + +function _load_nuclideMarshalersAtom() { + return _nuclideMarshalersAtom = require('../../nuclide-marshalers-atom'); +} + +var _nuclideRpc; + +function _load_nuclideRpc() { + return _nuclideRpc = require('../../nuclide-rpc'); +} + +var _config; + +function _load_config() { + return _config = require('../../nuclide-rpc/lib/config'); +} + +var _servicesConfig; + +function _load_servicesConfig() { + return _servicesConfig = _interopRequireDefault(require('../../nuclide-server/lib/servicesConfig')); +} + +var _utils; + +function _load_utils() { + return _utils = require('../../nuclide-server/lib/utils'); +} + +var _constants; + +function _load_constants() { + return _constants = require('../../nuclide-server2/lib/constants'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,57 +55,31 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {BigDigClient} from 'big-dig/src/client'; -import type {ServerConnectionConfiguration} from './ServerConnection'; -import type {Transport} from '../../nuclide-rpc'; - -import {createBigDigClient} from 'big-dig/src/client'; -import {getAtomSideMarshalers} from '../../nuclide-marshalers-atom'; -import {RpcConnection} from '../../nuclide-rpc'; -import {SERVICE_FRAMEWORK3_PROTOCOL} from '../../nuclide-rpc/lib/config'; -import servicesConfig from '../../nuclide-server/lib/servicesConfig'; -import {protocolLogger} from '../../nuclide-server/lib/utils'; -import {NUCLIDE_RPC_TAG} from '../../nuclide-server2/lib/constants'; - -export default (async function createBigDigRpcClient( - config: ServerConnectionConfiguration, -): Promise<{ - bigDigClient: BigDigClient, - rpcConnection: RpcConnection, -}> { - const bigDigClient = await createBigDigClient({ - ...config, +exports.default = async function createBigDigRpcClient(config) { + const bigDigClient = await (0, (_client || _load_client()).createBigDigClient)(Object.assign({}, config, { ignoreIntransientErrors: true, - protocolLogger, - }); - const bigDigTransport: Transport = { - send(message: string) { - bigDigClient.sendMessage(NUCLIDE_RPC_TAG, message); + protocolLogger: (_utils || _load_utils()).protocolLogger + })); + const bigDigTransport = { + send(message) { + bigDigClient.sendMessage((_constants || _load_constants()).NUCLIDE_RPC_TAG, message); }, onMessage() { - return bigDigClient.onMessage(NUCLIDE_RPC_TAG); + return bigDigClient.onMessage((_constants || _load_constants()).NUCLIDE_RPC_TAG); }, close() { bigDigClient.close(); }, isClosed() { return bigDigClient.isClosed(); - }, + } }; return { bigDigClient, - rpcConnection: RpcConnection.createRemote( - bigDigTransport, - getAtomSideMarshalers(config.host), - servicesConfig, - {trackSampleRate: 10}, - SERVICE_FRAMEWORK3_PROTOCOL, - null, - protocolLogger, - ), + rpcConnection: (_nuclideRpc || _load_nuclideRpc()).RpcConnection.createRemote(bigDigTransport, (0, (_nuclideMarshalersAtom || _load_nuclideMarshalersAtom()).getAtomSideMarshalers)(config.host), (_servicesConfig || _load_servicesConfig()).default, { trackSampleRate: 10 }, (_config || _load_config()).SERVICE_FRAMEWORK3_PROTOCOL, null, (_utils || _load_utils()).protocolLogger) }; -}); +}; \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/lookup-prefer-ip-v6.js b/pkg/nuclide-remote-connection/lib/lookup-prefer-ip-v6.js index 2f870eed6e..47f88b90f0 100644 --- a/pkg/nuclide-remote-connection/lib/lookup-prefer-ip-v6.js +++ b/pkg/nuclide-remote-connection/lib/lookup-prefer-ip-v6.js @@ -1,3 +1,13 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _dns = _interopRequireDefault(require('dns')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,23 +15,11 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -import invariant from 'assert'; -import dns from 'dns'; - -export type DnsFamily = 4 | 6; - -export type DnsLookup = { - address: string, - family: DnsFamily, -}; - -export default (async function lookupPreferIpv6( - host: string, -): Promise { +exports.default = async function lookupPreferIpv6(host) { try { return await lookup(host, 6); } catch (e) { @@ -30,23 +28,22 @@ export default (async function lookupPreferIpv6( } throw e; } -}); +}; -function lookup(host: string, family: DnsFamily): Promise { +function lookup(host, family) { return new Promise((resolve, reject) => { - dns.lookup( - host, - family, - (error: ?Error, address: ?string, resultFamily: ?number) => { - if (error) { - reject(error); - } else if (address != null) { - invariant(resultFamily === 4 || resultFamily === 6); - resolve({address, family: resultFamily}); - } else { - reject(new Error('One of error or address must be set.')); + _dns.default.lookup(host, family, (error, address, resultFamily) => { + if (error) { + reject(error); + } else if (address != null) { + if (!(resultFamily === 4 || resultFamily === 6)) { + throw new Error('Invariant violation: "resultFamily === 4 || resultFamily === 6"'); } - }, - ); + + resolve({ address, family: resultFamily }); + } else { + reject(new Error('One of error or address must be set.')); + } + }); }); -} +} \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/main.js b/pkg/nuclide-remote-connection/lib/main.js index 605cee80de..3d614842b0 100644 --- a/pkg/nuclide-remote-connection/lib/main.js +++ b/pkg/nuclide-remote-connection/lib/main.js @@ -1,246 +1,271 @@ -/** - * 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 strict-local - * @format - */ - -import type {Directory as LocalDirectoryType} from 'atom'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {BigDigClient} from 'big-dig/src/client'; - -import nullthrows from 'nullthrows'; -import invariant from 'assert'; - -import {RemoteConnection} from './RemoteConnection'; -import {RemoteDirectory} from './RemoteDirectory'; -import {RemoteFile} from './RemoteFile'; -import {ServerConnection} from './ServerConnection'; -import {ConnectionCache} from './ConnectionCache'; - -import { - SshHandshake, - decorateSshConnectionDelegateWithTracking, -} from './SshHandshake'; - -import { - getService, - getServiceByConnection, - getServiceByNuclideUri, - awaitServiceByNuclideUri, - getlocalService, -} from './service-manager'; - -export type Directory = LocalDirectoryType | RemoteDirectory; - -export { - RemoteConnection, - RemoteDirectory, - RemoteFile, - ServerConnection, - ConnectionCache, - SshHandshake, - decorateSshConnectionDelegateWithTracking, - getService, - getServiceByConnection, - getServiceByNuclideUri, - getlocalService, -}; - -export { - bufferForUri, - existingBufferForUri, - loadBufferForUri, -} from './remote-text-buffer'; - -export { - default as RemoteDirectoryPlaceholder, -} from './RemoteDirectoryPlaceholder'; - -import typeof * as BuckService from '../../nuclide-buck-rpc'; -import typeof * as ClangService from '../../nuclide-clang-rpc'; -import typeof * as CodeSearchService from '../../nuclide-code-search-rpc/lib/CodeSearchService'; -import typeof * as CtagsService from '../../nuclide-ctags-rpc'; -import typeof * as DefinitionPreviewService from '../../nuclide-definition-preview-rpc'; -import typeof * as FbsimctlService from '../../nuclide-fbsimctl-rpc'; -import typeof * as FileSystemService from '../../nuclide-server/lib/services/FileSystemService'; -import typeof * as FileWatcherService from '../../nuclide-filewatcher-rpc'; -import typeof * as FlowService from '../../nuclide-flow-rpc'; -import typeof * as FuzzyFileSearchService from '../../nuclide-fuzzy-file-search-rpc'; -import typeof * as GeneratedFileService from '../../nuclide-generated-files-rpc'; -import typeof * as GrepService from '../../nuclide-grep-rpc'; -import typeof * as HackService from '../../nuclide-hack-rpc'; -import typeof * as HgService from '../../nuclide-hg-rpc/lib/HgService'; -import typeof * as InfoService from '../../nuclide-server/lib/services/InfoService'; -import typeof * as MetroService from '../../nuclide-metro-rpc/lib/MetroService'; -import typeof * as OpenFilesService from '../../nuclide-open-files-rpc/lib/OpenFilesService'; -import typeof * as HhvmDebuggerService from '../../nuclide-debugger-hhvm-rpc'; -import typeof * as PythonService from '../../nuclide-python-rpc'; -import typeof * as RemoteCommandService from '../../nuclide-remote-atom-rpc'; -import typeof * as SdbService from '../../nuclide-adb-sdb-rpc/lib/SdbService'; -import typeof * as SocketService from '../../nuclide-socket-rpc'; -import typeof * as SourceControlService from '../../nuclide-server/lib/services/SourceControlService'; -import typeof * as VSCodeLanguageService from '../../nuclide-vscode-language-service-rpc'; -import typeof * as CqueryLSPService from '../../nuclide-cquery-lsp-rpc'; - -export function getBigDigClientByNuclideUri(uri: NuclideUri): BigDigClient { - const connection = ServerConnection.getForUri(uri); - invariant(connection, `no server connection for ${uri}`); - return connection.getBigDigClient(); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RemoteDirectoryPlaceholder = exports.loadBufferForUri = exports.existingBufferForUri = exports.bufferForUri = exports.getlocalService = exports.getServiceByNuclideUri = exports.getServiceByConnection = exports.getService = exports.decorateSshConnectionDelegateWithTracking = exports.SshHandshake = exports.ConnectionCache = exports.ServerConnection = exports.RemoteFile = exports.RemoteDirectory = exports.RemoteConnection = undefined; + +var _remoteTextBuffer; + +function _load_remoteTextBuffer() { + return _remoteTextBuffer = require('./remote-text-buffer'); +} + +Object.defineProperty(exports, 'bufferForUri', { + enumerable: true, + get: function () { + return (_remoteTextBuffer || _load_remoteTextBuffer()).bufferForUri; + } +}); +Object.defineProperty(exports, 'existingBufferForUri', { + enumerable: true, + get: function () { + return (_remoteTextBuffer || _load_remoteTextBuffer()).existingBufferForUri; + } +}); +Object.defineProperty(exports, 'loadBufferForUri', { + enumerable: true, + get: function () { + return (_remoteTextBuffer || _load_remoteTextBuffer()).loadBufferForUri; + } +}); + +var _RemoteDirectoryPlaceholder; + +function _load_RemoteDirectoryPlaceholder() { + return _RemoteDirectoryPlaceholder = require('./RemoteDirectoryPlaceholder'); +} + +Object.defineProperty(exports, 'RemoteDirectoryPlaceholder', { + enumerable: true, + get: function () { + return _interopRequireDefault(_RemoteDirectoryPlaceholder || _load_RemoteDirectoryPlaceholder()).default; + } +}); +exports.getBigDigClientByNuclideUri = getBigDigClientByNuclideUri; +exports.getBuckServiceByNuclideUri = getBuckServiceByNuclideUri; +exports.getClangServiceByNuclideUri = getClangServiceByNuclideUri; +exports.getCodeSearchServiceByNuclideUri = getCodeSearchServiceByNuclideUri; +exports.getCtagsServiceByNuclideUri = getCtagsServiceByNuclideUri; +exports.getDefinitionPreviewServiceByNuclideUri = getDefinitionPreviewServiceByNuclideUri; +exports.getFbsimctlServiceByNuclideUri = getFbsimctlServiceByNuclideUri; +exports.getFileSystemServiceByNuclideUri = getFileSystemServiceByNuclideUri; +exports.getFileSystemServiceByConnection = getFileSystemServiceByConnection; +exports.getFileWatcherServiceByNuclideUri = getFileWatcherServiceByNuclideUri; +exports.getFlowServiceByNuclideUri = getFlowServiceByNuclideUri; +exports.getFuzzyFileSearchServiceByNuclideUri = getFuzzyFileSearchServiceByNuclideUri; +exports.awaitGeneratedFileServiceByNuclideUri = awaitGeneratedFileServiceByNuclideUri; +exports.getGrepServiceByNuclideUri = getGrepServiceByNuclideUri; +exports.getHackLanguageForUri = getHackLanguageForUri; +exports.getHgServiceByNuclideUri = getHgServiceByNuclideUri; +exports.getHhvmDebuggerServiceByNuclideUri = getHhvmDebuggerServiceByNuclideUri; +exports.getInfoServiceByNuclideUri = getInfoServiceByNuclideUri; +exports.getMetroServiceByNuclideUri = getMetroServiceByNuclideUri; +exports.getOpenFilesServiceByNuclideUri = getOpenFilesServiceByNuclideUri; +exports.getPythonServiceByNuclideUri = getPythonServiceByNuclideUri; +exports.getPythonServiceByConnection = getPythonServiceByConnection; +exports.getRemoteCommandServiceByNuclideUri = getRemoteCommandServiceByNuclideUri; +exports.getSdbServiceByNuclideUri = getSdbServiceByNuclideUri; +exports.getSocketServiceByNuclideUri = getSocketServiceByNuclideUri; +exports.getSourceControlServiceByNuclideUri = getSourceControlServiceByNuclideUri; +exports.getVSCodeLanguageServiceByConnection = getVSCodeLanguageServiceByConnection; +exports.getVSCodeLanguageServiceByNuclideUri = getVSCodeLanguageServiceByNuclideUri; +exports.getCqueryLSPServiceByConnection = getCqueryLSPServiceByConnection; +exports.getCqueryLSPServiceByNuclideUri = getCqueryLSPServiceByNuclideUri; + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _RemoteConnection; + +function _load_RemoteConnection() { + return _RemoteConnection = require('./RemoteConnection'); +} + +var _RemoteDirectory; + +function _load_RemoteDirectory() { + return _RemoteDirectory = require('./RemoteDirectory'); +} + +var _RemoteFile; + +function _load_RemoteFile() { + return _RemoteFile = require('./RemoteFile'); +} + +var _ServerConnection; + +function _load_ServerConnection() { + return _ServerConnection = require('./ServerConnection'); +} + +var _ConnectionCache; + +function _load_ConnectionCache() { + return _ConnectionCache = require('./ConnectionCache'); +} + +var _SshHandshake; + +function _load_SshHandshake() { + return _SshHandshake = require('./SshHandshake'); +} + +var _serviceManager; + +function _load_serviceManager() { + return _serviceManager = require('./service-manager'); } -export function getBuckServiceByNuclideUri(uri: NuclideUri): BuckService { - return nullthrows(getServiceByNuclideUri('BuckService', uri)); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.RemoteConnection = (_RemoteConnection || _load_RemoteConnection()).RemoteConnection; +exports.RemoteDirectory = (_RemoteDirectory || _load_RemoteDirectory()).RemoteDirectory; +exports.RemoteFile = (_RemoteFile || _load_RemoteFile()).RemoteFile; +exports.ServerConnection = (_ServerConnection || _load_ServerConnection()).ServerConnection; +exports.ConnectionCache = (_ConnectionCache || _load_ConnectionCache()).ConnectionCache; +exports.SshHandshake = (_SshHandshake || _load_SshHandshake()).SshHandshake; +exports.decorateSshConnectionDelegateWithTracking = (_SshHandshake || _load_SshHandshake()).decorateSshConnectionDelegateWithTracking; +exports.getService = (_serviceManager || _load_serviceManager()).getService; +exports.getServiceByConnection = (_serviceManager || _load_serviceManager()).getServiceByConnection; +exports.getServiceByNuclideUri = (_serviceManager || _load_serviceManager()).getServiceByNuclideUri; +exports.getlocalService = (_serviceManager || _load_serviceManager()).getlocalService; /** + * 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. + * + * strict-local + * @format + */ + +function getBigDigClientByNuclideUri(uri) { + const connection = (_ServerConnection || _load_ServerConnection()).ServerConnection.getForUri(uri); + + if (!connection) { + throw new Error(`no server connection for ${uri}`); + } + + return connection.getBigDigClient(); } -export function getClangServiceByNuclideUri(uri: NuclideUri): ClangService { - return nullthrows(getServiceByNuclideUri('ClangService', uri)); +function getBuckServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('BuckService', uri)); } -export function getCodeSearchServiceByNuclideUri( - uri: NuclideUri, -): CodeSearchService { - return nullthrows(getServiceByNuclideUri('CodeSearchService', uri)); +function getClangServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('ClangService', uri)); } -export function getCtagsServiceByNuclideUri(uri: NuclideUri): CtagsService { - return nullthrows(getServiceByNuclideUri('CtagsService', uri)); +function getCodeSearchServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('CodeSearchService', uri)); } -export function getDefinitionPreviewServiceByNuclideUri( - uri: NuclideUri, -): DefinitionPreviewService { - return nullthrows(getServiceByNuclideUri('DefinitionPreviewService', uri)); +function getCtagsServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('CtagsService', uri)); } -export function getFbsimctlServiceByNuclideUri( - uri: NuclideUri, -): FbsimctlService { - return nullthrows(getServiceByNuclideUri('FbsimctlService', uri)); +function getDefinitionPreviewServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('DefinitionPreviewService', uri)); } -export function getFileSystemServiceByNuclideUri( - uri: NuclideUri, -): FileSystemService { - return nullthrows(getServiceByNuclideUri('FileSystemService', uri)); +function getFbsimctlServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('FbsimctlService', uri)); } -export function getFileSystemServiceByConnection( - connection: ?ServerConnection, -): FileSystemService { - return nullthrows(getServiceByConnection('FileSystemService', connection)); +function getFileSystemServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('FileSystemService', uri)); } -export function getFileWatcherServiceByNuclideUri( - uri: NuclideUri, -): FileWatcherService { - return nullthrows(getServiceByNuclideUri('FileWatcherService', uri)); +function getFileSystemServiceByConnection(connection) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByConnection)('FileSystemService', connection)); } -export function getFlowServiceByNuclideUri(uri: NuclideUri): FlowService { - return nullthrows(getServiceByNuclideUri('FlowService', uri)); +function getFileWatcherServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('FileWatcherService', uri)); } -export function getFuzzyFileSearchServiceByNuclideUri( - uri: NuclideUri, -): FuzzyFileSearchService { - return nullthrows(getServiceByNuclideUri('FuzzyFileSearchService', uri)); +function getFlowServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('FlowService', uri)); } -export function awaitGeneratedFileServiceByNuclideUri( - uri: NuclideUri, -): Promise { - return awaitServiceByNuclideUri('GeneratedFileService', uri).then(nullthrows); +function getFuzzyFileSearchServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('FuzzyFileSearchService', uri)); } -export function getGrepServiceByNuclideUri(uri: NuclideUri): GrepService { - return nullthrows(getServiceByNuclideUri('GrepService', uri)); +function awaitGeneratedFileServiceByNuclideUri(uri) { + return (0, (_serviceManager || _load_serviceManager()).awaitServiceByNuclideUri)('GeneratedFileService', uri).then((_nullthrows || _load_nullthrows()).default); } -export function getHackLanguageForUri(uri: NuclideUri): HackService { - return nullthrows(getServiceByNuclideUri('HackService', uri)); +function getGrepServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('GrepService', uri)); } -export function getHgServiceByNuclideUri(uri: NuclideUri): HgService { - return nullthrows(getServiceByNuclideUri('HgService', uri)); +function getHackLanguageForUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('HackService', uri)); } -export function getHhvmDebuggerServiceByNuclideUri( - uri: NuclideUri, -): HhvmDebuggerService { - return nullthrows(getServiceByNuclideUri('HhvmDebuggerService', uri)); +function getHgServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('HgService', uri)); } -export function getInfoServiceByNuclideUri(uri: NuclideUri): InfoService { - return nullthrows(getServiceByNuclideUri('InfoService', uri)); +function getHhvmDebuggerServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('HhvmDebuggerService', uri)); } -export function getMetroServiceByNuclideUri(uri: NuclideUri): MetroService { - return nullthrows(getServiceByNuclideUri('MetroService', uri)); +function getInfoServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('InfoService', uri)); } -export function getOpenFilesServiceByNuclideUri( - uri: NuclideUri, -): OpenFilesService { - return nullthrows(getServiceByNuclideUri('OpenFilesService', uri)); +function getMetroServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('MetroService', uri)); } -export function getPythonServiceByNuclideUri(uri: NuclideUri): PythonService { - return nullthrows(getServiceByNuclideUri('PythonService', uri)); +function getOpenFilesServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('OpenFilesService', uri)); } -export function getPythonServiceByConnection( - connection: ?ServerConnection, -): PythonService { - return getServiceByConnection('PythonService', connection); +function getPythonServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('PythonService', uri)); } -export function getRemoteCommandServiceByNuclideUri( - uri: NuclideUri, -): RemoteCommandService { - return nullthrows(getServiceByNuclideUri('RemoteCommandService', uri)); +function getPythonServiceByConnection(connection) { + return (0, (_serviceManager || _load_serviceManager()).getServiceByConnection)('PythonService', connection); } -export function getSdbServiceByNuclideUri(uri: NuclideUri): SdbService { - return nullthrows(getServiceByNuclideUri('SdbService', uri)); +function getRemoteCommandServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('RemoteCommandService', uri)); } -export function getSocketServiceByNuclideUri(uri: NuclideUri): SocketService { - return nullthrows(getServiceByNuclideUri('SocketService', uri)); +function getSdbServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('SdbService', uri)); } -export function getSourceControlServiceByNuclideUri( - uri: NuclideUri, -): SourceControlService { - return nullthrows(getServiceByNuclideUri('SourceControlService', uri)); +function getSocketServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('SocketService', uri)); } -export function getVSCodeLanguageServiceByConnection( - connection: ?ServerConnection, -): VSCodeLanguageService { - return nullthrows( - getServiceByConnection('VSCodeLanguageService', connection), - ); +function getSourceControlServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('SourceControlService', uri)); } -export function getVSCodeLanguageServiceByNuclideUri( - uri: NuclideUri, -): VSCodeLanguageService { - return nullthrows(getServiceByNuclideUri('VSCodeLanguageService', uri)); +function getVSCodeLanguageServiceByConnection(connection) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByConnection)('VSCodeLanguageService', connection)); } -export function getCqueryLSPServiceByConnection( - connection: ?ServerConnection, -): CqueryLSPService { - return nullthrows(getServiceByConnection('CqueryLSPService', connection)); +function getVSCodeLanguageServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('VSCodeLanguageService', uri)); } -export function getCqueryLSPServiceByNuclideUri( - uri: NuclideUri, -): CqueryLSPService { - return nullthrows(getServiceByNuclideUri('CqueryLSPService', uri)); +function getCqueryLSPServiceByConnection(connection) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByConnection)('CqueryLSPService', connection)); } + +function getCqueryLSPServiceByNuclideUri(uri) { + return (0, (_nullthrows || _load_nullthrows()).default)((0, (_serviceManager || _load_serviceManager()).getServiceByNuclideUri)('CqueryLSPService', uri)); +} \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/remote-text-buffer.js b/pkg/nuclide-remote-connection/lib/remote-text-buffer.js index 9b3c175a87..dddf2a244e 100644 --- a/pkg/nuclide-remote-connection/lib/remote-text-buffer.js +++ b/pkg/nuclide-remote-connection/lib/remote-text-buffer.js @@ -1,31 +1,54 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.loadBufferForUri = loadBufferForUri; +exports.bufferForUri = bufferForUri; +exports.existingBufferForUri = existingBufferForUri; + +var _atom = require('atom'); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _nuclideFsAtom; + +function _load_nuclideFsAtom() { + return _nuclideFsAtom = require('../../nuclide-fs-atom'); +} + +var _RemoteFile; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; +function _load_RemoteFile() { + return _RemoteFile = require('./RemoteFile'); +} -import invariant from 'assert'; -import {TextBuffer} from 'atom'; -import nuclideUri from 'nuclide-commons/nuclideUri'; +var _ServerConnection; + +function _load_ServerConnection() { + return _ServerConnection = require('./ServerConnection'); +} -import {ROOT_ARCHIVE_FS} from '../../nuclide-fs-atom'; -import {RemoteFile} from './RemoteFile'; -import {ServerConnection} from './ServerConnection'; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const TEXT_BUFFER_PARAMS = { - shouldDestroyOnFileDelete: () => atom.config.get('core.closeDeletedFileTabs'), -}; + shouldDestroyOnFileDelete: () => atom.config.get('core.closeDeletedFileTabs') +}; /** + * 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. + * + * strict-local + * @format + */ -export async function loadBufferForUri( - uri: NuclideUri, -): Promise { +async function loadBufferForUri(uri) { const buffer = existingBufferForUri(uri); if (buffer == null) { return loadBufferForUriStatic(uri).then(loadedBuffer => { @@ -45,28 +68,25 @@ export async function loadBufferForUri( } } -function loadBufferForUriStatic(uri: NuclideUri): Promise { - if (nuclideUri.isLocal(uri)) { - if (nuclideUri.isInArchive(uri)) { - return TextBuffer.load( - ROOT_ARCHIVE_FS.newArchiveFile(uri), - TEXT_BUFFER_PARAMS, - ); +function loadBufferForUriStatic(uri) { + if ((_nuclideUri || _load_nuclideUri()).default.isLocal(uri)) { + if ((_nuclideUri || _load_nuclideUri()).default.isInArchive(uri)) { + return _atom.TextBuffer.load((_nuclideFsAtom || _load_nuclideFsAtom()).ROOT_ARCHIVE_FS.newArchiveFile(uri), TEXT_BUFFER_PARAMS); } else { - return TextBuffer.load(uri, TEXT_BUFFER_PARAMS); + return _atom.TextBuffer.load(uri, TEXT_BUFFER_PARAMS); } } - const connection = ServerConnection.getForUri(uri); + const connection = (_ServerConnection || _load_ServerConnection()).ServerConnection.getForUri(uri); if (connection == null) { throw new Error(`ServerConnection cannot be found for uri: ${uri}`); } - return TextBuffer.load(new RemoteFile(connection, uri), TEXT_BUFFER_PARAMS); + return _atom.TextBuffer.load(new (_RemoteFile || _load_RemoteFile()).RemoteFile(connection, uri), TEXT_BUFFER_PARAMS); } /** * Returns an existing buffer for that uri, or create one if not existing. */ -export function bufferForUri(uri: NuclideUri): atom$TextBuffer { +function bufferForUri(uri) { const buffer = existingBufferForUri(uri); if (buffer != null) { return buffer; @@ -74,33 +94,36 @@ export function bufferForUri(uri: NuclideUri): atom$TextBuffer { return createBufferForUri(uri); } -function createBufferForUri(uri: NuclideUri): atom$TextBuffer { +function createBufferForUri(uri) { let buffer; - const params = { - ...TEXT_BUFFER_PARAMS, - filePath: uri, - }; - if (nuclideUri.isLocal(uri)) { - buffer = new TextBuffer(params); - if (nuclideUri.isInArchive(uri)) { - buffer.setFile(ROOT_ARCHIVE_FS.newArchiveFile(uri)); + const params = Object.assign({}, TEXT_BUFFER_PARAMS, { + filePath: uri + }); + if ((_nuclideUri || _load_nuclideUri()).default.isLocal(uri)) { + buffer = new _atom.TextBuffer(params); + if ((_nuclideUri || _load_nuclideUri()).default.isInArchive(uri)) { + buffer.setFile((_nuclideFsAtom || _load_nuclideFsAtom()).ROOT_ARCHIVE_FS.newArchiveFile(uri)); } } else { - const connection = ServerConnection.getForUri(uri); + const connection = (_ServerConnection || _load_ServerConnection()).ServerConnection.getForUri(uri); if (connection == null) { throw new Error(`ServerConnection cannot be found for uri: ${uri}`); } - buffer = new TextBuffer(params); - buffer.setFile(new RemoteFile(connection, uri)); + buffer = new _atom.TextBuffer(params); + buffer.setFile(new (_RemoteFile || _load_RemoteFile()).RemoteFile(connection, uri)); } atom.project.addBuffer(buffer); - invariant(buffer); + + if (!buffer) { + throw new Error('Invariant violation: "buffer"'); + } + return buffer; } /** * Returns an exsting buffer for that uri, or null if not existing. */ -export function existingBufferForUri(uri: NuclideUri): ?atom$TextBuffer { +function existingBufferForUri(uri) { return atom.project.findBufferForPath(uri); -} +} \ No newline at end of file diff --git a/pkg/nuclide-remote-connection/lib/service-manager.js b/pkg/nuclide-remote-connection/lib/service-manager.js index 982440442c..a9983c7104 100644 --- a/pkg/nuclide-remote-connection/lib/service-manager.js +++ b/pkg/nuclide-remote-connection/lib/service-manager.js @@ -1,106 +1,135 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getlocalService = getlocalService; +exports.getServiceByNuclideUri = getServiceByNuclideUri; +exports.awaitServiceByNuclideUri = awaitServiceByNuclideUri; +exports.getServiceByConnection = getServiceByConnection; +exports.getService = getService; +exports.awaitService = awaitService; + +var _fs = _interopRequireDefault(require('fs')); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _IpcTransports; + +function _load_IpcTransports() { + return _IpcTransports = require('./IpcTransports'); +} + +var _ServerConnection; + +function _load_ServerConnection() { + return _ServerConnection = require('./ServerConnection'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _runtimeInfo; + +function _load_runtimeInfo() { + return _runtimeInfo = require('../../commons-node/runtime-info'); +} + +var _serverPort; + +function _load_serverPort() { + return _serverPort = require('../../../modules/nuclide-commons/serverPort'); +} + +var _servicesConfig; + +function _load_servicesConfig() { + return _servicesConfig = _interopRequireDefault(require('../../nuclide-server/lib/servicesConfig')); +} + +var _nuclideRpc; + +function _load_nuclideRpc() { + return _nuclideRpc = require('../../nuclide-rpc'); +} + +var _nuclideMarshalersAtom; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {Transport} from '../../nuclide-rpc'; - -import invariant from 'assert'; -import fs from 'fs'; -import {Observable} from 'rxjs'; -import {IpcClientTransport} from './IpcTransports'; -import {ServerConnection} from './ServerConnection'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {fork, spawn, getOriginalEnvironment} from 'nuclide-commons/process'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {__DEV__} from '../../commons-node/runtime-info'; -import {getAvailableServerPort} from 'nuclide-commons/serverPort'; -import servicesConfig from '../../nuclide-server/lib/servicesConfig'; -import {RpcConnection} from '../../nuclide-rpc'; -import {getAtomSideLoopbackMarshalers} from '../../nuclide-marshalers-atom'; +function _load_nuclideMarshalersAtom() { + return _nuclideMarshalersAtom = require('../../nuclide-marshalers-atom'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // This code may be executed before the config has been loaded! // getWithDefaults is necessary to make sure that the default is 'true'. // (But not in tests, as it's slow to start it up every time.) // We disable this on Windows until fork gets fixed. -const useLocalRpc = - Boolean(featureConfig.getWithDefaults('useLocalRpc', !atom.inSpecMode())) && - process.platform !== 'win32'; -let localRpcClient: ?RpcConnection = null; +const useLocalRpc = Boolean((_featureConfig || _load_featureConfig()).default.getWithDefaults('useLocalRpc', !atom.inSpecMode())) && process.platform !== 'win32'; /** + * 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. + * + * + * @format + */ + +let localRpcClient = null; // Creates a local RPC client that connects to a separate process. -function createLocalRpcClient(): RpcConnection { +function createLocalRpcClient() { // The Electron Node process won't support --inspect until v1.7.x. // In the meantime, try to find a more standard Node process. - const fbNodeRun = nuclideUri.join( - __dirname, - '../../commons-node/fb-node-run.sh', - ); + const fbNodeRun = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../../commons-node/fb-node-run.sh'); const spawnOptions = { killTreeWhenDone: true, - stdio: ['pipe', 'pipe', 'pipe', 'pipe', 'ipc'], + stdio: ['pipe', 'pipe', 'pipe', 'pipe', 'ipc'] }; // We cannot synchronously spawn the process here due to the shell environment. // process.js will wait for Atom's shell environment to become ready. - const localServerProcess = - __DEV__ && fs.existsSync(fbNodeRun) && process.platform !== 'win32' - ? Observable.defer(() => - Promise.all([getAvailableServerPort(), getOriginalEnvironment()]), - ) - .do(([port]) => { - // eslint-disable-next-line no-console - console.log(`Starting local RPC process with --inspect=${port}`); - }) - .switchMap(([port, env]) => - spawn( - fbNodeRun, - [ - 'node', - // Electron v1.7.x will also allow --inspect=0. - `--inspect=${port}`, - '--require', - require.resolve('../../commons-node/load-transpiler'), - require.resolve('./LocalRpcServer'), - ], - spawnOptions, - ), - ) - : fork( - '--require', - [ - require.resolve('../../commons-node/load-transpiler'), - require.resolve('./LocalRpcServer'), - ], - spawnOptions, - ); - - const transport = new IpcClientTransport(localServerProcess); - return RpcConnection.createLocal( - transport, - getAtomSideLoopbackMarshalers, - servicesConfig, - ); -} - -export function getlocalService(serviceName: string): Object { + const localServerProcess = (_runtimeInfo || _load_runtimeInfo()).__DEV__ && _fs.default.existsSync(fbNodeRun) && process.platform !== 'win32' ? _rxjsBundlesRxMinJs.Observable.defer(() => Promise.all([(0, (_serverPort || _load_serverPort()).getAvailableServerPort)(), (0, (_process || _load_process()).getOriginalEnvironment)()])).do(([port]) => { + // eslint-disable-next-line no-console + console.log(`Starting local RPC process with --inspect=${port}`); + }).switchMap(([port, env]) => (0, (_process || _load_process()).spawn)(fbNodeRun, ['node', + // Electron v1.7.x will also allow --inspect=0. + `--inspect=${port}`, '--require', require.resolve('../../commons-node/load-transpiler'), require.resolve('./LocalRpcServer')], spawnOptions)) : (0, (_process || _load_process()).fork)('--require', [require.resolve('../../commons-node/load-transpiler'), require.resolve('./LocalRpcServer')], spawnOptions); + + const transport = new (_IpcTransports || _load_IpcTransports()).IpcClientTransport(localServerProcess); + return (_nuclideRpc || _load_nuclideRpc()).RpcConnection.createLocal(transport, (_nuclideMarshalersAtom || _load_nuclideMarshalersAtom()).getAtomSideLoopbackMarshalers, (_servicesConfig || _load_servicesConfig()).default); +} + +function getlocalService(serviceName) { if (useLocalRpc) { if (localRpcClient == null) { localRpcClient = createLocalRpcClient(); } return localRpcClient.getService(serviceName); } else { - const [serviceConfig] = servicesConfig.filter( - config => config.name === serviceName, - ); - invariant(serviceConfig, `No config found for service ${serviceName}`); + const [serviceConfig] = (_servicesConfig || _load_servicesConfig()).default.filter(config => config.name === serviceName); + + if (!serviceConfig) { + throw new Error(`No config found for service ${serviceName}`); + } // $FlowIgnore + + return require(serviceConfig.implementation); } } @@ -111,11 +140,8 @@ export function getlocalService(serviceName: string): Object { * `nuclide://$host/$path`. The function will use the $host from remote path to * create a remote service or create a local service if the uri is local path. */ -export function getServiceByNuclideUri( - serviceName: string, - uri: ?NuclideUri = null, -): ?any { - const hostname = nuclideUri.getHostnameOpt(uri); +function getServiceByNuclideUri(serviceName, uri = null) { + const hostname = (_nuclideUri || _load_nuclideUri()).default.getHostnameOpt(uri); return getService(serviceName, hostname); } @@ -125,11 +151,8 @@ export function getServiceByNuclideUri( * `nuclide://$host/$path`. The function will use the $host from remote path to * create a remote service or create a local service if the uri is local path. */ -export function awaitServiceByNuclideUri( - serviceName: string, - uri: ?NuclideUri = null, -): Promise { - const hostname = nuclideUri.getHostnameOpt(uri); +function awaitServiceByNuclideUri(serviceName, uri = null) { + const hostname = (_nuclideUri || _load_nuclideUri()).default.getHostnameOpt(uri); return awaitService(serviceName, hostname); } @@ -137,10 +160,7 @@ export function awaitServiceByNuclideUri( * Create or get cached service. * null connection implies get local service. */ -export function getServiceByConnection( - serviceName: string, - connection: ?ServerConnection, -): Object { +function getServiceByConnection(serviceName, connection) { if (connection == null) { return getlocalService(serviceName); } else { @@ -152,9 +172,9 @@ export function getServiceByConnection( * Create or get a cached service. If hostname is null or empty string, * it returns a local service, otherwise a remote service will be returned. */ -export function getService(serviceName: string, hostname: ?string): ?Object { +function getService(serviceName, hostname) { if (hostname != null && hostname !== '') { - const serverConnection = ServerConnection.getByHostname(hostname); + const serverConnection = (_ServerConnection || _load_ServerConnection()).ServerConnection.getByHostname(hostname); if (serverConnection == null) { return null; } @@ -168,16 +188,10 @@ export function getService(serviceName: string, hostname: ?string): ?Object { * Asynchronously create or get a cached service. If hostname is null or empty * string, it returns a local service, otherwise a remote service will be returned. */ -export function awaitService( - serviceName: string, - hostname: ?string, -): Promise { +function awaitService(serviceName, hostname) { if (hostname != null && hostname !== '') { - return ServerConnection.connectionAddedToHost(hostname) - .first() - .toPromise() - .then(serverConnection => serverConnection.getService(serviceName)); + return (_ServerConnection || _load_ServerConnection()).ServerConnection.connectionAddedToHost(hostname).first().toPromise().then(serverConnection => serverConnection.getService(serviceName)); } else { return Promise.resolve(getlocalService(serviceName)); } -} +} \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/AtomNotifications.js b/pkg/nuclide-remote-projects/lib/AtomNotifications.js index ac2a0cf11a..1c4292af5d 100644 --- a/pkg/nuclide-remote-projects/lib/AtomNotifications.js +++ b/pkg/nuclide-remote-projects/lib/AtomNotifications.js @@ -1,29 +1,27 @@ -/** - * 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 strict - * @format - */ +"use strict"; -type raiseNativeNotificationFunc = ?( - title: string, - body: string, - timeout: number, - raiseIfAtomHasFocus: boolean, -) => ?IDisposable; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.setNotificationService = setNotificationService; +exports.getNotificationService = getNotificationService; -let _raiseNativeNotification: ?raiseNativeNotificationFunc = null; -export function setNotificationService( - raiseNativeNotification: raiseNativeNotificationFunc, -): void { +let _raiseNativeNotification = null; /** + * 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. + * + * strict + * @format + */ + +function setNotificationService(raiseNativeNotification) { _raiseNativeNotification = raiseNativeNotification; } -export function getNotificationService(): ?raiseNativeNotificationFunc { +function getNotificationService() { return _raiseNativeNotification; -} +} \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/AuthenticationPrompt.js b/pkg/nuclide-remote-projects/lib/AuthenticationPrompt.js index 610323e414..800a83e780 100644 --- a/pkg/nuclide-remote-projects/lib/AuthenticationPrompt.js +++ b/pkg/nuclide-remote-projects/lib/AuthenticationPrompt.js @@ -1,3 +1,34 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _AtomNotifications; + +function _load_AtomNotifications() { + return _AtomNotifications = require('./AtomNotifications'); +} + +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 }; } + +/** Component to prompt the user for authentication information. */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,110 +36,84 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import nullthrows from 'nullthrows'; -import * as React from 'react'; -import {getNotificationService} from './AtomNotifications'; +class AuthenticationPrompt extends _react.Component { -type Props = { - instructions: string, - onConfirm: () => mixed, - onCancel: () => mixed, -}; + constructor(props) { + super(props); -/** Component to prompt the user for authentication information. */ -export default class AuthenticationPrompt extends React.Component { - props: Props; + this._onKeyUp = e => { + if (e.key === 'Enter') { + this.props.onConfirm(); + } - _disposables: UniversalDisposable; - _password: ?HTMLInputElement; - _root: ?HTMLElement; + if (e.key === 'Escape') { + this.props.onCancel(); + } + }; - constructor(props: Props) { - super(props); - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - componentDidMount(): void { + componentDidMount() { // Hitting enter when this panel has focus should confirm the dialog. - this._disposables.add( - atom.commands.add(nullthrows(this._root), 'core:confirm', event => - this.props.onConfirm(), - ), - ); + this._disposables.add(atom.commands.add((0, (_nullthrows || _load_nullthrows()).default)(this._root), 'core:confirm', event => this.props.onConfirm())); // Hitting escape should cancel the dialog. - this._disposables.add( - atom.commands.add('atom-workspace', 'core:cancel', event => - this.props.onCancel(), - ), - ); + this._disposables.add(atom.commands.add('atom-workspace', 'core:cancel', event => this.props.onCancel())); - nullthrows(this._password).focus(); + (0, (_nullthrows || _load_nullthrows()).default)(this._password).focus(); - const raiseNativeNotification = getNotificationService(); + const raiseNativeNotification = (0, (_AtomNotifications || _load_AtomNotifications()).getNotificationService)(); if (raiseNativeNotification != null) { - const pendingNotification = raiseNativeNotification( - 'Nuclide Remote Connection', - 'Nuclide requires additional action to authenticate your remote connection', - 2000, - false, - ); + const pendingNotification = raiseNativeNotification('Nuclide Remote Connection', 'Nuclide requires additional action to authenticate your remote connection', 2000, false); if (pendingNotification != null) { this._disposables.add(pendingNotification); } } } - componentWillUnmount(): void { + componentWillUnmount() { this._disposables.dispose(); } - focus(): void { - nullthrows(this._password).focus(); + focus() { + (0, (_nullthrows || _load_nullthrows()).default)(this._password).focus(); } - getPassword(): string { - return nullthrows(this._password).value; + getPassword() { + return (0, (_nullthrows || _load_nullthrows()).default)(this._password).value; } - _onKeyUp = (e: SyntheticKeyboardEvent<>): void => { - if (e.key === 'Enter') { - this.props.onConfirm(); - } - - if (e.key === 'Escape') { - this.props.onCancel(); - } - }; - - render(): React.Node { + render() { // * Need native-key-bindings so that delete works and we need `_onKeyUp` so that escape and // enter work // * `instructions` are pre-formatted, so apply `whiteSpace: pre` to maintain formatting coming // from the server. - return ( -
    { + return _react.createElement( + 'div', + { + ref: el => { this._root = el; - }}> -
    - {this.props.instructions} -
    - { - this._password = el; - }} - onKeyPress={this._onKeyUp} - /> -
    + } }, + _react.createElement( + 'div', + { className: 'block', style: { whiteSpace: 'pre' } }, + this.props.instructions + ), + _react.createElement('input', { + tabIndex: '0', + type: 'password', + className: 'nuclide-password native-key-bindings', + ref: el => { + this._password = el; + }, + onKeyPress: this._onKeyUp + }) ); } } +exports.default = AuthenticationPrompt; \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/ConnectionDetailsForm.js b/pkg/nuclide-remote-projects/lib/ConnectionDetailsForm.js index 803ea3fe70..e75b9bead5 100644 --- a/pkg/nuclide-remote-projects/lib/ConnectionDetailsForm.js +++ b/pkg/nuclide-remote-projects/lib/ConnectionDetailsForm.js @@ -1,3 +1,65 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _connectionProfileUtils; + +function _load_connectionProfileUtils() { + return _connectionProfileUtils = require('./connection-profile-utils'); +} + +var _addTooltip; + +function _load_addTooltip() { + return _addTooltip = _interopRequireDefault(require('../../../modules/nuclide-commons-ui/addTooltip')); +} + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../../../modules/nuclide-commons-ui/AtomInput'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _lookupPreferIpV; + +function _load_lookupPreferIpV() { + return _lookupPreferIpV = _interopRequireDefault(require('../../nuclide-remote-connection/lib/lookup-prefer-ip-v6')); +} + +var _RadioGroup; + +function _load_RadioGroup() { + return _RadioGroup = _interopRequireDefault(require('../../../modules/nuclide-commons-ui/RadioGroup')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _reactDom = _interopRequireDefault(require('react-dom')); + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,83 +67,62 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {DnsLookup} from '../../nuclide-remote-connection/lib/lookup-prefer-ip-v6'; -import type {SshHandshakeAuthMethodsType} from '../../nuclide-remote-connection/lib/SshHandshake'; -import type {NuclideRemoteConnectionParamsWithPassword} from './connection-types'; - -import {getOfficialRemoteServerCommand} from './connection-profile-utils'; - -import addTooltip from 'nuclide-commons-ui/addTooltip'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import nullthrows from 'nullthrows'; -import {getIPsForHosts} from './connection-profile-utils'; -import lookupPreferIpv6 from '../../nuclide-remote-connection/lib/lookup-prefer-ip-v6'; -import RadioGroup from 'nuclide-commons-ui/RadioGroup'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import {SshHandshake} from '../../nuclide-remote-connection'; - -const {SupportedMethods} = SshHandshake; -const authMethods: Array = [ - SupportedMethods.PASSWORD, - SupportedMethods.SSL_AGENT, - SupportedMethods.PRIVATE_KEY, -]; - -type Props = { - className?: string, - initialUsername: string, - initialServer: string, - initialCwd: string, - initialRemoteServerCommand: string, - initialSshPort: string, - initialPathToPrivateKey: string, - initialAuthMethod: SshHandshakeAuthMethodsType, - initialDisplayTitle: string, - onCancel: () => mixed, - onConfirm: () => mixed, - onDidChange: () => mixed, - needsPasswordValue: boolean, - profileHosts: ?Array, -}; - -type State = { - cwd: string, - displayTitle: string, - IPs: ?Promise>, - pathToPrivateKey: string, - remoteServerCommand: string, - selectedAuthMethodIndex: number, - server: string, - shouldDisplayTooltipWarning: boolean, - sshPort: string, - username: string, -}; +const { SupportedMethods } = (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).SshHandshake; +const authMethods = [SupportedMethods.PASSWORD, SupportedMethods.SSL_AGENT, SupportedMethods.PRIVATE_KEY]; /** Component to prompt the user for connection details. */ -export default class ConnectionDetailsForm extends React.Component< - Props, - State, -> { - _disposables: ?UniversalDisposable; - _promptChanged: boolean; - - _cwd: ?AtomInput; - _username: ?AtomInput; - _password: ?HTMLInputElement; - _pathToPrivateKey: ?AtomInput; - _remoteServerCommand: ?AtomInput; - _server: ?AtomInput; - _sshPort: ?AtomInput; - - constructor(props: Props) { +class ConnectionDetailsForm extends _react.Component { + + constructor(props) { super(props); + this._handleAuthMethodChange = newIndex => { + this.props.onDidChange(); + this.setState({ + selectedAuthMethodIndex: newIndex + }); + }; + + this._handleInputDidChange = () => { + this.props.onDidChange(); + }; + + this._handleInputDidChangeForServer = () => { + // If the input changed due to a higher level change in the + // ConnectionDetailsPrompt, don't check for host collisions + if (!this._promptChanged) { + this._checkForHostCollisions(this._getText(this._server)); + this.props.onDidChange(); + } + this._promptChanged = false; + }; + + this._handleKeyFileInputClick = event => { + const privateKeyAuthMethodIndex = authMethods.indexOf(SupportedMethods.PRIVATE_KEY); + this.setState({ + selectedAuthMethodIndex: privateKeyAuthMethodIndex + }, () => { + // when setting this immediately, Atom will unset the focus... + setTimeout(() => { + // $FlowFixMe + _reactDom.default.findDOMNode(this._pathToPrivateKey).focus(); + }, 0); + }); + }; + + this._handlePasswordInputClick = event => { + const passwordAuthMethodIndex = authMethods.indexOf(SupportedMethods.PASSWORD); + this.setState({ + selectedAuthMethodIndex: passwordAuthMethodIndex + }, () => { + (0, (_nullthrows || _load_nullthrows()).default)(this._password).focus(); + }); + }; + this._promptChanged = false; this.state = { username: props.initialUsername, @@ -93,11 +134,11 @@ export default class ConnectionDetailsForm extends React.Component< selectedAuthMethodIndex: authMethods.indexOf(props.initialAuthMethod), displayTitle: props.initialDisplayTitle, IPs: null, - shouldDisplayTooltipWarning: false, + shouldDisplayTooltipWarning: false }; } - _onKeyPress(e: SyntheticKeyboardEvent<>): void { + _onKeyPress(e) { if (e.key === 'Enter') { this.props.onConfirm(); } @@ -107,72 +148,19 @@ export default class ConnectionDetailsForm extends React.Component< } } - _handleAuthMethodChange = (newIndex: number) => { - this.props.onDidChange(); - this.setState({ - selectedAuthMethodIndex: newIndex, - }); - }; - - _handleInputDidChange = (): void => { - this.props.onDidChange(); - }; - - _handleInputDidChangeForServer = () => { - // If the input changed due to a higher level change in the - // ConnectionDetailsPrompt, don't check for host collisions - if (!this._promptChanged) { - this._checkForHostCollisions(this._getText(this._server)); - this.props.onDidChange(); - } - this._promptChanged = false; - }; - - _handleKeyFileInputClick = (event: SyntheticEvent<>): void => { - const privateKeyAuthMethodIndex = authMethods.indexOf( - SupportedMethods.PRIVATE_KEY, - ); - this.setState( - { - selectedAuthMethodIndex: privateKeyAuthMethodIndex, - }, - () => { - // when setting this immediately, Atom will unset the focus... - setTimeout(() => { - // $FlowFixMe - ReactDOM.findDOMNode(this._pathToPrivateKey).focus(); - }, 0); - }, - ); - }; - - _handlePasswordInputClick = (event: SyntheticEvent<>): void => { - const passwordAuthMethodIndex = authMethods.indexOf( - SupportedMethods.PASSWORD, - ); - this.setState( - { - selectedAuthMethodIndex: passwordAuthMethodIndex, - }, - () => { - nullthrows(this._password).focus(); - }, - ); - }; - - async _checkForHostCollisions(hostName: string) { + async _checkForHostCollisions(hostName) { const uniqueHosts = this.props.profileHosts; if (uniqueHosts == null || this.state.IPs == null) { return; } const IPs = await this.state.IPs; - const ip = await lookupPreferIpv6(hostName).catch(() => { + const ip = await (0, (_lookupPreferIpV || _load_lookupPreferIpV()).default)(hostName).catch(() => { return; }); let shouldDisplayWarning = false; if (ip == null) { if (this.state.shouldDisplayTooltipWarning) { - this.setState({shouldDisplayTooltipWarning: false}); + this.setState({ shouldDisplayTooltipWarning: false }); } } else { for (let i = 0; i < uniqueHosts.length; i++) { @@ -183,184 +171,216 @@ export default class ConnectionDetailsForm extends React.Component< } } if (this.state.shouldDisplayTooltipWarning !== shouldDisplayWarning) { - this.setState({shouldDisplayTooltipWarning: shouldDisplayWarning}); + this.setState({ shouldDisplayTooltipWarning: shouldDisplayWarning }); } } } - render(): React.Node { - const {className, needsPasswordValue} = this.props; + render() { + const { className, needsPasswordValue } = this.props; const activeAuthMethod = authMethods[this.state.selectedAuthMethodIndex]; // We need native-key-bindings so that delete works and we need // _onKeyPress so that escape and enter work const passwordLabelName = 'Password' + (needsPasswordValue ? ':' : ''); - const passwordLabel = ( -
    -
    {passwordLabelName}
    - {needsPasswordValue ? ( -
    - { - this._password = el; - }} - /> -
    - ) : null} -
    + const passwordLabel = _react.createElement( + 'div', + { className: 'nuclide-auth-method' }, + _react.createElement( + 'div', + { className: 'nuclide-auth-method-label' }, + passwordLabelName + ), + needsPasswordValue ? _react.createElement( + 'div', + { + className: 'nuclide-auth-method-input nuclide-auth-method-password', + onClick: this._handlePasswordInputClick }, + _react.createElement('input', { + type: 'password', + className: 'nuclide-password native-key-bindings', + disabled: activeAuthMethod !== SupportedMethods.PASSWORD, + onChange: this._handleInputDidChange, + onKeyPress: this._onKeyPress.bind(this), + ref: el => { + this._password = el; + } + }) + ) : null ); - const privateKeyLabel = ( -
    -
    Private Key File:
    -
    - { - this._pathToPrivateKey = input; - }} - unstyled={true} - /> -
    -
    + const privateKeyLabel = _react.createElement( + 'div', + { className: 'nuclide-auth-method' }, + _react.createElement( + 'div', + { className: 'nuclide-auth-method-label' }, + 'Private Key File:' + ), + _react.createElement( + 'div', + { className: 'nuclide-auth-method-input nuclide-auth-method-privatekey' }, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + disabled: activeAuthMethod !== SupportedMethods.PRIVATE_KEY, + initialValue: this.state.pathToPrivateKey, + onClick: this._handleKeyFileInputClick, + onDidChange: this._handleInputDidChange, + placeholder: 'Path to private key', + ref: input => { + this._pathToPrivateKey = input; + }, + unstyled: true + }) + ) ); - const sshAgentLabel = ( -
    Use ssh-agent
    + const sshAgentLabel = _react.createElement( + 'div', + { className: 'nuclide-auth-method' }, + 'Use ssh-agent' ); let toolTipWarning; if (this.state.shouldDisplayTooltipWarning) { - toolTipWarning = ( - - ); + toolTipWarning = _react.createElement('span', { + style: { paddingLeft: 10 }, + className: 'icon icon-info pull-right nuclide-remote-projects-tooltip-warning' + // eslint-disable-next-line nuclide-internal/jsx-simple-callback-refs + , ref: (0, (_addTooltip || _load_addTooltip()).default)({ + // Intentionally *not* an arrow function so the jQuery + // Tooltip plugin can set the context to the Tooltip + // instance. + placement() { + // Atom modals have z indices of 9999. This Tooltip needs + // to stack on top of the modal; beat the modal's z-index. + this.tip.style.zIndex = 10999; + return 'right'; + }, + title: 'One of your profiles uses a host name that resolves to the' + ' same IP as this one. Consider using the uniform host ' + 'name to avoid potential collisions.' + }) + }); } - return ( -
    -
    - - { - this._username = input; - }} - unstyled={true} - /> -
    -
    -
    - - { - this._server = input; - }} - unstyled={true} - /> -
    -
    - - { - this._sshPort = input; - }} - unstyled={true} - /> -
    -
    -
    - - { - this._cwd = input; - }} - unstyled={true} - /> -
    -
    - - -
    -
    - - { - this._remoteServerCommand = input; - }} - unstyled={true} - /> -
    -
    + return _react.createElement( + 'div', + { className: className }, + _react.createElement( + 'div', + { className: 'form-group' }, + _react.createElement( + 'label', + null, + 'Username:' + ), + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + initialValue: this.state.username, + onDidChange: this._handleInputDidChange, + ref: input => { + this._username = input; + }, + unstyled: true + }) + ), + _react.createElement( + 'div', + { className: 'form-group nuclide-auth-server-group' }, + _react.createElement( + 'div', + { className: 'nuclide-auth-server' }, + _react.createElement( + 'label', + null, + 'Server:', + toolTipWarning + ), + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + initialValue: this.state.server, + onDidChange: this._handleInputDidChangeForServer, + ref: input => { + this._server = input; + }, + unstyled: true + }) + ), + _react.createElement( + 'div', + { className: 'col-xs-3' }, + _react.createElement( + 'label', + null, + 'SSH Port:' + ), + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + initialValue: this.state.sshPort, + onDidChange: this._handleInputDidChange, + ref: input => { + this._sshPort = input; + }, + unstyled: true + }) + ) + ), + _react.createElement( + 'div', + { className: 'form-group' }, + _react.createElement( + 'label', + null, + 'Initial Directory:' + ), + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + initialValue: this.state.cwd, + onDidChange: this._handleInputDidChange, + ref: input => { + this._cwd = input; + }, + unstyled: true + }) + ), + _react.createElement( + 'div', + { className: 'form-group' }, + _react.createElement( + 'label', + null, + 'Authentication method:' + ), + _react.createElement((_RadioGroup || _load_RadioGroup()).default, { + optionLabels: [passwordLabel, sshAgentLabel, privateKeyLabel], + onSelectedChange: this._handleAuthMethodChange, + selectedIndex: this.state.selectedAuthMethodIndex + }) + ), + _react.createElement( + 'div', + { className: 'form-group' }, + _react.createElement( + 'label', + null, + 'Remote Server Command:' + ), + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + initialValue: this.state.remoteServerCommand, + onDidChange: this._handleInputDidChange, + ref: input => { + this._remoteServerCommand = input; + }, + unstyled: true + }) + ) ); } componentDidMount() { - const disposables = new UniversalDisposable(); + const disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._disposables = disposables; - const root = ReactDOM.findDOMNode(this); + const root = _reactDom.default.findDOMNode(this); // Hitting enter when this panel has focus should confirm the dialog. - disposables.add( - atom.commands.add( - // $FlowFixMe - root, - 'core:confirm', - event => this.props.onConfirm(), - ), - ); + disposables.add(atom.commands.add( + // $FlowFixMe + root, 'core:confirm', event => this.props.onConfirm())); // Hitting escape should cancel the dialog. - disposables.add( - atom.commands.add('atom-workspace', 'core:cancel', event => - this.props.onCancel(), - ), - ); + disposables.add(atom.commands.add('atom-workspace', 'core:cancel', event => this.props.onCancel())); if (this.props.profileHosts) { - this.setState({IPs: getIPsForHosts(this.props.profileHosts)}); + this.setState({ IPs: (0, (_connectionProfileUtils || _load_connectionProfileUtils()).getIPsForHosts)(this.props.profileHosts) }); } } @@ -371,37 +391,26 @@ export default class ConnectionDetailsForm extends React.Component< } } - getFormFields(): NuclideRemoteConnectionParamsWithPassword { + getFormFields() { return { username: this._getText(this._username), server: this._getText(this._server), cwd: this._getText(this._cwd), - remoteServerCommand: - this._getText(this._remoteServerCommand) || - getOfficialRemoteServerCommand(), + remoteServerCommand: this._getText(this._remoteServerCommand) || (0, (_connectionProfileUtils || _load_connectionProfileUtils()).getOfficialRemoteServerCommand)(), sshPort: this._getText(this._sshPort), pathToPrivateKey: this._getText(this._pathToPrivateKey), authMethod: this._getAuthMethod(), password: this._getPassword(), - displayTitle: this.state.displayTitle, + displayTitle: this.state.displayTitle }; } - focus(): void { - nullthrows(this._username).focus(); + focus() { + (0, (_nullthrows || _load_nullthrows()).default)(this._username).focus(); } // Note: 'password' is not settable. The only exposed method is 'clearPassword'. - setFormFields(fields: { - username?: string, - server?: string, - cwd?: string, - remoteServerCommand?: string, - sshPort?: string, - pathToPrivateKey?: string, - authMethod?: SshHandshakeAuthMethodsType, - displayTitle?: string, - }): void { + setFormFields(fields) { this._setText(this._username, fields.username); this._setText(this._server, fields.server); this._setText(this._cwd, fields.cwd); @@ -411,14 +420,14 @@ export default class ConnectionDetailsForm extends React.Component< this._setAuthMethod(fields.authMethod); // `displayTitle` is not editable and therefore has no ``. Its value is // stored only in local state. - this.setState({displayTitle: fields.displayTitle}); + this.setState({ displayTitle: fields.displayTitle }); } - _getText(atomInput: ?AtomInput): string { - return (atomInput && atomInput.getText().trim()) || ''; + _getText(atomInput) { + return atomInput && atomInput.getText().trim() || ''; } - _setText(atomInput: ?AtomInput, text: ?string): void { + _setText(atomInput, text) { if (text == null) { return; } @@ -427,33 +436,34 @@ export default class ConnectionDetailsForm extends React.Component< } } - _getAuthMethod(): SshHandshakeAuthMethodsType { + _getAuthMethod() { return authMethods[this.state.selectedAuthMethodIndex]; } - _setAuthMethod(authMethod: ?SshHandshakeAuthMethodsType): void { + _setAuthMethod(authMethod) { if (authMethod == null) { return; } const newIndex = authMethods.indexOf(authMethod); if (newIndex >= 0) { - this.setState({selectedAuthMethodIndex: newIndex}); + this.setState({ selectedAuthMethodIndex: newIndex }); } } - _getPassword(): string { - return (this._password && this._password.value) || ''; + _getPassword() { + return this._password && this._password.value || ''; } - clearPassword(): void { + clearPassword() { const passwordInput = this._password; if (passwordInput) { passwordInput.value = ''; } } - promptChanged(): void { + promptChanged() { this._promptChanged = true; - this.setState({shouldDisplayTooltipWarning: false}); + this.setState({ shouldDisplayTooltipWarning: false }); } } +exports.default = ConnectionDetailsForm; \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/ConnectionDetailsPrompt.js b/pkg/nuclide-remote-projects/lib/ConnectionDetailsPrompt.js index 8f79dba7fe..103db29012 100644 --- a/pkg/nuclide-remote-projects/lib/ConnectionDetailsPrompt.js +++ b/pkg/nuclide-remote-projects/lib/ConnectionDetailsPrompt.js @@ -1,59 +1,56 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _addTooltip; + +function _load_addTooltip() { + return _addTooltip = _interopRequireDefault(require('../../../modules/nuclide-commons-ui/addTooltip')); +} + +var _classnames; + +function _load_classnames() { + return _classnames = _interopRequireDefault(require('classnames')); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _ConnectionDetailsForm; + +function _load_ConnectionDetailsForm() { + return _ConnectionDetailsForm = _interopRequireDefault(require('./ConnectionDetailsForm')); +} + +var _connectionProfileUtils; -import type {DnsLookup} from '../../nuclide-remote-connection/lib/lookup-prefer-ip-v6'; - -import type { - NuclideRemoteConnectionParams, - NuclideRemoteConnectionParamsWithPassword, - NuclideRemoteConnectionProfile, -} from './connection-types'; - -import addTooltip from 'nuclide-commons-ui/addTooltip'; -import classnames from 'classnames'; -import nullthrows from 'nullthrows'; -import ConnectionDetailsForm from './ConnectionDetailsForm'; -import {getIPsForHosts} from './connection-profile-utils'; -import {getUniqueHostsForProfiles} from './connection-profile-utils'; -import {HR} from 'nuclide-commons-ui/HR'; -import {MutableListSelector} from '../../nuclide-ui/MutableListSelector'; -import * as React from 'react'; - -type Props = { - // The initial list of connection profiles that will be displayed. - // Whenever a user add/removes profiles via the child NuclideListSelector, - // these props should be updated from the top-level by calling ReactDOM.render() - // again (with the new props) on the ConnectionDetailsPrompt. - connectionProfiles: ?Array, - // If there is >= 1 connection profile, this index indicates the profile to use. - selectedProfileIndex: ?number, - // Function to call when 'enter'/'confirm' is selected by the user in this view. - onConfirm: () => mixed, - // Function to call when 'cancel' is selected by the user in this view. - onCancel: () => mixed, - onDidChange: () => mixed, - // Function that is called when the "+" button on the profiles list is clicked. - // The user's intent is to create a new profile. - onAddProfileClicked: () => mixed, - // Function that is called when the "-" button on the profiles list is clicked - // ** while a profile is selected **. - // The user's intent is to delete the currently-selected profile. - onDeleteProfileClicked: (selectedProfileIndex: number) => mixed, - onProfileClicked: (selectedProfileIndex: number) => mixed, -}; - -type State = { - IPs: ?Promise>, - shouldDisplayTooltipWarning: boolean, -}; +function _load_connectionProfileUtils() { + return _connectionProfileUtils = require('./connection-profile-utils'); +} + +var _HR; + +function _load_HR() { + return _HR = require('../../../modules/nuclide-commons-ui/HR'); +} + +var _MutableListSelector; + +function _load_MutableListSelector() { + return _MutableListSelector = require('../../nuclide-ui/MutableListSelector'); +} + +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 }; } /** * This component contains the entire view in which the user inputs their @@ -63,45 +60,75 @@ type State = { * 'profiles'. Clicking on a 'profile' in the NuclideListSelector auto-fills * the form with the information associated with that profile. */ -export default class ConnectionDetailsPrompt extends React.Component< - Props, - State, -> { - _connectionDetailsForm: ?ConnectionDetailsForm; - _settingFormFieldsLock: boolean; - - constructor(props: Props) { +class ConnectionDetailsPrompt extends _react.Component { + + constructor(props) { super(props); + + this._handleConnectionDetailsFormDidChange = () => { + if (this._settingFormFieldsLock) { + return; + } + + this.props.onDidChange(); + }; + + this._onDefaultProfileClicked = () => { + const existingConnectionDetailsForm = this._connectionDetailsForm; + if (existingConnectionDetailsForm) { + existingConnectionDetailsForm.promptChanged(); + } + this.props.onProfileClicked(0); + }; + + this._onDeleteProfileClicked = profileId => { + if (profileId == null) { + return; + } + const existingConnectionDetailsForm = this._connectionDetailsForm; + if (existingConnectionDetailsForm) { + existingConnectionDetailsForm.promptChanged(); + } + // The id of a profile is its index in the list of props. + // * This requires a `+ 1` because the default profile is sliced from the Array during render + // creating an effective offset of -1 for each index passed to the `MutableListSelector`. + this.props.onDeleteProfileClicked(parseInt(profileId, 10) + 1); + }; + + this._onProfileClicked = profileId => { + const existingConnectionDetailsForm = this._connectionDetailsForm; + if (existingConnectionDetailsForm) { + existingConnectionDetailsForm.promptChanged(); + } + // The id of a profile is its index in the list of props. + // * This requires a `+ 1` because the default profile is sliced from the Array during render + // creating an effective offset of -1 for each index passed to the `MutableListSelector`. + this.props.onProfileClicked(parseInt(profileId, 10) + 1); + }; + this._settingFormFieldsLock = false; this.state = { IPs: null, - shouldDisplayTooltipWarning: false, + shouldDisplayTooltipWarning: false }; } componentDidMount() { if (this.props.connectionProfiles) { this.setState({ - IPs: getIPsForHosts( - getUniqueHostsForProfiles(this.props.connectionProfiles), - ), + IPs: (0, (_connectionProfileUtils || _load_connectionProfileUtils()).getIPsForHosts)((0, (_connectionProfileUtils || _load_connectionProfileUtils()).getUniqueHostsForProfiles)(this.props.connectionProfiles)) }); } this._checkForHostCollisions(); } - componentDidUpdate(prevProps: Props, prevState: State) { + componentDidUpdate(prevProps, prevState) { // Manually update the contents of an existing `ConnectionDetailsForm`, because it contains // `AtomInput` components (which don't update their contents when their props change). - if ( - prevProps.selectedProfileIndex !== this.props.selectedProfileIndex || - // If the connection profiles changed length, the effective selected profile also changed. - (prevProps.connectionProfiles != null && - this.props.connectionProfiles != null && - prevProps.connectionProfiles.length !== - this.props.connectionProfiles.length) - ) { + if (prevProps.selectedProfileIndex !== this.props.selectedProfileIndex || + // If the connection profiles changed length, the effective selected profile also changed. + prevProps.connectionProfiles != null && this.props.connectionProfiles != null && prevProps.connectionProfiles.length !== this.props.connectionProfiles.length) { const existingConnectionDetailsForm = this._connectionDetailsForm; if (existingConnectionDetailsForm) { // Setting values in the ConnectionDetailsForm fires change events. However, this is a @@ -109,108 +136,55 @@ export default class ConnectionDetailsPrompt extends React.Component< // synchronous updates to the form are complete. this._settingFormFieldsLock = true; existingConnectionDetailsForm.setFormFields( - // $FlowFixMe - this.getPrefilledConnectionParams(), - ); + // $FlowFixMe + this.getPrefilledConnectionParams()); existingConnectionDetailsForm.clearPassword(); this._settingFormFieldsLock = false; existingConnectionDetailsForm.focus(); } } - if ( - prevProps.connectionProfiles !== this.props.connectionProfiles && - this.props.connectionProfiles - ) { + if (prevProps.connectionProfiles !== this.props.connectionProfiles && this.props.connectionProfiles) { this.setState({ - IPs: getIPsForHosts( - getUniqueHostsForProfiles(this.props.connectionProfiles), - ), + IPs: (0, (_connectionProfileUtils || _load_connectionProfileUtils()).getIPsForHosts)((0, (_connectionProfileUtils || _load_connectionProfileUtils()).getUniqueHostsForProfiles)(this.props.connectionProfiles)) }); } this._checkForHostCollisions(); } - focus(): void { - nullthrows(this._connectionDetailsForm).focus(); + focus() { + (0, (_nullthrows || _load_nullthrows()).default)(this._connectionDetailsForm).focus(); } - getFormFields(): NuclideRemoteConnectionParamsWithPassword { - return nullthrows(this._connectionDetailsForm).getFormFields(); + getFormFields() { + return (0, (_nullthrows || _load_nullthrows()).default)(this._connectionDetailsForm).getFormFields(); } - getPrefilledConnectionParams(): ?NuclideRemoteConnectionParams { + getPrefilledConnectionParams() { // If there are profiles, pre-fill the form with the information from the specified selected // profile. - if ( - this.props.connectionProfiles != null && - this.props.connectionProfiles.length > 0 && - this.props.selectedProfileIndex != null - ) { - const selectedProfile = this.props.connectionProfiles[ - this.props.selectedProfileIndex - ]; + if (this.props.connectionProfiles != null && this.props.connectionProfiles.length > 0 && this.props.selectedProfileIndex != null) { + const selectedProfile = this.props.connectionProfiles[this.props.selectedProfileIndex]; return selectedProfile.params; } } - _handleConnectionDetailsFormDidChange = (): void => { - if (this._settingFormFieldsLock) { - return; - } - - this.props.onDidChange(); - }; - - _onDefaultProfileClicked = (): void => { - const existingConnectionDetailsForm = this._connectionDetailsForm; - if (existingConnectionDetailsForm) { - existingConnectionDetailsForm.promptChanged(); - } - this.props.onProfileClicked(0); - }; - - _onDeleteProfileClicked = (profileId: ?string): void => { - if (profileId == null) { - return; - } - const existingConnectionDetailsForm = this._connectionDetailsForm; - if (existingConnectionDetailsForm) { - existingConnectionDetailsForm.promptChanged(); - } - // The id of a profile is its index in the list of props. - // * This requires a `+ 1` because the default profile is sliced from the Array during render - // creating an effective offset of -1 for each index passed to the `MutableListSelector`. - this.props.onDeleteProfileClicked(parseInt(profileId, 10) + 1); - }; - - _onProfileClicked = (profileId: string): void => { - const existingConnectionDetailsForm = this._connectionDetailsForm; - if (existingConnectionDetailsForm) { - existingConnectionDetailsForm.promptChanged(); - } - // The id of a profile is its index in the list of props. - // * This requires a `+ 1` because the default profile is sliced from the Array during render - // creating an effective offset of -1 for each index passed to the `MutableListSelector`. - this.props.onProfileClicked(parseInt(profileId, 10) + 1); - }; - async _checkForHostCollisions() { if (this.state.IPs) { const IPs = await this.state.IPs; if (IPs.length !== new Set(IPs).size) { if (!this.state.shouldDisplayTooltipWarning) { - this.setState({shouldDisplayTooltipWarning: true}); + this.setState({ shouldDisplayTooltipWarning: true }); } } else { if (this.state.shouldDisplayTooltipWarning) { - this.setState({shouldDisplayTooltipWarning: false}); + this.setState({ shouldDisplayTooltipWarning: false }); } } } } - render(): React.Node { + render() { // If there are profiles, pre-fill the form with the information from the // specified selected profile. const prefilledConnectionParams = this.getPrefilledConnectionParams() || {}; @@ -221,40 +195,42 @@ export default class ConnectionDetailsPrompt extends React.Component< if (connectionProfiles == null || connectionProfiles.length === 0) { listSelectorItems = []; } else { - uniqueHosts = getUniqueHostsForProfiles(connectionProfiles); - const mostRecentClassName = classnames('list-item', { - selected: this.props.selectedProfileIndex === 0, + uniqueHosts = (0, (_connectionProfileUtils || _load_connectionProfileUtils()).getUniqueHostsForProfiles)(connectionProfiles); + const mostRecentClassName = (0, (_classnames || _load_classnames()).default)('list-item', { + selected: this.props.selectedProfileIndex === 0 }); - defaultConnectionProfileList = ( -
    -
      -
    1. - - Most Recent -
    2. -
    -
    -
    + defaultConnectionProfileList = _react.createElement( + 'div', + { className: 'block select-list' }, + _react.createElement( + 'ol', + { className: 'list-group', style: { marginTop: 0 } }, + _react.createElement( + 'li', + { + className: mostRecentClassName, + onClick: this._onDefaultProfileClicked, + onDoubleClick: this.props.onConfirm }, + _react.createElement('span', { + className: 'icon icon-info pull-right connection-details-icon-info' + // eslint-disable-next-line nuclide-internal/jsx-simple-callback-refs + , ref: (0, (_addTooltip || _load_addTooltip()).default)({ + // Intentionally *not* an arrow function so the jQuery Tooltip plugin can set the + // context to the Tooltip instance. + placement() { + // Atom modals have z indices of 9999. This Tooltip needs to stack on top of the + // modal; beat the modal's z-index. + this.tip.style.zIndex = 10999; + return 'right'; + }, + title: 'The settings most recently used to connect. To save settings permanently, ' + 'create a profile.' + }) + }), + 'Most Recent' + ) + ), + _react.createElement((_HR || _load_HR()).HR, null) ); listSelectorItems = connectionProfiles.slice(1).map((profile, index) => { @@ -264,17 +240,14 @@ export default class ConnectionDetailsPrompt extends React.Component< deletable: profile.deletable, displayTitle: profile.displayTitle, id: String(index), - saveable: profile.saveable, + saveable: profile.saveable }; }); } // The default profile is sliced from the Array to render it separately, which means // decrementing the effective index into the Array passed to the `MutableListSelector`. - let idOfSelectedItem = - this.props.selectedProfileIndex == null - ? null - : this.props.selectedProfileIndex - 1; + let idOfSelectedItem = this.props.selectedProfileIndex == null ? null : this.props.selectedProfileIndex - 1; // eslint-disable-next-line eqeqeq if (idOfSelectedItem === null || idOfSelectedItem < 0) { idOfSelectedItem = null; @@ -284,69 +257,76 @@ export default class ConnectionDetailsPrompt extends React.Component< let toolTipWarning; if (this.state.shouldDisplayTooltipWarning) { - toolTipWarning = ( - - ); + toolTipWarning = _react.createElement('span', { + style: { paddingLeft: 10 }, + className: 'icon icon-info pull-right nuclide-remote-projects-tooltip-warning' + // eslint-disable-next-line nuclide-internal/jsx-simple-callback-refs + , ref: (0, (_addTooltip || _load_addTooltip()).default)({ + // Intentionally *not* an arrow function so the jQuery + // Tooltip plugin can set the context to the Tooltip + // instance. + placement() { + // Atom modals have z indices of 9999. This Tooltip needs + // to stack on top of the modal; beat the modal's z-index. + this.tip.style.zIndex = 10999; + return 'right'; + }, + title: 'Two or more of your profiles use host names that resolve ' + 'to the same IP address. Consider unifying them to avoid ' + 'potential collisions.' + }) + }); } - return ( -
    -
    - {defaultConnectionProfileList} -
    - Profiles - {toolTipWarning} -
    - -
    - { - this._connectionDetailsForm = form; - }} - /> -
    + return _react.createElement( + 'div', + { className: 'nuclide-remote-projects-connection-dialog' }, + _react.createElement( + 'div', + { className: 'nuclide-remote-projects-connection-profiles' }, + defaultConnectionProfileList, + _react.createElement( + 'h6', + null, + 'Profiles', + toolTipWarning + ), + _react.createElement((_MutableListSelector || _load_MutableListSelector()).MutableListSelector, { + items: listSelectorItems, + idOfSelectedItem: idOfSelectedItem, + onItemClicked: this._onProfileClicked, + onItemDoubleClicked: this.props.onConfirm, + onAddButtonClicked: this.props.onAddProfileClicked, + onDeleteButtonClicked: this._onDeleteProfileClicked + }) + ), + _react.createElement((_ConnectionDetailsForm || _load_ConnectionDetailsForm()).default, { + className: 'nuclide-remote-projects-connection-details', + initialUsername: prefilledConnectionParams.username, + initialServer: prefilledConnectionParams.server, + initialRemoteServerCommand: prefilledConnectionParams.remoteServerCommand, + initialCwd: prefilledConnectionParams.cwd, + initialSshPort: prefilledConnectionParams.sshPort, + initialPathToPrivateKey: prefilledConnectionParams.pathToPrivateKey, + initialAuthMethod: prefilledConnectionParams.authMethod, + initialDisplayTitle: prefilledConnectionParams.displayTitle, + profileHosts: uniqueHosts, + onConfirm: this.props.onConfirm, + onCancel: this.props.onCancel, + onDidChange: this._handleConnectionDetailsFormDidChange, + needsPasswordValue: true, + ref: form => { + this._connectionDetailsForm = form; + } + }) ); } } +exports.default = ConnectionDetailsPrompt; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/ConnectionDialog.js b/pkg/nuclide-remote-projects/lib/ConnectionDialog.js index 4a6fb396af..e2092f71f8 100644 --- a/pkg/nuclide-remote-projects/lib/ConnectionDialog.js +++ b/pkg/nuclide-remote-projects/lib/ConnectionDialog.js @@ -1,80 +1,95 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _AuthenticationPrompt; + +function _load_AuthenticationPrompt() { + return _AuthenticationPrompt = _interopRequireDefault(require('./AuthenticationPrompt')); +} + +var _Button; + +function _load_Button() { + return _Button = require('../../../modules/nuclide-commons-ui/Button'); +} + +var _ButtonGroup; + +function _load_ButtonGroup() { + return _ButtonGroup = require('../../../modules/nuclide-commons-ui/ButtonGroup'); +} + +var _connectBigDigSshHandshake; + +function _load_connectBigDigSshHandshake() { + return _connectBigDigSshHandshake = _interopRequireDefault(require('./connectBigDigSshHandshake')); +} + +var _ConnectionDetailsPrompt; + +function _load_ConnectionDetailsPrompt() { + return _ConnectionDetailsPrompt = _interopRequireDefault(require('./ConnectionDetailsPrompt')); +} + +var _IndeterminateProgressBar; -import type { - NuclideRemoteConnectionParams, - NuclideRemoteConnectionParamsWithPassword, - NuclideRemoteConnectionProfile, -} from './connection-types'; -import type { - SshHandshakeErrorType, - SshConnectionConfiguration, - SshConnectionDelegate, -} from '../../nuclide-remote-connection/lib/SshHandshake'; - -import {Observable} from 'rxjs'; -import AuthenticationPrompt from './AuthenticationPrompt'; -import {Button, ButtonTypes} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; -import connectBigDigSshHandshake from './connectBigDigSshHandshake'; -import ConnectionDetailsPrompt from './ConnectionDetailsPrompt'; -import IndeterminateProgressBar from './IndeterminateProgressBar'; -import invariant from 'assert'; -import {notifySshHandshakeError} from './notification'; -import * as React from 'react'; -import electron from 'electron'; -import { - RemoteConnection, - decorateSshConnectionDelegateWithTracking, -} from '../../nuclide-remote-connection'; -import {validateFormInputs} from './form-validation-utils'; -import {getLogger} from 'log4js'; - -const logger = getLogger('nuclide-remote-projects'); -const {remote} = electron; -invariant(remote != null); - -type Props = { - // The list of connection profiles that will be displayed. - connectionProfiles: ?Array, - // If there is >= 1 connection profile, this index indicates the initial - // profile to use. - selectedProfileIndex: number, - // Function that is called when the "+" button on the profiles list is clicked. - // The user's intent is to create a new profile. - onAddProfileClicked: () => mixed, - // Function that is called when the "-" button on the profiles list is clicked - // ** while a profile is selected **. - // The user's intent is to delete the currently-selected profile. - onDeleteProfileClicked: (selectedProfileIndex: number) => mixed, - onConnect: ( - connection: RemoteConnection, - config: SshConnectionConfiguration, - ) => mixed, - onError: (error: Error, config: SshConnectionConfiguration) => mixed, - onCancel: () => mixed, - onClosed: ?() => mixed, - onSaveProfile: ( - index: number, - profile: NuclideRemoteConnectionProfile, - ) => mixed, - onProfileSelected: (index: number) => mixed, -}; - -type State = { - finish: (answers: Array) => mixed, - instructions: string, - isDirty: boolean, - mode: number, -}; +function _load_IndeterminateProgressBar() { + return _IndeterminateProgressBar = _interopRequireDefault(require('./IndeterminateProgressBar')); +} + +var _notification; + +function _load_notification() { + return _notification = require('./notification'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _electron = _interopRequireDefault(require('electron')); + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _formValidationUtils; + +function _load_formValidationUtils() { + return _formValidationUtils = require('./form-validation-utils'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +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 logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-remote-projects'); /** + * 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. + * + * strict-local + * @format + */ + +const { remote } = _electron.default; + +if (!(remote != null)) { + throw new Error('Invariant violation: "remote != null"'); +} const REQUEST_CONNECTION_DETAILS = 1; const WAITING_FOR_CONNECTION = 2; @@ -84,79 +99,184 @@ const WAITING_FOR_AUTHENTICATION = 4; /** * Component that manages the state transitions as the user connects to a server. */ -export default class ConnectionDialog extends React.Component { - _cancelButton: ?Button; - _okButton: ?Button; - _content: ?(AuthenticationPrompt | ConnectionDetailsPrompt); - _delegate: SshConnectionDelegate; - _pendingHandshake: ?rxjs$ISubscription; - - constructor(props: Props) { +class ConnectionDialog extends _react.Component { + + constructor(props) { super(props); - this._delegate = decorateSshConnectionDelegateWithTracking({ - onKeyboardInteractive: ( - name, - instructions, - instructionsLang, - prompts, - finish, - ) => { + this._handleDidChange = () => { + this.setState({ isDirty: true }); + }; + + this._handleClickSave = () => { + if (!(this.props.connectionProfiles != null)) { + throw new Error('Invariant violation: "this.props.connectionProfiles != null"'); + } + + const selectedProfile = this.props.connectionProfiles[this.props.selectedProfileIndex]; + const connectionDetailsPrompt = this._content; + + if (!(connectionDetailsPrompt instanceof (_ConnectionDetailsPrompt || _load_ConnectionDetailsPrompt()).default)) { + throw new Error('Invariant violation: "connectionDetailsPrompt instanceof ConnectionDetailsPrompt"'); + } + + const connectionDetails = connectionDetailsPrompt.getFormFields(); + const validationResult = (0, (_formValidationUtils || _load_formValidationUtils()).validateFormInputs)(selectedProfile.displayTitle, connectionDetails, ''); + + if (typeof validationResult.errorMessage === 'string') { + atom.notifications.addError(validationResult.errorMessage); + return; + } + + if (!(validationResult.validatedProfile != null && typeof validationResult.validatedProfile === 'object')) { + throw new Error('Invariant violation: "validationResult.validatedProfile != null &&\\n typeof validationResult.validatedProfile === \'object\'"'); + } + // Save the validated profile, and show any warning messages. + + + const newProfile = validationResult.validatedProfile; + if (typeof validationResult.warningMessage === 'string') { + atom.notifications.addWarning(validationResult.warningMessage); + } + + this.props.onSaveProfile(this.props.selectedProfileIndex, newProfile); + this.setState({ isDirty: false }); + }; + + this.cancel = () => { + const mode = this.state.mode; + + if (this._pendingHandshake != null) { + this._pendingHandshake.unsubscribe(); + this._pendingHandshake = null; + } + + if (mode === WAITING_FOR_CONNECTION) { + this.setState({ + isDirty: false, + mode: REQUEST_CONNECTION_DETAILS + }); + } else { + this.props.onCancel(); + this.close(); + } + }; + + this.ok = () => { + const { mode, isDirty } = this.state; + + if (mode === REQUEST_CONNECTION_DETAILS) { + // User is trying to submit connection details. + const connectionDetailsForm = this._content; + + if (!(connectionDetailsForm instanceof (_ConnectionDetailsPrompt || _load_ConnectionDetailsPrompt()).default)) { + throw new Error('Invariant violation: "connectionDetailsForm instanceof ConnectionDetailsPrompt"'); + } + + const { + username, + server, + cwd, + remoteServerCommand, + sshPort, + pathToPrivateKey, + authMethod, + password, + displayTitle + } = connectionDetailsForm.getFormFields(); + + if (!this._validateInitialDirectory(cwd)) { + remote.dialog.showErrorBox('Invalid initial path', 'Please specify a non-root directory.'); + return; + } + + if (username && server && cwd && remoteServerCommand) { + this.setState({ + isDirty: false, + mode: WAITING_FOR_CONNECTION + }); + this._pendingHandshake = this._connect({ + host: server, + sshPort: parseInt(sshPort, 10), + username, + pathToPrivateKey, + authMethod, + cwd, + remoteServerCommand, + password, + // Modified profiles probably don't match the display title. + displayTitle: isDirty ? '' : displayTitle + }); + } else { + remote.dialog.showErrorBox('Missing information', "Please make sure you've filled out all the form fields."); + } + } else if (mode === REQUEST_AUTHENTICATION_DETAILS) { + const authenticationPrompt = this._content; + + if (!(authenticationPrompt instanceof (_AuthenticationPrompt || _load_AuthenticationPrompt()).default)) { + throw new Error('Invariant violation: "authenticationPrompt instanceof AuthenticationPrompt"'); + } + + const password = authenticationPrompt.getPassword(); + + this.state.finish([password]); + + this.setState({ + isDirty: false, + mode: WAITING_FOR_AUTHENTICATION + }); + } + }; + + this.onProfileClicked = selectedProfileIndex => { + this.setState({ isDirty: false }); + this.props.onProfileSelected(selectedProfileIndex); + }; + + this._delegate = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).decorateSshConnectionDelegateWithTracking)({ + onKeyboardInteractive: (name, instructions, instructionsLang, prompts, finish) => { // TODO: Display all prompts, not just the first one. this.requestAuthentication(prompts[0], finish); }, onWillConnect: () => {}, - onDidConnect: ( - connection: RemoteConnection, - config: SshConnectionConfiguration, - ) => { + onDidConnect: (connection, config) => { this.close(); // Close the dialog. this.props.onConnect(connection, config); }, - onError: ( - errorType: SshHandshakeErrorType, - error: Error, - config: SshConnectionConfiguration, - ) => { + onError: (errorType, error, config) => { this.close(); // Close the dialog. - notifySshHandshakeError(errorType, error, config); + (0, (_notification || _load_notification()).notifySshHandshakeError)(errorType, error, config); this.props.onError(error, config); logger.debug(error); - }, + } }); this.state = { finish: answers => {}, instructions: '', isDirty: false, - mode: REQUEST_CONNECTION_DETAILS, + mode: REQUEST_CONNECTION_DETAILS }; } - componentDidMount(): void { + componentDidMount() { this._focus(); } - componentDidUpdate(prevProps: Props, prevState: State) { + componentDidUpdate(prevProps, prevState) { if (this.state.mode !== prevState.mode) { this._focus(); - } else if ( - this.state.mode === REQUEST_CONNECTION_DETAILS && - this.props.selectedProfileIndex === prevProps.selectedProfileIndex && - !this.state.isDirty && - prevState.isDirty && - this._okButton != null - ) { + } else if (this.state.mode === REQUEST_CONNECTION_DETAILS && this.props.selectedProfileIndex === prevProps.selectedProfileIndex && !this.state.isDirty && prevState.isDirty && this._okButton != null) { // When editing a profile and clicking "Save", the Save button disappears. Focus the primary // button after re-rendering so focus is on a logical element. this._okButton.focus(); } } - _focus(): void { + _focus() { const content = this._content; if (content == null) { if (this._cancelButton == null) { @@ -168,163 +288,106 @@ export default class ConnectionDialog extends React.Component { } } - _handleDidChange = (): void => { - this.setState({isDirty: true}); - }; - - _handleClickSave = (): void => { - invariant(this.props.connectionProfiles != null); - - const selectedProfile = this.props.connectionProfiles[ - this.props.selectedProfileIndex - ]; - const connectionDetailsPrompt = this._content; - invariant(connectionDetailsPrompt instanceof ConnectionDetailsPrompt); - const connectionDetails: NuclideRemoteConnectionParamsWithPassword = connectionDetailsPrompt.getFormFields(); - const validationResult = validateFormInputs( - selectedProfile.displayTitle, - connectionDetails, - '', - ); - - if (typeof validationResult.errorMessage === 'string') { - atom.notifications.addError(validationResult.errorMessage); - return; - } - - invariant( - validationResult.validatedProfile != null && - typeof validationResult.validatedProfile === 'object', - ); - // Save the validated profile, and show any warning messages. - const newProfile = validationResult.validatedProfile; - if (typeof validationResult.warningMessage === 'string') { - atom.notifications.addWarning(validationResult.warningMessage); - } - - this.props.onSaveProfile(this.props.selectedProfileIndex, newProfile); - this.setState({isDirty: false}); - }; - - _validateInitialDirectory(path: string): boolean { + _validateInitialDirectory(path) { return path !== '/'; } - render(): React.Node { + render() { const mode = this.state.mode; let content; let isOkDisabled; let okButtonText; if (mode === REQUEST_CONNECTION_DETAILS) { - content = ( - { - this._content = prompt; - }} - /> - ); + content = _react.createElement((_ConnectionDetailsPrompt || _load_ConnectionDetailsPrompt()).default, { + connectionProfiles: this.props.connectionProfiles, + selectedProfileIndex: this.props.selectedProfileIndex, + onAddProfileClicked: this.props.onAddProfileClicked, + onCancel: this.cancel, + onConfirm: this.ok, + onDeleteProfileClicked: this.props.onDeleteProfileClicked, + onDidChange: this._handleDidChange, + onProfileClicked: this.onProfileClicked, + ref: prompt => { + this._content = prompt; + } + }); isOkDisabled = false; okButtonText = 'Connect'; - } else if ( - mode === WAITING_FOR_CONNECTION || - mode === WAITING_FOR_AUTHENTICATION - ) { - content = ; + } else if (mode === WAITING_FOR_CONNECTION || mode === WAITING_FOR_AUTHENTICATION) { + content = _react.createElement((_IndeterminateProgressBar || _load_IndeterminateProgressBar()).default, null); isOkDisabled = true; okButtonText = 'Connect'; } else { - content = ( - { - this._content = prompt; - }} - /> - ); + content = _react.createElement((_AuthenticationPrompt || _load_AuthenticationPrompt()).default, { + instructions: this.state.instructions, + onCancel: this.cancel, + onConfirm: this.ok, + ref: prompt => { + this._content = prompt; + } + }); isOkDisabled = false; okButtonText = 'OK'; } let saveButtonGroup; let selectedProfile; - if ( - this.props.selectedProfileIndex >= 0 && - this.props.connectionProfiles != null - ) { - selectedProfile = this.props.connectionProfiles[ - this.props.selectedProfileIndex - ]; + if (this.props.selectedProfileIndex >= 0 && this.props.connectionProfiles != null) { + selectedProfile = this.props.connectionProfiles[this.props.selectedProfileIndex]; } - if ( - this.state.isDirty && - selectedProfile != null && - selectedProfile.saveable - ) { - saveButtonGroup = ( - - - + if (this.state.isDirty && selectedProfile != null && selectedProfile.saveable) { + saveButtonGroup = _react.createElement( + (_ButtonGroup || _load_ButtonGroup()).ButtonGroup, + { className: 'inline-block' }, + _react.createElement( + (_Button || _load_Button()).Button, + { onClick: this._handleClickSave }, + 'Save' + ) ); } - return ( -
    -
    {content}
    -
    - {saveButtonGroup} - - - - -
    -
    + } }, + okButtonText + ) + ) + ) ); } - cancel = () => { - const mode = this.state.mode; - - if (this._pendingHandshake != null) { - this._pendingHandshake.unsubscribe(); - this._pendingHandshake = null; - } - - if (mode === WAITING_FOR_CONNECTION) { - this.setState({ - isDirty: false, - mode: REQUEST_CONNECTION_DETAILS, - }); - } else { - this.props.onCancel(); - this.close(); - } - }; - close() { if (this._pendingHandshake != null) { this._pendingHandshake.unsubscribe(); @@ -336,88 +399,25 @@ export default class ConnectionDialog extends React.Component { } } - ok = () => { - const {mode, isDirty} = this.state; - - if (mode === REQUEST_CONNECTION_DETAILS) { - // User is trying to submit connection details. - const connectionDetailsForm = this._content; - invariant(connectionDetailsForm instanceof ConnectionDetailsPrompt); - const { - username, - server, - cwd, - remoteServerCommand, - sshPort, - pathToPrivateKey, - authMethod, - password, - displayTitle, - } = connectionDetailsForm.getFormFields(); - - if (!this._validateInitialDirectory(cwd)) { - remote.dialog.showErrorBox( - 'Invalid initial path', - 'Please specify a non-root directory.', - ); - return; - } - - if (username && server && cwd && remoteServerCommand) { - this.setState({ - isDirty: false, - mode: WAITING_FOR_CONNECTION, - }); - this._pendingHandshake = this._connect({ - host: server, - sshPort: parseInt(sshPort, 10), - username, - pathToPrivateKey, - authMethod, - cwd, - remoteServerCommand, - password, - // Modified profiles probably don't match the display title. - displayTitle: isDirty ? '' : displayTitle, - }); - } else { - remote.dialog.showErrorBox( - 'Missing information', - "Please make sure you've filled out all the form fields.", - ); - } - } else if (mode === REQUEST_AUTHENTICATION_DETAILS) { - const authenticationPrompt = this._content; - invariant(authenticationPrompt instanceof AuthenticationPrompt); - const password = authenticationPrompt.getPassword(); - - this.state.finish([password]); - - this.setState({ - isDirty: false, - mode: WAITING_FOR_AUTHENTICATION, - }); - } - }; - - requestAuthentication( - instructions: {echo: boolean, prompt: string}, - finish: (answers: Array) => void, - ) { + requestAuthentication(instructions, finish) { this.setState({ finish, instructions: instructions.prompt, isDirty: false, - mode: REQUEST_AUTHENTICATION_DETAILS, + mode: REQUEST_AUTHENTICATION_DETAILS }); } - getFormFields(): ?NuclideRemoteConnectionParams { + getFormFields() { const connectionDetailsForm = this._content; if (!connectionDetailsForm) { return null; } - invariant(connectionDetailsForm instanceof ConnectionDetailsPrompt); + + if (!(connectionDetailsForm instanceof (_ConnectionDetailsPrompt || _load_ConnectionDetailsPrompt()).default)) { + throw new Error('Invariant violation: "connectionDetailsForm instanceof ConnectionDetailsPrompt"'); + } + const { username, server, @@ -426,7 +426,7 @@ export default class ConnectionDialog extends React.Component { sshPort, pathToPrivateKey, authMethod, - displayTitle, + displayTitle } = connectionDetailsForm.getFormFields(); return { username, @@ -436,45 +436,22 @@ export default class ConnectionDialog extends React.Component { sshPort, pathToPrivateKey, authMethod, - displayTitle, + displayTitle }; } - onProfileClicked = (selectedProfileIndex: number): void => { - this.setState({isDirty: false}); - this.props.onProfileSelected(selectedProfileIndex); - }; - - _connect(connectionConfig: SshConnectionConfiguration): rxjs$ISubscription { - return Observable.defer(() => - RemoteConnection.reconnect( - connectionConfig.host, - connectionConfig.cwd, - connectionConfig.displayTitle, - ), - ) - .switchMap(existingConnection => { - if (existingConnection != null) { - this._delegate.onWillConnect(connectionConfig); // required for the API - this._delegate.onDidConnect(existingConnection, connectionConfig); - return Observable.empty(); - } - const sshHandshake = connectBigDigSshHandshake( - connectionConfig, - this._delegate, - ); - return Observable.create(() => { - return () => sshHandshake.cancel(); - }); - }) - .subscribe( - next => {}, - err => - this._delegate.onError( - err.sshHandshakeErrorType || 'UNKNOWN', - err, - connectionConfig, - ), - ); + _connect(connectionConfig) { + return _rxjsBundlesRxMinJs.Observable.defer(() => (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).RemoteConnection.reconnect(connectionConfig.host, connectionConfig.cwd, connectionConfig.displayTitle)).switchMap(existingConnection => { + if (existingConnection != null) { + this._delegate.onWillConnect(connectionConfig); // required for the API + this._delegate.onDidConnect(existingConnection, connectionConfig); + return _rxjsBundlesRxMinJs.Observable.empty(); + } + const sshHandshake = (0, (_connectBigDigSshHandshake || _load_connectBigDigSshHandshake()).default)(connectionConfig, this._delegate); + return _rxjsBundlesRxMinJs.Observable.create(() => { + return () => sshHandshake.cancel(); + }); + }).subscribe(next => {}, err => this._delegate.onError(err.sshHandshakeErrorType || 'UNKNOWN', err, connectionConfig)); } } +exports.default = ConnectionDialog; \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/ConnectionState.js b/pkg/nuclide-remote-projects/lib/ConnectionState.js index 9dbaa39412..cc414c64d3 100644 --- a/pkg/nuclide-remote-projects/lib/ConnectionState.js +++ b/pkg/nuclide-remote-projects/lib/ConnectionState.js @@ -1,3 +1,8 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,12 +10,12 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -export default Object.freeze({ +exports.default = Object.freeze({ NONE: 0, CONNECTED: 1, - DISCONNECTED: 2, -}); + DISCONNECTED: 2 +}); \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/CreateConnectionProfileForm.js b/pkg/nuclide-remote-projects/lib/CreateConnectionProfileForm.js index 7596e8ba61..3ff2a0de8a 100644 --- a/pkg/nuclide-remote-projects/lib/CreateConnectionProfileForm.js +++ b/pkg/nuclide-remote-projects/lib/CreateConnectionProfileForm.js @@ -1,3 +1,59 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../../../modules/nuclide-commons-ui/AtomInput'); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _reactDom = _interopRequireDefault(require('react-dom')); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _ConnectionDetailsForm; + +function _load_ConnectionDetailsForm() { + return _ConnectionDetailsForm = _interopRequireDefault(require('./ConnectionDetailsForm')); +} + +var _formValidationUtils; + +function _load_formValidationUtils() { + return _formValidationUtils = require('./form-validation-utils'); +} + +var _Button; + +function _load_Button() { + return _Button = require('../../../modules/nuclide-commons-ui/Button'); +} + +var _ButtonGroup; + +function _load_ButtonGroup() { + return _ButtonGroup = require('../../../modules/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; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,43 +61,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type { - NuclideNewConnectionProfileInitialFields, - NuclideRemoteConnectionParams, - NuclideRemoteConnectionParamsWithPassword, - NuclideRemoteConnectionProfile, -} from './connection-types'; - -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import nullthrows from 'nullthrows'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import invariant from 'assert'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import ConnectionDetailsForm from './ConnectionDetailsForm'; -import {validateFormInputs} from './form-validation-utils'; -import {Button, ButtonTypes} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; - -type Props = { - // A function called when the "Cancel" button is clicked. - onCancel: () => mixed, - // A function called when the "Save" button is clicked. The profile passed - // to the function is the profile that the user has just created. - // The CreateConnectionProfileForm will do basic validation on the inputs: It - // checks that the fields are non-empty before calling this function. - onSave: (profile: NuclideRemoteConnectionProfile) => mixed, - // The inputs to pre-fill the form with. - initialFormFields: - | NuclideNewConnectionProfileInitialFields - | NuclideRemoteConnectionParams, - profileHosts: ?Array, -}; - const PROFILE_NAME_LABEL = 'Profile Name'; const DEFAULT_SERVER_COMMAND_PLACEHOLDER = '(DEFAULT)'; @@ -50,34 +73,53 @@ const emptyFunction = () => {}; /** * A form that is used to create a new connection profile. */ -export default class CreateConnectionProfileForm extends React.Component< - Props, -> { - props: Props; +class CreateConnectionProfileForm extends _react.Component { - _connectionDetails: ?ConnectionDetailsForm; - disposables: UniversalDisposable; - _profileName: ?AtomInput; - - constructor(props: Props) { + constructor(props) { super(props); - this.disposables = new UniversalDisposable(); + + this._clickSave = () => { + // Validate the form inputs. + const profileName = this._getProfileName(); + const connectionDetails = (0, (_nullthrows || _load_nullthrows()).default)(this._connectionDetails).getFormFields(); + const validationResult = (0, (_formValidationUtils || _load_formValidationUtils()).validateFormInputs)(profileName, connectionDetails, DEFAULT_SERVER_COMMAND_PLACEHOLDER); + if (typeof validationResult.errorMessage === 'string') { + atom.notifications.addError(validationResult.errorMessage); + return; + } + + if (!(validationResult.validatedProfile != null && typeof validationResult.validatedProfile === 'object')) { + throw new Error('Invariant violation: "validationResult.validatedProfile != null &&\\n typeof validationResult.validatedProfile === \'object\'"'); + } + + const newProfile = validationResult.validatedProfile; + // Save the validated profile, and show any warning messages. + if (typeof validationResult.warningMessage === 'string') { + atom.notifications.addWarning(validationResult.warningMessage); + } + this.props.onSave(newProfile); + }; + + this._clickCancel = () => { + this.props.onCancel(); + }; + + this.disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - componentDidMount(): void { - const root = ReactDOM.findDOMNode(this); + componentDidMount() { + const root = _reactDom.default.findDOMNode(this); this.disposables.add( - // Hitting enter when this panel has focus should confirm the dialog. - // $FlowFixMe - atom.commands.add(root, 'core:confirm', this._clickSave), - // Hitting escape when this panel has focus should cancel the dialog. - // $FlowFixMe - atom.commands.add(root, 'core:cancel', this._clickCancel), - ); - nullthrows(this._profileName).focus(); + // Hitting enter when this panel has focus should confirm the dialog. + // $FlowFixMe + atom.commands.add(root, 'core:confirm', this._clickSave), + // Hitting escape when this panel has focus should cancel the dialog. + // $FlowFixMe + atom.commands.add(root, 'core:cancel', this._clickCancel)); + (0, (_nullthrows || _load_nullthrows()).default)(this._profileName).focus(); } - componentWillUnmount(): void { + componentWillUnmount() { this.disposables.dispose(); } @@ -86,87 +128,73 @@ export default class CreateConnectionProfileForm extends React.Component< * remote server command. The remote server command will only be saved if the * user changes it from this default. */ - render(): React.Node { + render() { const initialFields = this.props.initialFormFields; - return ( -
    -
    - - { - this._profileName = input; - }} - unstyled={true} - /> -
    - { - this._connectionDetails = details; - }} - /> -
    - - - - -
    -
    + return _react.createElement( + 'div', + null, + _react.createElement( + 'div', + { className: 'form-group' }, + _react.createElement( + 'label', + null, + PROFILE_NAME_LABEL, + ':' + ), + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + initialValue: '', + ref: input => { + this._profileName = input; + }, + unstyled: true + }) + ), + _react.createElement((_ConnectionDetailsForm || _load_ConnectionDetailsForm()).default, { + initialUsername: initialFields.username, + initialServer: initialFields.server, + initialCwd: initialFields.cwd, + initialRemoteServerCommand: + // flowlint-next-line sketchy-null-string:off + initialFields.remoteServerCommand || DEFAULT_SERVER_COMMAND_PLACEHOLDER, + initialSshPort: initialFields.sshPort, + initialPathToPrivateKey: initialFields.pathToPrivateKey, + initialAuthMethod: initialFields.authMethod, + initialDisplayTitle: initialFields.displayTitle, + profileHosts: this.props.profileHosts, + onCancel: emptyFunction, + onConfirm: this._clickSave, + onDidChange: emptyFunction, + needsPasswordValue: false, + ref: details => { + this._connectionDetails = details; + } + }), + _react.createElement( + 'div', + { style: { display: 'flex', justifyContent: 'flex-end' } }, + _react.createElement( + (_ButtonGroup || _load_ButtonGroup()).ButtonGroup, + null, + _react.createElement( + (_Button || _load_Button()).Button, + { onClick: this._clickCancel }, + 'Cancel' + ), + _react.createElement( + (_Button || _load_Button()).Button, + { buttonType: (_Button || _load_Button()).ButtonTypes.PRIMARY, onClick: this._clickSave }, + 'Save' + ) + ) + ) ); } - _getProfileName(): string { - return (this._profileName && this._profileName.getText().trim()) || ''; + _getProfileName() { + return this._profileName && this._profileName.getText().trim() || ''; } - _clickSave = (): void => { - // Validate the form inputs. - const profileName = this._getProfileName(); - const connectionDetails: NuclideRemoteConnectionParamsWithPassword = nullthrows( - this._connectionDetails, - ).getFormFields(); - const validationResult = validateFormInputs( - profileName, - connectionDetails, - DEFAULT_SERVER_COMMAND_PLACEHOLDER, - ); - if (typeof validationResult.errorMessage === 'string') { - atom.notifications.addError(validationResult.errorMessage); - return; - } - invariant( - validationResult.validatedProfile != null && - typeof validationResult.validatedProfile === 'object', - ); - const newProfile = validationResult.validatedProfile; - // Save the validated profile, and show any warning messages. - if (typeof validationResult.warningMessage === 'string') { - atom.notifications.addWarning(validationResult.warningMessage); - } - this.props.onSave(newProfile); - }; - - _clickCancel = (): void => { - this.props.onCancel(); - }; } +exports.default = CreateConnectionProfileForm; \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/IndeterminateProgressBar.js b/pkg/nuclide-remote-projects/lib/IndeterminateProgressBar.js index 970696ae5e..2dc9feef5b 100644 --- a/pkg/nuclide-remote-projects/lib/IndeterminateProgressBar.js +++ b/pkg/nuclide-remote-projects/lib/IndeterminateProgressBar.js @@ -1,25 +1,32 @@ -/** - * 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 strict - * @format - */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = _interopRequireWildcard(require("react")); -import * as React from '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; } } /** * Component to entertain the user while he is waiting to hear back from the server. */ -export default class IndeterminateProgressBar extends React.Component<{}> { - render(): React.Node { - return ( -
    - -
    +class IndeterminateProgressBar extends _react.Component { + render() { + return _react.createElement( + "div", + { className: "text-center padded" }, + _react.createElement("span", { className: "loading loading-spinner-medium inline-block" }) ); } } +exports.default = IndeterminateProgressBar; /** + * 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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/RemoteDirectoryProvider.js b/pkg/nuclide-remote-projects/lib/RemoteDirectoryProvider.js index 4c3aff00e0..a825d5c88e 100644 --- a/pkg/nuclide-remote-projects/lib/RemoteDirectoryProvider.js +++ b/pkg/nuclide-remote-projects/lib/RemoteDirectoryProvider.js @@ -1,32 +1,37 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); -import { - RemoteConnection, - RemoteDirectoryPlaceholder, -} from '../../nuclide-remote-connection'; +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} /** * The prefix a URI must have for `RemoteDirectoryProvider` to try to produce a * `RemoteDirectory` for it. This should also be the path prefix checked by the * handler we register with `atom.project.registerOpener()` to open remote files. */ -const REMOTE_PATH_URI_PREFIX = 'nuclide://'; +const REMOTE_PATH_URI_PREFIX = 'nuclide://'; /** + * 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. + * + * strict-local + * @format + */ -export default class RemoteDirectoryProvider { - directoryForURISync(uri: string): mixed { +class RemoteDirectoryProvider { + directoryForURISync(uri) { if (!uri.startsWith(REMOTE_PATH_URI_PREFIX)) { return null; } - const connection = RemoteConnection.getForUri(uri); + const connection = (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).RemoteConnection.getForUri(uri); if (connection) { return connection.createDirectory(uri); } else { @@ -34,11 +39,12 @@ export default class RemoteDirectoryProvider { // This is to prevent Atom from displaying an error at startup. // We remove all remote projects in Nuclide's main.js file, and then // later reload them manually in the remote-projects main file. - return new RemoteDirectoryPlaceholder(uri); + return new (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).RemoteDirectoryPlaceholder(uri); } } - directoryForURI(uri: string): Promise { + directoryForURI(uri) { return Promise.resolve(this.directoryForURISync(uri)); } } +exports.default = RemoteDirectoryProvider; \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/RemoteDirectorySearcher.js b/pkg/nuclide-remote-projects/lib/RemoteDirectorySearcher.js index e171d644d5..f2db6301e0 100644 --- a/pkg/nuclide-remote-projects/lib/RemoteDirectorySearcher.js +++ b/pkg/nuclide-remote-projects/lib/RemoteDirectorySearcher.js @@ -1,114 +1,99 @@ -/** - * 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 - */ - -import typeof * as CodeSearchService from '../../nuclide-code-search-rpc'; -import type {search$FileResult} from '../../nuclide-code-search-rpc/lib/types'; -import type {WorkingSetsStore} from '../../nuclide-working-sets/lib/types'; -import type {NuclideCodeSearchConfig} from '../../nuclide-code-search/lib/types'; - -import {RemoteDirectory} from '../../nuclide-remote-connection'; -import {WORKING_SET_PATH_MARKER} from '../../nuclide-working-sets-common/lib/constants'; -import {logger} from './constants'; -import invariant from 'assert'; -import {arrayFlatten} from 'nuclide-commons/collection'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {Observable, ReplaySubject} from 'rxjs'; - -type RemoteDirectorySearch = { - then: (onFullfilled: any, onRejected: any) => Promise, - cancel: () => void, -}; - -export default class RemoteDirectorySearcher { - _serviceProvider: (dir: RemoteDirectory) => CodeSearchService; - _getWorkingSetsStore: () => ?WorkingSetsStore; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _constants; + +function _load_constants() { + return _constants = require('../../nuclide-working-sets-common/lib/constants'); +} + +var _constants2; + +function _load_constants2() { + return _constants2 = require('./constants'); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class RemoteDirectorySearcher { // When constructed, RemoteDirectorySearcher must be passed a function that // it can use to get a 'CodeSearchService' for a given remote path. - constructor( - serviceProvider: (dir: RemoteDirectory) => CodeSearchService, - getWorkingSetsStore: () => ?WorkingSetsStore, - ) { + constructor(serviceProvider, getWorkingSetsStore) { this._serviceProvider = serviceProvider; this._getWorkingSetsStore = getWorkingSetsStore; } - canSearchDirectory(directory: atom$Directory | RemoteDirectory): boolean { - return RemoteDirectory.isRemoteDirectory(directory); + canSearchDirectory(directory) { + return (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).RemoteDirectory.isRemoteDirectory(directory); } - search( - directories: Array, - regex: RegExp, - options: Object, - ): RemoteDirectorySearch { - const config: NuclideCodeSearchConfig = (featureConfig.get( - 'nuclide-code-search', - ): any); + search(directories, regex, options) { + const config = (_featureConfig || _load_featureConfig()).default.get('nuclide-code-search'); // Track the files that we have seen updates for. const seenFiles = new Set(); // Get the remote service that corresponds to each remote directory. const services = directories.map(dir => this._serviceProvider(dir)); - const includePaths = directories.map(dir => - this.processPaths(dir.getPath(), options.inclusions), - ); - - const searchStreams: Array< - Observable, - > = includePaths.map( - (inclusion, index) => - // processPaths returns null if the inclusions are too strict for the - // given directory, so we don't even want to start the search. This can - // happen if we're searching in a working set that excludes the directory. - inclusion - ? services[index] - .remoteAtomSearch( - directories[index].getPath(), - regex, - inclusion, - config.remoteUseVcsSearch, - config.remoteTool.length === 0 ? null : config.remoteTool, - ) - .refCount() - : Observable.empty(), - ); + const includePaths = directories.map(dir => this.processPaths(dir.getPath(), options.inclusions)); + + const searchStreams = includePaths.map((inclusion, index) => + // processPaths returns null if the inclusions are too strict for the + // given directory, so we don't even want to start the search. This can + // happen if we're searching in a working set that excludes the directory. + inclusion ? services[index].remoteAtomSearch(directories[index].getPath(), regex, inclusion, config.remoteUseVcsSearch, config.remoteTool.length === 0 ? null : config.remoteTool).refCount() : _rxjsBundlesRxMinJs.Observable.empty()); // Start the search in each directory, and merge the resulting streams. - const searchStream = Observable.merge(...searchStreams); + const searchStream = _rxjsBundlesRxMinJs.Observable.merge(...searchStreams); // Create a subject that we can use to track search completion. - const searchCompletion = new ReplaySubject(); + const searchCompletion = new _rxjsBundlesRxMinJs.ReplaySubject(); searchCompletion.next(); - const subscription = searchStream.subscribe( - next => { - options.didMatch(next); - - // Call didSearchPaths with the number of unique files we have seen matches in. This is - // not technically correct, as didSearchPaths is also supposed to count files for which - // no matches were found. However, we currently have no way of obtaining this information. - seenFiles.add(next.filePath); - options.didSearchPaths(seenFiles.size); - }, - error => { - options.didError(error); - searchCompletion.error(error); - }, - () => { - searchCompletion.complete(); - }, - ); + const subscription = searchStream.subscribe(next => { + options.didMatch(next); + + // Call didSearchPaths with the number of unique files we have seen matches in. This is + // not technically correct, as didSearchPaths is also supposed to count files for which + // no matches were found. However, we currently have no way of obtaining this information. + seenFiles.add(next.filePath); + options.didSearchPaths(seenFiles.size); + }, error => { + options.didError(error); + searchCompletion.error(error); + }, () => { + searchCompletion.complete(); + }); // Return a promise that resolves on search completion. const completionPromise = searchCompletion.toPromise(); @@ -117,7 +102,7 @@ export default class RemoteDirectorySearcher { cancel() { // Cancel the subscription, which should also kill the grep process. subscription.unsubscribe(); - }, + } }; } @@ -126,47 +111,47 @@ export default class RemoteDirectorySearcher { * Based on https://github.com/atom/atom/blob/master/src/scan-handler.coffee. * Returns null if we shouldn't search rootPath. */ - processPaths(rootPath: string, paths: ?Array): ?Array { + processPaths(rootPath, paths) { if (paths == null) { return []; } - const rootPathBase = nuclideUri.basename(rootPath); + const rootPathBase = (_nuclideUri || _load_nuclideUri()).default.basename(rootPath); const results = []; for (const path of paths) { - if (path === WORKING_SET_PATH_MARKER) { + if (path === (_constants || _load_constants()).WORKING_SET_PATH_MARKER) { const workingSetsStore = this._getWorkingSetsStore(); if (!workingSetsStore) { - logger.error( - 'workingSetsStore not found but trying to search in working sets', - ); + (_constants2 || _load_constants2()).logger.error('workingSetsStore not found but trying to search in working sets'); continue; } - const workingSetUris = arrayFlatten( - workingSetsStore - .getApplicableDefinitions() - .filter(def => def.active) - .map(def => def.uris), - ) - // A working set can contain paths outside of rootPath. Ignore these. - .filter(uri => nuclideUri.contains(rootPath, uri)) - // `processPaths` expects the second argument to be a relative path - // instead of the fully qualified NuclideUris we have here. - .map(uri => nuclideUri.relative(rootPath, uri)); + const workingSetUris = (0, (_collection || _load_collection()).arrayFlatten)(workingSetsStore.getApplicableDefinitions().filter(def => def.active).map(def => def.uris)) + // A working set can contain paths outside of rootPath. Ignore these. + .filter(uri => (_nuclideUri || _load_nuclideUri()).default.contains(rootPath, uri)) + // `processPaths` expects the second argument to be a relative path + // instead of the fully qualified NuclideUris we have here. + .map(uri => (_nuclideUri || _load_nuclideUri()).default.relative(rootPath, uri)); if (workingSetUris.length === 0) { // Working set and rootPath are disjoint, we shouldn't search rootPath return null; } - invariant(!workingSetUris.includes(WORKING_SET_PATH_MARKER)); + if (!!workingSetUris.includes((_constants || _load_constants()).WORKING_SET_PATH_MARKER)) { + throw new Error('Invariant violation: "!workingSetUris.includes(WORKING_SET_PATH_MARKER)"'); + } + const processed = this.processPaths(rootPath, workingSetUris); - invariant(processed); + + if (!processed) { + throw new Error('Invariant violation: "processed"'); + } + results.push(...processed); continue; } - const segments = nuclideUri.split(path); + const segments = (_nuclideUri || _load_nuclideUri()).default.split(path); const firstSegment = segments.shift(); results.push(path); if (firstSegment === rootPathBase) { @@ -175,10 +160,20 @@ export default class RemoteDirectorySearcher { return []; } else { // Try interpreting this as a subdirectory of the base as well. - results.push(nuclideUri.join(...segments)); + results.push((_nuclideUri || _load_nuclideUri()).default.join(...segments)); } } } return results; } } +exports.default = RemoteDirectorySearcher; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/RemoteProjectConnectionModal.js b/pkg/nuclide-remote-projects/lib/RemoteProjectConnectionModal.js index 3c56e4df84..6e1e893fd1 100644 --- a/pkg/nuclide-remote-projects/lib/RemoteProjectConnectionModal.js +++ b/pkg/nuclide-remote-projects/lib/RemoteProjectConnectionModal.js @@ -1,66 +1,64 @@ -/** - * 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 strict-local - * @format - */ - -/* globals Element */ - -import type {RemoteConnection} from '../../nuclide-remote-connection'; -import type {NuclideRemoteConnectionProfile} from './connection-types'; -import type { - NuclideNewConnectionProfileInitialFields, - NuclideRemoteConnectionParams, -} from './connection-types'; -import type {SshConnectionConfiguration} from '../../nuclide-remote-connection/lib/SshHandshake'; - -import {getUniqueHostsForProfiles} from './connection-profile-utils'; -import ConnectionDialog from './ConnectionDialog'; -import CreateConnectionProfileForm from './CreateConnectionProfileForm'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; - -type Screen = 'connect' | 'create-connection'; - -export type Props = { - connectionProfiles: Array, - initialFormFields: - | NuclideNewConnectionProfileInitialFields - | NuclideRemoteConnectionParams, - selectedProfileIndex: number, - screen: Screen, - onScreenChange: (screen: Screen) => mixed, - - onCancel: () => mixed, - onClosed?: () => mixed, - onConnect: ( - connection: RemoteConnection, - config: SshConnectionConfiguration, - ) => mixed, - onError: (error: Error, config: SshConnectionConfiguration) => mixed, - onDeleteProfileClicked: (selectedProfileIndex: number) => mixed, - onSaveProfile: ( - index: number, - profile: NuclideRemoteConnectionProfile, - ) => void, - onProfileSelected: (selectedProfileIndex: number) => void, - - onProfileCreated: (profile: NuclideRemoteConnectionProfile) => mixed, -}; - -export default class RemoteProjectConnectionModal extends React.Component< - Props, -> { - componentDidMount(): void { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _connectionProfileUtils; + +function _load_connectionProfileUtils() { + return _connectionProfileUtils = require('./connection-profile-utils'); +} + +var _ConnectionDialog; + +function _load_ConnectionDialog() { + return _ConnectionDialog = _interopRequireDefault(require('./ConnectionDialog')); +} + +var _CreateConnectionProfileForm; + +function _load_CreateConnectionProfileForm() { + return _CreateConnectionProfileForm = _interopRequireDefault(require('./CreateConnectionProfileForm')); +} + +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 }; } + +class RemoteProjectConnectionModal extends _react.Component { + constructor(...args) { + var _temp; + + return _temp = super(...args), this._updatePanelClass = () => { + const el = _reactDom.default.findDOMNode(this); + if (!(el instanceof Element)) { + return; + } + const panelEl = el.closest('atom-panel'); + if (panelEl == null) { + return; + } + + // Remove existing classes. + ['connect', 'create-connection'].forEach(screen => { + panelEl.classList.remove(`nuclide-remote-projects-panel-${screen}`); + }); + + // Add a class for the current screen. + panelEl.classList.add(`nuclide-remote-projects-panel-${this.props.screen}`); + }, _temp; + } + + componentDidMount() { this._updatePanelClass(); } - componentDidUpdate(prevProps: Props): void { + componentDidUpdate(prevProps) { if (this.props.screen !== prevProps.screen) { this._updatePanelClass(); } @@ -70,60 +68,49 @@ export default class RemoteProjectConnectionModal extends React.Component< * Reach outside the component to change the modal size. This is a little gross and would probably * ideally be done by the thing that creates the modal panel. */ - _updatePanelClass = () => { - const el = ReactDOM.findDOMNode(this); - if (!(el instanceof Element)) { - return; - } - const panelEl = el.closest('atom-panel'); - if (panelEl == null) { - return; - } - - // Remove existing classes. - ['connect', 'create-connection'].forEach(screen => { - panelEl.classList.remove(`nuclide-remote-projects-panel-${screen}`); - }); - // Add a class for the current screen. - panelEl.classList.add(`nuclide-remote-projects-panel-${this.props.screen}`); - }; - render(): React.Node { + render() { switch (this.props.screen) { case 'connect': - return ( - { - this.props.onScreenChange('create-connection'); - }} - onCancel={this.props.onCancel} - onClosed={this.props.onClosed} - onConnect={this.props.onConnect} - onError={this.props.onError} - onDeleteProfileClicked={this.props.onDeleteProfileClicked} - onSaveProfile={this.props.onSaveProfile} - onProfileSelected={this.props.onProfileSelected} - /> - ); + return _react.createElement((_ConnectionDialog || _load_ConnectionDialog()).default, { + selectedProfileIndex: this.props.selectedProfileIndex, + connectionProfiles: this.props.connectionProfiles, + onAddProfileClicked: () => { + this.props.onScreenChange('create-connection'); + }, + onCancel: this.props.onCancel, + onClosed: this.props.onClosed, + onConnect: this.props.onConnect, + onError: this.props.onError, + onDeleteProfileClicked: this.props.onDeleteProfileClicked, + onSaveProfile: this.props.onSaveProfile, + onProfileSelected: this.props.onProfileSelected + }); case 'create-connection': - return ( - { - this.props.onScreenChange('connect'); - }} - onSave={this.props.onProfileCreated} - initialFormFields={this.props.initialFormFields} - profileHosts={getUniqueHostsForProfiles( - this.props.connectionProfiles, - )} - /> - ); + return _react.createElement((_CreateConnectionProfileForm || _load_CreateConnectionProfileForm()).default, { + onCancel: () => { + this.props.onScreenChange('connect'); + }, + onSave: this.props.onProfileCreated, + initialFormFields: this.props.initialFormFields, + profileHosts: (0, (_connectionProfileUtils || _load_connectionProfileUtils()).getUniqueHostsForProfiles)(this.props.connectionProfiles) + }); default: - (this.props.screen: empty); + this.props.screen; throw new Error(`Invalid screen: ${this.props.screen}`); } } } +exports.default = RemoteProjectConnectionModal; /** + * 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. + * + * strict-local + * @format + */ + +/* globals Element */ \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/RemoteProjectsController.js b/pkg/nuclide-remote-projects/lib/RemoteProjectsController.js index 7352a1861f..f17734eced 100644 --- a/pkg/nuclide-remote-projects/lib/RemoteProjectsController.js +++ b/pkg/nuclide-remote-projects/lib/RemoteProjectsController.js @@ -1,3 +1,69 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports._observeConnectionState = _observeConnectionState; + +var _bindObservableAsProps; + +function _load_bindObservableAsProps() { + return _bindObservableAsProps = require('../../../modules/nuclide-commons-ui/bindObservableAsProps'); +} + +var _renderReactRoot; + +function _load_renderReactRoot() { + return _renderReactRoot = require('../../../modules/nuclide-commons-ui/renderReactRoot'); +} + +var _event; + +function _load_event() { + return _event = require('../../../modules/nuclide-commons/event'); +} + +var _observable; + +function _load_observable() { + return _observable = require('../../../modules/nuclide-commons/observable'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _ConnectionState; + +function _load_ConnectionState() { + return _ConnectionState = _interopRequireDefault(require('./ConnectionState')); +} + +var _StatusBarTile; + +function _load_StatusBarTile() { + return _StatusBarTile = _interopRequireDefault(require('./StatusBarTile')); +} + +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 THROTTLE_TIME_MS = 500; + +// Exported for testing. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,99 +71,51 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {Props as StatusBarTilePropsType} from './StatusBarTile'; - -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import {renderReactRoot} from 'nuclide-commons-ui/renderReactRoot'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import {throttle} from 'nuclide-commons/observable'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import * as React from 'react'; -import {Observable} from 'rxjs'; -import {ServerConnection} from '../../nuclide-remote-connection'; -import ConnectionState from './ConnectionState'; -import StatusBarTile from './StatusBarTile'; - -const THROTTLE_TIME_MS = 500; - -// Exported for testing. -export function _observeConnectionState( - connectionStream: Observable>, -): Observable { - return connectionStream - .switchMap( - ( - connections, - ): Observable]>> => { - if (connections.length === 0) { - return Observable.of([]); - } - // Observe the connection states of all connections simultaneously. - // $FlowFixMe: add array signature to combineLatest - return Observable.combineLatest( - connections.map(conn => { - const heartbeat = conn.getHeartbeat(); - return ( - Observable.of( - heartbeat.isAway() - ? ConnectionState.DISCONNECTED - : ConnectionState.CONNECTED, - ) - .concat( - Observable.merge( - observableFromSubscribeFunction(cb => - heartbeat.onHeartbeat(cb), - ).mapTo(ConnectionState.CONNECTED), - observableFromSubscribeFunction(cb => - heartbeat.onHeartbeatError(cb), - ).mapTo(ConnectionState.DISCONNECTED), - ), - ) - .distinctUntilChanged() - // Key the connection states by hostname. - .map(state => [conn.getRemoteHostname(), state]) - ); - }), - ); - }, - ) - .map(states => ({ - connectionStates: new Map(states), +function _observeConnectionState(connectionStream) { + return connectionStream.switchMap(connections => { + if (connections.length === 0) { + return _rxjsBundlesRxMinJs.Observable.of([]); + } + // Observe the connection states of all connections simultaneously. + // $FlowFixMe: add array signature to combineLatest + return _rxjsBundlesRxMinJs.Observable.combineLatest(connections.map(conn => { + const heartbeat = conn.getHeartbeat(); + return _rxjsBundlesRxMinJs.Observable.of(heartbeat.isAway() ? (_ConnectionState || _load_ConnectionState()).default.DISCONNECTED : (_ConnectionState || _load_ConnectionState()).default.CONNECTED).concat(_rxjsBundlesRxMinJs.Observable.merge((0, (_event || _load_event()).observableFromSubscribeFunction)(cb => heartbeat.onHeartbeat(cb)).mapTo((_ConnectionState || _load_ConnectionState()).default.CONNECTED), (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => heartbeat.onHeartbeatError(cb)).mapTo((_ConnectionState || _load_ConnectionState()).default.DISCONNECTED))).distinctUntilChanged() + // Key the connection states by hostname. + .map(state => [conn.getRemoteHostname(), state]); })); + }).map(states => ({ + connectionStates: new Map(states) + })); } -export default class RemoteProjectsController { - _disposables: UniversalDisposable; +class RemoteProjectsController { constructor() { - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - consumeStatusBar(statusBar: atom$StatusBar): IDisposable { - const BoundStatusBarTile = bindObservableAsProps( - _observeConnectionState(ServerConnection.observeRemoteConnections()).let( - throttle(THROTTLE_TIME_MS), - ), - StatusBarTile, - ); - const item = renderReactRoot(); + consumeStatusBar(statusBar) { + const BoundStatusBarTile = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)(_observeConnectionState((_nuclideRemoteConnection || _load_nuclideRemoteConnection()).ServerConnection.observeRemoteConnections()).let((0, (_observable || _load_observable()).throttle)(THROTTLE_TIME_MS)), (_StatusBarTile || _load_StatusBarTile()).default); + const item = (0, (_renderReactRoot || _load_renderReactRoot()).renderReactRoot)(_react.createElement(BoundStatusBarTile, null)); item.className = 'inline-block'; const statusBarTile = statusBar.addLeftTile({ item, - priority: -99, + priority: -99 }); - const disposable = new UniversalDisposable(() => statusBarTile.destroy()); + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(() => statusBarTile.destroy()); this._disposables.add(disposable); - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { this._disposables.remove(disposable); }); } - dispose(): void { + dispose() { this._disposables.dispose(); } } +exports.default = RemoteProjectsController; \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/RemoteProjectsService.js b/pkg/nuclide-remote-projects/lib/RemoteProjectsService.js index d0d86ade37..917c430d55 100644 --- a/pkg/nuclide-remote-projects/lib/RemoteProjectsService.js +++ b/pkg/nuclide-remote-projects/lib/RemoteProjectsService.js @@ -1,60 +1,58 @@ -/** - * 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 strict-local - * @format - */ - -import type {SerializableRemoteConnectionConfiguration} from '..'; -import type {OpenConnectionDialogOptions} from './open-connection'; -import type {RemoteConnectionConfiguration} from '../../nuclide-remote-connection/lib/RemoteConnection'; - -import {ReplaySubject} from 'rxjs'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {RemoteConnection} from '../../nuclide-remote-connection'; -import {openConnectionDialog} from './open-connection'; - -export default class RemoteProjectsService { - _subject: ReplaySubject>; +'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('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _openConnection; + +function _load_openConnection() { + return _openConnection = require('./open-connection'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class RemoteProjectsService { constructor() { - this._subject = new ReplaySubject(1); + this._subject = new _rxjsBundlesRxMinJs.ReplaySubject(1); } dispose() { this._subject.complete(); } - _reloadFinished(projects: Array) { + _reloadFinished(projects) { this._subject.next(projects); this._subject.complete(); } - waitForRemoteProjectReload( - callback: (loadedProjects: Array) => mixed, - ): IDisposable { - return new UniversalDisposable(this._subject.subscribe(callback)); + waitForRemoteProjectReload(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(this._subject.subscribe(callback)); } - async createRemoteConnection( - remoteProjectConfig: SerializableRemoteConnectionConfiguration, - ): Promise { + async createRemoteConnection(remoteProjectConfig) { const { host, path, displayTitle, - promptReconnectOnFailure = true, + promptReconnectOnFailure = true } = remoteProjectConfig; - const connection = await RemoteConnection.reconnect( - host, - path, - displayTitle, - promptReconnectOnFailure, - ); + const connection = await (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).RemoteConnection.reconnect(host, path, displayTitle, promptReconnectOnFailure); if (connection != null) { return connection; } @@ -62,21 +60,27 @@ export default class RemoteProjectsService { return null; } // If connection fails using saved config, open connect dialog. - return openConnectionDialog({ + return (0, (_openConnection || _load_openConnection()).openConnectionDialog)({ initialServer: host, - initialCwd: path, + initialCwd: path }); } - openConnectionDialog( - options: OpenConnectionDialogOptions, - ): Promise { - return openConnectionDialog(options); + openConnectionDialog(options) { + return (0, (_openConnection || _load_openConnection()).openConnectionDialog)(options); } - async findOrCreate( - config: RemoteConnectionConfiguration, - ): Promise { - return RemoteConnection.findOrCreate(config); + async findOrCreate(config) { + return (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).RemoteConnection.findOrCreate(config); } } +exports.default = RemoteProjectsService; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/RemoteTextEditorPlaceholder.js b/pkg/nuclide-remote-projects/lib/RemoteTextEditorPlaceholder.js index 2dcae24497..cb00876169 100644 --- a/pkg/nuclide-remote-projects/lib/RemoteTextEditorPlaceholder.js +++ b/pkg/nuclide-remote-projects/lib/RemoteTextEditorPlaceholder.js @@ -1,3 +1,34 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RemoteTextEditorPlaceholder = exports.TextEditor = undefined; + +var _renderReactRoot; + +function _load_renderReactRoot() { + return _renderReactRoot = require('../../../modules/nuclide-commons-ui/renderReactRoot'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _RemoteTextEditorPlaceholderComponent; + +function _load_RemoteTextEditorPlaceholderComponent() { + return _RemoteTextEditorPlaceholderComponent = _interopRequireDefault(require('./RemoteTextEditorPlaceholderComponent')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,31 +36,13 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import {renderReactRoot} from 'nuclide-commons-ui/renderReactRoot'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import * as React from 'react'; -import RemoteTextEditorPlaceholderComponent from './RemoteTextEditorPlaceholderComponent'; - -export type RemoteTextEditorPlaceholderState = { - deserializer: 'RemoteTextEditorPlaceholder', - data: { - uri: string, - contents: string, - // If the editor was unsaved, we'll restore the unsaved contents after load. - isModified: boolean, - }, -}; - -export class TextEditor implements atom$PaneItem { - _uri: string; - _contents: string; - _isModified: boolean; - - constructor({data}: RemoteTextEditorPlaceholderState) { +class TextEditor { + + constructor({ data }) { this._uri = data.uri; this._contents = data.contents; this._isModified = data.isModified; @@ -37,51 +50,50 @@ export class TextEditor implements atom$PaneItem { destroy() {} - serialize(): RemoteTextEditorPlaceholderState { + serialize() { return { deserializer: 'RemoteTextEditorPlaceholder', data: { uri: this._uri, contents: this._contents, // If the editor was unsaved, we'll restore the unsaved contents after load. - isModified: this._isModified, - }, + isModified: this._isModified + } }; } - getTitle(): string { - return nuclideUri.basename(this._uri); + getTitle() { + return (_nuclideUri || _load_nuclideUri()).default.basename(this._uri); } // This shouldn't *exactly* match the real URI. // Otherwise it makes it difficult to swap it out for the real editor. - getURI(): string { + getURI() { return this._uri.replace('nuclide://', 'nuclide-placeholder://'); } - getPath(): string { + getPath() { return this._uri; } - getText(): string { + getText() { return this._contents; } - isModified(): boolean { + isModified() { return this._isModified; } - getElement(): HTMLElement { - return renderReactRoot( - , - ); + getElement() { + return (0, (_renderReactRoot || _load_renderReactRoot()).renderReactRoot)(_react.createElement((_RemoteTextEditorPlaceholderComponent || _load_RemoteTextEditorPlaceholderComponent()).default, { + contents: this._contents, + uri: this._uri + })); } } -// We name the class "TextEditor" because Atom uses the constructor name as the `data-type` +exports.TextEditor = TextEditor; // We name the class "TextEditor" because Atom uses the constructor name as the `data-type` // attribute of the tab and themes style that. We want to make sure that these themes style our tab // like text editor tabs. -export const RemoteTextEditorPlaceholder = TextEditor; + +const RemoteTextEditorPlaceholder = exports.RemoteTextEditorPlaceholder = TextEditor; \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/RemoteTextEditorPlaceholderComponent.js b/pkg/nuclide-remote-projects/lib/RemoteTextEditorPlaceholderComponent.js index 8cf78a57ec..eb4085dbf8 100644 --- a/pkg/nuclide-remote-projects/lib/RemoteTextEditorPlaceholderComponent.js +++ b/pkg/nuclide-remote-projects/lib/RemoteTextEditorPlaceholderComponent.js @@ -1,50 +1,73 @@ -/** - * 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 - */ - -import {TextBuffer} from 'atom'; -import {AtomTextEditor} from 'nuclide-commons-ui/AtomTextEditor'; -import {Message, MessageTypes} from 'nuclide-commons-ui/Message'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import * as React from 'react'; - -type Props = { - contents: string, - uri: string, -}; - -export default class RemoteTextEditorPlaceholderComponent extends React.PureComponent< - Props, -> { - render(): React.Node { - const {hostname} = nuclideUri.parseRemoteUri(this.props.uri); - return ( -
    - - This is a read-only preview. -
    - Please reconnect to the remote host {hostname} to edit or save this - file. -
    - -
    +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _atom = require('atom'); + +var _AtomTextEditor; + +function _load_AtomTextEditor() { + return _AtomTextEditor = require('../../../modules/nuclide-commons-ui/AtomTextEditor'); +} + +var _Message; + +function _load_Message() { + return _Message = require('../../../modules/nuclide-commons-ui/Message'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +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 }; } + +class RemoteTextEditorPlaceholderComponent extends _react.PureComponent { + render() { + const { hostname } = (_nuclideUri || _load_nuclideUri()).default.parseRemoteUri(this.props.uri); + return _react.createElement( + 'div', + { className: 'nuclide-remote-text-editor-placeholder' }, + _react.createElement( + (_Message || _load_Message()).Message, + { + className: 'nuclide-remote-text-editor-placeholder-header', + type: (_Message || _load_Message()).MessageTypes.info }, + _react.createElement( + 'strong', + null, + 'This is a read-only preview.' + ), + _react.createElement('br', null), + 'Please reconnect to the remote host ', + hostname, + ' to edit or save this file.' + ), + _react.createElement((_AtomTextEditor || _load_AtomTextEditor()).AtomTextEditor, { + readOnly: true, + textBuffer: new _atom.TextBuffer({ + filePath: this.props.uri, + text: this.props.contents + }) + }) ); } } +exports.default = RemoteTextEditorPlaceholderComponent; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/StatusBarTile.js b/pkg/nuclide-remote-projects/lib/StatusBarTile.js index ad022390f6..3e8e09df06 100644 --- a/pkg/nuclide-remote-projects/lib/StatusBarTile.js +++ b/pkg/nuclide-remote-projects/lib/StatusBarTile.js @@ -1,67 +1,82 @@ -/** - * 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 - */ - -import addTooltip from 'nuclide-commons-ui/addTooltip'; -import {collect, someOfIterable} from 'nuclide-commons/collection'; -import nullthrows from 'nullthrows'; -import * as React from 'react'; -import ConnectionState from './ConnectionState'; - -export type Props = { - // Map of hostname to connection states. - connectionStates: Map>, -}; - -export default class StatusBarTile extends React.Component { - render(): React.Node { - const {connectionStates} = this.props; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _addTooltip; + +function _load_addTooltip() { + return _addTooltip = _interopRequireDefault(require('../../../modules/nuclide-commons-ui/addTooltip')); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _nullthrows; + +function _load_nullthrows() { + return _nullthrows = _interopRequireDefault(require('nullthrows')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _ConnectionState; + +function _load_ConnectionState() { + return _ConnectionState = _interopRequireDefault(require('./ConnectionState')); +} + +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 StatusBarTile extends _react.Component { + constructor(...args) { + var _temp; + + return _temp = super(...args), this._onStatusBarTileClicked = () => { + const { connectionStates } = this.props; + if (connectionStates.size === 0) { + return; + } + const grouped = (0, (_collection || _load_collection()).collect)(Array.from(connectionStates).map(([hostname, state]) => [state, hostname])); + const disconnectedHosts = grouped.get((_ConnectionState || _load_ConnectionState()).default.DISCONNECTED); + if (disconnectedHosts != null) { + atom.notifications.addWarning(`Lost connection to ${disconnectedHosts.join(', ')}. Attempting to reconnect...`); + } else { + const connectedHosts = (0, (_nullthrows || _load_nullthrows()).default)(grouped.get((_ConnectionState || _load_ConnectionState()).default.CONNECTED)); + atom.notifications.addInfo(`Connected to ${connectedHosts.join(', ')}.`); + } + }, _temp; + } + + render() { + const { connectionStates } = this.props; if (connectionStates.size === 0) { return null; } - const isDisconnected = someOfIterable( - connectionStates.values(), - x => x === ConnectionState.DISCONNECTED, - ); - const iconName: atom$Octicon = isDisconnected ? 'alert' : 'cloud-upload'; - return ( - - ); + const isDisconnected = (0, (_collection || _load_collection()).someOfIterable)(connectionStates.values(), x => x === (_ConnectionState || _load_ConnectionState()).default.DISCONNECTED); + const iconName = isDisconnected ? 'alert' : 'cloud-upload'; + return _react.createElement('span', { + className: `icon icon-${iconName} nuclide-remote-projects-status-icon`, + onClick: this._onStatusBarTileClicked + // eslint-disable-next-line nuclide-internal/jsx-simple-callback-refs + , ref: (0, (_addTooltip || _load_addTooltip()).default)({ title: 'Click for connection details.' }) + }); } - _onStatusBarTileClicked = (): void => { - const {connectionStates} = this.props; - if (connectionStates.size === 0) { - return; - } - const grouped = collect( - Array.from(connectionStates).map(([hostname, state]) => [ - state, - hostname, - ]), - ); - const disconnectedHosts = grouped.get(ConnectionState.DISCONNECTED); - if (disconnectedHosts != null) { - atom.notifications.addWarning( - `Lost connection to ${disconnectedHosts.join( - ', ', - )}. Attempting to reconnect...`, - ); - } else { - const connectedHosts = nullthrows(grouped.get(ConnectionState.CONNECTED)); - atom.notifications.addInfo(`Connected to ${connectedHosts.join(', ')}.`); - } - }; } +exports.default = StatusBarTile; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/config.js b/pkg/nuclide-remote-projects/lib/config.js index 277c1c3504..0300ee6ef0 100644 --- a/pkg/nuclide-remote-projects/lib/config.js +++ b/pkg/nuclide-remote-projects/lib/config.js @@ -1,3 +1,26 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getConnectionDialogDefaultSettings = getConnectionDialogDefaultSettings; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _os = _interopRequireDefault(require('os')); + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,18 +28,12 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideRemoteConnectionParams} from './connection-types'; - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import os from 'os'; -import {SshHandshake} from '../../nuclide-remote-connection'; - -export function getConnectionDialogDefaultSettings(): NuclideRemoteConnectionParams { - const {username, homedir} = os.userInfo(); +function getConnectionDialogDefaultSettings() { + const { username, homedir } = _os.default.userInfo(); return { server: '', username, @@ -24,10 +41,10 @@ export function getConnectionDialogDefaultSettings(): NuclideRemoteConnectionPar // so we always want to use `/` as the path separator for cwd, even if Atom // is running on Windows. cwd: `/home/${username}/`, - pathToPrivateKey: nuclideUri.join(homedir, '.ssh', 'id_rsa'), + pathToPrivateKey: (_nuclideUri || _load_nuclideUri()).default.join(homedir, '.ssh', 'id_rsa'), remoteServerCommand: 'nuclide-start-server', - authMethod: SshHandshake.SupportedMethods.PASSWORD, + authMethod: (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).SshHandshake.SupportedMethods.PASSWORD, displayTitle: '(default)', - sshPort: '22', + sshPort: '22' }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/connectBigDigSshHandshake.js b/pkg/nuclide-remote-projects/lib/connectBigDigSshHandshake.js index 6798d2a6f0..2b54189dd9 100644 --- a/pkg/nuclide-remote-projects/lib/connectBigDigSshHandshake.js +++ b/pkg/nuclide-remote-projects/lib/connectBigDigSshHandshake.js @@ -1,3 +1,52 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = connectBigDigSshHandshake; + +var _client; + +function _load_client() { + return _client = require('../../../modules/big-dig/src/client'); +} + +var _yargs; + +function _load_yargs() { + return _yargs = _interopRequireDefault(require('yargs')); +} + +var _fsPlus; + +function _load_fsPlus() { + return _fsPlus = _interopRequireDefault(require('fs-plus')); +} + +var _systemInfo; + +function _load_systemInfo() { + return _systemInfo = require('../../commons-node/system-info'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _ServerConnection; + +function _load_ServerConnection() { + return _ServerConnection = require('../../nuclide-remote-connection/lib/ServerConnection'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Adapts big-dig's SshHandshake to what Nuclide expects. + * After the migration is complete, we should be able to refactor this away. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,52 +54,19 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type { - SshHandshakeErrorType, - SshConnectionConfiguration, - RemoteConnectionConfiguration, -} from 'big-dig/src/client/SshHandshake'; -import type { - SshConnectionConfiguration as NuclideSshConnectionConfigurationType, - SshConnectionDelegate as NuclideSshConnectionDelegateType, -} from '../../nuclide-remote-connection/lib/SshHandshake'; - -import {SshHandshake} from 'big-dig/src/client/index'; -import yargs from 'yargs'; -import fs from 'fs-plus'; -import {getNuclideVersion} from '../../commons-node/system-info'; -import { - SshHandshake as NuclideSshHandshake, - RemoteConnection, -} from '../../nuclide-remote-connection'; -import {BIG_DIG_VERSION} from '../../nuclide-remote-connection/lib/ServerConnection'; - -/** - * Adapts big-dig's SshHandshake to what Nuclide expects. - * After the migration is complete, we should be able to refactor this away. - */ -export default function connectBigDigSshHandshake( - connectionConfig: NuclideSshConnectionConfigurationType, - delegate: NuclideSshConnectionDelegateType, -): SshHandshake { - const sshHandshake = new SshHandshake({ +function connectBigDigSshHandshake(connectionConfig, delegate) { + const sshHandshake = new (_client || _load_client()).SshHandshake({ onKeyboardInteractive(name, instructions, instructionsLang, prompts) { const prompt = prompts[0]; return new Promise(resolve => { switch (prompt.kind) { case 'ssh': case 'private-key': - delegate.onKeyboardInteractive( - name, - instructions, - instructionsLang, - [{prompt: prompt.prompt, echo: prompt.echo}], - resolve, - ); + delegate.onKeyboardInteractive(name, instructions, instructionsLang, [{ prompt: prompt.prompt, echo: prompt.echo }], resolve); break; default: // No need to handle update/install for unmanaged startups. @@ -58,43 +74,24 @@ export default function connectBigDigSshHandshake( } }); }, - onWillConnect(config: SshConnectionConfiguration) { + onWillConnect(config) { delegate.onWillConnect(connectionConfig); }, - onDidConnect( - remoteConfig: RemoteConnectionConfiguration, - config: SshConnectionConfiguration, - ) { - RemoteConnection.findOrCreate({ - ...remoteConfig, + onDidConnect(remoteConfig, config) { + (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).RemoteConnection.findOrCreate(Object.assign({}, remoteConfig, { path: connectionConfig.cwd, displayTitle: connectionConfig.displayTitle, - version: BIG_DIG_VERSION, - }).then( - connection => { - delegate.onDidConnect(connection, connectionConfig); - }, - err => { - delegate.onError( - err.code === 'CERT_NOT_YET_VALID' - ? NuclideSshHandshake.ErrorType.CERT_NOT_YET_VALID - : NuclideSshHandshake.ErrorType.SERVER_CANNOT_CONNECT, - err, - connectionConfig, - ); - }, - ); + version: (_ServerConnection || _load_ServerConnection()).BIG_DIG_VERSION + })).then(connection => { + delegate.onDidConnect(connection, connectionConfig); + }, err => { + delegate.onError(err.code === 'CERT_NOT_YET_VALID' ? (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).SshHandshake.ErrorType.CERT_NOT_YET_VALID : (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).SshHandshake.ErrorType.SERVER_CANNOT_CONNECT, err, connectionConfig); + }); }, - onError( - errorType: SshHandshakeErrorType, - error: Error, - config: SshConnectionConfiguration, - ) { - const nuclideErrorType = - NuclideSshHandshake.ErrorType[(errorType: any)] || - NuclideSshHandshake.ErrorType.UNKNOWN; + onError(errorType, error, config) { + const nuclideErrorType = (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).SshHandshake.ErrorType[errorType] || (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).SshHandshake.ErrorType.UNKNOWN; delegate.onError(nuclideErrorType, error, connectionConfig); - }, + } }); const { host, @@ -102,22 +99,22 @@ export default function connectBigDigSshHandshake( username, pathToPrivateKey, authMethod, - password, + password } = connectionConfig; - let {remoteServerCommand} = connectionConfig; + let { remoteServerCommand } = connectionConfig; // If the user does not specify --port or -p in the remoteServerCommand, then // we default to '9093-9090' as the port range. Currently, we do not give the // user a way to specify their own port range from the connection dialog. // We can straighten this out once we completely cutover to Big Dig. let remoteServerPorts = '9093-9090'; // Add the current Nuclide version, unless explicitly provided. - let version = getNuclideVersion(); + let version = (0, (_systemInfo || _load_systemInfo()).getNuclideVersion)(); // We'll only allow one Nuclide server per user - but you can override this. let exclusive = 'atom'; // big-dig doesn't parse extra arguments. // We'll try to adapt commonly used ones for now. if (remoteServerCommand.includes(' ')) { - const parsed = yargs.parse(remoteServerCommand); + const parsed = (_yargs || _load_yargs()).default.parse(remoteServerCommand); remoteServerCommand = parsed._[0]; if (parsed.version != null) { version = parsed.version; @@ -134,7 +131,7 @@ export default function connectBigDigSshHandshake( } // We use fs-plus's normalize() function because it will expand the ~, if present. - const expandedPath = fs.normalize(pathToPrivateKey); + const expandedPath = (_fsPlus || _load_fsPlus()).default.normalize(pathToPrivateKey); // Add an extra flag to indicate the use of big-dig. remoteServerCommand += ' --big-dig'; @@ -145,12 +142,12 @@ export default function connectBigDigSshHandshake( username, pathToPrivateKey: expandedPath, remoteServer: { - command: remoteServerCommand, + command: remoteServerCommand }, remoteServerPorts, authMethod, password, - exclusive, + exclusive }); return sshHandshake; -} +} \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/connection-profile-utils.js b/pkg/nuclide-remote-projects/lib/connection-profile-utils.js index b37629ef47..91a0909eae 100644 --- a/pkg/nuclide-remote-projects/lib/connection-profile-utils.js +++ b/pkg/nuclide-remote-projects/lib/connection-profile-utils.js @@ -1,29 +1,37 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getDefaultConnectionProfile = getDefaultConnectionProfile; +exports.getSavedConnectionProfiles = getSavedConnectionProfiles; +exports.saveConnectionProfiles = saveConnectionProfiles; +exports.onSavedConnectionProfilesDidChange = onSavedConnectionProfilesDidChange; +exports.getUniqueHostsForProfiles = getUniqueHostsForProfiles; +exports.getIPsForHosts = getIPsForHosts; +exports.saveConnectionConfig = saveConnectionConfig; +exports.getDefaultConfig = getDefaultConfig; +exports.getOfficialRemoteServerCommand = getOfficialRemoteServerCommand; + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} -/* global localStorage */ +var _collection; -import type { - NuclideRemoteConnectionParams, - NuclideRemoteConnectionProfile, - NuclideSavedConnectionDialogConfig, -} from './connection-types'; +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} -import type {SshConnectionConfiguration} from '../../nuclide-remote-connection/lib/SshHandshake'; -import type {DnsLookup} from '../../nuclide-remote-connection/lib/lookup-prefer-ip-v6'; +var _lookupPreferIpV; -import invariant from 'assert'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {arrayCompact} from 'nuclide-commons/collection'; -import lookupPreferIpv6 from '../../nuclide-remote-connection/lib/lookup-prefer-ip-v6'; +function _load_lookupPreferIpV() { + return _lookupPreferIpV = _interopRequireDefault(require('../../nuclide-remote-connection/lib/lookup-prefer-ip-v6')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Section: Default Connection Profile @@ -34,21 +42,13 @@ import lookupPreferIpv6 from '../../nuclide-remote-connection/lib/lookup-prefer- * the connection dialog and the default settings, plus the update logic we use * to change the remote server command. */ -export function getDefaultConnectionProfile( - options?: { - initialServer?: string, - initialCwd?: string, - initialRemoteServerCommand?: string, - } = {}, -): NuclideRemoteConnectionProfile { +function getDefaultConnectionProfile(options = {}) { const defaultConnectionSettings = getDefaultConfig(); const currentOfficialRSC = defaultConnectionSettings.remoteServerCommand; - const rawLastConnectionDetails = localStorage.getItem( - 'nuclide:nuclide-remote-projects:lastConnectionDetails', - ); + const rawLastConnectionDetails = localStorage.getItem('nuclide:nuclide-remote-projects:lastConnectionDetails'); - let lastConnectionDetails: ?NuclideSavedConnectionDialogConfig; + let lastConnectionDetails; try { // $FlowIgnore: null is ok here lastConnectionDetails = JSON.parse(rawLastConnectionDetails); @@ -60,27 +60,25 @@ export function getDefaultConnectionProfile( } } - invariant(lastConnectionDetails != null); + if (!(lastConnectionDetails != null)) { + throw new Error('Invariant violation: "lastConnectionDetails != null"'); + } + const { lastOfficialRemoteServerCommand, - updatedConfig, + updatedConfig } = lastConnectionDetails; const lastConfig = updatedConfig || {}; // Only use the user's last saved remote server command if there has been no // change (upgrade) in the official remote server command. let remoteServerCommand = currentOfficialRSC; - if ( - lastOfficialRemoteServerCommand === currentOfficialRSC && - lastConfig.remoteServerCommand - ) { + if (lastOfficialRemoteServerCommand === currentOfficialRSC && lastConfig.remoteServerCommand) { remoteServerCommand = lastConfig.remoteServerCommand; } - const dialogSettings: NuclideRemoteConnectionParams = { - ...defaultConnectionSettings, - ...lastConfig, - remoteServerCommand, - }; + const dialogSettings = Object.assign({}, defaultConnectionSettings, lastConfig, { + remoteServerCommand + }); if (options.initialServer != null) { dialogSettings.server = options.initialServer; @@ -101,7 +99,7 @@ export function getDefaultConnectionProfile( deletable: false, displayTitle: '(default)', params: dialogSettings, - saveable: false, + saveable: false }; } @@ -112,13 +110,26 @@ export function getDefaultConnectionProfile( /** * Returns an array of saved connection profiles. */ -export function getSavedConnectionProfiles(): Array< - NuclideRemoteConnectionProfile, -> { - const connectionProfiles: ?Array< - NuclideRemoteConnectionProfile, - > = (featureConfig.get('nuclide-remote-projects.connectionProfiles'): any); - invariant(Array.isArray(connectionProfiles)); +/** + * 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. + * + * + * @format + */ + +/* global localStorage */ + +function getSavedConnectionProfiles() { + const connectionProfiles = (_featureConfig || _load_featureConfig()).default.get('nuclide-remote-projects.connectionProfiles'); + + if (!Array.isArray(connectionProfiles)) { + throw new Error('Invariant violation: "Array.isArray(connectionProfiles)"'); + } + prepareSavedConnectionProfilesForDisplay(connectionProfiles); return connectionProfiles; } @@ -126,41 +137,27 @@ export function getSavedConnectionProfiles(): Array< /** * Saves the connection profiles. Overwrites any existing profiles. */ -export function saveConnectionProfiles( - profiles: Array, -): void { +function saveConnectionProfiles(profiles) { prepareConnectionProfilesForSaving(profiles); - featureConfig.set('nuclide-remote-projects.connectionProfiles', profiles); + (_featureConfig || _load_featureConfig()).default.set('nuclide-remote-projects.connectionProfiles', profiles); } -type ConnectionProfileChange = { - newValue: ?Array, - oldValue: ?Array, - keyPath: string, -}; /** * Calls the callback when the saved connection profiles change. * @return Disposable that can be disposed to stop listening for changes. */ -export function onSavedConnectionProfilesDidChange( - callback: (newProfiles: ?Array) => mixed, -): IDisposable { - return featureConfig.onDidChange( - 'nuclide-remote-projects.connectionProfiles', - (event: ConnectionProfileChange) => { - const newProfiles = event.newValue; - prepareSavedConnectionProfilesForDisplay(newProfiles); - callback(newProfiles); - }, - ); +function onSavedConnectionProfilesDidChange(callback) { + return (_featureConfig || _load_featureConfig()).default.onDidChange('nuclide-remote-projects.connectionProfiles', event => { + const newProfiles = event.newValue; + prepareSavedConnectionProfilesForDisplay(newProfiles); + callback(newProfiles); + }); } /** * Returns an array of host names for a given array of connection profiles */ -export function getUniqueHostsForProfiles( - profiles: Array, -): Array { +function getUniqueHostsForProfiles(profiles) { const uniqueHosts = new Set(); for (let i = 0; i < profiles.length; i++) { uniqueHosts.add(profiles[i].params.server); @@ -171,15 +168,11 @@ export function getUniqueHostsForProfiles( /** * Returns an array of IP addresses for a given array of host names */ -export async function getIPsForHosts( - hosts: Array, -): Promise> { - const promise_array = hosts.map(host => - lookupPreferIpv6(host).catch(() => {}), - ); +async function getIPsForHosts(hosts) { + const promise_array = hosts.map(host => (0, (_lookupPreferIpV || _load_lookupPreferIpV()).default)(host).catch(() => {})); const values = await Promise.all(promise_array); // $FlowFixMe(>=0.55.0) Flow suppress - return arrayCompact(values); + return (0, (_collection || _load_collection()).arrayCompact)(values); } /** @@ -189,31 +182,25 @@ export async function getIPsForHosts( /** * Saves a connection configuration along with the last official server command. */ -export function saveConnectionConfig( - config: SshConnectionConfiguration, - lastOfficialRemoteServerCommand: string, -): void { +function saveConnectionConfig(config, lastOfficialRemoteServerCommand) { // Don't store user's password. - const updatedConfig = {...config, password: ''}; + const updatedConfig = Object.assign({}, config, { password: '' }); // SshConnectionConfiguration's sshPort type is 'number', but we want to save // everything as strings. updatedConfig.sshPort = String(config.sshPort); - localStorage.setItem( - 'nuclide:nuclide-remote-projects:lastConnectionDetails', - JSON.stringify({ - updatedConfig, - // Save last official command to detect upgrade. - lastOfficialRemoteServerCommand, - }), - ); + localStorage.setItem('nuclide:nuclide-remote-projects:lastConnectionDetails', JSON.stringify({ + updatedConfig, + // Save last official command to detect upgrade. + lastOfficialRemoteServerCommand + })); } -let defaultConfig: ?any = null; +let defaultConfig = null; /** * This fetches the 'default' connection configuration supplied to the user * regardless of any connection profiles they might have saved. */ -export function getDefaultConfig(): any { +function getDefaultConfig() { if (defaultConfig) { return defaultConfig; } @@ -228,13 +215,11 @@ export function getDefaultConfig(): any { return defaultConfig; } -export function getOfficialRemoteServerCommand(): string { +function getOfficialRemoteServerCommand() { return getDefaultConfig().remoteServerCommand; } -function prepareSavedConnectionProfilesForDisplay( - connectionProfiles: ?Array, -): void { +function prepareSavedConnectionProfilesForDisplay(connectionProfiles) { if (!connectionProfiles) { return; } @@ -242,24 +227,22 @@ function prepareSavedConnectionProfilesForDisplay( // intended to use the default server command. We must fill this in. const defaultConnectionSettings = getDefaultConfig(); const currentOfficialRSC = defaultConnectionSettings.remoteServerCommand; - connectionProfiles.forEach((profile: NuclideRemoteConnectionProfile) => { + connectionProfiles.forEach(profile => { if (!profile.params.remoteServerCommand) { profile.params.remoteServerCommand = currentOfficialRSC; } }); } -function prepareConnectionProfilesForSaving( - connectionProfiles: Array, -): void { +function prepareConnectionProfilesForSaving(connectionProfiles) { // If a connection profile has a default remote server command, replace it with // an empty string. This indicates that this server command should be filled in // when this profile is used. const defaultConnectionSettings = getDefaultConfig(); const currentOfficialRSC = defaultConnectionSettings.remoteServerCommand; - connectionProfiles.forEach((profile: NuclideRemoteConnectionProfile) => { + connectionProfiles.forEach(profile => { if (profile.params.remoteServerCommand === currentOfficialRSC) { profile.params.remoteServerCommand = ''; } }); -} +} \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/connection-types.js b/pkg/nuclide-remote-projects/lib/connection-types.js index 0d4980507f..a726efc43f 100644 --- a/pkg/nuclide-remote-projects/lib/connection-types.js +++ b/pkg/nuclide-remote-projects/lib/connection-types.js @@ -1,60 +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 strict-local - * @format - */ - -import type {SshHandshakeAuthMethodsType} from '../../nuclide-remote-connection/lib/SshHandshake'; - -export type NuclideRemoteConnectionParams = { - username: string, - server: string, - cwd: string, - remoteServerCommand: string, - sshPort: string, - pathToPrivateKey: string, - authMethod: SshHandshakeAuthMethodsType, - displayTitle: string, -}; - -// The same as NuclideRemoteConnectionParams with optional `remoteServerCommand`. -export type NuclideNewConnectionProfileInitialFields = { - username: string, - server: string, - cwd: string, - remoteServerCommand?: string, - sshPort: string, - pathToPrivateKey: string, - authMethod: SshHandshakeAuthMethodsType, - displayTitle: string, -}; - -export type NuclideRemoteConnectionProfile = { - deletable: boolean, - displayTitle: string, - params: NuclideRemoteConnectionParams, - saveable: boolean, -}; - -export type NuclideSavedConnectionDialogConfig = { - lastOfficialRemoteServerCommand?: string, - updatedConfig?: NuclideRemoteConnectionParams, -}; - -// This type should not be saved -- it contains the user's password. -export type NuclideRemoteConnectionParamsWithPassword = { - username: string, - server: string, - cwd: string, - remoteServerCommand: string, - sshPort: string, - pathToPrivateKey: string, - authMethod: SshHandshakeAuthMethodsType, - password: string, - displayTitle: string, -}; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/constants.js b/pkg/nuclide-remote-projects/lib/constants.js index 588f157d33..e4c5cf67de 100644 --- a/pkg/nuclide-remote-projects/lib/constants.js +++ b/pkg/nuclide-remote-projects/lib/constants.js @@ -1,14 +1,23 @@ -/** - * 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 strict - * @format - */ - -import {getLogger} from 'log4js'; - -export const logger = getLogger('nuclide-remote-projects'); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.logger = undefined; + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +const logger = exports.logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-remote-projects'); /** + * 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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/form-validation-utils.js b/pkg/nuclide-remote-projects/lib/form-validation-utils.js index d3c171ee46..96ba37aa17 100644 --- a/pkg/nuclide-remote-projects/lib/form-validation-utils.js +++ b/pkg/nuclide-remote-projects/lib/form-validation-utils.js @@ -1,27 +1,15 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import {SshHandshake} from '../../nuclide-remote-connection'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.validateFormInputs = validateFormInputs; -import type { - NuclideRemoteConnectionParamsWithPassword, - NuclideRemoteConnectionProfile, -} from './connection-types'; +var _nuclideRemoteConnection; -export type NuclideNewConnectionProfileValidationResult = - | {|errorMessage: string|} - | {| - validatedProfile: NuclideRemoteConnectionProfile, - warningMessage?: string, - |}; +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} /* * This function checks that the required inputs to a connection profile are non-empty @@ -35,11 +23,7 @@ export type NuclideNewConnectionProfileValidationResult = * @return If the validation fails: an error object. If validation succeeds: * an object containing a valid profile to save. */ -export function validateFormInputs( - profileName: string, - connectionDetails: NuclideRemoteConnectionParamsWithPassword, - defaultRemoteServerCommand: string, -): NuclideNewConnectionProfileValidationResult { +function validateFormInputs(profileName, connectionDetails, defaultRemoteServerCommand) { // Validate the form inputs. The form must be fully filled-out. const missingFields = []; const profileParams = {}; @@ -76,13 +60,8 @@ export function validateFormInputs( } else { profileParams.authMethod = authMethod; } - if ( - authMethod === SshHandshake.SupportedMethods.PRIVATE_KEY && - !connectionDetails.pathToPrivateKey - ) { - missingFields.push( - 'Private Key File (required for the authentication method you selected)', - ); + if (authMethod === (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).SshHandshake.SupportedMethods.PRIVATE_KEY && !connectionDetails.pathToPrivateKey) { + missingFields.push('Private Key File (required for the authentication method you selected)'); } else { profileParams.pathToPrivateKey = connectionDetails.pathToPrivateKey; } @@ -91,7 +70,7 @@ export function validateFormInputs( if (missingFields.length) { const missingFieldsString = missingFields.join(', '); const errorMessage = `You must fill out all fields. Currently missing:\n${missingFieldsString}`; - return {errorMessage}; + return { errorMessage }; } // If all the fields are filled out, there are some additional checks we @@ -99,20 +78,11 @@ export function validateFormInputs( let warningMessage = ''; // 1. If a password is provided, all parts of the profile will be save except the password. - if ( - authMethod === SshHandshake.SupportedMethods.PASSWORD && - connectionDetails.password - ) { - warningMessage += - '* You provided a password for this profile. ' + - 'For security, Nuclide will save the other parts of this profile, ' + - 'but not the password.\n'; + if (authMethod === (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).SshHandshake.SupportedMethods.PASSWORD && connectionDetails.password) { + warningMessage += '* You provided a password for this profile. ' + 'For security, Nuclide will save the other parts of this profile, ' + 'but not the password.\n'; } // 2. Save the remote server command only if it is changed. - if ( - connectionDetails.remoteServerCommand && - connectionDetails.remoteServerCommand !== defaultRemoteServerCommand - ) { + if (connectionDetails.remoteServerCommand && connectionDetails.remoteServerCommand !== defaultRemoteServerCommand) { profileParams.remoteServerCommand = connectionDetails.remoteServerCommand; } else { profileParams.remoteServerCommand = ''; @@ -121,14 +91,20 @@ export function validateFormInputs( deletable: true, displayTitle: profileName, params: profileParams, - saveable: true, + saveable: true }; - const validationResult = - warningMessage.length > 0 - ? { - validatedProfile, - warningMessage, - } - : {validatedProfile}; + const validationResult = warningMessage.length > 0 ? { + validatedProfile, + warningMessage + } : { validatedProfile }; return validationResult; -} +} /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/main.js b/pkg/nuclide-remote-projects/lib/main.js index ca93dc3efb..5024b7458b 100644 --- a/pkg/nuclide-remote-projects/lib/main.js +++ b/pkg/nuclide-remote-projects/lib/main.js @@ -1,155 +1,221 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; + +var _idx; + +function _load_idx() { + return _idx = _interopRequireDefault(require('idx')); +} + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _textEditor; + +function _load_textEditor() { + return _textEditor = require('../../../modules/nuclide-commons-atom/text-editor'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _constants; + +function _load_constants() { + return _constants = require('./constants'); +} + +var _RemoteTextEditorPlaceholder; + +function _load_RemoteTextEditorPlaceholder() { + return _RemoteTextEditorPlaceholder = require('./RemoteTextEditorPlaceholder'); +} + +var _utils; + +function _load_utils() { + return _utils = require('./utils'); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _loadingNotification; + +function _load_loadingNotification() { + return _loadingNotification = _interopRequireDefault(require('../../commons-atom/loading-notification')); +} + +var _atom = require('atom'); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _openConnection; + +function _load_openConnection() { + return _openConnection = require('./open-connection'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _RemoteDirectorySearcher; + +function _load_RemoteDirectorySearcher() { + return _RemoteDirectorySearcher = _interopRequireDefault(require('./RemoteDirectorySearcher')); +} + +var _RemoteDirectoryProvider; + +function _load_RemoteDirectoryProvider() { + return _RemoteDirectoryProvider = _interopRequireDefault(require('./RemoteDirectoryProvider')); +} + +var _RemoteProjectsController; + +function _load_RemoteProjectsController() { + return _RemoteProjectsController = _interopRequireDefault(require('./RemoteProjectsController')); +} + +var _RemoteProjectsService; + +function _load_RemoteProjectsService() { + return _RemoteProjectsService = _interopRequireDefault(require('./RemoteProjectsService')); +} + +var _patchAtomWorkspaceReplace; -import type {HomeFragments} from '../../nuclide-home/lib/types'; -import type {RemoteConnectionConfiguration} from '../../nuclide-remote-connection/lib/RemoteConnection'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {OpenConnectionDialogOptions} from './open-connection'; -import type {WorkingSetsStore} from '../../nuclide-working-sets/lib/types'; - -import idx from 'idx'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import {enforceReadOnlyEditor} from 'nuclide-commons-atom/text-editor'; -import { - loadBufferForUri, - bufferForUri, - getServiceByNuclideUri, -} from '../../nuclide-remote-connection'; -import {logger} from './constants'; -import { - RemoteTextEditorPlaceholder, - type RemoteTextEditorPlaceholderState, -} from './RemoteTextEditorPlaceholder'; -import {getOpenFileEditorForRemoteProject} from './utils'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import loadingNotification from '../../commons-atom/loading-notification'; -import invariant from 'assert'; -import {TextEditor} from 'atom'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import { - RemoteConnection, - RemoteDirectory, - RemoteFile, - ServerConnection, - getCodeSearchServiceByNuclideUri, -} from '../../nuclide-remote-connection'; -import {trackImmediate} from '../../nuclide-analytics'; -import {openConnectionDialog} from './open-connection'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {sleep} from 'nuclide-commons/promise'; -import RemoteDirectorySearcher from './RemoteDirectorySearcher'; -import RemoteDirectoryProvider from './RemoteDirectoryProvider'; -import RemoteProjectsController from './RemoteProjectsController'; -import RemoteProjectsServiceImpl from './RemoteProjectsService'; -import patchAtomWorkspaceReplace from './patchAtomWorkspaceReplace'; -import {setNotificationService} from './AtomNotifications'; - -export type RemoteProjectsService = { - /** - * A simple way to wait for remote projects to finish reloading after startup. - * Resolves with a list of successfully reloaded project paths. - * If reloading has already finished, this immediately resolves. - */ - waitForRemoteProjectReload( - callback: (loadedProjects: Array) => mixed, - ): IDisposable, - - /** - * Attempts to open a remote connection, first by attempting the previously cached connection - * and then by opening a connection dialog. - */ - createRemoteConnection( - config: SerializableRemoteConnectionConfiguration, - ): Promise, - - /** - * Start the flow to open a remote connection by opening a connection dialog, regardless of - * the previously cached connections. - */ - openConnectionDialog( - config: OpenConnectionDialogOptions, - ): Promise, - - /** - * Find an existing connection or create one given the remote connetion details. - */ - findOrCreate( - config: RemoteConnectionConfiguration, - ): Promise, -}; +function _load_patchAtomWorkspaceReplace() { + return _patchAtomWorkspaceReplace = _interopRequireDefault(require('./patchAtomWorkspaceReplace')); +} + +var _AtomNotifications; + +function _load_AtomNotifications() { + return _AtomNotifications = require('./AtomNotifications'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Stores the host, path, displayTitle of a remote connection and * a property switch for whether to prompt to connect again if reconnect attempt fails. */ -export type SerializableRemoteConnectionConfiguration = { - host: string, - path: string, - displayTitle: string, - promptReconnectOnFailure?: boolean, -}; +const CLOSE_PROJECT_DELAY_MS = 100; /** + * 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. + * + * strict-local + * @format + */ -type SerializedPackageState = {| - remoteProjectsConfig: Array, -|}; +class Activation { -const CLOSE_PROJECT_DELAY_MS = 100; + constructor(state) { + var _ref; -class Activation { - _subscriptions = new UniversalDisposable(); - _pendingFiles = {}; - _controller = new RemoteProjectsController(); - _remoteProjectsService = new RemoteProjectsServiceImpl(); - _workingSetsStore: ?WorkingSetsStore; - - constructor(state: ?mixed) { - this._subscriptions.add( - RemoteConnection.onDidAddRemoteConnection(connection => { - this._subscriptions.add(addRemoteFolderToProject(connection)); - replaceRemoteEditorPlaceholders(connection); - }), - ); - - this._subscriptions.add( - atom.commands.add( - 'atom-workspace', - 'nuclide-remote-projects:connect', - event => { - const {initialCwd, project} = event.detail || {}; - openConnectionDialog({ - initialCwd, - project, - }); - }, - ), - atom.commands.add( - 'atom-workspace', - 'nuclide-remote-projects:kill-and-restart', - () => shutdownServersAndRestartNuclide(), - ), - ); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + this._pendingFiles = {}; + this._controller = new (_RemoteProjectsController || _load_RemoteProjectsController()).default(); + this._remoteProjectsService = new (_RemoteProjectsService || _load_RemoteProjectsService()).default(); + + this._openRemoteFile = (uri = '') => { + if ((_nuclideUri || _load_nuclideUri()).default.looksLikeImageUri(uri) && atom.packages.getLoadedPackage('nuclide-image-view') != null) { + // Images will be handled by the nuclide-remote-images package. Ideally, all remote files + // would go through one code path and then be delegated to the appropriate handler (instead + // of having this need to be aware of the nuclide-remote-images package implementation), but + // this is quick and dirty. + return; + } + if (!uri.startsWith('nuclide:') && !(_nuclideUri || _load_nuclideUri()).default.isInArchive(uri)) { + return; + } + if (uri.startsWith('nuclide:')) { + const serverConnection = (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).ServerConnection.getForUri(uri); + if (serverConnection == null) { + // It's possible that the URI opens before the remote connection has finished loading + // (or the remote connection cannot be restored for some reason). + // + // In this case, we can just let Atom open a blank editor. Once the connection + // is re-established, the `onDidAddRemoteConnection` logic above will restore the + // editor contents as appropriate. + return; + } + const connection = (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).RemoteConnection.getForUri(uri); + // On Atom restart, it tries to open the uri path as a file tab because it's not a local + // directory. We can't let that create a file with the initial working directory path. + if (connection != null && uri === connection.getUri()) { + const blankEditor = atom.workspace.buildTextEditor({}); + // No matter what we do here, Atom is going to create a blank editor. + // We don't want the user to see this, so destroy it as soon as possible. + setImmediate(() => blankEditor.destroy()); + return blankEditor; + } + } + if (this._pendingFiles[uri]) { + return this._pendingFiles[uri]; + } + const textEditorPromise = createEditorForNuclide(uri); + this._pendingFiles[uri] = textEditorPromise; + const removeFromCache = () => delete this._pendingFiles[uri]; + textEditorPromise.then(removeFromCache, removeFromCache); + return textEditorPromise; + }; + + this._subscriptions.add((_nuclideRemoteConnection || _load_nuclideRemoteConnection()).RemoteConnection.onDidAddRemoteConnection(connection => { + this._subscriptions.add(addRemoteFolderToProject(connection)); + replaceRemoteEditorPlaceholders(connection); + })); + + this._subscriptions.add(atom.commands.add('atom-workspace', 'nuclide-remote-projects:connect', event => { + const { initialCwd, project } = event.detail || {}; + (0, (_openConnection || _load_openConnection()).openConnectionDialog)({ + initialCwd, + project + }); + }), atom.commands.add('atom-workspace', 'nuclide-remote-projects:kill-and-restart', () => shutdownServersAndRestartNuclide())); // Subscribe opener before restoring the remote projects. this._subscriptions.add(atom.workspace.addOpener(this._openRemoteFile)); - this._subscriptions.add( - atom.workspace.observeTextEditors(editor => { - const uri = editor.getURI(); - if (uri != null && nuclideUri.isInArchive(uri)) { - enforceReadOnlyEditor(editor); - } - }), - ); + this._subscriptions.add(atom.workspace.observeTextEditors(editor => { + const uri = editor.getURI(); + if (uri != null && (_nuclideUri || _load_nuclideUri()).default.isInArchive(uri)) { + (0, (_textEditor || _load_textEditor()).enforceReadOnlyEditor)(editor); + } + })); - this._subscriptions.add(patchAtomWorkspaceReplace()); + this._subscriptions.add((0, (_patchAtomWorkspaceReplace || _load_patchAtomWorkspaceReplace()).default)()); // If RemoteDirectoryProvider is called before this, and it failed // to provide a RemoteDirectory for a @@ -160,15 +226,11 @@ class Activation { deleteDummyRemoteRootDirectories(); // Attempt to reload previously open projects. - const remoteProjectsConfig = validateRemoteProjectConfig( - typeof state === 'object' - ? idx(state, _ => _.remoteProjectsConfig) - : null, - ); + const remoteProjectsConfig = validateRemoteProjectConfig(typeof state === 'object' ? (_ref = state) != null ? _ref.remoteProjectsConfig : _ref : null); reloadRemoteProjects(remoteProjectsConfig, this._remoteProjectsService); } - dispose(): Promise { + dispose() { this._subscriptions.dispose(); this._controller.dispose(); this._remoteProjectsService.dispose(); @@ -178,163 +240,88 @@ class Activation { const shutdownTimeout = 1000; // This tells Atom to wait for the close request to be acknowledged - // but don't wait too long. - return Promise.race([ - ServerConnection.closeAll(shutdown).catch(err => { - // log4js is potentially also being shut down during deactivation. - // eslint-disable-next-line no-console - console.error('Error closing server connections in deactivate', err); - }), - sleep(shutdownTimeout), - ]); + return Promise.race([(_nuclideRemoteConnection || _load_nuclideRemoteConnection()).ServerConnection.closeAll(shutdown).catch(err => { + // log4js is potentially also being shut down during deactivation. + // eslint-disable-next-line no-console + console.error('Error closing server connections in deactivate', err); + }), (0, (_promise || _load_promise()).sleep)(shutdownTimeout)]); } - serialize(): SerializedPackageState { + serialize() { + var _ref2; + const currentProjectSpec = - // $FlowIgnore: Add this to our types once we upstream - atom.project.getSpecification == null - ? null - : atom.project.getSpecification(); - const projectFileUri = idx(currentProjectSpec, _ => _.originPath); + // $FlowIgnore: Add this to our types once we upstream + atom.project.getSpecification == null ? null : atom.project.getSpecification(); + const projectFileUri = (_ref2 = currentProjectSpec) != null ? _ref2.originPath : _ref2; let remoteProjectSpecUris; - if (projectFileUri != null && nuclideUri.isRemote(projectFileUri)) { - const projectSpecPaths = idx(currentProjectSpec, _ => _.paths) || []; - remoteProjectSpecUris = new Set( - projectSpecPaths.map(path => nuclideUri.resolve(projectFileUri, path)), - ); + if (projectFileUri != null && (_nuclideUri || _load_nuclideUri()).default.isRemote(projectFileUri)) { + var _ref3; + + const projectSpecPaths = ((_ref3 = currentProjectSpec) != null ? _ref3.paths : _ref3) || []; + remoteProjectSpecUris = new Set(projectSpecPaths.map(path => (_nuclideUri || _load_nuclideUri()).default.resolve(projectFileUri, path))); } else { remoteProjectSpecUris = new Set(); } // Get the directories that aren't part of the project file. They were added by the user so we // want to restore those too. - const remoteConnections = getRemoteRootDirectories() - .map(dir => RemoteConnection.getForUri(dir.getPath())) - .filter(Boolean); - const projectConnections = remoteConnections.filter(conn => - remoteProjectSpecUris.has(conn.getUri()), - ); - const nonProjectConnections = remoteConnections.filter( - conn => !projectConnections.includes(conn), - ); - - const projectConfig = - projectConnections.length === 0 - ? null - : projectConnections[0].getConfig(); - const activeProject = - projectFileUri == null || projectConfig == null - ? null - : { - ...projectConfig, - host: nuclideUri.getHostname(projectFileUri), - path: nuclideUri.getPath(projectFileUri), - }; - - const remoteProjectsConfig = [ - activeProject, - ...nonProjectConnections.map(conn => - createSerializableRemoteConnectionConfiguration(conn.getConfig()), - ), - ].filter(Boolean); - - return {remoteProjectsConfig}; - } + const remoteConnections = getRemoteRootDirectories().map(dir => (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).RemoteConnection.getForUri(dir.getPath())).filter(Boolean); + const projectConnections = remoteConnections.filter(conn => remoteProjectSpecUris.has(conn.getUri())); + const nonProjectConnections = remoteConnections.filter(conn => !projectConnections.includes(conn)); + + const projectConfig = projectConnections.length === 0 ? null : projectConnections[0].getConfig(); + const activeProject = projectFileUri == null || projectConfig == null ? null : Object.assign({}, projectConfig, { + host: (_nuclideUri || _load_nuclideUri()).default.getHostname(projectFileUri), + path: (_nuclideUri || _load_nuclideUri()).default.getPath(projectFileUri) + }); - _openRemoteFile = (uri = '') => { - if ( - nuclideUri.looksLikeImageUri(uri) && - atom.packages.getLoadedPackage('nuclide-image-view') != null - ) { - // Images will be handled by the nuclide-remote-images package. Ideally, all remote files - // would go through one code path and then be delegated to the appropriate handler (instead - // of having this need to be aware of the nuclide-remote-images package implementation), but - // this is quick and dirty. - return; - } - if (!uri.startsWith('nuclide:') && !nuclideUri.isInArchive(uri)) { - return; - } - if (uri.startsWith('nuclide:')) { - const serverConnection = ServerConnection.getForUri(uri); - if (serverConnection == null) { - // It's possible that the URI opens before the remote connection has finished loading - // (or the remote connection cannot be restored for some reason). - // - // In this case, we can just let Atom open a blank editor. Once the connection - // is re-established, the `onDidAddRemoteConnection` logic above will restore the - // editor contents as appropriate. - return; - } - const connection = RemoteConnection.getForUri(uri); - // On Atom restart, it tries to open the uri path as a file tab because it's not a local - // directory. We can't let that create a file with the initial working directory path. - if (connection != null && uri === connection.getUri()) { - const blankEditor = atom.workspace.buildTextEditor({}); - // No matter what we do here, Atom is going to create a blank editor. - // We don't want the user to see this, so destroy it as soon as possible. - setImmediate(() => blankEditor.destroy()); - return blankEditor; - } - } - if (this._pendingFiles[uri]) { - return this._pendingFiles[uri]; - } - const textEditorPromise = createEditorForNuclide(uri); - this._pendingFiles[uri] = textEditorPromise; - const removeFromCache = () => delete this._pendingFiles[uri]; - textEditorPromise.then(removeFromCache, removeFromCache); - return textEditorPromise; - }; + const remoteProjectsConfig = [activeProject, ...nonProjectConnections.map(conn => createSerializableRemoteConnectionConfiguration(conn.getConfig()))].filter(Boolean); + + return { remoteProjectsConfig }; + } // // Services // - getHomeFragments(): HomeFragments { + getHomeFragments() { return { feature: { title: 'Remote Connection', icon: 'cloud-upload', description: 'Connect to a remote server to edit files.', - command: 'nuclide-remote-projects:connect', + command: 'nuclide-remote-projects:connect' }, - priority: 8, + priority: 8 }; } - provideRemoteProjectsService(): RemoteProjectsService { + provideRemoteProjectsService() { return this._remoteProjectsService; } - provideRpcServices(): nuclide$RpcService { + provideRpcServices() { return Object.freeze({ - getServiceByNuclideUri: (serviceName: string, uri: ?string) => - getServiceByNuclideUri(serviceName, uri), + getServiceByNuclideUri: (serviceName, uri) => (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getServiceByNuclideUri)(serviceName, uri) }); } - createRemoteDirectorySearcher(): RemoteDirectorySearcher { - return new RemoteDirectorySearcher((dir: RemoteDirectory) => { - return getCodeSearchServiceByNuclideUri(dir.getPath()); + createRemoteDirectorySearcher() { + return new (_RemoteDirectorySearcher || _load_RemoteDirectorySearcher()).default(dir => { + return (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getCodeSearchServiceByNuclideUri)(dir.getPath()); }, () => this._workingSetsStore); } - consumeStatusBar(statusBar: atom$StatusBar): void { + consumeStatusBar(statusBar) { this._controller.consumeStatusBar(statusBar); } - consumeNotifications( - raiseNativeNotification: ( - title: string, - body: string, - timeout: number, - raiseIfAtomHasFocus: boolean, - ) => ?IDisposable, - ): void { - setNotificationService(raiseNativeNotification); + consumeNotifications(raiseNativeNotification) { + (0, (_AtomNotifications || _load_AtomNotifications()).setNotificationService)(raiseNativeNotification); } - consumeWorkingSetsStore(store: WorkingSetsStore): void { + consumeWorkingSetsStore(store) { this._workingSetsStore = store; } @@ -342,25 +329,21 @@ class Activation { // Deserializers // - deserializeRemoteTextEditorPlaceholder( - state: RemoteTextEditorPlaceholderState, - ): RemoteTextEditorPlaceholder { - return new RemoteTextEditorPlaceholder(state); + deserializeRemoteTextEditorPlaceholder(state) { + return new (_RemoteTextEditorPlaceholder || _load_RemoteTextEditorPlaceholder()).RemoteTextEditorPlaceholder(state); } } -function createSerializableRemoteConnectionConfiguration( - config: RemoteConnectionConfiguration, -): SerializableRemoteConnectionConfiguration { +function createSerializableRemoteConnectionConfiguration(config) { return { host: config.host, path: config.path, displayTitle: config.displayTitle, - promptReconnectOnFailure: config.promptReconnectOnFailure, + promptReconnectOnFailure: config.promptReconnectOnFailure }; } -function addRemoteFolderToProject(connection: RemoteConnection): IDisposable { +function addRemoteFolderToProject(connection) { const workingDirectoryUri = connection.getUri(); // If restoring state, then the project already exists with local directory and wrong repo // instances. Hence, we remove it here, if existing, and add the new path for which we added a @@ -375,7 +358,7 @@ function addRemoteFolderToProject(connection: RemoteConnection): IDisposable { } // The project was removed from the tree. - logger.info(`Project ${workingDirectoryUri} removed from the tree`); + (_constants || _load_constants()).logger.info(`Project ${workingDirectoryUri} removed from the tree`); subscription.dispose(); if (connection.getConnection().hasSingleMountPoint()) { closeOpenFilesForRemoteProject(connection); @@ -393,16 +376,14 @@ function addRemoteFolderToProject(connection: RemoteConnection): IDisposable { }); function closeRemoteConnection() { - const closeConnection = (shutdownIfLast: boolean) => { - logger.info('Closing remote connection.', {shutdownIfLast}); + const closeConnection = shutdownIfLast => { + (_constants || _load_constants()).logger.info('Closing remote connection.', { shutdownIfLast }); connection.close(shutdownIfLast); }; - logger.info('Closing connection to remote project.'); + (_constants || _load_constants()).logger.info('Closing connection to remote project.'); if (!connection.getConnection().hasSingleMountPoint()) { - logger.info( - 'Remaining remote projects using Nuclide Server - no prompt to shutdown', - ); + (_constants || _load_constants()).logger.info('Remaining remote projects using Nuclide Server - no prompt to shutdown'); const shutdownIfLast = false; closeConnection(shutdownIfLast); return; @@ -413,39 +394,36 @@ function addRemoteFolderToProject(connection: RemoteConnection): IDisposable { return; } - const shutdownServerAfterDisconnection = featureConfig.get( - 'nuclide-remote-projects.shutdownServerAfterDisconnection', - ); - invariant(typeof shutdownServerAfterDisconnection === 'boolean'); - logger.info({shutdownServerAfterDisconnection}); + const shutdownServerAfterDisconnection = (_featureConfig || _load_featureConfig()).default.get('nuclide-remote-projects.shutdownServerAfterDisconnection'); + + if (!(typeof shutdownServerAfterDisconnection === 'boolean')) { + throw new Error('Invariant violation: "typeof shutdownServerAfterDisconnection === \'boolean\'"'); + } + + (_constants || _load_constants()).logger.info({ shutdownServerAfterDisconnection }); closeConnection(shutdownServerAfterDisconnection); } return subscription; } -function closeOpenFilesForRemoteProject(connection: RemoteConnection): void { +function closeOpenFilesForRemoteProject(connection) { const remoteProjectConfig = connection.getConfig(); - const openInstances = getOpenFileEditorForRemoteProject(remoteProjectConfig); + const openInstances = (0, (_utils || _load_utils()).getOpenFileEditorForRemoteProject)(remoteProjectConfig); for (const openInstance of openInstances) { - const {uri, editor, pane} = openInstance; + const { uri, editor, pane } = openInstance; // It's possible to open files outside of the root of the connection. // Only clean up these files if we're the only connection left. - if ( - connection.getConnection().hasSingleMountPoint() || - nuclideUri.contains(connection.getUri(), uri) - ) { + if (connection.getConnection().hasSingleMountPoint() || (_nuclideUri || _load_nuclideUri()).default.contains(connection.getUri(), uri)) { pane.removeItem(editor); editor.destroy(); } } } -function getRemoteRootDirectories(): Array { +function getRemoteRootDirectories() { // TODO: Use nuclideUri instead. - return atom.project - .getDirectories() - .filter(directory => directory.getPath().startsWith('nuclide:')); + return atom.project.getDirectories().filter(directory => directory.getPath().startsWith('nuclide:')); } /** @@ -454,10 +432,7 @@ function getRemoteRootDirectories(): Array { */ function deleteDummyRemoteRootDirectories() { for (const directory of atom.project.getDirectories()) { - if ( - nuclideUri.isRemote(directory.getPath()) && - !RemoteDirectory.isRemoteDirectory(directory) - ) { + if ((_nuclideUri || _load_nuclideUri()).default.isRemote(directory.getPath()) && !(_nuclideRemoteConnection || _load_nuclideRemoteConnection()).RemoteDirectory.isRemoteDirectory(directory)) { atom.project.removePath(directory.getPath()); } } @@ -467,14 +442,11 @@ function deleteDummyRemoteRootDirectories() { * The same TextEditor must be returned to prevent Atom from creating multiple tabs * for the same file, because Atom doesn't cache pending opener promises. */ -async function createEditorForNuclide(uri: NuclideUri): Promise { +async function createEditorForNuclide(uri) { try { let buffer; try { - buffer = await loadingNotification( - loadBufferForUri(uri), - `Opening \`${nuclideUri.nuclideUriToDisplayString(uri)}\`...`, - 1000 /* delay */, + buffer = await (0, (_loadingNotification || _load_loadingNotification()).default)((0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).loadBufferForUri)(uri), `Opening \`${(_nuclideUri || _load_nuclideUri()).default.nuclideUriToDisplayString(uri)}\`...`, 1000 /* delay */ ); } catch (err) { // Suppress ENOENT errors which occur if the file doesn't exist. @@ -488,7 +460,7 @@ async function createEditorForNuclide(uri: NuclideUri): Promise { // as `loaded` and the proper events are fired. The effect of all of this // is that files that don't exist remotely anymore are shown as empty // unsaved text editors. - buffer = bufferForUri(uri); + buffer = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).bufferForUri)(uri); buffer.finishLoading(); } // When in "large file mode", syntax highlighting and line wrapping are @@ -499,17 +471,17 @@ async function createEditorForNuclide(uri: NuclideUri): Promise { const textEditor = atom.textEditors.build({ buffer, largeFileMode, - autoHeight: false, + autoHeight: false }); // Add a custom serializer that deserializes to a placeholder TextEditor // that we have total control over. The usual Atom deserialization flow for editors // typically involves attempting to load the file from disk, which tends to throw. const textEditorSerialize = textEditor.serialize; // $FlowIgnore - textEditor.serialize = function(): RemoteTextEditorPlaceholderState { + textEditor.serialize = function () { const path = textEditor.getPath(); // It's possible for an editor's path to become local (via Save As). - if (path == null || !nuclideUri.isRemote(path)) { + if (path == null || !(_nuclideUri || _load_nuclideUri()).default.isRemote(path)) { return textEditorSerialize.call(textEditor); } return { @@ -518,8 +490,8 @@ async function createEditorForNuclide(uri: NuclideUri): Promise { uri: path, contents: textEditor.getText(), // If the editor was unsaved, we'll restore the unsaved contents after load. - isModified: textEditor.isModified(), - }, + isModified: textEditor.isModified() + } }; }; // Null out the buffer's serializer. @@ -530,40 +502,30 @@ async function createEditorForNuclide(uri: NuclideUri): Promise { // $FlowIgnore const bufferSerialize = buffer.serialize; // $FlowIgnore - buffer.serialize = function() { + buffer.serialize = function () { const path = buffer.getPath(); - if (path == null || !nuclideUri.isRemote(path)) { + if (path == null || !(_nuclideUri || _load_nuclideUri()).default.isRemote(path)) { return bufferSerialize.call(buffer); } return null; }; return textEditor; } catch (err) { - logger.warn('buffer load issue:', err); + (_constants || _load_constants()).logger.warn('buffer load issue:', err); atom.notifications.addError(`Failed to open ${uri}: ${err.message}`); throw err; } } -async function reloadRemoteProjects( - remoteProjects: Array, - remoteProjectsService: RemoteProjectsServiceImpl, -): Promise { +async function reloadRemoteProjects(remoteProjects, remoteProjectsService) { // This is intentionally serial. // The 90% use case is to have multiple remote projects for a single connection; - // after the first one succeeds the rest should require no user action. - const reloadedProjects: Array = []; + const reloadedProjects = []; for (const config of remoteProjects) { // eslint-disable-next-line no-await-in-loop - const connection = await remoteProjectsService.createRemoteConnection( - config, - ); + const connection = await remoteProjectsService.createRemoteConnection(config); if (!connection) { - logger.info( - 'No RemoteConnection returned on restore state trial:', - config.host, - config.path, - ); + (_constants || _load_constants()).logger.info('No RemoteConnection returned on restore state trial:', config.host, config.path); // Atom restores remote files with a malformed URIs, which somewhat resemble local paths. // If after an unsuccessful connection user modifies and saves them he's presented @@ -587,7 +549,7 @@ async function reloadRemoteProjects( } }); - ServerConnection.cancelConnection(config.host); + (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).ServerConnection.cancelConnection(config.host); } else { reloadedProjects.push(connection.getUri()); } @@ -595,49 +557,44 @@ async function reloadRemoteProjects( remoteProjectsService._reloadFinished(reloadedProjects); } -function shutdownServersAndRestartNuclide(): void { +function shutdownServersAndRestartNuclide() { atom.confirm({ - message: - 'This will shutdown your Nuclide servers and restart Atom, ' + - 'discarding all unsaved changes. Continue?', + message: 'This will shutdown your Nuclide servers and restart Atom, ' + 'discarding all unsaved changes. Continue?', buttons: { 'Shutdown && Restart': async () => { try { - await trackImmediate('nuclide-remote-projects:kill-and-restart'); + await (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackImmediate)('nuclide-remote-projects:kill-and-restart'); } finally { // This directly kills the servers without removing the RemoteConnections // so that restarting Nuclide preserves the existing workspace state. - await ServerConnection.forceShutdownAllServers(); + await (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).ServerConnection.forceShutdownAllServers(); atom.reload(); } }, - Cancel: () => {}, - }, + Cancel: () => {} + } }); } -function replaceRemoteEditorPlaceholders(connection: RemoteConnection): void { +function replaceRemoteEditorPlaceholders(connection) { // On Atom restart, it tries to open uri paths as local `TextEditor` pane items. // Here, Nuclide reloads the remote project files that have empty text editors open. const config = connection.getConfig(); - const openInstances = getOpenFileEditorForRemoteProject(config); + const openInstances = (0, (_utils || _load_utils()).getOpenFileEditorForRemoteProject)(config); for (const openInstance of openInstances) { // Keep the original open editor item with a unique name until the remote buffer is loaded, // Then, we are ready to replace it with the remote tab in the same pane. - const {pane, editor, uri, filePath} = openInstance; + const { pane, editor, uri, filePath } = openInstance; // Skip restoring the editor who has remote content loaded. - if ( - editor instanceof TextEditor && - editor.getBuffer().file instanceof RemoteFile - ) { + if (editor instanceof _atom.TextEditor && editor.getBuffer().file instanceof (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).RemoteFile) { continue; } // Atom ensures that each pane only has one item per unique URI. // Null out the existing pane item's URI so we can insert the new one // without closing the pane. - if (editor instanceof TextEditor) { + if (editor instanceof _atom.TextEditor) { editor.getURI = () => null; } // Cleanup the old pane item on successful opening or when no connection could be @@ -652,61 +609,50 @@ function replaceRemoteEditorPlaceholders(connection: RemoteConnection): void { // If we clean up the buffer before the `openUriInPane` finishes, // the pane will be closed, because it could have no other items. // So we must clean up after. - atom.workspace - .openURIInPane(uri, pane) - .then(newEditor => { - if ( - editor instanceof RemoteTextEditorPlaceholder && - editor.isModified() - ) { - // If we had unsaved changes previously, restore them. - newEditor.setText(editor.getText()); - } - }) - .then(cleanupBuffer, cleanupBuffer); + atom.workspace.openURIInPane(uri, pane).then(newEditor => { + if (editor instanceof (_RemoteTextEditorPlaceholder || _load_RemoteTextEditorPlaceholder()).RemoteTextEditorPlaceholder && editor.isModified()) { + // If we had unsaved changes previously, restore them. + newEditor.setText(editor.getText()); + } + }).then(cleanupBuffer, cleanupBuffer); } } } -function validateRemoteProjectConfig( - raw: ?mixed, -): Array { +function validateRemoteProjectConfig(raw) { if (raw == null || !Array.isArray(raw)) { return []; } - return raw - .map(config => { - if (config == null || typeof config !== 'object') { - return null; - } - const { - host, - path: path_, - cwd, - displayTitle, - promptReconnectOnFailure, - } = config; - const path = cwd == null ? path_ : cwd; // We renamed this. Make sure we check the old name. - if (host == null || path == null || displayTitle == null) { - return null; - } - const formatted: SerializableRemoteConnectionConfiguration = { - host: String(host), - path: String(path), - displayTitle: String(displayTitle), - }; - if (typeof promptReconnectOnFailure === 'boolean') { - formatted.promptReconnectOnFailure = promptReconnectOnFailure; - } - return formatted; - }) - .filter(Boolean); + return raw.map(config => { + if (config == null || typeof config !== 'object') { + return null; + } + const { + host, + path: path_, + cwd, + displayTitle, + promptReconnectOnFailure + } = config; + const path = cwd == null ? path_ : cwd; // We renamed this. Make sure we check the old name. + if (host == null || path == null || displayTitle == null) { + return null; + } + const formatted = { + host: String(host), + path: String(path), + displayTitle: String(displayTitle) + }; + if (typeof promptReconnectOnFailure === 'boolean') { + formatted.promptReconnectOnFailure = promptReconnectOnFailure; + } + return formatted; + }).filter(Boolean); } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); // The "atom.directory-provider" service is unique in that it's requested prior to package // activation. Since the Activation class pattern guards against this, we need to special-case it. // eslint-disable-next-line nuclide-internal/no-commonjs -module.exports.createRemoteDirectoryProvider = () => - new RemoteDirectoryProvider(); +module.exports.createRemoteDirectoryProvider = () => new (_RemoteDirectoryProvider || _load_RemoteDirectoryProvider()).default(); \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/notification.js b/pkg/nuclide-remote-projects/lib/notification.js index f53184f42d..4ac8c1959f 100644 --- a/pkg/nuclide-remote-projects/lib/notification.js +++ b/pkg/nuclide-remote-projects/lib/notification.js @@ -1,3 +1,22 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.notifySshHandshakeError = notifySshHandshakeError; + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _electron = require('electron'); + +var _child_process = _interopRequireDefault(require('child_process')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,59 +24,29 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type { - SshConnectionConfiguration, - SshHandshakeErrorType, -} from '../../nuclide-remote-connection/lib/SshHandshake'; - -import {SshHandshake} from '../../nuclide-remote-connection'; - -import {shell} from 'electron'; -import child_process from 'child_process'; - -export function notifySshHandshakeError( - errorType: SshHandshakeErrorType, - error: Error, - config: SshConnectionConfiguration, -): void { +function notifySshHandshakeError(errorType, error, config) { let message = ''; let detail = ''; let buttons = []; const originalErrorDetail = `Original error message:\n ${error.message}`; - const createTimeoutDetail = () => - 'Troubleshooting:\n' + - `Make sure you can run "sftp ${config.host}" on the command line.\n` + - 'Check your .bashrc / .bash_profile for extraneous output.\n' + - 'You may need to add the following to the top of your .bashrc:\n' + - ' [ -z "$PS1" ] && return'; + const createTimeoutDetail = () => 'Troubleshooting:\n' + `Make sure you can run "sftp ${config.host}" on the command line.\n` + 'Check your .bashrc / .bash_profile for extraneous output.\n' + 'You may need to add the following to the top of your .bashrc:\n' + ' [ -z "$PS1" ] && return'; switch (errorType) { case 'HOST_NOT_FOUND': message = `Can't resolve IP address for host ${config.host}.`; - detail = - 'Troubleshooting:\n' + - ' 1. Check your network connection.\n' + - ` 2. Make sure the hostname ${config.host} is valid.\n`; + detail = 'Troubleshooting:\n' + ' 1. Check your network connection.\n' + ` 2. Make sure the hostname ${config.host} is valid.\n`; break; case 'CANT_READ_PRIVATE_KEY': - message = `Can't read content of private key path ${ - config.pathToPrivateKey - }.`; - detail = - 'Make sure the private key path is properly configured.\n' + - 'You may need to convert your private key from PKCS to RSA.\n' + - originalErrorDetail; + message = `Can't read content of private key path ${config.pathToPrivateKey}.`; + detail = 'Make sure the private key path is properly configured.\n' + 'You may need to convert your private key from PKCS to RSA.\n' + originalErrorDetail; break; case 'SSH_CONNECT_TIMEOUT': message = `Timeout while connecting to ${config.host}.`; - detail = - 'Troubleshooting:\n' + - ' 1. Check your network connection.\n' + - ' 2. Input correct 2Fac passcode when prompted.'; + detail = 'Troubleshooting:\n' + ' 1. Check your network connection.\n' + ' 2. Input correct 2Fac passcode when prompted.'; break; case 'SFTP_TIMEOUT': message = `Timeout while connecting to ${config.host}.`; @@ -69,43 +58,25 @@ export function notifySshHandshakeError( break; case 'SSH_CONNECT_FAILED': message = `Failed to connect to ${config.host}:${config.sshPort}.`; - detail = - 'Troubleshooting:\n' + - ' 1. Check your network connection.\n' + - ` 2. Make sure the host ${config.host} is running and has` + - ` ssh server running on ${config.sshPort}.\n\n` + - originalErrorDetail; + detail = 'Troubleshooting:\n' + ' 1. Check your network connection.\n' + ` 2. Make sure the host ${config.host} is running and has` + ` ssh server running on ${config.sshPort}.\n\n` + originalErrorDetail; break; case 'SSH_AUTHENTICATION': switch (config.authMethod) { - case SshHandshake.SupportedMethods.PASSWORD: + case (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).SshHandshake.SupportedMethods.PASSWORD: message = 'Password Authentication failed'; - detail = - 'Troubleshooting:\n' + - ' 1. Did you mean to choose password authentication?\n' + - ' 2. Make sure you provided the correct username and password.'; + detail = 'Troubleshooting:\n' + ' 1. Did you mean to choose password authentication?\n' + ' 2. Make sure you provided the correct username and password.'; break; - case SshHandshake.SupportedMethods.PRIVATE_KEY: + case (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).SshHandshake.SupportedMethods.PRIVATE_KEY: message = 'Private Key Authentication failed'; - detail = - 'Troubleshooting:\n' + - ' 1. Did you mean to choose private key authentication?\n' + - ' 2. Make sure your SSH private key is properly configured.'; + detail = 'Troubleshooting:\n' + ' 1. Did you mean to choose private key authentication?\n' + ' 2. Make sure your SSH private key is properly configured.'; break; - case SshHandshake.SupportedMethods.SSL_AGENT: + case (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).SshHandshake.SupportedMethods.SSL_AGENT: message = 'SSL Agent Authentication failed'; - detail = - 'Troubleshooting:\n' + - ' 1. Did you mean to choose SSL agent authentication?\n' + - ' 2. Make sure your SSH connection is properly configured.'; + detail = 'Troubleshooting:\n' + ' 1. Did you mean to choose SSL agent authentication?\n' + ' 2. Make sure your SSH connection is properly configured.'; break; default: message = 'Unknown SSH Authentication Method failed'; - detail = - `Unknown authentication method '${ - config.authMethod - }' provided. Make sure your` + - ' SSH connection is properly configured.'; + detail = `Unknown authentication method '${config.authMethod}' provided. Make sure your` + ' SSH connection is properly configured.'; break; } break; @@ -114,72 +85,49 @@ export function notifySshHandshakeError( detail = `Make sure ${config.cwd} exists on ${config.host}.`; break; case 'SERVER_START_FAILED': - message = - `Failed to start nuclide-server on ${config.host} using ` + - `${config.remoteServerCommand}`; - detail = - 'Troubleshooting: \n' + - ` 1. Make sure the command "${ - config.remoteServerCommand - }" is correct.\n` + - ' 2. The server might take longer to start up than expected, try to connect again.\n' + - ` 3. If none of above works, ssh to ${ - config.host - } and kill existing nuclide-server` + - ' by running "killall node", and reconnect.\n\n\n' + - originalErrorDetail; + message = `Failed to start nuclide-server on ${config.host} using ` + `${config.remoteServerCommand}`; + detail = 'Troubleshooting: \n' + ` 1. Make sure the command "${config.remoteServerCommand}" is correct.\n` + ' 2. The server might take longer to start up than expected, try to connect again.\n' + ` 3. If none of above works, ssh to ${config.host} and kill existing nuclide-server` + ' by running "killall node", and reconnect.\n\n\n' + originalErrorDetail; break; case 'SERVER_CANNOT_CONNECT': message = 'Unable to connect to server'; - detail = - 'The server successfully started, but we were unable to connect.\n\n' + - originalErrorDetail; + detail = 'The server successfully started, but we were unable to connect.\n\n' + originalErrorDetail; break; case 'CERT_NOT_YET_VALID': message = 'Your clock is behind'; - detail = - 'Your system clock is behind - unable to authenticate.\n' + - 'Please check your date and time settings to continue.\n\n' + - originalErrorDetail; - buttons = [ - { - className: 'icon icon-watch', - text: 'Sync System Clock with Time Server', - onDidClick: () => handleSyncDateTime(notification), - }, - ]; + detail = 'Your system clock is behind - unable to authenticate.\n' + 'Please check your date and time settings to continue.\n\n' + originalErrorDetail; + buttons = [{ + className: 'icon icon-watch', + text: 'Sync System Clock with Time Server', + onDidClick: () => handleSyncDateTime(notification) + }]; break; case 'UNKNOWN': message = `Unexpected error occurred: ${error.message}.`; detail = originalErrorDetail; break; default: - (errorType: empty); + errorType; detail = originalErrorDetail; } const notification = atom.notifications.addError(message, { detail, dismissable: true, - buttons, + buttons }); } function handleSyncDateTime(notification) { switch (process.platform) { case 'darwin': - shell.openItem('/System/Library/PreferencePanes/DateAndTime.prefPane'); + _electron.shell.openItem('/System/Library/PreferencePanes/DateAndTime.prefPane'); notification.dismiss(); break; case 'win32': - child_process.spawn('powershell', [ - '-Command', - 'Start-Process cmd.exe -Verb RunAs -ArgumentList {/c w32tm /resync}', - ]); + _child_process.default.spawn('powershell', ['-Command', 'Start-Process cmd.exe -Verb RunAs -ArgumentList {/c w32tm /resync}']); notification.onDidDismiss(() => { atom.notifications.addSuccess('System Time Synced', { - detail: - 'Your system time has been automatically synced with the time server.', + detail: 'Your system time has been automatically synced with the time server.' }); }); notification.dismiss(); @@ -187,4 +135,4 @@ function handleSyncDateTime(notification) { default: notification.dismiss(); } -} +} \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/open-connection.js b/pkg/nuclide-remote-projects/lib/open-connection.js index 5c0f7ee62b..8fa388c4e4 100644 --- a/pkg/nuclide-remote-projects/lib/open-connection.js +++ b/pkg/nuclide-remote-projects/lib/open-connection.js @@ -1,3 +1,67 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.openConnectionDialog = openConnectionDialog; + +var _Model; + +function _load_Model() { + return _Model = _interopRequireDefault(require('../../../modules/nuclide-commons/Model')); +} + +var _showModal; + +function _load_showModal() { + return _showModal = _interopRequireDefault(require('../../../modules/nuclide-commons-ui/showModal')); +} + +var _ProjectManager; + +function _load_ProjectManager() { + return _ProjectManager = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/ProjectManager')); +} + +var _connectionProfileUtils; + +function _load_connectionProfileUtils() { + return _connectionProfileUtils = require('./connection-profile-utils'); +} + +var _RemoteProjectConnectionModal; + +function _load_RemoteProjectConnectionModal() { + return _RemoteProjectConnectionModal = _interopRequireDefault(require('./RemoteProjectConnectionModal')); +} + +var _event; + +function _load_event() { + return _event = require('../../../modules/nuclide-commons/event'); +} + +var _bindObservableAsProps; + +function _load_bindObservableAsProps() { + return _bindObservableAsProps = require('../../../modules/nuclide-commons-ui/bindObservableAsProps'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +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 }; } + +// eslint-disable-next-line nuclide-internal/import-type-style /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,66 +69,23 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {RemoteConnection} from '../../nuclide-remote-connection'; -import type {NuclideRemoteConnectionProfile} from './connection-types'; -// eslint-disable-next-line nuclide-internal/import-type-style -import type {Props as RemoteProjectConnectionModalProps} from './RemoteProjectConnectionModal'; - -import Model from 'nuclide-commons/Model'; -import showModal from 'nuclide-commons-ui/showModal'; -import ProjectManager from 'nuclide-commons-atom/ProjectManager'; -import { - getDefaultConnectionProfile, - getOfficialRemoteServerCommand, - getSavedConnectionProfiles, - onSavedConnectionProfilesDidChange, - saveConnectionConfig, - saveConnectionProfiles, -} from './connection-profile-utils'; -import {getUniqueHostsForProfiles} from './connection-profile-utils'; -import RemoteProjectConnectionModal from './RemoteProjectConnectionModal'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import {getLogger as getLogger_} from 'log4js'; -import * as React from 'react'; -import {Observable} from 'rxjs'; - -export type OpenConnectionDialogOptions = { - initialServer?: string, - initialCwd?: string, - initialRemoteServerCommand?: string, - project?: {| - repo: string, - path: string, - originPath?: string, - |}, -}; - -const getLogger = () => getLogger_('nuclide-remote-projects'); +const getLogger = () => (0, (_log4js || _load_log4js()).getLogger)('nuclide-remote-projects'); /** * Opens the remote connection dialog flow, which includes asking the user * for connection parameters (e.g. username, server name, etc), and optionally * asking for additional (e.g. 2-fac) authentication. */ -export function openConnectionDialog( - dialogOptions?: OpenConnectionDialogOptions, -): Promise { +function openConnectionDialog(dialogOptions) { return new Promise(resolve => { - showModal( - ({dismiss}) => { - const StatefulModal = bindObservableAsProps( - createPropsStream({dismiss, onConnected: resolve, dialogOptions}), - RemoteProjectConnectionModal, - ); - return ; - }, - {shouldDismissOnClickOutsideModal: () => false}, - ); + (0, (_showModal || _load_showModal()).default)(({ dismiss }) => { + const StatefulModal = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)(createPropsStream({ dismiss, onConnected: resolve, dialogOptions }), (_RemoteProjectConnectionModal || _load_RemoteProjectConnectionModal()).default); + return _react.createElement(StatefulModal, null); + }, { shouldDismissOnClickOutsideModal: () => false }); }); } @@ -73,143 +94,113 @@ export function openConnectionDialog( * the observable emits new props and (thanks to `bindObservableAsProps`), we re-render the * component. */ -function createPropsStream({dismiss, onConnected, dialogOptions}) { +function createPropsStream({ dismiss, onConnected, dialogOptions }) { // During the lifetime of this 'openConnectionDialog' flow, the 'default' // connection profile should not change (even if it is reset by the user // connecting to a remote project from another Atom window). - const defaultConnectionProfile = getDefaultConnectionProfile(dialogOptions); + const defaultConnectionProfile = (0, (_connectionProfileUtils || _load_connectionProfileUtils()).getDefaultConnectionProfile)(dialogOptions); - const initialConnectionProfiles = [ - defaultConnectionProfile, - ...getSavedConnectionProfiles(), - ]; + const initialConnectionProfiles = [defaultConnectionProfile, ...(0, (_connectionProfileUtils || _load_connectionProfileUtils()).getSavedConnectionProfiles)()]; // These props don't change over the lifetime of the modal. const staticProps = { defaultConnectionProfile, initialFormFields: defaultConnectionProfile.params, - profileHosts: getUniqueHostsForProfiles(initialConnectionProfiles), + profileHosts: (0, (_connectionProfileUtils || _load_connectionProfileUtils()).getUniqueHostsForProfiles)(initialConnectionProfiles), onScreenChange: screen => { - updateState({screen}); + updateState({ screen }); }, onConnect: async (connection, config) => { onConnected(connection); const project = dialogOptions && dialogOptions.project; if (project) { - ProjectManager.addRecentProject(project, connection.getConfig().host); + (_ProjectManager || _load_ProjectManager()).default.addRecentProject(project, connection.getConfig().host); } - saveConnectionConfig(config, getOfficialRemoteServerCommand()); + (0, (_connectionProfileUtils || _load_connectionProfileUtils()).saveConnectionConfig)(config, (0, (_connectionProfileUtils || _load_connectionProfileUtils()).getOfficialRemoteServerCommand)()); }, onCancel: () => { onConnected(null); dismiss(); }, onError: (err_, config) => { - onConnected(/* connection */ null); - saveConnectionConfig(config, getOfficialRemoteServerCommand()); + onConnected( /* connection */null); + (0, (_connectionProfileUtils || _load_connectionProfileUtils()).saveConnectionConfig)(config, (0, (_connectionProfileUtils || _load_connectionProfileUtils()).getOfficialRemoteServerCommand)()); }, onClosed: () => { dismiss(); }, - onSaveProfile( - index: number, - profile: NuclideRemoteConnectionProfile, - ): void { + onSaveProfile(index, profile) { const connectionProfiles = model.state.connectionProfiles.slice(); // Override the existing version. connectionProfiles.splice(index, 1, profile); - updateState({connectionProfiles}); + updateState({ connectionProfiles }); }, - onDeleteProfileClicked(indexToDelete: number): void { + onDeleteProfileClicked(indexToDelete) { if (indexToDelete === 0) { // no-op: The default connection profile can't be deleted. // TODO jessicalin: Show this error message in a better place. - atom.notifications.addError( - 'The default connection profile cannot be deleted.', - ); + atom.notifications.addError('The default connection profile cannot be deleted.'); return; } - const {connectionProfiles, selectedProfileIndex} = model.state; + const { connectionProfiles, selectedProfileIndex } = model.state; if (connectionProfiles) { if (indexToDelete >= connectionProfiles.length) { - getLogger().fatal( - 'Tried to delete a connection profile with an index that does not exist. ' + - 'This should never happen.', - ); + getLogger().fatal('Tried to delete a connection profile with an index that does not exist. ' + 'This should never happen.'); return; } const nextConnectionProfiles = connectionProfiles.slice(); nextConnectionProfiles.splice(indexToDelete, 1); - const nextSelectedProfileIndex = - selectedProfileIndex >= indexToDelete - ? selectedProfileIndex - 1 - : selectedProfileIndex; + const nextSelectedProfileIndex = selectedProfileIndex >= indexToDelete ? selectedProfileIndex - 1 : selectedProfileIndex; updateState({ selectedProfileIndex: nextSelectedProfileIndex, - connectionProfiles: nextConnectionProfiles, + connectionProfiles: nextConnectionProfiles }); } }, - onProfileCreated(newProfile: NuclideRemoteConnectionProfile) { - const connectionProfiles = [ - ...model.state.connectionProfiles, - newProfile, - ]; + onProfileCreated(newProfile) { + const connectionProfiles = [...model.state.connectionProfiles, newProfile]; updateState({ connectionProfiles, selectedProfileIndex: connectionProfiles.length - 1, - screen: 'connect', + screen: 'connect' }); }, - onProfileSelected(selectedProfileIndex: number): void { - updateState({selectedProfileIndex}); - }, + onProfileSelected(selectedProfileIndex) { + updateState({ selectedProfileIndex }); + } }; - function updateState(nextState: Object, saveProfiles: boolean = true): void { + function updateState(nextState, saveProfiles = true) { const prevState = model.state; model.setState(nextState); // If the connection profiles changed, save them to the config. The `saveProfiles` option allows // us to opt out because this is a bi-directional sync and we don't want to cause an infinite // loop! - if ( - saveProfiles && - nextState.connectionProfiles != null && - nextState.connectionProfiles !== prevState.connectionProfiles - ) { + if (saveProfiles && nextState.connectionProfiles != null && nextState.connectionProfiles !== prevState.connectionProfiles) { // Don't include the first profile when saving since that's the default. - saveConnectionProfiles(nextState.connectionProfiles.slice(1)); + (0, (_connectionProfileUtils || _load_connectionProfileUtils()).saveConnectionProfiles)(nextState.connectionProfiles.slice(1)); } } - const model = new Model({ + const model = new (_Model || _load_Model()).default({ screen: 'connect', selectedProfileIndex: 0, - connectionProfiles: initialConnectionProfiles, + connectionProfiles: initialConnectionProfiles }); - const props: Observable< - RemoteProjectConnectionModalProps, - > = model.toObservable().map(state => ({...state, ...staticProps})); - - const savedProfilesStream = observableFromSubscribeFunction( - onSavedConnectionProfilesDidChange, - ).map(() => getSavedConnectionProfiles()); - - return Observable.using( - () => - // If something else changes the saved profiles, we want to update our state to reflect those - // changes. - savedProfilesStream.subscribe(savedProfiles => { - updateState( - {connectionProfiles: [defaultConnectionProfile, ...savedProfiles]}, - // Don't write the changes to the config; that's where we got them from and we don't want - // to cause an infinite loop. - false, - ); - }), - () => props, - ); -} + const props = model.toObservable().map(state => Object.assign({}, state, staticProps)); + + const savedProfilesStream = (0, (_event || _load_event()).observableFromSubscribeFunction)((_connectionProfileUtils || _load_connectionProfileUtils()).onSavedConnectionProfilesDidChange).map(() => (0, (_connectionProfileUtils || _load_connectionProfileUtils()).getSavedConnectionProfiles)()); + + return _rxjsBundlesRxMinJs.Observable.using(() => + // If something else changes the saved profiles, we want to update our state to reflect those + // changes. + savedProfilesStream.subscribe(savedProfiles => { + updateState({ connectionProfiles: [defaultConnectionProfile, ...savedProfiles] }, + // Don't write the changes to the config; that's where we got them from and we don't want + // to cause an infinite loop. + false); + }), () => props); +} \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/patchAtomWorkspaceReplace.js b/pkg/nuclide-remote-projects/lib/patchAtomWorkspaceReplace.js index 17233d50e0..ccdb594979 100644 --- a/pkg/nuclide-remote-projects/lib/patchAtomWorkspaceReplace.js +++ b/pkg/nuclide-remote-projects/lib/patchAtomWorkspaceReplace.js @@ -1,18 +1,35 @@ -/** - * 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 - */ +'use strict'; -import {setDifference} from 'nuclide-commons/collection'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {getGrepServiceByNuclideUri} from '../../nuclide-remote-connection'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = patchAtomWorkspaceReplace; + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * |\___/| @@ -35,42 +52,30 @@ import {getGrepServiceByNuclideUri} from '../../nuclide-remote-connection'; * The right fix is probably to have Atom call `Directory.replace` or similar, * which we can then override in our custom `RemoteDirectory` implementation. */ -export default function patchAtomWorkspaceReplace(): UniversalDisposable { - const workspace = (atom.workspace: any); +/** + * 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. + * + * + * @format + */ + +function patchAtomWorkspaceReplace() { + const workspace = atom.workspace; const originalReplace = workspace.replace; - workspace.replace = ( - regex: RegExp, - replacementText: string, - filePaths: Array, - iterator: Function, - ) => { + workspace.replace = (regex, replacementText, filePaths, iterator) => { // Atom can handle local paths and opened buffers, so filter those out. const filePathSet = new Set(filePaths); - const openBuffers = new Set( - atom.project - .getBuffers() - .map(buf => buf.getPath()) - .filter(Boolean), - ); - const unopenedRemotePaths = new Set( - filePaths.filter( - path => nuclideUri.isRemote(path) && !openBuffers.has(path), - ), - ); - const regularReplace = - unopenedRemotePaths.size === filePathSet.size - ? Promise.resolve(null) - : originalReplace.call( - atom.workspace, - regex, - replacementText, - Array.from(setDifference(filePathSet, unopenedRemotePaths)), - iterator, - ); + const openBuffers = new Set(atom.project.getBuffers().map(buf => buf.getPath()).filter(Boolean)); + const unopenedRemotePaths = new Set(filePaths.filter(path => (_nuclideUri || _load_nuclideUri()).default.isRemote(path) && !openBuffers.has(path))); + const regularReplace = unopenedRemotePaths.size === filePathSet.size ? Promise.resolve(null) : originalReplace.call(atom.workspace, regex, replacementText, Array.from((0, (_collection || _load_collection()).setDifference)(filePathSet, unopenedRemotePaths)), iterator); const remotePaths = new Map(); for (const path of unopenedRemotePaths) { - const service = getGrepServiceByNuclideUri(path); + const service = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getGrepServiceByNuclideUri)(path); let list = remotePaths.get(service); if (list == null) { list = []; @@ -80,30 +85,20 @@ export default function patchAtomWorkspaceReplace(): UniversalDisposable { } const promises = [regularReplace]; remotePaths.forEach((paths, service) => { - promises.push( - service - .grepReplace(paths, regex, replacementText) - .refCount() - .do(result => { - if (result.type === 'error') { - iterator( - null, - new Error(`${result.filePath}: ${result.message}`), - ); - } else { - iterator(result); - } - }) - .toPromise() - .catch(err => { - iterator(null, err); - }), - ); + promises.push(service.grepReplace(paths, regex, replacementText).refCount().do(result => { + if (result.type === 'error') { + iterator(null, new Error(`${result.filePath}: ${result.message}`)); + } else { + iterator(result); + } + }).toPromise().catch(err => { + iterator(null, err); + })); }); return Promise.all(promises); }; - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { workspace.replace = originalReplace; }); -} +} \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/lib/utils.js b/pkg/nuclide-remote-projects/lib/utils.js index a218904cbe..416bbff57f 100644 --- a/pkg/nuclide-remote-projects/lib/utils.js +++ b/pkg/nuclide-remote-projects/lib/utils.js @@ -1,49 +1,55 @@ -/** - * 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 strict-local - * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {RemoteConnectionConfiguration} from '../../nuclide-remote-connection/lib/RemoteConnection'; - -import invariant from 'assert'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {RemoteTextEditorPlaceholder} from './RemoteTextEditorPlaceholder'; - -export type OpenFileEditorInstance = { - pane: atom$Pane, - editor: RemoteTextEditorPlaceholder, - uri: NuclideUri, - filePath: string, -}; - -export function* getOpenFileEditorForRemoteProject( - connectionConfig: RemoteConnectionConfiguration, -): Iterator { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getOpenFileEditorForRemoteProject = getOpenFileEditorForRemoteProject; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _RemoteTextEditorPlaceholder; + +function _load_RemoteTextEditorPlaceholder() { + return _RemoteTextEditorPlaceholder = require('./RemoteTextEditorPlaceholder'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function* getOpenFileEditorForRemoteProject(connectionConfig) { for (const pane of atom.workspace.getPanes()) { const paneItems = pane.getItems(); for (const paneItem of paneItems) { - if (!(paneItem instanceof RemoteTextEditorPlaceholder)) { + if (!(paneItem instanceof (_RemoteTextEditorPlaceholder || _load_RemoteTextEditorPlaceholder()).RemoteTextEditorPlaceholder)) { continue; } const uri = paneItem.getPath(); - const {hostname: fileHostname, path: filePath} = nuclideUri.parse(uri); + const { hostname: fileHostname, path: filePath } = (_nuclideUri || _load_nuclideUri()).default.parse(uri); if (fileHostname === connectionConfig.host) { // flowlint-next-line sketchy-null-string:off - invariant(fileHostname); + if (!fileHostname) { + throw new Error('Invariant violation: "fileHostname"'); + } + yield { pane, editor: paneItem, uri, - filePath, + filePath }; } } } -} +} /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-remote-projects/spec/RemoteDirectorySearcher-spec.js b/pkg/nuclide-remote-projects/spec/RemoteDirectorySearcher-spec.js deleted file mode 100644 index b8a2b42506..0000000000 --- a/pkg/nuclide-remote-projects/spec/RemoteDirectorySearcher-spec.js +++ /dev/null @@ -1,79 +0,0 @@ -/** - * 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 - */ - -import {Observable} from 'rxjs'; - -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {RemoteDirectory} from '../../nuclide-remote-connection'; -import RemoteDirectorySearcher from '../lib/RemoteDirectorySearcher'; -import {WORKING_SET_PATH_MARKER} from '../../nuclide-working-sets-common/lib/constants'; - -describe('RemoteDirectorySearcher.processPaths', () => { - const serviceSpy: any = {remoteAtomSearch: () => null}; - const workingSetsStore: any = {getApplicableDefinitions: () => []}; - const searcher = new RemoteDirectorySearcher( - _ => serviceSpy, - () => workingSetsStore, - ); - it('expands basename searches to the whole directory', () => { - expect(searcher.processPaths('a/b/c', ['c/d', 'c'])).toEqual([]); - }); - - it('tries subdirs for basename searches', () => { - expect(searcher.processPaths('a/b/c', ['c/d', 'c/e'])).toEqual([ - 'c/d', - 'd', - 'c/e', - 'e', - ]); - }); - - it('does not expand regular searches', () => { - expect(searcher.processPaths('a/b/c', ['a', 'b'])).toEqual(['a', 'b']); - }); - - it('adds working set directories to search path', () => { - const workingSetPaths = ['a/b', 'a/c/d']; - spyOn(workingSetsStore, 'getApplicableDefinitions').andReturn([ - {name: 'foo', active: true, uris: workingSetPaths}, - ]); - expect(searcher.processPaths('a', [WORKING_SET_PATH_MARKER])).toEqual([ - 'b', - 'c/d', - ]); - }); - - it('does not search directories excluded by working set', () => { - spyOn(serviceSpy, 'remoteAtomSearch').andReturn({ - refCount: () => Observable.empty(), - }); - spyOn(featureConfig, 'get').andReturn({ - remoteTool: 'grep', - remoteUseVcsSearch: true, - }); - const workingSetPaths = ['nuclide://host/a/b']; - spyOn(workingSetsStore, 'getApplicableDefinitions').andReturn([ - {name: 'foo', active: true, uris: workingSetPaths}, - ]); - const connection: any = null; - const directories = ['nuclide://host/a', 'nuclide://host/c'].map( - path => new RemoteDirectory(connection, path), - ); - searcher.search(directories, /./, {inclusions: [WORKING_SET_PATH_MARKER]}); - expect(serviceSpy.remoteAtomSearch).toHaveBeenCalledWith( - 'nuclide://host/a', - /./, - ['b'], - true, - 'grep', - ); - }); -}); diff --git a/pkg/nuclide-remote-projects/spec/RemoteProjectsController-spec.js b/pkg/nuclide-remote-projects/spec/RemoteProjectsController-spec.js deleted file mode 100644 index 86c49ce309..0000000000 --- a/pkg/nuclide-remote-projects/spec/RemoteProjectsController-spec.js +++ /dev/null @@ -1,94 +0,0 @@ -/** - * 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 - */ - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {BehaviorSubject} from 'rxjs'; -import ConnectionState from '../lib/ConnectionState'; -import {_observeConnectionState} from '../lib/RemoteProjectsController'; - -class MockHeartbeat { - away: BehaviorSubject = new BehaviorSubject(false); - isAway() { - return this.away.getValue(); - } - - onHeartbeat(callback: () => mixed): IDisposable { - return new UniversalDisposable( - this.away.filter(x => !x).subscribe(callback), - ); - } - - onHeartbeatError(callback: () => mixed): IDisposable { - return new UniversalDisposable( - this.away.filter(x => x).subscribe(callback), - ); - } -} - -describe('_observeConnectionState', () => { - it('reflects the state of all connections', () => { - const connectionSubject = new BehaviorSubject([]); - const propStream = []; - _observeConnectionState(connectionSubject).subscribe(props => - propStream.push(props), - ); - - const heartbeat1 = new MockHeartbeat(); - const connection1: any = { - getRemoteHostname: () => 'host1', - getHeartbeat: () => heartbeat1, - }; - connectionSubject.next([connection1]); - - const heartbeat2 = new MockHeartbeat(); - const connection2: any = { - getRemoteHostname: () => 'host2', - getHeartbeat: () => heartbeat2, - }; - connectionSubject.next([connection1, connection2]); - - heartbeat1.away.next(true); - heartbeat2.away.next(true); - heartbeat2.away.next(false); - - connectionSubject.next([]); - - expect(propStream).toEqual([ - {connectionStates: new Map()}, - {connectionStates: new Map([['host1', ConnectionState.CONNECTED]])}, - { - connectionStates: new Map([ - ['host1', ConnectionState.CONNECTED], - ['host2', ConnectionState.CONNECTED], - ]), - }, - { - connectionStates: new Map([ - ['host1', ConnectionState.DISCONNECTED], - ['host2', ConnectionState.CONNECTED], - ]), - }, - { - connectionStates: new Map([ - ['host1', ConnectionState.DISCONNECTED], - ['host2', ConnectionState.DISCONNECTED], - ]), - }, - { - connectionStates: new Map([ - ['host1', ConnectionState.DISCONNECTED], - ['host2', ConnectionState.CONNECTED], - ]), - }, - {connectionStates: new Map()}, - ]); - }); -}); diff --git a/pkg/nuclide-remote-projects/spec/RemoteProjectsService-spec.js b/pkg/nuclide-remote-projects/spec/RemoteProjectsService-spec.js deleted file mode 100644 index de8a8c0817..0000000000 --- a/pkg/nuclide-remote-projects/spec/RemoteProjectsService-spec.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import RemoteProjectsService from '../lib/RemoteProjectsService'; - -describe('RemoteProjectsService', () => { - it('waits for reload', () => { - const service = new RemoteProjectsService(); - const spy = jasmine.createSpy('loaded'); - service.waitForRemoteProjectReload(spy); - const projects = ['test']; - service._reloadFinished(projects); - expect(spy).toHaveBeenCalledWith(projects); - - // The callback should still resolve if already loaded. - const spy2 = jasmine.createSpy('loaded'); - service.waitForRemoteProjectReload(spy2); - expect(spy2).toHaveBeenCalledWith(projects); - }); -}); diff --git a/pkg/nuclide-remote-projects/spec/form-validation-utils-spec.js b/pkg/nuclide-remote-projects/spec/form-validation-utils-spec.js deleted file mode 100644 index 4fe5d00dd4..0000000000 --- a/pkg/nuclide-remote-projects/spec/form-validation-utils-spec.js +++ /dev/null @@ -1,262 +0,0 @@ -/** - * 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 - */ - -import {SshHandshake} from '../../nuclide-remote-connection'; -import {validateFormInputs} from '../lib/form-validation-utils'; - -describe('validateFormInputs', () => { - let validProfileName; - let defaultServerCommand; - let connectionProfileBase; - let minimumValidParamsWithPrivateKey; - let minimumValidParamsWithPassword; - let minimumValidParamsWithSshAgent; - - beforeEach(() => { - validProfileName = 'MyProfile'; - defaultServerCommand = 'defaultcommand'; - connectionProfileBase = { - displayTitle: 'testProfile', - username: 'testuser', - password: '', - server: 'test@test.com', - cwd: '/Test', - sshPort: '22', - pathToPrivateKey: '', - remoteServerCommand: defaultServerCommand, - }; - minimumValidParamsWithPrivateKey = { - ...connectionProfileBase, - authMethod: SshHandshake.SupportedMethods.PRIVATE_KEY, - pathToPrivateKey: '/Test', - }; - minimumValidParamsWithPassword = { - ...connectionProfileBase, - authMethod: SshHandshake.SupportedMethods.PASSWORD, - }; - minimumValidParamsWithSshAgent = { - ...connectionProfileBase, - authMethod: SshHandshake.SupportedMethods.SSL_AGENT, - }; - }); - - /** - * Section: Valid Profiles - */ - it('accepts a valid profile with the Private Key authentication method', () => { - const resultFromProfileWithPrivateKey: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPrivateKey, - defaultServerCommand, - ); - expect(resultFromProfileWithPrivateKey.validatedProfile).toBeDefined(); - expect(resultFromProfileWithPrivateKey.warningMessage).not.toBeDefined(); - }); - - it('accepts a valid profile with the Password authentication method', () => { - const resultFromProfileWithPassword: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPassword, - defaultServerCommand, - ); - expect(resultFromProfileWithPassword.validatedProfile).toBeDefined(); - expect(resultFromProfileWithPassword.warningMessage).not.toBeDefined(); - }); - - it('accepts a valid profile with the SSH Agent authentication method', () => { - const resultFromProfileWithSshAgent: any = validateFormInputs( - validProfileName, - minimumValidParamsWithSshAgent, - defaultServerCommand, - ); - expect(resultFromProfileWithSshAgent.validatedProfile).toBeDefined(); - expect(resultFromProfileWithSshAgent.warningMessage).not.toBeDefined(); - }); - - /** - * Section: Invalid Profiles - */ - it('rejects a profile if a Profile Name is missing.', () => { - const resultFromNullProfileName: any = validateFormInputs( - // $FlowIgnore - null, - minimumValidParamsWithPrivateKey, - defaultServerCommand, - ); - expect(resultFromNullProfileName.errorMessage).not.toBeNull(); - - const resultFromEmptyProfileName: any = validateFormInputs( - '', - minimumValidParamsWithPrivateKey, - defaultServerCommand, - ); - expect(resultFromEmptyProfileName.errorMessage).not.toBeNull(); - }); - - it('rejects a profile if a Username is missing.', () => { - minimumValidParamsWithPrivateKey.username = ''; - const resultFromNullUsername: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPrivateKey, - defaultServerCommand, - ); - expect(resultFromNullUsername.errorMessage).not.toBeNull(); - - minimumValidParamsWithPrivateKey.username = ''; - const resultFromEmptyUsername: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPrivateKey, - defaultServerCommand, - ); - expect(resultFromEmptyUsername.errorMessage).not.toBeNull(); - }); - - it('rejects a profile if a Server is missing.', () => { - minimumValidParamsWithPrivateKey.server = ''; - const resultFromNullServer: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPrivateKey, - defaultServerCommand, - ); - expect(resultFromNullServer.errorMessage).not.toBeNull(); - - minimumValidParamsWithPrivateKey.server = ''; - const resultFromEmptyServer: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPrivateKey, - defaultServerCommand, - ); - expect(resultFromEmptyServer.errorMessage).not.toBeNull(); - }); - - it('rejects a profile if an Initial Directory is missing.', () => { - minimumValidParamsWithPrivateKey.cwd = ''; - const resultFromNullCwd: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPrivateKey, - defaultServerCommand, - ); - expect(resultFromNullCwd.errorMessage).not.toBeNull(); - - minimumValidParamsWithPrivateKey.cwd = ''; - const resultFromEmptyCwd: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPrivateKey, - defaultServerCommand, - ); - expect(resultFromEmptyCwd.errorMessage).not.toBeNull(); - }); - - it('rejects a profile if an SSH Port is missing.', () => { - minimumValidParamsWithPrivateKey.sshPort = ''; - const resultFromNullSshPort: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPrivateKey, - defaultServerCommand, - ); - expect(resultFromNullSshPort.errorMessage).not.toBeNull(); - - minimumValidParamsWithPrivateKey.sshPort = ''; - const resultFromEmptySshPort: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPrivateKey, - defaultServerCommand, - ); - expect(resultFromEmptySshPort.errorMessage).not.toBeNull(); - }); - - it('rejects a profile if an Authentication Method is missing.', () => { - minimumValidParamsWithPrivateKey.authMethod = (null: any); - const resultFromNullAuthMethod: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPrivateKey, - defaultServerCommand, - ); - expect(resultFromNullAuthMethod.errorMessage).not.toBeNull(); - - minimumValidParamsWithPrivateKey.authMethod = ('': any); - const resultFromEmptyAuthMethod: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPrivateKey, - defaultServerCommand, - ); - expect(resultFromEmptyAuthMethod.errorMessage).not.toBeNull(); - }); - - // eslint-disable-next-line max-len - it('rejects a profile if the Authentication Method selected is "Private Key", and a Private Key File is missing', () => { - minimumValidParamsWithPrivateKey.pathToPrivateKey = ''; - const resultFromEmptyPathToPrivateKey: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPrivateKey, - defaultServerCommand, - ); - expect(resultFromEmptyPathToPrivateKey.errorMessage).not.toBeNull(); - }); - - // eslint-disable-next-line max-len - it('does not reject a profile if the Private Key File is missing, but the Authentication Method selected is not "Private Key"', () => { - const passwordAuthMethodProfile: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPassword, - defaultServerCommand, - ); - expect(passwordAuthMethodProfile.validatedProfile).toBeDefined(); - - const sshAgentAuthMethodProfile: any = validateFormInputs( - validProfileName, - minimumValidParamsWithSshAgent, - defaultServerCommand, - ); - expect(sshAgentAuthMethodProfile.validatedProfile).toBeDefined(); - }); - - /** - * Section: Special Cases - */ - // eslint-disable-next-line max-len - it('strips a password, if it is provided and the "Password" Authentication Method is chosen, and provides a warning message.', () => { - minimumValidParamsWithPassword.password = 'secretpassword'; - const resultFromProfileWithPassword: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPassword, - defaultServerCommand, - ); - expect(resultFromProfileWithPassword.validatedProfile).toBeDefined(); - expect( - resultFromProfileWithPassword.validatedProfile.params.password, - ).not.toBeDefined(); - expect(resultFromProfileWithPassword.warningMessage).toBeDefined(); - }); - - it('only saves the remote server command if it is different than the "default".', () => { - const resultFromProfileWithDefaultRSC: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPassword, - defaultServerCommand, - ); - expect( - resultFromProfileWithDefaultRSC.validatedProfile.params - .remoteServerCommand, - ).toBe(''); - - minimumValidParamsWithPassword.remoteServerCommand = 'differentCommand'; - const resultFromProfileWithDifferentRSC: any = validateFormInputs( - validProfileName, - minimumValidParamsWithPassword, - defaultServerCommand, - ); - expect( - resultFromProfileWithDifferentRSC.validatedProfile.params - .remoteServerCommand, - ).toBe('differentCommand'); - }); -}); diff --git a/pkg/nuclide-rpc/__mocks__/BidiService.js b/pkg/nuclide-rpc/__mocks__/BidiService.js index ef4c65028f..c826454eae 100644 --- a/pkg/nuclide-rpc/__mocks__/BidiService.js +++ b/pkg/nuclide-rpc/__mocks__/BidiService.js @@ -1,21 +1,20 @@ -/** - * 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 strict - * @format - */ +"use strict"; -interface I { - m(arg: string): Promise; - dispose(): void; -} - -export async function f(s: string, i: I): Promise { +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.f = f; +async function f(s, i) { const result = await i.m(s); i.dispose(); return result; -} +} /** + * 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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-rpc/__mocks__/CounterService.js b/pkg/nuclide-rpc/__mocks__/CounterService.js index 3eef824859..4d57af1fc0 100644 --- a/pkg/nuclide-rpc/__mocks__/CounterService.js +++ b/pkg/nuclide-rpc/__mocks__/CounterService.js @@ -1,38 +1,23 @@ -/** - * 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 strict - * @format - */ +'use strict'; -import {ConnectableObservable, Subject} from 'rxjs'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Counter = undefined; -export type CounterChangeEvent = { - type: string, - oldValue: number, - newValue: number, -}; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); -export class Counter { - _count: number; - _changes: Subject; - - static _counters: Array = []; - static _newCounters = new Subject(); +class Counter { // Create a new counter with the given initial count. - constructor(initialCount: number) { + constructor(initialCount) { // Set initial count. this._count = initialCount; // Set the changes subscription observable. - this._changes = new Subject(); + this._changes = new _rxjsBundlesRxMinJs.Subject(); } - static async createCounter(initialCount: number): Promise { + static async createCounter(initialCount) { const counter = new Counter(initialCount); // Add this counter to global list. Counter._counters.push(counter); @@ -42,28 +27,28 @@ export class Counter { } // Get the current value of a counter. - async getCount(): Promise { + async getCount() { return this._count; } // Add the specified value to the counter's count. - async addCount(x: number): Promise { + async addCount(x) { // Broadcast an event. this._changes.next({ type: 'add', oldValue: this._count, - newValue: this._count + x, + newValue: this._count + x }); this._count += x; } // Subscribe to changes in this counter. - watchChanges(): ConnectableObservable { + watchChanges() { return this._changes.publish(); } // Dispose function that removes this counter from the global list. - async dispose(): Promise { + async dispose() { // Remove this counter from the global list. Counter._counters.splice(Counter._counters.indexOf(this), 1); // Signal that the changes stream is over. @@ -73,17 +58,30 @@ export class Counter { /** Static Methods */ // List all of the counters that have been created. - static async listCounters(): Promise> { + static async listCounters() { return Counter._counters; } // Returns a stream of counters as they are created. - static watchNewCounters(): ConnectableObservable { + static watchNewCounters() { return Counter._newCounters.publish(); } // A static method that takes a Counter object as an argument. - static async indexOf(counter: Counter): Promise { + static async indexOf(counter) { return Counter._counters.indexOf(counter); } } +exports.Counter = Counter; /** + * 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. + * + * strict + * @format + */ + +Counter._counters = []; +Counter._newCounters = new _rxjsBundlesRxMinJs.Subject(); \ No newline at end of file diff --git a/pkg/nuclide-rpc/__mocks__/EchoService.js b/pkg/nuclide-rpc/__mocks__/EchoService.js index bdba04650f..c1a4ed61b7 100644 --- a/pkg/nuclide-rpc/__mocks__/EchoService.js +++ b/pkg/nuclide-rpc/__mocks__/EchoService.js @@ -1,3 +1,32 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RemotableObject = undefined; +exports.echoAny = echoAny; +exports.echoString = echoString; +exports.echoNumber = echoNumber; +exports.echoBoolean = echoBoolean; +exports.echoDefaultNumber = echoDefaultNumber; +exports.echoVoid = echoVoid; +exports.echoDate = echoDate; +exports.echoRegExp = echoRegExp; +exports.echoBuffer = echoBuffer; +exports.echoArrayOfArrayOfDate = echoArrayOfArrayOfDate; +exports.echoObject = echoObject; +exports.echoSet = echoSet; +exports.echoMap = echoMap; +exports.echoTuple = echoTuple; +exports.echoValueType = echoValueType; +exports.echoNuclideUri = echoNuclideUri; +exports.echoRemotableObject = echoRemotableObject; + +var _assert = _interopRequireDefault(require('assert')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Basic Primitives. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,118 +34,83 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import assert from 'assert'; - -// Basic Primitives. -export async function echoAny(arg: any): Promise { +async function echoAny(arg) { return arg; } -export async function echoString(arg: string): Promise { - assert( - typeof arg === 'string', - `Argument to echoString must be a string, not ${typeof arg}.`, - ); +async function echoString(arg) { + (0, _assert.default)(typeof arg === 'string', `Argument to echoString must be a string, not ${typeof arg}.`); return arg; } -export async function echoNumber(arg: number): Promise { - assert( - typeof arg === 'number', - `Argument to echoNumber must be a number, not ${typeof arg}.`, - ); +async function echoNumber(arg) { + (0, _assert.default)(typeof arg === 'number', `Argument to echoNumber must be a number, not ${typeof arg}.`); return arg; } -export async function echoBoolean(arg: boolean): Promise { - assert( - typeof arg === 'boolean', - `Argument to echoBoolean must be a boolean, not ${typeof arg}.`, - ); +async function echoBoolean(arg) { + (0, _assert.default)(typeof arg === 'boolean', `Argument to echoBoolean must be a boolean, not ${typeof arg}.`); return arg; } -export async function echoDefaultNumber(arg: number = 1): Promise { +async function echoDefaultNumber(arg = 1) { return arg; } -export async function echoVoid(arg: void): Promise { - assert(arg === undefined, 'Argument to echoVoid must be undefined'); +async function echoVoid(arg) { + (0, _assert.default)(arg === undefined, 'Argument to echoVoid must be undefined'); return arg; } // More Complex Objects. -export async function echoDate(arg: Date): Promise { - assert(arg instanceof Date, 'Argument to echoDate must be a Date.'); +async function echoDate(arg) { + (0, _assert.default)(arg instanceof Date, 'Argument to echoDate must be a Date.'); return arg; } -export async function echoRegExp(arg: RegExp): Promise { - assert( - arg instanceof RegExp, - // $FlowFixMe - `Argument to echoRegExp must be a RegExp. Not ${arg.constructor}`, - ); +async function echoRegExp(arg) { + (0, _assert.default)(arg instanceof RegExp, + // $FlowFixMe + `Argument to echoRegExp must be a RegExp. Not ${arg.constructor}`); return arg; } -export async function echoBuffer(arg: Buffer): Promise { - assert( - arg instanceof Buffer, - // $FlowFixMe - `Argument to echoBuffer must be a Buffer. Not ${arg.constructor}`, - ); +async function echoBuffer(arg) { + (0, _assert.default)(arg instanceof Buffer, + // $FlowFixMe + `Argument to echoBuffer must be a Buffer. Not ${arg.constructor}`); return arg; } // Parameterized types. -export async function echoArrayOfArrayOfDate( - arg: Array>, -): Promise>> { +async function echoArrayOfArrayOfDate(arg) { return arg; } -export async function echoObject(arg: { - a: ?string, - b: Buffer, - c?: string, -}): Promise<{a: ?string, b: Buffer, c?: string}> { +async function echoObject(arg) { return arg; } -export async function echoSet(arg: Set): Promise> { +async function echoSet(arg) { return arg; } -export async function echoMap( - arg: Map, -): Promise> { +async function echoMap(arg) { return arg; } -export async function echoTuple( - arg: [number, string], -): Promise<[number, string]> { +async function echoTuple(arg) { return arg; } // Value Type -export type BufferAlias = Buffer; -export type ValueTypeA = { - a: Date, - b: BufferAlias, - c?: number, // Note that as of 5.8.14, there is a bug with parsing optional props in Babel. -}; -export async function echoValueType(arg: ValueTypeA): Promise { +async function echoValueType(arg) { return arg; } // NuclideUri -export async function echoNuclideUri(arg: NuclideUri): Promise { +async function echoNuclideUri(arg) { return arg; } // Remotable object -export class RemotableObject { - dispose(): void {} +class RemotableObject { + dispose() {} } -export async function echoRemotableObject( - arg: RemotableObject, -): Promise { +exports.RemotableObject = RemotableObject; +async function echoRemotableObject(arg) { return arg; -} +} \ No newline at end of file diff --git a/pkg/nuclide-rpc/__mocks__/ErrorService.js b/pkg/nuclide-rpc/__mocks__/ErrorService.js index 5501d95f3c..4a517968a1 100644 --- a/pkg/nuclide-rpc/__mocks__/ErrorService.js +++ b/pkg/nuclide-rpc/__mocks__/ErrorService.js @@ -1,66 +1,72 @@ -/** - * 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 - */ +'use strict'; -import {Observable, ConnectableObservable} from 'rxjs'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.promiseError = promiseError; +exports.promiseErrorString = promiseErrorString; +exports.promiseErrorUndefined = promiseErrorUndefined; +exports.promiseErrorCode = promiseErrorCode; +exports.observableError = observableError; +exports.observableErrorString = observableErrorString; +exports.observableErrorUndefined = observableErrorUndefined; +exports.observableErrorCode = observableErrorCode; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); // Contains services that let us test marshalling of Errors. -export async function promiseError(message: string): Promise { +async function promiseError(message) { throw new Error(message); -} +} /** + * 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. + * + * + * @format + */ -export async function promiseErrorString(message: string): Promise { +async function promiseErrorString(message) { throw message; } -export function promiseErrorUndefined(): Promise { +function promiseErrorUndefined() { // eslint-disable-next-line no-throw-literal throw undefined; } -export function promiseErrorCode(code: number): Promise { +function promiseErrorCode(code) { throw createErrorCode(code); } -export function observableError( - message: string, -): ConnectableObservable { +function observableError(message) { return createErrorObservable(new Error(message)); } -export function observableErrorString( - message: string, -): ConnectableObservable { +function observableErrorString(message) { return createErrorObservable(message); } -export function observableErrorUndefined(): ConnectableObservable { +function observableErrorUndefined() { return createErrorObservable(undefined); } -export function observableErrorCode( - code: number, -): ConnectableObservable { +function observableErrorCode(code) { return createErrorObservable(createErrorCode(code)); } -function createErrorObservable(error: any): ConnectableObservable { - return Observable.create(observer => { +function createErrorObservable(error) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { observer.error(error); }).publish(); } -function createErrorCode(code: number) { +function createErrorCode(code) { const e = new Error(); // $FlowIssue - Error should have a code e.code = code; return e; -} +} \ No newline at end of file diff --git a/pkg/nuclide-rpc/__mocks__/ImportService.js b/pkg/nuclide-rpc/__mocks__/ImportService.js index 63f45089e1..fdb5fcaf9f 100644 --- a/pkg/nuclide-rpc/__mocks__/ImportService.js +++ b/pkg/nuclide-rpc/__mocks__/ImportService.js @@ -1,3 +1,17 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.f = f; +exports.f2 = f2; +exports.f3 = f3; +exports.g = g; +let _NonRpcDefinition = exports._NonRpcDefinition = undefined; + +// We should be able to import types from non-rpc compatible files +// as long as they are not used in the external interface of the file. +// $FlowIgnore - Ignore the fact that the file doesn't exist. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,36 +19,22 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -import type {ImportedType} from './Types'; -import type { - AliasImportedType, - AliasImportedType2, - AnotherImportedType, -} from './MoreTypes'; - -// We should be able to import types from non-rpc compatible files -// as long as they are not used in the external interface of the file. -// $FlowIgnore - Ignore the fact that the file doesn't exist. -import type {NonRpcType} from './NonRpcFile'; - -export let _NonRpcDefinition: NonRpcType; - -export async function f(t: ImportedType): Promise { +async function f(t) { return t; } -export async function f2(t: AliasImportedType): Promise { +async function f2(t) { return t; } -export async function f3(t: AliasImportedType2): Promise { +async function f3(t) { return t; } -export async function g(t: AnotherImportedType): Promise { +async function g(t) { return t.field; -} +} \ No newline at end of file diff --git a/pkg/nuclide-rpc/__mocks__/MoreTypes.js b/pkg/nuclide-rpc/__mocks__/MoreTypes.js index 0726fabea1..4d120b2284 100644 --- a/pkg/nuclide-rpc/__mocks__/MoreTypes.js +++ b/pkg/nuclide-rpc/__mocks__/MoreTypes.js @@ -1,3 +1,16 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.f = f; + + +// Use ImportedType from another file - testing, multiple +// imports the same file. +function f(x) {} + +// Non-RPC compatible types are fine, as long as they're not used. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,24 +18,9 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -import type {ImportedType as AliasImportedType} from './Types'; - -// Use ImportedType from another file - testing, multiple -// imports the same file. -export type AnotherImportedType = { - field: AliasImportedType, -}; - -export type {AliasImportedType}; - -export type {ImportedType as AliasImportedType2} from './Types'; - -// Non-RPC compatible types are fine, as long as they're not used. -export type NonRpcType = () => string; -export function f(x: string | number): void {} -export class C {} -export interface I {} +class C {} +exports.C = C; \ No newline at end of file diff --git a/pkg/nuclide-rpc/__mocks__/ServiceTester.js b/pkg/nuclide-rpc/__mocks__/ServiceTester.js index 070ec693b4..160612a1d1 100644 --- a/pkg/nuclide-rpc/__mocks__/ServiceTester.js +++ b/pkg/nuclide-rpc/__mocks__/ServiceTester.js @@ -1,3 +1,34 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ServiceTester = undefined; + +var _LoopbackTransports; + +function _load_LoopbackTransports() { + return _LoopbackTransports = require('../lib/LoopbackTransports'); +} + +var _RpcConnection; + +function _load_RpcConnection() { + return _RpcConnection = require('../lib/RpcConnection'); +} + +var _ServiceRegistry; + +function _load_ServiceRegistry() { + return _ServiceRegistry = require('../lib/ServiceRegistry'); +} + +var _nuclideMarshalersCommon; + +function _load_nuclideMarshalersCommon() { + return _nuclideMarshalersCommon = require('../../nuclide-marshalers-common'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,57 +36,31 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {ConfigEntry, Transport} from '../lib/index'; - -import {LoopbackTransports} from '../lib/LoopbackTransports'; -import {RpcConnection} from '../lib/RpcConnection'; -import {ServiceRegistry} from '../lib/ServiceRegistry'; -import {localNuclideUriMarshalers} from '../../nuclide-marshalers-common'; -import {getRemoteNuclideUriMarshalers} from '../../nuclide-marshalers-common'; - -export class ServiceTester { - _serviceRegistry: ServiceRegistry; - _client: RpcConnection; - _clientConnection: RpcConnection; - - async start( - customServices: Array, - protocol: string, - ): Promise { - const transports = new LoopbackTransports(); - this._serviceRegistry = new ServiceRegistry( - [localNuclideUriMarshalers], - customServices, - protocol, - ); - this._clientConnection = RpcConnection.createServer( - this._serviceRegistry, - transports.serverTransport, - ); - - this._client = RpcConnection.createRemote( - transports.clientTransport, - [getRemoteNuclideUriMarshalers('localhost')], - customServices, - {}, - protocol, - ); +class ServiceTester { + + async start(customServices, protocol) { + const transports = new (_LoopbackTransports || _load_LoopbackTransports()).LoopbackTransports(); + this._serviceRegistry = new (_ServiceRegistry || _load_ServiceRegistry()).ServiceRegistry([(_nuclideMarshalersCommon || _load_nuclideMarshalersCommon()).localNuclideUriMarshalers], customServices, protocol); + this._clientConnection = (_RpcConnection || _load_RpcConnection()).RpcConnection.createServer(this._serviceRegistry, transports.serverTransport); + + this._client = (_RpcConnection || _load_RpcConnection()).RpcConnection.createRemote(transports.clientTransport, [(0, (_nuclideMarshalersCommon || _load_nuclideMarshalersCommon()).getRemoteNuclideUriMarshalers)('localhost')], customServices, {}, protocol); } - stop(): void { + stop() { this._client.dispose(); this._clientConnection.dispose(); } - getRemoteService(serviceName: string): any { + getRemoteService(serviceName) { return this._client.getService(serviceName); } - getUriOfRemotePath(remotePath: string): string { + getUriOfRemotePath(remotePath) { return `nuclide://localhost${remotePath}`; } } +exports.ServiceTester = ServiceTester; \ No newline at end of file diff --git a/pkg/nuclide-rpc/__mocks__/Types.js b/pkg/nuclide-rpc/__mocks__/Types.js index 3810d8fc89..9a390c31f7 100644 --- a/pkg/nuclide-rpc/__mocks__/Types.js +++ b/pkg/nuclide-rpc/__mocks__/Types.js @@ -1,12 +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 strict - * @format - */ - -export type ImportedType = string; +"use strict"; \ No newline at end of file diff --git a/pkg/nuclide-rpc/__mocks__/fixtures/dummy-service/DummyService.js b/pkg/nuclide-rpc/__mocks__/fixtures/dummy-service/DummyService.js index e30affa777..f36110ae93 100644 --- a/pkg/nuclide-rpc/__mocks__/fixtures/dummy-service/DummyService.js +++ b/pkg/nuclide-rpc/__mocks__/fixtures/dummy-service/DummyService.js @@ -1,3 +1,16 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.binarysystems = binarysystems; +exports.polarbears = polarbears; +exports.a = a; +exports.b = b; +exports.c = c; +exports.d = d; +exports.error = error; +exports.kill = kill; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,35 +18,35 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -export function binarysystems(): Promise<{hello: string}> { +function binarysystems() { throw new Error('RPC stub'); } -export function polarbears(): Promise<{hello: string}> { +function polarbears() { throw new Error('RPC stub'); } -export function a(): Promise<{hello: string}> { +function a() { throw new Error('RPC stub'); } -export function b(): Promise<{hello: string}> { +function b() { throw new Error('RPC stub'); } -export function c(): Promise<{hello: string}> { +function c() { throw new Error('RPC stub'); } -export function d(): Promise<{hello: string}> { +function d() { throw new Error('RPC stub'); } -export function error(): Promise { +function error() { throw new Error('RPC stub'); } -export function kill(): Promise { +function kill() { throw new Error('RPC stub'); -} +} \ No newline at end of file diff --git a/pkg/nuclide-rpc/__tests__/BidiService-test.js b/pkg/nuclide-rpc/__tests__/BidiService-test.js index c5787f7aeb..a3691da687 100644 --- a/pkg/nuclide-rpc/__tests__/BidiService-test.js +++ b/pkg/nuclide-rpc/__tests__/BidiService-test.js @@ -1,3 +1,19 @@ +'use strict'; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _ServiceTester; + +function _load_ServiceTester() { + return _ServiceTester = require('../__mocks__/ServiceTester'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,16 +21,12 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {ServiceTester} from '../__mocks__/ServiceTester'; -import typeof * as BidiServiceType from '../__mocks__/BidiService'; - class I1 { - async m(arg: string): Promise { + async m(arg) { return 'I1:' + arg; } @@ -22,7 +34,7 @@ class I1 { } class I2 { - async m(arg: string): Promise { + async m(arg) { return 'I2:' + arg; } @@ -31,25 +43,14 @@ class I2 { describe('BidiService', () => { let testHelper; - let service: BidiServiceType = (null: any); + let service = null; beforeEach(async () => { - testHelper = new ServiceTester(); - await testHelper.start( - [ - { - name: 'BidiService', - definition: nuclideUri.join( - __dirname, - '../__mocks__/BidiService.def', - ), - implementation: nuclideUri.join( - __dirname, - '../__mocks__/BidiService.js', - ), - }, - ], - 'bidi_protocol', - ); + testHelper = new (_ServiceTester || _load_ServiceTester()).ServiceTester(); + await testHelper.start([{ + name: 'BidiService', + definition: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/BidiService.def'), + implementation: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/BidiService.js') + }], 'bidi_protocol'); service = testHelper.getRemoteService('BidiService'); }); @@ -67,4 +68,4 @@ describe('BidiService', () => { }); afterEach(() => testHelper.stop()); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-rpc/__tests__/CounterService-test.js b/pkg/nuclide-rpc/__tests__/CounterService-test.js index 8bca353eaf..dbf6ffa30a 100644 --- a/pkg/nuclide-rpc/__tests__/CounterService-test.js +++ b/pkg/nuclide-rpc/__tests__/CounterService-test.js @@ -1,3 +1,25 @@ +'use strict'; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _ServiceTester; + +function _load_ServiceTester() { + return _ServiceTester = require('../__mocks__/ServiceTester'); +} + +var _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../../../jest/waits_for')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,50 +27,34 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import invariant from 'assert'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {ServiceTester} from '../__mocks__/ServiceTester'; -import waitsFor from '../../../jest/waits_for'; - describe('CounterService', () => { let testHelper; let service; beforeEach(async () => { - testHelper = new ServiceTester(); - await testHelper.start( - [ - { - name: 'CounterService', - definition: nuclideUri.join( - __dirname, - '../__mocks__/CounterService.js', - ), - implementation: nuclideUri.join( - __dirname, - '../__mocks__/CounterService.js', - ), - }, - ], - 'counter_protocol', - ); + testHelper = new (_ServiceTester || _load_ServiceTester()).ServiceTester(); + await testHelper.start([{ + name: 'CounterService', + definition: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/CounterService.js'), + implementation: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/CounterService.js') + }], 'counter_protocol'); service = testHelper.getRemoteService('CounterService'); }); it('Can create two remotable counters in parallel.', async () => { - invariant(service); + if (!service) { + throw new Error('Invariant violation: "service"'); + } let watchedCounters = 0; - service.Counter.watchNewCounters() - .refCount() - .subscribe(async counter => { - await counter.getCount(); - ++watchedCounters; - }); + service.Counter.watchNewCounters().refCount().subscribe(async counter => { + await counter.getCount(); + ++watchedCounters; + }); // Create two services. const counter1 = await service.Counter.createCounter(3); @@ -56,39 +62,32 @@ describe('CounterService', () => { // Subscribe to events from counter1. let completed1 = false; - counter1 - .watchChanges() - .refCount() - .subscribe( - event => { - expect(event.type).toBe('add'); - expect(event.oldValue).toBe(3); - expect(event.newValue).toBe(4); - }, - () => {}, - () => { - completed1 = true; - }, - ); + counter1.watchChanges().refCount().subscribe(event => { + expect(event.type).toBe('add'); + expect(event.oldValue).toBe(3); + expect(event.newValue).toBe(4); + }, () => {}, () => { + completed1 = true; + }); // Confirm their initial value. - expect(await counter1.getCount()).toBe(3); - expect(await counter2.getCount()).toBe(5); + expect((await counter1.getCount())).toBe(3); + expect((await counter2.getCount())).toBe(5); // Increment the counters / check values. await counter1.addCount(1); await counter2.addCount(2); - expect(await counter1.getCount()).toBe(4); - expect(await counter2.getCount()).toBe(7); + expect((await counter1.getCount())).toBe(4); + expect((await counter2.getCount())).toBe(7); // Call a static method that returns Counter instances. const counters = await service.Counter.listCounters(); - expect(await counters[0].getCount()).toBe(4); - expect(await counters[1].getCount()).toBe(7); + expect((await counters[0].getCount())).toBe(4); + expect((await counters[1].getCount())).toBe(7); // Call a static method with a counter as an argument. - expect(await service.Counter.indexOf(counter1)).toBe(0); - expect(await service.Counter.indexOf(counter2)).toBe(1); + expect((await service.Counter.indexOf(counter1))).toBe(0); + expect((await service.Counter.indexOf(counter2))).toBe(1); // Dispose the counters, ensuring that they are removed from the global list. await counter1.dispose(); @@ -99,18 +98,17 @@ describe('CounterService', () => { await counter2.dispose(); // Wait for the counter1 Observable to complete. - waitsFor(() => completed1, 'The counter1 Observable to complete.'); + (0, (_waits_for || _load_waits_for()).default)(() => completed1, 'The counter1 Observable to complete.'); // Wait for our watch to have seen all of the Counters. - waitsFor( - () => watchedCounters === 2, - 'We have watched two counters get created.', - ); + (0, (_waits_for || _load_waits_for()).default)(() => watchedCounters === 2, 'We have watched two counters get created.'); }); it('can subscribe/unsubscribe to the same observable multiple times.', async () => { await (async () => { - invariant(service); + if (!service) { + throw new Error('Invariant violation: "service"'); + } const obs = service.Counter.watchNewCounters().refCount(); @@ -143,4 +141,4 @@ describe('CounterService', () => { }); afterEach(() => testHelper.stop()); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-rpc/__tests__/EchoService-test.js b/pkg/nuclide-rpc/__tests__/EchoService-test.js index fb3f8e0a5d..ec9e461ad9 100644 --- a/pkg/nuclide-rpc/__tests__/EchoService-test.js +++ b/pkg/nuclide-rpc/__tests__/EchoService-test.js @@ -1,3 +1,25 @@ +'use strict'; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _ServiceTester; + +function _load_ServiceTester() { + return _ServiceTester = require('../__mocks__/ServiceTester'); +} + +var _EchoService; + +function _load_EchoService() { + return _EchoService = require('../__mocks__/EchoService'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,35 +27,21 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import invariant from 'assert'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {ServiceTester} from '../__mocks__/ServiceTester'; -import typeof * as EchoServiceType from '../__mocks__/EchoService'; -import {RemotableObject} from '../__mocks__/EchoService'; - describe('EchoServer', () => { let testHelper; - let service: EchoServiceType = (null: any); + let service = null; beforeEach(async () => { - testHelper = new ServiceTester(); - await testHelper.start( - [ - { - name: 'EchoService', - definition: nuclideUri.join(__dirname, '../__mocks__/EchoService.js'), - implementation: nuclideUri.join( - __dirname, - '../__mocks__/EchoService.js', - ), - }, - ], - 'echo_protocol', - ); + testHelper = new (_ServiceTester || _load_ServiceTester()).ServiceTester(); + await testHelper.start([{ + name: 'EchoService', + definition: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/EchoService.js'), + implementation: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/EchoService.js') + }], 'echo_protocol'); service = testHelper.getRemoteService('EchoService'); }); @@ -45,7 +53,7 @@ describe('EchoServer', () => { const results = await service.echoAny(number); expect(results).toBe(number); })(); - const object = {hello: 'world', success: true}; + const object = { hello: 'world', success: true }; await (async () => { const results = await service.echoAny(object); expect(results).toEqual(object); @@ -131,11 +139,11 @@ describe('EchoServer', () => { const c = undefined; await (async () => { - const results = await service.echoObject({a, b}); + const results = await service.echoObject({ a, b }); expect(results.a).toBe(null); expect(results.b.equals(b)).toBe(true); - const results2 = await service.echoObject({a, b, c}); + const results2 = await service.echoObject({ a, b, c }); // hasOwnProperty('c') evaluates to false since JSON doesn't serialize undefined. // This is an imperfection in the service framework. expect(results2.hasOwnProperty('c')).toBeFalsy(); @@ -152,10 +160,7 @@ describe('EchoServer', () => { })(); }); it('Echoes a Map.', async () => { - const original = new Map([ - ['a', new Date()], - ['b', new Date(1995, 11, 17, 3, 24, 0)], - ]); + const original = new Map([['a', new Date()], ['b', new Date(1995, 11, 17, 3, 24, 0)]]); await (async () => { const results = await service.echoMap(original); @@ -163,7 +168,11 @@ describe('EchoServer', () => { expect(originalA).toBeTruthy(); if (originalA != null) { const resultA = results.get('a'); - invariant(resultA != null); + + if (!(resultA != null)) { + throw new Error('Invariant violation: "resultA != null"'); + } + expect(resultA.getTime()).toEqual(originalA.getTime()); } @@ -171,7 +180,11 @@ describe('EchoServer', () => { expect(originalB).toBeTruthy(); if (originalB != null) { const resultB = results.get('b'); - invariant(resultB != null); + + if (!(resultB != null)) { + throw new Error('Invariant violation: "resultB != null"'); + } + expect(resultB.getTime()).toEqual(originalB.getTime()); } @@ -192,11 +205,14 @@ describe('EchoServer', () => { it('Echoes a value type (struct).', async () => { const expected = { a: new Date(), - b: new Buffer('Buffer Test Data.'), + b: new Buffer('Buffer Test Data.') }; await (async () => { - invariant(service); + if (!service) { + throw new Error('Invariant violation: "service"'); + } + const results = await service.echoValueType(expected); expect(results.a.getTime()).toBe(expected.a.getTime()); @@ -208,7 +224,10 @@ describe('EchoServer', () => { it('Echoes a NuclideUri.', async () => { const expected = testHelper.getUriOfRemotePath('/fake/file.txt'); await (async () => { - invariant(service); + if (!service) { + throw new Error('Invariant violation: "service"'); + } + const results = await service.echoNuclideUri(expected); expect(results).toBe(expected); })(); @@ -216,9 +235,12 @@ describe('EchoServer', () => { // Echo a RemotableObject. it('Echoes a RemotableObject.', async () => { - const expected = new RemotableObject(); + const expected = new (_EchoService || _load_EchoService()).RemotableObject(); await (async () => { - invariant(service); + if (!service) { + throw new Error('Invariant violation: "service"'); + } + const results = await service.echoRemotableObject(expected); expect(results).toBe(expected); })(); @@ -233,11 +255,13 @@ describe('EchoServer', () => { err = _err; } expect(err).toBeTruthy(); - invariant(err != null); - expect(err.message).toBe( - 'constructors are not supported for remote objects', - ); + + if (!(err != null)) { + throw new Error('Invariant violation: "err != null"'); + } + + expect(err.message).toBe('constructors are not supported for remote objects'); }); afterEach(() => testHelper.stop()); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-rpc/__tests__/ErrorService-test.js b/pkg/nuclide-rpc/__tests__/ErrorService-test.js index 11943db5f5..ed31bac1aa 100644 --- a/pkg/nuclide-rpc/__tests__/ErrorService-test.js +++ b/pkg/nuclide-rpc/__tests__/ErrorService-test.js @@ -1,3 +1,25 @@ +'use strict'; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _ServiceTester; + +function _load_ServiceTester() { + return _ServiceTester = require('../__mocks__/ServiceTester'); +} + +var _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../../../jest/waits_for')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,56 +27,45 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import invariant from 'assert'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {ServiceTester} from '../__mocks__/ServiceTester'; -import waitsFor from '../../../jest/waits_for'; - describe('ErrorServer', () => { let testHelper; let service; beforeEach(async () => { - testHelper = new ServiceTester(); - invariant(testHelper); - await testHelper.start( - [ - { - name: 'ErrorService', - definition: nuclideUri.join( - __dirname, - '../__mocks__/ErrorService.def', - ), - implementation: nuclideUri.join( - __dirname, - '../__mocks__/ErrorService.js', - ), - }, - ], - 'error_protocol', - ); - - invariant(testHelper); + testHelper = new (_ServiceTester || _load_ServiceTester()).ServiceTester(); + + if (!testHelper) { + throw new Error('Invariant violation: "testHelper"'); + } + + await testHelper.start([{ + name: 'ErrorService', + definition: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/ErrorService.def'), + implementation: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/ErrorService.js') + }], 'error_protocol'); + + if (!testHelper) { + throw new Error('Invariant violation: "testHelper"'); + } + service = testHelper.getRemoteService('ErrorService'); }); it('ErrorService - error message', async () => { await (async () => { try { - invariant(service); + if (!service) { + throw new Error('Invariant violation: "service"'); + } + await service.promiseError('msg'); expect(false).toBe(true); } catch (e) { expect(e instanceof Error).toBe(true); - expect( - e.message.startsWith( - 'Remote Error: msg processing message {"protocol":"error_protocol","type":' + - '"call","method":"ErrorService/promiseError","id":1,"args":{"message":"msg"}}', - ), - ).toBe(true); + expect(e.message.startsWith('Remote Error: msg processing message {"protocol":"error_protocol","type":' + '"call","method":"ErrorService/promiseError","id":1,"args":{"message":"msg"}}')).toBe(true); } })(); }); @@ -62,7 +73,10 @@ describe('ErrorServer', () => { it('ErrorService - error string', async () => { await (async () => { try { - invariant(service); + if (!service) { + throw new Error('Invariant violation: "service"'); + } + await service.promiseErrorString('msg'); expect(false).toBe(true); } catch (e) { @@ -74,7 +88,10 @@ describe('ErrorServer', () => { it('ErrorService - error undefined', async () => { await (async () => { try { - invariant(service); + if (!service) { + throw new Error('Invariant violation: "service"'); + } + await service.promiseErrorUndefined(); expect(false).toBe(true); } catch (e) { @@ -86,7 +103,10 @@ describe('ErrorServer', () => { it('ErrorService - error code', async () => { await (async () => { try { - invariant(service); + if (!service) { + throw new Error('Invariant violation: "service"'); + } + await service.promiseErrorCode(42); expect(false).toBe(true); } catch (e) { @@ -97,96 +117,90 @@ describe('ErrorServer', () => { }); it('ErrorService - observable error.message', () => { - invariant(service); + if (!service) { + throw new Error('Invariant violation: "service"'); + } + const o = service.observableError('msg').refCount(); let completed = false; - o.subscribe( - () => { - expect(true).toBe(false); - }, - e => { - expect( - e.message.startsWith( - 'Remote Error: msg processing message {"protocol":"error_protocol","type":' + - '"call","method":"ErrorService/observableError","id":1,"args":{"message":"msg"}}', - ), - ).toBe(true); - completed = true; - }, - () => { - expect(true).toBe(false); - }, - ); - - waitsFor(() => completed); + o.subscribe(() => { + expect(true).toBe(false); + }, e => { + expect(e.message.startsWith('Remote Error: msg processing message {"protocol":"error_protocol","type":' + '"call","method":"ErrorService/observableError","id":1,"args":{"message":"msg"}}')).toBe(true); + completed = true; + }, () => { + expect(true).toBe(false); + }); + + (0, (_waits_for || _load_waits_for()).default)(() => completed); }); it('ErrorService - observable message', () => { - invariant(service); + if (!service) { + throw new Error('Invariant violation: "service"'); + } + const o = service.observableErrorString('msg').refCount(); let completed = false; - o.subscribe( - () => { - expect(true).toBe(false); - }, - e => { - expect(e).toBe('msg'); - completed = true; - }, - () => { - expect(true).toBe(false); - }, - ); - - waitsFor(() => completed); + o.subscribe(() => { + expect(true).toBe(false); + }, e => { + expect(e).toBe('msg'); + completed = true; + }, () => { + expect(true).toBe(false); + }); + + (0, (_waits_for || _load_waits_for()).default)(() => completed); }); it('ErrorService - observable undefined', () => { - invariant(service); + if (!service) { + throw new Error('Invariant violation: "service"'); + } + const o = service.observableErrorUndefined().refCount(); let completed = false; - o.subscribe( - () => { - expect(true).toBe(false); - }, - e => { - expect(e).toBe(undefined); - completed = true; - }, - () => { - expect(true).toBe(false); - }, - ); - - waitsFor(() => completed); + o.subscribe(() => { + expect(true).toBe(false); + }, e => { + expect(e).toBe(undefined); + completed = true; + }, () => { + expect(true).toBe(false); + }); + + (0, (_waits_for || _load_waits_for()).default)(() => completed); }); it('ErrorService - observable code', () => { - invariant(service); + if (!service) { + throw new Error('Invariant violation: "service"'); + } + const o = service.observableErrorCode(42).refCount(); let completed = false; - o.subscribe( - () => { - expect(true).toBe(false); - }, - e => { - expect(e.code).toBe(42); - completed = true; - }, - () => { - expect(true).toBe(false); - }, - ); - - waitsFor(() => completed); + o.subscribe(() => { + expect(true).toBe(false); + }, e => { + expect(e.code).toBe(42); + completed = true; + }, () => { + expect(true).toBe(false); + }); + + (0, (_waits_for || _load_waits_for()).default)(() => completed); }); afterEach(() => { - invariant(testHelper); + if (!testHelper) { + throw new Error('Invariant violation: "testHelper"'); + } + return testHelper.stop(); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-rpc/__tests__/ImportService-test.js b/pkg/nuclide-rpc/__tests__/ImportService-test.js index 5b9c793895..12dc761cba 100644 --- a/pkg/nuclide-rpc/__tests__/ImportService-test.js +++ b/pkg/nuclide-rpc/__tests__/ImportService-test.js @@ -1,3 +1,19 @@ +'use strict'; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _ServiceTester; + +function _load_ServiceTester() { + return _ServiceTester = require('../__mocks__/ServiceTester'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,60 +21,58 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import typeof * as ImportService from '../__mocks__/ImportService'; - -import invariant from 'assert'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {ServiceTester} from '../__mocks__/ServiceTester'; - describe('ImportService', () => { let testHelper; - let service: ImportService; + let service; beforeEach(async () => { - testHelper = new ServiceTester(); + testHelper = new (_ServiceTester || _load_ServiceTester()).ServiceTester(); await (() => { - invariant(testHelper); - return testHelper.start( - [ - { - name: 'ImportService', - definition: nuclideUri.join( - __dirname, - '../__mocks__/ImportService.js', - ), - implementation: nuclideUri.join( - __dirname, - '../__mocks__/ImportService.js', - ), - }, - ], - 'import_protocol', - ); + if (!testHelper) { + throw new Error('Invariant violation: "testHelper"'); + } + + return testHelper.start([{ + name: 'ImportService', + definition: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/ImportService.js'), + implementation: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/ImportService.js') + }], 'import_protocol'); })(); - invariant(testHelper); + if (!testHelper) { + throw new Error('Invariant violation: "testHelper"'); + } + service = testHelper.getRemoteService('ImportService'); }); it('ImportService - basic type import', async () => { - invariant(service); + if (!service) { + throw new Error('Invariant violation: "service"'); + } + const result = await service.f('msg'); expect(result).toBe('msg'); }); it('ImportService - type import requiring multiple imports of a ImportedType', async () => { - invariant(service); - const result = await service.g({field: 'msg'}); + if (!service) { + throw new Error('Invariant violation: "service"'); + } + + const result = await service.g({ field: 'msg' }); expect(result).toBe('msg'); }); it('ImportService - type import of export specifiers', async () => { - invariant(service); + if (!service) { + throw new Error('Invariant violation: "service"'); + } + const result = await service.f2('msg'); expect(result).toBe('msg'); const result2 = await service.f3('msg'); @@ -66,7 +80,10 @@ describe('ImportService', () => { }); afterEach(() => { - invariant(testHelper); + if (!testHelper) { + throw new Error('Invariant violation: "testHelper"'); + } + return testHelper.stop(); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-rpc/__tests__/RpcProcess-test.js b/pkg/nuclide-rpc/__tests__/RpcProcess-test.js index d30e97d898..9d2c53e7fd 100644 --- a/pkg/nuclide-rpc/__tests__/RpcProcess-test.js +++ b/pkg/nuclide-rpc/__tests__/RpcProcess-test.js @@ -1,68 +1,72 @@ -/** - * 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 strict-local - * @format - */ - -import typeof * as DummyService from '../__mocks__/fixtures/dummy-service/DummyService'; - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import invariant from 'assert'; -import {spawn} from 'nuclide-commons/process'; -import {RpcProcess} from '../lib/RpcProcess'; -import {ServiceRegistry} from '../../nuclide-rpc'; -import {Scheduler} from 'rxjs'; -import waitsFor from '../../../jest/waits_for'; +'use strict'; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _RpcProcess; + +function _load_RpcProcess() { + return _RpcProcess = require('../lib/RpcProcess'); +} + +var _nuclideRpc; + +function _load_nuclideRpc() { + return _nuclideRpc = require('../../nuclide-rpc'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _waits_for; + +function _load_waits_for() { + return _waits_for = _interopRequireDefault(require('../../../jest/waits_for')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } describe('RpcProcess', () => { - let server: RpcProcess; + let server; beforeEach(() => { - const PROCESS_PATH = nuclideUri.join( - __dirname, - '../__mocks__/fixtures/dummy-service/dummyioserver.py', - ); + const PROCESS_PATH = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures/dummy-service/dummyioserver.py'); const OPTS = { - cwd: nuclideUri.dirname(PROCESS_PATH), + cwd: (_nuclideUri || _load_nuclideUri()).default.dirname(PROCESS_PATH), stdio: 'pipe', - detached: false, + detached: false }; - const serviceRegistry = new ServiceRegistry( - [], - [ - { - name: 'dummy', - definition: nuclideUri.join( - __dirname, - '../__mocks__/fixtures/dummy-service/DummyService.js', - ), - implementation: nuclideUri.join( - __dirname, - '../__mocks__/fixtures/dummy-service/DummyService.js', - ), - preserveFunctionNames: true, - }, - ], - ); - - const processStream = spawn('python', [PROCESS_PATH], OPTS) - // For the sake of our tests, simulate creating the process asynchronously. - .subscribeOn(Scheduler.async); - server = new RpcProcess('Dummy IO Server', serviceRegistry, processStream); + const serviceRegistry = new (_nuclideRpc || _load_nuclideRpc()).ServiceRegistry([], [{ + name: 'dummy', + definition: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures/dummy-service/DummyService.js'), + implementation: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures/dummy-service/DummyService.js'), + preserveFunctionNames: true + }]); + + const processStream = (0, (_process || _load_process()).spawn)('python', [PROCESS_PATH], OPTS) + // For the sake of our tests, simulate creating the process asynchronously. + .subscribeOn(_rxjsBundlesRxMinJs.Scheduler.async); + server = new (_RpcProcess || _load_RpcProcess()).RpcProcess('Dummy IO Server', serviceRegistry, processStream); }); afterEach(() => { - invariant(server != null); + if (!(server != null)) { + throw new Error('Invariant violation: "server != null"'); + } + server.dispose(); }); - function getService(): Promise { + function getService() { return server.getService('dummy'); } @@ -72,7 +76,7 @@ describe('RpcProcess', () => { // dummy server. const response = await (await getService()).binarysystems(); expect(response).toEqual({ - hello: 'Hello World', + hello: 'Hello World' }); })(); }); @@ -80,19 +84,9 @@ describe('RpcProcess', () => { it('should be able to handle multiple calls', async () => { await (async () => { const service = await getService(); - const responses = await Promise.all([ - service.a(), - service.b(), - service.c(), - service.d(), - ]); + const responses = await Promise.all([service.a(), service.b(), service.c(), service.d()]); expect(responses.length).toBe(4); - expect(responses).toEqual([ - {hello: 'Hello World'}, - {hello: 'Hello World'}, - {hello: 'Hello World'}, - {hello: 'Hello World'}, - ]); + expect(responses).toEqual([{ hello: 'Hello World' }, { hello: 'Hello World' }, { hello: 'Hello World' }, { hello: 'Hello World' }]); })(); }); @@ -100,7 +94,10 @@ describe('RpcProcess', () => { await (async () => { try { await (await getService()).error(); - invariant(false, 'Fail - expected promise to reject'); + + if (!false) { + throw new Error('Fail - expected promise to reject'); + } } catch (e) { expect(e).toEqual('Command to error received'); } @@ -109,19 +106,15 @@ describe('RpcProcess', () => { it('should reject pending calls upon the child process exiting', async () => { await (async () => { - const message = server - .observeExitMessage() - .take(1) - .toPromise(); + const message = server.observeExitMessage().take(1).toPromise(); try { await (await getService()).kill(); - invariant(false, 'Fail - expected promise to reject'); + + if (!false) { + throw new Error('Fail - expected promise to reject'); + } } catch (e) { - expect( - e.message.startsWith( - 'Remote Error: Connection Closed processing message', - ), - ).toBeTruthy(); + expect(e.message.startsWith('Remote Error: Connection Closed processing message')).toBeTruthy(); } expect((await message).exitCode).toBe(0); })(); @@ -131,16 +124,19 @@ describe('RpcProcess', () => { await (async () => { try { await (await getService()).kill(); - invariant(false, 'Fail - expected promise to reject'); - } catch (e) { - // Ignore. - } + + if (!false) { + throw new Error('Fail - expected promise to reject'); + } + } catch (e) {} + // Ignore. + // Subsequent request should process successfully, meaning the killed // child process has been restarted. const response = await (await getService()).polarbears(); expect(response).toEqual({ - hello: 'Hello World', + hello: 'Hello World' }); expect(server.isDisposed()).toBe(false); })(); @@ -150,11 +146,15 @@ describe('RpcProcess', () => { await (async () => { await getService(); const process = server._process; - invariant(process != null); + + if (!(process != null)) { + throw new Error('Invariant violation: "process != null"'); + } + const spy = jasmine.createSpy(); process.on('exit', spy); server.dispose(); - waitsFor(() => spy.wasCalled); + (0, (_waits_for || _load_waits_for()).default)(() => spy.wasCalled); const exitSpy = jasmine.createSpy(); server.observeExitMessage().subscribe(() => exitSpy()); @@ -175,4 +175,13 @@ describe('RpcProcess', () => { throw new Error('should have thrown'); })(); }); -}); +}); /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-rpc/__tests__/SocketServer-test.js b/pkg/nuclide-rpc/__tests__/SocketServer-test.js index e1057adf4f..18021de16a 100644 --- a/pkg/nuclide-rpc/__tests__/SocketServer-test.js +++ b/pkg/nuclide-rpc/__tests__/SocketServer-test.js @@ -1,76 +1,92 @@ -/** - * 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 strict-local - * @format - */ - -import typeof * as EchoService from '../__mocks__/EchoService'; - -import invariant from 'assert'; -import net from 'net'; -import {SocketServer} from '../lib/SocketServer'; -import {SocketTransport} from '../lib/SocketTransport'; -import {RpcConnection} from '../lib/RpcConnection'; -import loadServicesConfig from '../lib/loadServicesConfig'; -import {generateFixture} from 'nuclide-commons/test-helpers'; -import {ServiceRegistry} from '../lib/ServiceRegistry'; -import {localNuclideUriMarshalers} from '../../nuclide-marshalers-common'; -import nuclideUri from 'nuclide-commons/nuclideUri'; +'use strict'; + +var _net = _interopRequireDefault(require('net')); + +var _SocketServer; + +function _load_SocketServer() { + return _SocketServer = require('../lib/SocketServer'); +} + +var _SocketTransport; + +function _load_SocketTransport() { + return _SocketTransport = require('../lib/SocketTransport'); +} + +var _RpcConnection; + +function _load_RpcConnection() { + return _RpcConnection = require('../lib/RpcConnection'); +} + +var _loadServicesConfig; + +function _load_loadServicesConfig() { + return _loadServicesConfig = _interopRequireDefault(require('../lib/loadServicesConfig')); +} + +var _testHelpers; + +function _load_testHelpers() { + return _testHelpers = require('../../../modules/nuclide-commons/test-helpers'); +} + +var _ServiceRegistry; + +function _load_ServiceRegistry() { + return _ServiceRegistry = require('../lib/ServiceRegistry'); +} + +var _nuclideMarshalersCommon; + +function _load_nuclideMarshalersCommon() { + return _nuclideMarshalersCommon = require('../../nuclide-marshalers-common'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } describe('SocketServer', () => { - let configPath: ?string; + let configPath; beforeEach(async () => { await (async () => { - const services3json = [ - { - implementation: nuclideUri.join( - __dirname, - '../__mocks__/EchoService.js', - ), - name: 'EchoService', - }, - ]; + const services3json = [{ + implementation: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/EchoService.js'), + name: 'EchoService' + }]; const fbservices3json = []; - configPath = await generateFixture( - 'services', - new Map([ - ['services-3.json', JSON.stringify(services3json)], - ['fb-services-3.json', JSON.stringify(fbservices3json)], - ]), - ); + configPath = await (0, (_testHelpers || _load_testHelpers()).generateFixture)('services', new Map([['services-3.json', JSON.stringify(services3json)], ['fb-services-3.json', JSON.stringify(fbservices3json)]])); })(); }); it.skip('connect and send message', async () => { await (async () => { // flowlint-next-line sketchy-null-string:off - invariant(configPath); - const services = loadServicesConfig(configPath); - const registry = new ServiceRegistry( - [localNuclideUriMarshalers], - services, - ); - const server = new SocketServer(registry); + if (!configPath) { + throw new Error('Invariant violation: "configPath"'); + } + + const services = (0, (_loadServicesConfig || _load_loadServicesConfig()).default)(configPath); + const registry = new (_ServiceRegistry || _load_ServiceRegistry()).ServiceRegistry([(_nuclideMarshalersCommon || _load_nuclideMarshalersCommon()).localNuclideUriMarshalers], services); + const server = new (_SocketServer || _load_SocketServer()).SocketServer(registry); const address = await server.getAddress(); - invariant(address.port !== 0); - - const clientSocket = net.connect(address.port); - const clientTransport = new SocketTransport(clientSocket); - const clientConnection = RpcConnection.createLocal( - clientTransport, - [localNuclideUriMarshalers], - services, - ); - - const echoService: EchoService = clientConnection.getService( - 'EchoService', - ); + + if (!(address.port !== 0)) { + throw new Error('Invariant violation: "address.port !== 0"'); + } + + const clientSocket = _net.default.connect(address.port); + const clientTransport = new (_SocketTransport || _load_SocketTransport()).SocketTransport(clientSocket); + const clientConnection = (_RpcConnection || _load_RpcConnection()).RpcConnection.createLocal(clientTransport, [(_nuclideMarshalersCommon || _load_nuclideMarshalersCommon()).localNuclideUriMarshalers], services); + + const echoService = clientConnection.getService('EchoService'); const result = await echoService.echoString('Hello World!'); expect(result).toBe('Hello World!'); @@ -78,4 +94,13 @@ describe('SocketServer', () => { server.dispose(); })(); }); -}); +}); /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-rpc/__tests__/TypeRegistry-test.js b/pkg/nuclide-rpc/__tests__/TypeRegistry-test.js index 6fdb1a7862..1d4373b9da 100644 --- a/pkg/nuclide-rpc/__tests__/TypeRegistry-test.js +++ b/pkg/nuclide-rpc/__tests__/TypeRegistry-test.js @@ -1,3 +1,17 @@ +'use strict'; + +var _TypeRegistry; + +function _load_TypeRegistry() { + return _TypeRegistry = require('../lib/TypeRegistry'); +} + +var _builtinTypes; + +function _load_builtinTypes() { + return _builtinTypes = require('../lib/builtin-types'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,116 +19,59 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import {TypeRegistry} from '../lib/TypeRegistry'; -import invariant from 'assert'; - -import type { - NamedType, - ArrayType, - ObjectType, - NullableType, - BooleanType, - UnionType, - IntersectionType, -} from '../lib/types'; - -import { - builtinLocation, - numberType, - stringType, - booleanType, - dateType, - regExpType, - bufferType, - anyType, - mixedType, - objectType, -} from '../lib/builtin-types'; -import type {ObjectRegistry} from '../lib/ObjectRegistry'; - describe('TypeRegistry', () => { - let typeRegistry: TypeRegistry = (null: any); - let context: ObjectRegistry = (null: any); + let typeRegistry = null; + let context = null; beforeEach(() => { - typeRegistry = new TypeRegistry([]); - context = ({}: any); + typeRegistry = new (_TypeRegistry || _load_TypeRegistry()).TypeRegistry([]); + context = {}; }); it('Can serialize / deserialize basic primitive types', async () => { - invariant(typeRegistry); + if (!typeRegistry) { + throw new Error('Invariant violation: "typeRegistry"'); + } const expected1 = 'Hello World'; - const str1 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected1, stringType), - stringType, - ); + const str1 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected1, (_builtinTypes || _load_builtinTypes()).stringType)), (_builtinTypes || _load_builtinTypes()).stringType); expect(str1).toBe(expected1); const expected2 = 312213; - const num2 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected2, numberType), - numberType, - ); + const num2 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected2, (_builtinTypes || _load_builtinTypes()).numberType)), (_builtinTypes || _load_builtinTypes()).numberType); expect(num2).toBe(expected2); const expected3 = false; - const bool3 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected3, booleanType), - booleanType, - ); + const bool3 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected3, (_builtinTypes || _load_builtinTypes()).booleanType)), (_builtinTypes || _load_builtinTypes()).booleanType); expect(bool3).toBe(expected3); const expected4 = false; - const bool4 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected4, anyType), - anyType, - ); + const bool4 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected4, (_builtinTypes || _load_builtinTypes()).anyType)), (_builtinTypes || _load_builtinTypes()).anyType); expect(bool4).toBe(expected4); const expected5 = 42; - const num5 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected5, mixedType), - mixedType, - ); + const num5 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected5, (_builtinTypes || _load_builtinTypes()).mixedType)), (_builtinTypes || _load_builtinTypes()).mixedType); expect(num5).toBe(expected5); const expected6 = Number.NEGATIVE_INFINITY; - const num6 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected6, numberType), - numberType, - ); + const num6 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected6, (_builtinTypes || _load_builtinTypes()).numberType)), (_builtinTypes || _load_builtinTypes()).numberType); expect(num6).toBe(expected6); const expected7 = Number.POSITIVE_INFINITY; - const num7 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected7, numberType), - numberType, - ); + const num7 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected7, (_builtinTypes || _load_builtinTypes()).numberType)), (_builtinTypes || _load_builtinTypes()).numberType); expect(num7).toBe(expected7); const expected8 = Number.POSITIVE_INFINITY; - const num8 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected8, numberType), - numberType, - ); + const num8 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected8, (_builtinTypes || _load_builtinTypes()).numberType)), (_builtinTypes || _load_builtinTypes()).numberType); expect(num8).toBe(expected8); // Marshalling an unexpected value throws. let thrown = false; try { - await typeRegistry.marshal(context, null, numberType); + await typeRegistry.marshal(context, null, (_builtinTypes || _load_builtinTypes()).numberType); } catch (e) { thrown = true; } @@ -124,44 +81,35 @@ describe('TypeRegistry', () => { it('Can serialize / deserialize literal types', async () => { await (async () => { const stringLiteralType = { - location: builtinLocation, + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'string-literal', - value: 'Hello World', + value: 'Hello World' }; - invariant(typeRegistry); + + if (!typeRegistry) { + throw new Error('Invariant violation: "typeRegistry"'); + } const expected1 = 'Hello World'; - const str1 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected1, stringLiteralType), - stringLiteralType, - ); + const str1 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected1, stringLiteralType)), stringLiteralType); expect(str1).toBe(expected1); const numberLiteralType = { - location: builtinLocation, + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'number-literal', - value: 312213, + value: 312213 }; const expected2 = 312213; - const num2 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected2, numberLiteralType), - numberLiteralType, - ); + const num2 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected2, numberLiteralType)), numberLiteralType); expect(num2).toBe(expected2); - const falseLiteralType: BooleanType = { - location: builtinLocation, + const falseLiteralType = { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'boolean', - value: false, + value: false }; const expected3 = false; - const bool3 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected3, falseLiteralType), - falseLiteralType, - ); + const bool3 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected3, falseLiteralType)), falseLiteralType); expect(bool3).toBe(expected3); // Marshalling an unexpected value throws. @@ -177,116 +125,90 @@ describe('TypeRegistry', () => { it('Can serialize / deserialize complex types like Date, Regex and Buffer', async () => { await (async () => { - invariant(typeRegistry); - - const expected1 = {a: 42, b: {c: 'str'}}; - const object1 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected1, objectType), - objectType, - ); + if (!typeRegistry) { + throw new Error('Invariant violation: "typeRegistry"'); + } + + const expected1 = { a: 42, b: { c: 'str' } }; + const object1 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected1, (_builtinTypes || _load_builtinTypes()).objectType)), (_builtinTypes || _load_builtinTypes()).objectType); expect(object1).toBe(expected1); const expected2 = new Date(); - const date2 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected2, dateType), - dateType, - ); + const date2 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected2, (_builtinTypes || _load_builtinTypes()).dateType)), (_builtinTypes || _load_builtinTypes()).dateType); expect(date2.getTime()).toBe(expected2.getTime()); const expected3 = /nuclide/gi; - const regex3 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected3, regExpType), - regExpType, - ); + const regex3 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected3, (_builtinTypes || _load_builtinTypes()).regExpType)), (_builtinTypes || _load_builtinTypes()).regExpType); expect(regex3.source).toBe(expected3.source); const expected4 = new Buffer('test buffer data.'); - const buf4: Buffer = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected4, bufferType), - bufferType, - ); + const buf4 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected4, (_builtinTypes || _load_builtinTypes()).bufferType)), (_builtinTypes || _load_builtinTypes()).bufferType); expect(expected4.equals(buf4)).toBeTruthy(); })(); }); it('Can serialize / deserialize parameterized types like Array and Object', async () => { await (async () => { - invariant(typeRegistry); + if (!typeRegistry) { + throw new Error('Invariant violation: "typeRegistry"'); + } // An array of buffers. + + const expected = [new Buffer('testdas'), new Buffer('test')]; - const type: ArrayType = { - location: builtinLocation, + const type = { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'array', - type: bufferType, + type: (_builtinTypes || _load_builtinTypes()).bufferType }; - const result = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected, type), - type, - ); + const result = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected, type)), type); expect(result.length).toBe(2); expect(result[0].equals(expected[0])).toBeTruthy(); expect(result[1].equals(expected[1])).toBeTruthy(); // Object with a a nullable property and a buffer property. - const customObjectType: ObjectType = { - location: builtinLocation, + const customObjectType = { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'object', fields: [ - // A nullable string property. - { - location: builtinLocation, - type: { - location: builtinLocation, - kind: 'nullable', - type: stringType, - }, - name: 'a', - optional: false, - }, - // A non-nullable buffer property. - { - location: builtinLocation, - type: bufferType, - name: 'b', - optional: false, - }, - // An optional number property. - { - location: builtinLocation, - type: numberType, - name: 'c', - optional: true, + // A nullable string property. + { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + type: { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + kind: 'nullable', + type: (_builtinTypes || _load_builtinTypes()).stringType }, - ], + name: 'a', + optional: false + }, + // A non-nullable buffer property. + { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + type: (_builtinTypes || _load_builtinTypes()).bufferType, + name: 'b', + optional: false + }, + // An optional number property. + { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + type: (_builtinTypes || _load_builtinTypes()).numberType, + name: 'c', + optional: true + }] }; - const expected2 = {a: null, b: new Buffer('test')}; - const result2 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, expected2, customObjectType), - customObjectType, - ); + const expected2 = { a: null, b: new Buffer('test') }; + const result2 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, expected2, customObjectType)), customObjectType); expect(result2.a).toBeNull(); expect(result2.b.equals(expected2.b)).toBeTruthy(); // Undefined is acceptable for nullable fields. - const expected3 = {a: undefined, b: new Buffer('test')}; - const marshalled = await typeRegistry.marshal( - context, - expected3, - customObjectType, - ); - const result3 = await typeRegistry.unmarshal( - context, - // JSON omits undefined values, so accurately test that. - JSON.parse(JSON.stringify(marshalled)), - customObjectType, - ); + const expected3 = { a: undefined, b: new Buffer('test') }; + const marshalled = await typeRegistry.marshal(context, expected3, customObjectType); + const result3 = await typeRegistry.unmarshal(context, + // JSON omits undefined values, so accurately test that. + JSON.parse(JSON.stringify(marshalled)), customObjectType); expect(result3.a).toBe(undefined); expect(result3.b.equals(expected3.b)).toBeTruthy(); })(); @@ -294,20 +216,19 @@ describe('TypeRegistry', () => { it('Can serialize / deserialize type aliases.', async () => { await (async () => { - invariant(typeRegistry); - typeRegistry.registerAlias('ValueTypeA', builtinLocation, ValueTypeA); + if (!typeRegistry) { + throw new Error('Invariant violation: "typeRegistry"'); + } + + typeRegistry.registerAlias('ValueTypeA', (_builtinTypes || _load_builtinTypes()).builtinLocation, ValueTypeA); - const data = {valueA: 'Hello World.', valueB: null}; - const type: NamedType = { - location: builtinLocation, + const data = { valueA: 'Hello World.', valueB: null }; + const type = { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'named', - name: 'ValueTypeA', + name: 'ValueTypeA' }; - const result = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, data, type), - type, - ); + const result = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, data, type)), type); expect(result.valueA).toBe(data.valueA); expect(result.valueB).toBeNull(); expect(result.hasOwnProperty('valueC')).toBeFalsy(); @@ -316,56 +237,45 @@ describe('TypeRegistry', () => { it('Can serialize / deserialize named types with same name as type kinds.', async () => { await (async () => { - invariant(typeRegistry); - typeRegistry.registerAlias('nullable', builtinLocation, numberType); + if (!typeRegistry) { + throw new Error('Invariant violation: "typeRegistry"'); + } + + typeRegistry.registerAlias('nullable', (_builtinTypes || _load_builtinTypes()).builtinLocation, (_builtinTypes || _load_builtinTypes()).numberType); const data = null; - const type: NullableType = { - location: builtinLocation, + const type = { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'nullable', - type: stringType, + type: (_builtinTypes || _load_builtinTypes()).stringType }; - const result = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, data, type), - type, - ); + const result = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, data, type)), type); expect(result).toBe(null); })(); }); it('Can serialize / deserialize union literal types.', async () => { await (async () => { - invariant(typeRegistry); + if (!typeRegistry) { + throw new Error('Invariant violation: "typeRegistry"'); + } - const type: UnionType = { - location: builtinLocation, + const type = { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'union', - types: [a1, a2, a3], + types: [a1, a2, a3] }; const data1 = 'bork'; - const result1 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, data1, type), - type, - ); + const result1 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, data1, type)), type); expect(result1).toBe(data1); const data2 = 'bork!'; - const result2 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, data2, type), - type, - ); + const result2 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, data2, type)), type); expect(result2).toBe(data2); const data3 = 42; - const result3 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, data3, type), - type, - ); + const result3 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, data3, type)), type); expect(result3).toBe(data3); const data4 = 'not bork!'; @@ -381,109 +291,88 @@ describe('TypeRegistry', () => { it('Can serialize / deserialize union object types.', async () => { await (async () => { - invariant(typeRegistry); + if (!typeRegistry) { + throw new Error('Invariant violation: "typeRegistry"'); + } // {kind: 'bork'; n: number } - const o1: ObjectType = { - location: builtinLocation, + + + const o1 = { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'object', - fields: [ - { - location: builtinLocation, - type: a1, - name: 'kind', - optional: false, - }, - { - location: builtinLocation, - type: numberType, - name: 'n', - optional: false, - }, - ], + fields: [{ + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + type: a1, + name: 'kind', + optional: false + }, { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + type: (_builtinTypes || _load_builtinTypes()).numberType, + name: 'n', + optional: false + }] }; // {kind: 'bork!'; s: string } - const o2: ObjectType = { - location: builtinLocation, + const o2 = { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'object', - fields: [ - { - location: builtinLocation, - type: a2, - name: 'kind', - optional: false, - }, - { - location: builtinLocation, - type: stringType, - name: 's', - optional: false, - }, - ], + fields: [{ + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + type: a2, + name: 'kind', + optional: false + }, { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + type: (_builtinTypes || _load_builtinTypes()).stringType, + name: 's', + optional: false + }] }; // {kind: 42; b: boolean } - const o3: ObjectType = { - location: builtinLocation, + const o3 = { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'object', - fields: [ - { - location: builtinLocation, - type: a3, - name: 'kind', - optional: false, - }, - { - location: builtinLocation, - type: booleanType, - name: 'b', - optional: false, - }, - ], + fields: [{ + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + type: a3, + name: 'kind', + optional: false + }, { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + type: (_builtinTypes || _load_builtinTypes()).booleanType, + name: 'b', + optional: false + }] }; - const type: UnionType = { - location: builtinLocation, + const type = { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'union', types: [o1, o2, o3], - discriminantField: 'kind', + discriminantField: 'kind' }; - const data1 = {kind: 'bork', n: 42}; - const result1 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, data1, type), - type, - ); + const data1 = { kind: 'bork', n: 42 }; + const result1 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, data1, type)), type); expect(result1).toEqual(data1); - const data2 = {kind: 'bork!', s: 'hello'}; - const result2 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, data2, type), - type, - ); + const data2 = { kind: 'bork!', s: 'hello' }; + const result2 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, data2, type)), type); expect(result2).toEqual(data2); - const data3 = {kind: 42, b: true}; - const result3 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, data3, type), - type, - ); + const data3 = { kind: 42, b: true }; + const result3 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, data3, type)), type); expect(result3).toEqual(data3); // Ensure no extra fields are accidentally marshalled. - const data4 = {kind: 'bork', n: 42, s: 'hello', b: true}; - const result4 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, data4, type), - type, - ); + const data4 = { kind: 'bork', n: 42, s: 'hello', b: true }; + const result4 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, data4, type)), type); expect(result4).toEqual(data1); - const data5 = {kind: 'not bork!'}; + const data5 = { kind: 'not bork!' }; let thrown = false; try { await typeRegistry.marshal(context, data5, type); @@ -496,87 +385,76 @@ describe('TypeRegistry', () => { it('can serialize/deserialize intersection object types', async () => { await (async () => { - invariant(typeRegistry); + if (!typeRegistry) { + throw new Error('Invariant violation: "typeRegistry"'); + } // { x: number, y: number } - const o1: ObjectType = { - location: builtinLocation, + + + const o1 = { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'object', - fields: [ - { - location: builtinLocation, - type: numberType, - name: 'x', - optional: false, - }, - { - location: builtinLocation, - type: numberType, - name: 'y', - optional: false, - }, - ], + fields: [{ + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + type: (_builtinTypes || _load_builtinTypes()).numberType, + name: 'x', + optional: false + }, { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + type: (_builtinTypes || _load_builtinTypes()).numberType, + name: 'y', + optional: false + }] }; // { s: string } - const o2: ObjectType = { - location: builtinLocation, + const o2 = { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'object', - fields: [ - { - location: builtinLocation, - type: stringType, - name: 's', - optional: false, - }, - ], + fields: [{ + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + type: (_builtinTypes || _load_builtinTypes()).stringType, + name: 's', + optional: false + }] }; - const type: IntersectionType = { - location: builtinLocation, + const type = { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'intersection', types: [o1, o2], flattened: { kind: 'object', - location: builtinLocation, - fields: o1.fields.concat(o2.fields), - }, + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + fields: o1.fields.concat(o2.fields) + } }; - const data1 = {x: 5, y: 6, s: 'asdf'}; - const result1 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, data1, type), - type, - ); + const data1 = { x: 5, y: 6, s: 'asdf' }; + const result1 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, data1, type)), type); expect(result1).toEqual(data1); // Ensure no extra fields are accidentally marshalled. - const data4 = {x: 5, y: 6, s: 'asdf', b: true}; - const result4 = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, data4, type), - type, - ); + const data4 = { x: 5, y: 6, s: 'asdf', b: true }; + const result4 = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, data4, type)), type); expect(result4).toEqual(data1); })(); }); it('Can serialize / deserialize undefined values', async () => { await (async () => { - invariant(typeRegistry); + if (!typeRegistry) { + throw new Error('Invariant violation: "typeRegistry"'); + } const data = undefined; - const type: NullableType = { - location: builtinLocation, + const type = { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'nullable', - type: stringType, + type: (_builtinTypes || _load_builtinTypes()).stringType }; - const result = await typeRegistry.unmarshal( - context, - await typeRegistry.marshal(context, data, type), - type, - ); + const result = await typeRegistry.unmarshal(context, (await typeRegistry.marshal(context, data, type)), type); expect(result).toBe(undefined); })(); }); @@ -586,12 +464,12 @@ describe('TypeRegistry', () => { for (let i = 0; i < 100000; i++) { testArray.push('this is a test string'); } - const {heapUsed} = process.memoryUsage(); + const { heapUsed } = process.memoryUsage(); const startTime = Date.now(); const result = await typeRegistry.marshal(context, testArray, { - location: builtinLocation, + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'array', - type: stringType, + type: (_builtinTypes || _load_builtinTypes()).stringType }); const mem = process.memoryUsage().heapUsed - heapUsed; // eslint-disable-next-line no-console @@ -607,103 +485,90 @@ describe('TypeRegistry', () => { it('works for parameter names same name as members from Object.prototype', async () => { await (async () => { - invariant(typeRegistry); + if (!typeRegistry) { + throw new Error('Invariant violation: "typeRegistry"'); + } - const parameters = [ - { - name: 'hasOwnProperty', - type: stringType, - }, - ]; + const parameters = [{ + name: 'hasOwnProperty', + type: (_builtinTypes || _load_builtinTypes()).stringType + }]; const expected = 'Hello World'; - const results = await typeRegistry.unmarshalArguments( - context, - await typeRegistry.marshalArguments(context, [expected], parameters), - parameters, - ); + const results = await typeRegistry.unmarshalArguments(context, (await typeRegistry.marshalArguments(context, [expected], parameters)), parameters); expect(results).toEqual([expected]); })(); }); it('accepts undefined parameters for nullable/mixed/any types', async () => { await (async () => { - invariant(typeRegistry); - - const parameters = [ - { - name: 'a', - type: { - location: builtinLocation, - kind: 'nullable', - type: stringType, - }, - }, - { - name: 'b', - type: anyType, - }, - { - name: 'c', - type: mixedType, - }, - ]; + if (!typeRegistry) { + throw new Error('Invariant violation: "typeRegistry"'); + } - const results = await typeRegistry.unmarshalArguments( - context, - {}, // JSON.stringify removes all undefined values. - parameters, - ); + const parameters = [{ + name: 'a', + type: { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + kind: 'nullable', + type: (_builtinTypes || _load_builtinTypes()).stringType + } + }, { + name: 'b', + type: (_builtinTypes || _load_builtinTypes()).anyType + }, { + name: 'c', + type: (_builtinTypes || _load_builtinTypes()).mixedType + }]; + + const results = await typeRegistry.unmarshalArguments(context, {}, // JSON.stringify removes all undefined values. + parameters); expect(results).toEqual([undefined, undefined, undefined]); })(); }); }); const a1 = { - location: builtinLocation, + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'string-literal', - value: 'bork', + value: 'bork' }; const a2 = { - location: builtinLocation, + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'string-literal', - value: 'bork!', + value: 'bork!' }; const a3 = { - location: builtinLocation, + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'number-literal', - value: 42, + value: 42 }; -const ValueTypeA: ObjectType = { - location: builtinLocation, +const ValueTypeA = { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'object', - fields: [ - { - location: builtinLocation, - name: 'valueA', - optional: false, - type: stringType, - }, - { - location: builtinLocation, - name: 'valueB', - optional: false, + fields: [{ + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + name: 'valueA', + optional: false, + type: (_builtinTypes || _load_builtinTypes()).stringType + }, { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + name: 'valueB', + optional: false, + type: { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + kind: 'nullable', type: { - location: builtinLocation, - kind: 'nullable', - type: { - location: builtinLocation, - kind: 'named', - name: 'ValueTypeB', - }, - }, - }, - { - location: builtinLocation, - name: 'valueC', - optional: true, - type: booleanType, - }, - ], -}; + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + kind: 'named', + name: 'ValueTypeB' + } + } + }, { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, + name: 'valueC', + optional: true, + type: (_builtinTypes || _load_builtinTypes()).booleanType + }] +}; \ No newline at end of file diff --git a/pkg/nuclide-rpc/__tests__/loadServicesConfig-test.js b/pkg/nuclide-rpc/__tests__/loadServicesConfig-test.js index 2087fd7490..dd93e3e439 100644 --- a/pkg/nuclide-rpc/__tests__/loadServicesConfig-test.js +++ b/pkg/nuclide-rpc/__tests__/loadServicesConfig-test.js @@ -1,3 +1,25 @@ +'use strict'; + +var _loadServicesConfig; + +function _load_loadServicesConfig() { + return _loadServicesConfig = _interopRequireDefault(require('../lib/loadServicesConfig')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _testHelpers; + +function _load_testHelpers() { + return _testHelpers = require('../../../modules/nuclide-commons/test-helpers'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,90 +27,91 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import invariant from 'assert'; -import loadServicesConfig from '../lib/loadServicesConfig'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {generateFixture} from 'nuclide-commons/test-helpers'; - describe('loadServicesConfig()', () => { - let configPath: ?string; + let configPath; beforeEach(async () => { await (async () => { - const services3json = [ - { - implementation: './FooService.js', - name: 'FooService', - }, - { - definition: './BarServiceDefinition.js', - implementation: './BarServiceImplementation.js', - name: 'BarService', - }, - ]; - const fbservices3json = [ - { - implementation: './BazService.js', - name: 'BazService', - preserveFunctionNames: true, - }, - ]; - configPath = await generateFixture( - 'services', - new Map([ - ['services-3.json', JSON.stringify(services3json)], - ['fb-services-3.json', JSON.stringify(fbservices3json)], - ]), - ); + const services3json = [{ + implementation: './FooService.js', + name: 'FooService' + }, { + definition: './BarServiceDefinition.js', + implementation: './BarServiceImplementation.js', + name: 'BarService' + }]; + const fbservices3json = [{ + implementation: './BazService.js', + name: 'BazService', + preserveFunctionNames: true + }]; + configPath = await (0, (_testHelpers || _load_testHelpers()).generateFixture)('services', new Map([['services-3.json', JSON.stringify(services3json)], ['fb-services-3.json', JSON.stringify(fbservices3json)]])); })(); }); it('resolves absolute paths', () => { // flowlint-next-line sketchy-null-string:off - invariant(configPath); - const servicesConfig = loadServicesConfig(configPath); + if (!configPath) { + throw new Error('Invariant violation: "configPath"'); + } + + const servicesConfig = (0, (_loadServicesConfig || _load_loadServicesConfig()).default)(configPath); servicesConfig.forEach(service => { - expect(nuclideUri.isAbsolute(service.definition)).toBe(true); - expect(nuclideUri.isAbsolute(service.implementation)).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute(service.definition)).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute(service.implementation)).toBe(true); }); }); it('uses the implementation when the definition is missing', () => { // flowlint-next-line sketchy-null-string:off - invariant(configPath); - const servicesConfig = loadServicesConfig(configPath); - const fooService = servicesConfig.find( - service => service.name === 'FooService', - ); - invariant(fooService != null); + if (!configPath) { + throw new Error('Invariant violation: "configPath"'); + } + + const servicesConfig = (0, (_loadServicesConfig || _load_loadServicesConfig()).default)(configPath); + const fooService = servicesConfig.find(service => service.name === 'FooService'); + + if (!(fooService != null)) { + throw new Error('Invariant violation: "fooService != null"'); + } + expect(fooService.definition).toBe(fooService.implementation); }); it('respects preserveFunctionNames', () => { // flowlint-next-line sketchy-null-string:off - invariant(configPath); - const servicesConfig = loadServicesConfig(configPath); + if (!configPath) { + throw new Error('Invariant violation: "configPath"'); + } + + const servicesConfig = (0, (_loadServicesConfig || _load_loadServicesConfig()).default)(configPath); + + const fooService = servicesConfig.find(service => service.name === 'FooService'); + + if (!(fooService != null)) { + throw new Error('Invariant violation: "fooService != null"'); + } - const fooService = servicesConfig.find( - service => service.name === 'FooService', - ); - invariant(fooService != null); expect(fooService.preserveFunctionNames).toBe(false); - const barService = servicesConfig.find( - service => service.name === 'BarService', - ); - invariant(barService != null); + const barService = servicesConfig.find(service => service.name === 'BarService'); + + if (!(barService != null)) { + throw new Error('Invariant violation: "barService != null"'); + } + expect(barService.preserveFunctionNames).toBe(false); - const BazService = servicesConfig.find( - service => service.name === 'BazService', - ); - invariant(BazService != null); + const BazService = servicesConfig.find(service => service.name === 'BazService'); + + if (!(BazService != null)) { + throw new Error('Invariant violation: "BazService != null"'); + } + expect(BazService.preserveFunctionNames).toBe(true); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-rpc/__tests__/location-test.js b/pkg/nuclide-rpc/__tests__/location-test.js index d64ff88650..9287b1654e 100644 --- a/pkg/nuclide-rpc/__tests__/location-test.js +++ b/pkg/nuclide-rpc/__tests__/location-test.js @@ -1,3 +1,17 @@ +'use strict'; + +var _builtinTypes; + +function _load_builtinTypes() { + return _builtinTypes = require('../lib/builtin-types'); +} + +var _location; + +function _load_location() { + return _location = require('../lib/location'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,60 +19,57 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import {builtinLocation} from '../lib/builtin-types'; -import {locationsEqual, locationToString} from '../lib/location'; - const builtin2 = { - type: 'builtin', + type: 'builtin' }; const loc1 = { type: 'source', fileName: 'file1', - line: 42, + line: 42 }; const loc2 = { type: 'source', fileName: 'file1', - line: 42, + line: 42 }; const loc3 = { type: 'source', fileName: 'file2', - line: 42, + line: 42 }; const loc4 = { type: 'source', fileName: 'file1', - line: 43, + line: 43 }; const loc5 = { type: 'source', fileName: 'file2', - line: 43, + line: 43 }; describe('Location', () => { it('toString', () => { - expect(locationToString(builtinLocation)).toBe(''); - expect(locationToString(loc1)).toBe('file1(42)'); + expect((0, (_location || _load_location()).locationToString)((_builtinTypes || _load_builtinTypes()).builtinLocation)).toBe(''); + expect((0, (_location || _load_location()).locationToString)(loc1)).toBe('file1(42)'); }); it('equals', () => { - expect(locationsEqual(builtinLocation, builtin2)).toBe(true); - expect(locationsEqual(builtinLocation, loc1)).toBe(false); + expect((0, (_location || _load_location()).locationsEqual)((_builtinTypes || _load_builtinTypes()).builtinLocation, builtin2)).toBe(true); + expect((0, (_location || _load_location()).locationsEqual)((_builtinTypes || _load_builtinTypes()).builtinLocation, loc1)).toBe(false); - expect(locationsEqual(loc1, loc2)).toBe(true); - expect(locationsEqual(loc1, loc3)).toBe(false); - expect(locationsEqual(loc1, loc4)).toBe(false); - expect(locationsEqual(loc1, loc5)).toBe(false); + expect((0, (_location || _load_location()).locationsEqual)(loc1, loc2)).toBe(true); + expect((0, (_location || _load_location()).locationsEqual)(loc1, loc3)).toBe(false); + expect((0, (_location || _load_location()).locationsEqual)(loc1, loc4)).toBe(false); + expect((0, (_location || _load_location()).locationsEqual)(loc1, loc5)).toBe(false); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-rpc/__tests__/module-test.js b/pkg/nuclide-rpc/__tests__/module-test.js index bb15d28857..7e31e76dd1 100644 --- a/pkg/nuclide-rpc/__tests__/module-test.js +++ b/pkg/nuclide-rpc/__tests__/module-test.js @@ -1,41 +1,37 @@ -/** - * 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 - */ - -import {createProxyFactory, __test__} from '../lib/main'; +'use strict'; + +var _main; + +function _load_main() { + return _main = require('../lib/main'); +} describe('Module public API.', () => { beforeEach(() => { - __test__.proxiesCache.clear(); + (_main || _load_main()).__test__.proxiesCache.clear(); }); it('Creates a remote proxy for a module, caching the intermediate results.', () => { - const fakeClient: any = {}; - const defFile = require.resolve( - '../__mocks__/fixtures/FunctionService.def', - ); + const fakeClient = {}; + const defFile = require.resolve('../__mocks__/fixtures/FunctionService.def'); - expect(__test__.proxiesCache.size).toBe(0); + expect((_main || _load_main()).__test__.proxiesCache.size).toBe(0); - const factory = createProxyFactory('FunctionService', false, defFile, []); + const factory = (0, (_main || _load_main()).createProxyFactory)('FunctionService', false, defFile, []); const proxy = factory(fakeClient); - expect(Object.keys(proxy)).toEqual([ - 'TestFunctionA', - 'TestFunctionB', - 'TestFunctionC', - 'TestFunctionD', - 'ReturnAlias', - ]); + expect(Object.keys(proxy)).toEqual(['TestFunctionA', 'TestFunctionB', 'TestFunctionC', 'TestFunctionD', 'ReturnAlias']); // Expect that createProxyFactory added files to the cache. - expect(__test__.proxiesCache.size).toBe(1); + expect((_main || _load_main()).__test__.proxiesCache.size).toBe(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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-rpc/__tests__/observable-test.js b/pkg/nuclide-rpc/__tests__/observable-test.js index dba448f694..cdebedd428 100644 --- a/pkg/nuclide-rpc/__tests__/observable-test.js +++ b/pkg/nuclide-rpc/__tests__/observable-test.js @@ -1,26 +1,17 @@ -/** - * 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 strict - * @format - */ +'use strict'; -import {Observable} from 'rxjs'; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); describe('ConnectableObservable', () => { it('connect', () => { let created = 0; let unsubscribed = 0; - const obs = Observable.create(observer => { + const obs = _rxjsBundlesRxMinJs.Observable.create(observer => { created += 1; return { unsubscribe: () => { unsubscribed += 1; - }, + } }; }); const connectable = obs.publish(); @@ -61,12 +52,12 @@ describe('ConnectableObservable', () => { it('refcount', () => { let created = 0; let unsubscribed = 0; - const obs = Observable.create(observer => { + const obs = _rxjsBundlesRxMinJs.Observable.create(observer => { created += 1; return { unsubscribe: () => { unsubscribed += 1; - }, + } }; }); const connectable = obs.publish(); @@ -95,4 +86,13 @@ describe('ConnectableObservable', () => { }); // TODO: Test disconnect when a subscription is outstanding. -}); +}); /** + * 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. + * + * strict + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-rpc/__tests__/proxy-generator-test.js b/pkg/nuclide-rpc/__tests__/proxy-generator-test.js index 9d2e62646f..4f0a84f485 100644 --- a/pkg/nuclide-rpc/__tests__/proxy-generator-test.js +++ b/pkg/nuclide-rpc/__tests__/proxy-generator-test.js @@ -1,96 +1,97 @@ -/** - * 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 - */ - -import fs from 'fs'; -import * as t from '@babel/types'; -import generate from '@babel/generator'; -import createProxyGenerator from '../lib/proxy-generator'; -import {parseServiceDefinition} from '../lib/service-parser'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import vm from 'vm'; - -const {generateProxy, __test__} = createProxyGenerator(t, generate); - -import type {Type} from '../lib/types'; - -import {builtinLocation} from '../lib/builtin-types'; +'use strict'; + +var _fs = _interopRequireDefault(require('fs')); + +var _types; + +function _load_types() { + return _types = _interopRequireWildcard(require('@babel/types')); +} + +var _generator; + +function _load_generator() { + return _generator = _interopRequireDefault(require('@babel/generator')); +} + +var _proxyGenerator; + +function _load_proxyGenerator() { + return _proxyGenerator = _interopRequireDefault(require('../lib/proxy-generator')); +} + +var _serviceParser; + +function _load_serviceParser() { + return _serviceParser = require('../lib/service-parser'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _vm = _interopRequireDefault(require('vm')); + +var _builtinTypes; + +function _load_builtinTypes() { + return _builtinTypes = require('../lib/builtin-types'); +} + +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 { generateProxy, __test__ } = (0, (_proxyGenerator || _load_proxyGenerator()).default)(_types || _load_types(), (_generator || _load_generator()).default); /** + * 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. + * + * + * @format + */ describe('Proxy generator test suite.', () => { - for (const file of fs.readdirSync( - nuclideUri.join(__dirname, '../__mocks__/fixtures'), - )) { + for (const file of _fs.default.readdirSync((_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures'))) { if (file.endsWith('.def')) { it(`Successfully generates proxy for ${file}`, () => { - const fixturePath = nuclideUri.join( - __dirname, - '../__mocks__/fixtures', - file, - ); - const definitions = parseServiceDefinition( - file, - fs.readFileSync(fixturePath, 'utf8'), - [], - ); - - const code = generateProxy( - nuclideUri.basename(file, '.def'), - false, - definitions, - ); - const expected = fs.readFileSync( - nuclideUri - .join(__dirname, '../__mocks__/fixtures', file) - .replace('.def', '.proxy'), - 'utf8', - ); + const fixturePath = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures', file); + const definitions = (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)(file, _fs.default.readFileSync(fixturePath, 'utf8'), []); + + const code = generateProxy((_nuclideUri || _load_nuclideUri()).default.basename(file, '.def'), false, definitions); + const expected = _fs.default.readFileSync((_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures', file).replace('.def', '.proxy'), 'utf8'); expect(code.trim()).toBe(expected.trim()); }); } } }); -const ArrayOfArrayOfNuclideUri: Type = { - location: builtinLocation, +const ArrayOfArrayOfNuclideUri = { + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'array', type: { - location: builtinLocation, + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'array', type: { - location: builtinLocation, + location: (_builtinTypes || _load_builtinTypes()).builtinLocation, kind: 'named', - name: nuclideUri.NUCLIDE_URI_TYPE_NAME, - }, - }, + name: (_nuclideUri || _load_nuclideUri()).default.NUCLIDE_URI_TYPE_NAME + } + } }; describe('generateTransformStatement helper function', () => { it('Generates a marshal statement.', () => { - const code = generate( - __test__.generateTransformStatement( - t.identifier('value'), - ArrayOfArrayOfNuclideUri, - true, - ), - ).code; + const code = (0, (_generator || _load_generator()).default)(__test__.generateTransformStatement((_types || _load_types()).identifier('value'), ArrayOfArrayOfNuclideUri, true)).code; expect(code).toBe(marshalText); }); it('Generates an unmarshal statement.', () => { - const code = generate( - __test__.generateTransformStatement( - t.identifier('value'), - ArrayOfArrayOfNuclideUri, - false, - ), - ).code; + const code = (0, (_generator || _load_generator()).default)(__test__.generateTransformStatement((_types || _load_types()).identifier('value'), ArrayOfArrayOfNuclideUri, false)).code; expect(code).toBe(unmarshalText); }); }); @@ -137,66 +138,58 @@ const unmarshalText = `_client.unmarshal(value, { describe('objectToLiteral helper function', () => { it('works on numbers', () => { - expect(generate(__test__.objectToLiteral(1)).code).toBe('1'); + expect((0, (_generator || _load_generator()).default)(__test__.objectToLiteral(1)).code).toBe('1'); }); it('works on strings', () => { - expect(generate(__test__.objectToLiteral('1')).code).toBe('"1"'); + expect((0, (_generator || _load_generator()).default)(__test__.objectToLiteral('1')).code).toBe('"1"'); }); it('works on booleans', () => { - expect(generate(__test__.objectToLiteral(false)).code).toBe('false'); + expect((0, (_generator || _load_generator()).default)(__test__.objectToLiteral(false)).code).toBe('false'); }); it('works on Maps', () => { - expect(generate(__test__.objectToLiteral(new Map())).code).toBe( - 'new Map()', - ); + expect((0, (_generator || _load_generator()).default)(__test__.objectToLiteral(new Map())).code).toBe('new Map()'); }); it('works on objects with simple keys', () => { - expect(generate(__test__.objectToLiteral({a: 1})).code).toBe( - '{\n a: 1\n}', - ); + expect((0, (_generator || _load_generator()).default)(__test__.objectToLiteral({ a: 1 })).code).toBe('{\n a: 1\n}'); }); it('works on objects with complex keys', () => { - expect(generate(__test__.objectToLiteral({'.': 1})).code).toBe( - '{\n ".": 1\n}', - ); + expect((0, (_generator || _load_generator()).default)(__test__.objectToLiteral({ '.': 1 })).code).toBe('{\n ".": 1\n}'); }); it('works on null', () => { - expect(generate(__test__.objectToLiteral(null)).code).toBe('null'); + expect((0, (_generator || _load_generator()).default)(__test__.objectToLiteral(null)).code).toBe('null'); }); it('works on undefined', () => { - expect(generate(__test__.objectToLiteral()).code).toBe('undefined'); - expect(generate(__test__.objectToLiteral(undefined)).code).toBe( - 'undefined', - ); + expect((0, (_generator || _load_generator()).default)(__test__.objectToLiteral()).code).toBe('undefined'); + expect((0, (_generator || _load_generator()).default)(__test__.objectToLiteral(undefined)).code).toBe('undefined'); }); it('works on arrays', () => { - expect(generate(__test__.objectToLiteral([])).code).toBe('[]'); + expect((0, (_generator || _load_generator()).default)(__test__.objectToLiteral([])).code).toBe('[]'); }); it('throws on unknown type function', () => { expect(() => { - generate(__test__.objectToLiteral(() => {})).code; + (0, (_generator || _load_generator()).default)(__test__.objectToLiteral(() => {})).code; }).toThrow(new Error('Cannot convert unknown type function to literal.')); }); it('throws on unknown type nested function', () => { expect(() => { - generate(__test__.objectToLiteral({fn: () => {}})).code; + (0, (_generator || _load_generator()).default)(__test__.objectToLiteral({ fn: () => {} })).code; }).toThrow(new Error('Cannot convert unknown type function to literal.')); }); it('throws on unknown type class', () => { expect(() => { - generate(__test__.objectToLiteral(class X {})).code; + (0, (_generator || _load_generator()).default)(__test__.objectToLiteral(class X {})).code; // Native classes also pass typeof === 'function' }).toThrow(new Error('Cannot convert unknown type function to literal.')); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-rpc/__tests__/service-parser-test.js b/pkg/nuclide-rpc/__tests__/service-parser-test.js index 2561c20946..283b7ae8f0 100644 --- a/pkg/nuclide-rpc/__tests__/service-parser-test.js +++ b/pkg/nuclide-rpc/__tests__/service-parser-test.js @@ -1,3 +1,27 @@ +'use strict'; + +var _fs = _interopRequireDefault(require('fs')); + +var _serviceParser; + +function _load_serviceParser() { + return _serviceParser = require('../lib/service-parser'); +} + +var _location; + +function _load_location() { + return _location = require('../lib/location'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,39 +29,23 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import fs from 'fs'; -import {parseServiceDefinition, _clearFileParsers} from '../lib/service-parser'; -import {stripLocationsFileName} from '../lib/location'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - describe('Nuclide service parser test suite.', () => { afterEach(() => { - _clearFileParsers(); + (0, (_serviceParser || _load_serviceParser())._clearFileParsers)(); }); - for (const file of fs.readdirSync( - nuclideUri.join(__dirname, '../__mocks__/fixtures'), - )) { + for (const file of _fs.default.readdirSync((_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures'))) { if (file.endsWith('.def')) { it(`Successfully parses ${file}`, () => { - const fixturePath = nuclideUri.join( - __dirname, - '../__mocks__/fixtures', - file, - ); - const code = fs.readFileSync(fixturePath, 'utf8'); - const expected = JSON.parse( - fs.readFileSync( - nuclideUri.join(__dirname, '../__mocks__/fixtures', file) + '.json', - 'utf8', - ), - ); - const definitions = parseServiceDefinition(fixturePath, code, []); - stripLocationsFileName(definitions); + const fixturePath = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures', file); + const code = _fs.default.readFileSync(fixturePath, 'utf8'); + const expected = JSON.parse(_fs.default.readFileSync((_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../__mocks__/fixtures', file) + '.json', 'utf8')); + const definitions = (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)(fixturePath, code, []); + (0, (_location || _load_location()).stripLocationsFileName)(definitions); expect(definitions).toEqual(expected); }); } @@ -51,7 +59,7 @@ describe('Nuclide service parser test suite.', () => { dispose(): void {} }`; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -63,7 +71,7 @@ describe('Nuclide service parser test suite.', () => { dispose(): void {} }`; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -73,7 +81,7 @@ describe('Nuclide service parser test suite.', () => { dispose(x: int): void {} }`; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -83,7 +91,7 @@ describe('Nuclide service parser test suite.', () => { dispose(): int {} }`; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -93,7 +101,7 @@ describe('Nuclide service parser test suite.', () => { m(): void {} }`; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -104,7 +112,7 @@ describe('Nuclide service parser test suite.', () => { dispose(): void {} }`; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -115,7 +123,7 @@ describe('Nuclide service parser test suite.', () => { dispose(): void {} }`; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -127,7 +135,7 @@ describe('Nuclide service parser test suite.', () => { export function f(p: UsesMissingType): void {} `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -138,7 +146,7 @@ describe('Nuclide service parser test suite.', () => { dispose(): void {} }`; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -148,7 +156,7 @@ describe('Nuclide service parser test suite.', () => { dispose(p: Promise): void {} }`; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -159,7 +167,7 @@ describe('Nuclide service parser test suite.', () => { dispose(): void {} }`; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -168,7 +176,7 @@ describe('Nuclide service parser test suite.', () => { export type R = R; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -177,7 +185,7 @@ describe('Nuclide service parser test suite.', () => { export type R = Promise; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -187,7 +195,7 @@ describe('Nuclide service parser test suite.', () => { export type B = A; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -198,7 +206,7 @@ describe('Nuclide service parser test suite.', () => { export type O = {f: A}; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -208,7 +216,7 @@ describe('Nuclide service parser test suite.', () => { export function f(): A {}; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -217,7 +225,7 @@ describe('Nuclide service parser test suite.', () => { export type A = B | 42; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -226,7 +234,7 @@ describe('Nuclide service parser test suite.', () => { export type A = 42 | A; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -235,7 +243,7 @@ describe('Nuclide service parser test suite.', () => { export type A = 42 | Promise<42>; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -244,7 +252,7 @@ describe('Nuclide service parser test suite.', () => { export type A = 42 | number; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -253,7 +261,7 @@ describe('Nuclide service parser test suite.', () => { export type A = 42 | 42; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -262,7 +270,7 @@ describe('Nuclide service parser test suite.', () => { export type A = {kind: 'foo'} | '42'; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -271,7 +279,7 @@ describe('Nuclide service parser test suite.', () => { export type A = {kind: 'foo'} | {kind: string}; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -280,7 +288,7 @@ describe('Nuclide service parser test suite.', () => { export type A = {kind1: 'foo'} | {kind2: 'bar'}; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -289,7 +297,7 @@ describe('Nuclide service parser test suite.', () => { export type A = {kind: 'foo'} | {kind: 'foo'}; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -298,7 +306,7 @@ describe('Nuclide service parser test suite.', () => { export type A = {x: string} & {y: string}; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).not.toThrow(); }); @@ -307,7 +315,7 @@ describe('Nuclide service parser test suite.', () => { export type A = {x: string} & boolean; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -316,7 +324,7 @@ describe('Nuclide service parser test suite.', () => { export type A = {x: string} & {x: string}; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -326,7 +334,7 @@ describe('Nuclide service parser test suite.', () => { export f(p: T): void {}; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -335,7 +343,7 @@ describe('Nuclide service parser test suite.', () => { export function f(x: number = 1): void {} `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).not.toThrow(); }); @@ -346,7 +354,7 @@ describe('Nuclide service parser test suite.', () => { }; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -358,7 +366,7 @@ describe('Nuclide service parser test suite.', () => { }; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).not.toThrow(); }); @@ -369,7 +377,7 @@ describe('Nuclide service parser test suite.', () => { }; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -383,7 +391,7 @@ describe('Nuclide service parser test suite.', () => { }; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); @@ -397,21 +405,21 @@ describe('Nuclide service parser test suite.', () => { }; `; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); it('re-exporting functions not supported', () => { const code = "export {getPreview} from 'symbol-definition-preview'"; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); it('exporting functions without declaration not supported', () => { const code = 'export {someFunction};'; expect(() => { - parseServiceDefinition('fileName', code, []); + (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)('fileName', code, []); }).toThrow(); }); -}); +}); \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/DefinitionValidator.js b/pkg/nuclide-rpc/lib/DefinitionValidator.js index db699390ee..e0d2ab1d27 100644 --- a/pkg/nuclide-rpc/lib/DefinitionValidator.js +++ b/pkg/nuclide-rpc/lib/DefinitionValidator.js @@ -1,3 +1,28 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.validateDefinitions = validateDefinitions; + +var _location; + +function _load_location() { + return _location = require('./location'); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +/** + * Throws if a named type referenced in an RPC interface is not defined. + * The error message thrown is suitable for display to a human. + * + * NOTE: Will also mutate the incoming definitions in place to make them easier to marshal. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,49 +30,20 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import {locationToString} from './location'; -import invariant from 'assert'; -import {setIntersect} from 'nuclide-commons/collection'; - -import type { - Definitions, - Definition, - AliasDefinition, - InterfaceDefinition, - Type, - FunctionType, - NamedType, - UnionType, - IntersectionType, - ObjectType, - ObjectField, - LiteralType, - Location, -} from './types'; - -/** - * Throws if a named type referenced in an RPC interface is not defined. - * The error message thrown is suitable for display to a human. - * - * NOTE: Will also mutate the incoming definitions in place to make them easier to marshal. - */ -export function validateDefinitions(definitions: Definitions): void { - const namedTypes: Map< - string, - AliasDefinition | InterfaceDefinition, - > = new Map(); +function validateDefinitions(definitions) { + const namedTypes = new Map(); gatherKnownTypes(); // Location of the currently visited definition. // It's too painfulto thread this through everywhere. - let contextLocation: ?Location; + let contextLocation; validate(); - function validate(): void { + function validate() { findMissingTypeNames(); findRecursiveAliases(); validateReturnTypes(); @@ -58,7 +54,7 @@ export function validateDefinitions(definitions: Definitions): void { visitAllTypes(checkTypeForMissingNames); } - function gatherKnownTypes(): void { + function gatherKnownTypes() { Object.keys(definitions).forEach(name => { const definition = definitions[name]; switch (definition.kind) { @@ -70,7 +66,7 @@ export function validateDefinitions(definitions: Definitions): void { }); } - function checkTypeForMissingNames(type: Type): void { + function checkTypeForMissingNames(type) { switch (type.kind) { case 'any': case 'mixed': @@ -114,9 +110,7 @@ export function validateDefinitions(definitions: Definitions): void { type.types.forEach(checkTypeForMissingNames); break; case 'function': - type.argumentTypes.forEach(parameter => - checkTypeForMissingNames(parameter.type), - ); + type.argumentTypes.forEach(parameter => checkTypeForMissingNames(parameter.type)); checkTypeForMissingNames(type.returnType); break; case 'named': @@ -126,7 +120,7 @@ export function validateDefinitions(definitions: Definitions): void { } break; default: - (type: empty); + type; throw new Error(JSON.stringify(type)); } } @@ -142,7 +136,7 @@ export function validateDefinitions(definitions: Definitions): void { }); } - function checkAliasLayout(alias: AliasDefinition): void { + function checkAliasLayout(alias) { if (alias.definition) { validateLayoutRec([alias], alias.definition); } @@ -154,11 +148,8 @@ export function validateDefinitions(definitions: Definitions): void { * * If recursion is found the chain of types which recursively contain each other is reported. */ - function validateLayoutRec( - containingDefinitions: Array, - type: Type, - ): void { - function validateTypeRec(typeRec: Type): void { + function validateLayoutRec(containingDefinitions, type) { + function validateTypeRec(typeRec) { validateLayoutRec(containingDefinitions, typeRec); } @@ -186,10 +177,7 @@ export function validateDefinitions(definitions: Definitions): void { // Containers break the layout chain as they may be empty. break; case 'object': - type.fields - .filter(field => !field.optional) - .map(field => field.type) - .forEach(validateTypeRec); + type.fields.filter(field => !field.optional).map(field => field.type).forEach(validateTypeRec); break; case 'tuple': type.types.forEach(validateTypeRec); @@ -206,23 +194,16 @@ export function validateDefinitions(definitions: Definitions): void { break; case 'named': const name = type.name; - const definition: - | AliasDefinition - // $FlowFixMe(peterhal) - | InterfaceDefinition = namedTypes.get(name); - if (containingDefinitions.indexOf((definition: any)) !== -1) { - throw errorDefinitions( - (containingDefinitions.slice( - containingDefinitions.indexOf((definition: any)), - ): any), - `Type ${name} contains itself.`, - ); - } else if ( - definition.kind === 'alias' && - definition.definition != null - ) { + const definition = namedTypes.get(name); + if (containingDefinitions.indexOf(definition) !== -1) { + throw errorDefinitions(containingDefinitions.slice(containingDefinitions.indexOf(definition)), `Type ${name} contains itself.`); + } else if (definition.kind === 'alias' && definition.definition != null) { containingDefinitions.push(definition); - invariant(definition.definition); + + if (!definition.definition) { + throw new Error('Invariant violation: "definition.definition"'); + } + validateLayoutRec(containingDefinitions, definition.definition); containingDefinitions.pop(); } @@ -232,7 +213,7 @@ export function validateDefinitions(definitions: Definitions): void { } } - function validateReturnTypes(): void { + function validateReturnTypes() { Object.keys(definitions).forEach(defName => { const definition = definitions[defName]; switch (definition.kind) { @@ -264,7 +245,7 @@ export function validateDefinitions(definitions: Definitions): void { // Validates a type which must be a return type. // Caller must resolve named types. - function validateReturnType(funcType: FunctionType, type: Type): void { + function validateReturnType(funcType, type) { switch (type.kind) { case 'void': break; @@ -275,15 +256,12 @@ export function validateDefinitions(definitions: Definitions): void { } break; default: - throw error( - 'The return type of a remote function must be of type Void, Promise, or Observable' + - `(got ${type.kind})`, - ); + throw error('The return type of a remote function must be of type Void, Promise, or Observable' + `(got ${type.kind})`); } } // Aliases may be return types, or non-return types. - function validateAliasType(type: Type): void { + function validateAliasType(type) { switch (type.kind) { case 'void': break; @@ -302,7 +280,7 @@ export function validateDefinitions(definitions: Definitions): void { } } - function isLiteralType(type: Type): boolean { + function isLiteralType(type) { switch (type.kind) { case 'string-literal': case 'number-literal': @@ -313,23 +291,19 @@ export function validateDefinitions(definitions: Definitions): void { } } - function validateIntersectionType(intersectionType: IntersectionType): void { + function validateIntersectionType(intersectionType) { const fields = flattenIntersection(intersectionType); const fieldNames = new Set(); for (const field of fields) { if (fieldNames.has(field.name)) { // TODO allow duplicate field names if they have the same type. - throw error( - `Duplicate field name '${ - field.name - }' in intersection types are not supported.`, - ); + throw error(`Duplicate field name '${field.name}' in intersection types are not supported.`); } fieldNames.add(field.name); } } - function validateUnionType(type: UnionType): void { + function validateUnionType(type) { const alternates = flattenUnionAlternates(type.types); if (isLiteralType(alternates[0])) { @@ -337,44 +311,31 @@ export function validateDefinitions(definitions: Definitions): void { } else if (alternates[0].kind === 'object') { validateObjectUnionType(type, alternates); } else { - throw error( - 'Union alternates must be either be typed object or literal types. ' + - `(got ${alternates[0].kind})`, - ); + throw error('Union alternates must be either be typed object or literal types. ' + `(got ${alternates[0].kind})`); } } - function validateLiteralUnionType( - type: UnionType, - alternates: Array, - ): void { + function validateLiteralUnionType(type, alternates) { alternates.reduce((previousAlternates, alternate) => { validateType(alternate); // Ensure a valid alternate if (!isLiteralType(alternate)) { - throw error( - 'Union alternates may only be literal types. ' + - `(got ${alternate.kind})`, - ); + throw error('Union alternates may only be literal types. ' + `(got ${alternate.kind})`); } // Ensure no duplicates previousAlternates.forEach(previous => { - invariant( - previous.kind === 'string-literal' || - previous.kind === 'number-literal' || - previous.kind === 'boolean-literal', - ); - invariant( - alternate.kind === 'string-literal' || - alternate.kind === 'number-literal' || - alternate.kind === 'boolean-literal', - ); + if (!(previous.kind === 'string-literal' || previous.kind === 'number-literal' || previous.kind === 'boolean-literal')) { + throw new Error('Invariant violation: "previous.kind === \'string-literal\' ||\\n previous.kind === \'number-literal\' ||\\n previous.kind === \'boolean-literal\'"'); + } + + if (!(alternate.kind === 'string-literal' || alternate.kind === 'number-literal' || alternate.kind === 'boolean-literal')) { + throw new Error('Invariant violation: "alternate.kind === \'string-literal\' ||\\n alternate.kind === \'number-literal\' ||\\n alternate.kind === \'boolean-literal\'"'); + } + if (previous.value === alternate.value) { - throw error( - `Union alternates may not have the same value (${previous.kind}).`, - ); + throw error(`Union alternates may not have the same value (${previous.kind}).`); } }); @@ -383,59 +344,41 @@ export function validateDefinitions(definitions: Definitions): void { }, []); } - function validateObjectUnionType( - type: UnionType, - alternates: Array, - ): void { + function validateObjectUnionType(type, alternates) { alternates.forEach(alternate => { validateType(alternate); // Ensure alternates match if (alternate.kind !== 'object') { - throw error( - `Union alternates must be of the same type. (mismatch: ${ - alternate.kind - })`, - ); + throw error(`Union alternates must be of the same type. (mismatch: ${alternate.kind})`); } }); - type.discriminantField = findObjectUnionDiscriminant( - type, - (alternates: Array), - ); + type.discriminantField = findObjectUnionDiscriminant(type, alternates); } - function findObjectUnionDiscriminant( - type: UnionType, - alternates: Array, - ): string { + function findObjectUnionDiscriminant(type, alternates) { // Get set of fields which are literal types in al alternates. - invariant(alternates.length > 0); + if (!(alternates.length > 0)) { + throw new Error('Invariant violation: "alternates.length > 0"'); + } // $FlowFixMe - const possibleFields: Set = alternates.reduce( - (possibilities: ?Set, alternate: ObjectType) => { - const alternatePossibilities = possibleDiscriminantFieldsOfUnionAlternate( - alternate, - ); - if (alternatePossibilities.size === 0) { - throw error( - 'Object union alternative has no possible discriminant fields.', - ); - } - // Use null to represent the set containing everything. - if (possibilities == null) { - return alternatePossibilities; - } else { - return setIntersect(alternatePossibilities, possibilities); - } - }, - null, - ); - const validFields = Array.from(possibleFields).filter(fieldName => - isValidDiscriminantField(alternates, fieldName), - ); + + const possibleFields = alternates.reduce((possibilities, alternate) => { + const alternatePossibilities = possibleDiscriminantFieldsOfUnionAlternate(alternate); + if (alternatePossibilities.size === 0) { + throw error('Object union alternative has no possible discriminant fields.'); + } + // Use null to represent the set containing everything. + if (possibilities == null) { + return alternatePossibilities; + } else { + return (0, (_collection || _load_collection()).setIntersect)(alternatePossibilities, possibilities); + } + }, null); + + const validFields = Array.from(possibleFields).filter(fieldName => isValidDiscriminantField(alternates, fieldName)); if (validFields.length > 0) { // If there are multiple valid discriminant fields, we just pick the first. return validFields[0]; @@ -445,16 +388,9 @@ export function validateDefinitions(definitions: Definitions): void { } } - function isValidDiscriminantField( - alternates: Array, - candidateField: string, - ): boolean { + function isValidDiscriminantField(alternates, candidateField) { // $FlowFixMe - const fieldTypes: Array = alternates.map(alternate => - resolvePossiblyNamedType( - getObjectFieldByName(alternate, candidateField).type, - ), - ); + const fieldTypes = alternates.map(alternate => resolvePossiblyNamedType(getObjectFieldByName(alternate, candidateField).type)); // Fields in all alternates must have same type. if (!fieldTypes.every(fieldType => fieldType.kind === fieldTypes[0].kind)) { @@ -463,33 +399,25 @@ export function validateDefinitions(definitions: Definitions): void { // Must not have duplicate values in any alternate. // All alternates must be unique. - return ( - new Set(fieldTypes.map(fieldType => fieldType.value)).size === - alternates.length - ); + return new Set(fieldTypes.map(fieldType => fieldType.value)).size === alternates.length; } - function getObjectFieldByName( - type: ObjectType, - fieldName: string, - ): ObjectField { + function getObjectFieldByName(type, fieldName) { const result = type.fields.find(field => field.name === fieldName); - invariant(result != null); + + if (!(result != null)) { + throw new Error('Invariant violation: "result != null"'); + } + return result; } - function possibleDiscriminantFieldsOfUnionAlternate( - alternate: ObjectType, - ): Set { - return new Set( - alternate.fields - .filter(field => isLiteralType(resolvePossiblyNamedType(field.type))) - .map(field => field.name), - ); + function possibleDiscriminantFieldsOfUnionAlternate(alternate) { + return new Set(alternate.fields.filter(field => isLiteralType(resolvePossiblyNamedType(field.type))).map(field => field.name)); } // Validates a type which is not directly a return type. - function validateType(type: Type): void { + function validateType(type) { switch (type.kind) { case 'any': case 'mixed': @@ -503,9 +431,7 @@ export function validateDefinitions(definitions: Definitions): void { break; case 'promise': case 'observable': - throw error( - 'Promise and Observable types may only be used as return types', - ); + throw error('Promise and Observable types may only be used as return types'); case 'array': validateType(type.type); break; @@ -545,9 +471,7 @@ export function validateDefinitions(definitions: Definitions): void { case 'void': case 'promise': case 'observable': - throw error( - 'Promise, void and Observable types may only be used as return types', - ); + throw error('Promise, void and Observable types may only be used as return types'); } break; default: @@ -558,15 +482,15 @@ export function validateDefinitions(definitions: Definitions): void { // Replaces all uses of type aliases in return types with their definition // so that clients need not be aware of aliases. // TODO: Should replace all aliases, however that will require rewriting marsalling. - function cannonicalize(): void { + function cannonicalize() { visitAllTypes(cannonicalizeType); } - function cannonicalizeTypeArray(types: Array): void { + function cannonicalizeTypeArray(types) { types.forEach(cannonicalizeType); } - function cannonicalizeType(type: Type): void { + function cannonicalizeType(type) { switch (type.kind) { case 'any': case 'mixed': @@ -628,17 +552,15 @@ export function validateDefinitions(definitions: Definitions): void { } } - function canonicalizeIntersection(intersectionType: IntersectionType): void { + function canonicalizeIntersection(intersectionType) { const fields = flattenIntersection(intersectionType); intersectionType.flattened = { kind: 'object', - fields, + fields }; } - function flattenIntersection( - intersectionType: IntersectionType, - ): Array { + function flattenIntersection(intersectionType) { const fields = []; for (const type of intersectionType.types) { const resolvedType = resolvePossiblyNamedType(type); @@ -647,17 +569,14 @@ export function validateDefinitions(definitions: Definitions): void { } else if (resolvedType.kind === 'intersection') { fields.push(...flattenIntersection(resolvedType)); } else { - throw error( - 'Types in intersections must be object or intersection types ' + - `(got ${resolvedType.kind})`, - ); + throw error('Types in intersections must be object or intersection types ' + `(got ${resolvedType.kind})`); } } return fields; } // Will return a named type if and only if the alias resolves to a builtin type, or an interface. - function resolvePossiblyNamedType(type: Type): Type { + function resolvePossiblyNamedType(type) { if (type.kind === 'named') { return resolveNamedType(type); } else { @@ -665,23 +584,23 @@ export function validateDefinitions(definitions: Definitions): void { } } - function flattenUnionAlternates(types: Array): Array { - return [].concat( - ...types.map(alternate => { - const resolvedAlternate = resolvePossiblyNamedType(alternate); - return resolvedAlternate.kind === 'union' - ? flattenUnionAlternates(resolvedAlternate.types) - : resolvedAlternate; - }), - ); + function flattenUnionAlternates(types) { + return [].concat(...types.map(alternate => { + const resolvedAlternate = resolvePossiblyNamedType(alternate); + return resolvedAlternate.kind === 'union' ? flattenUnionAlternates(resolvedAlternate.types) : resolvedAlternate; + })); } // Returns the definition of a named type. If the type resolves to an alias it returns the // alias's definition. // Will return a named type if and only if the alias resolves to a builtin type, or an interface. - function resolveNamedType(namedType: NamedType): Type { + function resolveNamedType(namedType) { const def = namedTypes.get(namedType.name); - invariant(def != null); + + if (!(def != null)) { + throw new Error('Invariant violation: "def != null"'); + } + switch (def.kind) { case 'alias': const type = def.definition; @@ -699,7 +618,7 @@ export function validateDefinitions(definitions: Definitions): void { } } - function visitAllTypes(operation: (type: Type) => void): void { + function visitAllTypes(operation) { Object.keys(definitions).forEach(name => { const definition = definitions[name]; switch (definition.kind) { @@ -729,33 +648,23 @@ export function validateDefinitions(definitions: Definitions): void { }); } - function error(message: string) { - invariant(contextLocation != null, 'Missing context'); + function error(message) { + if (!(contextLocation != null)) { + throw new Error('Missing context'); + } + return errorLocations([contextLocation], message); } - function errorLocations(locations: Array, message: string): Error { - let fullMessage = `${locationToString(locations[0])}:${message}`; - fullMessage = fullMessage.concat( - ...locations - .slice(1) - .map(location => `\n${locationToString(location)}: Related location`), - ); + function errorLocations(locations, message) { + let fullMessage = `${(0, (_location || _load_location()).locationToString)(locations[0])}:${message}`; + fullMessage = fullMessage.concat(...locations.slice(1).map(location => `\n${(0, (_location || _load_location()).locationToString)(location)}: Related location`)); return new Error(fullMessage); } - function errorDefinitions(defs: Array, message: string): Error { - let fullMessage = `${locationToString(defs[0].location)}:${message}`; - fullMessage = fullMessage.concat( - ...defs - .slice(1) - .map( - definition => - `\n${locationToString(definition.location)}: Related definition ${ - definition.name - }`, - ), - ); + function errorDefinitions(defs, message) { + let fullMessage = `${(0, (_location || _load_location()).locationToString)(defs[0].location)}:${message}`; + fullMessage = fullMessage.concat(...defs.slice(1).map(definition => `\n${(0, (_location || _load_location()).locationToString)(definition.location)}: Related definition ${definition.name}`)); return new Error(fullMessage); } -} +} \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/LoopbackTransports.js b/pkg/nuclide-rpc/lib/LoopbackTransports.js index 14cfe98f9a..1648b6f8a7 100644 --- a/pkg/nuclide-rpc/lib/LoopbackTransports.js +++ b/pkg/nuclide-rpc/lib/LoopbackTransports.js @@ -1,56 +1,58 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import type {Transport} from '../lib/index'; -import type {Observable} from 'rxjs'; -import {Subject} from 'rxjs'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LoopbackTransports = undefined; -export class LoopbackTransports { - serverTransport: Transport; - clientTransport: Transport; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +class LoopbackTransports { constructor() { - const serverMessages: Subject = new Subject(); - const clientMessages: Subject = new Subject(); + const serverMessages = new _rxjsBundlesRxMinJs.Subject(); + const clientMessages = new _rxjsBundlesRxMinJs.Subject(); this.serverTransport = { _isClosed: false, - send(message: string): void { + send(message) { clientMessages.next(message); }, - onMessage(): Observable { + onMessage() { return serverMessages; }, close() { this._isClosed = true; }, - isClosed(): boolean { + isClosed() { return this._isClosed; - }, + } }; this.clientTransport = { _isClosed: false, - send(message: string): void { + send(message) { serverMessages.next(message); }, - onMessage(): Observable { + onMessage() { return clientMessages; }, close() { this._isClosed = true; }, - isClosed(): boolean { + isClosed() { return this._isClosed; - }, + } }; } } +exports.LoopbackTransports = LoopbackTransports; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/ObjectRegistry.js b/pkg/nuclide-rpc/lib/ObjectRegistry.js index 1abab0ab4b..ce37437d6d 100644 --- a/pkg/nuclide-rpc/lib/ObjectRegistry.js +++ b/pkg/nuclide-rpc/lib/ObjectRegistry.js @@ -1,3 +1,26 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ObjectRegistry = undefined; + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _eventKit; + +function _load_eventKit() { + return _eventKit = require('event-kit'); +} + +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-rpc'); + +// All remotable objects have some set of named functions, +// and they also have a dispose method. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,60 +28,20 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import invariant from 'assert'; -import {getLogger} from 'log4js'; -import {Emitter} from 'event-kit'; -import type {ServiceRegistry} from './ServiceRegistry'; -import type {RpcContext} from './main'; - -const logger = getLogger('nuclide-rpc'); - -type ObjectRegistration = { - interface: string, - remoteId: number, - object: RemoteObject, -}; - -// All remotable objects have some set of named functions, -// and they also have a dispose method. -export type RemoteObject = { - [id: string]: Function, - dispose: () => void, -}; - -type RegistryKind = 'server' | 'client'; - // Handles lifetimes of marshalling wrappers remote objects. // // Object passed by reference over RPC are assigned an ID. // Positive IDs represent objects which live on the server, // negative IDs represent objects which live on the client. -export class ObjectRegistry { - // These members handle local objects which have been marshalled remotely. - _registrationsById: Map; - _registrationsByObject: Map; - _nextObjectId: number; - _subscriptions: Map; - _delta: number; - // These members handle remote objects. - _proxiesById: Map; - // null means the proxy has been disposed. - _idsByProxy: Map; +class ObjectRegistry { // Maps service name to proxy - _serviceRegistry: ServiceRegistry; - _services: Map; - _context: RpcContext; - _emitter: Emitter; - - constructor( - kind: RegistryKind, - serviceRegistry: ServiceRegistry, - context: RpcContext, - ) { + + // These members handle remote objects. + constructor(kind, serviceRegistry, context) { this._delta = kind === 'server' ? 1 : -1; this._nextObjectId = this._delta; this._registrationsById = new Map(); @@ -69,81 +52,88 @@ export class ObjectRegistry { this._serviceRegistry = serviceRegistry; this._services = new Map(); this._context = context; - this._emitter = new Emitter(); + this._emitter = new (_eventKit || _load_eventKit()).Emitter(); } + // null means the proxy has been disposed. + + // These members handle local objects which have been marshalled remotely. + - onRegisterLocal(callback: number => void): IDisposable { + onRegisterLocal(callback) { return this._emitter.on('register-local', callback); } - onUnregisterLocal(callback: number => void): IDisposable { + onUnregisterLocal(callback) { return this._emitter.on('unregister-local', callback); } - onRegisterRemote(callback: number => void): IDisposable { + onRegisterRemote(callback) { return this._emitter.on('register-remote', callback); } - getService(serviceName: string): Object { + getService(serviceName) { let service = this._services.get(serviceName); if (service == null) { - service = this._serviceRegistry - .getService(serviceName) - .factory(this._context); + service = this._serviceRegistry.getService(serviceName).factory(this._context); this._services.set(serviceName, service); } return service; } - unmarshal( - id: number, - interfaceName?: string, - proxyClass?: Function, - ): RemoteObject { + unmarshal(id, interfaceName, proxyClass) { if (this._isLocalId(id)) { return this._unmarshalLocalObject(id); } else { - invariant(proxyClass != null); - invariant(interfaceName != null); + if (!(proxyClass != null)) { + throw new Error('Invariant violation: "proxyClass != null"'); + } + + if (!(interfaceName != null)) { + throw new Error('Invariant violation: "interfaceName != null"'); + } + return this._unmarshalRemoteObject(id, interfaceName, proxyClass); } } - _unmarshalLocalObject(id: number): RemoteObject { + _unmarshalLocalObject(id) { return this._getRegistration(id).object; } - _unmarshalRemoteObject( - remoteId: number, - interfaceName: string, - proxyClass: Function, - ): RemoteObject { + _unmarshalRemoteObject(remoteId, interfaceName, proxyClass) { const existingProxy = this._proxiesById.get(remoteId); if (existingProxy != null) { return existingProxy.object; } - invariant(proxyClass != null); + + if (!(proxyClass != null)) { + throw new Error('Invariant violation: "proxyClass != null"'); + } // Generate the proxy by manually setting the prototype of the proxy to be the // prototype of the remote proxy constructor. + + const newProxy = Object.create(proxyClass.prototype); this._addProxy(newProxy, interfaceName, remoteId); return newProxy; } - _getRegistration(id: number): ObjectRegistration { - const result = this._isLocalId(id) - ? this._registrationsById.get(id) - : this._proxiesById.get(id); - invariant(result != null, `Unknown registration ${id}`); + _getRegistration(id) { + const result = this._isLocalId(id) ? this._registrationsById.get(id) : this._proxiesById.get(id); + + if (!(result != null)) { + throw new Error(`Unknown registration ${id}`); + } + return result; } - getInterface(id: number): string { + getInterface(id) { return this._getRegistration(id).interface; } - async disposeObject(remoteId: number): Promise { + async disposeObject(remoteId) { this._emitter.emit('unregister-local', remoteId); const registration = this._getRegistration(remoteId); const object = registration.object; @@ -155,7 +145,7 @@ export class ObjectRegistry { await object.dispose(); } - disposeSubscription(id: number): void { + disposeSubscription(id) { const subscription = this.removeSubscription(id); if (subscription != null) { subscription.unsubscribe(); @@ -163,7 +153,7 @@ export class ObjectRegistry { } // Put the object in the registry. - marshal(interfaceName: string, object: Object): number { + marshal(interfaceName, object) { if (this._isRemoteObject(object)) { return this._marshalRemoteObject(object); } else { @@ -171,16 +161,23 @@ export class ObjectRegistry { } } - _marshalRemoteObject(proxy: Object): number { + _marshalRemoteObject(proxy) { const result = this._idsByProxy.get(proxy); - invariant(result != null); + + if (!(result != null)) { + throw new Error('Invariant violation: "result != null"'); + } + return result; } - _marshalLocalObject(interfaceName: string, object: Object): number { + _marshalLocalObject(interfaceName, object) { const existingRegistration = this._registrationsByObject.get(object); if (existingRegistration != null) { - invariant(existingRegistration.interface === interfaceName); + if (!(existingRegistration.interface === interfaceName)) { + throw new Error('Invariant violation: "existingRegistration.interface === interfaceName"'); + } + return existingRegistration.remoteId; } @@ -190,7 +187,7 @@ export class ObjectRegistry { const registration = { interface: interfaceName, remoteId: objectId, - object, + object }; this._emitter.emit('register-local', objectId); @@ -200,11 +197,11 @@ export class ObjectRegistry { return objectId; } - addSubscription(id: number, subscription: rxjs$ISubscription): void { + addSubscription(id, subscription) { this._subscriptions.set(id, subscription); } - removeSubscription(id: number): ?rxjs$ISubscription { + removeSubscription(id) { const subscription = this._subscriptions.get(id); if (subscription != null) { this._subscriptions.delete(id); @@ -213,19 +210,17 @@ export class ObjectRegistry { } // Disposes all object in the registry - async dispose(): Promise { + async dispose() { const ids = Array.from(this._registrationsById.keys()); logger.info(`Disposing ${ids.length} registrations`); - await Promise.all( - ids.map(async id => { - try { - await this.disposeObject(id); - } catch (e) { - logger.error('Error disposing marshalled object.', e); - } - }), - ); + await Promise.all(ids.map(async id => { + try { + await this.disposeObject(id); + } catch (e) { + logger.error('Error disposing marshalled object.', e); + } + })); const subscriptions = Array.from(this._subscriptions.keys()); logger.info(`Disposing ${subscriptions.length} subscriptions`); @@ -239,7 +234,7 @@ export class ObjectRegistry { } // Returns null if the object is already disposed. - disposeProxy(proxy: Object): ?number { + disposeProxy(proxy) { const objectId = this._idsByProxy.get(proxy); if (objectId != null) { this._idsByProxy.set(proxy, null); @@ -249,28 +244,35 @@ export class ObjectRegistry { } } - _addProxy(proxy: Object, interfaceName: string, id: number): void { - invariant(!this._idsByProxy.has(proxy)); + _addProxy(proxy, interfaceName, id) { + if (!!this._idsByProxy.has(proxy)) { + throw new Error('Invariant violation: "!this._idsByProxy.has(proxy)"'); + } + this._idsByProxy.set(proxy, id); - invariant(!this._proxiesById.has(id)); + if (!!this._proxiesById.has(id)) { + throw new Error('Invariant violation: "!this._proxiesById.has(id)"'); + } + this._emitter.emit('register-remote', id); this._proxiesById.set(id, { interface: interfaceName, remoteId: id, - object: proxy, + object: proxy }); } - isRegistered(object: Object): boolean { + isRegistered(object) { return this._registrationsByObject.has(object); } - _isRemoteObject(object: Object): boolean { + _isRemoteObject(object) { return this._idsByProxy.has(object); } - _isLocalId(id: number): boolean { + _isLocalId(id) { return id * this._delta > 0; } } +exports.ObjectRegistry = ObjectRegistry; \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/RpcConnection.js b/pkg/nuclide-rpc/lib/RpcConnection.js index d65bc7cd19..a8ff561797 100644 --- a/pkg/nuclide-rpc/lib/RpcConnection.js +++ b/pkg/nuclide-rpc/lib/RpcConnection.js @@ -1,81 +1,94 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RpcConnection = exports.RpcTimeoutError = undefined; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _ServiceRegistry; + +function _load_ServiceRegistry() { + return _ServiceRegistry = require('./ServiceRegistry'); +} + +var _ObjectRegistry; + +function _load_ObjectRegistry() { + return _ObjectRegistry = require('./ObjectRegistry'); +} + +var _messages; + +function _load_messages() { + return _messages = require('./messages'); +} + +var _builtinTypes; + +function _load_builtinTypes() { + return _builtinTypes = require('./builtin-types'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _config; + +function _load_config() { + return _config = require('./config'); +} + +var _string; -import type {ConfigEntry, Transport} from './index'; -import type {ReturnType, Type, Parameter} from './types'; -import type {TypeRegistry} from './TypeRegistry'; -import type { - ResponseMessage, - RequestMessage, - CallMessage, - CallObjectMessage, -} from './messages'; -import type {ClassDefinition, FunctionImplementation} from './ServiceRegistry'; -import type {PredefinedTransformer} from './index'; -import type {MemoryLogger} from '../../commons-node/memoryLogger'; - -import invariant from 'assert'; -import {Observable, ConnectableObservable} from 'rxjs'; -import {ServiceRegistry} from './ServiceRegistry'; -import {ObjectRegistry} from './ObjectRegistry'; -import { - createCallMessage, - createCallObjectMessage, - createDisposeMessage, - createUnsubscribeMessage, - createPromiseMessage, - createErrorResponseMessage, - createNextMessage, - createCompleteMessage, - createObserveErrorMessage, - decodeError, -} from './messages'; -import {voidType} from './builtin-types'; -import {track, trackTiming} from '../../nuclide-analytics'; -import {SERVICE_FRAMEWORK3_PROTOCOL} from './config'; -import {shorten} from 'nuclide-commons/string'; -import {getLogger} from 'log4js'; - -const logger = getLogger('nuclide-rpc'); +function _load_string() { + return _string = require('../../../modules/nuclide-commons/string'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-rpc'); /** + * 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. + * + * + * @format + */ const SERVICE_FRAMEWORK_RPC_TIMEOUT_MS = 60 * 1000; const LARGE_RESPONSE_SIZE = 100000; -type RpcConnectionKind = 'server' | 'client'; - class Subscription { - _message: RequestMessage; - _observer: rxjs$Observer; // Track the total number of received bytes to track large subscriptions. // Reset the count every minute so frequent offenders fire repeatedly. - _totalBytes: number; - _firstByteTime: number; - - constructor(message: RequestMessage, observer: rxjs$Observer) { + constructor(message, observer) { this._message = message; this._observer = observer; this._totalBytes = 0; this._firstByteTime = 0; } - error(error): void { + error(error) { try { - this._observer.error(decodeError(this._message, error)); + this._observer.error((0, (_messages || _load_messages()).decodeError)(this._message, error)); } catch (e) { logger.error(`Caught exception in Subscription.error: ${e.toString()}`); } } - next(data: any, bytes: number): void { + next(data, bytes) { try { this._observer.next(data); // TODO: consider implementing a rate limit @@ -85,17 +98,15 @@ class Subscription { } } - complete(): void { + complete() { try { this._observer.complete(); } catch (e) { - logger.error( - `Caught exception in Subscription.complete: ${e.toString()}`, - ); + logger.error(`Caught exception in Subscription.complete: ${e.toString()}`); } } - getBytes(): number { + getBytes() { if (Date.now() - this._firstByteTime > 60000) { this._totalBytes = 0; this._firstByteTime = Date.now(); @@ -105,26 +116,19 @@ class Subscription { } // Special marker error for RPC timeouts. -export class RpcTimeoutError extends Error { - name: string = 'RpcTimeoutError'; +class RpcTimeoutError extends Error { + constructor(...args) { + var _temp; + + return _temp = super(...args), this.name = 'RpcTimeoutError', _temp; + } + } +exports.RpcTimeoutError = RpcTimeoutError; class Call { - _message: RequestMessage; - _timeoutMessage: ?string; - _reject: (error: any) => void; - _resolve: (result: any) => void; - _cleanup: () => void; - _complete: boolean; - _timerId: ?TimeoutID; - - constructor( - message: RequestMessage, - timeoutMessage: ?string, - resolve: (result: any) => void, - reject: (error: any) => void, - cleanup: () => void, - ) { + + constructor(message, timeoutMessage, resolve, reject, cleanup) { this._message = message; this._timeoutMessage = timeoutMessage; this._resolve = resolve; @@ -138,21 +142,21 @@ class Call { } } - reject(error): void { + reject(error) { if (!this._complete) { this.cleanup(); - this._reject(decodeError(this._message, error)); + this._reject((0, (_messages || _load_messages()).decodeError)(this._message, error)); } } - resolve(result): void { + resolve(result) { if (!this._complete) { this.cleanup(); this._resolve(result); } } - cleanup(): void { + cleanup() { if (!this._complete) { this._complete = true; // $FlowFixMe @@ -162,67 +166,34 @@ class Call { } } - _timeout(): void { + _timeout() { const timeoutMessage = this._timeoutMessage; - invariant(timeoutMessage != null); + + if (!(timeoutMessage != null)) { + throw new Error('Invariant violation: "timeoutMessage != null"'); + } + if (!this._complete) { this.cleanup(); - this._reject( - new RpcTimeoutError( - `Timeout after ${SERVICE_FRAMEWORK_RPC_TIMEOUT_MS} for id: ` + - `${ - this._message.id - }, ${timeoutMessage}. Nuclide was trying to call ` + - 'to the remote Nuclide server. This usually means the server was ' + - 'not reachable, or the network connection is unreliable.', - ), - ); + this._reject(new RpcTimeoutError(`Timeout after ${SERVICE_FRAMEWORK_RPC_TIMEOUT_MS} for id: ` + `${this._message.id}, ${timeoutMessage}. Nuclide was trying to call ` + 'to the remote Nuclide server. This usually means the server was ' + 'not reachable, or the network connection is unreliable.')); } } } -export type RpcConnectionOptions = { - // Enables timing tracking for function/method calls (with the given sample rate). - // Must be a positive integer; e.g. trackSampling = 10 means a 1/10 sample rate. - trackSampleRate?: number, -}; - -export class RpcConnection { - _connectionId: string; - _kind: RpcConnectionKind; - _rpcRequestId: number; - _rpcResponseId: number; - _transport: TransportType; - _serviceRegistry: ServiceRegistry; - _objectRegistry: ObjectRegistry; - _subscriptions: Map; - _calls: Map; - _options: RpcConnectionOptions; - - // Used to track if the IDs are incrementing atomically - _lastRequestId: number; - _lastResponseId: number; +class RpcConnection { // Do not call this directly, use factory methods below. - constructor( - kind: RpcConnectionKind, - serviceRegistry: ServiceRegistry, - transport: TransportType, - options: RpcConnectionOptions = {}, - connectionId: ?string = null, - protocolLogger: ?MemoryLogger = null, - ) { + + + // Used to track if the IDs are incrementing atomically + constructor(kind, serviceRegistry, transport, options = {}, connectionId = null, protocolLogger = null) { this._kind = kind; this._transport = transport; this._options = options; this._rpcRequestId = 1; this._rpcResponseId = 1; this._serviceRegistry = serviceRegistry; - this._objectRegistry = new ObjectRegistry( - kind, - this._serviceRegistry, - this, - ); + this._objectRegistry = new (_ObjectRegistry || _load_ObjectRegistry()).ObjectRegistry(kind, this._serviceRegistry, this); this._transport.onMessage().subscribe(message => { this._handleMessage(message); }); @@ -233,114 +204,63 @@ export class RpcConnection { if (protocolLogger != null) { const prefix = connectionId == null ? '' : `${connectionId} `; - this._objectRegistry.onRegisterLocal(id => - protocolLogger.info('%sadding local object %s', prefix, id), - ); - this._objectRegistry.onUnregisterLocal(id => - protocolLogger.info('%sremoving local object %s', prefix, id), - ); - this._objectRegistry.onRegisterRemote(id => - protocolLogger.info('%sadding remote object %s', prefix, id), - ); + this._objectRegistry.onRegisterLocal(id => protocolLogger.info('%sadding local object %s', prefix, id)); + this._objectRegistry.onUnregisterLocal(id => protocolLogger.info('%sremoving local object %s', prefix, id)); + this._objectRegistry.onRegisterRemote(id => protocolLogger.info('%sadding remote object %s', prefix, id)); } } // Creates a connection on the server side. - static createServer( - serviceRegistry: ServiceRegistry, - transport: TransportType, - options: RpcConnectionOptions = {}, - connectionId: ?string = null, - protocolLogger: ?MemoryLogger = null, - ): RpcConnection { - return new RpcConnection( - 'server', - serviceRegistry, - transport, - options, - connectionId, - protocolLogger, - ); + static createServer(serviceRegistry, transport, options = {}, connectionId = null, protocolLogger = null) { + return new RpcConnection('server', serviceRegistry, transport, options, connectionId, protocolLogger); } // Creates a client side connection to a server on another machine. - static createRemote( - transport: TransportType, - predefinedTypes: Array, - services: Array, - options: RpcConnectionOptions = {}, - protocol: string = SERVICE_FRAMEWORK3_PROTOCOL, - connectionId: ?string = null, - protocolLogger: ?MemoryLogger = null, - ): RpcConnection { - return new RpcConnection( - 'client', - new ServiceRegistry(predefinedTypes, services, protocol, {lazy: true}), - transport, - options, - connectionId, - protocolLogger, - ); + static createRemote(transport, predefinedTypes, services, options = {}, protocol = (_config || _load_config()).SERVICE_FRAMEWORK3_PROTOCOL, connectionId = null, protocolLogger = null) { + return new RpcConnection('client', new (_ServiceRegistry || _load_ServiceRegistry()).ServiceRegistry(predefinedTypes, services, protocol, { lazy: true }), transport, options, connectionId, protocolLogger); } // Creates a client side connection to a server on the same machine. - static createLocal( - transport: TransportType, - predefinedTypes: Array, - services: Array, - protocol: string = SERVICE_FRAMEWORK3_PROTOCOL, - connectionId: ?string = null, - protocolLogger: ?MemoryLogger = null, - ): RpcConnection { - return new RpcConnection( - 'client', - // We can afford to be lazy when creating the RPC client. - // Client code always explicitly loads services by name! - new ServiceRegistry(predefinedTypes, services, protocol, {lazy: true}), - transport, - {}, - connectionId, - protocolLogger, - ); - } - - getService(serviceName: string): Object { + static createLocal(transport, predefinedTypes, services, protocol = (_config || _load_config()).SERVICE_FRAMEWORK3_PROTOCOL, connectionId = null, protocolLogger = null) { + return new RpcConnection('client', + // We can afford to be lazy when creating the RPC client. + // Client code always explicitly loads services by name! + new (_ServiceRegistry || _load_ServiceRegistry()).ServiceRegistry(predefinedTypes, services, protocol, { lazy: true }), transport, {}, connectionId, protocolLogger); + } + + getService(serviceName) { const service = this._objectRegistry.getService(serviceName); - invariant(service != null, `No config found for service ${serviceName}`); + + if (!(service != null)) { + throw new Error(`No config found for service ${serviceName}`); + } + return service; } - addServices(services: Array): void { + addServices(services) { services.forEach(this.addService, this); } - addService(service: ConfigEntry): void { + addService(service) { this._serviceRegistry.addService(service); } // Delegate marshalling to the type registry. - marshal(value: any, type: Type): any { + marshal(value, type) { return this._getTypeRegistry().marshal(this._objectRegistry, value, type); } - unmarshal(value: any, type: Type): any { + unmarshal(value, type) { return this._getTypeRegistry().unmarshal(this._objectRegistry, value, type); } - marshalArguments(args: Array, argTypes: Array): Object { - return this._getTypeRegistry().marshalArguments( - this._objectRegistry, - args, - argTypes, - ); + marshalArguments(args, argTypes) { + return this._getTypeRegistry().marshalArguments(this._objectRegistry, args, argTypes); } - unmarshalArguments(args: Object, argTypes: Array): Array { - return this._getTypeRegistry().unmarshalArguments( - this._objectRegistry, - args, - argTypes, - ); + unmarshalArguments(args, argTypes) { + return this._getTypeRegistry().unmarshalArguments(this._objectRegistry, args, argTypes); } /** @@ -350,21 +270,8 @@ export class RpcConnection { * layer can register the appropriate listeners. * @param args - The serialized arguments to invoke the remote function with. */ - callRemoteFunction( - functionName: string, - returnType: ReturnType, - args: Object, - ): any { - return this._sendMessageAndListenForResult( - createCallMessage( - this._getProtocol(), - functionName, - this._generateRequestId(), - args, - ), - returnType, - `Calling function ${functionName}`, - ); + callRemoteFunction(functionName, returnType, args) { + return this._sendMessageAndListenForResult((0, (_messages || _load_messages()).createCallMessage)(this._getProtocol(), functionName, this._generateRequestId(), args), returnType, `Calling function ${functionName}`); } /** @@ -375,23 +282,8 @@ export class RpcConnection { * layer can register the appropriate listeners. * @param args - The serialized arguments to invoke the remote method with. */ - callRemoteMethod( - objectId: number, - methodName: string, - returnType: ReturnType, - args: Object, - ): any { - return this._sendMessageAndListenForResult( - createCallObjectMessage( - this._getProtocol(), - methodName, - objectId, - this._generateRequestId(), - args, - ), - returnType, - `Calling remote method ${methodName}`, - ); + callRemoteMethod(objectId, methodName, returnType, args) { + return this._sendMessageAndListenForResult((0, (_messages || _load_messages()).createCallObjectMessage)(this._getProtocol(), methodName, objectId, this._generateRequestId(), args), returnType, `Calling remote method ${methodName}`); } /** @@ -400,22 +292,14 @@ export class RpcConnection { * @param object - The remote object. * @returns A Promise that resolves when the object disposal has completed. */ - async disposeRemoteObject(object: Object): Promise { + async disposeRemoteObject(object) { const objectId = this._objectRegistry.disposeProxy(object); if (objectId == null) { logger.info('Duplicate dispose call on remote proxy'); } else if (this._transport.isClosed()) { logger.info('Dispose call on remote proxy after connection closed'); } else { - return this._sendMessageAndListenForResult( - createDisposeMessage( - this._getProtocol(), - this._generateRequestId(), - objectId, - ), - 'promise', - `Disposing object ${objectId}`, - ); + return this._sendMessageAndListenForResult((0, (_messages || _load_messages()).createDisposeMessage)(this._getProtocol(), this._generateRequestId(), objectId), 'promise', `Disposing object ${objectId}`); } } @@ -427,11 +311,7 @@ export class RpcConnection { * @returns Depending on the expected return type, this function either returns undefined, a * Promise, or an Observable. */ - _sendMessageAndListenForResult( - message: RequestMessage, - returnType: ReturnType, - timeoutMessage: string, - ): any { + _sendMessageAndListenForResult(message, returnType, timeoutMessage) { switch (returnType) { case 'void': this._transport.send(JSON.stringify(message)); @@ -442,183 +322,114 @@ export class RpcConnection { // just queue up the message on the reliable transport; timeout errors // are solely intended to help clients behave nicer. const promise = new Promise((resolve, reject) => { - this._calls.set( - message.id, - new Call( - message, - this._kind === 'server' ? null : timeoutMessage, - resolve, - reject, - () => { - this._calls.delete(message.id); - }, - ), - ); + this._calls.set(message.id, new Call(message, this._kind === 'server' ? null : timeoutMessage, resolve, reject, () => { + this._calls.delete(message.id); + })); this._transport.send(JSON.stringify(message)); }); - const {trackSampleRate} = this._options; + const { trackSampleRate } = this._options; // flowlint-next-line sketchy-null-number:off if (trackSampleRate && Math.random() * trackSampleRate <= 1) { - return trackTiming( - trackingIdOfMessageAndNetwork(this._objectRegistry, message), - () => promise, - ); + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(trackingIdOfMessageAndNetwork(this._objectRegistry, message), () => promise); } return promise; - case 'observable': { - const id = message.id; - invariant(!this._subscriptions.has(id)); + case 'observable': + { + const id = message.id; - const sendSubscribe = () => { - this._transport.send(JSON.stringify(message)); - }; - const sendUnsubscribe = () => { - if (!this._transport.isClosed()) { - this._transport.send( - JSON.stringify(createUnsubscribeMessage(this._getProtocol(), id)), - ); + if (!!this._subscriptions.has(id)) { + throw new Error('Invariant violation: "!this._subscriptions.has(id)"'); } - }; - let hadSubscription = false; - const observable = Observable.create(observer => { - // Only allow a single subscription. This will be the common case, - // and adding this restriction allows disposing of the observable - // on the remote side after the initial subscription is complete. - if (hadSubscription) { - throw new Error('Attempt to re-connect with a remote Observable.'); - } - hadSubscription = true; - - const subscription = new Subscription(message, observer); - this._subscriptions.set(id, subscription); - sendSubscribe(); - - // Observable dispose function, which is called on subscription dispose, on stream - // completion, and on stream error. - return { - unsubscribe: () => { - if (!this._subscriptions.has(id)) { - // guard against multiple unsubscribe calls - return; - } - this._subscriptions.delete(id); - sendUnsubscribe(); - }, + const sendSubscribe = () => { + this._transport.send(JSON.stringify(message)); }; - }); + const sendUnsubscribe = () => { + if (!this._transport.isClosed()) { + this._transport.send(JSON.stringify((0, (_messages || _load_messages()).createUnsubscribeMessage)(this._getProtocol(), id))); + } + }; + let hadSubscription = false; + const observable = _rxjsBundlesRxMinJs.Observable.create(observer => { + // Only allow a single subscription. This will be the common case, + // and adding this restriction allows disposing of the observable + // on the remote side after the initial subscription is complete. + if (hadSubscription) { + throw new Error('Attempt to re-connect with a remote Observable.'); + } + hadSubscription = true; + + const subscription = new Subscription(message, observer); + this._subscriptions.set(id, subscription); + sendSubscribe(); + + // Observable dispose function, which is called on subscription dispose, on stream + // completion, and on stream error. + return { + unsubscribe: () => { + if (!this._subscriptions.has(id)) { + // guard against multiple unsubscribe calls + return; + } + this._subscriptions.delete(id); + + sendUnsubscribe(); + } + }; + }); - // Conversion to ConnectableObservable happens in the generated - // proxies. - return observable; - } + // Conversion to ConnectableObservable happens in the generated + // proxies. + return observable; + } default: throw new Error(`Unknown return type: ${returnType}.`); } } - _returnPromise(id: number, candidate: any, type: Type): void { + _returnPromise(id, candidate, type) { let returnVal = candidate; // Ensure that the return value is a promise. if (!isThenable(returnVal)) { - returnVal = Promise.reject( - new Error( - 'Expected a Promise, but the function returned something else.', - ), - ); + returnVal = Promise.reject(new Error('Expected a Promise, but the function returned something else.')); } // Send the result of the promise across the socket. - returnVal.then( - result => { - this._transport.send( - JSON.stringify( - createPromiseMessage( - this._getProtocol(), - id, - this._generateResponseId(), - this.marshal(result, type), - ), - ), - ); - }, - error => { - this._transport.send( - JSON.stringify( - createErrorResponseMessage( - this._getProtocol(), - id, - this._generateResponseId(), - error, - ), - ), - ); - }, - ); - } - - _returnObservable(id: number, returnVal: any, elementType: Type): void { - let result: ConnectableObservable; + returnVal.then(result => { + this._transport.send(JSON.stringify((0, (_messages || _load_messages()).createPromiseMessage)(this._getProtocol(), id, this._generateResponseId(), this.marshal(result, type)))); + }, error => { + this._transport.send(JSON.stringify((0, (_messages || _load_messages()).createErrorResponseMessage)(this._getProtocol(), id, this._generateResponseId(), error))); + }); + } + + _returnObservable(id, returnVal, elementType) { + let result; // Ensure that the return value is an observable. if (!isConnectableObservable(returnVal)) { - result = Observable.throw( - new Error( - 'Expected an Observable, but the function returned something else.', - ), - ).publish(); + result = _rxjsBundlesRxMinJs.Observable.throw(new Error('Expected an Observable, but the function returned something else.')).publish(); } else { result = returnVal; } result - // Marshal in a map() so that errors are caught below. - .map(data => this.marshal(data, elementType)) - // Send the next, error, and completion events of the observable across the socket. - .subscribe( - data => { - this._transport.send( - JSON.stringify( - createNextMessage( - this._getProtocol(), - id, - this._generateResponseId(), - data, - ), - ), - ); - }, - error => { - this._transport.send( - JSON.stringify( - createObserveErrorMessage( - this._getProtocol(), - id, - this._generateResponseId(), - error, - ), - ), - ); - this._objectRegistry.removeSubscription(id); - }, - completed => { - this._transport.send( - JSON.stringify( - createCompleteMessage( - this._getProtocol(), - id, - this._generateResponseId(), - ), - ), - ); - this._objectRegistry.removeSubscription(id); - }, - ); + // Marshal in a map() so that errors are caught below. + .map(data => this.marshal(data, elementType)) + // Send the next, error, and completion events of the observable across the socket. + .subscribe(data => { + this._transport.send(JSON.stringify((0, (_messages || _load_messages()).createNextMessage)(this._getProtocol(), id, this._generateResponseId(), data))); + }, error => { + this._transport.send(JSON.stringify((0, (_messages || _load_messages()).createObserveErrorMessage)(this._getProtocol(), id, this._generateResponseId(), error))); + this._objectRegistry.removeSubscription(id); + }, completed => { + this._transport.send(JSON.stringify((0, (_messages || _load_messages()).createCompleteMessage)(this._getProtocol(), id, this._generateResponseId()))); + this._objectRegistry.removeSubscription(id); + }); this._objectRegistry.addSubscription(id, result.connect()); } // Returns true if a promise was returned. - _returnValue(id: number, value: any, type: Type): void { + _returnValue(id, value, type) { switch (type.kind) { case 'void': break; // No need to send anything back to the user. @@ -633,47 +444,34 @@ export class RpcConnection { } } - _callFunction(id: number, call: CallMessage): void { - const {getLocalImplementation, type} = this._getFunctionImplemention( - call.method, - ); - const marshalledArgs = this.unmarshalArguments( - call.args, - type.argumentTypes, - ); + _callFunction(id, call) { + const { getLocalImplementation, type } = this._getFunctionImplemention(call.method); + const marshalledArgs = this.unmarshalArguments(call.args, type.argumentTypes); const localImplementation = getLocalImplementation(); - this._returnValue( - id, - localImplementation.apply(this, marshalledArgs), - type.returnType, - ); + this._returnValue(id, localImplementation.apply(this, marshalledArgs), type.returnType); } - _callMethod(id: number, call: CallObjectMessage): void { + _callMethod(id, call) { const object = this._objectRegistry.unmarshal(call.objectId); - invariant(object != null); + + if (!(object != null)) { + throw new Error('Invariant violation: "object != null"'); + } const interfaceName = this._objectRegistry.getInterface(call.objectId); - const {definition} = this._getClassDefinition(interfaceName); + const { definition } = this._getClassDefinition(interfaceName); const type = definition.instanceMethods[call.method]; - const marshalledArgs = this.unmarshalArguments( - call.args, - type.argumentTypes, - ); + const marshalledArgs = this.unmarshalArguments(call.args, type.argumentTypes); - this._returnValue( - id, - object[call.method](...marshalledArgs), - type.returnType, - ); + this._returnValue(id, object[call.method](...marshalledArgs), type.returnType); } - getTransport(): TransportType { + getTransport() { return this._transport; } - _parseMessage(value: string): ?Object { + _parseMessage(value) { try { const result = JSON.parse(value); if (result == null) { @@ -692,14 +490,12 @@ export class RpcConnection { } } - _getProtocol(): string { + _getProtocol() { return this._serviceRegistry.getProtocol(); } - _handleMessage(value: string): void { - const message: ?(RequestMessage | ResponseMessage) = this._parseMessage( - value, - ); + _handleMessage(value) { + const message = this._parseMessage(value); if (message == null) { return; } @@ -724,95 +520,89 @@ export class RpcConnection { } // Handles the response and returns the originating request message (if possible). - _handleResponseMessage(message: ResponseMessage, rawMessage: string): void { + _handleResponseMessage(message, rawMessage) { const id = message.id; // Keep track of the request message for logging let requestMessage = null; // Here's the main message handler ... switch (message.type) { - case 'response': { - const call = this._calls.get(id); - if (call != null) { - const {result} = message; - call.resolve(result); - requestMessage = call._message; - if (rawMessage.length >= LARGE_RESPONSE_SIZE) { - this._trackLargeResponse(call._message, rawMessage.length); + case 'response': + { + const call = this._calls.get(id); + if (call != null) { + const { result } = message; + call.resolve(result); + requestMessage = call._message; + if (rawMessage.length >= LARGE_RESPONSE_SIZE) { + this._trackLargeResponse(call._message, rawMessage.length); + } } + break; } - break; - } - case 'error-response': { - const call = this._calls.get(id); - if (call != null) { - const {error} = message; - call.reject(error); - requestMessage = call._message; + case 'error-response': + { + const call = this._calls.get(id); + if (call != null) { + const { error } = message; + call.reject(error); + requestMessage = call._message; + } + break; } - break; - } - case 'next': { - const subscription = this._subscriptions.get(id); - if (subscription != null) { - const {value} = message; - const prevBytes = subscription.getBytes(); - subscription.next(value, rawMessage.length); - requestMessage = subscription._message; - if (prevBytes < LARGE_RESPONSE_SIZE) { - const bytes = subscription.getBytes(); - if (bytes >= LARGE_RESPONSE_SIZE) { - this._trackLargeResponse(subscription._message, bytes); + case 'next': + { + const subscription = this._subscriptions.get(id); + if (subscription != null) { + const { value } = message; + const prevBytes = subscription.getBytes(); + subscription.next(value, rawMessage.length); + requestMessage = subscription._message; + if (prevBytes < LARGE_RESPONSE_SIZE) { + const bytes = subscription.getBytes(); + if (bytes >= LARGE_RESPONSE_SIZE) { + this._trackLargeResponse(subscription._message, bytes); + } } } + break; } - break; - } - case 'complete': { - const subscription = this._subscriptions.get(id); - if (subscription != null) { - subscription.complete(); - this._subscriptions.delete(id); - requestMessage = subscription._message; + case 'complete': + { + const subscription = this._subscriptions.get(id); + if (subscription != null) { + subscription.complete(); + this._subscriptions.delete(id); + requestMessage = subscription._message; + } + break; } - break; - } - case 'error': { - const subscription = this._subscriptions.get(id); - if (subscription != null) { - const {error} = message; - subscription.error(error); - this._subscriptions.delete(id); - requestMessage = subscription._message; + case 'error': + { + const subscription = this._subscriptions.get(id); + if (subscription != null) { + const { error } = message; + subscription.error(error); + this._subscriptions.delete(id); + requestMessage = subscription._message; + } + break; } - break; - } default: throw new Error(`Unexpected message type ${JSON.stringify(message)}`); } // end main handler const responseId = message.responseId; - if ( - responseId !== this._lastResponseId + 1 && - this._lastResponseId !== -1 && - requestMessage != null && - this._options.trackSampleRate != null - ) { - const eventName = trackingIdOfMessage( - this._objectRegistry, - requestMessage, - ); - - logger.warn( - `Out-of-order response received, responseId === ${responseId},` + - `_lastResponseId === ${this._lastResponseId}`, - ); - - track('response-message-id-mismatch', { + if (responseId !== this._lastResponseId + 1 && this._lastResponseId !== -1 && requestMessage != null && this._options.trackSampleRate != null) { + const eventName = trackingIdOfMessage(this._objectRegistry, requestMessage); + + logger.warn(`Out-of-order response received, responseId === ${responseId},` + `_lastResponseId === ${this._lastResponseId}`); + + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('response-message-id-mismatch', { eventName, responseId, - lastResponseId: this._lastResponseId, + lastResponseId: this._lastResponseId }); } @@ -821,28 +611,22 @@ export class RpcConnection { } } - _handleRequestMessage(message: RequestMessage): void { + _handleRequestMessage(message) { const id = message.id; - if ( - id !== this._lastRequestId + 1 && - this._lastRequestId !== -1 && - // We're excluding Unsubscribe messages since they reuse the IDs from - // their corresponding Subscribe messages, and will trigger - // false positive warnings. - message.type !== 'unsubscribe' - ) { + if (id !== this._lastRequestId + 1 && this._lastRequestId !== -1 && + // We're excluding Unsubscribe messages since they reuse the IDs from + // their corresponding Subscribe messages, and will trigger + // false positive warnings. + message.type !== 'unsubscribe') { const eventName = trackingIdOfMessage(this._objectRegistry, message); - logger.warn( - `Out-of-order message received, id === ${id},` + - `_lastRequestId === ${this._lastRequestId}`, - ); + logger.warn(`Out-of-order message received, id === ${id},` + `_lastRequestId === ${this._lastRequestId}`); - track('message-id-mismatch', { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('message-id-mismatch', { eventName, id, - lastRequestId: this._lastRequestId, + lastRequestId: this._lastRequestId }); } @@ -860,11 +644,7 @@ export class RpcConnection { this._callMethod(id, message); break; case 'dispose': - this._returnPromise( - id, - this._objectRegistry.disposeObject(message.objectId), - voidType, - ); + this._returnPromise(id, this._objectRegistry.disposeObject(message.objectId), (_builtinTypes || _load_builtinTypes()).voidType); break; case 'unsubscribe': this._objectRegistry.disposeSubscription(id); @@ -874,58 +654,46 @@ export class RpcConnection { } } catch (e) { logger.error(`Error handling RPC ${message.type} message`, e); - this._transport.send( - JSON.stringify( - createErrorResponseMessage( - this._getProtocol(), - id, - this._generateResponseId(), - e, - ), - ), - ); + this._transport.send(JSON.stringify((0, (_messages || _load_messages()).createErrorResponseMessage)(this._getProtocol(), id, this._generateResponseId(), e))); } } - _getFunctionImplemention(name: string): FunctionImplementation { + _getFunctionImplemention(name) { return this._serviceRegistry.getFunctionImplemention(name); } - _getClassDefinition(className: string): ClassDefinition { + _getClassDefinition(className) { return this._serviceRegistry.getClassDefinition(className); } - _generateRequestId(): number { + _generateRequestId() { return this._rpcRequestId++; } - _generateResponseId(): number { + _generateResponseId() { return this._rpcResponseId++; } - _getTypeRegistry(): TypeRegistry { + _getTypeRegistry() { return this._serviceRegistry.getTypeRegistry(); } - _trackLargeResponse(message: RequestMessage, size: number) { + _trackLargeResponse(message, size) { // flowlint-next-line sketchy-null-number:off if (!this._options.trackSampleRate) { return; } const eventName = trackingIdOfMessage(this._objectRegistry, message); - const args = - message.args != null - ? shorten(JSON.stringify(message.args), 100, '...') - : ''; + const args = message.args != null ? (0, (_string || _load_string()).shorten)(JSON.stringify(message.args), 100, '...') : ''; logger.warn(`${eventName}: Large response of size ${size}. Args:`, args); - track('large-rpc-response', { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('large-rpc-response', { eventName, size, - args, + args }); } - dispose(): void { + dispose() { this._transport.close(); this._objectRegistry.dispose(); this._calls.forEach(call => { @@ -938,10 +706,8 @@ export class RpcConnection { } } -function trackingIdOfMessage( - registry: ObjectRegistry, - message: RequestMessage, -): string { +exports.RpcConnection = RpcConnection; +function trackingIdOfMessage(registry, message) { switch (message.type) { case 'call': return `service-framework:${message.method}`; @@ -958,25 +724,20 @@ function trackingIdOfMessage( } } -function trackingIdOfMessageAndNetwork( - registry: ObjectRegistry, - message: RequestMessage, -): string { +function trackingIdOfMessageAndNetwork(registry, message) { return trackingIdOfMessage(registry, message) + ':plus-network'; } /** * A helper function that checks if an object is thenable (Promise-like). */ -function isThenable(object: any): boolean { +function isThenable(object) { return Boolean(object && object.then); } /** * A helper function that checks if an object is an Observable. */ -function isConnectableObservable(object: any): boolean { - return Boolean( - object && object.concatMap && object.subscribe && object.connect, - ); -} +function isConnectableObservable(object) { + return Boolean(object && object.concatMap && object.subscribe && object.connect); +} \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/RpcProcess.js b/pkg/nuclide-rpc/lib/RpcProcess.js index 94cd9e4c99..f7e8a8b614 100644 --- a/pkg/nuclide-rpc/lib/RpcProcess.js +++ b/pkg/nuclide-rpc/lib/RpcProcess.js @@ -1,3 +1,36 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RpcProcess = undefined; + +var _StreamTransport; + +function _load_StreamTransport() { + return _StreamTransport = require('./StreamTransport'); +} + +var _RpcConnection; + +function _load_RpcConnection() { + return _RpcConnection = require('./RpcConnection'); +} + +var _process; + +function _load_process() { + return _process = require('../../../modules/nuclide-commons/process'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,22 +38,11 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {Subscription, Observable} from 'rxjs'; -import type {ServiceRegistry, MessageLogger} from '..'; -import type {ProcessMessage, ProcessExitMessage} from 'nuclide-commons/process'; - -import {StreamTransport} from './StreamTransport'; -import {RpcConnection} from './RpcConnection'; -import {exitEventToMessage, getOutputStream} from 'nuclide-commons/process'; -import {getLogger} from 'log4js'; -import invariant from 'assert'; -import {Subject} from 'rxjs'; - -const logger = getLogger('nuclide-rpc'); +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-rpc'); /** * A generic process wrapper around a stdio-based child process, providing a simple @@ -35,31 +57,16 @@ const logger = getLogger('nuclide-rpc'); * - Note that stdin, stdout, and stderr must be piped, done by node by default. * Don't override the stdio to close off any of these streams in the constructor opts. */ -export class RpcProcess { - _processStream: Observable; - _messageLogger: MessageLogger; - _name: string; - _disposed: boolean; - _process: ?child_process$ChildProcess; - _subscription: ?Subscription; - _serviceRegistry: ServiceRegistry; - _rpcConnection: ?Promise>; - _disposals: Subject; - _exitMessage: Subject; +class RpcProcess { /** * @param name a name for this server, used to tag log entries * @param processStream a (cold) Observable that creates processes upon subscription, * both during initialization and on restart (see spawn) */ - constructor( - name: string, - serviceRegistry: ServiceRegistry, - processStream: Observable, - messageLogger: MessageLogger = (direction, message) => { - return; - }, - ) { + constructor(name, serviceRegistry, processStream, messageLogger = (direction, message) => { + return; + }) { this._processStream = processStream; this._messageLogger = messageLogger; this._name = name; @@ -68,19 +75,19 @@ export class RpcProcess { this._subscription = null; this._serviceRegistry = serviceRegistry; this._rpcConnection = null; - this._disposals = new Subject(); - this._exitMessage = new Subject(); + this._disposals = new _rxjsBundlesRxMinJs.Subject(); + this._exitMessage = new _rxjsBundlesRxMinJs.Subject(); } - getName(): string { + getName() { return this._name; } - isDisposed(): boolean { + isDisposed() { return this._disposed; } - async getService(serviceName: string): Promise { + async getService(serviceName) { const connection = this._ensureConnection(); return (await connection).getService(serviceName); } @@ -89,7 +96,7 @@ export class RpcProcess { * Emits the exit message of the currently running process, or null on error. * Completes when the process finishes. */ - observeExitMessage(): Observable { + observeExitMessage() { return this._exitMessage.takeUntil(this._disposals); } @@ -97,53 +104,36 @@ export class RpcProcess { * Ensures that the child process is available. Asynchronously creates the child process, * only if it is currently null. */ - _ensureConnection(): Promise> { + _ensureConnection() { this._disposed = false; if (this._rpcConnection == null) { - const processStream = this._processStream - .do({ - error: e => { - logger.error(`${this._name} - error spawning child process: `, e); - this._exitMessage.next(null); - this.dispose(); - }, - }) - .takeUntil(this._disposals) - .publish(); - - processStream - .switchMap(proc => - getOutputStream(proc, { - /* TODO(T17353599) */ isExitError: () => false, - }), - ) - // switchMap won't stop until the mapped observable stops. - // Manual disposals shouldn't trigger the exit message. - .takeUntil(this._disposals) - .subscribe(this._onProcessMessage.bind(this)); - - const connection = (this._rpcConnection = processStream - .take(1) - .toPromise() - .then(proc => { - if (proc == null) { - throw new Error('RpcProcess disposed during getService'); - } - this._process = proc; - logger.info( - `${this._name} - created child process with PID: `, - proc.pid, - ); - - proc.stdin.on('error', error => { - logger.error(`${this._name} - error writing data: `, error); - }); - return new RpcConnection( - 'client', - this._serviceRegistry, - new StreamTransport(proc.stdin, proc.stdout, this._messageLogger), - ); - })); + const processStream = this._processStream.do({ + error: e => { + logger.error(`${this._name} - error spawning child process: `, e); + this._exitMessage.next(null); + this.dispose(); + } + }).takeUntil(this._disposals).publish(); + + processStream.switchMap(proc => (0, (_process || _load_process()).getOutputStream)(proc, { + /* TODO(T17353599) */isExitError: () => false + })) + // switchMap won't stop until the mapped observable stops. + // Manual disposals shouldn't trigger the exit message. + .takeUntil(this._disposals).subscribe(this._onProcessMessage.bind(this)); + + const connection = this._rpcConnection = processStream.take(1).toPromise().then(proc => { + if (proc == null) { + throw new Error('RpcProcess disposed during getService'); + } + this._process = proc; + logger.info(`${this._name} - created child process with PID: `, proc.pid); + + proc.stdin.on('error', error => { + logger.error(`${this._name} - error writing data: `, error); + }); + return new (_RpcConnection || _load_RpcConnection()).RpcConnection('client', this._serviceRegistry, new (_StreamTransport || _load_StreamTransport()).StreamTransport(proc.stdin, proc.stdout, this._messageLogger)); + }); this._subscription = processStream.connect(); return connection; @@ -155,29 +145,24 @@ export class RpcProcess { * Handles lifecycle messages from stderr, exit, and error streams, * responding by logging and staging for process restart. */ - _onProcessMessage(message: ProcessMessage): void { + _onProcessMessage(message) { switch (message.kind) { case 'stdout': break; case 'stderr': - logger.warn( - `${this._name} - error from stderr received: `, - message.data.toString(), - ); + logger.warn(`${this._name} - error from stderr received: `, message.data.toString()); break; case 'exit': - logger.error( - `${this._name} - exited with ${exitEventToMessage(message)}`, - ); + logger.error(`${this._name} - exited with ${(0, (_process || _load_process()).exitEventToMessage)(message)}`); this._exitMessage.next(message); this.dispose(); break; default: // This case should never be reached. - invariant( - false, - `${this._name} - unknown message received: ${message}`, - ); + if (!false) { + throw new Error(`${this._name} - unknown message received: ${message}`); + } + } } @@ -185,7 +170,7 @@ export class RpcProcess { * Cleans up in case of disposal or failure, clearing all pending calls, * and killing the child process if necessary. */ - dispose(): void { + dispose() { if (this._disposed) { return; } @@ -196,9 +181,7 @@ export class RpcProcess { if (this._rpcConnection != null) { // If this wasn't already resolved, then it's rejected via `this._disposals`. - this._rpcConnection - .then(connection => connection.dispose()) - .catch(() => {}); + this._rpcConnection.then(connection => connection.dispose()).catch(() => {}); this._rpcConnection = null; } @@ -210,3 +193,4 @@ export class RpcProcess { } } } +exports.RpcProcess = RpcProcess; \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/ServiceRegistry.js b/pkg/nuclide-rpc/lib/ServiceRegistry.js index f53ced8ab9..bcdb924d38 100644 --- a/pkg/nuclide-rpc/lib/ServiceRegistry.js +++ b/pkg/nuclide-rpc/lib/ServiceRegistry.js @@ -1,164 +1,108 @@ -/** - * 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 - */ - -import type {PredefinedTransformer} from './index'; - -import {createProxyFactory} from './main'; -import {TypeRegistry} from './TypeRegistry'; -import type {FunctionType, Definitions, InterfaceDefinition} from './types'; -import type {ProxyFactory} from './main'; -import invariant from 'assert'; -import type {ConfigEntry} from './index'; -import type {ObjectRegistry} from './ObjectRegistry'; -import {getLogger} from 'log4js'; -import {SERVICE_FRAMEWORK3_PROTOCOL} from './config'; - -const logger = getLogger('nuclide-rpc'); - -export type FunctionImplementation = { - getLocalImplementation: Function, - type: FunctionType, -}; -export type ClassDefinition = { - getLocalImplementation: any, - definition: InterfaceDefinition, -}; -export type ServiceDefinition = { - name: string, - factory: ProxyFactory, // Maps from RpcContext to proxy -}; - -type ServiceRegistryOptions = { - // Lazily load services. - lazy?: boolean, -}; - -export class ServiceRegistry { - _protocol: string; - - _typeRegistry: TypeRegistry; +'use strict'; - /** - * Store a mapping from function name to a structure holding both the local implementation and - * the type definition of the function. - */ - _functionsByName: Map; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ServiceRegistry = undefined; + +var _main; + +function _load_main() { + return _main = require('./main'); +} + +var _TypeRegistry; + +function _load_TypeRegistry() { + return _TypeRegistry = require('./TypeRegistry'); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _config; + +function _load_config() { + return _config = require('./config'); +} + +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-rpc'); /** + * 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. + * + * + * @format + */ + +class ServiceRegistry { /** * Store a mapping from a class name to a struct containing it's local constructor and it's * interface definition. */ - _classesByName: Map; - - _predefinedTypes: Array; - _services: Map; - // Cache the configs for lazy loading. - _serviceConfigs: Map; - - constructor( - predefinedTypes: Array, - services: Array, - protocol: string = SERVICE_FRAMEWORK3_PROTOCOL, - options: ServiceRegistryOptions = {}, - ) { + constructor(predefinedTypes, services, protocol = (_config || _load_config()).SERVICE_FRAMEWORK3_PROTOCOL, options = {}) { this._protocol = protocol; - this._typeRegistry = new TypeRegistry(predefinedTypes); - this._predefinedTypes = predefinedTypes.map( - predefinedType => predefinedType.typeName, - ); + this._typeRegistry = new (_TypeRegistry || _load_TypeRegistry()).TypeRegistry(predefinedTypes); + this._predefinedTypes = predefinedTypes.map(predefinedType => predefinedType.typeName); this._functionsByName = new Map(); this._classesByName = new Map(); this._services = new Map(); - this._serviceConfigs = new Map( - services.map(service => [service.name, service]), - ); + this._serviceConfigs = new Map(services.map(service => [service.name, service])); if (options.lazy !== true) { services.map(service => this.addService(service)); } } + // Cache the configs for lazy loading. + + + /** + * Store a mapping from function name to a structure holding both the local implementation and + * the type definition of the function. + */ - getProtocol(): string { + + getProtocol() { return this._protocol; } - addService(service: ConfigEntry): ServiceDefinition { - const preserveFunctionNames = - service.preserveFunctionNames != null && service.preserveFunctionNames; + addService(service) { + const preserveFunctionNames = service.preserveFunctionNames != null && service.preserveFunctionNames; try { - const factory = createProxyFactory( - service.name, - preserveFunctionNames, - service.definition, - this._predefinedTypes, - ); - const serviceDefinition = {name: service.name, factory}; + const factory = (0, (_main || _load_main()).createProxyFactory)(service.name, preserveFunctionNames, service.definition, this._predefinedTypes); + const serviceDefinition = { name: service.name, factory }; this._services.set(service.name, serviceDefinition); // Register type aliases. - const defs: Definitions = factory.defs; + const defs = factory.defs; Object.keys(defs).forEach(defName => { const definition = defs[defName]; const name = definition.name; switch (definition.kind) { case 'alias': if (definition.definition != null) { - this._typeRegistry.registerAlias( - name, - definition.location, - definition.definition, - ); + this._typeRegistry.registerAlias(name, definition.location, definition.definition); } break; case 'function': // Register module-level functions. - const functionName = service.preserveFunctionNames - ? name - : `${service.name}/${name}`; - this._registerFunction( - functionName, - service.implementation, - impl => impl[name], - definition.type, - ); + const functionName = service.preserveFunctionNames ? name : `${service.name}/${name}`; + this._registerFunction(functionName, service.implementation, impl => impl[name], definition.type); break; case 'interface': // Register interfaces. - this._registerClass( - name, - service.implementation, - impl => impl[name], - definition, - ); - this._typeRegistry.registerType( - name, - definition.location, - (object, context: ObjectRegistry) => - context.marshal(name, object), - (objectId, context: ObjectRegistry) => - context.unmarshal( - objectId, - name, - context.getService(service.name)[name], - ), - ); + this._registerClass(name, service.implementation, impl => impl[name], definition); + this._typeRegistry.registerType(name, definition.location, (object, context) => context.marshal(name, object), (objectId, context) => context.unmarshal(objectId, name, context.getService(service.name)[name])); // Register all of the static methods as remote functions. Object.keys(definition.staticMethods).forEach(methodName => { - this._registerFunction( - `${name}/${methodName}`, - service.implementation, - impl => impl[name][methodName], - definition.staticMethods[methodName], - ); + this._registerFunction(`${name}/${methodName}`, service.implementation, impl => impl[name][methodName], definition.staticMethods[methodName]); }); break; } @@ -166,19 +110,12 @@ export class ServiceRegistry { return serviceDefinition; } catch (e) { - logger.error( - `Failed to load service ${service.name}. Stack Trace:\n${e.stack}`, - ); + logger.error(`Failed to load service ${service.name}. Stack Trace:\n${e.stack}`); throw e; } } - _registerFunction( - name: string, - id: string, - accessor: Function, - type: FunctionType, - ): void { + _registerFunction(name, id, accessor, type) { if (this._functionsByName.has(name)) { throw new Error(`Duplicate RPC function: ${name}`); } @@ -191,16 +128,11 @@ export class ServiceRegistry { } return impl; }, - type, + type }); } - _registerClass( - name: string, - id: string, - accessor: Function, - definition: InterfaceDefinition, - ): void { + _registerClass(name, id, accessor, definition) { let impl; this._classesByName.set(name, { getLocalImplementation() { @@ -210,33 +142,46 @@ export class ServiceRegistry { } return impl; }, - definition, + definition }); } - getFunctionImplemention(name: string): FunctionImplementation { + getFunctionImplemention(name) { const result = this._functionsByName.get(name); - invariant(result); + + if (!result) { + throw new Error('Invariant violation: "result"'); + } + return result; } - getClassDefinition(className: string): ClassDefinition { + getClassDefinition(className) { const result = this._classesByName.get(className); - invariant(result != null); + + if (!(result != null)) { + throw new Error('Invariant violation: "result != null"'); + } + return result; } - getTypeRegistry(): TypeRegistry { + getTypeRegistry() { return this._typeRegistry; } - getService(serviceName: string): ServiceDefinition { + getService(serviceName) { let result = this._services.get(serviceName); if (result == null) { const config = this._serviceConfigs.get(serviceName); - invariant(config != null, `Service ${serviceName} does not exist`); + + if (!(config != null)) { + throw new Error(`Service ${serviceName} does not exist`); + } + result = this.addService(config); } return result; } } +exports.ServiceRegistry = ServiceRegistry; \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/SocketServer.js b/pkg/nuclide-rpc/lib/SocketServer.js index a8d0d93d8e..abc0d8659e 100644 --- a/pkg/nuclide-rpc/lib/SocketServer.js +++ b/pkg/nuclide-rpc/lib/SocketServer.js @@ -1,38 +1,54 @@ -/** - * 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 strict-local - * @format - */ - -import type {Server, Socket} from 'net'; - -import net from 'net'; -import {Deferred} from 'nuclide-commons/promise'; -import {RpcConnection} from './RpcConnection'; -import {SocketTransport} from './SocketTransport'; -import {ServiceRegistry} from './ServiceRegistry'; -import {Emitter} from 'event-kit'; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SocketServer = undefined; + +var _net = _interopRequireDefault(require('net')); + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +var _RpcConnection; + +function _load_RpcConnection() { + return _RpcConnection = require('./RpcConnection'); +} + +var _SocketTransport; + +function _load_SocketTransport() { + return _SocketTransport = require('./SocketTransport'); +} + +var _ServiceRegistry; + +function _load_ServiceRegistry() { + return _ServiceRegistry = require('./ServiceRegistry'); +} + +var _eventKit; + +function _load_eventKit() { + return _eventKit = require('event-kit'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // An RPC server which listens for connections on a localhost socket. // TODO: Consider extending with more socket listening options. -export class SocketServer { - _serviceRegistry: ServiceRegistry; - _server: Server; - _listening: Deferred; - _connections: Set>; - _emitter: Emitter; - - constructor(serviceRegistry: ServiceRegistry) { - this._emitter = new Emitter(); +class SocketServer { + + constructor(serviceRegistry) { + this._emitter = new (_eventKit || _load_eventKit()).Emitter(); this._connections = new Set(); this._serviceRegistry = serviceRegistry; - this._listening = new Deferred(); - this._server = net.createServer(); + this._listening = new (_promise || _load_promise()).Deferred(); + this._server = _net.default.createServer(); this._server.on('connection', socket => { this._onConnection(socket); }); @@ -44,39 +60,36 @@ export class SocketServer { }); } - _onConnection(socket: Socket): void { - const transport = new SocketTransport(socket); - const connection = RpcConnection.createServer( - this._serviceRegistry, - transport, - // Track calls with a sampling rate of 1/10. - {trackSampleRate: 10}, - ); + _onConnection(socket) { + const transport = new (_SocketTransport || _load_SocketTransport()).SocketTransport(socket); + const connection = (_RpcConnection || _load_RpcConnection()).RpcConnection.createServer(this._serviceRegistry, transport, + // Track calls with a sampling rate of 1/10. + { trackSampleRate: 10 }); transport.onClose(() => { this._connections.delete(connection); }); this._connections.add(connection); } - _onError(error: Error): void { + _onError(error) { this._emitter.emit('error', error); } - onError(callback: (error: Error) => mixed): IDisposable { + onError(callback) { return this._emitter.on('error', callback); } - untilListening(): Promise { + untilListening() { return this._listening.promise; } - async getAddress(): Promise { + async getAddress() { await this.untilListening(); return this._server.address(); } // Close all open connections and shutdown the server. - dispose(): void { + dispose() { for (const connection of this._connections) { connection.getTransport().close(); } @@ -86,3 +99,13 @@ export class SocketServer { this._emitter.dispose(); } } +exports.SocketServer = SocketServer; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/SocketTransport.js b/pkg/nuclide-rpc/lib/SocketTransport.js index 5274616bba..5dce00fec8 100644 --- a/pkg/nuclide-rpc/lib/SocketTransport.js +++ b/pkg/nuclide-rpc/lib/SocketTransport.js @@ -1,35 +1,36 @@ -/** - * 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 strict-local - * @format - */ - -import type {Socket} from 'net'; -import type {MessageLogger} from './index'; - -import {StreamTransport} from './StreamTransport'; -import {Emitter} from 'event-kit'; -import {Deferred} from 'nuclide-commons/promise'; - -export class SocketTransport extends StreamTransport { - _socket: Socket; - _emitter: Emitter; - _onConnect: Deferred; - - constructor( - socket: Socket, - messageLogger: MessageLogger = (direction, message) => { - return; - }, - ) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SocketTransport = undefined; + +var _StreamTransport; + +function _load_StreamTransport() { + return _StreamTransport = require('./StreamTransport'); +} + +var _eventKit; + +function _load_eventKit() { + return _eventKit = require('event-kit'); +} + +var _promise; + +function _load_promise() { + return _promise = require('../../../modules/nuclide-commons/promise'); +} + +class SocketTransport extends (_StreamTransport || _load_StreamTransport()).StreamTransport { + + constructor(socket, messageLogger = (direction, message) => { + return; + }) { super(socket, socket, messageLogger); this._socket = socket; - this._emitter = new Emitter(); + this._emitter = new (_eventKit || _load_eventKit()).Emitter(); socket.on('close', () => { if (!this.isClosed()) { @@ -38,22 +39,22 @@ export class SocketTransport extends StreamTransport { this._emitter.emit('close'); }); - const connectionDeferred = new Deferred(); + const connectionDeferred = new (_promise || _load_promise()).Deferred(); socket.on('connect', connectionDeferred.resolve); socket.on('error', error => connectionDeferred.reject(error)); this._onConnect = connectionDeferred; } // Returns a promise which resolves on connection or rejects if connection fails. - onConnected(): Promise { + onConnected() { return this._onConnect.promise; } - onClose(callback: () => mixed): IDisposable { + onClose(callback) { return this._emitter.on('close', callback); } - close(): void { + close() { super.close(); // Send the FIN packet ... @@ -64,3 +65,13 @@ export class SocketTransport extends StreamTransport { this._emitter.dispose(); } } +exports.SocketTransport = SocketTransport; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/StreamTransport.js b/pkg/nuclide-rpc/lib/StreamTransport.js index dd3119f6f2..43a2d9196b 100644 --- a/pkg/nuclide-rpc/lib/StreamTransport.js +++ b/pkg/nuclide-rpc/lib/StreamTransport.js @@ -1,59 +1,64 @@ -/** - * 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 strict-local - * @format - */ - -import type {Observable} from 'rxjs'; -import {splitStream} from 'nuclide-commons/observable'; -import {observeStream} from 'nuclide-commons/stream'; -import invariant from 'assert'; -import type {MessageLogger} from './index'; - -export class StreamTransport { - _output: stream$Writable; - _messages: Observable; - _messageLogger: MessageLogger; - _isClosed: boolean; - - constructor( - output: stream$Writable, - input: stream$Readable, - messageLogger: MessageLogger = (direction, message) => { - return; - }, - ) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.StreamTransport = undefined; + +var _observable; + +function _load_observable() { + return _observable = require('../../../modules/nuclide-commons/observable'); +} + +var _stream; + +function _load_stream() { + return _stream = require('../../../modules/nuclide-commons/stream'); +} + +class StreamTransport { + + constructor(output, input, messageLogger = (direction, message) => { + return; + }) { this._isClosed = false; this._messageLogger = messageLogger; this._output = output; - this._messages = splitStream(observeStream(input), false).do(message => { + this._messages = (0, (_observable || _load_observable()).splitStream)((0, (_stream || _load_stream()).observeStream)(input), false).do(message => { this._messageLogger('receive', message); }); } - send(message: string): void { + send(message) { this._messageLogger('send', message); - invariant( - message.indexOf('\n') === -1, - 'StreamTransport.send - unexpected newline in JSON message', - ); + + if (!(message.indexOf('\n') === -1)) { + throw new Error('StreamTransport.send - unexpected newline in JSON message'); + } + this._output.write(message + '\n'); } - onMessage(): Observable { + onMessage() { return this._messages; } - close(): void { + close() { this._isClosed = true; } - isClosed(): boolean { + isClosed() { return this._isClosed; } } +exports.StreamTransport = StreamTransport; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/TypeRegistry.js b/pkg/nuclide-rpc/lib/TypeRegistry.js index 14db085dbb..ff0c525c50 100644 --- a/pkg/nuclide-rpc/lib/TypeRegistry.js +++ b/pkg/nuclide-rpc/lib/TypeRegistry.js @@ -1,3 +1,35 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.TypeRegistry = undefined; + +var _assert = _interopRequireDefault(require('assert')); + +var _fs = _interopRequireDefault(require('fs')); + +var _builtinTypes; + +function _load_builtinTypes() { + return _builtinTypes = require('./builtin-types'); +} + +var _location; + +function _load_location() { + return _location = require('./location'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/* + * This type represents a Transformer function, which takes in a value, and either serializes + * or deserializes it. Transformer's are added to a registry and indexed by the name of + * the type they handle (eg: 'Date'). The second argument is the actual type object that represent + * the value. Parameterized types like Array, or Object can use this to recursively call other + * transformers. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,57 +37,15 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import assert from 'assert'; -import invariant from 'assert'; -import fs from 'fs'; - -import type { - Type, - ObjectType, - ObjectField, - UnionType, - Location, - Parameter, -} from './types'; -import { - builtinLocation, - objectType, - dateType, - regExpType, - bufferType, - fsStatsType, -} from './builtin-types'; -import type {ObjectRegistry} from './ObjectRegistry'; -import {locationsEqual, locationToString} from './location'; -import type {NamedTransformer, PredefinedTransformer} from './index'; - -/* - * This type represents a Transformer function, which takes in a value, and either serializes - * or deserializes it. Transformer's are added to a registry and indexed by the name of - * the type they handle (eg: 'Date'). The second argument is the actual type object that represent - * the value. Parameterized types like Array, or Object can use this to recursively call other - * transformers. - */ -export type Transformer = ( - value: any, - type: Type, - context: ObjectRegistry, -) => any; - -function canBeUndefined(type: Type): boolean { - return ( - type.kind === 'nullable' || - type.kind === 'mixed' || - type.kind === 'any' || - type.kind === 'void' - ); +function canBeUndefined(type) { + return type.kind === 'nullable' || type.kind === 'mixed' || type.kind === 'any' || type.kind === 'void'; } -function statsToObject(stats: fs.Stats): Object { +function statsToObject(stats) { const result = { dev: stats.dev, mode: stats.mode, @@ -69,18 +59,18 @@ function statsToObject(stats: fs.Stats): Object { blocks: stats.blocks, atime: stats.atime.toJSON(), mtime: stats.mtime.toJSON(), - ctime: stats.ctime.toJSON(), + ctime: stats.ctime.toJSON() }; if (stats.birthtime instanceof Date) { - return {...result, birthtime: stats.birthtime.toJSON()}; + return Object.assign({}, result, { birthtime: stats.birthtime.toJSON() }); } return result; } -function objectToStats(jsonStats: Object): fs.Stats { - const stats = new fs.Stats(); +function objectToStats(jsonStats) { + const stats = new _fs.default.Stats(); stats.dev = jsonStats.dev; stats.mode = jsonStats.mode; @@ -113,27 +103,9 @@ function objectToStats(jsonStats: Object): fs.Stats { * The ObjectRegistry is opaque to the TypeRegistry and allows for adding per-connection * context to marshalling transformations. */ -export class TypeRegistry { +class TypeRegistry { /** Store marshallers and and unmarshallers, index by the kind of the type. */ - _kindMarshallers: Map< - string, - { - marshaller: Transformer, - unmarshaller: Transformer, - }, - >; - - /** Store marshallers and and unmarshallers, index by the name of the type. */ - _namedMarshallers: Map< - string, - { - location: Location, - marshaller: NamedTransformer, - unmarshaller: NamedTransformer, - }, - >; - - constructor(predefinedTypes: Array) { + constructor(predefinedTypes) { this._kindMarshallers = new Map(); this._namedMarshallers = new Map(); @@ -145,77 +117,71 @@ export class TypeRegistry { this._registerIntersections(); // Register NullableType and NamedType - this._registerKind( - 'nullable', - (value: any, type: Type, context: ObjectRegistry) => { - invariant(type.kind === 'nullable'); - if (value == null) { - return value; - } - return this._marshal(context, value, type.type); - }, - (value: any, type: Type, context: ObjectRegistry) => { - invariant(type.kind === 'nullable'); - if (value == null) { - return value; - } - return this._unmarshal(context, value, type.type); - }, - ); - - this._registerKind( - 'named', - (value: any, type: Type, context: ObjectRegistry) => { - invariant(type.kind === 'named'); - const namedMarshaller = this._namedMarshallers.get(type.name); - if (namedMarshaller == null) { - throw new Error(`No marshaller found for named type ${type.name}.`); - } - return namedMarshaller.marshaller(value, context); - }, - (value: any, type: Type, context: ObjectRegistry) => { - invariant(type.kind === 'named'); - const namedMarshaller = this._namedMarshallers.get(type.name); - if (namedMarshaller == null) { - throw new Error(`No marshaller found for named type ${type.name}.`); - } - return namedMarshaller.unmarshaller(value, context); - }, - ); + this._registerKind('nullable', (value, type, context) => { + if (!(type.kind === 'nullable')) { + throw new Error('Invariant violation: "type.kind === \'nullable\'"'); + } - this._registerKind( - 'void', - (value, type, context) => undefined, - (value, type, context) => undefined, - ); + if (value == null) { + return value; + } + return this._marshal(context, value, type.type); + }, (value, type, context) => { + if (!(type.kind === 'nullable')) { + throw new Error('Invariant violation: "type.kind === \'nullable\'"'); + } + + if (value == null) { + return value; + } + return this._unmarshal(context, value, type.type); + }); + + this._registerKind('named', (value, type, context) => { + if (!(type.kind === 'named')) { + throw new Error('Invariant violation: "type.kind === \'named\'"'); + } + + const namedMarshaller = this._namedMarshallers.get(type.name); + if (namedMarshaller == null) { + throw new Error(`No marshaller found for named type ${type.name}.`); + } + return namedMarshaller.marshaller(value, context); + }, (value, type, context) => { + if (!(type.kind === 'named')) { + throw new Error('Invariant violation: "type.kind === \'named\'"'); + } + + const namedMarshaller = this._namedMarshallers.get(type.name); + if (namedMarshaller == null) { + throw new Error(`No marshaller found for named type ${type.name}.`); + } + return namedMarshaller.unmarshaller(value, context); + }); + + this._registerKind('void', (value, type, context) => undefined, (value, type, context) => undefined); predefinedTypes.forEach(type => { - this.registerPredefinedType( - type.typeName, - type.marshaller, - type.unmarshaller, - ); + this.registerPredefinedType(type.typeName, type.marshaller, type.unmarshaller); }); } - _registerKind( - kind: string, - marshaller: Transformer, - unmarshaller: Transformer, - ): void { - invariant(!this._kindMarshallers.has(kind)); + /** Store marshallers and and unmarshallers, index by the name of the type. */ + + + _registerKind(kind, marshaller, unmarshaller) { + if (!!this._kindMarshallers.has(kind)) { + throw new Error('Invariant violation: "!this._kindMarshallers.has(kind)"'); + } + this._kindMarshallers.set(kind, { marshaller: makeKindMarshaller(kind, marshaller), - unmarshaller: makeKindMarshaller(kind, unmarshaller), + unmarshaller: makeKindMarshaller(kind, unmarshaller) }); } - registerPredefinedType( - typeName: string, - marshaller: NamedTransformer, - unmarshaller: NamedTransformer, - ): void { - this.registerType(typeName, builtinLocation, marshaller, unmarshaller); + registerPredefinedType(typeName, marshaller, unmarshaller) { + this.registerType(typeName, (_builtinTypes || _load_builtinTypes()).builtinLocation, marshaller, unmarshaller); } /** @@ -226,30 +192,18 @@ export class TypeRegistry { * @param marshaller - Serialize the type. * @param unmarshaller - Deserialize the type. */ - registerType( - typeName: string, - location: Location, - marshaller: NamedTransformer, - unmarshaller: NamedTransformer, - ): void { + registerType(typeName, location, marshaller, unmarshaller) { const existingMarshaller = this._namedMarshallers.get(typeName); if (existingMarshaller != null) { // If the locations are equal then assume that the types are equal. - if (!locationsEqual(existingMarshaller.location, location)) { - throw new Error( - `${locationToString( - location, - )}: A type by the name ${typeName} has already` + - ` been registered at ${locationToString( - existingMarshaller.location, - )}.`, - ); + if (!(0, (_location || _load_location()).locationsEqual)(existingMarshaller.location, location)) { + throw new Error(`${(0, (_location || _load_location()).locationToString)(location)}: A type by the name ${typeName} has already` + ` been registered at ${(0, (_location || _load_location()).locationToString)(existingMarshaller.location)}.`); } } else { this._namedMarshallers.set(typeName, { location, marshaller: makeNamedMarshaller(typeName, marshaller), - unmarshaller: makeNamedMarshaller(typeName, unmarshaller), + unmarshaller: makeNamedMarshaller(typeName, unmarshaller) }); } } @@ -259,13 +213,8 @@ export class TypeRegistry { * @param name - The name of the alias type. * @param type - The type the the alias represents. */ - registerAlias(name: string, location: Location, type: Type): void { - this.registerType( - name, - location, - (value, context) => this._marshal(context, value, type), - (value, context) => this._unmarshal(context, value, type), - ); + registerAlias(name, location, type) { + this.registerType(name, location, (value, context) => this._marshal(context, value, type), (value, context) => this._unmarshal(context, value, type)); } /** @@ -273,11 +222,11 @@ export class TypeRegistry { * @param value - The value to be marshalled. * @param type - The type object (used to find the appropriate function). */ - marshal(context: ObjectRegistry, value: any, type: Type): any { + marshal(context, value, type) { return this._marshal(context, value, type); } - _marshal(context: ObjectRegistry, value: any, type: Type): any { + _marshal(context, value, type) { const kindMarshaller = this._kindMarshallers.get(type.kind); if (kindMarshaller == null) { throw new Error(`No marshaller found for type kind ${type.kind}.`); @@ -285,22 +234,14 @@ export class TypeRegistry { return kindMarshaller.marshaller(value, type, context); } - marshalArguments( - context: ObjectRegistry, - args: Array, - argTypes: Array, - ): Object { - const marshalledargs = argTypes.map((param, i) => - this.marshal(context, args[i], param.type), - ); + marshalArguments(context, args, argTypes) { + const marshalledargs = argTypes.map((param, i) => this.marshal(context, args[i], param.type)); const result = {}; marshalledargs.forEach((arg, i) => { if (typeof argTypes[i].name !== 'string') { const type = argTypes[i].type; const nameOrKind = type.kind === 'named' ? type.name : type.kind; - throw new Error( - `Unnamed function parameter for ${nameOrKind}. (Are you destructuring in a function argument list?)`, - ); + throw new Error(`Unnamed function parameter for ${nameOrKind}. (Are you destructuring in a function argument list?)`); } result[argTypes[i].name] = arg; }); @@ -312,25 +253,21 @@ export class TypeRegistry { * @param value - The value to be marshalled. * @param type - The type object (used to find the appropriate function). */ - unmarshal(context: ObjectRegistry, value: any, type: Type): any { + unmarshal(context, value, type) { return this._unmarshal(context, value, type); } - unmarshalArguments( - context: ObjectRegistry, - args: Object, - argTypes: Array, - ): Array { + unmarshalArguments(context, args, argTypes) { return argTypes.map((arg, i) => { - invariant( - Object.hasOwnProperty.call(args, arg.name) || canBeUndefined(arg.type), - `unmarshalArguments: Missing argument: ${arg.name}`, - ); + if (!(Object.hasOwnProperty.call(args, arg.name) || canBeUndefined(arg.type))) { + throw new Error(`unmarshalArguments: Missing argument: ${arg.name}`); + } + return this.unmarshal(context, args[arg.name], arg.type); }); } - _unmarshal(context: ObjectRegistry, value: any, type: Type): any { + _unmarshal(context, value, type) { const kindMarshaller = this._kindMarshallers.get(type.kind); if (kindMarshaller == null) { throw new Error(`No unmarshaller found for type kind ${type.kind}.`); @@ -338,7 +275,7 @@ export class TypeRegistry { return kindMarshaller.unmarshaller(value, type, context); } - _registerPrimitives(): void { + _registerPrimitives() { // Since string, number, and boolean are JSON primitives, // they require no marshalling. Instead, simply create wrapped transformers // that assert the type of their argument. @@ -346,7 +283,7 @@ export class TypeRegistry { let arg = arg_; // Unbox argument. arg = arg instanceof String ? arg.valueOf() : arg; - assert(typeof arg === 'string', 'Expected a string argument'); + (0, _assert.default)(typeof arg === 'string', 'Expected a string argument'); return arg; }; const numberMarshaller = arg_ => { @@ -355,7 +292,7 @@ export class TypeRegistry { if (arg instanceof Number) { arg = arg.valueOf(); } - assert(typeof arg === 'number', 'Expected a number argument'); + (0, _assert.default)(typeof arg === 'number', 'Expected a number argument'); if (!Number.isFinite(arg)) { if (arg === Number.NEGATIVE_INFINITY) { arg = 'NEGATIVE_INFINITY'; @@ -387,7 +324,7 @@ export class TypeRegistry { } else if (arg instanceof Number) { arg = arg.valueOf(); } - assert(typeof arg === 'number', 'Expected a number argument'); + (0, _assert.default)(typeof arg === 'number', 'Expected a number argument'); return arg; }; const booleanTransformer = arg_ => { @@ -396,7 +333,7 @@ export class TypeRegistry { if (arg instanceof Boolean) { arg = arg.valueOf(); } - assert(typeof arg === 'boolean', 'Expected a boolean argument'); + (0, _assert.default)(typeof arg === 'boolean', 'Expected a boolean argument'); return arg; }; // We assume an 'any' and 'mixed' types require no marshalling. @@ -410,58 +347,64 @@ export class TypeRegistry { this._registerKind('mixed', identityTransformer, identityTransformer); } - _registerLiterals(): void { + _registerLiterals() { const literalTransformer = (arg, type) => { - invariant( - type.kind === 'string-literal' || - type.kind === 'number-literal' || - type.kind === 'boolean-literal', - ); - invariant(arg === type.value); + if (!(type.kind === 'string-literal' || type.kind === 'number-literal' || type.kind === 'boolean-literal')) { + throw new Error('Invariant violation: "type.kind === \'string-literal\' ||\\n type.kind === \'number-literal\' ||\\n type.kind === \'boolean-literal\'"'); + } + + if (!(arg === type.value)) { + throw new Error('Invariant violation: "arg === type.value"'); + } + return arg; }; - this._registerKind( - 'string-literal', - literalTransformer, - literalTransformer, - ); - this._registerKind( - 'number-literal', - literalTransformer, - literalTransformer, - ); - this._registerKind( - 'boolean-literal', - literalTransformer, - literalTransformer, - ); + this._registerKind('string-literal', literalTransformer, literalTransformer); + this._registerKind('number-literal', literalTransformer, literalTransformer); + this._registerKind('boolean-literal', literalTransformer, literalTransformer); } - _registerUnions(): void { + _registerUnions() { const unionLiteralTransformer = (arg, type) => { - invariant(type.kind === 'union'); + if (!(type.kind === 'union')) { + throw new Error('Invariant violation: "type.kind === \'union\'"'); + } + const alternate = type.types.find(element => { - invariant( - element.kind === 'string-literal' || - element.kind === 'number-literal' || - element.kind === 'boolean-literal', - ); + if (!(element.kind === 'string-literal' || element.kind === 'number-literal' || element.kind === 'boolean-literal')) { + throw new Error('Invariant violation: "element.kind === \'string-literal\' ||\\n element.kind === \'number-literal\' ||\\n element.kind === \'boolean-literal\'"'); + } + return arg === element.value; }); - invariant(alternate); + + if (!alternate) { + throw new Error('Invariant violation: "alternate"'); + } // This is just the literal transformer inlined ... + + return arg; }; const unionObjectMarshaller = (arg, type, context) => { - invariant(type.kind === 'union'); + if (!(type.kind === 'union')) { + throw new Error('Invariant violation: "type.kind === \'union\'"'); + } + return this._marshal(context, arg, findAlternate(arg, type)); }; const unionObjectUnmarshaller = (arg, type, context) => { - invariant(type.kind === 'union'); + if (!(type.kind === 'union')) { + throw new Error('Invariant violation: "type.kind === \'union\'"'); + } + return this._unmarshal(context, arg, findAlternate(arg, type)); }; const unionMarshaller = (arg, type, context) => { - invariant(type.kind === 'union'); + if (!(type.kind === 'union')) { + throw new Error('Invariant violation: "type.kind === \'union\'"'); + } + if (type.discriminantField != null) { return unionObjectMarshaller(arg, type, context); } else { @@ -469,7 +412,10 @@ export class TypeRegistry { } }; const unionUnmarshaller = (arg, type, context) => { - invariant(type.kind === 'union'); + if (!(type.kind === 'union')) { + throw new Error('Invariant violation: "type.kind === \'union\'"'); + } + if (type.discriminantField != null) { return unionObjectUnmarshaller(arg, type, context); } else { @@ -479,323 +425,294 @@ export class TypeRegistry { this._registerKind('union', unionMarshaller, unionUnmarshaller); } - _registerIntersections(): void { + _registerIntersections() { const intersectionMarshaller = (arg, type, context) => { - invariant(type.kind === 'intersection'); - invariant(type.flattened != null); + if (!(type.kind === 'intersection')) { + throw new Error('Invariant violation: "type.kind === \'intersection\'"'); + } + + if (!(type.flattened != null)) { + throw new Error('Invariant violation: "type.flattened != null"'); + } + return this._marshal(context, arg, type.flattened); }; const intersectionUnmarshaller = (arg, type, context) => { - invariant(type.kind === 'intersection'); - invariant(type.flattened != null); + if (!(type.kind === 'intersection')) { + throw new Error('Invariant violation: "type.kind === \'intersection\'"'); + } + + if (!(type.flattened != null)) { + throw new Error('Invariant violation: "type.flattened != null"'); + } + return this._unmarshal(context, arg, type.flattened); }; - this._registerKind( - 'intersection', - intersectionMarshaller, - intersectionUnmarshaller, - ); + this._registerKind('intersection', intersectionMarshaller, intersectionUnmarshaller); } - _registerSpecialTypes(): void { + _registerSpecialTypes() { // Serialize / Deserialize any Object type - this.registerType( - objectType.name, - builtinLocation, - object => { - assert( - object != null && typeof object === 'object', - 'Expected Object argument.', - ); - return object; - }, - object => { - assert( - object != null && typeof object === 'object', - 'Expected Object argument.', - ); - return object; - }, - ); + this.registerType((_builtinTypes || _load_builtinTypes()).objectType.name, (_builtinTypes || _load_builtinTypes()).builtinLocation, object => { + (0, _assert.default)(object != null && typeof object === 'object', 'Expected Object argument.'); + return object; + }, object => { + (0, _assert.default)(object != null && typeof object === 'object', 'Expected Object argument.'); + return object; + }); // Serialize / Deserialize Javascript Date objects - this.registerType( - dateType.name, - builtinLocation, - date => { - assert(date instanceof Date, 'Expected date argument.'); - return date.toJSON(); - }, - dateStr_ => { - let dateStr = dateStr_; - // Unbox argument. - dateStr = dateStr instanceof String ? dateStr.valueOf() : dateStr; - - assert(typeof dateStr === 'string', 'Expeceted a string argument.'); - return new Date(dateStr); - }, - ); + this.registerType((_builtinTypes || _load_builtinTypes()).dateType.name, (_builtinTypes || _load_builtinTypes()).builtinLocation, date => { + (0, _assert.default)(date instanceof Date, 'Expected date argument.'); + return date.toJSON(); + }, dateStr_ => { + let dateStr = dateStr_; + // Unbox argument. + dateStr = dateStr instanceof String ? dateStr.valueOf() : dateStr; + + (0, _assert.default)(typeof dateStr === 'string', 'Expeceted a string argument.'); + return new Date(dateStr); + }); // Serialize / Deserialize RegExp objects - this.registerType( - regExpType.name, - builtinLocation, - regexp => { - assert( - regexp instanceof RegExp, - 'Expected a RegExp object as an argument', - ); - return [regexp.source, regexp.flags]; - }, - regexpParts => { - assert( - Array.isArray(regexpParts) && regexpParts.length === 2, - 'Expected a tuple of [source, flags]', - ); - return new RegExp(regexpParts[0], regexpParts[1]); - }, - ); + this.registerType((_builtinTypes || _load_builtinTypes()).regExpType.name, (_builtinTypes || _load_builtinTypes()).builtinLocation, regexp => { + (0, _assert.default)(regexp instanceof RegExp, 'Expected a RegExp object as an argument'); + return [regexp.source, regexp.flags]; + }, regexpParts => { + (0, _assert.default)(Array.isArray(regexpParts) && regexpParts.length === 2, 'Expected a tuple of [source, flags]'); + return new RegExp(regexpParts[0], regexpParts[1]); + }); // Serialize / Deserialize Buffer objects through Base64 strings - this.registerType( - bufferType.name, - builtinLocation, - buffer => { - assert(buffer instanceof Buffer, 'Expected a buffer argument.'); - return buffer.toString('base64'); - }, - base64string_ => { - let base64string = base64string_; - // Unbox argument. - base64string = - base64string instanceof String - ? base64string.valueOf() - : base64string; - - assert( - typeof base64string === 'string', - `Expected a base64 string. Not ${typeof base64string}`, - ); - return new Buffer(base64string, 'base64'); - }, - ); + this.registerType((_builtinTypes || _load_builtinTypes()).bufferType.name, (_builtinTypes || _load_builtinTypes()).builtinLocation, buffer => { + (0, _assert.default)(buffer instanceof Buffer, 'Expected a buffer argument.'); + return buffer.toString('base64'); + }, base64string_ => { + let base64string = base64string_; + // Unbox argument. + base64string = base64string instanceof String ? base64string.valueOf() : base64string; + + (0, _assert.default)(typeof base64string === 'string', `Expected a base64 string. Not ${typeof base64string}`); + return new Buffer(base64string, 'base64'); + }); // fs.Stats - this.registerType( - fsStatsType.name, - builtinLocation, - stats => { - assert(stats instanceof fs.Stats); - return JSON.stringify(statsToObject(stats)); - }, - json => { - assert(typeof json === 'string'); - return objectToStats(JSON.parse(json)); - }, - ); + this.registerType((_builtinTypes || _load_builtinTypes()).fsStatsType.name, (_builtinTypes || _load_builtinTypes()).builtinLocation, stats => { + (0, _assert.default)(stats instanceof _fs.default.Stats); + return JSON.stringify(statsToObject(stats)); + }, json => { + (0, _assert.default)(typeof json === 'string'); + return objectToStats(JSON.parse(json)); + }); } - _registerContainers(): void { + _registerContainers() { // Serialize / Deserialize Arrays. - this._registerKind( - 'array', - (value: any, type: Type, context: ObjectRegistry) => { - assert(value instanceof Array, 'Expected an object of type Array.'); - invariant(type.kind === 'array'); - const elemType = type.type; - return value.map(elem => this._marshal(context, elem, elemType)); - }, - (value: any, type: Type, context: ObjectRegistry) => { - assert(value instanceof Array, 'Expected an object of type Array.'); - invariant(type.kind === 'array'); - const elemType = type.type; - return value.map(elem => this._unmarshal(context, elem, elemType)); - }, - ); + this._registerKind('array', (value, type, context) => { + (0, _assert.default)(value instanceof Array, 'Expected an object of type Array.'); + + if (!(type.kind === 'array')) { + throw new Error('Invariant violation: "type.kind === \'array\'"'); + } + + const elemType = type.type; + return value.map(elem => this._marshal(context, elem, elemType)); + }, (value, type, context) => { + (0, _assert.default)(value instanceof Array, 'Expected an object of type Array.'); + + if (!(type.kind === 'array')) { + throw new Error('Invariant violation: "type.kind === \'array\'"'); + } + + const elemType = type.type; + return value.map(elem => this._unmarshal(context, elem, elemType)); + }); // Serialize and Deserialize Objects. - this._registerKind( - 'object', - (obj: any, type: Type, context: ObjectRegistry) => { - assert(typeof obj === 'object', 'Expected an argument of type object.'); - invariant(type.kind === 'object'); - const newObj = {}; // Create a new object so we don't mutate the original one. - type.fields.map(prop => { + this._registerKind('object', (obj, type, context) => { + (0, _assert.default)(typeof obj === 'object', 'Expected an argument of type object.'); + + if (!(type.kind === 'object')) { + throw new Error('Invariant violation: "type.kind === \'object\'"'); + } + + const newObj = {}; // Create a new object so we don't mutate the original one. + type.fields.map(prop => { + const name = prop.name; + const originalValue = obj[name]; + const annotateErrorAndThrow = e => { + addMarshallingContextToError(`Field: ${name}`, originalValue, e); + throw e; + }; + // Check if the source object has this key. + if (obj != null && obj.hasOwnProperty(name)) { + try { + let value; + // Optional props can be explicitly set to `undefined` + if (originalValue === undefined && prop.optional) { + value = undefined; + } else { + value = this._marshal(context, originalValue, prop.type); + } + newObj[name] = value; + } catch (e) { + annotateErrorAndThrow(e); + } + } else if (!prop.optional) { + // If the property is optional, it's okay for it to be missing. + throw new Error(`Source object: ${JSON.stringify(obj)} is missing property ${prop.name}.`); + } + }); + return newObj; + }, (obj, type, context) => { + (0, _assert.default)(typeof obj === 'object', 'Expected an argument of type object.'); + + if (!(type.kind === 'object')) { + throw new Error('Invariant violation: "type.kind === \'object\'"'); + } + + const newObj = {}; // Create a new object so we don't mutate the original one. + type.fields.map(prop => { + // Check if the source object has this key. + if (obj != null && obj.hasOwnProperty(prop.name)) { const name = prop.name; const originalValue = obj[name]; const annotateErrorAndThrow = e => { addMarshallingContextToError(`Field: ${name}`, originalValue, e); throw e; }; - // Check if the source object has this key. - if (obj != null && obj.hasOwnProperty(name)) { - try { - let value; - // Optional props can be explicitly set to `undefined` - if (originalValue === undefined && prop.optional) { - value = undefined; - } else { - value = this._marshal(context, originalValue, prop.type); - } - newObj[name] = value; - } catch (e) { - annotateErrorAndThrow(e); - } - } else if (!prop.optional) { - // If the property is optional, it's okay for it to be missing. - throw new Error( - `Source object: ${JSON.stringify(obj)} is missing property ${ - prop.name - }.`, - ); + try { + newObj[name] = this._unmarshal(context, originalValue, prop.type); + } catch (e) { + annotateErrorAndThrow(e); } - }); - return newObj; - }, - (obj: any, type: Type, context: ObjectRegistry) => { - assert(typeof obj === 'object', 'Expected an argument of type object.'); - invariant(type.kind === 'object'); - const newObj = {}; // Create a new object so we don't mutate the original one. - type.fields.map(prop => { - // Check if the source object has this key. - if (obj != null && obj.hasOwnProperty(prop.name)) { - const name = prop.name; - const originalValue = obj[name]; - const annotateErrorAndThrow = e => { - addMarshallingContextToError(`Field: ${name}`, originalValue, e); - throw e; - }; - try { - newObj[name] = this._unmarshal(context, originalValue, prop.type); - } catch (e) { - annotateErrorAndThrow(e); - } - } else if (!prop.optional && !canBeUndefined(prop.type)) { - // If the property is optional, it's okay for it to be missing. - // JSON omits undefined values, so they can also be missing. - throw new Error( - `Source object: ${JSON.stringify(obj)} is missing property ${ - prop.name - }.`, - ); - } - }); - return newObj; - }, - ); + } else if (!prop.optional && !canBeUndefined(prop.type)) { + // If the property is optional, it's okay for it to be missing. + // JSON omits undefined values, so they can also be missing. + throw new Error(`Source object: ${JSON.stringify(obj)} is missing property ${prop.name}.`); + } + }); + return newObj; + }); // Serialize / Deserialize Sets. - this._registerKind( - 'set', - (value: any, type: Type, context: ObjectRegistry) => { - invariant(type.kind === 'set'); - assert(value instanceof Set, 'Expected an object of type Set.'); - return Array.from(value).map(elem => - this._marshal(context, elem, type.type), - ); - }, - (value: any, type: Type, context: ObjectRegistry) => { - assert(value instanceof Array, 'Expected an object of type Array.'); - invariant(type.kind === 'set'); - const elemType = type.type; - return new Set( - value.map(elem => this._unmarshal(context, elem, elemType)), - ); - }, - ); + this._registerKind('set', (value, type, context) => { + if (!(type.kind === 'set')) { + throw new Error('Invariant violation: "type.kind === \'set\'"'); + } + + (0, _assert.default)(value instanceof Set, 'Expected an object of type Set.'); + return Array.from(value).map(elem => this._marshal(context, elem, type.type)); + }, (value, type, context) => { + (0, _assert.default)(value instanceof Array, 'Expected an object of type Array.'); + + if (!(type.kind === 'set')) { + throw new Error('Invariant violation: "type.kind === \'set\'"'); + } + + const elemType = type.type; + return new Set(value.map(elem => this._unmarshal(context, elem, elemType))); + }); // Serialize / Deserialize Maps. - this._registerKind( - 'map', - (map: Map, type: Type, context: ObjectRegistry) => { - assert(map instanceof Map, 'Expected an object of type Set.'); - invariant(type.kind === 'map'); - return Array.from(map).map(([key, value]) => [ - this._marshal(context, key, type.keyType), - this._marshal(context, value, type.valueType), - ]); - }, - (serialized: any, type: Type, context: ObjectRegistry) => { - assert( - serialized instanceof Array, - 'Expected an object of type Array.', - ); - invariant(type.kind === 'map'); - const keyType = type.keyType; - const valueType = type.valueType; - return new Map( - serialized.map(entry => [ - this._unmarshal(context, entry[0], keyType), - this._unmarshal(context, entry[1], valueType), - ]), - ); - }, - ); + this._registerKind('map', (map, type, context) => { + (0, _assert.default)(map instanceof Map, 'Expected an object of type Set.'); + + if (!(type.kind === 'map')) { + throw new Error('Invariant violation: "type.kind === \'map\'"'); + } + + return Array.from(map).map(([key, value]) => [this._marshal(context, key, type.keyType), this._marshal(context, value, type.valueType)]); + }, (serialized, type, context) => { + (0, _assert.default)(serialized instanceof Array, 'Expected an object of type Array.'); + + if (!(type.kind === 'map')) { + throw new Error('Invariant violation: "type.kind === \'map\'"'); + } + + const keyType = type.keyType; + const valueType = type.valueType; + return new Map(serialized.map(entry => [this._unmarshal(context, entry[0], keyType), this._unmarshal(context, entry[1], valueType)])); + }); // Serialize / Deserialize Tuples. - this._registerKind( - 'tuple', - (value: any, type: Type, context: ObjectRegistry) => { - // Assert the length of the array. - assert(Array.isArray(value), 'Expected an object of type Array.'); - invariant(type.kind === 'tuple'); - const types = type.types; - assert( - value.length === types.length, - `Expected tuple of length ${types.length}.`, - ); - - // Convert all of the elements through the correct marshaller. - return value.map((elem, i) => this._marshal(context, elem, types[i])); - }, - (value: any, type: Type, context: ObjectRegistry) => { - // Assert the length of the array. - assert(Array.isArray(value), 'Expected an object of type Array.'); - invariant(type.kind === 'tuple'); - const types = type.types; - assert( - value.length === types.length, - `Expected tuple of length ${types.length}.`, - ); - - // Convert all of the elements through the correct unmarshaller. - return value.map((elem, i) => this._unmarshal(context, elem, types[i])); - }, - ); + this._registerKind('tuple', (value, type, context) => { + // Assert the length of the array. + (0, _assert.default)(Array.isArray(value), 'Expected an object of type Array.'); + + if (!(type.kind === 'tuple')) { + throw new Error('Invariant violation: "type.kind === \'tuple\'"'); + } + + const types = type.types; + (0, _assert.default)(value.length === types.length, `Expected tuple of length ${types.length}.`); + + // Convert all of the elements through the correct marshaller. + return value.map((elem, i) => this._marshal(context, elem, types[i])); + }, (value, type, context) => { + // Assert the length of the array. + (0, _assert.default)(Array.isArray(value), 'Expected an object of type Array.'); + + if (!(type.kind === 'tuple')) { + throw new Error('Invariant violation: "type.kind === \'tuple\'"'); + } + + const types = type.types; + (0, _assert.default)(value.length === types.length, `Expected tuple of length ${types.length}.`); + + // Convert all of the elements through the correct unmarshaller. + return value.map((elem, i) => this._unmarshal(context, elem, types[i])); + }); } } -function getObjectFieldByName( - type: ObjectType, - fieldName: string, -): ObjectField { +exports.TypeRegistry = TypeRegistry; +function getObjectFieldByName(type, fieldName) { const result = type.fields.find(field => field.name === fieldName); - invariant(result != null); + + if (!(result != null)) { + throw new Error('Invariant violation: "result != null"'); + } + return result; } -function findAlternate(arg: Object, type: UnionType): ObjectType { +function findAlternate(arg, type) { const discriminantField = type.discriminantField; - invariant(discriminantField != null); + + if (!(discriminantField != null)) { + throw new Error('Invariant violation: "discriminantField != null"'); + } + const discriminant = arg[discriminantField]; - invariant(discriminant != null); - const alternates: Array = (type.types: any); + + if (!(discriminant != null)) { + throw new Error('Invariant violation: "discriminant != null"'); + } + + const alternates = type.types; const result = alternates.find(alternate => { - invariant(alternate.kind === 'object'); - const alternateType = getObjectFieldByName(alternate, discriminantField) - .type; - invariant( - alternateType.kind === 'string-literal' || - alternateType.kind === 'number-literal' || - alternateType.kind === 'boolean-literal', - ); + if (!(alternate.kind === 'object')) { + throw new Error('Invariant violation: "alternate.kind === \'object\'"'); + } + + const alternateType = getObjectFieldByName(alternate, discriminantField).type; + + if (!(alternateType.kind === 'string-literal' || alternateType.kind === 'number-literal' || alternateType.kind === 'boolean-literal')) { + throw new Error('Invariant violation: "alternateType.kind === \'string-literal\' ||\\n alternateType.kind === \'number-literal\' ||\\n alternateType.kind === \'boolean-literal\'"'); + } + return alternateType.value === discriminant; }); - invariant(result != null); + + if (!(result != null)) { + throw new Error('Invariant violation: "result != null"'); + } + return result; } -function valueToString(value: any): string { +function valueToString(value) { try { return JSON.stringify(value); } catch (e) { @@ -803,24 +720,17 @@ function valueToString(value: any): string { } } -function addMarshallingContextToError( - message: string, - value: any, - e: Error, -): void { +function addMarshallingContextToError(message, value, e) { // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) if (e.hasMarshallingError == null) { - (e: any).hasMarshallingError = true; + e.hasMarshallingError = true; e.message += `\nError marshalling value: '${valueToString(value)}'\n`; } e.message += `${message}\n`; } -function makeKindMarshaller( - kind: string, - transformer: Transformer, -): Transformer { - return (value: any, type: Type, context: ObjectRegistry) => { +function makeKindMarshaller(kind, transformer) { + return (value, type, context) => { try { return transformer(value, type, context); } catch (e) { @@ -830,11 +740,8 @@ function makeKindMarshaller( }; } -function makeNamedMarshaller( - typeName: string, - transformer: NamedTransformer, -): NamedTransformer { - return (value: any, context: ObjectRegistry) => { +function makeNamedMarshaller(typeName, transformer) { + return (value, context) => { try { return transformer(value, context); } catch (e) { @@ -842,4 +749,4 @@ function makeNamedMarshaller( throw e; } }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/builtin-types.js b/pkg/nuclide-rpc/lib/builtin-types.js index 01af14128c..0ee9971696 100644 --- a/pkg/nuclide-rpc/lib/builtin-types.js +++ b/pkg/nuclide-rpc/lib/builtin-types.js @@ -1,82 +1,68 @@ -/** - * 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 strict - * @format - */ +'use strict'; -import type { - BuiltinLocation, - StringType, - NumberType, - BooleanType, - AnyType, - MixedType, - NamedType, - VoidType, -} from './types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +const builtinLocation = exports.builtinLocation = { + type: 'builtin' +}; /** + * 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. + * + * strict + * @format + */ -export const builtinLocation: BuiltinLocation = { - type: 'builtin', +const voidType = exports.voidType = { + kind: 'void' }; -export const voidType: VoidType = { - kind: 'void', +const anyType = exports.anyType = { + kind: 'any' }; -export const anyType: AnyType = { - kind: 'any', +const mixedType = exports.mixedType = { + kind: 'mixed' }; -export const mixedType: MixedType = { - kind: 'mixed', +const stringType = exports.stringType = { + kind: 'string' }; -export const stringType: StringType = { - kind: 'string', +const booleanType = exports.booleanType = { + kind: 'boolean' }; -export const booleanType: BooleanType = { - kind: 'boolean', +const numberType = exports.numberType = { + kind: 'number' }; -export const numberType: NumberType = { - kind: 'number', -}; - -export const objectType: NamedType = { +const objectType = exports.objectType = { kind: 'named', - name: 'Object', + name: 'Object' }; -export const dateType: NamedType = { +const dateType = exports.dateType = { kind: 'named', - name: 'Date', + name: 'Date' }; -export const regExpType: NamedType = { +const regExpType = exports.regExpType = { kind: 'named', - name: 'RegExp', + name: 'RegExp' }; -export const bufferType: NamedType = { +const bufferType = exports.bufferType = { kind: 'named', - name: 'Buffer', + name: 'Buffer' }; -export const fsStatsType: NamedType = { +const fsStatsType = exports.fsStatsType = { kind: 'named', - name: 'fs.Stats', + name: 'fs.Stats' }; -export const namedBuiltinTypes: Array = [ - objectType.name, - dateType.name, - regExpType.name, - bufferType.name, - fsStatsType.name, -]; +const namedBuiltinTypes = exports.namedBuiltinTypes = [objectType.name, dateType.name, regExpType.name, bufferType.name, fsStatsType.name]; \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/config.js b/pkg/nuclide-rpc/lib/config.js index 02c2954b13..dd36298613 100644 --- a/pkg/nuclide-rpc/lib/config.js +++ b/pkg/nuclide-rpc/lib/config.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,8 +10,8 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -export const SERVICE_FRAMEWORK3_PROTOCOL = 'service_framework3_rpc'; +const SERVICE_FRAMEWORK3_PROTOCOL = exports.SERVICE_FRAMEWORK3_PROTOCOL = 'service_framework3_rpc'; \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/generate-proxy-main.js b/pkg/nuclide-rpc/lib/generate-proxy-main.js index 51a41e6ea3..41f67516bf 100755 --- a/pkg/nuclide-rpc/lib/generate-proxy-main.js +++ b/pkg/nuclide-rpc/lib/generate-proxy-main.js @@ -1,112 +1,141 @@ -/** - * 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 - */ +'use strict'; -/* eslint-disable no-console */ +var _types; + +function _load_types() { + return _types = _interopRequireWildcard(require('@babel/types')); +} + +var _generator; + +function _load_generator() { + return _generator = _interopRequireDefault(require('@babel/generator')); +} + +var _yargs; + +function _load_yargs() { + return _yargs = _interopRequireDefault(require('yargs')); +} + +var _fs = _interopRequireDefault(require('fs')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _main; + +function _load_main() { + return _main = require('./main'); +} + +var _location; + +function _load_location() { + return _location = require('./location'); +} + +var _proxyGenerator; + +function _load_proxyGenerator() { + return _proxyGenerator = _interopRequireDefault(require('./proxy-generator')); +} + +var _serviceParser; + +function _load_serviceParser() { + return _serviceParser = require('./service-parser'); +} + +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; } } -import * as t from '@babel/types'; // eslint-disable-next-line nuclide-internal/no-unresolved -import generate from '@babel/generator'; -import yargs from 'yargs'; -import fs from 'fs'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {createProxyFactory, proxyFilename} from './main'; -import {stripLocationsFileName} from './location'; -import createProxyGenerator from './proxy-generator'; -import {parseServiceDefinition} from './service-parser'; - -const {generateProxy} = createProxyGenerator(t, generate); - -const argv = yargs - .usage('Usage: $0 -d path/to/definition -n serviceName') - .options({ - definitionPath: { - demand: true, - describe: 'Path to definition', - type: 'string', - }, - serviceName: { - demand: true, - describe: 'Service name', - type: 'string', - }, - preserveFunctionNames: { - demand: false, - default: false, - describe: 'Preserve function names', - type: 'boolean', - }, - useBasename: { - demand: false, - default: false, - describe: 'Removes full paths from definitions in favor of base names', - type: 'boolean', - }, - save: { - demand: false, - default: false, - describe: 'Save the proxy next to definition file', - type: 'boolean', - }, - code: { - demand: false, - default: false, - describe: 'Prints the proxy code', - type: 'boolean', - }, - json: { - demand: false, - default: false, - describe: 'Prints details in JSON format', - type: 'boolean', - }, - validate: { - demand: false, - default: false, - describe: 'Validate the proxy by running it', - type: 'boolean', - }, - }).argv; - -const definitionPath = nuclideUri.resolve(argv.definitionPath); +const { generateProxy } = (0, (_proxyGenerator || _load_proxyGenerator()).default)(_types || _load_types(), (_generator || _load_generator()).default); /** + * 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. + * + * + * @format + */ + +/* eslint-disable no-console */ + +const argv = (_yargs || _load_yargs()).default.usage('Usage: $0 -d path/to/definition -n serviceName').options({ + definitionPath: { + demand: true, + describe: 'Path to definition', + type: 'string' + }, + serviceName: { + demand: true, + describe: 'Service name', + type: 'string' + }, + preserveFunctionNames: { + demand: false, + default: false, + describe: 'Preserve function names', + type: 'boolean' + }, + useBasename: { + demand: false, + default: false, + describe: 'Removes full paths from definitions in favor of base names', + type: 'boolean' + }, + save: { + demand: false, + default: false, + describe: 'Save the proxy next to definition file', + type: 'boolean' + }, + code: { + demand: false, + default: false, + describe: 'Prints the proxy code', + type: 'boolean' + }, + json: { + demand: false, + default: false, + describe: 'Prints details in JSON format', + type: 'boolean' + }, + validate: { + demand: false, + default: false, + describe: 'Validate the proxy by running it', + type: 'boolean' + } +}).argv; + +const definitionPath = (_nuclideUri || _load_nuclideUri()).default.resolve(argv.definitionPath); const preserveFunctionNames = argv.preserveFunctionNames; const serviceName = argv.serviceName; // TODO: Make this a command line option. -const predefinedTypeNames = [ - nuclideUri.NUCLIDE_URI_TYPE_NAME, - 'atom$Point', - 'atom$Range', -]; - -const filename = proxyFilename(definitionPath); -const definitionSource = fs.readFileSync(definitionPath, 'utf8'); -const defs = parseServiceDefinition( - definitionPath, - definitionSource, - predefinedTypeNames, -); +const predefinedTypeNames = [(_nuclideUri || _load_nuclideUri()).default.NUCLIDE_URI_TYPE_NAME, 'atom$Point', 'atom$Range']; + +const filename = (0, (_main || _load_main()).proxyFilename)(definitionPath); +const definitionSource = _fs.default.readFileSync(definitionPath, 'utf8'); +const defs = (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)(definitionPath, definitionSource, predefinedTypeNames); if (argv.useBasename) { - stripLocationsFileName(defs); + (0, (_location || _load_location()).stripLocationsFileName)(defs); } const code = generateProxy(argv.serviceName, argv.preserveFunctionNames, defs); if (argv.validate) { try { - const fakeClient: any = {}; - const factory = createProxyFactory( - serviceName, - preserveFunctionNames, - definitionPath, - predefinedTypeNames, - ); + const fakeClient = {}; + const factory = (0, (_main || _load_main()).createProxyFactory)(serviceName, preserveFunctionNames, definitionPath, predefinedTypeNames); factory(fakeClient); } catch (e) { console.error(`Failed to validate "${definitionPath}"`); @@ -115,21 +144,15 @@ if (argv.validate) { } if (argv.save) { - fs.writeFileSync(filename, code); + _fs.default.writeFileSync(filename, code); } if (argv.json) { - console.log( - JSON.stringify( - { - src: definitionPath, - dest: filename, - code: argv.code ? code : undefined, - }, - null, - 2, - ), - ); + console.log(JSON.stringify({ + src: definitionPath, + dest: filename, + code: argv.code ? code : undefined + }, null, 2)); } else if (argv.code) { console.log(code); -} +} \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/index.js b/pkg/nuclide-rpc/lib/index.js index 6a98c7a21e..ca0c83e74a 100644 --- a/pkg/nuclide-rpc/lib/index.js +++ b/pkg/nuclide-rpc/lib/index.js @@ -1,52 +1,113 @@ -/** - * 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 - */ - -import type {Observable} from 'rxjs'; -import type {ObjectRegistry} from './ObjectRegistry'; - -export {ServiceRegistry} from './ServiceRegistry'; -export {RpcConnection, RpcTimeoutError} from './RpcConnection'; -export {LoopbackTransports} from './LoopbackTransports'; -export {StreamTransport} from './StreamTransport'; -export {SocketTransport} from './SocketTransport'; -export {SocketServer} from './SocketServer'; -export {RpcProcess} from './RpcProcess'; - -import loadServicesConfig from './loadServicesConfig'; -export {loadServicesConfig}; - -export type MessageLogger = ( - direction: 'send' | 'receive', - message: string, -) => void; - -export type ConfigEntry = { - name: string, - definition: string, - implementation: string, - // When true, doesn't mangle in the service name into the method names for functions. - preserveFunctionNames?: boolean, -}; - -export type NamedTransformer = (value: any, context: ObjectRegistry) => any; - -export type PredefinedTransformer = { - typeName: string, - marshaller: NamedTransformer, - unmarshaller: NamedTransformer, -}; - -export type Transport = { - send(message: string): void, - onMessage(): Observable, - close(): void, - isClosed(): boolean, -}; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.loadServicesConfig = exports.RpcProcess = exports.SocketServer = exports.SocketTransport = exports.StreamTransport = exports.LoopbackTransports = exports.RpcTimeoutError = exports.RpcConnection = exports.ServiceRegistry = undefined; + +var _ServiceRegistry; + +function _load_ServiceRegistry() { + return _ServiceRegistry = require('./ServiceRegistry'); +} + +Object.defineProperty(exports, 'ServiceRegistry', { + enumerable: true, + get: function () { + return (_ServiceRegistry || _load_ServiceRegistry()).ServiceRegistry; + } +}); + +var _RpcConnection; + +function _load_RpcConnection() { + return _RpcConnection = require('./RpcConnection'); +} + +Object.defineProperty(exports, 'RpcConnection', { + enumerable: true, + get: function () { + return (_RpcConnection || _load_RpcConnection()).RpcConnection; + } +}); +Object.defineProperty(exports, 'RpcTimeoutError', { + enumerable: true, + get: function () { + return (_RpcConnection || _load_RpcConnection()).RpcTimeoutError; + } +}); + +var _LoopbackTransports; + +function _load_LoopbackTransports() { + return _LoopbackTransports = require('./LoopbackTransports'); +} + +Object.defineProperty(exports, 'LoopbackTransports', { + enumerable: true, + get: function () { + return (_LoopbackTransports || _load_LoopbackTransports()).LoopbackTransports; + } +}); + +var _StreamTransport; + +function _load_StreamTransport() { + return _StreamTransport = require('./StreamTransport'); +} + +Object.defineProperty(exports, 'StreamTransport', { + enumerable: true, + get: function () { + return (_StreamTransport || _load_StreamTransport()).StreamTransport; + } +}); + +var _SocketTransport; + +function _load_SocketTransport() { + return _SocketTransport = require('./SocketTransport'); +} + +Object.defineProperty(exports, 'SocketTransport', { + enumerable: true, + get: function () { + return (_SocketTransport || _load_SocketTransport()).SocketTransport; + } +}); + +var _SocketServer; + +function _load_SocketServer() { + return _SocketServer = require('./SocketServer'); +} + +Object.defineProperty(exports, 'SocketServer', { + enumerable: true, + get: function () { + return (_SocketServer || _load_SocketServer()).SocketServer; + } +}); + +var _RpcProcess; + +function _load_RpcProcess() { + return _RpcProcess = require('./RpcProcess'); +} + +Object.defineProperty(exports, 'RpcProcess', { + enumerable: true, + get: function () { + return (_RpcProcess || _load_RpcProcess()).RpcProcess; + } +}); + +var _loadServicesConfig; + +function _load_loadServicesConfig() { + return _loadServicesConfig = _interopRequireDefault(require('./loadServicesConfig')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.loadServicesConfig = (_loadServicesConfig || _load_loadServicesConfig()).default; \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/loadServicesConfig.js b/pkg/nuclide-rpc/lib/loadServicesConfig.js index 44327f9e05..65fd202711 100644 --- a/pkg/nuclide-rpc/lib/loadServicesConfig.js +++ b/pkg/nuclide-rpc/lib/loadServicesConfig.js @@ -1,3 +1,23 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = loadServicesConfig; + +var _fs = _interopRequireDefault(require('fs')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Load service configs, and resolve all of the paths to absolute paths. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,29 +25,16 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import fs from 'fs'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - -import type {ConfigEntry} from '../../nuclide-rpc'; - -/** - * Load service configs, and resolve all of the paths to absolute paths. - */ -export default function loadServicesConfig( - dirname: string, -): Array { - return [ - nuclideUri.resolve(dirname, './services-3.json'), - nuclideUri.resolve(dirname, './fb-services-3.json'), - ].reduce((acc, servicePath) => { - if (fs.existsSync(servicePath)) { - const basedir = nuclideUri.dirname(servicePath); - const src = fs.readFileSync(servicePath, 'utf8'); - const jsonConfig: Array = JSON.parse(src); +function loadServicesConfig(dirname) { + return [(_nuclideUri || _load_nuclideUri()).default.resolve(dirname, './services-3.json'), (_nuclideUri || _load_nuclideUri()).default.resolve(dirname, './fb-services-3.json')].reduce((acc, servicePath) => { + if (_fs.default.existsSync(servicePath)) { + const basedir = (_nuclideUri || _load_nuclideUri()).default.dirname(servicePath); + const src = _fs.default.readFileSync(servicePath, 'utf8'); + const jsonConfig = JSON.parse(src); acc.push(...createServiceConfigObject(basedir, jsonConfig)); } return acc; @@ -40,20 +47,14 @@ export default function loadServicesConfig( * Service paths must either be absolute or relative to the service config * config file. */ -function createServiceConfigObject( - basedir: string, - jsonConfig: Array, -): Array { +function createServiceConfigObject(basedir, jsonConfig) { return jsonConfig.map(config => { return { name: config.name, // TODO(peterhal): Remove this once all services have had their def files removed. - definition: nuclideUri.resolve( - basedir, - config.definition || config.implementation, - ), - implementation: nuclideUri.resolve(basedir, config.implementation), - preserveFunctionNames: config.preserveFunctionNames === true, + definition: (_nuclideUri || _load_nuclideUri()).default.resolve(basedir, config.definition || config.implementation), + implementation: (_nuclideUri || _load_nuclideUri()).default.resolve(basedir, config.implementation), + preserveFunctionNames: config.preserveFunctionNames === true }; }); -} +} \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/location.js b/pkg/nuclide-rpc/lib/location.js index 234ca190d7..32b95b6f0b 100644 --- a/pkg/nuclide-rpc/lib/location.js +++ b/pkg/nuclide-rpc/lib/location.js @@ -1,55 +1,64 @@ -/** - * 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 - */ +'use strict'; -import type {Location} from './types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.locationToString = locationToString; +exports.locationsEqual = locationsEqual; +exports.stripLocationsFileName = stripLocationsFileName; -import invariant from 'assert'; -import nuclideUri from 'nuclide-commons/nuclideUri'; +var _nuclideUri; -export function locationToString(location: Location): string { +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function locationToString(location) { switch (location.type) { case 'source': return `${location.fileName}(${location.line})`; case 'builtin': return ''; default: - (location.type: empty); + location.type; throw new Error('Bad location type'); } -} +} /** + * 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. + * + * + * @format + */ -export function locationsEqual(first: Location, second: Location): boolean { +function locationsEqual(first, second) { if (first.type !== second.type) { return false; } switch (first.type) { case 'source': - invariant(second.type === 'source'); + if (!(second.type === 'source')) { + throw new Error('Invariant violation: "second.type === \'source\'"'); + } + return first.fileName === second.fileName && first.line === second.line; case 'builtin': return true; default: - (first.type: empty); + first.type; throw new Error('Bad location type'); } } -export function stripLocationsFileName(obj: any): any { - function inspect(key: ?string, value: any): void { - if ( - key === 'location' && - value != null && - typeof value.fileName === 'string' - ) { - value.fileName = nuclideUri.basename(value.fileName); +function stripLocationsFileName(obj) { + function inspect(key, value) { + if (key === 'location' && value != null && typeof value.fileName === 'string') { + value.fileName = (_nuclideUri || _load_nuclideUri()).default.basename(value.fileName); } else { stripLocationsFileName(value); } @@ -68,4 +77,4 @@ export function stripLocationsFileName(obj: any): any { }); } return obj; -} +} \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/main.js b/pkg/nuclide-rpc/lib/main.js index d65a7683b4..7d3cc006bb 100644 --- a/pkg/nuclide-rpc/lib/main.js +++ b/pkg/nuclide-rpc/lib/main.js @@ -1,3 +1,46 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.__test__ = undefined; + +var _memoize2; + +function _load_memoize() { + return _memoize2 = _interopRequireDefault(require('lodash/memoize')); +} + +exports.proxyFilename = proxyFilename; +exports.createProxyFactory = createProxyFactory; + +var _fs = _interopRequireDefault(require('fs')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _module = _interopRequireDefault(require('module')); + +var _os = _interopRequireDefault(require('os')); + +var _memoizeWithDisk; + +function _load_memoizeWithDisk() { + return _memoizeWithDisk = _interopRequireDefault(require('../../commons-node/memoizeWithDisk')); +} + +var _serviceParser; + +function _load_serviceParser() { + return _serviceParser = require('./service-parser'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** Cache for remote proxies. */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,79 +48,33 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import fs from 'fs'; -import {memoize} from 'lodash'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import invariant from 'assert'; -import Module from 'module'; -import os from 'os'; - -import memoizeWithDisk from '../../commons-node/memoizeWithDisk'; -import {parseServiceDefinition} from './service-parser'; - -import type {ReturnKind, Type, Parameter} from './types'; - -export type RpcContext = { - callRemoteFunction( - functionName: string, - returnType: ReturnKind, - args: Object, - ): any, - callRemoteMethod( - objectId: number, - methodName: string, - returnType: ReturnKind, - args: Object, - ): any, - disposeRemoteObject(object: Object): Promise, - marshal(value: any, type: Type): any, - unmarshal(value: any, type: Type): any, - marshalArguments(args: Array, argTypes: Array): Object, - unmarshalArguments(args: Object, argTypes: Array): Array, -}; - -export type ProxyFactory = (context: RpcContext) => Object; +const proxiesCache = new Map(); -/** Cache for remote proxies. */ -const proxiesCache: Map = new Map(); - -export function proxyFilename(definitionPath: string): string { - invariant( - nuclideUri.isAbsolute(definitionPath), - `"${definitionPath}" definition path must be absolute.`, - ); - const dir = nuclideUri.dirname(definitionPath); - const name = nuclideUri.basename( - definitionPath, - nuclideUri.extname(definitionPath), - ); - const filename = nuclideUri.join(dir, name + 'Proxy.js'); +function proxyFilename(definitionPath) { + if (!(_nuclideUri || _load_nuclideUri()).default.isAbsolute(definitionPath)) { + throw new Error(`"${definitionPath}" definition path must be absolute.`); + } + + const dir = (_nuclideUri || _load_nuclideUri()).default.dirname(definitionPath); + const name = (_nuclideUri || _load_nuclideUri()).default.basename(definitionPath, (_nuclideUri || _load_nuclideUri()).default.extname(definitionPath)); + const filename = (_nuclideUri || _load_nuclideUri()).default.join(dir, name + 'Proxy.js'); return filename; } -export function createProxyFactory( - serviceName: string, - preserveFunctionNames: boolean, - definitionPath: string, - predefinedTypes: Array, -): ProxyFactory { +function createProxyFactory(serviceName, preserveFunctionNames, definitionPath, predefinedTypes) { if (!proxiesCache.has(definitionPath)) { const filename = proxyFilename(definitionPath); let code; - if (fs.existsSync(filename)) { - code = fs.readFileSync(filename, 'utf8'); + if (_fs.default.existsSync(filename)) { + code = _fs.default.readFileSync(filename, 'utf8'); } else { - const definitionSource = fs.readFileSync(definitionPath, 'utf8'); - const defs = parseServiceDefinition( - definitionPath, - definitionSource, - predefinedTypes, - ); + const definitionSource = _fs.default.readFileSync(definitionPath, 'utf8'); + const defs = (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)(definitionPath, definitionSource, predefinedTypes); code = memoizedGenerateProxy(serviceName, preserveFunctionNames, defs); } @@ -86,43 +83,32 @@ export function createProxyFactory( } const factory = proxiesCache.get(definitionPath); - invariant(factory != null); + + if (!(factory != null)) { + throw new Error('Invariant violation: "factory != null"'); + } return factory; } -const memoizedReadFile = memoize( - (filename: string): string => { - return fs.readFileSync(filename, 'utf8'); - }, -); - -const memoizedGenerateProxy = memoizeWithDisk( - function generateProxy(serviceName, preserveFunctionNames, defs) { - // External dependencies: ensure that they're included in the key below. - const createProxyGenerator = require('./proxy-generator').default; - const generate = require('@babel/generator').default; - const t = require('@babel/types'); - return createProxyGenerator(t, generate).generateProxy( - serviceName, - preserveFunctionNames, - defs, - ); - }, - (serviceName, preserveFunctionNames, defs) => [ - serviceName, - preserveFunctionNames, - defs, - memoizedReadFile(require.resolve('./proxy-generator')), - require('@babel/generator/package.json').version, - require('@babel/types/package.json').version, - ], - nuclideUri.join(os.tmpdir(), 'nuclide-rpc-cache'), -); - -function loadCodeAsModule(code: string, filename: string): Module { - invariant(code.length > 0, 'Code must not be empty.'); - const m = new Module(filename); +const memoizedReadFile = (0, (_memoize2 || _load_memoize()).default)(filename => { + return _fs.default.readFileSync(filename, 'utf8'); +}); + +const memoizedGenerateProxy = (0, (_memoizeWithDisk || _load_memoizeWithDisk()).default)(function generateProxy(serviceName, preserveFunctionNames, defs) { + // External dependencies: ensure that they're included in the key below. + const createProxyGenerator = require('./proxy-generator').default; + const generate = require('@babel/generator').default; + const t = require('@babel/types'); + return createProxyGenerator(t, generate).generateProxy(serviceName, preserveFunctionNames, defs); +}, (serviceName, preserveFunctionNames, defs) => [serviceName, preserveFunctionNames, defs, memoizedReadFile(require.resolve('./proxy-generator')), require('@babel/generator/package.json').version, require('@babel/types/package.json').version], (_nuclideUri || _load_nuclideUri()).default.join(_os.default.tmpdir(), 'nuclide-rpc-cache')); + +function loadCodeAsModule(code, filename) { + if (!(code.length > 0)) { + throw new Error('Code must not be empty.'); + } + + const m = new _module.default(filename); m.filename = filename; m.paths = []; // Disallow require resolving by removing lookup paths. m._compile(code, filename); @@ -132,6 +118,6 @@ function loadCodeAsModule(code: string, filename: string): Module { } // Export caches for testing. -export const __test__ = { - proxiesCache, -}; +const __test__ = exports.__test__ = { + proxiesCache +}; \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/messages.js b/pkg/nuclide-rpc/lib/messages.js index 5ba06ed083..010a63f106 100644 --- a/pkg/nuclide-rpc/lib/messages.js +++ b/pkg/nuclide-rpc/lib/messages.js @@ -1,3 +1,24 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.decodeError = decodeError; +exports.createCallMessage = createCallMessage; +exports.createCallObjectMessage = createCallObjectMessage; +exports.createPromiseMessage = createPromiseMessage; +exports.createNextMessage = createNextMessage; +exports.createCompleteMessage = createCompleteMessage; +exports.createObserveErrorMessage = createObserveErrorMessage; +exports.createDisposeMessage = createDisposeMessage; +exports.createUnsubscribeMessage = createUnsubscribeMessage; +exports.createErrorResponseMessage = createErrorResponseMessage; + + +// Encodes the structure of messages that can be sent from the server to the client. +const ERROR_MESSAGE_LIMIT = 1000; + +// TODO: This should be a custom marshaller registered in the TypeRegistry /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,114 +26,19 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ // Encodes the structure of messages that can be sent from the client to the server. -export type RequestMessage = - | CallMessage - | CallObjectMessage - | DisposeMessage - | UnsubscribeMessage; - -export type CallMessage = { - protocol: string, - type: 'call', - method: string, - id: number, - args: Object, -}; - -export type CallObjectMessage = { - protocol: string, - type: 'call-object', - method: string, - id: number, - objectId: number, - args: Object, -}; - -export type DisposeMessage = { - protocol: string, - type: 'dispose', - id: number, - objectId: number, -}; - -export type UnsubscribeMessage = { - protocol: string, - type: 'unsubscribe', - id: number, -}; - -// Encodes the structure of messages that can be sent from the server to the client. -export type ResponseMessage = - | PromiseResponseMessage - | ErrorResponseMessage - | NextMessage - | CompleteMessage - | ErrorMessage; - -export type ErrorResponseMessage = { - protocol: string, - type: 'error-response', - id: number, - responseId: number, - error: any, -}; - -export type PromiseResponseMessage = { - protocol: string, - type: 'response', - id: number, - responseId: number, - result: any, -}; - -export type NextMessage = { - protocol: string, - type: 'next', - id: number, - responseId: number, - value: any, -}; - -export type CompleteMessage = { - protocol: string, - type: 'complete', - responseId: number, - id: number, -}; - -export type ErrorMessage = { - protocol: string, - type: 'error', - id: number, - responseId: number, - error: any, -}; - -const ERROR_MESSAGE_LIMIT = 1000; - -// TODO: This should be a custom marshaller registered in the TypeRegistry -export function decodeError( - message: Object, - encodedError: ?(Object | string), -): ?(Error | string) { +function decodeError(message, encodedError) { if (encodedError != null && typeof encodedError === 'object') { const resultError = new Error(); let messageStr = JSON.stringify(message); if (messageStr.length > ERROR_MESSAGE_LIMIT) { - messageStr = - messageStr.substr(0, ERROR_MESSAGE_LIMIT) + - `<${messageStr.length - ERROR_MESSAGE_LIMIT} bytes>`; + messageStr = messageStr.substr(0, ERROR_MESSAGE_LIMIT) + `<${messageStr.length - ERROR_MESSAGE_LIMIT} bytes>`; } - resultError.message = - `Remote Error: ${ - encodedError.message - } processing message ${messageStr}\n` + - JSON.stringify(encodedError.stack); + resultError.message = `Remote Error: ${encodedError.message} processing message ${messageStr}\n` + JSON.stringify(encodedError.stack); // $FlowIssue - some Errors (notably file operations) have a code. resultError.code = encodedError.code; resultError.stack = encodedError.stack; @@ -122,132 +48,90 @@ export function decodeError( } } -export function createCallMessage( - protocol: string, - functionName: string, - id: number, - args: Object, -): CallMessage { +function createCallMessage(protocol, functionName, id, args) { return { protocol, type: 'call', method: functionName, id, - args, + args }; } -export function createCallObjectMessage( - protocol: string, - methodName: string, - objectId: number, - id: number, - args: Object, -): CallObjectMessage { +function createCallObjectMessage(protocol, methodName, objectId, id, args) { return { protocol, type: 'call-object', method: methodName, objectId, id, - args, + args }; } -export function createPromiseMessage( - protocol: string, - id: number, - responseId: number, - result: any, -): PromiseResponseMessage { +function createPromiseMessage(protocol, id, responseId, result) { return { protocol, type: 'response', id, responseId, - result, + result }; } -export function createNextMessage( - protocol: string, - id: number, - responseId: number, - value: any, -): NextMessage { +function createNextMessage(protocol, id, responseId, value) { return { protocol, type: 'next', id, responseId, - value, + value }; } -export function createCompleteMessage( - protocol: string, - id: number, - responseId: number, -): CompleteMessage { +function createCompleteMessage(protocol, id, responseId) { return { protocol, type: 'complete', id, - responseId, + responseId }; } -export function createObserveErrorMessage( - protocol: string, - id: number, - responseId: number, - error: any, -): ErrorMessage { +function createObserveErrorMessage(protocol, id, responseId, error) { return { protocol, type: 'error', id, responseId, - error: formatError(error), + error: formatError(error) }; } -export function createDisposeMessage( - protocol: string, - id: number, - objectId: number, -): DisposeMessage { +function createDisposeMessage(protocol, id, objectId) { return { protocol, type: 'dispose', id, - objectId, + objectId }; } -export function createUnsubscribeMessage( - protocol: string, - id: number, -): UnsubscribeMessage { +function createUnsubscribeMessage(protocol, id) { return { protocol, type: 'unsubscribe', - id, + id }; } -export function createErrorResponseMessage( - protocol: string, - id: number, - responseId: number, - error: any, -): ErrorResponseMessage { +function createErrorResponseMessage(protocol, id, responseId, error) { return { protocol, type: 'error-response', id, responseId, - error: formatError(error), + error: formatError(error) }; } @@ -255,12 +139,12 @@ export function createErrorResponseMessage( * Format the error before sending over the web socket. * TODO: This should be a custom marshaller registered in the TypeRegistry */ -function formatError(error: any): ?(Object | string) { +function formatError(error) { if (error instanceof Error) { return { message: error.message, code: error.code, - stack: error.stack, + stack: error.stack }; } else if (typeof error === 'string') { return error.toString(); @@ -273,4 +157,4 @@ function formatError(error: any): ?(Object | string) { return `Unknown Error: ${error.toString()}`; } } -} +} \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/proxy-generator.js b/pkg/nuclide-rpc/lib/proxy-generator.js index 667029c864..f5cc200c4d 100644 --- a/pkg/nuclide-rpc/lib/proxy-generator.js +++ b/pkg/nuclide-rpc/lib/proxy-generator.js @@ -1,80 +1,32 @@ -/** - * 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 - */ +'use strict'; -/** - * NOTE: Keep this file free of runtime dependencies! - * Dependencies should be injected into createProxyGenerator below. - * This allows us to easily cache the result of this function during development - * to minimize the impact on reload times. - */ +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = createProxyGenerator; -import typeof * as babelTypes from '@babel/types'; // This is in devDependencies. This file is only reachable in dev mode. // eslint-disable-next-line nuclide-internal/no-unresolved -import typeof * as babelGenerator from '@babel/generator'; - -import type { - Definitions, - FunctionType, - NamedType, - Type, - InterfaceDefinition, -} from './types'; - -export default function createProxyGenerator( - t: babelTypes, - generate: babelGenerator, -) { +function createProxyGenerator(t, generate) { const thenIdent = t.identifier('then'); - const moduleDotExportsExpression = t.memberExpression( - t.identifier('module'), - t.identifier('exports'), - ); + const moduleDotExportsExpression = t.memberExpression(t.identifier('module'), t.identifier('exports')); const clientIdentifier = t.identifier('_client'); // Functions that are implemented at the connection layer. - const callRemoteFunctionExpression = t.memberExpression( - clientIdentifier, - t.identifier('callRemoteFunction'), - ); - const callRemoteMethodExpression = t.memberExpression( - clientIdentifier, - t.identifier('callRemoteMethod'), - ); - const disposeRemoteObjectExpression = t.memberExpression( - clientIdentifier, - t.identifier('disposeRemoteObject'), - ); + const callRemoteFunctionExpression = t.memberExpression(clientIdentifier, t.identifier('callRemoteFunction')); + const callRemoteMethodExpression = t.memberExpression(clientIdentifier, t.identifier('callRemoteMethod')); + const disposeRemoteObjectExpression = t.memberExpression(clientIdentifier, t.identifier('disposeRemoteObject')); const remoteModule = t.identifier('remoteModule'); const emptyObject = t.objectExpression([]); - const clientDotMarshalExpression = t.memberExpression( - clientIdentifier, - t.identifier('marshal'), - ); - const clientDotUnmarshalExpression = t.memberExpression( - clientIdentifier, - t.identifier('unmarshal'), - ); - const marshalCall = (...args) => - t.callExpression(clientDotMarshalExpression, args); - const unmarshalCall = (...args) => - t.callExpression(clientDotUnmarshalExpression, args); - - const clientDotMarshalArgsExpression = t.memberExpression( - clientIdentifier, - t.identifier('marshalArguments'), - ); + const clientDotMarshalExpression = t.memberExpression(clientIdentifier, t.identifier('marshal')); + const clientDotUnmarshalExpression = t.memberExpression(clientIdentifier, t.identifier('unmarshal')); + const marshalCall = (...args) => t.callExpression(clientDotMarshalExpression, args); + const unmarshalCall = (...args) => t.callExpression(clientDotUnmarshalExpression, args); + + const clientDotMarshalArgsExpression = t.memberExpression(clientIdentifier, t.identifier('marshalArguments')); // const clientDotUnmarshalArgsExpression // = t.memberExpression(clientIdentifier, t.identifier('unmarshalArguments')); @@ -84,14 +36,7 @@ export default function createProxyGenerator( * @param argumentTypes - An array of the types of the function's arguments. * @returns An expression representing a promise that resolves to an array of the arguments. */ - const marshalArgsCall = params => - t.callExpression(clientDotMarshalArgsExpression, [ - t.callExpression( - t.memberExpression(t.identifier('Array'), t.identifier('from')), - [t.identifier('arguments')], - ), - objectToLiteral(params), - ]); + const marshalArgsCall = params => t.callExpression(clientDotMarshalArgsExpression, [t.callExpression(t.memberExpression(t.identifier('Array'), t.identifier('from')), [t.identifier('arguments')]), objectToLiteral(params)]); // const unmarshalArgsCall = params => t.callExpression(clientDotUnmarshalArgsExpression, [ // t.arguments, @@ -99,18 +44,7 @@ export default function createProxyGenerator( // ]); // Generates `Object.defineProperty(module.exports, name, {value: …})` - const objectDefinePropertyCall = (name, value) => - t.callExpression( - t.memberExpression( - t.identifier('Object'), - t.identifier('defineProperty'), - ), - [ - moduleDotExportsExpression, - t.stringLiteral(name), - t.objectExpression([t.objectProperty(t.identifier('value'), value)]), - ], - ); + const objectDefinePropertyCall = (name, value) => t.callExpression(t.memberExpression(t.identifier('Object'), t.identifier('defineProperty')), [moduleDotExportsExpression, t.stringLiteral(name), t.objectExpression([t.objectProperty(t.identifier('value'), value)])]); /** * Given the parsed result of a definition file, generate a remote proxy module @@ -121,50 +55,24 @@ export default function createProxyGenerator( * @param defs - The result of parsing the definition file. * @returns The proxy factory method. */ - function generateProxy( - serviceName: string, - preserveFunctionNames: boolean, - defs: Definitions, - ): string { + function generateProxy(serviceName, preserveFunctionNames, defs) { const statements = []; // Declare remoteModule as empty object. - statements.push( - t.variableDeclaration('const', [ - t.variableDeclarator(t.identifier('remoteModule'), emptyObject), - ]), - ); + statements.push(t.variableDeclaration('const', [t.variableDeclarator(t.identifier('remoteModule'), emptyObject)])); Object.keys(defs).forEach(defName => { const definition = defs[defName]; const name = definition.name; switch (definition.kind) { case 'function': - const functionName = preserveFunctionNames - ? name - : `${serviceName}/${name}`; + const functionName = preserveFunctionNames ? name : `${serviceName}/${name}`; // Generate a remote proxy for each module-level function. - statements.push( - t.expressionStatement( - t.assignmentExpression( - '=', - t.memberExpression(remoteModule, t.identifier(name)), - generateFunctionProxy(functionName, definition.type), - ), - ), - ); + statements.push(t.expressionStatement(t.assignmentExpression('=', t.memberExpression(remoteModule, t.identifier(name)), generateFunctionProxy(functionName, definition.type)))); break; case 'interface': // Generate a remote proxy for each remotable interface. - statements.push( - t.expressionStatement( - t.assignmentExpression( - '=', - t.memberExpression(remoteModule, t.identifier(name)), - generateInterfaceProxy(definition), - ), - ), - ); + statements.push(t.expressionStatement(t.assignmentExpression('=', t.memberExpression(remoteModule, t.identifier(name)), generateInterfaceProxy(definition)))); break; case 'alias': // nothing @@ -177,23 +85,11 @@ export default function createProxyGenerator( // Wrap the remoteModule construction in a function that takes a RpcConnection // object as an argument. - const func = t.arrowFunctionExpression( - [clientIdentifier], - t.blockStatement(statements), - ); - const assignment = t.assignmentExpression( - '=', - moduleDotExportsExpression, - func, - ); + const func = t.arrowFunctionExpression([clientIdentifier], t.blockStatement(statements)); + const assignment = t.assignmentExpression('=', moduleDotExportsExpression, func); const program = t.program([ - // !!!This module is not transpiled!!! - t.expressionStatement(t.stringLiteral('use strict')), - t.expressionStatement(assignment), - t.expressionStatement( - objectDefinePropertyCall('defs', objectToLiteral(defs)), - ), - ]); + // !!!This module is not transpiled!!! + t.expressionStatement(t.stringLiteral('use strict')), t.expressionStatement(assignment), t.expressionStatement(objectDefinePropertyCall('defs', objectToLiteral(defs)))]); // Use Babel to generate code from the AST. return generate(program).code; @@ -205,25 +101,15 @@ export default function createProxyGenerator( * @returns The proxy function (as an arrow function) that should be assigned to * a property of the remote module. */ - function generateFunctionProxy(name: string, funcType: FunctionType): any { + function generateFunctionProxy(name, funcType) { // _client.callRemoteFunction(name, kind, args) - const callExpression = t.callExpression(callRemoteFunctionExpression, [ - t.stringLiteral(name), - t.stringLiteral(funcType.returnType.kind), - marshalArgsCall(funcType.argumentTypes), - ]); + const callExpression = t.callExpression(callRemoteFunctionExpression, [t.stringLiteral(name), t.stringLiteral(funcType.returnType.kind), marshalArgsCall(funcType.argumentTypes)]); const result = generateUnmarshalResult(funcType.returnType, callExpression); // function(arg0, ... argN) { return ... } - const args = funcType.argumentTypes.map((arg, i) => - t.identifier(`arg${i}`), - ); - return t.functionExpression( - null, - args, - t.blockStatement([t.returnStatement(result)]), - ); + const args = funcType.argumentTypes.map((arg, i) => t.identifier(`arg${i}`)); + return t.functionExpression(null, args, t.blockStatement([t.returnStatement(result)])); } /** @@ -231,36 +117,26 @@ export default function createProxyGenerator( * @param def - The InterfaceDefinition object that encodes all if the interface's operations. * @returns An anonymous ClassExpression node that can be assigned to a module property. */ - function generateInterfaceProxy(def: InterfaceDefinition): any { + function generateInterfaceProxy(def) { const methodDefinitions = []; // Generate proxies for static methods. Object.keys(def.staticMethods).forEach(methodName => { const funcType = def.staticMethods[methodName]; - const funcProxy = generateFunctionProxy( - `${def.name}/${methodName}`, - funcType, - ); - methodDefinitions.push( - t.classMethod( - 'method', - t.identifier(methodName), - funcProxy.params, - funcProxy.body, - /* computed: */ false, - /* static: */ true, - ), - ); + const funcProxy = generateFunctionProxy(`${def.name}/${methodName}`, funcType); + methodDefinitions.push(t.classMethod('method', t.identifier(methodName), funcProxy.params, funcProxy.body, + /* computed: */false, + /* static: */true)); }); // Generate a constructor stub. methodDefinitions.push(generateRemoteConstructor()); // Generate proxies for instance methods. - const thisType: NamedType = { + const thisType = { kind: 'named', location: def.location, - name: def.name, + name: def.name }; Object.keys(def.instanceMethods).forEach(methodName => { const funcType = def.instanceMethods[methodName]; @@ -268,11 +144,7 @@ export default function createProxyGenerator( if (methodName === 'dispose') { return; } - const methodDefinition = generateRemoteDispatch( - methodName, - thisType, - funcType, - ); + const methodDefinition = generateRemoteDispatch(methodName, thisType, funcType); methodDefinitions.push(methodDefinition); }); @@ -289,19 +161,10 @@ export default function createProxyGenerator( */ function generateRemoteConstructor() { // throw Error(...) - const throwStatement = t.throwStatement( - t.callExpression(t.identifier('Error'), [ - t.stringLiteral('constructors are not supported for remote objects'), - ]), - ); + const throwStatement = t.throwStatement(t.callExpression(t.identifier('Error'), [t.stringLiteral('constructors are not supported for remote objects')])); // constructor() { ... } - return t.classMethod( - 'constructor', - t.identifier('constructor'), - [], - t.blockStatement([throwStatement]), - ); + return t.classMethod('constructor', t.identifier('constructor'), [], t.blockStatement([throwStatement])); } /** @@ -310,38 +173,19 @@ export default function createProxyGenerator( * @param funcType - The type information for the function. * @returns A MethodDefinition node that can be added to a ClassBody */ - function generateRemoteDispatch( - methodName: string, - thisType: NamedType, - funcType: FunctionType, - ) { + function generateRemoteDispatch(methodName, thisType, funcType) { // _client.callRemoteMethod(id, methodName, returnType, args) - const callRemoteMethod = t.callExpression(callRemoteMethodExpression, [ - generateTransformStatement(t.thisExpression(), thisType, true), - t.stringLiteral(methodName), - t.stringLiteral(funcType.returnType.kind), - marshalArgsCall(funcType.argumentTypes), - ]); + const callRemoteMethod = t.callExpression(callRemoteMethodExpression, [generateTransformStatement(t.thisExpression(), thisType, true), t.stringLiteral(methodName), t.stringLiteral(funcType.returnType.kind), marshalArgsCall(funcType.argumentTypes)]); // ... .then(value => _client.unmarshal(...)) - const result = generateUnmarshalResult( - funcType.returnType, - callRemoteMethod, - ); + const result = generateUnmarshalResult(funcType.returnType, callRemoteMethod); // methodName(arg0, ... argN) { return ... } - const funcTypeArgs = funcType.argumentTypes.map((arg, i) => - t.identifier(`arg${i}`), - ); - return t.classMethod( - 'method', - t.identifier(methodName), - funcTypeArgs, - t.blockStatement([t.returnStatement(result)]), - ); + const funcTypeArgs = funcType.argumentTypes.map((arg, i) => t.identifier(`arg${i}`)); + return t.classMethod('method', t.identifier(methodName), funcTypeArgs, t.blockStatement([t.returnStatement(result)])); } - function generateUnmarshalResult(returnType: Type, valueExpression) { + function generateUnmarshalResult(returnType, valueExpression) { switch (returnType.kind) { case 'void': return valueExpression; @@ -352,30 +196,19 @@ export default function createProxyGenerator( // Map the events through the appropriate marshaller. // ... .map(value => _client.unmarshal(value, returnType)) const observableTransformer = generateValueTransformer(returnType.type); - const unmarshalledObservable = t.callExpression( - t.memberExpression(valueExpression, t.identifier('map')), - [observableTransformer], - ); + const unmarshalledObservable = t.callExpression(t.memberExpression(valueExpression, t.identifier('map')), [observableTransformer]); // And finally, convert to a ConnectableObservable with publish. - return t.callExpression( - t.memberExpression(unmarshalledObservable, t.identifier('publish')), - [], - ); + return t.callExpression(t.memberExpression(unmarshalledObservable, t.identifier('publish')), []); default: throw new Error(`Unknown return type ${returnType.kind}.`); } } // value => _client.unmarshal(value, type) - function generateValueTransformer(type: Type) { + function generateValueTransformer(type) { const value = t.identifier('value'); - return t.arrowFunctionExpression( - [value], - t.blockStatement([ - t.returnStatement(generateTransformStatement(value, type, false)), - ]), - ); + return t.arrowFunctionExpression([value], t.blockStatement([t.returnStatement(generateTransformStatement(value, type, false))])); } /** @@ -385,17 +218,10 @@ export default function createProxyGenerator( */ function generateDisposeMethod() { // return _client.disposeRemoteObject(this); - const returnStatement = t.returnStatement( - t.callExpression(disposeRemoteObjectExpression, [t.thisExpression()]), - ); + const returnStatement = t.returnStatement(t.callExpression(disposeRemoteObjectExpression, [t.thisExpression()])); // dispose() { ... } - return t.classMethod( - 'method', - t.identifier('dispose'), - [], - t.blockStatement([returnStatement]), - ); + return t.classMethod('method', t.identifier('dispose'), [], t.blockStatement([returnStatement])); } /** @@ -406,11 +232,7 @@ export default function createProxyGenerator( * @param marshal {boolean} - If true, then we are trying to marshal the value. If false, then * we are trying to unmarshal. */ - function generateTransformStatement( - id: any, - type: Type, - marshal: boolean, - ): any { + function generateTransformStatement(id, type, marshal) { // The first argument is the value to be marshalled or unmarshalled. // The second argument is the type object, which encodes all of the information required // to marshal / unmarshal the value. @@ -432,7 +254,7 @@ export default function createProxyGenerator( * @param obj - The object to convert. * @returns A babel AST node. */ - function objectToLiteral(obj: any): any { + function objectToLiteral(obj) { if (typeof obj === 'string') { return t.stringLiteral(obj); } else if (typeof obj === 'number') { @@ -449,24 +271,12 @@ export default function createProxyGenerator( // [...] return t.arrayExpression(obj.map(elem => objectToLiteral(elem))); } else if (obj instanceof Map) { - return t.newExpression( - t.identifier('Map'), - obj.size - ? // new Map([...]) - [objectToLiteral(Array.from(obj.entries()))] - : // new Map() - [], - ); + return t.newExpression(t.identifier('Map'), obj.size ? // new Map([...]) + [objectToLiteral(Array.from(obj.entries()))] : // new Map() + []); } else if (typeof obj === 'object') { // {a: 1, b: 2} - return t.objectExpression( - Object.keys(obj).map(key => - t.objectProperty( - t.isValidIdentifier(key) ? t.identifier(key) : t.stringLiteral(key), - objectToLiteral(obj[key]), - ), - ), - ); + return t.objectExpression(Object.keys(obj).map(key => t.objectProperty(t.isValidIdentifier(key) ? t.identifier(key) : t.stringLiteral(key), objectToLiteral(obj[key])))); } throw new Error(`Cannot convert unknown type ${typeof obj} to literal.`); @@ -478,10 +288,8 @@ export default function createProxyGenerator( * @param functionExpression - A function to pass as an argument to `.then` * @returns A CallExpression node that `.then`s on the provided promise. */ - function thenPromise(promiseExpression, functionExpression): any { - return t.callExpression(t.memberExpression(promiseExpression, thenIdent), [ - functionExpression, - ]); + function thenPromise(promiseExpression, functionExpression) { + return t.callExpression(t.memberExpression(promiseExpression, thenIdent), [functionExpression]); } return { @@ -489,7 +297,23 @@ export default function createProxyGenerator( /** Export private functions for unit-testing. */ __test__: { generateTransformStatement, - objectToLiteral, - }, + objectToLiteral + } }; -} +} /** + * 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. + * + * + * @format + */ + +/** + * NOTE: Keep this file free of runtime dependencies! + * Dependencies should be injected into createProxyGenerator below. + * This allows us to easily cache the result of this function during development + * to minimize the impact on reload times. + */ \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/regenerate-baselines-main.js b/pkg/nuclide-rpc/lib/regenerate-baselines-main.js index 5f855ae193..5b58a9a2b4 100755 --- a/pkg/nuclide-rpc/lib/regenerate-baselines-main.js +++ b/pkg/nuclide-rpc/lib/regenerate-baselines-main.js @@ -1,50 +1,76 @@ -/** - * 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 - */ +'use strict'; -// Regenerates the .proxy baseline files in the spec/fixtures directory. +var _types; + +function _load_types() { + return _types = _interopRequireWildcard(require('@babel/types')); +} + +var _generator; + +function _load_generator() { + return _generator = _interopRequireDefault(require('@babel/generator')); +} + +var _serviceParser; + +function _load_serviceParser() { + return _serviceParser = require('./service-parser'); +} + +var _proxyGenerator; + +function _load_proxyGenerator() { + return _proxyGenerator = _interopRequireDefault(require('./proxy-generator')); +} + +var _location; + +function _load_location() { + return _location = require('./location'); +} + +var _fs = _interopRequireDefault(require('fs')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +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; } } -import * as t from '@babel/types'; // eslint-disable-next-line nuclide-internal/no-unresolved -import generate from '@babel/generator'; -import {parseServiceDefinition} from './service-parser'; -import createProxyGenerator from './proxy-generator'; -import {stripLocationsFileName} from './location'; -import fs from 'fs'; -import nuclideUri from 'nuclide-commons/nuclideUri'; +const { generateProxy } = (0, (_proxyGenerator || _load_proxyGenerator()).default)(_types || _load_types(), (_generator || _load_generator()).default); /** + * 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. + * + * + * @format + */ -const {generateProxy} = createProxyGenerator(t, generate); +// Regenerates the .proxy baseline files in the spec/fixtures directory. -const dir = nuclideUri.join(__dirname, '../spec/fixtures'); -for (const file of fs.readdirSync(dir)) { +const dir = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../spec/fixtures'); +for (const file of _fs.default.readdirSync(dir)) { if (file.endsWith('.def')) { - const serviceName = nuclideUri.basename(file, '.def'); + const serviceName = (_nuclideUri || _load_nuclideUri()).default.basename(file, '.def'); const preserveFunctionNames = false; - const definitionPath = nuclideUri.join(dir, file); + const definitionPath = (_nuclideUri || _load_nuclideUri()).default.join(dir, file); - const definitionSource = fs.readFileSync(definitionPath, 'utf8'); - const definitions = parseServiceDefinition( - definitionPath, - definitionSource, - [], - ); + const definitionSource = _fs.default.readFileSync(definitionPath, 'utf8'); + const definitions = (0, (_serviceParser || _load_serviceParser()).parseServiceDefinition)(definitionPath, definitionSource, []); - stripLocationsFileName(definitions); + (0, (_location || _load_location()).stripLocationsFileName)(definitions); - fs.writeFileSync( - definitionPath.replace('.def', '.def.json'), - JSON.stringify(definitions, null, 4), - 'utf8', - ); + _fs.default.writeFileSync(definitionPath.replace('.def', '.def.json'), JSON.stringify(definitions, null, 4), 'utf8'); const code = generateProxy(serviceName, preserveFunctionNames, definitions); - fs.writeFileSync(definitionPath.replace('.def', '.proxy'), code, 'utf8'); + _fs.default.writeFileSync(definitionPath.replace('.def', '.proxy'), code, 'utf8'); } -} +} \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/service-parser.js b/pkg/nuclide-rpc/lib/service-parser.js index ce642ee4af..85662dd52a 100644 --- a/pkg/nuclide-rpc/lib/service-parser.js +++ b/pkg/nuclide-rpc/lib/service-parser.js @@ -1,3 +1,59 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.parseServiceDefinition = parseServiceDefinition; +exports._clearFileParsers = _clearFileParsers; + +var _memoizeWithDisk; + +function _load_memoizeWithDisk() { + return _memoizeWithDisk = _interopRequireDefault(require('../../commons-node/memoizeWithDisk')); +} + +var _builtinTypes; + +function _load_builtinTypes() { + return _builtinTypes = require('./builtin-types'); +} + +var _location; + +function _load_location() { + return _location = require('./location'); +} + +var _DefinitionValidator; + +function _load_DefinitionValidator() { + return _DefinitionValidator = require('./DefinitionValidator'); +} + +var _resolveFrom; + +function _load_resolveFrom() { + return _resolveFrom = _interopRequireDefault(require('resolve-from')); +} + +var _collection; + +function _load_collection() { + return _collection = require('../../../modules/nuclide-commons/collection'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _fs = _interopRequireDefault(require('fs')); + +var _os = _interopRequireDefault(require('os')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,37 +61,11 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import invariant from 'assert'; - -import type { - Definition, - FunctionDefinition, - AliasDefinition, - Definitions, - Parameter, - FunctionType, - InterfaceDefinition, - Type, - Location, - SourceLocation, - Babel$Node, -} from './types'; - -import memoizeWithDisk from '../../commons-node/memoizeWithDisk'; -import {namedBuiltinTypes} from './builtin-types'; -import {locationToString} from './location'; -import {validateDefinitions} from './DefinitionValidator'; -import resolveFrom from 'resolve-from'; -import {objectFromMap} from 'nuclide-commons/collection'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import fs from 'fs'; -import os from 'os'; - -function isPrivateMemberName(name: string): boolean { +function isPrivateMemberName(name) { return name.startsWith('_'); } @@ -45,55 +75,50 @@ function isPrivateMemberName(name: string): boolean { * data over a network. * @param source - The string source of the definition file. */ -export function parseServiceDefinition( - fileName: string, - source: string, - predefinedTypes: Array, -): Definitions { +function parseServiceDefinition(fileName, source, predefinedTypes) { return new ServiceParser(predefinedTypes).parseService(fileName, source); } class ServiceParser { - _defs: Map; - // Set of exported AST nodes. Ensures we don't process the same export twice. - _visitedExports: WeakSet; - constructor(predefinedTypes: Array) { + constructor(predefinedTypes) { this._defs = new Map(); this._visitedExports = new WeakSet(); // Add all builtin types const defineBuiltinType = name => { - invariant(!this._defs.has(name), 'Duplicate builtin type'); + if (!!this._defs.has(name)) { + throw new Error('Duplicate builtin type'); + } + this._defs.set(name, { kind: 'alias', name, - location: {type: 'builtin'}, + location: { type: 'builtin' } }); }; - namedBuiltinTypes.forEach(defineBuiltinType); + (_builtinTypes || _load_builtinTypes()).namedBuiltinTypes.forEach(defineBuiltinType); predefinedTypes.forEach(defineBuiltinType); } + // Set of exported AST nodes. Ensures we don't process the same export twice. - parseService(fileName: string, source: string): Definitions { + + parseService(fileName, source) { const fileParser = getFileParser(fileName, source, true); fileParser.getExports().forEach(node => fileParser.parseExport(this, node)); - const objDefs = objectFromMap(this._defs); - validateDefinitions(objDefs); + const objDefs = (0, (_collection || _load_collection()).objectFromMap)(this._defs); + (0, (_DefinitionValidator || _load_DefinitionValidator()).validateDefinitions)(objDefs); return objDefs; } - hasDefinition(id: string): boolean { + hasDefinition(id) { return this._defs.has(id); } - addDefinition(definition: T): T { + addDefinition(definition) { const existingDef = this._defs.get(definition.name); if (existingDef != null) { - throw errorLocations( - [definition.location, existingDef.location], - `Duplicate definition for ${definition.name}`, - ); + throw errorLocations([definition.location, existingDef.location], `Duplicate definition for ${definition.name}`); } else { this._defs.set(definition.name, definition); } @@ -104,7 +129,7 @@ class ServiceParser { * Returns false if the export node has already been visited. * This prevents duplicate exports from being added. */ - visitExport(node: Object): boolean { + visitExport(node) { if (this._visitedExports.has(node)) { return false; } @@ -113,81 +138,65 @@ class ServiceParser { } } -type Import = { - imported: string, - file: string, -}; - -const fileParsers: Map = new Map(); +const fileParsers = new Map(); -function getFileParser( - fileName: string, - source: ?string, - isDefinition: ?boolean, -): FileParser { +function getFileParser(fileName, source, isDefinition) { let parser = fileParsers.get(fileName); if (parser != null) { return parser; } parser = new FileParser(fileName, Boolean(isDefinition)); // flowlint-next-line sketchy-null-string:off - parser.parse(source || fs.readFileSync(fileName, 'utf8')); + parser.parse(source || _fs.default.readFileSync(fileName, 'utf8')); fileParsers.set(fileName, parser); return parser; } // Exported for testing. -export function _clearFileParsers(): void { +function _clearFileParsers() { fileParsers.clear(); } -const memoizedBabylonParse = memoizeWithDisk( - function babylonParse(src, options) { - // External dependency: ensure that it's included in the key below. - const babylon = require('babylon'); - return babylon.parse(src, options).program; - }, - (src, options) => [src, options, require('babylon/package.json').version], - nuclideUri.join(os.tmpdir(), 'nuclide-rpc-cache'), -); +const memoizedBabylonParse = (0, (_memoizeWithDisk || _load_memoizeWithDisk()).default)(function babylonParse(src, options) { + // External dependency: ensure that it's included in the key below. + const babylon = require('babylon'); + return babylon.parse(src, options).program; +}, (src, options) => [src, options, require('babylon/package.json').version], (_nuclideUri || _load_nuclideUri()).default.join(_os.default.tmpdir(), 'nuclide-rpc-cache')); class FileParser { - _fileName: string; - // Whether this file defines the service (i.e. not an import) - _isDefinition: boolean; // Map of exported identifiers to their nodes. - _exports: Map; - // Map of imported identifiers to their source file/identifier. - _imports: Map; - - constructor(fileName: string, isDefinition: boolean) { + constructor(fileName, isDefinition) { this._fileName = fileName; this._isDefinition = isDefinition; this._exports = new Map(); this._imports = new Map(); } + // Map of imported identifiers to their source file/identifier. + + // Whether this file defines the service (i.e. not an import) - getExports(): Map { + + getExports() { return this._exports; } - _locationOfNode(node: any): SourceLocation { + _locationOfNode(node) { return { type: 'source', fileName: this._fileName, - line: node.loc.start.line, + line: node.loc.start.line }; } - _nodeLocationString(node: Babel$Node): string { + _nodeLocationString(node) { return `${this._fileName}(${node.loc.start.line})`; } - _error(node: Babel$Node, message: string): Error { + _error(node, message) { return new Error(`${this._nodeLocationString(node)}:${message}`); } - _assert(node, condition, message): void { + _assert(node, condition, message) { if (!condition) { throw this._error(node, message); } @@ -197,25 +206,20 @@ class FileParser { * Performs a quick pass to index the file's exports and imports. * This doesn't actually visit any of the type definitions. */ - parse(source: string): void { + parse(source) { const babylonOptions = { sourceType: 'module', - plugins: [ - 'jsx', - 'flow', - 'exportExtensions', - 'objectRestSpread', - 'classProperties', - 'optionalChaining', - ], + plugins: ['jsx', 'flow', 'exportExtensions', 'objectRestSpread', 'classProperties', 'optionalChaining'] }; const program = memoizedBabylonParse(source, babylonOptions); - invariant( - program && program.type === 'Program', - 'The result of parsing is a Program node.', - ); + + if (!(program && program.type === 'Program')) { + throw new Error('The result of parsing is a Program node.'); + } // Iterate through each node in the program body. + + for (const node of program.body) { switch (node.type) { case 'ExportNamedDeclaration': @@ -229,27 +233,21 @@ class FileParser { // Prevent undeclared function re-exports at service definition // because sans type information we cannot write the RPC method. // e.g. export {someFunction} from './anotherFile'; - throw this._error( - node, - 'Exports without declarations are not supported.', - ); + throw this._error(node, 'Exports without declarations are not supported.'); } } // Only support export type {...} for now. if (node.specifiers != null && node.exportKind === 'type') { node.specifiers.forEach(specifier => { - const {exported, local} = specifier; + const { exported, local } = specifier; this._exports.set(exported.name, specifier); // export type {X as Y} from 'xyz' is equivalent to: // import type {X} from 'xyz'; // export type {X as Y}; - if ( - node.source != null && - typeof node.source.value === 'string' - ) { + if (node.source != null && typeof node.source.value === 'string') { this._imports.set(local.name, { imported: local.name, - file: node.source.value, + file: node.source.value }); } }); @@ -272,17 +270,21 @@ class FileParser { * Dive into the specified export node and visit all its dependencies as * necessary. This may also visit other files (if they're imported). */ - parseExport(serviceParser: ServiceParser, node: Object): void { + parseExport(serviceParser, node) { if (!serviceParser.visitExport(node)) { return; } if (node.type === 'ExportSpecifier') { - const {exported, local} = node; + const { exported, local } = node; const imp = this._imports.get(local.name); // It's difficult to resolve types that are defined elsewhere, // but in the same file. An easy workaround is to just export them // where they're defined, anyway. - invariant(imp != null, 'export type {...} only supports imported types.'); + + if (!(imp != null)) { + throw new Error('export type {...} only supports imported types.'); + } + if (exported.name !== imp.imported) { // import type {A as B} from ...; // export type {B as C}; @@ -293,13 +295,17 @@ class FileParser { kind: 'alias', name: exported.name, location: this._locationOfNode(node), - definition: {kind: 'named', name: imp.imported}, + definition: { kind: 'named', name: imp.imported } }); } this._visitImport(serviceParser, imp); return; } - invariant(node.type === 'ExportNamedDeclaration'); + + if (!(node.type === 'ExportNamedDeclaration')) { + throw new Error('Invariant violation: "node.type === \'ExportNamedDeclaration\'"'); + } + const declaration = node.declaration; switch (declaration.type) { // An exported function that can be directly called by a client. @@ -326,32 +332,32 @@ class FileParser { break; // Unknown export declaration. default: - throw this._error( - declaration, - `Unknown declaration type ${declaration.type} in definition body.`, - ); + throw this._error(declaration, `Unknown declaration type ${declaration.type} in definition body.`); } } - _visitImport(serviceParser: ServiceParser, imp: Import): void { - let resolved = resolveFrom(nuclideUri.dirname(this._fileName), imp.file); + _visitImport(serviceParser, imp) { + let resolved = (0, (_resolveFrom || _load_resolveFrom()).default)((_nuclideUri || _load_nuclideUri()).default.dirname(this._fileName), imp.file); // Prioritize .flow files. - if (fs.existsSync(resolved + '.flow')) { + if (_fs.default.existsSync(resolved + '.flow')) { resolved += '.flow'; } const importedFile = getFileParser(resolved); const exportNode = importedFile.getExports().get(imp.imported); - invariant( - exportNode != null, - `Could not find export for ${imp.imported} in ${resolved}`, - ); + + if (!(exportNode != null)) { + throw new Error(`Could not find export for ${imp.imported} in ${resolved}`); + } + importedFile.parseExport(serviceParser, exportNode); } - _parseImport(node: Object): void { + _parseImport(node) { const from = node.source.value; - invariant(typeof from === 'string'); + if (!(typeof from === 'string')) { + throw new Error('Invariant violation: "typeof from === \'string\'"'); + } for (const specifier of node.specifiers) { if (specifier.type === 'ImportSpecifier') { @@ -359,7 +365,7 @@ class FileParser { const local = specifier.local.name; this._imports.set(local, { imported, - file: from, + file: from }); } } @@ -369,31 +375,16 @@ class FileParser { * Helper function that parses an exported function declaration, and returns the function name, * along with a FunctionType object that encodes the argument and return types of the function. */ - _parseFunctionDeclaration( - serviceParser: ServiceParser, - declaration: any, - ): FunctionDefinition { + _parseFunctionDeclaration(serviceParser, declaration) { // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) if (this._fileType === 'import') { throw this._error(declaration, 'Exported function in imported RPC file'); } - this._assert( - declaration, - declaration.id && declaration.id.type === 'Identifier', - 'Remote function declarations must have an identifier.', - ); - this._assert( - declaration, - declaration.returnType != null && - declaration.returnType.type === 'TypeAnnotation', - 'Remote functions must be annotated with a return type.', - ); + this._assert(declaration, declaration.id && declaration.id.type === 'Identifier', 'Remote function declarations must have an identifier.'); + this._assert(declaration, declaration.returnType != null && declaration.returnType.type === 'TypeAnnotation', 'Remote functions must be annotated with a return type.'); - const returnType = this._parseTypeAnnotation( - serviceParser, - declaration.returnType.typeAnnotation, - ); + const returnType = this._parseTypeAnnotation(serviceParser, declaration.returnType.typeAnnotation); return serviceParser.addDefinition({ kind: 'function', @@ -402,11 +393,9 @@ class FileParser { type: { location: this._locationOfNode(declaration), kind: 'function', - argumentTypes: declaration.params.map(param => - this._parseParameter(serviceParser, param), - ), - returnType, - }, + argumentTypes: declaration.params.map(param => this._parseParameter(serviceParser, param)), + returnType + } }); } @@ -414,20 +403,13 @@ class FileParser { * Helper function that parses an exported type alias, and returns the name of the alias, * along with the type that it refers to. */ - _parseTypeAlias( - serviceParser: ServiceParser, - declaration: any, - ): AliasDefinition { - this._assert( - declaration, - declaration.type === 'TypeAlias', - 'parseTypeAlias accepts a TypeAlias node.', - ); + _parseTypeAlias(serviceParser, declaration) { + this._assert(declaration, declaration.type === 'TypeAlias', 'parseTypeAlias accepts a TypeAlias node.'); return serviceParser.addDefinition({ kind: 'alias', location: this._locationOfNode(declaration), name: declaration.id.name, - definition: this._parseTypeAnnotation(serviceParser, declaration.right), + definition: this._parseTypeAnnotation(serviceParser, declaration.right) }); } @@ -435,63 +417,45 @@ class FileParser { * Parse a ClassDeclaration AST Node. * @param declaration - The AST node. */ - _parseClassDeclaration( - serviceParser: ServiceParser, - declaration: Object, - ): InterfaceDefinition { + _parseClassDeclaration(serviceParser, declaration) { // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) if (this._fileType === 'import') { throw this._error(declaration, 'Exported class in imported RPC file'); } - const def: InterfaceDefinition = { + const def = { kind: 'interface', name: declaration.id.name, location: this._locationOfNode(declaration), staticMethods: {}, - instanceMethods: {}, + instanceMethods: {} }; const classBody = declaration.body; for (const method of classBody.body) { if (method.kind !== 'constructor') { if (!isPrivateMemberName(method.key.name)) { - const {name, type} = this._parseClassMethod(serviceParser, method); + const { name, type } = this._parseClassMethod(serviceParser, method); const isStatic = Boolean(method.static); this._validateMethod(method, name, type, isStatic); - this._defineMethod( - name, - type, - isStatic ? def.staticMethods : def.instanceMethods, - ); + this._defineMethod(name, type, isStatic ? def.staticMethods : def.instanceMethods); } } } if (!def.instanceMethods.hasOwnProperty('dispose')) { - throw this._error( - declaration, - 'Remotable interfaces must include a dispose method', - ); + throw this._error(declaration, 'Remotable interfaces must include a dispose method'); } return serviceParser.addDefinition(def); } - _validateMethod( - node: Babel$Node, - name: string, - type: FunctionType, - isStatic: boolean, - ): void { + _validateMethod(node, name, type, isStatic) { if (name === 'dispose' && !isStatic) { // Validate dispose method has a reasonable signature if (type.argumentTypes.length > 0) { throw this._error(node, 'dispose method may not take arguments'); } if (!isValidDisposeReturnType(type.returnType)) { - throw this._error( - node, - 'dispose method must return either void or Promise', - ); + throw this._error(node, 'dispose method must return either void or Promise'); } } } @@ -500,56 +464,46 @@ class FileParser { * Parse a InterfaceDeclaration AST Node. * @param declaration - The AST node. */ - _parseInterfaceDeclaration( - serviceParser: ServiceParser, - declaration: Object, - ): InterfaceDefinition { - const def: InterfaceDefinition = { + _parseInterfaceDeclaration(serviceParser, declaration) { + const def = { kind: 'interface', name: declaration.id.name, location: this._locationOfNode(declaration), staticMethods: {}, - instanceMethods: {}, + instanceMethods: {} }; - invariant(declaration.body.type === 'ObjectTypeAnnotation'); + if (!(declaration.body.type === 'ObjectTypeAnnotation')) { + throw new Error('Invariant violation: "declaration.body.type === \'ObjectTypeAnnotation\'"'); + } + const properties = declaration.body.properties; for (const property of properties) { - invariant(property.type === 'ObjectTypeProperty'); + if (!(property.type === 'ObjectTypeProperty')) { + throw new Error('Invariant violation: "property.type === \'ObjectTypeProperty\'"'); + } if (!isPrivateMemberName(property.key.name)) { - const {name, type} = this._parseInterfaceClassMethod( - serviceParser, - property, - ); - invariant( - !property.static, - 'static interface members are a parse error', - ); + const { name, type } = this._parseInterfaceClassMethod(serviceParser, property); + + if (!!property.static) { + throw new Error('static interface members are a parse error'); + } + this._validateMethod(property, name, type, false); this._defineMethod(name, type, def.instanceMethods); } } if (!def.instanceMethods.hasOwnProperty('dispose')) { - throw this._error( - declaration, - 'Remotable interfaces must include a dispose method', - ); + throw this._error(declaration, 'Remotable interfaces must include a dispose method'); } return serviceParser.addDefinition(def); } - _defineMethod( - name: string, - type: FunctionType, - peers: {[name: string]: FunctionType}, - ): void { + _defineMethod(name, type, peers) { if (peers.hasOwnProperty(name)) { const peer = peers[name]; - throw errorLocations( - [type.location, peer.location], - `Duplicate method definition ${name}`, - ); + throw errorLocations([type.location, peer.location], `Duplicate method definition ${name}`); } else { peers[name] = type; } @@ -561,41 +515,21 @@ class FileParser { * @returns A record containing the name of the method, and a FunctionType object * encoding the arguments and return type of the method. */ - _parseClassMethod( - serviceParser: ServiceParser, - definition: any, - ): {name: string, type: FunctionType} { - this._assert( - definition, - definition.type === 'ClassMethod', - 'This is a ClassMethod object.', - ); - this._assert( - definition, - definition.key && definition.key.type === 'Identifier', - 'This method defintion has an key (a name).', - ); - this._assert( - definition, - definition.returnType && definition.returnType.type === 'TypeAnnotation', - `${definition.key.name} missing a return type annotation.`, - ); - - const returnType = this._parseTypeAnnotation( - serviceParser, - definition.returnType.typeAnnotation, - ); + _parseClassMethod(serviceParser, definition) { + this._assert(definition, definition.type === 'ClassMethod', 'This is a ClassMethod object.'); + this._assert(definition, definition.key && definition.key.type === 'Identifier', 'This method defintion has an key (a name).'); + this._assert(definition, definition.returnType && definition.returnType.type === 'TypeAnnotation', `${definition.key.name} missing a return type annotation.`); + + const returnType = this._parseTypeAnnotation(serviceParser, definition.returnType.typeAnnotation); return { location: this._locationOfNode(definition.key), name: definition.key.name, type: { location: this._locationOfNode(definition), kind: 'function', - argumentTypes: definition.params.map(param => - this._parseParameter(serviceParser, param), - ), - returnType, - }, + argumentTypes: definition.params.map(param => this._parseParameter(serviceParser, param)), + returnType + } }; } @@ -606,36 +540,22 @@ class FileParser { * @returns A record containing the name of the method, and a FunctionType object * encoding the arguments and return type of the method. */ - _parseInterfaceClassMethod( - serviceParser: ServiceParser, - definition: any, - ): {name: string, type: FunctionType} { - this._assert( - definition, - definition.type === 'ObjectTypeProperty', - 'This is a ObjectTypeProperty object.', - ); - this._assert( - definition, - definition.key && definition.key.type === 'Identifier', - 'This method definition has an key (a name).', - ); - this._assert( - definition, - definition.value.returnType != null, - `${definition.key.name} missing a return type annotation.`, - ); - const returnType = this._parseTypeAnnotation( - serviceParser, - definition.value.returnType, - ); - invariant(typeof definition.key.name === 'string'); - invariant(typeof definition.optional === 'boolean'); + _parseInterfaceClassMethod(serviceParser, definition) { + this._assert(definition, definition.type === 'ObjectTypeProperty', 'This is a ObjectTypeProperty object.'); + this._assert(definition, definition.key && definition.key.type === 'Identifier', 'This method definition has an key (a name).'); + this._assert(definition, definition.value.returnType != null, `${definition.key.name} missing a return type annotation.`); + const returnType = this._parseTypeAnnotation(serviceParser, definition.value.returnType); + + if (!(typeof definition.key.name === 'string')) { + throw new Error('Invariant violation: "typeof definition.key.name === \'string\'"'); + } + + if (!(typeof definition.optional === 'boolean')) { + throw new Error('Invariant violation: "typeof definition.optional === \'boolean\'"'); + } + if (definition.optional) { - throw this._error( - definition, - `${definition.key.name} optional interface methods are not supported.`, - ); + throw this._error(definition, `${definition.key.name} optional interface methods are not supported.`); } return { location: this._locationOfNode(definition.key), @@ -643,81 +563,67 @@ class FileParser { type: { location: this._locationOfNode(definition.value), kind: 'function', - argumentTypes: definition.value.params.map(param => - this._parseInterfaceParameter(serviceParser, param), - ), - returnType, - }, + argumentTypes: definition.value.params.map(param => this._parseInterfaceParameter(serviceParser, param)), + returnType + } }; } - _parseInterfaceParameter( - serviceParser: ServiceParser, - param: Object, - ): Parameter { + _parseInterfaceParameter(serviceParser, param) { if (!param.typeAnnotation) { - throw this._error( - param, - `Parameter ${param.name} doesn't have type annotation.`, - ); + throw this._error(param, `Parameter ${param.name} doesn't have type annotation.`); } else { const name = param.name.name; - invariant(typeof name === 'string'); - const type = this._parseTypeAnnotation( - serviceParser, - param.typeAnnotation, - ); + + if (!(typeof name === 'string')) { + throw new Error('Invariant violation: "typeof name === \'string\'"'); + } + + const type = this._parseTypeAnnotation(serviceParser, param.typeAnnotation); if (param.optional && type.kind !== 'nullable') { return { name, type: { kind: 'nullable', - type, - }, + type + } }; } else { return { name, - type, + type }; } } } - _parseParameter(serviceParser: ServiceParser, param: Object): Parameter { + _parseParameter(serviceParser, param) { // Parameter with a default type, e.g. (x: number = 1). // Babel's transpiled implementation will take care of actually setting the default. if (param.type === 'AssignmentPattern') { - return this._parseParameter(serviceParser, { - ...param.left, + return this._parseParameter(serviceParser, Object.assign({}, param.left, { // Having a default value implies that it's optional. - optional: true, - }); + optional: true + })); } if (!param.typeAnnotation) { - throw this._error( - param, - `Parameter ${param.name} doesn't have type annotation.`, - ); + throw this._error(param, `Parameter ${param.name} doesn't have type annotation.`); } else { const name = param.name; - const type = this._parseTypeAnnotation( - serviceParser, - param.typeAnnotation.typeAnnotation, - ); + const type = this._parseTypeAnnotation(serviceParser, param.typeAnnotation.typeAnnotation); if (param.optional && type.kind !== 'nullable') { return { name, type: { kind: 'nullable', - type, - }, + type + } }; } else { return { name, - type, + type }; } } @@ -727,82 +633,67 @@ class FileParser { * Helper function that parses a Flow type annotation into our intermediate format. * @returns {Type} A representation of the type. */ - _parseTypeAnnotation( - serviceParser: ServiceParser, - typeAnnotation: Object, - ): Type { + _parseTypeAnnotation(serviceParser, typeAnnotation) { switch (typeAnnotation.type) { case 'AnyTypeAnnotation': - return {kind: 'any'}; + return { kind: 'any' }; case 'MixedTypeAnnotation': - return {kind: 'mixed'}; + return { kind: 'mixed' }; case 'StringTypeAnnotation': - return {kind: 'string'}; + return { kind: 'string' }; case 'NumberTypeAnnotation': - return {kind: 'number'}; + return { kind: 'number' }; case 'BooleanTypeAnnotation': - return {kind: 'boolean'}; + return { kind: 'boolean' }; case 'StringLiteralTypeAnnotation': - return {kind: 'string-literal', value: typeAnnotation.value}; + return { kind: 'string-literal', value: typeAnnotation.value }; case 'NumberLiteralTypeAnnotation': - return {kind: 'number-literal', value: typeAnnotation.value}; + return { kind: 'number-literal', value: typeAnnotation.value }; case 'BooleanLiteralTypeAnnotation': - return {kind: 'boolean-literal', value: typeAnnotation.value}; + return { kind: 'boolean-literal', value: typeAnnotation.value }; case 'NullableTypeAnnotation': return { kind: 'nullable', - type: this._parseTypeAnnotation( - serviceParser, - typeAnnotation.typeAnnotation, - ), + type: this._parseTypeAnnotation(serviceParser, typeAnnotation.typeAnnotation) }; case 'ObjectTypeAnnotation': return { kind: 'object', fields: typeAnnotation.properties.map(prop => { - invariant(prop.type === 'ObjectTypeProperty'); + if (!(prop.type === 'ObjectTypeProperty')) { + throw new Error('Invariant violation: "prop.type === \'ObjectTypeProperty\'"'); + } + return { name: prop.key.name, type: this._parseTypeAnnotation(serviceParser, prop.value), - optional: prop.optional, + optional: prop.optional }; - }), + }) }; case 'VoidTypeAnnotation': - return {kind: 'void'}; + return { kind: 'void' }; case 'TupleTypeAnnotation': return { kind: 'tuple', - types: typeAnnotation.types.map( - this._parseTypeAnnotation.bind(this, serviceParser), - ), + types: typeAnnotation.types.map(this._parseTypeAnnotation.bind(this, serviceParser)) }; case 'UnionTypeAnnotation': return { kind: 'union', - types: typeAnnotation.types.map( - this._parseTypeAnnotation.bind(this, serviceParser), - ), + types: typeAnnotation.types.map(this._parseTypeAnnotation.bind(this, serviceParser)) }; case 'IntersectionTypeAnnotation': return { kind: 'intersection', - types: typeAnnotation.types.map( - this._parseTypeAnnotation.bind(this, serviceParser), - ), + types: typeAnnotation.types.map(this._parseTypeAnnotation.bind(this, serviceParser)) }; case 'GenericTypeAnnotation': return this._parseGenericTypeAnnotation(serviceParser, typeAnnotation); case 'FunctionTypeAnnotation': - throw this._error( - typeAnnotation, - 'Properties that are of a function type are not supported. Use a method instead.', - ); + throw this._error(typeAnnotation, 'Properties that are of a function type are not supported. Use a method instead.'); default: - throw this._error( - typeAnnotation, - `Unknown type annotation ${typeAnnotation.type}.`, - ); + throw this._error(typeAnnotation, `Unknown type annotation ${typeAnnotation.type}.`); } } @@ -810,152 +701,96 @@ class FileParser { * Helper function that parses annotations of type 'GenericTypeAnnotation'. Meant to be called * from parseTypeAnnotation. */ - _parseGenericTypeAnnotation( - serviceParser: ServiceParser, - typeAnnotation, - ): Type { - invariant(typeAnnotation.type === 'GenericTypeAnnotation'); + _parseGenericTypeAnnotation(serviceParser, typeAnnotation) { + if (!(typeAnnotation.type === 'GenericTypeAnnotation')) { + throw new Error('Invariant violation: "typeAnnotation.type === \'GenericTypeAnnotation\'"'); + } + const id = this._parseTypeName(serviceParser, typeAnnotation.id); switch (id) { case 'Array': return { kind: 'array', - type: this._parseGenericTypeParameterOfKnownType( - serviceParser, - id, - typeAnnotation, - ), + type: this._parseGenericTypeParameterOfKnownType(serviceParser, id, typeAnnotation) }; case 'Set': return { kind: 'set', - type: this._parseGenericTypeParameterOfKnownType( - serviceParser, - id, - typeAnnotation, - ), + type: this._parseGenericTypeParameterOfKnownType(serviceParser, id, typeAnnotation) }; case 'Promise': return { kind: 'promise', - type: this._parseGenericTypeParameterOfKnownType( - serviceParser, - id, - typeAnnotation, - ), + type: this._parseGenericTypeParameterOfKnownType(serviceParser, id, typeAnnotation) }; case 'ConnectableObservable': return { kind: 'observable', - type: this._parseGenericTypeParameterOfKnownType( - serviceParser, - id, - typeAnnotation, - ), + type: this._parseGenericTypeParameterOfKnownType(serviceParser, id, typeAnnotation) }; case 'Map': - this._assert( - typeAnnotation, - typeAnnotation.typeParameters != null && - typeAnnotation.typeParameters.params.length === 2, - `${id} takes exactly two type parameters.`, - ); + this._assert(typeAnnotation, typeAnnotation.typeParameters != null && typeAnnotation.typeParameters.params.length === 2, `${id} takes exactly two type parameters.`); return { kind: 'map', - keyType: this._parseTypeAnnotation( - serviceParser, - typeAnnotation.typeParameters.params[0], - ), - valueType: this._parseTypeAnnotation( - serviceParser, - typeAnnotation.typeParameters.params[1], - ), + keyType: this._parseTypeAnnotation(serviceParser, typeAnnotation.typeParameters.params[0]), + valueType: this._parseTypeAnnotation(serviceParser, typeAnnotation.typeParameters.params[1]) }; default: - this._assert( - typeAnnotation, - id !== 'Observable', - 'Use of Observable in RPC interface. Use ConnectableObservable instead.', - ); + this._assert(typeAnnotation, id !== 'Observable', 'Use of Observable in RPC interface. Use ConnectableObservable instead.'); // Named types are represented as Generic types with no type parameters. - this._assert( - typeAnnotation, - typeAnnotation.typeParameters == null, - `Unknown generic type ${id}.`, - ); + this._assert(typeAnnotation, typeAnnotation.typeParameters == null, `Unknown generic type ${id}.`); if (!serviceParser.hasDefinition(id)) { const imp = this._imports.get(id); if (imp != null) { this._visitImport(serviceParser, imp); if (id !== imp.imported) { - return {kind: 'named', name: imp.imported}; + return { kind: 'named', name: imp.imported }; } } else { const exportNode = this._exports.get(id); if (exportNode == null) { - throw errorLocations( - [this._locationOfNode(typeAnnotation)], - `Type ${id} should be exported from ${this._fileName}.`, - ); + throw errorLocations([this._locationOfNode(typeAnnotation)], `Type ${id} should be exported from ${this._fileName}.`); } this.parseExport(serviceParser, exportNode); } } } - return {kind: 'named', name: id}; + return { kind: 'named', name: id }; } - _parseGenericTypeParameterOfKnownType( - serviceParser: ServiceParser, - id: string, - typeAnnotation: Object, - ): Type { - this._assert( - typeAnnotation, - typeAnnotation.typeParameters != null && - typeAnnotation.typeParameters.params.length === 1, - `${id} has exactly one type parameter.`, - ); - return this._parseTypeAnnotation( - serviceParser, - typeAnnotation.typeParameters.params[0], - ); + _parseGenericTypeParameterOfKnownType(serviceParser, id, typeAnnotation) { + this._assert(typeAnnotation, typeAnnotation.typeParameters != null && typeAnnotation.typeParameters.params.length === 1, `${id} has exactly one type parameter.`); + return this._parseTypeAnnotation(serviceParser, typeAnnotation.typeParameters.params[0]); } /** * Type names may either be simple Identifiers, or they may be * qualified identifiers. */ - _parseTypeName(serviceParser: ServiceParser, type: Object): string { + _parseTypeName(serviceParser, type) { switch (type.type) { case 'Identifier': return type.name; case 'QualifiedTypeIdentifier': - invariant(type.id.type === 'Identifier'); - return `${this._parseTypeName(serviceParser, type.qualification)}.${ - type.id.name - }`; + if (!(type.id.type === 'Identifier')) { + throw new Error('Invariant violation: "type.id.type === \'Identifier\'"'); + } + + return `${this._parseTypeName(serviceParser, type.qualification)}.${type.id.name}`; default: throw this._error(type, `Expected named type. Found ${type.type}`); } } } -function errorLocations(locations: Array, message: string): Error { - let fullMessage = `${locationToString(locations[0])}:${message}`; - fullMessage = fullMessage.concat( - ...locations - .slice(1) - .map(location => `\n${locationToString(location)}: Related location`), - ); +function errorLocations(locations, message) { + let fullMessage = `${(0, (_location || _load_location()).locationToString)(locations[0])}:${message}`; + fullMessage = fullMessage.concat(...locations.slice(1).map(location => `\n${(0, (_location || _load_location()).locationToString)(location)}: Related location`)); return new Error(fullMessage); } -function isValidDisposeReturnType(type: Type): boolean { - return ( - type.kind === 'void' || - (type.kind === 'promise' && type.type.kind === 'void') - ); -} +function isValidDisposeReturnType(type) { + return type.kind === 'void' || type.kind === 'promise' && type.type.kind === 'void'; +} \ No newline at end of file diff --git a/pkg/nuclide-rpc/lib/types.js b/pkg/nuclide-rpc/lib/types.js index 025918fd99..a726efc43f 100644 --- a/pkg/nuclide-rpc/lib/types.js +++ b/pkg/nuclide-rpc/lib/types.js @@ -1,187 +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 strict - * @format - */ - -export type ReturnType = 'promise' | 'observable' | 'void'; - -/** - * `Definitions` encodes all of the information in a service definition file that is required to - * generate a remote proxy. - */ -export type Definitions = {[name: string]: Definition}; - -export type Definition = - | FunctionDefinition - | InterfaceDefinition - | AliasDefinition; - -// A top level function. -export type FunctionDefinition = { - kind: 'function', - name: string, - location: Location, - type: FunctionType, -}; - -export type Parameter = { - name: string, - type: Type, -}; - -// An interface class. -export type InterfaceDefinition = { - kind: 'interface', - name: string, - location: Location, - instanceMethods: {[name: string]: FunctionType}, - staticMethods: {[name: string]: FunctionType}, -}; - -// A type alias. -export type AliasDefinition = { - kind: 'alias', - name: string, - location: Location, - definition?: Type, -}; - -export type Type = - | NullableType - | MixedType - | AnyType - | StringType - | BooleanType - | NumberType // Primitive types. - | ObjectType - | ArrayType - | MapType - | SetType - | TupleType // Container types. - | VoidType - | PromiseType - | ObservableType // Return types. - | StringLiteralType - | NumberLiteralType - | BooleanLiteralType // Literal types. - | NamedType - | FunctionType - | UnionType - | IntersectionType; // Type aliases. - -// Nullable type. -export type NullableType = {kind: 'nullable', type: Type}; - -// Functions. -export type FunctionType = { - kind: 'function', - // Preserve locations for function types, since methods don't have definitions. - location: Location, - argumentTypes: Array, - returnType: Type, -}; - -// Primitive types. -export type AnyType = {kind: 'any'}; -export type MixedType = {kind: 'mixed'}; -export type StringType = {kind: 'string'}; -export type BooleanType = {kind: 'boolean'}; -export type NumberType = {kind: 'number'}; - -// Literal types. -export type LiteralType = - | StringLiteralType - | NumberLiteralType - | BooleanLiteralType; -export type StringLiteralType = { - kind: 'string-literal', - value: string, -}; -export type NumberLiteralType = { - kind: 'number-literal', - value: number, -}; -export type BooleanLiteralType = { - kind: 'boolean-literal', - value: boolean, -}; - -// Possible Return formats. -export type VoidType = {kind: 'void'}; -export type PromiseType = {kind: 'promise', type: Type}; -export type ObservableType = { - kind: 'observable', - type: Type, -}; - -// Container Types. -export type ArrayType = {kind: 'array', type: Type}; -export type SetType = {kind: 'set', type: Type}; -export type MapType = { - kind: 'map', - keyType: Type, - valueType: Type, -}; -export type ObjectType = { - kind: 'object', - fields: Array, -}; -export type ObjectField = { - name: string, - type: Type, - optional: boolean, -}; -export type TupleType = {kind: 'tuple', types: Array}; - -export type UnionType = { - kind: 'union', - types: Array, - discriminantField?: string, // This is filled in for unions of object types during validation. -}; - -export type IntersectionType = { - kind: 'intersection', - types: Array, - // Filled in during validation -- this is the flattened object type containing all of the relevant - // fields. - flattened?: ObjectType, -}; - -// Represents a named, custom type. -export type NamedType = {kind: 'named', name: string}; - -export type Location = SourceLocation | BuiltinLocation; - -export type SourceLocation = { - type: 'source', - fileName: string, - line: number, -}; - -export type BuiltinLocation = { - type: 'builtin', -}; - -export type ReturnKind = 'promise' | 'observable' | 'void'; - -// Babel Definitions -// TODO: Move these to external-interfaces package. - -export type Babel$Node = { - loc: Babel$Range, -}; - -export type Babel$Range = { - start: Babel$Location, - end: Babel$Location, -}; - -export type Babel$Location = { - line: number, -}; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-server/lib/NuclideServer.js b/pkg/nuclide-server/lib/NuclideServer.js index 9217dda56f..9954d3bf93 100644 --- a/pkg/nuclide-server/lib/NuclideServer.js +++ b/pkg/nuclide-server/lib/NuclideServer.js @@ -1,3 +1,89 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.HEARTBEAT_CHANNEL = undefined; + +var _os = _interopRequireDefault(require('os')); + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _ws; + +function _load_ws() { + return _ws = _interopRequireDefault(require('ws')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _blocked; + +function _load_blocked() { + return _blocked = _interopRequireDefault(require('./blocked')); +} + +var _QueuedAckTransport; + +function _load_QueuedAckTransport() { + return _QueuedAckTransport = require('../../../modules/big-dig/src/socket/QueuedAckTransport'); +} + +var _utils; + +function _load_utils() { + return _utils = require('./utils'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _nuclideVersion; + +function _load_nuclideVersion() { + return _nuclideVersion = require('../../nuclide-version'); +} + +var _nuclideLogging; + +function _load_nuclideLogging() { + return _nuclideLogging = require('../../nuclide-logging'); +} + +var _nuclideRpc; + +function _load_nuclideRpc() { + return _nuclideRpc = require('../../nuclide-rpc'); +} + +var _WebSocketTransport; + +function _load_WebSocketTransport() { + return _WebSocketTransport = require('../../../modules/big-dig/src/socket/WebSocketTransport'); +} + +var _nuclideMarshalersCommon; + +function _load_nuclideMarshalersCommon() { + return _nuclideMarshalersCommon = require('../../nuclide-marshalers-common'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const HEARTBEAT_CHANNEL = exports.HEARTBEAT_CHANNEL = 'heartbeat'; + +// eslint-disable-next-line nuclide-internal/no-commonjs /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,65 +91,27 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {ConfigEntry} from '../../nuclide-rpc'; +const connect = require('connect'); +// eslint-disable-next-line nuclide-internal/no-commonjs +const http = require('http'); +// eslint-disable-next-line nuclide-internal/no-commonjs +const https = require('https'); -import invariant from 'assert'; -import os from 'os'; -import {getLogger} from 'log4js'; -import WS from 'ws'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-server'); -import blocked from './blocked'; -import {QueuedAckTransport} from 'big-dig/src/socket/QueuedAckTransport'; -import {deserializeArgs, sendJsonResponse, sendTextResponse} from './utils'; -import {HistogramTracker} from '../../nuclide-analytics'; -import {getVersion} from '../../nuclide-version'; -import {flushLogsAndExit} from '../../nuclide-logging'; -import {RpcConnection, ServiceRegistry} from '../../nuclide-rpc'; -import {WebSocketTransport} from 'big-dig/src/socket/WebSocketTransport'; -import {getServerSideMarshalers} from '../../nuclide-marshalers-common'; -import {protocolLogger} from './utils'; -import {track} from '../../nuclide-analytics'; +class NuclideServer { -export const HEARTBEAT_CHANNEL = 'heartbeat'; + constructor(options, services) { + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + + if (!(NuclideServer._theServer == null)) { + throw new Error('Invariant violation: "NuclideServer._theServer == null"'); + } -// eslint-disable-next-line nuclide-internal/no-commonjs -const connect: connect$module = require('connect'); -// eslint-disable-next-line nuclide-internal/no-commonjs -const http: http$fixed = (require('http'): any); -// eslint-disable-next-line nuclide-internal/no-commonjs -const https: https$fixed = (require('https'): any); - -const logger = getLogger('nuclide-server'); - -type NuclideServerOptions = { - port: number, - serverKey?: Buffer, - serverCertificate?: Buffer, - certificateAuthorityCertificate?: Buffer, - trackEventLoop?: boolean, -}; - -export default class NuclideServer { - static _theServer: ?NuclideServer; - static _shutdownCallbacks: Set<() => void> = new Set(); - - _webServer: http$fixed$Server; - _webSocketServer: WS.Server; - _clients: Map>; - _port: number; - _app: connect$Server; - _xhrServiceRegistry: {[serviceName: string]: () => any}; - _version: string; - _rpcServiceRegistry: ServiceRegistry; - _disposables: UniversalDisposable = new UniversalDisposable(); - - constructor(options: NuclideServerOptions, services: Array) { - invariant(NuclideServer._theServer == null); NuclideServer._theServer = this; const { @@ -71,22 +119,20 @@ export default class NuclideServer { serverCertificate, port, certificateAuthorityCertificate, - trackEventLoop, + trackEventLoop } = options; - this._version = getVersion().toString(); + this._version = (0, (_nuclideVersion || _load_nuclideVersion()).getVersion)().toString(); this._app = connect(); this._attachUtilHandlers(); - const isHttps = Boolean( - serverKey && serverCertificate && certificateAuthorityCertificate, - ); + const isHttps = Boolean(serverKey && serverCertificate && certificateAuthorityCertificate); if (isHttps) { const webServerOptions = { key: serverKey, cert: serverCertificate, ca: certificateAuthorityCertificate, requestCert: true, - rejectUnauthorized: true, + rejectUnauthorized: true }; this._webServer = https.createServer(webServerOptions, this._app); @@ -101,26 +147,18 @@ export default class NuclideServer { this._setupServices(); // Setup 1.0 and 2.0 services. if (trackEventLoop) { - const stallTracker = new HistogramTracker( - 'server-event-loop-blocked', - /* max */ 1000, - /* buckets */ 10, - ); - this._disposables.add( - stallTracker, - blocked((ms: number) => { - stallTracker.track(ms); - logger.info('NuclideServer event loop blocked for ' + ms + 'ms'); - }), - ); + const stallTracker = new (_nuclideAnalytics || _load_nuclideAnalytics()).HistogramTracker('server-event-loop-blocked', + /* max */1000, + /* buckets */10); + this._disposables.add(stallTracker, (0, (_blocked || _load_blocked()).default)(ms => { + stallTracker.track(ms); + logger.info('NuclideServer event loop blocked for ' + ms + 'ms'); + })); } - this._rpcServiceRegistry = new ServiceRegistry( - getServerSideMarshalers, - services, - ); + this._rpcServiceRegistry = new (_nuclideRpc || _load_nuclideRpc()).ServiceRegistry((_nuclideMarshalersCommon || _load_nuclideMarshalersCommon()).getServerSideMarshalers, services); - track('server-created', {port, isHttps, host: os.hostname()}); + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('server-created', { port, isHttps, host: _os.default.hostname() }); } _attachUtilHandlers() { @@ -140,17 +178,13 @@ export default class NuclideServer { }); } - _createWebSocketServer(): WS.Server { - const webSocketServer = new WS.Server({ + _createWebSocketServer() { + const webSocketServer = new (_ws || _load_ws()).default.Server({ server: this._webServer, - perMessageDeflate: true, + perMessageDeflate: true }); - webSocketServer.on('connection', (socket, req) => - this._onConnection(socket, req), - ); - webSocketServer.on('error', error => - logger.error('WebSocketServer Error:', error), - ); + webSocketServer.on('connection', (socket, req) => this._onConnection(socket, req)); + webSocketServer.on('error', error => logger.error('WebSocketServer Error:', error)); return webSocketServer; } @@ -161,36 +195,20 @@ export default class NuclideServer { this._setupHeartbeatHandler(); // Setup error handler. - this._app.use( - ( - error: ?connect$Error, - request: http$fixed$IncomingMessage, - response: http$fixed$ServerResponse, - next: Function, - ) => { - if (error != null) { - sendJsonResponse( - response, - {code: error.code, message: error.message}, - 500, - ); - } else { - next(); - } - }, - ); + this._app.use((error, request, response, next) => { + if (error != null) { + (0, (_utils || _load_utils()).sendJsonResponse)(response, { code: error.code, message: error.message }, 500); + } else { + next(); + } + }); } _setupHeartbeatHandler() { - this._registerService( - '/' + HEARTBEAT_CHANNEL, - async () => this._version, - 'post', - true, - ); + this._registerService('/' + HEARTBEAT_CHANNEL, async () => this._version, 'post', true); } - static shutdown(): void { + static shutdown() { logger.info('Shutting down the server'); for (const callback of NuclideServer._shutdownCallbacks) { try { @@ -206,30 +224,30 @@ export default class NuclideServer { } catch (e) { logger.error('Error while shutting down, but proceeding anyway:', e); } finally { - flushLogsAndExit(0); + (0, (_nuclideLogging || _load_nuclideLogging()).flushLogsAndExit)(0); } } - static registerShutdownCallback(callback: () => void): IDisposable { + static registerShutdownCallback(callback) { NuclideServer._shutdownCallbacks.add(callback); - return {dispose: () => NuclideServer._shutdownCallbacks.delete(callback)}; + return { dispose: () => NuclideServer._shutdownCallbacks.delete(callback) }; } - static closeConnection(client: RpcConnection): void { + static closeConnection(client) { logger.info(`Closing client: #${client.getTransport().id}`); if (NuclideServer._theServer != null) { NuclideServer._theServer._closeConnection(client); } } - _closeConnection(client: RpcConnection): void { + _closeConnection(client) { if (this._clients.get(client.getTransport().id) === client) { this._clients.delete(client.getTransport().id); client.dispose(); } } - connect(): Promise { + connect() { return new Promise((resolve, reject) => { this._webServer.on('listening', () => { resolve(); @@ -245,7 +263,7 @@ export default class NuclideServer { /** * Calls a registered service with a name and arguments. */ - callService(serviceName: string, args: Array): Promise { + callService(serviceName, args) { const serviceFunction = this._xhrServiceRegistry[serviceName]; if (!serviceFunction) { throw new Error('No service registered with name: ' + serviceName); @@ -258,76 +276,59 @@ export default class NuclideServer { * This allows simple future calls of the service by name and arguments or http-triggered * endpoint calls with arguments serialized over http. */ - _registerService( - serviceName: string, - serviceFunction: () => Promise, - method: string, - isTextResponse: boolean, - ) { + _registerService(serviceName, serviceFunction, method, isTextResponse) { if (this._xhrServiceRegistry[serviceName]) { - throw new Error( - 'A service with this name is already registered: ' + serviceName, - ); + throw new Error('A service with this name is already registered: ' + serviceName); } this._xhrServiceRegistry[serviceName] = serviceFunction; this._registerHttpService(serviceName, method, isTextResponse); } - _registerHttpService( - serviceName: string, - method: string, - isTextResponse: ?boolean, - ) { + _registerHttpService(serviceName, method, isTextResponse) { const loweredCaseMethod = method.toLowerCase(); // $FlowFixMe - Use map instead of computed property. - this._app[loweredCaseMethod]( - serviceName, - async (request, response, next) => { - try { - const result = await this.callService( - serviceName, - deserializeArgs(request.url), - ); - if (isTextResponse) { - sendTextResponse(response, result || ''); - } else { - sendJsonResponse(response, result); - } - } catch (e) { - // Delegate to the registered connect error handler. - next(e); + this._app[loweredCaseMethod](serviceName, async (request, response, next) => { + try { + const result = await this.callService(serviceName, (0, (_utils || _load_utils()).deserializeArgs)(request.url)); + if (isTextResponse) { + (0, (_utils || _load_utils()).sendTextResponse)(response, result || ''); + } else { + (0, (_utils || _load_utils()).sendJsonResponse)(response, result); } - }, - ); + } catch (e) { + // Delegate to the registered connect error handler. + next(e); + } + }); } - _onConnection(socket: WS, req: http$IncomingMessage): void { + _onConnection(socket, req) { logger.debug('WebSocket connecting'); const clientId = req.headers.client_id; logger.info(`received client_id in header ${clientId}`); - let client: ?RpcConnection = null; + let client = null; client = this._clients.get(clientId); - const transport = new WebSocketTransport(clientId, socket); + const transport = new (_WebSocketTransport || _load_WebSocketTransport()).WebSocketTransport(clientId, socket); if (client == null) { - client = RpcConnection.createServer( - this._rpcServiceRegistry, - new QueuedAckTransport(clientId, transport, protocolLogger), - {}, - clientId, - protocolLogger, - ); + client = (_nuclideRpc || _load_nuclideRpc()).RpcConnection.createServer(this._rpcServiceRegistry, new (_QueuedAckTransport || _load_QueuedAckTransport()).QueuedAckTransport(clientId, transport, (_utils || _load_utils()).protocolLogger), {}, clientId, (_utils || _load_utils()).protocolLogger); this._clients.set(clientId, client); } else { - invariant(clientId === client.getTransport().id); + if (!(clientId === client.getTransport().id)) { + throw new Error('Invariant violation: "clientId === client.getTransport().id"'); + } + client.getTransport().reconnect(transport); } } close() { - invariant(NuclideServer._theServer === this); + if (!(NuclideServer._theServer === this)) { + throw new Error('Invariant violation: "NuclideServer._theServer === this"'); + } + NuclideServer._theServer = null; this._disposables.dispose(); @@ -335,3 +336,5 @@ export default class NuclideServer { this._webServer.close(); } } +exports.default = NuclideServer; +NuclideServer._shutdownCallbacks = new Set(); \ No newline at end of file diff --git a/pkg/nuclide-server/lib/blocked.js b/pkg/nuclide-server/lib/blocked.js index e7cc7417c6..6adcfaa02b 100644 --- a/pkg/nuclide-server/lib/blocked.js +++ b/pkg/nuclide-server/lib/blocked.js @@ -1,15 +1,17 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = blocked; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Copy of the npm package: blocked, but without the unref, because that doesn't work in apm tests. @@ -19,14 +21,10 @@ import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; * @return the interval handler. * To cancel, call clearInterval on the returned interval handler. */ -export default function blocked( - fn: (ms: number) => void, - intervalMs: number = 100, - thresholdMs: number = 50, -): IDisposable { +function blocked(fn, intervalMs = 100, thresholdMs = 50) { let start = Date.now(); - const interval: any = setInterval(() => { + const interval = setInterval(() => { const deltaMs = Date.now() - start; const blockTimeMs = deltaMs - intervalMs; if (blockTimeMs > thresholdMs) { @@ -35,5 +33,14 @@ export default function blocked( start = Date.now(); }, intervalMs); - return new UniversalDisposable(() => clearInterval(interval)); -} + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => clearInterval(interval)); +} /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-server/lib/main.js b/pkg/nuclide-server/lib/main.js index bac9c98c17..011f1d756c 100644 --- a/pkg/nuclide-server/lib/main.js +++ b/pkg/nuclide-server/lib/main.js @@ -1,45 +1,71 @@ -/** - * 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 - */ - -import fsPromise from 'nuclide-commons/fsPromise'; -import { - flushLogsAndAbort, - flushLogsAndExit, - initializeLogging, -} from '../../nuclide-logging'; -import {startTracking} from '../../nuclide-analytics'; - -import NuclideServer from './NuclideServer'; -import servicesConfig from './servicesConfig'; - -import yargs from 'yargs'; -import {getLogger} from 'log4js'; - -const DEFAULT_PORT = 9090; - -const logger = getLogger('nuclide-server'); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideLogging; + +function _load_nuclideLogging() { + return _nuclideLogging = require('../../nuclide-logging'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _NuclideServer; + +function _load_NuclideServer() { + return _NuclideServer = _interopRequireDefault(require('./NuclideServer')); +} + +var _servicesConfig; + +function _load_servicesConfig() { + return _servicesConfig = _interopRequireDefault(require('./servicesConfig')); +} + +var _yargs; + +function _load_yargs() { + return _yargs = _interopRequireDefault(require('yargs')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const DEFAULT_PORT = 9090; /** + * 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. + * + * + * @format + */ + +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-server'); async function getServerCredentials(args) { - const {key, cert, ca} = args; + const { key, cert, ca } = args; if (key && cert && ca) { - const [ - serverKey, - serverCertificate, - certificateAuthorityCertificate, - ] = await Promise.all([ - fsPromise.readFile(key), - fsPromise.readFile(cert), - fsPromise.readFile(ca), - ]); - return {serverKey, serverCertificate, certificateAuthorityCertificate}; + const [serverKey, serverCertificate, certificateAuthorityCertificate] = await Promise.all([(_fsPromise || _load_fsPromise()).default.readFile(key), (_fsPromise || _load_fsPromise()).default.readFile(cert), (_fsPromise || _load_fsPromise()).default.readFile(ca)]); + return { serverKey, serverCertificate, certificateAuthorityCertificate }; } return null; } @@ -48,27 +74,22 @@ async function main(args) { let serverStartTimer; try { process.on('SIGHUP', () => {}); - initializeLogging(); - serverStartTimer = startTracking('nuclide-server:start'); + (0, (_nuclideLogging || _load_nuclideLogging()).initializeLogging)(); + serverStartTimer = (0, (_nuclideAnalytics || _load_nuclideAnalytics()).startTracking)('nuclide-server:start'); - const {port, expirationDays} = args; + const { port, expirationDays } = args; if (expirationDays) { setTimeout(() => { - logger.warn( - `NuclideServer exiting - ${expirationDays} day expiration time reached.`, - ); - flushLogsAndExit(0); + logger.warn(`NuclideServer exiting - ${expirationDays} day expiration time reached.`); + (0, (_nuclideLogging || _load_nuclideLogging()).flushLogsAndExit)(0); }, expirationDays * 24 * 60 * 60 * 1000); } const serverCredentials = await getServerCredentials(args); - const server = new NuclideServer( - { - port, - ...serverCredentials, - trackEventLoop: true, - }, - servicesConfig, - ); + const server = new (_NuclideServer || _load_NuclideServer()).default(Object.assign({ + port + }, serverCredentials, { + trackEventLoop: true + }), (_servicesConfig || _load_servicesConfig()).default); await server.connect(); serverStartTimer.onSuccess(); logger.info(`NuclideServer started on port ${port}.`); @@ -79,7 +100,7 @@ async function main(args) { serverStartTimer.onError(e); } logger.fatal(e); - flushLogsAndAbort(); + (0, (_nuclideLogging || _load_nuclideLogging()).flushLogsAndAbort)(); } } @@ -93,7 +114,7 @@ process.on('uncaughtException', err => { logger.fatal('uncaughtException:', err); // According to the docs, we need to close our server when this happens once we logged or // handled it: https://nodejs.org/api/process.html#process_event_uncaughtexception - flushLogsAndAbort(); + (0, (_nuclideLogging || _load_nuclideLogging()).flushLogsAndAbort)(); }); // This works in io.js as of v2.4.0 (possibly earlier versions, as well). Support for this was @@ -107,9 +128,8 @@ process.on('unhandledRejection', (error, promise) => { logger.error(`Unhandled promise rejection ${promise}. Error:`, error); }); -const argv = yargs.default('port', DEFAULT_PORT).argv; +const argv = (_yargs || _load_yargs()).default.default('port', DEFAULT_PORT).argv; main(argv); -// Make it clear that this is not a types module by adding an empty export. -export {}; +// Make it clear that this is not a types module by adding an empty export. \ No newline at end of file diff --git a/pkg/nuclide-server/lib/services/FileSystemService.js b/pkg/nuclide-server/lib/services/FileSystemService.js index 713ad08dac..791b887c64 100644 --- a/pkg/nuclide-server/lib/services/FileSystemService.js +++ b/pkg/nuclide-server/lib/services/FileSystemService.js @@ -1,3 +1,81 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.exists = exists; +exports.findNearestAncestorNamed = findNearestAncestorNamed; +exports.findFilesInDirectories = findFilesInDirectories; +exports.lstat = lstat; +exports.mkdir = mkdir; +exports.mkdirp = mkdirp; +exports.chmod = chmod; +exports.newFile = newFile; +exports.readdir = readdir; +exports.readdirSorted = readdirSorted; +exports.realpath = realpath; +exports.resolveRealPath = resolveRealPath; +exports.expandHomeDir = expandHomeDir; +exports.rename = rename; +exports.move = move; +exports.copy = copy; +exports.copyDir = copyDir; +exports.rmdir = rmdir; +exports.rmdirAll = rmdirAll; +exports.stat = stat; +exports.unlink = unlink; +exports.readFile = readFile; +exports.createReadStream = createReadStream; +exports.isNfs = isNfs; +exports.isFuse = isFuse; +exports.writeFile = writeFile; +exports.writeFileBuffer = writeFileBuffer; +exports.getFreeSpace = getFreeSpace; +exports.tempdir = tempdir; + +var _fs = _interopRequireDefault(require('fs')); + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../../../modules/nuclide-commons/fsPromise')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../../modules/nuclide-commons/nuclideUri')); +} + +var _process; + +function _load_process() { + return _process = require('../../../../modules/nuclide-commons/process'); +} + +var _stream; + +function _load_stream() { + return _stream = require('../../../../modules/nuclide-commons/stream'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideFs; + +function _load_nuclideFs() { + return _nuclideFs = require('../../../nuclide-fs'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +//------------------------------------------------------------------------------ +// Services +//------------------------------------------------------------------------------ + +/** + * Checks a certain path for existence and returns 'true'/'false' accordingly + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +83,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ @@ -15,27 +93,8 @@ * readFile, writeFile, etc. */ -import type {ConnectableObservable} from 'rxjs'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {DirectoryEntry, WriteOptions} from '../../../nuclide-fs'; - -import fs from 'fs'; -import fsPromise from 'nuclide-commons/fsPromise'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {runCommand} from 'nuclide-commons/process'; -import {observeRawStream} from 'nuclide-commons/stream'; -import {Observable} from 'rxjs'; -import {ROOT_FS} from '../../../nuclide-fs'; - -//------------------------------------------------------------------------------ -// Services -//------------------------------------------------------------------------------ - -/** - * Checks a certain path for existence and returns 'true'/'false' accordingly - */ -export function exists(path: NuclideUri): Promise { - return ROOT_FS.exists(path); +function exists(path) { + return (_nuclideFs || _load_nuclideFs()).ROOT_FS.exists(path); } /** @@ -44,39 +103,29 @@ export function exists(path: NuclideUri): Promise { * parent directory. If it gets all the way to the root and still does not find the file, then it * returns `null`. */ -export async function findNearestAncestorNamed( - fileName: string, - pathToDirectory: NuclideUri, -): Promise { - const directory = await ROOT_FS.findNearestFile(fileName, pathToDirectory); +async function findNearestAncestorNamed(fileName, pathToDirectory) { + const directory = await (_nuclideFs || _load_nuclideFs()).ROOT_FS.findNearestFile(fileName, pathToDirectory); if (directory != null) { - return nuclideUri.join(directory, fileName); + return (_nuclideUri || _load_nuclideUri()).default.join(directory, fileName); } else { return null; } } -export function findFilesInDirectories( - searchPaths: Array, - fileName: string, -): ConnectableObservable> { +function findFilesInDirectories(searchPaths, fileName) { if (searchPaths.length === 0) { - return Observable.throw( - new Error('No directories to search in!'), - ).publish(); + return _rxjsBundlesRxMinJs.Observable.throw(new Error('No directories to search in!')).publish(); } const findArgs = [...searchPaths, '-type', 'f', '-name', fileName]; - return runCommand('find', findArgs) - .map(stdout => stdout.split('\n').filter(filePath => filePath !== '')) - .publish(); + return (0, (_process || _load_process()).runCommand)('find', findArgs).map(stdout => stdout.split('\n').filter(filePath => filePath !== '')).publish(); } /** * The lstat endpoint is the same as the stat endpoint except it will return * the stat of a link instead of the file the link points to. */ -export function lstat(path: NuclideUri): Promise { - return ROOT_FS.lstat(path); +function lstat(path) { + return (_nuclideFs || _load_nuclideFs()).ROOT_FS.lstat(path); } /** @@ -84,8 +133,8 @@ export function lstat(path: NuclideUri): Promise { * Throws EEXIST error if the directory already exists. * Throws ENOENT if the path given is nested in a non-existing directory. */ -export function mkdir(path: NuclideUri): Promise { - return ROOT_FS.mkdir(path); +function mkdir(path) { + return (_nuclideFs || _load_nuclideFs()).ROOT_FS.mkdir(path); } /** @@ -95,15 +144,15 @@ export function mkdir(path: NuclideUri): Promise { * directories were created for some prefix of the given path. * @return true if the path was created; false if it already existed. */ -export function mkdirp(path: NuclideUri): Promise { - return ROOT_FS.mkdirp(path); +function mkdirp(path) { + return (_nuclideFs || _load_nuclideFs()).ROOT_FS.mkdirp(path); } /** * Changes permissions on a file. */ -export function chmod(path: NuclideUri, mode: number): Promise { - return ROOT_FS.chmod(path, mode); +function chmod(path, mode) { + return (_nuclideFs || _load_nuclideFs()).ROOT_FS.chmod(path, mode); } /** @@ -113,12 +162,12 @@ export function chmod(path: NuclideUri, mode: number): Promise { * * @return A boolean indicating whether the file was created. */ -export async function newFile(filePath: NuclideUri): Promise { - const isExistingFile = await ROOT_FS.exists(filePath); +async function newFile(filePath) { + const isExistingFile = await (_nuclideFs || _load_nuclideFs()).ROOT_FS.exists(filePath); if (isExistingFile) { return false; } - await ROOT_FS.mkdirp(nuclideUri.dirname(filePath)); + await (_nuclideFs || _load_nuclideFs()).ROOT_FS.mkdirp((_nuclideUri || _load_nuclideUri()).default.dirname(filePath)); await writeFile(filePath, ''); return true; } @@ -126,19 +175,15 @@ export async function newFile(filePath: NuclideUri): Promise { /** * Lists all children of the given directory. */ -export async function readdir( - path: NuclideUri, -): Promise> { - return ROOT_FS.readdir(path); +async function readdir(path) { + return (_nuclideFs || _load_nuclideFs()).ROOT_FS.readdir(path); } /** * Sorts the result of readdir() by alphabetical order (case-insensitive). */ -export async function readdirSorted( - path: NuclideUri, -): Promise> { - return (await ROOT_FS.readdir(path)).sort((a, b) => { +async function readdirSorted(path) { + return (await (_nuclideFs || _load_nuclideFs()).ROOT_FS.readdir(path)).sort((a, b) => { return a[0].toLowerCase().localeCompare(b[0].toLowerCase()); }); } @@ -148,65 +193,54 @@ export async function readdirSorted( * It could be different than the given path if the file is a symlink * or exists in a symlinked directory. */ -export function realpath(path: NuclideUri): Promise { - return ROOT_FS.realpath(path); +function realpath(path) { + return (_nuclideFs || _load_nuclideFs()).ROOT_FS.realpath(path); } /** * Gets the real path of a file path, while expanding tilda paths and symlinks * like: ~/abc to its absolute path format. */ -export function resolveRealPath(path: string): Promise { - return ROOT_FS.realpath(nuclideUri.expandHomeDir(path)); +function resolveRealPath(path) { + return (_nuclideFs || _load_nuclideFs()).ROOT_FS.realpath((_nuclideUri || _load_nuclideUri()).default.expandHomeDir(path)); } /** * Returns the specified file path with the home dir ~/ expanded. */ -export function expandHomeDir(path: string): Promise { - return Promise.resolve(nuclideUri.expandHomeDir(path)); +function expandHomeDir(path) { + return Promise.resolve((_nuclideUri || _load_nuclideUri()).default.expandHomeDir(path)); } /** * Runs the equivalent of `mv sourcePath destinationPath`. */ -export function rename( - sourcePath: NuclideUri, - destinationPath: NuclideUri, -): Promise { - return ROOT_FS.move(sourcePath, destinationPath); +function rename(sourcePath, destinationPath) { + return (_nuclideFs || _load_nuclideFs()).ROOT_FS.move(sourcePath, destinationPath); } /** * Moves all sourcePaths into the specified destDir, assumed to be a directory name. */ -export async function move( - sourcePaths: Array, - destDir: NuclideUri, -): Promise { - await Promise.all( - sourcePaths.map(path => { - const destPath = nuclideUri.join(destDir, nuclideUri.basename(path)); - return ROOT_FS.move(path, destPath); - }), - ); +async function move(sourcePaths, destDir) { + await Promise.all(sourcePaths.map(path => { + const destPath = (_nuclideUri || _load_nuclideUri()).default.join(destDir, (_nuclideUri || _load_nuclideUri()).default.basename(path)); + return (_nuclideFs || _load_nuclideFs()).ROOT_FS.move(path, destPath); + })); } /** * Runs the equivalent of `cp sourcePath destinationPath`. * @return true if the operation was successful; false if it wasn't. */ -export async function copy( - sourcePath: NuclideUri, - destinationPath: NuclideUri, -): Promise { - const isExistingFile = await ROOT_FS.exists(destinationPath); +async function copy(sourcePath, destinationPath) { + const isExistingFile = await (_nuclideFs || _load_nuclideFs()).ROOT_FS.exists(destinationPath); if (isExistingFile) { return false; } - await ROOT_FS.copy(sourcePath, destinationPath); + await (_nuclideFs || _load_nuclideFs()).ROOT_FS.copy(sourcePath, destinationPath); // TODO: May need to move into ROOT_FS if future filesystems support writing. - await fsPromise.copyFilePermissions(sourcePath, destinationPath); + await (_fsPromise || _load_fsPromise()).default.copyFilePermissions(sourcePath, destinationPath); return true; } @@ -214,27 +248,19 @@ export async function copy( * Runs the equivalent of `cp -R sourcePath destinationPath`. * @return true if the operation was successful; false if it wasn't. */ -export async function copyDir( - sourcePath: NuclideUri, - destinationPath: NuclideUri, -): Promise { - const oldContents = (await Promise.all([ - mkdir(destinationPath), - readdir(sourcePath), - ]))[1]; - - const didCopyAll = await Promise.all( - oldContents.map(([file, isFile]) => { - const oldItem = nuclideUri.join(sourcePath, file); - const newItem = nuclideUri.join(destinationPath, file); - if (isFile) { - // it's a file, copy it - return copy(oldItem, newItem); - } - // it's a directory, copy it - return copyDir(oldItem, newItem); - }), - ); +async function copyDir(sourcePath, destinationPath) { + const oldContents = (await Promise.all([mkdir(destinationPath), readdir(sourcePath)]))[1]; + + const didCopyAll = await Promise.all(oldContents.map(([file, isFile]) => { + const oldItem = (_nuclideUri || _load_nuclideUri()).default.join(sourcePath, file); + const newItem = (_nuclideUri || _load_nuclideUri()).default.join(destinationPath, file); + if (isFile) { + // it's a file, copy it + return copy(oldItem, newItem); + } + // it's a directory, copy it + return copyDir(oldItem, newItem); + })); // Are all the resulting booleans true? return didCopyAll.every(b => b); } @@ -242,12 +268,12 @@ export async function copyDir( /** * Removes directories even if they are non-empty. Does not fail if the directory doesn't exist. */ -export function rmdir(path: NuclideUri): Promise { - return ROOT_FS.rimraf(path); +function rmdir(path) { + return (_nuclideFs || _load_nuclideFs()).ROOT_FS.rimraf(path); } -export async function rmdirAll(paths: Array): Promise { - await Promise.all(paths.map(p => ROOT_FS.rimraf(p))); +async function rmdirAll(paths) { + await Promise.all(paths.map(p => (_nuclideFs || _load_nuclideFs()).ROOT_FS.rimraf(p))); } /** @@ -274,15 +300,15 @@ export async function rmdirAll(paths: Array): Promise { * } * */ -export function stat(path: NuclideUri): Promise { - return ROOT_FS.stat(path); +function stat(path) { + return (_nuclideFs || _load_nuclideFs()).ROOT_FS.stat(path); } /** * Removes files. Does not fail if the file doesn't exist. */ -export function unlink(path: NuclideUri): Promise { - return ROOT_FS.unlink(path).catch(error => { +function unlink(path) { + return (_nuclideFs || _load_nuclideFs()).ROOT_FS.unlink(path).catch(error => { if (error.code !== 'ENOENT') { throw error; } @@ -297,32 +323,26 @@ export function unlink(path: NuclideUri): Promise { * * Callers who want a string should call buffer.toString('utf8'). */ -export async function readFile( - path: NuclideUri, - options?: {flag?: string}, -): Promise { - return ROOT_FS.readFile(path, options); +async function readFile(path, options) { + return (_nuclideFs || _load_nuclideFs()).ROOT_FS.readFile(path, options); } -export function createReadStream( - path: NuclideUri, - options?: {flag?: string}, -): ConnectableObservable { - return observeRawStream(fs.createReadStream(path, options)).publish(); +function createReadStream(path, options) { + return (0, (_stream || _load_stream()).observeRawStream)(_fs.default.createReadStream(path, options)).publish(); } /** * Returns true if the path being checked exists in a `NFS` mounted directory device. */ -export function isNfs(path: NuclideUri): Promise { - return ROOT_FS.isNfs(path); +function isNfs(path) { + return (_nuclideFs || _load_nuclideFs()).ROOT_FS.isNfs(path); } /** * Returns true if the path being checked exists in a `Fuse` mounted directory device. */ -export function isFuse(path: NuclideUri): Promise { - return ROOT_FS.isFuse(path); +function isFuse(path) { + return (_nuclideFs || _load_nuclideFs()).ROOT_FS.isFuse(path); } /** @@ -333,13 +353,9 @@ export function isFuse(path: NuclideUri): Promise { * * `options` is passed directly into fs.writeFile. */ -export function writeFile( - path: NuclideUri, - data: string, - options?: WriteOptions, -): Promise { +function writeFile(path, data, options) { // TODO: May need to move into ROOT_FS if future filesystems support writing. - return fsPromise.writeFileAtomic(path, data, options); + return (_fsPromise || _load_fsPromise()).default.writeFileAtomic(path, data, options); } /** @@ -347,35 +363,28 @@ export function writeFile( * The RPC framework can't use string | Buffer so we have to create a separate function. * Note that options.encoding is ignored for raw buffers. */ -export function writeFileBuffer( - path: NuclideUri, - data: Buffer, - options?: {encoding?: string, mode?: number, flag?: string}, -): Promise { - return fsPromise.writeFileAtomic(path, data, options); +function writeFileBuffer(path, data, options) { + return (_fsPromise || _load_fsPromise()).default.writeFileAtomic(path, data, options); } -export async function getFreeSpace(path: NuclideUri): Promise { +async function getFreeSpace(path) { // Only supported on Linux for now. if (process.platform !== 'linux') { return null; } // The output of this command is "Avail\n12345678\n". // Just return the first line that parses to an integer. - return runCommand('df', ['--output=avail', path]) - .map(output => { - for (const line of output.split('\n')) { - const number = parseInt(line, 10); - if (Number.isInteger(number)) { - return number; - } + return (0, (_process || _load_process()).runCommand)('df', ['--output=avail', path]).map(output => { + for (const line of output.split('\n')) { + const number = parseInt(line, 10); + if (Number.isInteger(number)) { + return number; } - }) - .toPromise() - .catch(() => null); + } + }).toPromise().catch(() => null); } // Wrapper around fsPromise.tempdir() -export async function tempdir(prefix: string = ''): Promise { - return fsPromise.tempdir(prefix); -} +async function tempdir(prefix = '') { + return (_fsPromise || _load_fsPromise()).default.tempdir(prefix); +} \ No newline at end of file diff --git a/pkg/nuclide-server/lib/services/FileSystemServiceProxy.js b/pkg/nuclide-server/lib/services/FileSystemServiceProxy.js new file mode 100644 index 0000000000..dd0e6d3a50 --- /dev/null +++ b/pkg/nuclide-server/lib/services/FileSystemServiceProxy.js @@ -0,0 +1,1692 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + + remoteModule.exists = function (arg0) { + return _client.callRemoteFunction("FileSystemService/exists", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "boolean" + }); + }); + }; + + remoteModule.findNearestAncestorNamed = function (arg0, arg1) { + return _client.callRemoteFunction("FileSystemService/findNearestAncestorNamed", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "fileName", + type: { + kind: "string" + } + }, { + name: "pathToDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "NuclideUri" + } + }); + }); + }; + + remoteModule.findFilesInDirectories = function (arg0, arg1) { + return _client.callRemoteFunction("FileSystemService/findFilesInDirectories", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "searchPaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }, { + name: "fileName", + type: { + kind: "string" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + }); + }).publish(); + }; + + remoteModule.lstat = function (arg0) { + return _client.callRemoteFunction("FileSystemService/lstat", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "fs.Stats" + }); + }); + }; + + remoteModule.mkdir = function (arg0) { + return _client.callRemoteFunction("FileSystemService/mkdir", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.mkdirp = function (arg0) { + return _client.callRemoteFunction("FileSystemService/mkdirp", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "boolean" + }); + }); + }; + + remoteModule.chmod = function (arg0, arg1) { + return _client.callRemoteFunction("FileSystemService/chmod", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "mode", + type: { + kind: "number" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.newFile = function (arg0) { + return _client.callRemoteFunction("FileSystemService/newFile", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "boolean" + }); + }); + }; + + remoteModule.readdir = function (arg0) { + return _client.callRemoteFunction("FileSystemService/readdir", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "DirectoryEntry" + } + }); + }); + }; + + remoteModule.readdirSorted = function (arg0) { + return _client.callRemoteFunction("FileSystemService/readdirSorted", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "array", + type: { + kind: "named", + name: "DirectoryEntry" + } + }); + }); + }; + + remoteModule.realpath = function (arg0) { + return _client.callRemoteFunction("FileSystemService/realpath", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "NuclideUri" + }); + }); + }; + + remoteModule.resolveRealPath = function (arg0) { + return _client.callRemoteFunction("FileSystemService/resolveRealPath", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }); + }; + + remoteModule.expandHomeDir = function (arg0) { + return _client.callRemoteFunction("FileSystemService/expandHomeDir", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }); + }; + + remoteModule.rename = function (arg0, arg1) { + return _client.callRemoteFunction("FileSystemService/rename", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "sourcePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "destinationPath", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.move = function (arg0, arg1) { + return _client.callRemoteFunction("FileSystemService/move", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "sourcePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }, { + name: "destDir", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.copy = function (arg0, arg1) { + return _client.callRemoteFunction("FileSystemService/copy", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "sourcePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "destinationPath", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "boolean" + }); + }); + }; + + remoteModule.copyDir = function (arg0, arg1) { + return _client.callRemoteFunction("FileSystemService/copyDir", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "sourcePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "destinationPath", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "boolean" + }); + }); + }; + + remoteModule.rmdir = function (arg0) { + return _client.callRemoteFunction("FileSystemService/rmdir", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.rmdirAll = function (arg0) { + return _client.callRemoteFunction("FileSystemService/rmdirAll", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "paths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.stat = function (arg0) { + return _client.callRemoteFunction("FileSystemService/stat", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "fs.Stats" + }); + }); + }; + + remoteModule.unlink = function (arg0) { + return _client.callRemoteFunction("FileSystemService/unlink", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.readFile = function (arg0, arg1) { + return _client.callRemoteFunction("FileSystemService/readFile", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "options", + type: { + kind: "nullable", + type: { + kind: "object", + fields: [{ + name: "flag", + type: { + kind: "string" + }, + optional: true + }] + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "Buffer" + }); + }); + }; + + remoteModule.createReadStream = function (arg0, arg1) { + return _client.callRemoteFunction("FileSystemService/createReadStream", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "options", + type: { + kind: "nullable", + type: { + kind: "object", + fields: [{ + name: "flag", + type: { + kind: "string" + }, + optional: true + }] + } + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "Buffer" + }); + }).publish(); + }; + + remoteModule.isNfs = function (arg0) { + return _client.callRemoteFunction("FileSystemService/isNfs", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "boolean" + }); + }); + }; + + remoteModule.isFuse = function (arg0) { + return _client.callRemoteFunction("FileSystemService/isFuse", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "boolean" + }); + }); + }; + + remoteModule.writeFile = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("FileSystemService/writeFile", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "data", + type: { + kind: "string" + } + }, { + name: "options", + type: { + kind: "nullable", + type: { + kind: "named", + name: "WriteOptions" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.writeFileBuffer = function (arg0, arg1, arg2) { + return _client.callRemoteFunction("FileSystemService/writeFileBuffer", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "data", + type: { + kind: "named", + name: "Buffer" + } + }, { + name: "options", + type: { + kind: "nullable", + type: { + kind: "object", + fields: [{ + name: "encoding", + type: { + kind: "string" + }, + optional: true + }, { + name: "mode", + type: { + kind: "number" + }, + optional: true + }, { + name: "flag", + type: { + kind: "string" + }, + optional: true + }] + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + remoteModule.getFreeSpace = function (arg0) { + return _client.callRemoteFunction("FileSystemService/getFreeSpace", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "number" + } + }); + }); + }; + + remoteModule.tempdir = function (arg0) { + return _client.callRemoteFunction("FileSystemService/tempdir", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "prefix", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + exists: { + kind: "function", + name: "exists", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 37 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 37 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "boolean" + } + } + } + }, + findNearestAncestorNamed: { + kind: "function", + name: "findNearestAncestorNamed", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 47 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 47 + }, + kind: "function", + argumentTypes: [{ + name: "fileName", + type: { + kind: "string" + } + }, { + name: "pathToDirectory", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "NuclideUri" + } + } + } + } + }, + findFilesInDirectories: { + kind: "function", + name: "findFilesInDirectories", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 59 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 59 + }, + kind: "function", + argumentTypes: [{ + name: "searchPaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }, { + name: "fileName", + type: { + kind: "string" + } + }], + returnType: { + kind: "observable", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + } + } + }, + lstat: { + kind: "function", + name: "lstat", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 78 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 78 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "fs.Stats" + } + } + } + }, + mkdir: { + kind: "function", + name: "mkdir", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 87 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 87 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + mkdirp: { + kind: "function", + name: "mkdirp", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 98 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 98 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "boolean" + } + } + } + }, + chmod: { + kind: "function", + name: "chmod", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 105 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 105 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "mode", + type: { + kind: "number" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + newFile: { + kind: "function", + name: "newFile", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 116 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 116 + }, + kind: "function", + argumentTypes: [{ + name: "filePath", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "boolean" + } + } + } + }, + DirectoryEntry: { + kind: "alias", + location: { + type: "source", + fileName: "FileSystem.js", + line: 28 + }, + name: "DirectoryEntry", + definition: { + kind: "tuple", + types: [{ + kind: "string" + }, { + kind: "boolean" + }, { + kind: "boolean" + }] + } + }, + readdir: { + kind: "function", + name: "readdir", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 129 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 129 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "array", + type: { + kind: "named", + name: "DirectoryEntry" + } + } + } + } + }, + readdirSorted: { + kind: "function", + name: "readdirSorted", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 138 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 138 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "array", + type: { + kind: "named", + name: "DirectoryEntry" + } + } + } + } + }, + realpath: { + kind: "function", + name: "realpath", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 151 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 151 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "NuclideUri" + } + } + } + }, + resolveRealPath: { + kind: "function", + name: "resolveRealPath", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 159 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 159 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "string" + } + } + } + }, + expandHomeDir: { + kind: "function", + name: "expandHomeDir", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 166 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 166 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "string" + } + } + } + }, + rename: { + kind: "function", + name: "rename", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 173 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 173 + }, + kind: "function", + argumentTypes: [{ + name: "sourcePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "destinationPath", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + move: { + kind: "function", + name: "move", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 183 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 183 + }, + kind: "function", + argumentTypes: [{ + name: "sourcePaths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }, { + name: "destDir", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + copy: { + kind: "function", + name: "copy", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 199 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 199 + }, + kind: "function", + argumentTypes: [{ + name: "sourcePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "destinationPath", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "boolean" + } + } + } + }, + copyDir: { + kind: "function", + name: "copyDir", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 217 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 217 + }, + kind: "function", + argumentTypes: [{ + name: "sourcePath", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "destinationPath", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "boolean" + } + } + } + }, + rmdir: { + kind: "function", + name: "rmdir", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 245 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 245 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + rmdirAll: { + kind: "function", + name: "rmdirAll", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 249 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 249 + }, + kind: "function", + argumentTypes: [{ + name: "paths", + type: { + kind: "array", + type: { + kind: "named", + name: "NuclideUri" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + stat: { + kind: "function", + name: "stat", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 277 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 277 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "fs.Stats" + } + } + } + }, + unlink: { + kind: "function", + name: "unlink", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 284 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 284 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + readFile: { + kind: "function", + name: "readFile", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 300 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 300 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "options", + type: { + kind: "nullable", + type: { + kind: "object", + fields: [{ + name: "flag", + type: { + kind: "string" + }, + optional: true + }] + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "Buffer" + } + } + } + }, + createReadStream: { + kind: "function", + name: "createReadStream", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 307 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 307 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "options", + type: { + kind: "nullable", + type: { + kind: "object", + fields: [{ + name: "flag", + type: { + kind: "string" + }, + optional: true + }] + } + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "Buffer" + } + } + } + }, + isNfs: { + kind: "function", + name: "isNfs", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 317 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 317 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "boolean" + } + } + } + }, + isFuse: { + kind: "function", + name: "isFuse", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 324 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 324 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "boolean" + } + } + } + }, + WriteOptions: { + kind: "alias", + location: { + type: "source", + fileName: "FileSystem.js", + line: 34 + }, + name: "WriteOptions", + definition: { + kind: "object", + fields: [{ + name: "encoding", + type: { + kind: "string" + }, + optional: true + }, { + name: "mode", + type: { + kind: "number" + }, + optional: true + }, { + name: "flag", + type: { + kind: "string" + }, + optional: true + }] + } + }, + writeFile: { + kind: "function", + name: "writeFile", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 336 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 336 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "data", + type: { + kind: "string" + } + }, { + name: "options", + type: { + kind: "nullable", + type: { + kind: "named", + name: "WriteOptions" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + writeFileBuffer: { + kind: "function", + name: "writeFileBuffer", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 350 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 350 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }, { + name: "data", + type: { + kind: "named", + name: "Buffer" + } + }, { + name: "options", + type: { + kind: "nullable", + type: { + kind: "object", + fields: [{ + name: "encoding", + type: { + kind: "string" + }, + optional: true + }, { + name: "mode", + type: { + kind: "number" + }, + optional: true + }, { + name: "flag", + type: { + kind: "string" + }, + optional: true + }] + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + }, + getFreeSpace: { + kind: "function", + name: "getFreeSpace", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 358 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 358 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "number" + } + } + } + } + }, + tempdir: { + kind: "function", + name: "tempdir", + location: { + type: "source", + fileName: "FileSystemService.js", + line: 379 + }, + type: { + location: { + type: "source", + fileName: "FileSystemService.js", + line: 379 + }, + kind: "function", + argumentTypes: [{ + name: "prefix", + type: { + kind: "nullable", + type: { + kind: "string" + } + } + }], + returnType: { + kind: "promise", + type: { + kind: "string" + } + } + } + } + } +}); \ No newline at end of file diff --git a/pkg/nuclide-server/lib/services/InfoService.js b/pkg/nuclide-server/lib/services/InfoService.js index f7e111cc1e..960098e8c9 100644 --- a/pkg/nuclide-server/lib/services/InfoService.js +++ b/pkg/nuclide-server/lib/services/InfoService.js @@ -1,3 +1,25 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getServerVersion = getServerVersion; +exports.closeConnection = closeConnection; + +var _nuclideVersion; + +function _load_nuclideVersion() { + return _nuclideVersion = require('../../../nuclide-version'); +} + +var _NuclideServer; + +function _load_NuclideServer() { + return _NuclideServer = _interopRequireDefault(require('../NuclideServer')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,30 +27,24 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {QueuedAckTransport} from 'big-dig/src/socket/QueuedAckTransport'; -import type {RpcConnection} from '../../../nuclide-rpc'; - -import {getVersion} from '../../../nuclide-version'; -import NuclideServer from '../NuclideServer'; - -export function getServerVersion(): Promise { - return Promise.resolve(getVersion()); +function getServerVersion() { + return Promise.resolve((0, (_nuclideVersion || _load_nuclideVersion()).getVersion)()); } // Mark this as async so the client can wait for an acknowledgement. // However, we can't close the connection right away, as otherwise the response never gets sent! // Add a small delay to allow the return message to go through. -export function closeConnection(shutdownServer: boolean): Promise { - const client: RpcConnection = (this: any); +function closeConnection(shutdownServer) { + const client = this; setTimeout(() => { - NuclideServer.closeConnection(client); + (_NuclideServer || _load_NuclideServer()).default.closeConnection(client); if (shutdownServer) { - NuclideServer.shutdown(); + (_NuclideServer || _load_NuclideServer()).default.shutdown(); } }, 1000); return Promise.resolve(); -} +} \ No newline at end of file diff --git a/pkg/nuclide-server/lib/services/InfoServiceProxy.js b/pkg/nuclide-server/lib/services/InfoServiceProxy.js new file mode 100644 index 0000000000..a7868a73b9 --- /dev/null +++ b/pkg/nuclide-server/lib/services/InfoServiceProxy.js @@ -0,0 +1,142 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + + remoteModule.getServerVersion = function () { + return _client.callRemoteFunction("InfoService/getServerVersion", "promise", _client.marshalArguments(Array.from(arguments), [])).then(value => { + return _client.unmarshal(value, { + kind: "string" + }); + }); + }; + + remoteModule.closeConnection = function (arg0) { + return _client.callRemoteFunction("InfoService/closeConnection", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "shutdownServer", + type: { + kind: "boolean" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "void" + }); + }); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + getServerVersion: { + kind: "function", + name: "getServerVersion", + location: { + type: "source", + fileName: "InfoService.js", + line: 18 + }, + type: { + location: { + type: "source", + fileName: "InfoService.js", + line: 18 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "string" + } + } + } + }, + closeConnection: { + kind: "function", + name: "closeConnection", + location: { + type: "source", + fileName: "InfoService.js", + line: 25 + }, + type: { + location: { + type: "source", + fileName: "InfoService.js", + line: 25 + }, + kind: "function", + argumentTypes: [{ + name: "shutdownServer", + type: { + kind: "boolean" + } + }], + returnType: { + kind: "promise", + type: { + kind: "void" + } + } + } + } + } +}); \ No newline at end of file diff --git a/pkg/nuclide-server/lib/services/SourceControlService.js b/pkg/nuclide-server/lib/services/SourceControlService.js index a5cd6a2fe9..90a805974e 100644 --- a/pkg/nuclide-server/lib/services/SourceControlService.js +++ b/pkg/nuclide-server/lib/services/SourceControlService.js @@ -1,28 +1,29 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import {findHgRepository} from '../../../nuclide-source-control-helpers'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getHgRepository = getHgRepository; + +var _nuclideSourceControlHelpers; + +function _load_nuclideSourceControlHelpers() { + return _nuclideSourceControlHelpers = require('../../../nuclide-source-control-helpers'); +} /** * This is a workaround that should be removed when Atom 2.0 comes out. * See t6913624. */ -export type HgRepositoryDescription = { - repoPath: string, - originURL: ?string, - workingDirectoryPath: string, -}; - -export function getHgRepository( - directoryPath: string, -): Promise { - return Promise.resolve(findHgRepository(directoryPath)); -} +function getHgRepository(directoryPath) { + return Promise.resolve((0, (_nuclideSourceControlHelpers || _load_nuclideSourceControlHelpers()).findHgRepository)(directoryPath)); +} /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-server/lib/services/SourceControlServiceProxy.js b/pkg/nuclide-server/lib/services/SourceControlServiceProxy.js new file mode 100644 index 0000000000..7339b0c2b3 --- /dev/null +++ b/pkg/nuclide-server/lib/services/SourceControlServiceProxy.js @@ -0,0 +1,152 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + + remoteModule.getHgRepository = function (arg0) { + return _client.callRemoteFunction("SourceControlService/getHgRepository", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "directoryPath", + type: { + kind: "string" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "nullable", + type: { + kind: "named", + name: "HgRepositoryDescription" + } + }); + }); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + HgRepositoryDescription: { + kind: "alias", + location: { + type: "source", + fileName: "SourceControlService.js", + line: 18 + }, + name: "HgRepositoryDescription", + definition: { + kind: "object", + fields: [{ + name: "repoPath", + type: { + kind: "string" + }, + optional: false + }, { + name: "originURL", + type: { + kind: "nullable", + type: { + kind: "string" + } + }, + optional: false + }, { + name: "workingDirectoryPath", + type: { + kind: "string" + }, + optional: false + }] + } + }, + getHgRepository: { + kind: "function", + name: "getHgRepository", + location: { + type: "source", + fileName: "SourceControlService.js", + line: 24 + }, + type: { + location: { + type: "source", + fileName: "SourceControlService.js", + line: 24 + }, + kind: "function", + argumentTypes: [{ + name: "directoryPath", + type: { + kind: "string" + } + }], + returnType: { + kind: "promise", + type: { + kind: "nullable", + type: { + kind: "named", + name: "HgRepositoryDescription" + } + } + } + } + } + } +}); \ No newline at end of file diff --git a/pkg/nuclide-server/lib/servicesConfig.js b/pkg/nuclide-server/lib/servicesConfig.js index d61bebae96..e6dab2dd3b 100644 --- a/pkg/nuclide-server/lib/servicesConfig.js +++ b/pkg/nuclide-server/lib/servicesConfig.js @@ -1,3 +1,23 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _nuclideRpc; + +function _load_nuclideRpc() { + return _nuclideRpc = require('../../nuclide-rpc'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,11 +25,8 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import {loadServicesConfig} from '../../nuclide-rpc'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - -export default loadServicesConfig(nuclideUri.join(__dirname, '..')); +exports.default = (0, (_nuclideRpc || _load_nuclideRpc()).loadServicesConfig)((_nuclideUri || _load_nuclideUri()).default.join(__dirname, '..')); \ No newline at end of file diff --git a/pkg/nuclide-server/lib/utils.js b/pkg/nuclide-server/lib/utils.js index 054481f109..4d07c813c4 100644 --- a/pkg/nuclide-server/lib/utils.js +++ b/pkg/nuclide-server/lib/utils.js @@ -1,33 +1,43 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.protocolLogger = undefined; +exports.sendTextResponse = sendTextResponse; +exports.sendJsonResponse = sendJsonResponse; +exports.parseRequestBody = parseRequestBody; +exports.getQueryParameters = getQueryParameters; +exports.serializeArgs = serializeArgs; +exports.deserializeArgs = deserializeArgs; + +var _url = _interopRequireDefault(require('url')); + +var _memoryLogger; -import invariant from 'assert'; -import url from 'url'; -import {MemoryLogger} from '../../commons-node/memoryLogger'; +function _load_memoryLogger() { + return _memoryLogger = require('../../commons-node/memoryLogger'); +} -const MAX_REQUEST_LENGTH = 1e6; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -export const protocolLogger = new MemoryLogger(null); +const MAX_REQUEST_LENGTH = 1e6; /** + * 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. + * + * + * @format + */ -type QueryParams = {[key: string]: any}; -type SerializedArguments = {args: Array, argTypes: Array}; +const protocolLogger = exports.protocolLogger = new (_memoryLogger || _load_memoryLogger()).MemoryLogger(null); /** * Write a text or convert to text response with an optional status code. */ -export function sendTextResponse( - response: http$fixed$ServerResponse, - text: any, - statusCode: ?number, -): void { +function sendTextResponse(response, text, statusCode) { if (typeof statusCode === 'number') { response.statusCode = statusCode; } @@ -38,11 +48,7 @@ export function sendTextResponse( /** * Write a json response text with an optional status code. */ -export function sendJsonResponse( - response: http$fixed$ServerResponse, - json: any, - statusCode: ?number, -): void { +function sendJsonResponse(response, json, statusCode) { response.setHeader('Content-Type', 'application/json'); sendTextResponse(response, JSON.stringify(json), statusCode); } @@ -50,10 +56,7 @@ export function sendJsonResponse( /** * Parses the request body in an anyc/promise way */ -export function parseRequestBody( - httpRequest: http$fixed$IncomingMessage, - isJson: ?boolean, -): Promise { +function parseRequestBody(httpRequest, isJson) { return new Promise((resolve, reject) => { let body = ''; httpRequest.on('data', data => { @@ -71,10 +74,14 @@ export function parseRequestBody( /** * Parses the url parameters ?abc=erf&lol=432c */ -export function getQueryParameters(requestUrl: string): QueryParams { - const components: ?Object = url.parse(requestUrl, true); - invariant(components != null); - const {query} = components; +function getQueryParameters(requestUrl) { + const components = _url.default.parse(requestUrl, true); + + if (!(components != null)) { + throw new Error('Invariant violation: "components != null"'); + } + + const { query } = components; return query; } @@ -83,7 +90,7 @@ export function getQueryParameters(requestUrl: string): QueryParams { * to send the metadata about the argument types with the data * to help the server understand and parse it. */ -export function serializeArgs(args: Array): SerializedArguments { +function serializeArgs(args) { const argsOnHttp = []; const argTypes = []; args.forEach(arg => { @@ -102,7 +109,7 @@ export function serializeArgs(args: Array): SerializedArguments { }); return { args: argsOnHttp, - argTypes, + argTypes }; } @@ -110,8 +117,8 @@ export function serializeArgs(args: Array): SerializedArguments { * Deserializes a url with query parameters: args, argTypes to an array * of the original arguments of the same types the client called the function with. */ -export function deserializeArgs(requestUrl: string): Array { - let {args, argTypes} = getQueryParameters(requestUrl); +function deserializeArgs(requestUrl) { + let { args, argTypes } = getQueryParameters(requestUrl); args = args || []; argTypes = argTypes || []; const argsArray = Array.isArray(args) ? args : [args]; @@ -127,4 +134,4 @@ export function deserializeArgs(requestUrl: string): Array { return JSON.parse(arg); } }); -} +} \ No newline at end of file diff --git a/pkg/nuclide-server/scripts/mock/nuclide-main.js b/pkg/nuclide-server/scripts/mock/nuclide-main.js index 790e8ed628..0b716495f6 100644 --- a/pkg/nuclide-server/scripts/mock/nuclide-main.js +++ b/pkg/nuclide-server/scripts/mock/nuclide-main.js @@ -1,3 +1,16 @@ +'use strict'; + +var _https = _interopRequireDefault(require('https')); + +var _http = _interopRequireDefault(require('http')); + +var _fs = _interopRequireDefault(require('fs')); + +var _url = _interopRequireDefault(require('url')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Set the initial version by reading from the file. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,22 +18,12 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ -import https from 'https'; -import http from 'http'; -import fs from 'fs'; -import url from 'url'; - -// Set the initial version by reading from the file. -const json = JSON.parse( - fs.readFileSync(require.resolve('./package.json'), 'utf8'), -); -const version = /^(\d+)\.(\d+)\.(\d+)(?:-([a-z0-9.-]+))?$/.exec( - json.version, -)[2]; +const json = JSON.parse(_fs.default.readFileSync(require.resolve('./package.json'), 'utf8')); +const version = /^(\d+)\.(\d+)\.(\d+)(?:-([a-z0-9.-]+))?$/.exec(json.version)[2]; function processArgs() { const args = process.argv.slice(2); @@ -38,18 +41,18 @@ function startServer(args) { let _webServer; if (args.key && args.cert && args.ca) { const webServerOptions = { - key: fs.readFileSync(args.key), - cert: fs.readFileSync(args.cert), - ca: fs.readFileSync(args.ca), + key: _fs.default.readFileSync(args.key), + cert: _fs.default.readFileSync(args.cert), + ca: _fs.default.readFileSync(args.ca), requestCert: true, - rejectUnauthorized: true, + rejectUnauthorized: true }; - _webServer = https.createServer(webServerOptions, handleRequest); + _webServer = _https.default.createServer(webServerOptions, handleRequest); // eslint-disable-next-line no-console console.log('running in secure mode'); } else { - _webServer = http.createServer(handleRequest); + _webServer = _http.default.createServer(handleRequest); } _webServer.on('listening', () => { @@ -61,7 +64,7 @@ function startServer(args) { } function handleRequest(request, response) { - const pathname = url.parse(request.url, false).pathname; + const pathname = _url.default.parse(request.url, false).pathname; switch (pathname) { case '/heartbeat': @@ -81,4 +84,4 @@ function handleVersion(request, response) { response.end(); } -startServer(processArgs()); +startServer(processArgs()); \ No newline at end of file diff --git a/pkg/nuclide-server/spec/NuclideSearchService-spec.js b/pkg/nuclide-server/spec/NuclideSearchService-spec.js deleted file mode 100644 index 9ba5ad06b8..0000000000 --- a/pkg/nuclide-server/spec/NuclideSearchService-spec.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import NuclideServer from '../lib/NuclideServer'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import servicesConfig from '../lib/servicesConfig'; - -const pathToTestDir = nuclideUri.join(__dirname, 'testfiles'); -const pathToTestFile = nuclideUri.join(pathToTestDir, 'testfile.txt'); - -let server; -let client; - -// eslint-disable-next-line jasmine/no-disabled-tests -xdescribe('NuclideSearch test suite', () => { - beforeEach(() => { - jasmine.getEnv().defaultTimeoutInterval = 10000; - waitsForPromise(async () => { - server = new NuclideServer({port: 8176}, servicesConfig); - await server.connect(); - // client = new NuclideClient('test', new NuclideRemoteEventbus('http://localhost:8176')); - }); - }); - - afterEach(() => { - client.eventbus.socket.close(); - server.close(); - }); - - describe('Querying', () => { - it('should return query results for the given directory', () => { - waitsForPromise(async () => { - const results = await client.searchDirectory(pathToTestDir, 'te'); - expect(results.length).toBe(1); - expect(results[0].path).toBe( - nuclideUri.join(pathToTestDir, 'testfile.txt'), - ); - }); - }); - - it('should return query results for the given directory if it has a hostname', () => { - waitsForPromise(async () => { - const results = await client.searchDirectory( - `nuclide://some.host.com${pathToTestDir}`, - 'te', - ); - expect(results.length).toBe(1); - expect(results[0].path).toBe( - `nuclide://some.host.com${pathToTestDir}/testfile.txt`, - ); - }); - }); - }); - - describe('Errors', () => { - it('should throw an error if the directory does not exist', () => { - waitsForPromise({shouldReject: true}, async () => { - await client.searchDirectory('not-a-folder', 'query'); - }); - }); - - it('should throw an error if the specified path is not a directory', () => { - waitsForPromise({shouldReject: true}, async () => { - await client.searchDirectory(pathToTestFile, 'query'); - }); - }); - }); -}); diff --git a/pkg/nuclide-server/spec/NuclideServer-spec.js b/pkg/nuclide-server/spec/NuclideServer-spec.js deleted file mode 100644 index 9583d842ba..0000000000 --- a/pkg/nuclide-server/spec/NuclideServer-spec.js +++ /dev/null @@ -1,130 +0,0 @@ -/** - * 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 - */ - -import WS from 'ws'; -import NuclideServer from '../lib/NuclideServer'; -import {RpcConnection} from '../../nuclide-rpc'; -import servicesConfig from '../lib/servicesConfig'; - -import invariant from 'assert'; -import {ReliableSocket} from 'big-dig/src/socket/ReliableSocket'; -import {getRemoteNuclideUriMarshalers} from '../../nuclide-marshalers-common'; - -const HEARTBEAT_CHANNEL = 'test-heartbeat'; - -let server; -let client; -let socket; - -describe('Nuclide Server test suite', () => { - beforeEach(() => { - jasmine.getEnv().defaultTimeoutInterval = 10000; - - waitsForPromise(async () => { - server = new NuclideServer({port: 8176}, servicesConfig); - await server.connect(); - socket = new ReliableSocket( - 'http://localhost:8176', - HEARTBEAT_CHANNEL, - null, - ); - client = RpcConnection.createRemote( - socket, - [getRemoteNuclideUriMarshalers('localhost')], - servicesConfig, - ); - }); - }); - - afterEach(() => { - client.dispose(); - server.close(); - }); - - it('websocket is connected with the server', () => { - const websocket = new WS('ws://localhost:8176'); - let opened = false; - websocket.once('open', () => { - opened = true; - }); - waitsFor(() => opened); - }); - - // eslint-disable-next-line jasmine/no-disabled-tests - xdescribe('reconnect websocket flow', () => { - it('server sent messages, while disconnected will still be delievered', () => { - // Here is the initial message. - const reliableSocket = socket; - const messageHandler: Function = (jasmine.createSpy(): any); - const reconnectHandler: Function = (jasmine.createSpy(): any); - reliableSocket.onReconnect(reconnectHandler); - reliableSocket.onMessage().subscribe(messageHandler); - // The maximum reconnect time is 5 seconds - advance clock to sip the reconnect time. - reliableSocket.onDisconnect(() => - process.nextTick(() => advanceClock(6000)), - ); - - waitsForPromise(() => reliableSocket.waitForConnect()); - - const message1 = JSON.stringify({foo1: 'bar1'}); - const message2 = JSON.stringify({foo2: 'bar2'}); - const message3 = JSON.stringify({foo3: 'bar3'}); - const message4 = JSON.stringify({foo4: 'bar4'}); - - // Wait for the connection to exist on the server. - waitsFor(() => server._clients.size === 1); - - let serverSocketClient = null; - runs(() => { - const clientId = Array.from(server._clients.keys())[0]; - serverSocketClient = server._clients.get(clientId); - invariant(serverSocketClient != null); - expect(serverSocketClient.getTransport().id).toBe(clientId); - - serverSocketClient.getTransport().send(message1); - }); - - waitsFor(() => messageHandler.callCount === 1); - runs(() => { - // Close the client socket and start a reconnect trial, send a message in between. - // A server socket close will trigger a client disconnect and a scheduled reconnect. - // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) - if (serverSocketClient != null && serverSocketClient.socket != null) { - // $FlowIgnore: This test has bitrotted - serverSocketClient.socket.close(); - serverSocketClient.getTransport().send(message2); - // The default WebSocket's close timeout is 30 seconds. - advanceClock(31 * 1000); - serverSocketClient.getTransport().send(message3); - } - }); - - waitsFor(() => reconnectHandler.callCount === 1); - runs(() => { - if (serverSocketClient != null) { - serverSocketClient.getTransport().send(message4); - } - }); - - waitsFor(() => messageHandler.callCount === 4); - runs(() => { - // Received on the first stable websocket connection. - expect(messageHandler.argsForCall[0][0]).toEqual(message1); - // Cached in the queue when disconnected. - expect(messageHandler.argsForCall[1][0]).toEqual(message2); - // Cached in the queue when disconnected. - expect(messageHandler.argsForCall[2][0]).toEqual(message3); - // Received on the reconnected stable websocket connection. - expect(messageHandler.argsForCall[3][0]).toEqual(message4); - }); - }); - }); -}); diff --git a/pkg/nuclide-server/spec/NuclideServerSecure-spec.js b/pkg/nuclide-server/spec/NuclideServerSecure-spec.js deleted file mode 100644 index 8fcda16ee3..0000000000 --- a/pkg/nuclide-server/spec/NuclideServerSecure-spec.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * 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 - */ - -import fs from 'fs'; - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import NuclideServer from '../lib/NuclideServer'; -import {RpcConnection} from '../../nuclide-rpc'; -import servicesConfig from '../lib/servicesConfig'; -import {ReliableSocket} from 'big-dig/src/socket/ReliableSocket'; -import {WebSocketTransport} from 'big-dig/src/socket/WebSocketTransport'; -import {getRemoteNuclideUriMarshalers} from '../../nuclide-marshalers-common'; -import {getVersion} from '../../nuclide-version'; -import invariant from 'assert'; -import child_process from 'child_process'; -import nullthrows from 'nullthrows'; - -const HEARTBEAT_CHANNEL = 'test-heartbeat'; - -let server; -let socket; - -// Paths to certificate authority crt (certificate) -let ca_cert_path; - -// Path to server key, and crt (certificate) -let server_cert_path; -let server_key_path; - -// Path to client key, and crt (certificate) -let client_cert_path; -let client_key_path; - -const gen_certs_path = nuclideUri.resolve( - __dirname, - '../scripts/nuclide_certificates_generator.py', -); - -describe('Nuclide Secure Server test suite', () => { - it('Starts a server', () => { - jasmine.getEnv().defaultTimeoutInterval = 10000; - waitsForPromise(async () => { - generateCertificates(); - - server = new NuclideServer( - { - port: 8176, - serverKey: fs.readFileSync(server_key_path), - serverCertificate: fs.readFileSync(server_cert_path), - certificateAuthorityCertificate: fs.readFileSync(ca_cert_path), - }, - servicesConfig, - ); - - await server.connect(); - - socket = new ReliableSocket('https://localhost:8176', HEARTBEAT_CHANNEL, { - ca: fs.readFileSync(ca_cert_path), - cert: fs.readFileSync(client_cert_path), - key: fs.readFileSync(client_key_path), - family: 6, - }); - const client = RpcConnection.createRemote( - socket, - [getRemoteNuclideUriMarshalers('localhost')], - servicesConfig, - ); - invariant(client); - - const version = await client.getService('InfoService').getServerVersion(); - expect(version).toBe(getVersion()); - - // Ensure that we resolved the IPv6 address. - const rpcTransport = client._transport; - const queuedTransport = nullthrows(rpcTransport)._transport; - const webSocketTransport = (nullthrows(queuedTransport): any)._transport; - invariant(webSocketTransport instanceof WebSocketTransport); - const webSocket = nullthrows(webSocketTransport._socket); - expect(webSocket._socket.remoteAddress).toBe('::1'); - - socket.close(); - server.close(); - }); - }); -}); - -function generateCertificates() { - const out = child_process - .execSync(`${gen_certs_path} -s localhost`) - .toString('utf8'); - const json = JSON.parse(out); - ca_cert_path = json.ca_cert; - server_cert_path = json.server_cert; - server_key_path = json.server_key; - client_cert_path = json.client_cert; - client_key_path = json.client_key; -} diff --git a/pkg/nuclide-server/spec/blocked-spec.js b/pkg/nuclide-server/spec/blocked-spec.js deleted file mode 100644 index 3138ac81af..0000000000 --- a/pkg/nuclide-server/spec/blocked-spec.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import blocked from '../lib/blocked'; - -let now = 0; - -describe('blocked()', () => { - let blockHandler; - let intervalHandler; - - beforeEach(() => { - jasmine.useRealClock(); - blockHandler = jasmine.createSpy(); - jasmine.Clock.useMock(); - spyOn(Date, 'now').andCallFake(() => now); - - intervalHandler = blocked(blockHandler, 100, 10); - }); - - afterEach(() => { - intervalHandler.dispose(); - }); - - it('reports blocking events over the threshold', () => { - now = 150; - jasmine.Clock.tick(150); - - expect(blockHandler.callCount).toBe(1); - expect(blockHandler.argsForCall[0][0]).toBe(50); - }); -}); diff --git a/pkg/nuclide-server/spec/services/FileSystemService-spec.js b/pkg/nuclide-server/spec/services/FileSystemService-spec.js deleted file mode 100644 index 17a66af8f3..0000000000 --- a/pkg/nuclide-server/spec/services/FileSystemService-spec.js +++ /dev/null @@ -1,617 +0,0 @@ -/** - * 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 - */ - -import typeof * as FileSystemService from '../../lib/services/FileSystemService'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import ServiceTestHelper from './ServiceTestHelper'; -import invariant from 'assert'; -import fs from 'fs'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import rimraf from 'rimraf'; -import temp from 'temp'; - -temp.track(); - -const pathToTestDir = nuclideUri.join(__dirname, '../testfiles'); -const pathToTestFile = nuclideUri.join(pathToTestDir, 'testfile.txt'); -const pathToWriteFile = pathToTestFile + '.1'; -const pathToLinkFile = pathToTestFile + '.2'; -const pathToBrokenLinkFile = pathToTestFile + '.3'; -const pathToMissingFile = pathToTestFile + '.oops'; - -describe('FileSystemService', () => { - let testHelper; - let service: FileSystemService; - beforeEach(() => { - waitsForPromise(async () => { - testHelper = new ServiceTestHelper(); - const FILE_SYSTEM_SERVICE_PATH = require.resolve( - '../../lib/services/FileSystemService', - ); - await testHelper.start([ - { - name: 'FileSystemService', - definition: FILE_SYSTEM_SERVICE_PATH, - implementation: FILE_SYSTEM_SERVICE_PATH, - }, - ]); - service = testHelper.getRemoteService('FileSystemService'); - }); - }); - - it('can readFile', () => { - waitsForPromise(async () => { - const body = await service.readFile(pathToTestFile); - expect(body.toString()).toEqual("I'm a little teapot.\n"); - }); - }); - - it('returns 500 code if file cannot be opened', () => { - waitsForPromise(async () => { - let err; - try { - await service.readFile(pathToMissingFile); - } catch (e) { - err = e; - } - invariant(err != null); - expect(err.code).toBe('ENOENT'); - }); - }); - - it('can writeFile', () => { - waitsForPromise(async () => { - await service.writeFile(pathToWriteFile, "I'm a little teapot.\n"); - expect(fs.readFileSync(pathToWriteFile).toString()).toEqual( - "I'm a little teapot.\n", - ); - }); - }); - - function normalizeStat(stat: Object) { - // Access time will naturally differ between calls. - delete stat.atime; - // "Ms" fields are new to Node 8 and are not currently supported. - Object.keys(stat).forEach(key => { - if (key.endsWith('Ms')) { - delete stat[key]; - } - }); - } - - it('can stat', () => { - waitsForPromise(async () => { - const stats = await service.stat(pathToTestFile); - const expected = fs.statSync(pathToTestFile); - expect(normalizeStat(stats)).toEqual(normalizeStat(expected)); - }); - }); - - it('can readdir', () => { - waitsForPromise(async () => { - fs.symlinkSync(pathToTestFile, pathToLinkFile, 'file'); - fs.symlinkSync(pathToMissingFile, pathToBrokenLinkFile, 'file'); - const entries = await service.readdir(pathToTestDir); - expect(entries.length).toBe(2); // Skips broken link - entries.sort((a, b) => { - return a[0].localeCompare(b[0]); - }); - - expect(entries[0]).toEqual(['testfile.txt', true, false]); - expect(entries[1]).toEqual(['testfile.txt.2', true, true]); - }); - }); - - it('can readdirSorted', () => { - waitsForPromise(async () => { - fs.symlinkSync(pathToTestFile, pathToLinkFile, 'file'); - fs.symlinkSync(pathToMissingFile, pathToBrokenLinkFile, 'file'); - const entries = await service.readdirSorted(pathToTestDir); - expect(entries.length).toBe(2); // Skips broken link - expect(entries[0]).toEqual(['testfile.txt', true, false]); - expect(entries[1]).toEqual(['testfile.txt.2', true, true]); - }); - }); - - it('can lstat', () => { - waitsForPromise(async () => { - fs.symlinkSync(pathToTestFile, pathToLinkFile, 'file'); - const lstats = await service.lstat(pathToLinkFile); - const expected = fs.lstatSync(pathToLinkFile); - expect(normalizeStat(lstats)).toEqual(normalizeStat(expected)); - }); - }); - - it('returns false from exists if file missing', () => { - waitsForPromise(async () => { - const exists = await service.exists(pathToMissingFile); - expect(exists).toBe(false); - }); - }); - - it('returns true from exists if file exists', () => { - waitsForPromise(async () => { - const exists = await service.exists(pathToTestFile); - expect(exists).toBe(true); - }); - }); - - describe('newFile()', () => { - let dirPath: string = (null: any); - - beforeEach(() => { - dirPath = nuclideUri.join(__dirname, 'newFile_test'); - }); - - afterEach(() => { - rimraf.sync(dirPath); - }); - - it('creates the file and the expected subdirectories', () => { - waitsForPromise(async () => { - const newPath = nuclideUri.join(dirPath, 'foo/bar/baz.txt'); - expect(fs.existsSync(newPath)).toBe(false); - const isNew = await service.newFile(newPath); - expect(fs.existsSync(newPath)).toBe(true); - expect(fs.statSync(newPath).isFile()).toBe(true); - expect(fs.readFileSync(newPath).toString()).toBe(''); - expect(isNew).toBe(true); - }); - }); - - it('is a no-op for an existing file', () => { - waitsForPromise(async () => { - fs.mkdirSync(dirPath); - fs.mkdirSync(nuclideUri.join(dirPath, 'foo')); - fs.mkdirSync(nuclideUri.join(dirPath, 'foo/bar')); - const newPath = nuclideUri.join(dirPath, 'foo/bar/baz.txt'); - fs.writeFileSync(newPath, 'contents'); - expect(fs.existsSync(newPath)).toBe(true); - - const isNew = await service.newFile(newPath); - expect(fs.statSync(newPath).isFile()).toBe(true); - expect(fs.readFileSync(newPath).toString()).toBe('contents'); - expect(isNew).toBe(false); - }); - }); - }); - - describe('realpath()', () => { - it('gets the same exact path of a normal file', () => { - waitsForPromise(async () => { - const realpath = await service.realpath(pathToTestFile); - expect(realpath).toBe(testHelper.getUriOfRemotePath(pathToTestFile)); - }); - }); - - it('gets the real path of a symlinked file', () => { - waitsForPromise(async () => { - fs.symlinkSync(pathToTestFile, pathToLinkFile, 'file'); - const realpath = await service.realpath(pathToLinkFile); - expect(realpath).toBe(testHelper.getUriOfRemotePath(pathToTestFile)); - }); - }); - }); - - describe('rename()', () => { - let dirPath; - - beforeEach(() => { - dirPath = temp.mkdirSync('rename_test'); - }); - - it('succeeds when renaming a file', () => { - waitsForPromise(async () => { - const sourcePath = nuclideUri.join(dirPath, 'file'); - fs.writeFileSync(sourcePath, ''); - const destinationPath = nuclideUri.join(dirPath, 'destination_file'); - - await service.rename(sourcePath, destinationPath); - - expect(fs.existsSync(sourcePath)).toBe(false); - expect(fs.existsSync(destinationPath)).toBe(true); - }); - }); - - it('succeeds when renaming a folder', () => { - waitsForPromise(async () => { - const sourcePath = nuclideUri.join(dirPath, 'directory'); - fs.mkdirSync(sourcePath); - const destinationPath = nuclideUri.join(dirPath, 'destination_folder'); - - await service.rename(sourcePath, destinationPath); - - expect(fs.existsSync(sourcePath)).toBe(false); - expect(fs.existsSync(destinationPath)).toBe(true); - }); - }); - - it('succeeds when renaming into a non-existent directory', () => { - waitsForPromise(async () => { - const sourcePath = nuclideUri.join(dirPath, 'file'); - fs.writeFileSync(sourcePath, ''); - const destinationPath = nuclideUri.join( - dirPath, - 'non-existent', - 'destination_file', - ); - - await service.rename(sourcePath, destinationPath); - - expect(fs.existsSync(sourcePath)).toBe(false); - expect(fs.existsSync(destinationPath)).toBe(true); - }); - }); - - it('throws error if the source does not exist', () => { - waitsForPromise(async () => { - const sourcePath = nuclideUri.join(dirPath, 'file'); - const destinationPath = nuclideUri.join(dirPath, 'destination_file'); - - let err; - try { - await service.rename(sourcePath, destinationPath); - } catch (e) { - err = e; - } - - invariant(err != null); - expect(err.code).toBe('ENOENT'); - expect(fs.existsSync(destinationPath)).toBe(false); - }); - }); - - it('throws error if the destination exists', () => { - waitsForPromise(async () => { - const sourcePath = nuclideUri.join(dirPath, 'file'); - fs.writeFileSync(sourcePath, ''); - const destinationPath = nuclideUri.join(dirPath, 'destination_file'); - fs.writeFileSync(destinationPath, ''); - - let err; - try { - await service.rename(sourcePath, destinationPath); - } catch (e) { - err = e; - } - - invariant(err != null); - expect(err.code).toBe('EEXIST'); - }); - }); - }); - - describe('mkdir()', () => { - let dirPath: string = (null: any); - - beforeEach(() => { - dirPath = nuclideUri.join(__dirname, 'mkdir_test'); - }); - - afterEach(() => { - if (fs.existsSync(dirPath)) { - fs.rmdir(dirPath); - } - }); - - it('creates a directory at a given path', () => { - waitsForPromise(async () => { - expect(fs.existsSync(dirPath)).toBe(false); - await service.mkdir(dirPath); - expect(fs.existsSync(dirPath)).toBe(true); - expect(fs.statSync(dirPath).isDirectory()).toBe(true); - }); - }); - - it('throws an error if already existing directory', () => { - waitsForPromise(async () => { - let err; - fs.mkdirSync(dirPath); - try { - await service.mkdir(dirPath); - } catch (e) { - err = e; - } - invariant(err != null); - expect(err.code).toBe('EEXIST'); - }); - }); - - it('throws an error if the path is nested in a non-existing directory', () => { - waitsForPromise(async () => { - let err; - try { - await service.mkdir(nuclideUri.join(dirPath, 'foo')); - } catch (e) { - err = e; - } - invariant(err != null); - expect(err.code).toBe('ENOENT'); - }); - }); - }); - - describe('mkdirp()', () => { - let dirPath: string = (null: any); - - beforeEach(() => { - dirPath = nuclideUri.join(__dirname, 'mkdirp_test'); - }); - - afterEach(() => { - rimraf.sync(dirPath); - }); - - it('creates the expected subdirectories', () => { - waitsForPromise(async () => { - const newPath = nuclideUri.join(dirPath, 'foo/bar/baz'); - expect(fs.existsSync(newPath)).toBe(false); - const isNew = await service.mkdirp(newPath); - expect(fs.existsSync(newPath)).toBe(true); - expect(isNew).toBe(true); - }); - }); - - it('is a no-op for an existing directory', () => { - waitsForPromise(async () => { - fs.mkdirSync(dirPath); - fs.mkdirSync(nuclideUri.join(dirPath, 'foo')); - fs.mkdirSync(nuclideUri.join(dirPath, 'foo/bar')); - const newPath = nuclideUri.join(dirPath, 'foo/bar/baz'); - fs.mkdirSync(newPath); - expect(fs.existsSync(newPath)).toBe(true); - - const isNew = await service.mkdirp(newPath); - expect(fs.existsSync(newPath)).toBe(true); - expect(isNew).toBe(false); - }); - }); - }); - - describe('rmdir()', () => { - let dirPath; - - beforeEach(() => { - dirPath = temp.mkdirSync('rmdir_test'); - }); - - it('removes non-empty directories', () => { - waitsForPromise(async () => { - const directoryToRemove = nuclideUri.join(dirPath, 'foo'); - await service.mkdirp(nuclideUri.join(directoryToRemove, 'bar')); - expect(fs.existsSync(directoryToRemove)).toBe(true); - await service.rmdir(directoryToRemove); - expect(fs.existsSync(directoryToRemove)).toBe(false); - }); - }); - - it('does nothing for non-existent directories', () => { - waitsForPromise(async () => { - const directoryToRemove = nuclideUri.join(dirPath, 'foo'); - await service.rmdir(directoryToRemove); - expect(fs.existsSync(directoryToRemove)).toBe(false); - }); - }); - }); - - describe('unlink()', () => { - let dirPath; - - beforeEach(() => { - dirPath = temp.mkdirSync('unlink_test'); - }); - - it('removes file if it exists', () => { - waitsForPromise(async () => { - const fileToRemove = nuclideUri.join(dirPath, 'foo'); - fs.writeFileSync(fileToRemove, ''); - expect(fs.existsSync(fileToRemove)).toBe(true); - await service.unlink(fileToRemove); - expect(fs.existsSync(fileToRemove)).toBe(false); - }); - }); - - it('does nothing for non-existent files', () => { - waitsForPromise(async () => { - const fileToRemove = nuclideUri.join(dirPath, 'foo'); - await service.unlink(fileToRemove); - expect(fs.existsSync(fileToRemove)).toBe(false); - }); - }); - }); - - describe('chmod()', () => { - let dirPath = null; - let testFilePath = null; - - beforeEach(() => { - dirPath = temp.mkdirSync('chmod_test'); - testFilePath = nuclideUri.join(dirPath, 'foo'); - fs.writeFileSync(testFilePath, ''); - fs.chmodSync(testFilePath, '0644'); - }); - - afterEach(() => { - if (dirPath != null) { - service.rmdir(dirPath); - } - }); - - it('can change permissions', () => { - waitsForPromise(async () => { - invariant(testFilePath != null); - // chmod 0777 - await service.chmod(testFilePath, 511); - expect(fs.statSync(testFilePath).mode % 512).toBe(511); - }); - }); - }); - - describe('findNearestAncestorNamed', () => { - let dirPath: string = (null: any); - - beforeEach(() => { - dirPath = temp.mkdirSync('findNearestAncestorNamed_test'); - fs.mkdirSync(nuclideUri.join(dirPath, 'foo')); - fs.mkdirSync(nuclideUri.join(dirPath, 'foo', 'bar')); - fs.mkdirSync(nuclideUri.join(dirPath, 'foo', 'bar', 'baz')); - fs.mkdirSync(nuclideUri.join(dirPath, 'boo')); - const filePaths = [ - nuclideUri.join(dirPath, 'foo', 'BUCK'), - nuclideUri.join(dirPath, 'foo', 'bar', 'baz', 'BUCK'), - ]; - filePaths.forEach(filePath => fs.writeFileSync(filePath, 'any contents')); - }); - - it('findNearestAncestorNamed in dir', async () => { - const pathToDirectory1 = nuclideUri.join(dirPath, 'foo'); - const nearestFile1 = await service.findNearestAncestorNamed( - 'BUCK', - pathToDirectory1, - ); - expect(nearestFile1).toBe(nuclideUri.join(dirPath, 'foo', 'BUCK')); - - const pathToDirectory2 = nuclideUri.join(dirPath, 'foo', 'bar', 'baz'); - const nearestFile2 = await service.findNearestAncestorNamed( - 'BUCK', - pathToDirectory2, - ); - expect(nearestFile2).toBe( - nuclideUri.join(dirPath, 'foo', 'bar', 'baz', 'BUCK'), - ); - }); - - it('findNearestAncestorNamed in ancestor', async () => { - const pathToDirectory = nuclideUri.join(dirPath, 'foo', 'bar'); - const nearestFile = await service.findNearestAncestorNamed( - 'BUCK', - pathToDirectory, - ); - expect(nearestFile).toBe(nuclideUri.join(dirPath, 'foo', 'BUCK')); - }); - - it('findNearestAncestorNamed not in ancestor', async () => { - const pathToDirectory = nuclideUri.join(dirPath, 'boo'); - const nearestFile = await service.findNearestAncestorNamed( - 'BUCK', - pathToDirectory, - ); - expect(nearestFile).toBe(null); - }); - }); - - describe('findFilesInDirectories()', () => { - let dirPath: string = (null: any); - let fileName: string = (null: any); - let filePaths: Array = (null: any); - - function toLocalPaths(fileUris: Array): Array { - return fileUris.map(fileUri => nuclideUri.getPath(fileUri)); - } - - beforeEach(() => { - dirPath = nuclideUri.join(__dirname, 'find_in_dir'); - fileName = 'file.txt'; - - fs.mkdirSync(dirPath); - fs.mkdirSync(nuclideUri.join(dirPath, 'foo')); - fs.mkdirSync(nuclideUri.join(dirPath, 'foo', 'bar')); - fs.mkdirSync(nuclideUri.join(dirPath, 'baz')); - // A directory with the same file name won't be matched. - fs.mkdirSync(nuclideUri.join(dirPath, 'foo', fileName)); - - filePaths = [ - nuclideUri.join(dirPath, fileName), - nuclideUri.join(dirPath, 'baz', fileName), - nuclideUri.join(dirPath, 'baz', 'other_file1'), - nuclideUri.join(dirPath, 'foo', 'other_file2'), - nuclideUri.join(dirPath, 'foo', 'bar', 'other_file3'), - nuclideUri.join(dirPath, 'foo', 'bar', fileName), - ]; - filePaths.forEach(filePath => fs.writeFileSync(filePath, 'any contents')); - }); - - afterEach(() => { - rimraf.sync(dirPath); - }); - - it('errors when no search directories are provided', () => { - waitsForPromise(async () => { - let error; - try { - await service - .findFilesInDirectories([], fileName) - .refCount() - .toPromise(); - } catch (e) { - error = e; - } - expect(error != null).toBeTruthy(); - }); - }); - - it('return empty list when no files are matching', () => { - waitsForPromise(async () => { - const foundFiles = await service - .findFilesInDirectories([dirPath], 'not_existing') - .refCount() - .toPromise(); - expect(foundFiles.length).toBe(0); - }); - }); - - it('return matching file names in a directory (& nested directories)', () => { - waitsForPromise(async () => { - const foundFiles = await service - .findFilesInDirectories([dirPath], fileName) - .refCount() - .toPromise(); - expect(foundFiles.length).toBe(3); - expect(toLocalPaths(foundFiles).sort()).toEqual( - [filePaths[0], filePaths[1], filePaths[5]].sort(), - ); - }); - }); - - it('return matching file names in specific search directories', () => { - waitsForPromise(async () => { - const foundFiles = await service - .findFilesInDirectories( - [nuclideUri.join(dirPath, 'baz'), nuclideUri.join(dirPath, 'foo')], - fileName, - ) - .refCount() - .toPromise(); - expect(foundFiles.length).toBe(2); - expect(toLocalPaths(foundFiles).sort()).toEqual( - [filePaths[1], filePaths[5]].sort(), - ); - }); - }); - }); - - afterEach(() => { - invariant(testHelper); - testHelper.stop(); - if (fs.existsSync(pathToWriteFile)) { - fs.unlinkSync(pathToWriteFile); - } - if (fs.existsSync(pathToLinkFile)) { - fs.unlinkSync(pathToLinkFile); - } - try { - fs.unlinkSync(pathToBrokenLinkFile); - } catch (e) { - /* exists can't check for broken symlinks, just absorb the error for cleanup */ - } - }); -}); diff --git a/pkg/nuclide-server/spec/services/FindInProjectIntegration-spec.js b/pkg/nuclide-server/spec/services/FindInProjectIntegration-spec.js deleted file mode 100644 index e06570d6ed..0000000000 --- a/pkg/nuclide-server/spec/services/FindInProjectIntegration-spec.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import fs from 'fs'; -import {addMatchers} from '../../../nuclide-test-helpers'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import ServiceTestHelper from './ServiceTestHelper'; - -describe('GrepSearch', () => { - beforeEach(function() { - addMatchers(this); - }); - - // Strips out hostname and current file directory. - function makePortable(jsonObject) { - // eslint-disable-next-line no-path-concat - const regex = new RegExp('\\/\\/localhost/*' + __dirname, 'g'); - return JSON.parse( - JSON.stringify(jsonObject, null, 2).replace(regex, 'VARIABLE'), - ); - } - - it('can execute a basic search', () => { - const testHelper = new ServiceTestHelper(); - - waitsForPromise(async () => { - const FIND_IN_PROJECT_SERVICE_PATH = require.resolve( - '../../../nuclide-code-search-rpc', - ); - - // Start the integration test helper. - await testHelper.start([ - { - name: 'CodeSearchService', - definition: FIND_IN_PROJECT_SERVICE_PATH, - implementation: FIND_IN_PROJECT_SERVICE_PATH, - }, - ]); - - const remoteService = testHelper.getRemoteService('CodeSearchService'); - - // Search in the fixtures/basic directory. - const input_dir = nuclideUri.join(__dirname, 'fixtures', 'basic'); - const uri = testHelper.getUriOfRemotePath(input_dir); - - // Do search. - const updates = await remoteService - .remoteAtomSearch(uri, /hello world/i, [], false, 'grep') - .refCount() - .toArray() - .toPromise(); - - const expected = JSON.parse( - fs.readFileSync(input_dir + '.json', {encoding: 'utf8'}), - ); - expect(makePortable(updates)).diffJson(expected); - testHelper.stop(); - }); - }); -}); diff --git a/pkg/nuclide-server/spec/services/InfoService-spec.js b/pkg/nuclide-server/spec/services/InfoService-spec.js deleted file mode 100644 index c70247f17e..0000000000 --- a/pkg/nuclide-server/spec/services/InfoService-spec.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import typeof * as InfoService from '../../lib/services/InfoService'; - -import ServiceTestHelper from './ServiceTestHelper'; -import {getVersion} from '../../../nuclide-version'; -import invariant from 'assert'; -import servicesConfig from '../../lib/servicesConfig'; - -describe('InfoService', () => { - let testHelper; - beforeEach(() => { - testHelper = new ServiceTestHelper(); - waitsForPromise(() => testHelper.start(servicesConfig)); - }); - - it('Returns the correct version number', () => { - waitsForPromise(async () => { - invariant(testHelper); - const service: InfoService = testHelper.getRemoteService('InfoService'); - - const version = await service.getServerVersion(); - expect(version).toBe(getVersion()); - }); - }); - - afterEach(() => testHelper.stop()); -}); diff --git a/pkg/nuclide-server/spec/services/ServiceTestHelper.js b/pkg/nuclide-server/spec/services/ServiceTestHelper.js deleted file mode 100644 index 04333c8952..0000000000 --- a/pkg/nuclide-server/spec/services/ServiceTestHelper.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * 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 - */ - -import type {ConfigEntry} from '../../../nuclide-rpc'; - -import NuclideServer from '../../lib/NuclideServer'; -import {ReliableSocket} from 'big-dig/src/socket/ReliableSocket'; -import {RpcConnection} from '../../../nuclide-rpc'; -import {getRemoteNuclideUriMarshalers} from '../../../nuclide-marshalers-common'; - -type Services = Array; - -const HEARTBEAT_CHANNEL = 'test-heartbeat'; - -export default class ServiceTestHelper { - _server: NuclideServer; - _client: RpcConnection; - - async start(customServices: Services): Promise { - this._server = new NuclideServer({port: 0}, customServices); - await this._server.connect(); - - const port = this._server._webServer.address().port; - this._client = RpcConnection.createRemote( - new ReliableSocket(`http://localhost:${port}`, HEARTBEAT_CHANNEL, null), - [getRemoteNuclideUriMarshalers('localhost')], - customServices, - ); - } - - stop(): void { - this._client.dispose(); - this._server.close(); - } - - getRemoteService(serviceName: string): any { - return this._client.getService(serviceName); - } - - getUriOfRemotePath(remotePath: string): string { - return `nuclide://localhost${remotePath}`; - } -} diff --git a/pkg/nuclide-server/spec/services/fixtures/basic.json b/pkg/nuclide-server/spec/services/fixtures/basic.json deleted file mode 100644 index 0c50f12cc5..0000000000 --- a/pkg/nuclide-server/spec/services/fixtures/basic.json +++ /dev/null @@ -1,37 +0,0 @@ -[ - { - "matches": [ - { - "lineText": "Console.log('Hello World.');", - "lineTextOffset": 0, - "matchText": "Hello World", - "range": [ - [ - 11, - 13 - ], - [ - 11, - 24 - ] - ] - }, - { - "lineText": "Console.log('Hello World.');", - "lineTextOffset": 0, - "matchText": "Hello World", - "range": [ - [ - 13, - 13 - ], - [ - 13, - 24 - ] - ] - } - ], - "filePath": "nuclide:VARIABLE/fixtures/basic/test.js.txt" - } -] diff --git a/pkg/nuclide-server/spec/services/fixtures/basic/test.js.txt b/pkg/nuclide-server/spec/services/fixtures/basic/test.js.txt deleted file mode 100644 index 6139914de1..0000000000 --- a/pkg/nuclide-server/spec/services/fixtures/basic/test.js.txt +++ /dev/null @@ -1,14 +0,0 @@ -/** - * 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 - */ - -const Console = {log: text => {}}; -Console.log('Hello World.'); -const a = 3; Console.log(a); -Console.log('Hello World.'); diff --git a/pkg/nuclide-server/spec/servicesConfig-spec.js b/pkg/nuclide-server/spec/servicesConfig-spec.js deleted file mode 100644 index ff3b81fe54..0000000000 --- a/pkg/nuclide-server/spec/servicesConfig-spec.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * 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 - */ - -import fs from 'fs'; -import servicesConfig from '../lib/servicesConfig'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - -describe('servicesConfig()', () => { - it('refers to files that exist', () => { - servicesConfig.forEach(service => { - expect(fs.existsSync(service.definition)).toBe(true); - expect(fs.existsSync(service.implementation)).toBe(true); - }); - }); - - it('resolves absolute paths', () => { - servicesConfig.forEach(service => { - expect(nuclideUri.isAbsolute(service.definition)).toBe(true); - expect(nuclideUri.isAbsolute(service.implementation)).toBe(true); - }); - }); - - it('loads the number of services expected', () => { - const numberOfServices = servicesConfig.length; - const numberOfPublicServices = require('../services-3.json').length; - expect(numberOfServices >= numberOfPublicServices).toBe(true); - }); -}); diff --git a/pkg/nuclide-server/spec/testfiles/testfile.txt b/pkg/nuclide-server/spec/testfiles/testfile.txt deleted file mode 100644 index 146fe9b844..0000000000 --- a/pkg/nuclide-server/spec/testfiles/testfile.txt +++ /dev/null @@ -1 +0,0 @@ -I'm a little teapot. diff --git a/pkg/nuclide-server/spec/utils-spec.js b/pkg/nuclide-server/spec/utils-spec.js deleted file mode 100644 index 01fdb23034..0000000000 --- a/pkg/nuclide-server/spec/utils-spec.js +++ /dev/null @@ -1,110 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import http from 'http'; -import querystring from 'querystring'; -import * as utils from '../lib/utils'; -import asyncRequest from 'big-dig/src/client/utils/asyncRequest'; - -describe('NuclideServer utils test', () => { - let server; - let customHandler; - - beforeEach(() => { - let connected = false; - server = http.createServer((req, res) => { - if (customHandler) { - customHandler(req, res); - } else { - res.writeHead(200, {'Content-Type': 'text/plain'}); - res.end('okay'); - } - }); - server.listen(36845, '127.0.0.1', 511 /* backlog */, () => { - connected = true; - }); - waitsFor(() => connected); - }); - - afterEach(() => { - server.close(); - customHandler = null; - }); - - it('parses the request body', () => { - const bodyHandler = jasmine.createSpy(); - customHandler = (req, res) => { - utils - // $FlowFixMe(asuarez): Use Flow builtin defs for IncomingMessage. - .parseRequestBody(req) - .then(bodyHandler) - .then(() => res.end()); - }; - asyncRequest({ - uri: 'http://127.0.0.1:36845/abc', - method: 'POST', - body: 'string_abc', - }); - waitsFor(() => bodyHandler.callCount > 0); - runs(() => expect(bodyHandler.argsForCall[0][0]).toBe('string_abc')); - }); - - it('gets query params', () => { - const params = utils.getQueryParameters('http://fburil.com?one=2&yoga=def'); - expect(params).toEqual({one: '2', yoga: 'def'}); - }); - - describe('serializeArgs', () => { - it('serializes empty args', () => { - const {args, argTypes} = utils.serializeArgs([]); - expect(args).toEqual([]); - expect(argTypes).toEqual([]); - }); - - it('serializes undefined args', () => { - const {args, argTypes} = utils.serializeArgs(['abc', undefined]); - expect(args).toEqual(['abc', '']); - expect(argTypes).toEqual(['string', 'undefined']); - }); - - it('serializes object args', () => { - const {args, argTypes} = utils.serializeArgs([{def: 'lol'}]); - expect(args).toEqual([JSON.stringify({def: 'lol'})]); - expect(argTypes).toEqual(['object']); - }); - }); - - describe('deserializeArgs', () => { - it('deserializes strings and undefined', () => { - const url = - 'http://localhost:8090/?args=abc&args=&argTypes=string&argTypes=undefined'; - const [str, undef] = utils.deserializeArgs(url); - expect(str).toBe('abc'); - expect(undef).not.toBeDefined(); - }); - - it('deserializes objects', () => { - const escapedObj = querystring.escape(JSON.stringify({def: 'lol'})); - const url = - 'http://localhost:8090/?args=' + escapedObj + '&argTypes=object'; - const [obj] = utils.deserializeArgs(url); - expect(obj).toEqual({def: 'lol'}); - }); - }); - - it('serializeArgs then deserializeArgs for strings with non-escaped chars', () => { - const {args, argTypes} = utils.serializeArgs(['a d+']); - const [str] = utils.deserializeArgs( - 'http://localhost:8090/?' + querystring.stringify({args, argTypes}), - ); - expect(str).toBe('a d+'); - }); -}); diff --git a/pkg/nuclide-server2/lib/constants.js b/pkg/nuclide-server2/lib/constants.js index 6eea92251a..bfba5eb831 100644 --- a/pkg/nuclide-server2/lib/constants.js +++ b/pkg/nuclide-server2/lib/constants.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,9 +10,9 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict + * strict * @format */ // Tag for all nuclide-rpc messages. -export const NUCLIDE_RPC_TAG = 'nuclide-rpc'; +const NUCLIDE_RPC_TAG = exports.NUCLIDE_RPC_TAG = 'nuclide-rpc'; \ No newline at end of file diff --git a/pkg/nuclide-server2/lib/server.js b/pkg/nuclide-server2/lib/server.js index 5d7e142a15..25779615fc 100644 --- a/pkg/nuclide-server2/lib/server.js +++ b/pkg/nuclide-server2/lib/server.js @@ -1,3 +1,37 @@ +'use strict'; + +var _nuclideLogging; + +function _load_nuclideLogging() { + return _nuclideLogging = require('../../nuclide-logging'); +} + +var _nuclideMarshalersCommon; + +function _load_nuclideMarshalersCommon() { + return _nuclideMarshalersCommon = require('../../nuclide-marshalers-common'); +} + +var _nuclideRpc; + +function _load_nuclideRpc() { + return _nuclideRpc = require('../../nuclide-rpc'); +} + +var _servicesConfig; + +function _load_servicesConfig() { + return _servicesConfig = _interopRequireDefault(require('../../nuclide-server/lib/servicesConfig')); +} + +var _constants; + +function _load_constants() { + return _constants = require('./constants'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,35 +39,19 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {Transport} from 'big-dig/src/server/BigDigServer'; -import type { - LauncherParameters, - LauncherType, -} from 'big-dig/src/server/NuclideServer'; -import type {Transport as RpcTransportType} from '../../nuclide-rpc'; - -import {initializeLogging} from '../../nuclide-logging'; -import {getServerSideMarshalers} from '../../nuclide-marshalers-common'; -import {RpcConnection, ServiceRegistry} from '../../nuclide-rpc'; -import servicesConfig from '../../nuclide-server/lib/servicesConfig'; -import {NUCLIDE_RPC_TAG} from './constants'; - -initializeLogging(); - -function launch(launcherParams: LauncherParameters): Promise { - const rpcServiceRegistry = new ServiceRegistry( - getServerSideMarshalers, - servicesConfig, - ); - - const {server} = launcherParams; - server.addSubscriber(NUCLIDE_RPC_TAG, { - onConnection(transport: Transport) { - const rpcTransport: RpcTransportType = { +(0, (_nuclideLogging || _load_nuclideLogging()).initializeLogging)(); + +function launch(launcherParams) { + const rpcServiceRegistry = new (_nuclideRpc || _load_nuclideRpc()).ServiceRegistry((_nuclideMarshalersCommon || _load_nuclideMarshalersCommon()).getServerSideMarshalers, (_servicesConfig || _load_servicesConfig()).default); + + const { server } = launcherParams; + server.addSubscriber((_constants || _load_constants()).NUCLIDE_RPC_TAG, { + onConnection(transport) { + const rpcTransport = { send(message) { transport.send(message); }, @@ -44,14 +62,14 @@ function launch(launcherParams: LauncherParameters): Promise { close() {}, isClosed() { return false; - }, + } }; - RpcConnection.createServer(rpcServiceRegistry, rpcTransport, {}); - }, + (_nuclideRpc || _load_nuclideRpc()).RpcConnection.createServer(rpcServiceRegistry, rpcTransport, {}); + } }); return Promise.resolve(); } // eslint-disable-next-line nuclide-internal/no-commonjs -module.exports = (launch: LauncherType); +module.exports = launch; \ No newline at end of file diff --git a/pkg/nuclide-settings/lib/SettingsCategory.js b/pkg/nuclide-settings/lib/SettingsCategory.js index 246274cd1a..b0e3bd37fb 100644 --- a/pkg/nuclide-settings/lib/SettingsCategory.js +++ b/pkg/nuclide-settings/lib/SettingsCategory.js @@ -1,3 +1,21 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = _interopRequireWildcard(require('react')); + +var _SettingsControl; + +function _load_SettingsControl() { + return _SettingsControl = _interopRequireDefault(require('../../../modules/nuclide-commons-ui/SettingsControl')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,77 +23,80 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import * as React from 'react'; -import SettingsControl from 'nuclide-commons-ui/SettingsControl'; - -type Props = { - name: string, - packages: Object, -}; - -export default class SettingsCategory extends React.Component { - render(): React.Node { - const children = Object.keys(this.props.packages) - .sort() - .map(pkgName => { - const pkgData = this.props.packages[pkgName]; - const settingsArray = getSortedSettingsArray(pkgData.settings, pkgName); - const elements = settingsArray.map(settingName => { - const settingData = pkgData.settings[settingName]; - return ( - - - - ); - }); - // We create a control group for the whole group of controls and then another for each - // individual one. Why? Because that's what Atom does in its settings view. - return ( - -
    - {/* Package title. */} -

    {pkgData.title}

    -
    {elements}
    -
    -
    +class SettingsCategory extends _react.Component { + render() { + const children = Object.keys(this.props.packages).sort().map(pkgName => { + const pkgData = this.props.packages[pkgName]; + const settingsArray = getSortedSettingsArray(pkgData.settings, pkgName); + const elements = settingsArray.map(settingName => { + const settingData = pkgData.settings[settingName]; + return _react.createElement( + ControlGroup, + { key: settingName }, + _react.createElement((_SettingsControl || _load_SettingsControl()).default, { + keyPath: settingData.keyPath, + value: settingData.value, + onChange: settingData.onChange, + schema: settingData.schema + }) ); }); - return ( -
    - {/* Category Title */} -

    - {this.props.name} Settings -

    - {children} -
    + // We create a control group for the whole group of controls and then another for each + // individual one. Why? Because that's what Atom does in its settings view. + return _react.createElement( + ControlGroup, + { key: pkgName }, + _react.createElement( + 'section', + { className: 'sub-section' }, + _react.createElement( + 'h2', + { className: 'sub-section-heading' }, + pkgData.title + ), + _react.createElement( + 'div', + { className: 'sub-section-body' }, + elements + ) + ) + ); + }); + return _react.createElement( + 'section', + { className: 'section settings-panel' }, + _react.createElement( + 'h1', + { className: 'block section-heading icon icon-gear' }, + this.props.name, + ' Settings' + ), + children ); } } -// $FlowFixMe(>=0.53.0) Flow suppress -function ControlGroup(props: {children?: React.Children}): React.Element { - return ( -
    -
    {props.children}
    -
    +exports.default = SettingsCategory; // $FlowFixMe(>=0.53.0) Flow suppress + +function ControlGroup(props) { + return _react.createElement( + 'div', + { className: 'control-group' }, + _react.createElement( + 'div', + { className: 'controls' }, + props.children + ) ); } -function getSortedSettingsArray( - settings: Object, - pkgName: string, -): Array { +function getSortedSettingsArray(settings, pkgName) { // Sort the package's settings by name, then by order. const settingsArray = Object.keys(settings); settingsArray.sort().sort((a, b) => settings[a].order - settings[b].order); return settingsArray; -} +} \ No newline at end of file diff --git a/pkg/nuclide-settings/lib/SettingsPaneItem.js b/pkg/nuclide-settings/lib/SettingsPaneItem.js index 9f5f70f53a..2b58ef4a2e 100644 --- a/pkg/nuclide-settings/lib/SettingsPaneItem.js +++ b/pkg/nuclide-settings/lib/SettingsPaneItem.js @@ -1,3 +1,54 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.WORKSPACE_VIEW_URI = undefined; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/feature-config')); +} + +var _observePaneItemVisibility; + +function _load_observePaneItemVisibility() { + return _observePaneItemVisibility = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/observePaneItemVisibility')); +} + +var _react = _interopRequireWildcard(require('react')); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _SettingsCategory; + +function _load_SettingsCategory() { + return _SettingsCategory = _interopRequireDefault(require('./SettingsCategory')); +} + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../../../modules/nuclide-commons-ui/AtomInput'); +} + +var _Section; + +function _load_Section() { + return _Section = require('../../../modules/nuclide-commons-ui/Section'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,47 +56,36 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import observePaneItemVisibility from 'nuclide-commons-atom/observePaneItemVisibility'; -import * as React from 'react'; -import {Observable, Scheduler} from 'rxjs'; -import SettingsCategory from './SettingsCategory'; - -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {Section} from 'nuclide-commons-ui/Section'; +const WORKSPACE_VIEW_URI = exports.WORKSPACE_VIEW_URI = 'atom://nuclide/settings'; -export const WORKSPACE_VIEW_URI = 'atom://nuclide/settings'; +class SettingsPaneItem extends _react.Component { -type Props = { - initialFilter?: string, -}; - -type State = { - filter: string, -}; + constructor(props) { + super(props); -export default class SettingsPaneItem extends React.Component { - _disposables: UniversalDisposable; - _filterInput: ?AtomInput; + this._handleComponentChange = (keyPath, value) => { + (_featureConfig || _load_featureConfig()).default.set(keyPath, value); + }; - constructor(props: Props) { - super(props); + this._onFilterTextChanged = filterText => { + const filter = filterText != null ? filterText.trim() : ''; + this.setState({ + filter + }); + }; this.state = { - filter: props.initialFilter || '', + filter: props.initialFilter || '' }; } - _getConfigData(): Object { + _getConfigData() { const configData = {}; - const nuclidePackages = atom.packages - .getLoadedPackages() - .filter(pkg => pkg.metadata && pkg.metadata.nuclide); + const nuclidePackages = atom.packages.getLoadedPackages().filter(pkg => pkg.metadata && pkg.metadata.nuclide); // Config data is organized as a series of nested objects. First, by category // and then by packages in each category. Each package contains a title and an @@ -72,11 +112,11 @@ export default class SettingsPaneItem extends React.Component { // ``` nuclidePackages.forEach(pkg => { const pkgName = pkg.name; - const {nuclide} = pkg.metadata; + const { nuclide } = pkg.metadata; const config = pkg.metadata.atomConfig || nuclide.config; if (config && nuclide.configMetadata) { - const {pathComponents} = nuclide.configMetadata; + const { pathComponents } = nuclide.configMetadata; const categoryName = pathComponents[0]; const packageTitle = pathComponents[1] || pkgName; @@ -91,17 +131,10 @@ export default class SettingsPaneItem extends React.Component { const settings = {}; Object.keys(config).forEach(settingName => { const keyPath = pkgName + '.' + settingName; - const schema = featureConfig.getSchema(keyPath); + const schema = (_featureConfig || _load_featureConfig()).default.getSchema(keyPath); const title = getTitle(schema, settingName); const description = getDescription(schema); - if ( - this.state == null || - matchesFilter(this.state.filter, categoryName) || - matchesFilter(this.state.filter, packageTitle) || - matchesFilter(this.state.filter, title) || - matchesFilter(this.state.filter, description) || - matchesFilter(this.state.filter, keyPath) - ) { + if (this.state == null || matchesFilter(this.state.filter, categoryName) || matchesFilter(this.state.filter, packageTitle) || matchesFilter(this.state.filter, title) || matchesFilter(this.state.filter, description) || matchesFilter(this.state.filter, keyPath)) { settings[settingName] = { name: settingName, description, @@ -112,7 +145,7 @@ export default class SettingsPaneItem extends React.Component { order: getOrder(schema), schema, title, - value: featureConfig.get(keyPath), + value: (_featureConfig || _load_featureConfig()).default.get(keyPath) }; } }); @@ -120,7 +153,7 @@ export default class SettingsPaneItem extends React.Component { if (Object.keys(settings).length !== 0) { packages[pkgName] = { title: packageTitle, - settings, + settings }; } } @@ -128,98 +161,87 @@ export default class SettingsPaneItem extends React.Component { return configData; } - _handleComponentChange = (keyPath: string, value: any): void => { - featureConfig.set(keyPath, value); - }; - - _getSettingsKeyPaths(): Array { + _getSettingsKeyPaths() { const keyPaths = []; - const nuclidePackages = atom.packages - .getLoadedPackages() - .filter(pkg => pkg.metadata && pkg.metadata.nuclide); + const nuclidePackages = atom.packages.getLoadedPackages().filter(pkg => pkg.metadata && pkg.metadata.nuclide); nuclidePackages.forEach(pkg => { const pkgName = pkg.name; - const {nuclide} = pkg.metadata; + const { nuclide } = pkg.metadata; const config = pkg.metadata.atomConfig || nuclide.config; if (config != null) { - Object.keys(config).forEach(settingName => - keyPaths.push(pkgName + '.' + settingName), - ); + Object.keys(config).forEach(settingName => keyPaths.push(pkgName + '.' + settingName)); } }); return keyPaths; } - componentDidMount(): void { + componentDidMount() { const settingsKeyPaths = this._getSettingsKeyPaths(); - const changedSettings = settingsKeyPaths.map(keyPath => - featureConfig.observeAsStream(keyPath), - ); + const changedSettings = settingsKeyPaths.map(keyPath => (_featureConfig || _load_featureConfig()).default.observeAsStream(keyPath)); - this._disposables = new UniversalDisposable( - observePaneItemVisibility(this) - .filter(Boolean) - .delay(0, Scheduler.animationFrame) - .subscribe(() => { - if (this._filterInput != null) { - this._filterInput.focus(); - } - }), - Observable.merge(...changedSettings) - // throttle to prevent rerendering for each change if changes occur in - // rapid succession - .throttleTime(50) - .subscribe(() => { - this.setState(this._getConfigData()); - }), - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default((0, (_observePaneItemVisibility || _load_observePaneItemVisibility()).default)(this).filter(Boolean).delay(0, _rxjsBundlesRxMinJs.Scheduler.animationFrame).subscribe(() => { + if (this._filterInput != null) { + this._filterInput.focus(); + } + }), _rxjsBundlesRxMinJs.Observable.merge(...changedSettings) + // throttle to prevent rerendering for each change if changes occur in + // rapid succession + .throttleTime(50).subscribe(() => { + this.setState(this._getConfigData()); + })); } - render(): React.Node { + render() { const elements = []; const configData = this._getConfigData(); - Object.keys(configData) - .sort() - .forEach(categoryName => { - const packages = configData[categoryName]; - if (Object.keys(packages).length > 0) { - elements.push( - , - ); - } - }); + Object.keys(configData).sort().forEach(categoryName => { + const packages = configData[categoryName]; + if (Object.keys(packages).length > 0) { + elements.push(_react.createElement((_SettingsCategory || _load_SettingsCategory()).default, { + key: categoryName, + name: categoryName, + packages: packages + })); + } + }); const settings = elements.length === 0 ? null : elements; - return ( -
    -
    -
    -
    -
    -
    - { - this._filterInput = component; - }} - size="lg" - placeholderText="Filter by setting title or description" - initialValue={this.props.initialFilter} - onDidChange={this._onFilterTextChanged} - /> -
    -
    - {settings} -
    -
    -
    -
    + return _react.createElement( + 'div', + { className: 'pane-item padded settings-gadgets-pane' }, + _react.createElement( + 'div', + { className: 'settings-view panels panels-item' }, + _react.createElement( + 'div', + { className: 'panels' }, + _react.createElement( + 'div', + { className: 'panels-item' }, + _react.createElement( + 'section', + { className: 'section' }, + _react.createElement( + (_Section || _load_Section()).Section, + { headline: 'Filter', collapsable: true }, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + ref: component => { + this._filterInput = component; + }, + size: 'lg', + placeholderText: 'Filter by setting title or description', + initialValue: this.props.initialFilter, + onDidChange: this._onFilterTextChanged + }) + ) + ), + settings + ) + ) + ) ); } @@ -229,68 +251,58 @@ export default class SettingsPaneItem extends React.Component { } } - _onFilterTextChanged = (filterText: string): void => { - const filter = filterText != null ? filterText.trim() : ''; - this.setState({ - filter, - }); - }; - - getTitle(): string { + getTitle() { return 'Nuclide Settings'; } - getIconName(): string { + getIconName() { return 'tools'; } - getDefaultLocation(): string { + getDefaultLocation() { return 'center'; } - getURI(): string { + getURI() { return WORKSPACE_VIEW_URI; } // Prevent the tab getting split. - copy(): boolean { + copy() { return false; } } -function getOrder(schema: atom$ConfigSchema): number { +exports.default = SettingsPaneItem; +function getOrder(schema) { // $FlowFixMe(>=0.68.0) Flow suppress (T27187857) return typeof schema.order === 'number' ? schema.order : 0; } -function getTitle(schema: atom$ConfigSchema, settingName: string): string { +function getTitle(schema, settingName) { let title = schema.title; // flowlint-next-line sketchy-null-string:off if (!title) { - title = settingName - .replace(/([A-Z])/g, ' $1') - .replace(/^./, str => str.toUpperCase()) - .split('.') - .join(' '); + title = settingName.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase()).split('.').join(' '); } return title; } -function getDescription(schema: atom$ConfigSchema): string { +function getDescription(schema) { return schema.description || ''; } // Remove spaces and hyphens -function strip(str: string): string { +function strip(str) { return str.replace(/\s+/g, '').replace(/-+/g, ''); } /** Returns true if filter matches search string. Return true if filter is empty. */ -function matchesFilter(filter: string, searchString: string): boolean { +function matchesFilter(filter, searchString) { if (filter.length === 0) { return true; } const needle = strip(filter.toLowerCase()); const hay = strip(searchString.toLowerCase()); return hay.indexOf(needle) !== -1; -} +} \ No newline at end of file diff --git a/pkg/nuclide-settings/lib/main.js b/pkg/nuclide-settings/lib/main.js index 6e3038ded7..da6bf35248 100644 --- a/pkg/nuclide-settings/lib/main.js +++ b/pkg/nuclide-settings/lib/main.js @@ -1,3 +1,59 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.activate = activate; +exports.deactivate = deactivate; +exports.consumeToolBar = consumeToolBar; +exports.consumeDeepLinkService = consumeDeepLinkService; + +var _goToLocation; + +function _load_goToLocation() { + return _goToLocation = require('../../../modules/nuclide-commons-atom/go-to-location'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _querystring = _interopRequireDefault(require('querystring')); + +var _SettingsPaneItem; + +function _load_SettingsPaneItem() { + return _SettingsPaneItem = _interopRequireDefault(require('./SettingsPaneItem')); +} + +var _SettingsPaneItem2; + +function _load_SettingsPaneItem2() { + return _SettingsPaneItem2 = require('./SettingsPaneItem'); +} + +var _destroyItemWhere; + +function _load_destroyItemWhere() { + return _destroyItemWhere = require('../../../modules/nuclide-commons-atom/destroyItemWhere'); +} + +var _ToolbarUtils; + +function _load_ToolbarUtils() { + return _ToolbarUtils = require('../../../modules/nuclide-commons-ui/ToolbarUtils'); +} + +var _openSettingsView; + +function _load_openSettingsView() { + return _openSettingsView = _interopRequireDefault(require('./openSettingsView')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,76 +61,54 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type { - DeepLinkService, - DeepLinkParams, -} from '../../nuclide-deep-link/lib/types'; - -import {goToLocation} from 'nuclide-commons-atom/go-to-location'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import querystring from 'querystring'; -import SettingsPaneItem, {WORKSPACE_VIEW_URI} from './SettingsPaneItem'; -import {destroyItemWhere} from 'nuclide-commons-atom/destroyItemWhere'; -import {makeToolbarButtonSpec} from 'nuclide-commons-ui/ToolbarUtils'; -import openSettingsView from './openSettingsView'; +let subscriptions = null; -let subscriptions: UniversalDisposable = (null: any); - -export function activate(state: ?Object): void { - subscriptions = new UniversalDisposable(registerCommandAndOpener()); +function activate(state) { + subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(registerCommandAndOpener()); } -export function deactivate(): void { +function deactivate() { subscriptions.dispose(); - subscriptions = (null: any); + subscriptions = null; } -function registerCommandAndOpener(): UniversalDisposable { - return new UniversalDisposable( - atom.workspace.addOpener(openSettingsView), - () => destroyItemWhere(item => item instanceof SettingsPaneItem), - atom.commands.add('atom-workspace', 'nuclide-settings:toggle', () => { - atom.workspace.toggle(WORKSPACE_VIEW_URI); - }), - ); +function registerCommandAndOpener() { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(atom.workspace.addOpener((_openSettingsView || _load_openSettingsView()).default), () => (0, (_destroyItemWhere || _load_destroyItemWhere()).destroyItemWhere)(item => item instanceof (_SettingsPaneItem || _load_SettingsPaneItem()).default), atom.commands.add('atom-workspace', 'nuclide-settings:toggle', () => { + atom.workspace.toggle((_SettingsPaneItem2 || _load_SettingsPaneItem2()).WORKSPACE_VIEW_URI); + })); } -export function consumeToolBar(getToolBar: toolbar$GetToolbar): IDisposable { +function consumeToolBar(getToolBar) { const toolBar = getToolBar('nuclide-home'); toolBar.addSpacer({ - priority: -501, + priority: -501 }); - toolBar.addButton( - makeToolbarButtonSpec({ - icon: 'gear', - callback: 'nuclide-settings:toggle', - tooltip: 'Open Nuclide Settings', - priority: -500, - }), - ); - const disposable = new UniversalDisposable(() => { + toolBar.addButton((0, (_ToolbarUtils || _load_ToolbarUtils()).makeToolbarButtonSpec)({ + icon: 'gear', + callback: 'nuclide-settings:toggle', + tooltip: 'Open Nuclide Settings', + priority: -500 + })); + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { toolBar.removeItems(); }); subscriptions.add(disposable); return disposable; } -export function consumeDeepLinkService(service: DeepLinkService): IDisposable { - const disposable = service.subscribeToPath( - 'settings', - (params: DeepLinkParams): void => { - const {filter} = params; - let uri = WORKSPACE_VIEW_URI; - if (typeof filter === 'string') { - uri += '?' + querystring.stringify({filter}); - } - goToLocation(uri); - }, - ); +function consumeDeepLinkService(service) { + const disposable = service.subscribeToPath('settings', params => { + const { filter } = params; + let uri = (_SettingsPaneItem2 || _load_SettingsPaneItem2()).WORKSPACE_VIEW_URI; + if (typeof filter === 'string') { + uri += '?' + _querystring.default.stringify({ filter }); + } + (0, (_goToLocation || _load_goToLocation()).goToLocation)(uri); + }); subscriptions.add(disposable); return disposable; -} +} \ No newline at end of file diff --git a/pkg/nuclide-settings/lib/openSettingsView.js b/pkg/nuclide-settings/lib/openSettingsView.js index 518efc5d7e..4529c93d81 100644 --- a/pkg/nuclide-settings/lib/openSettingsView.js +++ b/pkg/nuclide-settings/lib/openSettingsView.js @@ -1,32 +1,47 @@ -/** - * 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 - */ - -import {viewableFromReactElement} from '../../commons-atom/viewableFromReactElement'; -import SettingsPaneItem, {WORKSPACE_VIEW_URI} from './SettingsPaneItem'; -import querystring from 'querystring'; -import * as React from 'react'; -import url from 'url'; - -export default function(uri: string) { - if (uri.startsWith(WORKSPACE_VIEW_URI)) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = function (uri) { + if (uri.startsWith((_SettingsPaneItem2 || _load_SettingsPaneItem2()).WORKSPACE_VIEW_URI)) { let initialFilter = ''; - const {query} = url.parse(uri); + const { query } = _url.default.parse(uri); if (query != null) { - const params = querystring.parse(query); + const params = _querystring.default.parse(query); if (typeof params.filter === 'string') { initialFilter = params.filter; } } - return viewableFromReactElement( - , - ); + return (0, (_viewableFromReactElement || _load_viewableFromReactElement()).viewableFromReactElement)(_react.createElement((_SettingsPaneItem || _load_SettingsPaneItem()).default, { initialFilter: initialFilter })); } +}; + +var _viewableFromReactElement; + +function _load_viewableFromReactElement() { + return _viewableFromReactElement = require('../../commons-atom/viewableFromReactElement'); } + +var _SettingsPaneItem; + +function _load_SettingsPaneItem() { + return _SettingsPaneItem = _interopRequireDefault(require('./SettingsPaneItem')); +} + +var _SettingsPaneItem2; + +function _load_SettingsPaneItem2() { + return _SettingsPaneItem2 = require('./SettingsPaneItem'); +} + +var _querystring = _interopRequireDefault(require('querystring')); + +var _react = _interopRequireWildcard(require('react')); + +var _url = _interopRequireDefault(require('url')); + +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 }; } \ No newline at end of file diff --git a/pkg/nuclide-settings/lib/types.js b/pkg/nuclide-settings/lib/types.js index 32de8db408..9a390c31f7 100644 --- a/pkg/nuclide-settings/lib/types.js +++ b/pkg/nuclide-settings/lib/types.js @@ -1,19 +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 - */ - -export type SettingsData = { - name: string, - description: string, - keyPath: string, - onChange: (value: any) => mixed, - title: string, - value: ?any, -}; +"use strict"; \ No newline at end of file diff --git a/pkg/nuclide-settings/spec/SettingsPaneItem-spec.js b/pkg/nuclide-settings/spec/SettingsPaneItem-spec.js deleted file mode 100644 index 1db865987d..0000000000 --- a/pkg/nuclide-settings/spec/SettingsPaneItem-spec.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * 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 - */ - -import invariant from 'assert'; -import nullthrows from 'nullthrows'; -import openSettingsView from '../lib/openSettingsView'; -import {WORKSPACE_VIEW_URI} from '../lib/SettingsPaneItem'; - -describe('SettingsPaneItem', () => { - beforeEach(() => { - nullthrows(document.body).appendChild(atom.views.getView(atom.workspace)); - atom.workspace.addOpener(openSettingsView); - }); - - it('sets focus to the filter input after the pane is opened', () => { - waitsForPromise(() => atom.workspace.open(WORKSPACE_VIEW_URI)); - runs(() => { - const settingsViewEl = document.querySelector('.settings-view'); - invariant(settingsViewEl != null); - - expect(settingsViewEl.contains(document.activeElement)).toBe( - true, - 'focused element is not a descendant of the .settings-view element', - ); - }); - }); -}); diff --git a/pkg/nuclide-socket-rpc/lib/Connection.js b/pkg/nuclide-socket-rpc/lib/Connection.js index af76af996c..7c9a10ab6e 100644 --- a/pkg/nuclide-socket-rpc/lib/Connection.js +++ b/pkg/nuclide-socket-rpc/lib/Connection.js @@ -1,57 +1,69 @@ -/** - * 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 strict-local - * @format - */ - -import type {TunnelHost} from 'nuclide-adb/lib/types'; -import type {IRemoteSocket} from './types'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {getLogger} from 'log4js'; -import net from 'net'; -import {protocolLogger} from '../../nuclide-server/lib/utils'; -import {track} from '../../nuclide-analytics'; - -const PROTOCOL_LOGGER_COUNT = 20; - -export class Connection { - _socket: net.Socket; - _remoteSocket: IRemoteSocket; - _disposables: UniversalDisposable; - _closed: boolean; - _disposeCalled: boolean; - _error: ?Error; - - constructor(tunnelHost: TunnelHost, remoteSocket: IRemoteSocket) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ConnectionFactory = exports.Connection = undefined; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _net = _interopRequireDefault(require('net')); + +var _utils; + +function _load_utils() { + return _utils = require('../../nuclide-server/lib/utils'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const PROTOCOL_LOGGER_COUNT = 20; /** + * 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. + * + * strict-local + * @format + */ + +class Connection { + + constructor(tunnelHost, remoteSocket) { trace('Connection: creating connection: ' + JSON.stringify(tunnelHost)); this._closed = false; this._disposeCalled = false; this._remoteSocket = remoteSocket; this._error = null; - this._socket = net.createConnection( - {port: tunnelHost.port, family: tunnelHost.family}, - socket => { - trace('Connection: connection created and ready to write data.'); - }, - ); + this._socket = _net.default.createConnection({ port: tunnelHost.port, family: tunnelHost.family }, socket => { + trace('Connection: connection created and ready to write data.'); + }); - this._disposables = new UniversalDisposable( - () => this._socket.end(), - this._remoteSocket, - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(() => this._socket.end(), this._remoteSocket); this._socket.on('error', err => { // TODO: we should find a way to send the error back // to the remote socket this._error = err; - getLogger('SocketService').error('Connection error', err); + (0, (_log4js || _load_log4js()).getLogger)('SocketService').error('Connection error', err); this._closed = true; this._socket.end(); }); @@ -64,20 +76,20 @@ export class Connection { if (!this._closed) { this._remoteSocket.write(data); } else { - track('socket-service:attempting-to-write-data-after-close', { + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('socket-service:attempting-to-write-data-after-close', { disposeCalled: this._disposeCalled, lastError: this._error, - protocolLog: protocolLogger.dump(PROTOCOL_LOGGER_COUNT), + protocolLog: (_utils || _load_utils()).protocolLogger.dump(PROTOCOL_LOGGER_COUNT) }); } }); } - write(msg: Buffer): void { + write(msg) { this._socket.write(msg); } - dispose(): void { + dispose() { trace('Connection: disposing connection'); this._disposeCalled = true; this._closed = true; @@ -85,21 +97,20 @@ export class Connection { } } -export class ConnectionFactory { +exports.Connection = Connection; +class ConnectionFactory { constructor() {} - async createConnection( - tunnelHost: TunnelHost, - socket: IRemoteSocket, - ): Promise { + async createConnection(tunnelHost, socket) { return new Connection(tunnelHost, socket); } - dispose(): void { + dispose() { trace('disposing connection.'); } } -function trace(message: string) { - getLogger('SocketService').trace(message); -} +exports.ConnectionFactory = ConnectionFactory; +function trace(message) { + (0, (_log4js || _load_log4js()).getLogger)('SocketService').trace(message); +} \ No newline at end of file diff --git a/pkg/nuclide-socket-rpc/lib/SocketService.js b/pkg/nuclide-socket-rpc/lib/SocketService.js index c8e021ebdd..4913410b0b 100644 --- a/pkg/nuclide-socket-rpc/lib/SocketService.js +++ b/pkg/nuclide-socket-rpc/lib/SocketService.js @@ -1,38 +1,54 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import * as Tunnel from './Tunnel'; -import {ConnectionFactory} from './Connection'; -import {getAvailableServerPort as _getAvailableServerPort} from 'nuclide-commons/serverPort'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getConnectionFactory = getConnectionFactory; +exports.createTunnel = createTunnel; +exports.getAvailableServerPort = getAvailableServerPort; -import type {ResolvedTunnel} from 'nuclide-adb/lib/types'; -import type {ConnectableObservable} from 'rxjs'; -import type {SocketEvent} from './types'; +var _Tunnel; + +function _load_Tunnel() { + return _Tunnel = _interopRequireWildcard(require('./Tunnel')); +} + +var _Connection; + +function _load_Connection() { + return _Connection = require('./Connection'); +} + +var _serverPort; + +function _load_serverPort() { + return _serverPort = require('../../../modules/nuclide-commons/serverPort'); +} + +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; } } /** * The role of the Connection Factory is to create * connections on the remote host. There is no easy * built-in way to do this with the current RPC framework */ -export function getConnectionFactory(): Promise { - return Promise.resolve(new ConnectionFactory()); -} +function getConnectionFactory() { + return Promise.resolve(new (_Connection || _load_Connection()).ConnectionFactory()); +} /** + * 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. + * + * strict-local + * @format + */ -export function createTunnel( - t: ResolvedTunnel, - cf: ConnectionFactory, -): ConnectableObservable { - return Tunnel.createTunnel(t, cf); +function createTunnel(t, cf) { + return (_Tunnel || _load_Tunnel()).createTunnel(t, cf); } -export async function getAvailableServerPort(): Promise { - return _getAvailableServerPort(); -} +async function getAvailableServerPort() { + return (0, (_serverPort || _load_serverPort()).getAvailableServerPort)(); +} \ No newline at end of file diff --git a/pkg/nuclide-socket-rpc/lib/SocketServiceProxy.js b/pkg/nuclide-socket-rpc/lib/SocketServiceProxy.js new file mode 100644 index 0000000000..b27dfa5c33 --- /dev/null +++ b/pkg/nuclide-socket-rpc/lib/SocketServiceProxy.js @@ -0,0 +1,544 @@ +"use strict"; + +module.exports = _client => { + const remoteModule = {}; + remoteModule.Connection = class { + constructor() { + throw Error("constructors are not supported for remote objects"); + } + + write(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "Connection.js", + line: 23 + }, + name: "Connection" + }), "write", "void", _client.marshalArguments(Array.from(arguments), [{ + name: "msg", + type: { + kind: "named", + name: "Buffer" + } + }])); + } + + dispose() { + return _client.disposeRemoteObject(this); + } + + }; + remoteModule.IRemoteSocket = class { + constructor() { + throw Error("constructors are not supported for remote objects"); + } + + write(arg0) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "types.js", + line: 20 + }, + name: "IRemoteSocket" + }), "write", "void", _client.marshalArguments(Array.from(arguments), [{ + name: "msg", + type: { + kind: "named", + name: "Buffer" + } + }])); + } + + dispose() { + return _client.disposeRemoteObject(this); + } + + }; + remoteModule.ConnectionFactory = class { + constructor() { + throw Error("constructors are not supported for remote objects"); + } + + createConnection(arg0, arg1) { + return _client.callRemoteMethod(_client.marshal(this, { + kind: "named", + location: { + type: "source", + fileName: "Connection.js", + line: 88 + }, + name: "ConnectionFactory" + }), "createConnection", "promise", _client.marshalArguments(Array.from(arguments), [{ + name: "tunnelHost", + type: { + kind: "named", + name: "TunnelHost" + } + }, { + name: "socket", + type: { + kind: "named", + name: "IRemoteSocket" + } + }])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "Connection" + }); + }); + } + + dispose() { + return _client.disposeRemoteObject(this); + } + + }; + + remoteModule.getConnectionFactory = function () { + return _client.callRemoteFunction("SocketService/getConnectionFactory", "promise", _client.marshalArguments(Array.from(arguments), [])).then(value => { + return _client.unmarshal(value, { + kind: "named", + name: "ConnectionFactory" + }); + }); + }; + + remoteModule.createTunnel = function (arg0, arg1) { + return _client.callRemoteFunction("SocketService/createTunnel", "observable", _client.marshalArguments(Array.from(arguments), [{ + name: "t", + type: { + kind: "named", + name: "ResolvedTunnel" + } + }, { + name: "cf", + type: { + kind: "named", + name: "ConnectionFactory" + } + }])).map(value => { + return _client.unmarshal(value, { + kind: "named", + name: "SocketEvent" + }); + }).publish(); + }; + + remoteModule.getAvailableServerPort = function () { + return _client.callRemoteFunction("SocketService/getAvailableServerPort", "promise", _client.marshalArguments(Array.from(arguments), [])).then(value => { + return _client.unmarshal(value, { + kind: "number" + }); + }); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "defs", { + value: { + Object: { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }, + Date: { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }, + RegExp: { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }, + Buffer: { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }, + "fs.Stats": { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }, + NuclideUri: { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }, + atom$Point: { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }, + atom$Range: { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }, + Connection: { + kind: "interface", + name: "Connection", + location: { + type: "source", + fileName: "Connection.js", + line: 23 + }, + staticMethods: {}, + instanceMethods: { + write: { + location: { + type: "source", + fileName: "Connection.js", + line: 76 + }, + kind: "function", + argumentTypes: [{ + name: "msg", + type: { + kind: "named", + name: "Buffer" + } + }], + returnType: { + kind: "void" + } + }, + dispose: { + location: { + type: "source", + fileName: "Connection.js", + line: 80 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "void" + } + } + } + }, + TunnelHost: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 57 + }, + name: "TunnelHost", + definition: { + kind: "object", + fields: [{ + name: "host", + type: { + kind: "string" + }, + optional: false + }, { + name: "port", + type: { + kind: "number" + }, + optional: false + }, { + name: "family", + type: { + kind: "union", + types: [{ + kind: "number-literal", + value: 4 + }, { + kind: "number-literal", + value: 6 + }] + }, + optional: false + }] + } + }, + IRemoteSocket: { + kind: "interface", + name: "IRemoteSocket", + location: { + type: "source", + fileName: "types.js", + line: 20 + }, + staticMethods: {}, + instanceMethods: { + write: { + location: { + type: "source", + fileName: "types.js", + line: 21 + }, + kind: "function", + argumentTypes: [{ + name: "msg", + type: { + kind: "named", + name: "Buffer" + } + }], + returnType: { + kind: "void" + } + }, + dispose: { + location: { + type: "source", + fileName: "types.js", + line: 22 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "void" + } + } + } + }, + ConnectionFactory: { + kind: "interface", + name: "ConnectionFactory", + location: { + type: "source", + fileName: "Connection.js", + line: 88 + }, + staticMethods: {}, + instanceMethods: { + createConnection: { + location: { + type: "source", + fileName: "Connection.js", + line: 91 + }, + kind: "function", + argumentTypes: [{ + name: "tunnelHost", + type: { + kind: "named", + name: "TunnelHost" + } + }, { + name: "socket", + type: { + kind: "named", + name: "IRemoteSocket" + } + }], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "Connection" + } + } + }, + dispose: { + location: { + type: "source", + fileName: "Connection.js", + line: 98 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "void" + } + } + } + }, + getConnectionFactory: { + kind: "function", + name: "getConnectionFactory", + location: { + type: "source", + fileName: "SocketService.js", + line: 25 + }, + type: { + location: { + type: "source", + fileName: "SocketService.js", + line: 25 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "named", + name: "ConnectionFactory" + } + } + } + }, + SocketEvent: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 12 + }, + name: "SocketEvent", + definition: { + kind: "union", + types: [{ + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "server_started" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "client_connected" + }, + optional: false + }, { + name: "clientPort", + type: { + kind: "number" + }, + optional: false + }] + }, { + kind: "object", + fields: [{ + name: "type", + type: { + kind: "string-literal", + value: "client_disconnected" + }, + optional: false + }, { + name: "clientPort", + type: { + kind: "number" + }, + optional: false + }] + }], + discriminantField: "type" + } + }, + ResolvedTunnel: { + kind: "alias", + location: { + type: "source", + fileName: "types.js", + line: 63 + }, + name: "ResolvedTunnel", + definition: { + kind: "object", + fields: [{ + name: "from", + type: { + kind: "named", + name: "TunnelHost" + }, + optional: false + }, { + name: "to", + type: { + kind: "named", + name: "TunnelHost" + }, + optional: false + }] + } + }, + createTunnel: { + kind: "function", + name: "createTunnel", + location: { + type: "source", + fileName: "SocketService.js", + line: 29 + }, + type: { + location: { + type: "source", + fileName: "SocketService.js", + line: 29 + }, + kind: "function", + argumentTypes: [{ + name: "t", + type: { + kind: "named", + name: "ResolvedTunnel" + } + }, { + name: "cf", + type: { + kind: "named", + name: "ConnectionFactory" + } + }], + returnType: { + kind: "observable", + type: { + kind: "named", + name: "SocketEvent" + } + } + } + }, + getAvailableServerPort: { + kind: "function", + name: "getAvailableServerPort", + location: { + type: "source", + fileName: "SocketService.js", + line: 36 + }, + type: { + location: { + type: "source", + fileName: "SocketService.js", + line: 36 + }, + kind: "function", + argumentTypes: [], + returnType: { + kind: "promise", + type: { + kind: "number" + } + } + } + } + } +}); \ No newline at end of file diff --git a/pkg/nuclide-socket-rpc/lib/Tunnel.js b/pkg/nuclide-socket-rpc/lib/Tunnel.js index 7cbe294d61..746f79a453 100644 --- a/pkg/nuclide-socket-rpc/lib/Tunnel.js +++ b/pkg/nuclide-socket-rpc/lib/Tunnel.js @@ -1,3 +1,31 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RemoteSocket = undefined; +exports.createTunnel = createTunnel; +exports.tunnelDescription = tunnelDescription; +exports.shortenHostname = shortenHostname; + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _net = _interopRequireDefault(require('net')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,33 +33,19 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {ResolvedTunnel} from 'nuclide-adb/lib/types'; -import type {Connection, ConnectionFactory} from './Connection'; -import type {SocketEvent, IRemoteSocket} from './types.js'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import {getLogger} from 'log4js'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {ConnectableObservable, Observable} from 'rxjs'; - -import net from 'net'; - const LOG_DELTA = 500000; // log for every half megabyte of transferred data const DEBUG_VERBOSE = false; const activeTunnels = new Map(); -export function createTunnel( - t: ResolvedTunnel, - cf: ConnectionFactory, -): ConnectableObservable { +function createTunnel(t, cf) { const logStatsIfNecessary = getStatLogger(LOG_DELTA); - let bytesReceived: number = 0; - let bytesWritten: number = 0; + let bytesReceived = 0; + let bytesWritten = 0; // We check if a tunnel already exists listening to the same port, if it // does we stop it so this one can take precedence. The onus on managing @@ -40,30 +54,26 @@ export function createTunnel( const tunnelKey = `${shortenHostname(t.from.host)}:${t.from.port}`; const existingTunnel = activeTunnels.get(tunnelKey); if (existingTunnel) { - trace( - `Tunnel: Stopping existing tunnel -- ${tunnelDescription( - existingTunnel.tunnel, - )}`, - ); + trace(`Tunnel: Stopping existing tunnel -- ${tunnelDescription(existingTunnel.tunnel)}`); existingTunnel.dispose(); } - return Observable.create(observer => { + return _rxjsBundlesRxMinJs.Observable.create(observer => { const tunnel = t; trace(`Tunnel: creating tunnel -- ${tunnelDescription(tunnel)}`); - const {port, family} = tunnel.from; - const connections: Map> = new Map(); + const { port, family } = tunnel.from; + const connections = new Map(); // set up server to start listening for connections // on client_connected - const listener: net.Server = net.createServer(async socket => { + const listener = _net.default.createServer(async socket => { const clientPort = socket.remotePort; if (DEBUG_VERBOSE) { trace('Tunnel: client connected on remote port ' + clientPort); } - observer.next({type: 'client_connected', clientPort}); + observer.next({ type: 'client_connected', clientPort }); // create outgoing connection using connection factory const localSocket = new LocalSocket(socket); @@ -84,16 +94,12 @@ export function createTunnel( if (DEBUG_VERBOSE) { socket.on('end', () => { - trace( - `Tunnel: end (port: ${clientPort}, ${tunnelDescription(tunnel)})`, - ); + trace(`Tunnel: end (port: ${clientPort}, ${tunnelDescription(tunnel)})`); }); } socket.on('error', err => { - trace( - `Tunnel: error (port: ${clientPort}, ${tunnelDescription(tunnel)})`, - ); + trace(`Tunnel: error (port: ${clientPort}, ${tunnelDescription(tunnel)})`); trace(`Tunnel: error (server: ${port}, client: ${clientPort}): ${err}`); socket.destroy(err); }); @@ -111,15 +117,13 @@ export function createTunnel( socket.on('close', () => { // on client_disconnect remove and dispose the connection if (DEBUG_VERBOSE) { - trace( - `Tunnel: close (port: ${clientPort}, ${tunnelDescription(tunnel)})`, - ); + trace(`Tunnel: close (port: ${clientPort}, ${tunnelDescription(tunnel)})`); } connectionPromise.then(connection => { connection.dispose(); connections.delete(clientPort); }); - observer.next({type: 'client_disconnected', clientPort}); + observer.next({ type: 'client_disconnected', clientPort }); }); }); @@ -128,40 +132,36 @@ export function createTunnel( observer.error(err); }); - listener.listen({host: family === 6 ? '::' : '0.0.0.0', port}, () => { + listener.listen({ host: family === 6 ? '::' : '0.0.0.0', port }, () => { trace('Tunnel: server listening on port ' + port); - observer.next({type: 'server_started'}); + observer.next({ type: 'server_started' }); }); const dispose = () => { trace(`Tunnel: shutting down tunnel ${tunnelDescription(tunnel)}`); - connections.forEach(connectionPromise => - connectionPromise.then(conn => { - conn.dispose(); - }), - ); + connections.forEach(connectionPromise => connectionPromise.then(conn => { + conn.dispose(); + })); connections.clear(); cf.dispose(); listener.close(); activeTunnels.delete(tunnelKey); }; - activeTunnels.set(tunnelKey, {dispose, tunnel}); + activeTunnels.set(tunnelKey, { dispose, tunnel }); return dispose; }).publish(); } -export function tunnelDescription(tunnel: ResolvedTunnel) { - return `${shortenHostname(tunnel.from.host)}:${ - tunnel.from.port - }->${shortenHostname(tunnel.to.host)}:${tunnel.to.port}`; +function tunnelDescription(tunnel) { + return `${shortenHostname(tunnel.from.host)}:${tunnel.from.port}->${shortenHostname(tunnel.to.host)}:${tunnel.to.port}`; } -export function shortenHostname(host: NuclideUri): string { +function shortenHostname(host) { let result = host; - if (nuclideUri.isRemote(result)) { - result = nuclideUri.getHostname(result); + if ((_nuclideUri || _load_nuclideUri()).default.isRemote(result)) { + result = (_nuclideUri || _load_nuclideUri()).default.getHostname(result); } if (result.endsWith('.facebook.com')) { result = result.slice(0, result.length - '.facebook.com'.length); @@ -176,47 +176,45 @@ export function shortenHostname(host: NuclideUri): string { } class LocalSocket { - _socket: net.Socket; - _writeListener: (byteCount: number) => void; - constructor(socket: net.Socket) { + constructor(socket) { this._socket = socket; - this._writeListener = (byteCount: number) => {}; + this._writeListener = byteCount => {}; } - onWrite(listener: (byteCount: number) => void) { + onWrite(listener) { this._writeListener = listener; } - write(data: Buffer): void { + write(data) { this._socket.write(data); this._writeListener(data.length); } - end(): void { + end() { this._socket.end(); } } -export class RemoteSocket implements IRemoteSocket { - _socket: LocalSocket | net.Socket; +class RemoteSocket { - constructor(socket: LocalSocket | net.Socket) { + constructor(socket) { this._socket = socket; } - write(data: Buffer): void { + write(data) { this._socket.write(data); } - dispose(): void { + dispose() { this._socket.end(); } } -function getStatLogger(delta): (number, number) => void { - let lastLoggedBytes: number = 0; - return (bytesWritten: number, bytesReceived: number): void => { +exports.RemoteSocket = RemoteSocket; +function getStatLogger(delta) { + let lastLoggedBytes = 0; + return (bytesWritten, bytesReceived) => { const totalBytes = bytesWritten + bytesReceived; if (totalBytes > lastLoggedBytes + delta) { lastLoggedBytes = totalBytes; @@ -225,16 +223,10 @@ function getStatLogger(delta): (number, number) => void { }; } -function logStats( - bytesWritten: number, - bytesReceived: number, - totalBytes: number, -): void { - trace( - `Tunnel: ${totalBytes} bytes transferred; ${bytesWritten} written, ${bytesReceived} received`, - ); +function logStats(bytesWritten, bytesReceived, totalBytes) { + trace(`Tunnel: ${totalBytes} bytes transferred; ${bytesWritten} written, ${bytesReceived} received`); } -function trace(message: string) { - getLogger('SocketService').trace(message); -} +function trace(message) { + (0, (_log4js || _load_log4js()).getLogger)('SocketService').trace(message); +} \ No newline at end of file diff --git a/pkg/nuclide-socket-rpc/lib/types.js b/pkg/nuclide-socket-rpc/lib/types.js index f92b97f596..a726efc43f 100644 --- a/pkg/nuclide-socket-rpc/lib/types.js +++ b/pkg/nuclide-socket-rpc/lib/types.js @@ -1,23 +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 strict - * @format - */ - -export type SocketEvent = - | {type: 'server_started'} - | { - type: 'client_connected', - clientPort: number, - } - | {type: 'client_disconnected', clientPort: number}; - -export interface IRemoteSocket { - write(msg: Buffer): void; - dispose(): void; -} +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-socket-rpc/spec/Connection-spec.js b/pkg/nuclide-socket-rpc/spec/Connection-spec.js deleted file mode 100644 index 848a544b33..0000000000 --- a/pkg/nuclide-socket-rpc/spec/Connection-spec.js +++ /dev/null @@ -1,156 +0,0 @@ -/** - * 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 - */ - -import {Connection, ConnectionFactory} from '../lib/Connection'; -import net from 'net'; -import invariant from 'assert'; -import {getLogger} from 'log4js'; -import {RemoteSocket} from '../lib/Tunnel'; - -const TEST_PORT = 5004; -const TEST_TUNNEL_HOST = { - host: 'localhost', - port: TEST_PORT, - family: 6, -}; - -describe('Connection', () => { - const connectionFactory = new ConnectionFactory(); - let remoteSocket: RemoteSocket; - let remoteServer; - - beforeEach(done => { - getLogger('SocketService-spec').debug('--SPEC START--'); - waitsForPromise(async () => { - remoteServer = await createServer(TEST_PORT + 1); - remoteSocket = await createRemoteSocket(TEST_PORT + 1); - invariant(done); - done(); - }); - }); - - afterEach(done => { - waitsForPromise(async () => { - await closeRemoteSocket(remoteSocket, remoteServer.server); - await closeServer(remoteServer.server); - getLogger('SocketService-spec').debug('--SPEC END--'); - invariant(done); - done(); - }); - }); - - it('should create a connection to an already listening server', done => { - const connectionSpy = jasmine.createSpy('connectionSpy'); - let localServer: net.Server; - let connection: Connection; - - waitsForPromise(async () => { - const port = TEST_PORT; - - await new Promise(resolve => { - localServer = net.createServer(connectionSpy); - localServer.listen({port}, resolve); - }); - - connection = await connectionFactory.createConnection( - TEST_TUNNEL_HOST, - remoteSocket, - ); - - waitsFor(() => connectionSpy.callCount > 0); - - runs(() => { - expect(connectionSpy).toHaveBeenCalled(); - connection.dispose(); - localServer.close(done); - }); - }); - }); - - it('should write to the remote server when the local server responds', done => { - const remoteServerWriteSpy = jasmine.createSpy('remoteServerSpy'); - const connectionSpy = jasmine.createSpy('connectionSpy'); - let localServer: net.Server; - let connection: Connection; - - remoteServer.socket.on('data', remoteServerWriteSpy); - - waitsForPromise(async () => { - const port = TEST_PORT; - - await new Promise(resolve => { - // echo server - localServer = net.createServer(socket => { - connectionSpy(); - socket.pipe(socket); - }); - localServer.listen({port}, resolve); - }); - - connection = await connectionFactory.createConnection( - TEST_TUNNEL_HOST, - remoteSocket, - ); - - waitsFor(() => connectionSpy.callCount > 0); - - runs(() => { - expect(connectionSpy).toHaveBeenCalled(); - connection.write(new Buffer('hello world')); - }); - - waitsFor(() => remoteServerWriteSpy.callCount > 0); - - runs(() => { - expect(remoteServerWriteSpy).toHaveBeenCalled(); - connection.dispose(); - localServer.close(done); - }); - }); - }); -}); - -async function createRemoteSocket(port: number): Promise { - return new Promise(resolve => { - const socket = net.createConnection({port, family: 6}, () => { - resolve(new RemoteSocket(socket)); - }); - }); -} - -async function closeRemoteSocket( - remoteSocket: RemoteSocket, - remoteServer: net.Server, -): Promise { - remoteSocket.dispose(); - await closeServer(remoteServer); -} - -async function createServer(port: number): Promise { - const result = {}; - return new Promise(resolve => { - const server: net.Server = net.createServer(socket => { - result.socket = socket; - }); - - result.server = server; - invariant(server); - server.listen({host: '::', port}, () => { - resolve(result); - }); - }); -} - -async function closeServer(server: net.Server): Promise { - return new Promise(resolve => { - server.close(resolve); - }); -} diff --git a/pkg/nuclide-socket-rpc/spec/SocketService-spec.js b/pkg/nuclide-socket-rpc/spec/SocketService-spec.js deleted file mode 100644 index 7061335ad7..0000000000 --- a/pkg/nuclide-socket-rpc/spec/SocketService-spec.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * 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 strict - * @format - */ - -import {getLogger} from 'log4js'; - -describe('SocketService', () => { - beforeEach(() => { - getLogger('SocketService-spec').debug('--SPEC START--'); - }); - - afterEach(() => { - getLogger('SocketService-spec').debug('--SPEC END--'); - }); -}); diff --git a/pkg/nuclide-socket-rpc/spec/Tunnel-spec.js b/pkg/nuclide-socket-rpc/spec/Tunnel-spec.js deleted file mode 100644 index 85eb818177..0000000000 --- a/pkg/nuclide-socket-rpc/spec/Tunnel-spec.js +++ /dev/null @@ -1,298 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import * as Tunnel from '../lib/Tunnel'; -import {ConnectionFactory} from '../lib/Connection'; -import net from 'net'; -import invariant from 'assert'; -import {ConnectableObservable} from 'rxjs'; -import {getLogger} from 'log4js'; - -import type {SocketEvent} from '../lib/types.js'; - -const TEST_PORT = 5004; -const cf = new ConnectionFactory(); - -describe('createTunnel', () => { - let td; - - beforeEach(() => { - getLogger('SocketService-spec').debug('--SPEC START--'); - td = { - to: { - host: 'localhost', - port: TEST_PORT + 1, - family: 6, - }, - from: { - host: 'localhost', - port: TEST_PORT, - family: 6, - }, - }; - }); - - afterEach(() => { - getLogger('SocketService-spec').debug('--SPEC END--'); - }); - - it('should set up a listener that a client can connect to', done => { - const events = Tunnel.createTunnel(td, new ConnectionFactory()); - let serverListening = false; - let subscription; - - waitsForPromise(async () => { - await new Promise(resolve => { - subscription = events.refCount().subscribe({ - next: event => { - if (event.type === 'server_started') { - serverListening = true; - resolve(); - } - }, - }); - }); - }); - - waitsForPromise(async () => { - expect(serverListening).toBe(true); - await testConnectability(TEST_PORT); - subscription.unsubscribe(); - invariant(done); - done(); - }); - }); - - it('should return a ConnectableObservable that emits listener events', done => { - const events: ConnectableObservable = Tunnel.createTunnel( - td, - cf, - ); - const eventList = []; - let types; - - const subscription = events.refCount().subscribe({ - next: event => { - eventList.push(event); - }, - }); - - waitsForPromise(async () => { - await testConnectability(TEST_PORT); - subscription.unsubscribe(); - types = eventList.map(event => event.type); - expect(types).toContain('server_started'); - expect(types).toContain('client_connected'); - expect(types).toContain('client_disconnected'); - invariant(done); - done(); - }); - }); - - it('should send replies back to the originating client', done => { - const message = 'HELLO WORLD'; - let response = null; - let echoServer; - - // start echo server - waitsForPromise(async () => { - echoServer = net.createServer(socket => { - socket.pipe(socket); - }); - await new Promise(resolve => { - echoServer.listen({host: '::', port: TEST_PORT + 1}, resolve); - }); - }); - - // create tunnel - const subscription = Tunnel.createTunnel(td, cf) - .refCount() - .subscribe(); - - // create connection and send data - waitsForPromise(async () => { - await new Promise(resolve => { - const socket = net.createConnection(TEST_PORT, () => { - socket.on('data', data => { - response = data.toString(); - resolve(); - }); - socket.write(new Buffer(message)); - }); - }); - }); - - runs(() => { - expect(message).toEqual(response); - subscription.unsubscribe(); - invariant(done); - echoServer.close(done); - }); - }); - - it('should re-tunnel if the port is already bound on a tunnel', done => { - let subscription = null; - waitsForPromise(async () => { - await new Promise(resolve => { - subscription = Tunnel.createTunnel(td, cf) - .refCount() - .subscribe({ - next: resolve, - }); - }); - }); - - waitsForPromise(async () => { - await new Promise(resolve => { - subscription = Tunnel.createTunnel(td, cf) - .refCount() - .subscribe({ - next: resolve, - }); - }); - }); - - runs(() => { - invariant(subscription); - subscription.unsubscribe(); - invariant(done); - done(); - }); - }); - - it('should stop listening when the observable is unsubscribed', () => { - waitsForPromise(async () => { - const observable = Tunnel.createTunnel(td, cf); - - await new Promise(resolve => { - const subscription = observable - .refCount() - .take(1) - .subscribe({ - next: event => { - resolve(event); - subscription.unsubscribe(); - }, - }); - }); - }); - - waitsForPromise({shouldReject: true}, async () => { - await testConnectability(TEST_PORT); - }); - }); - - it('should allow for multiple clients to connect and interact', done => { - let toServer; - const sockets: Array = []; - let subscription = null; - - // create the 'to' server - waitsForPromise(async () => { - await new Promise(resolve => { - toServer = net.createServer(socket => { - socket.pipe(socket); - }); - toServer.listen({host: '::', port: TEST_PORT + 1}, resolve); - }); - }); - - waitsForPromise(async () => { - await new Promise(resolve => { - subscription = Tunnel.createTunnel(td, cf) - .refCount() - .subscribe({next: resolve}); - }); - }); - - waitsForPromise(async () => { - await new Promise(resolve => { - sockets.push(net.createConnection(TEST_PORT, resolve)); - }); - }); - - waitsForPromise(async () => { - await new Promise(resolve => { - sockets.push(net.createConnection(TEST_PORT, resolve)); - }); - }); - - waitsForPromise(async () => { - await new Promise(resolve => { - sockets.forEach((socket, index) => { - socket.on('data', data => { - expect(data.toString()).toEqual('data' + index); - }); - socket.write(new Buffer('data' + index)); - }); - resolve(); - }); - }); - - runs(() => { - invariant(subscription); - subscription.unsubscribe(); - toServer.close(done); - }); - }); - - it('should handle clients that error out', done => { - let subscription = null; - let toServer; - - // create the 'to' server - waitsForPromise(async () => { - await new Promise(resolve => { - toServer = net.createServer(socket => { - socket.pipe(socket); - }); - toServer.listen({host: '::', port: TEST_PORT + 1}, resolve); - }); - }); - - waitsForPromise(async () => { - await new Promise(resolve => { - subscription = Tunnel.createTunnel(td, cf) - .refCount() - .subscribe({next: resolve}); - }); - }); - - waitsForPromise(async () => { - await new Promise(resolve => { - const socket = net.createConnection(TEST_PORT, () => { - socket.destroy(new Error('boom')); - resolve(); - }); - socket.on('error', () => {}); - }); - }); - - runs(() => { - invariant(subscription); - subscription.unsubscribe(); - toServer.close(done); - }); - }); -}); - -async function testConnectability(port: number): Promise { - return new Promise((resolve, reject) => { - const socket = net.connect(port); - socket.on('error', err => reject(err)); - invariant(socket); - socket.on('connect', async () => { - socket.write(new Buffer('hello world')); - socket.on('end', () => resolve()); - socket.end(); - }); - }); -} diff --git a/pkg/nuclide-source-control-helpers/__tests__/hg-repository-test.js b/pkg/nuclide-source-control-helpers/__tests__/hg-repository-test.js index bea552883d..3564195cf4 100644 --- a/pkg/nuclide-source-control-helpers/__tests__/hg-repository-test.js +++ b/pkg/nuclide-source-control-helpers/__tests__/hg-repository-test.js @@ -1,80 +1,72 @@ -/** - * 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 strict-local - * @format - */ +'use strict'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {generateFixture} from 'nuclide-commons/test-helpers'; +var _nuclideUri; -import findHgRepository from '../lib/hg-repository'; +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _testHelpers; + +function _load_testHelpers() { + return _testHelpers = require('../../../modules/nuclide-commons/test-helpers'); +} + +var _hgRepository; + +function _load_hgRepository() { + return _hgRepository = _interopRequireDefault(require('../lib/hg-repository')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } describe('findHgRepository', () => { it('finds an hg repo without an hgrc', async () => { await (async () => { - const fixturePath = await generateFixture( - 'hg-repo', - new Map([['a/b/.hg/fakefile', ''], ['a/b/c/d/e', '']]), - ); - expect(findHgRepository(nuclideUri.join(fixturePath, 'a/b/c/d'))).toEqual( - { - repoPath: nuclideUri.join(fixturePath, 'a/b/.hg'), - originURL: null, - workingDirectoryPath: nuclideUri.join(fixturePath, 'a/b'), - }, - ); + const fixturePath = await (0, (_testHelpers || _load_testHelpers()).generateFixture)('hg-repo', new Map([['a/b/.hg/fakefile', ''], ['a/b/c/d/e', '']])); + expect((0, (_hgRepository || _load_hgRepository()).default)((_nuclideUri || _load_nuclideUri()).default.join(fixturePath, 'a/b/c/d'))).toEqual({ + repoPath: (_nuclideUri || _load_nuclideUri()).default.join(fixturePath, 'a/b/.hg'), + originURL: null, + workingDirectoryPath: (_nuclideUri || _load_nuclideUri()).default.join(fixturePath, 'a/b') + }); })(); }); it('finds an hg repo with an hgrc', async () => { await (async () => { - const fixturePath = await generateFixture( - 'hg-repo', - new Map([ - ['a/b/.hg/hgrc', '[paths]\ndefault = foo'], - ['a/b/c/d/e', ''], - ]), - ); - expect(findHgRepository(nuclideUri.join(fixturePath, 'a/b/c/d'))).toEqual( - { - repoPath: nuclideUri.join(fixturePath, 'a/b/.hg'), - originURL: 'foo', - workingDirectoryPath: nuclideUri.join(fixturePath, 'a/b'), - }, - ); + const fixturePath = await (0, (_testHelpers || _load_testHelpers()).generateFixture)('hg-repo', new Map([['a/b/.hg/hgrc', '[paths]\ndefault = foo'], ['a/b/c/d/e', '']])); + expect((0, (_hgRepository || _load_hgRepository()).default)((_nuclideUri || _load_nuclideUri()).default.join(fixturePath, 'a/b/c/d'))).toEqual({ + repoPath: (_nuclideUri || _load_nuclideUri()).default.join(fixturePath, 'a/b/.hg'), + originURL: 'foo', + workingDirectoryPath: (_nuclideUri || _load_nuclideUri()).default.join(fixturePath, 'a/b') + }); })(); }); it('finds the first hg repo', async () => { await (async () => { - const fixturePath = await generateFixture( - 'hg-repo', - new Map([['a/b/.hg/hgrc', ''], ['a/.hg/hgrc', ''], ['a/b/c/d/e', '']]), - ); - expect(findHgRepository(nuclideUri.join(fixturePath, 'a/b/c/d'))).toEqual( - { - repoPath: nuclideUri.join(fixturePath, 'a/b/.hg'), - originURL: null, - workingDirectoryPath: nuclideUri.join(fixturePath, 'a/b'), - }, - ); + const fixturePath = await (0, (_testHelpers || _load_testHelpers()).generateFixture)('hg-repo', new Map([['a/b/.hg/hgrc', ''], ['a/.hg/hgrc', ''], ['a/b/c/d/e', '']])); + expect((0, (_hgRepository || _load_hgRepository()).default)((_nuclideUri || _load_nuclideUri()).default.join(fixturePath, 'a/b/c/d'))).toEqual({ + repoPath: (_nuclideUri || _load_nuclideUri()).default.join(fixturePath, 'a/b/.hg'), + originURL: null, + workingDirectoryPath: (_nuclideUri || _load_nuclideUri()).default.join(fixturePath, 'a/b') + }); })(); }); it('works with no hg repo', async () => { await (async () => { - const fixturePath = await generateFixture( - 'hg-repo', - new Map([['a/b/.git/fakefile', ''], ['a/b/c/d/e', '']]), - ); - expect(findHgRepository(nuclideUri.join(fixturePath, 'a/b/c/d'))).toBe( - null, - ); + const fixturePath = await (0, (_testHelpers || _load_testHelpers()).generateFixture)('hg-repo', new Map([['a/b/.git/fakefile', ''], ['a/b/c/d/e', '']])); + expect((0, (_hgRepository || _load_hgRepository()).default)((_nuclideUri || _load_nuclideUri()).default.join(fixturePath, 'a/b/c/d'))).toBe(null); })(); }); -}); +}); /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-source-control-helpers/lib/hg-repository.js b/pkg/nuclide-source-control-helpers/lib/hg-repository.js index e178eedcd7..5bfd139ab2 100644 --- a/pkg/nuclide-source-control-helpers/lib/hg-repository.js +++ b/pkg/nuclide-source-control-helpers/lib/hg-repository.js @@ -1,60 +1,70 @@ -/** - * 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 - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = findHgRepository; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import ini from 'ini'; -import fs from 'fs'; +var _nuclideUri; -import type {HgRepositoryDescription} from '..'; +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _ini; + +function _load_ini() { + return _ini = _interopRequireDefault(require('ini')); +} + +var _fs = _interopRequireDefault(require('fs')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * This function returns HgRepositoryDescription filled with a repoPath and * originURL iff it finds that the given directory is within an Hg repository. */ -export default function findHgRepository( - startDirectoryPath: string, -): ?HgRepositoryDescription { - if (!nuclideUri.isLocal(startDirectoryPath)) { +function findHgRepository(startDirectoryPath) { + if (!(_nuclideUri || _load_nuclideUri()).default.isLocal(startDirectoryPath)) { return null; } let workingDirectoryPath = startDirectoryPath; for (;;) { - const repoPath = nuclideUri.join(workingDirectoryPath, '.hg'); + const repoPath = (_nuclideUri || _load_nuclideUri()).default.join(workingDirectoryPath, '.hg'); if (tryIsDirectorySync(repoPath)) { let originURL = null; // Note that .hg/hgrc will not exist in a local repo created via `hg init`, for example. - const hgrc = tryReadFileSync(nuclideUri.join(repoPath, 'hgrc')); + const hgrc = tryReadFileSync((_nuclideUri || _load_nuclideUri()).default.join(repoPath, 'hgrc')); if (hgrc != null) { - const config = ini.parse(hgrc); - if ( - typeof config.paths === 'object' && - typeof config.paths.default === 'string' - ) { + const config = (_ini || _load_ini()).default.parse(hgrc); + if (typeof config.paths === 'object' && typeof config.paths.default === 'string') { originURL = config.paths.default; } } - return {repoPath, originURL, workingDirectoryPath}; + return { repoPath, originURL, workingDirectoryPath }; } - const parentDir = nuclideUri.dirname(workingDirectoryPath); + const parentDir = (_nuclideUri || _load_nuclideUri()).default.dirname(workingDirectoryPath); if (parentDir === workingDirectoryPath) { return null; } else { workingDirectoryPath = parentDir; } } -} +} /** + * 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. + * + * + * @format + */ function tryIsDirectorySync(dirname) { try { - const stat = fs.statSync(dirname); + const stat = _fs.default.statSync(dirname); return stat.isDirectory(); } catch (err) { return false; @@ -63,8 +73,8 @@ function tryIsDirectorySync(dirname) { function tryReadFileSync(filename) { try { - return fs.readFileSync(filename, 'utf8'); + return _fs.default.readFileSync(filename, 'utf8'); } catch (err) { return null; } -} +} \ No newline at end of file diff --git a/pkg/nuclide-source-control-helpers/lib/main.js b/pkg/nuclide-source-control-helpers/lib/main.js index 276c18e83e..a1d3a0f500 100644 --- a/pkg/nuclide-source-control-helpers/lib/main.js +++ b/pkg/nuclide-source-control-helpers/lib/main.js @@ -1,3 +1,18 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.findHgRepository = undefined; + +var _hgRepository; + +function _load_hgRepository() { + return _hgRepository = _interopRequireDefault(require('./hg-repository')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,16 +20,8 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -export type HgRepositoryDescription = { - repoPath: string, - originURL: ?string, - workingDirectoryPath: string, -}; - -import findHgRepository from './hg-repository'; - -export {findHgRepository}; +exports.findHgRepository = (_hgRepository || _load_hgRepository()).default; \ No newline at end of file diff --git a/pkg/nuclide-ssh-tunnel/lib/ActiveTunnels.js b/pkg/nuclide-ssh-tunnel/lib/ActiveTunnels.js index 8c55ff9a22..d920f33a97 100644 --- a/pkg/nuclide-ssh-tunnel/lib/ActiveTunnels.js +++ b/pkg/nuclide-ssh-tunnel/lib/ActiveTunnels.js @@ -1,58 +1,58 @@ -/** - * 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 strict-local - * @format - */ - -import type {ResolvedTunnel} from 'nuclide-adb/lib/types'; -import type {ActiveTunnel} from './types'; - -import {List, Map} from 'immutable'; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ActiveTunnels = undefined; + +var _immutable; + +function _load_immutable() { + return _immutable = require('immutable'); +} // A thin wrapper around Immutable.Map with a key factory -export class ActiveTunnels { - _storage: Map; +class ActiveTunnels { + + constructor(storage = (0, (_immutable || _load_immutable()).Map)()) { + this.get = tunnel => { + return this._storage.get(this._keyForTunnel(tunnel)); + }; + + this.set = (tunnel, value) => { + const key = this._keyForTunnel(tunnel); + return new ActiveTunnels(this._storage.set(key, value)); + }; + + this.toList = () => { + return this._storage.toList(); + }; + + this.update = (tunnel, updater) => { + const key = this._keyForTunnel(tunnel); + return new ActiveTunnels(this._storage.update(key, value => updater(value))); + }; + + this.delete = tunnel => { + const key = this._keyForTunnel(tunnel); + return new ActiveTunnels(this._storage.delete(key)); + }; + + this._keyForTunnel = resolved => { + return `${resolved.from.host}:${resolved.from.port}:${resolved.from.family}->${resolved.to.host}:${resolved.to.port}:${resolved.to.family}`; + }; - constructor(storage: Map = Map()) { this._storage = storage; } - get = (tunnel: ResolvedTunnel): ?ActiveTunnel => { - return this._storage.get(this._keyForTunnel(tunnel)); - }; - - set = (tunnel: ResolvedTunnel, value: ActiveTunnel): ActiveTunnels => { - const key = this._keyForTunnel(tunnel); - return new ActiveTunnels(this._storage.set(key, value)); - }; - - toList = (): List => { - return this._storage.toList(); - }; - - update = ( - tunnel: ResolvedTunnel, - updater: ActiveTunnel => ActiveTunnel, - ): ActiveTunnels => { - const key = this._keyForTunnel(tunnel); - return new ActiveTunnels( - this._storage.update(key, value => updater(value)), - ); - }; - - delete = (tunnel: ResolvedTunnel): ActiveTunnels => { - const key = this._keyForTunnel(tunnel); - return new ActiveTunnels(this._storage.delete(key)); - }; - - _keyForTunnel = (resolved: ResolvedTunnel): string => { - return `${resolved.from.host}:${resolved.from.port}:${ - resolved.from.family - }->${resolved.to.host}:${resolved.to.port}:${resolved.to.family}`; - }; } +exports.ActiveTunnels = ActiveTunnels; /** + * 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. + * + * strict-local + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-ssh-tunnel/lib/CreateObservables.js b/pkg/nuclide-ssh-tunnel/lib/CreateObservables.js index 8092ce1e09..a51f2d2d1c 100644 --- a/pkg/nuclide-ssh-tunnel/lib/CreateObservables.js +++ b/pkg/nuclide-ssh-tunnel/lib/CreateObservables.js @@ -1,3 +1,41 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.createObservableForTunnels = createObservableForTunnels; +exports.createObservableForTunnel = createObservableForTunnel; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _shallowequal; + +function _load_shallowequal() { + return _shallowequal = _interopRequireDefault(require('shallowequal')); +} + +var _Normalization; + +function _load_Normalization() { + return _Normalization = require('./Normalization'); +} + +var _Actions; + +function _load_Actions() { + return _Actions = _interopRequireWildcard(require('./redux/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; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,40 +43,26 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {Tunnel} from 'nuclide-adb/lib/types'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Observable} from 'rxjs'; -import shallowEqual from 'shallowequal'; -import {resolveTunnel} from './Normalization'; -import * as Actions from './redux/Actions'; - -export function createObservableForTunnels( - tunnels: Array, - store: Store, -): Observable<'ready'> { +function createObservableForTunnels(tunnels, store) { const observables = tunnels.map(t => createObservableForTunnel(t, store)); - const highOrder = Observable.from(observables); + const highOrder = _rxjsBundlesRxMinJs.Observable.from(observables); // $FlowFixMe combineAll return highOrder.combineAll().mapTo('ready'); } -export function createObservableForTunnel( - tunnel: Tunnel, - store: Store, -): Observable<'ready'> { - const resolved = resolveTunnel(tunnel); - if (shallowEqual(resolved.from, resolved.to)) { +function createObservableForTunnel(tunnel, store) { + const resolved = (0, (_Normalization || _load_Normalization()).resolveTunnel)(tunnel); + if ((0, (_shallowequal || _load_shallowequal()).default)(resolved.from, resolved.to)) { // Identical source/destination tunnels are always immediately ready, never close. // Makes it easy for users to call this function without branching on whether they need to. - return Observable.of('ready').concat(Observable.never()); + return _rxjsBundlesRxMinJs.Observable.of('ready').concat(_rxjsBundlesRxMinJs.Observable.never()); } - return Observable.create(observer => { + return _rxjsBundlesRxMinJs.Observable.create(observer => { const subscription = { description: tunnel.description, onTunnelClose: error => { @@ -47,20 +71,16 @@ export function createObservableForTunnel( } else { observer.error(error); } - }, + } }; - store.dispatch( - Actions.subscribeToTunnel(subscription, resolved, error => { - if (error == null) { - observer.next('ready'); - } else { - observer.error(error); - } - }), - ); + store.dispatch((_Actions || _load_Actions()).subscribeToTunnel(subscription, resolved, error => { + if (error == null) { + observer.next('ready'); + } else { + observer.error(error); + } + })); - return new UniversalDisposable(() => - store.dispatch(Actions.unsubscribeFromTunnel(subscription, resolved)), - ); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => store.dispatch((_Actions || _load_Actions()).unsubscribeFromTunnel(subscription, resolved))); }); -} +} \ No newline at end of file diff --git a/pkg/nuclide-ssh-tunnel/lib/Normalization.js b/pkg/nuclide-ssh-tunnel/lib/Normalization.js index 84420ede77..7d3596fd96 100644 --- a/pkg/nuclide-ssh-tunnel/lib/Normalization.js +++ b/pkg/nuclide-ssh-tunnel/lib/Normalization.js @@ -1,3 +1,35 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.resolveTunnel = resolveTunnel; +exports.getSharedHostUri = getSharedHostUri; +exports.getSocketServiceByHost = getSocketServiceByHost; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../../modules/nuclide-commons/nuclideUri')); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../nuclide-remote-connection'); +} + +var _nuclideSocketRpc; + +function _load_nuclideSocketRpc() { + return _nuclideSocketRpc = _interopRequireWildcard(require('../../nuclide-socket-rpc')); +} + +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 }; } + +// Normalize host URIs /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,57 +37,44 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {Tunnel, ResolvedTunnel} from 'nuclide-adb/lib/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import typeof * as SocketService from '../../nuclide-socket-rpc'; - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {getSocketServiceByNuclideUri} from '../../nuclide-remote-connection'; -import * as SocketServiceImpl from '../../nuclide-socket-rpc'; - -// Normalize host URIs -export function resolveTunnel(tunnel: Tunnel): ResolvedTunnel { - const {from, to} = tunnel; +function resolveTunnel(tunnel) { + const { from, to } = tunnel; return { from: { host: getSharedHostUri(from.host), port: from.port, - family: from.family || 6, + family: from.family || 6 }, to: { host: getSharedHostUri(to.host), port: to.port, - family: to.family || 6, - }, + family: to.family || 6 + } }; } // From tunneling perspective, host is a "singleton", all roots can reuse the same socket service. -export function getSharedHostUri( - host: 'localhost' | NuclideUri | string, -): 'localhost' | NuclideUri { +function getSharedHostUri(host) { if (host === 'localhost' || host === '') { return 'localhost'; - } else if (nuclideUri.isRemote(host)) { - return nuclideUri.createRemoteUri(nuclideUri.getHostname(host), '/'); + } else if ((_nuclideUri || _load_nuclideUri()).default.isRemote(host)) { + return (_nuclideUri || _load_nuclideUri()).default.createRemoteUri((_nuclideUri || _load_nuclideUri()).default.getHostname(host), '/'); } else { // We assume that the passed string is a hostname. - return nuclideUri.createRemoteUri(host, '/'); + return (_nuclideUri || _load_nuclideUri()).default.createRemoteUri(host, '/'); } } // We assume `host` has already been processed by getSharedHostUri -export function getSocketServiceByHost( - host: 'localhost' | NuclideUri, -): SocketService { +function getSocketServiceByHost(host) { if (host === 'localhost') { // Bypass the RPC framework to avoid extra marshal/unmarshaling. - return SocketServiceImpl; + return _nuclideSocketRpc || _load_nuclideSocketRpc(); } else { - return getSocketServiceByNuclideUri(host); + return (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getSocketServiceByNuclideUri)(host); } -} +} \ No newline at end of file diff --git a/pkg/nuclide-ssh-tunnel/lib/Whitelist.js b/pkg/nuclide-ssh-tunnel/lib/Whitelist.js index bea2368aac..83ab344405 100644 --- a/pkg/nuclide-ssh-tunnel/lib/Whitelist.js +++ b/pkg/nuclide-ssh-tunnel/lib/Whitelist.js @@ -1,3 +1,19 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _memoize2; + +function _load_memoize() { + return _memoize2 = _interopRequireDefault(require('lodash/memoize')); +} + +exports.validateTunnel = validateTunnel; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,15 +21,11 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {ResolvedTunnel} from 'nuclide-adb/lib/types'; - -import {memoize} from 'lodash'; - -export async function validateTunnel(tunnel: ResolvedTunnel): Promise { +async function validateTunnel(tunnel) { if (tunnel.to.host === 'localhost') { return true; } @@ -26,7 +38,7 @@ export async function validateTunnel(tunnel: ResolvedTunnel): Promise { } // require fb-sitevar module lazily -const requireFetchSitevarOnce = memoize(() => { +const requireFetchSitevarOnce = (0, (_memoize2 || _load_memoize()).default)(() => { try { // $FlowFB return require('../../commons-node/fb-sitevar').fetchSitevarOnce; @@ -36,7 +48,7 @@ const requireFetchSitevarOnce = memoize(() => { }); // returns either a list of allowed ports, or null if not restricted -async function getAllowedPorts(): Promise> { +async function getAllowedPorts() { const fetchSitevarOnce = requireFetchSitevarOnce(); if (fetchSitevarOnce == null) { return null; @@ -46,4 +58,4 @@ async function getAllowedPorts(): Promise> { return []; } return allowedPorts; -} +} \ No newline at end of file diff --git a/pkg/nuclide-ssh-tunnel/lib/main.js b/pkg/nuclide-ssh-tunnel/lib/main.js index 8aff06937c..9642879474 100644 --- a/pkg/nuclide-ssh-tunnel/lib/main.js +++ b/pkg/nuclide-ssh-tunnel/lib/main.js @@ -1,3 +1,75 @@ +'use strict'; + +var _createPackage; + +function _load_createPackage() { + return _createPackage = _interopRequireDefault(require('../../../modules/nuclide-commons-atom/createPackage')); +} + +var _destroyItemWhere; + +function _load_destroyItemWhere() { + return _destroyItemWhere = require('../../../modules/nuclide-commons-atom/destroyItemWhere'); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../../modules/nuclide-commons/UniversalDisposable')); +} + +var _CreateObservables; + +function _load_CreateObservables() { + return _CreateObservables = require('./CreateObservables'); +} + +var _Normalization; + +function _load_Normalization() { + return _Normalization = require('./Normalization'); +} + +var _TunnelsPanel; + +function _load_TunnelsPanel() { + return _TunnelsPanel = require('./ui/TunnelsPanel'); +} + +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 = _interopRequireWildcard(require('./redux/Reducers')); +} + +var _reduxMin; + +function _load_reduxMin() { + return _reduxMin = require('redux/dist/redux.min.js'); +} + +var _reduxObservable; + +function _load_reduxObservable() { + return _reduxObservable = require('../../../modules/nuclide-commons/redux-observable'); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,113 +77,62 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {OutputService} from 'atom-ide-ui'; -import type {SshTunnelService} from 'nuclide-adb/lib/types'; -import type CwdApi from '../../nuclide-current-working-directory/lib/CwdApi'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import {destroyItemWhere} from 'nuclide-commons-atom/destroyItemWhere'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {createObservableForTunnels} from './CreateObservables'; -import {getSharedHostUri, getSocketServiceByHost} from './Normalization'; -import {TunnelsPanel, WORKSPACE_VIEW_URI} from './ui/TunnelsPanel'; -import * as Actions from './redux/Actions'; -import * as Epics from './redux/Epics'; -import * as Reducers from './redux/Reducers'; -import {applyMiddleware, combineReducers, createStore} from 'redux'; -import { - combineEpics, - createEpicMiddleware, -} from 'nuclide-commons/redux-observable'; - class Activation { - _disposables: UniversalDisposable; - _store: Store; - - constructor(rawState: ?Object) { - const epics = Object.keys(Epics) - .map(k => Epics[k]) - .filter(epic => typeof epic === 'function'); - this._store = createStore( - combineReducers(Reducers), - applyMiddleware(createEpicMiddleware(combineEpics(...epics))), - ); - - this._disposables = new UniversalDisposable( - this._closeAllTunnels.bind(this), - this._registerCommandAndOpener(), - ); + + constructor(rawState) { + const epics = Object.keys(_Epics || _load_Epics()).map(k => (_Epics || _load_Epics())[k]).filter(epic => typeof epic === 'function'); + this._store = (0, (_reduxMin || _load_reduxMin()).createStore)((0, (_reduxMin || _load_reduxMin()).combineReducers)(_Reducers || _load_Reducers()), (0, (_reduxMin || _load_reduxMin()).applyMiddleware)((0, (_reduxObservable || _load_reduxObservable()).createEpicMiddleware)((0, (_reduxObservable || _load_reduxObservable()).combineEpics)(...epics)))); + + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(this._closeAllTunnels.bind(this), this._registerCommandAndOpener()); } dispose() { this._disposables.dispose(); } - _registerCommandAndOpener(): UniversalDisposable { - return new UniversalDisposable( - atom.workspace.addOpener(uri => { - if (uri === WORKSPACE_VIEW_URI) { - return new TunnelsPanel(this._store); - } - }), - () => destroyItemWhere(item => item instanceof TunnelsPanel), - atom.commands.add( - 'atom-workspace', - 'nuclide-ssh-tunnels-panel:toggle', - () => { - atom.workspace.toggle(WORKSPACE_VIEW_URI); - }, - ), - ); + _registerCommandAndOpener() { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(atom.workspace.addOpener(uri => { + if (uri === (_TunnelsPanel || _load_TunnelsPanel()).WORKSPACE_VIEW_URI) { + return new (_TunnelsPanel || _load_TunnelsPanel()).TunnelsPanel(this._store); + } + }), () => (0, (_destroyItemWhere || _load_destroyItemWhere()).destroyItemWhere)(item => item instanceof (_TunnelsPanel || _load_TunnelsPanel()).TunnelsPanel), atom.commands.add('atom-workspace', 'nuclide-ssh-tunnels-panel:toggle', () => { + atom.workspace.toggle((_TunnelsPanel || _load_TunnelsPanel()).WORKSPACE_VIEW_URI); + })); } - provideSshTunnelService(): SshTunnelService { + provideSshTunnelService() { return { - openTunnels: tunnel => createObservableForTunnels(tunnel, this._store), - getOpenTunnels: () => - this._store - .getState() - .tunnels.toList() - .map(t => t.tunnel) - .toSet(), - getAvailableServerPort: async uri => - getSocketServiceByHost(getSharedHostUri(uri)).getAvailableServerPort(), + openTunnels: tunnel => (0, (_CreateObservables || _load_CreateObservables()).createObservableForTunnels)(tunnel, this._store), + getOpenTunnels: () => this._store.getState().tunnels.toList().map(t => t.tunnel).toSet(), + getAvailableServerPort: async uri => (0, (_Normalization || _load_Normalization()).getSocketServiceByHost)((0, (_Normalization || _load_Normalization()).getSharedHostUri)(uri)).getAvailableServerPort() }; } - deserializeSshTunnelsPanel(): atom$PaneItem { - return new TunnelsPanel(this._store); + deserializeSshTunnelsPanel() { + return new (_TunnelsPanel || _load_TunnelsPanel()).TunnelsPanel(this._store); } _closeAllTunnels() { const tunnels = this._store.getState().tunnels; - tunnels - .toList() - .forEach(active => - this._store.dispatch(Actions.closeTunnel(active.tunnel)), - ); + tunnels.toList().forEach(active => this._store.dispatch((_Actions || _load_Actions()).closeTunnel(active.tunnel))); } - consumeCurrentWorkingDirectory(api: CwdApi): void { - this._disposables.add( - api.observeCwd(directory => { - this._store.dispatch(Actions.setCurrentWorkingDirectory(directory)); - }), - ); + consumeCurrentWorkingDirectory(api) { + this._disposables.add(api.observeCwd(directory => { + this._store.dispatch((_Actions || _load_Actions()).setCurrentWorkingDirectory(directory)); + })); } - consumeOutputService(api: OutputService): void { - this._disposables.add( - api.registerOutputProvider({ - id: 'SSH tunnels', - messages: this._store.getState().consoleOutput, - }), - ); + consumeOutputService(api) { + this._disposables.add(api.registerOutputProvider({ + id: 'SSH tunnels', + messages: this._store.getState().consoleOutput + })); } } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/pkg/nuclide-ssh-tunnel/lib/redux/Actions.js b/pkg/nuclide-ssh-tunnel/lib/redux/Actions.js index 0887494067..da3f2a1a22 100644 --- a/pkg/nuclide-ssh-tunnel/lib/redux/Actions.js +++ b/pkg/nuclide-ssh-tunnel/lib/redux/Actions.js @@ -1,3 +1,16 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.closeTunnel = closeTunnel; +exports.deleteTunnel = deleteTunnel; +exports.openTunnel = openTunnel; +exports.requestTunnel = requestTunnel; +exports.setTunnelState = setTunnelState; +exports.setCurrentWorkingDirectory = setCurrentWorkingDirectory; +exports.subscribeToTunnel = subscribeToTunnel; +exports.unsubscribeFromTunnel = unsubscribeFromTunnel; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,106 +18,71 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow strict-local + * strict-local * @format */ -import type {ResolvedTunnel} from 'nuclide-adb/lib/types'; -import type { - CloseTunnelAction, - DeleteTunnelAction, - OpenTunnelAction, - RequestTunnelAction, - SetTunnelStateAction, - SubscribeToTunnelAction, - TunnelState, - TunnelSubscription, - UnsubscribeFromTunnelAction, -} from '../types'; - -export const CLOSE_TUNNEL = 'CLOSE_TUNNEL'; -export const DELETE_TUNNEL = 'DELETE_TUNNEL'; -export const OPEN_TUNNEL = 'OPEN_TUNNEL'; -export const REQUEST_TUNNEL = 'REQUEST_TUNNEL'; -export const SET_TUNNEL_STATE = 'SET_TUNNEL_STATE'; -export const SET_CURRENT_WORKING_DIRECTORY = 'SET_CURRENT_WORKING_DIRECTORY'; -export const SUBSCRIBE_TO_TUNNEL = 'SUBSCRIBE_TO_TUNNEL'; -export const UNSUBSCRIBE_FROM_TUNNEL = 'UNSUBSCRIBE_FROM_TUNNEL'; +const CLOSE_TUNNEL = exports.CLOSE_TUNNEL = 'CLOSE_TUNNEL'; +const DELETE_TUNNEL = exports.DELETE_TUNNEL = 'DELETE_TUNNEL'; +const OPEN_TUNNEL = exports.OPEN_TUNNEL = 'OPEN_TUNNEL'; +const REQUEST_TUNNEL = exports.REQUEST_TUNNEL = 'REQUEST_TUNNEL'; +const SET_TUNNEL_STATE = exports.SET_TUNNEL_STATE = 'SET_TUNNEL_STATE'; +const SET_CURRENT_WORKING_DIRECTORY = exports.SET_CURRENT_WORKING_DIRECTORY = 'SET_CURRENT_WORKING_DIRECTORY'; +const SUBSCRIBE_TO_TUNNEL = exports.SUBSCRIBE_TO_TUNNEL = 'SUBSCRIBE_TO_TUNNEL'; +const UNSUBSCRIBE_FROM_TUNNEL = exports.UNSUBSCRIBE_FROM_TUNNEL = 'UNSUBSCRIBE_FROM_TUNNEL'; -export function closeTunnel( - tunnel: ResolvedTunnel, - error: ?Error, -): CloseTunnelAction { +function closeTunnel(tunnel, error) { return { type: CLOSE_TUNNEL, - payload: {tunnel, error}, + payload: { tunnel, error } }; } -export function deleteTunnel(tunnel: ResolvedTunnel): DeleteTunnelAction { +function deleteTunnel(tunnel) { return { type: DELETE_TUNNEL, - payload: {tunnel}, + payload: { tunnel } }; } -export function openTunnel( - tunnel: ResolvedTunnel, - open: () => void, - close: () => void, -): OpenTunnelAction { +function openTunnel(tunnel, open, close) { return { type: OPEN_TUNNEL, - payload: {tunnel, open, close}, + payload: { tunnel, open, close } }; } -export function requestTunnel( - description: string, - tunnel: ResolvedTunnel, - onOpen: (?Error) => void, - onClose: (?Error) => void, -): RequestTunnelAction { +function requestTunnel(description, tunnel, onOpen, onClose) { return { type: REQUEST_TUNNEL, - payload: {description, tunnel, onOpen, onClose}, + payload: { description, tunnel, onOpen, onClose } }; } -export function setTunnelState( - tunnel: ResolvedTunnel, - state: TunnelState, -): SetTunnelStateAction { +function setTunnelState(tunnel, state) { return { type: SET_TUNNEL_STATE, - payload: {tunnel, state}, + payload: { tunnel, state } }; } -export function setCurrentWorkingDirectory(directory: ?string) { +function setCurrentWorkingDirectory(directory) { return { type: SET_CURRENT_WORKING_DIRECTORY, - payload: {directory}, + payload: { directory } }; } -export function subscribeToTunnel( - subscription: TunnelSubscription, - tunnel: ResolvedTunnel, - onOpen: (?Error) => void, -): SubscribeToTunnelAction { +function subscribeToTunnel(subscription, tunnel, onOpen) { return { type: SUBSCRIBE_TO_TUNNEL, - payload: {onOpen, subscription, tunnel}, + payload: { onOpen, subscription, tunnel } }; } -export function unsubscribeFromTunnel( - subscription: TunnelSubscription, - tunnel: ResolvedTunnel, -): UnsubscribeFromTunnelAction { +function unsubscribeFromTunnel(subscription, tunnel) { return { type: UNSUBSCRIBE_FROM_TUNNEL, - payload: {subscription, tunnel}, + payload: { subscription, tunnel } }; -} +} \ No newline at end of file diff --git a/pkg/nuclide-ssh-tunnel/lib/redux/Epics.js b/pkg/nuclide-ssh-tunnel/lib/redux/Epics.js index 7624470aa5..52e1c843cc 100644 --- a/pkg/nuclide-ssh-tunnel/lib/redux/Epics.js +++ b/pkg/nuclide-ssh-tunnel/lib/redux/Epics.js @@ -1,3 +1,62 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.subscribeToTunnelEpic = subscribeToTunnelEpic; +exports.unsubscribeFromTunnelEpic = unsubscribeFromTunnelEpic; +exports.requestTunnelEpic = requestTunnelEpic; +exports.openTunnelEpic = openTunnelEpic; +exports.closeTunnelEpic = closeTunnelEpic; + +var _Normalization; + +function _load_Normalization() { + return _Normalization = require('../Normalization'); +} + +var _Whitelist; + +function _load_Whitelist() { + return _Whitelist = require('../Whitelist'); +} + +var _Actions; + +function _load_Actions() { + return _Actions = _interopRequireWildcard(require('./Actions')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _log4js; + +function _load_log4js() { + return _log4js = require('log4js'); +} + +var _Tunnel; + +function _load_Tunnel() { + return _Tunnel = require('../../../nuclide-socket-rpc/lib/Tunnel'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../../../nuclide-remote-connection'); +} + +var _passesGK; + +function _load_passesGK() { + return _passesGK = _interopRequireDefault(require('../../../commons-node/passesGK')); +} + +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) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,280 +64,227 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * * @format */ -import type {ActionsObservable} from 'nuclide-commons/redux-observable'; -import type {Action, Store} from '../types'; - -import {getSocketServiceByHost} from '../Normalization'; -import {validateTunnel} from '../Whitelist'; -import * as Actions from './Actions'; -import {Observable} from 'rxjs'; -import {getLogger} from 'log4js'; -import invariant from 'assert'; -import {tunnelDescription} from '../../../nuclide-socket-rpc/lib/Tunnel'; -import {getBigDigClientByNuclideUri} from '../../../nuclide-remote-connection'; -import passesGK from '../../../commons-node/passesGK'; - -const logger = getLogger('nuclide-ssh-tunnel'); - -export function subscribeToTunnelEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions - .ofType(Actions.SUBSCRIBE_TO_TUNNEL) - .mergeMap(async action => { - invariant(action.type === Actions.SUBSCRIBE_TO_TUNNEL); - const {onOpen, subscription, tunnel} = action.payload; - const {tunnels} = store.getState(); - const activeTunnel = tunnels.get(tunnel); - invariant(activeTunnel); - if (activeTunnel.subscriptions.count() > 1) { - const friendlyString = `${tunnelDescription(tunnel)} (${ - subscription.description - })`; - store.getState().consoleOutput.next({ - text: `Reusing tunnel: ${friendlyString}`, - level: 'info', - }); - onOpen(null); - return null; - } +const logger = (0, (_log4js || _load_log4js()).getLogger)('nuclide-ssh-tunnel'); - return Actions.requestTunnel( - subscription.description, - tunnel, - onOpen, - subscription.onTunnelClose, - ); - }) - .mergeMap(action => { - if (action == null) { - return Observable.empty(); - } else { - return Observable.of(action); - } - }); +function subscribeToTunnelEpic(actions, store) { + return actions.ofType((_Actions || _load_Actions()).SUBSCRIBE_TO_TUNNEL).mergeMap(async action => { + if (!(action.type === (_Actions || _load_Actions()).SUBSCRIBE_TO_TUNNEL)) { + throw new Error('Invariant violation: "action.type === Actions.SUBSCRIBE_TO_TUNNEL"'); + } + + const { onOpen, subscription, tunnel } = action.payload; + const { tunnels } = store.getState(); + const activeTunnel = tunnels.get(tunnel); + + if (!activeTunnel) { + throw new Error('Invariant violation: "activeTunnel"'); + } + + if (activeTunnel.subscriptions.count() > 1) { + const friendlyString = `${(0, (_Tunnel || _load_Tunnel()).tunnelDescription)(tunnel)} (${subscription.description})`; + store.getState().consoleOutput.next({ + text: `Reusing tunnel: ${friendlyString}`, + level: 'info' + }); + onOpen(null); + return null; + } + + return (_Actions || _load_Actions()).requestTunnel(subscription.description, tunnel, onOpen, subscription.onTunnelClose); + }).mergeMap(action => { + if (action == null) { + return _rxjsBundlesRxMinJs.Observable.empty(); + } else { + return _rxjsBundlesRxMinJs.Observable.of(action); + } + }); } -export function unsubscribeFromTunnelEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions - .ofType(Actions.UNSUBSCRIBE_FROM_TUNNEL) - .mergeMap(async action => { - invariant(action.type === Actions.UNSUBSCRIBE_FROM_TUNNEL); - const {subscription, tunnel} = action.payload; - const {tunnels} = store.getState(); - const activeTunnel = tunnels.get(tunnel); - if ( - activeTunnel == null || - activeTunnel.error != null || - activeTunnel.state === 'initializing' - ) { - // We want to show the tunnel error message only once, not for every subscription. - return null; - } - const friendlyString = `${tunnelDescription(tunnel)} (${ - subscription.description - })`; - if (activeTunnel.subscriptions.count() > 0) { - store.getState().consoleOutput.next({ - text: `Stopped reusing tunnel: ${friendlyString}`, - level: 'info', - }); - // Don't close the tunnel just yet, there are other subscribers. - return null; - } else { - store.getState().consoleOutput.next({ - text: `Closed tunnel: ${friendlyString}`, - level: 'info', - }); - } +function unsubscribeFromTunnelEpic(actions, store) { + return actions.ofType((_Actions || _load_Actions()).UNSUBSCRIBE_FROM_TUNNEL).mergeMap(async action => { + if (!(action.type === (_Actions || _load_Actions()).UNSUBSCRIBE_FROM_TUNNEL)) { + throw new Error('Invariant violation: "action.type === Actions.UNSUBSCRIBE_FROM_TUNNEL"'); + } - if (activeTunnel.state === 'closing') { - return null; - } + const { subscription, tunnel } = action.payload; + const { tunnels } = store.getState(); + const activeTunnel = tunnels.get(tunnel); + if (activeTunnel == null || activeTunnel.error != null || activeTunnel.state === 'initializing') { + // We want to show the tunnel error message only once, not for every subscription. + return null; + } + const friendlyString = `${(0, (_Tunnel || _load_Tunnel()).tunnelDescription)(tunnel)} (${subscription.description})`; + if (activeTunnel.subscriptions.count() > 0) { + store.getState().consoleOutput.next({ + text: `Stopped reusing tunnel: ${friendlyString}`, + level: 'info' + }); + // Don't close the tunnel just yet, there are other subscribers. + return null; + } else { + store.getState().consoleOutput.next({ + text: `Closed tunnel: ${friendlyString}`, + level: 'info' + }); + } - return Actions.closeTunnel(tunnel, null); - }) - .mergeMap(action => { - if (action == null) { - return Observable.empty(); - } else { - return Observable.of(action); - } - }); + if (activeTunnel.state === 'closing') { + return null; + } + + return (_Actions || _load_Actions()).closeTunnel(tunnel, null); + }).mergeMap(action => { + if (action == null) { + return _rxjsBundlesRxMinJs.Observable.empty(); + } else { + return _rxjsBundlesRxMinJs.Observable.of(action); + } + }); } -export function requestTunnelEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions - .ofType(Actions.REQUEST_TUNNEL) - .mergeMap(async action => { - invariant(action.type === Actions.REQUEST_TUNNEL); - const {tunnel, onOpen} = action.payload; - const {from, to} = tunnel; - - const [useBigDigTunnel, isValidated] = await Promise.all([ - passesGK('nuclide_big_dig_tunnel'), - validateTunnel(tunnel), - ]); - - if (!isValidated) { - onOpen( - new Error( - `Trying to open a tunnel on a non-whitelisted port: ${ - to.port - }\n\n` + - 'Contact the Nuclide team if you would like this port to be available.', - ), - ); - return null; - } +function requestTunnelEpic(actions, store) { + return actions.ofType((_Actions || _load_Actions()).REQUEST_TUNNEL).mergeMap(async action => { + if (!(action.type === (_Actions || _load_Actions()).REQUEST_TUNNEL)) { + throw new Error('Invariant violation: "action.type === Actions.REQUEST_TUNNEL"'); + } + + const { tunnel, onOpen } = action.payload; + const { from, to } = tunnel; + + const [useBigDigTunnel, isValidated] = await Promise.all([(0, (_passesGK || _load_passesGK()).default)('nuclide_big_dig_tunnel'), (0, (_Whitelist || _load_Whitelist()).validateTunnel)(tunnel)]); + + if (!isValidated) { + onOpen(new Error(`Trying to open a tunnel on a non-whitelisted port: ${to.port}\n\n` + 'Contact the Nuclide team if you would like this port to be available.')); + return null; + } + + const remoteTunnelHost = from.host === 'localhost' ? to : from; + const localTunnelHost = from.host === 'localhost' ? from : to; + const isReverse = from.host !== 'localhost'; + const useIPv4 = to.family === 4; - const remoteTunnelHost = from.host === 'localhost' ? to : from; - const localTunnelHost = from.host === 'localhost' ? from : to; - const isReverse = from.host !== 'localhost'; - const useIPv4 = to.family === 4; - - const fromService = getSocketServiceByHost(from.host); - const toService = getSocketServiceByHost(to.host); - const bigDigClient = getBigDigClientByNuclideUri(remoteTunnelHost.host); - - let clientCount = 0; - const connectionFactory = await toService.getConnectionFactory(); - - let subscription; - let newTunnelPromise; - - let isTunnelOpen = false; - const open = () => { - if (!useBigDigTunnel) { - const events = fromService.createTunnel(tunnel, connectionFactory); - subscription = events.refCount().subscribe({ - next: event => { - if (event.type === 'server_started') { - const state = store.getState(); - const activeTunnel = state.tunnels.get(tunnel); - invariant(activeTunnel); - const friendlyString = `${tunnelDescription( - tunnel, - )} (${activeTunnel.subscriptions - .map(s => s.description) - .join(', ')})`; - state.consoleOutput.next({ - text: `Opened tunnel: ${friendlyString}`, - level: 'info', - }); - isTunnelOpen = true; - store.dispatch(Actions.setTunnelState(tunnel, 'ready')); - onOpen(); - } else if (event.type === 'client_connected') { - clientCount++; - store.dispatch(Actions.setTunnelState(tunnel, 'active')); - } else if (event.type === 'client_disconnected') { - clientCount--; - if (clientCount === 0) { - store.dispatch(Actions.setTunnelState(tunnel, 'ready')); - } + const fromService = (0, (_Normalization || _load_Normalization()).getSocketServiceByHost)(from.host); + const toService = (0, (_Normalization || _load_Normalization()).getSocketServiceByHost)(to.host); + const bigDigClient = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getBigDigClientByNuclideUri)(remoteTunnelHost.host); + + let clientCount = 0; + const connectionFactory = await toService.getConnectionFactory(); + + let subscription; + let newTunnelPromise; + + let isTunnelOpen = false; + const open = () => { + if (!useBigDigTunnel) { + const events = fromService.createTunnel(tunnel, connectionFactory); + subscription = events.refCount().subscribe({ + next: event => { + if (event.type === 'server_started') { + const state = store.getState(); + const activeTunnel = state.tunnels.get(tunnel); + + if (!activeTunnel) { + throw new Error('Invariant violation: "activeTunnel"'); } - }, - error: error => { - if (!isTunnelOpen) { - onOpen(error); + + const friendlyString = `${(0, (_Tunnel || _load_Tunnel()).tunnelDescription)(tunnel)} (${activeTunnel.subscriptions.map(s => s.description).join(', ')})`; + state.consoleOutput.next({ + text: `Opened tunnel: ${friendlyString}`, + level: 'info' + }); + isTunnelOpen = true; + store.dispatch((_Actions || _load_Actions()).setTunnelState(tunnel, 'ready')); + onOpen(); + } else if (event.type === 'client_connected') { + clientCount++; + store.dispatch((_Actions || _load_Actions()).setTunnelState(tunnel, 'active')); + } else if (event.type === 'client_disconnected') { + clientCount--; + if (clientCount === 0) { + store.dispatch((_Actions || _load_Actions()).setTunnelState(tunnel, 'ready')); } - store.dispatch(Actions.closeTunnel(tunnel, error)); - }, - }); - } else { - logger.info( - `using Big Dig to create a tunnel: ${localTunnelHost.port}<=>${ - remoteTunnelHost.port - }`, - ); - try { - newTunnelPromise = bigDigClient.createTunnel( - localTunnelHost.port, - remoteTunnelHost.port, - isReverse, - useIPv4, - ); - } catch (error) { - onOpen(error); - store.dispatch(Actions.closeTunnel(tunnel, error)); - throw error; + } + }, + error: error => { + if (!isTunnelOpen) { + onOpen(error); + } + store.dispatch((_Actions || _load_Actions()).closeTunnel(tunnel, error)); } + }); + } else { + logger.info(`using Big Dig to create a tunnel: ${localTunnelHost.port}<=>${remoteTunnelHost.port}`); + try { + newTunnelPromise = bigDigClient.createTunnel(localTunnelHost.port, remoteTunnelHost.port, isReverse, useIPv4); + } catch (error) { + onOpen(error); + store.dispatch((_Actions || _load_Actions()).closeTunnel(tunnel, error)); + throw error; + } - newTunnelPromise.then(newTunnel => { - newTunnel.on('error', error => { - logger.error('error from tunnel: ', error); - store.dispatch(Actions.closeTunnel(tunnel, error)); - }); - store.dispatch(Actions.setTunnelState(tunnel, 'ready')); - onOpen(); - - const friendlyString = `${tunnelDescription(tunnel)}`; - - const state = store.getState(); - state.consoleOutput.next({ - text: `Opened tunnel: ${friendlyString}`, - level: 'info', - }); + newTunnelPromise.then(newTunnel => { + newTunnel.on('error', error => { + logger.error('error from tunnel: ', error); + store.dispatch((_Actions || _load_Actions()).closeTunnel(tunnel, error)); }); - } - }; + store.dispatch((_Actions || _load_Actions()).setTunnelState(tunnel, 'ready')); + onOpen(); - let close; + const friendlyString = `${(0, (_Tunnel || _load_Tunnel()).tunnelDescription)(tunnel)}`; - if (!useBigDigTunnel) { - close = () => subscription.unsubscribe(); - } else { - close = () => { - newTunnelPromise.then(newTunnel => newTunnel.close()).catch(e => { - logger.error('Tunnel error on close: ', e); + const state = store.getState(); + state.consoleOutput.next({ + text: `Opened tunnel: ${friendlyString}`, + level: 'info' }); - }; + }); } + }; - return Actions.openTunnel(tunnel, open, close); - }) - .mergeMap(action => { - if (action == null) { - return Observable.empty(); - } else { - return Observable.of(action); - } - }); + let close; + + if (!useBigDigTunnel) { + close = () => subscription.unsubscribe(); + } else { + close = () => { + newTunnelPromise.then(newTunnel => newTunnel.close()).catch(e => { + logger.error('Tunnel error on close: ', e); + }); + }; + } + + return (_Actions || _load_Actions()).openTunnel(tunnel, open, close); + }).mergeMap(action => { + if (action == null) { + return _rxjsBundlesRxMinJs.Observable.empty(); + } else { + return _rxjsBundlesRxMinJs.Observable.of(action); + } + }); } -export function openTunnelEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions - .ofType(Actions.OPEN_TUNNEL) - .do(action => { - invariant(action.type === Actions.OPEN_TUNNEL); - action.payload.open(); - }) - .ignoreElements(); +function openTunnelEpic(actions, store) { + return actions.ofType((_Actions || _load_Actions()).OPEN_TUNNEL).do(action => { + if (!(action.type === (_Actions || _load_Actions()).OPEN_TUNNEL)) { + throw new Error('Invariant violation: "action.type === Actions.OPEN_TUNNEL"'); + } + + action.payload.open(); + }).ignoreElements(); } -export function closeTunnelEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions.ofType(Actions.CLOSE_TUNNEL).map(action => { - invariant(action.type === Actions.CLOSE_TUNNEL); - const {tunnels} = store.getState(); - const {error, tunnel} = action.payload; +function closeTunnelEpic(actions, store) { + return actions.ofType((_Actions || _load_Actions()).CLOSE_TUNNEL).map(action => { + if (!(action.type === (_Actions || _load_Actions()).CLOSE_TUNNEL)) { + throw new Error('Invariant violation: "action.type === Actions.CLOSE_TUNNEL"'); + } + + const { tunnels } = store.getState(); + const { error, tunnel } = action.payload; const activeTunnel = tunnels.get(tunnel); if (activeTunnel != null) { @@ -287,16 +293,14 @@ export function closeTunnelEpic( } activeTunnel.subscriptions.forEach(s => s.onTunnelClose(error)); if (error != null) { - const friendlyString = `${tunnelDescription( - tunnel, - )} (${activeTunnel.subscriptions.map(s => s.description).join(', ')})`; + const friendlyString = `${(0, (_Tunnel || _load_Tunnel()).tunnelDescription)(tunnel)} (${activeTunnel.subscriptions.map(s => s.description).join(', ')})`; store.getState().consoleOutput.next({ text: `Tunnel error: ${friendlyString}\n${error.message}`, - level: 'error', + level: 'error' }); } } - return Actions.deleteTunnel(tunnel); + return (_Actions || _load_Actions()).deleteTunnel(tunnel); }); -} +} \ No newline at end of file diff --git a/pkg/nuclide-ssh-tunnel/lib/redux/Reducers.js b/pkg/nuclide-ssh-tunnel/lib/redux/Reducers.js index e2a8e4002f..8a54b0fc59 100644 --- a/pkg/nuclide-ssh-tunnel/lib/redux/Reducers.js +++ b/pkg/nuclide-ssh-tunnel/lib/redux/Reducers.js @@ -1,95 +1,101 @@ -/** - * 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 strict-local - * @format - */ - -import type {ConsoleMessage} from 'atom-ide-ui'; -import type {Action} from '../types'; -import type {Directory} from '../../../nuclide-remote-connection'; - -import {ActiveTunnels} from '../ActiveTunnels'; -import * as Actions from './Actions'; -import {Set} from 'immutable'; -import {Subject} from 'rxjs'; - -export function tunnels( - state: ActiveTunnels = new ActiveTunnels(), - action: Action, -) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.tunnels = tunnels; +exports.currentWorkingDirectory = currentWorkingDirectory; +exports.consoleOutput = consoleOutput; + +var _ActiveTunnels; + +function _load_ActiveTunnels() { + return _ActiveTunnels = require('../ActiveTunnels'); +} + +var _Actions; + +function _load_Actions() { + return _Actions = _interopRequireWildcard(require('./Actions')); +} + +var _immutable; + +function _load_immutable() { + return _immutable = require('immutable'); +} + +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 tunnels(state = new (_ActiveTunnels || _load_ActiveTunnels()).ActiveTunnels(), action) { switch (action.type) { - case Actions.SUBSCRIBE_TO_TUNNEL: + case (_Actions || _load_Actions()).SUBSCRIBE_TO_TUNNEL: let existing = state.get(action.payload.tunnel); if (existing == null) { existing = { tunnel: action.payload.tunnel, - subscriptions: Set(), - state: 'initializing', + subscriptions: (0, (_immutable || _load_immutable()).Set)(), + state: 'initializing' }; } - return state.set(action.payload.tunnel, { - ...existing, - subscriptions: existing.subscriptions.add(action.payload.subscription), - }); + return state.set(action.payload.tunnel, Object.assign({}, existing, { + subscriptions: existing.subscriptions.add(action.payload.subscription) + })); - case Actions.UNSUBSCRIBE_FROM_TUNNEL: - return state.update(action.payload.tunnel, value => ({ - ...value, - subscriptions: value.subscriptions.remove(action.payload.subscription), + case (_Actions || _load_Actions()).UNSUBSCRIBE_FROM_TUNNEL: + return state.update(action.payload.tunnel, value => Object.assign({}, value, { + subscriptions: value.subscriptions.remove(action.payload.subscription) })); - case Actions.OPEN_TUNNEL: + case (_Actions || _load_Actions()).OPEN_TUNNEL: const toOpen = state.get(action.payload.tunnel); - return state.set(action.payload.tunnel, { - ...toOpen, - close: action.payload.close, - }); - - case Actions.SET_TUNNEL_STATE: - return state.update(action.payload.tunnel, value => ({ - ...value, - state: action.payload.state, + return state.set(action.payload.tunnel, Object.assign({}, toOpen, { + close: action.payload.close })); - case Actions.CLOSE_TUNNEL: + case (_Actions || _load_Actions()).SET_TUNNEL_STATE: + return state.update(action.payload.tunnel, value => Object.assign({}, value, { + state: action.payload.state + })); + + case (_Actions || _load_Actions()).CLOSE_TUNNEL: if (state.get(action.payload.tunnel) === undefined) { return state; } - return state.update(action.payload.tunnel, value => ({ - ...value, + return state.update(action.payload.tunnel, value => Object.assign({}, value, { error: action.payload.error, - state: 'closing', + state: 'closing' })); - case Actions.DELETE_TUNNEL: + case (_Actions || _load_Actions()).DELETE_TUNNEL: return state.delete(action.payload.tunnel); default: return state; } -} +} /** + * 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. + * + * strict-local + * @format + */ -export function currentWorkingDirectory( - state: ?Directory = null, - action: Action, -) { +function currentWorkingDirectory(state = null, action) { switch (action.type) { - case Actions.SET_CURRENT_WORKING_DIRECTORY: + case (_Actions || _load_Actions()).SET_CURRENT_WORKING_DIRECTORY: return action.payload.directory; default: return state; } } -export function consoleOutput( - state: Subject = new Subject(), - action: Action, -) { +function consoleOutput(state = new _rxjsBundlesRxMinJs.Subject(), action) { return state; -} +} \ No newline at end of file diff --git a/pkg/nuclide-ssh-tunnel/lib/types.js b/pkg/nuclide-ssh-tunnel/lib/types.js index a3a8a45d02..483c6577d8 100644 --- a/pkg/nuclide-ssh-tunnel/lib/types.js +++ b/pkg/nuclide-ssh-tunnel/lib/types.js @@ -1,125 +1,7 @@ -/** - * 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 - */ +'use strict'; -import type {ResolvedTunnel} from 'nuclide-adb/lib/types'; -import type {Subject} from 'rxjs'; -import type {ConsoleMessage} from 'atom-ide-ui'; -import type {ActiveTunnels} from './ActiveTunnels'; +var _immutable; -import {Map, Set} from 'immutable'; - -export type Store = { - getState(): AppState, - dispatch(action: Action): void, -}; - -export type AppState = { - openTunnels: Map, - tunnels: ActiveTunnels, - currentWorkingDirectory: ?string, - consoleOutput: Subject, -}; - -export type TunnelSubscription = { - description: string, - onTunnelClose: (?Error) => void, -}; - -export type ActiveTunnel = $ReadOnly<{ - tunnel: ResolvedTunnel, - subscriptions: Set, - state: TunnelState, - error: ?Error, - close?: (?Error) => void, -}>; - -export type OpenTunnel = { - close(error: ?Error): void, - state: TunnelState, -}; - -export type TunnelState = 'initializing' | 'ready' | 'active' | 'closing'; - -export type Action = - | CloseTunnelAction - | DeleteTunnelAction - | OpenTunnelAction - | RequestTunnelAction - | SetCurrentWorkingDirectoryAction - | SetTunnelStateAction - | SubscribeToTunnelAction - | UnsubscribeFromTunnelAction; - -export type CloseTunnelAction = { - type: 'CLOSE_TUNNEL', - payload: { - tunnel: ResolvedTunnel, - error: ?Error, - }, -}; - -export type DeleteTunnelAction = { - type: 'DELETE_TUNNEL', - payload: { - tunnel: ResolvedTunnel, - }, -}; - -export type OpenTunnelAction = { - type: 'OPEN_TUNNEL', - payload: { - tunnel: ResolvedTunnel, - open: () => void, - close: (?Error) => void, - }, -}; - -export type RequestTunnelAction = { - type: 'REQUEST_TUNNEL', - payload: { - description: string, - tunnel: ResolvedTunnel, - onOpen: (?Error) => void, - onClose: (?Error) => void, - }, -}; - -export type SetCurrentWorkingDirectoryAction = { - type: 'SET_CURRENT_WORKING_DIRECTORY', - payload: { - directory: ?string, - }, -}; - -export type SetTunnelStateAction = { - type: 'SET_TUNNEL_STATE', - payload: { - tunnel: ResolvedTunnel, - state: TunnelState, - }, -}; - -export type SubscribeToTunnelAction = { - type: 'SUBSCRIBE_TO_TUNNEL', - payload: { - onOpen: (?Error) => void, - subscription: TunnelSubscription, - tunnel: ResolvedTunnel, - }, -}; - -export type UnsubscribeFromTunnelAction = { - type: 'UNSUBSCRIBE_FROM_TUNNEL', - payload: { - subscription: TunnelSubscription, - tunnel: ResolvedTunnel, - }, -}; +function _load_immutable() { + return _immutable = require('immutable'); +} \ No newline at end of file diff --git a/pkg/nuclide-ssh-tunnel/lib/ui/ManualTunnelSection.js b/pkg/nuclide-ssh-tunnel/lib/ui/ManualTunnelSection.js index ff70304f71..18d4779de2 100644 --- a/pkg/nuclide-ssh-tunnel/lib/ui/ManualTunnelSection.js +++ b/pkg/nuclide-ssh-tunnel/lib/ui/ManualTunnelSection.js @@ -1,208 +1,207 @@ -/** - * 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 - */ - -import type {Tunnel} from 'nuclide-adb/lib/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import invariant from 'assert'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import * as React from 'react'; -import {Button} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; -import {Section} from 'nuclide-commons-ui/Section'; -import {shortenHostname} from '../../../nuclide-socket-rpc/lib/Tunnel'; - -type Props = { - openTunnel(tunnel: Tunnel): void, - workingDirectoryHost: 'localhost' | ?NuclideUri, -}; -type State = { - description: string, - family: 4 | 6, - fromCurrentWorkingRoot: boolean, - fromPortString: string, - toPortString: string, - fromPort?: number, - toPort?: number, -}; - -export default class ManualTunnelSection extends React.Component { - props: Props; - - constructor(props: Props) { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _AtomInput; + +function _load_AtomInput() { + return _AtomInput = require('../../../../modules/nuclide-commons-ui/AtomInput'); +} + +var _react = _interopRequireWildcard(require('react')); + +var _Button; + +function _load_Button() { + return _Button = require('../../../../modules/nuclide-commons-ui/Button'); +} + +var _ButtonGroup; + +function _load_ButtonGroup() { + return _ButtonGroup = require('../../../../modules/nuclide-commons-ui/ButtonGroup'); +} + +var _Section; + +function _load_Section() { + return _Section = require('../../../../modules/nuclide-commons-ui/Section'); +} + +var _Tunnel; + +function _load_Tunnel() { + return _Tunnel = require('../../../nuclide-socket-rpc/lib/Tunnel'); +} + +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 ManualTunnelSection extends _react.Component { + + constructor(props) { super(props); this.state = { description: '', family: 6, fromCurrentWorkingRoot: true, fromPortString: '', - toPortString: '', + toPortString: '' }; } - render(): React.Element { + render() { let boxContents; - if ( - this.props.workingDirectoryHost == null || - this.props.workingDirectoryHost === 'localhost' - ) { - boxContents = - 'Set a remote Current Working Root to open tunnels to that host.'; + if (this.props.workingDirectoryHost == null || this.props.workingDirectoryHost === 'localhost') { + boxContents = 'Set a remote Current Working Root to open tunnels to that host.'; } else { boxContents = this._getManualEntryForm(this.props.workingDirectoryHost); } - return ( -
    -
    - {boxContents} -
    -
    + return _react.createElement( + (_Section || _load_Section()).Section, + { headline: 'Manual tunnel', collapsable: false }, + _react.createElement( + 'div', + { className: 'nuclide-ssh-tunnels-manual-tunnel-section' }, + boxContents + ) ); } - _getManualEntryForm(hostname: NuclideUri): Array> { - const workingRootLabel = ( - - {shortenHostname(hostname)}: - + _getManualEntryForm(hostname) { + const workingRootLabel = _react.createElement( + 'code', + { className: 'nuclide-ssh-tunnels-manual-tunnel-section-host-field' }, + (0, (_Tunnel || _load_Tunnel()).shortenHostname)(hostname), + ':' ); - const localhostLabel = ( - - localhost: - + const localhostLabel = _react.createElement( + 'code', + { className: 'nuclide-ssh-tunnels-manual-tunnel-section-host-field' }, + 'localhost:' ); - const fromAndToRow = ( -
    -
    - {this.state.fromCurrentWorkingRoot - ? workingRootLabel - : localhostLabel} - - this.setState({ - fromPortString: text, - fromPort: this._parsePort(text), - }) - } - /> -
    - -
    - {this.state.fromCurrentWorkingRoot - ? localhostLabel - : workingRootLabel} - - this.setState({ - toPortString: text, - toPort: this._parsePort(text), - }) - } - /> -
    -
    + const fromAndToRow = _react.createElement( + 'div', + { className: 'nuclide-ssh-tunnels-manual-tunnel-section-row' }, + _react.createElement( + 'div', + null, + this.state.fromCurrentWorkingRoot ? workingRootLabel : localhostLabel, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + placeholderText: 'port', + value: this.state.fromPortString, + size: 'sm', + width: 40, + onDidChange: text => this.setState({ + fromPortString: text, + fromPort: this._parsePort(text) + }) + }) + ), + _react.createElement( + (_Button || _load_Button()).Button, + { onClick: () => this._switchToAndFrom() }, + '\u21C4' + ), + _react.createElement( + 'div', + null, + this.state.fromCurrentWorkingRoot ? localhostLabel : workingRootLabel, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + placeholderText: 'port', + value: this.state.toPortString, + size: 'sm', + width: 40, + onDidChange: text => this.setState({ + toPortString: text, + toPort: this._parsePort(text) + }) + }) + ) ); - const descriptionFamilyOpenRow = ( -
    - this.setState({description})} - /> - - - - - -
    + const descriptionFamilyOpenRow = _react.createElement( + 'div', + { className: 'nuclide-ssh-tunnels-manual-tunnel-section-row' }, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + placeholderText: 'description', + className: 'nuclide-ssh-tunnels-manual-tunnel-section-description', + size: 'sm', + style: { 'flex-grow': 1 }, + onDidChange: description => this.setState({ description }) + }), + _react.createElement( + (_ButtonGroup || _load_ButtonGroup()).ButtonGroup, + null, + _react.createElement( + (_Button || _load_Button()).Button, + { + key: '4', + selected: this.state.family === 4, + onClick: () => this.setState({ family: 4 }) }, + 'IPv4' + ), + _react.createElement( + (_Button || _load_Button()).Button, + { + key: '6', + selected: this.state.family === 6, + onClick: () => this.setState({ family: 6 }) }, + 'IPv6' + ) + ), + _react.createElement( + (_Button || _load_Button()).Button, + { + disabled: !this._openButtonEnabled(), + onClick: () => this._openTunnel() }, + 'Open' + ) ); return [fromAndToRow, descriptionFamilyOpenRow]; } - _openTunnel(): void { - invariant( - this.props.workingDirectoryHost != null && - this.props.workingDirectoryHost !== 'localhost' && - this.state.fromPort != null && - this.state.toPort != null, - ); - const fromHost = this.state.fromCurrentWorkingRoot - ? this.props.workingDirectoryHost - : 'localhost'; - const toHost = this.state.fromCurrentWorkingRoot - ? 'localhost' - : this.props.workingDirectoryHost; + _openTunnel() { + if (!(this.props.workingDirectoryHost != null && this.props.workingDirectoryHost !== 'localhost' && this.state.fromPort != null && this.state.toPort != null)) { + throw new Error('Invariant violation: "this.props.workingDirectoryHost != null &&\\n this.props.workingDirectoryHost !== \'localhost\' &&\\n this.state.fromPort != null &&\\n this.state.toPort != null"'); + } + + const fromHost = this.state.fromCurrentWorkingRoot ? this.props.workingDirectoryHost : 'localhost'; + const toHost = this.state.fromCurrentWorkingRoot ? 'localhost' : this.props.workingDirectoryHost; const tunnel = { from: { host: fromHost, port: this.state.fromPort, - family: this.state.family, + family: this.state.family }, to: { host: toHost, port: this.state.toPort, - family: this.state.family, + family: this.state.family }, - description: this.state.description.trim() || 'manual', + description: this.state.description.trim() || 'manual' }; this.props.openTunnel(tunnel); } - _openButtonEnabled(): boolean { - return ( - this.props.workingDirectoryHost != null && - this.props.workingDirectoryHost !== 'localhost' && - this.state.fromPort != null && - this.state.toPort != null - ); + _openButtonEnabled() { + return this.props.workingDirectoryHost != null && this.props.workingDirectoryHost !== 'localhost' && this.state.fromPort != null && this.state.toPort != null; } - _switchToAndFrom(): void { + _switchToAndFrom() { this.setState({ fromCurrentWorkingRoot: !this.state.fromCurrentWorkingRoot, fromPortString: this.state.toPortString, toPortString: this.state.fromPortString, fromPort: this.state.toPort, - toPort: this.state.fromPort, + toPort: this.state.fromPort }); } - _parsePort(text: string): number | void { + _parsePort(text) { const port = parseInt(text, 10); if (!(port >= 0 && port <= 65535)) { return undefined; @@ -211,3 +210,13 @@ export default class ManualTunnelSection extends React.Component { } } } +exports.default = ManualTunnelSection; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/pkg/nuclide-ssh-tunnel/lib/ui/TunnelCloseButton.js b/pkg/nuclide-ssh-tunnel/lib/ui/TunnelCloseButton.js index 9cba46ae83..2813d72104 100644 --- a/pkg/nuclide-ssh-tunnel/lib/ui/TunnelCloseButton.js +++ b/pkg/nuclide-ssh-tunnel/lib/ui/TunnelCloseButton.js @@ -1,31 +1,34 @@ -/** - * 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 - */ +'use strict'; -import type {ResolvedTunnel} from 'nuclide-adb/lib/types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = TunnelCloseButton; -import {Button} from 'nuclide-commons-ui/Button'; -import * as React from 'react'; +var _Button; -type Props = { - tunnel: ResolvedTunnel, - closeTunnel: (tunnel: ResolvedTunnel) => void, -}; - -export default function TunnelCloseButton(props: Props) { - return ( - - - ); - } -} - -class Group extends React.Component<{ - addMessages: AddMessagesType, - severity: 'error' | 'warning' | 'info', -}> { - _input: ?AtomInput; - - _onButtonClick = (event: SyntheticMouseEvent<*>): void => { - const input = this._input; - if (input == null) { - return; - } - const n = parseInt(input.getText(), 10); - if (Number.isNaN(n)) { - return; - } - this.props.addMessages(this.props.severity, n); - }; - - render() { - return ( -
    -

    {this.props.severity}

    - { - this._input = input; - }} - initialValue="1" - /> - -
    - ); - } -} diff --git a/pkg/sample-diagnostics-tester/lib/PanelViewModel.js b/pkg/sample-diagnostics-tester/lib/PanelViewModel.js deleted file mode 100644 index 3e8cc2a3b4..0000000000 --- a/pkg/sample-diagnostics-tester/lib/PanelViewModel.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import {renderReactRoot} from 'nuclide-commons-ui/renderReactRoot'; -import PanelView from './PanelView'; -import * as React from 'react'; - -export type AddMessagesType = ( - severity: 'error' | 'warning' | 'info', - count: number, -) => mixed; -export type ClearType = () => mixed; - -export const WORKSPACE_ITEM_URI = 'atom://nuclide/sample-diagnostics-tester'; - -export default class PanelViewModel { - element: ?HTMLElement; - - constructor(options: {+addMessages: AddMessagesType, +clear: ClearType}) { - this.element = renderReactRoot(); - } - - getURI(): string { - return WORKSPACE_ITEM_URI; - } - - getTitle() { - return 'Diagnostics Tester'; - } - - getDefaultLocation(): string { - return 'right'; - } - - serialize(): mixed { - return {deserializer: 'nuclide.DiagnosticsTester'}; - } -} diff --git a/pkg/sample-diagnostics-tester/lib/main.js b/pkg/sample-diagnostics-tester/lib/main.js deleted file mode 100644 index 950f4ac138..0000000000 --- a/pkg/sample-diagnostics-tester/lib/main.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * 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 - */ - -import type {RegisterIndieLinter} from 'atom-ide-ui'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import {destroyItemWhere} from 'nuclide-commons-atom/destroyItemWhere'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import PackageModel from './PackageModel'; -import PanelViewModel, {WORKSPACE_ITEM_URI} from './PanelViewModel'; - -class Activation { - _disposables: UniversalDisposable; - _model = new PackageModel(); - - constructor(state: ?mixed) { - this._disposables = new UniversalDisposable( - this._model, - atom.workspace.addOpener(uri => { - if (uri === WORKSPACE_ITEM_URI) { - return new PanelViewModel(this._model); - } - }), - () => destroyItemWhere(item => item instanceof PanelViewModel), - atom.commands.add( - 'atom-workspace', - 'sample-diagnostics-tester:toggle', - () => { - atom.workspace.toggle(WORKSPACE_ITEM_URI); - }, - ), - ); - } - - dispose(): void { - this._disposables.dispose(); - } - - consumeIndie(register: RegisterIndieLinter): IDisposable { - const linter = register({name: 'Sample Diagnostics Tester'}); - this._disposables.add(linter); - return new UniversalDisposable( - this._model.observeMessages(messages => { - linter.setAllMessages(messages); - }), - () => { - this._disposables.remove(linter); - }, - ); - } - - deserializeDiagnosticsTester(): PanelViewModel { - return new PanelViewModel(this._model); - } -} - -createPackage(module.exports, Activation); diff --git a/pkg/sample-diagnostics-tester/package.json b/pkg/sample-diagnostics-tester/package.json deleted file mode 100644 index 0a20a5da99..0000000000 --- a/pkg/sample-diagnostics-tester/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "sample-diagnostics-tester", - "main": "./lib/main.js", - "version": "0.0.0", - "description": "A package that adds utilities for testing diagnostics", - "author": "Nuclide : Core UI", - "atomTestRunner": "../../lib/test-runner-entry.js", - "deserializers": { - "nuclide.DiagnosticsTester": "deserializeDiagnosticsTester" - }, - "nuclide": { - "packageType": "Atom", - "testRunner": "apm" - }, - "consumedServices": { - "linter-indie": { - "versions": { - "2.0.0": "consumeIndie" - } - } - } -} diff --git a/pkg/sample-executor/lib/main.js b/pkg/sample-executor/lib/main.js deleted file mode 100644 index 0804ba439f..0000000000 --- a/pkg/sample-executor/lib/main.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * 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 - */ - -import type {RegisterExecutorFunction} from 'atom-ide-ui'; - -import invariant from 'assert'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Subject} from 'rxjs'; - -let disposables: ?UniversalDisposable = null; - -export function activate(state: ?Object): void { - invariant(disposables == null); - disposables = new UniversalDisposable(); -} - -export function deactivate(): void { - invariant(disposables != null); - disposables.dispose(); - disposables = null; -} - -export function consumeRegisterExecutor( - registerExecutor: RegisterExecutorFunction, -): void { - invariant(disposables != null); - const messages: Subject<{result?: Object}> = new Subject(); - disposables.add( - registerExecutor({ - id: 'echo', - name: 'Echo', - scopeName: 'text.plain', - send(code: string): void { - messages.next({ - level: 'log', - data: { - value: code, - type: 'text', - }, - }); - }, - output: messages.asObservable(), - }), - ); -} diff --git a/pkg/sample-executor/package.json b/pkg/sample-executor/package.json deleted file mode 100644 index e1732b7874..0000000000 --- a/pkg/sample-executor/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "sample-executor", - "main": "./lib/main.js", - "version": "0.0.0", - "description": "A sample executor that just echos the input back", - "author": "Nuclide : Core UI", - "atomTestRunner": "../../lib/test-runner-entry.js", - "nuclide": { - "packageType": "Atom", - "testRunner": "apm" - }, - "consumedServices": { - "DEPRECATED-nuclide.registerExecutor": { - "versions": { - "0.0.0": "consumeRegisterExecutor" - } - } - } -} diff --git a/pkg/sample-experimental-console-service/lib/SimpleConsoleClient.js b/pkg/sample-experimental-console-service/lib/SimpleConsoleClient.js deleted file mode 100644 index 05adb700c6..0000000000 --- a/pkg/sample-experimental-console-service/lib/SimpleConsoleClient.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * 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 - */ - -import type {ServiceConnection} from 'nuclide-commons-atom/experimental-packages/types'; - -export default class SimpleConsoleClient { - _connection: ServiceConnection; - - constructor(connection: ServiceConnection) { - this._connection = connection; - } - - log(message: string): void { - this._connection.sendNotification('message', {message}); - } -} diff --git a/pkg/sample-experimental-console-service/lib/main.js b/pkg/sample-experimental-console-service/lib/main.js deleted file mode 100644 index 5e0c19de0f..0000000000 --- a/pkg/sample-experimental-console-service/lib/main.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * 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 - */ - -import type {ServiceConnection} from 'nuclide-commons-atom/experimental-packages/types'; - -import {getLogger} from 'log4js'; -import {initializeLogging} from '../../nuclide-logging'; - -initializeLogging(); -const logger = getLogger('sample-experimental-console-service'); - -function connectClient(connection: ServiceConnection): void { - const {sourceName} = connection.config; - if (sourceName == null) { - logger.error( - 'Improperly configured consumer sample-experimental-console-service consumer. ' + - 'You need a source name in your config!', - ); - return; - } - - connection.onNotification( - {method: 'message'}, - (params: {message: string}) => { - logger.info(`got message from ${sourceName}`, params); - }, - ); -} - -export default class Package { - constructor( - services: {}, - serviceConsumers: {console: Array}, - ) { - logger.info('loaded main.js'); - serviceConsumers.console.forEach(connection => { - connectClient(connection); - }); - } - - dispose(): void { - logger.info('disposed!'); - } -} diff --git a/pkg/sample-experimental-console-service/package.json b/pkg/sample-experimental-console-service/package.json deleted file mode 100644 index 1afe41c247..0000000000 --- a/pkg/sample-experimental-console-service/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "sample-experimental-console-service", - "main": "./lib/main.js", - "version": "0.0.0", - "description": "Experimental console provider", - "author": "Nuclide : Core UI", - "atomTestRunner": "../../lib/test-runner-entry.js", - "nuclide": { - "packageType": "Atom", - "testRunner": "apm" - }, - "experimental": { - "main": "./lib/main.js", - "providedServices": { - "console": { - "name": "sample-experimental-service-simple-console", - "version": "1.0.0", - "client": "./lib/SimpleConsoleClient" - } - } - } -} diff --git a/pkg/sample-experimental-service-consumer/lib/WidgetComponent.js b/pkg/sample-experimental-service-consumer/lib/WidgetComponent.js deleted file mode 100644 index 4bf676e68a..0000000000 --- a/pkg/sample-experimental-service-consumer/lib/WidgetComponent.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * 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 - */ - -import {Button} from 'nuclide-commons-ui/Button'; -import * as React from 'react'; - -type Props = {| - +dispatch: (action: Object) => mixed, // TODO: Actually type action - count: number, -|}; - -export default class WidgetComponent extends React.Component { - render(): React.Node { - return ( -
    - This is the widget! Count is {this.props.count} -
    - - -
    - ); - } - - _increment = () => { - this.props.dispatch({type: 'increment'}); - }; - - _decrement = () => { - this.props.dispatch({type: 'decrement'}); - }; -} diff --git a/pkg/sample-experimental-service-consumer/lib/WidgetView.js b/pkg/sample-experimental-service-consumer/lib/WidgetView.js deleted file mode 100644 index bce4f32e4d..0000000000 --- a/pkg/sample-experimental-service-consumer/lib/WidgetView.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * 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 - */ - -import {Subject, ReplaySubject, Observable} from 'rxjs'; - -type State = {count: number}; - -export default class WidgetView { - componentId = 'sample-experimental-service-consumer.WidgetComponent'; - _updates: Subject = new Subject(); - _disposed = new ReplaySubject(1); - state: State = {count: 0}; - - get updates(): Observable { - return this._updates.takeUntil(this._disposed); - } - - setState(state: State): void { - this.state = {...this.state, ...state}; - this._updates.next(this.render()); - } - - render(): State { - return this.state; - } - - handleAction(action: Object) { - // TODO: Type action - switch (action.type) { - case 'increment': - this.setState({count: this.state.count + 1}); - break; - case 'decrement': - this.setState({count: this.state.count - 1}); - break; - default: - throw new Error(`Invalid action type: ${action.type}`); - } - } - - dispose(): void { - this._disposed.next(); - } -} diff --git a/pkg/sample-experimental-service-consumer/lib/main.js b/pkg/sample-experimental-service-consumer/lib/main.js deleted file mode 100644 index e619b22e08..0000000000 --- a/pkg/sample-experimental-service-consumer/lib/main.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import type SimpleConsoleClient from '../../sample-experimental-console-service/lib/SimpleConsoleClient'; -import type WindowServiceClient from '../../sample-experimental-window-service/lib/WindowServiceClient'; - -import {getLogger} from 'log4js'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {initializeLogging} from '../../nuclide-logging'; -import WidgetView from './WidgetView'; - -initializeLogging(); -const logger = getLogger('sample-experimental-service-consumer'); - -export default class Package { - _disposables: UniversalDisposable = new UniversalDisposable(); - - constructor(services: { - console: SimpleConsoleClient, - window: WindowServiceClient, - }) { - const {console, window} = services; - logger.info('loaded main.js'); - - console.log('test1234'); - - window.open({ - width: 300, - height: 300, - frame: false, - createView: () => new WidgetView(), - }); - } - - dispose(): void { - this._disposables.dispose(); - } -} diff --git a/pkg/sample-experimental-service-consumer/package.json b/pkg/sample-experimental-service-consumer/package.json deleted file mode 100644 index d900a4f860..0000000000 --- a/pkg/sample-experimental-service-consumer/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "sample-experimental-service-consumer", - "main": "./lib/main.js", - "version": "0.0.0", - "description": "Experimental console consumer", - "author": "Nuclide : Core UI", - "atomTestRunner": "../../lib/test-runner-entry.js", - "nuclide": { - "packageType": "Atom", - "testRunner": "apm" - }, - "experimental": { - "main": "./lib/main.js", - "components": { - "sample-experimental-service-consumer.WidgetComponent": - "./lib/WidgetComponent" - }, - "consumedServices": { - "console": { - "name": "sample-experimental-service-simple-console", - "version": "1.0.0", - "config": { - "sourceName": "Experimental Service Consumer" - } - }, - "window": { - "name": "sample-experimental-window-service", - "version": "1.0.0" - } - } - } -} diff --git a/pkg/sample-experimental-window-service/lib/WindowServiceClient.js b/pkg/sample-experimental-window-service/lib/WindowServiceClient.js deleted file mode 100644 index 924516243a..0000000000 --- a/pkg/sample-experimental-window-service/lib/WindowServiceClient.js +++ /dev/null @@ -1,108 +0,0 @@ -/** - * 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 - */ - -import type {ServiceConnection} from 'nuclide-commons-atom/experimental-packages/types'; - -import invariant from 'assert'; -import {Observable} from 'rxjs'; -import {getLogger} from 'log4js'; - -const logger = getLogger('sample-experimental-window-service.connectClient'); - -export type OpenParams = { - width: number, - height: number, - frame: boolean, - view: { - componentId: string, - initialState: T, - }, -}; - -export type UpdateParams = { - id: number, - update: U, -}; - -export type DestroyParams = { - id: number, -}; - -type View = { - componentId: string, - render(): T, - +updates: Observable, - +dispose?: () => mixed, - +handleAction?: (action: Object) => mixed, // TODO: Type action? -}; - -type WindowOptions = {| - width: number, - height: number, - frame?: boolean, - createView: () => View, -|}; - -type Window = {| - destroy(): void, -|}; - -export default class WindowServiceClient { - _connection: ServiceConnection; - - constructor(connection: ServiceConnection) { - this._connection = connection; - } - - open(options: WindowOptions<*, *>): Window { - const view = options.createView(); - const idPromise = this._connection.sendRequest('open', { - width: options.width, - height: options.height, - frame: options.frame, - view: { - componentId: view.componentId, - initialState: view.render(), - }, - }); - const updatesSubscription = Observable.fromPromise(idPromise) - .switchMap(id => - view.updates.map(update => ({ - id, - update: update == null ? view.render() : update, - })), - ) - .subscribe(params => { - this._connection.sendNotification('update', params); - }); - if (view.handleAction != null) { - this._connection.onNotification( - {method: 'dispatch'}, - ({action}: Object) => { - logger.info(`client receiving action: ${JSON.stringify(action)}`); - invariant(view.handleAction != null); - view.handleAction(action); - }, - ); - } - return { - destroy(): void { - updatesSubscription.unsubscribe(); - if (view.dispose != null) { - view.dispose(); - } - idPromise.then(id => { - this._connection.sendNotification('destroy', ({id}: DestroyParams)); - }); - }, - }; - } -} diff --git a/pkg/sample-experimental-window-service/lib/connectClient.js b/pkg/sample-experimental-window-service/lib/connectClient.js deleted file mode 100644 index 94487b5dae..0000000000 --- a/pkg/sample-experimental-window-service/lib/connectClient.js +++ /dev/null @@ -1,182 +0,0 @@ -/** - * 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 - */ - -import type {MessageConnection} from 'vscode-jsonrpc'; -import type {ServiceConnection} from 'nuclide-commons-atom/experimental-packages/types'; -import type { - OpenParams, - UpdateParams, - DestroyParams, -} from './WindowServiceClient'; - -import invariant from 'assert'; -import {getLogger} from 'log4js'; -import {remote} from 'electron'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import nullthrows from 'nullthrows'; -import path from 'path'; // eslint-disable-line nuclide-internal/prefer-nuclide-uri - -const logger = getLogger('sample-experimental-window-service.connectClient'); - -invariant(remote != null); - -let windowCount = 1; -const windowManagers: Map = new Map(); -const windowManagersToConnections: WeakMap< - WindowManager, - MessageConnection, -> = new WeakMap(); - -// TODO: Actually get this information from package.json files. -const viewRegistry = new Map([ - [ - 'sample-experimental-service-consumer.WidgetComponent', - path.join( - __dirname, - '../../sample-experimental-service-consumer/lib/WidgetComponent', - ), - ], -]); - -// Route messages from the windows to the correct connection. -remote.ipcMain.on('dispatch', (_, {windowId, action}) => { - logger.info( - `client handling action from window ${windowId}: ${JSON.stringify(action)}`, - ); - const windowManager = nullthrows(windowManagers.get(windowId)); - const connection = nullthrows(windowManagersToConnections.get(windowManager)); - connection.sendNotification('dispatch', {action}); -}); - -export default function connectClient( - connection: ServiceConnection, -): IDisposable { - const disposables = new UniversalDisposable(); - connection.onRequest( - {method: 'open'}, - (params: OpenParams<*>): number => { - logger.info('got create request:', params); - if (disposables.disposed) { - throw new Error('attempted to open after dispose'); - } - const windowId = windowCount++; - const windowManager = new WindowManager({ - windowId, - openParams: params, - onDestroy: () => { - disposables.dispose(); - }, - }); - windowManagers.set(windowId, windowManager); - windowManagersToConnections.set(windowManager, connection); - disposables.add(() => { - logger.info('disposing of connection to window client!'); - windowManagers.delete(windowId); - windowManagersToConnections.delete(windowManager); - windowManager.destroy(); - }); - return windowId; - }, - ); - connection.onNotification({method: 'update'}, (params: UpdateParams<*>) => { - logger.info('got update request:', params); - const windowManager = nullthrows(windowManagers.get(params.id)); - windowManager.update(params.update); - }); - connection.onNotification({method: 'destroy'}, (params: DestroyParams) => { - logger.info('got destroy request:', params.id); - disposables.dispose(); - }); - return disposables; -} - -// An object that abstracts away the asynchronous nature of window creation/initialization. We could -// also do this (probably more elegantly) with Rx, but that's a heavy dep. -class WindowManager { - _initPromise: Promise; - _destroyed: boolean = false; - _windowId: number; - _onDestroy: () => mixed; - - constructor(options: { - windowId: number, - openParams: OpenParams<*>, - onDestroy: () => mixed, - }) { - const {windowId, openParams, onDestroy} = options; - this._windowId = windowId; - this._onDestroy = onDestroy; - this._initPromise = this._init(windowId, openParams); - } - - async _init( - windowId: number, - params: OpenParams<*>, - ): Promise { - const {BrowserWindow} = remote; - const win = new BrowserWindow({ - width: params.width, - height: params.height, - frame: params.frame, - show: false, - }); - win.loadURL(`file://${__dirname}/index.html`); - - win.on('closed', () => { - this.destroy(); - }); - - await new Promise(resolve => { - win.webContents.on('did-finish-load', resolve); - }); - - if (this._destroyed) { - return null; - } - - // Initialize the new window. - const {view} = params; - /* const componentModule = */ win.webContents.send('initialize', { - windowId, - componentModule: nullthrows(viewRegistry.get(view.componentId)), - initialState: view.initialState, - }); - - // TODO: Wait until first render is complete to show? - win.show(); - - return win; - } - - update(update: Object): void { - this._initPromise.then(win => { - if (this._destroyed || win == null) { - return; - } - win.webContents.send('update', update); - }); - } - - destroy(): void { - if (this._destroyed) { - return; - } - logger.info(`window ${this._windowId} destruction requested`); - this._destroyed = true; - this._onDestroy(); - this._initPromise.then(win => { - if (win != null) { - logger.info(`destroying window ${this._windowId}`); - win.destroy(); - } - }); - } -} diff --git a/pkg/sample-experimental-window-service/lib/index.html b/pkg/sample-experimental-window-service/lib/index.html deleted file mode 100644 index 3bec086642..0000000000 --- a/pkg/sample-experimental-window-service/lib/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - -
    - - - diff --git a/pkg/sample-experimental-window-service/lib/main.js b/pkg/sample-experimental-window-service/lib/main.js deleted file mode 100644 index 5c0efa43b7..0000000000 --- a/pkg/sample-experimental-window-service/lib/main.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import type {ServiceConnection} from 'nuclide-commons-atom/experimental-packages/types'; - -import invariant from 'assert'; -import {getLogger} from 'log4js'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {initializeLogging} from '../../nuclide-logging'; -import {remote} from 'electron'; -import connectClient from './connectClient'; - -invariant(remote != null); - -initializeLogging(); -const logger = getLogger('sample-experimental-window-service'); - -export default class WindowServicePackage { - _disposables: UniversalDisposable; - - constructor( - services: {}, - serviceConsumers: { - window: Array, - }, - ) { - logger.info('loaded main.js'); - logger.info('access to the atom global:', typeof atom === 'object'); - this._disposables = new UniversalDisposable( - ...serviceConsumers.window.map(connectClient), - ); - } - - dispose(): void { - logger.info('disposing window service package!'); - this._disposables.dispose(); - } -} diff --git a/pkg/sample-experimental-window-service/lib/window-script-entry.js b/pkg/sample-experimental-window-service/lib/window-script-entry.js deleted file mode 100644 index a70195cf10..0000000000 --- a/pkg/sample-experimental-window-service/lib/window-script-entry.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * 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. - * - * @noflow - */ -'use strict'; - -/* eslint - comma-dangle: [1, always-multiline], - prefer-object-spread/prefer-object-spread: 0, - nuclide-internal/no-commonjs: 0, - */ -'use strict'; - -require('../../commons-node/load-transpiler'); -require('./window-script'); diff --git a/pkg/sample-experimental-window-service/lib/window-script.js b/pkg/sample-experimental-window-service/lib/window-script.js deleted file mode 100644 index 2040b95cf4..0000000000 --- a/pkg/sample-experimental-window-service/lib/window-script.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * 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 - */ - -import invariant from 'assert'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import nullthrows from 'nullthrows'; -import electron from 'electron'; -import {getLogger} from 'log4js'; - -import {initializeLogging} from '../../nuclide-logging'; -initializeLogging(); - -const logger = getLogger('sample-experimental-window-service.window-script'); - -const {ipcRenderer} = electron; - -invariant(ipcRenderer != null); - -export type InitializeMessage = {| - windowId: number, - componentModule: string, - initialState: T, -|}; - -let windowId; -let Component; -let reduceState; -let currentState; -const container = nullthrows(document.getElementById('app')); - -function dispatch(action) { - logger.info(`window ${windowId} sending action: ${JSON.stringify(action)}`); - // TODO: This is fine for now but we may have to include more info for routing when each window can contain multiple component roots. - ipcRenderer.send('dispatch', {windowId, action}); -} - -function render(props) { - invariant(Component != null); - ReactDOM.render(, container); -} - -ipcRenderer.on('initialize', (_, message: InitializeMessage<*>) => { - const {componentModule, initialState} = message; - windowId = message.windowId; - // $FlowIgnore - const module = require(componentModule); - Component = module.default; - reduceState = module.reduceState; - currentState = initialState; - render(currentState); -}); - -ipcRenderer.on('update', (_, update: Object) => { - currentState = - reduceState == null ? update : reduceState(currentState, update); - render(currentState); -}); - -// TODO: Use JSONRpc? -// TODO: Dispatch actions back. diff --git a/pkg/sample-experimental-window-service/package.json b/pkg/sample-experimental-window-service/package.json deleted file mode 100644 index a0e77ebe16..0000000000 --- a/pkg/sample-experimental-window-service/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "sample-experimental-window-service", - "main": "./lib/main.js", - "version": "0.0.0", - "description": "Experimental window service", - "author": "Nuclide : Core UI", - "atomTestRunner": "../../lib/test-runner-entry.js", - "nuclide": { - "packageType": "Atom", - "testRunner": "apm" - }, - "experimental": { - "main": "./lib/main.js", - "runInAtom_UNSAFE": true, - "providedServices": { - "window": { - "name": "sample-experimental-window-service", - "version": "1.0.0", - "client": "./lib/WindowServiceClient.js" - } - } - } -} diff --git a/pkg/sample-logging-console/lib/main.js b/pkg/sample-logging-console/lib/main.js deleted file mode 100644 index a74245f75f..0000000000 --- a/pkg/sample-logging-console/lib/main.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import type {ConsoleLevel, ConsoleService} from 'atom-ide-ui'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import {getNuclideConsoleMessages} from '../../nuclide-logging/lib/nuclideConsoleAppender'; - -class Activation { - _disposables: UniversalDisposable; - - constructor() { - this._disposables = new UniversalDisposable(); - } - - consumeConsole(getConsole: ConsoleService): IDisposable { - const console = getConsole({ - id: 'Nuclide', - name: 'Nuclide', - }); - const disposable = new UniversalDisposable( - getNuclideConsoleMessages() - .map(loggingEvent => ({ - text: String(loggingEvent.data), - level: getLevel(loggingEvent.level), - })) - .subscribe(message => { - console.append(message); - }), - ); - - // If this package is disabled, stop producing messages and dispose of the console we created. - this._disposables.add(disposable, console); - - // If the console package goes away, stop producing messages. - return disposable; - } - - dispose() { - this._disposables.dispose(); - } -} - -function getLevel(atomNotificationType: string): ConsoleLevel { - switch (atomNotificationType) { - case 'debug': - case 'error': - case 'info': - return atomNotificationType; - case 'warn': - return 'warning'; - default: - return 'log'; - } -} - -createPackage(module.exports, Activation); diff --git a/pkg/sample-logging-console/package.json b/pkg/sample-logging-console/package.json deleted file mode 100644 index b2f6e816e5..0000000000 --- a/pkg/sample-logging-console/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "sample-logging-console", - "main": "./lib/main.js", - "version": "0.0.0", - "description": "Display Nuclide log messages in the Nuclide console", - "author": "Nuclide : Core UI", - "atomTestRunner": "../../lib/test-runner-entry.js", - "nuclide": { - "packageType": "Atom", - "testRunner": "apm" - }, - "consumedServices": { - "console": { - "versions": { - "0.1.0": "consumeConsole" - } - } - } -} diff --git a/pkg/sample-lsp-tester/lib/LspTester.js b/pkg/sample-lsp-tester/lib/LspTester.js deleted file mode 100644 index feddd2873e..0000000000 --- a/pkg/sample-lsp-tester/lib/LspTester.js +++ /dev/null @@ -1,248 +0,0 @@ -/** - * 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 - */ - -import type {LegacyProcessMessage} from 'nuclide-commons/process'; -import type {Message} from './PanelView'; - -import {getLogger} from 'log4js'; -import {renderReactRoot} from 'nuclide-commons-ui/renderReactRoot'; -import {bufferUntil, takeWhileInclusive} from 'nuclide-commons/observable'; -import {splitOnce} from 'nuclide-commons/string'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {spawn, getOutputStream} from 'nuclide-commons/process'; -import Model from 'nuclide-commons/Model'; -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import SafeStreamMessageReader from 'nuclide-commons/SafeStreamMessageReader'; -import {PanelView} from './PanelView'; -import * as React from 'react'; -import * as rpc from 'vscode-jsonrpc'; -import invariant from 'assert'; -import {Observable, ReplaySubject, Scheduler} from 'rxjs'; -import {shellParse} from 'nuclide-commons/string'; - -export const WORKSPACE_VIEW_URI = 'atom://nuclide/sample-lsp-tester'; - -type State = { - lastCommand: ?string, - running: boolean, -}; - -type SerializedState = { - lastCommand: ?string, -}; - -export class LspTester { - _messages: ReplaySubject; - _serverDisposable: ?UniversalDisposable; - _writer: ?rpc.StreamMessageWriter; - _model: Model; - - constructor(serialized: ?SerializedState) { - this._model = new Model({ - lastCommand: serialized && serialized.lastCommand, - running: false, - }); - this._messages = new ReplaySubject(/* buffer size */ 200); - } - - destroy(): void { - this._stopServer(); - } - - getTitle(): string { - return 'LSP Tester'; - } - - getURI(): string { - return WORKSPACE_VIEW_URI; - } - - getDefaultLocation(): string { - return 'right'; - } - - getElement(): HTMLElement { - const initialMessage = this._getInitialMessage(); - const props = this._model.toObservable().map(state => ({ - initialCommand: state.lastCommand, - initialMessage, - messages: this._messages, - running: state.running, - sendMessage: this._sendMessage, - startServer: this._startServer, - stopServer: this._stopServer, - })); - const StatefulPanelView = bindObservableAsProps(props, PanelView); - return renderReactRoot(); - } - - _getInitialMessage(): string { - const dirs = atom.project.getDirectories(); - const rootPath = dirs.length > 0 ? dirs[0].getPath() : null; - // flowlint-next-line sketchy-null-string:off - const rootUri = rootPath ? `file://${rootPath}` : 'file://path/to/root'; - const initialMessage = { - jsonrpc: '2.0', - id: 0, - method: 'initialize', - params: { - processId: process.pid, - rootPath: rootUri, - rootUri, - capabilities: {}, - trace: 'verbose', - }, - }; - return JSON.stringify(initialMessage, undefined, 2); - } - - _sendMessage = (message: Object): void => { - this._messages.next({ - kind: 'request', - body: JSON.stringify(message, undefined, 2), - }); - invariant(this._writer != null); - this._writer.write(message); - }; - - _startServer = (commandString: string): void => { - this._stopServer(); - const [command, ...args] = shellParse(commandString); - const events = - // Use the async scheduler so that `disposable.dispose()` can still be called in - // error/complete handlers. - spawn(command, args) - .do(process => { - this._writer = new rpc.StreamMessageWriter(process.stdin); - const reader = new SafeStreamMessageReader(process.stdout); - rpc - .createMessageConnection( - reader, - this._writer, - getLogger('LspTester-jsonrpc'), - ) - .listen(); - }) - .flatMap(proc => - getOutputStream(proc, { - /* TODO(T17353599) */ isExitError: () => false, - }), - ) - .subscribeOn(Scheduler.async) - .let( - takeWhileInclusive( - event => event.kind !== 'error' && event.kind !== 'exit', - ), - ) - .share(); - const responses = parseResponses( - events - .catch(() => Observable.empty()) // We'll handle them on the "other" stream. - .filter(event => event.kind === 'stdout') - .map(event => { - invariant(event.kind === 'stdout'); - return event.data; - }), - ); - const other = events.filter(event => event.kind !== 'stdout'); - - this._model.setState({ - lastCommand: commandString, - running: true, - }); - - const disposable = (this._serverDisposable = new UniversalDisposable( - responses.subscribe(response => { - this._messages.next({kind: 'response', body: response}); - }), - other.subscribe( - this._handleEvent, - err => { - atom.notifications.addError('Error!', {detail: err.message}); - disposable.dispose(); - }, - () => { - disposable.dispose(); - }, - ), - () => { - this._writer = null; - }, - () => { - this._model.setState({running: false}); - }, - )); - }; - - _stopServer = (): void => { - if (this._serverDisposable != null) { - this._serverDisposable.dispose(); - this._serverDisposable = null; - } - }; - - serialize(): Object { - return { - deserializer: 'nuclide.LspTester', - data: { - lastCommand: this._model.state.lastCommand, - }, - }; - } - - _handleEvent = (event: LegacyProcessMessage /* TODO(T17463635) */): void => { - switch (event.kind) { - case 'stderr': - // eslint-disable-next-line no-console - console.error('stderr from the lsp server process', event.data); - break; - case 'exit': - atom.notifications.addError('LSP Server process exited unexpectedly.'); - break; - case 'error': - atom.notifications.addError('Unexpected LSP Server process error', { - detail: String(event.error), - }); - break; - } - }; -} - -function parseChunks(chunks: Array): ?{header: string, body: mixed} { - const combined = chunks.join(''); - const [header, body] = splitOnce(combined, '\r\n\r\n'); - if (body == null) { - // The header isn't complete yet. - return null; - } - let parsed; - try { - parsed = JSON.parse(body); - } catch (err) { - // Guess we haven't received the entire body yet. - return null; - } - return {header, body: parsed}; -} - -function parseResponses(raw: Observable): Observable { - // TODO: We're parsing twice out of laziness here: once for validation, then for usage. - return raw - .let(bufferUntil((_, chunks) => parseChunks(chunks) != null)) - .map(chunks => { - const parsed = parseChunks(chunks); - invariant(parsed != null); - return parsed; - }) - .map( - ({header, body}) => `${header}\n${JSON.stringify(body, undefined, 2)}`, - ); -} diff --git a/pkg/sample-lsp-tester/lib/PanelView.js b/pkg/sample-lsp-tester/lib/PanelView.js deleted file mode 100644 index c0afff57e3..0000000000 --- a/pkg/sample-lsp-tester/lib/PanelView.js +++ /dev/null @@ -1,204 +0,0 @@ -/** - * 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 - */ - -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import {indent} from 'nuclide-commons/string'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {AtomTextEditor} from 'nuclide-commons-ui/AtomTextEditor'; -import {Button} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; -import invariant from 'assert'; -import nullthrows from 'nullthrows'; -import * as React from 'react'; -import {Observable} from 'rxjs'; - -export type Message = - | {| - kind: 'response', - body: string, - |} - | {| - kind: 'request', - body: string, - |}; - -type Props = { - initialCommand: string, - initialMessage: string, - messages: Observable, - running: boolean, - sendMessage(message: Object): void, - startServer: (command: string) => void, - stopServer: () => void, -}; - -type State = { - grammar: ?atom$Grammar, -}; - -export class PanelView extends React.Component { - _disposables: ?UniversalDisposable; - _commandField: ?AtomInput; - _inputField: ?AtomTextEditor; - _outputField: ?AtomTextEditor; - - constructor(props: Props) { - super(props); - this.state = { - grammar: null, - }; - } - - componentWillUnmount(): void { - invariant(this._disposables != null); - this._disposables.unsubscribe(); - } - - render(): React.Node { - return ( -
    -
    - { - this._commandField = input; - }} - className="sample-lsp-tester-command" - placeholderText="Command to Run (e.g. node jsonServerMain.js --stdio)" - /> - -
    - { - this._inputField = editor; - }} - className="sample-lsp-tester-input" - grammar={this.state.grammar} - gutterHidden={true} - placeholderText="Enter JSON message" - /> - -
    - - { - this._outputField = editor; - }} - className="sample-lsp-tester-output" - gutterHidden={true} - disabled={true} - /> -
    -
    - ); - } - - _handleStartButtonClick = (): void => { - const commandString = nullthrows(this._commandField).getText(); - this.props.startServer(commandString.trim()); - }; - - componentDidMount(): void { - // Fill in initial command - nullthrows(this._commandField).setText(this.props.initialCommand || ''); - - // Fill in initial message text. - nullthrows(this._inputField) - .getModel() - .setText(this.props.initialMessage); - - this._disposables = new UniversalDisposable( - // Subscribe to the responses. Note that we don't handle this prop changing after mount. - this.props.messages - .map( - message => - `${message.kind.toUpperCase()}...\n${indent(message.body)}`, - ) - .subscribe(data => { - const textEditor = nullthrows(this._outputField).getModel(); - textEditor.getBuffer().append(`${data}\n\n`); - (atom.views.getView(textEditor): any).scrollToBottom(); - }), - getGrammar('source.json').subscribe(grammar => { - this.setState({grammar}); - }), - ); - } - - _handleSendButtonClick = (event: SyntheticMouseEvent<>): void => { - const inputField = nullthrows(this._inputField); - const rawMessage = inputField.getModel().getText(); - let parsed; - try { - parsed = parseMessage(rawMessage); - } catch (err) { - if (err instanceof InvalidInputError) { - atom.notifications.addError(err.message); - return; - } - throw err; - } - inputField.getModel().setText(''); - this.props.sendMessage(parsed); - }; -} - -function parseMessage(raw_: string): Object { - const raw = raw_.trim(); - let message; - if (raw === '') { - throw new InvalidInputError('You must enter a command'); - } - try { - message = JSON.parse(raw); - } catch (err) { - throw new InvalidInputError(`Invalid JSON: ${err.message}`); - } - if (message.jsonrpc == null) { - throw new InvalidInputError('Missing "jsonrpc" field. Use 2.0.'); - } - return message; -} - -class InvalidInputError extends Error { - constructor(message: string) { - super(message); - this.name = 'InvalidInputError'; - } -} - -function getGrammar(scopeName: string): Observable { - const grammar = atom.grammars.grammarForScopeName(scopeName); - if (grammar != null) { - return Observable.of(grammar); - } - return observableFromSubscribeFunction( - atom.grammars.onDidAddGrammar.bind(atom.grammars), - ) - .filter(g => g.scopeName === scopeName) - .take(1); -} diff --git a/pkg/sample-lsp-tester/lib/main.js b/pkg/sample-lsp-tester/lib/main.js deleted file mode 100644 index 7c8d01acaa..0000000000 --- a/pkg/sample-lsp-tester/lib/main.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import {destroyItemWhere} from 'nuclide-commons-atom/destroyItemWhere'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {WORKSPACE_VIEW_URI, LspTester} from './LspTester'; - -class Activation { - _disposables: UniversalDisposable; - - constructor(state: ?mixed) { - this._disposables = this._registerCommandAndOpener(); - } - - dispose(): void { - this._disposables.dispose(); - } - - _registerCommandAndOpener(): UniversalDisposable { - return new UniversalDisposable( - atom.workspace.addOpener(uri => { - if (uri === WORKSPACE_VIEW_URI) { - return new LspTester(); - } - }), - () => destroyItemWhere(item => item instanceof LspTester), - atom.commands.add('atom-workspace', 'sample-lsp-tester:toggle', () => { - atom.workspace.toggle(WORKSPACE_VIEW_URI); - }), - ); - } - - deserializeLspTester(serialized: ?mixed): LspTester { - // flowlint-next-line sketchy-null-mixed:off - const data = (serialized && serialized.data) || null; - return new LspTester({ - lastCommand: - data != null && typeof data.lastCommand === 'string' - ? data.lastCommand || null - : null, - }); - } -} - -createPackage(module.exports, Activation); diff --git a/pkg/sample-lsp-tester/package.json b/pkg/sample-lsp-tester/package.json deleted file mode 100644 index ddfd142d06..0000000000 --- a/pkg/sample-lsp-tester/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "sample-lsp-tester", - "main": "./lib/main.js", - "version": "0.0.0", - "description": "A panel for testing LSP", - "author": "NEEDS OWNER", - "atomTestRunner": "../../lib/test-runner-entry.js", - "nuclide": { - "packageType": "Atom", - "testRunner": "apm" - }, - "activationCommands": {}, - "deserializers": { - "nuclide.LspTester": "deserializeLspTester" - } -} diff --git a/pkg/sample-lsp-tester/styles/styles.less b/pkg/sample-lsp-tester/styles/styles.less deleted file mode 100644 index ced8ccc0ac..0000000000 --- a/pkg/sample-lsp-tester/styles/styles.less +++ /dev/null @@ -1,40 +0,0 @@ -@import "ui-variables"; - -.sample-lsp-tester-panel { - display: flex; - flex-direction: column; - width: 100%; - background-color: @pane-item-background-color; - - atom-dock &, - atom-panel & { // TODO(matthewwithanm): Remove this selector when killing workspace views - background-color: @tool-panel-background-color; - } -} - -.sample-lsp-tester-input { - flex: 0.5; - margin-bottom: @component-padding; -} - -.sample-lsp-tester-output { - flex: 1; - max-height: none !important; -} - -.sample-lsp-tester-command-wrapper { - display: flex; - margin-bottom: @component-padding; -} - -.sample-lsp-tester-command { - flex: 1; - margin-right: @component-padding; -} - -.sample-lsp-tester-output-wrapper { - display: flex; - flex: 1; - flex-direction: column; - margin-top: 2 * @component-padding; -} diff --git a/pkg/sample-nux-example/lib/main.js b/pkg/sample-nux-example/lib/main.js deleted file mode 100644 index a3df6f5628..0000000000 --- a/pkg/sample-nux-example/lib/main.js +++ /dev/null @@ -1,134 +0,0 @@ -/** - * 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 - */ - -import invariant from 'assert'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -import type {NuxTourModel} from '../../nuclide-nux/lib/NuxModel'; -import type {RegisterNux, TriggerNux} from '../../nuclide-nux/lib/main'; -import {makeToolbarButtonSpec} from 'nuclide-commons-ui/ToolbarUtils'; - -const SAMPLE_NUX_ID = 0; -const SAMPLE_NUX_NAME = 'sample-nux-example.sample-nux-id'; - -class Activation { - _disposables: UniversalDisposable; - - constructor() { - this._disposables = new UniversalDisposable(); - } - - dispose() { - this._disposables.dispose(); - } - - consumeToolBar(getToolBar: toolbar$GetToolbar): IDisposable { - const toolBar = getToolBar('nux-example-toolbar'); - const {element} = toolBar.addButton( - makeToolbarButtonSpec({ - icon: 'mortar-board', - callback: 'nux-example-toolbar:noop', - tooltip: 'Example Nux Toolbar Item', - }), - ); - element.classList.add('sample-nux-toolbar-button'); - const disposable = new UniversalDisposable(() => { - toolBar.removeItems(); - }); - this._disposables.add(disposable); - return disposable; - } - - addDisposable(disposable: IDisposable) { - this._disposables.add(disposable); - } -} - -let activation: ?Activation = null; - -export function activate() { - if (activation == null) { - activation = new Activation(); - } -} - -export function deactivate() { - if (activation != null) { - activation.dispose(); - activation = null; - } -} - -export function consumeToolBar(getToolBar: toolbar$GetToolbar): IDisposable { - invariant(activation != null); - return activation.consumeToolBar(getToolBar); -} - -function generateTestNuxTour( - id: number, - name: string, - numViews: number = 1, -): NuxTourModel { - const getNuxViewModel = viewNumber => ({ - content: `Content NUX #${viewNumber}`, - selector: '.sample-nux-toolbar-button', - position: 'auto', - /** - * OPTIONAL: Use a custom selector function to return a DOM element if the - * element to bind the NUX to cannot be returned by a query selector class. - */ - // selectorFunction: () => document.querySelector('.sample-nux-toolbar-button'), - /** - * OPTIONAL: If set, the completion predicate will be evaluated after every - * NUX interaction. The NuxView will not progress to the next one in the - * NuxTour until the predicate evaluates to true. - */ - // completionPredicate: () => true, - }); - const nuxList = Array(numViews) - .fill() // Fill holes so map doesn't skip them - .map((_, index) => getNuxViewModel(index + 1)); - return { - id, - name, - nuxList, - /** - * OPTIONAL (but recommended): Add your own gatekeeper to control who the - * NUX is displayed to. Use the global `nuclide_all_nuxes` if you want the - * NUX to always appear. See `nuclide-nux/lib/NuxModel.js` for more details. - */ - gatekeeperID: 'nuclide_all_nuxes', - /** - * OPTIONAL: Include a custom trigger handled by the NUX framework if you - * choose to not use the `nux-trigger` service. - */ - // trigger: null, - /** - * DEV-ONLY: Setting this will always show the NUX when triggered every - * session. Only to be used for development purposes - the flow typing ensures - * that this cannot be set to true when shipping the NUX. - */ - // developmentMode: true, - }; -} - -export function consumeRegisterNuxService(addNewNux: RegisterNux): IDisposable { - invariant(activation != null); - const disposable = addNewNux( - generateTestNuxTour(SAMPLE_NUX_ID, SAMPLE_NUX_NAME, 2), - ); - activation.addDisposable(disposable); - return disposable; -} - -export function consumeTriggerNuxService(tryTriggerNux: TriggerNux): void { - tryTriggerNux(SAMPLE_NUX_ID); -} diff --git a/pkg/sample-nux-example/package.json b/pkg/sample-nux-example/package.json deleted file mode 100644 index f3b8a50b3b..0000000000 --- a/pkg/sample-nux-example/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "sample-nux-example", - "main": "./lib/main.js", - "version": "0.0.0", - "description": "A package demonstrating usage of NUXes within Nuclide.", - "author": "NEEDS OWNER", - "atomTestRunner": "../../lib/test-runner-entry.js", - "nuclide": { - "packageType": "Atom", - "testRunner": "apm" - }, - "consumedServices": { - "tool-bar": { - "versions": { - "^1.0.0": "consumeToolBar" - } - }, - "nux-register": { - "versions": { - "0.0.0": "consumeRegisterNuxService" - } - }, - "nux-trigger": { - "versions": { - "0.0.0": "consumeTriggerNuxService" - } - } - } -} diff --git a/pkg/sample-quickopen-provider-example/keymaps/quickopen-provider-example.json b/pkg/sample-quickopen-provider-example/keymaps/quickopen-provider-example.json deleted file mode 100644 index 034c47a007..0000000000 --- a/pkg/sample-quickopen-provider-example/keymaps/quickopen-provider-example.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - ".platform-darwin atom-workspace": { - "cmd-alt-x": "sample-quickopen-provider-example:toggle-provider" - }, - ".platform-win32 atom-workspace, .platform-linux atom-workspace": { - "ctrl-alt-x": "sample-quickopen-provider-example:toggle-provider" - } -} diff --git a/pkg/sample-quickopen-provider-example/lib/ExampleProvider.js b/pkg/sample-quickopen-provider-example/lib/ExampleProvider.js deleted file mode 100644 index cc21627527..0000000000 --- a/pkg/sample-quickopen-provider-example/lib/ExampleProvider.js +++ /dev/null @@ -1,181 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import type {FileResult, Provider} from '../../nuclide-quick-open/lib/types'; - -const FIXTURE = [ - 'ac', - 'accumsan', - 'adipiscing', - 'amet', - 'auctor', - 'consectetur', - 'dictum', - 'dolor', - 'efficitur', - 'eget', - 'elit', - 'enim', - 'eros', - 'eu', - 'Fusce', - 'imperdiet', - 'in', - 'ipsum', - 'lacus', - 'leo', - 'libero', - 'lorem', - 'Lorem', - 'luctus', - 'mattis', - 'maximus', - 'mi', - 'Morbi', - 'Nam', - 'nec', - 'non', - 'Nulla', - 'Nullam', - 'odio', - 'placerat', - 'quis', - 'sagittis', - 'sapien', - 'scelerisque', - 'Sed', - 'semper', - 'sit', - 'tellus', - 'tempus', - 'tincidunt', - 'turpis', - 'ultricies', - 'Ut', - 'vel', - 'venenatis', - 'vestibulum', - 'Vestibulum', - 'vitae', -]; - -const ExampleProvider: Provider = { - /** - * One of 'GLOBAL', 'DIRECTORY'. - * DIRECTORY providers work in the context of a mounted directory (e.g. Hack symbol search). - * GLOBAL providers work regardless of mounted directories (e.g. open tabs search; web requests). - */ - providerType: 'DIRECTORY', - - /** - * A unique name, used internally by quick-open to store cached results. - */ - name: 'ExampleProvider', - - /** - * Information used to render the provider in a dedicated tab. If omitted, results from the - * provider will only be shown in the OmniSearch result list. - */ - display: { - /** - * The title of the quick-open tab that exclusively contains results from this provider. - */ - title: 'IpsumSearch', - - /** - * Shown as a placeholder in the query input. - */ - prompt: 'Search Lorem Ipsum', - - /** - * Optional: The Atom action for toggling this provider via a command. Used to render - * the associated keybinding. - */ - action: 'sample-quickopen-provider-example:toggle-provider', - - /** - * Optional: return whether the "Open All" button is allowed for this provider. - * Default: true. - */ - canOpenAll: false, - }, - - /** - * Optional: return a specific delay (in ms) used to debounce queries to this provider. - * Default: 200ms. Useful for e.g. reducing the delay for cheap queries (e.g. opened files). - */ - debounceDelay: 0, - - /** - * An optional number ≥ 0 used to determine ranking order in OmniSearch. - * 0 == highest rank, +Infinity == lowest rank. Defaults to Number.POSITIVE_INFINITY. - */ - priority: 20, - - /** - * Only required if providerType === 'DIRECTORY'. - */ - isEligibleForDirectory(directory: atom$Directory): Promise { - return Promise.resolve(true); - }, - - /** - * Only required if providerType === 'GLOBAL'. - */ - isEligibleForDirectories( - directories: Array, - ): Promise { - return Promise.resolve(true); - }, - - /** - * Return the actual search results. - * For providerType === 'DIRECTORY' the second parameter is `directory`. - * For providerType === 'GLOBAL' it is `directories: Array` - */ - executeQuery( - query: string, - directory: atom$Directory, - ): Promise> { - if (!query.length) { - return Promise.resolve([]); - } - const results = FIXTURE.filter(f => f.indexOf(query) !== -1).map(str => ({ - resultType: 'FILE', - path: '/foo/bar/' + str + '.js', - })); - return new Promise((resolve, reject) => { - setTimeout(() => { - resolve(results); - }, 1000); - }); - }, - - /** - * getComponentForItem Optional function that returns a React Element. - * Useful for overriding the default view of a quick-open result. - */ - // import React from 'react'; - // getComponentForItem(item: FileResult): React.Element { - // var { - // matchIndexes, - // path, - // } = item; - // return ( - //
    - // {path} - //
    - // ); - // }; -}; - -// eslint-disable-next-line nuclide-internal/no-commonjs -module.exports = ExampleProvider; diff --git a/pkg/sample-quickopen-provider-example/lib/main.js b/pkg/sample-quickopen-provider-example/lib/main.js deleted file mode 100644 index 227b068bba..0000000000 --- a/pkg/sample-quickopen-provider-example/lib/main.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * 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 - */ - -import type {FileResult, Provider} from '../../nuclide-quick-open/lib/types'; - -import ExampleProvider from './ExampleProvider'; - -export function registerProvider(): Provider { - return ExampleProvider; -} - -export function activate(state: ?Object) {} - -export function deactivate() {} diff --git a/pkg/sample-quickopen-provider-example/package.json b/pkg/sample-quickopen-provider-example/package.json deleted file mode 100644 index a666bc65c0..0000000000 --- a/pkg/sample-quickopen-provider-example/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "sample-quickopen-provider-example", - "main": "./lib/main.js", - "version": "0.0.0", - "description": "An example provider for the nuclide-quick-open package", - "author": "NEEDS OWNER", - "atomTestRunner": "../../lib/test-runner-entry.js", - "nuclide": { - "packageType": "Atom", - "testRunner": "apm" - }, - "providedServices": { - "nuclide-quick-open-register-provider": { - "description": "Register ourselves with the quick-open package", - "versions": { - "0.0.0": "registerProvider" - } - } - } -} diff --git a/pkg/sample-task-runner/lib/ExampleEmitterTask.js b/pkg/sample-task-runner/lib/ExampleEmitterTask.js deleted file mode 100644 index 339f484477..0000000000 --- a/pkg/sample-task-runner/lib/ExampleEmitterTask.js +++ /dev/null @@ -1,83 +0,0 @@ -/** - * 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 - */ - -import type {Message} from 'nuclide-commons/process'; - -import invariant from 'assert'; -import {Emitter} from 'event-kit'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -export default class ExampleTask { - _emitter: Emitter = new Emitter(); - _completeTimeoutId: ?TimeoutID; - _messageIntervalId: ?IntervalID; - _progressIntervalId: ?IntervalID; - _progress: number; - - start = (): void => { - invariant(this._completeTimeoutId == null); - invariant(this._messageIntervalId == null); - invariant(this._progressIntervalId == null); - this._progress = 0; - this._messageIntervalId = setInterval(this._handleMessageInterval, 3000); - this._progressIntervalId = setInterval(this._handleProgrssInterval, 1000); - this._completeTimeoutId = setTimeout(this._handleComplete, 15000); - }; - - cancel = (): void => { - this._tearDown(); - }; - - _handleMessageInterval = (): void => { - this._emitter.emit('message', { - level: 'info', - text: `It is currently ${new Date().toString()}`, - }); - }; - - _handleProgrssInterval = (): void => { - this._emitter.emit('progress', (this._progress += 0.05)); - }; - - _handleComplete = (): void => { - this._tearDown(); - this._emitter.emit('complete'); - }; - - _tearDown = (): void => { - if (this._messageIntervalId != null) { - clearInterval(this._messageIntervalId); - } - if (this._progressIntervalId != null) { - clearInterval(this._progressIntervalId); - } - if (this._completeTimeoutId != null) { - clearTimeout(this._completeTimeoutId); - } - }; - - onDidComplete = (callback: () => mixed): IDisposable => { - return this._emitter.on('complete', callback); - }; - - onDidError = (callback: (err: Error) => mixed): IDisposable => { - // If your task can error make sure to do something here. - return new UniversalDisposable(); - }; - - onMessage = (callback: (message: Message) => mixed): IDisposable => { - return this._emitter.on('message', callback); - }; - - onProgress = (callback: (progress: ?number) => mixed): IDisposable => { - return this._emitter.on('progress', callback); - }; -} diff --git a/pkg/sample-task-runner/lib/ExtraUi.js b/pkg/sample-task-runner/lib/ExtraUi.js deleted file mode 100644 index 018c2d262b..0000000000 --- a/pkg/sample-task-runner/lib/ExtraUi.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * 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 strict - * @format - */ - -import * as React from 'react'; - -export default class ExtraUi extends React.Component<{}> { - render(): React.Node { - return
    Extra UI!
    ; - } -} diff --git a/pkg/sample-task-runner/lib/Icon.js b/pkg/sample-task-runner/lib/Icon.js deleted file mode 100644 index 1fef91b7c4..0000000000 --- a/pkg/sample-task-runner/lib/Icon.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * 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 strict - * @format - */ - -import * as React from 'react'; - -export default class Icon extends React.Component<{}> { - render(): React.Node { - return AWE; - } -} diff --git a/pkg/sample-task-runner/lib/TaskRunner.js b/pkg/sample-task-runner/lib/TaskRunner.js deleted file mode 100644 index dc4d166fdd..0000000000 --- a/pkg/sample-task-runner/lib/TaskRunner.js +++ /dev/null @@ -1,74 +0,0 @@ -/** - * 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 - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {Task} from '../../commons-node/tasks'; -import type {TaskMetadata} from '../../nuclide-task-runner/lib/types'; - -import createExampleObservableTask from './createExampleObservableTask'; -import ExampleEmitterTask from './ExampleEmitterTask'; -import ExtraUi from './ExtraUi'; -import Icon from './Icon'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -export default class TaskRunner { - id = 'my-awesome-task-runner'; - name = 'Awesome Stuff'; - - getExtraUi(): React$ComponentType { - return ExtraUi; - } - - getIcon(): React$ComponentType { - return Icon; - } - - setProjectRoot( - projectRoot: ?NuclideUri, - callback: (enabled: boolean, taskList: Array) => mixed, - ): IDisposable { - // Invoke the callback whenever the tasks change. For the purpose of the example, we'll assume - // they never do and just invoke it once now. - callback(true, [ - { - type: 'build', - label: 'Build', - description: 'Build something cool', - icon: 'tools', - }, - { - type: 'run', - label: 'Run', - description: 'Run it', - icon: 'triangle-right', - }, - ]); - - // The returned disposable should clean up any resources being used to determine when the tasks - // change. - return new UniversalDisposable(); - } - - runTask(taskType: string): Task { - // You can create a task however you want as long as it conforms to the Task API. However, - // because tasks have event registration methods, you'll probably either want to either use Rx - // or extend event-kit's Emitter. An example of each is provided; both do the same thing. - // Neither implements the full functionality so check out the Task definition for more detail. - switch (taskType) { - case 'build': - return createExampleObservableTask(); - case 'run': - return new ExampleEmitterTask(); - default: - throw new Error(`Invalid task type: ${taskType}`); - } - } -} diff --git a/pkg/sample-task-runner/lib/createExampleObservableTask.js b/pkg/sample-task-runner/lib/createExampleObservableTask.js deleted file mode 100644 index f33af0107e..0000000000 --- a/pkg/sample-task-runner/lib/createExampleObservableTask.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import type {Task} from '../../commons-node/tasks'; - -import {taskFromObservable} from '../../commons-node/tasks'; -import {Observable} from 'rxjs'; - -export default function createExampleObservableTask(): Task { - const messageEvents = Observable.interval(3000).map(() => ({ - type: 'message', - message: { - level: 'info', - text: `It is currently ${new Date().toString()}`, - }, - })); - - const progressEvents = Observable.interval(1000).map(x => ({ - type: 'progress', - progress: x * 0.05, - })); - - const allEvents = Observable.merge(messageEvents, progressEvents); - const complete = Observable.timer(15000); - return taskFromObservable(allEvents.takeUntil(complete)); -} diff --git a/pkg/sample-task-runner/lib/main.js b/pkg/sample-task-runner/lib/main.js deleted file mode 100644 index 3de9849263..0000000000 --- a/pkg/sample-task-runner/lib/main.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -import type {TaskRunnerServiceApi} from '../../nuclide-task-runner/lib/types'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import TaskRunner from './TaskRunner'; - -class Activation { - _disposables = new UniversalDisposable(); - - consumeTaskRunnerApi(api: TaskRunnerServiceApi): IDisposable { - const disposable = api.register(new TaskRunner()); - this._disposables.add(disposable); - return new UniversalDisposable(() => { - this._disposables.remove(disposable); - }); - } - - dispose(): void { - this._disposables.dispose(); - } -} - -createPackage(module.exports, Activation); diff --git a/pkg/sample-task-runner/package.json b/pkg/sample-task-runner/package.json deleted file mode 100644 index fbe93e28ba..0000000000 --- a/pkg/sample-task-runner/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "sample-task-runner", - "main": "./lib/main.js", - "version": "0.0.0", - "description": "A sample task runner", - "author": "NEEDS OWNER", - "atomTestRunner": "../../lib/test-runner-entry.js", - "nuclide": { - "packageType": "Atom", - "testRunner": "apm" - }, - "consumedServices": { - "nuclide.task-runner": { - "versions": { - "0.0.0": "consumeTaskRunnerApi" - } - } - } -} diff --git a/pkg/sample-web-view/README.md b/pkg/sample-web-view/README.md deleted file mode 100644 index f9a1853f73..0000000000 --- a/pkg/sample-web-view/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# sample-web-view - -Sample Atom package that demonstrates how to open a `` in a pane in Atom. - -Once this package is installed, run `Sample Web View: Open Url` from the command -palette to activate the package and open a tab with a ``. Learn more about -what you can do with a `` at -https://github.com/atom/electron/blob/master/docs/api/web-view-tag.md. diff --git a/pkg/sample-web-view/lib/WebViewPane.js b/pkg/sample-web-view/lib/WebViewPane.js deleted file mode 100644 index 7032fd61e5..0000000000 --- a/pkg/sample-web-view/lib/WebViewPane.js +++ /dev/null @@ -1,101 +0,0 @@ -/** - * 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 - */ - -/* global HTMLElement */ - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -import {Emitter} from 'atom'; - -class WebViewPane extends HTMLElement { - _title: string; - _subscriptions: UniversalDisposable; - _emitter: Emitter; - _webview: WebviewElement; - - // When it comes to ES6 classes and HTML5 custom elements, "constructors don't really work yet": - // - // http://h3manth.com/new/blog/2015/custom-elements-with-es6/ - // - // As such, we must override createdCallback() instead: - // - // http://www.html5rocks.com/en/tutorials/webcomponents/customelements/#lifecycle. - // - // This is probably confusing for Flow because it cannot tell which properties are defined during - // initialization since this is not the constructor. - createdCallback(): mixed { - this._title = 'Loading...'; - this._subscriptions = new UniversalDisposable(); - this._emitter = new Emitter(); - this._subscriptions.add(this._emitter); - - // The element is an element specific to Electron (the framework on which - // Atom is built). It is similar to an

    - This is intended to debug python script files. -
    - To debug buck targets, you should{' '} -
    - use the buck toolbar instead - . -