New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

typescript-language-server

Package Overview
Dependencies
Maintainers
2
Versions
136
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

typescript-language-server - npm Package Compare versions

Comparing version 0.4.0-dev.b964d21 to 0.4.0-dev.e032d7d

lib/callHierarchy.d.ts

6

lib/cli.js

@@ -15,3 +15,4 @@ #!/usr/bin/env node

.option('--tsserver-log-file <tsserverLogFile>', 'Specify a tsserver log file. example: --tsserver-log-file ts-logs.txt')
.option('--tsserver-log-verbosity <tsserverLogVerbosity>', 'Specify a tsserver log verbosity (terse, normal, verbose). example: --tsserver-log-verbosity verbose')
.option('--tsserver-log-verbosity <tsserverLogVerbosity>', 'Specify a tsserver log verbosity (terse, normal, verbose). Defaults to `normal`.' +
' example: --tsserver-log-verbosity verbose')
.option('--tsserver-path <path>', `Specify path to tsserver. example: --tsserver-path=${utils_1.getTsserverExecutable()}`)

@@ -23,2 +24,5 @@ .parse(process.argv);

}
if (program.tsserverLogFile && !program.tsserverLogVerbosity) {
program.tsserverLogVerbosity = 'normal';
}
let logLevel = lsp.MessageType.Warning;

