private _visitEnum()

in src/assembler.ts [1473:1545]


  private _visitEnum(type: ts.Type, ctx: EmitContext): spec.EnumType | undefined {
    if (LOG.isTraceEnabled()) {
      LOG.trace(`Processing enum: ${chalk.gray(ctx.namespace.join('.'))}.${chalk.cyan(type.symbol.name)}`);
    }

    // Forcefully resolving to the EnumDeclaration symbol for single-valued enums
    let decl: ts.Node | undefined = type.symbol.declarations?.[0];
    let symbol: ts.Symbol | undefined;
    if (decl && ts.isEnumMember(decl)) {
      decl = decl?.parent;
    }
    if (decl && ts.isEnumDeclaration(decl)) {
      symbol = getSymbolFromDeclaration(decl, this._typeChecker);
    }
    if (!decl || !symbol || !ts.isEnumDeclaration(decl)) {
      throw new JsiiError(`Unable to resolve enum declaration for ${type.symbol.name}!`);
    }

    if (_hasInternalJsDocTag(symbol)) {
      return undefined;
    }

    // check the enum to see if there are duplicate enum values
    this.assertNoDuplicateEnumValues(decl);

    this._warnAboutReservedWords(symbol);

    const flags = ts.getCombinedModifierFlags(decl);
    if (flags & ts.ModifierFlags.Const) {
      this._diagnostics.push(
        JsiiDiagnostic.JSII_1000_NO_CONST_ENUM.create(
          decl.modifiers?.find((mod) => mod.kind === ts.SyntaxKind.ConstKeyword) ?? decl,
        ),
      );
    }

    const { docs } = this._visitDocumentation(symbol, ctx);

    const typeContext = ctx.replaceStability(docs?.stability);
    const members = type.isUnion() ? type.types : [type];

    if (Case.pascal(symbol.name) !== symbol.name) {
      this._diagnostics.push(
        JsiiDiagnostic.JSII_8000_PASCAL_CASED_TYPE_NAMES.create(
          (symbol.valueDeclaration as ts.EnumDeclaration).name,
          symbol.name,
        ),
      );
    }

    const jsiiType: spec.EnumType = bindings.setEnumRelatedNode(
      {
        assembly: this.projectInfo.name,
        fqn: `${[this.projectInfo.name, ...ctx.namespace].join('.')}.${symbol.name}`,
        kind: spec.TypeKind.Enum,
        members: members.map((m) => {
          // eslint-disable-next-line @typescript-eslint/no-shadow
          const { docs } = this._visitDocumentation(m.symbol, typeContext);
          return { name: m.symbol.name, docs };
        }),
        name: symbol.name,
        namespace: ctx.namespace.length > 0 ? ctx.namespace.join('.') : undefined,
        docs,

        // Set SymbolId here instead of later, as by default TS will pick single-enum members
        // as the target symbol if possible.
        symbolId: symbolIdentifier(this._typeChecker, symbol),
      },
      decl,
    );

    return jsiiType;
  }