Added vscode settings

This commit is contained in:
Kristofers Solo
2022-04-28 20:54:44 +03:00
parent 245c3ca779
commit 837a479d82
25004 changed files with 2499800 additions and 0 deletions

View File

@@ -0,0 +1 @@
github: pranaygp

View File

@@ -0,0 +1,3 @@
server/out
client/out
tests/out

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<Metadata>
<Identity Language="en-US" Id="vscode-css-peek" Version="4.2.0" Publisher="pranaygp"/>
<DisplayName>CSS Peek</DisplayName>
<Description xml:space="preserve">Allow peeking to css ID and class strings as definitions from html files to respective CSS. Allows peek and goto definition.</Description>
<Tags>definition,css,scss,sass,less,peek,style,stylesheet,jump to stylesheet,multi-root ready</Tags>
<Categories></Categories>
<GalleryFlags>Public</GalleryFlags>
<Badges></Badges>
<Properties>
<Property Id="Microsoft.VisualStudio.Code.Engine" Value="^1.33.0" />
<Property Id="Microsoft.VisualStudio.Code.ExtensionDependencies" Value="" />
<Property Id="Microsoft.VisualStudio.Code.ExtensionPack" Value="" />
<Property Id="Microsoft.VisualStudio.Code.ExtensionKind" Value="workspace" />
<Property Id="Microsoft.VisualStudio.Code.LocalizedLanguages" Value="" />
<Property Id="Microsoft.VisualStudio.Services.Links.Source" Value="https://github.com/pranaygp/vscode-css-peek" />
<Property Id="Microsoft.VisualStudio.Services.Links.Getstarted" Value="https://github.com/pranaygp/vscode-css-peek" />
<Property Id="Microsoft.VisualStudio.Services.Links.GitHub" Value="https://github.com/pranaygp/vscode-css-peek" />
<Property Id="Microsoft.VisualStudio.Services.Links.Support" Value="https://github.com/pranaygp/vscode-css-peek/issues" />
<Property Id="Microsoft.VisualStudio.Services.Links.Learn" Value="https://github.com/pranaygp/vscode-css-peek/blob/master/README.md" />
<Property Id="Microsoft.VisualStudio.Services.GitHubFlavoredMarkdown" Value="true" />
</Properties>
<License>extension/LICENSE.txt</License>
<Icon>extension/css_peek_icon.png</Icon>
</Metadata>
<Installation>
<InstallationTarget Id="Microsoft.VisualStudio.Code"/>
</Installation>
<Dependencies/>
<Assets>
<Asset Type="Microsoft.VisualStudio.Code.Manifest" Path="extension/package.json" Addressable="true" />
<Asset Type="Microsoft.VisualStudio.Services.Content.Details" Path="extension/README.md" Addressable="true" /><Asset Type="Microsoft.VisualStudio.Services.Content.License" Path="extension/LICENSE.txt" Addressable="true" /><Asset Type="Microsoft.VisualStudio.Services.Icons.Default" Path="extension/css_peek_icon.png" Addressable="true" />
</Assets>
</PackageManifest>

View File

@@ -0,0 +1,17 @@
Copyright (c) Pranay Prakash
All rights reserved.
MIT License
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.

View File

