diff --git a/Jakefile.js b/Jakefile.js index 1f88ee39082..997795fd4ee 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -105,6 +105,14 @@ var serverSources = [ return path.join(serverDirectory, f); }); +var languageServiceLibrarySources = [ + "editorServices.ts", + "protocol.d.ts", + "session.ts" +].map(function (f) { + return path.join(serverDirectory, f); +}).concat(servicesSources); + var harnessSources = [ "harness.ts", "sourceMapRecorder.ts", @@ -369,6 +377,20 @@ compileFile(servicesFile, servicesSources,[builtLocalDirectory, copyright].conca var serverFile = path.join(builtLocalDirectory, "tsserver.js"); compileFile(serverFile, serverSources,[builtLocalDirectory, copyright].concat(serverSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true); +var lsslFile = path.join(builtLocalDirectory, "tslssl.js"); +compileFile( + lsslFile, + languageServiceLibrarySources, + [builtLocalDirectory, copyright].concat(languageServiceLibrarySources), + /*prefixes*/ [copyright], + /*useBuiltCompiler*/ true, + /*noOutFile*/ false, + /*generateDeclarations*/ true); + +// Local target to build the language service server library +desc("Builds language service server library"); +task("lssl", [lsslFile]); + // Local target to build the compiler and services desc("Builds the full compiler and services"); task("local", ["generate-diagnostics", "lib", tscFile, servicesFile, nodeDefinitionsFile, serverFile]); diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 0e0b8d82918..8eb77817533 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -583,7 +583,7 @@ module Harness.LanguageService { // This host is just a proxy for the clientHost, it uses the client // host to answer server queries about files on disk var serverHost = new SessionServerHost(clientHost); - var server = new ts.server.Session(serverHost, serverHost); + var server = new ts.server.Session(serverHost, Buffer.byteLength, process.hrtime, serverHost); // Fake the connection between the client and the server serverHost.writeMessage = client.onMessage.bind(client); diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 0e5dc0d81e3..91d400ff263 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -2,7 +2,6 @@ /// /// /// -/// namespace ts.server { export interface Logger { @@ -28,7 +27,7 @@ namespace ts.server { }); } - class ScriptInfo { + export class ScriptInfo { svc: ScriptVersionCache; children: ScriptInfo[] = []; // files referenced by this file defaultProject: Project; // project to use by default for file @@ -36,7 +35,7 @@ namespace ts.server { formatCodeOptions = ts.clone(CompilerService.defaultFormatCodeOptions); constructor(private host: ServerHost, public fileName: string, public content: string, public isOpen = false) { - this.svc = ScriptVersionCache.fromString(content); + this.svc = ScriptVersionCache.fromString(host, content); } setFormatOptions(formatOptions: protocol.FormatOptions): void { @@ -80,7 +79,7 @@ namespace ts.server { } } - class LSHost implements ts.LanguageServiceHost { + export class LSHost implements ts.LanguageServiceHost { ls: ts.LanguageService = null; compilationSettings: ts.CompilerOptions; filenameToScript: ts.Map = {}; @@ -273,7 +272,7 @@ namespace ts.server { } } - interface ProjectOptions { + export interface ProjectOptions { // these fields can be present in the project file files?: string[]; compilerOptions?: ts.CompilerOptions; @@ -376,7 +375,7 @@ namespace ts.server { } } - interface ProjectOpenResult { + export interface ProjectOpenResult { success?: boolean; errorMsg?: string; project?: Project; @@ -392,11 +391,11 @@ namespace ts.server { return copiedList; } - interface ProjectServiceEventHandler { + export interface ProjectServiceEventHandler { (eventName: string, project: Project, fileName: string): void; } - interface HostConfiguration { + export interface HostConfiguration { formatCodeOptions: ts.FormatCodeOptions; hostInfo: string; } @@ -916,7 +915,7 @@ namespace ts.server { return rawConfig.error; } else { - var parsedCommandLine = ts.parseConfigFile(rawConfig.config, ts.sys, dirPath); + var parsedCommandLine = ts.parseConfigFile(rawConfig.config, this.host, dirPath); if (parsedCommandLine.errors && (parsedCommandLine.errors.length > 0)) { return { errorMsg: "tsconfig option errors" }; } @@ -953,7 +952,7 @@ namespace ts.server { } - class CompilerService { + export class CompilerService { host: LSHost; languageService: ts.LanguageService; classifier: ts.Classifier; @@ -985,7 +984,7 @@ namespace ts.server { static defaultFormatCodeOptions: ts.FormatCodeOptions = { IndentSize: 4, TabSize: 4, - NewLineCharacter: ts.sys.newLine, + NewLineCharacter: ts.sys ? ts.sys.newLine : '\n', ConvertTabsToSpaces: true, InsertSpaceAfterCommaDelimiter: true, InsertSpaceAfterSemicolonInForStatements: true, @@ -999,7 +998,7 @@ namespace ts.server { } - interface LineCollection { + export interface LineCollection { charCount(): number; lineCount(): number; isLeaf(): boolean; @@ -1013,7 +1012,7 @@ namespace ts.server { leaf?: LineLeaf; } - enum CharRangeSection { + export enum CharRangeSection { PreStart, Start, Entire, @@ -1022,7 +1021,7 @@ namespace ts.server { PostEnd } - interface ILineIndexWalker { + export interface ILineIndexWalker { goSubtree: boolean; done: boolean; leaf(relativeStart: number, relativeLength: number, lineCollection: LineLeaf): void; @@ -1248,7 +1247,7 @@ namespace ts.server { } // text change information - class TextChange { + export class TextChange { constructor(public pos: number, public deleteLen: number, public insertedText?: string) { } @@ -1263,6 +1262,7 @@ namespace ts.server { versions: LineIndexSnapshot[] = []; minVersion = 0; // no versions earlier than min version will maintain change history private currentVersion = 0; + private host: ServerHost; static changeNumberThreshold = 8; static changeLengthThreshold = 256; @@ -1290,7 +1290,7 @@ namespace ts.server { } reloadFromFile(filename: string, cb?: () => any) { - var content = ts.sys.readFile(filename); + var content = this.host.readFile(filename); this.reload(content); if (cb) cb(); @@ -1360,10 +1360,11 @@ namespace ts.server { } } - static fromString(script: string) { + static fromString(host: ServerHost, script: string) { var svc = new ScriptVersionCache(); var snap = new LineIndexSnapshot(0, svc); svc.versions[svc.currentVersion] = snap; + svc.host = host; snap.index = new LineIndex(); var lm = LineIndex.linesFromText(script); snap.index.load(lm.lines); @@ -1371,7 +1372,7 @@ namespace ts.server { } } - class LineIndexSnapshot implements ts.IScriptSnapshot { + export class LineIndexSnapshot implements ts.IScriptSnapshot { index: LineIndex; changesSincePreviousVersion: TextChange[] = []; @@ -1605,7 +1606,7 @@ namespace ts.server { } } - class LineNode implements LineCollection { + export class LineNode implements LineCollection { totalChars = 0; totalLines = 0; children: LineCollection[] = []; @@ -1891,7 +1892,7 @@ namespace ts.server { } } - class LineLeaf implements LineCollection { + export class LineLeaf implements LineCollection { udata: any; constructor(public text: string) { diff --git a/src/server/server.ts b/src/server/server.ts index 735a438ff98..843197b918a 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -11,7 +11,7 @@ namespace ts.server { input: process.stdin, output: process.stdout, terminal: false, - }); + }); class Logger implements ts.server.Logger { fd = -1; @@ -170,11 +170,11 @@ namespace ts.server { removeFile(file: WatchedFile) { this.watchedFiles = WatchedFileSet.copyListRemovingItem(file, this.watchedFiles); } - } + } class IOSession extends Session { constructor(host: ServerHost, logger: ts.server.Logger) { - super(host, logger); + super(host, Buffer.byteLength, process.hrtime, logger); } exit() { diff --git a/src/server/session.ts b/src/server/session.ts index dc88a8528a2..c95b1a7cc1b 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1,6 +1,5 @@ /// /// -/// /// /// @@ -61,7 +60,7 @@ namespace ts.server { }; } - interface PendingErrorCheck { + export interface PendingErrorCheck { fileName: string; project: Project; } @@ -114,11 +113,16 @@ namespace ts.server { pendingOperation = false; fileHash: ts.Map = {}; nextFileId = 1; - errorTimer: NodeJS.Timer; + errorTimer: any; /*NodeJS.Timer | number*/ immediateId: any; changeSeq = 0; - constructor(private host: ServerHost, private logger: Logger) { + constructor( + private host: ServerHost, + private byteLength: (buf: string, encoding?: string) => number, + private hrtime: (start?: number[]) => number[], + private logger: Logger + ) { this.projectService = new ProjectService(host, logger, (eventName,project,fileName) => { this.handleEvent(eventName, project, fileName); @@ -149,17 +153,17 @@ namespace ts.server { this.host.write(line + this.host.newLine); } - send(msg: NodeJS._debugger.Message) { + send(msg: protocol.Message) { var json = JSON.stringify(msg); if (this.logger.isVerbose()) { this.logger.info(msg.type + ": " + json); } - this.sendLineToClient('Content-Length: ' + (1 + Buffer.byteLength(json, 'utf8')) + + this.sendLineToClient('Content-Length: ' + (1 + this.byteLength(json, 'utf8')) + '\r\n\r\n' + json); } event(info: any, eventName: string) { - var ev: NodeJS._debugger.Event = { + var ev: protocol.Event = { seq: 0, type: "event", event: eventName, @@ -838,7 +842,7 @@ namespace ts.server { onMessage(message: string) { if (this.logger.isVerbose()) { this.logger.info("request: " + message); - var start = process.hrtime(); + var start = this.hrtime(); } try { var request = JSON.parse(message); @@ -980,7 +984,7 @@ namespace ts.server { } if (this.logger.isVerbose()) { - var elapsed = process.hrtime(start); + var elapsed = this.hrtime(start); var seconds = elapsed[0] var nanoseconds = elapsed[1]; var elapsedMs = ((1e9 * seconds) + nanoseconds)/1000000.0; diff --git a/tests/cases/unittests/versionCache.ts b/tests/cases/unittests/versionCache.ts index 12cf9c1b817..06c2cadbfe9 100644 --- a/tests/cases/unittests/versionCache.ts +++ b/tests/cases/unittests/versionCache.ts @@ -231,7 +231,7 @@ and grew 1cm per day`; }); it("Edit ScriptVersionCache ", () => { - let svc = server.ScriptVersionCache.fromString(testContent); + let svc = server.ScriptVersionCache.fromString(ts.sys, testContent); let checkText = testContent; for (let i = 0; i < iterationCount; i++) {