chore(doc-gen): add createDecoratorDocs processor

The createDecoratorDocs processor identifies docs of exports that actually
represent decorators and get useful information for them.

This commit also set up the rest of the generation to display these new
decorator docs with their own template and updates the API list so that
we can filter the docs by decorator docType.
This commit is contained in:
Peter Bacon Darwin 2015-12-15 10:43:43 +00:00 committed by Naomi Black
parent 9f80a27bad
commit c94ad87dd4
8 changed files with 144 additions and 1 deletions

View File

@ -1,5 +1,9 @@
@mixin icon {
line-height: 14px;
&.decorator:before {
content: 'A';
background: $blueberry;
}
&.directive:before {
content: 'D';
background: #db4437;

View File

@ -28,9 +28,10 @@ angularIO.directive('apiList', function () {
$ctrl.apiTypes = [
{ cssClass: 'directive', title: 'Directive', matches: ['directive'] },
{ cssClass: 'decorator', title: 'Decorator', matches: ['decorator'] },
{ cssClass: 'class', title: 'Class', matches: ['class'] },
{ cssClass: 'interface', title: 'Interface', matches: ['interface'] },
{ cssClass: 'function', title: 'function', matches: ['function'] },
{ cssClass: 'function', title: 'Function', matches: ['function'] },
{ cssClass: 'const', title: 'Const or Enum', matches: ['const', 'enum'] },
{ cssClass: 'var', title: 'Variable', matches: ['var', 'let'] }
];

View File

@ -92,6 +92,13 @@ module.exports = new Package('angular.io', [basePackage, targetPackage, cheatshe
outputPathTemplate:'${moduleDoc.moduleFolder}/${name}-${docType}.jade',
});
computePathsProcessor.pathTemplates.push({
docTypes: ['decorator'],
pathTemplate: '${moduleDoc.moduleFolder}/${name}-${docType}.html',
outputPathTemplate:'${moduleDoc.moduleFolder}/${name}-${docType}.jade',
});
computePathsProcessor.pathTemplates.push({
docTypes: ['jade-data'],
pathTemplate: '${originalDoc.moduleFolder}/_data',

View File

@ -0,0 +1,23 @@
{% include "lib/githubLinks.html" -%}
{% include "lib/paramList.html" -%}
{% extends 'layout/base.template.html' %}
{% block body %}
include {$ relativePath(doc.path, '_util-fns') $}
.l-main-section
h2(class="decorator export")
pre.prettyprint
code.
export {$ doc.name $}(options : {@link {$ doc.decoratorType $} {$ doc.decoratorType | escape $}}){$ returnType(doc.returnType) $}
p.location-badge.
exported from {@link {$ doc.moduleDoc.id $} {$doc.moduleDoc.id $} }
defined in {$ githubViewLink(doc) $}
:marked
{%- if doc.notYetDocumented %}
*Not Yet Documented*
{% else %}
{$ doc.description | indentForMarkdown(4) | trimBlankLines $}
{% endif -%}
{% endblock %}

View File

@ -19,6 +19,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'))
// Configure the log service
.config(function(log) {

View File

@ -0,0 +1,39 @@
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 = <InjectableFactory>makeDecorator(InjectableMetadata);
// and
// export var RouteConfig: (configs: RouteDefinition[]) => ClassDecorator = makeDecorator(RouteConfigAnnotation);
// In the first case, the type assertion `<InjectableFactory>` 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;
}
}
}

View File

@ -0,0 +1,67 @@
var mockPackage = require('../mocks/mockPackage');
var Dgeni = require('dgeni');
describe('mergeDecoratorDocs processor', function() {
var dgeni, injector, processor, decoratorDoc, otherDoc;
beforeEach(function() {
dgeni = new Dgeni([mockPackage()]);
injector = dgeni.configureInjector();
processor = injector.get('mergeDecoratorDocs');
decoratorDoc = {
name: 'X',
docType: 'var',
exportSymbol: {
valueDeclaration: {
initializer: {
expression: { text: 'makeDecorator' },
arguments: [{ text: 'XMetadata' }]
}
}
}
};
decoratorDocWithTypeAssertion = {
name: 'Y',
docType: 'var',
exportSymbol: {
valueDeclaration: {
initializer: {
expression: {
type: {},
expression: { text: 'makeDecorator' },
arguments: [{ text: 'YMetadata' }]
}
}
}
}
};
otherDoc = {
name: 'Y',
docType: 'var',
exportSymbol: {
valueDeclaration: {
initializer: {
expression: { text: 'otherCall' },
arguments: [{ text: 'param1' }]
}
}
}
};
});
it('should change the docType of only the docs that are initialied by a call to makeDecorator', function() {
processor.$process([decoratorDoc, decoratorDocWithTypeAssertion, otherDoc]);
expect(decoratorDoc.docType).toEqual('decorator');
expect(decoratorDocWithTypeAssertion.docType).toEqual('decorator');
expect(otherDoc.docType).toEqual('var');
});
it('should extract the "type" of the decorator meta data', function() {
processor.$process([decoratorDoc, decoratorDocWithTypeAssertion, otherDoc]);
expect(decoratorDoc.decoratorType).toEqual('XMetadata');
expect(decoratorDocWithTypeAssertion.decoratorType).toEqual('YMetadata');
});
});

View File

@ -202,6 +202,7 @@ module.exports = function readTypeScriptModules(tsParser, modules, getFileInfo,
var exportDoc = {
docType: getExportDocType(exportSymbol),
exportSymbol: exportSymbol,
name: name,
id: moduleDoc.id + '/' + name,
typeParams: typeParamString,