Skip to content

CompilerHost.getSourceFile is being called for odd filenames besides the one being compiled #13629

@justinfagnani

Description

@justinfagnani

TypeScript Version: 2.1.4

Code

I'm trying to write a CompilerHost for an in-memory system, so I have to deal with each filename passed to getSourceFile. When debugging I noticed that the compiler is calling into getSourceFile with the file I'm trying to compiler, along with filenames that are only extensions, like .ts, .tsx, and .js(that one only ifallowJs` is true).

Here's a simple reproduction.

const testSource = `
  class Foo extends HTMLElement {
    bar: string = 'baz';
  }
`;
const host: ts.CompilerHost = {
  getSourceFile(fileName: string, languageVersion: ts.ScriptTarget,
      onError?: (message: string) => void): ts.SourceFile {
    console.log('getSourceFile', fileName);
    if (fileName === 'test.ts') {
      return ts.createSourceFile(fileName, testSource, languageVersion);
    }
    if (onError) onError('not found');
    // tsc's declarations don't support strict null checks
    return null as any as ts.SourceFile;
  },
  getDefaultLibFileName: () => '',
  writeFile: (_fileName, _content) => {},
  getCurrentDirectory: () => ts.sys.getCurrentDirectory(),
  getCanonicalFileName: fileName => ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(),
  getNewLine: () => ts.sys.newLine,
  useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames,
  fileExists: (fileName: string) => fileName === 'test.ts',
  readFile(fileName: string): string {
    if (fileName === 'test.ts') {
      return testSource;
    }
    return null as any as string;
  },
  resolveModuleNames(_moduleNames: string[], _containingFile: string): ts.ResolvedModule[] {
    throw new Error('unsupported');
  },
  getDirectories(_path: string): string[] {
    throw new Error('unsupported');
  }
};
const program = ts.createProgram(['test.ts'], {allowJs: true}, host);

Expected behavior:

The console has the output:

getSourceFile test.ts

Actual behavior:
The console has the output:

getSourceFile test.ts
getSourceFile .ts
getSourceFile .tsx
getSourceFile .d.ts
getSourceFile .js
getSourceFile .jsx

I'm not sure what to do with these requests. Do they relate the the previous full path that was passed? The sample source here just reads from the filesystem - is the compiler really asking to load hidden files? What do they represent?

One complicating factor here is that there is essentially no documentation for CompilerHost, so I'm not sure what argument values to expect or what contract to adhere to.

Metadata

Metadata

Assignees

No one assigned

    Labels

    APIRelates to the public API for TypeScriptBugA bug in TypeScriptFixedA PR has been merged for this issueGood First IssueWell scoped, documented and has the green lightHelp WantedYou can do this

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions