Skip to content

Proposal: Pass SourceFile being emitted to Program.emit's callback #7438

@chuckjaz

Description

@chuckjaz

I propose including the SourceFile being emitted in the emit callback.

TypeScript Version:

1.7.5 / 1.8.0-beta / nightly (1.9.0-dev.20160217)

Code

import * as ts from 'typescript';
import * as fs from 'fs';
import * as fse from 'fse';

const fileName = 'index.ts';
const fileNames = [fileName];

class LocalHost implements ts.LanguageServiceHost {
  getCompilationSettings(): ts.CompilerOptions {
    return {
      experimentalDecorators: true,
      modules:  ts.ModuleKind.CommonJS,
      target: ts.ScriptTarget.ES5
    };
  }

  getProjectVersion(): string { return "1";}
  getScriptFileNames(): string[] { return fileNames; }
  getScriptVersion(fileName: string): string { return "1"; }
  getCurrentDirectory(): string { return dir; }

  getScriptSnapshot(fileName: string): ts.IScriptSnapshot {
    const filteredName = nameFilter(fileName);
    if (fs.existsSync(filteredName))
      return ts.ScriptSnapshot.fromString(fs.readFileSync(filteredName, 'utf8'));
  }

  getDefaultLibFileName(options: ts.CompilerOptions): string {
    return './node_modules/typescript/lib/lib.es7.d.ts';  
  }
}

const host = new LocalHost();
const ls = ts.createLanguageService(host);
const program = ls.getProgram();

const emitResult = program.emit(undefined, (absoluteFilePath, fileContent, sourceFile) => {
    console.log('emitting', absoluteFilePath, 'for', sourceFile.fileName);
    fse.mkdirsSync(path.dirname(absoluteFilePath));
    fs.writeFileSync(absoluteFilePath, this.fixSourceMapSources(fileContent), { encoding: 'utf-8' });
});

Expected behavior:
If this proposal is taken then the sourceFile parameter above will contain the SourceFile instance emit currently emitting the file absoluteFilePath on behalf of.

Justification:
.d.ts files do not contain information about the decorators used in the .ts files, nor can it. However, these decorators often contain valuable information that other processors might need, such as, in our case, the Angular 2 offline compiler and the Angular 2 language service. To preserve this information we emit a .metadata.json file for each .d.ts file emitted if the corresponding module contains classes with decorators.

We use program.emit() in our build process and use the callback to trigger the emit of the .metadata.json file but we must make an educated guess as to which SourceFile the .d.ts file is being emitted for. It would be more straight forward for the SourceFile to passed into the callback to emit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    APIRelates to the public API for TypeScriptFixedA PR has been merged for this issueSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions