/** * Convert a reflected decorator to metadata. */ function decoratorToMetadata(decorator) { // Decorators have a type. var properties = [ ts.createPropertyAssignment('type', ts.updateIdentifier(decorator.identifier)), ]; // Sometimes they have arguments. if (decorator.args !== null && decorator.args.length > 0) { var args = decorator.args.map(function (arg) { return ts.getMutableClone(arg); }); properties.push(ts.createPropertyAssignment('args', ts.createArrayLiteral(args))); } return ts.createObjectLiteral(properties, true); }
/** * Given a class declaration, generate a call to `setClassMetadata` with the Angular metadata * present on the class or its member fields. * * If no such metadata is present, this function returns `null`. Otherwise, the call is returned * as a `Statement` for inclusion along with the class. */ function generateSetClassMetadataCall(clazz, reflection, defaultImportRecorder, isCore) { if (!reflection.isClass(clazz)) { return null; } var id = ts.updateIdentifier(clazz.name); // Reflect over the class decorators. If none are present, or those that are aren't from // Angular, then return null. Otherwise, turn them into metadata. var classDecorators = reflection.getDecoratorsOfDeclaration(clazz); if (classDecorators === null) { return null; } var ngClassDecorators = classDecorators.filter(function (dec) { return isAngularDecorator(dec, isCore); }).map(decoratorToMetadata); if (ngClassDecorators.length === 0) { return null; } var metaDecorators = ts.createArrayLiteral(ngClassDecorators); // Convert the constructor parameters to metadata, passing null if none are present. var metaCtorParameters = new compiler_1.LiteralExpr(null); var classCtorParameters = reflection.getConstructorParameters(clazz); if (classCtorParameters !== null) { var ctorParameters = classCtorParameters.map(function (param) { return ctorParameterToMetadata(param, defaultImportRecorder, isCore); }); metaCtorParameters = new compiler_1.FunctionExpr([], [ new compiler_1.ReturnStatement(new compiler_1.LiteralArrayExpr(ctorParameters)), ]); } // Do the same for property decorators. var metaPropDecorators = ts.createNull(); var decoratedMembers = reflection.getMembersOfClass(clazz) .filter(function (member) { return !member.isStatic && member.decorators !== null; }) .map(function (member) { return classMemberToMetadata(member.name, member.decorators, isCore); }); if (decoratedMembers.length > 0) { metaPropDecorators = ts.createObjectLiteral(decoratedMembers); } // Generate a pure call to setClassMetadata with the class identifier and its metadata. var setClassMetadata = new compiler_1.ExternalExpr(compiler_1.Identifiers.setClassMetadata); var fnCall = new compiler_1.InvokeFunctionExpr( /* fn */ setClassMetadata, /* args */ [ new compiler_1.WrappedNodeExpr(id), new compiler_1.WrappedNodeExpr(metaDecorators), metaCtorParameters, new compiler_1.WrappedNodeExpr(metaPropDecorators), ], /* type */ undefined, /* sourceSpan */ undefined, /* pure */ true); return fnCall.toStmt(); }