public runtimeTypeTransformer()

in src/transforms/runtime-info.ts [40:89]


  public runtimeTypeTransformer(): ts.TransformerFactory<ts.SourceFile> {
    return (context) => {
      const { factory } = context;

      return (sourceFile): ts.SourceFile => {
        const rttiSymbolIdentifier = factory.createUniqueName('JSII_RTTI_SYMBOL');

        let classesAnnotated = false;
        const visitor = (node: ts.Node): ts.Node => {
          if (ts.isClassDeclaration(node)) {
            const fqn = this.getClassFqn(node);
            if (fqn) {
              classesAnnotated = true;
              return this.addRuntimeInfoToClass(node, fqn, rttiSymbolIdentifier, factory);
            }
          }
          return ts.visitEachChild(node, visitor, context);
        };

        // Visit the source file, annotating the classes.
        let annotatedSourceFile = ts.visitNode(sourceFile, visitor) as ts.SourceFile;

        // Only add the symbol definition if it's actually used.
        if (classesAnnotated) {
          const rttiSymbol = factory.createCallExpression(
            factory.createPropertyAccessExpression(factory.createIdentifier('Symbol'), factory.createIdentifier('for')),
            undefined,
            [factory.createStringLiteral('jsii.rtti')],
          );
          const rttiSymbolDeclaration = factory.createVariableDeclaration(
            rttiSymbolIdentifier,
            undefined,
            undefined,
            rttiSymbol,
          );
          const variableDeclaration = factory.createVariableStatement(
            [],
            factory.createVariableDeclarationList([rttiSymbolDeclaration], ts.NodeFlags.Const),
          );

          annotatedSourceFile = factory.updateSourceFile(annotatedSourceFile, [
            variableDeclaration,
            ...annotatedSourceFile.statements,
          ]);
        }

        return annotatedSourceFile;
      };
    };
  }