@@ -0,0 +1,132 @@
[![Build Status](https://travis-ci.org/pranaygp/vscode-css-peek.svg?branch=master)](https://travis-ci.org/pranaygp/vscode-css-peek)
[![Installs](https://vsmarketplacebadge.apphb.com/installs-short/pranaygp.vscode-css-peek.svg)](https://marketplace.visualstudio.com/items?itemName=pranaygp.vscode-css-peek)
[![Version](https://vsmarketplacebadge.apphb.com/version/pranaygp.vscode-css-peek.svg)](https://marketplace.visualstudio.com/items?itemName=pranaygp.vscode-css-peek)
[![Open VSX](https://img.shields.io/badge/Open%20VSX-vscode--css--peek-purple)](https://open-vsx.org/extension/pranaygp/vscode-css-peek)
[![codecov](https://codecov.io/gh/pranaygp/vscode-css-peek/branch/master/graph/badge.svg)](https://codecov.io/gh/pranaygp/vscode-css-peek)
## Backed By
> An amazing tool I've used before and they didn't ask me to say that :) - Extension Author
<p><a title="Try CodeStream" href="https://sponsorlink.codestream.com/?utm_source=vscmarket&amp;utm_campaign=pranaygp_css_peek&amp;utm_medium=banner"><img src="https://alt-images.codestream.com/codestream_logo_pranaygp_css_peek.png"></a></br>
Manage pull requests and conduct code reviews in your IDE with full source-tree context. Comment on any line, not just the diffs. Use jump-to-definition, your favorite keybindings, and code intelligence with more of your workflow.<br> <a title="Try CodeStream" href="https://sponsorlink.codestream.com/?utm_source=vscmarket&amp;utm_campaign=pranaygp_css_peek&amp;utm_medium=banner">Learn More</a></p>
# Functionality
This extension extends HTML and ejs code editing with `Go To Definition` and `Go To Symbol in Workspace` support for css/scss/less (classes and IDs) found in strings within the source code.
This was heavily inspired by a similar feature in [Brackets](http://brackets.io/) called CSS Inline Editors.
![working](https://github.com/pranaygp/vscode-css-peek/raw/master/readme/working.gif)
The extension supports all the normal capabilities of symbol definition tracking, but does it for css selectors (classes, IDs and HTML tags). This includes:
- Peek: load the css file inline and make quick edits right there. (`Ctrl+Shift+F12`)
- Go To: jump directly to the css file or open it in a new editor (`F12`)
- Hover: show the definition in a hover over the symbol (`Ctrl+hover`)
In addition, it supports the Symbol Provider so you can quickly jump to the right CSS/SCSS/LESS code if you already know the class or ID name
![Symbol Provider](https://github.com/pranaygp/vscode-css-peek/raw/master/readme/symbolProvider.gif)
## Configuration
- `cssPeek.supportTags` - Enable Peeking from HTML tags in addition to classnames and IDs. React components are ignored, but it's a good idea to disable this feature when using Angular.
- `cssPeek.peekFromLanguages` - A list of vscode language names where the extension should be used.
- `cssPeek.peekToExclude` - A list of file globs that filters out style files to not look for. By default, `node_modules` and `bower_components`
See editor docs for more details
- [Visual Studio Code: Goto Definition](https://code.visualstudio.com/docs/editor/editingevolved#_go-to-definition)
- [Visual Studio Code: Peek](https://code.visualstudio.com/docs/editor/editingevolved#_peek)
- [Visual Studio Code: Open Symbol By Name](https://code.visualstudio.com/Docs/editor/editingevolved#_open-symbol-by-name)
# Contributing
Contributions are greatly appreciated. Please fork the repository and submit a pull request.
# Changelog
> TODO: Keep the changelog upto date
## 4.2.0
- Support VSCode Workspace Trust [#107](https://github.com/pranaygp/vscode-css-peek/issues/107)
## 4.1.1
- Add CodeStream Banner
## 3.0.2
- Use Globs for configuration options instead of RegExp via [#61](https://github.com/pranaygp/vscode-css-peek/pull/61) ❤ [@arch-stack](https://github.com/arch-stack)
## 2.2.0
- Initial JSX support via [#49](https://github.com/pranaygp/vscode-css-peek/pull/49) ❤ [@ReiMcCl](https://github.com/ReiMcCl)
## 2.1.1
- (Temporarily) fix bug [#19](https://github.com/pranaygp/vscode-css-peek/issues/18) by handling errors from `findDocumentSymbols`
## 2.1.0
- Add support for Symbol Provider [#18](https://github.com/pranaygp/vscode-css-peek/issues/18)
> ![Symbol Provider](https://github.com/pranaygp/vscode-css-peek/raw/master/readme/symbolProvider.gif)
## 2.0.3
- Fix bug [#14](https://github.com/pranaygp/vscode-css-peek/issues/14) that caused CSS Peek to fail after any HTML comments
## 2.0.2
- Fix bug that limited the language support only to HTML. Now supports all languages provided by "activeLanguages" config
## 2.0.1
- Fix an error wherby the Overview was missing on the Visual Studio Marketplace
## 2.0.0
- A complete rewrite featuring the new [Language Server Protocol](https://github.com/Microsoft/language-server-protocol)
- Added scss support
- Added multi definition support (provides all CSS rules matching the selector)
- Added support for HTML tag selectors
## 1.3.3
- New Logo
## 1.3.0
- Add configuration option to ignore file from CSS lookup
## 1.2.4
- Crucial bug fix
## 1.2.3
- Workaround for bug if large number of files exist
## 1.2.2
- Better recognition of CSS selector word from cursor position
- Optimize code for fewer file lookups
## 1.2.1
- Fix README typo
## 1.2.0
- Add `less` support
- Configure search file extensions using "css_peek.searchFileExtensions"
## 1.1.0
- Update Icon
## 1.0.0
- Shamelessly copied code from [https://github.com/abierbaum/vscode-file-peek](https://github.com/abierbaum/vscode-file-peek)

View File

@@ -0,0 +1,160 @@
#!/usr/bin/env node
// Standalone semver comparison program.
// Exits successfully and prints matching version(s) if
// any supplied version is valid and passes all tests.
var argv = process.argv.slice(2)
var versions = []
var range = []
var inc = null
var version = require('../package.json').version
var loose = false
var includePrerelease = false
var coerce = false
var identifier
var semver = require('../semver')
var reverse = false
var options = {}
main()
function main () {
if (!argv.length) return help()
while (argv.length) {
var a = argv.shift()
var indexOfEqualSign = a.indexOf('=')
if (indexOfEqualSign !== -1) {
a = a.slice(0, indexOfEqualSign)
argv.unshift(a.slice(indexOfEqualSign + 1))
}
switch (a) {
case '-rv': case '-rev': case '--rev': case '--reverse':
reverse = true
break
case '-l': case '--loose':
loose = true
break
case '-p': case '--include-prerelease':
includePrerelease = true
break
case '-v': case '--version':
versions.push(argv.shift())
break
case '-i': case '--inc': case '--increment':
switch (argv[0]) {
case 'major': case 'minor': case 'patch': case 'prerelease':
case 'premajor': case 'preminor': case 'prepatch':
inc = argv.shift()
break
default:
inc = 'patch'
break
}
break
case '--preid':
identifier = argv.shift()
break
case '-r': case '--range':
range.push(argv.shift())
break
case '-c': case '--coerce':
coerce = true
break
case '-h': case '--help': case '-?':
return help()
default:
versions.push(a)
break
}
}
var options = { loose: loose, includePrerelease: includePrerelease }
versions = versions.map(function (v) {
return coerce ? (semver.coerce(v) || { version: v }).version : v
}).filter(function (v) {
return semver.valid(v)
})
if (!versions.length) return fail()
if (inc && (versions.length !== 1 || range.length)) { return failInc() }
for (var i = 0, l = range.length; i < l; i++) {
versions = versions.filter(function (v) {
return semver.satisfies(v, range[i], options)
})
if (!versions.length) return fail()
}
return success(versions)
}
function failInc () {
console.error('--inc can only be used on a single version with no range')
fail()
}
function fail () { process.exit(1) }
function success () {
var compare = reverse ? 'rcompare' : 'compare'
versions.sort(function (a, b) {
return semver[compare](a, b, options)
}).map(function (v) {
return semver.clean(v, options)
}).map(function (v) {
return inc ? semver.inc(v, inc, options, identifier) : v
}).forEach(function (v, i, _) { console.log(v) })
}
function help () {
console.log(['SemVer ' + version,
'',
'A JavaScript implementation of the https://semver.org/ specification',
'Copyright Isaac Z. Schlueter',
'',
'Usage: semver [options] <version> [<version> [...]]',
'Prints valid versions sorted by SemVer precedence',
'',
'Options:',
'-r --range <range>',
' Print versions that match the specified range.',
'',
'-i --increment [<level>]',
' Increment a version by the specified level. Level can',
' be one of: major, minor, patch, premajor, preminor,',
" prepatch, or prerelease. Default level is 'patch'.",
' Only one version may be specified.',
'',
'--preid <identifier>',
' Identifier to be used to prefix premajor, preminor,',
' prepatch or prerelease version increments.',
'',
'-l --loose',
' Interpret versions and ranges loosely',
'',
'-p --include-prerelease',
' Always include prerelease versions in range matching',
'',
'-c --coerce',
' Coerce a string into SemVer if possible',
' (does not imply --loose)',
'',
'Program exits successfully if any valid version satisfies',
'all supplied ranges, and prints all satisfying versions.',
'',
'If no satisfying versions are found, then exits failure.',
'',
'Versions are printed in ascending order, so supplying',
'multiple versions to the utility will just sort them.'
].join('\n'))
}

View File

@@ -0,0 +1,25 @@
{
"systemParams": "darwin-x64-83",
"modulesFolders": [
"node_modules"
],
"flags": [],
"linkedModules": [
"@windsorio/instatrace",
"instatrace"
],
"topLevelPatterns": [
"@types/vscode@^1.33.0",
"vscode-languageclient@^5.2.1"
],
"lockfileEntries": {
"@types/vscode@^1.33.0": "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.47.0.tgz#4a4051c21ecaadcf383a2c4387bea282540e96de",
"semver@^5.5.0": "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7",
"vscode-jsonrpc@^4.0.0": "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz#a7bf74ef3254d0a0c272fab15c82128e378b3be9",
"vscode-languageclient@^5.2.1": "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz#7cfc83a294c409f58cfa2b910a8cfeaad0397193",
"vscode-languageserver-protocol@3.14.1": "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz#b8aab6afae2849c84a8983d39a1cf742417afe2f",
"vscode-languageserver-types@3.14.0": "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743"
},
"files": [],
"artifacts": {}
}

View File

@@ -0,0 +1,39 @@
# changes log
## 5.7
* Add `minVersion` method
## 5.6
* Move boolean `loose` param to an options object, with
backwards-compatibility protection.
* Add ability to opt out of special prerelease version handling with
the `includePrerelease` option flag.
## 5.5
* Add version coercion capabilities
## 5.4
* Add intersection checking
## 5.3
* Add `minSatisfying` method
## 5.2
* Add `prerelease(v)` that returns prerelease components
## 5.1
* Add Backus-Naur for ranges
* Remove excessively cute inspection methods
## 5.0
* Remove AMD/Browserified build artifacts
* Fix ltr and gtr when using the `*` range
* Fix for range `*` with a prerelease identifier

View File

@@ -0,0 +1,15 @@
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@@ -0,0 +1,160 @@
#!/usr/bin/env node
// Standalone semver comparison program.
// Exits successfully and prints matching version(s) if
// any supplied version is valid and passes all tests.
var argv = process.argv.slice(2)
var versions = []
var range = []
var inc = null
var version = require('../package.json').version
var loose = false
var includePrerelease = false
var coerce = false
var identifier
var semver = require('../semver')
var reverse = false
var options = {}
main()
function main () {
if (!argv.length) return help()
while (argv.length) {
var a = argv.shift()
var indexOfEqualSign = a.indexOf('=')
if (indexOfEqualSign !== -1) {
a = a.slice(0, indexOfEqualSign)
argv.unshift(a.slice(indexOfEqualSign + 1))
}
switch (a) {
case '-rv': case '-rev': case '--rev': case '--reverse':
reverse = true
break
case '-l': case '--loose':
loose = true
break
case '-p': case '--include-prerelease':
includePrerelease = true
break
case '-v': case '--version':
versions.push(argv.shift())
break
case '-i': case '--inc': case '--increment':
switch (argv[0]) {
case 'major': case 'minor': case 'patch': case 'prerelease':
case 'premajor': case 'preminor': case 'prepatch':
inc = argv.shift()
break
default:
inc = 'patch'
break
}
break
case '--preid':
identifier = argv.shift()
break
case '-r': case '--range':
range.push(argv.shift())
break
case '-c': case '--coerce':
coerce = true
break
case '-h': case '--help': case '-?':
return help()
default:
versions.push(a)
break
}
}
var options = { loose: loose, includePrerelease: includePrerelease }
versions = versions.map(function (v) {
return coerce ? (semver.coerce(v) || { version: v }).version : v
}).filter(function (v) {
return semver.valid(v)
})
if (!versions.length) return fail()
if (inc && (versions.length !== 1 || range.length)) { return failInc() }
for (var i = 0, l = range.length; i < l; i++) {
versions = versions.filter(function (v) {
return semver.satisfies(v, range[i], options)
})
if (!versions.length) return fail()
}
return success(versions)
}
function failInc () {
console.error('--inc can only be used on a single version with no range')
fail()
}
function fail () { process.exit(1) }
function success () {
var compare = reverse ? 'rcompare' : 'compare'
versions.sort(function (a, b) {
return semver[compare](a, b, options)
}).map(function (v) {
return semver.clean(v, options)
}).map(function (v) {
return inc ? semver.inc(v, inc, options, identifier) : v
}).forEach(function (v, i, _) { console.log(v) })
}
function help () {
console.log(['SemVer ' + version,
'',
'A JavaScript implementation of the https://semver.org/ specification',
'Copyright Isaac Z. Schlueter',
'',
'Usage: semver [options] <version> [<version> [...]]',
'Prints valid versions sorted by SemVer precedence',
'',
'Options:',
'-r --range <range>',
' Print versions that match the specified range.',
'',
'-i --increment [<level>]',
' Increment a version by the specified level. Level can',
' be one of: major, minor, patch, premajor, preminor,',
" prepatch, or prerelease. Default level is 'patch'.",
' Only one version may be specified.',
'',
'--preid <identifier>',
' Identifier to be used to prefix premajor, preminor,',
' prepatch or prerelease version increments.',
'',
'-l --loose',
' Interpret versions and ranges loosely',
'',
'-p --include-prerelease',
' Always include prerelease versions in range matching',
'',
'-c --coerce',
' Coerce a string into SemVer if possible',
' (does not imply --loose)',
'',
'Program exits successfully if any valid version satisfies',
'all supplied ranges, and prints all satisfying versions.',
'',
'If no satisfying versions are found, then exits failure.',
'',
'Versions are printed in ascending order, so supplying',
'multiple versions to the utility will just sort them.'
].join('\n'))
}

View File

@@ -0,0 +1,28 @@
{
"name": "semver",
"version": "5.7.1",
"description": "The semantic version parser used by npm.",
"main": "semver.js",
"scripts": {
"test": "tap",
"preversion": "npm test",
"postversion": "npm publish",
"postpublish": "git push origin --all; git push origin --tags"
},
"devDependencies": {
"tap": "^13.0.0-rc.18"
},
"license": "ISC",
"repository": "https://github.com/npm/node-semver",
"bin": {
"semver": "./bin/semver"
},
"files": [
"bin",
"range.bnf",
"semver.js"
],
"tap": {
"check-coverage": true
}
}

View File

@@ -0,0 +1,16 @@
range-set ::= range ( logical-or range ) *
logical-or ::= ( ' ' ) * '||' ( ' ' ) *
range ::= hyphen | simple ( ' ' simple ) * | ''
hyphen ::= partial ' - ' partial
simple ::= primitive | partial | tilde | caret
primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
xr ::= 'x' | 'X' | '*' | nr
nr ::= '0' | [1-9] ( [0-9] ) *
tilde ::= '~' partial
caret ::= '^' partial
qualifier ::= ( '-' pre )? ( '+' build )?
pre ::= parts
build ::= parts
parts ::= part ( '.' part ) *
part ::= nr | [-0-9A-Za-z]+

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
Copyright (c) Microsoft Corporation
All rights reserved.
MIT License
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.

View File

@@ -0,0 +1,81 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("./events");
const Is = require("./is");
var CancellationToken;
(function (CancellationToken) {
CancellationToken.None = Object.freeze({
isCancellationRequested: false,
onCancellationRequested: events_1.Event.None
});
CancellationToken.Cancelled = Object.freeze({
isCancellationRequested: true,
onCancellationRequested: events_1.Event.None
});
function is(value) {
let candidate = value;
return candidate && (candidate === CancellationToken.None
|| candidate === CancellationToken.Cancelled
|| (Is.boolean(candidate.isCancellationRequested) && !!candidate.onCancellationRequested));
}
CancellationToken.is = is;
})(CancellationToken = exports.CancellationToken || (exports.CancellationToken = {}));
const shortcutEvent = Object.freeze(function (callback, context) {
let handle = setTimeout(callback.bind(context), 0);
return { dispose() { clearTimeout(handle); } };
});
class MutableToken {
constructor() {
this._isCancelled = false;
}
cancel() {
if (!this._isCancelled) {
this._isCancelled = true;
if (this._emitter) {
this._emitter.fire(undefined);
this._emitter = undefined;
}
}
}
get isCancellationRequested() {
return this._isCancelled;
}
get onCancellationRequested() {
if (this._isCancelled) {
return shortcutEvent;
}
if (!this._emitter) {
this._emitter = new events_1.Emitter();
}
return this._emitter.event;
}
}
class CancellationTokenSource {
get token() {
if (!this._token) {
// be lazy and create the token only when
// actually needed
this._token = new MutableToken();
}
return this._token;
}
cancel() {
if (!this._token) {
// save an object by returning the default
// cancelled token when cancellation happens
// before someone asks for the token
this._token = CancellationToken.Cancelled;
}
else {
this._token.cancel();
}
}
dispose() {
this.cancel();
}
}
exports.CancellationTokenSource = CancellationTokenSource;

View File

@@ -0,0 +1,131 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var Disposable;
(function (Disposable) {
function create(func) {
return {
dispose: func
};
}
Disposable.create = create;
})(Disposable = exports.Disposable || (exports.Disposable = {}));
var Event;
(function (Event) {
const _disposable = { dispose() { } };
Event.None = function () { return _disposable; };
})(Event = exports.Event || (exports.Event = {}));
class CallbackList {
add(callback, context = null, bucket) {
if (!this._callbacks) {
this._callbacks = [];
this._contexts = [];
}
this._callbacks.push(callback);
this._contexts.push(context);
if (Array.isArray(bucket)) {
bucket.push({ dispose: () => this.remove(callback, context) });
}
}
remove(callback, context = null) {
if (!this._callbacks) {
return;
}
var foundCallbackWithDifferentContext = false;
for (var i = 0, len = this._callbacks.length; i < len; i++) {
if (this._callbacks[i] === callback) {
if (this._contexts[i] === context) {
// callback & context match => remove it
this._callbacks.splice(i, 1);
this._contexts.splice(i, 1);
return;
}
else {
foundCallbackWithDifferentContext = true;
}
}
}
if (foundCallbackWithDifferentContext) {
throw new Error('When adding a listener with a context, you should remove it with the same context');
}
}
invoke(...args) {
if (!this._callbacks) {
return [];
}
var ret = [], callbacks = this._callbacks.slice(0), contexts = this._contexts.slice(0);
for (var i = 0, len = callbacks.length; i < len; i++) {
try {
ret.push(callbacks[i].apply(contexts[i], args));
}
catch (e) {
console.error(e);
}
}
return ret;
}
isEmpty() {
return !this._callbacks || this._callbacks.length === 0;
}
dispose() {
this._callbacks = undefined;
this._contexts = undefined;
}
}
class Emitter {
constructor(_options) {
this._options = _options;
}
/**
* For the public to allow to subscribe
* to events from this Emitter
*/
get event() {
if (!this._event) {
this._event = (listener, thisArgs, disposables) => {
if (!this._callbacks) {
this._callbacks = new CallbackList();
}
if (this._options && this._options.onFirstListenerAdd && this._callbacks.isEmpty()) {
this._options.onFirstListenerAdd(this);
}
this._callbacks.add(listener, thisArgs);
let result;
result = {
dispose: () => {
this._callbacks.remove(listener, thisArgs);
result.dispose = Emitter._noop;
if (this._options && this._options.onLastListenerRemove && this._callbacks.isEmpty()) {
this._options.onLastListenerRemove(this);
}
}
};
if (Array.isArray(disposables)) {
disposables.push(result);
}
return result;
};
}
return this._event;
}
/**
* To be kept private to fire an event to
* subscribers
*/
fire(event) {
if (this._callbacks) {
this._callbacks.invoke.call(this._callbacks, event);
}
}
dispose() {
if (this._callbacks) {
this._callbacks.dispose();
this._callbacks = undefined;
}
}
}
Emitter._noop = function () { };
exports.Emitter = Emitter;

View File

@@ -0,0 +1,34 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
function boolean(value) {
return value === true || value === false;
}
exports.boolean = boolean;
function string(value) {
return typeof value === 'string' || value instanceof String;
}
exports.string = string;
function number(value) {
return typeof value === 'number' || value instanceof Number;
}
exports.number = number;
function error(value) {
return value instanceof Error;
}
exports.error = error;
function func(value) {
return typeof value === 'function';
}
exports.func = func;
function array(value) {
return Array.isArray(value);
}
exports.array = array;
function stringArray(value) {
return array(value) && value.every(elem => string(elem));
}
exports.stringArray = stringArray;

View File

@@ -0,0 +1,279 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
var Touch;
(function (Touch) {
Touch.None = 0;
Touch.First = 1;
Touch.Last = 2;
})(Touch = exports.Touch || (exports.Touch = {}));
class LinkedMap {
constructor() {
this._map = new Map();
this._head = undefined;
this._tail = undefined;
this._size = 0;
}
clear() {
this._map.clear();
this._head = undefined;
this._tail = undefined;
this._size = 0;
}
isEmpty() {
return !this._head && !this._tail;
}
get size() {
return this._size;
}
has(key) {
return this._map.has(key);
}
get(key) {
const item = this._map.get(key);
if (!item) {
return undefined;
}
return item.value;
}
set(key, value, touch = Touch.None) {
let item = this._map.get(key);
if (item) {
item.value = value;
if (touch !== Touch.None) {
this.touch(item, touch);
}
}
else {
item = { key, value, next: undefined, previous: undefined };
switch (touch) {
case Touch.None:
this.addItemLast(item);
break;
case Touch.First:
this.addItemFirst(item);
break;
case Touch.Last:
this.addItemLast(item);
break;
default:
this.addItemLast(item);
break;
}
this._map.set(key, item);
this._size++;
}
}
delete(key) {
const item = this._map.get(key);
if (!item) {
return false;
}
this._map.delete(key);
this.removeItem(item);
this._size--;
return true;
}
shift() {
if (!this._head && !this._tail) {
return undefined;
}
if (!this._head || !this._tail) {
throw new Error('Invalid list');
}
const item = this._head;
this._map.delete(item.key);
this.removeItem(item);
this._size--;
return item.value;
}
forEach(callbackfn, thisArg) {
let current = this._head;
while (current) {
if (thisArg) {
callbackfn.bind(thisArg)(current.value, current.key, this);
}
else {
callbackfn(current.value, current.key, this);
}
current = current.next;
}
}
forEachReverse(callbackfn, thisArg) {
let current = this._tail;
while (current) {
if (thisArg) {
callbackfn.bind(thisArg)(current.value, current.key, this);
}
else {
callbackfn(current.value, current.key, this);
}
current = current.previous;
}
}
values() {
let result = [];
let current = this._head;
while (current) {
result.push(current.value);
current = current.next;
}
return result;
}
keys() {
let result = [];
let current = this._head;
while (current) {
result.push(current.key);
current = current.next;
}
return result;
}
/* JSON RPC run on es5 which has no Symbol.iterator
public keys(): IterableIterator<K> {
let current = this._head;
let iterator: IterableIterator<K> = {
[Symbol.iterator]() {
return iterator;
},
next():IteratorResult<K> {
if (current) {
let result = { value: current.key, done: false };
current = current.next;
return result;
} else {
return { value: undefined, done: true };
}
}
};
return iterator;
}
public values(): IterableIterator<V> {
let current = this._head;
let iterator: IterableIterator<V> = {
[Symbol.iterator]() {
return iterator;
},
next():IteratorResult<V> {
if (current) {
let result = { value: current.value, done: false };
current = current.next;
return result;
} else {
return { value: undefined, done: true };
}
}
};
return iterator;
}
*/
addItemFirst(item) {
// First time Insert
if (!this._head && !this._tail) {
this._tail = item;
}
else if (!this._head) {
throw new Error('Invalid list');
}
else {
item.next = this._head;
this._head.previous = item;
}
this._head = item;
}
addItemLast(item) {
// First time Insert
if (!this._head && !this._tail) {
this._head = item;
}
else if (!this._tail) {
throw new Error('Invalid list');
}
else {
item.previous = this._tail;
this._tail.next = item;
}
this._tail = item;
}
removeItem(item) {
if (item === this._head && item === this._tail) {
this._head = undefined;
this._tail = undefined;
}
else if (item === this._head) {
this._head = item.next;
}
else if (item === this._tail) {
this._tail = item.previous;
}
else {
const next = item.next;
const previous = item.previous;
if (!next || !previous) {
throw new Error('Invalid list');
}
next.previous = previous;
previous.next = next;
}
}
touch(item, touch) {
if (!this._head || !this._tail) {
throw new Error('Invalid list');
}
if ((touch !== Touch.First && touch !== Touch.Last)) {
return;
}
if (touch === Touch.First) {
if (item === this._head) {
return;
}
const next = item.next;
const previous = item.previous;
// Unlink the item
if (item === this._tail) {
// previous must be defined since item was not head but is tail
// So there are more than on item in the map
previous.next = undefined;
this._tail = previous;
}
else {
// Both next and previous are not undefined since item was neither head nor tail.
next.previous = previous;
previous.next = next;
}
// Insert the node at head
item.previous = undefined;
item.next = this._head;
this._head.previous = item;
this._head = item;
}
else if (touch === Touch.Last) {
if (item === this._tail) {
return;
}
const next = item.next;
const previous = item.previous;
// Unlink the item.
if (item === this._head) {
// next must be defined since item was not tail but is head
// So there are more than on item in the map
next.previous = undefined;
this._head = next;
}
else {
// Both next and previous are not undefined since item was neither head nor tail.
next.previous = previous;
previous.next = next;
}
item.next = undefined;
item.previous = this._tail;
this._tail.next = item;
this._tail = item;
}
}
}
exports.LinkedMap = LinkedMap;

View File

@@ -0,0 +1,923 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
/// <reference path="./thenable.ts" />
'use strict';
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
const Is = require("./is");
const messages_1 = require("./messages");
exports.RequestType = messages_1.RequestType;
exports.RequestType0 = messages_1.RequestType0;
exports.RequestType1 = messages_1.RequestType1;
exports.RequestType2 = messages_1.RequestType2;
exports.RequestType3 = messages_1.RequestType3;
exports.RequestType4 = messages_1.RequestType4;
exports.RequestType5 = messages_1.RequestType5;
exports.RequestType6 = messages_1.RequestType6;
exports.RequestType7 = messages_1.RequestType7;
exports.RequestType8 = messages_1.RequestType8;
exports.RequestType9 = messages_1.RequestType9;
exports.ResponseError = messages_1.ResponseError;
exports.ErrorCodes = messages_1.ErrorCodes;
exports.NotificationType = messages_1.NotificationType;
exports.NotificationType0 = messages_1.NotificationType0;
exports.NotificationType1 = messages_1.NotificationType1;
exports.NotificationType2 = messages_1.NotificationType2;
exports.NotificationType3 = messages_1.NotificationType3;
exports.NotificationType4 = messages_1.NotificationType4;
exports.NotificationType5 = messages_1.NotificationType5;
exports.NotificationType6 = messages_1.NotificationType6;
exports.NotificationType7 = messages_1.NotificationType7;
exports.NotificationType8 = messages_1.NotificationType8;
exports.NotificationType9 = messages_1.NotificationType9;
const messageReader_1 = require("./messageReader");
exports.MessageReader = messageReader_1.MessageReader;
exports.StreamMessageReader = messageReader_1.StreamMessageReader;
exports.IPCMessageReader = messageReader_1.IPCMessageReader;
exports.SocketMessageReader = messageReader_1.SocketMessageReader;
const messageWriter_1 = require("./messageWriter");
exports.MessageWriter = messageWriter_1.MessageWriter;
exports.StreamMessageWriter = messageWriter_1.StreamMessageWriter;
exports.IPCMessageWriter = messageWriter_1.IPCMessageWriter;
exports.SocketMessageWriter = messageWriter_1.SocketMessageWriter;
const events_1 = require("./events");
exports.Disposable = events_1.Disposable;
exports.Event = events_1.Event;
exports.Emitter = events_1.Emitter;
const cancellation_1 = require("./cancellation");
exports.CancellationTokenSource = cancellation_1.CancellationTokenSource;
exports.CancellationToken = cancellation_1.CancellationToken;
const linkedMap_1 = require("./linkedMap");
__export(require("./pipeSupport"));
__export(require("./socketSupport"));
var CancelNotification;
(function (CancelNotification) {
CancelNotification.type = new messages_1.NotificationType('$/cancelRequest');
})(CancelNotification || (CancelNotification = {}));
exports.NullLogger = Object.freeze({
error: () => { },
warn: () => { },
info: () => { },
log: () => { }
});
var Trace;
(function (Trace) {
Trace[Trace["Off"] = 0] = "Off";
Trace[Trace["Messages"] = 1] = "Messages";
Trace[Trace["Verbose"] = 2] = "Verbose";
})(Trace = exports.Trace || (exports.Trace = {}));
(function (Trace) {
function fromString(value) {
value = value.toLowerCase();
switch (value) {
case 'off':
return Trace.Off;
case 'messages':
return Trace.Messages;
case 'verbose':
return Trace.Verbose;
default:
return Trace.Off;
}
}
Trace.fromString = fromString;
function toString(value) {
switch (value) {
case Trace.Off:
return 'off';
case Trace.Messages:
return 'messages';
case Trace.Verbose:
return 'verbose';
default:
return 'off';
}
}
Trace.toString = toString;
})(Trace = exports.Trace || (exports.Trace = {}));
var TraceFormat;
(function (TraceFormat) {
TraceFormat["Text"] = "text";
TraceFormat["JSON"] = "json";
})(TraceFormat = exports.TraceFormat || (exports.TraceFormat = {}));
(function (TraceFormat) {
function fromString(value) {
value = value.toLowerCase();
if (value === 'json') {
return TraceFormat.JSON;
}
else {
return TraceFormat.Text;
}
}
TraceFormat.fromString = fromString;
})(TraceFormat = exports.TraceFormat || (exports.TraceFormat = {}));
var SetTraceNotification;
(function (SetTraceNotification) {
SetTraceNotification.type = new messages_1.NotificationType('$/setTraceNotification');
})(SetTraceNotification = exports.SetTraceNotification || (exports.SetTraceNotification = {}));
var LogTraceNotification;
(function (LogTraceNotification) {
LogTraceNotification.type = new messages_1.NotificationType('$/logTraceNotification');
})(LogTraceNotification = exports.LogTraceNotification || (exports.LogTraceNotification = {}));
var ConnectionErrors;
(function (ConnectionErrors) {
/**
* The connection is closed.
*/
ConnectionErrors[ConnectionErrors["Closed"] = 1] = "Closed";
/**
* The connection got disposed.
*/
ConnectionErrors[ConnectionErrors["Disposed"] = 2] = "Disposed";
/**
* The connection is already in listening mode.
*/
ConnectionErrors[ConnectionErrors["AlreadyListening"] = 3] = "AlreadyListening";
})(ConnectionErrors = exports.ConnectionErrors || (exports.ConnectionErrors = {}));
class ConnectionError extends Error {
constructor(code, message) {
super(message);
this.code = code;
Object.setPrototypeOf(this, ConnectionError.prototype);
}
}
exports.ConnectionError = ConnectionError;
var ConnectionStrategy;
(function (ConnectionStrategy) {
function is(value) {
let candidate = value;
return candidate && Is.func(candidate.cancelUndispatched);
}
ConnectionStrategy.is = is;
})(ConnectionStrategy = exports.ConnectionStrategy || (exports.ConnectionStrategy = {}));
var ConnectionState;
(function (ConnectionState) {
ConnectionState[ConnectionState["New"] = 1] = "New";
ConnectionState[ConnectionState["Listening"] = 2] = "Listening";
ConnectionState[ConnectionState["Closed"] = 3] = "Closed";
ConnectionState[ConnectionState["Disposed"] = 4] = "Disposed";
})(ConnectionState || (ConnectionState = {}));
function _createMessageConnection(messageReader, messageWriter, logger, strategy) {
let sequenceNumber = 0;
let notificationSquenceNumber = 0;
let unknownResponseSquenceNumber = 0;
const version = '2.0';
let starRequestHandler = undefined;
let requestHandlers = Object.create(null);
let starNotificationHandler = undefined;
let notificationHandlers = Object.create(null);
let timer;
let messageQueue = new linkedMap_1.LinkedMap();
let responsePromises = Object.create(null);
let requestTokens = Object.create(null);
let trace = Trace.Off;
let traceFormat = TraceFormat.Text;
let tracer;
let state = ConnectionState.New;
let errorEmitter = new events_1.Emitter();
let closeEmitter = new events_1.Emitter();
let unhandledNotificationEmitter = new events_1.Emitter();
let disposeEmitter = new events_1.Emitter();
function createRequestQueueKey(id) {
return 'req-' + id.toString();
}
function createResponseQueueKey(id) {
if (id === null) {
return 'res-unknown-' + (++unknownResponseSquenceNumber).toString();
}
else {
return 'res-' + id.toString();
}
}
function createNotificationQueueKey() {
return 'not-' + (++notificationSquenceNumber).toString();
}
function addMessageToQueue(queue, message) {
if (messages_1.isRequestMessage(message)) {
queue.set(createRequestQueueKey(message.id), message);
}
else if (messages_1.isResponseMessage(message)) {
queue.set(createResponseQueueKey(message.id), message);
}
else {
queue.set(createNotificationQueueKey(), message);
}
}
function cancelUndispatched(_message) {
return undefined;
}
function isListening() {
return state === ConnectionState.Listening;
}
function isClosed() {
return state === ConnectionState.Closed;
}
function isDisposed() {
return state === ConnectionState.Disposed;
}
function closeHandler() {
if (state === ConnectionState.New || state === ConnectionState.Listening) {
state = ConnectionState.Closed;
closeEmitter.fire(undefined);
}
// If the connection is disposed don't sent close events.
}
;
function readErrorHandler(error) {
errorEmitter.fire([error, undefined, undefined]);
}
function writeErrorHandler(data) {
errorEmitter.fire(data);
}
messageReader.onClose(closeHandler);
messageReader.onError(readErrorHandler);
messageWriter.onClose(closeHandler);
messageWriter.onError(writeErrorHandler);
function triggerMessageQueue() {
if (timer || messageQueue.size === 0) {
return;
}
timer = setImmediate(() => {
timer = undefined;
processMessageQueue();
});
}
function processMessageQueue() {
if (messageQueue.size === 0) {
return;
}
let message = messageQueue.shift();
try {
if (messages_1.isRequestMessage(message)) {
handleRequest(message);
}
else if (messages_1.isNotificationMessage(message)) {
handleNotification(message);
}
else if (messages_1.isResponseMessage(message)) {
handleResponse(message);
}
else {
handleInvalidMessage(message);
}
}
finally {
triggerMessageQueue();
}
}
let callback = (message) => {
try {
// We have received a cancellation message. Check if the message is still in the queue
// and cancel it if allowed to do so.
if (messages_1.isNotificationMessage(message) && message.method === CancelNotification.type.method) {
let key = createRequestQueueKey(message.params.id);
let toCancel = messageQueue.get(key);
if (messages_1.isRequestMessage(toCancel)) {
let response = strategy && strategy.cancelUndispatched ? strategy.cancelUndispatched(toCancel, cancelUndispatched) : cancelUndispatched(toCancel);
if (response && (response.error !== void 0 || response.result !== void 0)) {
messageQueue.delete(key);
response.id = toCancel.id;
traceSendingResponse(response, message.method, Date.now());
messageWriter.write(response);
return;
}
}
}
addMessageToQueue(messageQueue, message);
}
finally {
triggerMessageQueue();
}
};
function handleRequest(requestMessage) {
if (isDisposed()) {
// we return here silently since we fired an event when the
// connection got disposed.
return;
}
function reply(resultOrError, method, startTime) {
let message = {
jsonrpc: version,
id: requestMessage.id
};
if (resultOrError instanceof messages_1.ResponseError) {
message.error = resultOrError.toJson();
}
else {
message.result = resultOrError === void 0 ? null : resultOrError;
}
traceSendingResponse(message, method, startTime);
messageWriter.write(message);
}
function replyError(error, method, startTime) {
let message = {
jsonrpc: version,
id: requestMessage.id,
error: error.toJson()
};
traceSendingResponse(message, method, startTime);
messageWriter.write(message);
}
function replySuccess(result, method, startTime) {
// The JSON RPC defines that a response must either have a result or an error
// So we can't treat undefined as a valid response result.
if (result === void 0) {
result = null;
}
let message = {
jsonrpc: version,
id: requestMessage.id,
result: result
};
traceSendingResponse(message, method, startTime);
messageWriter.write(message);
}
traceReceivedRequest(requestMessage);
let element = requestHandlers[requestMessage.method];
let type;
let requestHandler;
if (element) {
type = element.type;
requestHandler = element.handler;
}
let startTime = Date.now();
if (requestHandler || starRequestHandler) {
let cancellationSource = new cancellation_1.CancellationTokenSource();
let tokenKey = String(requestMessage.id);
requestTokens[tokenKey] = cancellationSource;
try {
let handlerResult;
if (requestMessage.params === void 0 || (type !== void 0 && type.numberOfParams === 0)) {
handlerResult = requestHandler
? requestHandler(cancellationSource.token)
: starRequestHandler(requestMessage.method, cancellationSource.token);
}
else if (Is.array(requestMessage.params) && (type === void 0 || type.numberOfParams > 1)) {
handlerResult = requestHandler
? requestHandler(...requestMessage.params, cancellationSource.token)
: starRequestHandler(requestMessage.method, ...requestMessage.params, cancellationSource.token);
}
else {
handlerResult = requestHandler
? requestHandler(requestMessage.params, cancellationSource.token)
: starRequestHandler(requestMessage.method, requestMessage.params, cancellationSource.token);
}
let promise = handlerResult;
if (!handlerResult) {
delete requestTokens[tokenKey];
replySuccess(handlerResult, requestMessage.method, startTime);
}
else if (promise.then) {
promise.then((resultOrError) => {
delete requestTokens[tokenKey];
reply(resultOrError, requestMessage.method, startTime);
}, error => {
delete requestTokens[tokenKey];
if (error instanceof messages_1.ResponseError) {
replyError(error, requestMessage.method, startTime);
}
else if (error && Is.string(error.message)) {
replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error.message}`), requestMessage.method, startTime);
}
else {
replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed unexpectedly without providing any details.`), requestMessage.method, startTime);
}
});
}
else {
delete requestTokens[tokenKey];
reply(handlerResult, requestMessage.method, startTime);
}
}
catch (error) {
delete requestTokens[tokenKey];
if (error instanceof messages_1.ResponseError) {
reply(error, requestMessage.method, startTime);
}
else if (error && Is.string(error.message)) {
replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error.message}`), requestMessage.method, startTime);
}
else {
replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed unexpectedly without providing any details.`), requestMessage.method, startTime);
}
}
}
else {
replyError(new messages_1.ResponseError(messages_1.ErrorCodes.MethodNotFound, `Unhandled method ${requestMessage.method}`), requestMessage.method, startTime);
}
}
function handleResponse(responseMessage) {
if (isDisposed()) {
// See handle request.
return;
}
if (responseMessage.id === null) {
if (responseMessage.error) {
logger.error(`Received response message without id: Error is: \n${JSON.stringify(responseMessage.error, undefined, 4)}`);
}
else {
logger.error(`Received response message without id. No further error information provided.`);
}
}
else {
let key = String(responseMessage.id);
let responsePromise = responsePromises[key];
traceReceivedResponse(responseMessage, responsePromise);
if (responsePromise) {
delete responsePromises[key];
try {
if (responseMessage.error) {
let error = responseMessage.error;
responsePromise.reject(new messages_1.ResponseError(error.code, error.message, error.data));
}
else if (responseMessage.result !== void 0) {
responsePromise.resolve(responseMessage.result);
}
else {
throw new Error('Should never happen.');
}
}
catch (error) {
if (error.message) {
logger.error(`Response handler '${responsePromise.method}' failed with message: ${error.message}`);
}
else {
logger.error(`Response handler '${responsePromise.method}' failed unexpectedly.`);
}
}
}
}
}
function handleNotification(message) {
if (isDisposed()) {
// See handle request.
return;
}
let type = undefined;
let notificationHandler;
if (message.method === CancelNotification.type.method) {
notificationHandler = (params) => {
let id = params.id;
let source = requestTokens[String(id)];
if (source) {
source.cancel();
}
};
}
else {
let element = notificationHandlers[message.method];
if (element) {
notificationHandler = element.handler;
type = element.type;
}
}
if (notificationHandler || starNotificationHandler) {
try {
traceReceivedNotification(message);
if (message.params === void 0 || (type !== void 0 && type.numberOfParams === 0)) {
notificationHandler ? notificationHandler() : starNotificationHandler(message.method);
}
else if (Is.array(message.params) && (type === void 0 || type.numberOfParams > 1)) {
notificationHandler ? notificationHandler(...message.params) : starNotificationHandler(message.method, ...message.params);
}
else {
notificationHandler ? notificationHandler(message.params) : starNotificationHandler(message.method, message.params);
}
}
catch (error) {
if (error.message) {
logger.error(`Notification handler '${message.method}' failed with message: ${error.message}`);
}
else {
logger.error(`Notification handler '${message.method}' failed unexpectedly.`);
}
}
}
else {
unhandledNotificationEmitter.fire(message);
}
}
function handleInvalidMessage(message) {
if (!message) {
logger.error('Received empty message.');
return;
}
logger.error(`Received message which is neither a response nor a notification message:\n${JSON.stringify(message, null, 4)}`);
// Test whether we find an id to reject the promise
let responseMessage = message;
if (Is.string(responseMessage.id) || Is.number(responseMessage.id)) {
let key = String(responseMessage.id);
let responseHandler = responsePromises[key];
if (responseHandler) {
responseHandler.reject(new Error('The received response has neither a result nor an error property.'));
}
}
}
function traceSendingRequest(message) {
if (trace === Trace.Off || !tracer) {
return;
}
if (traceFormat === TraceFormat.Text) {
let data = undefined;
if (trace === Trace.Verbose && message.params) {
data = `Params: ${JSON.stringify(message.params, null, 4)}\n\n`;
}
tracer.log(`Sending request '${message.method} - (${message.id})'.`, data);
}
else {
logLSPMessage('send-request', message);
}
}
function traceSendingNotification(message) {
if (trace === Trace.Off || !tracer) {
return;
}
if (traceFormat === TraceFormat.Text) {
let data = undefined;
if (trace === Trace.Verbose) {
if (message.params) {
data = `Params: ${JSON.stringify(message.params, null, 4)}\n\n`;
}
else {
data = 'No parameters provided.\n\n';
}
}
tracer.log(`Sending notification '${message.method}'.`, data);
}
else {
logLSPMessage('send-notification', message);
}
}
function traceSendingResponse(message, method, startTime) {
if (trace === Trace.Off || !tracer) {
return;
}
if (traceFormat === TraceFormat.Text) {
let data = undefined;
if (trace === Trace.Verbose) {
if (message.error && message.error.data) {
data = `Error data: ${JSON.stringify(message.error.data, null, 4)}\n\n`;
}
else {
if (message.result) {
data = `Result: ${JSON.stringify(message.result, null, 4)}\n\n`;
}
else if (message.error === void 0) {
data = 'No result returned.\n\n';
}
}
}
tracer.log(`Sending response '${method} - (${message.id})'. Processing request took ${Date.now() - startTime}ms`, data);
}
else {
logLSPMessage('send-response', message);
}
}
function traceReceivedRequest(message) {
if (trace === Trace.Off || !tracer) {
return;
}
if (traceFormat === TraceFormat.Text) {
let data = undefined;
if (trace === Trace.Verbose && message.params) {
data = `Params: ${JSON.stringify(message.params, null, 4)}\n\n`;
}
tracer.log(`Received request '${message.method} - (${message.id})'.`, data);
}
else {
logLSPMessage('receive-request', message);
}
}
function traceReceivedNotification(message) {
if (trace === Trace.Off || !tracer || message.method === LogTraceNotification.type.method) {
return;
}
if (traceFormat === TraceFormat.Text) {
let data = undefined;
if (trace === Trace.Verbose) {
if (message.params) {
data = `Params: ${JSON.stringify(message.params, null, 4)}\n\n`;
}
else {
data = 'No parameters provided.\n\n';
}
}
tracer.log(`Received notification '${message.method}'.`, data);
}
else {
logLSPMessage('receive-notification', message);
}
}
function traceReceivedResponse(message, responsePromise) {
if (trace === Trace.Off || !tracer) {
return;
}
if (traceFormat === TraceFormat.Text) {
let data = undefined;
if (trace === Trace.Verbose) {
if (message.error && message.error.data) {
data = `Error data: ${JSON.stringify(message.error.data, null, 4)}\n\n`;
}
else {
if (message.result) {
data = `Result: ${JSON.stringify(message.result, null, 4)}\n\n`;
}
else if (message.error === void 0) {
data = 'No result returned.\n\n';
}
}
}
if (responsePromise) {
let error = message.error ? ` Request failed: ${message.error.message} (${message.error.code}).` : '';
tracer.log(`Received response '${responsePromise.method} - (${message.id})' in ${Date.now() - responsePromise.timerStart}ms.${error}`, data);
}
else {
tracer.log(`Received response ${message.id} without active response promise.`, data);
}
}
else {
logLSPMessage('receive-response', message);
}
}
function logLSPMessage(type, message) {
if (!tracer || trace === Trace.Off) {
return;
}
const lspMessage = {
isLSPMessage: true,
type,
message,
timestamp: Date.now()
};
tracer.log(lspMessage);
}
function throwIfClosedOrDisposed() {
if (isClosed()) {
throw new ConnectionError(ConnectionErrors.Closed, 'Connection is closed.');
}
if (isDisposed()) {
throw new ConnectionError(ConnectionErrors.Disposed, 'Connection is disposed.');
}
}
function throwIfListening() {
if (isListening()) {
throw new ConnectionError(ConnectionErrors.AlreadyListening, 'Connection is already listening');
}
}
function throwIfNotListening() {
if (!isListening()) {
throw new Error('Call listen() first.');
}
}
function undefinedToNull(param) {
if (param === void 0) {
return null;
}
else {
return param;
}
}
function computeMessageParams(type, params) {
let result;
let numberOfParams = type.numberOfParams;
switch (numberOfParams) {
case 0:
result = null;
break;
case 1:
result = undefinedToNull(params[0]);
break;
default:
result = [];
for (let i = 0; i < params.length && i < numberOfParams; i++) {
result.push(undefinedToNull(params[i]));
}
if (params.length < numberOfParams) {
for (let i = params.length; i < numberOfParams; i++) {
result.push(null);
}
}
break;
}
return result;
}
let connection = {
sendNotification: (type, ...params) => {
throwIfClosedOrDisposed();
let method;
let messageParams;
if (Is.string(type)) {
method = type;
switch (params.length) {
case 0:
messageParams = null;
break;
case 1:
messageParams = params[0];
break;
default:
messageParams = params;
break;
}
}
else {
method = type.method;
messageParams = computeMessageParams(type, params);
}
let notificationMessage = {
jsonrpc: version,
method: method,
params: messageParams
};
traceSendingNotification(notificationMessage);
messageWriter.write(notificationMessage);
},
onNotification: (type, handler) => {
throwIfClosedOrDisposed();
if (Is.func(type)) {
starNotificationHandler = type;
}
else if (handler) {
if (Is.string(type)) {
notificationHandlers[type] = { type: undefined, handler };
}
else {
notificationHandlers[type.method] = { type, handler };
}
}
},
sendRequest: (type, ...params) => {
throwIfClosedOrDisposed();
throwIfNotListening();
let method;
let messageParams;
let token = undefined;
if (Is.string(type)) {
method = type;
switch (params.length) {
case 0:
messageParams = null;
break;
case 1:
// The cancellation token is optional so it can also be undefined.
if (cancellation_1.CancellationToken.is(params[0])) {
messageParams = null;
token = params[0];
}
else {
messageParams = undefinedToNull(params[0]);
}
break;
default:
const last = params.length - 1;
if (cancellation_1.CancellationToken.is(params[last])) {
token = params[last];
if (params.length === 2) {
messageParams = undefinedToNull(params[0]);
}
else {
messageParams = params.slice(0, last).map(value => undefinedToNull(value));
}
}
else {
messageParams = params.map(value => undefinedToNull(value));
}
break;
}
}
else {
method = type.method;
messageParams = computeMessageParams(type, params);
let numberOfParams = type.numberOfParams;
token = cancellation_1.CancellationToken.is(params[numberOfParams]) ? params[numberOfParams] : undefined;
}
let id = sequenceNumber++;
let result = new Promise((resolve, reject) => {
let requestMessage = {
jsonrpc: version,
id: id,
method: method,
params: messageParams
};
let responsePromise = { method: method, timerStart: Date.now(), resolve, reject };
traceSendingRequest(requestMessage);
try {
messageWriter.write(requestMessage);
}
catch (e) {
// Writing the message failed. So we need to reject the promise.
responsePromise.reject(new messages_1.ResponseError(messages_1.ErrorCodes.MessageWriteError, e.message ? e.message : 'Unknown reason'));
responsePromise = null;
}
if (responsePromise) {
responsePromises[String(id)] = responsePromise;
}
});
if (token) {
token.onCancellationRequested(() => {
connection.sendNotification(CancelNotification.type, { id });
});
}
return result;
},
onRequest: (type, handler) => {
throwIfClosedOrDisposed();
if (Is.func(type)) {
starRequestHandler = type;
}
else if (handler) {
if (Is.string(type)) {
requestHandlers[type] = { type: undefined, handler };
}
else {
requestHandlers[type.method] = { type, handler };
}
}
},
trace: (_value, _tracer, sendNotificationOrTraceOptions) => {
let _sendNotification = false;
let _traceFormat = TraceFormat.Text;
if (sendNotificationOrTraceOptions !== void 0) {
if (Is.boolean(sendNotificationOrTraceOptions)) {
_sendNotification = sendNotificationOrTraceOptions;
}
else {
_sendNotification = sendNotificationOrTraceOptions.sendNotification || false;
_traceFormat = sendNotificationOrTraceOptions.traceFormat || TraceFormat.Text;
}
}
trace = _value;
traceFormat = _traceFormat;
if (trace === Trace.Off) {
tracer = undefined;
}
else {
tracer = _tracer;
}
if (_sendNotification && !isClosed() && !isDisposed()) {
connection.sendNotification(SetTraceNotification.type, { value: Trace.toString(_value) });
}
},
onError: errorEmitter.event,
onClose: closeEmitter.event,
onUnhandledNotification: unhandledNotificationEmitter.event,
onDispose: disposeEmitter.event,
dispose: () => {
if (isDisposed()) {
return;
}
state = ConnectionState.Disposed;
disposeEmitter.fire(undefined);
let error = new Error('Connection got disposed.');
Object.keys(responsePromises).forEach((key) => {
responsePromises[key].reject(error);
});
responsePromises = Object.create(null);
requestTokens = Object.create(null);
messageQueue = new linkedMap_1.LinkedMap();
// Test for backwards compatibility
if (Is.func(messageWriter.dispose)) {
messageWriter.dispose();
}
if (Is.func(messageReader.dispose)) {
messageReader.dispose();
}
},
listen: () => {
throwIfClosedOrDisposed();
throwIfListening();
state = ConnectionState.Listening;
messageReader.listen(callback);
},
inspect: () => {
console.log("inspect");
}
};
connection.onNotification(LogTraceNotification.type, (params) => {
if (trace === Trace.Off || !tracer) {
return;
}
tracer.log(params.message, trace === Trace.Verbose ? params.verbose : undefined);
});
return connection;
}
function isMessageReader(value) {
return value.listen !== void 0 && value.read === void 0;
}
function isMessageWriter(value) {
return value.write !== void 0 && value.end === void 0;
}
function createMessageConnection(input, output, logger, strategy) {
if (!logger) {
logger = exports.NullLogger;
}
let reader = isMessageReader(input) ? input : new messageReader_1.StreamMessageReader(input);
let writer = isMessageWriter(output) ? output : new messageWriter_1.StreamMessageWriter(output);
return _createMessageConnection(reader, writer, logger, strategy);
}
exports.createMessageConnection = createMessageConnection;

View File

@@ -0,0 +1,225 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("./events");
const Is = require("./is");
let DefaultSize = 8192;
let CR = Buffer.from('\r', 'ascii')[0];
let LF = Buffer.from('\n', 'ascii')[0];
let CRLF = '\r\n';
class MessageBuffer {
constructor(encoding = 'utf8') {
this.encoding = encoding;
this.index = 0;
this.buffer = Buffer.allocUnsafe(DefaultSize);
}
append(chunk) {
var toAppend = chunk;
if (typeof (chunk) === 'string') {
var str = chunk;
var bufferLen = Buffer.byteLength(str, this.encoding);
toAppend = Buffer.allocUnsafe(bufferLen);
toAppend.write(str, 0, bufferLen, this.encoding);
}
if (this.buffer.length - this.index >= toAppend.length) {
toAppend.copy(this.buffer, this.index, 0, toAppend.length);
}
else {
var newSize = (Math.ceil((this.index + toAppend.length) / DefaultSize) + 1) * DefaultSize;
if (this.index === 0) {
this.buffer = Buffer.allocUnsafe(newSize);
toAppend.copy(this.buffer, 0, 0, toAppend.length);
}
else {
this.buffer = Buffer.concat([this.buffer.slice(0, this.index), toAppend], newSize);
}
}
this.index += toAppend.length;
}
tryReadHeaders() {
let result = undefined;
let current = 0;
while (current + 3 < this.index && (this.buffer[current] !== CR || this.buffer[current + 1] !== LF || this.buffer[current + 2] !== CR || this.buffer[current + 3] !== LF)) {
current++;
}
// No header / body separator found (e.g CRLFCRLF)
if (current + 3 >= this.index) {
return result;
}
result = Object.create(null);
let headers = this.buffer.toString('ascii', 0, current).split(CRLF);
headers.forEach((header) => {
let index = header.indexOf(':');
if (index === -1) {
throw new Error('Message header must separate key and value using :');
}
let key = header.substr(0, index);
let value = header.substr(index + 1).trim();
result[key] = value;
});
let nextStart = current + 4;
this.buffer = this.buffer.slice(nextStart);
this.index = this.index - nextStart;
return result;
}
tryReadContent(length) {
if (this.index < length) {
return null;
}
let result = this.buffer.toString(this.encoding, 0, length);
let nextStart = length;
this.buffer.copy(this.buffer, 0, nextStart);
this.index = this.index - nextStart;
return result;
}
get numberOfBytes() {
return this.index;
}
}
var MessageReader;
(function (MessageReader) {
function is(value) {
let candidate = value;
return candidate && Is.func(candidate.listen) && Is.func(candidate.dispose) &&
Is.func(candidate.onError) && Is.func(candidate.onClose) && Is.func(candidate.onPartialMessage);
}
MessageReader.is = is;
})(MessageReader = exports.MessageReader || (exports.MessageReader = {}));
class AbstractMessageReader {
constructor() {
this.errorEmitter = new events_1.Emitter();
this.closeEmitter = new events_1.Emitter();
this.partialMessageEmitter = new events_1.Emitter();
}
dispose() {
this.errorEmitter.dispose();
this.closeEmitter.dispose();
}
get onError() {
return this.errorEmitter.event;
}
fireError(error) {
this.errorEmitter.fire(this.asError(error));
}
get onClose() {
return this.closeEmitter.event;
}
fireClose() {
this.closeEmitter.fire(undefined);
}
get onPartialMessage() {
return this.partialMessageEmitter.event;
}
firePartialMessage(info) {
this.partialMessageEmitter.fire(info);
}
asError(error) {
if (error instanceof Error) {
return error;
}
else {
return new Error(`Reader recevied error. Reason: ${Is.string(error.message) ? error.message : 'unknown'}`);
}
}
}
exports.AbstractMessageReader = AbstractMessageReader;
class StreamMessageReader extends AbstractMessageReader {
constructor(readable, encoding = 'utf8') {
super();
this.readable = readable;
this.buffer = new MessageBuffer(encoding);
this._partialMessageTimeout = 10000;
}
set partialMessageTimeout(timeout) {
this._partialMessageTimeout = timeout;
}
get partialMessageTimeout() {
return this._partialMessageTimeout;
}
listen(callback) {
this.nextMessageLength = -1;
this.messageToken = 0;
this.partialMessageTimer = undefined;
this.callback = callback;
this.readable.on('data', (data) => {
this.onData(data);
});
this.readable.on('error', (error) => this.fireError(error));
this.readable.on('close', () => this.fireClose());
}
onData(data) {
this.buffer.append(data);
while (true) {
if (this.nextMessageLength === -1) {
let headers = this.buffer.tryReadHeaders();
if (!headers) {
return;
}
let contentLength = headers['Content-Length'];
if (!contentLength) {
throw new Error('Header must provide a Content-Length property.');
}
let length = parseInt(contentLength);
if (isNaN(length)) {
throw new Error('Content-Length value must be a number.');
}
this.nextMessageLength = length;
// Take the encoding form the header. For compatibility
// treat both utf-8 and utf8 as node utf8
}
var msg = this.buffer.tryReadContent(this.nextMessageLength);
if (msg === null) {
/** We haven't recevied the full message yet. */
this.setPartialMessageTimer();
return;
}
this.clearPartialMessageTimer();
this.nextMessageLength = -1;
this.messageToken++;
var json = JSON.parse(msg);
this.callback(json);
}
}
clearPartialMessageTimer() {
if (this.partialMessageTimer) {
clearTimeout(this.partialMessageTimer);
this.partialMessageTimer = undefined;
}
}
setPartialMessageTimer() {
this.clearPartialMessageTimer();
if (this._partialMessageTimeout <= 0) {
return;
}
this.partialMessageTimer = setTimeout((token, timeout) => {
this.partialMessageTimer = undefined;
if (token === this.messageToken) {
this.firePartialMessage({ messageToken: token, waitingTime: timeout });
this.setPartialMessageTimer();
}
}, this._partialMessageTimeout, this.messageToken, this._partialMessageTimeout);
}
}
exports.StreamMessageReader = StreamMessageReader;
class IPCMessageReader extends AbstractMessageReader {
constructor(process) {
super();
this.process = process;
let eventEmitter = this.process;
eventEmitter.on('error', (error) => this.fireError(error));
eventEmitter.on('close', () => this.fireClose());
}
listen(callback) {
this.process.on('message', callback);
}
}
exports.IPCMessageReader = IPCMessageReader;
class SocketMessageReader extends StreamMessageReader {
constructor(socket, encoding = 'utf-8') {
super(socket, encoding);
}
}
exports.SocketMessageReader = SocketMessageReader;

View File

@@ -0,0 +1,190 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("./events");
const Is = require("./is");
let ContentLength = 'Content-Length: ';
let CRLF = '\r\n';
var MessageWriter;
(function (MessageWriter) {
function is(value) {
let candidate = value;
return candidate && Is.func(candidate.dispose) && Is.func(candidate.onClose) &&
Is.func(candidate.onError) && Is.func(candidate.write);
}
MessageWriter.is = is;
})(MessageWriter = exports.MessageWriter || (exports.MessageWriter = {}));
class AbstractMessageWriter {
constructor() {
this.errorEmitter = new events_1.Emitter();
this.closeEmitter = new events_1.Emitter();
}
dispose() {
this.errorEmitter.dispose();
this.closeEmitter.dispose();
}
get onError() {
return this.errorEmitter.event;
}
fireError(error, message, count) {
this.errorEmitter.fire([this.asError(error), message, count]);
}
get onClose() {
return this.closeEmitter.event;
}
fireClose() {
this.closeEmitter.fire(undefined);
}
asError(error) {
if (error instanceof Error) {
return error;
}
else {
return new Error(`Writer recevied error. Reason: ${Is.string(error.message) ? error.message : 'unknown'}`);
}
}
}
exports.AbstractMessageWriter = AbstractMessageWriter;
class StreamMessageWriter extends AbstractMessageWriter {
constructor(writable, encoding = 'utf8') {
super();
this.writable = writable;
this.encoding = encoding;
this.errorCount = 0;
this.writable.on('error', (error) => this.fireError(error));
this.writable.on('close', () => this.fireClose());
}
write(msg) {
let json = JSON.stringify(msg);
let contentLength = Buffer.byteLength(json, this.encoding);
let headers = [
ContentLength, contentLength.toString(), CRLF,
CRLF
];
try {
// Header must be written in ASCII encoding
this.writable.write(headers.join(''), 'ascii');
// Now write the content. This can be written in any encoding
this.writable.write(json, this.encoding);
this.errorCount = 0;
}
catch (error) {
this.errorCount++;
this.fireError(error, msg, this.errorCount);
}
}
}
exports.StreamMessageWriter = StreamMessageWriter;
class IPCMessageWriter extends AbstractMessageWriter {
constructor(process) {
super();
this.process = process;
this.errorCount = 0;
this.queue = [];
this.sending = false;
let eventEmitter = this.process;
eventEmitter.on('error', (error) => this.fireError(error));
eventEmitter.on('close', () => this.fireClose);
}
write(msg) {
if (!this.sending && this.queue.length === 0) {
// See https://github.com/nodejs/node/issues/7657
this.doWriteMessage(msg);
}
else {
this.queue.push(msg);
}
}
doWriteMessage(msg) {
try {
if (this.process.send) {
this.sending = true;
this.process.send(msg, undefined, undefined, (error) => {
this.sending = false;
if (error) {
this.errorCount++;
this.fireError(error, msg, this.errorCount);
}
else {
this.errorCount = 0;
}
if (this.queue.length > 0) {
this.doWriteMessage(this.queue.shift());
}
});
}
}
catch (error) {
this.errorCount++;
this.fireError(error, msg, this.errorCount);
}
}
}
exports.IPCMessageWriter = IPCMessageWriter;
class SocketMessageWriter extends AbstractMessageWriter {
constructor(socket, encoding = 'utf8') {
super();
this.socket = socket;
this.queue = [];
this.sending = false;
this.encoding = encoding;
this.errorCount = 0;
this.socket.on('error', (error) => this.fireError(error));
this.socket.on('close', () => this.fireClose());
}
write(msg) {
if (!this.sending && this.queue.length === 0) {
// See https://github.com/nodejs/node/issues/7657
this.doWriteMessage(msg);
}
else {
this.queue.push(msg);
}
}
doWriteMessage(msg) {
let json = JSON.stringify(msg);
let contentLength = Buffer.byteLength(json, this.encoding);
let headers = [
ContentLength, contentLength.toString(), CRLF,
CRLF
];
try {
// Header must be written in ASCII encoding
this.sending = true;
this.socket.write(headers.join(''), 'ascii', (error) => {
if (error) {
this.handleError(error, msg);
}
try {
// Now write the content. This can be written in any encoding
this.socket.write(json, this.encoding, (error) => {
this.sending = false;
if (error) {
this.handleError(error, msg);
}
else {
this.errorCount = 0;
}
if (this.queue.length > 0) {
this.doWriteMessage(this.queue.shift());
}
});
}
catch (error) {
this.handleError(error, msg);
}
});
}
catch (error) {
this.handleError(error, msg);
}
}
handleError(error, msg) {
this.errorCount++;
this.fireError(error, msg, this.errorCount);
}
}
exports.SocketMessageWriter = SocketMessageWriter;

View File

@@ -0,0 +1,245 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const is = require("./is");
/**
* Predefined error codes.
*/
var ErrorCodes;
(function (ErrorCodes) {
// Defined by JSON RPC
ErrorCodes.ParseError = -32700;
ErrorCodes.InvalidRequest = -32600;
ErrorCodes.MethodNotFound = -32601;
ErrorCodes.InvalidParams = -32602;
ErrorCodes.InternalError = -32603;
ErrorCodes.serverErrorStart = -32099;
ErrorCodes.serverErrorEnd = -32000;
ErrorCodes.ServerNotInitialized = -32002;
ErrorCodes.UnknownErrorCode = -32001;
// Defined by the protocol.
ErrorCodes.RequestCancelled = -32800;
// Defined by VSCode library.
ErrorCodes.MessageWriteError = 1;
ErrorCodes.MessageReadError = 2;
})(ErrorCodes = exports.ErrorCodes || (exports.ErrorCodes = {}));
/**
* An error object return in a response in case a request
* has failed.
*/
class ResponseError extends Error {
constructor(code, message, data) {
super(message);
this.code = is.number(code) ? code : ErrorCodes.UnknownErrorCode;
this.data = data;
Object.setPrototypeOf(this, ResponseError.prototype);
}
toJson() {
return {
code: this.code,
message: this.message,
data: this.data,
};
}
}
exports.ResponseError = ResponseError;
/**
* An abstract implementation of a MessageType.
*/
class AbstractMessageType {
constructor(_method, _numberOfParams) {
this._method = _method;
this._numberOfParams = _numberOfParams;
}
get method() {
return this._method;
}
get numberOfParams() {
return this._numberOfParams;
}
}
exports.AbstractMessageType = AbstractMessageType;
/**
* Classes to type request response pairs
*/
class RequestType0 extends AbstractMessageType {
constructor(method) {
super(method, 0);
this._ = undefined;
}
}
exports.RequestType0 = RequestType0;
class RequestType extends AbstractMessageType {
constructor(method) {
super(method, 1);
this._ = undefined;
}
}
exports.RequestType = RequestType;
class RequestType1 extends AbstractMessageType {
constructor(method) {
super(method, 1);
this._ = undefined;
}
}
exports.RequestType1 = RequestType1;
class RequestType2 extends AbstractMessageType {
constructor(method) {
super(method, 2);
this._ = undefined;
}
}
exports.RequestType2 = RequestType2;
class RequestType3 extends AbstractMessageType {
constructor(method) {
super(method, 3);
this._ = undefined;
}
}
exports.RequestType3 = RequestType3;
class RequestType4 extends AbstractMessageType {
constructor(method) {
super(method, 4);
this._ = undefined;
}
}
exports.RequestType4 = RequestType4;
class RequestType5 extends AbstractMessageType {
constructor(method) {
super(method, 5);
this._ = undefined;
}
}
exports.RequestType5 = RequestType5;
class RequestType6 extends AbstractMessageType {
constructor(method) {
super(method, 6);
this._ = undefined;
}
}
exports.RequestType6 = RequestType6;
class RequestType7 extends AbstractMessageType {
constructor(method) {
super(method, 7);
this._ = undefined;
}
}
exports.RequestType7 = RequestType7;
class RequestType8 extends AbstractMessageType {
constructor(method) {
super(method, 8);
this._ = undefined;
}
}
exports.RequestType8 = RequestType8;
class RequestType9 extends AbstractMessageType {
constructor(method) {
super(method, 9);
this._ = undefined;
}
}
exports.RequestType9 = RequestType9;
class NotificationType extends AbstractMessageType {
constructor(method) {
super(method, 1);
this._ = undefined;
}
}
exports.NotificationType = NotificationType;
class NotificationType0 extends AbstractMessageType {
constructor(method) {
super(method, 0);
this._ = undefined;
}
}
exports.NotificationType0 = NotificationType0;
class NotificationType1 extends AbstractMessageType {
constructor(method) {
super(method, 1);
this._ = undefined;
}
}
exports.NotificationType1 = NotificationType1;
class NotificationType2 extends AbstractMessageType {
constructor(method) {
super(method, 2);
this._ = undefined;
}
}
exports.NotificationType2 = NotificationType2;
class NotificationType3 extends AbstractMessageType {
constructor(method) {
super(method, 3);
this._ = undefined;
}
}
exports.NotificationType3 = NotificationType3;
class NotificationType4 extends AbstractMessageType {
constructor(method) {
super(method, 4);
this._ = undefined;
}
}
exports.NotificationType4 = NotificationType4;
class NotificationType5 extends AbstractMessageType {
constructor(method) {
super(method, 5);
this._ = undefined;
}
}
exports.NotificationType5 = NotificationType5;
class NotificationType6 extends AbstractMessageType {
constructor(method) {
super(method, 6);
this._ = undefined;
}
}
exports.NotificationType6 = NotificationType6;
class NotificationType7 extends AbstractMessageType {
constructor(method) {
super(method, 7);
this._ = undefined;
}
}
exports.NotificationType7 = NotificationType7;
class NotificationType8 extends AbstractMessageType {
constructor(method) {
super(method, 8);
this._ = undefined;
}
}
exports.NotificationType8 = NotificationType8;
class NotificationType9 extends AbstractMessageType {
constructor(method) {
super(method, 9);
this._ = undefined;
}
}
exports.NotificationType9 = NotificationType9;
/**
* Tests if the given message is a request message
*/
function isRequestMessage(message) {
let candidate = message;
return candidate && is.string(candidate.method) && (is.string(candidate.id) || is.number(candidate.id));
}
exports.isRequestMessage = isRequestMessage;
/**
* Tests if the given message is a notification message
*/
function isNotificationMessage(message) {
let candidate = message;
return candidate && is.string(candidate.method) && message.id === void 0;
}
exports.isNotificationMessage = isNotificationMessage;
/**
* Tests if the given message is a response message
*/
function isResponseMessage(message) {
let candidate = message;
return candidate && (candidate.result !== void 0 || !!candidate.error) && (is.string(candidate.id) || is.number(candidate.id) || candidate.id === null);
}
exports.isResponseMessage = isResponseMessage;

View File

@@ -0,0 +1,54 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = require("path");
const os_1 = require("os");
const crypto_1 = require("crypto");
const net_1 = require("net");
const messageReader_1 = require("./messageReader");
const messageWriter_1 = require("./messageWriter");
function generateRandomPipeName() {
const randomSuffix = crypto_1.randomBytes(21).toString('hex');
if (process.platform === 'win32') {
return `\\\\.\\pipe\\vscode-jsonrpc-${randomSuffix}-sock`;
}
else {
// Mac/Unix: use socket file
return path_1.join(os_1.tmpdir(), `vscode-${randomSuffix}.sock`);
}
}
exports.generateRandomPipeName = generateRandomPipeName;
function createClientPipeTransport(pipeName, encoding = 'utf-8') {
let connectResolve;
let connected = new Promise((resolve, _reject) => {
connectResolve = resolve;
});
return new Promise((resolve, reject) => {
let server = net_1.createServer((socket) => {
server.close();
connectResolve([
new messageReader_1.SocketMessageReader(socket, encoding),
new messageWriter_1.SocketMessageWriter(socket, encoding)
]);
});
server.on('error', reject);
server.listen(pipeName, () => {
server.removeListener('error', reject);
resolve({
onConnected: () => { return connected; }
});
});
});
}
exports.createClientPipeTransport = createClientPipeTransport;
function createServerPipeTransport(pipeName, encoding = 'utf-8') {
const socket = net_1.createConnection(pipeName);
return [
new messageReader_1.SocketMessageReader(socket, encoding),
new messageWriter_1.SocketMessageWriter(socket, encoding)
];
}
exports.createServerPipeTransport = createServerPipeTransport;

View File

@@ -0,0 +1,40 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const net_1 = require("net");
const messageReader_1 = require("./messageReader");
const messageWriter_1 = require("./messageWriter");
function createClientSocketTransport(port, encoding = 'utf-8') {
let connectResolve;
let connected = new Promise((resolve, _reject) => {
connectResolve = resolve;
});
return new Promise((resolve, reject) => {
let server = net_1.createServer((socket) => {
server.close();
connectResolve([
new messageReader_1.SocketMessageReader(socket, encoding),
new messageWriter_1.SocketMessageWriter(socket, encoding)
]);
});
server.on('error', reject);
server.listen(port, '127.0.0.1', () => {
server.removeListener('error', reject);
resolve({
onConnected: () => { return connected; }
});
});
});
}
exports.createClientSocketTransport = createClientSocketTransport;
function createServerSocketTransport(port, encoding = 'utf-8') {
const socket = net_1.createConnection(port, '127.0.0.1');
return [
new messageReader_1.SocketMessageReader(socket, encoding),
new messageWriter_1.SocketMessageWriter(socket, encoding)
];
}
exports.createServerSocketTransport = createServerSocketTransport;

View File

@@ -0,0 +1,28 @@
{
"name": "vscode-jsonrpc",
"description": "A json rpc implementation over streams",
"version": "4.0.0",
"author": "Microsoft Corporation",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/vscode-languageserver-node.git"
},
"bugs": {
"url": "https://github.com/Microsoft/vscode-languageserver-node/issues"
},
"engines": {
"node": ">=8.0.0 || >=10.0.0"
},
"main": "./lib/main.js",
"typings": "./lib/main.d.ts",
"scripts": {
"prepublishOnly": "npm run clean && npm run compile && npm test",
"postpublish": "node ../build/npm/post-publish.js",
"compile": "node ../build/bin/tsc -p ./tsconfig.json",
"watch": "node ../build/bin/tsc -w -p ./tsconfig.json",
"test": "node ../node_modules/mocha/bin/_mocha",
"clean": "node ../node_modules/rimraf/bin.js lib",
"preversion": "npm test"
}
}

View File

@@ -0,0 +1,31 @@
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
For Microsoft vscode-jsonrpc
This project incorporates material from the project(s) listed below (collectively, “Third Party Code”).
Microsoft is not the original author of the Third Party Code. The original copyright notice and license
under which Microsoft received such Third Party Code are set out below. This Third Party Code is licensed
to you under their original license terms set forth below. Microsoft reserves all other rights not expressly
granted, whether by implication, estoppel or otherwise.
1. DefinitelyTyped version 0.0.1 (https://github.com/borisyankov/DefinitelyTyped)
This project is licensed under the MIT license.
Copyrights are respective of each contributor listed at the beginning of each definition file.
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.

View File

@@ -0,0 +1,11 @@
Copyright (c) Microsoft Corporation
All rights reserved.
MIT License
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.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,383 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const code = require("vscode");
const proto = require("vscode-languageserver-protocol");
const Is = require("./utils/is");
const protocolCompletionItem_1 = require("./protocolCompletionItem");
const protocolCodeLens_1 = require("./protocolCodeLens");
const protocolDocumentLink_1 = require("./protocolDocumentLink");
function createConverter(uriConverter) {
const nullConverter = (value) => value.toString();
const _uriConverter = uriConverter || nullConverter;
function asUri(value) {
return _uriConverter(value);
}
function asTextDocumentIdentifier(textDocument) {
return {
uri: _uriConverter(textDocument.uri)
};
}
function asVersionedTextDocumentIdentifier(textDocument) {
return {
uri: _uriConverter(textDocument.uri),
version: textDocument.version
};
}
function asOpenTextDocumentParams(textDocument) {
return {
textDocument: {
uri: _uriConverter(textDocument.uri),
languageId: textDocument.languageId,
version: textDocument.version,
text: textDocument.getText()
}
};
}
function isTextDocumentChangeEvent(value) {
let candidate = value;
return !!candidate.document && !!candidate.contentChanges;
}
function isTextDocument(value) {
let candidate = value;
return !!candidate.uri && !!candidate.version;
}
function asChangeTextDocumentParams(arg) {
if (isTextDocument(arg)) {
let result = {
textDocument: {
uri: _uriConverter(arg.uri),
version: arg.version
},
contentChanges: [{ text: arg.getText() }]
};
return result;
}
else if (isTextDocumentChangeEvent(arg)) {
let document = arg.document;
let result = {
textDocument: {
uri: _uriConverter(document.uri),
version: document.version
},
contentChanges: arg.contentChanges.map((change) => {
let range = change.range;
return {
range: {
start: { line: range.start.line, character: range.start.character },
end: { line: range.end.line, character: range.end.character }
},
rangeLength: change.rangeLength,
text: change.text
};
})
};
return result;
}
else {
throw Error('Unsupported text document change parameter');
}
}
function asCloseTextDocumentParams(textDocument) {
return {
textDocument: asTextDocumentIdentifier(textDocument)
};
}
function asSaveTextDocumentParams(textDocument, includeContent = false) {
let result = {
textDocument: asVersionedTextDocumentIdentifier(textDocument)
};
if (includeContent) {
result.text = textDocument.getText();
}
return result;
}
function asTextDocumentSaveReason(reason) {
switch (reason) {
case code.TextDocumentSaveReason.Manual:
return proto.TextDocumentSaveReason.Manual;
case code.TextDocumentSaveReason.AfterDelay:
return proto.TextDocumentSaveReason.AfterDelay;
case code.TextDocumentSaveReason.FocusOut:
return proto.TextDocumentSaveReason.FocusOut;
}
return proto.TextDocumentSaveReason.Manual;
}
function asWillSaveTextDocumentParams(event) {
return {
textDocument: asTextDocumentIdentifier(event.document),
reason: asTextDocumentSaveReason(event.reason)
};
}
function asTextDocumentPositionParams(textDocument, position) {
return {
textDocument: asTextDocumentIdentifier(textDocument),
position: asWorkerPosition(position)
};
}
function asTriggerKind(triggerKind) {
switch (triggerKind) {
case code.CompletionTriggerKind.TriggerCharacter:
return proto.CompletionTriggerKind.TriggerCharacter;
case code.CompletionTriggerKind.TriggerForIncompleteCompletions:
return proto.CompletionTriggerKind.TriggerForIncompleteCompletions;
default:
return proto.CompletionTriggerKind.Invoked;
}
}
function asCompletionParams(textDocument, position, context) {
return {
textDocument: asTextDocumentIdentifier(textDocument),
position: asWorkerPosition(position),
context: {
triggerKind: asTriggerKind(context.triggerKind),
triggerCharacter: context.triggerCharacter
}
};
}
function asWorkerPosition(position) {
return { line: position.line, character: position.character };
}
function asPosition(value) {
if (value === void 0) {
return undefined;
}
else if (value === null) {
return null;
}
return { line: value.line, character: value.character };
}
function asRange(value) {
if (value === void 0 || value === null) {
return value;
}
return { start: asPosition(value.start), end: asPosition(value.end) };
}
function asDiagnosticSeverity(value) {
switch (value) {
case code.DiagnosticSeverity.Error:
return proto.DiagnosticSeverity.Error;
case code.DiagnosticSeverity.Warning:
return proto.DiagnosticSeverity.Warning;
case code.DiagnosticSeverity.Information:
return proto.DiagnosticSeverity.Information;
case code.DiagnosticSeverity.Hint:
return proto.DiagnosticSeverity.Hint;
}
}
function asDiagnostic(item) {
let result = proto.Diagnostic.create(asRange(item.range), item.message);
if (Is.number(item.severity)) {
result.severity = asDiagnosticSeverity(item.severity);
}
if (Is.number(item.code) || Is.string(item.code)) {
result.code = item.code;
}
if (item.source) {
result.source = item.source;
}
return result;
}
function asDiagnostics(items) {
if (items === void 0 || items === null) {
return items;
}
return items.map(asDiagnostic);
}
function asDocumentation(format, documentation) {
switch (format) {
case '$string':
return documentation;
case proto.MarkupKind.PlainText:
return { kind: format, value: documentation };
case proto.MarkupKind.Markdown:
return { kind: format, value: documentation.value };
default:
return `Unsupported Markup content received. Kind is: ${format}`;
}
}
function asCompletionItemKind(value, original) {
if (original !== void 0) {
return original;
}
return value + 1;
}
function asCompletionItem(item) {
let result = { label: item.label };
let protocolItem = item instanceof protocolCompletionItem_1.default ? item : undefined;
if (item.detail) {
result.detail = item.detail;
}
// We only send items back we created. So this can't be something else than
// a string right now.
if (item.documentation) {
if (!protocolItem || protocolItem.documentationFormat === '$string') {
result.documentation = item.documentation;
}
else {
result.documentation = asDocumentation(protocolItem.documentationFormat, item.documentation);
}
}
if (item.filterText) {
result.filterText = item.filterText;
}
fillPrimaryInsertText(result, item);
if (Is.number(item.kind)) {
result.kind = asCompletionItemKind(item.kind, protocolItem && protocolItem.originalItemKind);
}
if (item.sortText) {
result.sortText = item.sortText;
}
if (item.additionalTextEdits) {
result.additionalTextEdits = asTextEdits(item.additionalTextEdits);
}
if (item.commitCharacters) {
result.commitCharacters = item.commitCharacters.slice();
}
if (item.command) {
result.command = asCommand(item.command);
}
if (item.preselect === true || item.preselect === false) {
result.preselect = item.preselect;
}
if (protocolItem) {
if (protocolItem.data !== void 0) {
result.data = protocolItem.data;
}
if (protocolItem.deprecated === true || protocolItem.deprecated === false) {
result.deprecated = protocolItem.deprecated;
}
}
return result;
}
function fillPrimaryInsertText(target, source) {
let format = proto.InsertTextFormat.PlainText;
let text;
let range = undefined;
if (source.textEdit) {
text = source.textEdit.newText;
range = asRange(source.textEdit.range);
}
else if (source.insertText instanceof code.SnippetString) {
format = proto.InsertTextFormat.Snippet;
text = source.insertText.value;
}
else {
text = source.insertText;
}
if (source.range) {
range = asRange(source.range);
}
target.insertTextFormat = format;
if (source.fromEdit && text && range) {
target.textEdit = { newText: text, range: range };
}
else {
target.insertText = text;
}
}
function asTextEdit(edit) {
return { range: asRange(edit.range), newText: edit.newText };
}
function asTextEdits(edits) {
if (edits === void 0 || edits === null) {
return edits;
}
return edits.map(asTextEdit);
}
function asReferenceParams(textDocument, position, options) {
return {
textDocument: asTextDocumentIdentifier(textDocument),
position: asWorkerPosition(position),
context: { includeDeclaration: options.includeDeclaration }
};
}
function asCodeActionContext(context) {
if (context === void 0 || context === null) {
return context;
}
return proto.CodeActionContext.create(asDiagnostics(context.diagnostics), Is.string(context.only) ? [context.only] : undefined);
}
function asCommand(item) {
let result = proto.Command.create(item.title, item.command);
if (item.arguments) {
result.arguments = item.arguments;
}
return result;
}
function asCodeLens(item) {
let result = proto.CodeLens.create(asRange(item.range));
if (item.command) {
result.command = asCommand(item.command);
}
if (item instanceof protocolCodeLens_1.default) {
if (item.data) {
result.data = item.data;
}
;
}
return result;
}
function asFormattingOptions(item) {
return { tabSize: item.tabSize, insertSpaces: item.insertSpaces };
}
function asDocumentSymbolParams(textDocument) {
return {
textDocument: asTextDocumentIdentifier(textDocument)
};
}
function asCodeLensParams(textDocument) {
return {
textDocument: asTextDocumentIdentifier(textDocument)
};
}
function asDocumentLink(item) {
let result = proto.DocumentLink.create(asRange(item.range));
if (item.target) {
result.target = asUri(item.target);
}
let protocolItem = item instanceof protocolDocumentLink_1.default ? item : undefined;
if (protocolItem && protocolItem.data) {
result.data = protocolItem.data;
}
return result;
}
function asDocumentLinkParams(textDocument) {
return {
textDocument: asTextDocumentIdentifier(textDocument)
};
}
return {
asUri,
asTextDocumentIdentifier,
asVersionedTextDocumentIdentifier,
asOpenTextDocumentParams,
asChangeTextDocumentParams,
asCloseTextDocumentParams,
asSaveTextDocumentParams,
asWillSaveTextDocumentParams,
asTextDocumentPositionParams,
asCompletionParams,
asWorkerPosition,
asRange,
asPosition,
asDiagnosticSeverity,
asDiagnostic,
asDiagnostics,
asCompletionItem,
asTextEdit,
asReferenceParams,
asCodeActionContext,
asCommand,
asCodeLens,
asFormattingOptions,
asDocumentSymbolParams,
asCodeLensParams,
asDocumentLink,
asDocumentLinkParams
};
}
exports.createConverter = createConverter;

View File

@@ -0,0 +1,98 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const UUID = require("./utils/uuid");
const Is = require("./utils/is");
const vscode_1 = require("vscode");
const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
const client_1 = require("./client");
function ensure(target, key) {
if (target[key] === void 0) {
target[key] = {};
}
return target[key];
}
class ColorProviderFeature extends client_1.TextDocumentFeature {
constructor(client) {
super(client, vscode_languageserver_protocol_1.DocumentColorRequest.type);
}
fillClientCapabilities(capabilites) {
ensure(ensure(capabilites, 'textDocument'), 'colorProvider').dynamicRegistration = true;
}
initialize(capabilities, documentSelector) {
if (!capabilities.colorProvider) {
return;
}
const implCapabilities = capabilities.colorProvider;
const id = Is.string(implCapabilities.id) && implCapabilities.id.length > 0 ? implCapabilities.id : UUID.generateUuid();
const selector = implCapabilities.documentSelector || documentSelector;
if (selector) {
this.register(this.messages, {
id,
registerOptions: Object.assign({}, { documentSelector: selector })
});
}
}
registerLanguageProvider(options) {
let client = this._client;
let provideColorPresentations = (color, context, token) => {
const requestParams = {
color,
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(context.document),
range: client.code2ProtocolConverter.asRange(context.range)
};
return client.sendRequest(vscode_languageserver_protocol_1.ColorPresentationRequest.type, requestParams, token).then(this.asColorPresentations.bind(this), (error) => {
client.logFailedRequest(vscode_languageserver_protocol_1.ColorPresentationRequest.type, error);
return Promise.resolve(null);
});
};
let provideDocumentColors = (document, token) => {
const requestParams = {
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document)
};
return client.sendRequest(vscode_languageserver_protocol_1.DocumentColorRequest.type, requestParams, token).then(this.asColorInformations.bind(this), (error) => {
client.logFailedRequest(vscode_languageserver_protocol_1.ColorPresentationRequest.type, error);
return Promise.resolve(null);
});
};
let middleware = client.clientOptions.middleware;
return vscode_1.languages.registerColorProvider(options.documentSelector, {
provideColorPresentations: (color, context, token) => {
return middleware.provideColorPresentations
? middleware.provideColorPresentations(color, context, token, provideColorPresentations)
: provideColorPresentations(color, context, token);
},
provideDocumentColors: (document, token) => {
return middleware.provideDocumentColors
? middleware.provideDocumentColors(document, token, provideDocumentColors)
: provideDocumentColors(document, token);
}
});
}
asColor(color) {
return new vscode_1.Color(color.red, color.green, color.blue, color.alpha);
}
asColorInformations(colorInformation) {
if (Array.isArray(colorInformation)) {
return colorInformation.map(ci => {
return new vscode_1.ColorInformation(this._client.protocol2CodeConverter.asRange(ci.range), this.asColor(ci.color));
});
}
return [];
}
asColorPresentations(colorPresentations) {
if (Array.isArray(colorPresentations)) {
return colorPresentations.map(cp => {
let presentation = new vscode_1.ColorPresentation(cp.label);
presentation.additionalTextEdits = this._client.protocol2CodeConverter.asTextEdits(cp.additionalTextEdits);
presentation.textEdit = this._client.protocol2CodeConverter.asTextEdit(cp.textEdit);
return presentation;
});
}
return [];
}
}
exports.ColorProviderFeature = ColorProviderFeature;

View File

@@ -0,0 +1,63 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_1 = require("vscode");
const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
class ConfigurationFeature {
constructor(_client) {
this._client = _client;
}
fillClientCapabilities(capabilities) {
capabilities.workspace = capabilities.workspace || {};
capabilities.workspace.configuration = true;
}
initialize() {
let client = this._client;
client.onRequest(vscode_languageserver_protocol_1.ConfigurationRequest.type, (params, token) => {
let configuration = (params) => {
let result = [];
for (let item of params.items) {
let resource = item.scopeUri !== void 0 && item.scopeUri !== null ? this._client.protocol2CodeConverter.asUri(item.scopeUri) : undefined;
result.push(this.getConfiguration(resource, item.section !== null ? item.section : undefined));
}
return result;
};
let middleware = client.clientOptions.middleware.workspace;
return middleware && middleware.configuration
? middleware.configuration(params, token, configuration)
: configuration(params, token);
});
}
getConfiguration(resource, section) {
let result = null;
if (section) {
let index = section.lastIndexOf('.');
if (index === -1) {
result = vscode_1.workspace.getConfiguration(undefined, resource).get(section);
}
else {
let config = vscode_1.workspace.getConfiguration(section.substr(0, index));
if (config) {
result = config.get(section.substr(index + 1));
}
}
}
else {
let config = vscode_1.workspace.getConfiguration(undefined, resource);
result = {};
for (let key of Object.keys(config)) {
if (config.has(key)) {
result[key] = config.get(key);
}
}
}
if (!result) {
return null;
}
return result;
}
}
exports.ConfigurationFeature = ConfigurationFeature;

View File

@@ -0,0 +1,70 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const UUID = require("./utils/uuid");
const Is = require("./utils/is");
const vscode_1 = require("vscode");
const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
const client_1 = require("./client");
function ensure(target, key) {
if (target[key] === void 0) {
target[key] = {};
}
return target[key];
}
class DeclarationFeature extends client_1.TextDocumentFeature {
constructor(client) {
super(client, vscode_languageserver_protocol_1.DeclarationRequest.type);
}
fillClientCapabilities(capabilites) {
let declarationSupport = ensure(ensure(capabilites, 'textDocument'), 'declaration');
declarationSupport.dynamicRegistration = true;
declarationSupport.linkSupport = true;
}
initialize(capabilities, documentSelector) {
if (!capabilities.declarationProvider) {
return;
}
if (capabilities.declarationProvider === true) {
if (!documentSelector) {
return;
}
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: Object.assign({}, { documentSelector: documentSelector })
});
}
else {
const declCapabilities = capabilities.declarationProvider;
const id = Is.string(declCapabilities.id) && declCapabilities.id.length > 0 ? declCapabilities.id : UUID.generateUuid();
const selector = declCapabilities.documentSelector || documentSelector;
if (selector) {
this.register(this.messages, {
id,
registerOptions: Object.assign({}, { documentSelector: selector })
});
}
}
}
registerLanguageProvider(options) {
let client = this._client;
let provideDeclaration = (document, position, token) => {
return client.sendRequest(vscode_languageserver_protocol_1.DeclarationRequest.type, client.code2ProtocolConverter.asTextDocumentPositionParams(document, position), token).then(client.protocol2CodeConverter.asDeclarationResult, (error) => {
client.logFailedRequest(vscode_languageserver_protocol_1.DeclarationRequest.type, error);
return Promise.resolve(null);
});
};
let middleware = client.clientOptions.middleware;
return vscode_1.languages.registerDeclarationProvider(options.documentSelector, {
provideDeclaration: (document, position, token) => {
return middleware.provideDeclaration
? middleware.provideDeclaration(document, position, token, provideDeclaration)
: provideDeclaration(document, position, token);
}
});
}
}
exports.DeclarationFeature = DeclarationFeature;

View File

@@ -0,0 +1,84 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const UUID = require("./utils/uuid");
const Is = require("./utils/is");
const vscode_1 = require("vscode");
const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
const client_1 = require("./client");
function ensure(target, key) {
if (target[key] === void 0) {
target[key] = {};
}
return target[key];
}
class FoldingRangeFeature extends client_1.TextDocumentFeature {
constructor(client) {
super(client, vscode_languageserver_protocol_1.FoldingRangeRequest.type);
}
fillClientCapabilities(capabilites) {
let capability = ensure(ensure(capabilites, 'textDocument'), 'foldingRange');
capability.dynamicRegistration = true;
capability.rangeLimit = 5000;
capability.lineFoldingOnly = true;
}
initialize(capabilities, documentSelector) {
if (!capabilities.foldingRangeProvider) {
return;
}
const implCapabilities = capabilities.foldingRangeProvider;
const id = Is.string(implCapabilities.id) && implCapabilities.id.length > 0 ? implCapabilities.id : UUID.generateUuid();
const selector = implCapabilities.documentSelector || documentSelector;
if (selector) {
this.register(this.messages, {
id,
registerOptions: Object.assign({}, { documentSelector: selector })
});
}
}
registerLanguageProvider(options) {
let client = this._client;
let provideFoldingRanges = (document, _, token) => {
const requestParams = {
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document)
};
return client.sendRequest(vscode_languageserver_protocol_1.FoldingRangeRequest.type, requestParams, token).then(this.asFoldingRanges.bind(this), (error) => {
client.logFailedRequest(vscode_languageserver_protocol_1.FoldingRangeRequest.type, error);
return Promise.resolve(null);
});
};
let middleware = client.clientOptions.middleware;
return vscode_1.languages.registerFoldingRangeProvider(options.documentSelector, {
provideFoldingRanges(document, context, token) {
return middleware.provideFoldingRanges
? middleware.provideFoldingRanges(document, context, token, provideFoldingRanges)
: provideFoldingRanges(document, context, token);
}
});
}
asFoldingRangeKind(kind) {
if (kind) {
switch (kind) {
case vscode_languageserver_protocol_1.FoldingRangeKind.Comment:
return vscode_1.FoldingRangeKind.Comment;
case vscode_languageserver_protocol_1.FoldingRangeKind.Imports:
return vscode_1.FoldingRangeKind.Imports;
case vscode_languageserver_protocol_1.FoldingRangeKind.Region:
return vscode_1.FoldingRangeKind.Region;
}
}
return void 0;
}
asFoldingRanges(foldingRanges) {
if (Array.isArray(foldingRanges)) {
return foldingRanges.map(r => {
return new vscode_1.FoldingRange(r.startLine, r.endLine, this.asFoldingRangeKind(r.kind));
});
}
return [];
}
}
exports.FoldingRangeFeature = FoldingRangeFeature;

View File

@@ -0,0 +1,70 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const UUID = require("./utils/uuid");
const Is = require("./utils/is");
const vscode_1 = require("vscode");
const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
const client_1 = require("./client");
function ensure(target, key) {
if (target[key] === void 0) {
target[key] = {};
}
return target[key];
}
class ImplementationFeature extends client_1.TextDocumentFeature {
constructor(client) {
super(client, vscode_languageserver_protocol_1.ImplementationRequest.type);
}
fillClientCapabilities(capabilites) {
let implementationSupport = ensure(ensure(capabilites, 'textDocument'), 'implementation');
implementationSupport.dynamicRegistration = true;
implementationSupport.linkSupport = true;
}
initialize(capabilities, documentSelector) {
if (!capabilities.implementationProvider) {
return;
}
if (capabilities.implementationProvider === true) {
if (!documentSelector) {
return;
}
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: Object.assign({}, { documentSelector: documentSelector })
});
}
else {
const implCapabilities = capabilities.implementationProvider;
const id = Is.string(implCapabilities.id) && implCapabilities.id.length > 0 ? implCapabilities.id : UUID.generateUuid();
const selector = implCapabilities.documentSelector || documentSelector;
if (selector) {
this.register(this.messages, {
id,
registerOptions: Object.assign({}, { documentSelector: selector })
});
}
}
}
registerLanguageProvider(options) {
let client = this._client;
let provideImplementation = (document, position, token) => {
return client.sendRequest(vscode_languageserver_protocol_1.ImplementationRequest.type, client.code2ProtocolConverter.asTextDocumentPositionParams(document, position), token).then(client.protocol2CodeConverter.asDefinitionResult, (error) => {
client.logFailedRequest(vscode_languageserver_protocol_1.ImplementationRequest.type, error);
return Promise.resolve(null);
});
};
let middleware = client.clientOptions.middleware;
return vscode_1.languages.registerImplementationProvider(options.documentSelector, {
provideImplementation: (document, position, token) => {
return middleware.provideImplementation
? middleware.provideImplementation(document, position, token, provideImplementation)
: provideImplementation(document, position, token);
}
});
}
}
exports.ImplementationFeature = ImplementationFeature;

View File

@@ -0,0 +1,446 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
const cp = require("child_process");
const fs = require("fs");
const SemVer = require("semver");
const client_1 = require("./client");
const vscode_1 = require("vscode");
const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
const colorProvider_1 = require("./colorProvider");
const configuration_1 = require("./configuration");
const implementation_1 = require("./implementation");
const typeDefinition_1 = require("./typeDefinition");
const workspaceFolders_1 = require("./workspaceFolders");
const foldingRange_1 = require("./foldingRange");
const declaration_1 = require("./declaration");
const Is = require("./utils/is");
const processes_1 = require("./utils/processes");
__export(require("./client"));
const REQUIRED_VSCODE_VERSION = '^1.30'; // do not change format, updated by `updateVSCode` script
var Executable;
(function (Executable) {
function is(value) {
return Is.string(value.command);
}
Executable.is = is;
})(Executable || (Executable = {}));
var TransportKind;
(function (TransportKind) {
TransportKind[TransportKind["stdio"] = 0] = "stdio";
TransportKind[TransportKind["ipc"] = 1] = "ipc";
TransportKind[TransportKind["pipe"] = 2] = "pipe";
TransportKind[TransportKind["socket"] = 3] = "socket";
})(TransportKind = exports.TransportKind || (exports.TransportKind = {}));
var Transport;
(function (Transport) {
function isSocket(value) {
let candidate = value;
return candidate && candidate.kind === TransportKind.socket && Is.number(candidate.port);
}
Transport.isSocket = isSocket;
})(Transport || (Transport = {}));
var NodeModule;
(function (NodeModule) {
function is(value) {
return Is.string(value.module);
}
NodeModule.is = is;
})(NodeModule || (NodeModule = {}));
var StreamInfo;
(function (StreamInfo) {
function is(value) {
let candidate = value;
return candidate && candidate.writer !== void 0 && candidate.reader !== void 0;
}
StreamInfo.is = is;
})(StreamInfo || (StreamInfo = {}));
var ChildProcessInfo;
(function (ChildProcessInfo) {
function is(value) {
let candidate = value;
return candidate && candidate.process !== void 0 && typeof candidate.detached === 'boolean';
}
ChildProcessInfo.is = is;
})(ChildProcessInfo || (ChildProcessInfo = {}));
class LanguageClient extends client_1.BaseLanguageClient {
constructor(arg1, arg2, arg3, arg4, arg5) {
let id;
let name;
let serverOptions;
let clientOptions;
let forceDebug;
if (Is.string(arg2)) {
id = arg1;
name = arg2;
serverOptions = arg3;
clientOptions = arg4;
forceDebug = !!arg5;
}
else {
id = arg1.toLowerCase();
name = arg1;
serverOptions = arg2;
clientOptions = arg3;
forceDebug = arg4;
}
if (forceDebug === void 0) {
forceDebug = false;
}
super(id, name, clientOptions);
this._serverOptions = serverOptions;
this._forceDebug = forceDebug;
try {
this.checkVersion();
}
catch (error) {
if (Is.string(error.message)) {
this.outputChannel.appendLine(error.message);
}
throw error;
}
}
checkVersion() {
let codeVersion = SemVer.parse(vscode_1.version);
if (!codeVersion) {
throw new Error(`No valid VS Code version detected. Version string is: ${vscode_1.version}`);
}
// Remove the insider pre-release since we stay API compatible.
if (codeVersion.prerelease && codeVersion.prerelease.length > 0) {
codeVersion.prerelease = [];
}
if (!SemVer.satisfies(codeVersion, REQUIRED_VSCODE_VERSION)) {
throw new Error(`The language client requires VS Code version ${REQUIRED_VSCODE_VERSION} but received version ${vscode_1.version}`);
}
}
stop() {
return super.stop().then(() => {
if (this._serverProcess) {
let toCheck = this._serverProcess;
this._serverProcess = undefined;
if (this._isDetached === void 0 || !this._isDetached) {
this.checkProcessDied(toCheck);
}
this._isDetached = undefined;
}
});
}
checkProcessDied(childProcess) {
if (!childProcess) {
return;
}
setTimeout(() => {
// Test if the process is still alive. Throws an exception if not
try {
process.kill(childProcess.pid, 0);
processes_1.terminate(childProcess);
}
catch (error) {
// All is fine.
}
}, 2000);
}
handleConnectionClosed() {
this._serverProcess = undefined;
super.handleConnectionClosed();
}
createMessageTransports(encoding) {
function getEnvironment(env) {
if (!env) {
return process.env;
}
let result = Object.create(null);
Object.keys(process.env).forEach(key => result[key] = process.env[key]);
Object.keys(env).forEach(key => result[key] = env[key]);
return result;
}
function startedInDebugMode() {
let args = process.execArgv;
if (args) {
return args.some((arg) => /^--debug=?/.test(arg) || /^--debug-brk=?/.test(arg) || /^--inspect=?/.test(arg) || /^--inspect-brk=?/.test(arg));
}
;
return false;
}
let server = this._serverOptions;
// We got a function.
if (Is.func(server)) {
return server().then((result) => {
if (client_1.MessageTransports.is(result)) {
this._isDetached = !!result.detached;
return result;
}
else if (StreamInfo.is(result)) {
this._isDetached = !!result.detached;
return { reader: new vscode_languageserver_protocol_1.StreamMessageReader(result.reader), writer: new vscode_languageserver_protocol_1.StreamMessageWriter(result.writer) };
}
else {
let cp;
if (ChildProcessInfo.is(result)) {
cp = result.process;
this._isDetached = result.detached;
}
else {
cp = result;
this._isDetached = false;
}
cp.stderr.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
return { reader: new vscode_languageserver_protocol_1.StreamMessageReader(cp.stdout), writer: new vscode_languageserver_protocol_1.StreamMessageWriter(cp.stdin) };
}
});
}
let json;
let runDebug = server;
if (runDebug.run || runDebug.debug) {
// We are under debugging. So use debug as well.
if (typeof v8debug === 'object' || this._forceDebug || startedInDebugMode()) {
json = runDebug.debug;
}
else {
json = runDebug.run;
}
}
else {
json = server;
}
return this._getServerWorkingDir(json.options).then(serverWorkingDir => {
if (NodeModule.is(json) && json.module) {
let node = json;
let transport = node.transport || TransportKind.stdio;
if (node.runtime) {
let args = [];
let options = node.options || Object.create(null);
if (options.execArgv) {
options.execArgv.forEach(element => args.push(element));
}
args.push(node.module);
if (node.args) {
node.args.forEach(element => args.push(element));
}
let execOptions = Object.create(null);
execOptions.cwd = serverWorkingDir;
execOptions.env = getEnvironment(options.env);
let pipeName = undefined;
if (transport === TransportKind.ipc) {
// exec options not correctly typed in lib
execOptions.stdio = [null, null, null, 'ipc'];
args.push('--node-ipc');
}
else if (transport === TransportKind.stdio) {
args.push('--stdio');
}
else if (transport === TransportKind.pipe) {
pipeName = vscode_languageserver_protocol_1.generateRandomPipeName();
args.push(`--pipe=${pipeName}`);
}
else if (Transport.isSocket(transport)) {
args.push(`--socket=${transport.port}`);
}
args.push(`--clientProcessId=${process.pid.toString()}`);
if (transport === TransportKind.ipc || transport === TransportKind.stdio) {
let serverProcess = cp.spawn(node.runtime, args, execOptions);
if (!serverProcess || !serverProcess.pid) {
return Promise.reject(`Launching server using runtime ${node.runtime} failed.`);
}
this._serverProcess = serverProcess;
serverProcess.stderr.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
if (transport === TransportKind.ipc) {
serverProcess.stdout.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
return Promise.resolve({ reader: new vscode_languageserver_protocol_1.IPCMessageReader(serverProcess), writer: new vscode_languageserver_protocol_1.IPCMessageWriter(serverProcess) });
}
else {
return Promise.resolve({ reader: new vscode_languageserver_protocol_1.StreamMessageReader(serverProcess.stdout), writer: new vscode_languageserver_protocol_1.StreamMessageWriter(serverProcess.stdin) });
}
}
else if (transport == TransportKind.pipe) {
return vscode_languageserver_protocol_1.createClientPipeTransport(pipeName).then((transport) => {
let process = cp.spawn(node.runtime, args, execOptions);
if (!process || !process.pid) {
return Promise.reject(`Launching server using runtime ${node.runtime} failed.`);
}
this._serverProcess = process;
process.stderr.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
process.stdout.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
return transport.onConnected().then((protocol) => {
return { reader: protocol[0], writer: protocol[1] };
});
});
}
else if (Transport.isSocket(transport)) {
return vscode_languageserver_protocol_1.createClientSocketTransport(transport.port).then((transport) => {
let process = cp.spawn(node.runtime, args, execOptions);
if (!process || !process.pid) {
return Promise.reject(`Launching server using runtime ${node.runtime} failed.`);
}
this._serverProcess = process;
process.stderr.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
process.stdout.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
return transport.onConnected().then((protocol) => {
return { reader: protocol[0], writer: protocol[1] };
});
});
}
}
else {
let pipeName = undefined;
return new Promise((resolve, _reject) => {
let args = node.args && node.args.slice() || [];
if (transport === TransportKind.ipc) {
args.push('--node-ipc');
}
else if (transport === TransportKind.stdio) {
args.push('--stdio');
}
else if (transport === TransportKind.pipe) {
pipeName = vscode_languageserver_protocol_1.generateRandomPipeName();
args.push(`--pipe=${pipeName}`);
}
else if (Transport.isSocket(transport)) {
args.push(`--socket=${transport.port}`);
}
args.push(`--clientProcessId=${process.pid.toString()}`);
let options = node.options || Object.create(null);
options.execArgv = options.execArgv || [];
options.cwd = serverWorkingDir;
options.silent = true;
if (transport === TransportKind.ipc || transport === TransportKind.stdio) {
let sp = cp.fork(node.module, args || [], options);
this._serverProcess = sp;
sp.stderr.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
if (transport === TransportKind.ipc) {
sp.stdout.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
resolve({ reader: new vscode_languageserver_protocol_1.IPCMessageReader(this._serverProcess), writer: new vscode_languageserver_protocol_1.IPCMessageWriter(this._serverProcess) });
}
else {
resolve({ reader: new vscode_languageserver_protocol_1.StreamMessageReader(sp.stdout), writer: new vscode_languageserver_protocol_1.StreamMessageWriter(sp.stdin) });
}
}
else if (transport === TransportKind.pipe) {
vscode_languageserver_protocol_1.createClientPipeTransport(pipeName).then((transport) => {
let sp = cp.fork(node.module, args || [], options);
this._serverProcess = sp;
sp.stderr.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
sp.stdout.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
transport.onConnected().then((protocol) => {
resolve({ reader: protocol[0], writer: protocol[1] });
});
});
}
else if (Transport.isSocket(transport)) {
vscode_languageserver_protocol_1.createClientSocketTransport(transport.port).then((transport) => {
let sp = cp.fork(node.module, args || [], options);
this._serverProcess = sp;
sp.stderr.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
sp.stdout.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
transport.onConnected().then((protocol) => {
resolve({ reader: protocol[0], writer: protocol[1] });
});
});
}
});
}
}
else if (Executable.is(json) && json.command) {
let command = json;
let args = command.args || [];
let options = Object.assign({}, command.options);
options.cwd = options.cwd || serverWorkingDir;
let serverProcess = cp.spawn(command.command, args, options);
if (!serverProcess || !serverProcess.pid) {
return Promise.reject(`Launching server using command ${command.command} failed.`);
}
serverProcess.stderr.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
this._serverProcess = serverProcess;
this._isDetached = !!options.detached;
return Promise.resolve({ reader: new vscode_languageserver_protocol_1.StreamMessageReader(serverProcess.stdout), writer: new vscode_languageserver_protocol_1.StreamMessageWriter(serverProcess.stdin) });
}
return Promise.reject(new Error(`Unsupported server configuration ` + JSON.stringify(server, null, 4)));
});
}
registerProposedFeatures() {
this.registerFeatures(ProposedFeatures.createAll(this));
}
registerBuiltinFeatures() {
super.registerBuiltinFeatures();
this.registerFeature(new configuration_1.ConfigurationFeature(this));
this.registerFeature(new typeDefinition_1.TypeDefinitionFeature(this));
this.registerFeature(new implementation_1.ImplementationFeature(this));
this.registerFeature(new colorProvider_1.ColorProviderFeature(this));
this.registerFeature(new workspaceFolders_1.WorkspaceFoldersFeature(this));
this.registerFeature(new foldingRange_1.FoldingRangeFeature(this));
this.registerFeature(new declaration_1.DeclarationFeature(this));
}
_mainGetRootPath() {
let folders = vscode_1.workspace.workspaceFolders;
if (!folders || folders.length === 0) {
return undefined;
}
let folder = folders[0];
if (folder.uri.scheme === 'file') {
return folder.uri.fsPath;
}
return undefined;
}
_getServerWorkingDir(options) {
let cwd = options && options.cwd;
if (!cwd) {
cwd = this.clientOptions.workspaceFolder
? this.clientOptions.workspaceFolder.uri.fsPath
: this._mainGetRootPath();
}
if (cwd) {
// make sure the folder exists otherwise creating the process will fail
return new Promise(s => {
fs.lstat(cwd, (err, stats) => {
s(!err && stats.isDirectory() ? cwd : undefined);
});
});
}
return Promise.resolve(undefined);
}
}
exports.LanguageClient = LanguageClient;
class SettingMonitor {
constructor(_client, _setting) {
this._client = _client;
this._setting = _setting;
this._listeners = [];
}
start() {
vscode_1.workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this._listeners);
this.onDidChangeConfiguration();
return new vscode_1.Disposable(() => {
if (this._client.needsStop()) {
this._client.stop();
}
});
}
onDidChangeConfiguration() {
let index = this._setting.indexOf('.');
let primary = index >= 0 ? this._setting.substr(0, index) : this._setting;
let rest = index >= 0 ? this._setting.substr(index + 1) : undefined;
let enabled = rest ? vscode_1.workspace.getConfiguration(primary).get(rest, false) : vscode_1.workspace.getConfiguration(primary);
if (enabled && this._client.needsStart()) {
this._client.start();
}
else if (!enabled && this._client.needsStop()) {
this._client.stop();
}
}
}
exports.SettingMonitor = SettingMonitor;
// Exporting proposed protocol.
var ProposedFeatures;
(function (ProposedFeatures) {
function createAll(_client) {
let result = [];
return result;
}
ProposedFeatures.createAll = createAll;
})(ProposedFeatures = exports.ProposedFeatures || (exports.ProposedFeatures = {}));

View File

@@ -0,0 +1,13 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const code = require("vscode");
class ProtocolCodeLens extends code.CodeLens {
constructor(range) {
super(range);
}
}
exports.default = ProtocolCodeLens;

View File

@@ -0,0 +1,13 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const code = require("vscode");
class ProtocolCompletionItem extends code.CompletionItem {
constructor(label) {
super(label);
}
}
exports.default = ProtocolCompletionItem;

View File

@@ -0,0 +1,630 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const code = require("vscode");
const ls = require("vscode-languageserver-protocol");
const Is = require("./utils/is");
const protocolCompletionItem_1 = require("./protocolCompletionItem");
const protocolCodeLens_1 = require("./protocolCodeLens");
const protocolDocumentLink_1 = require("./protocolDocumentLink");
var CodeBlock;
(function (CodeBlock) {
function is(value) {
let candidate = value;
return candidate && Is.string(candidate.language) && Is.string(candidate.value);
}
CodeBlock.is = is;
})(CodeBlock || (CodeBlock = {}));
function createConverter(uriConverter) {
const nullConverter = (value) => code.Uri.parse(value);
const _uriConverter = uriConverter || nullConverter;
function asUri(value) {
return _uriConverter(value);
}
function asDiagnostics(diagnostics) {
return diagnostics.map(asDiagnostic);
}
function asDiagnostic(diagnostic) {
let result = new code.Diagnostic(asRange(diagnostic.range), diagnostic.message, asDiagnosticSeverity(diagnostic.severity));
if (Is.number(diagnostic.code) || Is.string(diagnostic.code)) {
result.code = diagnostic.code;
}
if (diagnostic.source) {
result.source = diagnostic.source;
}
if (diagnostic.relatedInformation) {
result.relatedInformation = asRelatedInformation(diagnostic.relatedInformation);
}
return result;
}
function asRelatedInformation(relatedInformation) {
return relatedInformation.map(asDiagnosticRelatedInformation);
}
function asDiagnosticRelatedInformation(information) {
return new code.DiagnosticRelatedInformation(asLocation(information.location), information.message);
}
function asPosition(value) {
if (!value) {
return undefined;
}
return new code.Position(value.line, value.character);
}
function asRange(value) {
if (!value) {
return undefined;
}
return new code.Range(asPosition(value.start), asPosition(value.end));
}
function asDiagnosticSeverity(value) {
if (value === void 0 || value === null) {
return code.DiagnosticSeverity.Error;
}
switch (value) {
case ls.DiagnosticSeverity.Error:
return code.DiagnosticSeverity.Error;
case ls.DiagnosticSeverity.Warning:
return code.DiagnosticSeverity.Warning;
case ls.DiagnosticSeverity.Information:
return code.DiagnosticSeverity.Information;
case ls.DiagnosticSeverity.Hint:
return code.DiagnosticSeverity.Hint;
}
return code.DiagnosticSeverity.Error;
}
function asHoverContent(value) {
if (Is.string(value)) {
return new code.MarkdownString(value);
}
else if (CodeBlock.is(value)) {
let result = new code.MarkdownString();
return result.appendCodeblock(value.value, value.language);
}
else if (Array.isArray(value)) {
let result = [];
for (let element of value) {
let item = new code.MarkdownString();
if (CodeBlock.is(element)) {
item.appendCodeblock(element.value, element.language);
}
else {
item.appendMarkdown(element);
}
result.push(item);
}
return result;
}
else {
let result;
switch (value.kind) {
case ls.MarkupKind.Markdown:
return new code.MarkdownString(value.value);
case ls.MarkupKind.PlainText:
result = new code.MarkdownString();
result.appendText(value.value);
return result;
default:
result = new code.MarkdownString();
result.appendText(`Unsupported Markup content received. Kind is: ${value.kind}`);
return result;
}
}
}
function asDocumentation(value) {
if (Is.string(value)) {
return value;
}
else {
switch (value.kind) {
case ls.MarkupKind.Markdown:
return new code.MarkdownString(value.value);
case ls.MarkupKind.PlainText:
return value.value;
default:
return `Unsupported Markup content received. Kind is: ${value.kind}`;
}
}
}
function asHover(hover) {
if (!hover) {
return undefined;
}
return new code.Hover(asHoverContent(hover.contents), asRange(hover.range));
}
function asCompletionResult(result) {
if (!result) {
return undefined;
}
if (Array.isArray(result)) {
let items = result;
return items.map(asCompletionItem);
}
let list = result;
return new code.CompletionList(list.items.map(asCompletionItem), list.isIncomplete);
}
function asCompletionItemKind(value) {
// Protocol item kind is 1 based, codes item kind is zero based.
if (ls.CompletionItemKind.Text <= value && value <= ls.CompletionItemKind.TypeParameter) {
return [value - 1, undefined];
}
;
return [code.CompletionItemKind.Text, value];
}
function asCompletionItem(item) {
let result = new protocolCompletionItem_1.default(item.label);
if (item.detail) {
result.detail = item.detail;
}
if (item.documentation) {
result.documentation = asDocumentation(item.documentation);
result.documentationFormat = Is.string(item.documentation) ? '$string' : item.documentation.kind;
}
;
if (item.filterText) {
result.filterText = item.filterText;
}
let insertText = asCompletionInsertText(item);
if (insertText) {
result.insertText = insertText.text;
result.range = insertText.range;
result.fromEdit = insertText.fromEdit;
}
if (Is.number(item.kind)) {
let [itemKind, original] = asCompletionItemKind(item.kind);
result.kind = itemKind;
if (original) {
result.originalItemKind = original;
}
}
if (item.sortText) {
result.sortText = item.sortText;
}
if (item.additionalTextEdits) {
result.additionalTextEdits = asTextEdits(item.additionalTextEdits);
}
if (Is.stringArray(item.commitCharacters)) {
result.commitCharacters = item.commitCharacters.slice();
}
if (item.command) {
result.command = asCommand(item.command);
}
if (item.deprecated === true || item.deprecated === false) {
result.deprecated = item.deprecated;
}
if (item.preselect === true || item.preselect === false) {
result.preselect = item.preselect;
}
if (item.data !== void 0) {
result.data = item.data;
}
return result;
}
function asCompletionInsertText(item) {
if (item.textEdit) {
if (item.insertTextFormat === ls.InsertTextFormat.Snippet) {
return { text: new code.SnippetString(item.textEdit.newText), range: asRange(item.textEdit.range), fromEdit: true };
}
else {
return { text: item.textEdit.newText, range: asRange(item.textEdit.range), fromEdit: true };
}
}
else if (item.insertText) {
if (item.insertTextFormat === ls.InsertTextFormat.Snippet) {
return { text: new code.SnippetString(item.insertText), fromEdit: false };
}
else {
return { text: item.insertText, fromEdit: false };
}
}
else {
return undefined;
}
}
function asTextEdit(edit) {
if (!edit) {
return undefined;
}
return new code.TextEdit(asRange(edit.range), edit.newText);
}
function asTextEdits(items) {
if (!items) {
return undefined;
}
return items.map(asTextEdit);
}
function asSignatureHelp(item) {
if (!item) {
return undefined;
}
let result = new code.SignatureHelp();
if (Is.number(item.activeSignature)) {
result.activeSignature = item.activeSignature;
}
else {
// activeSignature was optional in the past
result.activeSignature = 0;
}
if (Is.number(item.activeParameter)) {
result.activeParameter = item.activeParameter;
}
else {
// activeParameter was optional in the past
result.activeParameter = 0;
}
if (item.signatures) {
result.signatures = asSignatureInformations(item.signatures);
}
return result;
}
function asSignatureInformations(items) {
return items.map(asSignatureInformation);
}
function asSignatureInformation(item) {
let result = new code.SignatureInformation(item.label);
if (item.documentation) {
result.documentation = asDocumentation(item.documentation);
}
if (item.parameters) {
result.parameters = asParameterInformations(item.parameters);
}
return result;
}
function asParameterInformations(item) {
return item.map(asParameterInformation);
}
function asParameterInformation(item) {
let result = new code.ParameterInformation(item.label);
if (item.documentation) {
result.documentation = asDocumentation(item.documentation);
}
;
return result;
}
function asLocation(item) {
if (!item) {
return undefined;
}
return new code.Location(_uriConverter(item.uri), asRange(item.range));
}
function asDeclarationResult(item) {
if (!item) {
return undefined;
}
return asLocationResult(item);
}
function asDefinitionResult(item) {
if (!item) {
return undefined;
}
return asLocationResult(item);
}
function asLocationLink(item) {
if (!item) {
return undefined;
}
return {
targetUri: _uriConverter(item.targetUri),
targetRange: asRange(item.targetSelectionRange),
originSelectionRange: asRange(item.originSelectionRange),
targetSelectionRange: asRange(item.targetSelectionRange)
};
}
function asLocationResult(item) {
if (!item) {
return undefined;
}
if (Is.array(item)) {
if (item.length === 0) {
return [];
}
else if (ls.LocationLink.is(item[0])) {
let links = item;
return links.map((link) => asLocationLink(link));
}
else {
let locations = item;
return locations.map((location) => asLocation(location));
}
}
else if (ls.LocationLink.is(item)) {
return [asLocationLink(item)];
}
else {
return asLocation(item);
}
}
function asReferences(values) {
if (!values) {
return undefined;
}
return values.map(location => asLocation(location));
}
function asDocumentHighlights(values) {
if (!values) {
return undefined;
}
return values.map(asDocumentHighlight);
}
function asDocumentHighlight(item) {
let result = new code.DocumentHighlight(asRange(item.range));
if (Is.number(item.kind)) {
result.kind = asDocumentHighlightKind(item.kind);
}
return result;
}
function asDocumentHighlightKind(item) {
switch (item) {
case ls.DocumentHighlightKind.Text:
return code.DocumentHighlightKind.Text;
case ls.DocumentHighlightKind.Read:
return code.DocumentHighlightKind.Read;
case ls.DocumentHighlightKind.Write:
return code.DocumentHighlightKind.Write;
}
return code.DocumentHighlightKind.Text;
}
function asSymbolInformations(values, uri) {
if (!values) {
return undefined;
}
return values.map(information => asSymbolInformation(information, uri));
}
function asSymbolKind(item) {
if (item <= ls.SymbolKind.TypeParameter) {
// Symbol kind is one based in the protocol and zero based in code.
return item - 1;
}
return code.SymbolKind.Property;
}
function asSymbolInformation(item, uri) {
// Symbol kind is one based in the protocol and zero based in code.
let result = new code.SymbolInformation(item.name, asSymbolKind(item.kind), asRange(item.location.range), item.location.uri ? _uriConverter(item.location.uri) : uri);
if (item.containerName) {
result.containerName = item.containerName;
}
return result;
}
function asDocumentSymbols(values) {
if (values === void 0 || values === null) {
return undefined;
}
return values.map(asDocumentSymbol);
}
function asDocumentSymbol(value) {
let result = new code.DocumentSymbol(value.name, value.detail || '', asSymbolKind(value.kind), asRange(value.range), asRange(value.selectionRange));
if (value.children !== void 0 && value.children.length > 0) {
let children = [];
for (let child of value.children) {
children.push(asDocumentSymbol(child));
}
result.children = children;
}
return result;
}
function asCommand(item) {
let result = { title: item.title, command: item.command };
if (item.arguments) {
result.arguments = item.arguments;
}
return result;
}
function asCommands(items) {
if (!items) {
return undefined;
}
return items.map(asCommand);
}
const kindMapping = new Map();
kindMapping.set('', code.CodeActionKind.Empty);
kindMapping.set(ls.CodeActionKind.QuickFix, code.CodeActionKind.QuickFix);
kindMapping.set(ls.CodeActionKind.Refactor, code.CodeActionKind.Refactor);
kindMapping.set(ls.CodeActionKind.RefactorExtract, code.CodeActionKind.RefactorExtract);
kindMapping.set(ls.CodeActionKind.RefactorInline, code.CodeActionKind.RefactorInline);
kindMapping.set(ls.CodeActionKind.RefactorRewrite, code.CodeActionKind.RefactorRewrite);
kindMapping.set(ls.CodeActionKind.Source, code.CodeActionKind.Source);
kindMapping.set(ls.CodeActionKind.SourceOrganizeImports, code.CodeActionKind.SourceOrganizeImports);
function asCodeActionKind(item) {
if (item === void 0 || item === null) {
return undefined;
}
let result = kindMapping.get(item);
if (result) {
return result;
}
let parts = item.split('.');
result = code.CodeActionKind.Empty;
for (let part of parts) {
result = result.append(part);
}
return result;
}
function asCodeActionKinds(items) {
if (items === void 0 || items === null) {
return undefined;
}
return items.map(kind => asCodeActionKind(kind));
}
function asCodeAction(item) {
if (item === void 0 || item === null) {
return undefined;
}
let result = new code.CodeAction(item.title);
if (item.kind !== void 0) {
result.kind = asCodeActionKind(item.kind);
}
if (item.diagnostics) {
result.diagnostics = asDiagnostics(item.diagnostics);
}
if (item.edit) {
result.edit = asWorkspaceEdit(item.edit);
}
if (item.command) {
result.command = asCommand(item.command);
}
return result;
}
function asCodeLens(item) {
if (!item) {
return undefined;
}
let result = new protocolCodeLens_1.default(asRange(item.range));
if (item.command) {
result.command = asCommand(item.command);
}
if (item.data !== void 0 && item.data !== null) {
result.data = item.data;
}
return result;
}
function asCodeLenses(items) {
if (!items) {
return undefined;
}
return items.map((codeLens) => asCodeLens(codeLens));
}
function asWorkspaceEdit(item) {
if (!item) {
return undefined;
}
let result = new code.WorkspaceEdit();
if (item.documentChanges) {
item.documentChanges.forEach(change => {
if (ls.CreateFile.is(change)) {
result.createFile(_uriConverter(change.uri), change.options);
}
else if (ls.RenameFile.is(change)) {
result.renameFile(_uriConverter(change.oldUri), _uriConverter(change.newUri), change.options);
}
else if (ls.DeleteFile.is(change)) {
result.deleteFile(_uriConverter(change.uri), change.options);
}
else if (ls.TextDocumentEdit.is(change)) {
result.set(_uriConverter(change.textDocument.uri), asTextEdits(change.edits));
}
else {
console.error(`Unknown workspace edit change received:\n${JSON.stringify(change, undefined, 4)}`);
}
});
}
else if (item.changes) {
Object.keys(item.changes).forEach(key => {
result.set(_uriConverter(key), asTextEdits(item.changes[key]));
});
}
return result;
}
function asDocumentLink(item) {
let range = asRange(item.range);
let target = item.target ? asUri(item.target) : undefined;
// target must be optional in DocumentLink
let link = new protocolDocumentLink_1.default(range, target);
if (item.data !== void 0 && item.data !== null) {
link.data = item.data;
}
return link;
}
function asDocumentLinks(items) {
if (!items) {
return undefined;
}
return items.map(asDocumentLink);
}
function asColor(color) {
return new code.Color(color.red, color.green, color.blue, color.alpha);
}
function asColorInformation(ci) {
return new code.ColorInformation(asRange(ci.range), asColor(ci.color));
}
function asColorInformations(colorInformation) {
if (Array.isArray(colorInformation)) {
return colorInformation.map(asColorInformation);
}
return undefined;
}
function asColorPresentation(cp) {
let presentation = new code.ColorPresentation(cp.label);
presentation.additionalTextEdits = asTextEdits(cp.additionalTextEdits);
if (cp.textEdit) {
presentation.textEdit = asTextEdit(cp.textEdit);
}
return presentation;
}
function asColorPresentations(colorPresentations) {
if (Array.isArray(colorPresentations)) {
return colorPresentations.map(asColorPresentation);
}
return undefined;
}
function asFoldingRangeKind(kind) {
if (kind) {
switch (kind) {
case ls.FoldingRangeKind.Comment:
return code.FoldingRangeKind.Comment;
case ls.FoldingRangeKind.Imports:
return code.FoldingRangeKind.Imports;
case ls.FoldingRangeKind.Region:
return code.FoldingRangeKind.Region;
}
}
return void 0;
}
function asFoldingRange(r) {
return new code.FoldingRange(r.startLine, r.endLine, asFoldingRangeKind(r.kind));
}
function asFoldingRanges(foldingRanges) {
if (Array.isArray(foldingRanges)) {
return foldingRanges.map(asFoldingRange);
}
return void 0;
}
return {
asUri,
asDiagnostics,
asDiagnostic,
asRange,
asPosition,
asDiagnosticSeverity,
asHover,
asCompletionResult,
asCompletionItem,
asTextEdit,
asTextEdits,
asSignatureHelp,
asSignatureInformations,
asSignatureInformation,
asParameterInformations,
asParameterInformation,
asDeclarationResult,
asDefinitionResult,
asLocation,
asReferences,
asDocumentHighlights,
asDocumentHighlight,
asDocumentHighlightKind,
asSymbolInformations,
asSymbolInformation,
asDocumentSymbols,
asDocumentSymbol,
asCommand,
asCommands,
asCodeAction,
asCodeActionKind,
asCodeActionKinds,
asCodeLens,
asCodeLenses,
asWorkspaceEdit,
asDocumentLink,
asDocumentLinks,
asFoldingRangeKind,
asFoldingRange,
asFoldingRanges,
asColor,
asColorInformation,
asColorInformations,
asColorPresentation,
asColorPresentations
};
}
exports.createConverter = createConverter;

View File

@@ -0,0 +1,13 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const code = require("vscode");
class ProtocolDocumentLink extends code.DocumentLink {
constructor(range, target) {
super(range, target);
}
}
exports.default = ProtocolDocumentLink;

View File

@@ -0,0 +1,71 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const UUID = require("./utils/uuid");
const Is = require("./utils/is");
const vscode_1 = require("vscode");
const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
const client_1 = require("./client");
function ensure(target, key) {
if (target[key] === void 0) {
target[key] = {};
}
return target[key];
}
class TypeDefinitionFeature extends client_1.TextDocumentFeature {
constructor(client) {
super(client, vscode_languageserver_protocol_1.TypeDefinitionRequest.type);
}
fillClientCapabilities(capabilites) {
ensure(ensure(capabilites, 'textDocument'), 'typeDefinition').dynamicRegistration = true;
let typeDefinitionSupport = ensure(ensure(capabilites, 'textDocument'), 'typeDefinition');
typeDefinitionSupport.dynamicRegistration = true;
typeDefinitionSupport.linkSupport = true;
}
initialize(capabilities, documentSelector) {
if (!capabilities.typeDefinitionProvider) {
return;
}
if (capabilities.typeDefinitionProvider === true) {
if (!documentSelector) {
return;
}
this.register(this.messages, {
id: UUID.generateUuid(),
registerOptions: Object.assign({}, { documentSelector: documentSelector })
});
}
else {
const implCapabilities = capabilities.typeDefinitionProvider;
const id = Is.string(implCapabilities.id) && implCapabilities.id.length > 0 ? implCapabilities.id : UUID.generateUuid();
const selector = implCapabilities.documentSelector || documentSelector;
if (selector) {
this.register(this.messages, {
id,
registerOptions: Object.assign({}, { documentSelector: selector })
});
}
}
}
registerLanguageProvider(options) {
let client = this._client;
let provideTypeDefinition = (document, position, token) => {
return client.sendRequest(vscode_languageserver_protocol_1.TypeDefinitionRequest.type, client.code2ProtocolConverter.asTextDocumentPositionParams(document, position), token).then(client.protocol2CodeConverter.asDefinitionResult, (error) => {
client.logFailedRequest(vscode_languageserver_protocol_1.TypeDefinitionRequest.type, error);
return Promise.resolve(null);
});
};
let middleware = client.clientOptions.middleware;
return vscode_1.languages.registerTypeDefinitionProvider(options.documentSelector, {
provideTypeDefinition: (document, position, token) => {
return middleware.provideTypeDefinition
? middleware.provideTypeDefinition(document, position, token, provideTypeDefinition)
: provideTypeDefinition(document, position, token);
}
});
}
}
exports.TypeDefinitionFeature = TypeDefinitionFeature;

View File

@@ -0,0 +1,64 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
class Delayer {
constructor(defaultDelay) {
this.defaultDelay = defaultDelay;
this.timeout = undefined;
this.completionPromise = undefined;
this.onSuccess = undefined;
this.task = undefined;
}
trigger(task, delay = this.defaultDelay) {
this.task = task;
if (delay >= 0) {
this.cancelTimeout();
}
if (!this.completionPromise) {
this.completionPromise = new Promise((resolve) => {
this.onSuccess = resolve;
}).then(() => {
this.completionPromise = undefined;
this.onSuccess = undefined;
var result = this.task();
this.task = undefined;
return result;
});
}
if (delay >= 0 || this.timeout === void 0) {
this.timeout = setTimeout(() => {
this.timeout = undefined;
this.onSuccess(undefined);
}, delay >= 0 ? delay : this.defaultDelay);
}
return this.completionPromise;
}
forceDelivery() {
if (!this.completionPromise) {
return undefined;
}
this.cancelTimeout();
let result = this.task();
this.completionPromise = undefined;
this.onSuccess = undefined;
this.task = undefined;
return result;
}
isTriggered() {
return this.timeout !== void 0;
}
cancel() {
this.cancelTimeout();
this.completionPromise = undefined;
}
cancelTimeout() {
if (this.timeout !== void 0) {
clearTimeout(this.timeout);
this.timeout = undefined;
}
}
}
exports.Delayer = Delayer;

View File

@@ -0,0 +1,42 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
function boolean(value) {
return value === true || value === false;
}
exports.boolean = boolean;
function string(value) {
return typeof value === 'string' || value instanceof String;
}
exports.string = string;
function number(value) {
return typeof value === 'number' || value instanceof Number;
}
exports.number = number;
function error(value) {
return value instanceof Error;
}
exports.error = error;
function func(value) {
return typeof value === 'function';
}
exports.func = func;
function array(value) {
return Array.isArray(value);
}
exports.array = array;
function stringArray(value) {
return array(value) && value.every(elem => string(elem));
}
exports.stringArray = stringArray;
function typedArray(value, check) {
return Array.isArray(value) && value.every(check);
}
exports.typedArray = typedArray;
function thenable(value) {
return value && func(value.then);
}
exports.thenable = thenable;

View File

@@ -0,0 +1,46 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const cp = require("child_process");
const path_1 = require("path");
const isWindows = (process.platform === 'win32');
const isMacintosh = (process.platform === 'darwin');
const isLinux = (process.platform === 'linux');
function terminate(process, cwd) {
if (isWindows) {
try {
// This we run in Atom execFileSync is available.
// Ignore stderr since this is otherwise piped to parent.stderr
// which might be already closed.
let options = {
stdio: ['pipe', 'pipe', 'ignore']
};
if (cwd) {
options.cwd = cwd;
}
cp.execFileSync('taskkill', ['/T', '/F', '/PID', process.pid.toString()], options);
return true;
}
catch (err) {
return false;
}
}
else if (isLinux || isMacintosh) {
try {
var cmd = path_1.join(__dirname, 'terminateProcess.sh');
var result = cp.spawnSync(cmd, [process.pid.toString()]);
return result.error ? false : true;
}
catch (err) {
return false;
}
}
else {
process.kill('SIGKILL');
return true;
}
}
exports.terminate = terminate;

View File

@@ -0,0 +1,16 @@
#!/bin/bash
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
terminateTree() {
for cpid in $(pgrep -P $1); do
terminateTree $cpid
done
kill -9 $1 > /dev/null 2>&1
}
for pid in $*; do
terminateTree $pid
done

View File

@@ -0,0 +1,96 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
class ValueUUID {
constructor(_value) {
this._value = _value;
// empty
}
asHex() {
return this._value;
}
equals(other) {
return this.asHex() === other.asHex();
}
}
class V4UUID extends ValueUUID {
constructor() {
super([
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
'-',
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
'-',
'4',
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
'-',
V4UUID._oneOf(V4UUID._timeHighBits),
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
'-',
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
V4UUID._randomHex(),
].join(''));
}
static _oneOf(array) {
return array[Math.floor(array.length * Math.random())];
}
static _randomHex() {
return V4UUID._oneOf(V4UUID._chars);
}
}
V4UUID._chars = ['0', '1', '2', '3', '4', '5', '6', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
V4UUID._timeHighBits = ['8', '9', 'a', 'b'];
/**
* An empty UUID that contains only zeros.
*/
exports.empty = new ValueUUID('00000000-0000-0000-0000-000000000000');
function v4() {
return new V4UUID();
}
exports.v4 = v4;
const _UUIDPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
function isUUID(value) {
return _UUIDPattern.test(value);
}
exports.isUUID = isUUID;
/**
* Parses a UUID that is of the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
* @param value A uuid string.
*/
function parse(value) {
if (!isUUID(value)) {
throw new Error('invalid uuid');
}
return new ValueUUID(value);
}
exports.parse = parse;
function generateUuid() {
return v4().asHex();
}
exports.generateUuid = generateUuid;

View File

@@ -0,0 +1,111 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const UUID = require("./utils/uuid");
const vscode_1 = require("vscode");
const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
function access(target, key) {
if (target === void 0) {
return undefined;
}
return target[key];
}
class WorkspaceFoldersFeature {
constructor(_client) {
this._client = _client;
this._listeners = new Map();
}
get messages() {
return vscode_languageserver_protocol_1.DidChangeWorkspaceFoldersNotification.type;
}
fillInitializeParams(params) {
let folders = vscode_1.workspace.workspaceFolders;
if (folders === void 0) {
params.workspaceFolders = null;
}
else {
params.workspaceFolders = folders.map(folder => this.asProtocol(folder));
}
}
fillClientCapabilities(capabilities) {
capabilities.workspace = capabilities.workspace || {};
capabilities.workspace.workspaceFolders = true;
}
initialize(capabilities) {
let client = this._client;
client.onRequest(vscode_languageserver_protocol_1.WorkspaceFoldersRequest.type, (token) => {
let workspaceFolders = () => {
let folders = vscode_1.workspace.workspaceFolders;
if (folders === void 0) {
return null;
}
let result = folders.map((folder) => {
return this.asProtocol(folder);
});
return result;
};
let middleware = client.clientOptions.middleware.workspace;
return middleware && middleware.workspaceFolders
? middleware.workspaceFolders(token, workspaceFolders)
: workspaceFolders(token);
});
let value = access(access(access(capabilities, 'workspace'), 'workspaceFolders'), 'changeNotifications');
let id;
if (typeof value === 'string') {
id = value;
}
else if (value === true) {
id = UUID.generateUuid();
}
if (id) {
this.register(this.messages, {
id: id,
registerOptions: undefined
});
}
}
register(_message, data) {
let id = data.id;
let client = this._client;
let disposable = vscode_1.workspace.onDidChangeWorkspaceFolders((event) => {
let didChangeWorkspaceFolders = (event) => {
let params = {
event: {
added: event.added.map(folder => this.asProtocol(folder)),
removed: event.removed.map(folder => this.asProtocol(folder))
}
};
this._client.sendNotification(vscode_languageserver_protocol_1.DidChangeWorkspaceFoldersNotification.type, params);
};
let middleware = client.clientOptions.middleware.workspace;
middleware && middleware.didChangeWorkspaceFolders
? middleware.didChangeWorkspaceFolders(event, didChangeWorkspaceFolders)
: didChangeWorkspaceFolders(event);
});
this._listeners.set(id, disposable);
}
unregister(id) {
let disposable = this._listeners.get(id);
if (disposable === void 0) {
return;
}
this._listeners.delete(id);
disposable.dispose();
}
dispose() {
for (let disposable of this._listeners.values()) {
disposable.dispose();
}
this._listeners.clear();
}
asProtocol(workspaceFolder) {
if (workspaceFolder === void 0) {
return null;
}
return { uri: this._client.code2ProtocolConverter.asUri(workspaceFolder.uri), name: workspaceFolder.name };
}
}
exports.WorkspaceFoldersFeature = WorkspaceFoldersFeature;

View File

@@ -0,0 +1,160 @@
#!/usr/bin/env node
// Standalone semver comparison program.
// Exits successfully and prints matching version(s) if
// any supplied version is valid and passes all tests.
var argv = process.argv.slice(2)
var versions = []
var range = []
var inc = null
var version = require('../package.json').version
var loose = false
var includePrerelease = false
var coerce = false
var identifier
var semver = require('../semver')
var reverse = false
var options = {}
main()
function main () {
if (!argv.length) return help()
while (argv.length) {
var a = argv.shift()
var indexOfEqualSign = a.indexOf('=')
if (indexOfEqualSign !== -1) {
a = a.slice(0, indexOfEqualSign)
argv.unshift(a.slice(indexOfEqualSign + 1))
}
switch (a) {
case '-rv': case '-rev': case '--rev': case '--reverse':
reverse = true
break
case '-l': case '--loose':
loose = true
break
case '-p': case '--include-prerelease':
includePrerelease = true
break
case '-v': case '--version':
versions.push(argv.shift())
break
case '-i': case '--inc': case '--increment':
switch (argv[0]) {
case 'major': case 'minor': case 'patch': case 'prerelease':
case 'premajor': case 'preminor': case 'prepatch':
inc = argv.shift()
break
default:
inc = 'patch'
break
}
break
case '--preid':
identifier = argv.shift()
break
case '-r': case '--range':
range.push(argv.shift())
break
case '-c': case '--coerce':
coerce = true
break
case '-h': case '--help': case '-?':
return help()
default:
versions.push(a)
break
}
}
var options = { loose: loose, includePrerelease: includePrerelease }
versions = versions.map(function (v) {
return coerce ? (semver.coerce(v) || { version: v }).version : v
}).filter(function (v) {
return semver.valid(v)
})
if (!versions.length) return fail()
if (inc && (versions.length !== 1 || range.length)) { return failInc() }
for (var i = 0, l = range.length; i < l; i++) {
versions = versions.filter(function (v) {
return semver.satisfies(v, range[i], options)
})
if (!versions.length) return fail()
}
return success(versions)
}
function failInc () {
console.error('--inc can only be used on a single version with no range')
fail()
}
function fail () { process.exit(1) }
function success () {
var compare = reverse ? 'rcompare' : 'compare'
versions.sort(function (a, b) {
return semver[compare](a, b, options)
}).map(function (v) {
return semver.clean(v, options)
}).map(function (v) {
return inc ? semver.inc(v, inc, options, identifier) : v
}).forEach(function (v, i, _) { console.log(v) })
}
function help () {
console.log(['SemVer ' + version,
'',
'A JavaScript implementation of the https://semver.org/ specification',
'Copyright Isaac Z. Schlueter',
'',
'Usage: semver [options] <version> [<version> [...]]',
'Prints valid versions sorted by SemVer precedence',
'',
'Options:',
'-r --range <range>',
' Print versions that match the specified range.',
'',
'-i --increment [<level>]',
' Increment a version by the specified level. Level can',
' be one of: major, minor, patch, premajor, preminor,',
" prepatch, or prerelease. Default level is 'patch'.",
' Only one version may be specified.',
'',
'--preid <identifier>',
' Identifier to be used to prefix premajor, preminor,',
' prepatch or prerelease version increments.',
'',
'-l --loose',
' Interpret versions and ranges loosely',
'',
'-p --include-prerelease',
' Always include prerelease versions in range matching',
'',
'-c --coerce',
' Coerce a string into SemVer if possible',
' (does not imply --loose)',
'',
'Program exits successfully if any valid version satisfies',
'all supplied ranges, and prints all satisfying versions.',
'',
'If no satisfying versions are found, then exits failure.',
'',
'Versions are printed in ascending order, so supplying',
'multiple versions to the utility will just sort them.'
].join('\n'))
}

View File

@@ -0,0 +1,39 @@
{
"name": "vscode-languageclient",
"description": "VSCode Language client implementation",
"version": "5.2.1",
"author": "Microsoft Corporation",
"license": "MIT",
"engines": {
"vscode": "^1.30"
},
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/vscode-languageserver-node.git"
},
"bugs": {
"url": "https://github.com/Microsoft/vscode-languageserver-node/issues"
},
"main": "./lib/main.js",
"typings": "./lib/main",
"devDependencies": {
"@types/semver": "^5.5.0",
"shx": "^0.3.1",
"vscode": "^1.1.21"
},
"dependencies": {
"semver": "^5.5.0",
"vscode-languageserver-protocol": "3.14.1"
},
"scripts": {
"prepare": "npm run update-vscode",
"prepublishOnly": "npm run clean && npm run compile && npm test",
"postpublish": "node ../build/npm/post-publish.js",
"compile": "node ../build/bin/tsc -p ./tsconfig.json && shx cp src/utils/terminateProcess.sh lib/utils/terminateProcess.sh",
"watch": "node ../build/bin/tsc -w -p ./tsconfig.json",
"update-vscode": "node ./node_modules/vscode/bin/install && node bin/updateVSCode",
"clean": "node ../node_modules/rimraf/bin.js lib",
"test": "node bin/runTests",
"preversion": "npm test"
}
}

View File

@@ -0,0 +1,56 @@
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
For Microsoft vscode-languageclient
This project incorporates material from the project(s) listed below (collectively, “Third Party Code”).
Microsoft is not the original author of the Third Party Code. The original copyright notice and license
under which Microsoft received such Third Party Code are set out below. This Third Party Code is licensed
to you under their original license terms set forth below. Microsoft reserves all other rights not expressly
granted, whether by implication, estoppel or otherwise.
1. DefinitelyTyped version 0.0.1 (https://github.com/borisyankov/DefinitelyTyped)
2. semver version 5.5.0 (https://github.com/npm/node-semver)
%% DefinitelyTyped NOTICES AND INFORMATION BEGIN HERE
=========================================
This project is licensed under the MIT license.
Copyrights are respective of each contributor listed at the beginning of each definition file.
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.
=========================================
END OF DefinitelyTyped NOTICES AND INFORMATION
%% semver NOTICES AND INFORMATION BEGIN HERE
=========================================
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
=========================================
END OF semver NOTICES AND INFORMATION

View File

@@ -0,0 +1,11 @@
Copyright (c) Microsoft Corporation
All rights reserved.
MIT License
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.

View File

@@ -0,0 +1,43 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
exports.ErrorCodes = vscode_jsonrpc_1.ErrorCodes;
exports.ResponseError = vscode_jsonrpc_1.ResponseError;
exports.CancellationToken = vscode_jsonrpc_1.CancellationToken;
exports.CancellationTokenSource = vscode_jsonrpc_1.CancellationTokenSource;
exports.Disposable = vscode_jsonrpc_1.Disposable;
exports.Event = vscode_jsonrpc_1.Event;
exports.Emitter = vscode_jsonrpc_1.Emitter;
exports.Trace = vscode_jsonrpc_1.Trace;
exports.TraceFormat = vscode_jsonrpc_1.TraceFormat;
exports.SetTraceNotification = vscode_jsonrpc_1.SetTraceNotification;
exports.LogTraceNotification = vscode_jsonrpc_1.LogTraceNotification;
exports.RequestType = vscode_jsonrpc_1.RequestType;
exports.RequestType0 = vscode_jsonrpc_1.RequestType0;
exports.NotificationType = vscode_jsonrpc_1.NotificationType;
exports.NotificationType0 = vscode_jsonrpc_1.NotificationType0;
exports.MessageReader = vscode_jsonrpc_1.MessageReader;
exports.MessageWriter = vscode_jsonrpc_1.MessageWriter;
exports.ConnectionStrategy = vscode_jsonrpc_1.ConnectionStrategy;
exports.StreamMessageReader = vscode_jsonrpc_1.StreamMessageReader;
exports.StreamMessageWriter = vscode_jsonrpc_1.StreamMessageWriter;
exports.IPCMessageReader = vscode_jsonrpc_1.IPCMessageReader;
exports.IPCMessageWriter = vscode_jsonrpc_1.IPCMessageWriter;
exports.createClientPipeTransport = vscode_jsonrpc_1.createClientPipeTransport;
exports.createServerPipeTransport = vscode_jsonrpc_1.createServerPipeTransport;
exports.generateRandomPipeName = vscode_jsonrpc_1.generateRandomPipeName;
exports.createClientSocketTransport = vscode_jsonrpc_1.createClientSocketTransport;
exports.createServerSocketTransport = vscode_jsonrpc_1.createServerSocketTransport;
__export(require("vscode-languageserver-types"));
__export(require("./protocol"));
function createProtocolConnection(reader, writer, logger, strategy) {
return vscode_jsonrpc_1.createMessageConnection(reader, writer, logger, strategy);
}
exports.createProtocolConnection = createProtocolConnection;

View File

@@ -0,0 +1,27 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
/**
* A request to list all color symbols found in a given text document. The request's
* parameter is of type [DocumentColorParams](#DocumentColorParams) the
* response is of type [ColorInformation[]](#ColorInformation) or a Thenable
* that resolves to such.
*/
var DocumentColorRequest;
(function (DocumentColorRequest) {
DocumentColorRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/documentColor');
})(DocumentColorRequest = exports.DocumentColorRequest || (exports.DocumentColorRequest = {}));
/**
* A request to list all presentation for a color. The request's
* parameter is of type [ColorPresentationParams](#ColorPresentationParams) the
* response is of type [ColorInformation[]](#ColorInformation) or a Thenable
* that resolves to such.
*/
var ColorPresentationRequest;
(function (ColorPresentationRequest) {
ColorPresentationRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/colorPresentation');
})(ColorPresentationRequest = exports.ColorPresentationRequest || (exports.ColorPresentationRequest = {}));

View File

@@ -0,0 +1,20 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
/**
* The 'workspace/configuration' request is sent from the server to the client to fetch a certain
* configuration setting.
*
* This pull model replaces the old push model were the client signaled configuration change via an
* event. If the server still needs to react to configuration changes (since the server caches the
* result of `workspace/configuration` requests) the server should register for an empty configuration
* change event and empty the cache if such an event is received.
*/
var ConfigurationRequest;
(function (ConfigurationRequest) {
ConfigurationRequest.type = new vscode_jsonrpc_1.RequestType('workspace/configuration');
})(ConfigurationRequest = exports.ConfigurationRequest || (exports.ConfigurationRequest = {}));

View File

@@ -0,0 +1,20 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
// @ts-ignore: to avoid inlining LocatioLink as dynamic import
let __noDynamicImport;
/**
* A request to resolve the type definition locations of a symbol at a given text
* document position. The request's parameter is of type [TextDocumentPositioParams]
* (#TextDocumentPositionParams) the response is of type [Declaration](#Declaration)
* or a typed array of [DeclarationLink](#DeclarationLink) or a Thenable that resolves
* to such.
*/
var DeclarationRequest;
(function (DeclarationRequest) {
DeclarationRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/declaration');
})(DeclarationRequest = exports.DeclarationRequest || (exports.DeclarationRequest = {}));

View File

@@ -0,0 +1,35 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
/**
* Enum of known range kinds
*/
var FoldingRangeKind;
(function (FoldingRangeKind) {
/**
* Folding range for a comment
*/
FoldingRangeKind["Comment"] = "comment";
/**
* Folding range for a imports or includes
*/
FoldingRangeKind["Imports"] = "imports";
/**
* Folding range for a region (e.g. `#region`)
*/
FoldingRangeKind["Region"] = "region";
})(FoldingRangeKind = exports.FoldingRangeKind || (exports.FoldingRangeKind = {}));
/**
* A request to provide folding ranges in a document. The request's
* parameter is of type [FoldingRangeParams](#FoldingRangeParams), the
* response is of type [FoldingRangeList](#FoldingRangeList) or a Thenable
* that resolves to such.
*/
var FoldingRangeRequest;
(function (FoldingRangeRequest) {
FoldingRangeRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/foldingRange');
})(FoldingRangeRequest = exports.FoldingRangeRequest || (exports.FoldingRangeRequest = {}));

View File

@@ -0,0 +1,19 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
// @ts-ignore: to avoid inlining LocatioLink as dynamic import
let __noDynamicImport;
/**
* A request to resolve the implementation locations of a symbol at a given text
* document position. The request's parameter is of type [TextDocumentPositioParams]
* (#TextDocumentPositionParams) the response is of type [Definition](#Definition) or a
* Thenable that resolves to such.
*/
var ImplementationRequest;
(function (ImplementationRequest) {
ImplementationRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/implementation');
})(ImplementationRequest = exports.ImplementationRequest || (exports.ImplementationRequest = {}));

View File

@@ -0,0 +1,543 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const Is = require("./utils/is");
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
const protocol_implementation_1 = require("./protocol.implementation");
exports.ImplementationRequest = protocol_implementation_1.ImplementationRequest;
const protocol_typeDefinition_1 = require("./protocol.typeDefinition");
exports.TypeDefinitionRequest = protocol_typeDefinition_1.TypeDefinitionRequest;
const protocol_workspaceFolders_1 = require("./protocol.workspaceFolders");
exports.WorkspaceFoldersRequest = protocol_workspaceFolders_1.WorkspaceFoldersRequest;
exports.DidChangeWorkspaceFoldersNotification = protocol_workspaceFolders_1.DidChangeWorkspaceFoldersNotification;
const protocol_configuration_1 = require("./protocol.configuration");
exports.ConfigurationRequest = protocol_configuration_1.ConfigurationRequest;
const protocol_colorProvider_1 = require("./protocol.colorProvider");
exports.DocumentColorRequest = protocol_colorProvider_1.DocumentColorRequest;
exports.ColorPresentationRequest = protocol_colorProvider_1.ColorPresentationRequest;
const protocol_foldingRange_1 = require("./protocol.foldingRange");
exports.FoldingRangeRequest = protocol_foldingRange_1.FoldingRangeRequest;
const protocol_declaration_1 = require("./protocol.declaration");
exports.DeclarationRequest = protocol_declaration_1.DeclarationRequest;
// @ts-ignore: to avoid inlining LocatioLink as dynamic import
let __noDynamicImport;
var DocumentFilter;
(function (DocumentFilter) {
function is(value) {
let candidate = value;
return Is.string(candidate.language) || Is.string(candidate.scheme) || Is.string(candidate.pattern);
}
DocumentFilter.is = is;
})(DocumentFilter = exports.DocumentFilter || (exports.DocumentFilter = {}));
/**
* The `client/registerCapability` request is sent from the server to the client to register a new capability
* handler on the client side.
*/
var RegistrationRequest;
(function (RegistrationRequest) {
RegistrationRequest.type = new vscode_jsonrpc_1.RequestType('client/registerCapability');
})(RegistrationRequest = exports.RegistrationRequest || (exports.RegistrationRequest = {}));
/**
* The `client/unregisterCapability` request is sent from the server to the client to unregister a previously registered capability
* handler on the client side.
*/
var UnregistrationRequest;
(function (UnregistrationRequest) {
UnregistrationRequest.type = new vscode_jsonrpc_1.RequestType('client/unregisterCapability');
})(UnregistrationRequest = exports.UnregistrationRequest || (exports.UnregistrationRequest = {}));
var ResourceOperationKind;
(function (ResourceOperationKind) {
/**
* Supports creating new files and folders.
*/
ResourceOperationKind.Create = 'create';
/**
* Supports renaming existing files and folders.
*/
ResourceOperationKind.Rename = 'rename';
/**
* Supports deleting existing files and folders.
*/
ResourceOperationKind.Delete = 'delete';
})(ResourceOperationKind = exports.ResourceOperationKind || (exports.ResourceOperationKind = {}));
var FailureHandlingKind;
(function (FailureHandlingKind) {
/**
* Applying the workspace change is simply aborted if one of the changes provided
* fails. All operations executed before the failing operation stay executed.
*/
FailureHandlingKind.Abort = 'abort';
/**
* All operations are executed transactional. That means they either all
* succeed or no changes at all are applied to the workspace.
*/
FailureHandlingKind.Transactional = 'transactional';
/**
* If the workspace edit contains only textual file changes they are executed transactional.
* If resource changes (create, rename or delete file) are part of the change the failure
* handling startegy is abort.
*/
FailureHandlingKind.TextOnlyTransactional = 'textOnlyTransactional';
/**
* The client tries to undo the operations already executed. But there is no
* guaruntee that this is succeeding.
*/
FailureHandlingKind.Undo = 'undo';
})(FailureHandlingKind = exports.FailureHandlingKind || (exports.FailureHandlingKind = {}));
/**
* Defines how the host (editor) should sync
* document changes to the language server.
*/
var TextDocumentSyncKind;
(function (TextDocumentSyncKind) {
/**
* Documents should not be synced at all.
*/
TextDocumentSyncKind.None = 0;
/**
* Documents are synced by always sending the full content
* of the document.
*/
TextDocumentSyncKind.Full = 1;
/**
* Documents are synced by sending the full content on open.
* After that only incremental updates to the document are
* send.
*/
TextDocumentSyncKind.Incremental = 2;
})(TextDocumentSyncKind = exports.TextDocumentSyncKind || (exports.TextDocumentSyncKind = {}));
/**
* The initialize request is sent from the client to the server.
* It is sent once as the request after starting up the server.
* The requests parameter is of type [InitializeParams](#InitializeParams)
* the response if of type [InitializeResult](#InitializeResult) of a Thenable that
* resolves to such.
*/
var InitializeRequest;
(function (InitializeRequest) {
InitializeRequest.type = new vscode_jsonrpc_1.RequestType('initialize');
})(InitializeRequest = exports.InitializeRequest || (exports.InitializeRequest = {}));
/**
* Known error codes for an `InitializeError`;
*/
var InitializeError;
(function (InitializeError) {
/**
* If the protocol version provided by the client can't be handled by the server.
* @deprecated This initialize error got replaced by client capabilities. There is
* no version handshake in version 3.0x
*/
InitializeError.unknownProtocolVersion = 1;
})(InitializeError = exports.InitializeError || (exports.InitializeError = {}));
/**
* The intialized notification is sent from the client to the
* server after the client is fully initialized and the server
* is allowed to send requests from the server to the client.
*/
var InitializedNotification;
(function (InitializedNotification) {
InitializedNotification.type = new vscode_jsonrpc_1.NotificationType('initialized');
})(InitializedNotification = exports.InitializedNotification || (exports.InitializedNotification = {}));
//---- Shutdown Method ----
/**
* A shutdown request is sent from the client to the server.
* It is sent once when the client decides to shutdown the
* server. The only notification that is sent after a shutdown request
* is the exit event.
*/
var ShutdownRequest;
(function (ShutdownRequest) {
ShutdownRequest.type = new vscode_jsonrpc_1.RequestType0('shutdown');
})(ShutdownRequest = exports.ShutdownRequest || (exports.ShutdownRequest = {}));
//---- Exit Notification ----
/**
* The exit event is sent from the client to the server to
* ask the server to exit its process.
*/
var ExitNotification;
(function (ExitNotification) {
ExitNotification.type = new vscode_jsonrpc_1.NotificationType0('exit');
})(ExitNotification = exports.ExitNotification || (exports.ExitNotification = {}));
//---- Configuration notification ----
/**
* The configuration change notification is sent from the client to the server
* when the client's configuration has changed. The notification contains
* the changed configuration as defined by the language client.
*/
var DidChangeConfigurationNotification;
(function (DidChangeConfigurationNotification) {
DidChangeConfigurationNotification.type = new vscode_jsonrpc_1.NotificationType('workspace/didChangeConfiguration');
})(DidChangeConfigurationNotification = exports.DidChangeConfigurationNotification || (exports.DidChangeConfigurationNotification = {}));
//---- Message show and log notifications ----
/**
* The message type
*/
var MessageType;
(function (MessageType) {
/**
* An error message.
*/
MessageType.Error = 1;
/**
* A warning message.
*/
MessageType.Warning = 2;
/**
* An information message.
*/
MessageType.Info = 3;
/**
* A log message.
*/
MessageType.Log = 4;
})(MessageType = exports.MessageType || (exports.MessageType = {}));
/**
* The show message notification is sent from a server to a client to ask
* the client to display a particular message in the user interface.
*/
var ShowMessageNotification;
(function (ShowMessageNotification) {
ShowMessageNotification.type = new vscode_jsonrpc_1.NotificationType('window/showMessage');
})(ShowMessageNotification = exports.ShowMessageNotification || (exports.ShowMessageNotification = {}));
/**
* The show message request is sent from the server to the client to show a message
* and a set of options actions to the user.
*/
var ShowMessageRequest;
(function (ShowMessageRequest) {
ShowMessageRequest.type = new vscode_jsonrpc_1.RequestType('window/showMessageRequest');
})(ShowMessageRequest = exports.ShowMessageRequest || (exports.ShowMessageRequest = {}));
/**
* The log message notification is sent from the server to the client to ask
* the client to log a particular message.
*/
var LogMessageNotification;
(function (LogMessageNotification) {
LogMessageNotification.type = new vscode_jsonrpc_1.NotificationType('window/logMessage');
})(LogMessageNotification = exports.LogMessageNotification || (exports.LogMessageNotification = {}));
//---- Telemetry notification
/**
* The telemetry event notification is sent from the server to the client to ask
* the client to log telemetry data.
*/
var TelemetryEventNotification;
(function (TelemetryEventNotification) {
TelemetryEventNotification.type = new vscode_jsonrpc_1.NotificationType('telemetry/event');
})(TelemetryEventNotification = exports.TelemetryEventNotification || (exports.TelemetryEventNotification = {}));
/**
* The document open notification is sent from the client to the server to signal
* newly opened text documents. The document's truth is now managed by the client
* and the server must not try to read the document's truth using the document's
* uri. Open in this sense means it is managed by the client. It doesn't necessarily
* mean that its content is presented in an editor. An open notification must not
* be sent more than once without a corresponding close notification send before.
* This means open and close notification must be balanced and the max open count
* is one.
*/
var DidOpenTextDocumentNotification;
(function (DidOpenTextDocumentNotification) {
DidOpenTextDocumentNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/didOpen');
})(DidOpenTextDocumentNotification = exports.DidOpenTextDocumentNotification || (exports.DidOpenTextDocumentNotification = {}));
/**
* The document change notification is sent from the client to the server to signal
* changes to a text document.
*/
var DidChangeTextDocumentNotification;
(function (DidChangeTextDocumentNotification) {
DidChangeTextDocumentNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/didChange');
})(DidChangeTextDocumentNotification = exports.DidChangeTextDocumentNotification || (exports.DidChangeTextDocumentNotification = {}));
/**
* The document close notification is sent from the client to the server when
* the document got closed in the client. The document's truth now exists where
* the document's uri points to (e.g. if the document's uri is a file uri the
* truth now exists on disk). As with the open notification the close notification
* is about managing the document's content. Receiving a close notification
* doesn't mean that the document was open in an editor before. A close
* notification requires a previous open notification to be sent.
*/
var DidCloseTextDocumentNotification;
(function (DidCloseTextDocumentNotification) {
DidCloseTextDocumentNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/didClose');
})(DidCloseTextDocumentNotification = exports.DidCloseTextDocumentNotification || (exports.DidCloseTextDocumentNotification = {}));
/**
* The document save notification is sent from the client to the server when
* the document got saved in the client.
*/
var DidSaveTextDocumentNotification;
(function (DidSaveTextDocumentNotification) {
DidSaveTextDocumentNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/didSave');
})(DidSaveTextDocumentNotification = exports.DidSaveTextDocumentNotification || (exports.DidSaveTextDocumentNotification = {}));
/**
* A document will save notification is sent from the client to the server before
* the document is actually saved.
*/
var WillSaveTextDocumentNotification;
(function (WillSaveTextDocumentNotification) {
WillSaveTextDocumentNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/willSave');
})(WillSaveTextDocumentNotification = exports.WillSaveTextDocumentNotification || (exports.WillSaveTextDocumentNotification = {}));
/**
* A document will save request is sent from the client to the server before
* the document is actually saved. The request can return an array of TextEdits
* which will be applied to the text document before it is saved. Please note that
* clients might drop results if computing the text edits took too long or if a
* server constantly fails on this request. This is done to keep the save fast and
* reliable.
*/
var WillSaveTextDocumentWaitUntilRequest;
(function (WillSaveTextDocumentWaitUntilRequest) {
WillSaveTextDocumentWaitUntilRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/willSaveWaitUntil');
})(WillSaveTextDocumentWaitUntilRequest = exports.WillSaveTextDocumentWaitUntilRequest || (exports.WillSaveTextDocumentWaitUntilRequest = {}));
//---- File eventing ----
/**
* The watched files notification is sent from the client to the server when
* the client detects changes to file watched by the language client.
*/
var DidChangeWatchedFilesNotification;
(function (DidChangeWatchedFilesNotification) {
DidChangeWatchedFilesNotification.type = new vscode_jsonrpc_1.NotificationType('workspace/didChangeWatchedFiles');
})(DidChangeWatchedFilesNotification = exports.DidChangeWatchedFilesNotification || (exports.DidChangeWatchedFilesNotification = {}));
/**
* The file event type
*/
var FileChangeType;
(function (FileChangeType) {
/**
* The file got created.
*/
FileChangeType.Created = 1;
/**
* The file got changed.
*/
FileChangeType.Changed = 2;
/**
* The file got deleted.
*/
FileChangeType.Deleted = 3;
})(FileChangeType = exports.FileChangeType || (exports.FileChangeType = {}));
var WatchKind;
(function (WatchKind) {
/**
* Interested in create events.
*/
WatchKind.Create = 1;
/**
* Interested in change events
*/
WatchKind.Change = 2;
/**
* Interested in delete events
*/
WatchKind.Delete = 4;
})(WatchKind = exports.WatchKind || (exports.WatchKind = {}));
//---- Diagnostic notification ----
/**
* Diagnostics notification are sent from the server to the client to signal
* results of validation runs.
*/
var PublishDiagnosticsNotification;
(function (PublishDiagnosticsNotification) {
PublishDiagnosticsNotification.type = new vscode_jsonrpc_1.NotificationType('textDocument/publishDiagnostics');
})(PublishDiagnosticsNotification = exports.PublishDiagnosticsNotification || (exports.PublishDiagnosticsNotification = {}));
/**
* How a completion was triggered
*/
var CompletionTriggerKind;
(function (CompletionTriggerKind) {
/**
* Completion was triggered by typing an identifier (24x7 code
* complete), manual invocation (e.g Ctrl+Space) or via API.
*/
CompletionTriggerKind.Invoked = 1;
/**
* Completion was triggered by a trigger character specified by
* the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
*/
CompletionTriggerKind.TriggerCharacter = 2;
/**
* Completion was re-triggered as current completion list is incomplete
*/
CompletionTriggerKind.TriggerForIncompleteCompletions = 3;
})(CompletionTriggerKind = exports.CompletionTriggerKind || (exports.CompletionTriggerKind = {}));
/**
* Request to request completion at a given text document position. The request's
* parameter is of type [TextDocumentPosition](#TextDocumentPosition) the response
* is of type [CompletionItem[]](#CompletionItem) or [CompletionList](#CompletionList)
* or a Thenable that resolves to such.
*
* The request can delay the computation of the [`detail`](#CompletionItem.detail)
* and [`documentation`](#CompletionItem.documentation) properties to the `completionItem/resolve`
* request. However, properties that are needed for the initial sorting and filtering, like `sortText`,
* `filterText`, `insertText`, and `textEdit`, must not be changed during resolve.
*/
var CompletionRequest;
(function (CompletionRequest) {
CompletionRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/completion');
})(CompletionRequest = exports.CompletionRequest || (exports.CompletionRequest = {}));
/**
* Request to resolve additional information for a given completion item.The request's
* parameter is of type [CompletionItem](#CompletionItem) the response
* is of type [CompletionItem](#CompletionItem) or a Thenable that resolves to such.
*/
var CompletionResolveRequest;
(function (CompletionResolveRequest) {
CompletionResolveRequest.type = new vscode_jsonrpc_1.RequestType('completionItem/resolve');
})(CompletionResolveRequest = exports.CompletionResolveRequest || (exports.CompletionResolveRequest = {}));
//---- Hover Support -------------------------------
/**
* Request to request hover information at a given text document position. The request's
* parameter is of type [TextDocumentPosition](#TextDocumentPosition) the response is of
* type [Hover](#Hover) or a Thenable that resolves to such.
*/
var HoverRequest;
(function (HoverRequest) {
HoverRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/hover');
})(HoverRequest = exports.HoverRequest || (exports.HoverRequest = {}));
var SignatureHelpRequest;
(function (SignatureHelpRequest) {
SignatureHelpRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/signatureHelp');
})(SignatureHelpRequest = exports.SignatureHelpRequest || (exports.SignatureHelpRequest = {}));
//---- Goto Definition -------------------------------------
/**
* A request to resolve the definition location of a symbol at a given text
* document position. The request's parameter is of type [TextDocumentPosition]
* (#TextDocumentPosition) the response is of either type [Definition](#Definition)
* or a typed array of [DefinitionLink](#DefinitionLink) or a Thenable that resolves
* to such.
*/
var DefinitionRequest;
(function (DefinitionRequest) {
DefinitionRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/definition');
})(DefinitionRequest = exports.DefinitionRequest || (exports.DefinitionRequest = {}));
/**
* A request to resolve project-wide references for the symbol denoted
* by the given text document position. The request's parameter is of
* type [ReferenceParams](#ReferenceParams) the response is of type
* [Location[]](#Location) or a Thenable that resolves to such.
*/
var ReferencesRequest;
(function (ReferencesRequest) {
ReferencesRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/references');
})(ReferencesRequest = exports.ReferencesRequest || (exports.ReferencesRequest = {}));
//---- Document Highlight ----------------------------------
/**
* Request to resolve a [DocumentHighlight](#DocumentHighlight) for a given
* text document position. The request's parameter is of type [TextDocumentPosition]
* (#TextDocumentPosition) the request response is of type [DocumentHighlight[]]
* (#DocumentHighlight) or a Thenable that resolves to such.
*/
var DocumentHighlightRequest;
(function (DocumentHighlightRequest) {
DocumentHighlightRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/documentHighlight');
})(DocumentHighlightRequest = exports.DocumentHighlightRequest || (exports.DocumentHighlightRequest = {}));
//---- Document Symbol Provider ---------------------------
/**
* A request to list all symbols found in a given text document. The request's
* parameter is of type [TextDocumentIdentifier](#TextDocumentIdentifier) the
* response is of type [SymbolInformation[]](#SymbolInformation) or a Thenable
* that resolves to such.
*/
var DocumentSymbolRequest;
(function (DocumentSymbolRequest) {
DocumentSymbolRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/documentSymbol');
})(DocumentSymbolRequest = exports.DocumentSymbolRequest || (exports.DocumentSymbolRequest = {}));
//---- Workspace Symbol Provider ---------------------------
/**
* A request to list project-wide symbols matching the query string given
* by the [WorkspaceSymbolParams](#WorkspaceSymbolParams). The response is
* of type [SymbolInformation[]](#SymbolInformation) or a Thenable that
* resolves to such.
*/
var WorkspaceSymbolRequest;
(function (WorkspaceSymbolRequest) {
WorkspaceSymbolRequest.type = new vscode_jsonrpc_1.RequestType('workspace/symbol');
})(WorkspaceSymbolRequest = exports.WorkspaceSymbolRequest || (exports.WorkspaceSymbolRequest = {}));
/**
* A request to provide commands for the given text document and range.
*/
var CodeActionRequest;
(function (CodeActionRequest) {
CodeActionRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/codeAction');
})(CodeActionRequest = exports.CodeActionRequest || (exports.CodeActionRequest = {}));
/**
* A request to provide code lens for the given text document.
*/
var CodeLensRequest;
(function (CodeLensRequest) {
CodeLensRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/codeLens');
})(CodeLensRequest = exports.CodeLensRequest || (exports.CodeLensRequest = {}));
/**
* A request to resolve a command for a given code lens.
*/
var CodeLensResolveRequest;
(function (CodeLensResolveRequest) {
CodeLensResolveRequest.type = new vscode_jsonrpc_1.RequestType('codeLens/resolve');
})(CodeLensResolveRequest = exports.CodeLensResolveRequest || (exports.CodeLensResolveRequest = {}));
/**
* A request to to format a whole document.
*/
var DocumentFormattingRequest;
(function (DocumentFormattingRequest) {
DocumentFormattingRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/formatting');
})(DocumentFormattingRequest = exports.DocumentFormattingRequest || (exports.DocumentFormattingRequest = {}));
/**
* A request to to format a range in a document.
*/
var DocumentRangeFormattingRequest;
(function (DocumentRangeFormattingRequest) {
DocumentRangeFormattingRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/rangeFormatting');
})(DocumentRangeFormattingRequest = exports.DocumentRangeFormattingRequest || (exports.DocumentRangeFormattingRequest = {}));
/**
* A request to format a document on type.
*/
var DocumentOnTypeFormattingRequest;
(function (DocumentOnTypeFormattingRequest) {
DocumentOnTypeFormattingRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/onTypeFormatting');
})(DocumentOnTypeFormattingRequest = exports.DocumentOnTypeFormattingRequest || (exports.DocumentOnTypeFormattingRequest = {}));
/**
* A request to rename a symbol.
*/
var RenameRequest;
(function (RenameRequest) {
RenameRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/rename');
})(RenameRequest = exports.RenameRequest || (exports.RenameRequest = {}));
/**
* A request to test and perform the setup necessary for a rename.
*/
var PrepareRenameRequest;
(function (PrepareRenameRequest) {
PrepareRenameRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/prepareRename');
})(PrepareRenameRequest = exports.PrepareRenameRequest || (exports.PrepareRenameRequest = {}));
/**
* A request to provide document links
*/
var DocumentLinkRequest;
(function (DocumentLinkRequest) {
DocumentLinkRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/documentLink');
})(DocumentLinkRequest = exports.DocumentLinkRequest || (exports.DocumentLinkRequest = {}));
/**
* Request to resolve additional information for a given document link. The request's
* parameter is of type [DocumentLink](#DocumentLink) the response
* is of type [DocumentLink](#DocumentLink) or a Thenable that resolves to such.
*/
var DocumentLinkResolveRequest;
(function (DocumentLinkResolveRequest) {
DocumentLinkResolveRequest.type = new vscode_jsonrpc_1.RequestType('documentLink/resolve');
})(DocumentLinkResolveRequest = exports.DocumentLinkResolveRequest || (exports.DocumentLinkResolveRequest = {}));
/**
* A request send from the client to the server to execute a command. The request might return
* a workspace edit which the client will apply to the workspace.
*/
var ExecuteCommandRequest;
(function (ExecuteCommandRequest) {
ExecuteCommandRequest.type = new vscode_jsonrpc_1.RequestType('workspace/executeCommand');
})(ExecuteCommandRequest = exports.ExecuteCommandRequest || (exports.ExecuteCommandRequest = {}));
/**
* A request sent from the server to the client to modified certain resources.
*/
var ApplyWorkspaceEditRequest;
(function (ApplyWorkspaceEditRequest) {
ApplyWorkspaceEditRequest.type = new vscode_jsonrpc_1.RequestType('workspace/applyEdit');
})(ApplyWorkspaceEditRequest = exports.ApplyWorkspaceEditRequest || (exports.ApplyWorkspaceEditRequest = {}));

View File

@@ -0,0 +1,19 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
// @ts-ignore: to avoid inlining LocatioLink as dynamic import
let __noDynamicImport;
/**
* A request to resolve the type definition locations of a symbol at a given text
* document position. The request's parameter is of type [TextDocumentPositioParams]
* (#TextDocumentPositionParams) the response is of type [Definition](#Definition) or a
* Thenable that resolves to such.
*/
var TypeDefinitionRequest;
(function (TypeDefinitionRequest) {
TypeDefinitionRequest.type = new vscode_jsonrpc_1.RequestType('textDocument/typeDefinition');
})(TypeDefinitionRequest = exports.TypeDefinitionRequest || (exports.TypeDefinitionRequest = {}));

View File

@@ -0,0 +1,22 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
/**
* The `workspace/workspaceFolders` is sent from the server to the client to fetch the open workspace folders.
*/
var WorkspaceFoldersRequest;
(function (WorkspaceFoldersRequest) {
WorkspaceFoldersRequest.type = new vscode_jsonrpc_1.RequestType0('workspace/workspaceFolders');
})(WorkspaceFoldersRequest = exports.WorkspaceFoldersRequest || (exports.WorkspaceFoldersRequest = {}));
/**
* The `workspace/didChangeWorkspaceFolders` notification is sent from the client to the server when the workspace
* folder configuration changes.
*/
var DidChangeWorkspaceFoldersNotification;
(function (DidChangeWorkspaceFoldersNotification) {
DidChangeWorkspaceFoldersNotification.type = new vscode_jsonrpc_1.NotificationType('workspace/didChangeWorkspaceFolders');
})(DidChangeWorkspaceFoldersNotification = exports.DidChangeWorkspaceFoldersNotification || (exports.DidChangeWorkspaceFoldersNotification = {}));

View File

@@ -0,0 +1,42 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
function boolean(value) {
return value === true || value === false;
}
exports.boolean = boolean;
function string(value) {
return typeof value === 'string' || value instanceof String;
}
exports.string = string;
function number(value) {
return typeof value === 'number' || value instanceof Number;
}
exports.number = number;
function error(value) {
return value instanceof Error;
}
exports.error = error;
function func(value) {
return typeof value === 'function';
}
exports.func = func;
function array(value) {
return Array.isArray(value);
}
exports.array = array;
function stringArray(value) {
return array(value) && value.every(elem => string(elem));
}
exports.stringArray = stringArray;
function typedArray(value, check) {
return Array.isArray(value) && value.every(check);
}
exports.typedArray = typedArray;
function thenable(value) {
return value && func(value.then);
}
exports.thenable = thenable;

View File

@@ -0,0 +1,29 @@
{
"name": "vscode-languageserver-protocol",
"description": "VSCode Language Server Protocol implementation",
"version": "3.14.1",
"author": "Microsoft Corporation",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/vscode-languageserver-node.git"
},
"bugs": {
"url": "https://github.com/Microsoft/vscode-languageserver-node/issues"
},
"main": "./lib/main.js",
"typings": "./lib/main",
"dependencies": {
"vscode-jsonrpc": "^4.0.0",
"vscode-languageserver-types": "3.14.0"
},
"scripts": {
"prepublishOnly": "npm run clean && npm run compile && npm test",
"postpublish": "node ../build/npm/post-publish.js",
"compile": "node ../build/bin/tsc -p ./tsconfig.json",
"watch": "node ../build/bin/tsc -w -p ./tsconfig.json",
"test": "node ../node_modules/mocha/bin/_mocha",
"clean": "node ../node_modules/rimraf/bin.js lib",
"preversion": "npm test"
}
}

View File

@@ -0,0 +1,31 @@
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
For Microsoft vscode-languageclient
This project incorporates material from the project(s) listed below (collectively, “Third Party Code”).
Microsoft is not the original author of the Third Party Code. The original copyright notice and license
under which Microsoft received such Third Party Code are set out below. This Third Party Code is licensed
to you under their original license terms set forth below. Microsoft reserves all other rights not expressly
granted, whether by implication, estoppel or otherwise.
1. DefinitelyTyped version 0.0.1 (https://github.com/borisyankov/DefinitelyTyped)
This project is licensed under the MIT license.
Copyrights are respective of each contributor listed at the beginning of each definition file.
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.

View File

@@ -0,0 +1,11 @@
Copyright (c) Microsoft Corporation
All rights reserved.
MIT License
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.

View File

@@ -0,0 +1,27 @@
{
"name": "vscode-languageserver-types",
"description": "Types used by the Language server for node",
"version": "3.14.0",
"author": "Microsoft Corporation",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/vscode-languageserver-node.git"
},
"bugs": {
"url": "https://github.com/Microsoft/vscode-languageserver-node/issues"
},
"main": "./lib/umd/main.js",
"typings": "./lib/umd/main",
"module": "./lib/esm/main.js",
"scripts": {
"prepublishOnly": "npm run clean && npm run compile-esm && npm run compile && npm run test",
"postpublish": "node ../build/npm/post-publish.js",
"compile": "node ../build/bin/tsc -p ./tsconfig.json",
"compile-esm": "node ../build/bin/tsc -p ./tsconfig.esm.json",
"clean": "node ../node_modules/rimraf/bin.js lib",
"watch": "node ../build/bin/tsc -w -p ./tsconfig.json",
"test": "node ../node_modules/mocha/bin/_mocha",
"preversion": "npm test"
}
}

View File

@@ -0,0 +1,16 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"target": "es5",
"module": "es6",
"sourceMap": false,
"declaration": true,
"stripInternal": true,
"lib": [ "es2015" ],
"outDir": "lib/esm",
"rootDir": "src"
},
"include": [
"src"
]
}

View File

@@ -0,0 +1,170 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.deactivate = exports.activate = void 0;
const path = require("path");
const vscode_1 = require("vscode");
const vscode_languageclient_1 = require("vscode-languageclient");
const SUPPORTED_EXTENSIONS = ["css", "scss", "less"];
const SUPPORTED_EXTENSION_REGEX = /\.(css|scss|less)$/;
let defaultClient;
const clients = new Map();
let _sortedWorkspaceFolders;
function sortedWorkspaceFolders() {
if (_sortedWorkspaceFolders === void 0) {
_sortedWorkspaceFolders = vscode_1.workspace.workspaceFolders
? vscode_1.workspace.workspaceFolders
.map((folder) => {
let result = folder.uri.toString();
if (result.charAt(result.length - 1) !== "/") {
result = result + "/";
}
return result;
})
.sort((a, b) => {
return a.length - b.length;
})
: [];
}
return _sortedWorkspaceFolders;
}
vscode_1.workspace.onDidChangeWorkspaceFolders(() => (_sortedWorkspaceFolders = undefined));
function getOuterMostWorkspaceFolder(folder) {
const sorted = sortedWorkspaceFolders();
for (const element of sorted) {
let uri = folder.uri.toString();
if (uri.charAt(uri.length - 1) !== "/") {
uri = uri + "/";
}
if (uri.startsWith(element)) {
return vscode_1.workspace.getWorkspaceFolder(vscode_1.Uri.parse(element));
}
}
return folder;
}
function activate(context) {
const module = context.asAbsolutePath(path.join("server", "out", "server.js"));
const outputChannel = vscode_1.window.createOutputChannel("CSS Peek");
const config = vscode_1.workspace.getConfiguration("cssPeek");
const peekFromLanguages = config.get("peekFromLanguages");
const peekToInclude = SUPPORTED_EXTENSIONS.map((l) => `**/*.${l}`);
const peekToExclude = config.get("peekToExclude");
function didOpenTextDocument(document) {
// TODO: Return if unsupported document.languageId
if (!["file", "untitled"].includes(document.uri.scheme) ||
(!peekFromLanguages.includes(document.languageId) &&
!SUPPORTED_EXTENSION_REGEX.test(document.fileName))) {
return;
}
const documentSelector = [
...SUPPORTED_EXTENSIONS.map((language) => ({
scheme: "file",
language,
})),
...SUPPORTED_EXTENSIONS.map((language) => ({
scheme: "untitled",
language,
})),
...peekFromLanguages.map((language) => ({
scheme: "file",
language,
})),
...peekFromLanguages.map((language) => ({
scheme: "untitled",
language,
})),
];
const uri = document.uri;
// Untitled files go to a default client.
if (uri.scheme === "untitled" && !defaultClient) {
const debugOptions = { execArgv: ["--nolazy", "--inspect=6010"] };
const serverOptions = {
run: { module, transport: vscode_languageclient_1.TransportKind.ipc },
debug: { module, transport: vscode_languageclient_1.TransportKind.ipc, options: debugOptions },
};
const clientOptions = {
documentSelector,
synchronize: {
configurationSection: "cssPeek",
},
initializationOptions: {
stylesheets: [],
peekFromLanguages,
},
diagnosticCollectionName: "css-peek",
outputChannel,
};
defaultClient = new vscode_languageclient_1.LanguageClient("css-peek", "CSS Peek", serverOptions, clientOptions);
defaultClient.registerProposedFeatures();
defaultClient.start();
return;
}
let folder = vscode_1.workspace.getWorkspaceFolder(uri);
// Files outside a folder can't be handled. This might depend on the language.
// Single file languages like JSON might handle files outside the workspace folders.
if (!folder) {
return;
}
// If we have nested workspace folders we only start a server on the outer most workspace folder.
folder = getOuterMostWorkspaceFolder(folder);
if (!clients.has(folder.uri.toString())) {
vscode_1.workspace.findFiles(`{${(peekToInclude || []).join(",")}}`, `{${(peekToExclude || []).join(",")}}`).then((file_searches) => {
const potentialFiles = file_searches.filter((uri) => uri.scheme === "file");
const debugOptions = {
execArgv: ["--nolazy", `--inspect=${6011 + clients.size}`],
};
const serverOptions = {
run: { module, transport: vscode_languageclient_1.TransportKind.ipc },
debug: {
module,
transport: vscode_languageclient_1.TransportKind.ipc,
options: debugOptions,
},
};
const clientOptions = {
documentSelector,
diagnosticCollectionName: "css-peek",
synchronize: {
configurationSection: "cssPeek",
},
initializationOptions: {
stylesheets: potentialFiles.map((u) => ({
uri: u.toString(),
fsPath: u.fsPath,
})),
peekFromLanguages,
},
workspaceFolder: folder,
outputChannel,
};
const client = new vscode_languageclient_1.LanguageClient("css-peek", "CSS Peek", serverOptions, clientOptions);
client.registerProposedFeatures();
client.start();
clients.set(folder.uri.toString(), client);
});
}
}
vscode_1.workspace.onDidOpenTextDocument(didOpenTextDocument);
vscode_1.workspace.textDocuments.forEach(didOpenTextDocument);
vscode_1.workspace.onDidChangeWorkspaceFolders((event) => {
for (const folder of event.removed) {
const client = clients.get(folder.uri.toString());
if (client) {
clients.delete(folder.uri.toString());
client.stop();
}
}
});
}
exports.activate = activate;
function deactivate() {
const promises = [];
if (defaultClient) {
promises.push(defaultClient.stop());
}
for (const client of clients.values()) {
promises.push(client.stop());
}
return Promise.all(promises).then(() => undefined);
}
exports.deactivate = deactivate;
//# sourceMappingURL=extension.js.map

View File

@@ -0,0 +1,20 @@
{
"name": "vscode-css-peek-client-part",
"description": "VSCode part of the language server",
"license": "MIT",
"author": "Pranay Prakash <pranay.gp@gmail.com>",
"repository": {
"type": "git",
"url": "https://github.com/pranaygp/vscode-css-peek.git"
},
"engines": {
"vscode": "^1.33.0"
},
"scripts": {},
"dependencies": {
"vscode-languageclient": "^5.2.1"
},
"devDependencies": {
"@types/vscode": "^1.33.0"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

View File

@@ -0,0 +1,149 @@
{
"name": "vscode-css-peek",
"displayName": "CSS Peek",
"description": "Allow peeking to css ID and class strings as definitions from html files to respective CSS. Allows peek and goto definition.",
"author": "Pranay Prakash <pranay.gp@gmail.com>",
"icon": "css_peek_icon.png",
"license": "MIT",
"version": "4.2.0",
"repository": {
"type": "git",
"url": "https://github.com/pranaygp/vscode-css-peek"
},
"categories": [],
"keywords": [
"definition",
"css",
"scss",
"sass",
"less",
"peek",
"style",
"stylesheet",
"jump to stylesheet",
"multi-root ready"
],
"engines": {
"vscode": "^1.33.0"
},
"main": "./client/out/extension",
"publisher": "pranaygp",
"bugs": {
"url": "https://github.com/pranaygp/vscode-css-peek/issues"
},
"homepage": "https://github.com/pranaygp/vscode-css-peek/blob/master/README.md",
"activationEvents": [
"workspaceContains:**/*.css",
"workspaceContains:**/*.scss",
"workspaceContains:**/*.sass",
"workspaceContains:**/*.less"
],
"contributes": {
"configuration": {
"type": "object",
"title": "CSS Peek",
"properties": {
"cssPeek.enable": {
"scope": "window",
"type": "boolean",
"default": true,
"description": "Controls the enablement."
},
"cssPeek.supportTags": {
"scope": "window",
"type": "boolean",
"default": true,
"description": "Enable Peeking from HTML tags in addition to classnames and IDs. React components are ignored, but it's a good idea to disable this feature when using Angular"
},
"cssPeek.peekFromLanguages": {
"scope": "window",
"type": "array",
"default": [
"html",
"django-html",
"laravel-blade",
"razor",
"vue",
"blade",
"pug",
"jade",
"handlebars",
"php",
"twig",
"md",
"nunjucks",
"javascript",
"javascriptreact",
"erb",
"typescript",
"typescriptreact",
"HTML (Eex)",
"html-eex",
"ejs"
],
"items": {
"type": "string"
},
"description": "A list of vscode language names where the extension should be used."
},
"cssPeek.peekToExclude": {
"scope": "window",
"type": "array",
"default": [
"**/node_modules/**",
"**/bower_components/**"
],
"items": {
"type": "string"
},
"description": "A list of file globs that filters out peekable files"
},
"cssPeek.trace.server": {
"scope": "window",
"type": "string",
"enum": [
"off",
"messages",
"verbose"
],
"default": "off",
"description": "Traces the communication between VSCode and the language server."
}
}
}
},
"capabilities": {
"untrustedWorkspaces": {
"supported": true
}
},
"scripts": {
"vscode:prepublish": "yarn run compile",
"compile": "tsc -b",
"prettier": "prettier './{server,client,tests}/**/*' -c",
"lint": "yarn run eslint . --ext ts",
"watch": "tsc -b -w",
"test": "nyc node tests/out/runTest.js",
"posttest": "nyc report --reporter=json && codecov -f coverage/*.json",
"postinstall": "cd client && yarn && cd ../server && yarn && cd ../tests && yarn && cd .."
},
"devDependencies": {
"@types/mocha": "^8.0.0",
"@types/node": "^14.0.24",
"@typescript-eslint/eslint-plugin": "^3.7.0",
"@typescript-eslint/parser": "^3.7.0",
"codecov": "^3.7.2",
"eslint": "^7.5.0",
"mocha": "^8.3.2",
"nyc": "^15.1.0",
"prettier": "^2.0.5",
"typescript": "^3.9.7"
},
"__metadata": {
"id": "0b8f8d63-11a2-4194-969c-ca7488b3413a",
"publisherId": "3975bc66-f8bb-46a9-b8b6-430f013e4fa5",
"publisherDisplayName": "Pranay Prakash",
"isPreReleaseVersion": false,
"installedTimestamp": 1641229819949
}
}

View File

@@ -0,0 +1,70 @@
#!/usr/bin/env node
var path = require('path');
var fs = require('fs');
var cp = require('child_process');
var extensionDirectory = process.argv[2];
if (!extensionDirectory) {
console.error('No extension directory provided.');
process.exit(1)
}
extensionDirectory = path.resolve(extensionDirectory)
if (!fs.existsSync(extensionDirectory)) {
console.error('Extension directory ' + extensionDirectory + ' doesn\'t exist on disk.');
process.exit(1);
}
var packageFile = process.argv[3];
if (!packageFile) {
console.error('No package.json file provided.');
process.exit(1);
}
packageFile = path.resolve(packageFile);
if (!fs.existsSync(packageFile)) {
console.error('Package file ' + packageFile + ' doesn\'t exist on disk.');
process.exit(1);
}
var tsconfigFile = process.argv[4];
if (!tsconfigFile) {
console.error('No tsconfig.json file provided');
process.exit(1);
}
tsconfigFile = path.resolve(tsconfigFile);
if (!fs.existsSync(tsconfigFile)) {
console.error('tsconfig file ' + tsconfigFile + ' doesn\'t exist on disk.')
process.exit(1);
}
var extensionServerDirectory = path.join(extensionDirectory, 'server')
var json = require(tsconfigFile);
var compilerOptions = json.compilerOptions;
if (compilerOptions) {
var outDir = compilerOptions.outDir;
if (!outDir || path.join(path.dirname(tsconfigFile), outDir) !== extensionServerDirectory) {
console.error('outDir in ' + process.argv[4] + ' must point to ' + extensionServerDirectory + ' but it points to ' + path.join(path.dirname(tsconfigFile), outDir));
console.error('Please change outDir in ' + process.argv[4] + ' to ' + path.relative(path.dirname(tsconfigFile), extensionServerDirectory).replace(/\\/g, '/'));
process.exit(1);
}
}
if (!fs.existsSync(extensionServerDirectory)) {
fs.mkdirSync(extensionServerDirectory);
}
var dest = path.join(extensionServerDirectory, 'package.json');
console.log('Copying package.json to extension\'s server location...');
fs.writeFileSync(dest, fs.readFileSync(packageFile));
var shrinkwrapFile = process.argv[5];
if (fs.existsSync(shrinkwrapFile)) {
const shrinkWrapDest = path.join(extensionServerDirectory, 'npm-shrinkwrap.json');
shrinkwrapFile = path.resolve(shrinkwrapFile);
console.log('Copying npm-shrinkwrap.json to extension\'s server location...');
fs.writeFileSync(shrinkWrapDest, fs.readFileSync(shrinkwrapFile));
}
console.log('Updating server npm modules into extension\'s server location...');
cp.execSync('npm update --production --prefix ' + extensionServerDirectory);

View File

@@ -0,0 +1,36 @@
{
"systemParams": "darwin-x64-83",
"modulesFolders": [
"node_modules"
],
"flags": [],
"linkedModules": [
"@windsorio/instatrace",
"instatrace"
],
"topLevelPatterns": [
"minimatch@^3.0.4",
"vscode-css-languageservice@^4.3.0",
"vscode-html-languageservice@^3.1.0",
"vscode-languageserver@^5.2.1"
],
"lockfileEntries": {
"balanced-match@^1.0.0": "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767",
"brace-expansion@^1.1.7": "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd",
"concat-map@0.0.1": "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b",
"minimatch@^3.0.4": "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083",
"vscode-css-languageservice@^4.3.0": "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.3.0.tgz#40c797d664ab6188cace33cfbb19b037580a9318",
"vscode-html-languageservice@^3.1.0": "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-3.1.0.tgz#265b53bda595e6947b16b0fb8c604e1e58685393",
"vscode-jsonrpc@^4.0.0": "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz#a7bf74ef3254d0a0c272fab15c82128e378b3be9",
"vscode-languageserver-protocol@3.14.1": "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz#b8aab6afae2849c84a8983d39a1cf742417afe2f",
"vscode-languageserver-textdocument@^1.0.1": "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz#178168e87efad6171b372add1dea34f53e5d330f",
"vscode-languageserver-types@3.14.0": "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743",
"vscode-languageserver-types@3.16.0-next.2": "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0-next.2.tgz#940bd15c992295a65eae8ab6b8568a1e8daa3083",
"vscode-languageserver@^5.2.1": "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz#0d2feddd33f92aadf5da32450df498d52f6f14eb",
"vscode-nls@^4.1.2": "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.2.tgz#ca8bf8bb82a0987b32801f9fddfdd2fb9fd3c167",
"vscode-uri@^1.0.6": "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.8.tgz#9769aaececae4026fb6e22359cb38946580ded59",
"vscode-uri@^2.1.2": "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.2.tgz#c8d40de93eb57af31f3c715dd650e2ca2c096f1c"
},
"files": [],
"artifacts": {}
}

View File

@@ -0,0 +1,5 @@
test
.gitignore
.travis.yml
Makefile
example.js

View File

@@ -0,0 +1,21 @@
(MIT)
Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
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.

View File

@@ -0,0 +1,59 @@
'use strict';
module.exports = balanced;
function balanced(a, b, str) {
if (a instanceof RegExp) a = maybeMatch(a, str);
if (b instanceof RegExp) b = maybeMatch(b, str);
var r = range(a, b, str);
return r && {
start: r[0],
end: r[1],
pre: str.slice(0, r[0]),
body: str.slice(r[0] + a.length, r[1]),
post: str.slice(r[1] + b.length)
};
}
function maybeMatch(reg, str) {
var m = str.match(reg);
return m ? m[0] : null;
}
balanced.range = range;
function range(a, b, str) {
var begs, beg, left, right, result;
var ai = str.indexOf(a);
var bi = str.indexOf(b, ai + 1);
var i = ai;
if (ai >= 0 && bi > 0) {
begs = [];
left = str.length;
while (i >= 0 && !result) {
if (i == ai) {
begs.push(i);
ai = str.indexOf(a, i + 1);
} else if (begs.length == 1) {
result = [ begs.pop(), bi ];
} else {
beg = begs.pop();
if (beg < left) {
left = beg;
right = bi;
}
bi = str.indexOf(b, i + 1);
}
i = ai < bi && ai >= 0 ? ai : bi;
}
if (begs.length) {
result = [ left, right ];
}
}
return result;
}

View File

@@ -0,0 +1,49 @@
{
"name": "balanced-match",
"description": "Match balanced character pairs, like \"{\" and \"}\"",
"version": "1.0.0",
"repository": {
"type": "git",
"url": "git://github.com/juliangruber/balanced-match.git"
},
"homepage": "https://github.com/juliangruber/balanced-match",
"main": "index.js",
"scripts": {
"test": "make test",
"bench": "make bench"
},
"dependencies": {},
"devDependencies": {
"matcha": "^0.7.0",
"tape": "^4.6.0"
},
"keywords": [
"match",
"regexp",
"test",
"balanced",
"parse"
],
"author": {
"name": "Julian Gruber",
"email": "mail@juliangruber.com",
"url": "http://juliangruber.com"
},
"license": "MIT",
"testling": {
"files": "test/*.js",
"browsers": [
"ie/8..latest",
"firefox/20..latest",
"firefox/nightly",
"chrome/25..latest",
"chrome/canary",
"opera/12..latest",
"opera/next",
"safari/5.1..latest",
"ipad/6.0..latest",
"iphone/6.0..latest",
"android-browser/4.2..latest"
]
}
}

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
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.

View File

@@ -0,0 +1,201 @@
var concatMap = require('concat-map');
var balanced = require('balanced-match');
module.exports = expandTop;
var escSlash = '\0SLASH'+Math.random()+'\0';
var escOpen = '\0OPEN'+Math.random()+'\0';
var escClose = '\0CLOSE'+Math.random()+'\0';
var escComma = '\0COMMA'+Math.random()+'\0';
var escPeriod = '\0PERIOD'+Math.random()+'\0';
function numeric(str) {
return parseInt(str, 10) == str
? parseInt(str, 10)
: str.charCodeAt(0);
}
function escapeBraces(str) {
return str.split('\\\\').join(escSlash)
.split('\\{').join(escOpen)
.split('\\}').join(escClose)
.split('\\,').join(escComma)
.split('\\.').join(escPeriod);
}
function unescapeBraces(str) {
return str.split(escSlash).join('\\')
.split(escOpen).join('{')
.split(escClose).join('}')
.split(escComma).join(',')
.split(escPeriod).join('.');
}
// Basically just str.split(","), but handling cases
// where we have nested braced sections, which should be
// treated as individual members, like {a,{b,c},d}
function parseCommaParts(str) {
if (!str)
return [''];
var parts = [];
var m = balanced('{', '}', str);
if (!m)
return str.split(',');
var pre = m.pre;
var body = m.body;
var post = m.post;
var p = pre.split(',');
p[p.length-1] += '{' + body + '}';
var postParts = parseCommaParts(post);
if (post.length) {
p[p.length-1] += postParts.shift();
p.push.apply(p, postParts);
}
parts.push.apply(parts, p);
return parts;
}
function expandTop(str) {
if (!str)
return [];
// I don't know why Bash 4.3 does this, but it does.
// Anything starting with {} will have the first two bytes preserved
// but *only* at the top level, so {},a}b will not expand to anything,
// but a{},b}c will be expanded to [a}c,abc].
// One could argue that this is a bug in Bash, but since the goal of
// this module is to match Bash's rules, we escape a leading {}
if (str.substr(0, 2) === '{}') {
str = '\\{\\}' + str.substr(2);
}
return expand(escapeBraces(str), true).map(unescapeBraces);
}
function identity(e) {
return e;
}
function embrace(str) {
return '{' + str + '}';
}
function isPadded(el) {
return /^-?0\d/.test(el);
}
function lte(i, y) {
return i <= y;
}
function gte(i, y) {
return i >= y;
}
function expand(str, isTop) {
var expansions = [];
var m = balanced('{', '}', str);
if (!m || /\$$/.test(m.pre)) return [str];
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
var isSequence = isNumericSequence || isAlphaSequence;
var isOptions = m.body.indexOf(',') >= 0;
if (!isSequence && !isOptions) {
// {a},b}
if (m.post.match(/,.*\}/)) {
str = m.pre + '{' + m.body + escClose + m.post;
return expand(str);
}
return [str];
}
var n;
if (isSequence) {
n = m.body.split(/\.\./);
} else {
n = parseCommaParts(m.body);
if (n.length === 1) {
// x{{a,b}}y ==> x{a}y x{b}y
n = expand(n[0], false).map(embrace);
if (n.length === 1) {
var post = m.post.length
? expand(m.post, false)
: [''];
return post.map(function(p) {
return m.pre + n[0] + p;
});
}
}
}
// at this point, n is the parts, and we know it's not a comma set
// with a single entry.
// no need to expand pre, since it is guaranteed to be free of brace-sets
var pre = m.pre;
var post = m.post.length
? expand(m.post, false)
: [''];
var N;
if (isSequence) {
var x = numeric(n[0]);
var y = numeric(n[1]);
var width = Math.max(n[0].length, n[1].length)
var incr = n.length == 3
? Math.abs(numeric(n[2]))
: 1;
var test = lte;
var reverse = y < x;
if (reverse) {
incr *= -1;
test = gte;
}
var pad = n.some(isPadded);
N = [];
for (var i = x; test(i, y); i += incr) {
var c;
if (isAlphaSequence) {
c = String.fromCharCode(i);
if (c === '\\')
c = '';
} else {
c = String(i);
if (pad) {
var need = width - c.length;
if (need > 0) {
var z = new Array(need + 1).join('0');
if (i < 0)
c = '-' + z + c.slice(1);
else
c = z + c;
}
}
}
N.push(c);
}
} else {
N = concatMap(n, function(el) { return expand(el, false) });
}
for (var j = 0; j < N.length; j++) {
for (var k = 0; k < post.length; k++) {
var expansion = pre + N[j] + post[k];
if (!isTop || isSequence || expansion)
expansions.push(expansion);
}
}
return expansions;
}

View File

@@ -0,0 +1,47 @@
{
"name": "brace-expansion",
"description": "Brace expansion as known from sh/bash",
"version": "1.1.11",
"repository": {
"type": "git",
"url": "git://github.com/juliangruber/brace-expansion.git"
},
"homepage": "https://github.com/juliangruber/brace-expansion",
"main": "index.js",
"scripts": {
"test": "tape test/*.js",
"gentest": "bash test/generate.sh",
"bench": "matcha test/perf/bench.js"
},
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
},
"devDependencies": {
"matcha": "^0.7.0",
"tape": "^4.6.0"
},
"keywords": [],
"author": {
"name": "Julian Gruber",
"email": "mail@juliangruber.com",
"url": "http://juliangruber.com"
},
"license": "MIT",
"testling": {
"files": "test/*.js",
"browsers": [
"ie/8..latest",
"firefox/20..latest",
"firefox/nightly",
"chrome/25..latest",
"chrome/canary",
"opera/12..latest",
"opera/next",
"safari/5.1..latest",
"ipad/6.0..latest",
"iphone/6.0..latest",
"android-browser/4.2..latest"
]
}
}

View File

@@ -0,0 +1,18 @@
This software is released under the MIT license:
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.

View File

@@ -0,0 +1,62 @@
concat-map
==========
Concatenative mapdashery.
[![browser support](http://ci.testling.com/substack/node-concat-map.png)](http://ci.testling.com/substack/node-concat-map)
[![build status](https://secure.travis-ci.org/substack/node-concat-map.png)](http://travis-ci.org/substack/node-concat-map)
example
=======
``` js
var concatMap = require('concat-map');
var xs = [ 1, 2, 3, 4, 5, 6 ];
var ys = concatMap(xs, function (x) {
return x % 2 ? [ x - 0.1, x, x + 0.1 ] : [];
});
console.dir(ys);
```
***
```
[ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ]
```
methods
=======
``` js
var concatMap = require('concat-map')
```
concatMap(xs, fn)
-----------------
Return an array of concatenated elements by calling `fn(x, i)` for each element
`x` and each index `i` in the array `xs`.
When `fn(x, i)` returns an array, its result will be concatenated with the
result array. If `fn(x, i)` returns anything else, that value will be pushed
onto the end of the result array.
install
=======
With [npm](http://npmjs.org) do:
```
npm install concat-map
```
license
=======
MIT
notes
=====
This module was written while sitting high above the ground in a tree.

View File

@@ -0,0 +1,6 @@
var concatMap = require('../');
var xs = [ 1, 2, 3, 4, 5, 6 ];
var ys = concatMap(xs, function (x) {
return x % 2 ? [ x - 0.1, x, x + 0.1 ] : [];
});
console.dir(ys);

View File

@@ -0,0 +1,13 @@
module.exports = function (xs, fn) {
var res = [];
for (var i = 0; i < xs.length; i++) {
var x = fn(xs[i], i);
if (isArray(x)) res.push.apply(res, x);
else res.push(x);
}
return res;
};
var isArray = Array.isArray || function (xs) {
return Object.prototype.toString.call(xs) === '[object Array]';
};

View File

@@ -0,0 +1,43 @@
{
"name" : "concat-map",
"description" : "concatenative mapdashery",
"version" : "0.0.1",
"repository" : {
"type" : "git",
"url" : "git://github.com/substack/node-concat-map.git"
},
"main" : "index.js",
"keywords" : [
"concat",
"concatMap",
"map",
"functional",
"higher-order"
],
"directories" : {
"example" : "example",
"test" : "test"
},
"scripts" : {
"test" : "tape test/*.js"
},
"devDependencies" : {
"tape" : "~2.4.0"
},
"license" : "MIT",
"author" : {
"name" : "James Halliday",
"email" : "mail@substack.net",
"url" : "http://substack.net"
},
"testling" : {
"files" : "test/*.js",
"browsers" : {
"ie" : [ 6, 7, 8, 9 ],
"ff" : [ 3.5, 10, 15.0 ],
"chrome" : [ 10, 22 ],
"safari" : [ 5.1 ],
"opera" : [ 12 ]
}
}
}

View File

@@ -0,0 +1,39 @@
var concatMap = require('../');
var test = require('tape');
test('empty or not', function (t) {
var xs = [ 1, 2, 3, 4, 5, 6 ];
var ixes = [];
var ys = concatMap(xs, function (x, ix) {
ixes.push(ix);
return x % 2 ? [ x - 0.1, x, x + 0.1 ] : [];
});
t.same(ys, [ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ]);
t.same(ixes, [ 0, 1, 2, 3, 4, 5 ]);
t.end();
});
test('always something', function (t) {
var xs = [ 'a', 'b', 'c', 'd' ];
var ys = concatMap(xs, function (x) {
return x === 'b' ? [ 'B', 'B', 'B' ] : [ x ];
});
t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]);
t.end();
});
test('scalars', function (t) {
var xs = [ 'a', 'b', 'c', 'd' ];
var ys = concatMap(xs, function (x) {
return x === 'b' ? [ 'B', 'B', 'B' ] : x;
});
t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]);
t.end();
});
test('undefs', function (t) {
var xs = [ 'a', 'b', 'c', 'd' ];
var ys = concatMap(xs, function () {});
t.same(ys, [ undefined, undefined, undefined, undefined ]);
t.end();
});

View File

@@ -0,0 +1,15 @@
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@@ -0,0 +1,923 @@
module.exports = minimatch
minimatch.Minimatch = Minimatch
var path = { sep: '/' }
try {
path = require('path')
} catch (er) {}
var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
var expand = require('brace-expansion')
var plTypes = {
'!': { open: '(?:(?!(?:', close: '))[^/]*?)'},
'?': { open: '(?:', close: ')?' },
'+': { open: '(?:', close: ')+' },
'*': { open: '(?:', close: ')*' },
'@': { open: '(?:', close: ')' }
}
// any single thing other than /
// don't need to escape / when using new RegExp()
var qmark = '[^/]'
// * => any number of characters
var star = qmark + '*?'
// ** when dots are allowed. Anything goes, except .. and .
// not (^ or / followed by one or two dots followed by $ or /),
// followed by anything, any number of times.
var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'
// not a ^ or / followed by a dot,
// followed by anything, any number of times.
var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'
// characters that need to be escaped in RegExp.
var reSpecials = charSet('().*{}+?[]^$\\!')
// "abc" -> { a:true, b:true, c:true }
function charSet (s) {
return s.split('').reduce(function (set, c) {
set[c] = true
return set
}, {})
}
// normalizes slashes.
var slashSplit = /\/+/
minimatch.filter = filter
function filter (pattern, options) {
options = options || {}
return function (p, i, list) {
return minimatch(p, pattern, options)
}
}
function ext (a, b) {
a = a || {}
b = b || {}
var t = {}
Object.keys(b).forEach(function (k) {
t[k] = b[k]
})
Object.keys(a).forEach(function (k) {
t[k] = a[k]
})
return t
}
minimatch.defaults = function (def) {
if (!def || !Object.keys(def).length) return minimatch
var orig = minimatch
var m = function minimatch (p, pattern, options) {
return orig.minimatch(p, pattern, ext(def, options))
}
m.Minimatch = function Minimatch (pattern, options) {
return new orig.Minimatch(pattern, ext(def, options))
}
return m
}
Minimatch.defaults = function (def) {
if (!def || !Object.keys(def).length) return Minimatch
return minimatch.defaults(def).Minimatch
}
function minimatch (p, pattern, options) {
if (typeof pattern !== 'string') {
throw new TypeError('glob pattern string required')
}
if (!options) options = {}
// shortcut: comments match nothing.
if (!options.nocomment && pattern.charAt(0) === '#') {
return false
}
// "" only matches ""
if (pattern.trim() === '') return p === ''
return new Minimatch(pattern, options).match(p)
}
function Minimatch (pattern, options) {
if (!(this instanceof Minimatch)) {
return new Minimatch(pattern, options)
}
if (typeof pattern !== 'string') {
throw new TypeError('glob pattern string required')
}
if (!options) options = {}
pattern = pattern.trim()
// windows support: need to use /, not \
if (path.sep !== '/') {
pattern = pattern.split(path.sep).join('/')
}
this.options = options
this.set = []
this.pattern = pattern
this.regexp = null
this.negate = false
this.comment = false
this.empty = false
// make the set of regexps etc.
this.make()
}
Minimatch.prototype.debug = function () {}
Minimatch.prototype.make = make
function make () {
// don't do it more than once.
if (this._made) return
var pattern = this.pattern
var options = this.options
// empty patterns and comments match nothing.
if (!options.nocomment && pattern.charAt(0) === '#') {
this.comment = true
return
}
if (!pattern) {
this.empty = true
return
}
// step 1: figure out negation, etc.
this.parseNegate()
// step 2: expand braces
var set = this.globSet = this.braceExpand()
if (options.debug) this.debug = console.error
this.debug(this.pattern, set)
// step 3: now we have a set, so turn each one into a series of path-portion
// matching patterns.
// These will be regexps, except in the case of "**", which is
// set to the GLOBSTAR object for globstar behavior,
// and will not contain any / characters
set = this.globParts = set.map(function (s) {
return s.split(slashSplit)
})
this.debug(this.pattern, set)
// glob --> regexps
set = set.map(function (s, si, set) {
return s.map(this.parse, this)
}, this)
this.debug(this.pattern, set)
// filter out everything that didn't compile properly.
set = set.filter(function (s) {
return s.indexOf(false) === -1
})
this.debug(this.pattern, set)
this.set = set
}
Minimatch.prototype.parseNegate = parseNegate
function parseNegate () {
var pattern = this.pattern
var negate = false
var options = this.options
var negateOffset = 0
if (options.nonegate) return
for (var i = 0, l = pattern.length
; i < l && pattern.charAt(i) === '!'
; i++) {
negate = !negate
negateOffset++
}
if (negateOffset) this.pattern = pattern.substr(negateOffset)
this.negate = negate
}
// Brace expansion:
// a{b,c}d -> abd acd
// a{b,}c -> abc ac
// a{0..3}d -> a0d a1d a2d a3d
// a{b,c{d,e}f}g -> abg acdfg acefg
// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
//
// Invalid sets are not expanded.
// a{2..}b -> a{2..}b
// a{b}c -> a{b}c
minimatch.braceExpand = function (pattern, options) {
return braceExpand(pattern, options)
}
Minimatch.prototype.braceExpand = braceExpand
function braceExpand (pattern, options) {
if (!options) {
if (this instanceof Minimatch) {
options = this.options
} else {
options = {}
}
}
pattern = typeof pattern === 'undefined'
? this.pattern : pattern
if (typeof pattern === 'undefined') {
throw new TypeError('undefined pattern')
}
if (options.nobrace ||
!pattern.match(/\{.*\}/)) {
// shortcut. no need to expand.
return [pattern]
}
return expand(pattern)
}
// parse a component of the expanded set.
// At this point, no pattern may contain "/" in it
// so we're going to return a 2d array, where each entry is the full
// pattern, split on '/', and then turned into a regular expression.
// A regexp is made at the end which joins each array with an
// escaped /, and another full one which joins each regexp with |.
//
// Following the lead of Bash 4.1, note that "**" only has special meaning
// when it is the *only* thing in a path portion. Otherwise, any series
// of * is equivalent to a single *. Globstar behavior is enabled by
// default, and can be disabled by setting options.noglobstar.
Minimatch.prototype.parse = parse
var SUBPARSE = {}
function parse (pattern, isSub) {
if (pattern.length > 1024 * 64) {
throw new TypeError('pattern is too long')
}
var options = this.options
// shortcuts
if (!options.noglobstar && pattern === '**') return GLOBSTAR
if (pattern === '') return ''
var re = ''
var hasMagic = !!options.nocase
var escaping = false
// ? => one single character
var patternListStack = []
var negativeLists = []
var stateChar
var inClass = false
var reClassStart = -1
var classStart = -1
// . and .. never match anything that doesn't start with .,
// even when options.dot is set.
var patternStart = pattern.charAt(0) === '.' ? '' // anything
// not (start or / followed by . or .. followed by / or end)
: options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))'
: '(?!\\.)'
var self = this
function clearStateChar () {
if (stateChar) {
// we had some state-tracking character
// that wasn't consumed by this pass.
switch (stateChar) {
case '*':
re += star
hasMagic = true
break
case '?':
re += qmark
hasMagic = true
break
default:
re += '\\' + stateChar
break
}
self.debug('clearStateChar %j %j', stateChar, re)
stateChar = false
}
}
for (var i = 0, len = pattern.length, c
; (i < len) && (c = pattern.charAt(i))
; i++) {
this.debug('%s\t%s %s %j', pattern, i, re, c)
// skip over any that are escaped.
if (escaping && reSpecials[c]) {
re += '\\' + c
escaping = false
continue
}
switch (c) {
case '/':
// completely not allowed, even escaped.
// Should already be path-split by now.
return false
case '\\':
clearStateChar()
escaping = true
continue
// the various stateChar values
// for the "extglob" stuff.
case '?':
case '*':
case '+':
case '@':
case '!':
this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c)
// all of those are literals inside a class, except that
// the glob [!a] means [^a] in regexp
if (inClass) {
this.debug(' in class')
if (c === '!' && i === classStart + 1) c = '^'
re += c
continue
}
// if we already have a stateChar, then it means
// that there was something like ** or +? in there.
// Handle the stateChar, then proceed with this one.
self.debug('call clearStateChar %j', stateChar)
clearStateChar()
stateChar = c
// if extglob is disabled, then +(asdf|foo) isn't a thing.
// just clear the statechar *now*, rather than even diving into
// the patternList stuff.
if (options.noext) clearStateChar()
continue
case '(':
if (inClass) {
re += '('
continue
}
if (!stateChar) {
re += '\\('
continue
}
patternListStack.push({
type: stateChar,
start: i - 1,
reStart: re.length,
open: plTypes[stateChar].open,
close: plTypes[stateChar].close
})
// negation is (?:(?!js)[^/]*)
re += stateChar === '!' ? '(?:(?!(?:' : '(?:'
this.debug('plType %j %j', stateChar, re)
stateChar = false
continue
case ')':
if (inClass || !patternListStack.length) {
re += '\\)'
continue
}
clearStateChar()
hasMagic = true
var pl = patternListStack.pop()
// negation is (?:(?!js)[^/]*)
// The others are (?:<pattern>)<type>
re += pl.close
if (pl.type === '!') {
negativeLists.push(pl)
}
pl.reEnd = re.length
continue
case '|':
if (inClass || !patternListStack.length || escaping) {
re += '\\|'
escaping = false
continue
}
clearStateChar()
re += '|'
continue
// these are mostly the same in regexp and glob
case '[':
// swallow any state-tracking char before the [
clearStateChar()
if (inClass) {
re += '\\' + c
continue
}
inClass = true
classStart = i
reClassStart = re.length
re += c
continue
case ']':
// a right bracket shall lose its special
// meaning and represent itself in
// a bracket expression if it occurs
// first in the list. -- POSIX.2 2.8.3.2
if (i === classStart + 1 || !inClass) {
re += '\\' + c
escaping = false
continue
}
// handle the case where we left a class open.
// "[z-a]" is valid, equivalent to "\[z-a\]"
if (inClass) {
// split where the last [ was, make sure we don't have
// an invalid re. if so, re-walk the contents of the
// would-be class to re-translate any characters that
// were passed through as-is
// TODO: It would probably be faster to determine this
// without a try/catch and a new RegExp, but it's tricky
// to do safely. For now, this is safe and works.
var cs = pattern.substring(classStart + 1, i)
try {
RegExp('[' + cs + ']')
} catch (er) {
// not a valid class!
var sp = this.parse(cs, SUBPARSE)
re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'
hasMagic = hasMagic || sp[1]
inClass = false
continue
}
}
// finish up the class.
hasMagic = true
inClass = false
re += c
continue
default:
// swallow any state char that wasn't consumed
clearStateChar()
if (escaping) {
// no need
escaping = false
} else if (reSpecials[c]
&& !(c === '^' && inClass)) {
re += '\\'
}
re += c
} // switch
} // for
// handle the case where we left a class open.
// "[abc" is valid, equivalent to "\[abc"
if (inClass) {
// split where the last [ was, and escape it
// this is a huge pita. We now have to re-walk
// the contents of the would-be class to re-translate
// any characters that were passed through as-is
cs = pattern.substr(classStart + 1)
sp = this.parse(cs, SUBPARSE)
re = re.substr(0, reClassStart) + '\\[' + sp[0]
hasMagic = hasMagic || sp[1]
}
// handle the case where we had a +( thing at the *end*
// of the pattern.
// each pattern list stack adds 3 chars, and we need to go through
// and escape any | chars that were passed through as-is for the regexp.
// Go through and escape them, taking care not to double-escape any
// | chars that were already escaped.
for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {
var tail = re.slice(pl.reStart + pl.open.length)
this.debug('setting tail', re, pl)
// maybe some even number of \, then maybe 1 \, followed by a |
tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) {
if (!$2) {
// the | isn't already escaped, so escape it.
$2 = '\\'
}
// need to escape all those slashes *again*, without escaping the
// one that we need for escaping the | character. As it works out,
// escaping an even number of slashes can be done by simply repeating
// it exactly after itself. That's why this trick works.
//
// I am sorry that you have to see this.
return $1 + $1 + $2 + '|'
})
this.debug('tail=%j\n %s', tail, tail, pl, re)
var t = pl.type === '*' ? star
: pl.type === '?' ? qmark
: '\\' + pl.type
hasMagic = true
re = re.slice(0, pl.reStart) + t + '\\(' + tail
}
// handle trailing things that only matter at the very end.
clearStateChar()
if (escaping) {
// trailing \\
re += '\\\\'
}
// only need to apply the nodot start if the re starts with
// something that could conceivably capture a dot
var addPatternStart = false
switch (re.charAt(0)) {
case '.':
case '[':
case '(': addPatternStart = true
}
// Hack to work around lack of negative lookbehind in JS
// A pattern like: *.!(x).!(y|z) needs to ensure that a name
// like 'a.xyz.yz' doesn't match. So, the first negative
// lookahead, has to look ALL the way ahead, to the end of
// the pattern.
for (var n = negativeLists.length - 1; n > -1; n--) {
var nl = negativeLists[n]
var nlBefore = re.slice(0, nl.reStart)
var nlFirst = re.slice(nl.reStart, nl.reEnd - 8)
var nlLast = re.slice(nl.reEnd - 8, nl.reEnd)
var nlAfter = re.slice(nl.reEnd)
nlLast += nlAfter
// Handle nested stuff like *(*.js|!(*.json)), where open parens
// mean that we should *not* include the ) in the bit that is considered
// "after" the negated section.
var openParensBefore = nlBefore.split('(').length - 1
var cleanAfter = nlAfter
for (i = 0; i < openParensBefore; i++) {
cleanAfter = cleanAfter.replace(/\)[+*?]?/, '')
}
nlAfter = cleanAfter
var dollar = ''
if (nlAfter === '' && isSub !== SUBPARSE) {
dollar = '$'
}
var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast
re = newRe
}
// if the re is not "" at this point, then we need to make sure
// it doesn't match against an empty path part.
// Otherwise a/* will match a/, which it should not.
if (re !== '' && hasMagic) {
re = '(?=.)' + re
}
if (addPatternStart) {
re = patternStart + re
}
// parsing just a piece of a larger pattern.
if (isSub === SUBPARSE) {
return [re, hasMagic]
}
// skip the regexp for non-magical patterns
// unescape anything in it, though, so that it'll be
// an exact match against a file etc.
if (!hasMagic) {
return globUnescape(pattern)
}
var flags = options.nocase ? 'i' : ''
try {
var regExp = new RegExp('^' + re + '$', flags)
} catch (er) {
// If it was an invalid regular expression, then it can't match
// anything. This trick looks for a character after the end of
// the string, which is of course impossible, except in multi-line
// mode, but it's not a /m regex.
return new RegExp('$.')
}
regExp._glob = pattern
regExp._src = re
return regExp
}
minimatch.makeRe = function (pattern, options) {
return new Minimatch(pattern, options || {}).makeRe()
}
Minimatch.prototype.makeRe = makeRe
function makeRe () {
if (this.regexp || this.regexp === false) return this.regexp
// at this point, this.set is a 2d array of partial
// pattern strings, or "**".
//
// It's better to use .match(). This function shouldn't
// be used, really, but it's pretty convenient sometimes,
// when you just want to work with a regex.
var set = this.set
if (!set.length) {
this.regexp = false
return this.regexp
}
var options = this.options
var twoStar = options.noglobstar ? star
: options.dot ? twoStarDot
: twoStarNoDot
var flags = options.nocase ? 'i' : ''
var re = set.map(function (pattern) {
return pattern.map(function (p) {
return (p === GLOBSTAR) ? twoStar
: (typeof p === 'string') ? regExpEscape(p)
: p._src
}).join('\\\/')
}).join('|')
// must match entire pattern
// ending in a * or ** will make it less strict.
re = '^(?:' + re + ')$'
// can match anything, as long as it's not this.
if (this.negate) re = '^(?!' + re + ').*$'
try {
this.regexp = new RegExp(re, flags)
} catch (ex) {
this.regexp = false
}
return this.regexp
}
minimatch.match = function (list, pattern, options) {
options = options || {}
var mm = new Minimatch(pattern, options)
list = list.filter(function (f) {
return mm.match(f)
})
if (mm.options.nonull && !list.length) {
list.push(pattern)
}
return list
}
Minimatch.prototype.match = match
function match (f, partial) {
this.debug('match', f, this.pattern)
// short-circuit in the case of busted things.
// comments, etc.
if (this.comment) return false
if (this.empty) return f === ''
if (f === '/' && partial) return true
var options = this.options
// windows: need to use /, not \
if (path.sep !== '/') {
f = f.split(path.sep).join('/')
}
// treat the test path as a set of pathparts.
f = f.split(slashSplit)
this.debug(this.pattern, 'split', f)
// just ONE of the pattern sets in this.set needs to match
// in order for it to be valid. If negating, then just one
// match means that we have failed.
// Either way, return on the first hit.
var set = this.set
this.debug(this.pattern, 'set', set)
// Find the basename of the path by looking for the last non-empty segment
var filename
var i
for (i = f.length - 1; i >= 0; i--) {
filename = f[i]
if (filename) break
}
for (i = 0; i < set.length; i++) {
var pattern = set[i]
var file = f
if (options.matchBase && pattern.length === 1) {
file = [filename]
}
var hit = this.matchOne(file, pattern, partial)
if (hit) {
if (options.flipNegate) return true
return !this.negate
}
}
// didn't get any hits. this is success if it's a negative
// pattern, failure otherwise.
if (options.flipNegate) return false
return this.negate
}
// set partial to true to test if, for example,
// "/a/b" matches the start of "/*/b/*/d"
// Partial means, if you run out of file before you run
// out of pattern, then that's fine, as long as all
// the parts match.
Minimatch.prototype.matchOne = function (file, pattern, partial) {
var options = this.options
this.debug('matchOne',
{ 'this': this, file: file, pattern: pattern })
this.debug('matchOne', file.length, pattern.length)
for (var fi = 0,
pi = 0,
fl = file.length,
pl = pattern.length
; (fi < fl) && (pi < pl)
; fi++, pi++) {
this.debug('matchOne loop')
var p = pattern[pi]
var f = file[fi]
this.debug(pattern, p, f)
// should be impossible.
// some invalid regexp stuff in the set.
if (p === false) return false
if (p === GLOBSTAR) {
this.debug('GLOBSTAR', [pattern, p, f])
// "**"
// a/**/b/**/c would match the following:
// a/b/x/y/z/c
// a/x/y/z/b/c
// a/b/x/b/x/c
// a/b/c
// To do this, take the rest of the pattern after
// the **, and see if it would match the file remainder.
// If so, return success.
// If not, the ** "swallows" a segment, and try again.
// This is recursively awful.
//
// a/**/b/**/c matching a/b/x/y/z/c
// - a matches a
// - doublestar
// - matchOne(b/x/y/z/c, b/**/c)
// - b matches b
// - doublestar
// - matchOne(x/y/z/c, c) -> no
// - matchOne(y/z/c, c) -> no
// - matchOne(z/c, c) -> no
// - matchOne(c, c) yes, hit
var fr = fi
var pr = pi + 1
if (pr === pl) {
this.debug('** at the end')
// a ** at the end will just swallow the rest.
// We have found a match.
// however, it will not swallow /.x, unless
// options.dot is set.
// . and .. are *never* matched by **, for explosively
// exponential reasons.
for (; fi < fl; fi++) {
if (file[fi] === '.' || file[fi] === '..' ||
(!options.dot && file[fi].charAt(0) === '.')) return false
}
return true
}
// ok, let's see if we can swallow whatever we can.
while (fr < fl) {
var swallowee = file[fr]
this.debug('\nglobstar while', file, fr, pattern, pr, swallowee)
// XXX remove this slice. Just pass the start index.
if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
this.debug('globstar found match!', fr, fl, swallowee)
// found a match.
return true
} else {
// can't swallow "." or ".." ever.
// can only swallow ".foo" when explicitly asked.
if (swallowee === '.' || swallowee === '..' ||
(!options.dot && swallowee.charAt(0) === '.')) {
this.debug('dot detected!', file, fr, pattern, pr)
break
}
// ** swallows a segment, and continue.
this.debug('globstar swallow a segment, and continue')
fr++
}
}
// no match was found.
// However, in partial mode, we can't say this is necessarily over.
// If there's more *pattern* left, then
if (partial) {
// ran out of file
this.debug('\n>>> no match, partial?', file, fr, pattern, pr)
if (fr === fl) return true
}
return false
}
// something other than **
// non-magic patterns just have to match exactly
// patterns with magic have been turned into regexps.
var hit
if (typeof p === 'string') {
if (options.nocase) {
hit = f.toLowerCase() === p.toLowerCase()
} else {
hit = f === p
}
this.debug('string match', p, f, hit)
} else {
hit = f.match(p)
this.debug('pattern match', p, f, hit)
}
if (!hit) return false
}
// Note: ending in / means that we'll get a final ""
// at the end of the pattern. This can only match a
// corresponding "" at the end of the file.
// If the file ends in /, then it can only match a
// a pattern that ends in /, unless the pattern just
// doesn't have any more for it. But, a/b/ should *not*
// match "a/b/*", even though "" matches against the
// [^/]*? pattern, except in partial mode, where it might
// simply not be reached yet.
// However, a/b/ should still satisfy a/*
// now either we fell off the end of the pattern, or we're done.
if (fi === fl && pi === pl) {
// ran out of pattern and filename at the same time.
// an exact hit!
return true
} else if (fi === fl) {
// ran out of file, but still had pattern left.
// this is ok if we're doing the match as part of
// a glob fs traversal.
return partial
} else if (pi === pl) {
// ran out of pattern, still have file left.
// this is only acceptable if we're on the very last
// empty segment of a file with a trailing slash.
// a/* should match a/b/
var emptyFileEnd = (fi === fl - 1) && (file[fi] === '')
return emptyFileEnd
}
// should be unreachable.
throw new Error('wtf?')
}
// replace stuff like \* with *
function globUnescape (s) {
return s.replace(/\\(.)/g, '$1')
}
function regExpEscape (s) {
return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
}

View File

@@ -0,0 +1,30 @@
{
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
"name": "minimatch",
"description": "a glob matcher in javascript",
"version": "3.0.4",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/minimatch.git"
},
"main": "minimatch.js",
"scripts": {
"test": "tap test/*.js --cov",
"preversion": "npm test",
"postversion": "npm publish",
"postpublish": "git push origin --all; git push origin --tags"
},
"engines": {
"node": "*"
},
"dependencies": {
"brace-expansion": "^1.1.7"
},
"devDependencies": {
"tap": "^10.3.2"
},
"license": "ISC",
"files": [
"minimatch.js"
]
}

View File

@@ -0,0 +1,71 @@
4.3.0 - 2020-06-26
===================
* module resolving in urls (`~foo/hello.html`) when using `LanguageService.findDocumentLinks2` and if `fileSystemProvider` is provided.
* new API `LanguageService.doComplete2`. Support path completion if `fileSystemProvider.readDirectory` is provided.
* `DocumentContext.resolveReference` can also return undefined (if the ref is invalid)
4.2.0 - 2020-05-14
===================
* new API `LanguageServiceOptions.useDefaultDataProvider` to control whether the default data provider is used. Defaults to true
* new API `LanguageService.setDataProviders` to update the data providers.
4.1.0 - 2020-02-23
===================
* markdown descriptions in completions and hover
* new API `LanguageServiceOptions.clientCapabilities` with `ClientCapabilities` for completion documentationFormat and hover content
* extended format of CustomData (version 1.1) with MarkupContent contents and reference links
* dynamically resolved links for scss include statements
* new API `LanguageService.findDocumentLinks2`: Also returns dynamically resolved links if `fileSystemProvider` is provided
* new API `LanguageServiceOptions.fileSystemProvider` with `FileSystemProvider` to query the file system (currently used to resolve the location of included files)
* new API `CompletionSettings.completePropertyWithSemicolon`
* new API `ICompletionParticipant.onCssMixinReference`
* Switch to `TextDocument` from `vscode-languageserver-textdocument` (reexported from the main module)
4.0.0 / 2019-06-12
===================
* `LanguageServiceOptions.customDataProviders` allows you to use custom datasets for properties, at-properties, pseudo-classes and pseudo-elements.
* New API `LanguageService.getSelectionRanges`
3.0.12 / 2018-10-29
===================
* Selector hover shows specificity
* New linter setting `validProperties`: a comma separated list of all properties not to be included in validation checking.
3.0.10 / 2018-08-27
===================
* New API `ICompletionParticipant.onCssImportPath` to participate on @import statement.
* New API `LanguageService.doCodeActions2` returning code actions as `CodeAction[]`.
3.0.9 / 2018-07-25
==================
* Use MDN data for to enhance CSS properties definition. See [#91](https://github.com/Microsoft/vscode-css-languageservice/pull/91).
* New API `LanguageService.getFoldingRanges` returning folding ranges in the given document.
3.0.8 / 2018-03-08
==================
* Provide ems modules in lib/esm
3.0.0 / 2017-01-11
==================
* Changed API `LanguageService.getColorPresentations`: separate parameters `range` and `color` (to match LS API)
2.1.7 / 2017-09-21
==================
* New API `LanguageService.getColorPresentations` returning presentations for a given color.
* New API type `ColorPresentation` added.
2.1.4 / 2017-08-28
==================
* New API `LanguageService.findDocumentColors` returning the location and value of all colors in a document.
* New API types `ColorInformation` and `Color` added.
* Deprecated `LanguageService.findColorSymbols`. Use `LanguageService.findDocumentColors` instead.
2.1.3 / 2017-08-15
==================
* New argument `documentSettings` to `LanguageService.doValidation` to support resource specific settings. If present, document settings are used instead of the options passed in configure.
2.0.0 / 2017-02-17
==================
* Updating to [language server type 3.0](https://github.com/Microsoft/vscode-languageserver-node/tree/master/types) API.

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Microsoft
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.

View File

@@ -0,0 +1,107 @@
# Custom Data for CSS Language Service
In VS Code, there are two ways of loading custom CSS datasets:
1. With setting `css.customData`
```json
"css.customData": [
"./foo.css-data.json"
]
```
2. With an extension that contributes `contributes.css.customData`
Both setting point to a list of JSON files. This document describes the shape of the JSON files.
You can read more about custom data at: https://github.com/microsoft/vscode-custom-data.
## Custom Data Format
### Overview
The JSON have one required property, `version`, and 4 other top level properties:
```jsonc
{
"version": 1.1,
"properties": [],
"atDirectives": [],
"pseudoClasses": [],
"pseudoElements": []
}
```
Version denotes the schema version you are using. The latest schema version is `V1.1`.
You can find other properties' shapes at [cssLanguageTypes.ts](../src/cssLanguageTypes.ts) or the [JSON Schema](./customData.schema.json).
You should suffix your custom data file with `.css-data.json`, so VS Code will load the most recent schema for the JSON file to offer auto completion and error checking.
### Format
All top-level properties share two basic properties, `name` and `description`. For example:
```jsonc
{
"version": 1.1,
"properties": [
{ "name": "foo", "description": "Foo property" }
],
"atDirectives": [
{ "name": "@foo", "description": "Foo at directive" }
],
"pseudoClasses": [
{ "name": ":foo", "description": "Foo pseudo class" }
],
"pseudoElements": [
{ "name": "::foo", "description": "Foo pseudo elements" }
]
}
```
You can also specify 3 additional properties for them:
```jsonc
{
"properties": [
{
"name": "foo",
"description": "Foo property",
"browsers": [
"E12",
"S10",
"C50",
"IE10",
"O37"
],
"status": "standard",
"references": [
{
"name": "My foo property reference",
"url": "https://www.foo.com/property/foo"
}
]
}
]
}
```
- `browsers`: A list of supported browsers. The format is `browserName + version`. For example: `['E10', 'C30', 'FF20']`. Here are all browser names:
```
export let browserNames = {
E: 'Edge',
FF: 'Firefox',
S: 'Safari',
C: 'Chrome',
IE: 'IE',
O: 'Opera'
};
```
The browser compatibility will be rendered at completion and hover. Items that is supported in only one browser are dropped from completion.
- `status`: The status of the item. The format is:
```
export type EntryStatus = 'standard' | 'experimental' | 'nonstandard' | 'obsolete';
```
The status will be rendered at the top of completion and hover. For example, `nonstandard` items are prefixed with the message `🚨️ Property is nonstandard. Avoid using it.`.
- `references`: A list of references. They will be displayed in Markdown form in completion and hover as `[Ref1 Name](Ref1 URL) | [Ref2 Name](Ref2 URL) | ...`.

View File

@@ -0,0 +1,239 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "vscode-css-customdata",
"version": 1.1,
"title": "VS Code CSS Custom Data format",
"description": "Format for loading Custom Data in VS Code's CSS support",
"type": "object",
"required": ["version"],
"definitions": {
"references": {
"type": "object",
"required": ["name", "url"],
"properties": {
"name": {
"type": "string",
"description": "The name of the reference."
},
"url": {
"type": "string",
"description": "The URL of the reference.",
"pattern": "https?:\/\/",
"patternErrorMessage": "URL should start with http:// or https://"
}
}
},
"markupDescription": {
"type": "object",
"required": ["kind", "value"],
"properties": {
"kind": {
"type": "string",
"description": "Whether `description.value` should be rendered as plaintext or markdown",
"enum": ["plaintext", "markdown"]
},
"value": {
"type": "string",
"description": "Description shown in completion and hover"
}
}
}
},
"properties": {
"version": {
"const": 1.1,
"description": "The custom data version",
"type": "number"
},
"properties": {
"description": "Custom CSS properties",
"type": "array",
"items": {
"type": "object",
"required": ["name"],
"defaultSnippets": [
{
"body": {
"name": "$1",
"description": ""
}
}
],
"properties": {
"name": {
"type": "string",
"description": "Name of property"
},
"description": {
"description": "Description of property shown in completion and hover",
"anyOf": [
{
"type": "string"
},
{ "$ref": "#/definitions/markupDescription" }
]
},
"status": {
"type": "string",
"description": "Browser status",
"enum": ["standard", "experimental", "nonstandard", "obsolete"]
},
"browsers": {
"type": "array",
"description": "Supported browsers",
"items": {
"type": "string",
"pattern": "(E|FF|S|C|IE|O)([\\d|\\.]+)?",
"patternErrorMessage": "Browser item must follow the format of `${browser}${version}`. `browser` is one of:\n- E: Edge\n- FF: Firefox\n- S: Safari\n- C: Chrome\n- IE: Internet Explorer\n- O: Opera"
}
},
"references": {
"type": "array",
"description": "A list of references for the property shown in completion and hover",
"items": {
"$ref": "#/definitions/references"
}
}
}
}
},
"atDirectives": {
"description": "Custom CSS at directives",
"type": "array",
"items": {
"type": "object",
"required": ["name"],
"defaultSnippets": [
{
"body": {
"name": "@$1",
"description": ""
}
}
],
"properties": {
"name": {
"type": "string",
"description": "Name of at directive",
"pattern": "^@.+",
"patternErrorMessage": "Pseudo class must start with `@`"
},
"description": {
"description": "Description of at directive shown in completion and hover",
"anyOf": [
{
"type": "string"
},
{ "$ref": "#/definitions/markupDescription" }
]
},
"status": {
"$ref": "#/properties/properties/items/properties/status"
},
"browsers": {
"$ref": "#/properties/properties/items/properties/browsers"
},
"references": {
"type": "array",
"description": "A list of references for the at-directive shown in completion and hover",
"items": {
"$ref": "#/definitions/references"
}
}
}
}
},
"pseudoClasses": {
"description": "Custom CSS pseudo classes",
"type": "array",
"items": {
"type": "object",
"required": ["name"],
"defaultSnippets": [
{
"body": {
"name": ":$1",
"description": ""
}
}
],
"properties": {
"name": {
"type": "string",
"description": "Name of pseudo class",
"pattern": "^:.+",
"patternErrorMessage": "Pseudo class must start with `:`"
},
"description": {
"description": "Description of pseudo class shown in completion and hover",
"anyOf": [
{
"type": "string"
},
{ "$ref": "#/definitions/markupDescription" }
]
},
"status": {
"$ref": "#/properties/properties/items/properties/status"
},
"browsers": {
"$ref": "#/properties/properties/items/properties/browsers"
},
"references": {
"type": "array",
"description": "A list of references for the pseudo-class shown in completion and hover",
"items": {
"$ref": "#/definitions/references"
}
}
}
}
},
"pseudoElements": {
"description": "Custom CSS pseudo elements",
"type": "array",
"items": {
"type": "object",
"required": ["name"],
"defaultSnippets": [
{
"body": {
"name": "::$1",
"description": ""
}
}
],
"properties": {
"name": {
"type": "string",
"description": "Name of pseudo element",
"pattern": "^::.+",
"patternErrorMessage": "Pseudo class must start with `::`"
},
"description": {
"description": "Description of pseudo element shown in completion and hover",
"anyOf": [
{
"type": "string"
},
{ "$ref": "#/definitions/markupDescription" }
]
},
"status": {
"$ref": "#/properties/properties/items/properties/status"
},
"browsers": {
"$ref": "#/properties/properties/items/properties/browsers"
},
"references": {
"type": "array",
"description": "A list of references for the pseudo-element shown in completion and hover",
"items": {
"$ref": "#/definitions/references"
}
}
}
}
}
}
}

View File

@@ -0,0 +1,73 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { Parser } from './parser/cssParser';
import { CSSCompletion } from './services/cssCompletion';
import { CSSHover } from './services/cssHover';
import { CSSNavigation } from './services/cssNavigation';
import { CSSCodeActions } from './services/cssCodeActions';
import { CSSValidation } from './services/cssValidation';
import { SCSSParser } from './parser/scssParser';
import { SCSSCompletion } from './services/scssCompletion';
import { LESSParser } from './parser/lessParser';
import { LESSCompletion } from './services/lessCompletion';
import { getFoldingRanges } from './services/cssFolding';
import { CSSDataManager } from './languageFacts/dataManager';
import { CSSDataProvider } from './languageFacts/dataProvider';
import { getSelectionRanges } from './services/cssSelectionRange';
import { SCSSNavigation } from './services/scssNavigation';
import { cssData } from './data/webCustomData';
export * from './cssLanguageTypes';
export function getDefaultCSSDataProvider() {
return newCSSDataProvider(cssData);
}
export function newCSSDataProvider(data) {
return new CSSDataProvider(data);
}
function createFacade(parser, completion, hover, navigation, codeActions, validation, cssDataManager) {
return {
configure: function (settings) {
validation.configure(settings);
completion.configure(settings);
},
setDataProviders: cssDataManager.setDataProviders.bind(cssDataManager),
doValidation: validation.doValidation.bind(validation),
parseStylesheet: parser.parseStylesheet.bind(parser),
doComplete: completion.doComplete.bind(completion),
doComplete2: completion.doComplete2.bind(completion),
setCompletionParticipants: completion.setCompletionParticipants.bind(completion),
doHover: hover.doHover.bind(hover),
findDefinition: navigation.findDefinition.bind(navigation),
findReferences: navigation.findReferences.bind(navigation),
findDocumentHighlights: navigation.findDocumentHighlights.bind(navigation),
findDocumentLinks: navigation.findDocumentLinks.bind(navigation),
findDocumentLinks2: navigation.findDocumentLinks2.bind(navigation),
findDocumentSymbols: navigation.findDocumentSymbols.bind(navigation),
doCodeActions: codeActions.doCodeActions.bind(codeActions),
doCodeActions2: codeActions.doCodeActions2.bind(codeActions),
findColorSymbols: function (d, s) { return navigation.findDocumentColors(d, s).map(function (s) { return s.range; }); },
findDocumentColors: navigation.findDocumentColors.bind(navigation),
getColorPresentations: navigation.getColorPresentations.bind(navigation),
doRename: navigation.doRename.bind(navigation),
getFoldingRanges: getFoldingRanges,
getSelectionRanges: getSelectionRanges
};
}
var defaultLanguageServiceOptions = {};
export function getCSSLanguageService(options) {
if (options === void 0) { options = defaultLanguageServiceOptions; }
var cssDataManager = new CSSDataManager(options);
return createFacade(new Parser(), new CSSCompletion(null, options, cssDataManager), new CSSHover(options && options.clientCapabilities, cssDataManager), new CSSNavigation(options && options.fileSystemProvider), new CSSCodeActions(cssDataManager), new CSSValidation(cssDataManager), cssDataManager);
}
export function getSCSSLanguageService(options) {
if (options === void 0) { options = defaultLanguageServiceOptions; }
var cssDataManager = new CSSDataManager(options);
return createFacade(new SCSSParser(), new SCSSCompletion(options, cssDataManager), new CSSHover(options && options.clientCapabilities, cssDataManager), new SCSSNavigation(options && options.fileSystemProvider), new CSSCodeActions(cssDataManager), new CSSValidation(cssDataManager), cssDataManager);
}
export function getLESSLanguageService(options) {
if (options === void 0) { options = defaultLanguageServiceOptions; }
var cssDataManager = new CSSDataManager(options);
return createFacade(new LESSParser(), new LESSCompletion(options, cssDataManager), new CSSHover(options && options.clientCapabilities, cssDataManager), new CSSNavigation(options && options.fileSystemProvider), new CSSCodeActions(cssDataManager), new CSSValidation(cssDataManager), cssDataManager);
}

View File

@@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { MarkupKind } from 'vscode-languageserver-types';
export { TextDocument } from 'vscode-languageserver-textdocument';
export * from 'vscode-languageserver-types';
export var ClientCapabilities;
(function (ClientCapabilities) {
ClientCapabilities.LATEST = {
textDocument: {
completion: {
completionItem: {
documentationFormat: [MarkupKind.Markdown, MarkupKind.PlainText]
}
},
hover: {
contentFormat: [MarkupKind.Markdown, MarkupKind.PlainText]
}
}
};
})(ClientCapabilities || (ClientCapabilities = {}));
export var FileType;
(function (FileType) {
/**
* The file type is unknown.
*/
FileType[FileType["Unknown"] = 0] = "Unknown";
/**
* A regular file.
*/
FileType[FileType["File"] = 1] = "File";
/**
* A directory.
*/
FileType[FileType["Directory"] = 2] = "Directory";
/**
* A symbolic link to a file.
*/
FileType[FileType["SymbolicLink"] = 64] = "SymbolicLink";
})(FileType || (FileType = {}));

View File

@@ -0,0 +1,138 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
export var positionKeywords = {
'bottom': 'Computes to 100% for the vertical position if one or two values are given, otherwise specifies the bottom edge as the origin for the next offset.',
'center': 'Computes to 50% (left 50%) for the horizontal position if the horizontal position is not otherwise specified, or 50% (top 50%) for the vertical position if it is.',
'left': 'Computes to 0% for the horizontal position if one or two values are given, otherwise specifies the left edge as the origin for the next offset.',
'right': 'Computes to 100% for the horizontal position if one or two values are given, otherwise specifies the right edge as the origin for the next offset.',
'top': 'Computes to 0% for the vertical position if one or two values are given, otherwise specifies the top edge as the origin for the next offset.'
};
export var repeatStyleKeywords = {
'no-repeat': 'Placed once and not repeated in this direction.',
'repeat': 'Repeated in this direction as often as needed to cover the background painting area.',
'repeat-x': 'Computes to repeat no-repeat.',
'repeat-y': 'Computes to no-repeat repeat.',
'round': 'Repeated as often as will fit within the background positioning area. If it doesnt fit a whole number of times, it is rescaled so that it does.',
'space': 'Repeated as often as will fit within the background positioning area without being clipped and then the images are spaced out to fill the area.'
};
export var lineStyleKeywords = {
'dashed': 'A series of square-ended dashes.',
'dotted': 'A series of round dots.',
'double': 'Two parallel solid lines with some space between them.',
'groove': 'Looks as if it were carved in the canvas.',
'hidden': 'Same as none, but has different behavior in the border conflict resolution rules for border-collapsed tables.',
'inset': 'Looks as if the content on the inside of the border is sunken into the canvas.',
'none': 'No border. Color and width are ignored.',
'outset': 'Looks as if the content on the inside of the border is coming out of the canvas.',
'ridge': 'Looks as if it were coming out of the canvas.',
'solid': 'A single line segment.'
};
export var lineWidthKeywords = ['medium', 'thick', 'thin'];
export var boxKeywords = {
'border-box': 'The background is painted within (clipped to) the border box.',
'content-box': 'The background is painted within (clipped to) the content box.',
'padding-box': 'The background is painted within (clipped to) the padding box.'
};
export var geometryBoxKeywords = {
'margin-box': 'Uses the margin box as reference box.',
'fill-box': 'Uses the object bounding box as reference box.',
'stroke-box': 'Uses the stroke bounding box as reference box.',
'view-box': 'Uses the nearest SVG viewport as reference box.'
};
export var cssWideKeywords = {
'initial': 'Represents the value specified as the propertys initial value.',
'inherit': 'Represents the computed value of the property on the elements parent.',
'unset': 'Acts as either `inherit` or `initial`, depending on whether the property is inherited or not.'
};
export var imageFunctions = {
'url()': 'Reference an image file by URL',
'image()': 'Provide image fallbacks and annotations.',
'-webkit-image-set()': 'Provide multiple resolutions. Remember to use unprefixed image-set() in addition.',
'image-set()': 'Provide multiple resolutions of an image and const the UA decide which is most appropriate in a given situation.',
'-moz-element()': 'Use an element in the document as an image. Remember to use unprefixed element() in addition.',
'element()': 'Use an element in the document as an image.',
'cross-fade()': 'Indicates the two images to be combined and how far along in the transition the combination is.',
'-webkit-gradient()': 'Deprecated. Use modern linear-gradient() or radial-gradient() instead.',
'-webkit-linear-gradient()': 'Linear gradient. Remember to use unprefixed version in addition.',
'-moz-linear-gradient()': 'Linear gradient. Remember to use unprefixed version in addition.',
'-o-linear-gradient()': 'Linear gradient. Remember to use unprefixed version in addition.',
'linear-gradient()': 'A linear gradient is created by specifying a straight gradient line, and then several colors placed along that line.',
'-webkit-repeating-linear-gradient()': 'Repeating Linear gradient. Remember to use unprefixed version in addition.',
'-moz-repeating-linear-gradient()': 'Repeating Linear gradient. Remember to use unprefixed version in addition.',
'-o-repeating-linear-gradient()': 'Repeating Linear gradient. Remember to use unprefixed version in addition.',
'repeating-linear-gradient()': 'Same as linear-gradient, except the color-stops are repeated infinitely in both directions, with their positions shifted by multiples of the difference between the last specified color-stops position and the first specified color-stops position.',
'-webkit-radial-gradient()': 'Radial gradient. Remember to use unprefixed version in addition.',
'-moz-radial-gradient()': 'Radial gradient. Remember to use unprefixed version in addition.',
'radial-gradient()': 'Colors emerge from a single point and smoothly spread outward in a circular or elliptical shape.',
'-webkit-repeating-radial-gradient()': 'Repeating radial gradient. Remember to use unprefixed version in addition.',
'-moz-repeating-radial-gradient()': 'Repeating radial gradient. Remember to use unprefixed version in addition.',
'repeating-radial-gradient()': 'Same as radial-gradient, except the color-stops are repeated infinitely in both directions, with their positions shifted by multiples of the difference between the last specified color-stops position and the first specified color-stops position.'
};
export var transitionTimingFunctions = {
'ease': 'Equivalent to cubic-bezier(0.25, 0.1, 0.25, 1.0).',
'ease-in': 'Equivalent to cubic-bezier(0.42, 0, 1.0, 1.0).',
'ease-in-out': 'Equivalent to cubic-bezier(0.42, 0, 0.58, 1.0).',
'ease-out': 'Equivalent to cubic-bezier(0, 0, 0.58, 1.0).',
'linear': 'Equivalent to cubic-bezier(0.0, 0.0, 1.0, 1.0).',
'step-end': 'Equivalent to steps(1, end).',
'step-start': 'Equivalent to steps(1, start).',
'steps()': 'The first parameter specifies the number of intervals in the function. The second parameter, which is optional, is either the value “start” or “end”.',
'cubic-bezier()': 'Specifies a cubic-bezier curve. The four values specify points P1 and P2 of the curve as (x1, y1, x2, y2).',
'cubic-bezier(0.6, -0.28, 0.735, 0.045)': 'Ease-in Back. Overshoots.',
'cubic-bezier(0.68, -0.55, 0.265, 1.55)': 'Ease-in-out Back. Overshoots.',
'cubic-bezier(0.175, 0.885, 0.32, 1.275)': 'Ease-out Back. Overshoots.',
'cubic-bezier(0.6, 0.04, 0.98, 0.335)': 'Ease-in Circular. Based on half circle.',
'cubic-bezier(0.785, 0.135, 0.15, 0.86)': 'Ease-in-out Circular. Based on half circle.',
'cubic-bezier(0.075, 0.82, 0.165, 1)': 'Ease-out Circular. Based on half circle.',
'cubic-bezier(0.55, 0.055, 0.675, 0.19)': 'Ease-in Cubic. Based on power of three.',
'cubic-bezier(0.645, 0.045, 0.355, 1)': 'Ease-in-out Cubic. Based on power of three.',
'cubic-bezier(0.215, 0.610, 0.355, 1)': 'Ease-out Cubic. Based on power of three.',
'cubic-bezier(0.95, 0.05, 0.795, 0.035)': 'Ease-in Exponential. Based on two to the power ten.',
'cubic-bezier(1, 0, 0, 1)': 'Ease-in-out Exponential. Based on two to the power ten.',
'cubic-bezier(0.19, 1, 0.22, 1)': 'Ease-out Exponential. Based on two to the power ten.',
'cubic-bezier(0.47, 0, 0.745, 0.715)': 'Ease-in Sine.',
'cubic-bezier(0.445, 0.05, 0.55, 0.95)': 'Ease-in-out Sine.',
'cubic-bezier(0.39, 0.575, 0.565, 1)': 'Ease-out Sine.',
'cubic-bezier(0.55, 0.085, 0.68, 0.53)': 'Ease-in Quadratic. Based on power of two.',
'cubic-bezier(0.455, 0.03, 0.515, 0.955)': 'Ease-in-out Quadratic. Based on power of two.',
'cubic-bezier(0.25, 0.46, 0.45, 0.94)': 'Ease-out Quadratic. Based on power of two.',
'cubic-bezier(0.895, 0.03, 0.685, 0.22)': 'Ease-in Quartic. Based on power of four.',
'cubic-bezier(0.77, 0, 0.175, 1)': 'Ease-in-out Quartic. Based on power of four.',
'cubic-bezier(0.165, 0.84, 0.44, 1)': 'Ease-out Quartic. Based on power of four.',
'cubic-bezier(0.755, 0.05, 0.855, 0.06)': 'Ease-in Quintic. Based on power of five.',
'cubic-bezier(0.86, 0, 0.07, 1)': 'Ease-in-out Quintic. Based on power of five.',
'cubic-bezier(0.23, 1, 0.320, 1)': 'Ease-out Quintic. Based on power of five.'
};
export var basicShapeFunctions = {
'circle()': 'Defines a circle.',
'ellipse()': 'Defines an ellipse.',
'inset()': 'Defines an inset rectangle.',
'polygon()': 'Defines a polygon.'
};
export var units = {
'length': ['em', 'rem', 'ex', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ch', 'vw', 'vh', 'vmin', 'vmax'],
'angle': ['deg', 'rad', 'grad', 'turn'],
'time': ['ms', 's'],
'frequency': ['Hz', 'kHz'],
'resolution': ['dpi', 'dpcm', 'dppx'],
'percentage': ['%', 'fr']
};
export var html5Tags = ['a', 'abbr', 'address', 'area', 'article', 'aside', 'audio', 'b', 'base', 'bdi', 'bdo', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption',
'cite', 'code', 'col', 'colgroup', 'data', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'footer',
'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'keygen', 'label', 'legend', 'li', 'link',
'main', 'map', 'mark', 'menu', 'menuitem', 'meta', 'meter', 'nav', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param', 'picture', 'pre', 'progress', 'q',
'rb', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'script', 'section', 'select', 'small', 'source', 'span', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td',
'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'u', 'ul', 'const', 'video', 'wbr'];
export var svgElements = ['circle', 'clipPath', 'cursor', 'defs', 'desc', 'ellipse', 'feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting',
'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology',
'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence', 'filter', 'foreignObject', 'g', 'hatch', 'hatchpath', 'image', 'line', 'linearGradient',
'marker', 'mask', 'mesh', 'meshpatch', 'meshrow', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'set', 'solidcolor', 'stop', 'svg', 'switch',
'symbol', 'text', 'textPath', 'tspan', 'use', 'view'];
export var pageBoxDirectives = [
'@bottom-center', '@bottom-left', '@bottom-left-corner', '@bottom-right', '@bottom-right-corner',
'@left-bottom', '@left-middle', '@left-top', '@right-bottom', '@right-middle', '@right-top',
'@top-center', '@top-left', '@top-left-corner', '@top-right', '@top-right-corner'
];

View File

@@ -0,0 +1,403 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nodes from '../parser/cssNodes';
import * as nls from 'vscode-nls';
var localize = nls.loadMessageBundle();
export var colorFunctions = [
{ func: 'rgb($red, $green, $blue)', desc: localize('css.builtin.rgb', 'Creates a Color from red, green, and blue values.') },
{ func: 'rgba($red, $green, $blue, $alpha)', desc: localize('css.builtin.rgba', 'Creates a Color from red, green, blue, and alpha values.') },
{ func: 'hsl($hue, $saturation, $lightness)', desc: localize('css.builtin.hsl', 'Creates a Color from hue, saturation, and lightness values.') },
{ func: 'hsla($hue, $saturation, $lightness, $alpha)', desc: localize('css.builtin.hsla', 'Creates a Color from hue, saturation, lightness, and alpha values.') }
];
export var colors = {
aliceblue: '#f0f8ff',
antiquewhite: '#faebd7',
aqua: '#00ffff',
aquamarine: '#7fffd4',
azure: '#f0ffff',
beige: '#f5f5dc',
bisque: '#ffe4c4',
black: '#000000',
blanchedalmond: '#ffebcd',
blue: '#0000ff',
blueviolet: '#8a2be2',
brown: '#a52a2a',
burlywood: '#deb887',
cadetblue: '#5f9ea0',
chartreuse: '#7fff00',
chocolate: '#d2691e',
coral: '#ff7f50',
cornflowerblue: '#6495ed',
cornsilk: '#fff8dc',
crimson: '#dc143c',
cyan: '#00ffff',
darkblue: '#00008b',
darkcyan: '#008b8b',
darkgoldenrod: '#b8860b',
darkgray: '#a9a9a9',
darkgrey: '#a9a9a9',
darkgreen: '#006400',
darkkhaki: '#bdb76b',
darkmagenta: '#8b008b',
darkolivegreen: '#556b2f',
darkorange: '#ff8c00',
darkorchid: '#9932cc',
darkred: '#8b0000',
darksalmon: '#e9967a',
darkseagreen: '#8fbc8f',
darkslateblue: '#483d8b',
darkslategray: '#2f4f4f',
darkslategrey: '#2f4f4f',
darkturquoise: '#00ced1',
darkviolet: '#9400d3',
deeppink: '#ff1493',
deepskyblue: '#00bfff',
dimgray: '#696969',
dimgrey: '#696969',
dodgerblue: '#1e90ff',
firebrick: '#b22222',
floralwhite: '#fffaf0',
forestgreen: '#228b22',
fuchsia: '#ff00ff',
gainsboro: '#dcdcdc',
ghostwhite: '#f8f8ff',
gold: '#ffd700',
goldenrod: '#daa520',
gray: '#808080',
grey: '#808080',
green: '#008000',
greenyellow: '#adff2f',
honeydew: '#f0fff0',
hotpink: '#ff69b4',
indianred: '#cd5c5c',
indigo: '#4b0082',
ivory: '#fffff0',
khaki: '#f0e68c',
lavender: '#e6e6fa',
lavenderblush: '#fff0f5',
lawngreen: '#7cfc00',
lemonchiffon: '#fffacd',
lightblue: '#add8e6',
lightcoral: '#f08080',
lightcyan: '#e0ffff',
lightgoldenrodyellow: '#fafad2',
lightgray: '#d3d3d3',
lightgrey: '#d3d3d3',
lightgreen: '#90ee90',
lightpink: '#ffb6c1',
lightsalmon: '#ffa07a',
lightseagreen: '#20b2aa',
lightskyblue: '#87cefa',
lightslategray: '#778899',
lightslategrey: '#778899',
lightsteelblue: '#b0c4de',
lightyellow: '#ffffe0',
lime: '#00ff00',
limegreen: '#32cd32',
linen: '#faf0e6',
magenta: '#ff00ff',
maroon: '#800000',
mediumaquamarine: '#66cdaa',
mediumblue: '#0000cd',
mediumorchid: '#ba55d3',
mediumpurple: '#9370d8',
mediumseagreen: '#3cb371',
mediumslateblue: '#7b68ee',
mediumspringgreen: '#00fa9a',
mediumturquoise: '#48d1cc',
mediumvioletred: '#c71585',
midnightblue: '#191970',
mintcream: '#f5fffa',
mistyrose: '#ffe4e1',
moccasin: '#ffe4b5',
navajowhite: '#ffdead',
navy: '#000080',
oldlace: '#fdf5e6',
olive: '#808000',
olivedrab: '#6b8e23',
orange: '#ffa500',
orangered: '#ff4500',
orchid: '#da70d6',
palegoldenrod: '#eee8aa',
palegreen: '#98fb98',
paleturquoise: '#afeeee',
palevioletred: '#d87093',
papayawhip: '#ffefd5',
peachpuff: '#ffdab9',
peru: '#cd853f',
pink: '#ffc0cb',
plum: '#dda0dd',
powderblue: '#b0e0e6',
purple: '#800080',
red: '#ff0000',
rebeccapurple: '#663399',
rosybrown: '#bc8f8f',
royalblue: '#4169e1',
saddlebrown: '#8b4513',
salmon: '#fa8072',
sandybrown: '#f4a460',
seagreen: '#2e8b57',
seashell: '#fff5ee',
sienna: '#a0522d',
silver: '#c0c0c0',
skyblue: '#87ceeb',
slateblue: '#6a5acd',
slategray: '#708090',
slategrey: '#708090',
snow: '#fffafa',
springgreen: '#00ff7f',
steelblue: '#4682b4',
tan: '#d2b48c',
teal: '#008080',
thistle: '#d8bfd8',
tomato: '#ff6347',
turquoise: '#40e0d0',
violet: '#ee82ee',
wheat: '#f5deb3',
white: '#ffffff',
whitesmoke: '#f5f5f5',
yellow: '#ffff00',
yellowgreen: '#9acd32'
};
export var colorKeywords = {
'currentColor': 'The value of the \'color\' property. The computed value of the \'currentColor\' keyword is the computed value of the \'color\' property. If the \'currentColor\' keyword is set on the \'color\' property itself, it is treated as \'color:inherit\' at parse time.',
'transparent': 'Fully transparent. This keyword can be considered a shorthand for rgba(0,0,0,0) which is its computed value.',
};
function getNumericValue(node, factor) {
var val = node.getText();
var m = val.match(/^([-+]?[0-9]*\.?[0-9]+)(%?)$/);
if (m) {
if (m[2]) {
factor = 100.0;
}
var result = parseFloat(m[1]) / factor;
if (result >= 0 && result <= 1) {
return result;
}
}
throw new Error();
}
function getAngle(node) {
var val = node.getText();
var m = val.match(/^([-+]?[0-9]*\.?[0-9]+)(deg)?$/);
if (m) {
return parseFloat(val) % 360;
}
throw new Error();
}
export function isColorConstructor(node) {
var name = node.getName();
if (!name) {
return false;
}
return /^(rgb|rgba|hsl|hsla)$/gi.test(name);
}
/**
* Returns true if the node is a color value - either
* defined a hex number, as rgb or rgba function, or
* as color name.
*/
export function isColorValue(node) {
if (node.type === nodes.NodeType.HexColorValue) {
return true;
}
else if (node.type === nodes.NodeType.Function) {
return isColorConstructor(node);
}
else if (node.type === nodes.NodeType.Identifier) {
if (node.parent && node.parent.type !== nodes.NodeType.Term) {
return false;
}
var candidateColor = node.getText().toLowerCase();
if (candidateColor === 'none') {
return false;
}
if (colors[candidateColor]) {
return true;
}
}
return false;
}
var Digit0 = 48;
var Digit9 = 57;
var A = 65;
var F = 70;
var a = 97;
var f = 102;
export function hexDigit(charCode) {
if (charCode < Digit0) {
return 0;
}
if (charCode <= Digit9) {
return charCode - Digit0;
}
if (charCode < a) {
charCode += (a - A);
}
if (charCode >= a && charCode <= f) {
return charCode - a + 10;
}
return 0;
}
export function colorFromHex(text) {
if (text[0] !== '#') {
return null;
}
switch (text.length) {
case 4:
return {
red: (hexDigit(text.charCodeAt(1)) * 0x11) / 255.0,
green: (hexDigit(text.charCodeAt(2)) * 0x11) / 255.0,
blue: (hexDigit(text.charCodeAt(3)) * 0x11) / 255.0,
alpha: 1
};
case 5:
return {
red: (hexDigit(text.charCodeAt(1)) * 0x11) / 255.0,
green: (hexDigit(text.charCodeAt(2)) * 0x11) / 255.0,
blue: (hexDigit(text.charCodeAt(3)) * 0x11) / 255.0,
alpha: (hexDigit(text.charCodeAt(4)) * 0x11) / 255.0,
};
case 7:
return {
red: (hexDigit(text.charCodeAt(1)) * 0x10 + hexDigit(text.charCodeAt(2))) / 255.0,
green: (hexDigit(text.charCodeAt(3)) * 0x10 + hexDigit(text.charCodeAt(4))) / 255.0,
blue: (hexDigit(text.charCodeAt(5)) * 0x10 + hexDigit(text.charCodeAt(6))) / 255.0,
alpha: 1
};
case 9:
return {
red: (hexDigit(text.charCodeAt(1)) * 0x10 + hexDigit(text.charCodeAt(2))) / 255.0,
green: (hexDigit(text.charCodeAt(3)) * 0x10 + hexDigit(text.charCodeAt(4))) / 255.0,
blue: (hexDigit(text.charCodeAt(5)) * 0x10 + hexDigit(text.charCodeAt(6))) / 255.0,
alpha: (hexDigit(text.charCodeAt(7)) * 0x10 + hexDigit(text.charCodeAt(8))) / 255.0
};
}
return null;
}
export function colorFrom256RGB(red, green, blue, alpha) {
if (alpha === void 0) { alpha = 1.0; }
return {
red: red / 255.0,
green: green / 255.0,
blue: blue / 255.0,
alpha: alpha
};
}
export function colorFromHSL(hue, sat, light, alpha) {
if (alpha === void 0) { alpha = 1.0; }
hue = hue / 60.0;
if (sat === 0) {
return { red: light, green: light, blue: light, alpha: alpha };
}
else {
var hueToRgb = function (t1, t2, hue) {
while (hue < 0) {
hue += 6;
}
while (hue >= 6) {
hue -= 6;
}
if (hue < 1) {
return (t2 - t1) * hue + t1;
}
if (hue < 3) {
return t2;
}
if (hue < 4) {
return (t2 - t1) * (4 - hue) + t1;
}
return t1;
};
var t2 = light <= 0.5 ? (light * (sat + 1)) : (light + sat - (light * sat));
var t1 = light * 2 - t2;
return { red: hueToRgb(t1, t2, hue + 2), green: hueToRgb(t1, t2, hue), blue: hueToRgb(t1, t2, hue - 2), alpha: alpha };
}
}
export function hslFromColor(rgba) {
var r = rgba.red;
var g = rgba.green;
var b = rgba.blue;
var a = rgba.alpha;
var max = Math.max(r, g, b);
var min = Math.min(r, g, b);
var h = 0;
var s = 0;
var l = (min + max) / 2;
var chroma = max - min;
if (chroma > 0) {
s = Math.min((l <= 0.5 ? chroma / (2 * l) : chroma / (2 - (2 * l))), 1);
switch (max) {
case r:
h = (g - b) / chroma + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / chroma + 2;
break;
case b:
h = (r - g) / chroma + 4;
break;
}
h *= 60;
h = Math.round(h);
}
return { h: h, s: s, l: l, a: a };
}
export function getColorValue(node) {
if (node.type === nodes.NodeType.HexColorValue) {
var text = node.getText();
return colorFromHex(text);
}
else if (node.type === nodes.NodeType.Function) {
var functionNode = node;
var name = functionNode.getName();
var colorValues = functionNode.getArguments().getChildren();
if (!name || colorValues.length < 3 || colorValues.length > 4) {
return null;
}
try {
var alpha = colorValues.length === 4 ? getNumericValue(colorValues[3], 1) : 1;
if (name === 'rgb' || name === 'rgba') {
return {
red: getNumericValue(colorValues[0], 255.0),
green: getNumericValue(colorValues[1], 255.0),
blue: getNumericValue(colorValues[2], 255.0),
alpha: alpha
};
}
else if (name === 'hsl' || name === 'hsla') {
var h = getAngle(colorValues[0]);
var s = getNumericValue(colorValues[1], 100.0);
var l = getNumericValue(colorValues[2], 100.0);
return colorFromHSL(h, s, l, alpha);
}
}
catch (e) {
// parse error on numeric value
return null;
}
}
else if (node.type === nodes.NodeType.Identifier) {
if (node.parent && node.parent.type !== nodes.NodeType.Term) {
return null;
}
var term = node.parent;
if (term && term.parent && term.parent.type === nodes.NodeType.BinaryExpression) {
var expression = term.parent;
if (expression.parent && expression.parent.type === nodes.NodeType.ListEntry && expression.parent.key === expression) {
return null;
}
}
var candidateColor = node.getText().toLowerCase();
if (candidateColor === 'none') {
return null;
}
var colorHex = colors[candidateColor];
if (colorHex) {
return colorFromHex(colorHex);
}
}
return null;
}

View File

@@ -0,0 +1,92 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as objects from '../utils/objects';
import { cssData } from '../data/webCustomData';
import { CSSDataProvider } from './dataProvider';
var CSSDataManager = /** @class */ (function () {
function CSSDataManager(options) {
this.dataProviders = [];
this._propertySet = {};
this._atDirectiveSet = {};
this._pseudoClassSet = {};
this._pseudoElementSet = {};
this._properties = [];
this._atDirectives = [];
this._pseudoClasses = [];
this._pseudoElements = [];
this.setDataProviders((options === null || options === void 0 ? void 0 : options.useDefaultDataProvider) !== false, (options === null || options === void 0 ? void 0 : options.customDataProviders) || []);
}
CSSDataManager.prototype.setDataProviders = function (builtIn, providers) {
var _a;
this.dataProviders = [];
if (builtIn) {
this.dataProviders.push(new CSSDataProvider(cssData));
}
(_a = this.dataProviders).push.apply(_a, providers);
this.collectData();
};
/**
* Collect all data & handle duplicates
*/
CSSDataManager.prototype.collectData = function () {
var _this = this;
this._propertySet = {};
this._atDirectiveSet = {};
this._pseudoClassSet = {};
this._pseudoElementSet = {};
this.dataProviders.forEach(function (provider) {
provider.provideProperties().forEach(function (p) {
if (!_this._propertySet[p.name]) {
_this._propertySet[p.name] = p;
}
});
provider.provideAtDirectives().forEach(function (p) {
if (!_this._atDirectiveSet[p.name]) {
_this._atDirectiveSet[p.name] = p;
}
});
provider.providePseudoClasses().forEach(function (p) {
if (!_this._pseudoClassSet[p.name]) {
_this._pseudoClassSet[p.name] = p;
}
});
provider.providePseudoElements().forEach(function (p) {
if (!_this._pseudoElementSet[p.name]) {
_this._pseudoElementSet[p.name] = p;
}
});
});
this._properties = objects.values(this._propertySet);
this._atDirectives = objects.values(this._atDirectiveSet);
this._pseudoClasses = objects.values(this._pseudoClassSet);
this._pseudoElements = objects.values(this._pseudoElementSet);
};
CSSDataManager.prototype.getProperty = function (name) { return this._propertySet[name]; };
CSSDataManager.prototype.getAtDirective = function (name) { return this._atDirectiveSet[name]; };
CSSDataManager.prototype.getPseudoClass = function (name) { return this._pseudoClassSet[name]; };
CSSDataManager.prototype.getPseudoElement = function (name) { return this._pseudoElementSet[name]; };
CSSDataManager.prototype.getProperties = function () {
return this._properties;
};
CSSDataManager.prototype.getAtDirectives = function () {
return this._atDirectives;
};
CSSDataManager.prototype.getPseudoClasses = function () {
return this._pseudoClasses;
};
CSSDataManager.prototype.getPseudoElements = function () {
return this._pseudoElements;
};
CSSDataManager.prototype.isKnownProperty = function (name) {
return name.toLowerCase() in this._propertySet;
};
CSSDataManager.prototype.isStandardProperty = function (name) {
return this.isKnownProperty(name) &&
(!this._propertySet[name.toLowerCase()].status || this._propertySet[name.toLowerCase()].status === 'standard');
};
return CSSDataManager;
}());
export { CSSDataManager };

Some files were not shown because too many files have changed in this diff Show More