<p dir="auto">I propose including the SourceFile being emitted in the emit callback.</p>
<p dir="auto"><strong>TypeScript Version:</strong></p>
<p dir="auto">1.7.5 / 1.8.0-beta / nightly (1.9.0-dev.20160217)</p>
<p dir="auto"><strong>Code</strong></p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="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 &quot;1&quot;;}
  getScriptFileNames(): string[] { return fileNames; }
  getScriptVersion(fileName: string): string { return &quot;1&quot;; }
  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) =&gt; {
    console.log('emitting', absoluteFilePath, 'for', sourceFile.fileName);
    fse.mkdirsSync(path.dirname(absoluteFilePath));
    fs.writeFileSync(absoluteFilePath, this.fixSourceMapSources(fileContent), { encoding: 'utf-8' });
});"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-s1">ts</span> <span class="pl-k">from</span> <span class="pl-s">'typescript'</span><span class="pl-kos">;</span>
<span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-s1">fs</span> <span class="pl-k">from</span> <span class="pl-s">'fs'</span><span class="pl-kos">;</span>
<span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-s1">fse</span> <span class="pl-k">from</span> <span class="pl-s">'fse'</span><span class="pl-kos">;</span>

<span class="pl-k">const</span> <span class="pl-s1">fileName</span> <span class="pl-c1">=</span> <span class="pl-s">'index.ts'</span><span class="pl-kos">;</span>
<span class="pl-k">const</span> <span class="pl-s1">fileNames</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-s1">fileName</span><span class="pl-kos">]</span><span class="pl-kos">;</span>

