Recover from git corruption
This commit is contained in:
parent
99373dbd89
commit
a0b557e1e2
|
@ -128,7 +128,9 @@ module Harness.LanguageService {
|
|||
protected settings = ts.getDefaultCompilerOptions()) {
|
||||
}
|
||||
|
||||
public getNewLine(): string {
return "\r\n";
}
|
||||
public getNewLine(): string {
|
||||
return "\r\n";
|
||||
}
|
||||
|
||||
public getFilenames(): string[] {
|
||||
var fileNames: string[] = [];
|
||||
|
@ -435,17 +437,26 @@ module Harness.LanguageService {
|
|||
}
|
||||
|
||||
// Server adapter
|
||||
class ServerLanguageServiceHost extends NativeLanguageServiceHost {
|
||||
class SessionClientHost extends NativeLanguageServiceHost implements ts.server.SessionClientHost {
|
||||
private client: ts.server.SessionClient;
|
||||
|
||||
constructor(cancellationToken: ts.CancellationToken, settings: ts.CompilerOptions) {
|
||||
super(cancellationToken, settings);
|
||||
}
|
||||
|
||||
setClient(client: ts.server.SessionClient) {
|
||||
onMessage(message: string): void {
|
||||
|
||||
}
|
||||
|
||||
writeMessage(message: string): void {
|
||||
|
||||
}
|
||||
|
||||
setClient(client: ts.server.SessionClient) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
openFile(fileName: string): void {
|
||||
openFile(fileName: string): void {
|
||||
super.openFile(fileName);
|
||||
this.client.openFile(fileName);
|
||||
}
|
||||
|
@ -456,15 +467,135 @@ module Harness.LanguageService {
|
|||
}
|
||||
}
|
||||
|
||||
class SessionServerHost implements ts.server.ServerHost, ts.server.Logger {
|
||||
args: string[] = [];
|
||||
newLine: string;
|
||||
useCaseSensitiveFileNames: boolean = false;
|
||||
|
||||
constructor(private host: NativeLanguageServiceHost) {
|
||||
this.newLine = this.host.getNewLine();
|
||||
}
|
||||
|
||||
onMessage(message: string): void {
|
||||
|
||||
}
|
||||
|
||||
writeMessage(message: string): void {
|
||||
}
|
||||
|
||||
write(message: string): void {
|
||||
this.writeMessage(message);
|
||||
}
|
||||
|
||||
readFile(fileName: string): string {
|
||||
var snapshot = this.host.getScriptSnapshot(fileName);
|
||||
return snapshot && snapshot.getText(0, snapshot.getLength());
|
||||
}
|
||||
|
||||
writeFile(name: string, text: string, writeByteOrderMark: boolean): void {
|
||||
}
|
||||
|
||||
resolvePath(path: string): string {
|
||||
return path;
|
||||
}
|
||||
|
||||
fileExists(path: string): boolean {
|
||||
return !!this.host.getScriptSnapshot(path);
|
||||
}
|
||||
|
||||
directoryExists(path: string): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
getExecutingFilePath(): string {
|
||||
return "";
|
||||
}
|
||||
|
||||
exit(exitCode: number): void {
|
||||
}
|
||||
|
||||
createDirectory(directoryName: string): void {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
}
|
||||
|
||||
getCurrentDirectory(): string {
|
||||
return this.host.getCurrentDirectory();
|
||||
}
|
||||
|
||||
readDirectory(path: string, extension?: string): string[] {
|
||||
throw new Error("Not implemented Yet.");
|
||||
}
|
||||
|
||||
getModififedTime(fileName: string): Date {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
stat(path: string, callback?: (err: any, stats: any) => any) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
lineColToPosition(fileName: string, line: number, col: number): number {
|
||||
return this.host.lineColToPosition(fileName, line, col);
|
||||
}
|
||||
|
||||
positionToZeroBasedLineCol(fileName: string, position: number): ts.LineAndCharacter {
|
||||
return this.host.positionToZeroBasedLineCol(fileName, position);
|
||||
}
|
||||
|
||||
getFileLength(fileName: string): number {
|
||||
return this.host.getScriptSnapshot(fileName).getLength();
|
||||
}
|
||||
|
||||
getFileNames(): string[] {
|
||||
return this.host.getScriptFileNames();
|
||||
}
|
||||
|
||||
close(): void {
|
||||
}
|
||||
|
||||
info(message: string): void {
|
||||
return this.host.log(message);
|
||||
}
|
||||
|
||||
msg(message: string) {
|
||||
return this.host.log(message);
|
||||
}
|
||||
|
||||
endGroup(): void {
|
||||
}
|
||||
|
||||
perftrc(message: string): void {
|
||||
return this.host.log(message);
|
||||
}
|
||||
|
||||
startGroup(): void {
|
||||
}
|
||||
}
|
||||
|
||||
export class ServerLanugageServiceAdapter implements LanguageServiceAdapter {
|
||||
private host: ServerLanguageServiceHost;
|
||||
private host: SessionClientHost;
|
||||
private client: ts.server.SessionClient;
|
||||
constructor(cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions) {
|
||||
debugger;
|
||||
// This is the main host that tests use to direct tests
|
||||
var clientHost = new SessionClientHost(cancellationToken, options);
|
||||
var client = new ts.server.SessionClient(clientHost);
|
||||
|
||||
this.host = new ServerLanguageServiceHost(cancellationToken, options);
|
||||
this.client = new ts.server.SessionClient(this.host, /*abbreviate*/ true);
|
||||
this.host.setClient(this.client);
|
||||
// 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, /*useProtocol*/ true, /*prettyJSON*/ false);
|
||||
|
||||
// Fake the connection between the client and the server
|
||||
serverHost.writeMessage = client.onMessage.bind(client);
|
||||
clientHost.writeMessage = server.onMessage.bind(server);
|
||||
|
||||
// Wire the client to the host to get notifications when a file is open
|
||||
// or edited.
|
||||
clientHost.setClient(client);
|
||||
|
||||
// Set the properties
|
||||
this.client = client;
|
||||
this.host = clientHost;
|
||||
}
|
||||
getHost() { return this.host; }
|
||||
getLanguageService(): ts.LanguageService { return this.client; }
|
||||
|
|
|
@ -1,177 +1,49 @@
|
|||
/// <reference path="protocol.ts" />
|
||||
|
||||
module ts.server {
|
||||
|
||||
export interface SessionClientHost extends LanguageServiceHost {
|
||||
lineColToPosition(fileName: string, line: number, col: number): number;
|
||||
positionToZeroBasedLineCol(fileName: string, position: number): ts.LineAndCharacter;
|
||||
}
|
||||
|
||||
class SessionClientHostProxy implements ServerHost, Logger {
|
||||
args: string[] = [];
|
||||
newLine: string;
|
||||
useCaseSensitiveFileNames: boolean = false;
|
||||
lastReply: string;
|
||||
|
||||
constructor(private host: SessionClientHost) {
|
||||
this.newLine = this.host.getNewLine();
|
||||
}
|
||||
/// <reference path="protocol.ts" />
|
||||
|
||||
write(message: string): void {
|
||||
this.lastReply = message;
|
||||
}
|
||||
module ts.server {
|
||||
|
||||
readFile(fileName: string): string {
|
||||
var snapshot = this.host.getScriptSnapshot(fileName);
|
||||
return snapshot && snapshot.getText(0, snapshot.getLength());
|
||||
}
|
||||
|
||||
writeFile(name: string, text:string, writeByteOrderMark: boolean): void {
|
||||
}
|
||||
|
||||
resolvePath(path: string): string {
|
||||
return path;
|
||||
}
|
||||
|
||||
fileExists(path: string): boolean {
|
||||
return !!this.host.getScriptSnapshot(path);
|
||||
}
|
||||
|
||||
directoryExists(path: string): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
getExecutingFilePath(): string {
|
||||
return "";
|
||||
}
|
||||
|
||||
exit(exitCode: number): void {
|
||||
}
|
||||
|
||||
createDirectory(directoryName: string): void {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
}
|
||||
|
||||
getCurrentDirectory(): string {
|
||||
return this.host.getCurrentDirectory();
|
||||
}
|
||||
|
||||
readDirectory(path: string, extension?: string): string[] {
|
||||
throw new Error("Not implemented Yet.");
|
||||
}
|
||||
|
||||
getModififedTime(fileName: string): Date {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
stat(path: string, callback?: (err: any, stats: any) => any) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
lineColToPosition(fileName: string, line: number, col: number): number {
|
||||
return this.host.lineColToPosition(fileName, line, col);
|
||||
}
|
||||
|
||||
positionToZeroBasedLineCol(fileName: string, position: number): ts.LineAndCharacter {
|
||||
return this.host.positionToZeroBasedLineCol(fileName, position);
|
||||
}
|
||||
|
||||
getFileLength(fileName: string): number {
|
||||
return this.host.getScriptSnapshot(fileName).getLength();
|
||||
}
|
||||
|
||||
getFileNames(): string[] {
|
||||
return this.host.getScriptFileNames();
|
||||
}
|
||||
|
||||
close(): void {
|
||||
}
|
||||
|
||||
info(message: string): void {
|
||||
return this.host.log(message);
|
||||
}
|
||||
|
||||
msg(message: string) {
|
||||
return this.host.log(message);
|
||||
}
|
||||
|
||||
endGroup(): void {
|
||||
}
|
||||
|
||||
perftrc(message: string): void {
|
||||
return this.host.log(message);
|
||||
}
|
||||
|
||||
startGroup(): void {
|
||||
}
|
||||
export interface SessionClientHost extends LanguageServiceHost {
|
||||
writeMessage(message: string): void;
|
||||
}
|
||||
|
||||
export class SessionClient implements LanguageService {
|
||||
private session: Session;
|
||||
private sequence: number = 0;
|
||||
private host: SessionClientHostProxy;
|
||||
private expantionTable: ts.Map<string>;
|
||||
private fileMapping: ts.Map<string> = {};
|
||||
|
||||
constructor(host: SessionClientHost, abbreviate: boolean) {
|
||||
this.sequence = 0;
|
||||
this.host = new SessionClientHostProxy(host);
|
||||
this.session = new Session(this.host, this.host, /* useProtocol */ true, /*prettyJSON*/ false);
|
||||
|
||||
// Setup the abbreviation table
|
||||
if (abbreviate) {
|
||||
this.setupExpantionTable()
|
||||
}
|
||||
}
|
||||
|
||||
private setupExpantionTable(): void {
|
||||
var request = this.processRequest<ServerProtocol.AbbrevRequest>(CommandNames.Abbrev);
|
||||
var response = this.processResponse<ServerProtocol.AbbrevResponse>(request);
|
||||
var abbriviationTable = response.body;
|
||||
|
||||
Debug.assert(!!abbriviationTable, "Could not setup abbreviation. Abbreviation table was empty.");
|
||||
|
||||
var expantionTable: ts.Map<string> = {};
|
||||
for (var p in abbriviationTable) {
|
||||
if (abbriviationTable.hasOwnProperty(p)) {
|
||||
expantionTable[abbriviationTable[p]] = p;
|
||||
}
|
||||
}
|
||||
this.expantionTable = expantionTable;
|
||||
}
|
||||
|
||||
private expand<T>(obj: T): T {
|
||||
for (var p in obj) {
|
||||
if (obj.hasOwnProperty(p)) {
|
||||
if (typeof (<any>obj)[p] === "object") {
|
||||
// Expand the property value
|
||||
(<any>obj)[p] = this.expand((<any>obj)[p]);
|
||||
}
|
||||
|
||||
// Substitute the name if applicaple
|
||||
var substitution = ts.lookUp(this.expantionTable, p);
|
||||
if (substitution) {
|
||||
(<any>obj)[substitution] = (<any>obj)[p];
|
||||
(<any>obj)[p] = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
private lineColToPosition(fileName: string, lineCol: ServerProtocol.LineCol): number {
|
||||
return this.host.lineColToPosition(fileName, lineCol.line, lineCol.col);
|
||||
export class SessionClient implements LanguageService {
|
||||
private sequence: number = 0;
|
||||
private fileMapping: ts.Map<string> = {};
|
||||
private lineMaps: ts.Map<number[]> = {};
|
||||
private messages: string[] = [];
|
||||
|
||||
constructor(private host: SessionClientHost) {
|
||||
}
|
||||
|
||||
private positionToOneBasedLineCol(fileName: string, position: number): ServerProtocol.LineCol {
|
||||
var lineCol = this.host.positionToZeroBasedLineCol(fileName, position);
|
||||
public onMessage(message: string): void {
|
||||
this.messages.push(message);
|
||||
}
|
||||
|
||||
private writeMessage(message: string): void {
|
||||
this.host.writeMessage(message);
|
||||
}
|
||||
|
||||
private getLineMap(fileName: string): number[] {
|
||||
var lineMap = ts.lookUp(this.lineMaps, fileName);
|
||||
if (!lineMap) {
|
||||
var scriptSnapshot = this.host.getScriptSnapshot(fileName);
|
||||
lineMap = this.lineMaps[fileName] = ts.computeLineStarts(scriptSnapshot.getText(0, scriptSnapshot.getLength()));
|
||||
}
|
||||
return lineMap;
|
||||
}
|
||||
|
||||
private lineColToPosition(fileName: string, lineCol: ServerProtocol.LineCol): number {
|
||||
return ts.computePositionFromLineAndCharacter(this.getLineMap(fileName), lineCol.line, lineCol.col);
|
||||
}
|
||||
|
||||
private positionToOneBasedLineCol(fileName: string, position: number): ServerProtocol.LineCol {
|
||||
var lineCol = ts.computeLineAndCharacterOfPosition(this.getLineMap(fileName), position);
|
||||
return {
|
||||
line: lineCol.line + 1,
|
||||
col: lineCol.character + 1
|
||||
line: lineCol.line,
|
||||
col: lineCol.character
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private convertCodeEditsToTextChange(fileName: string, codeEdit: ServerProtocol.CodeEdit): ts.TextChange {
|
||||
var start = this.lineColToPosition(fileName, codeEdit.start);
|
||||
var end = this.lineColToPosition(fileName, codeEdit.end);
|
||||
|
@ -180,8 +52,8 @@ module ts.server {
|
|||
span: ts.createTextSpanFromBounds(start, end),
|
||||
newText: codeEdit.newText
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private getFileNameFromEncodedFile(fileId: ServerProtocol.EncodedFile): string {
|
||||
var fileName: string;
|
||||
if (typeof fileId === "object") {
|
||||
|
@ -196,9 +68,9 @@ module ts.server {
|
|||
Debug.fail("Got unexpedted fileId type.");
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
private processRequest<T extends ServerProtocol.Request>(command: string, arguments?: any): T {
|
||||
}
|
||||
|
||||
private processRequest<T extends ServerProtocol.Request>(command: string, arguments?: any): T {
|
||||
var request: ServerProtocol.Request = {
|
||||
seq: this.sequence++,
|
||||
type: "request",
|
||||
|
@ -206,34 +78,33 @@ module ts.server {
|
|||
arguments: arguments
|
||||
};
|
||||
|
||||
this.session.executeJSONcmd(JSON.stringify(request));
|
||||
|
||||
return <T>request;
|
||||
}
|
||||
|
||||
private processResponse<T extends ServerProtocol.Response>(request: ServerProtocol.Request): T {
|
||||
debugger;
|
||||
|
||||
var lastMessage = this.host.lastReply;
|
||||
this.host.lastReply = undefined;
|
||||
Debug.assert(!!lastMessage, "Did not recieve any responses.");
|
||||
|
||||
// Read the content length
|
||||
var contentLengthPrefix = "Content-Length: ";
|
||||
var lines = lastMessage.split("\r\n");
|
||||
Debug.assert(lines.length >= 2, "Malformed response: Expected 3 lines in the response.");
|
||||
|
||||
var contentLengthText = lines[0];
|
||||
Debug.assert(contentLengthText.indexOf(contentLengthPrefix) === 0, "Malformed response: Response text did not contain content-length header.");
|
||||
var contentLength = parseInt(contentLengthText.substring(contentLengthPrefix.length));
|
||||
|
||||
// Read the body
|
||||
var responseBody = lines[2];
|
||||
|
||||
// Verify content length
|
||||
Debug.assert(responseBody.length + 1 === contentLength, "Malformed response: Content length did not match the response's body length.");
|
||||
|
||||
try {
|
||||
this.writeMessage(JSON.stringify(request));
|
||||
|
||||
return <T>request;
|
||||
}
|
||||
|
||||
private processResponse<T extends ServerProtocol.Response>(request: ServerProtocol.Request): T {
|
||||
debugger;
|
||||
|
||||
var lastMessage = this.messages.shift();
|
||||
Debug.assert(!!lastMessage, "Did not recieve any responses.");
|
||||
|
||||
// Read the content length
|
||||
var contentLengthPrefix = "Content-Length: ";
|
||||
var lines = lastMessage.split("\r\n");
|
||||
Debug.assert(lines.length >= 2, "Malformed response: Expected 3 lines in the response.");
|
||||
|
||||
var contentLengthText = lines[0];
|
||||
Debug.assert(contentLengthText.indexOf(contentLengthPrefix) === 0, "Malformed response: Response text did not contain content-length header.");
|
||||
var contentLength = parseInt(contentLengthText.substring(contentLengthPrefix.length));
|
||||
|
||||
// Read the body
|
||||
var responseBody = lines[2];
|
||||
|
||||
// Verify content length
|
||||
Debug.assert(responseBody.length + 1 === contentLength, "Malformed response: Content length did not match the response's body length.");
|
||||
|
||||
try {
|
||||
var response: T = JSON.parse(responseBody);
|
||||
}
|
||||
catch (e) {
|
||||
|
@ -250,13 +121,9 @@ module ts.server {
|
|||
|
||||
Debug.assert(!!response.body, "Malformed response: Unexpected empty response body.");
|
||||
|
||||
if (this.expantionTable) {
|
||||
// Expand the response if abbreviated
|
||||
return this.expand(response);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
openFile(fileName: string): void {
|
||||
var args: ServerProtocol.FileRequestArgs = { file: fileName };
|
||||
this.processRequest(CommandNames.Open, args);
|
||||
|
@ -268,6 +135,9 @@ module ts.server {
|
|||
}
|
||||
|
||||
changeFile(fileName: string, start: number, end: number, newText: string): void {
|
||||
// clear the line map after an edit
|
||||
this.lineMaps[fileName] = undefined;
|
||||
|
||||
var lineCol = this.positionToOneBasedLineCol(fileName, start);
|
||||
var args: ServerProtocol.ChangeRequestArgs = {
|
||||
file: fileName,
|
||||
|
@ -326,7 +196,7 @@ module ts.server {
|
|||
getNavigateToItems(searchTerm: string): NavigateToItem[] {
|
||||
var args: ServerProtocol.NavtoRequestArgs = {
|
||||
searchTerm,
|
||||
file: this.host.getFileNames()[0]
|
||||
file: this.host.getScriptFileNames()[0]
|
||||
};
|
||||
|
||||
var request = this.processRequest<ServerProtocol.NavtoRequest>(CommandNames.Navto, args);
|
||||
|
@ -357,7 +227,7 @@ module ts.server {
|
|||
file: fileName,
|
||||
line: startLineCol.line,
|
||||
col: startLineCol.col,
|
||||
endLine: endLineCol.line,
|
||||
endLine: endLineCol.line,
|
||||
endCol: endLineCol.col,
|
||||
};
|
||||
|
||||
|
@ -369,7 +239,7 @@ module ts.server {
|
|||
}
|
||||
|
||||
getFormattingEditsForDocument(fileName: string, options: ts.FormatCodeOptions): ts.TextChange[] {
|
||||
return this.getFormattingEditsForRange(fileName, 0, this.host.getFileLength(fileName), options);
|
||||
return this.getFormattingEditsForRange(fileName, 0, this.host.getScriptSnapshot(fileName).getLength(), options);
|
||||
}
|
||||
|
||||
getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions): ts.TextChange[] {
|
||||
|
@ -537,7 +407,7 @@ module ts.server {
|
|||
}
|
||||
|
||||
dispose(): void {
|
||||
throw new Error("dispose is not available through the server layer.");
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Error("dispose is not available through the server layer.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -425,7 +425,8 @@ module ts.server {
|
|||
if (projectOptions.compilerOptions) {
|
||||
this.compilerService.setCompilerOptions(projectOptions.compilerOptions);
|
||||
}
|
||||
// TODO: format code options
}
|
||||
// TODO: format code options
|
||||
}
|
||||
}
|
||||
|
||||
export interface ProjectOpenResult {
|
||||
|
|
File diff suppressed because it is too large
Load diff
56
src/server/protodef.d.ts
vendored
56
src/server/protodef.d.ts
vendored
|
@ -188,18 +188,6 @@ declare module ServerProtocol {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Type request; value of command field is "type". Return response
|
||||
giving the code locations that define the type of the symbol
|
||||
found in file at location line, col.
|
||||
*/
|
||||
export interface TypeRequest extends CodeLocationRequest {
|
||||
}
|
||||
|
||||
export interface TypeResponse extends Response {
|
||||
body?: CodeSpan[];
|
||||
}
|
||||
|
||||
/**
|
||||
Open request; value of command field is "open". Notify the
|
||||
server that the client has file open. The server will not
|
||||
|
@ -483,8 +471,8 @@ declare module ServerProtocol {
|
|||
kindModifiers?: string;
|
||||
/**
|
||||
The file in which the symbol is found; the value of this
|
||||
field will always be a string unless the client opts-in to
|
||||
file encoding by sending the "abbrev" request.
|
||||
field will always be a string, number of a mapping between
|
||||
a string and a number.
|
||||
*/
|
||||
file: EncodedFile;
|
||||
/** The location within file at which the symbol is found*/
|
||||
|
@ -528,27 +516,6 @@ declare module ServerProtocol {
|
|||
arguments: ChangeRequestArgs;
|
||||
}
|
||||
|
||||
/*
|
||||
The following messages describe an OPTIONAL compression scheme
|
||||
that clients can choose to use. If a client does not opt-in to
|
||||
this scheme by sending an "abbrev" request, the server will not
|
||||
compress messages.
|
||||
*/
|
||||
|
||||
/**
|
||||
Abbrev request message; value of command field is "abbrev".
|
||||
Server returns an array of mappings from common message field
|
||||
names and common message field string values to shortened
|
||||
versions of these strings. Once a client opts-in by requesting
|
||||
the abbreviations, the server may send responses whose field
|
||||
names are shortened. The server may also send file names as
|
||||
instances of AssignFileId, or as file ids, if the corresponding
|
||||
id assignment had been previously returned. Currently, only
|
||||
responses to the "navto" request can be encoded.
|
||||
*/
|
||||
export interface AbbrevRequest extends Request {
|
||||
}
|
||||
|
||||
/**
|
||||
If an object of this type is returned in place of a string as
|
||||
the value of a file field in a response message, add the
|
||||
|
@ -572,25 +539,6 @@ declare module ServerProtocol {
|
|||
*/
|
||||
export type EncodedFile = number | IdFile | string;
|
||||
|
||||
/**
|
||||
Response to abbrev opt-in request message. This is a map of
|
||||
string field names and common string field values to shortened
|
||||
strings. Once the server sends this response, it will assume
|
||||
that it can use the shortened field names and field values. In
|
||||
addition, the server will assume it can assign ids to file
|
||||
names by returning an AssignFileId instance in place of a file
|
||||
name. Once an AssignFileId instance is returned, the server
|
||||
may send the file id (a number) in place of the file name.
|
||||
*/
|
||||
export interface AbbrevResponse extends Response {
|
||||
body?: {
|
||||
/** Map from full string (either field name or string
|
||||
field value) to shortened string */
|
||||
[fullString: string]: string;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Response to "brace" request. */
|
||||
export interface BraceResponse extends Response {
|
||||
body?: TextSpan[];
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
/// <reference path="node.d.ts" />
|
||||
/// <reference path="protocol.ts" />
|
||||
|
||||
module ts.server {
|
||||
/// <reference path="node.d.ts" />
|
||||
/// <reference path="protocol.ts" />
|
||||
|
||||
module ts.server {
|
||||
var nodeproto: typeof NodeJS._debugger = require('_debugger');
|
||||
var readline: NodeJS.ReadLine = require('readline');
|
||||
var path: NodeJS.Path = require('path');
|
||||
var path: NodeJS.Path = require('path');
|
||||
var fs: typeof NodeJS.fs = require('fs');
|
||||
|
||||
|
||||
var rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
terminal: false,
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
class Logger implements ts.server.Logger {
|
||||
fd = -1;
|
||||
seq = 0;
|
||||
|
@ -71,17 +71,17 @@ module ts.server {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class IOSession extends Session {
|
||||
protocol: NodeJS._debugger.Protocol;
|
||||
|
||||
constructor(host: ServerHost, logger: ts.server.Logger, useProtocol: boolean, prettyJSON: boolean) {
|
||||
super(host, logger, useProtocol, prettyJSON);
|
||||
|
||||
class IOSession extends Session {
|
||||
protocol: NodeJS._debugger.Protocol;
|
||||
|
||||
constructor(host: ServerHost, logger: ts.server.Logger, useProtocol: boolean, prettyJSON: boolean) {
|
||||
super(host, logger, useProtocol, prettyJSON);
|
||||
if (useProtocol) {
|
||||
this.initProtocol();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
initProtocol() {
|
||||
this.protocol = new nodeproto.Protocol();
|
||||
// note: onResponse was named by nodejs authors; we are re-purposing the Protocol
|
||||
|
@ -89,25 +89,16 @@ module ts.server {
|
|||
this.protocol.onResponse = (pkt) => {
|
||||
this.handleRequest(pkt);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handleRequest(req: NodeJS._debugger.Packet) {
|
||||
this.projectService.log("Got JSON msg:\n" + req.raw);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
listen() {
|
||||
rl.on('line',(input: string) => {
|
||||
var cmd = input.trim();
|
||||
if (cmd.indexOf("{") == 0) {
|
||||
// assumption is JSON on single line
|
||||
// plan is to also carry this protocol
|
||||
// over tcp, in which case JSON would
|
||||
// have a Content-Length header
|
||||
this.executeJSONcmd(cmd);
|
||||
}
|
||||
else {
|
||||
this.executeCmd(cmd);
|
||||
}
|
||||
var message = input.trim();
|
||||
this.onMessage(message);
|
||||
});
|
||||
|
||||
rl.on('close',() => {
|
||||
|
@ -115,20 +106,13 @@ module ts.server {
|
|||
this.projectService.log("Exiting...");
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// This places log file in the directory containing editorServices.js
|
||||
// TODO: check that this location is writable
|
||||
var logger = new Logger(__dirname + "/.log" + process.pid.toString());
|
||||
|
||||
var host: ServerHost = ts.sys;
|
||||
|
||||
// Wire the debugging interface
|
||||
if (!host.getDebuggerClient) {
|
||||
host.getDebuggerClient = () => new nodeproto.Client();
|
||||
}
|
||||
|
||||
// Start listening
|
||||
new IOSession(host, logger, /* useProtocol */ true, /* prettyJSON */ false).listen();
|
||||
var logger = new Logger(__dirname + "/.log" + process.pid.toString());
|
||||
|
||||
// Start listening
|
||||
new IOSession(ts.sys, logger, /* useProtocol */ true, /* prettyJSON */ false).listen();
|
||||
}
|
Loading…
Reference in a new issue