public constructor()

in src/translate.ts [166:226]


  public constructor(snippet: TypeScriptSnippet, private readonly options: SnippetTranslatorOptions = {}) {
    const compiler = options.compiler ?? new TypeScriptCompiler();
    const source = completeSource(snippet);
    const fakeCurrentDirectory = snippet.parameters?.[SnippetParameters.$COMPILATION_DIRECTORY] ?? process.cwd();
    this.compilation = compiler.compileInMemory(
      removeSlashes(formatLocation(snippet.location)),
      source,
      fakeCurrentDirectory,
    );

    // Respect '/// !hide' and '/// !show' directives
    this.visibleSpans = Spans.visibleSpansFromSource(source);

    // Find submodule references on explicit imports
    this.submoduleReferences = SubmoduleReference.inSourceFile(
      this.compilation.rootFile,
      this.compilation.program.getTypeChecker(),
    );

    // This makes it about 5x slower, so only do it on demand
    // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
    this.tryCompile = (options.includeCompilerDiagnostics || snippet.strict) ?? false;
    if (this.tryCompile) {
      const program = this.compilation.program;
      const diagnostics = [
        ...neverThrowing(program.getGlobalDiagnostics)(),
        ...neverThrowing(program.getSyntacticDiagnostics)(this.compilation.rootFile),
        ...neverThrowing(program.getDeclarationDiagnostics)(this.compilation.rootFile),
        ...neverThrowing(program.getSemanticDiagnostics)(this.compilation.rootFile),
      ];
      if (snippet.strict) {
        // In a strict assembly, so we'll need to brand all diagnostics here...
        for (const diag of diagnostics) {
          annotateStrictDiagnostic(diag);
        }
      }
      this.compileDiagnostics.push(...diagnostics);
    }

    /**
     * Intercepts all exceptions thrown by the wrapped call, and logs them to
     * console.error instead of re-throwing, then returns an empty array. This
     * is here to avoid compiler crashes due to broken code examples that cause
     * the TypeScript compiler to hit a "Debug Failure".
     */
    function neverThrowing<A extends unknown[], R>(call: (...args: A) => readonly R[]): (...args: A) => readonly R[] {
      return (...args: A) => {
        try {
          return call(...args);
        } catch (err: any) {
          const isExpectedTypescriptError = err.message.includes('Debug Failure');

          if (!isExpectedTypescriptError) {
            console.error(`Failed to execute ${call.name}: ${err}`);
          }

          return [];
        }
      };
    }
  }