TypeScript/src/services/shims.ts

836 lines
33 KiB
TypeScript
Raw Normal View History

2014-07-19 01:55:11 +02:00
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
2014-07-13 01:04:16 +02:00
2014-07-25 00:33:59 +02:00
/// <reference path='services.ts' />
2014-07-25 20:21:17 +02:00
var debugObjectHost = (<any>this);
2014-07-25 02:36:06 +02:00
module ts {
export interface ScriptSnapshotShim {
2014-09-25 00:27:17 +02:00
/** Gets a portion of the script snapshot specified by [start, end). */
2014-07-13 01:04:16 +02:00
getText(start: number, end: number): string;
2014-09-25 00:27:17 +02:00
/** Gets the length of this script snapshot. */
2014-07-13 01:04:16 +02:00
getLength(): number;
2014-09-24 21:55:27 +02:00
/**
2014-09-25 00:27:17 +02:00
* Returns a JSON-encoded value of the type:
2014-09-24 21:55:27 +02:00
* { span: { start: number; length: number }; newLength: number }
*
2014-09-25 00:27:17 +02:00
* Or undefined value if there was no change.
2014-09-24 21:55:27 +02:00
*/
getChangeRange(oldSnapshot: ScriptSnapshotShim): string;
2014-07-19 01:55:11 +02:00
}
export interface Logger {
log(s: string): void;
trace(s: string): void;
error(s: string): void;
}
2014-09-24 21:55:27 +02:00
/** Public interface of the host of a language service shim instance.*/
2014-07-25 01:01:51 +02:00
export interface LanguageServiceShimHost extends Logger {
2014-07-19 01:55:11 +02:00
getCompilationSettings(): string;
2014-09-25 00:27:17 +02:00
/** Returns a JSON-encoded value of the type: string[] */
2014-07-19 01:55:11 +02:00
getScriptFileNames(): string;
getScriptVersion(fileName: string): string;
getScriptSnapshot(fileName: string): ScriptSnapshotShim;
2014-07-19 01:55:11 +02:00
getLocalizedDiagnosticMessages(): string;
2014-07-25 21:18:12 +02:00
getCancellationToken(): CancellationToken;
getCurrentDirectory(): string;
getDefaultLibFileName(options: string): string;
getNewLine?(): string;
2014-07-19 01:55:11 +02:00
}
2014-10-28 22:45:32 +01:00
///
/// Pre-processing
///
// Note: This is being using by the host (VS) and is marshaled back and forth.
// When changing this make sure the changes are reflected in the managed side as well
2014-10-29 21:58:27 +01:00
export interface IFileReference {
2014-10-28 22:45:32 +01:00
path: string;
position: number;
length: number;
}
2014-09-24 21:55:27 +02:00
/** Public interface of a language service instance shim. */
export interface ShimFactory {
registerShim(shim: Shim): void;
unregisterShim(shim: Shim): void;
2014-07-19 01:55:11 +02:00
}
export interface Shim {
2014-07-19 01:55:11 +02:00
dispose(dummy: any): void;
}
export interface LanguageServiceShim extends Shim {
2014-07-24 20:57:18 +02:00
languageService: LanguageService;
2014-07-19 01:55:11 +02:00
dispose(dummy: any): void;
refresh(throwOnError: boolean): void;
cleanupSemanticCache(): void;
getSyntacticDiagnostics(fileName: string): string;
getSemanticDiagnostics(fileName: string): string;
getCompilerOptionsDiagnostics(): string;
getSyntacticClassifications(fileName: string, start: number, length: number): string;
2015-02-03 21:40:37 +01:00
getSemanticClassifications(fileName: string, start: number, length: number): string;
getCompletionsAtPosition(fileName: string, position: number): string;
2014-07-19 01:55:11 +02:00
getCompletionEntryDetails(fileName: string, position: number, entryName: string): string;
2014-09-20 00:32:27 +02:00
getQuickInfoAtPosition(fileName: string, position: number): string;
2014-07-19 01:55:11 +02:00
getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): string;
getBreakpointStatementAtPosition(fileName: string, position: number): string;
getSignatureHelpItems(fileName: string, position: number): string;
2014-09-24 21:55:27 +02:00
/**
2014-09-25 00:27:17 +02:00
* Returns a JSON-encoded value of the type:
2014-09-24 21:55:27 +02:00
* { canRename: boolean, localizedErrorMessage: string, displayName: string, fullDisplayName: string, kind: string, kindModifiers: string, triggerSpan: { start; length } }
*/
getRenameInfo(fileName: string, position: number): string;
2014-07-19 01:55:11 +02:00
/**
* Returns a JSON-encoded value of the type:
* { fileName: string, textSpan: { start: number, length: number } }[]
*/
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): string;
2014-09-24 21:55:27 +02:00
/**
2014-09-25 00:27:17 +02:00
* Returns a JSON-encoded value of the type:
2014-09-24 21:55:27 +02:00
* { fileName: string; textSpan: { start: number; length: number}; kind: string; name: string; containerKind: string; containerName: string }
*
2014-09-25 00:27:17 +02:00
* Or undefined value if no definition can be found.
2014-09-24 21:55:27 +02:00
*/
2014-07-19 01:55:11 +02:00
getDefinitionAtPosition(fileName: string, position: number): string;
2014-09-24 21:55:27 +02:00
/**
2014-09-25 00:27:17 +02:00
* Returns a JSON-encoded value of the type:
2014-09-24 21:55:27 +02:00
* { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean }[]
*/
2014-07-19 01:55:11 +02:00
getReferencesAtPosition(fileName: string, position: number): string;
2014-09-24 21:55:27 +02:00
/**
2014-09-25 00:27:17 +02:00
* Returns a JSON-encoded value of the type:
2014-09-24 21:55:27 +02:00
* { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean }[]
*/
2014-07-19 01:55:11 +02:00
getOccurrencesAtPosition(fileName: string, position: number): string;
2014-09-24 21:55:27 +02:00
/**
2014-09-25 00:27:17 +02:00
* Returns a JSON-encoded value of the type:
2014-09-24 21:55:27 +02:00
* { name: string; kind: string; kindModifiers: string; containerName: string; containerKind: string; matchKind: string; fileName: string; textSpan: { start: number; length: number}; } [] = [];
*/
getNavigateToItems(searchValue: string, maxResultCount?: number): string;
2014-07-19 01:55:11 +02:00
2014-09-24 21:55:27 +02:00
/**
2014-09-25 00:27:17 +02:00
* Returns a JSON-encoded value of the type:
2014-09-24 21:55:27 +02:00
* { text: string; kind: string; kindModifiers: string; bolded: boolean; grayed: boolean; indent: number; spans: { start: number; length: number; }[]; childItems: <recursive use of this type>[] } [] = [];
*/
getNavigationBarItems(fileName: string): string;
2014-07-19 01:55:11 +02:00
2014-09-24 21:55:27 +02:00
/**
2014-09-25 00:27:17 +02:00
* Returns a JSON-encoded value of the type:
2014-09-24 21:55:27 +02:00
* { textSpan: { start: number, length: number }; hintSpan: { start: number, length: number }; bannerText: string; autoCollapse: boolean } [] = [];
*/
getOutliningSpans(fileName: string): string;
getTodoComments(fileName: string, todoCommentDescriptors: string): string;
2014-07-19 01:55:11 +02:00
getBraceMatchingAtPosition(fileName: string, position: number): string;
getIndentationAtPosition(fileName: string, position: number, options: string/*Services.EditorOptions*/): string;
getFormattingEditsForRange(fileName: string, start: number, end: number, options: string/*Services.FormatCodeOptions*/): string;
getFormattingEditsForDocument(fileName: string, options: string/*Services.FormatCodeOptions*/): string;
2014-07-19 01:55:11 +02:00
getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: string/*Services.FormatCodeOptions*/): string;
getEmitOutput(fileName: string): string;
2014-07-13 01:04:16 +02:00
}
export interface ClassifierShim extends Shim {
getClassificationsForLine(text: string, lexState: EndOfLineState, syntacticClassifierAbsent?: boolean): string;
2014-07-24 20:57:18 +02:00
}
2014-07-19 01:55:11 +02:00
export interface CoreServicesShim extends Shim {
getPreProcessedFileInfo(fileName: string, sourceText: IScriptSnapshot): string;
2014-07-24 20:57:18 +02:00
getDefaultCompilationSettings(): string;
}
2014-07-25 01:01:51 +02:00
function logInternalError(logger: Logger, err: Error) {
logger.log("*INTERNAL ERROR* - Exception in typescript services: " + err.message);
}
class ScriptSnapshotShimAdapter implements IScriptSnapshot {
2014-07-13 01:04:16 +02:00
private lineStartPositions: number[] = null;
constructor(private scriptSnapshotShim: ScriptSnapshotShim) {
2014-07-13 01:04:16 +02:00
}
public getText(start: number, end: number): string {
return this.scriptSnapshotShim.getText(start, end);
}
public getLength(): number {
return this.scriptSnapshotShim.getLength();
}
public getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange {
var oldSnapshotShim = <ScriptSnapshotShimAdapter>oldSnapshot;
var encoded = this.scriptSnapshotShim.getChangeRange(oldSnapshotShim.scriptSnapshotShim);
2014-07-13 01:04:16 +02:00
if (encoded == null) {
return null;
}
var decoded: { span: { start: number; length: number; }; newLength: number; } = JSON.parse(encoded);
return createTextChangeRange(
2014-12-10 22:45:08 +01:00
createTextSpan(decoded.span.start, decoded.span.length), decoded.newLength);
2014-07-13 01:04:16 +02:00
}
}
export class LanguageServiceShimHostAdapter implements LanguageServiceHost {
private files: string[];
constructor(private shimHost: LanguageServiceShimHost) {
2014-07-19 01:55:11 +02:00
}
2014-07-13 01:04:16 +02:00
public log(s: string): void {
this.shimHost.log(s);
}
public trace(s: string): void {
this.shimHost.trace(s);
}
public error(s: string): void {
this.shimHost.error(s);
}
2014-07-25 21:18:12 +02:00
public getCompilationSettings(): CompilerOptions {
2014-07-13 01:04:16 +02:00
var settingsJson = this.shimHost.getCompilationSettings();
if (settingsJson == null || settingsJson == "") {
2014-07-19 01:55:11 +02:00
throw Error("LanguageServiceShimHostAdapter.getCompilationSettings: empty compilationSettings");
return null;
2014-07-13 01:04:16 +02:00
}
2014-12-10 22:02:31 +01:00
return <CompilerOptions>JSON.parse(settingsJson);
2014-07-13 01:04:16 +02:00
}
public getScriptFileNames(): string[] {
var encoded = this.shimHost.getScriptFileNames();
return this.files = JSON.parse(encoded);
2014-07-13 01:04:16 +02:00
}
public getScriptSnapshot(fileName: string): IScriptSnapshot {
// Shim the API changes for 1.5 release. This should be removed once
// TypeScript 1.5 has shipped.
if (this.files && this.files.indexOf(fileName) < 0) {
return undefined;
}
var scriptSnapshot = this.shimHost.getScriptSnapshot(fileName);
return scriptSnapshot && new ScriptSnapshotShimAdapter(scriptSnapshot);
2014-07-13 01:04:16 +02:00
}
public getScriptVersion(fileName: string): string {
2014-07-13 01:04:16 +02:00
return this.shimHost.getScriptVersion(fileName);
}
public getLocalizedDiagnosticMessages(): any {
var diagnosticMessagesJson = this.shimHost.getLocalizedDiagnosticMessages();
if (diagnosticMessagesJson == null || diagnosticMessagesJson == "") {
return null;
}
2014-07-13 01:04:16 +02:00
try {
return JSON.parse(diagnosticMessagesJson);
}
catch (e) {
this.log(e.description || "diagnosticMessages.generated.json has invalid JSON format");
return null;
}
}
2014-07-25 21:18:12 +02:00
public getCancellationToken(): CancellationToken {
2014-07-19 01:55:11 +02:00
return this.shimHost.getCancellationToken();
}
public getCurrentDirectory(): string {
return this.shimHost.getCurrentDirectory();
}
public getDefaultLibFileName(options: CompilerOptions): string {
// Wrap the API changes for 1.5 release. This try/catch
// should be removed once TypeScript 1.5 has shipped.
try {
return this.shimHost.getDefaultLibFileName(JSON.stringify(options));
}
catch (e) {
return "";
}
}
2014-07-19 01:55:11 +02:00
}
2014-07-25 01:01:51 +02:00
function simpleForwardCall(logger: Logger, actionDescription: string, action: () => any): any {
2014-07-19 01:55:11 +02:00
logger.log(actionDescription);
var start = Date.now();
var result = action();
var end = Date.now();
logger.log(actionDescription + " completed in " + (end - start) + " msec");
if (typeof (result) === "string") {
var str = <string>result;
if (str.length > 128) {
str = str.substring(0, 128) + "...";
}
logger.log(" result.length=" + str.length + ", result='" + JSON.stringify(str) + "'");
}
return result;
}
2014-07-25 01:01:51 +02:00
function forwardJSONCall(logger: Logger, actionDescription: string, action: () => any): string {
2014-07-19 01:55:11 +02:00
try {
var result = simpleForwardCall(logger, actionDescription, action);
return JSON.stringify({ result: result });
}
catch (err) {
if (err instanceof OperationCanceledException) {
return JSON.stringify({ canceled: true });
}
2014-07-24 20:57:18 +02:00
logInternalError(logger, err);
2014-07-19 01:55:11 +02:00
err.description = actionDescription;
return JSON.stringify({ error: err });
}
}
class ShimBase implements Shim {
constructor(private factory: ShimFactory) {
2014-07-24 20:57:18 +02:00
factory.registerShim(this);
}
public dispose(dummy: any): void {
this.factory.unregisterShim(this);
}
}
class LanguageServiceShimObject extends ShimBase implements LanguageServiceShim {
2014-07-25 01:01:51 +02:00
private logger: Logger;
2014-07-19 01:55:11 +02:00
constructor(factory: ShimFactory,
private host: LanguageServiceShimHost,
2014-07-24 20:57:18 +02:00
public languageService: LanguageService) {
2014-07-19 01:55:11 +02:00
super(factory);
this.logger = this.host;
}
public forwardJSONCall(actionDescription: string, action: () => any): string {
2014-07-24 20:57:18 +02:00
return forwardJSONCall(this.logger, actionDescription, action);
2014-07-19 01:55:11 +02:00
}
2014-09-24 21:55:27 +02:00
/// DISPOSE
/**
* Ensure (almost) deterministic release of internal Javascript resources when
* some external native objects holds onto us (e.g. Com/Interop).
*/
2014-07-19 01:55:11 +02:00
public dispose(dummy: any): void {
this.logger.log("dispose()");
this.languageService.dispose();
this.languageService = null;
// force a GC
if (debugObjectHost && debugObjectHost.CollectGarbage) {
debugObjectHost.CollectGarbage();
this.logger.log("CollectGarbage()");
}
this.logger = null;
super.dispose(dummy);
}
2014-09-24 21:55:27 +02:00
/// REFRESH
/**
* Update the list of scripts known to the compiler
*/
2014-07-19 01:55:11 +02:00
public refresh(throwOnError: boolean): void {
this.forwardJSONCall(
"refresh(" + throwOnError + ")",
() => {
return <any>null;
});
}
public cleanupSemanticCache(): void {
this.forwardJSONCall(
"cleanupSemanticCache()",
() => {
this.languageService.cleanupSemanticCache();
return <any>null;
});
}
private realizeDiagnostics(diagnostics: Diagnostic[]): { message: string; start: number; length: number; category: string; }[]{
var newLine = this.getNewLine();
return diagnostics.map(d => this.realizeDiagnostic(d, newLine));
}
private realizeDiagnostic(diagnostic: Diagnostic, newLine: string): { message: string; start: number; length: number; category: string; } {
2014-07-19 01:55:11 +02:00
return {
message: flattenDiagnosticMessageText(diagnostic.messageText, newLine),
2014-07-19 01:55:11 +02:00
start: diagnostic.start,
length: diagnostic.length,
/// TODO: no need for the tolowerCase call
category: DiagnosticCategory[diagnostic.category].toLowerCase(),
code: diagnostic.code
2014-07-19 01:55:11 +02:00
};
}
public getSyntacticClassifications(fileName: string, start: number, length: number): string {
return this.forwardJSONCall(
"getSyntacticClassifications('" + fileName + "', " + start + ", " + length + ")",
() => {
2014-12-10 22:45:08 +01:00
var classifications = this.languageService.getSyntacticClassifications(fileName, createTextSpan(start, length));
return classifications;
});
}
2014-09-13 03:28:54 +02:00
public getSemanticClassifications(fileName: string, start: number, length: number): string {
return this.forwardJSONCall(
"getSemanticClassifications('" + fileName + "', " + start + ", " + length + ")",
() => {
2014-12-10 22:45:08 +01:00
var classifications = this.languageService.getSemanticClassifications(fileName, createTextSpan(start, length));
2014-09-13 03:28:54 +02:00
return classifications;
});
}
private getNewLine(): string {
return this.host.getNewLine ? this.host.getNewLine() : "\r\n";
}
2014-07-19 01:55:11 +02:00
public getSyntacticDiagnostics(fileName: string): string {
return this.forwardJSONCall(
"getSyntacticDiagnostics('" + fileName + "')",
2014-07-19 01:55:11 +02:00
() => {
var diagnostics = this.languageService.getSyntacticDiagnostics(fileName);
return this.realizeDiagnostics(diagnostics);
2014-07-19 01:55:11 +02:00
});
}
public getSemanticDiagnostics(fileName: string): string {
return this.forwardJSONCall(
"getSemanticDiagnostics('" + fileName + "')",
2014-07-19 01:55:11 +02:00
() => {
var diagnostics = this.languageService.getSemanticDiagnostics(fileName);
return this.realizeDiagnostics(diagnostics);
2014-07-19 01:55:11 +02:00
});
}
public getCompilerOptionsDiagnostics(): string {
return this.forwardJSONCall(
"getCompilerOptionsDiagnostics()",
() => {
var diagnostics = this.languageService.getCompilerOptionsDiagnostics();
return this.realizeDiagnostics(diagnostics);
2014-07-19 01:55:11 +02:00
});
}
/// QUICKINFO
2014-09-24 21:55:27 +02:00
/**
* Computes a string representation of the type at the requested position
* in the active file.
*/
2014-09-20 00:32:27 +02:00
public getQuickInfoAtPosition(fileName: string, position: number): string {
return this.forwardJSONCall(
"getQuickInfoAtPosition('" + fileName + "', " + position + ")",
() => {
var quickInfo = this.languageService.getQuickInfoAtPosition(fileName, position);
return quickInfo;
});
}
2014-07-19 01:55:11 +02:00
/// NAMEORDOTTEDNAMESPAN
2014-09-24 21:55:27 +02:00
/**
* Computes span information of the name or dotted name at the requested position
* in the active file.
*/
2014-07-19 01:55:11 +02:00
public getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): string {
return this.forwardJSONCall(
"getNameOrDottedNameSpan('" + fileName + "', " + startPos + ", " + endPos + ")",
2014-07-19 01:55:11 +02:00
() => {
var spanInfo = this.languageService.getNameOrDottedNameSpan(fileName, startPos, endPos);
return spanInfo;
});
}
2014-09-24 21:55:27 +02:00
/**
* STATEMENTSPAN
* Computes span information of statement at the requested position in the active file.
*/
2014-07-19 01:55:11 +02:00
public getBreakpointStatementAtPosition(fileName: string, position: number): string {
return this.forwardJSONCall(
"getBreakpointStatementAtPosition('" + fileName + "', " + position + ")",
2014-07-19 01:55:11 +02:00
() => {
var spanInfo = this.languageService.getBreakpointStatementAtPosition(fileName, position);
return spanInfo;
});
}
/// SIGNATUREHELP
public getSignatureHelpItems(fileName: string, position: number): string {
2014-07-19 01:55:11 +02:00
return this.forwardJSONCall(
"getSignatureHelpItems('" + fileName + "', " + position + ")",
2014-07-19 01:55:11 +02:00
() => {
var signatureInfo = this.languageService.getSignatureHelpItems(fileName, position);
2014-07-19 01:55:11 +02:00
return signatureInfo;
});
}
/// GOTO DEFINITION
2014-09-24 21:55:27 +02:00
/**
* Computes the definition location and file for the symbol
* at the requested position.
*/
2014-07-19 01:55:11 +02:00
public getDefinitionAtPosition(fileName: string, position: number): string {
return this.forwardJSONCall(
"getDefinitionAtPosition('" + fileName + "', " + position + ")",
2014-07-19 01:55:11 +02:00
() => {
return this.languageService.getDefinitionAtPosition(fileName, position);
});
}
public getRenameInfo(fileName: string, position: number): string {
return this.forwardJSONCall(
"getRenameInfo('" + fileName + "', " + position + ")",
() => {
return this.languageService.getRenameInfo(fileName, position);
});
}
public findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): string {
return this.forwardJSONCall(
"findRenameLocations('" + fileName + "', " + position + ", " + findInStrings + ", " + findInComments + ")",
() => {
return this.languageService.findRenameLocations(fileName, position, findInStrings, findInComments);
});
}
2014-07-19 01:55:11 +02:00
/// GET BRACE MATCHING
public getBraceMatchingAtPosition(fileName: string, position: number): string {
return this.forwardJSONCall(
"getBraceMatchingAtPosition('" + fileName + "', " + position + ")",
2014-07-19 01:55:11 +02:00
() => {
var textRanges = this.languageService.getBraceMatchingAtPosition(fileName, position);
return textRanges;
});
}
/// GET SMART INDENT
public getIndentationAtPosition(fileName: string, position: number, options: string /*Services.EditorOptions*/): string {
return this.forwardJSONCall(
"getIndentationAtPosition('" + fileName + "', " + position + ")",
2014-07-19 01:55:11 +02:00
() => {
2014-07-24 20:57:18 +02:00
var localOptions: EditorOptions = JSON.parse(options);
return this.languageService.getIndentationAtPosition(fileName, position, localOptions);
2014-07-19 01:55:11 +02:00
});
}
/// GET REFERENCES
2014-09-24 21:55:27 +02:00
/**
* Return references to a symbol at the requested position.
* References are separated by "\n".
* Each reference is a "fileindex min lim" sub-string.
*/
2014-07-19 01:55:11 +02:00
public getReferencesAtPosition(fileName: string, position: number): string {
return this.forwardJSONCall(
"getReferencesAtPosition('" + fileName + "', " + position + ")",
2014-07-19 01:55:11 +02:00
() => {
return this.languageService.getReferencesAtPosition(fileName, position);
});
}
2014-07-13 01:04:16 +02:00
2014-07-19 01:55:11 +02:00
public getOccurrencesAtPosition(fileName: string, position: number): string {
return this.forwardJSONCall(
"getOccurrencesAtPosition('" + fileName + "', " + position + ")",
2014-07-19 01:55:11 +02:00
() => {
return this.languageService.getOccurrencesAtPosition(fileName, position);
});
}
/// COMPLETION LISTS
2014-09-24 21:55:27 +02:00
/**
* Get a string based representation of the completions
* to provide at the given source position and providing a member completion
* list if requested.
*/
public getCompletionsAtPosition(fileName: string, position: number) {
2014-07-19 01:55:11 +02:00
return this.forwardJSONCall(
"getCompletionsAtPosition('" + fileName + "', " + position + ")",
2014-07-19 01:55:11 +02:00
() => {
var completion = this.languageService.getCompletionsAtPosition(fileName, position);
2014-07-19 01:55:11 +02:00
return completion;
});
}
2014-09-24 21:55:27 +02:00
/** Get a string based representation of a completion list entry details */
2014-07-19 01:55:11 +02:00
public getCompletionEntryDetails(fileName: string, position: number, entryName: string) {
return this.forwardJSONCall(
"getCompletionEntryDetails('" + fileName + "', " + position + ", " + entryName + ")",
2014-07-19 01:55:11 +02:00
() => {
var details = this.languageService.getCompletionEntryDetails(fileName, position, entryName);
return details;
});
}
public getFormattingEditsForRange(fileName: string, start: number, end: number, options: string/*Services.FormatCodeOptions*/): string {
2014-07-19 01:55:11 +02:00
return this.forwardJSONCall(
"getFormattingEditsForRange('" + fileName + "', " + start + ", " + end + ")",
2014-07-19 01:55:11 +02:00
() => {
var localOptions: ts.FormatCodeOptions = JSON.parse(options);
var edits = this.languageService.getFormattingEditsForRange(fileName, start, end, localOptions);
2014-07-19 01:55:11 +02:00
return edits;
});
}
public getFormattingEditsForDocument(fileName: string, options: string/*Services.FormatCodeOptions*/): string {
2014-07-19 01:55:11 +02:00
return this.forwardJSONCall(
"getFormattingEditsForDocument('" + fileName + "')",
2014-07-19 01:55:11 +02:00
() => {
var localOptions: ts.FormatCodeOptions = JSON.parse(options);
var edits = this.languageService.getFormattingEditsForDocument(fileName, localOptions);
2014-07-19 01:55:11 +02:00
return edits;
});
}
public getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: string/*Services.FormatCodeOptions*/): string {
return this.forwardJSONCall(
"getFormattingEditsAfterKeystroke('" + fileName + "', " + position + ", '" + key + "')",
2014-07-19 01:55:11 +02:00
() => {
var localOptions: ts.FormatCodeOptions = JSON.parse(options);
2014-07-19 01:55:11 +02:00
var edits = this.languageService.getFormattingEditsAfterKeystroke(fileName, position, key, localOptions);
return edits;
});
}
/// NAVIGATE TO
2014-09-24 21:55:27 +02:00
/** Return a list of symbols that are interesting to navigate to */
public getNavigateToItems(searchValue: string, maxResultCount?: number): string {
2014-07-19 01:55:11 +02:00
return this.forwardJSONCall(
"getNavigateToItems('" + searchValue + "', " + maxResultCount+ ")",
2014-07-19 01:55:11 +02:00
() => {
var items = this.languageService.getNavigateToItems(searchValue, maxResultCount);
return items;
2014-07-19 01:55:11 +02:00
});
}
public getNavigationBarItems(fileName: string): string {
2014-07-19 01:55:11 +02:00
return this.forwardJSONCall(
"getNavigationBarItems('" + fileName + "')",
2014-07-19 01:55:11 +02:00
() => {
var items = this.languageService.getNavigationBarItems(fileName);
return items;
2014-07-19 01:55:11 +02:00
});
}
public getOutliningSpans(fileName: string): string {
2014-07-19 01:55:11 +02:00
return this.forwardJSONCall(
"getOutliningSpans('" + fileName + "')",
2014-07-19 01:55:11 +02:00
() => {
var items = this.languageService.getOutliningSpans(fileName);
return items;
});
}
public getTodoComments(fileName: string, descriptors: string): string {
return this.forwardJSONCall(
"getTodoComments('" + fileName + "')",
() => {
var items = this.languageService.getTodoComments(fileName, JSON.parse(descriptors));
return items;
2014-07-19 01:55:11 +02:00
});
}
/// Emit
public getEmitOutput(fileName: string): string {
return this.forwardJSONCall(
"getEmitOutput('" + fileName + "')",
2014-07-19 01:55:11 +02:00
() => {
var output = this.languageService.getEmitOutput(fileName);
2015-02-06 23:22:32 +01:00
// Shim the API changes for 1.5 release. This should be removed once
// TypeScript 1.5 has shipped.
(<any>output).emitOutputStatus = output.emitSkipped ? 1 : 0;
2014-07-19 01:55:11 +02:00
return output;
});
}
}
class ClassifierShimObject extends ShimBase implements ClassifierShim {
2014-07-24 20:57:18 +02:00
public classifier: Classifier;
2014-07-19 01:55:11 +02:00
constructor(factory: ShimFactory) {
2014-07-19 01:55:11 +02:00
super(factory);
this.classifier = createClassifier();
2014-07-19 01:55:11 +02:00
}
/// COLORIZATION
public getClassificationsForLine(text: string, lexState: EndOfLineState, classifyKeywordsInGenerics?: boolean): string {
var classification = this.classifier.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics);
2014-07-19 01:55:11 +02:00
var items = classification.entries;
var result = "";
for (var i = 0; i < items.length; i++) {
result += items[i].length + "\n";
result += items[i].classification + "\n";
}
result += classification.finalLexState;
return result;
}
}
class CoreServicesShimObject extends ShimBase implements CoreServicesShim {
2014-08-17 04:03:07 +02:00
constructor(factory: ShimFactory, public logger: Logger) {
2014-07-19 01:55:11 +02:00
super(factory);
}
private forwardJSONCall(actionDescription: string, action: () => any): any {
2014-08-17 04:03:07 +02:00
return forwardJSONCall(this.logger, actionDescription, action);
2014-07-19 01:55:11 +02:00
}
public getPreProcessedFileInfo(fileName: string, sourceTextSnapshot: IScriptSnapshot): string {
2014-07-19 01:55:11 +02:00
return this.forwardJSONCall(
"getPreProcessedFileInfo('" + fileName + "')",
2014-07-19 01:55:11 +02:00
() => {
var result = preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()));
2014-10-28 22:45:32 +01:00
var convertResult = {
referencedFiles: <IFileReference[]>[],
importedFiles: <IFileReference[]>[],
isLibFile: result.isLibFile
};
forEach(result.referencedFiles, refFile => {
convertResult.referencedFiles.push({
path: normalizePath(refFile.fileName),
2014-10-28 22:45:32 +01:00
position: refFile.pos,
length: refFile.end - refFile.pos
});
});
forEach(result.importedFiles, importedFile => {
convertResult.importedFiles.push({
path: normalizeSlashes(importedFile.fileName),
2014-10-28 22:45:32 +01:00
position: importedFile.pos,
length: importedFile.end - importedFile.pos
});
});
return convertResult;
2014-07-19 01:55:11 +02:00
});
}
public getDefaultCompilationSettings(): string {
return this.forwardJSONCall(
"getDefaultCompilationSettings()",
() => {
return getDefaultCompilerOptions();
2014-07-19 01:55:11 +02:00
});
}
2014-07-13 01:04:16 +02:00
}
export class TypeScriptServicesFactory implements ShimFactory {
private _shims: Shim[] = [];
2014-07-25 20:21:17 +02:00
private documentRegistry: DocumentRegistry = createDocumentRegistry();
/*
* Returns script API version.
*/
public getServicesVersion(): string {
return servicesVersion;
}
public createLanguageServiceShim(host: LanguageServiceShimHost): LanguageServiceShim {
try {
var hostAdapter = new LanguageServiceShimHostAdapter(host);
2014-08-08 08:32:43 +02:00
var languageService = createLanguageService(hostAdapter, this.documentRegistry);
return new LanguageServiceShimObject(this, host, languageService);
}
catch (err) {
2014-07-24 20:57:18 +02:00
logInternalError(host, err);
throw err;
}
}
2014-08-17 04:03:07 +02:00
public createClassifierShim(logger: Logger): ClassifierShim {
try {
return new ClassifierShimObject(this);
}
catch (err) {
2014-08-17 04:03:07 +02:00
logInternalError(logger, err);
throw err;
}
}
2014-08-17 04:03:07 +02:00
public createCoreServicesShim(logger: Logger): CoreServicesShim {
try {
2014-08-17 04:20:40 +02:00
return new CoreServicesShimObject(this, logger);
}
catch (err) {
2014-08-17 04:03:07 +02:00
logInternalError(logger, err);
throw err;
}
}
public close(): void {
// Forget all the registered shims
this._shims = [];
2014-07-25 20:21:17 +02:00
this.documentRegistry = createDocumentRegistry();
}
public registerShim(shim: Shim): void {
this._shims.push(shim);
}
public unregisterShim(shim: Shim): void {
for (var i = 0, n = this._shims.length; i < n; i++) {
if (this._shims[i] === shim) {
delete this._shims[i];
return;
}
}
throw new Error("Invalid operation");
}
}
2014-12-02 00:52:34 +01:00
2014-12-03 00:16:09 +01:00
// Here we expose the TypeScript services as an external module
// so that it may be consumed easily like a node module.
2014-12-02 00:52:34 +01:00
declare var module: any;
if (typeof module !== "undefined" && module.exports) {
module.exports = ts;
}
2014-07-19 01:55:11 +02:00
}
2014-09-10 02:41:34 +02:00
/// TODO: this is used by VS, clean this up on both sides of the interface
2014-07-25 02:36:06 +02:00
module TypeScript.Services {
export var TypeScriptServicesFactory = ts.TypeScriptServicesFactory;
}