mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-19 20:37:00 -05:00
Make the host cache store the fileName instead of undefined for the missing host files
This commit is contained in:
@@ -1161,7 +1161,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function diagnosticName(nameArg: __String | Identifier) {
|
||||
return typeof nameArg === "string" ? unescapeLeadingUnderscores(nameArg as __String) : declarationNameToString(nameArg as Identifier);
|
||||
return isString(nameArg) ? unescapeLeadingUnderscores(nameArg as __String) : declarationNameToString(nameArg as Identifier);
|
||||
}
|
||||
|
||||
function isTypeParameterSymbolDeclaredInContainer(symbol: Symbol, container: Node) {
|
||||
|
||||
@@ -880,7 +880,7 @@ namespace ts {
|
||||
*/
|
||||
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 };
|
||||
return isString(textOrDiagnostic) ? parseConfigFileTextToJson(fileName, textOrDiagnostic) : { config: {}, error: textOrDiagnostic };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -902,7 +902,7 @@ namespace ts {
|
||||
*/
|
||||
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] };
|
||||
return isString(textOrDiagnostic) ? parseJsonText(fileName, textOrDiagnostic) : <JsonSourceFile>{ parseDiagnostics: [textOrDiagnostic] };
|
||||
}
|
||||
|
||||
function tryReadFile(fileName: string, readFile: (path: string) => string | undefined): string | Diagnostic {
|
||||
@@ -1106,9 +1106,9 @@ namespace ts {
|
||||
if (!isDoubleQuotedString(valueExpression)) {
|
||||
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, Diagnostics.String_literal_with_double_quotes_expected));
|
||||
}
|
||||
reportInvalidOptionValue(option && (typeof option.type === "string" && option.type !== "string"));
|
||||
reportInvalidOptionValue(option && (isString(option.type) && option.type !== "string"));
|
||||
const text = (<StringLiteral>valueExpression).text;
|
||||
if (option && typeof option.type !== "string") {
|
||||
if (option && !isString(option.type)) {
|
||||
const customOption = <CommandLineOptionOfCustomType>option;
|
||||
// Validate custom option type
|
||||
if (!customOption.type.has(text)) {
|
||||
@@ -1179,7 +1179,7 @@ namespace ts {
|
||||
function getCompilerOptionValueTypeString(option: CommandLineOption) {
|
||||
return option.type === "list" ?
|
||||
"Array" :
|
||||
typeof option.type === "string" ? option.type : "string";
|
||||
isString(option.type) ? option.type : "string";
|
||||
}
|
||||
|
||||
function isCompilerOptionsValue(option: CommandLineOption, value: any): value is CompilerOptionsValue {
|
||||
@@ -1187,7 +1187,7 @@ namespace ts {
|
||||
if (option.type === "list") {
|
||||
return isArray(value);
|
||||
}
|
||||
const expectedType = typeof option.type === "string" ? option.type : "string";
|
||||
const expectedType = isString(option.type) ? option.type : "string";
|
||||
return typeof value === expectedType;
|
||||
}
|
||||
}
|
||||
@@ -1571,7 +1571,7 @@ namespace ts {
|
||||
let extendedConfigPath: Path;
|
||||
|
||||
if (json.extends) {
|
||||
if (typeof json.extends !== "string") {
|
||||
if (!isString(json.extends)) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "extends", "string"));
|
||||
}
|
||||
else {
|
||||
@@ -1796,7 +1796,7 @@ namespace ts {
|
||||
if (optType === "list" && isArray(value)) {
|
||||
return convertJsonOptionOfListType(<CommandLineOptionOfListType>opt, value, basePath, errors);
|
||||
}
|
||||
else if (typeof optType !== "string") {
|
||||
else if (!isString(optType)) {
|
||||
return convertJsonOptionOfCustomType(<CommandLineOptionOfCustomType>opt, <string>value, errors);
|
||||
}
|
||||
return normalizeNonListOptionValue(opt, basePath, value);
|
||||
@@ -1809,12 +1809,12 @@ namespace ts {
|
||||
function normalizeOptionValue(option: CommandLineOption, basePath: string, value: any): CompilerOptionsValue {
|
||||
if (option.type === "list") {
|
||||
const listOption = <CommandLineOptionOfListType>option;
|
||||
if (listOption.element.isFilePath || typeof listOption.element.type !== "string") {
|
||||
if (listOption.element.isFilePath || !isString(listOption.element.type)) {
|
||||
return <CompilerOptionsValue>filter(map(value, v => normalizeOptionValue(listOption.element, basePath, v)), v => !!v);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else if (typeof option.type !== "string") {
|
||||
else if (!isString(option.type)) {
|
||||
return option.type.get(value);
|
||||
}
|
||||
return normalizeNonListOptionValue(option, basePath, value);
|
||||
|
||||
@@ -1201,6 +1201,13 @@ namespace ts {
|
||||
return Array.isArray ? Array.isArray(value) : value instanceof Array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether a value is string
|
||||
*/
|
||||
export function isString(text: any): text is string {
|
||||
return typeof text === "string";
|
||||
}
|
||||
|
||||
export function tryCast<TOut extends TIn, TIn = any>(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut | undefined {
|
||||
return value !== undefined && test(value) ? value : undefined;
|
||||
}
|
||||
@@ -1454,16 +1461,16 @@ namespace ts {
|
||||
function compareMessageText(text1: string | DiagnosticMessageChain, text2: string | DiagnosticMessageChain): Comparison {
|
||||
while (text1 && text2) {
|
||||
// We still have both chains.
|
||||
const string1 = typeof text1 === "string" ? text1 : text1.messageText;
|
||||
const string2 = typeof text2 === "string" ? text2 : text2.messageText;
|
||||
const string1 = isString(text1) ? text1 : text1.messageText;
|
||||
const string2 = isString(text2) ? text2 : text2.messageText;
|
||||
|
||||
const res = compareValues(string1, string2);
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
|
||||
text1 = typeof text1 === "string" ? undefined : text1.next;
|
||||
text2 = typeof text2 === "string" ? undefined : text2.next;
|
||||
text1 = isString(text1) ? undefined : text1.next;
|
||||
text2 = isString(text2) ? undefined : text2.next;
|
||||
}
|
||||
|
||||
if (!text1 && !text2) {
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace ts {
|
||||
if (typeof value === "boolean") {
|
||||
return value ? createTrue() : createFalse();
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
if (isString(value)) {
|
||||
return createStringLiteral(value);
|
||||
}
|
||||
return createLiteralFromNode(value);
|
||||
@@ -2130,7 +2130,7 @@ namespace ts {
|
||||
|
||||
export function createCatchClause(variableDeclaration: string | VariableDeclaration, block: Block) {
|
||||
const node = <CatchClause>createSynthesizedNode(SyntaxKind.CatchClause);
|
||||
node.variableDeclaration = typeof variableDeclaration === "string" ? createVariableDeclaration(variableDeclaration) : variableDeclaration;
|
||||
node.variableDeclaration = isString(variableDeclaration) ? createVariableDeclaration(variableDeclaration) : variableDeclaration;
|
||||
node.block = block;
|
||||
return node;
|
||||
}
|
||||
@@ -2438,11 +2438,11 @@ namespace ts {
|
||||
function asName(name: string | EntityName): EntityName;
|
||||
function asName(name: string | Identifier | ThisTypeNode): Identifier | ThisTypeNode;
|
||||
function asName(name: string | Identifier | BindingName | PropertyName | QualifiedName | ThisTypeNode) {
|
||||
return typeof name === "string" ? createIdentifier(name) : name;
|
||||
return isString(name) ? createIdentifier(name) : name;
|
||||
}
|
||||
|
||||
function asExpression(value: string | number | Expression) {
|
||||
return typeof value === "string" || typeof value === "number" ? createLiteral(value) : value;
|
||||
return isString(value) || typeof value === "number" ? createLiteral(value) : value;
|
||||
}
|
||||
|
||||
function asNodeArray<T extends Node>(array: ReadonlyArray<T> | undefined): NodeArray<T> | undefined {
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const fileName = jsonContent[fieldName];
|
||||
if (typeof fileName !== "string") {
|
||||
if (!isString(fileName)) {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_string_got_1, fieldName, typeof fileName);
|
||||
}
|
||||
@@ -630,8 +630,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (matchedPattern) {
|
||||
const matchedStar = typeof matchedPattern === "string" ? undefined : matchedText(matchedPattern, moduleName);
|
||||
const matchedPatternText = typeof matchedPattern === "string" ? matchedPattern : patternText(matchedPattern);
|
||||
const matchedStar = isString(matchedPattern) ? undefined : matchedText(matchedPattern, moduleName);
|
||||
const matchedPatternText = isString(matchedPattern) ? matchedPattern : patternText(matchedPattern);
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText);
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain, newLine: string): string {
|
||||
if (typeof messageText === "string") {
|
||||
if (isString(messageText)) {
|
||||
return messageText;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -184,7 +184,7 @@ namespace ts {
|
||||
|
||||
function fileEventHandler(eventName: string, relativeFileName: string, baseDirPath: string) {
|
||||
// When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined"
|
||||
const fileName = typeof relativeFileName !== "string"
|
||||
const fileName = !isString(relativeFileName)
|
||||
? undefined
|
||||
: ts.getNormalizedAbsolutePath(relativeFileName, baseDirPath);
|
||||
// Some applications save a working file via rename operations
|
||||
|
||||
@@ -355,7 +355,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getTextOfConstantValue(value: string | number) {
|
||||
return typeof value === "string" ? '"' + escapeNonAsciiString(value) + '"' : "" + value;
|
||||
return isString(value) ? '"' + escapeNonAsciiString(value) + '"' : "" + value;
|
||||
}
|
||||
|
||||
// Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__'
|
||||
|
||||
@@ -391,7 +391,7 @@ namespace FourSlash {
|
||||
|
||||
// Entry points from fourslash.ts
|
||||
public goToMarker(name: string | Marker = "") {
|
||||
const marker = typeof name === "string" ? this.getMarkerByName(name) : name;
|
||||
const marker = ts.isString(name) ? this.getMarkerByName(name) : name;
|
||||
if (this.activeFile.fileName !== marker.fileName) {
|
||||
this.openFile(marker.fileName);
|
||||
}
|
||||
@@ -400,7 +400,7 @@ namespace FourSlash {
|
||||
if (marker.position === -1 || marker.position > content.length) {
|
||||
throw new Error(`Marker "${name}" has been invalidated by unrecoverable edits to the file.`);
|
||||
}
|
||||
const mName = typeof name === "string" ? name : this.markerName(marker);
|
||||
const mName = ts.isString(name) ? name : this.markerName(marker);
|
||||
this.lastKnownMarker = mName;
|
||||
this.goToPosition(marker.position);
|
||||
}
|
||||
@@ -1028,7 +1028,7 @@ namespace FourSlash {
|
||||
|
||||
public verifyNoReferences(markerNameOrRange?: string | Range) {
|
||||
if (markerNameOrRange) {
|
||||
if (typeof markerNameOrRange === "string") {
|
||||
if (ts.isString(markerNameOrRange)) {
|
||||
this.goToMarker(markerNameOrRange);
|
||||
}
|
||||
else {
|
||||
@@ -1524,7 +1524,7 @@ namespace FourSlash {
|
||||
resultString += "Diagnostics:" + Harness.IO.newLine();
|
||||
const diagnostics = ts.getPreEmitDiagnostics(this.languageService.getProgram());
|
||||
for (const diagnostic of diagnostics) {
|
||||
if (typeof diagnostic.messageText !== "string") {
|
||||
if (!ts.isString(diagnostic.messageText)) {
|
||||
let chainedMessage = <ts.DiagnosticMessageChain>diagnostic.messageText;
|
||||
let indentation = " ";
|
||||
while (chainedMessage) {
|
||||
@@ -2858,7 +2858,7 @@ namespace FourSlash {
|
||||
result = this.testData.files[index];
|
||||
}
|
||||
}
|
||||
else if (typeof indexOrName === "string") {
|
||||
else if (ts.isString(indexOrName)) {
|
||||
let name = <string>indexOrName;
|
||||
|
||||
// names are stored in the compiler with this relative path, this allows people to use goTo.file on just the fileName
|
||||
|
||||
@@ -225,7 +225,7 @@ namespace Utils {
|
||||
return JSON.stringify(file, (_, v) => isNodeOrArray(v) ? serializeNode(v) : v, " ");
|
||||
|
||||
function getKindName(k: number | string): string {
|
||||
if (typeof k === "string") {
|
||||
if (ts.isString(k)) {
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ class ProjectRunner extends RunnerBase {
|
||||
if (option) {
|
||||
const optType = option.type;
|
||||
let value = <any>testCase[name];
|
||||
if (typeof optType !== "string") {
|
||||
if (!ts.isString(optType)) {
|
||||
const key = value.toLowerCase();
|
||||
const optTypeValue = optType.get(key);
|
||||
if (optTypeValue) {
|
||||
|
||||
@@ -199,7 +199,8 @@ namespace ts {
|
||||
let diags = project.getLanguageService().getSemanticDiagnostics(root.name);
|
||||
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called");
|
||||
assert.isTrue(diags.length === 1, "one diagnostic expected");
|
||||
assert.isTrue(typeof diags[0].messageText === "string" && ((<string>diags[0].messageText).indexOf("Cannot find module") === 0), "should be 'cannot find module' message");
|
||||
const messageText = diags[0].messageText;
|
||||
assert.isTrue(isString(messageText) && messageText.indexOf("Cannot find module") === 0, "should be 'cannot find module' message");
|
||||
|
||||
fileMap.set(imported.name, imported);
|
||||
fileExistsCalledForBar = false;
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace ts {
|
||||
"/dev/tests/scenarios/first.json": "",
|
||||
"/dev/tests/baselines/first/output.ts": ""
|
||||
});
|
||||
const testContents = mapEntries(testContentsJson, (k, v) => [k, typeof v === "string" ? v : JSON.stringify(v)]);
|
||||
const testContents = mapEntries(testContentsJson, (k, v) => [k, isString(v) ? v : JSON.stringify(v)]);
|
||||
|
||||
const caseInsensitiveBasePath = "c:/dev/";
|
||||
const caseInsensitiveHost = new Utils.MockParseConfigHost(caseInsensitiveBasePath, /*useCaseSensitiveFileNames*/ false, mapEntries(testContents, (key, content) => [`c:${key}`, content]));
|
||||
|
||||
@@ -282,7 +282,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
function makeFile(path: string, content: {} = ""): projectSystem.FileOrFolder {
|
||||
return { path, content: typeof content === "string" ? "" : JSON.stringify(content) };
|
||||
return { path, content: isString(content) ? "" : JSON.stringify(content) };
|
||||
}
|
||||
|
||||
function fileStats(nonZeroStats: Partial<server.FileStats>): server.FileStats {
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
addPostExecAction(stdout: string | string[], cb: TI.RequestCompletedAction) {
|
||||
const out = typeof stdout === "string" ? stdout : createNpmPackageJsonString(stdout);
|
||||
const out = isString(stdout) ? stdout : createNpmPackageJsonString(stdout);
|
||||
const action: PostExecAction = {
|
||||
success: !!out,
|
||||
callback: cb
|
||||
@@ -258,7 +258,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
export function isFile(s: FSEntry): s is File {
|
||||
return s && typeof (<File>s).content === "string";
|
||||
return s && isString((<File>s).content);
|
||||
}
|
||||
|
||||
function invokeDirectoryWatcher(callbacks: DirectoryWatcherCallback[], getRelativeFilePath: () => string) {
|
||||
@@ -413,7 +413,7 @@ namespace ts.projectSystem {
|
||||
const currentEntry = this.fs.get(path);
|
||||
if (currentEntry) {
|
||||
if (isFile(currentEntry)) {
|
||||
if (typeof fileOrFolder.content === "string") {
|
||||
if (isString(fileOrFolder.content)) {
|
||||
// Update file
|
||||
if (currentEntry.content !== fileOrFolder.content) {
|
||||
currentEntry.content = fileOrFolder.content;
|
||||
@@ -426,7 +426,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
else {
|
||||
// Folder
|
||||
if (typeof fileOrFolder.content === "string") {
|
||||
if (isString(fileOrFolder.content)) {
|
||||
// TODO: Changing from folder => file
|
||||
}
|
||||
else {
|
||||
@@ -453,7 +453,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
ensureFileOrFolder(fileOrFolder: FileOrFolder) {
|
||||
if (typeof fileOrFolder.content === "string") {
|
||||
if (isString(fileOrFolder.content)) {
|
||||
const file = this.toFile(fileOrFolder);
|
||||
Debug.assert(!this.fs.get(file.path));
|
||||
const baseFolder = this.ensureFolder(getDirectoryPath(file.fullPath));
|
||||
|
||||
@@ -342,7 +342,7 @@ namespace ts.server {
|
||||
convertDiagnostic(entry: protocol.DiagnosticWithLinePosition, _fileName: string): Diagnostic {
|
||||
let category: DiagnosticCategory;
|
||||
for (const id in DiagnosticCategory) {
|
||||
if (typeof id === "string" && entry.category === id.toLowerCase()) {
|
||||
if (isString(id) && entry.category === id.toLowerCase()) {
|
||||
category = (<any>DiagnosticCategory)[id];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ namespace ts.server {
|
||||
};
|
||||
|
||||
export function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings {
|
||||
if (typeof protocolOptions.indentStyle === "string") {
|
||||
if (isString(protocolOptions.indentStyle)) {
|
||||
protocolOptions.indentStyle = indentStyle.get(protocolOptions.indentStyle.toLowerCase());
|
||||
Debug.assert(protocolOptions.indentStyle !== undefined);
|
||||
}
|
||||
@@ -169,7 +169,7 @@ namespace ts.server {
|
||||
export function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin {
|
||||
compilerOptionConverters.forEach((mappedValues, id) => {
|
||||
const propertyValue = protocolOptions[id];
|
||||
if (typeof propertyValue === "string") {
|
||||
if (isString(propertyValue)) {
|
||||
protocolOptions[id] = mappedValues.get(propertyValue.toLowerCase());
|
||||
}
|
||||
});
|
||||
@@ -177,9 +177,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
export function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind {
|
||||
return typeof scriptKindName === "string"
|
||||
? convertScriptKindName(scriptKindName)
|
||||
: scriptKindName;
|
||||
return isString(scriptKindName) ? convertScriptKindName(scriptKindName) : scriptKindName;
|
||||
}
|
||||
|
||||
export function convertScriptKindName(scriptKindName: protocol.ScriptKindName) {
|
||||
@@ -1947,7 +1945,7 @@ namespace ts.server {
|
||||
// RegExp group numbers are 1-based, but the first element in groups
|
||||
// is actually the original string, so it all works out in the end.
|
||||
if (typeof groupNumberOrString === "number") {
|
||||
if (typeof groups[groupNumberOrString] !== "string") {
|
||||
if (!isString(groups[groupNumberOrString])) {
|
||||
// Specification was wrong - exclude nothing!
|
||||
this.logger.info(`Incorrect RegExp specification in safelist rule ${name} - not enough groups`);
|
||||
// * can't appear in a filename; escape it because it's feeding into a RegExp
|
||||
|
||||
@@ -812,18 +812,21 @@ namespace ts {
|
||||
return codefix.getSupportedErrorCodes();
|
||||
}
|
||||
|
||||
// Either it will be file name if host doesnt have file or it will be the host's file information
|
||||
type CachedHostFileInformation = HostFileInformation | string;
|
||||
|
||||
// Cache host information about script Should be refreshed
|
||||
// at each language service public entry point, since we don't know when
|
||||
// the set of scripts handled by the host changes.
|
||||
class HostCache {
|
||||
private fileNameToEntry: Map<HostFileInformation>;
|
||||
private fileNameToEntry: Map<CachedHostFileInformation>;
|
||||
private _compilationSettings: CompilerOptions;
|
||||
private currentDirectory: string;
|
||||
|
||||
constructor(private host: LanguageServiceHost, getCanonicalFileName: (fileName: string) => string) {
|
||||
// script id => script index
|
||||
this.currentDirectory = host.getCurrentDirectory();
|
||||
this.fileNameToEntry = createMap<HostFileInformation>();
|
||||
this.fileNameToEntry = createMap<CachedHostFileInformation>();
|
||||
|
||||
// Initialize the list with the root file names
|
||||
const rootFileNames = host.getScriptFileNames();
|
||||
@@ -840,7 +843,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
private createEntry(fileName: string, path: Path) {
|
||||
let entry: HostFileInformation;
|
||||
let entry: CachedHostFileInformation;
|
||||
const scriptSnapshot = this.host.getScriptSnapshot(fileName);
|
||||
if (scriptSnapshot) {
|
||||
entry = {
|
||||
@@ -850,36 +853,41 @@ namespace ts {
|
||||
scriptKind: getScriptKind(fileName, this.host)
|
||||
};
|
||||
}
|
||||
else {
|
||||
entry = fileName;
|
||||
}
|
||||
|
||||
this.fileNameToEntry.set(path, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
public getEntryByPath(path: Path): HostFileInformation {
|
||||
public getEntryByPath(path: Path): CachedHostFileInformation | undefined {
|
||||
return this.fileNameToEntry.get(path);
|
||||
}
|
||||
|
||||
public containsEntryByPath(path: Path): boolean {
|
||||
return this.fileNameToEntry.has(path);
|
||||
public getHostFileInformation(path: Path): HostFileInformation | undefined {
|
||||
const entry = this.fileNameToEntry.get(path);
|
||||
return !isString(entry) ? entry : undefined;
|
||||
}
|
||||
|
||||
public getOrCreateEntryByPath(fileName: string, path: Path): HostFileInformation {
|
||||
return this.containsEntryByPath(path)
|
||||
? this.getEntryByPath(path)
|
||||
: this.createEntry(fileName, path);
|
||||
const info = this.getEntryByPath(path) || this.createEntry(fileName, path);
|
||||
return isString(info) ? undefined : info;
|
||||
}
|
||||
|
||||
public getRootFileNames(): string[] {
|
||||
return this.host.getScriptFileNames();
|
||||
return arrayFrom(this.fileNameToEntry.values(), entry => {
|
||||
return isString(entry) ? entry : entry.hostFileName;
|
||||
});
|
||||
}
|
||||
|
||||
public getVersion(path: Path): string {
|
||||
const file = this.getEntryByPath(path);
|
||||
const file = this.getHostFileInformation(path);
|
||||
return file && file.version;
|
||||
}
|
||||
|
||||
public getScriptSnapshot(path: Path): IScriptSnapshot {
|
||||
const file = this.getEntryByPath(path);
|
||||
const file = this.getHostFileInformation(path);
|
||||
return file && file.scriptSnapshot;
|
||||
}
|
||||
}
|
||||
@@ -1145,16 +1153,17 @@ namespace ts {
|
||||
fileExists: (fileName): boolean => {
|
||||
// stub missing host functionality
|
||||
const path = toPath(fileName, currentDirectory, getCanonicalFileName);
|
||||
return hostCache.containsEntryByPath(path) ?
|
||||
!!hostCache.getEntryByPath(path) :
|
||||
const entry = hostCache.getEntryByPath(path);
|
||||
return entry ?
|
||||
!isString(entry) :
|
||||
(host.fileExists && host.fileExists(fileName));
|
||||
},
|
||||
readFile(fileName) {
|
||||
// stub missing host functionality
|
||||
const path = toPath(fileName, currentDirectory, getCanonicalFileName);
|
||||
if (hostCache.containsEntryByPath(path)) {
|
||||
const entry = hostCache.getEntryByPath(path);
|
||||
return entry && entry.scriptSnapshot.getText(0, entry.scriptSnapshot.getLength());
|
||||
const entry = hostCache.getEntryByPath(path);
|
||||
if (entry) {
|
||||
return isString(entry) ? undefined : entry.scriptSnapshot.getText(0, entry.scriptSnapshot.getLength());
|
||||
}
|
||||
return host.readFile && host.readFile(fileName);
|
||||
},
|
||||
|
||||
@@ -522,7 +522,7 @@ namespace ts {
|
||||
if (logPerformance) {
|
||||
const end = timestamp();
|
||||
logger.log(`${actionDescription} completed in ${end - start} msec`);
|
||||
if (typeof result === "string") {
|
||||
if (isString(result)) {
|
||||
let str = result;
|
||||
if (str.length > 128) {
|
||||
str = str.substring(0, 128) + "...";
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace ts {
|
||||
|
||||
const value = options[opt.name];
|
||||
// Value should be a key of opt.type
|
||||
if (typeof value === "string") {
|
||||
if (isString(value)) {
|
||||
// If value is not a string, this will fail
|
||||
options[opt.name] = parseCustomTypeOption(opt, value, diagnostics);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user