@@ -25,0 +29,0 @@ if (program.logLevel) {

11

lib/diagnostic-queue.d.ts

@@ -6,7 +6,9 @@ /// <reference types="p-debounce" />

import { EventTypes } from './tsp-command-types';
import { LspDocuments } from './document';
declare class FileDiagnostics {
protected readonly uri: string;
protected readonly publishDiagnostics: (params: lsp.PublishDiagnosticsParams) => void;
protected readonly documents: LspDocuments;
private readonly diagnosticsPerKind;
constructor(uri: string, publishDiagnostics: (params: lsp.PublishDiagnosticsParams) => void);
constructor(uri: string, publishDiagnostics: (params: lsp.PublishDiagnosticsParams) => void, documents: LspDocuments);
update(kind: EventTypes, diagnostics: tsp.Diagnostic[]): void;

@@ -19,6 +21,7 @@ protected readonly firePublishDiagnostics: (() => Promise<void>) & {

export declare class DiagnosticEventQueue {
protected publishDiagnostics: (params: lsp.PublishDiagnosticsParams) => void;
protected logger: Logger;
protected readonly publishDiagnostics: (params: lsp.PublishDiagnosticsParams) => void;
protected readonly documents: LspDocuments;
protected readonly logger: Logger;
protected readonly diagnostics: Map<string, FileDiagnostics>;
constructor(publishDiagnostics: (params: lsp.PublishDiagnosticsParams) => void, logger: Logger);
constructor(publishDiagnostics: (params: lsp.PublishDiagnosticsParams) => void, documents: LspDocuments, logger: Logger);
updateDiagnostics(kind: EventTypes, event: tsp.DiagnosticEvent): void;

@@ -25,0 +28,0 @@ }

@@ -12,5 +12,6 @@ "use strict";

class FileDiagnostics {
constructor(uri, publishDiagnostics) {
constructor(uri, publishDiagnostics, documents) {
this.uri = uri;
this.publishDiagnostics = publishDiagnostics;
this.documents = documents;
this.diagnosticsPerKind = new Map();

@@ -23,3 +24,3 @@ this.firePublishDiagnostics = debounce(() => {

update(kind, diagnostics) {
this.diagnosticsPerKind.set(kind, diagnostics.map(protocol_translation_1.toDiagnostic));
this.diagnosticsPerKind.set(kind, diagnostics);
this.firePublishDiagnostics();

@@ -29,4 +30,6 @@ }

const result = [];
for (const value of this.diagnosticsPerKind.values()) {
result.push(...value);
for (const diagnostics of this.diagnosticsPerKind.values()) {
for (const diagnostic of diagnostics) {
result.push(protocol_translation_1.toDiagnostic(diagnostic, this.documents));
}
}

@@ -37,4 +40,5 @@ return result;

class DiagnosticEventQueue {
constructor(publishDiagnostics, logger) {
constructor(publishDiagnostics, documents, logger) {
this.publishDiagnostics = publishDiagnostics;
this.documents = documents;
this.logger = logger;

@@ -49,5 +53,6 @@ this.diagnostics = new Map();

const { file } = event.body;
const diagnostics = this.diagnostics.get(file) || new FileDiagnostics(protocol_translation_1.pathToUri(file), this.publishDiagnostics);
const uri = protocol_translation_1.pathToUri(file, this.documents);
const diagnostics = this.diagnostics.get(uri) || new FileDiagnostics(uri, this.publishDiagnostics, this.documents);
diagnostics.update(kind, event.body.diagnostics);
this.diagnostics.set(file, diagnostics);
this.diagnostics.set(uri, diagnostics);
}

@@ -54,0 +59,0 @@ }

@@ -5,3 +5,3 @@ import * as lsp from 'vscode-languageserver';

export declare function collectSymbolInformations(uri: string, current: tsp.NavigationTree, symbols: lsp.SymbolInformation[], containerName?: string): boolean;
export declare function shouldInclueEntry(item: tsp.NavigationTree | tsp.NavigationBarItem): boolean;
export declare function shouldIncludeEntry(item: tsp.NavigationTree | tsp.NavigationBarItem): boolean;
//# sourceMappingURL=document-symbol.d.ts.map

@@ -12,10 +12,17 @@ "use strict";

function collectDocumentSymbols(parent, symbols) {
let shouldInclude = shouldInclueEntry(parent);
return collectDocumentSymbolsInRange(parent, symbols, { start: protocol_translation_1.asRange(parent.spans[0]).start, end: protocol_translation_1.asRange(parent.spans[parent.spans.length - 1]).end });
}
exports.collectDocumentSymbols = collectDocumentSymbols;
function collectDocumentSymbolsInRange(parent, symbols, range) {
let shouldInclude = shouldIncludeEntry(parent);
for (const span of parent.spans) {
const range = protocol_translation_1.asRange(span);
const spanRange = protocol_translation_1.asRange(span);
if (!protocol_translation_1.Range.intersection(range, spanRange)) {
continue;
}
const children = [];
if (parent.childItems) {
for (const child of parent.childItems) {
if (child.spans.some(span => !!protocol_translation_1.Range.intersection(range, protocol_translation_1.asRange(span)))) {
const includedChild = collectDocumentSymbols(child, children);
if (child.spans.some(childSpan => !!protocol_translation_1.Range.intersection(spanRange, protocol_translation_1.asRange(childSpan)))) {
const includedChild = collectDocumentSymbolsInRange(child, children, spanRange);
shouldInclude = shouldInclude || includedChild;

@@ -25,2 +32,10 @@ }

}
let selectionRange = spanRange;
if (parent.nameSpan) {
const nameRange = protocol_translation_1.asRange(parent.nameSpan);
// In the case of mergeable definitions, the nameSpan is only correct for the first definition.
if (protocol_translation_1.Range.intersection(spanRange, nameRange)) {
selectionRange = nameRange;
}
}
if (shouldInclude) {

@@ -31,4 +46,4 @@ symbols.push({

kind: protocol_translation_1.toSymbolKind(parent.kind),
range,
selectionRange: range,
range: spanRange,
selectionRange: selectionRange,
children

@@ -40,5 +55,4 @@ });

}
exports.collectDocumentSymbols = collectDocumentSymbols;
function collectSymbolInformations(uri, current, symbols, containerName) {
let shouldInclude = shouldInclueEntry(current);
let shouldInclude = shouldIncludeEntry(current);
const name = current.text;

@@ -72,3 +86,3 @@ for (const span of current.spans) {

exports.collectSymbolInformations = collectSymbolInformations;
function shouldInclueEntry(item) {
function shouldIncludeEntry(item) {
if (item.kind === tsp_command_types_1.ScriptElementKind.alias) {

@@ -79,3 +93,3 @@ return false;

}
exports.shouldInclueEntry = shouldInclueEntry;
exports.shouldIncludeEntry = shouldIncludeEntry;
//# sourceMappingURL=document-symbol.js.map

@@ -10,2 +10,3 @@ "use strict";

const lsp = require("vscode-languageserver");
const lspCallHierarchy = require("./lsp-protocol.callHierarchy.proposed");
const logger_1 = require("./logger");

@@ -46,2 +47,4 @@ const lsp_server_1 = require("./lsp-server");

connection.onFoldingRanges(server.foldingRanges.bind(server));
// proposed `textDocument/callHierarchy` request
connection.onRequest(lspCallHierarchy.CallHierarchyRequest.type, server.callHierarchy.bind(server));
return connection;

@@ -48,0 +51,0 @@ }

/// <reference types="p-debounce" />
import * as lsp from 'vscode-languageserver';
import * as lspCallHierarchy from './lsp-protocol.callHierarchy.proposed';
import * as tsp from 'typescript/lib/protocol';

@@ -29,2 +30,3 @@ import { Logger } from './logger';

protected getLogFile(logVerbosity: string | undefined): string | undefined;
protected doGetLogFile(): string | undefined;
protected diagnosticsTokenSource: lsp.CancellationTokenSource | undefined;

@@ -52,3 +54,3 @@ protected interuptDiagnostics<R>(f: () => R): R;

protected readonly supportHierarchicalDocumentSymbol: boolean;
completion(params: lsp.CompletionParams): Promise<TSCompletionItem[]>;
completion(params: lsp.CompletionParams): Promise<TSCompletionItem[] | null>;
completionResolve(item: TSCompletionItem): Promise<lsp.CompletionItem>;

@@ -80,3 +82,4 @@ hover(params: lsp.TextDocumentPositionParams): Promise<lsp.Hover>;

protected onTsEvent(event: protocol.Event): void;
callHierarchy(params: lspCallHierarchy.CallHierarchyParams | lspCallHierarchy.ResolveCallHierarchyItemParams): Promise<lspCallHierarchy.CallHierarchyItem | null>;
}
//# sourceMappingURL=lsp-server.d.ts.map

@@ -37,2 +37,3 @@ "use strict";

const document_symbol_1 = require("./document-symbol");
const callHierarchy_1 = require("./callHierarchy");
class LspServer {

@@ -44,3 +45,3 @@ constructor(options) {

this.logger = new logger_1.PrefixingLogger(options.logger, '[lspserver]');
this.diagnosticQueue = new diagnostic_queue_1.DiagnosticEventQueue(diagnostics => this.options.lspClient.publishDiagnostics(diagnostics), this.logger);
this.diagnosticQueue = new diagnostic_queue_1.DiagnosticEventQueue(diagnostics => this.options.lspClient.publishDiagnostics(diagnostics), this.documents, this.logger);
}

@@ -66,5 +67,5 @@ closeAll() {

// 3) look into node_modules of typescript-language-server
const bundled = modules_resolver_1.findPathToModule(__dirname, `.bin/${utils_1.getTsserverExecutable()}`);
const bundled = modules_resolver_1.findPathToModule(__dirname, path.join("typescript", "lib", "tsserver.js"));
if (!bundled) {
throw Error(`Couldn't find '${utils_1.getTsserverExecutable()}' executable`);
throw Error(`Couldn't find '${utils_1.getTsserverExecutable()}' executable or 'tsserver.js' module`);
}

@@ -101,3 +102,3 @@ return bundled;

});
const logFileUri = logFile && protocol_translation_1.pathToUri(logFile);
const logFileUri = logFile && protocol_translation_1.pathToUri(logFile, undefined);
this.initializeResult = {

@@ -137,2 +138,3 @@ capabilities: {

};
this.initializeResult.capabilities.callHierarchyProvider = true;
this.logger.log('onInitialize result', this.initializeResult);

@@ -146,5 +148,13 @@ return this.initializeResult;

}
if (process.env.tsserverLogFile) {
return process.env.tsserverLogFile;
const logFile = this.doGetLogFile();
if (logFile) {
fs.ensureFileSync(logFile);
return logFile;
}
return tempy.file({ name: 'tsserver.log' });
}
doGetLogFile() {
if (process.env.TSSERVER_LOG_FILE) {
return process.env.TSSERVER_LOG_FILE;
}
if (this.options.tsserverLogFile) {

@@ -159,3 +169,3 @@ return this.options.tsserverLogFile;

}
return tempy.file({ name: 'tsserver.log' });
return undefined;
}

@@ -332,3 +342,3 @@ interuptDiagnostics(f) {

});
return result.body ? result.body.map(fileSpan => protocol_translation_1.toLocation(fileSpan)) : [];
return result.body ? result.body.map(fileSpan => protocol_translation_1.toLocation(fileSpan, this.documents)) : [];
});

@@ -384,11 +394,22 @@ }

}
const result = yield this.interuptDiagnostics(() => this.tspClient.request("completions" /* Completions */, {
file,
line: params.position.line + 1,
offset: params.position.character + 1,
includeExternalModuleExports: true,
includeInsertTextCompletions: true
}));
const body = result.body || [];
return body.map(entry => completion_1.asCompletionItem(entry, file, params.position, document));
try {
const result = yield this.interuptDiagnostics(() => this.tspClient.request("completions" /* Completions */, {
file,
line: params.position.line + 1,
offset: params.position.character + 1,
includeExternalModuleExports: true,
includeInsertTextCompletions: true
}));
const body = result.body || [];
return body.map(entry => completion_1.asCompletionItem(entry, file, params.position, document));
}
catch (error) {
if (error.message === "No content available.") {
this.logger.info('No content was available for completion request');
return null;
}
else {
throw error;
}
}
});

@@ -464,3 +485,3 @@ }

.forEach((spanGroup) => {
const uri = protocol_translation_1.pathToUri(spanGroup.file), textEdits = workspaceEdit.changes[uri] || (workspaceEdit.changes[uri] = []);
const uri = protocol_translation_1.pathToUri(spanGroup.file, this.documents), textEdits = workspaceEdit.changes[uri] || (workspaceEdit.changes[uri] = []);
spanGroup.locs.forEach((textSpan) => {

@@ -495,3 +516,3 @@ textEdits.push({

return result.body.refs
.map(fileSpan => protocol_translation_1.toLocation(fileSpan));
.map(fileSpan => protocol_translation_1.toLocation(fileSpan, this.documents));
});

@@ -577,3 +598,3 @@ }

const errorCodes = params.context.diagnostics.map(diagnostic => Number(diagnostic.code));
quickfix_1.provideQuickFix(yield this.getCodeFixes(Object.assign({}, args, { errorCodes })), codeActions);
quickfix_1.provideQuickFix(yield this.getCodeFixes(Object.assign({}, args, { errorCodes })), codeActions, this.documents);
refactor_1.provideRefactors(yield this.getRefactors(args), codeActions, args);

@@ -640,3 +661,3 @@ organize_imports_1.provideOrganizeImports(file, params.context, codeActions);

textDocument: {
uri: protocol_translation_1.pathToUri(args.file)
uri: protocol_translation_1.pathToUri(args.file, this.documents)
},

@@ -673,3 +694,3 @@ position: protocol_translation_1.toPosition(renameLocation)

for (const edit of edits) {
changes[protocol_translation_1.pathToUri(edit.fileName)] = edit.textChanges.map(protocol_translation_1.toTextEdit);
changes[protocol_translation_1.pathToUri(edit.fileName, this.documents)] = edit.textChanges.map(protocol_translation_1.toTextEdit);
}

@@ -757,3 +778,3 @@ const { applied } = yield this.options.lspClient.applyWorkspaceEdit({

location: {
uri: protocol_translation_1.pathToUri(item.file),
uri: protocol_translation_1.pathToUri(item.file, this.documents),
range: {

@@ -838,4 +859,12 @@ start: protocol_translation_1.toPosition(item.start),

}
callHierarchy(params) {
return __awaiter(this, void 0, void 0, function* () {
this.logger.log('callHierarchy', params);
const documentProvider = (file) => this.documents.get(file);
const result = yield callHierarchy_1.computeCallHierarchy(this.tspClient, documentProvider, params);
return result;
});
}
}
exports.LspServer = LspServer;
//# sourceMappingURL=lsp-server.js.map

@@ -62,2 +62,26 @@ "use strict";

})).timeout(10000);
it('incorrect source location', () => __awaiter(this, void 0, void 0, function* () {
const doc = {
uri: test_utils_1.uri('bar.ts'),
languageId: 'typescript',
version: 1,
text: `
export function foo(): void {
console.log('test')
}
`
};
server.didOpenTextDocument({
textDocument: doc
});
const pos = test_utils_1.position(doc, 'foo');
const proposals = yield server.completion({
textDocument: doc,
position: pos
});
assert.isTrue(proposals === null);
server.didCloseTextDocument({
textDocument: doc
});
})).timeout(10000);
});

@@ -122,3 +146,3 @@ describe('diagnostics', () => {

});
describe('symbol', () => {
describe('document symbol', () => {
it('simple test', () => __awaiter(this, void 0, void 0, function* () {

@@ -150,2 +174,71 @@ const doc = {

})).timeout(10000);
it('merges interfaces correctly', () => __awaiter(this, void 0, void 0, function* () {
const doc = {
uri: test_utils_1.uri('bar.ts'),
languageId: 'typescript',
version: 1,
text: `
interface Box {
height: number;
width: number;
}
interface Box {
scale: number;
}`
};
server.didOpenTextDocument({
textDocument: doc
});
const symbols = yield server.documentSymbol({
textDocument: doc,
position: lsp.Position.create(1, 1)
});
assert.equal(`
Box
height
width
Box
scale
`, symbolsAsString(symbols) + '\n');
})).timeout(10000);
it('duplication test', () => __awaiter(this, void 0, void 0, function* () {
const doc = {
uri: test_utils_1.uri('bar.ts'),
languageId: 'typescript',
version: 1,
text: `
export class Foo {
protected foo: string;
public myFunction(arg: string) {
}
}
export class Foo {
protected foo: string;
public myFunction(arg: string) {
}
}
`
};
server.didOpenTextDocument({
textDocument: doc
});
const symbols = yield server.documentSymbol({
textDocument: doc,
position: lsp.Position.create(1, 1)
});
const expectation = `
Foo
foo
myFunction
Foo
foo
myFunction
`;
assert.equal(symbolsAsString(symbols) + '\n', expectation);
assert.deepEqual(symbols[0].selectionRange, { "start": { "line": 1, "character": 21 }, "end": { "line": 1, "character": 24 } });
assert.deepEqual(symbols[0].range, { "start": { "line": 1, "character": 8 }, "end": { "line": 5, "character": 9 } });
assert.deepEqual(symbols[1].selectionRange, symbols[1].range);
assert.deepEqual(symbols[1].range, { "start": { "line": 6, "character": 8 }, "end": { "line": 10, "character": 9 } });
})).timeout(10000);
});

@@ -316,2 +409,159 @@ function symbolsAsString(symbols, indentation = '') {

});
describe.only('callHierarchy', () => {
function resultToString(item) {
if (!item) {
return '<not found>';
}
const arrow = '-|>';
const symbolToString = (item) => `${item.name} (symbol: ${item.uri.split('/').pop()}#${item.selectionRange.start.line})`;
const callToString = (call) => ` ${arrow} ${symbolToString(call)} - (call: ${call.callLocation.uri.split('/').pop()}#${call.callLocation.range.start.line})`;
const out = [];
out.push(`${arrow} ${symbolToString(item)}`);
if (item.callers) {
out.push(`callers:`);
for (const call of item.callers) {
out.push(callToString(call));
}
}
if (item.callees) {
out.push(`callees:`);
for (const call of item.callees) {
out.push(callToString(call));
}
}
return out.join('\n').trim();
}
const oneDoc = {
uri: test_utils_1.uri('one.ts'),
languageId: 'typescript',
version: 1,
text: `// comment line
import { Two } from './two'
export function main() {
new Two().callThreeTwice();
}`
};
const twoDoc = {
uri: test_utils_1.uri('two.ts'),
languageId: 'typescript',
version: 1,
text: `// comment line
import { Three } from "./three";
export class Two {
callThreeTwice() {
new Three().tada();
new Three().tada();
}
}
`
};
const threeDoc = {
uri: test_utils_1.uri('three.ts'),
languageId: 'typescript',
version: 1,
text: `// comment line
export class Three {
tada() {
print('🎉');
}
}
export function print(s: string) {
console.log(s);
}
`
};
function openDocuments() {
for (const textDocument of [oneDoc, twoDoc, threeDoc]) {
server.didOpenTextDocument({ textDocument });
}
}
it('find target symbol', () => __awaiter(this, void 0, void 0, function* () {
openDocuments();
const item = yield server.callHierarchy({
textDocument: twoDoc,
position: lsp.Position.create(4, 22),
direction: 'incoming',
resolve: 0
});
assert.equal(resultToString(item), `
-|> tada (symbol: three.ts#2)
`.trim());
})).timeout(10000);
it('callers: first level', () => __awaiter(this, void 0, void 0, function* () {
openDocuments();
const item = yield server.callHierarchy({
textDocument: twoDoc,
position: lsp.Position.create(4, 22),
direction: 'incoming',
resolve: 1
});
assert.equal(resultToString(item), `
-|> tada (symbol: three.ts#2)
callers:
-|> callThreeTwice (symbol: two.ts#3) - (call: two.ts#4)
-|> callThreeTwice (symbol: two.ts#3) - (call: two.ts#5)
`.trim());
})).timeout(10000);
it('callers: second level', () => __awaiter(this, void 0, void 0, function* () {
openDocuments();
const firstItem = yield server.callHierarchy({
textDocument: twoDoc,
position: lsp.Position.create(4, 22),
direction: 'incoming',
resolve: 1
});
assert.isTrue(firstItem !== null, "precondition failed: first level");
assert.isTrue(firstItem.callers !== undefined, "precondition failed: unresolved callers of first level");
assert.isTrue(firstItem.callers[0] !== undefined, "precondition failed: unresolved callers of first level");
const unresolvedItem = firstItem.callers[0];
const callsResult = yield server.callHierarchy({
item: unresolvedItem,
direction: 'incoming',
resolve: 1
});
assert.equal(resultToString(callsResult), `
-|> callThreeTwice (symbol: two.ts#3)
callers:
-|> main (symbol: one.ts#2) - (call: one.ts#3)
`.trim());
})).timeout(10000);
it('callees: first step', () => __awaiter(this, void 0, void 0, function* () {
openDocuments();
const item = yield server.callHierarchy({
textDocument: oneDoc,
position: lsp.Position.create(3, 18),
direction: 'outgoing',
resolve: 1
});
assert.equal(resultToString(item), `
-|> callThreeTwice (symbol: two.ts#3)
callees:
-|> Three (symbol: two.ts#1) - (call: two.ts#4)
-|> tada (symbol: three.ts#2) - (call: two.ts#4)
-|> Three (symbol: two.ts#1) - (call: two.ts#5)
-|> tada (symbol: three.ts#2) - (call: two.ts#5)`.trim());
})).timeout(10000);
it('callees: second step', () => __awaiter(this, void 0, void 0, function* () {
openDocuments();
const firstItem = yield server.callHierarchy({
textDocument: oneDoc,
position: lsp.Position.create(3, 18),
direction: 'outgoing',
resolve: 1
});
assert.isTrue(firstItem !== null, "precondition failed: first level");
assert.isTrue(firstItem.callees !== undefined, "precondition failed: unresolved callers of first level");
assert.isTrue(firstItem.callees[1] !== undefined, "precondition failed: unresolved callers of first level");
const unresolvedItem = firstItem.callees[1];
const item = yield server.callHierarchy({
item: unresolvedItem,
direction: 'outgoing',
resolve: 1
});
assert.equal(resultToString(item), `
-|> tada (symbol: three.ts#2)
callees:
-|> print (symbol: three.ts#6) - (call: three.ts#3)`.trim());
})).timeout(10000);
});
//# sourceMappingURL=lsp-server.spec.js.map

@@ -21,3 +21,3 @@ "use strict";

if (parent !== dir) {
return findPathToModule(paths.resolve(dir, '..'), moduleName);
return findPathToModule(parent, moduleName);
}

@@ -24,0 +24,0 @@ return undefined;

import * as lsp from 'vscode-languageserver';
import * as tsp from 'typescript/lib/protocol';
import { LspDocuments } from './document';
export declare function uriToPath(stringUri: string): string | undefined;
export declare function pathToUri(p: string): string;
export declare function pathToUri(filepath: string, documents: LspDocuments | undefined): string;
export declare function toPosition(location: tsp.Location): lsp.Position;
export declare function toLocation(fileSpan: tsp.FileSpan): lsp.Location;
export declare function toLocation(fileSpan: tsp.FileSpan, documents: LspDocuments | undefined): lsp.Location;
export declare function toFileRangeRequestArgs(file: string, range: lsp.Range): tsp.FileRangeRequestArgs;
export declare function toSymbolKind(tspKind: string): lsp.SymbolKind;
export declare function toDiagnosticSeverity(category: string): lsp.DiagnosticSeverity;
export declare function toDiagnostic(diagnostic: tsp.Diagnostic): lsp.Diagnostic;
export declare function asRelatedInformation(info: tsp.DiagnosticRelatedInformation[] | undefined): lsp.DiagnosticRelatedInformation[] | undefined;
export declare function toDiagnostic(diagnostic: tsp.Diagnostic, documents: LspDocuments | undefined): lsp.Diagnostic;
export declare function asRelatedInformation(info: tsp.DiagnosticRelatedInformation[] | undefined, documents: LspDocuments | undefined): lsp.DiagnosticRelatedInformation[] | undefined;
export declare function toTextEdit(edit: tsp.CodeEdit): lsp.TextEdit;
export declare function toMarkDown(documentation: tsp.SymbolDisplayPart[], tags: tsp.JSDocTagInfo[]): string;
export declare function toTextDocumentEdit(change: tsp.FileCodeEdits): lsp.TextDocumentEdit;
export declare function toTextDocumentEdit(change: tsp.FileCodeEdits, documents: LspDocuments | undefined): lsp.TextDocumentEdit;
export declare function toDocumentHighlight(item: tsp.DocumentHighlightsItem): lsp.DocumentHighlight[];
export declare function asRange(span: tsp.TextSpan): lsp.Range;
export declare function asTextSpan(range: lsp.Range): tsp.TextSpan;
export declare function asDocumentation(data: {

@@ -18,0 +20,0 @@ documentation?: tsp.SymbolDisplayPart[];

@@ -11,3 +11,2 @@ "use strict";

const vscode_uri_1 = require("vscode-uri");
const utils_1 = require("./utils");
function uriToPath(stringUri) {

@@ -21,4 +20,6 @@ const uri = vscode_uri_1.default.parse(stringUri);

exports.uriToPath = uriToPath;
function pathToUri(p) {
return 'file://' + (utils_1.isWindows() ? '/' + p.replace(/\//g, '/') : p);
function pathToUri(filepath, documents) {
const fileUri = vscode_uri_1.default.file(filepath);
const document = documents && documents.get(fileUri.fsPath);
return document ? document.uri : fileUri.toString();
}

@@ -33,5 +34,5 @@ exports.pathToUri = pathToUri;

exports.toPosition = toPosition;
function toLocation(fileSpan) {
function toLocation(fileSpan, documents) {
return {
uri: pathToUri(fileSpan.file),
uri: pathToUri(fileSpan.file, documents),
range: {

@@ -93,3 +94,3 @@ start: toPosition(fileSpan.start),

exports.toDiagnosticSeverity = toDiagnosticSeverity;
function toDiagnostic(diagnostic) {
function toDiagnostic(diagnostic, documents) {
return {

@@ -104,7 +105,7 @@ range: {

source: diagnostic.source || 'typescript',
relatedInformation: asRelatedInformation(diagnostic.relatedInformation)
relatedInformation: asRelatedInformation(diagnostic.relatedInformation, documents)
};
}
exports.toDiagnostic = toDiagnostic;
function asRelatedInformation(info) {
function asRelatedInformation(info, documents) {
if (!info) {

@@ -117,3 +118,3 @@ return undefined;

if (span) {
result.push(lsp.DiagnosticRelatedInformation.create(toLocation(span), item.message));
result.push(lsp.DiagnosticRelatedInformation.create(toLocation(span, documents), item.message));
}

@@ -155,6 +156,6 @@ }

exports.toMarkDown = toMarkDown;
function toTextDocumentEdit(change) {
function toTextDocumentEdit(change, documents) {
return {
textDocument: {
uri: pathToUri(change.fileName),
uri: pathToUri(change.fileName, documents),
version: 0 // TODO

@@ -195,5 +196,18 @@ },

function asRange(span) {
return lsp.Range.create(Math.max(0, span.start.line - 1), Math.max(span.start.offset - 1, 0), Math.max(0, span.end.line - 1), Math.max(0, span.end.offset - 1));
return lsp.Range.create(Math.max(0, span.start.line - 1), Math.max(0, span.start.offset - 1), Math.max(0, span.end.line - 1), Math.max(0, span.end.offset - 1));
}
exports.asRange = asRange;
function asTextSpan(range) {
return {
start: {
line: range.start.line + 1,
offset: range.start.character + 1
},
end: {
line: range.end.line + 1,
offset: range.end.character + 1
}
};
}
exports.asTextSpan = asTextSpan;
function asDocumentation(data) {

@@ -200,0 +214,0 @@ let value = '';

import * as lsp from 'vscode-languageserver';
import * as tsp from 'typescript/lib/protocol';
export declare function provideQuickFix(response: tsp.GetCodeFixesResponse | undefined, result: (lsp.Command | lsp.CodeAction)[]): void;
import { LspDocuments } from './document';
export declare function provideQuickFix(response: tsp.GetCodeFixesResponse | undefined, result: (lsp.Command | lsp.CodeAction)[], documents: LspDocuments | undefined): void;
//# sourceMappingURL=quickfix.d.ts.map

@@ -11,3 +11,3 @@ "use strict";

const protocol_translation_1 = require("./protocol-translation");
function provideQuickFix(response, result) {
function provideQuickFix(response, result, documents) {
if (!response || !response.body) {

@@ -21,3 +21,3 @@ return;

arguments: [{
documentChanges: fix.changes.map(c => protocol_translation_1.toTextDocumentEdit(c))
documentChanges: fix.changes.map(c => protocol_translation_1.toTextDocumentEdit(c, documents))
}]

@@ -24,0 +24,0 @@ });

@@ -25,3 +25,3 @@ "use strict";

const resolved = this.filePath(suffix);
return protocol_translation_1.pathToUri(resolved);
return protocol_translation_1.pathToUri(resolved, undefined);
}

@@ -28,0 +28,0 @@ exports.uri = uri;

@@ -10,2 +10,3 @@ "use strict";

const fs = require("fs");
const path = require("path");
const cp = require("child_process");

@@ -46,3 +47,6 @@ const readline = require("readline");

this.logger.info(`Starting tsserver : '${tsserverPath} ${args.join(' ')}'`);
this.tsserverProc = cp.spawn(tsserverPath, args);
const tsserverPathIsModule = path.extname(tsserverPath) === ".js";
this.tsserverProc = tsserverPathIsModule
? cp.fork(tsserverPath, args, { silent: true })
: cp.spawn(tsserverPath, args);
this.readlineInterface = readline.createInterface(this.tsserverProc.stdout, this.tsserverProc.stdin, undefined);

@@ -49,0 +53,0 @@ process.on('exit', () => {

@@ -10,60 +10,72 @@ "use strict";

const chai = require("chai");
const path = require("path");
const tsp_client_1 = require("./tsp-client");
const logger_1 = require("./logger");
const test_utils_1 = require("./test-utils");
const modules_resolver_1 = require("./modules-resolver");
const assert = chai.assert;
const server = new tsp_client_1.TspClient({
const executableServer = new tsp_client_1.TspClient({
logger: new logger_1.ConsoleLogger(),
tsserverPath: 'tsserver'
});
server.start();
describe('ts server client', () => {
it('completion', () => {
const f = test_utils_1.filePath('module2.ts');
server.notify("open" /* Open */, {
file: f,
fileContent: test_utils_1.readContents(f)
});
return server.request("completions" /* Completions */, {
file: f,
line: 1,
offset: 0,
prefix: 'im',
includeExternalModuleExports: true,
includeInsertTextCompletions: true
}).then(completions => {
assert.equal(completions.body[1].name, "ImageData");
});
}).timeout(5000);
it('references', () => {
const f = test_utils_1.filePath('module2.ts');
server.notify("open" /* Open */, {
file: f,
fileContent: test_utils_1.readContents(f)
});
return server.request("references" /* References */, {
file: f,
line: 8,
offset: 16
}).then(references => {
assert.equal(references.body.symbolName, "doStuff");
});
}).timeout(5000);
it('documentHighlight', () => {
const f = test_utils_1.filePath('module2.ts');
server.notify("open" /* Open */, {
file: f,
fileContent: test_utils_1.readContents(f)
});
return server.request("documentHighlights" /* DocumentHighlights */, {
file: f,
line: 8,
offset: 16,
filesToSearch: [f]
}).then(response => {
assert.isTrue(response.body.some(({ file }) => file.endsWith('module2.ts')), JSON.stringify(response.body, undefined, 2));
assert.isFalse(response.body.some(({ file }) => file.endsWith('module1.ts')), JSON.stringify(response.body, undefined, 2));
});
}).timeout(5000);
const tsserverModuleRelativePath = path.join("typescript", "lib", "tsserver.js");
const bundled = modules_resolver_1.findPathToModule(__dirname, tsserverModuleRelativePath);
const moduleServer = new tsp_client_1.TspClient({
logger: new logger_1.ConsoleLogger(),
tsserverPath: bundled
});
const servers = { executableServer, moduleServer };
Object.keys(servers).forEach(serverName => {
const server = servers[serverName];
server.start();
describe('ts server client using ' + serverName, () => {
it('completion', () => {
const f = test_utils_1.filePath('module2.ts');
server.notify("open" /* Open */, {
file: f,
fileContent: test_utils_1.readContents(f)
});
return server.request("completions" /* Completions */, {
file: f,
line: 1,
offset: 0,
prefix: 'im',
includeExternalModuleExports: true,
includeInsertTextCompletions: true
}).then(completions => {
assert.equal(completions.body[1].name, "ImageData");
});
}).timeout(5000);
it('references', () => {
const f = test_utils_1.filePath('module2.ts');
server.notify("open" /* Open */, {
file: f,
fileContent: test_utils_1.readContents(f)
});
return server.request("references" /* References */, {
file: f,
line: 8,
offset: 16
}).then(references => {
assert.equal(references.body.symbolName, "doStuff");
});
}).timeout(5000);
it('documentHighlight', () => {
const f = test_utils_1.filePath('module2.ts');
server.notify("open" /* Open */, {
file: f,
fileContent: test_utils_1.readContents(f)
});
return server.request("documentHighlights" /* DocumentHighlights */, {
file: f,
line: 8,
offset: 16,
filesToSearch: [f]
}).then(response => {
assert.isTrue(response.body.some(({ file }) => file.endsWith('module2.ts')), JSON.stringify(response.body, undefined, 2));
assert.isFalse(response.body.some(({ file }) => file.endsWith('module1.ts')), JSON.stringify(response.body, undefined, 2));
});
}).timeout(5000);
});
});
//# sourceMappingURL=tsp-client.spec.js.map
{
"name": "typescript-language-server",
"version": "0.4.0-dev.b964d21",
"version": "0.4.0-dev.e032d7d",
"description": "Language Server Protocol (LSP) implementation for TypeScript using tsserver",

@@ -37,3 +37,3 @@ "author": "TypeFox and others",

},
"gitHead": "b964d213daaf191f0673e460a6ba4ae4715b96a0"
"gitHead": "e032d7db441745f67f012234110fd07a503fdd53"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc