Merge pull request #11651 from Microsoft/vladima/literals-in-protocol

switch enums in protocol to unions of literal types
This commit is contained in:
Vladimir Matveev 2016-10-17 15:46:05 -07:00
parent 039c6e5819
commit 05ebd1d5fb
5 changed files with 346 additions and 68 deletions

View File

@ -10,6 +10,8 @@ function endsWith(s: string, suffix: string) {
class DeclarationsWalker {
private visitedTypes: ts.Type[] = [];
private text = "";
private removedTypes: ts.Type[] = [];
private constructor(private typeChecker: ts.TypeChecker, private protocolFile: ts.SourceFile) {
}
@ -17,9 +19,18 @@ class DeclarationsWalker {
let text = "declare namespace ts.server.protocol {\n";
var walker = new DeclarationsWalker(typeChecker, protocolFile);
walker.visitTypeNodes(protocolFile);
return walker.text
text = walker.text
? `declare namespace ts.server.protocol {\n${walker.text}}`
: "";
if (walker.removedTypes) {
text += "\ndeclare namespace ts {\n";
text += " // these types are empty stubs for types from services and should not be used directly\n"
for (const type of walker.removedTypes) {
text += ` export type ${type.symbol.name} = never;\n`;
}
text += "}"
}
return text;
}
private processType(type: ts.Type): void {
@ -41,19 +52,18 @@ class DeclarationsWalker {
if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") {
return;
}
// splice declaration in final d.ts file
let text = decl.getFullText();
if (decl.kind === ts.SyntaxKind.EnumDeclaration && !(decl.flags & ts.NodeFlags.Const)) {
// patch enum declaration to make them constan
const declStart = decl.getStart() - decl.getFullStart();
const prefix = text.substring(0, declStart);
const suffix = text.substring(declStart + "enum".length, decl.getEnd() - decl.getFullStart());
text = prefix + "const enum" + suffix;
if (decl.kind === ts.SyntaxKind.EnumDeclaration) {
this.removedTypes.push(type);
return;
}
this.text += `${text}\n`;
else {
// splice declaration in final d.ts file
let text = decl.getFullText();
this.text += `${text}\n`;
// recursively pull all dependencies into result dts file
// recursively pull all dependencies into result dts file
this.visitTypeNodes(decl);
this.visitTypeNodes(decl);
}
}
}
}
@ -69,15 +79,37 @@ class DeclarationsWalker {
case ts.SyntaxKind.Parameter:
case ts.SyntaxKind.IndexSignature:
if (((<ts.VariableDeclaration | ts.MethodDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration | ts.PropertySignature | ts.MethodSignature | ts.IndexSignatureDeclaration>node.parent).type) === node) {
const type = this.typeChecker.getTypeAtLocation(node);
if (type && !(type.flags & ts.TypeFlags.TypeParameter)) {
this.processType(type);
}
this.processTypeOfNode(node);
}
break;
case ts.SyntaxKind.InterfaceDeclaration:
const heritageClauses = (<ts.InterfaceDeclaration>node.parent).heritageClauses;
if (heritageClauses) {
if (heritageClauses[0].token !== ts.SyntaxKind.ExtendsKeyword) {
throw new Error(`Unexpected kind of heritage clause: ${ts.SyntaxKind[heritageClauses[0].kind]}`);
}
for (const type of heritageClauses[0].types) {
this.processTypeOfNode(type);
}
}
break;
}
}
ts.forEachChild(node, n => this.visitTypeNodes(n));
}
private processTypeOfNode(node: ts.Node): void {
if (node.kind === ts.SyntaxKind.UnionType) {
for (const t of (<ts.UnionTypeNode>node).types) {
this.processTypeOfNode(t);
}
}
else {
const type = this.typeChecker.getTypeAtLocation(node);
if (type && !(type.flags & (ts.TypeFlags.TypeParameter))) {
this.processType(type);
}
}
}
}
@ -128,9 +160,12 @@ function generateProtocolFile(protocolTs: string, typeScriptServicesDts: string)
if (extraDeclarations) {
protocolDts += extraDeclarations;
}
protocolDts += "\nimport protocol = ts.server.protocol;";
protocolDts += "\nexport = protocol;";
protocolDts += "\nexport as namespace protocol;";
// do sanity check and try to compile generated text as standalone program
const sanityCheckProgram = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ false);
const diagnostics = [...program.getSyntacticDiagnostics(), ...program.getSemanticDiagnostics(), ...program.getGlobalDiagnostics()];
const diagnostics = [...sanityCheckProgram.getSyntacticDiagnostics(), ...sanityCheckProgram.getSemanticDiagnostics(), ...sanityCheckProgram.getGlobalDiagnostics()];
if (diagnostics.length) {
const flattenedDiagnostics = diagnostics.map(d => ts.flattenDiagnosticMessageText(d.messageText, "\n")).join("\n");
throw new Error(`Unexpected errors during sanity check: ${flattenedDiagnostics}`);

View File

@ -39,12 +39,18 @@ namespace ts.server {
getLogFileName: (): string => undefined
};
class TestSession extends Session {
getProjectService() {
return this.projectService;
}
}
describe("the Session class", () => {
let session: Session;
let session: TestSession;
let lastSent: protocol.Message;
beforeEach(() => {
session = new Session(mockHost, nullCancellationToken, /*useOneInferredProject*/ false, /*typingsInstaller*/ undefined, Utils.byteLength, process.hrtime, mockLogger, /*canUseEvents*/ true);
session = new TestSession(mockHost, nullCancellationToken, /*useOneInferredProject*/ false, /*typingsInstaller*/ undefined, Utils.byteLength, process.hrtime, mockLogger, /*canUseEvents*/ true);
session.send = (msg: protocol.Message) => {
lastSent = msg;
};
@ -55,7 +61,7 @@ namespace ts.server {
const req: protocol.FileRequest = {
command: CommandNames.Open,
seq: 0,
type: "command",
type: "request",
arguments: {
file: undefined
}
@ -67,7 +73,7 @@ namespace ts.server {
const req: protocol.Request = {
command: "foobar",
seq: 0,
type: "command"
type: "request"
};
session.executeCommand(req);
@ -85,7 +91,7 @@ namespace ts.server {
const req: protocol.ConfigureRequest = {
command: CommandNames.Configure,
seq: 0,
type: "command",
type: "request",
arguments: {
hostInfo: "unit test",
formatOptions: {
@ -106,6 +112,47 @@ namespace ts.server {
body: undefined
});
});
it ("should handle literal types in request", () => {
const configureRequest: protocol.ConfigureRequest = {
command: CommandNames.Configure,
seq: 0,
type: "request",
arguments: {
formatOptions: {
indentStyle: "Block"
}
}
};
session.onMessage(JSON.stringify(configureRequest));
assert.equal(session.getProjectService().getFormatCodeOptions().indentStyle, IndentStyle.Block);
const setOptionsRequest: protocol.SetCompilerOptionsForInferredProjectsRequest = {
command: CommandNames.CompilerOptionsForInferredProjects,
seq: 1,
type: "request",
arguments: {
options: {
module: "System",
target: "ES5",
jsx: "React",
newLine: "Lf",
moduleResolution: "Node"
}
}
};
session.onMessage(JSON.stringify(setOptionsRequest));
assert.deepEqual(
session.getProjectService().getCompilerOptionsForInferredProjects(),
<CompilerOptions>{
module: ModuleKind.System,
target: ScriptTarget.ES5,
jsx: JsxEmit.React,
newLine: NewLineKind.LineFeed,
moduleResolution: ModuleResolutionKind.NodeJs
});
});
});
describe("onMessage", () => {
@ -118,7 +165,7 @@ namespace ts.server {
const req: protocol.Request = {
command: name,
seq: i,
type: "command"
type: "request"
};
i++;
session.onMessage(JSON.stringify(req));
@ -151,7 +198,7 @@ namespace ts.server {
const req: protocol.ConfigureRequest = {
command: CommandNames.Configure,
seq: 0,
type: "command",
type: "request",
arguments: {
hostInfo: "unit test",
formatOptions: {
@ -175,7 +222,7 @@ namespace ts.server {
describe("send", () => {
it("is an overrideable handle which sends protocol messages over the wire", () => {
const msg = { seq: 0, type: "none" };
const msg: server.protocol.Request = { seq: 0, type: "request", command: "" };
const strmsg = JSON.stringify(msg);
const len = 1 + Utils.byteLength(strmsg, "utf8");
const resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`;
@ -203,7 +250,7 @@ namespace ts.server {
expect(session.executeCommand({
command,
seq: 0,
type: "command"
type: "request"
})).to.deep.equal(result);
});
it("throws when a duplicate handler is passed", () => {
@ -304,7 +351,7 @@ namespace ts.server {
expect(session.executeCommand({
seq: 0,
type: "command",
type: "request",
command: session.customHandler
})).to.deep.equal({
response: undefined,
@ -405,7 +452,7 @@ namespace ts.server {
this.seq++;
this.server.enqueue({
seq: this.seq,
type: "command",
type: "request",
command,
arguments: args
});

View File

@ -17,6 +17,68 @@ namespace ts.server {
(event: ProjectServiceEvent): void;
}
function prepareConvertersForEnumLikeCompilerOptions(commandLineOptions: CommandLineOption[]): Map<Map<number>> {
const map: Map<Map<number>> = createMap<Map<number>>();
for (const option of commandLineOptions) {
if (typeof option.type === "object") {
const optionMap = <Map<number>>option.type;
// verify that map contains only numbers
for (const id in optionMap) {
Debug.assert(typeof optionMap[id] === "number");
}
map[option.name] = optionMap;
}
}
return map;
}
const compilerOptionConverters = prepareConvertersForEnumLikeCompilerOptions(optionDeclarations);
const indentStyle = createMap({
"none": IndentStyle.None,
"block": IndentStyle.Block,
"smart": IndentStyle.Smart
});
export function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings {
if (typeof protocolOptions.indentStyle === "string") {
protocolOptions.indentStyle = indentStyle[protocolOptions.indentStyle.toLowerCase()];
Debug.assert(protocolOptions.indentStyle !== undefined);
}
return <any>protocolOptions;
}
export function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin {
for (const id in compilerOptionConverters) {
const propertyValue = protocolOptions[id];
if (typeof propertyValue === "string") {
const mappedValues = compilerOptionConverters[id];
protocolOptions[id] = mappedValues[propertyValue.toLowerCase()];
}
}
return <any>protocolOptions;
}
export function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind {
return typeof scriptKindName === "string"
? convertScriptKindName(scriptKindName)
: scriptKindName;
}
export function convertScriptKindName(scriptKindName: protocol.ScriptKindName) {
switch (scriptKindName) {
case "JS":
return ScriptKind.JS;
case "JSX":
return ScriptKind.JSX;
case "TS":
return ScriptKind.TS;
case "TSX":
return ScriptKind.TSX;
default:
return ScriptKind.Unknown;
}
}
/**
* This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project.
*/
@ -63,7 +125,7 @@ namespace ts.server {
const externalFilePropertyReader: FilePropertyReader<protocol.ExternalFile> = {
getFileName: x => x.fileName,
getScriptKind: x => x.scriptKind,
getScriptKind: x => tryConvertScriptKindName(x.scriptKind),
hasMixedContent: x => x.hasMixedContent
};
@ -214,6 +276,10 @@ namespace ts.server {
this.ensureInferredProjectsUpToDate();
}
getCompilerOptionsForInferredProjects() {
return this.compilerOptionsForInferredProjects;
}
updateTypingsForProject(response: SetTypings | InvalidateCachedTypings): void {
const project = this.findProject(response.projectName);
if (!project) {
@ -231,10 +297,10 @@ namespace ts.server {
}
setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.ExternalProjectCompilerOptions): void {
this.compilerOptionsForInferredProjects = projectCompilerOptions;
this.compilerOptionsForInferredProjects = convertCompilerOptions(projectCompilerOptions);
this.compileOnSaveForInferredProjects = projectCompilerOptions.compileOnSave;
for (const proj of this.inferredProjects) {
proj.setCompilerOptions(projectCompilerOptions);
proj.setCompilerOptions(this.compilerOptionsForInferredProjects);
proj.compileOnSaveEnabled = projectCompilerOptions.compileOnSave;
}
this.updateProjectGraphs(this.inferredProjects);
@ -744,12 +810,13 @@ namespace ts.server {
}
private createAndAddExternalProject(projectFileName: string, files: protocol.ExternalFile[], options: protocol.ExternalProjectCompilerOptions, typingOptions: TypingOptions) {
const compilerOptions = convertCompilerOptions(options);
const project = new ExternalProject(
projectFileName,
this,
this.documentRegistry,
options,
/*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(options, files, externalFilePropertyReader),
compilerOptions,
/*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(compilerOptions, files, externalFilePropertyReader),
options.compileOnSave === undefined ? true : options.compileOnSave);
this.addFilesToProjectAndUpdateGraph(project, files, externalFilePropertyReader, /*clientFileName*/ undefined, typingOptions, /*configFileErrors*/ undefined);
@ -1018,7 +1085,7 @@ namespace ts.server {
if (args.file) {
const info = this.getScriptInfoForNormalizedPath(toNormalizedPath(args.file));
if (info) {
info.setFormatOptions(args.formatOptions);
info.setFormatOptions(convertFormatOptions(args.formatOptions));
this.logger.info(`Host configuration update for file ${args.file}`);
}
}
@ -1028,7 +1095,7 @@ namespace ts.server {
this.logger.info(`Host information ${args.hostInfo}`);
}
if (args.formatOptions) {
mergeMaps(this.hostConfiguration.formatCodeOptions, args.formatOptions);
mergeMaps(this.hostConfiguration.formatCodeOptions, convertFormatOptions(args.formatOptions));
this.logger.info("Format host information updated");
}
}
@ -1142,7 +1209,7 @@ namespace ts.server {
const scriptInfo = this.getScriptInfo(file.fileName);
Debug.assert(!scriptInfo || !scriptInfo.isOpen);
const normalizedPath = scriptInfo ? scriptInfo.fileName : toNormalizedPath(file.fileName);
this.openClientFileWithNormalizedPath(normalizedPath, file.content, file.scriptKind, file.hasMixedContent);
this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent);
}
}
@ -1235,7 +1302,7 @@ namespace ts.server {
if (externalProject) {
if (!tsConfigFiles) {
// external project already exists and not config files were added - update the project and return;
this.updateNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, proj.options, proj.typingOptions, proj.options.compileOnSave, /*configFileErrors*/ undefined);
this.updateNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, convertCompilerOptions(proj.options), proj.typingOptions, proj.options.compileOnSave, /*configFileErrors*/ undefined);
return;
}
// some config files were added to external project (that previously were not there)

View File

@ -109,7 +109,7 @@ namespace ts.server.protocol {
/**
* One of "request", "response", or "event"
*/
type: string;
type: "request" | "response" | "event";
}
/**
@ -833,7 +833,7 @@ namespace ts.server.protocol {
/**
* Script kind of the file
*/
scriptKind?: ScriptKind;
scriptKind?: ScriptKindName | ts.ScriptKind;
/**
* Whether file has mixed content (i.e. .cshtml file that combines html markup with C#/JavaScript)
*/
@ -866,20 +866,23 @@ namespace ts.server.protocol {
typingOptions?: TypingOptions;
}
/**
* For external projects, some of the project settings are sent together with
* compiler settings.
*/
export interface ExternalProjectCompilerOptions extends CompilerOptions {
export interface CompileOnSaveMixin {
/**
* If compile on save is enabled for the project
*/
compileOnSave?: boolean;
}
/**
* For external projects, some of the project settings are sent together with
* compiler settings.
*/
export type ExternalProjectCompilerOptions = CompilerOptions & CompileOnSaveMixin;
/**
* Contains information about current project version
*/
/* @internal */
export interface ProjectVersionInfo {
/**
* Project name
@ -896,7 +899,7 @@ namespace ts.server.protocol {
/**
* Current set of compiler options for project
*/
options: CompilerOptions;
options: ts.CompilerOptions;
}
/**
@ -920,6 +923,7 @@ namespace ts.server.protocol {
* if changes is set - then this is the set of changes that should be applied to existing project
* otherwise - assume that nothing is changed
*/
/* @internal */
export interface ProjectFiles {
/**
* Information abount project verison
@ -938,6 +942,7 @@ namespace ts.server.protocol {
/**
* Combines project information with project level errors.
*/
/* @internal */
export interface ProjectFilesWithDiagnostics extends ProjectFiles {
/**
* List of errors in project
@ -1012,9 +1017,11 @@ namespace ts.server.protocol {
* Used to specify the script kind of the file explicitly. It could be one of the following:
* "TS", "JS", "TSX", "JSX"
*/
scriptKindName?: "TS" | "JS" | "TSX" | "JSX";
scriptKindName?: ScriptKindName;
}
export type ScriptKindName = "TS" | "JS" | "TSX" | "JSX";
/**
* Open request; value of command field is "open". Notify the
* server that the client has file open. The server will not
@ -1109,6 +1116,7 @@ namespace ts.server.protocol {
/**
* Arguments to SynchronizeProjectListRequest
*/
/* @internal */
export interface SynchronizeProjectListRequestArgs {
/**
* List of last known projects
@ -2056,4 +2064,141 @@ namespace ts.server.protocol {
export interface NavTreeResponse extends Response {
body?: NavigationTree;
}
export namespace IndentStyle {
export type None = "None";
export type Block = "Block";
export type Smart = "Smart";
}
export type IndentStyle = IndentStyle.None | IndentStyle.Block | IndentStyle.Smart;
export interface EditorSettings {
baseIndentSize?: number;
indentSize?: number;
tabSize?: number;
newLineCharacter?: string;
convertTabsToSpaces?: boolean;
indentStyle?: IndentStyle | ts.IndentStyle;
}
export interface FormatCodeSettings extends EditorSettings {
insertSpaceAfterCommaDelimiter?: boolean;
insertSpaceAfterSemicolonInForStatements?: boolean;
insertSpaceBeforeAndAfterBinaryOperators?: boolean;
insertSpaceAfterKeywordsInControlFlowStatements?: boolean;
insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean;
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean;
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean;
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
placeOpenBraceOnNewLineForFunctions?: boolean;
placeOpenBraceOnNewLineForControlBlocks?: boolean;
}
export interface CompilerOptions {
allowJs?: boolean;
allowSyntheticDefaultImports?: boolean;
allowUnreachableCode?: boolean;
allowUnusedLabels?: boolean;
baseUrl?: string;
charset?: string;
declaration?: boolean;
declarationDir?: string;
disableSizeLimit?: boolean;
emitBOM?: boolean;
emitDecoratorMetadata?: boolean;
experimentalDecorators?: boolean;
forceConsistentCasingInFileNames?: boolean;
inlineSourceMap?: boolean;
inlineSources?: boolean;
isolatedModules?: boolean;
jsx?: JsxEmit | ts.JsxEmit;
lib?: string[];
locale?: string;
mapRoot?: string;
maxNodeModuleJsDepth?: number;
module?: ModuleKind | ts.ModuleKind;
moduleResolution?: ModuleResolutionKind | ts.ModuleResolutionKind;
newLine?: NewLineKind | ts.NewLineKind;
noEmit?: boolean;
noEmitHelpers?: boolean;
noEmitOnError?: boolean;
noErrorTruncation?: boolean;
noFallthroughCasesInSwitch?: boolean;
noImplicitAny?: boolean;
noImplicitReturns?: boolean;
noImplicitThis?: boolean;
noUnusedLocals?: boolean;
noUnusedParameters?: boolean;
noImplicitUseStrict?: boolean;
noLib?: boolean;
noResolve?: boolean;
out?: string;
outDir?: string;
outFile?: string;
paths?: MapLike<string[]>;
preserveConstEnums?: boolean;
project?: string;
reactNamespace?: string;
removeComments?: boolean;
rootDir?: string;
rootDirs?: string[];
skipLibCheck?: boolean;
skipDefaultLibCheck?: boolean;
sourceMap?: boolean;
sourceRoot?: string;
strictNullChecks?: boolean;
suppressExcessPropertyErrors?: boolean;
suppressImplicitAnyIndexErrors?: boolean;
target?: ScriptTarget | ts.ScriptTarget;
traceResolution?: boolean;
types?: string[];
/** Paths used to used to compute primary types search locations */
typeRoots?: string[];
[option: string]: CompilerOptionsValue | undefined;
}
export namespace JsxEmit {
export type None = "None";
export type Preserve = "Preserve";
export type React = "React";
}
export type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React;
export namespace ModuleKind {
export type None = "None";
export type CommonJS = "CommonJS";
export type AMD = "AMD";
export type UMD = "UMD";
export type System = "System";
export type ES6 = "ES6";
export type ES2015 = "ES2015";
}
export type ModuleKind = ModuleKind.None | ModuleKind.CommonJS | ModuleKind.AMD | ModuleKind.UMD | ModuleKind.System | ModuleKind.ES6 | ModuleKind.ES2015;
export namespace ModuleResolutionKind {
export type Classic = "Classic";
export type Node = "Node";
}
export type ModuleResolutionKind = ModuleResolutionKind.Classic | ModuleResolutionKind.Node;
export namespace NewLineKind {
export type Crlf = "Crlf";
export type Lf = "Lf";
}
export type NewLineKind = NewLineKind.Crlf | NewLineKind.Lf;
export namespace ScriptTarget {
export type ES3 = "ES3";
export type ES5 = "ES5";
export type ES6 = "ES6";
export type ES2015 = "ES2015";
}
export type ScriptTarget = ScriptTarget.ES3 | ScriptTarget.ES5 | ScriptTarget.ES6 | ScriptTarget.ES2015;
}

View File

@ -807,7 +807,7 @@ namespace ts.server {
private getIndentation(args: protocol.IndentationRequestArgs) {
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
const position = this.getPosition(args, project.getScriptInfoForNormalizedPath(file));
const options = args.options || this.projectService.getFormatCodeOptions(file);
const options = args.options ? convertFormatOptions(args.options) : this.projectService.getFormatCodeOptions(file);
const indentation = project.getLanguageService(/*ensureSynchronized*/ false).getIndentationAtPosition(file, position, options);
return { position, indentation };
}
@ -874,19 +874,19 @@ namespace ts.server {
private getFormattingEditsForRangeFull(args: protocol.FormatRequestArgs) {
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
const options = args.options || this.projectService.getFormatCodeOptions(file);
const options = args.options ? convertFormatOptions(args.options) : this.projectService.getFormatCodeOptions(file);
return project.getLanguageService(/*ensureSynchronized*/ false).getFormattingEditsForRange(file, args.position, args.endPosition, options);
}
private getFormattingEditsForDocumentFull(args: protocol.FormatRequestArgs) {
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
const options = args.options || this.projectService.getFormatCodeOptions(file);
const options = args.options ? convertFormatOptions(args.options) : this.projectService.getFormatCodeOptions(file);
return project.getLanguageService(/*ensureSynchronized*/ false).getFormattingEditsForDocument(file, options);
}
private getFormattingEditsAfterKeystrokeFull(args: protocol.FormatOnKeyRequestArgs) {
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
const options = args.options || this.projectService.getFormatCodeOptions(file);
const options = args.options ? convertFormatOptions(args.options) : this.projectService.getFormatCodeOptions(file);
return project.getLanguageService(/*ensureSynchronized*/ false).getFormattingEditsAfterKeystroke(file, args.position, args.key, options);
}
@ -1426,24 +1426,8 @@ namespace ts.server {
[CommandNames.RenameInfoFull]: (request: protocol.FileLocationRequest) => {
return this.requiredResponse(this.getRenameInfo(request.arguments));
},
[CommandNames.Open]: (request: protocol.Request) => {
const openArgs = <protocol.OpenRequestArgs>request.arguments;
let scriptKind: ScriptKind;
switch (openArgs.scriptKindName) {
case "TS":
scriptKind = ScriptKind.TS;
break;
case "JS":
scriptKind = ScriptKind.JS;
break;
case "TSX":
scriptKind = ScriptKind.TSX;
break;
case "JSX":
scriptKind = ScriptKind.JSX;
break;
}
this.openClientFile(toNormalizedPath(openArgs.file), openArgs.fileContent, scriptKind);
[CommandNames.Open]: (request: protocol.OpenRequest) => {
this.openClientFile(toNormalizedPath(request.arguments.file), request.arguments.fileContent, convertScriptKindName(request.arguments.scriptKindName));
return this.notRequired();
},
[CommandNames.Quickinfo]: (request: protocol.QuickInfoRequest) => {