public async emit()

in packages/jsii/lib/assembler.ts [149:334]


  public async emit(): Promise<ts.EmitResult> {
    this._diagnostics = [];
    if (!this.projectInfo.description) {
      this._diagnostics.push(
        JsiiDiagnostic.JSII_0001_PKG_MISSING_DESCRIPTION.createDetached(),
      );
    }
    if (!this.projectInfo.homepage) {
      this._diagnostics.push(
        JsiiDiagnostic.JSII_0002_PKG_MISSING_HOMEPAGE.createDetached(),
      );
    }
    const readme = await _loadReadme.call(this);
    if (readme == null) {
      this._diagnostics.push(
        JsiiDiagnostic.JSII_0003_MISSING_README.createDetached(),
      );
    }
    const docs = _loadDocs.call(this);

    this._types = {};
    this._deferred = [];
    const visitPromises = new Array<Promise<any>>();

    const sourceFile = this.program.getSourceFile(this.mainFile);

    if (sourceFile == null) {
      this._diagnostics.push(
        JsiiDiagnostic.JSII_0004_COULD_NOT_FIND_ENTRYPOINT.createDetached(
          this.mainFile,
        ),
      );
    } else {
      await this._registerDependenciesNamespaces(sourceFile);

      if (LOG.isTraceEnabled()) {
        LOG.trace(
          `Processing source file: ${chalk.blue(
            path.relative(this.projectInfo.projectRoot, sourceFile.fileName),
          )}`,
        );
      }
      const symbol = this._typeChecker.getSymbolAtLocation(sourceFile);
      if (symbol) {
        const moduleExports = this._typeChecker.getExportsOfModule(symbol);
        await Promise.all(
          moduleExports.map((item) =>
            this._registerNamespaces(item, this.projectInfo.projectRoot),
          ),
        );
        for (const node of moduleExports) {
          visitPromises.push(
            this._visitNode(
              node.declarations[0],
              new EmitContext([], this.projectInfo.stability),
            ),
          );
        }
      }
    }

    await Promise.all(visitPromises);

    this.callDeferredsInOrder();

    // Skip emitting if any diagnostic message is an error
    if (
      this._diagnostics.find(
        (diag) => diag.category === ts.DiagnosticCategory.Error,
      ) != null
    ) {
      LOG.debug('Skipping emit due to errors.');
      // Clearing ``this._types`` to allow contents to be garbage-collected.
      delete this._types;
      try {
        return { diagnostics: this._diagnostics, emitSkipped: true };
      } finally {
        // Clearing ``this._diagnostics`` to allow contents to be garbage-collected.
        delete this._diagnostics;
      }
    }

    const jsiiVersion =
      this.projectInfo.jsiiVersionFormat === 'short' ? SHORT_VERSION : VERSION;

    const assembly: spec.Assembly = {
      schema: spec.SchemaVersion.LATEST,
      name: this.projectInfo.name,
      version: this.projectInfo.version,
      description: this.projectInfo.description ?? this.projectInfo.name,
      license: this.projectInfo.license,
      keywords: this.projectInfo.keywords,
      homepage: this.projectInfo.homepage ?? this.projectInfo.repository.url,
      author: this.projectInfo.author,
      contributors: this.projectInfo.contributors && [
        ...this.projectInfo.contributors,
      ],
      repository: this.projectInfo.repository,
      dependencies: noEmptyDict({
        ...this.projectInfo.dependencies,
        ...this.projectInfo.peerDependencies,
      }),
      dependencyClosure: noEmptyDict(
        toDependencyClosure(this.projectInfo.dependencyClosure),
      ),
      bundled: this.projectInfo.bundleDependencies,
      types: this._types,
      submodules: noEmptyDict(toSubmoduleDeclarations(this.mySubmodules())),
      targets: this.projectInfo.targets,
      metadata: {
        ...this.projectInfo.metadata,

        // Downstream consumers need this to map a symbolId in the outDir to a
        // symbolId in the rootDir.
        tscRootDir: this.tscRootDir,
      },
      docs,
      readme,
      jsiiVersion,
      bin: this.projectInfo.bin,
      fingerprint: '<TBD>',
    };

    if (this.deprecatedRemover) {
      this._diagnostics.push(...this.deprecatedRemover.removeFrom(assembly));
    }

    if (this.warningsInjector) {
      const jsiiMetadata = {
        ...(assembly.metadata?.jsii ?? {}),
        ...{ compiledWithDeprecationWarnings: true },
      };

      if (assembly.metadata) {
        assembly.metadata.jsii = jsiiMetadata;
      } else {
        assembly.metadata = { jsii: jsiiMetadata };
      }
      this.warningsInjector.process(assembly, this.projectInfo);
    }

    const validator = new Validator(this.projectInfo, assembly);
    const validationResult = await validator.emit();
    if (!validationResult.emitSkipped) {
      const assemblyPath = path.join(this.projectInfo.projectRoot, '.jsii');
      LOG.trace(`Emitting assembly: ${chalk.blue(assemblyPath)}`);
      await fs.writeJson(assemblyPath, _fingerprint(assembly), {
        encoding: 'utf8',
        spaces: 2,
      });
    }

    try {
      return {
        diagnostics: [...this._diagnostics, ...validationResult.diagnostics],
        emitSkipped: validationResult.emitSkipped,
      };
    } finally {
      // Clearing ``this._types`` to allow contents to be garbage-collected.
      delete this._types;

      // Clearing ``this._diagnostics`` to allow contents to be garbage-collected.
      delete this._diagnostics;
    }

    async function _loadReadme(this: Assembler) {
      // Search for `README.md` in a case-insensitive way
      const fileName = (await fs.readdir(this.projectInfo.projectRoot)).find(
        (file) => file.toLocaleLowerCase() === 'readme.md',
      );
      if (fileName == null) {
        return undefined;
      }
      const readmePath = path.join(this.projectInfo.projectRoot, fileName);
      return loadAndRenderReadme(readmePath, this.projectInfo.projectRoot);
    }

    function _loadDocs(this: Assembler): spec.Docs | undefined {
      if (!this.projectInfo.stability && !this.projectInfo.deprecated) {
        return undefined;
      }
      const deprecated = this.projectInfo.deprecated;
      const stability = this.projectInfo.stability;
      return { deprecated, stability };
    }
  }