typescript-language-server
Advanced tools
Comparing version 0.4.0-dev.2ab20b1 to 0.4.0-dev.366aecb
@@ -1,13 +0,2 @@ | ||
/// <reference path="../../node_modules/@types/lodash/common/common.d.ts" /> | ||
/// <reference path="../../node_modules/@types/lodash/common/array.d.ts" /> | ||
/// <reference path="../../node_modules/@types/lodash/common/collection.d.ts" /> | ||
/// <reference path="../../node_modules/@types/lodash/common/date.d.ts" /> | ||
/// <reference path="../../node_modules/@types/lodash/common/function.d.ts" /> | ||
/// <reference path="../../node_modules/@types/lodash/common/lang.d.ts" /> | ||
/// <reference path="../../node_modules/@types/lodash/common/math.d.ts" /> | ||
/// <reference path="../../node_modules/@types/lodash/common/number.d.ts" /> | ||
/// <reference path="../../node_modules/@types/lodash/common/object.d.ts" /> | ||
/// <reference path="../../node_modules/@types/lodash/common/seq.d.ts" /> | ||
/// <reference path="../../node_modules/@types/lodash/common/string.d.ts" /> | ||
/// <reference path="../../node_modules/@types/lodash/common/util.d.ts" /> | ||
/// <reference types="p-debounce" /> | ||
import * as tsp from 'typescript/lib/protocol'; | ||
@@ -17,11 +6,21 @@ import * as lsp from 'vscode-languageserver'; | ||
import { EventTypes } from './tsp-command-types'; | ||
declare class FileDiagnostics { | ||
protected readonly uri: string; | ||
protected readonly publishDiagnostics: (params: lsp.PublishDiagnosticsParams) => void; | ||
private readonly diagnosticsPerKind; | ||
constructor(uri: string, publishDiagnostics: (params: lsp.PublishDiagnosticsParams) => void); | ||
update(kind: EventTypes, diagnostics: tsp.Diagnostic[]): void; | ||
protected readonly firePublishDiagnostics: (() => Promise<void>) & { | ||
abort(): void; | ||
}; | ||
protected getDiagnostics(): lsp.Diagnostic[]; | ||
} | ||
export declare class DiagnosticEventQueue { | ||
protected publicDiagnostics: (params: lsp.PublishDiagnosticsParams) => void; | ||
protected publishDiagnostics: (params: lsp.PublishDiagnosticsParams) => void; | ||
protected logger: Logger; | ||
protected readonly diagnostics: Map<string, Map<EventTypes, lsp.Diagnostic[]>>; | ||
constructor(publicDiagnostics: (params: lsp.PublishDiagnosticsParams) => void, logger: Logger); | ||
protected readonly diagnostics: Map<string, FileDiagnostics>; | ||
constructor(publishDiagnostics: (params: lsp.PublishDiagnosticsParams) => void, logger: Logger); | ||
updateDiagnostics(kind: EventTypes, event: tsp.DiagnosticEvent): void; | ||
protected firePublishDiagnostics: ((file: string) => void) & import("_").Cancelable; | ||
protected getDiagnostics(file: string): lsp.Diagnostic[]; | ||
} | ||
export {}; | ||
//# sourceMappingURL=diagnostic-queue.d.ts.map |
@@ -10,13 +10,30 @@ "use strict"; | ||
const protocol_translation_1 = require("./protocol-translation"); | ||
const debounce = require("lodash.debounce"); | ||
const debounce = require("p-debounce"); | ||
class FileDiagnostics { | ||
constructor(uri, publishDiagnostics) { | ||
this.uri = uri; | ||
this.publishDiagnostics = publishDiagnostics; | ||
this.diagnosticsPerKind = new Map(); | ||
this.firePublishDiagnostics = debounce(() => { | ||
const diagnostics = this.getDiagnostics(); | ||
this.publishDiagnostics({ uri: this.uri, diagnostics }); | ||
}, 50); | ||
} | ||
update(kind, diagnostics) { | ||
this.diagnosticsPerKind.set(kind, diagnostics.map(protocol_translation_1.toDiagnostic)); | ||
this.firePublishDiagnostics(); | ||
} | ||
getDiagnostics() { | ||
const result = []; | ||
for (const value of this.diagnosticsPerKind.values()) { | ||
result.push(...value); | ||
} | ||
return result; | ||
} | ||
} | ||
class DiagnosticEventQueue { | ||
constructor(publicDiagnostics, logger) { | ||
this.publicDiagnostics = publicDiagnostics; | ||
constructor(publishDiagnostics, logger) { | ||
this.publishDiagnostics = publishDiagnostics; | ||
this.logger = logger; | ||
this.diagnostics = new Map(); | ||
this.firePublishDiagnostics = debounce((file) => { | ||
const uri = protocol_translation_1.pathToUri(file); | ||
const diagnostics = this.getDiagnostics(file); | ||
this.publicDiagnostics({ uri, diagnostics }); | ||
}, 50); | ||
} | ||
@@ -29,20 +46,8 @@ updateDiagnostics(kind, event) { | ||
const { file } = event.body; | ||
const diagnostics = this.diagnostics.get(file) || new Map(); | ||
diagnostics.set(kind, event.body.diagnostics.map(protocol_translation_1.toDiagnostic)); | ||
const diagnostics = this.diagnostics.get(file) || new FileDiagnostics(protocol_translation_1.pathToUri(file), this.publishDiagnostics); | ||
diagnostics.update(kind, event.body.diagnostics); | ||
this.diagnostics.set(file, diagnostics); | ||
this.firePublishDiagnostics(file); | ||
} | ||
getDiagnostics(file) { | ||
const diagnostics = this.diagnostics.get(file); | ||
if (!diagnostics) { | ||
return []; | ||
} | ||
const result = []; | ||
for (const value of diagnostics.values()) { | ||
result.push(...value); | ||
} | ||
return result; | ||
} | ||
} | ||
exports.DiagnosticEventQueue = DiagnosticEventQueue; | ||
//# sourceMappingURL=diagnostic-queue.js.map |
import * as lsp from 'vscode-languageserver'; | ||
import * as tsp from 'typescript/lib/protocol'; | ||
export declare function collectDocumentSymbols(parent: tsp.NavigationTree, symbols: lsp.DocumentSymbol[]): boolean; | ||
export declare function collectSymbolInformations(uri: string, parent: tsp.NavigationTree, symbols: lsp.SymbolInformation[]): boolean; | ||
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; | ||
//# sourceMappingURL=document-symbol.d.ts.map |
@@ -38,11 +38,12 @@ "use strict"; | ||
exports.collectDocumentSymbols = collectDocumentSymbols; | ||
function collectSymbolInformations(uri, parent, symbols) { | ||
let shouldInclude = shouldInclueEntry(parent); | ||
for (const span of parent.spans) { | ||
function collectSymbolInformations(uri, current, symbols, containerName) { | ||
let shouldInclude = shouldInclueEntry(current); | ||
const name = current.text; | ||
for (const span of current.spans) { | ||
const range = protocol_translation_1.asRange(span); | ||
const children = []; | ||
if (parent.childItems) { | ||
for (const child of parent.childItems) { | ||
if (current.childItems) { | ||
for (const child of current.childItems) { | ||
if (child.spans.some(span => !!protocol_translation_1.Range.intersection(range, protocol_translation_1.asRange(span)))) { | ||
const includedChild = collectSymbolInformations(uri, child, children); | ||
const includedChild = collectSymbolInformations(uri, child, children, name); | ||
shouldInclude = shouldInclude || includedChild; | ||
@@ -54,8 +55,9 @@ } | ||
symbols.push({ | ||
name: parent.text, | ||
kind: protocol_translation_1.toSymbolKind(parent.kind), | ||
name, | ||
kind: protocol_translation_1.toSymbolKind(current.kind), | ||
location: { | ||
uri, | ||
range | ||
} | ||
}, | ||
containerName | ||
}); | ||
@@ -62,0 +64,0 @@ symbols.push(...children); |
import * as lsp from 'vscode-languageserver'; | ||
export declare class LspDocument implements lsp.TextDocument { | ||
protected readonly document: lsp.TextDocument; | ||
lastAccessed: number; | ||
protected document: lsp.TextDocument; | ||
constructor(doc: lsp.TextDocumentItem); | ||
markAccessed(): void; | ||
readonly uri: string; | ||
readonly languageId: string; | ||
readonly version: number; | ||
getText(range?: lsp.Range | undefined): string; | ||
getText(range?: lsp.Range): string; | ||
positionAt(offset: number): lsp.Position; | ||
@@ -19,3 +17,15 @@ offsetAt(position: lsp.Position): number; | ||
getLineStart(line: number): lsp.Position; | ||
applyEdit(version: number, change: lsp.TextDocumentContentChangeEvent): void; | ||
} | ||
export declare class LspDocuments { | ||
private readonly _files; | ||
private readonly documents; | ||
/** | ||
* Sorted by last access. | ||
*/ | ||
readonly files: string[]; | ||
get(file: string): LspDocument | undefined; | ||
open(file: string, doc: lsp.TextDocumentItem): boolean; | ||
close(file: string): LspDocument | undefined; | ||
} | ||
//# sourceMappingURL=document.d.ts.map |
@@ -12,9 +12,5 @@ "use strict"; | ||
constructor(doc) { | ||
this.lastAccessed = new Date().getTime(); | ||
const { uri, languageId, version, text } = doc; | ||
this.document = lsp.TextDocument.create(uri, languageId, version, text); | ||
} | ||
markAccessed() { | ||
this.lastAccessed = new Date().getTime(); | ||
} | ||
get uri() { | ||
@@ -61,4 +57,55 @@ return this.document.uri; | ||
} | ||
applyEdit(version, change) { | ||
const content = this.getText(); | ||
let newContent = change.text; | ||
if (change.range) { | ||
const start = this.offsetAt(change.range.start); | ||
const end = this.offsetAt(change.range.end); | ||
newContent = content.substr(0, start) + change.text + content.substr(end); | ||
} | ||
this.document = lsp.TextDocument.create(this.uri, this.languageId, version, newContent); | ||
} | ||
} | ||
exports.LspDocument = LspDocument; | ||
class LspDocuments { | ||
constructor() { | ||
this._files = []; | ||
this.documents = new Map(); | ||
} | ||
/** | ||
* Sorted by last access. | ||
*/ | ||
get files() { | ||
return this._files; | ||
} | ||
get(file) { | ||
const document = this.documents.get(file); | ||
if (!document) { | ||
return undefined; | ||
} | ||
if (this.files[0] !== file) { | ||
this._files.splice(this._files.indexOf(file), 1); | ||
this._files.unshift(file); | ||
} | ||
return document; | ||
} | ||
open(file, doc) { | ||
if (this.documents.has(file)) { | ||
return false; | ||
} | ||
this.documents.set(file, new LspDocument(doc)); | ||
this._files.unshift(file); | ||
return true; | ||
} | ||
close(file) { | ||
const document = this.documents.get(file); | ||
if (!document) { | ||
return undefined; | ||
} | ||
this.documents.delete(file); | ||
this._files.splice(this._files.indexOf(file), 1); | ||
return document; | ||
} | ||
} | ||
exports.LspDocuments = LspDocuments; | ||
//# sourceMappingURL=document.js.map |
@@ -0,1 +1,2 @@ | ||
/// <reference types="p-debounce" /> | ||
import * as lsp from 'vscode-languageserver'; | ||
@@ -20,5 +21,5 @@ import * as tsp from 'typescript/lib/protocol'; | ||
private tspClient; | ||
private openedDocumentUris; | ||
private diagnosticQueue; | ||
private logger; | ||
private readonly documents; | ||
constructor(options: IServerOptions); | ||
@@ -28,9 +29,15 @@ closeAll(): void; | ||
initialize(params: TypeScriptInitializeParams): Promise<TypeScriptInitializeResult>; | ||
protected getLogFile(logVerbosity: string | undefined): string | undefined; | ||
protected doGetLogFile(): string | undefined; | ||
protected diagnosticsTokenSource: lsp.CancellationTokenSource | undefined; | ||
protected interuptDiagnostics<R>(f: () => R): R; | ||
requestDiagnostics(): Promise<tsp.RequestCompletedEvent>; | ||
readonly requestDiagnostics: (() => Promise<tsp.RequestCompletedEvent>) & { | ||
abort(): void; | ||
}; | ||
protected doRequestDiagnostics(): Promise<tsp.RequestCompletedEvent>; | ||
protected cancelDiagnostics(): void; | ||
didOpenTextDocument(params: lsp.DidOpenTextDocumentParams): void; | ||
protected getScriptKindName(languageId: string): tsp.ScriptKindName | undefined; | ||
didCloseTextDocument(params: lsp.DidOpenTextDocumentParams): void; | ||
didCloseTextDocument(params: lsp.DidCloseTextDocumentParams): void; | ||
protected closeDocument(file: string): void; | ||
didChangeTextDocument(params: lsp.DidChangeTextDocumentParams): void; | ||
@@ -37,0 +44,0 @@ didSaveTextDocument(params: lsp.DidChangeTextDocumentParams): void; |
@@ -17,2 +17,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const path = require("path"); | ||
const tempy = require("tempy"); | ||
@@ -22,2 +23,3 @@ const lsp = require("vscode-languageserver"); | ||
const commandExists = require("command-exists"); | ||
const debounce = require("p-debounce"); | ||
const logger_1 = require("./logger"); | ||
@@ -40,3 +42,4 @@ const tsp_client_1 = require("./tsp-client"); | ||
this.options = options; | ||
this.openedDocumentUris = new Map(); | ||
this.documents = new document_1.LspDocuments(); | ||
this.requestDiagnostics = debounce(() => this.doRequestDiagnostics(), 200); | ||
this.logger = new logger_1.PrefixingLogger(options.logger, '[lspserver]'); | ||
@@ -46,11 +49,4 @@ this.diagnosticQueue = new diagnostic_queue_1.DiagnosticEventQueue(diagnostics => this.options.lspClient.publishDiagnostics(diagnostics), this.logger); | ||
closeAll() { | ||
for (const [uri, doc] of this.openedDocumentUris) { | ||
this.didCloseTextDocument({ | ||
textDocument: { | ||
uri, | ||
languageId: doc.languageId, | ||
version: doc.version, | ||
text: doc.getText() | ||
} | ||
}); | ||
for (const file of [...this.documents.files]) { | ||
this.closeDocument(file); | ||
} | ||
@@ -82,4 +78,10 @@ } | ||
this.initializeParams = params; | ||
const { logVerbosity } = Object.assign({ logVerbosity: this.options.tsserverLogVerbosity }, this.initializeParams.initializationOptions); | ||
const logFile = logVerbosity !== undefined ? this.options.tsserverLogFile || tempy.file({ name: 'tsserver.log' }) : undefined; | ||
const { logVerbosity, plugins } = Object.assign({ logVerbosity: this.options.tsserverLogVerbosity, plugins: [] }, this.initializeParams.initializationOptions); | ||
const logFile = this.getLogFile(logVerbosity); | ||
const globalPlugins = []; | ||
const pluginProbeLocations = []; | ||
for (const plugin of plugins) { | ||
globalPlugins.push(plugin.name); | ||
pluginProbeLocations.push(plugin.location); | ||
} | ||
const tsserverPath = this.findTsserverPath(); | ||
@@ -90,2 +92,4 @@ this.tspClient = new tsp_client_1.TspClient({ | ||
logVerbosity, | ||
globalPlugins, | ||
pluginProbeLocations, | ||
logger: this.options.logger, | ||
@@ -139,2 +143,28 @@ onEvent: this.onTsEvent.bind(this) | ||
} | ||
getLogFile(logVerbosity) { | ||
if (logVerbosity === undefined) { | ||
return undefined; | ||
} | ||
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) { | ||
return this.options.tsserverLogFile; | ||
} | ||
if (this.initializeParams.rootUri) { | ||
return path.join(protocol_translation_1.uriToPath(this.initializeParams.rootUri), '.log/tsserver.log'); | ||
} | ||
if (this.initializeParams.rootPath) { | ||
return path.join(this.initializeParams.rootPath, '.log/tsserver.log'); | ||
} | ||
return undefined; | ||
} | ||
interuptDiagnostics(f) { | ||
@@ -149,3 +179,3 @@ if (!this.diagnosticsTokenSource) { | ||
} | ||
requestDiagnostics() { | ||
doRequestDiagnostics() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -155,14 +185,5 @@ this.cancelDiagnostics(); | ||
this.diagnosticsTokenSource = geterrTokenSource; | ||
const files = []; | ||
// sort by least recently usage | ||
const orderedUris = [...this.openedDocumentUris.entries()].sort((a, b) => a[1].lastAccessed - b[1].lastAccessed).map(e => e[0]); | ||
for (const uri of orderedUris) { | ||
files.push(protocol_translation_1.uriToPath(uri)); | ||
} | ||
const args = { | ||
delay: 0, | ||
files: files | ||
}; | ||
const { files } = this.documents; | ||
try { | ||
return yield this.tspClient.request("geterr" /* Geterr */, args, this.diagnosticsTokenSource.token); | ||
return yield this.tspClient.request("geterr" /* Geterr */, { delay: 0, files }, this.diagnosticsTokenSource.token); | ||
} | ||
@@ -188,3 +209,12 @@ finally { | ||
} | ||
if (this.openedDocumentUris.get(params.textDocument.uri) !== undefined) { | ||
if (this.documents.open(file, params.textDocument)) { | ||
this.tspClient.notify("open" /* Open */, { | ||
file, | ||
fileContent: params.textDocument.text, | ||
scriptKindName: this.getScriptKindName(params.textDocument.languageId), | ||
projectRootPath: this.rootPath() | ||
}); | ||
this.requestDiagnostics(); | ||
} | ||
else { | ||
this.logger.log(`Cannot open already opened doc '${params.textDocument.uri}'.`); | ||
@@ -200,12 +230,2 @@ this.didChangeTextDocument({ | ||
} | ||
else { | ||
this.tspClient.notify("open" /* Open */, { | ||
file, | ||
fileContent: params.textDocument.text, | ||
scriptKindName: this.getScriptKindName(params.textDocument.languageId), | ||
projectRootPath: this.rootPath() | ||
}); | ||
this.openedDocumentUris.set(params.textDocument.uri, new document_1.LspDocument(params.textDocument)); | ||
this.requestDiagnostics(); | ||
} | ||
} | ||
@@ -227,8 +247,14 @@ getScriptKindName(languageId) { | ||
} | ||
this.closeDocument(file); | ||
} | ||
closeDocument(file) { | ||
const document = this.documents.close(file); | ||
if (!document) { | ||
return; | ||
} | ||
this.tspClient.notify("close" /* Close */, { file }); | ||
this.openedDocumentUris.delete(params.textDocument.uri); | ||
// We won't be updating diagnostics anymore for that file, so clear them | ||
// so we don't leave stale ones. | ||
this.options.lspClient.publishDiagnostics({ | ||
uri: params.textDocument.uri, | ||
uri: document.uri, | ||
diagnostics: [], | ||
@@ -238,3 +264,4 @@ }); | ||
didChangeTextDocument(params) { | ||
const file = protocol_translation_1.uriToPath(params.textDocument.uri); | ||
const { textDocument } = params; | ||
const file = protocol_translation_1.uriToPath(textDocument.uri); | ||
this.logger.log('onDidChangeTextDocument', params, file); | ||
@@ -244,8 +271,10 @@ if (!file) { | ||
} | ||
const document = this.openedDocumentUris.get(params.textDocument.uri); | ||
const document = this.documents.get(file); | ||
if (!document) { | ||
this.logger.error("Received change on non-opened document " + params.textDocument.uri); | ||
throw new Error("Received change on non-opened document " + params.textDocument.uri); | ||
this.logger.error("Received change on non-opened document " + textDocument.uri); | ||
throw new Error("Received change on non-opened document " + textDocument.uri); | ||
} | ||
document.markAccessed(); | ||
if (textDocument.version === null) { | ||
throw new Error(`Received document change event for ${textDocument.uri} without valid version identifier`); | ||
} | ||
for (const change of params.contentChanges) { | ||
@@ -274,2 +303,3 @@ let line, offset, endLine, endOffset = 0; | ||
}); | ||
document.applyEdit(textDocument.version, change); | ||
} | ||
@@ -365,3 +395,3 @@ this.requestDiagnostics(); | ||
} | ||
const document = this.openedDocumentUris.get(params.textDocument.uri); | ||
const document = this.documents.get(file); | ||
if (!document) { | ||
@@ -723,6 +753,3 @@ throw new Error("The document should be opened for completion, file: " + file); | ||
lastFileOrDummy() { | ||
for (const uri of this.openedDocumentUris.keys()) { | ||
return protocol_translation_1.uriToPath(uri); | ||
} | ||
return this.rootPath(); | ||
return this.documents.files[0] || this.rootPath(); | ||
} | ||
@@ -763,3 +790,3 @@ workspaceSymbol(params) { | ||
} | ||
const document = this.openedDocumentUris.get(params.textDocument.uri); | ||
const document = this.documents.get(file); | ||
if (!document) { | ||
@@ -766,0 +793,0 @@ throw new Error("The document should be opened for foldingRanges', file: " + file); |
@@ -27,6 +27,7 @@ "use strict"; | ||
rootUri: null, | ||
publishDiagnostics: args => diagnostics = args | ||
publishDiagnostics: args => diagnostics.push(args) | ||
}); | ||
})); | ||
beforeEach(() => { | ||
diagnostics = []; | ||
server.closeAll(); | ||
@@ -66,3 +67,3 @@ }); | ||
const doc = { | ||
uri: test_utils_1.uri('bar.ts'), | ||
uri: test_utils_1.uri('diagnosticsBar.ts'), | ||
languageId: 'typescript', | ||
@@ -79,8 +80,43 @@ version: 1, | ||
}); | ||
server.requestDiagnostics(); | ||
yield server.requestDiagnostics(); | ||
yield new Promise(resolve => setTimeout(resolve, 200)); | ||
const diagnosticsForThisFile = diagnostics.filter(d => d.uri === doc.uri); | ||
assert.equal(diagnosticsForThisFile.length, 1, JSON.stringify(diagnostics)); | ||
const fileDiagnostics = diagnosticsForThisFile[0].diagnostics; | ||
assert.equal(fileDiagnostics.length, 1); | ||
assert.equal("Cannot find name 'unknown'.", fileDiagnostics[0].message); | ||
})).timeout(10000); | ||
it('multiple files test', () => __awaiter(this, void 0, void 0, function* () { | ||
const doc = { | ||
uri: test_utils_1.uri('multipleFileDiagnosticsBar.ts'), | ||
languageId: 'typescript', | ||
version: 1, | ||
text: ` | ||
export function bar(): void { | ||
unknown('test') | ||
} | ||
` | ||
}; | ||
const doc2 = { | ||
uri: test_utils_1.uri('multipleFileDiagnosticsFoo.ts'), | ||
languageId: 'typescript', | ||
version: 1, | ||
text: ` | ||
export function foo(): void { | ||
unknown('test') | ||
} | ||
` | ||
}; | ||
server.didOpenTextDocument({ | ||
textDocument: doc | ||
}); | ||
server.didOpenTextDocument({ | ||
textDocument: doc2 | ||
}); | ||
yield server.requestDiagnostics(); | ||
yield new Promise(resolve => setTimeout(resolve, 200)); | ||
const diags = diagnostics.diagnostics; | ||
assert.equal(1, diags.length); | ||
assert.equal("Cannot find name 'unknown'.", diags[0].message); | ||
const diagnosticsForThisTest = diagnostics.filter(d => d.uri === doc.uri || d.uri === doc2.uri); | ||
yield new Promise(resolve => setTimeout(resolve, 200)); | ||
assert.equal(diagnosticsForThisTest.length, 2, JSON.stringify(diagnostics)); | ||
})).timeout(10000); | ||
@@ -119,5 +155,12 @@ }); | ||
let result = '\n' + indentation + symbol.name; | ||
if (lsp.DocumentSymbol.is(symbol) && symbol.children) { | ||
result = result + symbolsAsString(symbol.children, indentation + ' '); | ||
if (lsp.DocumentSymbol.is(symbol)) { | ||
if (symbol.children) { | ||
result = result + symbolsAsString(symbol.children, indentation + ' '); | ||
} | ||
} | ||
else { | ||
if (symbol.containerName) { | ||
result = result + ` in ${symbol.containerName}`; | ||
} | ||
} | ||
return result; | ||
@@ -129,3 +172,3 @@ }).join(''); | ||
const doc = { | ||
uri: test_utils_1.uri('bar.ts'), | ||
uri: test_utils_1.uri('openAndChangeBar.ts'), | ||
languageId: 'typescript', | ||
@@ -156,5 +199,5 @@ version: 1, | ||
yield new Promise(resolve => setTimeout(resolve, 200)); | ||
const diags = diagnostics.diagnostics; | ||
assert.isTrue(diags.length >= 1, diags.map(d => d.message).join(',')); | ||
assert.equal("Cannot find name 'unknown'.", diags[0].message); | ||
const fileDiagnostics = diagnostics.filter(d => d.uri === doc.uri)[0].diagnostics; | ||
assert.isTrue(fileDiagnostics.length >= 1, fileDiagnostics.map(d => d.message).join(',')); | ||
assert.equal("Cannot find name 'unknown'.", fileDiagnostics[0].message); | ||
})).timeout(10000); | ||
@@ -161,0 +204,0 @@ }); |
@@ -8,7 +8,12 @@ /** | ||
} | ||
export interface TypeScriptPlugin { | ||
name: string; | ||
location: string; | ||
} | ||
export interface TypeScriptInitializationOptions { | ||
logVerbosity?: string; | ||
plugins: TypeScriptPlugin[]; | ||
} | ||
export declare type TypeScriptInitializeParams = lsp.InitializeParams & { | ||
initializationOptions?: TypeScriptInitializationOptions; | ||
initializationOptions?: Partial<TypeScriptInitializationOptions>; | ||
}; | ||
@@ -15,0 +20,0 @@ export interface TypeScriptInitializeResult extends lsp.InitializeResult { |
@@ -10,2 +10,4 @@ import * as protocol from 'typescript/lib/protocol'; | ||
logVerbosity?: string; | ||
globalPlugins?: string[]; | ||
pluginProbeLocations?: string[]; | ||
onEvent?: (event: protocol.Event) => void; | ||
@@ -51,5 +53,3 @@ } | ||
private seq; | ||
private buffer; | ||
private header; | ||
private deferreds; | ||
private readonly deferreds; | ||
private logger; | ||
@@ -56,0 +56,0 @@ private tsserverLogger; |
@@ -20,3 +20,2 @@ "use strict"; | ||
this.seq = 0; | ||
this.buffer = ''; | ||
this.deferreds = {}; | ||
@@ -30,15 +29,20 @@ this.logger = new logger_1.PrefixingLogger(options.logger, '[tsclient]'); | ||
} | ||
const { tsserverPath, logFile, logVerbosity, globalPlugins, pluginProbeLocations } = this.options; | ||
const args = []; | ||
if (this.options.logFile) { | ||
args.push('--logFile'); | ||
args.push(this.options.logFile); | ||
if (logFile) { | ||
args.push('--logFile', logFile); | ||
} | ||
if (this.options.logVerbosity) { | ||
args.push('--logVerbosity'); | ||
args.push(this.options.logVerbosity); | ||
if (logVerbosity) { | ||
args.push('--logVerbosity', logVerbosity); | ||
} | ||
if (globalPlugins && globalPlugins.length) { | ||
args.push('--globalPlugins', globalPlugins.join(',')); | ||
} | ||
if (pluginProbeLocations && pluginProbeLocations.length) { | ||
args.push('--pluginProbeLocations', pluginProbeLocations.join(',')); | ||
} | ||
this.cancellationPipeName = tempy.file({ name: 'tscancellation' }); | ||
args.push('--cancellationPipeName', this.cancellationPipeName + '*'); | ||
this.logger.info(`Starting tsserver : '${this.options.tsserverPath} ${args.join(' ')}'`); | ||
this.tsserverProc = cp.spawn(this.options.tsserverPath, args); | ||
this.logger.info(`Starting tsserver : '${tsserverPath} ${args.join(' ')}'`); | ||
this.tsserverProc = cp.spawn(tsserverPath, args); | ||
this.readlineInterface = readline.createInterface(this.tsserverProc.stdout, this.tsserverProc.stdin, undefined); | ||
@@ -45,0 +49,0 @@ process.on('exit', () => { |
{ | ||
"name": "typescript-language-server", | ||
"version": "0.4.0-dev.2ab20b1", | ||
"version": "0.4.0-dev.366aecb", | ||
"description": "Language Server Protocol (LSP) implementation for TypeScript using tsserver", | ||
@@ -21,3 +21,3 @@ "author": "TypeFox and others", | ||
"fs-extra": "^7.0.0", | ||
"lodash.debounce": "^4.0.8", | ||
"p-debounce": "^1.0.0", | ||
"tempy": "^0.2.1", | ||
@@ -35,6 +35,6 @@ "vscode-languageserver": "^4.4.0", | ||
"@types/fs-extra": "^5.0.4", | ||
"@types/lodash.debounce": "^4.0.4", | ||
"@types/p-debounce": "^1.0.0", | ||
"@types/tempy": "^0.1.0" | ||
}, | ||
"gitHead": "2ab20b115475b6d6dc82ce9fd7a3da947887b8be" | ||
"gitHead": "366aecbe32c080762955a61688bd2d9b607c8562" | ||
} |
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
256561
3347
6
+ Addedp-debounce@^1.0.0
+ Addedp-debounce@1.0.0(transitive)
- Removedlodash.debounce@^4.0.8
- Removedlodash.debounce@4.0.8(transitive)