diff --git a/src/server/client.ts b/src/server/client.ts index 9da5ed9fdbd..22b346aa3ec 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -47,11 +47,11 @@ module ts.server { return lineMap; } - private lineColToPosition(fileName: string, lineCol: ServerProtocol.LineCol): number { + private lineColToPosition(fileName: string, lineCol: ts.server.protocol.LineCol): number { return ts.computePositionFromLineAndCharacter(this.getLineMap(fileName), lineCol.line, lineCol.col); } - private positionToOneBasedLineCol(fileName: string, position: number): ServerProtocol.LineCol { + private positionToOneBasedLineCol(fileName: string, position: number): ts.server.protocol.LineCol { var lineCol = ts.computeLineAndCharacterOfPosition(this.getLineMap(fileName), position); return { line: lineCol.line, @@ -59,7 +59,7 @@ module ts.server { }; } - private convertCodeEditsToTextChange(fileName: string, codeEdit: ServerProtocol.CodeEdit): ts.TextChange { + private convertCodeEditsToTextChange(fileName: string, codeEdit: ts.server.protocol.CodeEdit): ts.TextChange { var start = this.lineColToPosition(fileName, codeEdit.start); var end = this.lineColToPosition(fileName, codeEdit.end); @@ -69,11 +69,11 @@ module ts.server { }; } - private decodeEncodedFileId(fileId: ServerProtocol.EncodedFile): string { + private decodeEncodedFileId(fileId: ts.server.protocol.EncodedFile): string { var fileName: string; if (typeof fileId === "object") { - fileName = (fileId).file; - this.fileMapping[(fileId).id] = fileName; + fileName = (fileId).file; + this.fileMapping[(fileId).id] = fileName; } else if (typeof fileId === "number") { fileName = ts.lookUp(this.fileMapping, fileId.toString()); @@ -85,8 +85,8 @@ module ts.server { return fileName; } - private processRequest(command: string, arguments?: any): T { - var request: ServerProtocol.Request = { + private processRequest(command: string, arguments?: any): T { + var request: ts.server.protocol.Request = { seq: this.sequence++, type: "request", command: command, @@ -98,7 +98,7 @@ module ts.server { return request; } - private processResponse(request: ServerProtocol.Request): T { + private processResponse(request: ts.server.protocol.Request): T { var lastMessage = this.messages.shift(); Debug.assert(!!lastMessage, "Did not recieve any responses."); @@ -138,12 +138,12 @@ module ts.server { } openFile(fileName: string): void { - var args: ServerProtocol.FileRequestArgs = { file: fileName }; + var args: ts.server.protocol.FileRequestArgs = { file: fileName }; this.processRequest(CommandNames.Open, args); } closeFile(fileName: string): void { - var args: ServerProtocol.FileRequestArgs = { file: fileName }; + var args: ts.server.protocol.FileRequestArgs = { file: fileName }; this.processRequest(CommandNames.Close, args); } @@ -152,7 +152,7 @@ module ts.server { this.lineMaps[fileName] = undefined; var lineCol = this.positionToOneBasedLineCol(fileName, start); - var args: ServerProtocol.ChangeRequestArgs = { + var args: ts.server.protocol.ChangeRequestArgs = { file: fileName, line: lineCol.line, col: lineCol.col, @@ -166,14 +166,14 @@ module ts.server { getQuickInfoAtPosition(fileName: string, position: number): QuickInfo { var lineCol = this.positionToOneBasedLineCol(fileName, position); - var args: ServerProtocol.CodeLocationRequestArgs = { + var args: ts.server.protocol.CodeLocationRequestArgs = { file: fileName, line: lineCol.line, col: lineCol.col }; - var request = this.processRequest(CommandNames.Quickinfo, args); - var response = this.processResponse(request); + var request = this.processRequest(CommandNames.Quickinfo, args); + var response = this.processResponse(request); var start = this.lineColToPosition(fileName, response.body.start); var end = this.lineColToPosition(fileName, response.body.end); @@ -189,15 +189,15 @@ module ts.server { getCompletionsAtPosition(fileName: string, position: number): CompletionInfo { var lineCol = this.positionToOneBasedLineCol(fileName, position); - var args: ServerProtocol.CompletionsRequestArgs = { + var args: ts.server.protocol.CompletionsRequestArgs = { file: fileName, line: lineCol.line, col: lineCol.col, prefix: undefined }; - var request = this.processRequest(CommandNames.Completions, args); - var response = this.processResponse(request); + var request = this.processRequest(CommandNames.Completions, args); + var response = this.processResponse(request); return this.lastCompletionEntry = { isMemberCompletion: false, @@ -223,13 +223,13 @@ module ts.server { } getNavigateToItems(searchTerm: string): NavigateToItem[] { - var args: ServerProtocol.NavtoRequestArgs = { + var args: ts.server.protocol.NavtoRequestArgs = { searchTerm, file: this.host.getScriptFileNames()[0] }; - var request = this.processRequest(CommandNames.Navto, args); - var response = this.processResponse(request); + var request = this.processRequest(CommandNames.Navto, args); + var response = this.processResponse(request); return response.body.map(entry => { var fileName = this.decodeEncodedFileId(entry.file); @@ -252,7 +252,7 @@ module ts.server { getFormattingEditsForRange(fileName: string, start: number, end: number, options: ts.FormatCodeOptions): ts.TextChange[] { var startLineCol = this.positionToOneBasedLineCol(fileName, start); var endLineCol = this.positionToOneBasedLineCol(fileName, end); - var args: ServerProtocol.FormatRequestArgs = { + var args: ts.server.protocol.FormatRequestArgs = { file: fileName, line: startLineCol.line, col: startLineCol.col, @@ -261,8 +261,8 @@ module ts.server { }; // TODO: handle FormatCodeOptions - var request = this.processRequest(CommandNames.Format, args); - var response = this.processResponse(request); + var request = this.processRequest(CommandNames.Format, args); + var response = this.processResponse(request); return response.body.map(entry=> this.convertCodeEditsToTextChange(fileName, entry)); } @@ -273,7 +273,7 @@ module ts.server { getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions): ts.TextChange[] { var lineCol = this.positionToOneBasedLineCol(fileName, position); - var args: ServerProtocol.FormatOnKeyRequestArgs = { + var args: ts.server.protocol.FormatOnKeyRequestArgs = { file: fileName, line: lineCol.line, col: lineCol.col, @@ -281,22 +281,22 @@ module ts.server { }; // TODO: handle FormatCodeOptions - var request = this.processRequest(CommandNames.Formatonkey, args); - var response = this.processResponse(request); + var request = this.processRequest(CommandNames.Formatonkey, args); + var response = this.processResponse(request); return response.body.map(entry=> this.convertCodeEditsToTextChange(fileName, entry)); } getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { var lineCol = this.positionToOneBasedLineCol(fileName, position); - var args: ServerProtocol.CodeLocationRequestArgs = { + var args: ts.server.protocol.CodeLocationRequestArgs = { file: fileName, line: lineCol.line, col: lineCol.col, }; - var request = this.processRequest(CommandNames.Definition, args); - var response = this.processResponse(request); + var request = this.processRequest(CommandNames.Definition, args); + var response = this.processResponse(request); return response.body.map(entry => { var fileName = this.decodeEncodedFileId(entry.file); @@ -315,14 +315,14 @@ module ts.server { getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[] { var lineCol = this.positionToOneBasedLineCol(fileName, position); - var args: ServerProtocol.CodeLocationRequestArgs = { + var args: ts.server.protocol.CodeLocationRequestArgs = { file: fileName, line: lineCol.line, col: lineCol.col, }; - var request = this.processRequest(CommandNames.References, args); - var response = this.processResponse(request); + var request = this.processRequest(CommandNames.References, args); + var response = this.processResponse(request); return response.body.refs.map(entry => { var fileName = this.decodeEncodedFileId(entry.file); @@ -354,7 +354,7 @@ module ts.server { getRenameInfo(fileName: string, position: number, findInStrings?: boolean, findInComments?: boolean): RenameInfo { var lineCol = this.positionToOneBasedLineCol(fileName, position); - var args: ServerProtocol.RenameRequestArgs = { + var args: ts.server.protocol.RenameRequestArgs = { file: fileName, line: lineCol.line, col: lineCol.col, @@ -362,8 +362,8 @@ module ts.server { findInComments }; - var request = this.processRequest(CommandNames.Rename, args); - var response = this.processResponse(request); + var request = this.processRequest(CommandNames.Rename, args); + var response = this.processResponse(request); return this.lastRenameEntry = { canRename: response.body.info.canRename, @@ -401,7 +401,7 @@ module ts.server { return this.lastRenameEntry.locations; } - decodeNavigationBarItems(items: ServerProtocol.NavigationBarItem[], fileName: string): NavigationBarItem[] { + decodeNavigationBarItems(items: ts.server.protocol.NavigationBarItem[], fileName: string): NavigationBarItem[] { if (!items) { return []; } @@ -419,12 +419,12 @@ module ts.server { } getNavigationBarItems(fileName: string): NavigationBarItem[] { - var args: ServerProtocol.FileRequestArgs = { + var args: ts.server.protocol.FileRequestArgs = { file: fileName }; - var request = this.processRequest(CommandNames.NavBar, args); - var response = this.processResponse(request); + var request = this.processRequest(CommandNames.NavBar, args); + var response = this.processResponse(request); return this.decodeNavigationBarItems(response.body, fileName); } @@ -455,14 +455,14 @@ module ts.server { getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[] { var lineCol = this.positionToOneBasedLineCol(fileName, position); - var args: ServerProtocol.CodeLocationRequestArgs = { + var args: ts.server.protocol.CodeLocationRequestArgs = { file: fileName, line: lineCol.line, col: lineCol.col, }; - var request = this.processRequest(CommandNames.Brace, args); - var response = this.processResponse(request); + var request = this.processRequest(CommandNames.Brace, args); + var response = this.processResponse(request); return response.body.map(entry => { var start = this.lineColToPosition(fileName, entry.start); diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index d2dcf4260ef..b1eef8f1b7f 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -1,603 +1,597 @@ -/** Declaration module describing the TypeScript Server protocol */ -declare module ServerProtocol { - /** A TypeScript Server message */ - export interface Message { - /** Sequence number of the message */ - seq: number; - /** One of "request", "response", or "event" */ - type: string; - } - - /** Client-initiated request message */ - export interface Request extends Message { - /** The command to execute */ - command: string; - /** Object containing arguments for the command */ - arguments?: any; - } - - /** Server-initiated event message */ - export interface Event extends Message { - /** Name of event */ - event: string; - /** Event-specific information */ - body?: any; - } - - /** Response by server to client request message */ - export interface Response extends Message { - /** Sequence number of the request message */ - request_seq: number; - /** Outcome of the request */ - success: boolean; - /** The command requested */ - command: string; - /** Contains error message if success == false. */ - message?: string; - /** Contains message body if success == true. */ - body?: any; - } - - /** Arguments for FileRequest messages */ - export interface FileRequestArgs { - /** The file for the request (absolute pathname required) */ - file: string; - } - - /** - Request whose sole parameter is a file name - */ - export interface FileRequest extends Request { - arguments: FileRequestArgs; - } - - /** - Instances of this interface specify a code location: - (file, line, col), where line and column are 1-based. - */ - export interface CodeLocationRequestArgs extends FileRequestArgs { - /** The line number for the request (1-based) */ - line: number; - /** The column for the request (1-based) */ - col: number; - } - - /** - A request whose arguments specify a code location (file, line, col) - */ - export interface CodeLocationRequest extends FileRequest { - arguments: CodeLocationRequestArgs; - } - - /** - Go to definition request; value of command field is - "definition". Return response giving the code locations that - define the symbol found in file at location line, col. - */ - export interface DefinitionRequest extends CodeLocationRequest { - } - - /** - Object containing line and column (one-based) of code location - */ - export interface LineCol { - line: number; - col: number; - } - - /** - Object found in response messages defining a span of text in - source code. - */ - export interface TextSpan { - /** First character of the definition */ - start: LineCol; - /** One character past last character of the definition */ - end: LineCol; - } - - /** - Object found in response messages defining a span of text in - a specific source file. - */ - export interface CodeSpan extends TextSpan { - /** - File containing the definition; the value of this - field will always be a string, number of a mapping between - a string and a number. - */ - file: EncodedFile; - } - - /** - Definition response message. Gives text range for definition. - */ - export interface DefinitionResponse extends Response { - body?: CodeSpan[]; - } - - /** - Find references request; value of command field is - "references". Return response giving the code locations that - reference the symbol found in file at location line, col. - */ - export interface ReferencesRequest extends CodeLocationRequest { - } - - export interface ReferencesResponseItem extends CodeSpan { - /** Text of line containing the reference. Including this - with the response avoids latency of editor loading files - to show text of reference line (the server already has - loaded the referencing files). - */ - lineText: string; - - /** True if reference is a write location, false otherwise. */ - isWriteAccess: boolean; - } - - /** The body of a "references" response message. */ - export interface ReferencesResponseBody { - /** The code locations referencing the symbol */ - refs: ReferencesResponseItem[]; - /** The name of the symbol */ - symbolName: string; - /** - The start column of the symbol (on the line provided by the references request) - */ - symbolStartCol: number; - /** The full display name of the symbol */ - symbolDisplayString: string; - } - - /** Response to "references" request. */ - export interface ReferencesResponse extends Response { - body?: ReferencesResponseBody; - } - - export interface RenameRequestArgs extends CodeLocationRequestArgs { - findInComments?: boolean; - findInStrings?: boolean; - } - - - /** - Rename request; value of command field is "rename". Return - response giving the code locations that reference the symbol - found in file at location line, col. Also return full display - name of the symbol so that client can print it unambiguously. - */ - export interface RenameRequest extends CodeLocationRequest { - arguments: RenameRequestArgs; - } - - /** Information about the item to be renamed. */ - export interface RenameInfo { - /** True if item can be renamed */ - canRename: boolean; - /** Error message if item can not be renamed */ - localizedErrorMessage: string; - /** Display name of the item to be renamed */ - displayName: string; - /** Full display name of item to be renamed */ - fullDisplayName: string; - /** The items's kind (such as 'className' or 'parameterName' or plain 'text') */ - kind: string; - /** Optional modifiers for the kind (such as 'public') */ - kindModifiers: string; - } - - /** - Rename response message. - */ - export interface RenameResponse extends Response { - body?: { - /** Information about the item to be renamed */ - info: RenameInfo; - /** - An array of code locations that refer to the - item to be renamed. - */ - locs: CodeSpan[]; - } - } - - /** - Open request; value of command field is "open". Notify the - server that the client has file open. The server will not - monitor the filesystem for changes in this file and will assume - that the client is updating the server (using the change and/or - reload messages) when the file changes. Server does not currently - send a response to an open request. - */ - export interface OpenRequest extends FileRequest { - } - - /** - Close request; value of command field is "close". Notify the - server that the client has closed a previously open file. If - file is still referenced by open files, the server will resume - monitoring the filesystem for changes to file. Server does not - currently send a response to a close request. - */ - export interface CloseRequest extends FileRequest { - } - - /** - Quickinfo request; value of command field is - "quickinfo". Return response giving a quick type and - documentation string for the symbol found in file at location - line, col. - */ - export interface QuickInfoRequest extends CodeLocationRequest { - } - - /** Body of QuickInfoResponse */ - export interface QuickInfoResponseBody { - /** The symbol's kind (such as 'className' or 'parameterName' or plain 'text') */ - kind: string; - /** Optional modifiers for the kind (such as 'public') */ - kindModifiers: string; - /** Starting code location of symbol */ - start: LineCol; - /** One past last character of symbol */ - end: LineCol; - /** Type and kind of symbol */ - displayString: string; - /** Documentation associated with symbol */ - documentation: string; - } - - /** Quickinfo response message */ - export interface QuickInfoResponse extends Response { - body?: QuickInfoResponseBody; - } - - /** Arguments for format messages */ - export interface FormatRequestArgs extends CodeLocationRequestArgs { - /** Last line of range for which to format text in file */ - endLine: number; - /** Last column of range for which to format text in file */ - endCol: number; - } - - /** - Format request; value of command field is "format". Return - response giving zero or more edit instructions. The edit - instructions will be sorted in file order. Applying the edit - instructions in reverse to file will result in correctly - reformatted text. - */ - export interface FormatRequest extends CodeLocationRequest { - arguments: FormatRequestArgs; - } - - /** - Object found in response messages defining an editing - instruction for a span of text in source code. The effect of - this instruction is to replace the text starting at start and - ending one character before end with newText. For an insertion, - the text span is empty. For a deletion, newText is empty. - */ - export interface CodeEdit { - /** First character of the text span to edit. */ - start: LineCol; - /** One character past last character of the text span to edit */ - end: LineCol; - /** - Replace the span defined above with this string (may be - the empty string) - */ - newText: string; - } - - /** Format and format on key response message */ - export interface FormatResponse extends Response { - body?: CodeEdit[]; - } - - /** Arguments for format on key messages */ - export interface FormatOnKeyRequestArgs extends CodeLocationRequestArgs { - /** Key pressed (';', '\n', or '}') */ - key: string; - } - - /** - Format on key request; value of command field is - "formatonkey". Given file location and key typed (as string), - return response giving zero or more edit instructions. The - edit instructions will be sorted in file order. Applying the - edit instructions in reverse to file will result in correctly - reformatted text. - */ - export interface FormatOnKeyRequest extends CodeLocationRequest { - arguments: FormatOnKeyRequestArgs; - } - - /** Arguments for completions messages */ - export interface CompletionsRequestArgs extends CodeLocationRequestArgs { - /** Optional prefix to apply to possible completions. */ - prefix?: string; - } - - /** - Completions request; value of command field is "completions". - Given a file location (file, line, col) and a prefix (which may - be the empty string), return the possible completions that - begin with prefix. - */ - export interface CompletionsRequest extends CodeLocationRequest { - arguments: CompletionsRequestArgs; - } - - /** - Part of a symbol description. - */ - export interface SymbolDisplayPart { - /** Text of an item describing the symbol */ - text: string; - /** The symbol's kind (such as 'className' or 'parameterName' or plain 'text') */ - kind: string; - } - - /** An item found in a completion response */ - export interface CompletionItem { - /** The symbol's name */ - name: string; - /** The symbol's kind (such as 'className' or 'parameterName') */ - kind: string; - /** Optional modifiers for the kind (such as 'public') */ - kindModifiers?: string; - /** Display parts of the symbol (similar to quick info) */ - displayParts?: SymbolDisplayPart[]; - /** Documentation strings for the symbol */ - documentation?: SymbolDisplayPart[]; - } - - export interface CompletionsResponse extends Response { - body?: CompletionItem[]; - } - - /** Arguments for geterr messages. */ - export interface GeterrRequestArgs { - /** - List of file names for which to compute compiler errors. - The files will be checked in list order. - */ - files: string[]; - /** - Delay in milliseconds to wait before starting to compute - errors for the files in the file list - */ - delay: number; - } - - /** - Geterr request; value of command field is "geterr". Wait for - delay milliseconds and then, if during the wait no change or - reload messages have arrived for the first file in the files - list, get the syntactic errors for the file, field requests, - and then get the semantic errors for the file. Repeat with a - smaller delay for each subsequent file on the files list. Best - practice for an editor is to send a file list containing each - file that is currently visible, in most-recently-used order. - */ - export interface GeterrRequest extends Request { - arguments: GeterrRequestArgs; - } - - /** Item of diagnostic information found in a DiagEvent message */ - export interface Diagnostic { - /** Starting code location at which text appies */ - start: LineCol; - /** Length of code location at which text applies */ - len: number; - /** Text of diagnostic message */ - text: string; - } - - /** Event message for "syntaxDiag" and "semanticDiag" event types. - These events provide syntactic and semantic errors for a file. - */ - export interface DiagEvent extends Event { - body?: { - /** The file for which diagnostic information is reported */ - file: string; - /** An array of diagnostic information items */ - diagnostics: Diagnostic[]; - }; - } - - /** Arguments for reload request. */ - export interface ReloadRequestArgs extends FileRequestArgs { - /** - Name of temporary file from which to reload file - contents. May be same as file. - */ - tmpfile: string; - } - - /** - Reload request message; value of command field is "reload". - Reload contents of file with name given by the 'file' argument - from temporary file with name given by the 'tmpfile' argument. - The two names can be identical. - */ - export interface ReloadRequest extends FileRequest { - arguments: ReloadRequestArgs; - } - - /** - Response to "reload" request. This is just an acknowledgement, so - no body field is required. - */ - export interface ReloadResponse extends Response { - } - - /** Arguments for saveto request. */ - export interface SavetoRequestArgs extends FileRequestArgs { - /** - Name of temporary file into which to save server's view of - file contents. - */ - tmpfile: string; - } - - /** - Saveto request message; value of command field is "saveto". - For debugging purposes, save to a temporaryfile (named by - argument 'tmpfile') the contents of file named by argument - 'file'. The server does not currently send a response to a - "saveto" request. - */ - export interface SavetoRequest extends FileRequest { - arguments: SavetoRequestArgs; - } - - /** Arguments for navto request message */ - export interface NavtoRequestArgs extends FileRequestArgs { - /** - Search term to navigate to from current location; term can - be '.*' or an identifier prefix. - */ - searchTerm: string; - } - - /** - Navto request message; value of command field is "navto". - Return list of objects giving code locations and symbols that - match the search term given in argument 'searchTerm'. The - context for the search is given by the named file. - */ - export interface NavtoRequest extends FileRequest { - arguments: NavtoRequestArgs; - } - - /** An item found in a navto response. */ - export interface NavtoItem { - /** The symbol's name */ - name: string; - /** The symbol's kind (such as 'className' or 'parameterName') */ - kind: string; - /** exact, substring, or prefix */ - matchKind?: string; - /** Optional modifiers for the kind (such as 'public') */ - kindModifiers?: string; - /** - The file in which the symbol is found; the value of this - 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*/ - start: LineCol; - /** One past the last character of the symbol */ - end: LineCol; - /** - Name of symbol's container symbol (if any); for example, - the class name if symbol is a class member - */ - containerName?: string; - /** Kind of symbol's container symbol (if any) */ - containerKind?: string; - } - - /** - Navto response message. Body is an array of navto items. Each - item gives a symbol that matched the search term. - */ - export interface NavtoResponse extends Response { - body?: NavtoItem[]; - } - - /** Arguments for change request message. */ - export interface ChangeRequestArgs extends CodeLocationRequestArgs { - /** - Length of span deleted at location (file, line, col); nothing deleted - if this field is zero or undefined. - */ - deleteLen?: number; - /** Optional string to insert at location (file, line col). */ - insertString?: string; - } - - /** - Change request message; value of command field is "change". - Update the server's view of the file named by argument 'file'. - Server does not currently send a response to a change request. - */ - export interface ChangeRequest extends CodeLocationRequest { - arguments: ChangeRequestArgs; - } - - /** - 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 - mapping id => file to the client's cache of file id mappings, - and interpret the value as if it was the string in the 'file' - field. - */ - export interface IdFile { - /** Id to assign to file */ - id: number; - /** File name that will correspond to id */ - file: string; - } - - /** - The type of an encoded file name. If of type number, the value - is a file id. If of type IdFile, the value is interpreted as - 'file' and in addition the mapping 'id' to 'file' is - established. If of type string, the value is simply the file - name. - */ - export type EncodedFile = number | IdFile | string; - - /** Response to "brace" request. */ - export interface BraceResponse extends Response { - body?: TextSpan[]; - } - - /** - Brace matching request; value of command field is "brace". - Return response giving the code locations of matching braces - found in file at location line, col. - */ - export interface BraceRequest extends CodeLocationRequest { - } - - /** - NavBar itesm request; value of command field is "navbar". - Return response giving the list of navigation bar entries - extracted from the requested file. - */ - export interface NavBarRequest extends FileRequest { - } - +/** Declaration module describing the TypeScript Server protocol */ +declare module ts.server.protocol { + /** A TypeScript Server message */ + export interface Message { + /** Sequence number of the message */ + seq: number; + /** One of "request", "response", or "event" */ + type: string; + } + + /** Client-initiated request message */ + export interface Request extends Message { + /** The command to execute */ + command: string; + /** Object containing arguments for the command */ + arguments?: any; + } + + /** Server-initiated event message */ + export interface Event extends Message { + /** Name of event */ + event: string; + /** Event-specific information */ + body?: any; + } + + /** Response by server to client request message */ + export interface Response extends Message { + /** Sequence number of the request message */ + request_seq: number; + /** Outcome of the request */ + success: boolean; + /** The command requested */ + command: string; + /** Contains error message if success == false. */ + message?: string; + /** Contains message body if success == true. */ + body?: any; + } + + /** Arguments for FileRequest messages */ + export interface FileRequestArgs { + /** The file for the request (absolute pathname required) */ + file: string; + } + + /** + Request whose sole parameter is a file name + */ + export interface FileRequest extends Request { + arguments: FileRequestArgs; + } + + /** + Instances of this interface specify a code location: + (file, line, col), where line and column are 1-based. + */ + export interface CodeLocationRequestArgs extends FileRequestArgs { + /** The line number for the request (1-based) */ + line: number; + /** The column for the request (1-based) */ + col: number; + } + + /** + A request whose arguments specify a code location (file, line, col) + */ + export interface CodeLocationRequest extends FileRequest { + arguments: CodeLocationRequestArgs; + } + + /** + Go to definition request; value of command field is + "definition". Return response giving the code locations that + define the symbol found in file at location line, col. + */ + export interface DefinitionRequest extends CodeLocationRequest { + } + + /** + Object containing line and column (one-based) of code location + */ + export interface LineCol { + line: number; + col: number; + } + + /** + Object found in response messages defining a span of text in + source code. + */ + export interface TextSpan { + /** First character of the definition */ + start: LineCol; + /** One character past last character of the definition */ + end: LineCol; + } + + /** + Object found in response messages defining a span of text in + a specific source file. + */ + export interface CodeSpan extends TextSpan { + /** + File containing the definition; the value of this + field will always be a string, number of a mapping between + a string and a number. + */ + file: EncodedFile; + } + + /** + Definition response message. Gives text range for definition. + */ + export interface DefinitionResponse extends Response { + body?: CodeSpan[]; + } + + /** + Find references request; value of command field is + "references". Return response giving the code locations that + reference the symbol found in file at location line, col. + */ + export interface ReferencesRequest extends CodeLocationRequest { + } + + export interface ReferencesResponseItem extends CodeSpan { + /** Text of line containing the reference. Including this + with the response avoids latency of editor loading files + to show text of reference line (the server already has + loaded the referencing files). + */ + lineText: string; + + /** True if reference is a write location, false otherwise. */ + isWriteAccess: boolean; + } + + /** The body of a "references" response message. */ + export interface ReferencesResponseBody { + /** The code locations referencing the symbol */ + refs: ReferencesResponseItem[]; + /** The name of the symbol */ + symbolName: string; + /** + The start column of the symbol (on the line provided by the references request) + */ + symbolStartCol: number; + /** The full display name of the symbol */ + symbolDisplayString: string; + } + + /** Response to "references" request. */ + export interface ReferencesResponse extends Response { + body?: ReferencesResponseBody; + } + + export interface RenameRequestArgs extends CodeLocationRequestArgs { + findInComments?: boolean; + findInStrings?: boolean; + } + + + /** + Rename request; value of command field is "rename". Return + response giving the code locations that reference the symbol + found in file at location line, col. Also return full display + name of the symbol so that client can print it unambiguously. + */ + export interface RenameRequest extends CodeLocationRequest { + arguments: RenameRequestArgs; + } + + /** Information about the item to be renamed. */ + export interface RenameInfo { + /** True if item can be renamed */ + canRename: boolean; + /** Error message if item can not be renamed */ + localizedErrorMessage: string; + /** Display name of the item to be renamed */ + displayName: string; + /** Full display name of item to be renamed */ + fullDisplayName: string; + /** The items's kind (such as 'className' or 'parameterName' or plain 'text') */ + kind: string; + /** Optional modifiers for the kind (such as 'public') */ + kindModifiers: string; + } + + /** + Rename response message. + */ + export interface RenameResponse extends Response { + body?: { + /** Information about the item to be renamed */ + info: RenameInfo; + /** + An array of code locations that refer to the + item to be renamed. + */ + locs: CodeSpan[]; + } + } + + /** + Open request; value of command field is "open". Notify the + server that the client has file open. The server will not + monitor the filesystem for changes in this file and will assume + that the client is updating the server (using the change and/or + reload messages) when the file changes. Server does not currently + send a response to an open request. + */ + export interface OpenRequest extends FileRequest { + } + + /** + Close request; value of command field is "close". Notify the + server that the client has closed a previously open file. If + file is still referenced by open files, the server will resume + monitoring the filesystem for changes to file. Server does not + currently send a response to a close request. + */ + export interface CloseRequest extends FileRequest { + } + + /** + Quickinfo request; value of command field is + "quickinfo". Return response giving a quick type and + documentation string for the symbol found in file at location + line, col. + */ + export interface QuickInfoRequest extends CodeLocationRequest { + } + + /** Body of QuickInfoResponse */ + export interface QuickInfoResponseBody { + /** The symbol's kind (such as 'className' or 'parameterName' or plain 'text') */ + kind: string; + /** Optional modifiers for the kind (such as 'public') */ + kindModifiers: string; + /** Starting code location of symbol */ + start: LineCol; + /** One past last character of symbol */ + end: LineCol; + /** Type and kind of symbol */ + displayString: string; + /** Documentation associated with symbol */ + documentation: string; + } + + /** Quickinfo response message */ + export interface QuickInfoResponse extends Response { + body?: QuickInfoResponseBody; + } + + /** Arguments for format messages */ + export interface FormatRequestArgs extends CodeLocationRequestArgs { + /** Last line of range for which to format text in file */ + endLine: number; + /** Last column of range for which to format text in file */ + endCol: number; + } + + /** + Format request; value of command field is "format". Return + response giving zero or more edit instructions. The edit + instructions will be sorted in file order. Applying the edit + instructions in reverse to file will result in correctly + reformatted text. + */ + export interface FormatRequest extends CodeLocationRequest { + arguments: FormatRequestArgs; + } + + /** + Object found in response messages defining an editing + instruction for a span of text in source code. The effect of + this instruction is to replace the text starting at start and + ending one character before end with newText. For an insertion, + the text span is empty. For a deletion, newText is empty. + */ + export interface CodeEdit { + /** First character of the text span to edit. */ + start: LineCol; + /** One character past last character of the text span to edit */ + end: LineCol; + /** + Replace the span defined above with this string (may be + the empty string) + */ + newText: string; + } + + /** Format and format on key response message */ + export interface FormatResponse extends Response { + body?: CodeEdit[]; + } + + /** Arguments for format on key messages */ + export interface FormatOnKeyRequestArgs extends CodeLocationRequestArgs { + /** Key pressed (';', '\n', or '}') */ + key: string; + } + + /** + Format on key request; value of command field is + "formatonkey". Given file location and key typed (as string), + return response giving zero or more edit instructions. The + edit instructions will be sorted in file order. Applying the + edit instructions in reverse to file will result in correctly + reformatted text. + */ + export interface FormatOnKeyRequest extends CodeLocationRequest { + arguments: FormatOnKeyRequestArgs; + } + + /** Arguments for completions messages */ + export interface CompletionsRequestArgs extends CodeLocationRequestArgs { + /** Optional prefix to apply to possible completions. */ + prefix?: string; + } + + /** + Completions request; value of command field is "completions". + Given a file location (file, line, col) and a prefix (which may + be the empty string), return the possible completions that + begin with prefix. + */ + export interface CompletionsRequest extends CodeLocationRequest { + arguments: CompletionsRequestArgs; + } + + /** + Part of a symbol description. + */ + export interface SymbolDisplayPart { + /** Text of an item describing the symbol */ + text: string; + /** The symbol's kind (such as 'className' or 'parameterName' or plain 'text') */ + kind: string; + } + + /** An item found in a completion response */ + export interface CompletionItem { + /** The symbol's name */ + name: string; + /** The symbol's kind (such as 'className' or 'parameterName') */ + kind: string; + /** Optional modifiers for the kind (such as 'public') */ + kindModifiers?: string; + /** Display parts of the symbol (similar to quick info) */ + displayParts?: SymbolDisplayPart[]; + /** Documentation strings for the symbol */ + documentation?: SymbolDisplayPart[]; + } + + export interface CompletionsResponse extends Response { + body?: CompletionItem[]; + } + + /** Arguments for geterr messages. */ + export interface GeterrRequestArgs { + /** + List of file names for which to compute compiler errors. + The files will be checked in list order. + */ + files: string[]; + /** + Delay in milliseconds to wait before starting to compute + errors for the files in the file list + */ + delay: number; + } + + /** + Geterr request; value of command field is "geterr". Wait for + delay milliseconds and then, if during the wait no change or + reload messages have arrived for the first file in the files + list, get the syntactic errors for the file, field requests, + and then get the semantic errors for the file. Repeat with a + smaller delay for each subsequent file on the files list. Best + practice for an editor is to send a file list containing each + file that is currently visible, in most-recently-used order. + */ + export interface GeterrRequest extends Request { + arguments: GeterrRequestArgs; + } + + /** Item of diagnostic information found in a DiagEvent message */ + export interface Diagnostic { + /** Starting code location at which text appies */ + start: LineCol; + /** Length of code location at which text applies */ + len: number; + /** Text of diagnostic message */ + text: string; + } + + /** Event message for "syntaxDiag" and "semanticDiag" event types. + These events provide syntactic and semantic errors for a file. + */ + export interface DiagEvent extends Event { + body?: { + /** The file for which diagnostic information is reported */ + file: string; + /** An array of diagnostic information items */ + diagnostics: Diagnostic[]; + }; + } + + /** Arguments for reload request. */ + export interface ReloadRequestArgs extends FileRequestArgs { + /** + Name of temporary file from which to reload file + contents. May be same as file. + */ + tmpfile: string; + } + + /** + Reload request message; value of command field is "reload". + Reload contents of file with name given by the 'file' argument + from temporary file with name given by the 'tmpfile' argument. + The two names can be identical. + */ + export interface ReloadRequest extends FileRequest { + arguments: ReloadRequestArgs; + } + + /** + Response to "reload" request. This is just an acknowledgement, so + no body field is required. + */ + export interface ReloadResponse extends Response { + } + + /** Arguments for saveto request. */ + export interface SavetoRequestArgs extends FileRequestArgs { + /** + Name of temporary file into which to save server's view of + file contents. + */ + tmpfile: string; + } + + /** + Saveto request message; value of command field is "saveto". + For debugging purposes, save to a temporaryfile (named by + argument 'tmpfile') the contents of file named by argument + 'file'. The server does not currently send a response to a + "saveto" request. + */ + export interface SavetoRequest extends FileRequest { + arguments: SavetoRequestArgs; + } + + /** Arguments for navto request message */ + export interface NavtoRequestArgs extends FileRequestArgs { + /** + Search term to navigate to from current location; term can + be '.*' or an identifier prefix. + */ + searchTerm: string; + } + + /** + Navto request message; value of command field is "navto". + Return list of objects giving code locations and symbols that + match the search term given in argument 'searchTerm'. The + context for the search is given by the named file. + */ + export interface NavtoRequest extends FileRequest { + arguments: NavtoRequestArgs; + } + + /** An item found in a navto response. */ + export interface NavtoItem { + /** The symbol's name */ + name: string; + /** The symbol's kind (such as 'className' or 'parameterName') */ + kind: string; + /** exact, substring, or prefix */ + matchKind?: string; + /** Optional modifiers for the kind (such as 'public') */ + kindModifiers?: string; + /** + The file in which the symbol is found; the value of this + 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*/ + start: LineCol; + /** One past the last character of the symbol */ + end: LineCol; + /** + Name of symbol's container symbol (if any); for example, + the class name if symbol is a class member + */ + containerName?: string; + /** Kind of symbol's container symbol (if any) */ + containerKind?: string; + } + + /** + Navto response message. Body is an array of navto items. Each + item gives a symbol that matched the search term. + */ + export interface NavtoResponse extends Response { + body?: NavtoItem[]; + } + + /** Arguments for change request message. */ + export interface ChangeRequestArgs extends CodeLocationRequestArgs { + /** + Length of span deleted at location (file, line, col); nothing deleted + if this field is zero or undefined. + */ + deleteLen?: number; + /** Optional string to insert at location (file, line col). */ + insertString?: string; + } + + /** + Change request message; value of command field is "change". + Update the server's view of the file named by argument 'file'. + Server does not currently send a response to a change request. + */ + export interface ChangeRequest extends CodeLocationRequest { + arguments: ChangeRequestArgs; + } + + /** + 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 + mapping id => file to the client's cache of file id mappings, + and interpret the value as if it was the string in the 'file' + field. + */ + export interface IdFile { + /** Id to assign to file */ + id: number; + /** File name that will correspond to id */ + file: string; + } + + /** + The type of an encoded file name. If of type number, the value + is a file id. If of type IdFile, the value is interpreted as + 'file' and in addition the mapping 'id' to 'file' is + established. If of type string, the value is simply the file + name. + */ + export type EncodedFile = number | IdFile | string; + + /** Response to "brace" request. */ + export interface BraceResponse extends Response { + body?: TextSpan[]; + } + + /** + Brace matching request; value of command field is "brace". + Return response giving the code locations of matching braces + found in file at location line, col. + */ + export interface BraceRequest extends CodeLocationRequest { + } + + /** + NavBar itesm request; value of command field is "navbar". + Return response giving the list of navigation bar entries + extracted from the requested file. + */ + export interface NavBarRequest extends FileRequest { + } + export interface NavigationBarItem { - /** The item's display text */ - text: string; - - /** The symbol's kind (such as 'className' or 'parameterName') */ - kind: string; - - /** Optional modifiers for the kind (such as 'public') */ - kindModifiers?: string; - - /** The definition locations of the item */ - spans: TextSpan[]; + /** The item's display text */ + text: string; + + /** The symbol's kind (such as 'className' or 'parameterName') */ + kind: string; + + /** Optional modifiers for the kind (such as 'public') */ + kindModifiers?: string; + + /** The definition locations of the item */ + spans: TextSpan[]; /** Optional children */ childItems?: NavigationBarItem[]; - } - - export interface NavBarResponse extends Response { - body?: NavigationBarItem[]; - } -} - - - - - - + } + + export interface NavBarResponse extends Response { + body?: NavigationBarItem[]; + } +} diff --git a/src/server/session.ts b/src/server/session.ts index 715b8fa3d6a..e88932dcb77 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -27,7 +27,7 @@ module ts.server { } interface FileStart { - file: ServerProtocol.EncodedFile; + file: ts.server.protocol.EncodedFile; start: ILineInfo; } @@ -188,7 +188,7 @@ module ts.server { } response(info: any, cmdName: string, reqSeq = 0, errorMsg?: string) { - var res: ServerProtocol.Response = { + var res: ts.server.protocol.Response = { seq: 0, type: "response", command: cmdName, @@ -204,7 +204,7 @@ module ts.server { this.send(res); } - encodeFileName(fileName: string): ServerProtocol.EncodedFile { + encodeFileName(fileName: string): ts.server.protocol.EncodedFile { var id = ts.lookUp(this.fileHash, fileName); if (!id) { id = this.nextFileId++; @@ -277,7 +277,7 @@ module ts.server { } } - getDefinition(line: number, col: number, fileName: string): ServerProtocol.CodeSpan[] { + getDefinition(line: number, col: number, fileName: string): ts.server.protocol.CodeSpan[] { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); if (!project) { @@ -299,7 +299,7 @@ module ts.server { })); } - getRenameLocations(line: number, col: number, fileName: string, findInComments: boolean, findInStrings: boolean): { info: RenameInfo; locs: ServerProtocol.CodeSpan[] } { + getRenameLocations(line: number, col: number, fileName: string, findInComments: boolean, findInStrings: boolean): { info: RenameInfo; locs: ts.server.protocol.CodeSpan[] } { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); if (!project) { @@ -325,7 +325,7 @@ module ts.server { throw Errors.NoContent; } - var bakedRenameLocs = renameLocations.map(location => ({ + var bakedRenameLocs = renameLocations.map(location => ({ file: this.encodeFileName(location.fileName), start: compilerService.host.positionToLineCol(location.fileName, location.textSpan.start), end: compilerService.host.positionToLineCol(location.fileName, ts.textSpanEnd(location.textSpan)), @@ -334,7 +334,7 @@ module ts.server { return { info: renameInfo, locs: bakedRenameLocs }; } - getReferences(line: number, col: number, fileName: string): ServerProtocol.ReferencesResponseBody { + getReferences(line: number, col: number, fileName: string): ts.server.protocol.ReferencesResponseBody { // TODO: get all projects for this file; report refs for all projects deleting duplicates // can avoid duplicates by eliminating same ref file from subsequent projects var file = ts.normalizePath(fileName); @@ -360,7 +360,7 @@ module ts.server { var nameSpan = nameInfo.textSpan; var nameColStart = compilerService.host.positionToLineCol(file, nameSpan.start).col; var nameText = compilerService.host.getScriptSnapshot(file).getText(nameSpan.start, ts.textSpanEnd(nameSpan)); - var bakedRefs: ServerProtocol.ReferencesResponseItem[] = references.map((ref) => { + var bakedRefs: ts.server.protocol.ReferencesResponseItem[] = references.map((ref) => { var start = compilerService.host.positionToLineCol(ref.fileName, ref.textSpan.start); var refLineSpan = compilerService.host.lineToTextSpan(ref.fileName, start.line - 1); var snap = compilerService.host.getScriptSnapshot(ref.fileName); @@ -386,7 +386,7 @@ module ts.server { this.projectService.openClientFile(file); } - getQuickInfo(line: number, col: number, fileName: string): ServerProtocol.QuickInfoResponseBody { + getQuickInfo(line: number, col: number, fileName: string): ts.server.protocol.QuickInfoResponseBody { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); if (!project) { @@ -412,7 +412,7 @@ module ts.server { }; } - getFormattingEditsForRange(line: number, col: number, endLine: number, endCol: number, fileName: string): ServerProtocol.CodeEdit[] { + getFormattingEditsForRange(line: number, col: number, endLine: number, endCol: number, fileName: string): ts.server.protocol.CodeEdit[] { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); if (!project) { @@ -438,7 +438,7 @@ module ts.server { }); } - getFormattingEditsAfterKeystroke(line: number, col: number, key: string, fileName: string): ServerProtocol.CodeEdit[] { + getFormattingEditsAfterKeystroke(line: number, col: number, key: string, fileName: string): ts.server.protocol.CodeEdit[] { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); @@ -480,7 +480,7 @@ module ts.server { }); } - getCompletions(line: number, col: number, prefix: string, fileName: string): ServerProtocol.CompletionItem[] { + getCompletions(line: number, col: number, prefix: string, fileName: string): ts.server.protocol.CompletionItem[] { if (!prefix) { prefix = ""; } @@ -579,7 +579,7 @@ module ts.server { this.projectService.closeClientFile(file); } - decorateNavigationBarItem(project: Project, fileName: string, items: ts.NavigationBarItem[]): ServerProtocol.NavigationBarItem[] { + decorateNavigationBarItem(project: Project, fileName: string, items: ts.NavigationBarItem[]): ts.server.protocol.NavigationBarItem[] { if (!items) { return undefined; } @@ -598,7 +598,7 @@ module ts.server { })); } - getNavigationBarItems(fileName: string): ServerProtocol.NavigationBarItem[] { + getNavigationBarItems(fileName: string): ts.server.protocol.NavigationBarItem[] { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); if (!project) { @@ -614,7 +614,7 @@ module ts.server { return this.decorateNavigationBarItem(project, fileName, items); } - getNavigateToItems(searchTerm: string, fileName: string): ServerProtocol.NavtoItem[] { + getNavigateToItems(searchTerm: string, fileName: string): ts.server.protocol.NavtoItem[] { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); if (!project) { @@ -630,7 +630,7 @@ module ts.server { return navItems.map((navItem) => { var start = compilerService.host.positionToLineCol(navItem.fileName, navItem.textSpan.start); var end = compilerService.host.positionToLineCol(navItem.fileName, ts.textSpanEnd(navItem.textSpan)); - var bakedItem: ServerProtocol.NavtoItem = { + var bakedItem: ts.server.protocol.NavtoItem = { name: navItem.name, kind: navItem.kind, file: this.encodeFileName(navItem.fileName), @@ -653,7 +653,7 @@ module ts.server { }); } - getBraceMatching(line: number, col: number, fileName: string): ServerProtocol.TextSpan[] { + getBraceMatching(line: number, col: number, fileName: string): ts.server.protocol.TextSpan[] { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); @@ -677,87 +677,87 @@ module ts.server { onMessage(message: string) { try { - var request = JSON.parse(message); + var request = JSON.parse(message); var response: any; switch (request.command) { case CommandNames.Definition: { - var defArgs = request.arguments; + var defArgs = request.arguments; response = this.getDefinition(defArgs.line, defArgs.col, defArgs.file); break; } case CommandNames.References: { - var refArgs = request.arguments; + var refArgs = request.arguments; response = this.getReferences(refArgs.line, refArgs.col, refArgs.file); break; } case CommandNames.Rename: { - var renameArgs = request.arguments; + var renameArgs = request.arguments; response = this.getRenameLocations(renameArgs.line, renameArgs.col, renameArgs.file, renameArgs.findInComments, renameArgs.findInStrings); break; } case CommandNames.Open: { - var openArgs = request.arguments; + var openArgs = request.arguments; this.openClientFile(openArgs.file); break; } case CommandNames.Quickinfo: { - var quickinfoArgs = request.arguments; + var quickinfoArgs = request.arguments; response = this.getQuickInfo(quickinfoArgs.line, quickinfoArgs.col, quickinfoArgs.file); break; } case CommandNames.Format: { - var formatArgs = request.arguments; + var formatArgs = request.arguments; response = this.getFormattingEditsForRange(formatArgs.line, formatArgs.col, formatArgs.endLine, formatArgs.endCol, formatArgs.file); break; } case CommandNames.Formatonkey: { - var formatOnKeyArgs = request.arguments; + var formatOnKeyArgs = request.arguments; response = this.getFormattingEditsAfterKeystroke(formatOnKeyArgs.line, formatOnKeyArgs.col, formatOnKeyArgs.key, formatOnKeyArgs.file); break; } case CommandNames.Completions: { - var completionsArgs = request.arguments; + var completionsArgs = request.arguments; response = this.getCompletions(request.arguments.line, request.arguments.col, completionsArgs.prefix, request.arguments.file); break; } case CommandNames.Geterr: { - var geterrArgs = request.arguments; + var geterrArgs = request.arguments; response = this.getDiagnostics(geterrArgs.delay, geterrArgs.files); break; } case CommandNames.Change: { - var changeArgs = request.arguments; + var changeArgs = request.arguments; this.change(changeArgs.line, changeArgs.col, changeArgs.deleteLen, changeArgs.insertString, changeArgs.file); break; } case CommandNames.Reload: { - var reloadArgs = request.arguments; + var reloadArgs = request.arguments; this.reload(reloadArgs.file, reloadArgs.tmpfile, request.seq); break; } case CommandNames.Saveto: { - var savetoArgs = request.arguments; + var savetoArgs = request.arguments; this.saveToTmp(savetoArgs.file, savetoArgs.tmpfile); break; } case CommandNames.Close: { - var closeArgs = request.arguments; + var closeArgs = request.arguments; this.closeClientFile(closeArgs.file); break; } case CommandNames.Navto: { - var navtoArgs = request.arguments; + var navtoArgs = request.arguments; response = this.getNavigateToItems(navtoArgs.searchTerm, navtoArgs.file); break; } case CommandNames.Brace: { - var braceArguments = request.arguments; + var braceArguments = request.arguments; response = this.getBraceMatching(braceArguments.line, braceArguments.col, braceArguments.file); break; } case CommandNames.NavBar: { - var navBarArgs = request.arguments; + var navBarArgs = request.arguments; response = this.getNavigationBarItems(navBarArgs.file); break; }