readFile may return undefined

This commit is contained in:
Andy Hanson 2017-07-14 14:26:13 -07:00
parent e8421827e0
commit 96d537bc54
16 changed files with 44 additions and 45 deletions

View File

@ -752,7 +752,7 @@ namespace ts {
}
}
export function parseCommandLine(commandLine: string[], readFile?: (path: string) => string): ParsedCommandLine {
export function parseCommandLine(commandLine: string[], readFile?: (path: string) => string | undefined): ParsedCommandLine {
const options: CompilerOptions = {};
const fileNames: string[] = [];
const errors: Diagnostic[] = [];
@ -878,15 +878,9 @@ namespace ts {
* Read tsconfig.json file
* @param fileName The path to the config file
*/
export function readConfigFile(fileName: string, readFile: (path: string) => string): { config?: any; error?: Diagnostic } {
let text = "";
try {
text = readFile(fileName);
}
catch (e) {
return { config: {}, error: createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message) };
}
return parseConfigFileTextToJson(fileName, text);
export function readConfigFile(fileName: string, readFile: (path: string) => string | undefined): { config?: any; error?: Diagnostic } {
const textOrDiagnostic = tryReadFile(fileName, readFile);
return typeof textOrDiagnostic === "string" ? parseConfigFileTextToJson(fileName, textOrDiagnostic) : { config: {}, error: textOrDiagnostic };
}
/**
@ -906,15 +900,20 @@ namespace ts {
* Read tsconfig.json file
* @param fileName The path to the config file
*/
export function readJsonConfigFile(fileName: string, readFile: (path: string) => string): JsonSourceFile {
let text = "";
export function readJsonConfigFile(fileName: string, readFile: (path: string) => string | undefined): JsonSourceFile {
const textOrDiagnostic = tryReadFile(fileName, readFile);
return typeof textOrDiagnostic === "string" ? parseJsonText(fileName, textOrDiagnostic) : <JsonSourceFile>{ parseDiagnostics: [textOrDiagnostic] };
}
function tryReadFile(fileName: string, readFile: (path: string) => string | undefined): string | Diagnostic {
let text: string | undefined;
try {
text = readFile(fileName);
}
catch (e) {
return <JsonSourceFile>{ parseDiagnostics: [createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message)] };
return createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message);
}
return parseJsonText(fileName, text);
return text === undefined ? createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, "File does not exist.") : text;
}
function commandLineOptionsToMap(options: CommandLineOption[]) {

View File

@ -23,7 +23,7 @@ namespace ts {
newLine: string;
useCaseSensitiveFileNames: boolean;
write(s: string): void;
readFile(path: string, encoding?: string): string;
readFile(path: string, encoding?: string): string | undefined;
getFileSize?(path: string): number;
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
/**
@ -97,7 +97,7 @@ namespace ts {
directoryExists(path: string): boolean;
createDirectory(path: string): void;
resolvePath(path: string): string;
readFile(path: string): string;
readFile(path: string): string | undefined;
writeFile(path: string, contents: string): void;
getDirectories(path: string): string[];
readDirectory(path: string, extensions?: ReadonlyArray<string>, basePaths?: ReadonlyArray<string>, excludeEx?: string, includeFileEx?: string, includeDirEx?: string): string[];
@ -204,7 +204,7 @@ namespace ts {
const platform: string = _os.platform();
const useCaseSensitiveFileNames = isFileSystemCaseSensitive();
function readFile(fileName: string, _encoding?: string): string {
function readFile(fileName: string, _encoding?: string): string | undefined {
if (!fileExists(fileName)) {
return undefined;
}

View File

@ -2414,7 +2414,7 @@ namespace ts {
*/
fileExists(path: string): boolean;
readFile(path: string): string;
readFile(path: string): string | undefined;
}
export interface WriteFileCallback {
@ -3921,7 +3921,7 @@ namespace ts {
fileExists(fileName: string): boolean;
// readFile function is used to read arbitrary text files on disk, i.e. when resolution procedure needs the content of 'package.json'
// to determine location of bundled typings for node module
readFile(fileName: string): string;
readFile(fileName: string): string | undefined;
trace?(s: string): void;
directoryExists?(directoryName: string): boolean;
realpath?(path: string): string;

View File

@ -3921,7 +3921,7 @@ namespace ts {
*/
export function validateLocaleAndSetLanguage(
locale: string,
sys: { getExecutingFilePath(): string, resolvePath(path: string): string, fileExists(fileName: string): boolean, readFile(fileName: string): string },
sys: { getExecutingFilePath(): string, resolvePath(path: string): string, fileExists(fileName: string): boolean, readFile(fileName: string): string | undefined },
errors?: Diagnostic[]) {
const matchResult = /^([a-z]+)([_\-]([a-z]+))?$/.exec(locale.toLowerCase());

View File

@ -479,7 +479,7 @@ namespace Harness {
getCurrentDirectory(): string;
useCaseSensitiveFileNames(): boolean;
resolvePath(path: string): string;
readFile(path: string): string;
readFile(path: string): string | undefined;
writeFile(path: string, contents: string): void;
directoryName(path: string): string;
getDirectories(path: string): string[];
@ -719,7 +719,7 @@ namespace Harness {
}
});
export function readFile(file: string) {
export function readFile(file: string): string | undefined {
const response = Http.getFileFromServerSync(serverRoot + file);
if (response.status === 200) {
return response.responseText;
@ -976,7 +976,7 @@ namespace Harness {
useCaseSensitiveFileNames: () => useCaseSensitiveFileNames,
getNewLine: () => newLine,
fileExists: fileName => fileMap.has(toPath(fileName)),
readFile: (fileName: string): string => {
readFile(fileName: string): string | undefined {
const file = fileMap.get(toPath(fileName));
if (ts.endsWith(fileName, "json")) {
// strip comments

View File

@ -215,7 +215,7 @@ namespace Harness.LanguageService {
depth,
(p) => this.virtualFileSystem.getAccessibleFileSystemEntries(p));
}
readFile(path: string): string {
readFile(path: string): string | undefined {
const snapshot = this.getScriptSnapshot(path);
return snapshot.getText(0, snapshot.getLength());
}
@ -619,7 +619,7 @@ namespace Harness.LanguageService {
this.writeMessage(message);
}
readFile(fileName: string): string {
readFile(fileName: string): string | undefined {
if (fileName.indexOf(Harness.Compiler.defaultLibFileName) >= 0) {
fileName = Harness.Compiler.defaultLibFileName;
}

View File

@ -289,7 +289,7 @@ class ProjectRunner extends RunnerBase {
return Harness.IO.fileExists(getFileNameInTheProjectTest(fileName));
}
function readFile(fileName: string): string {
function readFile(fileName: string): string | undefined {
return Harness.IO.readFile(getFileNameInTheProjectTest(fileName));
}

View File

@ -56,7 +56,7 @@ namespace ts {
else {
return { readFile, fileExists: path => map.has(path) };
}
function readFile(path: string): string {
function readFile(path: string): string | undefined {
const file = map.get(path);
return file && file.content;
}

View File

@ -9,7 +9,7 @@ namespace ts.server {
newLine: "\n",
useCaseSensitiveFileNames: true,
write(s): void { lastWrittenToHost = s; },
readFile(): string { return void 0; },
readFile: () => undefined,
writeFile: noop,
resolvePath(): string { return void 0; },
fileExists: () => false,

View File

@ -209,7 +209,7 @@ namespace Utils {
}
}
readFile(path: string): string {
readFile(path: string): string | undefined {
const value = this.traversePath(path);
if (value && value.isFile()) {
return value.content.content;

View File

@ -217,7 +217,7 @@ namespace ts.server {
return !this.project.isWatchedMissingFile(path) && this.host.fileExists(file);
}
readFile(fileName: string): string {
readFile(fileName: string): string | undefined {
return this.host.readFile(fileName);
}

View File

@ -93,10 +93,10 @@ namespace ts.server.typingsInstaller {
abstract readonly typesRegistry: Map<void>;
constructor(
readonly installTypingHost: InstallTypingHost,
readonly globalCachePath: string,
readonly safeListPath: Path,
readonly throttleLimit: number,
protected readonly installTypingHost: InstallTypingHost,
private readonly globalCachePath: string,
private readonly safeListPath: Path,
private readonly throttleLimit: number,
protected readonly log = nullLog) {
if (this.log.isEnabled()) {
this.log.writeLine(`Global cache location '${globalCachePath}', safe file path '${safeListPath}'`);

View File

@ -9,10 +9,10 @@
namespace ts.JsTyping {
export interface TypingResolutionHost {
directoryExists: (path: string) => boolean;
fileExists: (fileName: string) => boolean;
readFile: (path: string, encoding?: string) => string;
readDirectory: (rootDir: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string>, includes: ReadonlyArray<string>, depth?: number) => string[];
directoryExists(path: string): boolean;
fileExists(fileName: string): boolean;
readFile(path: string, encoding?: string): string | undefined;
readDirectory(rootDir: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string>, includes: ReadonlyArray<string>, depth?: number): string[];
}
interface PackageJson {

View File

@ -1149,7 +1149,7 @@ namespace ts {
!!hostCache.getEntryByPath(path) :
(host.fileExists && host.fileExists(fileName));
},
readFile: (fileName): string => {
readFile(fileName) {
// stub missing host functionality
const path = toPath(fileName, currentDirectory, getCanonicalFileName);
if (hostCache.containsEntryByPath(path)) {

View File

@ -69,7 +69,7 @@ namespace ts {
getTypeRootsVersion?(): number;
readDirectory(rootDir: string, extension: string, basePaths?: string, excludeEx?: string, includeFileEx?: string, includeDirEx?: string, depth?: number): string;
readFile(path: string, encoding?: string): string;
readFile(path: string, encoding?: string): string | undefined;
fileExists(path: string): boolean;
getModuleResolutionsForFile?(fileName: string): string;
@ -95,7 +95,7 @@ namespace ts {
/**
* Read arbitary text files on disk, i.e. when resolution procedure needs the content of 'package.json' to determine location of bundled typings for node modules
*/
readFile(fileName: string): string;
readFile(fileName: string): string | undefined;
realpath?(path: string): string;
trace(s: string): void;
useCaseSensitiveFileNames?(): boolean;
@ -458,7 +458,7 @@ namespace ts {
));
}
public readFile(path: string, encoding?: string): string {
public readFile(path: string, encoding?: string): string | undefined {
return this.shimHost.readFile(path, encoding);
}
@ -501,7 +501,7 @@ namespace ts {
return this.shimHost.fileExists(fileName);
}
public readFile(fileName: string): string {
public readFile(fileName: string): string | undefined {
return this.shimHost.readFile(fileName);
}
@ -1006,7 +1006,7 @@ namespace ts {
class CoreServicesShimObject extends ShimBase implements CoreServicesShim {
private logPerformance = false;
constructor(factory: ShimFactory, public logger: Logger, private host: CoreServicesShimHostAdapter) {
constructor(factory: ShimFactory, public readonly logger: Logger, private readonly host: CoreServicesShimHostAdapter) {
super(factory);
}

View File

@ -165,7 +165,7 @@ namespace ts {
* Without these methods, only completions for ambient modules will be provided.
*/
readDirectory?(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
readFile?(path: string, encoding?: string): string;
readFile?(path: string, encoding?: string): string | undefined;
fileExists?(path: string): boolean;
/*