fix(docs): Working generated angular2.d.ts

This requires some hacks, documented in
https://docs.google.com/document/d/1nNebWTiLzz5ePcit_bjZPtaiSIFU4EsQKUlX7LX0c0A/edit

Changes:
- include subtyping info in angular2.d.ts by adding 'extends supertype'
- export missing symbols needed transitively by angular2/angular2
- because of decorator/annotation mismatch, we can't export these to applications.
  So I've added a separate angular2.api.ts file to re-export specifically to .d.ts
  generation.
- Hack to remove aliases introduced by 'import * as alias' syntax
- Hack to deal with Error still an interface

note that we require users to install the transitive dependencies - this is how TSD works.
This commit is contained in:
Alex Eagle 2015-06-02 17:32:03 -07:00
parent 5357b1548a
commit 7141c15e65
5 changed files with 108 additions and 10 deletions

View File

@ -15,8 +15,9 @@ module.exports = function createTypeDefinitionFile() {
};
_.forEach(docs, function(doc) {
// The shape of the public API is determined by what is reexported into
// angular2/angular2.
if (doc.id === 'angular2/angular2') {
// angular2/angular2, with hacks layered into angular2.api.ts
if (doc.id === 'angular2/angular2.api') {
doc.id = 'angular2/angular2';
typeDefDoc.modules.push(doc);
}
});

View File

@ -3,7 +3,8 @@ var path = require('canonical-path');
var _ = require('lodash');
var ts = require('typescript');
module.exports = function readTypeScriptModules(tsParser, readFilesProcessor, modules, getFileInfo, getExportDocType, getContent, log) {
module.exports = function readTypeScriptModules(tsParser, readFilesProcessor, modules, getFileInfo,
getExportDocType, getContent, log) {
return {
$runAfter: ['files-read'],
@ -12,8 +13,8 @@ module.exports = function readTypeScriptModules(tsParser, readFilesProcessor, mo
$validate: {
sourceFiles: {presence: true},
basePath: {presence: true},
hidePrivateMembers: { inclusion: [true, false] },
sortClassMembers: { inclusion: [true, false] },
hidePrivateMembers: {inclusion: [true, false]},
sortClassMembers: {inclusion: [true, false]},
ignoreExportsMatching: {}
},
@ -64,7 +65,7 @@ module.exports = function readTypeScriptModules(tsParser, readFilesProcessor, mo
// Generate docs for each of the export's members
if (resolvedExport.flags & ts.SymbolFlags.HasMembers) {
exportDoc.members = [];
for(var memberName in resolvedExport.members) {
log.silly('>>>>>> member: ' + memberName + ' from ' + exportDoc.id + ' in ' + moduleDoc.id);
@ -115,6 +116,29 @@ module.exports = function readTypeScriptModules(tsParser, readFilesProcessor, mo
}
function createExportDoc(name, exportSymbol, moduleDoc, basePath, typeChecker) {
exportSymbol.declarations.forEach(function(decl) {
var sourceFile = ts.getSourceFileOfNode(decl);
if (decl.typeParameters) {
name = name + '<' + getText(sourceFile, decl.typeParameters) + '>';
}
if (decl.heritageClauses) {
decl.heritageClauses.forEach(function(heritage) {
if (heritage.token == ts.SyntaxKind.ExtendsKeyword) {
name = name + " extends ";
heritage.types.forEach(function(typ, idx) {
name = name + (idx > 0 ? ', ' : '') + typ.getFullText();
});
}
if (heritage.token == ts.SyntaxKind.ImplementsKeyword) {
name = name + " implements ";
heritage.types.forEach(function(typ, idx) {
name = name + (idx > 0 ? ', ' : '') + typ.getFullText();
});
}
});
}
});
var exportDoc = {
docType: getExportDocType(exportSymbol),
name: name,
@ -167,14 +191,21 @@ module.exports = function readTypeScriptModules(tsParser, readFilesProcessor, mo
function getParameters(typeChecker, symbol) {
var declaration = symbol.valueDeclaration || symbol.declarations[0];
var sourceFile = ts.getSourceFileOfNode(declaration);
if(!declaration.parameters) {
if (!declaration.parameters) {
var location = getLocation(symbol);
throw new Error('missing declaration parameters for "' + symbol.name +
'" in ' + sourceFile.fileName +
' at line ' + location.start.line);
}
return declaration.parameters.map(function(parameter) {
return getText(sourceFile, parameter).trim();
var paramText = getText(sourceFile, parameter.name);
if (parameter.questionToken || parameter.initializer) {
paramText += '?';
}
if (parameter.type) {
paramText += ':' + getType(sourceFile, parameter.type);
}
return paramText.trim();
});
}
@ -182,7 +213,7 @@ module.exports = function readTypeScriptModules(tsParser, readFilesProcessor, mo
var declaration = symbol.valueDeclaration || symbol.declarations[0];
var sourceFile = ts.getSourceFileOfNode(declaration);
if (declaration.type) {
return getText(sourceFile, declaration.type).trim();
return getType(sourceFile, declaration.type).trim();
}
}
@ -201,6 +232,18 @@ module.exports = function readTypeScriptModules(tsParser, readFilesProcessor, mo
}
// Strip any local renamed imports from the front of types
function getType(sourceFile, type) {
var text = getText(sourceFile, type);
while (text.indexOf(".") >= 0) {
// Keep namespaced symbols in Rx
if (text.match(/^\s*Rx\./)) break;
// handle the case List<thing.stuff> -> List<stuff>
text = text.replace(/([^.<]*)\.([^>]*)/, "$2");
}
return text;
}
function getLocation(symbol) {
var node = symbol.valueDeclaration || symbol.declarations[0];
var sourceFile = ts.getSourceFileOfNode(node);

View File

@ -6,7 +6,7 @@
{$ '*/' | indent(level, true) | replace(r/\n$/, "") $}{% endif -%}
{%- endmacro -%}
// Type definitions for Angular v2.0.0-alpha.22
// Type definitions for Angular v2.0.0-alpha.26
// Project: http://angular.io/
// Definitions by: angular team <https://github.com/angular/>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
@ -16,6 +16,29 @@
// Please do not create manual edits or send pull requests
// modifying this file.
// ***********************************************************
// Angular depends transitively on these libraries.
// If you don't have them installed you can run
// $ tsd query es6-promise rx rx-lite --action install --save
///<reference path="../es6-promise/es6-promise.d.ts"/>
///<reference path="../rx/rx.d.ts"/>
interface List<T> extends Array<T> {}
interface Map<K,V> {}
interface StringMap<K,V> extends Map<K,V> {}
interface Type {}
declare module "angular2/angular2" {
type SetterFn = typeof Function;
type int = number;
// See https://github.com/Microsoft/TypeScript/issues/1168
class BaseException /* extends Error */ {
message;
stack;
toString(): string;
}
}
{% for module in doc.modules %}
{$ commentBlock(module, 1) $}
declare module "{$ module.id $}" {

View File

@ -0,0 +1,3 @@
library angular2.angular2.api;
// Ignore this file for dart emit.
// It is used only for generating the TypeScript .d.ts file.

View File

@ -0,0 +1,28 @@
// This module is used by dgeni to produce the angular2.d.ts file.
// Re-export everything we export to the application runtime
export * from './angular2';
// Horrible hack. See
// https://docs.google.com/document/d/1nNebWTiLzz5ePcit_bjZPtaiSIFU4EsQKUlX7LX0c0A/edit
// Exports needed to make angular2.d.ts work,
// because these symbols are dependencies of other exports but are not otherwise exported.
// This should be cleaned up in one of two ways:
// 1) if the symbol is intended to be part of the public API, then re-export somewhere else
// 2) if the symbol should be omitted from the public API, then the class exposing it should
// not be exported, or should avoid exposing the symbol.
export {AbstractChangeDetector} from './src/change_detection/abstract_change_detector';
export {ProtoRecord} from './src/change_detection/proto_record';
export * from './src/core/compiler/element_injector';
// FIXME: this is a workaround for https://github.com/angular/angular/issues/2356
// We export the Directive *annotation* instead of the *decorator*.
// But it breaks the build.
export {Directive, LifecycleEvent} from './src/core/annotations_impl/annotations';
export {FormDirective} from './src/forms/directives/form_directive';
export {ControlContainerDirective} from './src/forms/directives/control_container_directive';
export {Injectable} from './src/di/annotations_impl';
export {BaseQueryList} from './src/core/compiler/base_query_list';
export {AppProtoView, AppView, AppViewContainer} from './src/core/compiler/view';
export * from './src/change_detection/parser/ast';
export {Visibility} from './src/core/annotations_impl/visibility';
export {AppViewManager} from './src/core/compiler/view_manager';