diff --git a/tools/api-builder/docs-package/index.js b/tools/api-builder/docs-package/index.js index 52ead1ba98..c068016e09 100644 --- a/tools/api-builder/docs-package/index.js +++ b/tools/api-builder/docs-package/index.js @@ -18,7 +18,7 @@ module.exports = new Package('angular-v2-docs', [jsdocPackage, nunjucksPackage, .processor(require('./processors/checkUnbalancedBackTicks')) .processor(require('./processors/convertBackticksToCodeBlocks')) .processor(require('./processors/addNotYetDocumentedProperty')) -.processor(require('./processors/createDecoratorDocs')) +.processor(require('./processors/mergeDecoratorDocs')) .config(function(parseTagsProcessor) { parseTagsProcessor.tagDefinitions.push({ name: 'internal', transforms: function() { return true; } }); diff --git a/tools/api-builder/docs-package/processors/createDecoratorDocs.js b/tools/api-builder/docs-package/processors/createDecoratorDocs.js deleted file mode 100644 index 4e3b70dfd5..0000000000 --- a/tools/api-builder/docs-package/processors/createDecoratorDocs.js +++ /dev/null @@ -1,39 +0,0 @@ -module.exports = function mergeDecoratorDocs() { - return { - $runAfter: ['processing-docs'], - $runBefore: ['docs-processed'], - $process: function(docs) { - docs.forEach(function(doc) { - var makeDecorator = getMakeDecoratorCall(doc); - if (makeDecorator) { - doc.docType = 'decorator'; - doc.decoratorType = makeDecorator.arguments[0].text; - } - }); - } - }; -}; - -function getMakeDecoratorCall(doc, type) { - - var makeDecoratorFnName = 'make' + (type || '')+ 'Decorator'; - - var initializer = doc.exportSymbol && - doc.exportSymbol.valueDeclaration && - doc.exportSymbol.valueDeclaration.initializer; - - if (initializer) { - // There appear to be two forms of initializer: - // export var Injectable: InjectableFactory = makeDecorator(InjectableMetadata); - // and - // export var RouteConfig: (configs: RouteDefinition[]) => ClassDecorator = makeDecorator(RouteConfigAnnotation); - // In the first case, the type assertion `` causes the AST to contain an extra level of expression - // to hold the new type of the expression. - if (initializer.expression && initializer.expression.expression) { - initializer = initializer.expression; - } - if (initializer.expression && initializer.expression.text === makeDecoratorFnName) { - return initializer; - } - } -} \ No newline at end of file diff --git a/tools/api-builder/docs-package/processors/mergeDecoratorDocs.js b/tools/api-builder/docs-package/processors/mergeDecoratorDocs.js new file mode 100644 index 0000000000..dcde64b665 --- /dev/null +++ b/tools/api-builder/docs-package/processors/mergeDecoratorDocs.js @@ -0,0 +1,76 @@ +var _ = require('lodash'); + +module.exports = function mergeDecoratorDocs() { + return { + $runAfter: ['processing-docs'], + $runBefore: ['docs-processed'], + docsToMergeInfo: [ + { nameTemplate: _.template('${name}Decorator'), decoratorProperty: 'decoratorInterfaceDoc' }, + { nameTemplate: _.template('${name}Metadata'), decoratorProperty: 'metadataDoc' }, + { nameTemplate: _.template('${name}MetadataType'), decoratorProperty: 'metadataInterfaceDoc' }, + { nameTemplate: _.template('${name}MetadataFactory'), decoratorProperty: 'metadataFactoryDoc' } + ], + $process: function(docs) { + + var docsToMergeInfo = this.docsToMergeInfo; + var docsToMerge = Object.create(null); + + docs.forEach(function(doc) { + + // find all the decorators, signified by a call to `makeDecorator(metadata)` + var makeDecorator = getMakeDecoratorCall(doc); + if (makeDecorator) { + doc.docType = 'decorator'; + doc.decoratorType = makeDecorator.arguments[0].text; + + // keep track of the docs that need to be merged into this decorator doc + docsToMergeInfo.forEach(function(info) { + docsToMerge[info.nameTemplate({name: doc.name})] = { decoratorDoc: doc, property: info.decoratorProperty }; + }); + } + }); + + // merge the metadata docs into the decorator docs + docs = docs.filter(function(doc) { + if (docsToMerge[doc.name]) { + var decoratorDoc = docsToMerge[doc.name].decoratorDoc; + var property = docsToMerge[doc.name].property; + + // attach this document to its decorator + decoratorDoc[property] = doc; + + // remove doc from its module doc's exports + doc.moduleDoc.exports = doc.moduleDoc.exports.filter(function(exportDoc) { return exportDoc !== doc; }); + + // remove from the overall list of docs to be rendered + return false; + } + return true; + }); + } + }; +}; + +function getMakeDecoratorCall(doc, type) { + + var makeDecoratorFnName = 'make' + (type || '')+ 'Decorator'; + + var initializer = doc.exportSymbol && + doc.exportSymbol.valueDeclaration && + doc.exportSymbol.valueDeclaration.initializer; + + if (initializer) { + // There appear to be two forms of initializer: + // export var Injectable: InjectableFactory = makeDecorator(InjectableMetadata); + // and + // export var RouteConfig: (configs: RouteDefinition[]) => ClassDecorator = makeDecorator(RouteConfigAnnotation); + // In the first case, the type assertion `` causes the AST to contain an extra level of expression + // to hold the new type of the expression. + if (initializer.expression && initializer.expression.expression) { + initializer = initializer.expression; + } + if (initializer.expression && initializer.expression.text === makeDecoratorFnName) { + return initializer; + } + } +} \ No newline at end of file diff --git a/tools/api-builder/docs-package/processors/createDecoratorDocs.spec.js b/tools/api-builder/docs-package/processors/mergeDecoratorDocs.spec.js similarity index 100% rename from tools/api-builder/docs-package/processors/createDecoratorDocs.spec.js rename to tools/api-builder/docs-package/processors/mergeDecoratorDocs.spec.js