private consumeProgram()

in src/compiler.ts [268:335]


  private consumeProgram(program: ts.Program, stdlib: string): ts.EmitResult {
    const diagnostics = [...ts.getPreEmitDiagnostics(program)];
    let hasErrors = false;

    if (!hasErrors && this.diagsHaveAbortableErrors(diagnostics)) {
      hasErrors = true;
      LOG.error('Compilation errors prevented the JSII assembly from being created');
    }

    // Do the "Assembler" part first because we need some of the analysis done in there
    // to post-process the AST
    const assembler = new Assembler(this.options.projectInfo, this.system, program, stdlib, {
      stripDeprecated: this.options.stripDeprecated,
      stripDeprecatedAllowListFile: this.options.stripDeprecatedAllowListFile,
      addDeprecationWarnings: this.options.addDeprecationWarnings,
      compressAssembly: this.options.compressAssembly,
    });

    try {
      const assmEmit = assembler.emit();
      if (!hasErrors && (assmEmit.emitSkipped || this.diagsHaveAbortableErrors(assmEmit.diagnostics))) {
        hasErrors = true;
        LOG.error('Type model errors prevented the JSII assembly from being created');
      }

      diagnostics.push(...assmEmit.diagnostics);
    } catch (e: any) {
      diagnostics.push(JsiiDiagnostic.JSII_9997_UNKNOWN_ERROR.createDetached(e));
      hasErrors = true;
    }

    // Do the emit, but add in transformers which are going to replace real
    // comments with synthetic ones.
    const emit = program.emit(
      undefined, // targetSourceFile
      undefined, // writeFile
      undefined, // cancellationToken
      undefined, // emitOnlyDtsFiles
      assembler.customTransformers,
    );
    diagnostics.push(...emit.diagnostics);

    if (!hasErrors && (emit.emitSkipped || this.diagsHaveAbortableErrors(emit.diagnostics))) {
      hasErrors = true;
      LOG.error('Compilation errors prevented the JSII assembly from being created');
    }

    // Some extra validation on the config.
    // Make sure that { "./.warnings.jsii.js": "./.warnings.jsii.js" } is in the set of
    // exports, if they are specified.
    if (this.options.addDeprecationWarnings && this.options.projectInfo.exports !== undefined) {
      const expected = `./${WARNINGSCODE_FILE_NAME}`;
      const warningsExport = Object.entries(this.options.projectInfo.exports).filter(
        ([k, v]) => k === expected && v === expected,
      );

      if (warningsExport.length === 0) {
        hasErrors = true;
        diagnostics.push(JsiiDiagnostic.JSII_0007_MISSING_WARNINGS_EXPORT.createDetached());
      }
    }

    return {
      emitSkipped: hasErrors,
      diagnostics: ts.sortAndDeduplicateDiagnostics(diagnostics),
      emittedFiles: emit.emittedFiles,
    };
  }