jsii
Version:
[](https://cdk.dev) [](https://github.com/aws/jsii
128 lines • 5.89 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.RuntimeTypeInfoInjector = void 0;
const ts = __importStar(require("typescript"));
/**
* Provides a TransformerFactory to annotate classes with runtime information
* (e.g., fully-qualified name, version).
*
* It does this by first inserting this definition at the top of each source file:
* ```
* var JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
* ```
*
* Then, for each class that has registered runtime information during assembly,
* insert a static member to the class with its fqn and version:
* ```
* private static readonly [JSII_RTTI_SYMBOL_1] = { fqn: "ModuleName.ClassName", version: "1.2.3" }
* ```
*/
class RuntimeTypeInfoInjector {
version;
fqnsByClass = new Map();
constructor(version) {
this.version = version;
}
/**
* Register the fully-qualified name (fqn) of a class with its ClassDeclaration.
* Only ClassDeclarations with registered fqns will be annotated.
*/
registerClassFqn(clazz, fqn) {
this.fqnsByClass.set(clazz, fqn);
}
/**
* Return the set of Transformers to be used in TSC's program.emit()
*/
makeTransformers() {
return {
before: [this.runtimeTypeTransformer()],
};
}
runtimeTypeTransformer() {
return (context) => {
const { factory } = context;
return (sourceFile) => {
const rttiSymbolIdentifier = factory.createUniqueName('JSII_RTTI_SYMBOL');
let classesAnnotated = false;
const visitor = (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);
// 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;
};
};
}
/** Used instead of direct access to the map to faciliate testing. */
getClassFqn(clazz) {
return this.fqnsByClass.get(clazz);
}
/**
* If the ClassDeclaration has an associated fully-qualified name registered,
* will append a static property to the class with the fqn and version.
*/
addRuntimeInfoToClass(node, fqn, rttiSymbol, factory) {
const runtimeInfo = factory.createObjectLiteralExpression([
factory.createPropertyAssignment(factory.createIdentifier('fqn'), factory.createStringLiteral(fqn)),
factory.createPropertyAssignment(factory.createIdentifier('version'), factory.createStringLiteral(this.version)),
]);
const runtimeProperty = factory.createPropertyDeclaration([
factory.createModifier(ts.SyntaxKind.PrivateKeyword),
factory.createModifier(ts.SyntaxKind.StaticKeyword),
factory.createModifier(ts.SyntaxKind.ReadonlyKeyword),
], factory.createComputedPropertyName(rttiSymbol), undefined, undefined, runtimeInfo);
return factory.updateClassDeclaration(node, node.modifiers, node.name, node.typeParameters, node.heritageClauses, factory.createNodeArray([runtimeProperty, ...node.members]));
}
}
exports.RuntimeTypeInfoInjector = RuntimeTypeInfoInjector;
//# sourceMappingURL=runtime-info.js.map