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);
}