After reading the src\services code, it seems this is the interface any host of a language service must satisfy:
//
// Public interface of the host of a language service instance.
//
export interface ILanguageServiceHost extends TypeScript.ILogger {
getCompilationSettings(): TypeScript.CompilationSettings;
getScriptCount(): number;
getScriptId(scriptIndex: number): string;
getScriptSourceText(scriptIndex: number, start: number, end: number): string;
getScriptSourceLength(scriptIndex: number): number;
getScriptIsResident(scriptIndex: number): bool;
getScriptVersion(scriptIndex: number): number;
getScriptEditRangeSinceVersion(scriptIndex: number, scriptVersion: number): TypeScript.ScriptEditRange;
}
I haven't been able to find any documentation or samples, and while some methods are self-explanatory, others are not, notably:
getScriptId()
getScriptIsResident()
getScriptVersion()
getScriptEditRangeSinceVersion()
Is the language service API ready for use? Could someone explain briefly the purpose of the methods above?
Disclaimer: The language service hosting API will be changing in future versions. I'm not sure what the full extent of the changes will be -- I expect things will be mostly the same, but there will almost certainly be breaking changes.
Also, there's a full TypeScript implementation of the hosting API in src\harness\harness.ts
used for the language service unit tests you can refer to. Here's a conceptual breakdown of the functions you listed:
getScriptId()
You need to return a string that is unique for each file (script), but doesn't change from invocation from invocation. Returning the filename of the script would work nicely.
getScriptIsResident()
The compiler has a notion of a 'resident' file that isn't mutable (for example, lib.d.ts). Resident status is used for performance reasons -- for example, types that came out of a resident file are considered immutable (this is why you see oddness in Visual Studio when you try to extend a type defined in lib.d.ts). You can safely return false
for all files here, or if you know a file is immutable, you can return true
. The concept of a 'resident' file will go away in some future version of the compiler once the improved type-checker comes online.
getScriptVersion()
Here, you need to return a monotonically increasing number that is incremented whenever the source text of the script changes. The language service uses this number to determine whether or not it should do reparsing / retypechecking of the files.
getScriptEditRangeSinceVersion()
This function should return a list of edit ranges (hopefully self-explanatory) that have occurred between now and the specified prior version number (see above getScriptVersion
). Obviously this is a bit of a pain to implement, but it is allowable here to return TypeScript.ScriptEditRange.unknown()
, at which point the language service will do a full reparse of the file (significant perf impact, so try to do this sparingly in interactive contexts).