<commit_before>/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */

import * as path from 'path';
import * as ts from 'typescript';

export interface ShimGenerator {
  /**
   * Get the original source file for the given shim path, the contents of which determine the
   * contents of the shim file.
   *
   * If this returns `null` then the given file was not a shim file handled by this generator.
   */
  getOriginalSourceOfShim(fileName: string): string|null;

  /**
   * Generate a shim's `ts.SourceFile` for the given original file.
   */
  generate(original: ts.SourceFile, genFileName: string): ts.SourceFile;
}

/**
 * A wrapper around a `ts.CompilerHost` which supports generated files.
 */
export class GeneratedShimsHostWrapper implements ts.CompilerHost {
  constructor(private delegate: ts.CompilerHost, private shimGenerators: ShimGenerator[]) {
    if (delegate.resolveTypeReferenceDirectives) {
      // Backward compatibility with TypeScript 2.9 and older since return
      // type has changed from (ts.ResolvedTypeReferenceDirective | undefined)[]
      // to ts.ResolvedTypeReferenceDirective[] in Typescript 3.0
      type ts3ResolveTypeReferenceDirectives = (names: string[], containingFile: string) =>
          ts.ResolvedTypeReferenceDirective[];
      this.resolveTypeReferenceDirectives = (names: string[], containingFile: string) =>
          (delegate.resolveTypeReferenceDirectives as ts3ResolveTypeReferenceDirectives) !(
              names, containingFile);
    }
    if (delegate.directoryExists !== undefined) {
      this.directoryExists = (directoryName: string) => delegate.directoryExists !(directoryName);
    }
  }

  resolveTypeReferenceDirectives?:
      (names: string[], containingFile: string) => ts.ResolvedTypeReferenceDirective[];

  directoryExists?: (directoryName: string) => boolean;

  getSourceFile(
      fileName: string, languageVersion: ts.ScriptTarget,
      onError?: ((message: string) => void)|undefined,
      shouldCreateNewSourceFile?: boolean|undefined): ts.SourceFile|undefined {
    const canonical = this.getCanonicalFileName(fileName);
    for (let i = 0; i < this.shimGenerators.length; i++) {
      const generator = this.shimGenerators[i];
      const originalFile = generator.getOriginalSourceOfShim(canonical);
      if (originalFile !== null) {
        // This shim generator has recognized the filename being requested, and is now responsible
        // for generating its contents, based on the contents of the original file it has requested.
        const originalSource = this.delegate.getSourceFile(
            originalFile, languageVersion, onError, shouldCreateNewSourceFile);
        if (originalSource === undefined) {
          // The original requested file doesn't exist, so the shim cannot exist either.
          return undefined;
        }
        return generator.generate(originalSource, fileName);<commit_msg>fix(compiler-cli): ngtsc shim files not being generated on case-insensitive platforms (#27466)<commit_after>/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */

import * as path from 'path';
import * as ts from 'typescript';

export interface ShimGenerator {
  /**
   * Get the original source file for the given shim path, the contents of which determine the
   * contents of the shim file.
   *
   * If this returns `null` then the given file was not a shim file handled by this generator.
   */
  getOriginalSourceOfShim(fileName: string): string|null;

  /**
   * Generate a shim's `ts.SourceFile` for the given original file.
   */
  generate(original: ts.SourceFile, genFileName: string): ts.SourceFile;
}

/**
 * A wrapper around a `ts.CompilerHost` which supports generated files.
 */
export class GeneratedShimsHostWrapper implements ts.CompilerHost {
  constructor(private delegate: ts.CompilerHost, private shimGenerators: ShimGenerator[]) {
    if (delegate.resolveTypeReferenceDirectives) {
      // Backward compatibility with TypeScript 2.9 and older since return
      // type has changed from (ts.ResolvedTypeReferenceDirective | undefined)[]
      // to ts.ResolvedTypeReferenceDirective[] in Typescript 3.0
      type ts3ResolveTypeReferenceDirectives = (names: string[], containingFile: string) =>
          ts.ResolvedTypeReferenceDirective[];
      this.resolveTypeReferenceDirectives = (names: string[], containingFile: string) =>
          (delegate.resolveTypeReferenceDirectives as ts3ResolveTypeReferenceDirectives) !(
              names, containingFile);
    }
    if (delegate.directoryExists !== undefined) {
      this.directoryExists = (directoryName: string) => delegate.directoryExists !(directoryName);
    }
  }

  resolveTypeReferenceDirectives?:
      (names: string[], containingFile: string) => ts.ResolvedTypeReferenceDirective[];

  directoryExists?: (directoryName: string) => boolean;

  getSourceFile(
      fileName: string, languageVersion: ts.ScriptTarget,
      onError?: ((message: string) => void)|undefined,
      shouldCreateNewSourceFile?: boolean|undefined): ts.SourceFile|undefined {
    for (let i = 0; i < this.shimGenerators.length; i++) {
      const generator = this.shimGenerators[i];
      const originalFile = generator.getOriginalSourceOfShim(fileName);
      if (originalFile !== null) {
        // This shim generator has recognized the filename being requested, and is now responsible
        // for generating its contents, based on the contents of the original file it has requested.
        const originalSource = this.delegate.getSourceFile(
            originalFile, languageVersion, onError, shouldCreateNewSourceFile);
        if (originalSource === undefined) {
          // The original requested file doesn't exist, so the shim cannot exist either.
          return undefined;
        }
        return generator.generate(originalSource, fileName);
{'fraction_non_alphanumeric': 0.09277678134681233, 'fraction_numerical': 0.0030979944562204466, 'mean_word_length': 3.7039877300613497, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2884201', 'n_tokens_mistral': 1562, 'n_tokens_neox': 1557, 'n_words': 528}