mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
idea
This commit is contained in:
29
dataprotocol-node/.gitignore
vendored
29
dataprotocol-node/.gitignore
vendored
@@ -1,29 +0,0 @@
|
|||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
|
|
||||||
# Runtime data
|
|
||||||
pids
|
|
||||||
*.pid
|
|
||||||
*.seed
|
|
||||||
|
|
||||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
||||||
lib-cov
|
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
|
||||||
coverage
|
|
||||||
|
|
||||||
# node-waf configuration
|
|
||||||
.lock-wscript
|
|
||||||
|
|
||||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
|
||||||
build/Release
|
|
||||||
lib/
|
|
||||||
out/
|
|
||||||
|
|
||||||
# Dependency directory
|
|
||||||
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
|
|
||||||
node_modules
|
|
||||||
|
|
||||||
# Debug log from npm
|
|
||||||
npm-debug.log
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
|
|
||||||
Copyright (c) Microsoft Corporation
|
|
||||||
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Source EULA
|
|
||||||
|
|
||||||
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.
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# Microsoft Data Management Protocol - Node
|
|
||||||
|
|
||||||
## License
|
|
||||||
[MIT](https://github.com/Microsoft/carbon/blob/dev/license.txt)
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
"rules": {
|
|
||||||
"indent": [
|
|
||||||
2,
|
|
||||||
"tab"
|
|
||||||
],
|
|
||||||
"quotes": [
|
|
||||||
2,
|
|
||||||
"single"
|
|
||||||
],
|
|
||||||
"linebreak-style": [
|
|
||||||
2,
|
|
||||||
"windows"
|
|
||||||
],
|
|
||||||
"semi": [
|
|
||||||
2,
|
|
||||||
"always"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"env": {
|
|
||||||
"node": true
|
|
||||||
},
|
|
||||||
"extends": "eslint:recommended"
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
.vscode/
|
|
||||||
lib/test/
|
|
||||||
lib/*.map
|
|
||||||
src/
|
|
||||||
test/
|
|
||||||
.eslintrc
|
|
||||||
.gitignore
|
|
||||||
gulpfile.js
|
|
||||||
tsd.json
|
|
||||||
32
dataprotocol-node/client/.vscode/launch.json
vendored
32
dataprotocol-node/client/.vscode/launch.json
vendored
@@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "0.1.0",
|
|
||||||
// List of configurations. Add new configurations or edit existing ones.
|
|
||||||
// ONLY "node" and "mono" are supported, change "type" to switch.
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"request": "launch",
|
|
||||||
// Name of configuration; appears in the launch configuration drop down menu.
|
|
||||||
"name": "Mocha",
|
|
||||||
// Type of configuration. Possible values: "node", "mono".
|
|
||||||
"type": "node",
|
|
||||||
// Workspace relative or absolute path to the program.
|
|
||||||
"program": "node_modules/mocha/bin/_mocha",
|
|
||||||
// Automatically stop program after launch.
|
|
||||||
"stopOnEntry": false,
|
|
||||||
// Command line arguments passed to the program.
|
|
||||||
"args": ["--timeout", "999999"],
|
|
||||||
// Workspace relative or absolute path to the working directory of the program being debugged. Default is the current workspace.
|
|
||||||
"cwd": ".",
|
|
||||||
// Workspace relative or absolute path to the runtime executable to be used. Default is the runtime executable on the PATH.
|
|
||||||
"runtimeExecutable": null,
|
|
||||||
// Optional arguments passed to the runtime executable.
|
|
||||||
"runtimeArgs": [],
|
|
||||||
// Environment variables passed to the program.
|
|
||||||
"env": { },
|
|
||||||
// Use JavaScript source maps (if they exist).
|
|
||||||
"sourceMaps": true,
|
|
||||||
// If JavaScript source maps are enabled, the generated code is expected in this directory.
|
|
||||||
"outDir": "lib"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
11
dataprotocol-node/client/.vscode/settings.json
vendored
11
dataprotocol-node/client/.vscode/settings.json
vendored
@@ -1,11 +0,0 @@
|
|||||||
// Place your settings in this file to overwrite default and user settings.
|
|
||||||
{
|
|
||||||
"javascript.validate.enable": false,
|
|
||||||
"files.trimTrailingWhitespace": true,
|
|
||||||
"eslint.enable": false,
|
|
||||||
"editor.insertSpaces": false,
|
|
||||||
"editor.tabSize": 4,
|
|
||||||
"tslint.enable": false,
|
|
||||||
"typescript.tsdk": "./node_modules/typescript/lib",
|
|
||||||
"typescript.tsserver.trace": "off"
|
|
||||||
}
|
|
||||||
9
dataprotocol-node/client/.vscode/tasks.json
vendored
9
dataprotocol-node/client/.vscode/tasks.json
vendored
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "0.1.0",
|
|
||||||
"command": "npm",
|
|
||||||
"isShellCommand": true,
|
|
||||||
"args": ["run", "watch"],
|
|
||||||
"showOutput": "silent",
|
|
||||||
"isWatching": true,
|
|
||||||
"problemMatcher": "$tsc-watch"
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# Microsoft Data Management Protocol - Node
|
|
||||||
|
|
||||||
## License
|
|
||||||
[MIT](https://github.com/Microsoft/carbon/blob/dev/license.txt)
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "dataprotocol-client",
|
|
||||||
"description": "VSCode Language client implementation",
|
|
||||||
"version": "2.6.3",
|
|
||||||
"author": "Microsoft Corporation",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"vscode": "^1.5.0"
|
|
||||||
},
|
|
||||||
"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": {
|
|
||||||
"typescript": "2.0.3"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"dataprotocol-jsonrpc": "file:../jsonrpc",
|
|
||||||
"dataprotocol-languageserver-types": "file:../types"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"prepublish": "tsc -p ./src",
|
|
||||||
"compile": "tsc -p ./src",
|
|
||||||
"watch": "tsc -w -p ./src",
|
|
||||||
"update-vscode": "node ./node_modules/vscode/bin/install"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,526 +0,0 @@
|
|||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
* ------------------------------------------------------------------------------------------ */
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import * as code from 'vscode';
|
|
||||||
import * as data from 'data';
|
|
||||||
import * as ls from 'dataprotocol-languageserver-types';
|
|
||||||
import * as proto from './protocol';
|
|
||||||
import * as is from './utils/is';
|
|
||||||
import ProtocolCompletionItem from './protocolCompletionItem';
|
|
||||||
import ProtocolCodeLens from './protocolCodeLens';
|
|
||||||
import os = require('os');
|
|
||||||
import path = require('path');
|
|
||||||
|
|
||||||
export interface Converter {
|
|
||||||
|
|
||||||
asUri(uri: code.Uri): string;
|
|
||||||
|
|
||||||
asTextDocumentIdentifier(textDocument: code.TextDocument): ls.TextDocumentIdentifier;
|
|
||||||
|
|
||||||
asOpenTextDocumentParams(textDocument: code.TextDocument): proto.DidOpenTextDocumentParams;
|
|
||||||
|
|
||||||
asChangeTextDocumentParams(textDocument: code.TextDocument): proto.DidChangeTextDocumentParams;
|
|
||||||
asChangeTextDocumentParams(event: code.TextDocumentChangeEvent): proto.DidChangeTextDocumentParams;
|
|
||||||
|
|
||||||
asCloseTextDocumentParams(textDocument: code.TextDocument): proto.DidCloseTextDocumentParams;
|
|
||||||
|
|
||||||
asSaveTextDocumentParams(textDocument: code.TextDocument): proto.DidSaveTextDocumentParams;
|
|
||||||
|
|
||||||
asTextDocumentPositionParams(textDocument: code.TextDocument, position: code.Position): proto.TextDocumentPositionParams;
|
|
||||||
|
|
||||||
asWorkerPosition(position: code.Position): ls.Position;
|
|
||||||
|
|
||||||
asRange(value: code.Range): ls.Range;
|
|
||||||
|
|
||||||
asPosition(value: code.Position): ls.Position;
|
|
||||||
|
|
||||||
asDiagnosticSeverity(value: code.DiagnosticSeverity): ls.DiagnosticSeverity;
|
|
||||||
|
|
||||||
asDiagnostic(item: code.Diagnostic): ls.Diagnostic;
|
|
||||||
asDiagnostics(items: code.Diagnostic[]): ls.Diagnostic[];
|
|
||||||
|
|
||||||
asCompletionItem(item: code.CompletionItem): ls.CompletionItem;
|
|
||||||
|
|
||||||
asTextEdit(edit: code.TextEdit): ls.TextEdit;
|
|
||||||
|
|
||||||
asReferenceParams(textDocument: code.TextDocument, position: code.Position, options: { includeDeclaration: boolean; }): proto.ReferenceParams;
|
|
||||||
|
|
||||||
asCodeActionContext(context: code.CodeActionContext): ls.CodeActionContext;
|
|
||||||
|
|
||||||
asCommand(item: code.Command): ls.Command;
|
|
||||||
|
|
||||||
asCodeLens(item: code.CodeLens): ls.CodeLens;
|
|
||||||
|
|
||||||
asFormattingOptions(item: code.FormattingOptions): ls.FormattingOptions;
|
|
||||||
|
|
||||||
asDocumentSymbolParams(textDocument: code.TextDocument): proto.DocumentSymbolParams;
|
|
||||||
|
|
||||||
asCodeLensParams(textDocument: code.TextDocument): proto.CodeLensParams;
|
|
||||||
|
|
||||||
asDocumentLink(item: code.DocumentLink): ls.DocumentLink;
|
|
||||||
|
|
||||||
asDocumentLinkParams(textDocument: code.TextDocument): proto.DocumentLinkParams;
|
|
||||||
|
|
||||||
asConnectionParams(connectionUri: string, connectionInfo: data.ConnectionInfo): proto.ConnectParams;
|
|
||||||
|
|
||||||
asCapabilitiesParams(client: data.DataProtocolClientCapabilities): proto.CapabiltiesDiscoveryParams;
|
|
||||||
|
|
||||||
asMetadataQueryParams(connectionUri: string): ls.MetadataQueryParams;
|
|
||||||
|
|
||||||
asListDatabasesParams(connectionUri: string): proto.ListDatabasesParams;
|
|
||||||
|
|
||||||
asTableMetadataParams(connectionUri: string, metadata: data.ObjectMetadata): proto.TableMetadataParams;
|
|
||||||
|
|
||||||
asScriptingParams(connectionUri: string, operation: ls.ScriptOperation, metadata: data.ObjectMetadata, paramDetails: data.ScriptingParamDetails): ls.ScriptingParams;
|
|
||||||
|
|
||||||
asConnectionDetail(connInfo: data.ConnectionInfo): ls.ConnectionDetails;
|
|
||||||
|
|
||||||
asExpandInfo(nodeInfo: data.ExpandNodeInfo): ls.ExpandParams;
|
|
||||||
|
|
||||||
asCloseSessionInfo(nodeInfo: data.ObjectExplorerCloseSessionInfo): ls.CloseSessionParams;
|
|
||||||
|
|
||||||
asExecutionPlanOptions(planOptions: data.ExecutionPlanOptions): proto.ExecutionPlanOptions;
|
|
||||||
|
|
||||||
asListTasksParams(params: data.ListTasksParams): ls.ListTasksParams;
|
|
||||||
|
|
||||||
asCancelTaskParams(params: data.CancelTaskParams): ls.CancelTaskParams;
|
|
||||||
|
|
||||||
asRestoreParams(ownerUri: string, params: data.RestoreInfo): ls.RestoreParams;
|
|
||||||
|
|
||||||
asRestoreConfigInfoParams(ownerUri: string): ls.RestoreConfigInfoRequestParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface URIConverter {
|
|
||||||
(value: code.Uri): string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createConverter(uriConverter?: URIConverter): Converter {
|
|
||||||
|
|
||||||
const nullConverter = (value: code.Uri) => value.toString();
|
|
||||||
|
|
||||||
const _uriConverter: URIConverter = uriConverter || nullConverter;
|
|
||||||
|
|
||||||
function asUri(value: code.Uri): string {
|
|
||||||
return _uriConverter(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asTextDocumentIdentifier(textDocument: code.TextDocument): ls.TextDocumentIdentifier {
|
|
||||||
return {
|
|
||||||
uri: _uriConverter(textDocument.uri)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asOpenTextDocumentParams(textDocument: code.TextDocument): proto.DidOpenTextDocumentParams {
|
|
||||||
return {
|
|
||||||
textDocument: {
|
|
||||||
uri: _uriConverter(textDocument.uri),
|
|
||||||
languageId: textDocument.languageId,
|
|
||||||
version: textDocument.version,
|
|
||||||
text: textDocument.getText()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function isTextDocumentChangeEvent(value: any): value is code.TextDocumentChangeEvent {
|
|
||||||
let candidate = <code.TextDocumentChangeEvent>value;
|
|
||||||
return is.defined(candidate.document) && is.defined(candidate.contentChanges);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isTextDocument(value: any): value is code.TextDocument {
|
|
||||||
let candidate = <code.TextDocument>value;
|
|
||||||
return is.defined(candidate.uri) && is.defined(candidate.version);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asChangeTextDocumentParams(textDocument: code.TextDocument): proto.DidChangeTextDocumentParams;
|
|
||||||
function asChangeTextDocumentParams(event: code.TextDocumentChangeEvent): proto.DidChangeTextDocumentParams;
|
|
||||||
function asChangeTextDocumentParams(arg: code.TextDocumentChangeEvent | code.TextDocument): proto.DidChangeTextDocumentParams {
|
|
||||||
if (isTextDocument(arg)) {
|
|
||||||
let result: proto.DidChangeTextDocumentParams = {
|
|
||||||
textDocument: {
|
|
||||||
uri: _uriConverter(arg.uri),
|
|
||||||
version: arg.version
|
|
||||||
},
|
|
||||||
contentChanges: [{ text: arg.getText() }]
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} else if (isTextDocumentChangeEvent(arg)) {
|
|
||||||
let document = arg.document;
|
|
||||||
let result: proto.DidChangeTextDocumentParams = {
|
|
||||||
textDocument: {
|
|
||||||
uri: _uriConverter(document.uri),
|
|
||||||
version: document.version
|
|
||||||
},
|
|
||||||
contentChanges: arg.contentChanges.map((change): proto.TextDocumentContentChangeEvent => {
|
|
||||||
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: code.TextDocument): proto.DidCloseTextDocumentParams {
|
|
||||||
return {
|
|
||||||
textDocument: asTextDocumentIdentifier(textDocument)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asSaveTextDocumentParams(textDocument: code.TextDocument): proto.DidSaveTextDocumentParams {
|
|
||||||
return {
|
|
||||||
textDocument: asTextDocumentIdentifier(textDocument)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function asTextDocumentPositionParams(textDocument: code.TextDocument, position: code.Position): proto.TextDocumentPositionParams {
|
|
||||||
return {
|
|
||||||
textDocument: asTextDocumentIdentifier(textDocument),
|
|
||||||
position: asWorkerPosition(position)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asWorkerPosition(position: code.Position): ls.Position {
|
|
||||||
return { line: position.line, character: position.character };
|
|
||||||
}
|
|
||||||
|
|
||||||
function asRange(value: code.Range): ls.Range {
|
|
||||||
if (is.undefined(value)) {
|
|
||||||
return undefined;
|
|
||||||
} else if (is.nil(value)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return { start: asPosition(value.start), end: asPosition(value.end) };
|
|
||||||
}
|
|
||||||
|
|
||||||
function asPosition(value: code.Position): ls.Position {
|
|
||||||
if (is.undefined(value)) {
|
|
||||||
return undefined;
|
|
||||||
} else if (is.nil(value)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return { line: value.line, character: value.character };
|
|
||||||
}
|
|
||||||
|
|
||||||
function set(value, func: () => void): void {
|
|
||||||
if (is.defined(value)) {
|
|
||||||
func();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function asDiagnosticSeverity(value: code.DiagnosticSeverity): ls.DiagnosticSeverity {
|
|
||||||
switch (value) {
|
|
||||||
case code.DiagnosticSeverity.Error:
|
|
||||||
return ls.DiagnosticSeverity.Error;
|
|
||||||
case code.DiagnosticSeverity.Warning:
|
|
||||||
return ls.DiagnosticSeverity.Warning;
|
|
||||||
case code.DiagnosticSeverity.Information:
|
|
||||||
return ls.DiagnosticSeverity.Information;
|
|
||||||
case code.DiagnosticSeverity.Hint:
|
|
||||||
return ls.DiagnosticSeverity.Hint;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function asDiagnostic(item: code.Diagnostic): ls.Diagnostic {
|
|
||||||
let result: ls.Diagnostic = ls.Diagnostic.create(asRange(item.range), item.message);
|
|
||||||
set(item.severity, () => result.severity = asDiagnosticSeverity(item.severity));
|
|
||||||
set(item.code, () => result.code = item.code);
|
|
||||||
set(item.source, () => result.source = item.source);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asDiagnostics(items: code.Diagnostic[]): ls.Diagnostic[] {
|
|
||||||
if (is.undefined(items) || is.nil(items)) {
|
|
||||||
return items;
|
|
||||||
}
|
|
||||||
return items.map(asDiagnostic);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asCompletionItem(item: code.CompletionItem): ls.CompletionItem {
|
|
||||||
let result: ls.CompletionItem = { label: item.label };
|
|
||||||
set(item.detail, () => result.detail = item.detail);
|
|
||||||
set(item.documentation, () => result.documentation = item.documentation);
|
|
||||||
set(item.filterText, () => result.filterText = item.filterText);
|
|
||||||
set(item.insertText, () => result.insertText = String(item.insertText));
|
|
||||||
// Protocol item kind is 1 based, codes item kind is zero based.
|
|
||||||
set(item.kind, () => result.kind = item.kind + 1);
|
|
||||||
set(item.sortText, () => result.sortText = item.sortText);
|
|
||||||
set(item.textEdit, () => result.textEdit = asTextEdit(item.textEdit));
|
|
||||||
set(item.additionalTextEdits, () => result.additionalTextEdits = asTextEdits(item.additionalTextEdits));
|
|
||||||
set(item.command, () => result.command = asCommand(item.command));
|
|
||||||
if (item instanceof ProtocolCompletionItem) {
|
|
||||||
set(item.data, () => result.data = item.data);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asTextEdit(edit: code.TextEdit): ls.TextEdit {
|
|
||||||
return { range: asRange(edit.range), newText: edit.newText };
|
|
||||||
}
|
|
||||||
|
|
||||||
function asTextEdits(edits: code.TextEdit[]): ls.TextEdit[] {
|
|
||||||
if (is.undefined(edits) || is.nil(edits)) {
|
|
||||||
return edits;
|
|
||||||
}
|
|
||||||
return edits.map(asTextEdit);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asReferenceParams(textDocument: code.TextDocument, position: code.Position, options: { includeDeclaration: boolean; }): proto.ReferenceParams {
|
|
||||||
return {
|
|
||||||
textDocument: asTextDocumentIdentifier(textDocument),
|
|
||||||
position: asWorkerPosition(position),
|
|
||||||
context: { includeDeclaration: options.includeDeclaration }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asCodeActionContext(context: code.CodeActionContext): ls.CodeActionContext {
|
|
||||||
if (is.undefined(context) || is.nil(context)) {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
return ls.CodeActionContext.create(asDiagnostics(context.diagnostics));
|
|
||||||
}
|
|
||||||
|
|
||||||
function asCommand(item: code.Command): ls.Command {
|
|
||||||
let result = ls.Command.create(item.title, item.command);
|
|
||||||
if (is.defined(item.arguments)) result.arguments = item.arguments;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asCodeLens(item: code.CodeLens): ls.CodeLens {
|
|
||||||
let result = ls.CodeLens.create(asRange(item.range));
|
|
||||||
if (is.defined(item.command)) result.command = asCommand(item.command);
|
|
||||||
if (item instanceof ProtocolCodeLens) {
|
|
||||||
if (is.defined(item.data)) result.data = item.data;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asFormattingOptions(item: code.FormattingOptions): ls.FormattingOptions {
|
|
||||||
return { tabSize: item.tabSize, insertSpaces: item.insertSpaces };
|
|
||||||
}
|
|
||||||
|
|
||||||
function asDocumentSymbolParams(textDocument: code.TextDocument): proto.DocumentSymbolParams {
|
|
||||||
return {
|
|
||||||
textDocument: asTextDocumentIdentifier(textDocument)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function asCodeLensParams(textDocument: code.TextDocument): proto.CodeLensParams {
|
|
||||||
return {
|
|
||||||
textDocument: asTextDocumentIdentifier(textDocument)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asDocumentLink(item: code.DocumentLink): ls.DocumentLink {
|
|
||||||
let result = ls.DocumentLink.create(asRange(item.range));
|
|
||||||
if (is.defined(item.target)) result.target = asUri(item.target);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asDocumentLinkParams(textDocument: code.TextDocument): proto.DocumentLinkParams {
|
|
||||||
return {
|
|
||||||
textDocument: asTextDocumentIdentifier(textDocument)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asCapabilitiesParams(client: data.DataProtocolClientCapabilities): proto.CapabiltiesDiscoveryParams {
|
|
||||||
let params: proto.CapabiltiesDiscoveryParams = {
|
|
||||||
hostName: client.hostName,
|
|
||||||
hostVersion: client.hostVersion
|
|
||||||
};
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asConnectionParams(connUri: string, connInfo: data.ConnectionInfo): proto.ConnectParams {
|
|
||||||
return {
|
|
||||||
ownerUri: connUri,
|
|
||||||
connection: {
|
|
||||||
options: connInfo.options
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asMetadataQueryParams(connectionUri: string): ls.MetadataQueryParams {
|
|
||||||
return <ls.MetadataQueryParams>{
|
|
||||||
ownerUri: connectionUri
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asListDatabasesParams(connectionUri: string): proto.ListDatabasesParams {
|
|
||||||
return <proto.ListDatabasesParams>{
|
|
||||||
ownerUri: connectionUri
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asTableMetadataParams(connectionUri: string, metadata: data.ObjectMetadata): proto.TableMetadataParams {
|
|
||||||
return <proto.TableMetadataParams>{
|
|
||||||
ownerUri: connectionUri,
|
|
||||||
schema: metadata.schema,
|
|
||||||
objectName: metadata.name
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asScriptingParams(connectionUri: string, operation: ls.ScriptOperation, metadata: data.ObjectMetadata, paramDetails: data.ScriptingParamDetails): ls.ScriptingParams {
|
|
||||||
let scriptingObject: ls.ScriptingObject = {
|
|
||||||
type: metadata.metadataTypeName,
|
|
||||||
schema: metadata.schema,
|
|
||||||
name: metadata.name
|
|
||||||
}
|
|
||||||
let targetDatabaseEngineEdition = paramDetails.targetDatabaseEngineEdition;
|
|
||||||
let targetDatabaseEngineType = paramDetails.targetDatabaseEngineType;
|
|
||||||
let scriptCompatibilityOption = paramDetails.scriptCompatibilityOption;
|
|
||||||
let options: ls.ScriptOptions = {
|
|
||||||
scriptCreateDrop: (operation === ls.ScriptOperation.Delete) ? "ScriptDrop" :
|
|
||||||
(operation === ls.ScriptOperation.Select) ? "ScriptSelect" : "ScriptCreate",
|
|
||||||
typeOfDataToScript: "SchemaOnly",
|
|
||||||
scriptStatistics: "ScriptStatsNone",
|
|
||||||
targetDatabaseEngineEdition: targetDatabaseEngineEdition ? targetDatabaseEngineEdition : "SqlServerEnterpriseEdition",
|
|
||||||
targetDatabaseEngineType: targetDatabaseEngineType ? targetDatabaseEngineType : "SingleInstance",
|
|
||||||
scriptCompatibilityOption: scriptCompatibilityOption ? scriptCompatibilityOption : "Script140Compat"
|
|
||||||
}
|
|
||||||
return <ls.ScriptingParams> {
|
|
||||||
connectionString: null,
|
|
||||||
filePath: paramDetails.filePath,
|
|
||||||
scriptingObjects: [scriptingObject],
|
|
||||||
scriptDestination: "ToEditor",
|
|
||||||
includeObjectCriteria: null,
|
|
||||||
excludeObjectCriteria: null,
|
|
||||||
includeSchemas: null,
|
|
||||||
excludeSchemas: null,
|
|
||||||
includeTypes: null,
|
|
||||||
excludeTypes: null,
|
|
||||||
scriptOptions: options,
|
|
||||||
connectionDetails: null,
|
|
||||||
ownerURI: connectionUri,
|
|
||||||
operation: operation
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asConnectionDetail(connInfo: data.ConnectionInfo): ls.ConnectionDetails {
|
|
||||||
return <ls.ConnectionDetails>{
|
|
||||||
options: connInfo.options
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asExpandInfo(nodeInfo: data.ExpandNodeInfo): ls.ExpandParams {
|
|
||||||
return <ls.ExpandParams>{
|
|
||||||
sessionId: nodeInfo.sessionId,
|
|
||||||
nodePath: nodeInfo.nodePath
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asCloseSessionInfo(nodeInfo: data.ObjectExplorerCloseSessionInfo): ls.CloseSessionParams {
|
|
||||||
return <ls.CloseSessionParams>{
|
|
||||||
sessionId: nodeInfo.sessionId
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asExecutionPlanOptions(planOptions: data.ExecutionPlanOptions): proto.ExecutionPlanOptions {
|
|
||||||
return <proto.ExecutionPlanOptions>{
|
|
||||||
includeEstimatedExecutionPlanXml: planOptions ? planOptions.displayEstimatedQueryPlan : undefined,
|
|
||||||
includeActualExecutionPlanXml: planOptions ? planOptions.displayActualQueryPlan : undefined
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asListTasksParams(params: data.ListTasksParams): ls.ListTasksParams {
|
|
||||||
return <ls.ListTasksParams>{
|
|
||||||
listActiveTasksOnly: params.listActiveTasksOnly
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asCancelTaskParams(params: data.CancelTaskParams): ls.CancelTaskParams {
|
|
||||||
return <ls.CancelTaskParams>{
|
|
||||||
taskId: params.taskId
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asRestoreParams(ownerUri: string, params: data.RestoreInfo): ls.RestoreParams {
|
|
||||||
return <ls.RestoreParams>{
|
|
||||||
ownerUri: ownerUri,
|
|
||||||
options: params.options,
|
|
||||||
taskExecutionMode: params.taskExecutionMode
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asRestoreConfigInfoParams(ownerUri: string): ls.RestoreConfigInfoRequestParams {
|
|
||||||
return <ls.RestoreConfigInfoRequestParams>{
|
|
||||||
ownerUri: ownerUri
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
asUri,
|
|
||||||
asTextDocumentIdentifier,
|
|
||||||
asOpenTextDocumentParams,
|
|
||||||
asChangeTextDocumentParams,
|
|
||||||
asCloseTextDocumentParams,
|
|
||||||
asSaveTextDocumentParams,
|
|
||||||
asTextDocumentPositionParams,
|
|
||||||
asWorkerPosition,
|
|
||||||
asRange,
|
|
||||||
asPosition,
|
|
||||||
asDiagnosticSeverity,
|
|
||||||
asDiagnostic,
|
|
||||||
asDiagnostics,
|
|
||||||
asCompletionItem,
|
|
||||||
asTextEdit,
|
|
||||||
asReferenceParams,
|
|
||||||
asCodeActionContext,
|
|
||||||
asCommand,
|
|
||||||
asCodeLens,
|
|
||||||
asFormattingOptions,
|
|
||||||
asDocumentSymbolParams,
|
|
||||||
asCodeLensParams,
|
|
||||||
asDocumentLink,
|
|
||||||
asDocumentLinkParams,
|
|
||||||
asCapabilitiesParams,
|
|
||||||
asConnectionParams,
|
|
||||||
asMetadataQueryParams,
|
|
||||||
asTableMetadataParams,
|
|
||||||
asListDatabasesParams,
|
|
||||||
asScriptingParams,
|
|
||||||
asConnectionDetail,
|
|
||||||
asExpandInfo,
|
|
||||||
asCloseSessionInfo,
|
|
||||||
asExecutionPlanOptions,
|
|
||||||
asListTasksParams,
|
|
||||||
asCancelTaskParams,
|
|
||||||
asRestoreParams,
|
|
||||||
asRestoreConfigInfoParams
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// This for backward compatibility since we exported the converter functions as API.
|
|
||||||
let defaultConverter = createConverter();
|
|
||||||
|
|
||||||
export const asTextDocumentIdentifier: (textDocument: code.TextDocument) => ls.TextDocumentIdentifier = defaultConverter.asTextDocumentIdentifier;
|
|
||||||
export const asOpenTextDocumentParams: (textDocument: code.TextDocument) => proto.DidOpenTextDocumentParams = defaultConverter.asOpenTextDocumentParams;
|
|
||||||
export const asChangeTextDocumentParams: (arg: code.TextDocumentChangeEvent | code.TextDocument) => proto.DidChangeTextDocumentParams = defaultConverter.asChangeTextDocumentParams;
|
|
||||||
export const asCloseTextDocumentParams: (textDocument: code.TextDocument) => proto.DidCloseTextDocumentParams = defaultConverter.asCloseTextDocumentParams;
|
|
||||||
export const asSaveTextDocumentParams: (textDocument: code.TextDocument) => proto.DidSaveTextDocumentParams = defaultConverter.asSaveTextDocumentParams;
|
|
||||||
export const asTextDocumentPositionParams: (textDocument: code.TextDocument, position: code.Position) => proto.TextDocumentPositionParams = defaultConverter.asTextDocumentPositionParams;
|
|
||||||
export const asWorkerPosition: (position: code.Position) => ls.Position = defaultConverter.asWorkerPosition;
|
|
||||||
export const asRange: (value: code.Range) => ls.Range = defaultConverter.asRange;
|
|
||||||
export const asPosition: (value: code.Position) => ls.Position = defaultConverter.asPosition;
|
|
||||||
export const asDiagnosticSeverity: (value: code.DiagnosticSeverity) => ls.DiagnosticSeverity = defaultConverter.asDiagnosticSeverity;
|
|
||||||
export const asDiagnostic: (item: code.Diagnostic) => ls.Diagnostic = defaultConverter.asDiagnostic;
|
|
||||||
export const asDiagnostics: (items: code.Diagnostic[]) => ls.Diagnostic[] = defaultConverter.asDiagnostics;
|
|
||||||
export const asCompletionItem: (item: code.CompletionItem) => ls.CompletionItem = defaultConverter.asCompletionItem;
|
|
||||||
export const asTextEdit: (edit: code.TextEdit) => ls.TextEdit = defaultConverter.asTextEdit;
|
|
||||||
export const asReferenceParams: (textDocument: code.TextDocument, position: code.Position, options: { includeDeclaration: boolean; }) => proto.ReferenceParams = defaultConverter.asReferenceParams;
|
|
||||||
export const asCodeActionContext: (context: code.CodeActionContext) => ls.CodeActionContext = defaultConverter.asCodeActionContext;
|
|
||||||
export const asCommand: (item: code.Command) => ls.Command = defaultConverter.asCommand;
|
|
||||||
export const asCodeLens: (item: code.CodeLens) => ls.CodeLens = defaultConverter.asCodeLens;
|
|
||||||
export const asFormattingOptions: (item: code.FormattingOptions) => ls.FormattingOptions = defaultConverter.asFormattingOptions;
|
|
||||||
export const asDocumentSymbolParams: (textDocument: code.TextDocument) => proto.DocumentSymbolParams = defaultConverter.asDocumentSymbolParams;
|
|
||||||
export const asCodeLensParams: (textDocument: code.TextDocument) => proto.CodeLensParams = defaultConverter.asCodeLensParams;
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,16 +0,0 @@
|
|||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
* ------------------------------------------------------------------------------------------ */
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import * as code from 'vscode';
|
|
||||||
|
|
||||||
export default class ProtocolCodeLens extends code.CodeLens {
|
|
||||||
|
|
||||||
public data: any;
|
|
||||||
|
|
||||||
constructor(range: code.Range) {
|
|
||||||
super(range);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
* ------------------------------------------------------------------------------------------ */
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import * as code from 'vscode';
|
|
||||||
|
|
||||||
export default class ProtocolCompletionItem extends code.CompletionItem {
|
|
||||||
|
|
||||||
public data: any;
|
|
||||||
|
|
||||||
constructor(label: string) {
|
|
||||||
super(label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,769 +0,0 @@
|
|||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
* ------------------------------------------------------------------------------------------ */
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import * as code from 'vscode';
|
|
||||||
import * as data from 'data';
|
|
||||||
import * as ls from 'dataprotocol-languageserver-types';
|
|
||||||
import * as is from './utils/is';
|
|
||||||
import ProtocolCompletionItem from './protocolCompletionItem';
|
|
||||||
import ProtocolCodeLens from './protocolCodeLens';
|
|
||||||
|
|
||||||
export interface Converter {
|
|
||||||
|
|
||||||
asUri(value: string): code.Uri;
|
|
||||||
|
|
||||||
asDiagnostics(diagnostics: ls.Diagnostic[]): code.Diagnostic[];
|
|
||||||
|
|
||||||
asDiagnostic(diagnostic: ls.Diagnostic): code.Diagnostic;
|
|
||||||
|
|
||||||
asRange(value: ls.Range): code.Range;
|
|
||||||
|
|
||||||
asPosition(value: ls.Position): code.Position;
|
|
||||||
|
|
||||||
asDiagnosticSeverity(value: number): code.DiagnosticSeverity;
|
|
||||||
|
|
||||||
asHover(hover: ls.Hover): code.Hover;
|
|
||||||
|
|
||||||
asCompletionResult(result: ls.CompletionItem[] | ls.CompletionList): code.CompletionItem[] | code.CompletionList
|
|
||||||
|
|
||||||
asCompletionItem(item: ls.CompletionItem): ProtocolCompletionItem;
|
|
||||||
|
|
||||||
asTextEdit(edit: ls.TextEdit): code.TextEdit;
|
|
||||||
|
|
||||||
asTextEdits(items: ls.TextEdit[]): code.TextEdit[];
|
|
||||||
|
|
||||||
asSignatureHelp(item: ls.SignatureHelp): code.SignatureHelp;
|
|
||||||
|
|
||||||
asSignatureInformations(items: ls.SignatureInformation[]): code.SignatureInformation[];
|
|
||||||
|
|
||||||
asSignatureInformation(item: ls.SignatureInformation): code.SignatureInformation;
|
|
||||||
|
|
||||||
asParameterInformations(item: ls.ParameterInformation[]): code.ParameterInformation[];
|
|
||||||
|
|
||||||
asParameterInformation(item: ls.ParameterInformation): code.ParameterInformation;
|
|
||||||
|
|
||||||
asDefinitionResult(item: ls.Definition): code.Definition;
|
|
||||||
|
|
||||||
asLocation(item: ls.Location): code.Location;
|
|
||||||
|
|
||||||
asReferences(values: ls.Location[]): code.Location[];
|
|
||||||
|
|
||||||
asDocumentHighlights(values: ls.DocumentHighlight[]): code.DocumentHighlight[];
|
|
||||||
|
|
||||||
asDocumentHighlight(item: ls.DocumentHighlight): code.DocumentHighlight;
|
|
||||||
|
|
||||||
asDocumentHighlightKind(item: ls.DocumentHighlightKind): code.DocumentHighlightKind;
|
|
||||||
|
|
||||||
asSymbolInformations(values: ls.SymbolInformation[], uri?: code.Uri): code.SymbolInformation[];
|
|
||||||
|
|
||||||
asSymbolInformation(item: ls.SymbolInformation, uri?: code.Uri): code.SymbolInformation;
|
|
||||||
|
|
||||||
asCommand(item: ls.Command): code.Command;
|
|
||||||
|
|
||||||
asCommands(items: ls.Command[]): code.Command[];
|
|
||||||
|
|
||||||
asCodeLens(item: ls.CodeLens): code.CodeLens;
|
|
||||||
|
|
||||||
asCodeLenses(items: ls.CodeLens[]): code.CodeLens[];
|
|
||||||
|
|
||||||
asWorkspaceEdit(item: ls.WorkspaceEdit): code.WorkspaceEdit;
|
|
||||||
|
|
||||||
asDocumentLink(item: ls.DocumentLink): code.DocumentLink;
|
|
||||||
|
|
||||||
asDocumentLinks(items: ls.DocumentLink[]): code.DocumentLink[];
|
|
||||||
|
|
||||||
asConnectionSummary(params: ls.ConnectionCompleteParams): data.ConnectionInfoSummary;
|
|
||||||
|
|
||||||
asServerCapabilities(params: ls.CapabiltiesDiscoveryResult): data.DataProtocolServerCapabilities;
|
|
||||||
|
|
||||||
asProviderMetadata(params: ls.MetadataQueryResult): data.ProviderMetadata;
|
|
||||||
|
|
||||||
asScriptingResult(params: ls.ScriptingResult): data.ScriptingResult;
|
|
||||||
|
|
||||||
asObjectExplorerSession(params: ls.SessionCreatedParameters): data.ObjectExplorerSession;
|
|
||||||
|
|
||||||
asObjectExplorerCreateSessionResponse(params: ls.CreateSessionResponse): data.ObjectExplorerSessionResponse;
|
|
||||||
|
|
||||||
asObjectExplorerNodeInfo(params: ls.ExpandResponse): data.ObjectExplorerExpandInfo;
|
|
||||||
|
|
||||||
asObjectExplorerCloseSessionResponse(params: ls.CloseSessionResponse): data.ObjectExplorerCloseSessionResponse;
|
|
||||||
|
|
||||||
asListTasksResponse(response: ls.ListTasksResponse): data.ListTasksResponse;
|
|
||||||
|
|
||||||
asTaskInfo(params: ls.TaskInfo): data.TaskInfo;
|
|
||||||
|
|
||||||
asRestorePlanResponse(params: ls.RestorePlanResponse): data.RestorePlanResponse;
|
|
||||||
|
|
||||||
asRestoreResponse(params: ls.RestoreResponse): data.RestoreResponse;
|
|
||||||
|
|
||||||
asRestoreConfigInfo(params: ls.RestoreConfigInfoResponse): data.RestoreConfigInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface URIConverter {
|
|
||||||
(value: string): code.Uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createConverter(uriConverter?: URIConverter): Converter {
|
|
||||||
|
|
||||||
const nullConverter = (value: string) => code.Uri.parse(value);
|
|
||||||
|
|
||||||
const _uriConverter: URIConverter = uriConverter || nullConverter;
|
|
||||||
|
|
||||||
function asUri(value: string): code.Uri {
|
|
||||||
return _uriConverter(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asDiagnostics(diagnostics: ls.Diagnostic[]): code.Diagnostic[] {
|
|
||||||
return diagnostics.map(asDiagnostic);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asDiagnostic(diagnostic: ls.Diagnostic): code.Diagnostic {
|
|
||||||
let result = new code.Diagnostic(asRange(diagnostic.range), diagnostic.message, asDiagnosticSeverity(diagnostic.severity));
|
|
||||||
if (is.defined(diagnostic.code)) {
|
|
||||||
result.code = diagnostic.code;
|
|
||||||
}
|
|
||||||
if (is.defined(diagnostic.source)) {
|
|
||||||
result.source = diagnostic.source;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asRange(value: ls.Range): code.Range {
|
|
||||||
if (is.undefined(value)) {
|
|
||||||
return undefined;
|
|
||||||
} else if (is.nil(value)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new code.Range(asPosition(value.start), asPosition(value.end));
|
|
||||||
}
|
|
||||||
|
|
||||||
function asPosition(value: ls.Position): code.Position {
|
|
||||||
if (is.undefined(value)) {
|
|
||||||
return undefined;
|
|
||||||
} else if (is.nil(value)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new code.Position(value.line, value.character);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asDiagnosticSeverity(value: number): code.DiagnosticSeverity {
|
|
||||||
if (is.undefined(value) || is.nil(value)) {
|
|
||||||
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 asHover(hover: ls.Hover): code.Hover {
|
|
||||||
if (is.undefined(hover)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (is.nil(hover)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (is.nil(hover.contents) || is.undefined(hover.contents)) {
|
|
||||||
// Contents must be defined or hover will throw
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new code.Hover(hover.contents, is.defined(hover.range) ? asRange(hover.range) : undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asCompletionResult(result: ls.CompletionItem[] | ls.CompletionList): code.CompletionItem[] | code.CompletionList {
|
|
||||||
if (is.undefined(result)) {
|
|
||||||
return undefined;
|
|
||||||
} else if (is.nil(result)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (Array.isArray(result)) {
|
|
||||||
let items = <ls.CompletionItem[]>result;
|
|
||||||
return items.map(asCompletionItem);
|
|
||||||
}
|
|
||||||
let list = <ls.CompletionList>result;
|
|
||||||
return new code.CompletionList(list.items.map(asCompletionItem), list.isIncomplete);
|
|
||||||
}
|
|
||||||
|
|
||||||
function set<T>(value: T, func: () => void): void {
|
|
||||||
if (is.defined(value)) {
|
|
||||||
func();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function asCompletionItem(item: ls.CompletionItem): ProtocolCompletionItem {
|
|
||||||
let result = new ProtocolCompletionItem(item.label);
|
|
||||||
set(item.detail, () => result.detail = item.detail);
|
|
||||||
set(item.documentation, () => result.documentation = item.documentation);
|
|
||||||
set(item.filterText, () => result.filterText = item.filterText);
|
|
||||||
set(item.insertText, () => result.insertText = item.insertText);
|
|
||||||
// Protocol item kind is 1 based, codes item kind is zero based.
|
|
||||||
set(item.kind, () => result.kind = item.kind - 1);
|
|
||||||
set(item.sortText, () => result.sortText = item.sortText);
|
|
||||||
set(item.textEdit, () => result.textEdit = asTextEdit(item.textEdit));
|
|
||||||
set(item.additionalTextEdits, () => result.additionalTextEdits = asTextEdits(item.additionalTextEdits));
|
|
||||||
set(item.command, () => result.command = asCommand(item.command));
|
|
||||||
set(item.data, () => result.data = item.data);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asTextEdit(edit: ls.TextEdit): code.TextEdit {
|
|
||||||
return new code.TextEdit(asRange(edit.range), edit.newText);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asTextEdits(items: ls.TextEdit[]): code.TextEdit[] {
|
|
||||||
if (is.undefined(items)) {
|
|
||||||
return undefined;
|
|
||||||
} else if (is.nil(items)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return items.map(asTextEdit);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asSignatureHelp(item: ls.SignatureHelp): code.SignatureHelp {
|
|
||||||
if (is.undefined(item)) {
|
|
||||||
return undefined;
|
|
||||||
} else if (is.nil(item)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
let result = new code.SignatureHelp();
|
|
||||||
set(item.activeParameter, () => result.activeParameter = item.activeParameter);
|
|
||||||
set(item.activeSignature, () => result.activeSignature = item.activeSignature);
|
|
||||||
set(item.signatures, () => result.signatures = asSignatureInformations(item.signatures));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asSignatureInformations(items: ls.SignatureInformation[]): code.SignatureInformation[] {
|
|
||||||
return items ? items.map(asSignatureInformation) : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asSignatureInformation(item: ls.SignatureInformation): code.SignatureInformation {
|
|
||||||
if (!item) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
let result = new code.SignatureInformation(item.label);
|
|
||||||
set(item.documentation, () => result.documentation = item.documentation);
|
|
||||||
set(item.parameters, () => result.parameters = asParameterInformations(item.parameters));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asParameterInformations(item: ls.ParameterInformation[]): code.ParameterInformation[] {
|
|
||||||
return item.map(asParameterInformation);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asParameterInformation(item: ls.ParameterInformation): code.ParameterInformation {
|
|
||||||
let result = new code.ParameterInformation(item.label);
|
|
||||||
set(item.documentation, () => result.documentation = item.documentation);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asDefinitionResult(item: ls.Definition): code.Definition {
|
|
||||||
if (is.undefined(item)) {
|
|
||||||
return undefined;
|
|
||||||
} else if (is.nil(item)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (is.array(item)) {
|
|
||||||
return item.map(asLocation);
|
|
||||||
} else {
|
|
||||||
return asLocation(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function asLocation(item: ls.Location): code.Location {
|
|
||||||
if (is.undefined(item)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (is.nil(item)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new code.Location(_uriConverter(item.uri), asRange(item.range));
|
|
||||||
}
|
|
||||||
|
|
||||||
function asReferences(values: ls.Location[]): code.Location[] {
|
|
||||||
if (is.undefined(values)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (is.nil(values)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return values.map(asLocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asDocumentHighlights(values: ls.DocumentHighlight[]): code.DocumentHighlight[] {
|
|
||||||
if (is.undefined(values)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (is.nil(values)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return values.map(asDocumentHighlight);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asDocumentHighlight(item: ls.DocumentHighlight): code.DocumentHighlight {
|
|
||||||
let result = new code.DocumentHighlight(asRange(item.range));
|
|
||||||
set(item.kind, () => result.kind = asDocumentHighlightKind(item.kind));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asDocumentHighlightKind(item: ls.DocumentHighlightKind): code.DocumentHighlightKind {
|
|
||||||
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: ls.SymbolInformation[], uri?: code.Uri): code.SymbolInformation[] {
|
|
||||||
if (is.undefined(values)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (is.nil(values)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return values.map(information => asSymbolInformation(information, uri));
|
|
||||||
}
|
|
||||||
|
|
||||||
function asSymbolInformation(item: ls.SymbolInformation, uri?: code.Uri): code.SymbolInformation {
|
|
||||||
// Symbol kind is one based in the protocol and zero based in code.
|
|
||||||
let result = new code.SymbolInformation(
|
|
||||||
item.name, item.kind - 1,
|
|
||||||
asRange(item.location.range),
|
|
||||||
item.location.uri ? _uriConverter(item.location.uri) : uri);
|
|
||||||
set(item.containerName, () => result.containerName = item.containerName);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asCommand(item: ls.Command): code.Command {
|
|
||||||
let result: code.Command = { title: item.title, command: item.command };
|
|
||||||
set(item.arguments, () => result.arguments = item.arguments);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asCommands(items: ls.Command[]): code.Command[] {
|
|
||||||
if (is.undefined(items)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (is.nil(items)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return items.map(asCommand);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asCodeLens(item: ls.CodeLens): code.CodeLens {
|
|
||||||
let result: ProtocolCodeLens = new ProtocolCodeLens(asRange(item.range));
|
|
||||||
if (is.defined(item.command)) { result.command = asCommand(item.command); }
|
|
||||||
if (is.defined(item.data)) { result.data = item.data; }
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asCodeLenses(items: ls.CodeLens[]): code.CodeLens[] {
|
|
||||||
if (is.undefined(items)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (is.nil(items)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return items.map(asCodeLens);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asWorkspaceEdit(item: ls.WorkspaceEdit): code.WorkspaceEdit {
|
|
||||||
if (is.undefined(item)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (is.nil(item)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
let result = new code.WorkspaceEdit();
|
|
||||||
let keys = Object.keys(item.changes);
|
|
||||||
keys.forEach(key => result.set(_uriConverter(key), asTextEdits(item.changes[key])));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asDocumentLink(item: ls.DocumentLink): code.DocumentLink {
|
|
||||||
let range = asRange(item.range);
|
|
||||||
let target = is.defined(item.target) && asUri(item.target);
|
|
||||||
return new code.DocumentLink(range, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asDocumentLinks(items: ls.DocumentLink[]): code.DocumentLink[] {
|
|
||||||
if (is.undefined(items)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (is.nil(items)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return items.map(asDocumentLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
function asConnectionSummary(params: ls.ConnectionCompleteParams): data.ConnectionInfoSummary {
|
|
||||||
let connSummary: data.ConnectionInfoSummary = {
|
|
||||||
ownerUri: params.ownerUri,
|
|
||||||
connectionId: params.connectionId,
|
|
||||||
messages: params.messages,
|
|
||||||
errorMessage: params.errorMessage,
|
|
||||||
errorNumber: params.errorNumber,
|
|
||||||
serverInfo: params.serverInfo,
|
|
||||||
connectionSummary: params.connectionSummary
|
|
||||||
};
|
|
||||||
return connSummary;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asServiceOptionType(val: string): data.ServiceOptionType {
|
|
||||||
if (val === 'string') {
|
|
||||||
return data.ServiceOptionType.string;
|
|
||||||
} else if (val === 'multistring') {
|
|
||||||
return data.ServiceOptionType.multistring;
|
|
||||||
} else if (val === 'password') {
|
|
||||||
return data.ServiceOptionType.password;
|
|
||||||
} else if (val === 'number') {
|
|
||||||
return data.ServiceOptionType.number;
|
|
||||||
} else if (val === 'boolean') {
|
|
||||||
return data.ServiceOptionType.boolean;
|
|
||||||
} else if (val === 'category') {
|
|
||||||
return data.ServiceOptionType.category;
|
|
||||||
} else if (val === 'object') {
|
|
||||||
return data.ServiceOptionType.object;
|
|
||||||
}
|
|
||||||
|
|
||||||
// assume string for unknown value types
|
|
||||||
return data.ServiceOptionType.string;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asServerCapabilities(result: ls.CapabiltiesDiscoveryResult): data.DataProtocolServerCapabilities {
|
|
||||||
let capabilities: data.DataProtocolServerCapabilities = {
|
|
||||||
protocolVersion: result.capabilities.protocolVersion,
|
|
||||||
providerName: result.capabilities.providerName,
|
|
||||||
providerDisplayName: result.capabilities.providerDisplayName,
|
|
||||||
connectionProvider: undefined,
|
|
||||||
adminServicesProvider: undefined,
|
|
||||||
features: []
|
|
||||||
};
|
|
||||||
|
|
||||||
if (result.capabilities.adminServicesProvider) {
|
|
||||||
capabilities.adminServicesProvider = <data.AdminServicesOptions>{
|
|
||||||
databaseInfoOptions: new Array<data.ServiceOption>(),
|
|
||||||
databaseFileInfoOptions: new Array<data.ServiceOption>(),
|
|
||||||
fileGroupInfoOptions: new Array<data.ServiceOption>()
|
|
||||||
};
|
|
||||||
|
|
||||||
if (result.capabilities.adminServicesProvider.databaseInfoOptions
|
|
||||||
&& result.capabilities.adminServicesProvider.databaseInfoOptions.length > 0) {
|
|
||||||
for (let i = 0; i < result.capabilities.adminServicesProvider.databaseInfoOptions.length; ++i) {
|
|
||||||
let srcOption: ls.ServiceOption = result.capabilities.adminServicesProvider.databaseInfoOptions[i];
|
|
||||||
let descOption: data.ServiceOption = buildServiceOption(srcOption);
|
|
||||||
capabilities.adminServicesProvider.databaseInfoOptions.push(descOption);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.capabilities.adminServicesProvider.databaseFileInfoOptions
|
|
||||||
&& result.capabilities.adminServicesProvider.databaseFileInfoOptions.length > 0) {
|
|
||||||
for (let i = 0; i < result.capabilities.adminServicesProvider.databaseFileInfoOptions.length; ++i) {
|
|
||||||
let srcOption: ls.ServiceOption = result.capabilities.adminServicesProvider.databaseFileInfoOptions[i];
|
|
||||||
let descOption: data.ServiceOption = buildServiceOption(srcOption);
|
|
||||||
capabilities.adminServicesProvider.databaseFileInfoOptions.push(descOption);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.capabilities.adminServicesProvider.fileGroupInfoOptions
|
|
||||||
&& result.capabilities.adminServicesProvider.fileGroupInfoOptions.length > 0) {
|
|
||||||
for (let i = 0; i < result.capabilities.adminServicesProvider.fileGroupInfoOptions.length; ++i) {
|
|
||||||
let srcOption: ls.ServiceOption = result.capabilities.adminServicesProvider.fileGroupInfoOptions[i];
|
|
||||||
let descOption: data.ServiceOption = buildServiceOption(srcOption);
|
|
||||||
capabilities.adminServicesProvider.fileGroupInfoOptions.push(descOption);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.capabilities.connectionProvider
|
|
||||||
&& result.capabilities.connectionProvider.options
|
|
||||||
&& result.capabilities.connectionProvider.options.length > 0) {
|
|
||||||
capabilities.connectionProvider = <data.ConnectionProviderOptions>{
|
|
||||||
options: new Array<data.ConnectionOption>()
|
|
||||||
};
|
|
||||||
for (let i = 0; i < result.capabilities.connectionProvider.options.length; ++i) {
|
|
||||||
let srcOption: ls.ConnectionOption = result.capabilities.connectionProvider.options[i];
|
|
||||||
let descOption: data.ConnectionOption = {
|
|
||||||
name: srcOption.name,
|
|
||||||
displayName: srcOption.displayName ? srcOption.displayName : srcOption.name,
|
|
||||||
description: srcOption.description,
|
|
||||||
groupName: srcOption.groupName,
|
|
||||||
defaultValue: srcOption.defaultValue,
|
|
||||||
categoryValues: srcOption.categoryValues,
|
|
||||||
isIdentity: srcOption.isIdentity,
|
|
||||||
isRequired: srcOption.isRequired,
|
|
||||||
valueType: asServiceOptionType(srcOption.valueType),
|
|
||||||
specialValueType: undefined
|
|
||||||
};
|
|
||||||
|
|
||||||
if (srcOption.specialValueType === 'serverName') {
|
|
||||||
descOption.specialValueType = data.ConnectionOptionSpecialType.serverName;
|
|
||||||
} else if (srcOption.specialValueType === 'databaseName') {
|
|
||||||
descOption.specialValueType = data.ConnectionOptionSpecialType.databaseName;
|
|
||||||
} else if (srcOption.specialValueType === 'authType') {
|
|
||||||
descOption.specialValueType = data.ConnectionOptionSpecialType.authType;
|
|
||||||
} else if (srcOption.specialValueType === 'userName') {
|
|
||||||
descOption.specialValueType = data.ConnectionOptionSpecialType.userName;
|
|
||||||
} else if (srcOption.specialValueType === 'password') {
|
|
||||||
descOption.specialValueType = data.ConnectionOptionSpecialType.password;
|
|
||||||
} else if (srcOption.specialValueType === 'appName') {
|
|
||||||
descOption.specialValueType = data.ConnectionOptionSpecialType.appName;
|
|
||||||
}
|
|
||||||
|
|
||||||
capabilities.connectionProvider.options.push(descOption);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.capabilities.features
|
|
||||||
&& result.capabilities.features.length > 0) {
|
|
||||||
result.capabilities.features.forEach(feature => {
|
|
||||||
let descFeature: data.FeatureMetadataProvider = {
|
|
||||||
enabled: feature.enabled,
|
|
||||||
featureName: feature.featureName,
|
|
||||||
optionsMetadata: []
|
|
||||||
};
|
|
||||||
capabilities.features.push(descFeature);
|
|
||||||
if (feature.optionsMetadata) {
|
|
||||||
feature.optionsMetadata.forEach(srcOption => {
|
|
||||||
descFeature.optionsMetadata.push(buildServiceOption(srcOption));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return capabilities;
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildServiceOption(srcOption: ls.ServiceOption): data.ServiceOption {
|
|
||||||
return {
|
|
||||||
name: srcOption.name,
|
|
||||||
displayName: srcOption.displayName ? srcOption.displayName : srcOption.name,
|
|
||||||
description: srcOption.description,
|
|
||||||
groupName: srcOption.groupName,
|
|
||||||
defaultValue: srcOption.defaultValue,
|
|
||||||
categoryValues: srcOption.categoryValues,
|
|
||||||
isRequired: srcOption.isRequired,
|
|
||||||
isArray: srcOption.isArray,
|
|
||||||
objectType: srcOption.objectType,
|
|
||||||
valueType: asServiceOptionType(srcOption.valueType),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asProviderMetadata(params: ls.MetadataQueryResult): data.ProviderMetadata {
|
|
||||||
let objectMetadata: data.ObjectMetadata[] = [];
|
|
||||||
|
|
||||||
if (!params.metadata || !params.metadata.length) {
|
|
||||||
return {
|
|
||||||
objectMetadata: objectMetadata
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < params.metadata.length; ++i) {
|
|
||||||
let metadata: ls.ObjectMetadata = params.metadata[i];
|
|
||||||
|
|
||||||
let metadataTypeName: string;
|
|
||||||
if (metadata.metadataTypeName) {
|
|
||||||
// Read from the provider since it's defined
|
|
||||||
metadataTypeName = metadata.metadataTypeName;
|
|
||||||
} else if (metadata.metadataType === ls.MetadataType.View) {
|
|
||||||
metadataTypeName = 'View';
|
|
||||||
} else if (metadata.metadataType === ls.MetadataType.SProc) {
|
|
||||||
metadataTypeName = 'StoredProcedure';
|
|
||||||
} else if (metadata.metadataType === ls.MetadataType.Function) {
|
|
||||||
metadataTypeName = 'Function';
|
|
||||||
} else {
|
|
||||||
metadataTypeName = 'Table';
|
|
||||||
}
|
|
||||||
|
|
||||||
objectMetadata.push({
|
|
||||||
metadataTypeName: metadataTypeName,
|
|
||||||
metadataType: metadata.metadataType,
|
|
||||||
name: metadata.name,
|
|
||||||
schema: metadata.schema,
|
|
||||||
urn: metadata.urn
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return <data.ProviderMetadata>{
|
|
||||||
objectMetadata: objectMetadata
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asObjectExplorerSession(params: ls.SessionCreatedParameters): data.ObjectExplorerSession {
|
|
||||||
return <data.ObjectExplorerSession>{
|
|
||||||
success: params.success,
|
|
||||||
sessionId: params.sessionId,
|
|
||||||
rootNode: params.rootNode,
|
|
||||||
errorMessage: params.errorMessage
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asObjectExplorerCreateSessionResponse(params: ls.CreateSessionResponse): data.ObjectExplorerSessionResponse {
|
|
||||||
return <data.ObjectExplorerSessionResponse>{
|
|
||||||
sessionId: params.sessionId
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asObjectExplorerNodeInfo(params: ls.ExpandResponse): data.ObjectExplorerExpandInfo {
|
|
||||||
return <data.ObjectExplorerExpandInfo>{
|
|
||||||
sessionId: params.sessionId,
|
|
||||||
nodes: params.nodes,
|
|
||||||
errorMessage: params.errorMessage,
|
|
||||||
nodePath: params.nodePath
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asObjectExplorerCloseSessionResponse(params: ls.CloseSessionResponse): data.ObjectExplorerCloseSessionResponse {
|
|
||||||
return <data.ObjectExplorerCloseSessionResponse>{
|
|
||||||
sessionId: params.sessionId,
|
|
||||||
success: params.success
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asScriptingResult(params: ls.ScriptingResult): data.ScriptingResult {
|
|
||||||
return <data.ScriptingResult>{
|
|
||||||
operationId: params.operationId,
|
|
||||||
script: params.script
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asListTasksResponse(response: ls.ListTasksResponse): data.ListTasksResponse {
|
|
||||||
return <data.ListTasksResponse>{
|
|
||||||
tasks: response.tasks
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asTaskInfo(params: ls.TaskInfo): data.TaskInfo {
|
|
||||||
return <data.TaskInfo>{
|
|
||||||
taskId: params.taskId,
|
|
||||||
status: params.status,
|
|
||||||
taskExecutionMode: params.taskExecutionMode,
|
|
||||||
serverName: params.serverName,
|
|
||||||
name: params.name,
|
|
||||||
databaseName: params.databaseName,
|
|
||||||
description: params.description,
|
|
||||||
providerName: params.providerName,
|
|
||||||
isCancelable: params.isCancelable,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asRestorePlanResponse(params: ls.RestorePlanResponse): data.RestorePlanResponse {
|
|
||||||
return <data.RestorePlanResponse>{
|
|
||||||
backupSetsToRestore: params.backupSetsToRestore,
|
|
||||||
canRestore: params.canRestore,
|
|
||||||
databaseNamesFromBackupSets: params.databaseNamesFromBackupSets,
|
|
||||||
dbFiles: params.dbFiles,
|
|
||||||
errorMessage: params.errorMessage,
|
|
||||||
planDetails: params.planDetails,
|
|
||||||
sessionId: params.sessionId
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asRestoreResponse(params: ls.RestoreResponse): data.RestoreResponse {
|
|
||||||
return <data.RestoreResponse>{
|
|
||||||
result: params.result,
|
|
||||||
errorMessage: params.errorMessage,
|
|
||||||
taskId: params.taskId
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function asRestoreConfigInfo(params: ls.RestoreConfigInfoResponse): data.RestoreConfigInfo {
|
|
||||||
return <data.RestoreConfigInfo>{
|
|
||||||
configInfo: params.configInfo
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
asUri,
|
|
||||||
asDiagnostics,
|
|
||||||
asDiagnostic,
|
|
||||||
asRange,
|
|
||||||
asPosition,
|
|
||||||
asDiagnosticSeverity,
|
|
||||||
asHover,
|
|
||||||
asCompletionResult,
|
|
||||||
asCompletionItem,
|
|
||||||
asTextEdit,
|
|
||||||
asTextEdits,
|
|
||||||
asSignatureHelp,
|
|
||||||
asSignatureInformations,
|
|
||||||
asSignatureInformation,
|
|
||||||
asParameterInformations,
|
|
||||||
asParameterInformation,
|
|
||||||
asDefinitionResult,
|
|
||||||
asLocation,
|
|
||||||
asReferences,
|
|
||||||
asDocumentHighlights,
|
|
||||||
asDocumentHighlight,
|
|
||||||
asDocumentHighlightKind,
|
|
||||||
asSymbolInformations,
|
|
||||||
asSymbolInformation,
|
|
||||||
asCommand,
|
|
||||||
asCommands,
|
|
||||||
asCodeLens,
|
|
||||||
asCodeLenses,
|
|
||||||
asWorkspaceEdit,
|
|
||||||
asDocumentLink,
|
|
||||||
asDocumentLinks,
|
|
||||||
asConnectionSummary,
|
|
||||||
asServerCapabilities,
|
|
||||||
asProviderMetadata,
|
|
||||||
asScriptingResult,
|
|
||||||
asObjectExplorerSession,
|
|
||||||
asObjectExplorerCreateSessionResponse,
|
|
||||||
asObjectExplorerNodeInfo,
|
|
||||||
asObjectExplorerCloseSessionResponse,
|
|
||||||
asListTasksResponse,
|
|
||||||
asTaskInfo,
|
|
||||||
asRestorePlanResponse,
|
|
||||||
asRestoreResponse,
|
|
||||||
asRestoreConfigInfo
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// This for backward compatibility since we exported the converter functions as API.
|
|
||||||
const defaultConverter = createConverter();
|
|
||||||
|
|
||||||
export const asDiagnostics: (diagnostics: ls.Diagnostic[]) => code.Diagnostic[] = defaultConverter.asDiagnostics;
|
|
||||||
export const asDiagnostic: (diagnostic: ls.Diagnostic) => code.Diagnostic = defaultConverter.asDiagnostic;
|
|
||||||
export const asRange: (value: ls.Range) => code.Range = defaultConverter.asRange;
|
|
||||||
export const asPosition: (value: ls.Position) => code.Position = defaultConverter.asPosition;
|
|
||||||
export const asDiagnosticSeverity: (value: number) => code.DiagnosticSeverity = defaultConverter.asDiagnosticSeverity;
|
|
||||||
export const asHover: (hover: ls.Hover) => code.Hover = defaultConverter.asHover;
|
|
||||||
export const asCompletionResult: (result: ls.CompletionItem[] | ls.CompletionList) => code.CompletionItem[] | code.CompletionList = defaultConverter.asCompletionResult;
|
|
||||||
export const asCompletionItem: (item: ls.CompletionItem) => ProtocolCompletionItem = defaultConverter.asCompletionItem;
|
|
||||||
export const asTextEdit: (edit: ls.TextEdit) => code.TextEdit = defaultConverter.asTextEdit;
|
|
||||||
export const asTextEdits: (items: ls.TextEdit[]) => code.TextEdit[] = defaultConverter.asTextEdits;
|
|
||||||
export const asSignatureHelp: (item: ls.SignatureHelp) => code.SignatureHelp = defaultConverter.asSignatureHelp;
|
|
||||||
export const asSignatureInformations: (items: ls.SignatureInformation[]) => code.SignatureInformation[] = defaultConverter.asSignatureInformations;
|
|
||||||
export const asSignatureInformation: (item: ls.SignatureInformation) => code.SignatureInformation = defaultConverter.asSignatureInformation;
|
|
||||||
export const asParameterInformations: (item: ls.ParameterInformation[]) => code.ParameterInformation[] = defaultConverter.asParameterInformations;
|
|
||||||
export const asParameterInformation: (item: ls.ParameterInformation) => code.ParameterInformation = defaultConverter.asParameterInformation;
|
|
||||||
export const asDefinitionResult: (item: ls.Definition) => code.Definition = defaultConverter.asDefinitionResult;
|
|
||||||
export const asLocation: (item: ls.Location) => code.Location = defaultConverter.asLocation;
|
|
||||||
export const asReferences: (values: ls.Location[]) => code.Location[] = defaultConverter.asReferences;
|
|
||||||
export const asDocumentHighlights: (values: ls.DocumentHighlight[]) => code.DocumentHighlight[] = defaultConverter.asDocumentHighlights;
|
|
||||||
export const asDocumentHighlight: (item: ls.DocumentHighlight) => code.DocumentHighlight = defaultConverter.asDocumentHighlight;
|
|
||||||
export const asDocumentHighlightKind: (item: ls.DocumentHighlightKind) => code.DocumentHighlightKind = defaultConverter.asDocumentHighlightKind;
|
|
||||||
export const asSymbolInformations: (values: ls.SymbolInformation[], uri?: code.Uri) => code.SymbolInformation[] = defaultConverter.asSymbolInformations;
|
|
||||||
export const asSymbolInformation: (item: ls.SymbolInformation, uri?: code.Uri) => code.SymbolInformation = defaultConverter.asSymbolInformation;
|
|
||||||
export const asCommand: (item: ls.Command) => code.Command = defaultConverter.asCommand;
|
|
||||||
export const asCommands: (items: ls.Command[]) => code.Command[] = defaultConverter.asCommands;
|
|
||||||
export const asCodeLens: (item: ls.CodeLens) => code.CodeLens = defaultConverter.asCodeLens;
|
|
||||||
export const asCodeLenses: (items: ls.CodeLens[]) => code.CodeLens[] = defaultConverter.asCodeLenses;
|
|
||||||
export const asWorkspaceEdit: (item: ls.WorkspaceEdit) => code.WorkspaceEdit = defaultConverter.asWorkspaceEdit;
|
|
||||||
export const asDocumentLink: (item: ls.DocumentLink) => code.DocumentLink = defaultConverter.asDocumentLink;
|
|
||||||
export const asDocumentLinks: (item: ls.DocumentLink[]) => code.DocumentLink[] = defaultConverter.asDocumentLinks;
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "es5",
|
|
||||||
"module": "commonjs",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"sourceMap": false,
|
|
||||||
"inlineSources": false,
|
|
||||||
"declaration": true,
|
|
||||||
"stripInternal": true,
|
|
||||||
"outDir": "../lib"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
// Type definitions for es6-promise
|
|
||||||
// Project: https://github.com/jakearchibald/ES6-Promise
|
|
||||||
// Definitions by: François de Campredon <https://github.com/fdecampredon/>, vvakame <https://github.com/vvakame>
|
|
||||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
|
||||||
|
|
||||||
interface Thenable<T> {
|
|
||||||
then<U>(onFulfilled?: (value: T) => U | Thenable<U>, onRejected?: (error: any) => U | Thenable<U>): Thenable<U>;
|
|
||||||
then<U>(onFulfilled?: (value: T) => U | Thenable<U>, onRejected?: (error: any) => void): Thenable<U>;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare class Promise<T> implements Thenable<T> {
|
|
||||||
/**
|
|
||||||
* If you call resolve in the body of the callback passed to the constructor,
|
|
||||||
* your promise is fulfilled with result object passed to resolve.
|
|
||||||
* If you call reject your promise is rejected with the object passed to reject.
|
|
||||||
* For consistency and debugging (eg stack traces), obj should be an instanceof Error.
|
|
||||||
* Any errors thrown in the constructor callback will be implicitly passed to reject().
|
|
||||||
*/
|
|
||||||
constructor(callback: (resolve : (value?: T | Thenable<T>) => void, reject: (error?: any) => void) => void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* onFulfilled is called when/if "promise" resolves. onRejected is called when/if "promise" rejects.
|
|
||||||
* Both are optional, if either/both are omitted the next onFulfilled/onRejected in the chain is called.
|
|
||||||
* Both callbacks have a single parameter , the fulfillment value or rejection reason.
|
|
||||||
* "then" returns a new promise equivalent to the value you return from onFulfilled/onRejected after being passed through Promise.resolve.
|
|
||||||
* If an error is thrown in the callback, the returned promise rejects with that error.
|
|
||||||
*
|
|
||||||
* @param onFulfilled called when/if "promise" resolves
|
|
||||||
* @param onRejected called when/if "promise" rejects
|
|
||||||
*/
|
|
||||||
then<U>(onFulfilled?: (value: T) => U | Thenable<U>, onRejected?: (error: any) => U | Thenable<U>): Promise<U>;
|
|
||||||
then<U>(onFulfilled?: (value: T) => U | Thenable<U>, onRejected?: (error: any) => void): Promise<U>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sugar for promise.then(undefined, onRejected)
|
|
||||||
*
|
|
||||||
* @param onRejected called when/if "promise" rejects
|
|
||||||
*/
|
|
||||||
catch<U>(onRejected?: (error: any) => U | Thenable<U>): Promise<U>;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare namespace Promise {
|
|
||||||
/**
|
|
||||||
* Make a new promise from the thenable.
|
|
||||||
* A thenable is promise-like in as far as it has a "then" method.
|
|
||||||
*/
|
|
||||||
function resolve<T>(value?: T | Thenable<T>): Promise<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make a promise that rejects to obj. For consistency and debugging (eg stack traces), obj should be an instanceof Error
|
|
||||||
*/
|
|
||||||
function reject(error: any): Promise<any>;
|
|
||||||
function reject<T>(error: T): Promise<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make a promise that fulfills when every item in the array fulfills, and rejects if (and when) any item rejects.
|
|
||||||
* the array passed to all can be a mixture of promise-like objects and other objects.
|
|
||||||
* The fulfillment value is an array (in order) of fulfillment values. The rejection value is the first rejection value.
|
|
||||||
*/
|
|
||||||
function all<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>, T8 | Thenable<T8>, T9 | Thenable<T9>, T10 | Thenable<T10>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>;
|
|
||||||
function all<T1, T2, T3, T4, T5, T6, T7, T8, T9>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>, T8 | Thenable<T8>, T9 | Thenable<T9>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>;
|
|
||||||
function all<T1, T2, T3, T4, T5, T6, T7, T8>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>, T8 | Thenable<T8>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>;
|
|
||||||
function all<T1, T2, T3, T4, T5, T6, T7>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>]): Promise<[T1, T2, T3, T4, T5, T6, T7]>;
|
|
||||||
function all<T1, T2, T3, T4, T5, T6>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>]): Promise<[T1, T2, T3, T4, T5, T6]>;
|
|
||||||
function all<T1, T2, T3, T4, T5>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>]): Promise<[T1, T2, T3, T4, T5]>;
|
|
||||||
function all<T1, T2, T3, T4>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>]): Promise<[T1, T2, T3, T4]>;
|
|
||||||
function all<T1, T2, T3>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>]): Promise<[T1, T2, T3]>;
|
|
||||||
function all<T1, T2>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>]): Promise<[T1, T2]>;
|
|
||||||
function all<T>(values: (T | Thenable<T>)[]): Promise<T[]>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make a Promise that fulfills when any item fulfills, and rejects if any item rejects.
|
|
||||||
*/
|
|
||||||
function race<T>(promises: (T | Thenable<T>)[]): Promise<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module 'es6-promise' {
|
|
||||||
var foo: typeof Promise; // Temp variable to reference Promise in local context
|
|
||||||
namespace rsvp {
|
|
||||||
export var Promise: typeof foo;
|
|
||||||
export function polyfill(): void;
|
|
||||||
}
|
|
||||||
export = rsvp;
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"module": "commonjs",
|
|
||||||
"lib": [
|
|
||||||
"es5",
|
|
||||||
"dom"
|
|
||||||
],
|
|
||||||
"noImplicitAny": true,
|
|
||||||
"noImplicitThis": true,
|
|
||||||
"strictNullChecks": false,
|
|
||||||
"baseUrl": "../",
|
|
||||||
"typeRoots": [
|
|
||||||
"../"
|
|
||||||
],
|
|
||||||
"types": [],
|
|
||||||
"noEmit": true,
|
|
||||||
"forceConsistentCasingInFileNames": true
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"index.d.ts",
|
|
||||||
"es6-promise-tests.ts"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/// <reference path='../../../../src/vs/vscode.d.ts'/>
|
|
||||||
/// <reference path='../../../../src/sql/data.d.ts'/>
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
* ------------------------------------------------------------------------------------------ */
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
export interface ITask<T> {
|
|
||||||
(): T;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Delayer<T> {
|
|
||||||
|
|
||||||
public defaultDelay: number;
|
|
||||||
private timeout: NodeJS.Timer;
|
|
||||||
private completionPromise: Promise<T>;
|
|
||||||
private onSuccess: (value?: T | Thenable<T>) => void;
|
|
||||||
private task: ITask<T>;
|
|
||||||
|
|
||||||
constructor(defaultDelay: number) {
|
|
||||||
this.defaultDelay = defaultDelay;
|
|
||||||
this.timeout = null;
|
|
||||||
this.completionPromise = null;
|
|
||||||
this.onSuccess = null;
|
|
||||||
this.task = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public trigger(task: ITask<T>, delay: number = this.defaultDelay): Promise<T> {
|
|
||||||
this.task = task;
|
|
||||||
if (delay >= 0) {
|
|
||||||
this.cancelTimeout();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.completionPromise) {
|
|
||||||
this.completionPromise = new Promise<T>((resolve) => {
|
|
||||||
this.onSuccess = resolve
|
|
||||||
}).then(() => {
|
|
||||||
this.completionPromise = null;
|
|
||||||
this.onSuccess = null;
|
|
||||||
var result = this.task();
|
|
||||||
this.task = null;
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (delay >= 0 || this.timeout === null) {
|
|
||||||
this.timeout = setTimeout(() => {
|
|
||||||
this.timeout = null;
|
|
||||||
this.onSuccess(null);
|
|
||||||
}, delay >= 0 ? delay : this.defaultDelay);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.completionPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
public forceDelivery(): T {
|
|
||||||
if (!this.completionPromise) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
this.cancelTimeout();
|
|
||||||
let result: T = this.task();
|
|
||||||
this.completionPromise = null;
|
|
||||||
this.onSuccess = null;
|
|
||||||
this.task = null;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public isTriggered(): boolean {
|
|
||||||
return this.timeout !== null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public cancel(): void {
|
|
||||||
this.cancelTimeout();
|
|
||||||
this.completionPromise = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private cancelTimeout(): void {
|
|
||||||
if (this.timeout !== null) {
|
|
||||||
clearTimeout(this.timeout);
|
|
||||||
this.timeout = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
* ------------------------------------------------------------------------------------------ */
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import path = require('path');
|
|
||||||
import os = require('os');
|
|
||||||
import net = require('net');
|
|
||||||
import cp = require('child_process');
|
|
||||||
|
|
||||||
export interface IForkOptions {
|
|
||||||
cwd?: string;
|
|
||||||
env?: any;
|
|
||||||
encoding?: string;
|
|
||||||
execArgv?: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeRandomHexString(length: number): string {
|
|
||||||
let chars = ['0', '1', '2', '3', '4', '5', '6', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
|
|
||||||
let result = '';
|
|
||||||
for (let i = 0; i < length; i++) {
|
|
||||||
let idx = Math.floor(chars.length * Math.random());
|
|
||||||
result += chars[idx];
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function generatePipeName(): string {
|
|
||||||
var randomName = 'vscode-' + makeRandomHexString(40);
|
|
||||||
if (process.platform === 'win32') {
|
|
||||||
return '\\\\.\\pipe\\' + randomName + '-sock';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mac/Unix: use socket file
|
|
||||||
return path.join(os.tmpdir(), randomName + '.sock');
|
|
||||||
}
|
|
||||||
|
|
||||||
function generatePatchedEnv(env: any, stdInPipeName: string, stdOutPipeName: string): any {
|
|
||||||
// Set the two unique pipe names and the electron flag as process env
|
|
||||||
|
|
||||||
var newEnv: any = {};
|
|
||||||
for (var key in env) {
|
|
||||||
newEnv[key] = env[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
newEnv['STDIN_PIPE_NAME'] = stdInPipeName;
|
|
||||||
newEnv['STDOUT_PIPE_NAME'] = stdOutPipeName;
|
|
||||||
newEnv['ATOM_SHELL_INTERNAL_RUN_AS_NODE'] = '1';
|
|
||||||
|
|
||||||
return newEnv;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function fork(modulePath: string, args: string[], options: IForkOptions, callback: (error: any, cp: cp.ChildProcess) => void): void {
|
|
||||||
|
|
||||||
var callbackCalled = false;
|
|
||||||
var resolve = (result: cp.ChildProcess) => {
|
|
||||||
if (callbackCalled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callbackCalled = true;
|
|
||||||
callback(null, result);
|
|
||||||
};
|
|
||||||
var reject = (err: any) => {
|
|
||||||
if (callbackCalled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callbackCalled = true;
|
|
||||||
callback(err, null);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Generate two unique pipe names
|
|
||||||
var stdInPipeName = generatePipeName();
|
|
||||||
var stdOutPipeName = generatePipeName();
|
|
||||||
|
|
||||||
var newEnv = generatePatchedEnv(options.env || process.env, stdInPipeName, stdOutPipeName);
|
|
||||||
|
|
||||||
var childProcess: cp.ChildProcess;
|
|
||||||
|
|
||||||
// Begin listening to stdout pipe
|
|
||||||
var server = net.createServer((stream) => {
|
|
||||||
// The child process will write exactly one chunk with content `ready` when it has installed a listener to the stdin pipe
|
|
||||||
|
|
||||||
stream.once('data', (chunk: Buffer) => {
|
|
||||||
// The child process is sending me the `ready` chunk, time to connect to the stdin pipe
|
|
||||||
childProcess.stdin = <any>net.connect(stdInPipeName);
|
|
||||||
|
|
||||||
// From now on the childProcess.stdout is available for reading
|
|
||||||
childProcess.stdout = stream;
|
|
||||||
|
|
||||||
resolve(childProcess);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
server.listen(stdOutPipeName);
|
|
||||||
|
|
||||||
var serverClosed = false;
|
|
||||||
var closeServer = () => {
|
|
||||||
if (serverClosed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
serverClosed = true;
|
|
||||||
server.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the process
|
|
||||||
let bootstrapperPath = path.join(__dirname, 'electronForkStart');
|
|
||||||
childProcess = cp.fork(bootstrapperPath, [modulePath].concat(args), <any>{
|
|
||||||
silent: true,
|
|
||||||
cwd: options.cwd,
|
|
||||||
env: newEnv,
|
|
||||||
execArgv: options.execArgv
|
|
||||||
});
|
|
||||||
|
|
||||||
childProcess.once('error', (err: Error) => {
|
|
||||||
closeServer();
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
childProcess.once('exit', (err: Error) => {
|
|
||||||
closeServer();
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
* ------------------------------------------------------------------------------------------ */
|
|
||||||
var net = require('net'),
|
|
||||||
fs = require('fs'),
|
|
||||||
stream = require('stream'),
|
|
||||||
util = require('util');
|
|
||||||
|
|
||||||
var ENABLE_LOGGING = false;
|
|
||||||
|
|
||||||
var log = (function () {
|
|
||||||
if (!ENABLE_LOGGING) {
|
|
||||||
return function () { };
|
|
||||||
}
|
|
||||||
var isFirst = true;
|
|
||||||
var LOG_LOCATION = 'C:\\stdFork.log';
|
|
||||||
return function log(str) {
|
|
||||||
if (isFirst) {
|
|
||||||
isFirst = false;
|
|
||||||
fs.writeFileSync(LOG_LOCATION, str + '\n');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fs.appendFileSync(LOG_LOCATION, str + '\n');
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
var stdInPipeName = process.env['STDIN_PIPE_NAME'];
|
|
||||||
var stdOutPipeName = process.env['STDOUT_PIPE_NAME'];
|
|
||||||
|
|
||||||
log('STDIN_PIPE_NAME: ' + stdInPipeName);
|
|
||||||
log('STDOUT_PIPE_NAME: ' + stdOutPipeName);
|
|
||||||
log('ATOM_SHELL_INTERNAL_RUN_AS_NODE: ' + process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE']);
|
|
||||||
|
|
||||||
// stdout redirection to named pipe
|
|
||||||
(function () {
|
|
||||||
log('Beginning stdout redirection...');
|
|
||||||
|
|
||||||
// Create a writing stream to the stdout pipe
|
|
||||||
var stdOutStream = net.connect(stdOutPipeName);
|
|
||||||
|
|
||||||
// unref stdOutStream to behave like a normal standard out
|
|
||||||
stdOutStream.unref();
|
|
||||||
|
|
||||||
// handle process.stdout
|
|
||||||
(<any>process).__defineGetter__('stdout', function () { return stdOutStream; });
|
|
||||||
|
|
||||||
// handle process.stderr
|
|
||||||
(<any>process).__defineGetter__('stderr', function () { return stdOutStream; });
|
|
||||||
|
|
||||||
var fsWriteSyncString = function (fd, str, position, encoding) {
|
|
||||||
// fs.writeSync(fd, string[, position[, encoding]]);
|
|
||||||
var buf = new Buffer(str, encoding || 'utf8');
|
|
||||||
return fsWriteSyncBuffer(fd, buf, 0, buf.length);
|
|
||||||
};
|
|
||||||
|
|
||||||
var fsWriteSyncBuffer = function (fd, buffer, off, len) {
|
|
||||||
off = Math.abs(off | 0);
|
|
||||||
len = Math.abs(len | 0);
|
|
||||||
|
|
||||||
// fs.writeSync(fd, buffer, offset, length[, position]);
|
|
||||||
var buffer_length = buffer.length;
|
|
||||||
|
|
||||||
if (off > buffer_length) {
|
|
||||||
throw new Error('offset out of bounds');
|
|
||||||
}
|
|
||||||
if (len > buffer_length) {
|
|
||||||
throw new Error('length out of bounds');
|
|
||||||
}
|
|
||||||
if (((off + len) | 0) < off) {
|
|
||||||
throw new Error('off + len overflow');
|
|
||||||
}
|
|
||||||
if (buffer_length - off < len) {
|
|
||||||
// Asking for more than is left over in the buffer
|
|
||||||
throw new Error('off + len > buffer.length');
|
|
||||||
}
|
|
||||||
|
|
||||||
var slicedBuffer = buffer;
|
|
||||||
if (off !== 0 || len !== buffer_length) {
|
|
||||||
slicedBuffer = buffer.slice(off, off + len);
|
|
||||||
}
|
|
||||||
|
|
||||||
stdOutStream.write(slicedBuffer);
|
|
||||||
return slicedBuffer.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
// handle fs.writeSync(1, ...)
|
|
||||||
var originalWriteSync = fs.writeSync;
|
|
||||||
fs.writeSync = function (fd, data, position, encoding) {
|
|
||||||
if (fd !== 1) {
|
|
||||||
return originalWriteSync.apply(fs, arguments);
|
|
||||||
}
|
|
||||||
// usage:
|
|
||||||
// fs.writeSync(fd, buffer, offset, length[, position]);
|
|
||||||
// OR
|
|
||||||
// fs.writeSync(fd, string[, position[, encoding]]);
|
|
||||||
|
|
||||||
if (data instanceof Buffer) {
|
|
||||||
return fsWriteSyncBuffer.apply(null, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
// For compatibility reasons with fs.writeSync, writing null will write "null", etc
|
|
||||||
if (typeof data !== 'string') {
|
|
||||||
data += '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return fsWriteSyncString.apply(null, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
log('Finished defining process.stdout, process.stderr and fs.writeSync');
|
|
||||||
})();
|
|
||||||
|
|
||||||
// stdin redirection to named pipe
|
|
||||||
(function () {
|
|
||||||
|
|
||||||
// Begin listening to stdin pipe
|
|
||||||
var server = net.createServer(function (stream) {
|
|
||||||
// Stop accepting new connections, keep the existing one alive
|
|
||||||
server.close();
|
|
||||||
|
|
||||||
log('Parent process has connected to my stdin. All should be good now.');
|
|
||||||
|
|
||||||
// handle process.stdin
|
|
||||||
(<any>process).__defineGetter__('stdin', function () {
|
|
||||||
return stream;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove myself from process.argv
|
|
||||||
process.argv.splice(1, 1);
|
|
||||||
|
|
||||||
// Load the actual program
|
|
||||||
var program = process.argv[1];
|
|
||||||
log('Loading program: ' + program);
|
|
||||||
|
|
||||||
// Unset the custom environmental variables that should not get inherited
|
|
||||||
delete process.env['STDIN_PIPE_NAME'];
|
|
||||||
delete process.env['STDOUT_PIPE_NAME'];
|
|
||||||
delete process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'];
|
|
||||||
|
|
||||||
require(program);
|
|
||||||
|
|
||||||
log('Finished loading program.');
|
|
||||||
|
|
||||||
var stdinIsReferenced = true;
|
|
||||||
var timer = setInterval(function () {
|
|
||||||
var listenerCount = (
|
|
||||||
stream.listeners('data').length +
|
|
||||||
stream.listeners('end').length +
|
|
||||||
stream.listeners('close').length +
|
|
||||||
stream.listeners('error').length
|
|
||||||
);
|
|
||||||
// log('listenerCount: ' + listenerCount);
|
|
||||||
if (listenerCount <= 1) {
|
|
||||||
// No more "actual" listeners, only internal node
|
|
||||||
if (stdinIsReferenced) {
|
|
||||||
stdinIsReferenced = false;
|
|
||||||
// log('unreferencing stream!!!');
|
|
||||||
stream.unref();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// There are "actual" listeners
|
|
||||||
if (!stdinIsReferenced) {
|
|
||||||
stdinIsReferenced = true;
|
|
||||||
stream.ref();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// log(
|
|
||||||
// '' + stream.listeners('data').length +
|
|
||||||
// ' ' + stream.listeners('end').length +
|
|
||||||
// ' ' + stream.listeners('close').length +
|
|
||||||
// ' ' + stream.listeners('error').length
|
|
||||||
// );
|
|
||||||
}, 1000);
|
|
||||||
timer.unref();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
server.listen(stdInPipeName, function () {
|
|
||||||
// signal via stdout that the parent process can now begin writing to stdin pipe
|
|
||||||
process.stdout.write('ready');
|
|
||||||
});
|
|
||||||
|
|
||||||
})();
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
* ------------------------------------------------------------------------------------------ */
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const toString = Object.prototype.toString;
|
|
||||||
|
|
||||||
export function defined(value: any): boolean {
|
|
||||||
return typeof value !== 'undefined';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function undefined(value: any): boolean {
|
|
||||||
return typeof value === 'undefined';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function nil(value: any): boolean {
|
|
||||||
return value === null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function boolean(value: any): value is boolean {
|
|
||||||
return value === true || value === false;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function string(value: any): value is string {
|
|
||||||
return toString.call(value) === '[object String]';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function number(value: any): value is number {
|
|
||||||
return toString.call(value) === '[object Number]';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function error(value: any): value is Error {
|
|
||||||
return toString.call(value) === '[object Error]';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function func(value: any): value is Function {
|
|
||||||
return toString.call(value) === '[object Function]';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function array<T>(value: any): value is T[] {
|
|
||||||
return Array.isArray(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function stringArray(value: any): value is string[] {
|
|
||||||
return array(value) && (<any[]>value).every(elem => string(elem));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function typedArray<T>(value: any, check: (value: any) => boolean): value is T[] {
|
|
||||||
return Array.isArray(value) && (<any[]>value).every(check);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function thenable<T>(value: any): value is Thenable<T> {
|
|
||||||
return value && func(value.then);
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
* ------------------------------------------------------------------------------------------ */
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import * as cp from 'child_process';
|
|
||||||
import ChildProcess = cp.ChildProcess;
|
|
||||||
|
|
||||||
import { join } from 'path';
|
|
||||||
|
|
||||||
const isWindows = (process.platform === 'win32');
|
|
||||||
const isMacintosh = (process.platform === 'darwin');
|
|
||||||
const isLinux = (process.platform === 'linux');
|
|
||||||
export function terminate(process: ChildProcess, cwd?: string): boolean {
|
|
||||||
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: any = {
|
|
||||||
stdio: ['pipe', 'pipe', 'ignore']
|
|
||||||
};
|
|
||||||
if (cwd) {
|
|
||||||
options.cwd = cwd
|
|
||||||
}
|
|
||||||
(<any>cp).execFileSync('taskkill', ['/T', '/F', '/PID', process.pid.toString()], options);
|
|
||||||
return true;
|
|
||||||
} catch (err) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (isLinux || isMacintosh) {
|
|
||||||
try {
|
|
||||||
var cmd = join(__dirname, 'terminateProcess.sh');
|
|
||||||
var result = (<any>cp).spawnSync(cmd, [process.pid.toString()]);
|
|
||||||
return result.error ? false : true;
|
|
||||||
} catch (err) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
process.kill('SIGKILL');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# --------------------------------------------------------------------------------------------
|
|
||||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
# Licensed under the Source EULA. 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
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
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.
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
"rules": {
|
|
||||||
"indent": [
|
|
||||||
2,
|
|
||||||
"tab"
|
|
||||||
],
|
|
||||||
"quotes": [
|
|
||||||
2,
|
|
||||||
"single"
|
|
||||||
],
|
|
||||||
"linebreak-style": [
|
|
||||||
2,
|
|
||||||
"windows"
|
|
||||||
],
|
|
||||||
"semi": [
|
|
||||||
2,
|
|
||||||
"always"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"env": {
|
|
||||||
"node": true
|
|
||||||
},
|
|
||||||
"extends": "eslint:recommended"
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
.vscode/
|
|
||||||
lib/test/
|
|
||||||
lib/*.map
|
|
||||||
src/
|
|
||||||
test/
|
|
||||||
.eslintrc
|
|
||||||
.gitignore
|
|
||||||
gulpfile.js
|
|
||||||
tsd.json
|
|
||||||
32
dataprotocol-node/jsonrpc/.vscode/launch.json
vendored
32
dataprotocol-node/jsonrpc/.vscode/launch.json
vendored
@@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "0.1.0",
|
|
||||||
// List of configurations. Add new configurations or edit existing ones.
|
|
||||||
// ONLY "node" and "mono" are supported, change "type" to switch.
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"request": "launch",
|
|
||||||
// Name of configuration; appears in the launch configuration drop down menu.
|
|
||||||
"name": "Mocha",
|
|
||||||
// Type of configuration. Possible values: "node", "mono".
|
|
||||||
"type": "node",
|
|
||||||
// Workspace relative or absolute path to the program.
|
|
||||||
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
|
|
||||||
// Automatically stop program after launch.
|
|
||||||
"stopOnEntry": false,
|
|
||||||
// Command line arguments passed to the program.
|
|
||||||
"args": ["--timeout", "999999"],
|
|
||||||
// Workspace relative or absolute path to the working directory of the program being debugged. Default is the current workspace.
|
|
||||||
"cwd": "${workspaceRoot}",
|
|
||||||
// Workspace relative or absolute path to the runtime executable to be used. Default is the runtime executable on the PATH.
|
|
||||||
"runtimeExecutable": null,
|
|
||||||
// Optional arguments passed to the runtime executable.
|
|
||||||
"runtimeArgs": [],
|
|
||||||
// Environment variables passed to the program.
|
|
||||||
"env": { },
|
|
||||||
// Use JavaScript source maps (if they exist).
|
|
||||||
"sourceMaps": true,
|
|
||||||
// If JavaScript source maps are enabled, the generated code is expected in this directory.
|
|
||||||
"outDir": "${workspaceRoot}/lib"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
// Place your settings in this file to overwrite default and user settings.
|
|
||||||
{
|
|
||||||
"javascript.validate.enable": false,
|
|
||||||
"files.trimTrailingWhitespace": true,
|
|
||||||
"eslint.enable": false,
|
|
||||||
"editor.insertSpaces": false,
|
|
||||||
"editor.tabSize": 4,
|
|
||||||
"typescript.tsdk": "./node_modules/typescript/lib"
|
|
||||||
}
|
|
||||||
9
dataprotocol-node/jsonrpc/.vscode/tasks.json
vendored
9
dataprotocol-node/jsonrpc/.vscode/tasks.json
vendored
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "0.1.0",
|
|
||||||
"command": "npm",
|
|
||||||
"isShellCommand": true,
|
|
||||||
"args": ["run", "watch"],
|
|
||||||
"showOutput": "silent",
|
|
||||||
"isWatching": true,
|
|
||||||
"problemMatcher": "$tsc-watch"
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# Microsoft Data Management Protocol - Node
|
|
||||||
|
|
||||||
## License
|
|
||||||
[MIT](https://github.com/Microsoft/carbon/blob/dev/license.txt)
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "dataprotocol-jsonrpc",
|
|
||||||
"description": "A json rpc implementation over streams",
|
|
||||||
"version": "2.4.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": ">=4.0.0 || >=6.0.0"
|
|
||||||
},
|
|
||||||
"main": "./lib/main.js",
|
|
||||||
"typings": "./lib/main",
|
|
||||||
"devDependencies": {
|
|
||||||
"mocha": "^3.0.2",
|
|
||||||
"typescript": "2.0.3"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"prepublish": "tsc -p ./src",
|
|
||||||
"compile": "tsc -p ./src",
|
|
||||||
"watch": "tsc -w -p ./src",
|
|
||||||
"test": "mocha"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import { Event, Emitter } from './events';
|
|
||||||
|
|
||||||
export interface CancellationToken {
|
|
||||||
/**
|
|
||||||
* Is `true` when the token has been cancelled, `false` otherwise.
|
|
||||||
*/
|
|
||||||
isCancellationRequested: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An [event](#Event) which fires upon cancellation.
|
|
||||||
*/
|
|
||||||
onCancellationRequested: Event<any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace CancellationToken {
|
|
||||||
|
|
||||||
export const None: CancellationToken = Object.freeze({
|
|
||||||
isCancellationRequested: false,
|
|
||||||
onCancellationRequested: Event.None
|
|
||||||
});
|
|
||||||
|
|
||||||
export const Cancelled: CancellationToken = Object.freeze({
|
|
||||||
isCancellationRequested: true,
|
|
||||||
onCancellationRequested: Event.None
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const shortcutEvent: Event<any> = Object.freeze(function (callback, context?) {
|
|
||||||
let handle = setTimeout(callback.bind(context), 0);
|
|
||||||
return { dispose() { clearTimeout(handle); } };
|
|
||||||
});
|
|
||||||
|
|
||||||
class MutableToken implements CancellationToken {
|
|
||||||
|
|
||||||
private _isCancelled: boolean = false;
|
|
||||||
private _emitter: Emitter<any>;
|
|
||||||
|
|
||||||
public cancel() {
|
|
||||||
if (!this._isCancelled) {
|
|
||||||
this._isCancelled = true;
|
|
||||||
if (this._emitter) {
|
|
||||||
this._emitter.fire(undefined);
|
|
||||||
this._emitter = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get isCancellationRequested(): boolean {
|
|
||||||
return this._isCancelled;
|
|
||||||
}
|
|
||||||
|
|
||||||
get onCancellationRequested(): Event<any> {
|
|
||||||
if (this._isCancelled) {
|
|
||||||
return shortcutEvent;
|
|
||||||
}
|
|
||||||
if (!this._emitter) {
|
|
||||||
this._emitter = new Emitter<any>();
|
|
||||||
}
|
|
||||||
return this._emitter.event;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CancellationTokenSource {
|
|
||||||
|
|
||||||
private _token: CancellationToken;
|
|
||||||
|
|
||||||
get token(): CancellationToken {
|
|
||||||
if (!this._token) {
|
|
||||||
// be lazy and create the token only when
|
|
||||||
// actually needed
|
|
||||||
this._token = new MutableToken();
|
|
||||||
}
|
|
||||||
return this._token;
|
|
||||||
}
|
|
||||||
|
|
||||||
cancel(): void {
|
|
||||||
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 {
|
|
||||||
(<MutableToken>this._token).cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dispose(): void {
|
|
||||||
this.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,213 +0,0 @@
|
|||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
* ------------------------------------------------------------------------------------------ */
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
export interface Disposable {
|
|
||||||
/**
|
|
||||||
* Dispose this object.
|
|
||||||
*/
|
|
||||||
dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a typed event.
|
|
||||||
*/
|
|
||||||
export interface Event<T> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param listener The listener function will be call when the event happens.
|
|
||||||
* @param thisArgs The 'this' which will be used when calling the event listener.
|
|
||||||
* @param disposables An array to which a {{IDisposable}} will be added. The
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
(listener: (e: T) => any, thisArgs?: any, disposables?: Disposable[]): Disposable;
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace Event {
|
|
||||||
const _disposable = { dispose() { } };
|
|
||||||
export const None: Event<any> = function () { return _disposable; };
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a type which can release resources, such
|
|
||||||
* as event listening or a timer.
|
|
||||||
*/
|
|
||||||
class DisposableImpl implements Disposable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combine many disposable-likes into one. Use this method
|
|
||||||
* when having objects with a dispose function which are not
|
|
||||||
* instances of Disposable.
|
|
||||||
*
|
|
||||||
* @return Returns a new disposable which, upon dispose, will
|
|
||||||
* dispose all provides disposable-likes.
|
|
||||||
*/
|
|
||||||
static from(...disposables: { dispose(): any }[]): DisposableImpl {
|
|
||||||
return new DisposableImpl(function () {
|
|
||||||
if (disposables) {
|
|
||||||
for (let disposable of disposables) {
|
|
||||||
disposable.dispose();
|
|
||||||
}
|
|
||||||
disposables = undefined;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private _callOnDispose: Function;
|
|
||||||
|
|
||||||
constructor(callOnDispose: Function) {
|
|
||||||
this._callOnDispose = callOnDispose;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispose this object.
|
|
||||||
*/
|
|
||||||
dispose(): any {
|
|
||||||
if (typeof this._callOnDispose === 'function') {
|
|
||||||
this._callOnDispose();
|
|
||||||
this._callOnDispose = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CallbackList {
|
|
||||||
|
|
||||||
private _callbacks: Function[];
|
|
||||||
private _contexts: any[];
|
|
||||||
|
|
||||||
public add(callback: Function, context: any = null, bucket?: Disposable[]): void {
|
|
||||||
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) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public remove(callback: Function, context: any = null): void {
|
|
||||||
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');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public invoke(...args: any[]): any[] {
|
|
||||||
if (!this._callbacks) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var ret: any[] = [],
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
public isEmpty(): boolean {
|
|
||||||
return !this._callbacks || this._callbacks.length === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public dispose(): void {
|
|
||||||
this._callbacks = undefined;
|
|
||||||
this._contexts = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EmitterOptions {
|
|
||||||
onFirstListenerAdd?: Function;
|
|
||||||
onLastListenerRemove?: Function;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Emitter<T> {
|
|
||||||
|
|
||||||
private static _noop = function () { };
|
|
||||||
|
|
||||||
private _event: Event<T>;
|
|
||||||
private _callbacks: CallbackList;
|
|
||||||
|
|
||||||
constructor(private _options?: EmitterOptions) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For the public to allow to subscribe
|
|
||||||
* to events from this Emitter
|
|
||||||
*/
|
|
||||||
get event(): Event<T> {
|
|
||||||
if (!this._event) {
|
|
||||||
this._event = (listener: (e: T) => any, thisArgs?: any, disposables?: Disposable[]) => {
|
|
||||||
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: Disposable;
|
|
||||||
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: T): any {
|
|
||||||
if (this._callbacks) {
|
|
||||||
this._callbacks.invoke.call(this._callbacks, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dispose() {
|
|
||||||
if (this._callbacks) {
|
|
||||||
this._callbacks.dispose();
|
|
||||||
this._callbacks = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
* ------------------------------------------------------------------------------------------ */
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const toString = Object.prototype.toString;
|
|
||||||
|
|
||||||
export function defined(value: any): boolean {
|
|
||||||
return typeof value !== 'undefined';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function undefined(value: any): boolean {
|
|
||||||
return typeof value === 'undefined';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function nil(value: any): boolean {
|
|
||||||
return value === null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function boolean(value: any): value is boolean {
|
|
||||||
return value === true || value === false;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function string(value: any): value is string {
|
|
||||||
return toString.call(value) === '[object String]';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function number(value: any): value is number {
|
|
||||||
return toString.call(value) === '[object Number]';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function error(value: any): value is Error {
|
|
||||||
return toString.call(value) === '[object Error]';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function func(value: any): value is Function {
|
|
||||||
return toString.call(value) === '[object Function]';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function array<T>(value: any): value is T[] {
|
|
||||||
return Array.isArray(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function stringArray(value: any): value is string[] {
|
|
||||||
return array(value) && (<any[]>value).every(elem => string(elem));
|
|
||||||
}
|
|
||||||
@@ -1,576 +0,0 @@
|
|||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
* ------------------------------------------------------------------------------------------ */
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import * as is from './is';
|
|
||||||
|
|
||||||
import {
|
|
||||||
Message,
|
|
||||||
RequestMessage, RequestType, isRequestMessage,
|
|
||||||
ResponseMessage, isReponseMessage, ResponseError, ErrorCodes,
|
|
||||||
NotificationMessage, NotificationType, isNotificationMessage
|
|
||||||
} from './messages';
|
|
||||||
|
|
||||||
import { MessageReader, DataCallback, StreamMessageReader, IPCMessageReader } from './messageReader';
|
|
||||||
import { MessageWriter, StreamMessageWriter, IPCMessageWriter } from './messageWriter';
|
|
||||||
import { Disposable, Event, Emitter } from './events';
|
|
||||||
import { CancellationTokenSource, CancellationToken } from './cancellation';
|
|
||||||
|
|
||||||
export {
|
|
||||||
Message, ErrorCodes, ResponseError,
|
|
||||||
RequestMessage, RequestType,
|
|
||||||
NotificationMessage, NotificationType,
|
|
||||||
MessageReader, DataCallback, StreamMessageReader, IPCMessageReader,
|
|
||||||
MessageWriter, StreamMessageWriter, IPCMessageWriter,
|
|
||||||
CancellationTokenSource, CancellationToken,
|
|
||||||
Disposable, Event, Emitter
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CancelParams {
|
|
||||||
/**
|
|
||||||
* The request id to cancel.
|
|
||||||
*/
|
|
||||||
id: number | string;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace CancelNotification {
|
|
||||||
export const type: NotificationType<CancelParams> = { get method() { return '$/cancelRequest'; } };
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RequestHandler<P, R, E> {
|
|
||||||
(params: P, token: CancellationToken): R | ResponseError<E> | Thenable<R | ResponseError<E>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface NotificationHandler<P> {
|
|
||||||
(params: P): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Logger {
|
|
||||||
error(message: string): void;
|
|
||||||
warn(message: string): void;
|
|
||||||
info(message: string): void;
|
|
||||||
log(message: string): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum Trace {
|
|
||||||
Off, Messages, Verbose
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TraceValues = 'off' | 'messages' | 'verbose';
|
|
||||||
export namespace Trace {
|
|
||||||
export function fromString(value: string): Trace {
|
|
||||||
value = value.toLowerCase();
|
|
||||||
switch (value) {
|
|
||||||
case 'off':
|
|
||||||
return Trace.Off;
|
|
||||||
case 'messages':
|
|
||||||
return Trace.Messages;
|
|
||||||
case 'verbose':
|
|
||||||
return Trace.Verbose;
|
|
||||||
default:
|
|
||||||
return Trace.Off;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toString(value: Trace): TraceValues {
|
|
||||||
switch (value) {
|
|
||||||
case Trace.Off:
|
|
||||||
return 'off';
|
|
||||||
case Trace.Messages:
|
|
||||||
return 'messages';
|
|
||||||
case Trace.Verbose:
|
|
||||||
return 'verbose';
|
|
||||||
default:
|
|
||||||
return 'off';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SetTraceParams {
|
|
||||||
value: TraceValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace SetTraceNotification {
|
|
||||||
export const type: NotificationType<SetTraceParams> = { get method() { return '$/setTraceNotification'; } };
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface LogTraceParams {
|
|
||||||
message: string;
|
|
||||||
verbose?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace LogTraceNotification {
|
|
||||||
export const type: NotificationType<LogTraceParams> = { get method() { return '$/logTraceNotification'; } };
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Tracer {
|
|
||||||
log(message: string, data?: string): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MessageConnection {
|
|
||||||
sendRequest<P, R, E>(type: RequestType<P, R, E>, params: P, token?: CancellationToken): Thenable<R>;
|
|
||||||
onRequest<P, R, E>(type: RequestType<P, R, E>, handler: RequestHandler<P, R, E>): void;
|
|
||||||
sendNotification<P>(type: NotificationType<P>, params?: P): void;
|
|
||||||
onNotification<P>(type: NotificationType<P>, handler: NotificationHandler<P>): void;
|
|
||||||
trace(value: Trace, tracer: Tracer, sendNotification?: boolean): void;
|
|
||||||
onError: Event<[Error, Message, number]>;
|
|
||||||
onClose: Event<void>;
|
|
||||||
onUnhandledNotification: Event<NotificationMessage>;
|
|
||||||
listen();
|
|
||||||
onDispose: Event<void>;
|
|
||||||
dispose(): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ServerMessageConnection extends MessageConnection {
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ClientMessageConnection extends MessageConnection {
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ResponsePromise {
|
|
||||||
method: string;
|
|
||||||
timerStart: number;
|
|
||||||
resolve: (response) => void;
|
|
||||||
reject: (error: any) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ConnectionState {
|
|
||||||
New = 1,
|
|
||||||
Listening = 2,
|
|
||||||
Closed = 3,
|
|
||||||
Disposed = 4
|
|
||||||
}
|
|
||||||
|
|
||||||
function createMessageConnection<T extends MessageConnection>(messageReader: MessageReader, messageWriter: MessageWriter, logger: Logger, client: boolean = false): T {
|
|
||||||
let sequenceNumber = 0;
|
|
||||||
const version: string = '2.0';
|
|
||||||
|
|
||||||
let requestHandlers: { [name: string]: RequestHandler<any, any, any> } = Object.create(null);
|
|
||||||
let eventHandlers: { [name: string]: NotificationHandler<any> } = Object.create(null);
|
|
||||||
|
|
||||||
let responsePromises: { [name: string]: ResponsePromise } = Object.create(null);
|
|
||||||
let requestTokens: { [id: string]: CancellationTokenSource } = Object.create(null);
|
|
||||||
|
|
||||||
let trace: Trace = Trace.Off;
|
|
||||||
let tracer: Tracer;
|
|
||||||
|
|
||||||
let state: ConnectionState = ConnectionState.New;
|
|
||||||
let errorEmitter: Emitter<[Error, Message, number]> = new Emitter<[Error, Message, number]>();
|
|
||||||
let closeEmitter: Emitter<void> = new Emitter<void>();
|
|
||||||
let unhandledNotificationEmitter: Emitter<NotificationMessage> = new Emitter<NotificationMessage>();
|
|
||||||
let disposeEmitter: Emitter<void> = new Emitter<void>();
|
|
||||||
|
|
||||||
function isListening(): boolean {
|
|
||||||
return state === ConnectionState.Listening;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isClosed(): boolean {
|
|
||||||
return state === ConnectionState.Closed;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isDisposed(): boolean {
|
|
||||||
return state === ConnectionState.Disposed;
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeHandler(): void {
|
|
||||||
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: Error): void {
|
|
||||||
errorEmitter.fire([error, undefined, undefined]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeErrorHandler(data: [Error, Message, number]): void {
|
|
||||||
errorEmitter.fire(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
messageReader.onClose(closeHandler);
|
|
||||||
messageReader.onError(readErrorHandler);
|
|
||||||
|
|
||||||
messageWriter.onClose(closeHandler);
|
|
||||||
messageWriter.onError(writeErrorHandler);
|
|
||||||
|
|
||||||
function handleRequest(requestMessage: RequestMessage) {
|
|
||||||
if (isDisposed()) {
|
|
||||||
// we return here silently since we fired an event when the
|
|
||||||
// connection got disposed.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
function reply(resultOrError: any | ResponseError<any>): void {
|
|
||||||
let message: ResponseMessage = {
|
|
||||||
jsonrpc: version,
|
|
||||||
id: requestMessage.id
|
|
||||||
};
|
|
||||||
if (resultOrError instanceof ResponseError) {
|
|
||||||
message.error = (<ResponseError<any>>resultOrError).toJson();
|
|
||||||
} else {
|
|
||||||
message.result = is.undefined(resultOrError) ? null : resultOrError;
|
|
||||||
}
|
|
||||||
messageWriter.write(message);
|
|
||||||
}
|
|
||||||
function replyError(error: ResponseError<any>) {
|
|
||||||
let message: ResponseMessage = {
|
|
||||||
jsonrpc: version,
|
|
||||||
id: requestMessage.id,
|
|
||||||
error: error.toJson()
|
|
||||||
};
|
|
||||||
messageWriter.write(message);
|
|
||||||
}
|
|
||||||
function replySuccess(result: any) {
|
|
||||||
// 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 (is.undefined(result)) {
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
let message: ResponseMessage = {
|
|
||||||
jsonrpc: version,
|
|
||||||
id: requestMessage.id,
|
|
||||||
result: result
|
|
||||||
};
|
|
||||||
messageWriter.write(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
let requestHandler = requestHandlers[requestMessage.method];
|
|
||||||
if (requestHandler) {
|
|
||||||
let cancellationSource = new CancellationTokenSource();
|
|
||||||
let tokenKey = String(requestMessage.id);
|
|
||||||
requestTokens[tokenKey] = cancellationSource;
|
|
||||||
try {
|
|
||||||
let handlerResult = requestHandler(requestMessage.params, cancellationSource.token);
|
|
||||||
let promise = <Thenable<any | ResponseError<any>>>handlerResult;
|
|
||||||
if (!handlerResult) {
|
|
||||||
delete requestTokens[tokenKey];
|
|
||||||
replySuccess(handlerResult);
|
|
||||||
} else if (promise.then) {
|
|
||||||
promise.then((resultOrError): any | ResponseError<any> => {
|
|
||||||
delete requestTokens[tokenKey];
|
|
||||||
reply(resultOrError);
|
|
||||||
}, error => {
|
|
||||||
delete requestTokens[tokenKey];
|
|
||||||
if (error instanceof ResponseError) {
|
|
||||||
replyError(<ResponseError<any>>error);
|
|
||||||
} else if (error && is.string(error.message)) {
|
|
||||||
replyError(new ResponseError<void>(ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error.message}`));
|
|
||||||
} else {
|
|
||||||
replyError(new ResponseError<void>(ErrorCodes.InternalError, `Request ${requestMessage.method} failed unexpectedly without providing any details.`));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
delete requestTokens[tokenKey];
|
|
||||||
reply(handlerResult);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
delete requestTokens[tokenKey];
|
|
||||||
if (error instanceof ResponseError) {
|
|
||||||
reply(<ResponseError<any>>error);
|
|
||||||
} else if (error && is.string(error.message)) {
|
|
||||||
replyError(new ResponseError<void>(ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error.message}`));
|
|
||||||
} else {
|
|
||||||
replyError(new ResponseError<void>(ErrorCodes.InternalError, `Request ${requestMessage.method} failed unexpectedly without providing any details.`));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
replyError(new ResponseError<void>(ErrorCodes.MethodNotFound, `Unhandled method ${requestMessage.method}`));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleResponse(responseMessage: ResponseMessage) {
|
|
||||||
if (isDisposed()) {
|
|
||||||
// See handle request.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let key = String(responseMessage.id);
|
|
||||||
let responsePromise = responsePromises[key];
|
|
||||||
if (trace != Trace.Off && tracer) {
|
|
||||||
traceResponse(responseMessage, responsePromise);
|
|
||||||
}
|
|
||||||
if (responsePromise) {
|
|
||||||
delete responsePromises[key];
|
|
||||||
try {
|
|
||||||
if (is.defined(responseMessage.error)) {
|
|
||||||
let error = responseMessage.error;
|
|
||||||
responsePromise.reject(new ResponseError(error.code, error.message, error.data));
|
|
||||||
} else if (is.defined(responseMessage.result)) {
|
|
||||||
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: NotificationMessage) {
|
|
||||||
if (isDisposed()) {
|
|
||||||
// See handle request.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let eventHandler: NotificationHandler<any>;
|
|
||||||
if (message.method === CancelNotification.type.method) {
|
|
||||||
eventHandler = (params: CancelParams) => {
|
|
||||||
let id = params.id;
|
|
||||||
let source = requestTokens[String(id)];
|
|
||||||
if (source) {
|
|
||||||
source.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
eventHandler = eventHandlers[message.method];
|
|
||||||
}
|
|
||||||
if (eventHandler) {
|
|
||||||
try {
|
|
||||||
if (trace != Trace.Off && tracer) {
|
|
||||||
traceReceivedNotification(message);
|
|
||||||
}
|
|
||||||
eventHandler(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: 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: ResponseMessage = message as ResponseMessage;
|
|
||||||
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 traceRequest(message: RequestMessage): void {
|
|
||||||
let data: string = 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
function traceSendNotification(message: NotificationMessage): void {
|
|
||||||
let data: string = 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
function traceReceivedNotification(message: NotificationMessage): void {
|
|
||||||
if (message.method === LogTraceNotification.type.method) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let data: string = 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
function traceResponse(message: ResponseMessage, responsePromise: ResponsePromise): void {
|
|
||||||
let data: string = 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 (is.undefined(message.error)) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let callback: DataCallback = (message) => {
|
|
||||||
if (isRequestMessage(message)) {
|
|
||||||
handleRequest(message);
|
|
||||||
} else if (isReponseMessage(message)) {
|
|
||||||
handleResponse(message)
|
|
||||||
} else if (isNotificationMessage(message)) {
|
|
||||||
handleNotification(message);
|
|
||||||
} else {
|
|
||||||
handleInvalidMessage(message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function throwIfClosedOrDisposed() {
|
|
||||||
if (isClosed()) {
|
|
||||||
throw new Error('Connection is closed.');
|
|
||||||
}
|
|
||||||
if (isDisposed()) {
|
|
||||||
throw new Error('Connection is disposed.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function throwIfListening() {
|
|
||||||
if (isListening()) {
|
|
||||||
throw new Error('Connection is already listening');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let connection: MessageConnection = {
|
|
||||||
sendNotification: <P>(type: NotificationType<P>, params): void => {
|
|
||||||
throwIfClosedOrDisposed();
|
|
||||||
|
|
||||||
let notificatioMessage: NotificationMessage = {
|
|
||||||
jsonrpc: version,
|
|
||||||
method: type.method,
|
|
||||||
params: params
|
|
||||||
}
|
|
||||||
if (trace != Trace.Off && tracer) {
|
|
||||||
traceSendNotification(notificatioMessage);
|
|
||||||
}
|
|
||||||
messageWriter.write(notificatioMessage);
|
|
||||||
},
|
|
||||||
onNotification: <P>(type: NotificationType<P>, handler: NotificationHandler<P>) => {
|
|
||||||
throwIfClosedOrDisposed();
|
|
||||||
|
|
||||||
eventHandlers[type.method] = handler;
|
|
||||||
},
|
|
||||||
sendRequest: <P, R, E>(type: RequestType<P, R, E>, params: P, token?: CancellationToken) => {
|
|
||||||
throwIfClosedOrDisposed();
|
|
||||||
|
|
||||||
let id = sequenceNumber++;
|
|
||||||
let result = new Promise<R | ResponseError<E>>((resolve, reject) => {
|
|
||||||
let requestMessage: RequestMessage = {
|
|
||||||
jsonrpc: version,
|
|
||||||
id: id,
|
|
||||||
method: type.method,
|
|
||||||
params: params
|
|
||||||
}
|
|
||||||
let responsePromise: ResponsePromise = { method: type.method, timerStart: Date.now(), resolve, reject };
|
|
||||||
if (trace != Trace.Off && tracer) {
|
|
||||||
traceRequest(requestMessage);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
messageWriter.write(requestMessage);
|
|
||||||
} catch (e) {
|
|
||||||
// Writing the message failed. So we need to reject the promise.
|
|
||||||
responsePromise.reject(new ResponseError<void>(ErrorCodes.MessageWriteError, e.message ? e.message : 'Unknown reason'));
|
|
||||||
responsePromise = null;
|
|
||||||
}
|
|
||||||
if (responsePromise) {
|
|
||||||
responsePromises[String(id)] = responsePromise;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (token) {
|
|
||||||
token.onCancellationRequested((event) => {
|
|
||||||
connection.sendNotification(CancelNotification.type, { id });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
onRequest: <P, R, E>(type: RequestType<P, R, E>, handler: RequestHandler<P, R, E>) => {
|
|
||||||
throwIfClosedOrDisposed();
|
|
||||||
|
|
||||||
requestHandlers[type.method] = handler;
|
|
||||||
},
|
|
||||||
trace: (_value: Trace, _tracer: Tracer, sendNotification: boolean = false) => {
|
|
||||||
trace = _value;
|
|
||||||
if (trace === Trace.Off) {
|
|
||||||
tracer = null;
|
|
||||||
} 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);
|
|
||||||
},
|
|
||||||
listen: () => {
|
|
||||||
throwIfClosedOrDisposed();
|
|
||||||
throwIfListening();
|
|
||||||
|
|
||||||
state = ConnectionState.Listening;
|
|
||||||
messageReader.listen(callback);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
connection.onNotification(LogTraceNotification.type, (params) => {
|
|
||||||
if (trace === Trace.Off) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
tracer.log(params.message, trace === Trace.Verbose ? params.verbose : undefined);
|
|
||||||
});
|
|
||||||
return connection as T;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isMessageReader(value: any): value is MessageReader {
|
|
||||||
return is.defined(value.listen) && is.undefined(value.read);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isMessageWriter(value: any): value is MessageWriter {
|
|
||||||
return is.defined(value.write) && is.undefined(value.end);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createServerMessageConnection(reader: MessageReader, writer: MessageWriter, logger: Logger): ServerMessageConnection;
|
|
||||||
export function createServerMessageConnection(inputStream: NodeJS.ReadableStream, outputStream: NodeJS.WritableStream, logger: Logger): ServerMessageConnection;
|
|
||||||
export function createServerMessageConnection(input: MessageReader | NodeJS.ReadableStream, output: MessageWriter | NodeJS.WritableStream, logger: Logger): ServerMessageConnection {
|
|
||||||
let reader = isMessageReader(input) ? input : new StreamMessageReader(input);
|
|
||||||
let writer = isMessageWriter(output) ? output : new StreamMessageWriter(output);
|
|
||||||
return createMessageConnection<ServerMessageConnection>(reader, writer, logger);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createClientMessageConnection(reader: MessageReader, writer: MessageWriter, logger: Logger): ClientMessageConnection;
|
|
||||||
export function createClientMessageConnection(inputStream: NodeJS.ReadableStream, outputStream: NodeJS.WritableStream, logger: Logger): ClientMessageConnection;
|
|
||||||
export function createClientMessageConnection(input: MessageReader | NodeJS.ReadableStream, output: MessageWriter | NodeJS.WritableStream, logger: Logger): ClientMessageConnection {
|
|
||||||
let reader = isMessageReader(input) ? input : new StreamMessageReader(input);
|
|
||||||
let writer = isMessageWriter(output) ? output : new StreamMessageWriter(output);
|
|
||||||
return createMessageConnection<ClientMessageConnection>(reader, writer, logger, true);
|
|
||||||
}
|
|
||||||
@@ -1,265 +0,0 @@
|
|||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
* ------------------------------------------------------------------------------------------ */
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import { ChildProcess } from 'child_process';
|
|
||||||
|
|
||||||
import { Message } from './messages';
|
|
||||||
import { Event, Emitter } from './events';
|
|
||||||
import * as is from './is';
|
|
||||||
|
|
||||||
let DefaultSize: number = 8192;
|
|
||||||
let CR: number = new Buffer('\r', 'ascii')[0];
|
|
||||||
let LF: number = new Buffer('\n', 'ascii')[0];
|
|
||||||
let CRLF: string = '\r\n';
|
|
||||||
|
|
||||||
class MessageBuffer {
|
|
||||||
|
|
||||||
private encoding: string;
|
|
||||||
private index: number;
|
|
||||||
private buffer: Buffer;
|
|
||||||
|
|
||||||
constructor(encoding: string = 'utf-8') {
|
|
||||||
this.encoding = encoding;
|
|
||||||
this.index = 0;
|
|
||||||
this.buffer = new Buffer(DefaultSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public append(chunk: Buffer | String): void {
|
|
||||||
var toAppend: Buffer = <Buffer>chunk;
|
|
||||||
if (typeof (chunk) == 'string') {
|
|
||||||
var str = <string>chunk;
|
|
||||||
toAppend = new Buffer(str.length);
|
|
||||||
toAppend.write(str, 0, str.length, 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 = new Buffer(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
public tryReadHeaders(): { [key: string]: string; } {
|
|
||||||
let result: { [key: string]: string; } = 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: number = 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
public tryReadContent(length: number): string {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get numberOfBytes(): number {
|
|
||||||
return this.index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DataCallback {
|
|
||||||
(data: Message): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PartialMessageInfo {
|
|
||||||
messageToken: number;
|
|
||||||
waitingTime: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MessageReader {
|
|
||||||
onError: Event<Error>;
|
|
||||||
onClose: Event<void>;
|
|
||||||
onPartialMessage: Event<PartialMessageInfo>;
|
|
||||||
listen(callback: DataCallback): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export abstract class AbstractMessageReader {
|
|
||||||
|
|
||||||
private errorEmitter: Emitter<Error>;
|
|
||||||
private closeEmitter: Emitter<void>;
|
|
||||||
|
|
||||||
private partialMessageEmitter: Emitter<PartialMessageInfo>;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.errorEmitter = new Emitter<Error>();
|
|
||||||
this.closeEmitter = new Emitter<void>();
|
|
||||||
this.partialMessageEmitter = new Emitter<PartialMessageInfo>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public get onError(): Event<Error> {
|
|
||||||
return this.errorEmitter.event;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fireError(error: any): void {
|
|
||||||
this.errorEmitter.fire(this.asError(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
public get onClose(): Event<void> {
|
|
||||||
return this.closeEmitter.event;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fireClose(): void {
|
|
||||||
this.closeEmitter.fire(undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
public get onPartialMessage(): Event<PartialMessageInfo> {
|
|
||||||
return this.partialMessageEmitter.event;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected firePartialMessage(info: PartialMessageInfo): void {
|
|
||||||
this.partialMessageEmitter.fire(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
private asError(error: any): Error {
|
|
||||||
if (error instanceof Error) {
|
|
||||||
return error;
|
|
||||||
} else {
|
|
||||||
return new Error(`Reader recevied error. Reason: ${is.string(error.message) ? error.message : 'unknown'}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class StreamMessageReader extends AbstractMessageReader implements MessageReader {
|
|
||||||
|
|
||||||
private readable: NodeJS.ReadableStream;
|
|
||||||
private callback: DataCallback;
|
|
||||||
private buffer: MessageBuffer;
|
|
||||||
private nextMessageLength: number;
|
|
||||||
private messageToken: number;
|
|
||||||
private partialMessageTimer: NodeJS.Timer;
|
|
||||||
private _partialMessageTimeout: number;
|
|
||||||
|
|
||||||
public constructor(readable: NodeJS.ReadableStream, encoding: string = 'utf-8') {
|
|
||||||
super();
|
|
||||||
this.readable = readable;
|
|
||||||
this.buffer = new MessageBuffer(encoding);
|
|
||||||
this._partialMessageTimeout = 10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
public set partialMessageTimeout(timeout: number) {
|
|
||||||
this._partialMessageTimeout = timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get partialMessageTimeout(): number {
|
|
||||||
return this._partialMessageTimeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
public listen(callback: DataCallback): void {
|
|
||||||
this.nextMessageLength = -1;
|
|
||||||
this.messageToken = 0;
|
|
||||||
this.partialMessageTimer = undefined;
|
|
||||||
this.callback = callback;
|
|
||||||
this.readable.on('data', (data: Buffer) => {
|
|
||||||
this.onData(data);
|
|
||||||
});
|
|
||||||
this.readable.on('error', (error: any) => this.fireError(error));
|
|
||||||
this.readable.on('close', () => this.fireClose());
|
|
||||||
}
|
|
||||||
|
|
||||||
private onData(data: Buffer | String): void {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private clearPartialMessageTimer(): void {
|
|
||||||
if (this.partialMessageTimer) {
|
|
||||||
clearTimeout(this.partialMessageTimer);
|
|
||||||
this.partialMessageTimer = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private setPartialMessageTimer(): void {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class IPCMessageReader extends AbstractMessageReader implements MessageReader {
|
|
||||||
|
|
||||||
private process: NodeJS.Process | ChildProcess;
|
|
||||||
|
|
||||||
public constructor(process: NodeJS.Process | ChildProcess) {
|
|
||||||
super();
|
|
||||||
this.process = process;
|
|
||||||
|
|
||||||
let eventEmitter: NodeJS.EventEmitter = <NodeJS.EventEmitter>this.process;
|
|
||||||
eventEmitter.on('error', (error: any) => this.fireError(error));
|
|
||||||
eventEmitter.on('close', () => this.fireClose());
|
|
||||||
}
|
|
||||||
|
|
||||||
public listen(callback: DataCallback): void {
|
|
||||||
let eventEmitter: NodeJS.EventEmitter = <NodeJS.EventEmitter>this.process;
|
|
||||||
eventEmitter.on('message', callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
* ------------------------------------------------------------------------------------------ */
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import { ChildProcess } from 'child_process';
|
|
||||||
|
|
||||||
import { Message } from './messages';
|
|
||||||
import { Event, Emitter } from './events';
|
|
||||||
import * as is from './is';
|
|
||||||
|
|
||||||
let ContentLength: string = 'Content-Length: ';
|
|
||||||
let CRLF = '\r\n';
|
|
||||||
|
|
||||||
export interface MessageWriter {
|
|
||||||
onError: Event<[Error, Message, number]>;
|
|
||||||
onClose: Event<void>;
|
|
||||||
write(msg: Message): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export abstract class AbstractMessageWriter {
|
|
||||||
|
|
||||||
private errorEmitter: Emitter<[Error, Message, number]>;
|
|
||||||
private closeEmitter: Emitter<void>;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.errorEmitter = new Emitter<[Error, Message, number]>();
|
|
||||||
this.closeEmitter = new Emitter<void>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public get onError(): Event<[Error, Message, number]> {
|
|
||||||
return this.errorEmitter.event;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fireError(error: any, message?: Message, count?: number): void {
|
|
||||||
this.errorEmitter.fire([this.asError(error), message, count]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public get onClose(): Event<void> {
|
|
||||||
return this.closeEmitter.event;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fireClose(): void {
|
|
||||||
this.closeEmitter.fire(undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
private asError(error: any): Error {
|
|
||||||
if (error instanceof Error) {
|
|
||||||
return error;
|
|
||||||
} else {
|
|
||||||
return new Error(`Writer recevied error. Reason: ${is.string(error.message) ? error.message : 'unknown'}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class StreamMessageWriter extends AbstractMessageWriter implements MessageWriter {
|
|
||||||
|
|
||||||
private writable: NodeJS.WritableStream;
|
|
||||||
private encoding: string;
|
|
||||||
private errorCount: number;
|
|
||||||
|
|
||||||
public constructor(writable: NodeJS.WritableStream, encoding: string = '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());
|
|
||||||
}
|
|
||||||
|
|
||||||
public write(msg: Message): void {
|
|
||||||
let json = JSON.stringify(msg);
|
|
||||||
let contentLength = Buffer.byteLength(json, this.encoding);
|
|
||||||
|
|
||||||
let headers: string[] = [
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class IPCMessageWriter extends AbstractMessageWriter implements MessageWriter {
|
|
||||||
|
|
||||||
private process: NodeJS.Process | ChildProcess;
|
|
||||||
private errorCount: number;
|
|
||||||
|
|
||||||
public constructor(process: NodeJS.Process | ChildProcess) {
|
|
||||||
super();
|
|
||||||
this.process = process;
|
|
||||||
this.errorCount = 0;
|
|
||||||
|
|
||||||
let eventEmitter: NodeJS.EventEmitter = <NodeJS.EventEmitter>this.process;
|
|
||||||
eventEmitter.on('error', (error) => this.fireError(error));
|
|
||||||
eventEmitter.on('close', () => this.fireClose);
|
|
||||||
}
|
|
||||||
|
|
||||||
public write(msg: Message): void {
|
|
||||||
try {
|
|
||||||
(this.process.send as Function)(msg);
|
|
||||||
this.errorCount = 0;
|
|
||||||
} catch (error) {
|
|
||||||
this.errorCount++;
|
|
||||||
this.fireError(error, msg, this.errorCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
/* --------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
* ------------------------------------------------------------------------------------------ */
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import * as is from './is';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A language server message
|
|
||||||
*/
|
|
||||||
export interface Message {
|
|
||||||
jsonrpc: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request message
|
|
||||||
*/
|
|
||||||
export interface RequestMessage extends Message {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The request id.
|
|
||||||
*/
|
|
||||||
id: number | string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The method to be invoked.
|
|
||||||
*/
|
|
||||||
method: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The method's params.
|
|
||||||
*/
|
|
||||||
params?: any
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Predefined error codes.
|
|
||||||
*/
|
|
||||||
export namespace ErrorCodes {
|
|
||||||
// Defined by JSON RPC
|
|
||||||
export const ParseError: number = -32700;
|
|
||||||
export const InvalidRequest: number = -32600;
|
|
||||||
export const MethodNotFound: number = -32601;
|
|
||||||
export const InvalidParams: number = -32602;
|
|
||||||
export const InternalError: number = -32603;
|
|
||||||
export const serverErrorStart: number = -32099
|
|
||||||
export const serverErrorEnd: number = -32000;
|
|
||||||
|
|
||||||
// Defined by VSCode.
|
|
||||||
export const MessageWriteError: number = 1;
|
|
||||||
export const MessageReadError: number = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ResponseErrorLiteral<D> {
|
|
||||||
/**
|
|
||||||
* A number indicating the error type that occured.
|
|
||||||
*/
|
|
||||||
code: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A string providing a short decription of the error.
|
|
||||||
*/
|
|
||||||
message: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Primitive or Structured value that contains additional
|
|
||||||
* information about the error. Can be omitted.
|
|
||||||
*/
|
|
||||||
data?: D;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A error object return in a response in case a request
|
|
||||||
* has failed.
|
|
||||||
*/
|
|
||||||
export class ResponseError<D> extends Error {
|
|
||||||
|
|
||||||
public code: number;
|
|
||||||
|
|
||||||
public message: string;
|
|
||||||
|
|
||||||
public data: D;
|
|
||||||
|
|
||||||
constructor(code: number, message: string, data?: D) {
|
|
||||||
super(message);
|
|
||||||
this.code = code;
|
|
||||||
this.message = message;
|
|
||||||
if (is.defined(data)) {
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public toJson(): ResponseErrorLiteral<D> {
|
|
||||||
let result: ResponseErrorLiteral<D> = {
|
|
||||||
code: this.code,
|
|
||||||
message: this.message
|
|
||||||
};
|
|
||||||
if (is.defined(this.data)) {
|
|
||||||
result.data = this.data
|
|
||||||
};
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A response message.
|
|
||||||
*/
|
|
||||||
export interface ResponseMessage extends Message {
|
|
||||||
/**
|
|
||||||
* The request id.
|
|
||||||
*/
|
|
||||||
id: number | string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The result of a request. This can be omitted in
|
|
||||||
* the case of an error.
|
|
||||||
*/
|
|
||||||
result?: any;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The error object in case a request fails.
|
|
||||||
*/
|
|
||||||
error?: ResponseErrorLiteral<any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A interface to type the request parameter / response pair
|
|
||||||
*/
|
|
||||||
export interface RequestType<P, R, E> {
|
|
||||||
method: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notification Message
|
|
||||||
*/
|
|
||||||
export interface NotificationMessage extends Message {
|
|
||||||
/**
|
|
||||||
* The method to be invoked.
|
|
||||||
*/
|
|
||||||
method: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The notification's params.
|
|
||||||
*/
|
|
||||||
params?: any
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface NotificationType<P> {
|
|
||||||
method: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests if the given message is a request message
|
|
||||||
*/
|
|
||||||
export function isRequestMessage(message: Message): message is RequestMessage {
|
|
||||||
let candidate = <RequestMessage>message;
|
|
||||||
return candidate && is.string(candidate.method) && (is.string(candidate.id) || is.number(candidate.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests if the given message is a notification message
|
|
||||||
*/
|
|
||||||
export function isNotificationMessage(message: Message): message is NotificationMessage {
|
|
||||||
let candidate = <NotificationMessage>message;
|
|
||||||
return candidate && is.string(candidate.method) && is.undefined((<any>message).id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests if the given message is a response message
|
|
||||||
*/
|
|
||||||
export function isReponseMessage(message: Message): message is ResponseMessage {
|
|
||||||
let candidate = <ResponseMessage>message;
|
|
||||||
return candidate && (is.defined(candidate.result) || is.defined(candidate.error)) && (is.string(candidate.id) || is.number(candidate.id));
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "ES5",
|
|
||||||
"module": "commonjs",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"sourceMap": true,
|
|
||||||
"declaration": true,
|
|
||||||
"stripInternal": true,
|
|
||||||
"outDir": "../lib"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
112
dataprotocol-node/jsonrpc/src/typings/promise.d.ts
vendored
112
dataprotocol-node/jsonrpc/src/typings/promise.d.ts
vendored
@@ -1,112 +0,0 @@
|
|||||||
/*! *****************************************************************************
|
|
||||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
||||||
this file except in compliance with the License. You may obtain a copy of the
|
|
||||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
||||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
||||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
||||||
|
|
||||||
See the Apache Version 2.0 License for specific language governing permissions
|
|
||||||
and limitations under the License.
|
|
||||||
***************************************************************************** */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Thenable (E.g. PromiseLike) and Promise declarions are taken from TypeScript's
|
|
||||||
* lib.core.es6.d.ts file. See above Copyright notice.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise,
|
|
||||||
* and others. This API makes no assumption about what promise libary is being used which
|
|
||||||
* enables reusing existing code without migrating to a specific promise implementation. Still,
|
|
||||||
* we recommand the use of native promises which are available in VS Code.
|
|
||||||
*/
|
|
||||||
interface Thenable<R> {
|
|
||||||
/**
|
|
||||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
|
||||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
|
||||||
* @param onrejected The callback to execute when the Promise is rejected.
|
|
||||||
* @returns A Promise for the completion of which ever callback is executed.
|
|
||||||
*/
|
|
||||||
then<TResult>(onfulfilled?: (value: R) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Thenable<TResult>;
|
|
||||||
then<TResult>(onfulfilled?: (value: R) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Thenable<TResult>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents the completion of an asynchronous operation
|
|
||||||
*/
|
|
||||||
interface Promise<T> extends Thenable<T> {
|
|
||||||
/**
|
|
||||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
|
||||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
|
||||||
* @param onrejected The callback to execute when the Promise is rejected.
|
|
||||||
* @returns A Promise for the completion of which ever callback is executed.
|
|
||||||
*/
|
|
||||||
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Promise<TResult>;
|
|
||||||
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Promise<TResult>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attaches a callback for only the rejection of the Promise.
|
|
||||||
* @param onrejected The callback to execute when the Promise is rejected.
|
|
||||||
* @returns A Promise for the completion of the callback.
|
|
||||||
*/
|
|
||||||
catch(onrejected?: (reason: any) => T | Thenable<T>): Promise<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PromiseConstructor {
|
|
||||||
/**
|
|
||||||
* Creates a new Promise.
|
|
||||||
* @param executor A callback used to initialize the promise. This callback is passed two arguments:
|
|
||||||
* a resolve callback used resolve the promise with a value or the result of another promise,
|
|
||||||
* and a reject callback used to reject the promise with a provided reason or error.
|
|
||||||
*/
|
|
||||||
new <T>(executor: (resolve: (value?: T | Thenable<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises
|
|
||||||
* resolve, or rejected when any Promise is rejected.
|
|
||||||
* @param values An array of Promises.
|
|
||||||
* @returns A new Promise.
|
|
||||||
*/
|
|
||||||
all<T>(values: Array<T | Thenable<T>>): Promise<T[]>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
|
|
||||||
* or rejected.
|
|
||||||
* @param values An array of Promises.
|
|
||||||
* @returns A new Promise.
|
|
||||||
*/
|
|
||||||
race<T>(values: Array<T | Thenable<T>>): Promise<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new rejected promise for the provided reason.
|
|
||||||
* @param reason The reason the promise was rejected.
|
|
||||||
* @returns A new rejected Promise.
|
|
||||||
*/
|
|
||||||
reject(reason: any): Promise<void>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new rejected promise for the provided reason.
|
|
||||||
* @param reason The reason the promise was rejected.
|
|
||||||
* @returns A new rejected Promise.
|
|
||||||
*/
|
|
||||||
reject<T>(reason: any): Promise<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new resolved promise for the provided value.
|
|
||||||
* @param value A promise.
|
|
||||||
* @returns A promise whose internal state matches the provided promise.
|
|
||||||
*/
|
|
||||||
resolve<T>(value: T | Thenable<T>): Promise<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new resolved promise .
|
|
||||||
* @returns A resolved promise.
|
|
||||||
*/
|
|
||||||
resolve(): Promise<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare var Promise: PromiseConstructor;
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
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.
|
|
||||||
15
dataprotocol-node/package.json
Normal file
15
dataprotocol-node/package.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "dataprotocol-node",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "sqlops studio implementation of vscode-language-client",
|
||||||
|
"main": "lib/main.js",
|
||||||
|
"scripts": {},
|
||||||
|
"author": "Microsoft",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"vscode-languageclient": "^3.5.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^2.6.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
91
dataprotocol-node/src/main.ts
Normal file
91
dataprotocol-node/src/main.ts
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
import {
|
||||||
|
LanguageClient, ServerOptions, LanguageClientOptions, DynamicFeature, ServerCapabilities, RegistrationData,
|
||||||
|
RPCMessageType, Disposable
|
||||||
|
} from 'vscode-languageclient';
|
||||||
|
|
||||||
|
import { ClientCapabilities } from './protocol';
|
||||||
|
|
||||||
|
function ensure<T, K extends keyof T>(target: T, key: K): T[K] {
|
||||||
|
if (target[key] === void 0) {
|
||||||
|
target[key] = {} as any;
|
||||||
|
}
|
||||||
|
return target[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export abstract class SqlOpsFeature<T> implements DynamicFeature<T> {
|
||||||
|
|
||||||
|
protected _providers: Map<string, Disposable> = new Map<string, Disposable>();
|
||||||
|
|
||||||
|
constructor(protected _client: SqlOpsDataClient, private _message: RPCMessageType) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public get messages(): RPCMessageType {
|
||||||
|
return this._message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract fillClientCapabilities(capabilities: ClientCapabilities): void;
|
||||||
|
|
||||||
|
public abstract initialize(capabilities: ServerCapabilities): void;
|
||||||
|
|
||||||
|
register(message: RPCMessageType, data: RegistrationData<T>): void {
|
||||||
|
if (message.method !== this.messages.method) {
|
||||||
|
throw new Error(`Register called on wrong feature. Requested ${message.method} but reached feature ${this.messages.method}`);
|
||||||
|
}
|
||||||
|
let provider = this.registerProvider(data.registerOptions);
|
||||||
|
if (provider) {
|
||||||
|
this._providers.set(data.id, provider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract registerProvider(options: T): Disposable;
|
||||||
|
|
||||||
|
public unregister(id: string): void {
|
||||||
|
let provider = this._providers.get(id);
|
||||||
|
if (provider) {
|
||||||
|
provider.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public dispose(): void {
|
||||||
|
this._providers.forEach((value) => {
|
||||||
|
value.dispose();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConnectionFeature extends SqlOpsFeature<undefined> {
|
||||||
|
public fillClientCapabilities(capabilities: ClientCapabilities): void {
|
||||||
|
ensure(ensure(capabilities, 'connection')!, 'connection')!.dynamicRegistration = true;
|
||||||
|
}
|
||||||
|
public initialize(capabilities: ServerCapabilities): void {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
protected registerProvider(options: undefined): Disposable {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export class SqlOpsDataClient extends LanguageClient {
|
||||||
|
|
||||||
|
public constructor(name: string, serverOptions: ServerOptions, clientOptions: LanguageClientOptions, forceDebug?: boolean);
|
||||||
|
public constructor(id: string, name: string, serverOptions: ServerOptions, clientOptions: LanguageClientOptions, forceDebug?: boolean);
|
||||||
|
public constructor(arg1: string, arg2: ServerOptions | string, arg3: LanguageClientOptions | ServerOptions, arg4?: boolean | LanguageClientOptions, arg5?: boolean) {
|
||||||
|
if (typeof arg2 === 'string') {
|
||||||
|
super(arg1, arg2, arg3 as ServerOptions, arg4 as LanguageClientOptions, arg5);
|
||||||
|
} else {
|
||||||
|
super(arg1, arg2 as ServerOptions, arg3 as LanguageClientOptions, arg4 as boolean);
|
||||||
|
}
|
||||||
|
this.registerDataFeatures();
|
||||||
|
}
|
||||||
|
|
||||||
|
private registerDataFeatures() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
63
dataprotocol-node/src/protocol.ts
Normal file
63
dataprotocol-node/src/protocol.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import { ClientCapabilities as VSClientCapabilities } from 'vscode-languageclient';
|
||||||
|
|
||||||
|
export interface ConnectionClientCapabilities {
|
||||||
|
connection?: {
|
||||||
|
/**
|
||||||
|
* Whether the connection support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
},
|
||||||
|
backup?: {
|
||||||
|
/**
|
||||||
|
* Whether the backup support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
},
|
||||||
|
restore?: {
|
||||||
|
/**
|
||||||
|
* Whether the restore support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
},
|
||||||
|
query?: {
|
||||||
|
/**
|
||||||
|
* Whether the query support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
},
|
||||||
|
objectExplorer?: {
|
||||||
|
/**
|
||||||
|
* Whether the object explorer support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
},
|
||||||
|
scripting?: {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the scripting support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
},
|
||||||
|
taskServices?: {
|
||||||
|
/**
|
||||||
|
* Whether the task services support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
},
|
||||||
|
fileBrowser?: {
|
||||||
|
/**
|
||||||
|
* Whether the file browser support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
},
|
||||||
|
profiler?: {
|
||||||
|
/**
|
||||||
|
* Whether the profiler support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ClientCapabilities extends VSClientCapabilities {
|
||||||
|
connection?: ConnectionClientCapabilities;
|
||||||
|
}
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
"rules": {
|
|
||||||
"indent": [
|
|
||||||
2,
|
|
||||||
"tab"
|
|
||||||
],
|
|
||||||
"quotes": [
|
|
||||||
2,
|
|
||||||
"single"
|
|
||||||
],
|
|
||||||
"linebreak-style": [
|
|
||||||
2,
|
|
||||||
"windows"
|
|
||||||
],
|
|
||||||
"semi": [
|
|
||||||
2,
|
|
||||||
"always"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"env": {
|
|
||||||
"node": true
|
|
||||||
},
|
|
||||||
"extends": "eslint:recommended"
|
|
||||||
}
|
|
||||||
1
dataprotocol-node/types/.gitignore
vendored
1
dataprotocol-node/types/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
!bin/
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
.vscode/
|
|
||||||
lib/test/
|
|
||||||
lib/*.map
|
|
||||||
src/
|
|
||||||
test/
|
|
||||||
.eslintrc
|
|
||||||
.gitignore
|
|
||||||
gulpfile.js
|
|
||||||
tsd.json
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
// Place your settings in this file to overwrite default and user settings.
|
|
||||||
{
|
|
||||||
"javascript.validate.enable": false,
|
|
||||||
"files.trimTrailingWhitespace": true,
|
|
||||||
"eslint.enable": false,
|
|
||||||
"editor.insertSpaces": false,
|
|
||||||
"editor.tabSize": 4,
|
|
||||||
"typescript.tsdk": "./node_modules/typescript/lib"
|
|
||||||
}
|
|
||||||
9
dataprotocol-node/types/.vscode/tasks.json
vendored
9
dataprotocol-node/types/.vscode/tasks.json
vendored
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "0.1.0",
|
|
||||||
"command": "npm",
|
|
||||||
"isShellCommand": true,
|
|
||||||
"args": ["run", "watch"],
|
|
||||||
"showOutput": "silent",
|
|
||||||
"isWatching": true,
|
|
||||||
"problemMatcher": "$tsc-watch"
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# Microsoft Data Management Protocol - Node
|
|
||||||
|
|
||||||
## License
|
|
||||||
[MIT](https://github.com/Microsoft/carbon/blob/dev/license.txt)
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "dataprotocol-languageserver-types",
|
|
||||||
"description": "Types used by the Language server for node",
|
|
||||||
"version": "1.0.4",
|
|
||||||
"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",
|
|
||||||
"devDependencies": {
|
|
||||||
"mocha": "^2.4.5",
|
|
||||||
"typescript": "2.0.3"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"prepublish": "tsc -p ./src",
|
|
||||||
"compile": "tsc -p ./src",
|
|
||||||
"watch": "tsc -w -p ./src",
|
|
||||||
"test": "mocha"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "ES5",
|
|
||||||
"module": "umd",
|
|
||||||
"sourceMap": false,
|
|
||||||
"declaration": true,
|
|
||||||
"stripInternal": true,
|
|
||||||
"outDir": "../lib"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
112
dataprotocol-node/types/src/typings/promise.d.ts
vendored
112
dataprotocol-node/types/src/typings/promise.d.ts
vendored
@@ -1,112 +0,0 @@
|
|||||||
/*! *****************************************************************************
|
|
||||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
||||||
this file except in compliance with the License. You may obtain a copy of the
|
|
||||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
||||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
||||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
||||||
|
|
||||||
See the Apache Version 2.0 License for specific language governing permissions
|
|
||||||
and limitations under the License.
|
|
||||||
***************************************************************************** */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Thenable (E.g. PromiseLike) and Promise declarions are taken from TypeScript's
|
|
||||||
* lib.core.es6.d.ts file. See above Copyright notice.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise,
|
|
||||||
* and others. This API makes no assumption about what promise libary is being used which
|
|
||||||
* enables reusing existing code without migrating to a specific promise implementation. Still,
|
|
||||||
* we recommand the use of native promises which are available in VS Code.
|
|
||||||
*/
|
|
||||||
interface Thenable<R> {
|
|
||||||
/**
|
|
||||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
|
||||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
|
||||||
* @param onrejected The callback to execute when the Promise is rejected.
|
|
||||||
* @returns A Promise for the completion of which ever callback is executed.
|
|
||||||
*/
|
|
||||||
then<TResult>(onfulfilled?: (value: R) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Thenable<TResult>;
|
|
||||||
then<TResult>(onfulfilled?: (value: R) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Thenable<TResult>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents the completion of an asynchronous operation
|
|
||||||
*/
|
|
||||||
interface Promise<T> extends Thenable<T> {
|
|
||||||
/**
|
|
||||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
|
||||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
|
||||||
* @param onrejected The callback to execute when the Promise is rejected.
|
|
||||||
* @returns A Promise for the completion of which ever callback is executed.
|
|
||||||
*/
|
|
||||||
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Promise<TResult>;
|
|
||||||
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Promise<TResult>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attaches a callback for only the rejection of the Promise.
|
|
||||||
* @param onrejected The callback to execute when the Promise is rejected.
|
|
||||||
* @returns A Promise for the completion of the callback.
|
|
||||||
*/
|
|
||||||
catch(onrejected?: (reason: any) => T | Thenable<T>): Promise<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PromiseConstructor {
|
|
||||||
/**
|
|
||||||
* Creates a new Promise.
|
|
||||||
* @param executor A callback used to initialize the promise. This callback is passed two arguments:
|
|
||||||
* a resolve callback used resolve the promise with a value or the result of another promise,
|
|
||||||
* and a reject callback used to reject the promise with a provided reason or error.
|
|
||||||
*/
|
|
||||||
new <T>(executor: (resolve: (value?: T | Thenable<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises
|
|
||||||
* resolve, or rejected when any Promise is rejected.
|
|
||||||
* @param values An array of Promises.
|
|
||||||
* @returns A new Promise.
|
|
||||||
*/
|
|
||||||
all<T>(values: Array<T | Thenable<T>>): Promise<T[]>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
|
|
||||||
* or rejected.
|
|
||||||
* @param values An array of Promises.
|
|
||||||
* @returns A new Promise.
|
|
||||||
*/
|
|
||||||
race<T>(values: Array<T | Thenable<T>>): Promise<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new rejected promise for the provided reason.
|
|
||||||
* @param reason The reason the promise was rejected.
|
|
||||||
* @returns A new rejected Promise.
|
|
||||||
*/
|
|
||||||
reject(reason: any): Promise<void>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new rejected promise for the provided reason.
|
|
||||||
* @param reason The reason the promise was rejected.
|
|
||||||
* @returns A new rejected Promise.
|
|
||||||
*/
|
|
||||||
reject<T>(reason: any): Promise<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new resolved promise for the provided value.
|
|
||||||
* @param value A promise.
|
|
||||||
* @returns A promise whose internal state matches the provided promise.
|
|
||||||
*/
|
|
||||||
resolve<T>(value: T | Thenable<T>): Promise<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new resolved promise .
|
|
||||||
* @returns A resolved promise.
|
|
||||||
*/
|
|
||||||
resolve(): Promise<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare var Promise: PromiseConstructor;
|
|
||||||
Reference in New Issue
Block a user