Session: don't return undefined if a response is required (#17165)

* Session: don't return undefined if a response is required

* Use ReadonlyArray and emptyArray

* Remove inferred return type
This commit is contained in:
Andy
2017-08-09 13:46:47 -07:00
committed by GitHub
parent b8c37bb50c
commit f124e19971
5 changed files with 48 additions and 46 deletions

View File

@@ -4,12 +4,12 @@
namespace ts.projectSystem {
describe("Project errors", () => {
function checkProjectErrors(projectFiles: server.ProjectFilesWithTSDiagnostics, expectedErrors: string[]) {
function checkProjectErrors(projectFiles: server.ProjectFilesWithTSDiagnostics, expectedErrors: ReadonlyArray<string>): void {
assert.isTrue(projectFiles !== undefined, "missing project files");
checkProjectErrorsWorker(projectFiles.projectErrors, expectedErrors);
}
function checkProjectErrorsWorker(errors: Diagnostic[], expectedErrors: string[]) {
function checkProjectErrorsWorker(errors: ReadonlyArray<Diagnostic>, expectedErrors: ReadonlyArray<string>): void {
assert.equal(errors ? errors.length : 0, expectedErrors.length, `expected ${expectedErrors.length} error in the list`);
if (expectedErrors.length) {
for (let i = 0; i < errors.length; i++) {

View File

@@ -22,7 +22,7 @@ namespace ts.server {
export interface ConfigFileDiagEvent {
eventName: typeof ConfigFileDiagEvent;
data: { triggerFile: string, configFileName: string, diagnostics: Diagnostic[] };
data: { triggerFile: string, configFileName: string, diagnostics: ReadonlyArray<Diagnostic> };
}
export interface ProjectLanguageServiceStateEvent {
@@ -200,7 +200,7 @@ namespace ts.server {
/**
* This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project.
*/
export function combineProjectOutput<T>(projects: Project[], action: (project: Project) => T[], comparer?: (a: T, b: T) => number, areEqual?: (a: T, b: T) => boolean) {
export function combineProjectOutput<T>(projects: ReadonlyArray<Project>, action: (project: Project) => ReadonlyArray<T>, comparer?: (a: T, b: T) => number, areEqual?: (a: T, b: T) => boolean) {
const result = flatMap(projects, action).sort(comparer);
return projects.length > 1 ? deduplicate(result, areEqual) : result;
}
@@ -220,14 +220,14 @@ namespace ts.server {
interface OpenConfigFileResult {
success: boolean;
errors?: Diagnostic[];
errors?: ReadonlyArray<Diagnostic>;
project?: ConfiguredProject;
}
export interface OpenConfiguredProjectResult {
configFileName?: NormalizedPath;
configFileErrors?: Diagnostic[];
configFileErrors?: ReadonlyArray<Diagnostic>;
}
interface FilePropertyReader<T> {
@@ -1100,18 +1100,18 @@ namespace ts.server {
}
}
private reportConfigFileDiagnostics(configFileName: string, diagnostics: Diagnostic[], triggerFile: string) {
private reportConfigFileDiagnostics(configFileName: string, diagnostics: ReadonlyArray<Diagnostic>, triggerFile: string) {
if (!this.eventHandler) {
return;
}
this.eventHandler(<ConfigFileDiagEvent>{
eventName: ConfigFileDiagEvent,
data: { configFileName, diagnostics: diagnostics || [], triggerFile }
data: { configFileName, diagnostics: diagnostics || emptyArray, triggerFile }
});
}
private createAndAddConfiguredProject(configFileName: NormalizedPath, projectOptions: ProjectOptions, configFileErrors: Diagnostic[], clientFileName?: string) {
private createAndAddConfiguredProject(configFileName: NormalizedPath, projectOptions: ProjectOptions, configFileErrors: ReadonlyArray<Diagnostic>, clientFileName?: string) {
const sizeLimitExceeded = this.exceededTotalSizeLimitForNonTsFiles(configFileName, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader);
const project = new ConfiguredProject(
configFileName,
@@ -1143,7 +1143,7 @@ namespace ts.server {
}
}
private addFilesToProjectAndUpdateGraph<T>(project: ConfiguredProject | ExternalProject, files: T[], propertyReader: FilePropertyReader<T>, clientFileName: string, typeAcquisition: TypeAcquisition, configFileErrors: Diagnostic[]): void {
private addFilesToProjectAndUpdateGraph<T>(project: ConfiguredProject | ExternalProject, files: T[], propertyReader: FilePropertyReader<T>, clientFileName: string, typeAcquisition: TypeAcquisition, configFileErrors: ReadonlyArray<Diagnostic>): void {
let errors: Diagnostic[];
for (const f of files) {
const rootFilename = propertyReader.getFileName(f);
@@ -1456,7 +1456,7 @@ namespace ts.server {
openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult {
let configFileName: NormalizedPath;
let configFileErrors: Diagnostic[];
let configFileErrors: ReadonlyArray<Diagnostic>;
let project: ConfiguredProject | ExternalProject = this.findContainingExternalProject(fileName);
if (!project) {

View File

@@ -54,7 +54,7 @@ namespace ts.server {
/* @internal */
export interface ProjectFilesWithTSDiagnostics extends protocol.ProjectFiles {
projectErrors: Diagnostic[];
projectErrors: ReadonlyArray<Diagnostic>;
}
export class UnresolvedImportsMap {
@@ -147,7 +147,7 @@ namespace ts.server {
private typingFiles: SortedReadonlyArray<string>;
protected projectErrors: Diagnostic[];
protected projectErrors: ReadonlyArray<Diagnostic>;
public typesVersion = 0;
@@ -1045,7 +1045,7 @@ namespace ts.server {
return getDirectoryPath(this.getConfigFilePath());
}
setProjectErrors(projectErrors: Diagnostic[]) {
setProjectErrors(projectErrors: ReadonlyArray<Diagnostic>) {
this.projectErrors = projectErrors;
}
@@ -1189,7 +1189,7 @@ namespace ts.server {
return this.typeAcquisition;
}
setProjectErrors(projectErrors: Diagnostic[]) {
setProjectErrors(projectErrors: ReadonlyArray<Diagnostic>) {
this.projectErrors = projectErrors;
}

View File

@@ -914,7 +914,7 @@ namespace ts.server.protocol {
/**
* An array of span groups (one per file) that refer to the item to be renamed.
*/
locs: SpanGroup[];
locs: ReadonlyArray<SpanGroup>;
}
/**

View File

@@ -379,7 +379,7 @@ namespace ts.server {
this.host.write(formatMessage(msg, this.logger, this.byteLength, this.host.newLine));
}
public configFileDiagnosticEvent(triggerFile: string, configFile: string, diagnostics: Diagnostic[]) {
public configFileDiagnosticEvent(triggerFile: string, configFile: string, diagnostics: ReadonlyArray<Diagnostic>) {
const bakedDiags = map(diagnostics, diagnostic => formatConfigFileDiag(diagnostic, /*includeFileName*/ true));
const ev: protocol.ConfigFileDiagnosticEvent = {
seq: 0,
@@ -539,7 +539,7 @@ namespace ts.server {
);
}
private convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnostics: Diagnostic[]) {
private convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnostics: ReadonlyArray<Diagnostic>): protocol.DiagnosticWithLinePosition[] {
return diagnostics.map(d => <protocol.DiagnosticWithLinePosition>{
message: flattenDiagnosticMessageText(d.messageText, this.host.newLine),
start: d.start,
@@ -565,7 +565,7 @@ namespace ts.server {
);
}
private convertToDiagnosticsWithLinePosition(diagnostics: Diagnostic[], scriptInfo: ScriptInfo) {
private convertToDiagnosticsWithLinePosition(diagnostics: ReadonlyArray<Diagnostic>, scriptInfo: ScriptInfo): protocol.DiagnosticWithLinePosition[] {
return diagnostics.map(d => <protocol.DiagnosticWithLinePosition>{
message: flattenDiagnosticMessageText(d.messageText, this.host.newLine),
start: d.start,
@@ -578,10 +578,12 @@ namespace ts.server {
});
}
private getDiagnosticsWorker(args: protocol.FileRequestArgs, isSemantic: boolean, selector: (project: Project, file: string) => Diagnostic[], includeLinePosition: boolean) {
private getDiagnosticsWorker(
args: protocol.FileRequestArgs, isSemantic: boolean, selector: (project: Project, file: string) => ReadonlyArray<Diagnostic>, includeLinePosition: boolean
): ReadonlyArray<protocol.DiagnosticWithLinePosition> | ReadonlyArray<protocol.Diagnostic> {
const { project, file } = this.getFileAndProject(args);
if (isSemantic && isDeclarationFileInJSOnlyNonConfiguredProject(project, file)) {
return [];
return emptyArray;
}
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const diagnostics = selector(project, file);
@@ -590,14 +592,14 @@ namespace ts.server {
: diagnostics.map(d => formatDiag(file, project, d));
}
private getDefinition(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.FileSpan[] | DefinitionInfo[] {
private getDefinition(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.FileSpan> | ReadonlyArray<DefinitionInfo> {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
const definitions = project.getLanguageService().getDefinitionAtPosition(file, position);
if (!definitions) {
return undefined;
return emptyArray;
}
if (simplifiedResult) {
@@ -615,7 +617,7 @@ namespace ts.server {
}
}
private getTypeDefinition(args: protocol.FileLocationRequestArgs): protocol.FileSpan[] {
private getTypeDefinition(args: protocol.FileLocationRequestArgs): ReadonlyArray<protocol.FileSpan> {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
@@ -635,12 +637,12 @@ namespace ts.server {
});
}
private getImplementation(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.FileSpan[] | ImplementationLocation[] {
private getImplementation(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.FileSpan> | ReadonlyArray<ImplementationLocation> {
const { file, project } = this.getFileAndProject(args);
const position = this.getPosition(args, project.getScriptInfoForNormalizedPath(file));
const implementations = project.getLanguageService().getImplementationAtPosition(file, position);
if (!implementations) {
return [];
return emptyArray;
}
if (simplifiedResult) {
return implementations.map(({ fileName, textSpan }) => {
@@ -657,7 +659,7 @@ namespace ts.server {
}
}
private getOccurrences(args: protocol.FileLocationRequestArgs): protocol.OccurrencesResponseItem[] {
private getOccurrences(args: protocol.FileLocationRequestArgs): ReadonlyArray<protocol.OccurrencesResponseItem> {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
@@ -665,7 +667,7 @@ namespace ts.server {
const occurrences = project.getLanguageService().getOccurrencesAtPosition(file, position);
if (!occurrences) {
return undefined;
return emptyArray;
}
return occurrences.map(occurrence => {
@@ -687,17 +689,17 @@ namespace ts.server {
});
}
private getSyntacticDiagnosticsSync(args: protocol.SyntacticDiagnosticsSyncRequestArgs): protocol.Diagnostic[] | protocol.DiagnosticWithLinePosition[] {
private getSyntacticDiagnosticsSync(args: protocol.SyntacticDiagnosticsSyncRequestArgs): ReadonlyArray<protocol.Diagnostic> | ReadonlyArray<protocol.DiagnosticWithLinePosition> {
const { configFile } = this.getConfigFileAndProject(args);
if (configFile) {
// all the config file errors are reported as part of semantic check so nothing to report here
return [];
return emptyArray;
}
return this.getDiagnosticsWorker(args, /*isSemantic*/ false, (project, file) => project.getLanguageService().getSyntacticDiagnostics(file), args.includeLinePosition);
}
private getSemanticDiagnosticsSync(args: protocol.SemanticDiagnosticsSyncRequestArgs): protocol.Diagnostic[] | protocol.DiagnosticWithLinePosition[] {
private getSemanticDiagnosticsSync(args: protocol.SemanticDiagnosticsSyncRequestArgs): ReadonlyArray<protocol.Diagnostic> | ReadonlyArray<protocol.DiagnosticWithLinePosition> {
const { configFile, project } = this.getConfigFileAndProject(args);
if (configFile) {
return this.getConfigFileDiagnostics(configFile, project, args.includeLinePosition);
@@ -705,7 +707,7 @@ namespace ts.server {
return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSemanticDiagnostics(file), args.includeLinePosition);
}
private getDocumentHighlights(args: protocol.DocumentHighlightsRequestArgs, simplifiedResult: boolean): protocol.DocumentHighlightsItem[] | DocumentHighlights[] {
private getDocumentHighlights(args: protocol.DocumentHighlightsRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.DocumentHighlightsItem> | ReadonlyArray<DocumentHighlights> {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
@@ -796,7 +798,7 @@ namespace ts.server {
return info.getDefaultProject();
}
private getRenameLocations(args: protocol.RenameRequestArgs, simplifiedResult: boolean): protocol.RenameResponseBody | RenameLocation[] {
private getRenameLocations(args: protocol.RenameRequestArgs, simplifiedResult: boolean): protocol.RenameResponseBody | ReadonlyArray<RenameLocation> {
const file = toNormalizedPath(args.file);
const info = this.projectService.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, info);
@@ -813,7 +815,7 @@ namespace ts.server {
if (!renameInfo.canRename) {
return {
info: renameInfo,
locs: []
locs: emptyArray
};
}
@@ -822,7 +824,7 @@ namespace ts.server {
(project: Project) => {
const renameLocations = project.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments);
if (!renameLocations) {
return [];
return emptyArray;
}
return renameLocations.map(location => {
@@ -899,7 +901,7 @@ namespace ts.server {
}
}
private getReferences(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.ReferencesResponseBody | ReferencedSymbol[] {
private getReferences(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.ReferencesResponseBody | ReadonlyArray<ReferencedSymbol> {
const file = toNormalizedPath(args.file);
const projects = this.getProjects(args);
@@ -909,7 +911,7 @@ namespace ts.server {
if (simplifiedResult) {
const nameInfo = defaultProject.getLanguageService().getQuickInfoAtPosition(file, position);
if (!nameInfo) {
return undefined;
return emptyArray;
}
const displayString = displayPartsToString(nameInfo.displayParts);
@@ -921,7 +923,7 @@ namespace ts.server {
(project: Project) => {
const references = project.getLanguageService().getReferencesAtPosition(file, position);
if (!references) {
return [];
return emptyArray;
}
return references.map(ref => {
@@ -978,7 +980,7 @@ namespace ts.server {
if (this.eventHandler) {
this.eventHandler({
eventName: "configFileDiag",
data: { triggerFile: fileName, configFileName, diagnostics: configFileErrors || [] }
data: { triggerFile: fileName, configFileName, diagnostics: configFileErrors || emptyArray }
});
}
}
@@ -1163,7 +1165,7 @@ namespace ts.server {
});
}
private getCompletions(args: protocol.CompletionsRequestArgs, simplifiedResult: boolean): protocol.CompletionEntry[] | CompletionInfo {
private getCompletions(args: protocol.CompletionsRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.CompletionEntry> | CompletionInfo {
const prefix = args.prefix || "";
const { file, project } = this.getFileAndProject(args);
@@ -1172,7 +1174,7 @@ namespace ts.server {
const completions = project.getLanguageService().getCompletionsAtPosition(file, position);
if (!completions) {
return undefined;
return emptyArray;
}
if (simplifiedResult) {
return mapDefined(completions.entries, entry => {
@@ -1188,7 +1190,7 @@ namespace ts.server {
}
}
private getCompletionEntryDetails(args: protocol.CompletionDetailsRequestArgs): protocol.CompletionEntryDetails[] {
private getCompletionEntryDetails(args: protocol.CompletionDetailsRequestArgs): ReadonlyArray<protocol.CompletionEntryDetails> {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
@@ -1197,12 +1199,12 @@ namespace ts.server {
project.getLanguageService().getCompletionEntryDetails(file, position, entryName));
}
private getCompileOnSaveAffectedFileList(args: protocol.FileRequestArgs): protocol.CompileOnSaveAffectedFileListSingleProject[] {
private getCompileOnSaveAffectedFileList(args: protocol.FileRequestArgs): ReadonlyArray<protocol.CompileOnSaveAffectedFileListSingleProject> {
const info = this.projectService.getScriptInfo(args.file);
const result: protocol.CompileOnSaveAffectedFileListSingleProject[] = [];
if (!info) {
return [];
return emptyArray;
}
// if specified a project, we only return affected file list in this project
@@ -1360,7 +1362,7 @@ namespace ts.server {
: tree;
}
private getNavigateToItems(args: protocol.NavtoRequestArgs, simplifiedResult: boolean): protocol.NavtoItem[] | NavigateToItem[] {
private getNavigateToItems(args: protocol.NavtoRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.NavtoItem> | ReadonlyArray<NavigateToItem> {
const projects = this.getProjects(args);
const fileName = args.currentFileOnly ? args.file && normalizeSlashes(args.file) : undefined;
@@ -1370,7 +1372,7 @@ namespace ts.server {
project => {
const navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject());
if (!navItems) {
return [];
return emptyArray;
}
return navItems.map((navItem) => {