public process()

in src/transforms/deprecation-warnings.ts [27:140]


  public process(assembly: Assembly, projectInfo: ProjectInfo) {
    const projectRoot = projectInfo.projectRoot;
    const functionDeclarations: ts.FunctionDeclaration[] = [];

    const types = assembly.types ?? {};
    for (const type of Object.values(types)) {
      const statements: ts.Statement[] = [];
      let isEmpty = true;

      // This will add the parameter to the set of visited objects, to prevent infinite recursion
      statements.push(
        ts.factory.createExpressionStatement(
          ts.factory.createCallExpression(
            ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(VISITED_OBJECTS_SET_NAME), 'add'),
            undefined,
            [ts.factory.createIdentifier(PARAMETER_NAME)],
          ),
        ),
      );

      const tryStatements = [];
      if (spec.isDeprecated(type) && spec.isEnumType(type)) {
        // The type is deprecated
        tryStatements.push(createWarningFunctionCall(type.fqn, type.docs?.deprecated));
        isEmpty = false;
      }

      if (spec.isEnumType(type) && type.locationInModule?.filename) {
        tryStatements.push(createEnumRequireStatement(type.locationInModule?.filename));
        tryStatements.push(createDuplicateEnumValuesCheck(type));

        for (const member of Object.values(type.members ?? [])) {
          if (spec.isDeprecated(member)) {
            // The enum member is deprecated
            const condition = ts.factory.createBinaryExpression(
              ts.factory.createIdentifier(PARAMETER_NAME),
              ts.SyntaxKind.EqualsEqualsEqualsToken,
              ts.factory.createPropertyAccessExpression(
                ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(LOCAL_ENUM_NAMESPACE), type.name),
                member.name,
              ),
            );
            tryStatements.push(
              createWarningFunctionCall(`${type.fqn}#${member.name}`, member.docs?.deprecated, condition),
            );
            isEmpty = false;
          }
        }
      } else if (spec.isInterfaceType(type) && type.datatype) {
        const { statementsByProp, excludedProps } = processInterfaceType(
          type,
          types,
          assembly,
          projectInfo,
          undefined,
          undefined,
        );

        for (const [name, statement] of statementsByProp.entries()) {
          if (!excludedProps.has(name)) {
            tryStatements.push(statement);
            isEmpty = false;
          }
        }
      }

      statements.push(
        ts.factory.createTryStatement(
          ts.factory.createBlock(tryStatements),
          undefined,
          ts.factory.createBlock([
            ts.factory.createExpressionStatement(
              ts.factory.createCallExpression(
                ts.factory.createPropertyAccessExpression(
                  ts.factory.createIdentifier(VISITED_OBJECTS_SET_NAME),
                  'delete',
                ),
                undefined,
                [ts.factory.createIdentifier(PARAMETER_NAME)],
              ),
            ),
          ]),
        ),
      );

      const paramValue = ts.factory.createParameterDeclaration(undefined, undefined, PARAMETER_NAME);
      const functionName = fnName(type.fqn);
      const functionDeclaration = ts.factory.createFunctionDeclaration(
        undefined,
        undefined,
        ts.factory.createIdentifier(functionName),
        [],
        [paramValue],
        undefined,
        createFunctionBlock(isEmpty ? [] : statements),
      );
      functionDeclarations.push(functionDeclaration);
    }
    this.transformers = {
      before: [
        (context) => {
          const transformer = new Transformer(
            this.typeChecker,
            context,
            projectRoot,
            this.buildTypeIndex(assembly),
            assembly,
          );
          return transformer.transform.bind(transformer);
        },
      ],
    };
    generateWarningsFile(projectRoot, functionDeclarations);
  }