<span class="pl-k">class</span> <span class="pl-smi">LocalHost</span> <span class="pl-k">implements</span> <span class="pl-s1">ts</span><span class="pl-kos">.</span><span class="pl-smi">LanguageServiceHost</span> <span class="pl-kos">{</span>
  <span class="pl-en">getCompilationSettings</span><span class="pl-kos">(</span><span class="pl-kos">)</span>: <span class="pl-s1">ts</span><span class="pl-kos">.</span><span class="pl-smi">CompilerOptions</span> <span class="pl-kos">{</span>
    <span class="pl-k">return</span> <span class="pl-kos">{</span>
      <span class="pl-c1">experimentalDecorators</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span>
      <span class="pl-c1">modules</span>:  <span class="pl-s1">ts</span><span class="pl-kos">.</span><span class="pl-c1">ModuleKind</span><span class="pl-kos">.</span><span class="pl-c1">CommonJS</span><span class="pl-kos">,</span>
      <span class="pl-c1">target</span>: <span class="pl-s1">ts</span><span class="pl-kos">.</span><span class="pl-c1">ScriptTarget</span><span class="pl-kos">.</span><span class="pl-c1">ES5</span>
    <span class="pl-kos">}</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>

  <span class="pl-en">getProjectVersion</span><span class="pl-kos">(</span><span class="pl-kos">)</span>: <span class="pl-smi">string</span> <span class="pl-kos">{</span> <span class="pl-k">return</span> <span class="pl-s">"1"</span><span class="pl-kos">;</span><span class="pl-kos">}</span>
  <span class="pl-en">getScriptFileNames</span><span class="pl-kos">(</span><span class="pl-kos">)</span>: <span class="pl-smi">string</span><span class="pl-kos">[</span><span class="pl-kos">]</span> <span class="pl-kos">{</span> <span class="pl-k">return</span> <span class="pl-s1">fileNames</span><span class="pl-kos">;</span> <span class="pl-kos">}</span>
  <span class="pl-en">getScriptVersion</span><span class="pl-kos">(</span><span class="pl-s1">fileName</span>: <span class="pl-smi">string</span><span class="pl-kos">)</span>: <span class="pl-smi">string</span> <span class="pl-kos">{</span> <span class="pl-k">return</span> <span class="pl-s">"1"</span><span class="pl-kos">;</span> <span class="pl-kos">}</span>
  <span class="pl-en">getCurrentDirectory</span><span class="pl-kos">(</span><span class="pl-kos">)</span>: <span class="pl-smi">string</span> <span class="pl-kos">{</span> <span class="pl-k">return</span> <span class="pl-s1">dir</span><span class="pl-kos">;</span> <span class="pl-kos">}</span>

  <span class="pl-en">getScriptSnapshot</span><span class="pl-kos">(</span><span class="pl-s1">fileName</span>: <span class="pl-smi">string</span><span class="pl-kos">)</span>: <span class="pl-s1">ts</span><span class="pl-kos">.</span><span class="pl-smi">IScriptSnapshot</span> <span class="pl-kos">{</span>
    <span class="pl-k">const</span> <span class="pl-s1">filteredName</span> <span class="pl-c1">=</span> <span class="pl-en">nameFilter</span><span class="pl-kos">(</span><span class="pl-s1">fileName</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">fs</span><span class="pl-kos">.</span><span class="pl-en">existsSync</span><span class="pl-kos">(</span><span class="pl-s1">filteredName</span><span class="pl-kos">)</span><span class="pl-kos">)</span>
      <span class="pl-k">return</span> <span class="pl-s1">ts</span><span class="pl-kos">.</span><span class="pl-c1">ScriptSnapshot</span><span class="pl-kos">.</span><span class="pl-en">fromString</span><span class="pl-kos">(</span><span class="pl-s1">fs</span><span class="pl-kos">.</span><span class="pl-en">readFileSync</span><span class="pl-kos">(</span><span class="pl-s1">filteredName</span><span class="pl-kos">,</span> <span class="pl-s">'utf8'</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>

  <span class="pl-en">getDefaultLibFileName</span><span class="pl-kos">(</span><span class="pl-s1">options</span>: <span class="pl-s1">ts</span><span class="pl-kos">.</span><span class="pl-smi">CompilerOptions</span><span class="pl-kos">)</span>: <span class="pl-smi">string</span> <span class="pl-kos">{</span>
    <span class="pl-k">return</span> <span class="pl-s">'./node_modules/typescript/lib/lib.es7.d.ts'</span><span class="pl-kos">;</span>  
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-k">const</span> <span class="pl-s1">host</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-smi">LocalHost</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">const</span> <span class="pl-s1">ls</span> <span class="pl-c1">=</span> <span class="pl-s1">ts</span><span class="pl-kos">.</span><span class="pl-en">createLanguageService</span><span class="pl-kos">(</span><span class="pl-s1">host</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">const</span> <span class="pl-s1">program</span> <span class="pl-c1">=</span> <span class="pl-s1">ls</span><span class="pl-kos">.</span><span class="pl-en">getProgram</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">const</span> <span class="pl-s1">emitResult</span> <span class="pl-c1">=</span> <span class="pl-s1">program</span><span class="pl-kos">.</span><span class="pl-en">emit</span><span class="pl-kos">(</span><span class="pl-c1">undefined</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-s1">absoluteFilePath</span><span class="pl-kos">,</span> <span class="pl-s1">fileContent</span><span class="pl-kos">,</span> <span class="pl-s1">sourceFile</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">'emitting'</span><span class="pl-kos">,</span> <span class="pl-s1">absoluteFilePath</span><span class="pl-kos">,</span> <span class="pl-s">'for'</span><span class="pl-kos">,</span> <span class="pl-s1">sourceFile</span><span class="pl-kos">.</span><span class="pl-c1">fileName</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-s1">fse</span><span class="pl-kos">.</span><span class="pl-en">mkdirsSync</span><span class="pl-kos">(</span><span class="pl-s1">path</span><span class="pl-kos">.</span><span class="pl-en">dirname</span><span class="pl-kos">(</span><span class="pl-s1">absoluteFilePath</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-s1">fs</span><span class="pl-kos">.</span><span class="pl-en">writeFileSync</span><span class="pl-kos">(</span><span class="pl-s1">absoluteFilePath</span><span class="pl-kos">,</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-en">fixSourceMapSources</span><span class="pl-kos">(</span><span class="pl-s1">fileContent</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">encoding</span>: <span class="pl-s">'utf-8'</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Expected behavior:</strong><br>
If this proposal is taken then the <code class="notranslate">sourceFile</code> parameter above will contain the <code class="notranslate">SourceFile</code> instance emit currently emitting the file <code class="notranslate">absoluteFilePath</code> on behalf of.</p>
<p dir="auto"><strong>Justification:</strong><br>
<code class="notranslate">.d.ts</code> files do not contain information about the decorators used in the <code class="notranslate">.ts</code> 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 <code class="notranslate">.metadata.json</code> file for each <code class="notranslate">.d.ts</code> file emitted if the corresponding module contains classes with decorators.</p>
<p dir="auto">We use <code class="notranslate">program.emit()</code> in our build process and use the callback to trigger the emit of the <code class="notranslate">.metadata.json</code> file but we must make an educated guess as to which <code class="notranslate">SourceFile</code> the <code class="notranslate">.d.ts</code> file is being emitted for. It would be more straight forward for the <code class="notranslate">SourceFile</code> to passed into the callback to <code class="notranslate">emit</code>.</p>
<p dir="auto">I'm just reading <a href="https://github.com/Microsoft/TypeScript/blob/master/src/compiler/scanner.ts">scanner code</a> and find some unicode characters are duplicate in <code class="notranslate">unicodeES5IdentifierStart</code> array:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="var unicodeES5IdentifierStart = [170, 170, 181, 181, ..., 748, 748..."><pre class="notranslate"><code class="notranslate">var unicodeES5IdentifierStart = [170, 170, 181, 181, ..., 748, 748...
</code></pre></div>
<p dir="auto">Any reason?</p>