Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(631)

Unified Diff: pkg/docgen/lib/docgen.dart

Issue 139993008: Additional refactoring for docgen. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/docgen/bin/docgen.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/docgen/lib/docgen.dart
diff --git a/pkg/docgen/lib/docgen.dart b/pkg/docgen/lib/docgen.dart
index 168b6370d318259d93217041c31d65303b711397..d4704ce4fca192142e40200912afdeb172e11957 100644
--- a/pkg/docgen/lib/docgen.dart
+++ b/pkg/docgen/lib/docgen.dart
@@ -96,12 +96,6 @@ and
[Writing API Documentation](https://code.google.com/p/dart/wiki/WritingApiDocumentation).
""";
-// TODO(efortuna): The use of this field is odd (this is based on how it was
-// originally used. Try to cleanup.
-/// Index of all indexable items. This also ensures that no class is
-/// created more than once.
-Map<String, Indexable> entityMap = new Map<String, Indexable>();
-
/// Docgen constructor initializes the link resolver for markdown parsing.
/// Also initializes the command line arguments.
///
@@ -110,19 +104,37 @@ Map<String, Indexable> entityMap = new Map<String, Indexable>();
/// also be documented.
/// If [parseSdk] is `true`, then all Dart SDK libraries will be documented.
/// This option is useful when only the SDK libraries are needed.
+/// If [serve] is `true`, then after generating the documents we fire up a
+/// simple server to view the documentation.
///
/// Returned Future completes with true if document generation is successful.
Future<bool> docgen(List<String> files, {String packageRoot,
bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false,
bool parseSdk: false, bool append: false, String introFileName: '',
out: _DEFAULT_OUTPUT_DIRECTORY, List<String> excludeLibraries : const [],
- bool includeDependentPackages: false}) {
- return _Generator.generateDocumentation(files, packageRoot: packageRoot,
- outputToYaml: outputToYaml, includePrivate: includePrivate,
- includeSdk: includeSdk, parseSdk: parseSdk, append: append,
- introFileName: introFileName, out: out,
- excludeLibraries: excludeLibraries,
- includeDependentPackages: includeDependentPackages);
+ bool includeDependentPackages: false, bool serve: false,
+ bool noDocs: false}) {
+ var result;
+ if (!noDocs) {
+ _Viewer.ensureMovedViewerCode();
+ result = _Generator.generateDocumentation(files, packageRoot: packageRoot,
+ outputToYaml: outputToYaml, includePrivate: includePrivate,
+ includeSdk: includeSdk, parseSdk: parseSdk, append: append,
+ introFileName: introFileName, out: out,
+ excludeLibraries: excludeLibraries,
+ includeDependentPackages: includeDependentPackages);
+ _Viewer.addBackViewerCode();
+ if (serve) {
+ result.then((success) {
+ if (success) {
+ _Viewer._cloneAndServe();
+ }
+ });
+ }
+ } else if (serve) {
+ _Viewer._cloneAndServe();
+ }
+ return result;
}
/// Analyzes set of libraries by getting a mirror system and triggers the
@@ -189,6 +201,7 @@ class DummyMirror implements Indexable {
/// Docgen representation of an item to be documented, that wraps around a
/// dart2js mirror.
abstract class MirrorBased {
+ /// The original dart2js mirror around which this object wraps.
DeclarationMirror get mirror;
/// Returns a list of meta annotations assocated with a mirror.
@@ -208,8 +221,14 @@ abstract class MirrorBased {
}
}
+/// Top level documentation traversal and generation object.
+///
+/// Yes, everything in this class is used statically so this technically doesn't
+/// need to be its own class, but it's grouped together for semantic separation
+/// from the other classes and functionality in this library.
class _Generator {
- static var _outputDirectory;
+ /// The directory where the output docs are generated.
+ static String _outputDirectory;
/// This is set from the command line arguments flag --include-private
static bool _includePrivate = false;
@@ -220,6 +239,7 @@ class _Generator {
/// --exclude-lib.
static List<String> _excluded;
+ /// Logger for printing out progress of documentation generation.
static Logger logger = new Logger('Docgen');
/// Docgen constructor initializes the link resolver for markdown parsing.
@@ -259,7 +279,7 @@ class _Generator {
if (mirrorSystem.libraries.isEmpty) {
throw new StateError('No library mirrors were created.');
}
- Indexable.initializeTopLevelLibraries(mirrorSystem);
+ Indexable._initializeTopLevelLibraries(mirrorSystem);
var availableLibraries = mirrorSystem.libraries.values.where(
(each) => each.uri.scheme == 'file');
@@ -305,6 +325,21 @@ class _Generator {
mode: append ? FileMode.APPEND : FileMode.WRITE);
}
+ /// Resolve all the links in the introductory comments for a given library or
+ /// package as specified by [filename].
+ static String _readIntroductionFile(String fileName, bool includeSdk) {
+ var linkResolver = (name) => Indexable.globalFixReference(name);
+ var defaultText = includeSdk ? _DEFAULT_SDK_INTRODUCTION : '';
+ var introText = defaultText;
+ if (fileName.isNotEmpty) {
+ var introFile = new File(fileName);
+ introText = introFile.existsSync() ? introFile.readAsStringSync() :
+ defaultText;
+ }
+ return markdown.markdownToHtml(introText,
+ linkResolver: linkResolver, inlineSyntaxes: _MARKDOWN_SYNTAXES);
+ }
+
/// Creates documentation for filtered libraries.
static void _documentLibraries(List<LibraryMirror> libs,
{bool includeSdk: false, bool outputToYaml: true, bool append: false,
@@ -313,48 +348,27 @@ class _Generator {
// Files belonging to the SDK have a uri that begins with 'dart:'.
if (includeSdk || !lib.uri.toString().startsWith('dart:')) {
var library = generateLibrary(lib);
- entityMap[library.name] = library;
}
});
- var filteredEntities = entityMap.values.where(_isFullChainVisible);
-
- /*var filteredEntities2 = new Set<MirrorBased>();
- for (Map<String, Set<MirrorBased>> firstLevel in mirrorToDocgen.values) {
- for (Set<MirrorBased> items in firstLevel.values) {
- for (MirrorBased item in items) {
+ var filteredEntities = new Set<Indexable>();
+ for (Map<String, Set<Indexable>> firstLevel in
+ Indexable._mirrorToDocgen.values) {
+ for (Set<Indexable> items in firstLevel.values) {
+ for (Indexable item in items) {
if (_isFullChainVisible(item)) {
- filteredEntities2.add(item);
+ if (item is! Method ||
+ (item is Method && item.methodInheritedFrom == null)) {
+ filteredEntities.add(item);
+ }
}
}
}
- }*/
-
- /*print('THHHHHEEE DIFFERENCE IS');
- var set1 = new Set.from(filteredEntities);
- var set2 = new Set.from(filteredEntities2);
- var aResult = set2.difference(set1);
- for (MirrorBased r in aResult) {
- print(' a result is $r and ${r.docName}');
- }*/
- //print(set1.difference(set2));
+ }
// Outputs a JSON file with all libraries and their preview comments.
// This will help the viewer know what libraries are available to read in.
var libraryMap;
- var linkResolver = (name) => Indexable.globalFixReference(name);
-
- String readIntroductionFile(String fileName, includeSdk) {
- var defaultText = includeSdk ? _DEFAULT_SDK_INTRODUCTION : '';
- var introText = defaultText;
- if (fileName.isNotEmpty) {
- var introFile = new File(fileName);
- introText = introFile.existsSync() ? introFile.readAsStringSync() :
- defaultText;
- }
- return markdown.markdownToHtml(introText,
- linkResolver: linkResolver, inlineSyntaxes: _MARKDOWN_SYNTAXES);
- }
if (append) {
var docsDir = listDir(_outputDirectory);
@@ -370,16 +384,23 @@ class _Generator {
var intro = libraryMap['introduction'];
var spacing = intro.isEmpty ? '' : '<br/><br/>';
libraryMap['introduction'] =
- "$intro$spacing${readIntroductionFile(introFileName, includeSdk)}";
+ "$intro$spacing${_readIntroductionFile(introFileName, includeSdk)}";
outputToYaml = libraryMap['filetype'] == 'yaml';
} else {
libraryMap = {
'libraries' : filteredEntities.where((e) =>
e is Library).map((e) => e.previewMap).toList(),
- 'introduction' : readIntroductionFile(introFileName, includeSdk),
+ 'introduction' : _readIntroductionFile(introFileName, includeSdk),
'filetype' : outputToYaml ? 'yaml' : 'json'
};
}
+ _writeOutputFiles(libraryMap, filteredEntities, outputToYaml, append);
+ }
+
+ /// Output all of the libraries and classes into json or yaml files for
+ /// consumption by a viewer.
+ static void _writeOutputFiles(libraryMap,
+ Iterable<Indexable> filteredEntities, bool outputToYaml, bool append) {
_writeToFile(JSON.encode(libraryMap), 'library_list.json');
// Output libraries and classes to file after all information is generated.
@@ -404,6 +425,7 @@ class _Generator {
_writeToFile(JSON.encode(index), 'index.json');
}
+ /// Helper method to serialize the given Indexable out to a file.
static void _writeIndexableToFile(Indexable result, bool outputToYaml) {
var outputFile = result.fileName;
var output;
@@ -427,7 +449,8 @@ class _Generator {
}
}
-
+ /// Helper accessor to determine the full pathname of the root of the dart
+ /// checkout.
static String get _rootDirectory {
var scriptDir = path.absolute(path.dirname(Platform.script.toFilePath()));
var root = scriptDir;
@@ -472,11 +495,6 @@ class _Generator {
static String _obtainPackageRoot(String packageRoot, bool parseSdk,
List<String> files) {
if (packageRoot == null && !parseSdk) {
- // TODO(efortuna): This logic seems not very robust, but it's from the
- // original version of the code, pre-refactor, so I'm leavingt it for now.
- // Revisit to make more robust.
- // TODO(efortuna): See lines 303-311 in
- // https://codereview.chromium.org/116043013/diff/390001/pkg/docgen/lib/docgen.dart
var type = FileSystemEntity.typeSync(files.first);
if (type == FileSystemEntityType.DIRECTORY) {
var files2 = listDir(files.first, recursive: true);
@@ -570,12 +588,10 @@ class _Generator {
return sdk;
}
+ /// Return true if this item and all of its owners are all visible.
static bool _isFullChainVisible(Indexable item) {
- // TODO: reconcile with isVisible.
- // TODO: Also should be able to take MirrorBased items in general probably.
- var result = _includePrivate || (!item.isPrivate && (item.owner != null ?
+ return _includePrivate || (!item.isPrivate && (item.owner != null ?
_isFullChainVisible(item.owner) : true));
- return result;
}
/// Currently left public for testing purposes. :-/
@@ -587,6 +603,129 @@ class _Generator {
}
}
+/// Convenience methods wrapped up in a class to pull down the docgen viewer for
+/// a viewable website, and start up a server for viewing.
+class _Viewer {
+ static String _dartdocViewerString = path.join(Directory.current.path,
+ 'dartdoc-viewer');
+ static Directory _dartdocViewerDir = new Directory(_dartdocViewerString);
+ static Directory _topLevelTempDir;
+ static bool movedViewerCode = false;
+
+ /// If our dartdoc-viewer code is already checked out, move it to a temporary
+ /// directory outside of the package directory, so we don't try to process it
+ /// for documentation.
+ static void ensureMovedViewerCode() {
+ // TODO(efortuna): This will need to be modified to run on anyone's package
+ // outside of the checkout!
+ if (_dartdocViewerDir.existsSync()) {
+ _topLevelTempDir = new Directory(
+ _Generator._rootDirectory).createTempSync();
+ _dartdocViewerDir.renameSync(_topLevelTempDir.path);
+ }
+ }
+
+ /// Move the dartdoc-viewer code back into place for "webpage deployment."
+ static void addBackViewerCode() {
+ if (movedViewerCode) _dartdocViewerDir.renameSync(_dartdocViewerString);
+ }
+
+ /// Serve up our generated documentation for viewing in a browser.
+ static void _cloneAndServe() {
+ // If the viewer code is already there, then don't clone again.
+ if (_dartdocViewerDir.existsSync()) {
+ _moveDirectoryAndServe();
+ }
+ else {
+ var processResult = Process.runSync('git', ['clone', '-b', 'master',
+ 'git://github.com/dart-lang/dartdoc-viewer.git'],
+ runInShell: true);
+
+ if (processResult.exitCode == 0) {
+ _moveDirectoryAndServe();
+ } else {
+ print('Error cloning git repository:');
+ print('process output: ${processResult.stdout}');
+ print('process stderr: ${processResult.stderr}');
+ }
+ }
+ }
+
+ /// Move the generated json/yaml docs directory to the dartdoc-viewer
+ /// directory, to run as a webpage.
+ static void _moveDirectoryAndServe() {
+ var dir = new Directory(_Generator._outputDirectory == null? 'docs' :
+ _Generator._outputDirectory);
+ var webDocsDir = new Directory(path.join(_dartdocViewerDir.path, 'client',
+ 'web', 'docs'));
+ if (dir.existsSync()) {
+ // Move the docs folder to dartdoc-viewer/client/web/docs
+ dir.renameSync(webDocsDir.path);
+ }
+
+ if (webDocsDir.existsSync()) {
+ // Compile the code to JavaScript so we can run on any browser.
+ print('Compile app to JavaScript for viewing.');
+ var processResult = Process.runSync('dart', ['deploy.dart'],
+ workingDirectory : path.join(_dartdocViewerDir.path, 'client'),
+ runInShell: true);
+ print('process output: ${processResult.stdout}');
+ print('process stderr: ${processResult.stderr}');
+ _runServer();
+ }
+ }
+
+ /// A simple HTTP server. Implemented here because this is part of the SDK,
+ /// so it shouldn't have any external dependencies.
+ static void _runServer() {
+ // Launch a server to serve out of the directory dartdoc-viewer/client/web.
+ HttpServer.bind('localhost', 8080).then((HttpServer httpServer) {
+ print('Server launched. Navigate your browser to: '
+ 'http://localhost:${httpServer.port}');
+ httpServer.listen((HttpRequest request) {
+ var response = request.response;
+ var basePath = path.join(_dartdocViewerDir.path, 'client', 'out',
+ 'web');
+ var requestPath = path.join(basePath, request.uri.path.substring(1));
+ bool found = true;
+ var file = new File(requestPath);
+ if (file.existsSync()) {
+ // Set the correct header type.
+ if (requestPath.endsWith('.html')) {
+ response.headers.set('Content-Type', 'text/html');
+ } else if (requestPath.endsWith('.js')) {
+ response.headers.set('Content-Type', 'application/javascript');
+ } else if (requestPath.endsWith('.dart')) {
+ response.headers.set('Content-Type', 'application/dart');
+ } else if (requestPath.endsWith('.css')) {
+ response.headers.set('Content-Type', 'text/css');
+ }
+ } else {
+ if (requestPath == basePath) {
+ response.headers.set('Content-Type', 'text/html');
+ file = new File(path.join(basePath, 'index.html'));
+ } else {
+ print('Path not found: $requestPath');
+ found = false;
+ response.statusCode = HttpStatus.NOT_FOUND;
+ response.close();
+ }
+ }
+
+ if (found) {
+ // Serve up file contents.
+ file.openRead().pipe(response).catchError((e) {
+ print('HttpServer: error while closing the response stream $e');
+ });
+ }
+ },
+ onError: (e) {
+ print('HttpServer: an error occured $e');
+ });
+ });
+ }
+}
+
/// An item that is categorized in our mirrorToDocgen map, as a distinct,
/// searchable element.
///
@@ -647,7 +786,7 @@ abstract class Indexable extends MirrorBased {
return _getOwningLibrary(indexable.owner);
}
- static initializeTopLevelLibraries(MirrorSystem mirrorSystem) {
+ static _initializeTopLevelLibraries(MirrorSystem mirrorSystem) {
_sdkLibraries = mirrorSystem.libraries.values.where(
(each) => each.uri.scheme == 'dart');
_coreLibrary = new Library(_sdkLibraries.singleWhere((lib) =>
@@ -659,8 +798,6 @@ abstract class Indexable extends MirrorBased {
/// have them replaced with hyphens.
String get docName;
- markdown.Node fixReferenceWithScope(String name) => null;
-
/// Converts all [foo] references in comments to <a>libraryName.foo</a>.
markdown.Node fixReference(String name) {
// Attempt the look up the whole name up in the scope.
@@ -676,24 +813,36 @@ abstract class Indexable extends MirrorBased {
String findElementInScope(String name) =>
_findElementInScope(name, packagePrefix);
+ /// For a given name, determine if we need to resolve it as a qualified name
+ /// or a simple name in the source mirors.
static determineLookupFunc(name) => name.contains('.') ?
dart2js_util.lookupQualifiedInScope :
(mirror, name) => mirror.lookupInScope(name);
- // The qualified name (for URL purposes) and the file name are the same,
- // of the form packageName/ClassName or packageName/ClassName.methodName.
- // This defines both the URL and the directory structure.
- String get fileName {
- return packagePrefix + ownerPrefix + name;
- }
+ /// The reference to this element based on where it is printed as a
+ /// documentation file and also the unique URL to refer to this item.
+ ///
+ /// The qualified name (for URL purposes) and the file name are the same,
+ /// of the form packageName/ClassName or packageName/ClassName.methodName.
+ /// This defines both the URL and the directory structure.
+ String get fileName => packagePrefix + ownerPrefix + name;
+ /// The full docName of the owner element, appended with a '.' for this
+ /// object's name to be appended.
String get ownerPrefix => owner.docName != '' ? owner.docName + '.' : '';
+ /// The prefix String to refer to the package that this item is in, for URLs
+ /// and comment resolution.
+ ///
+ /// The prefix can be prepended to a qualified name to get a fully unique
+ /// name among all packages.
String get packagePrefix => '';
- /// Documentation comment with converted markdown.
+ /// Documentation comment with converted markdown and all links resolved.
String _comment;
+ /// Accessor to documentation comment with markdown converted to html and all
+ /// links resolved.
String get comment {
if (_comment != null) return _comment;
@@ -706,30 +855,19 @@ abstract class Indexable extends MirrorBased {
set comment(x) => _comment = x;
+ /// The simple name to refer to this item.
String get name => mirror.simpleName;
+ /// Accessor to the parent item that owns this item.
+ ///
+ /// "Owning" is defined as the object one scope-level above which this item
+ /// is defined. Ex: The owner for a top level class, would be its enclosing
+ /// library. The owner of a local variable in a method would be the enclosing
+ /// method.
Indexable get owner => new DummyMirror(mirror.owner);
/// Generates MDN comments from database.json.
- String _mdnComment() {
- //Check if MDN is loaded.
- if (_mdn == null) {
- // Reading in MDN related json file.
- var root = _Generator._rootDirectory;
- var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json');
- _mdn = JSON.decode(new File(mdnPath).readAsStringSync());
- }
- // TODO: refactor OOP
- if (this is Library) return '';
- var domAnnotation = this.annotations.firstWhere(
- (e) => e.mirror.qualifiedName == 'metadata.DomName',
- orElse: () => null);
- if (domAnnotation == null) return '';
- var domName = domAnnotation.parameters.single;
- var parts = domName.split('.');
- if (parts.length == 2) return _mdnMemberComment(parts[0], parts[1]);
- if (parts.length == 1) return _mdnTypeComment(parts[0]);
- }
+ String _mdnComment();
/// Generates the MDN Comment for variables and method DOM elements.
String _mdnMemberComment(String type, String member) {
@@ -740,7 +878,7 @@ abstract class Indexable extends MirrorBased {
if (mdnMember == null) return '';
if (mdnMember['help'] == null || mdnMember['help'] == '') return '';
if (mdnMember['url'] == null) return '';
- return _htmlMdn(mdnMember['help'], mdnMember['url']);
+ return _htmlifyMdn(mdnMember['help'], mdnMember['url']);
}
/// Generates the MDN Comment for class DOM elements.
@@ -749,10 +887,11 @@ abstract class Indexable extends MirrorBased {
if (mdnType == null) return '';
if (mdnType['summary'] == null || mdnType['summary'] == "") return '';
if (mdnType['srcUrl'] == null) return '';
- return _htmlMdn(mdnType['summary'], mdnType['srcUrl']);
+ return _htmlifyMdn(mdnType['summary'], mdnType['srcUrl']);
}
- String _htmlMdn(String content, String url) {
+ /// Encloses the given content in an MDN div and the original source link.
+ String _htmlifyMdn(String content, String url) {
return '<div class="mdn">' + content.trim() + '<p class="mdn-note">'
'<a href="' + url.trim() + '">from Mdn</a></p></div>';
}
@@ -770,7 +909,9 @@ abstract class Indexable extends MirrorBased {
return finalMap;
}
- String _getCommentText() {
+ /// Accessor to obtain the raw comment text for a given item, _without_ any
+ /// of the links resolved.
+ String get _commentText {
String commentText;
mirror.metadata.forEach((metadata) {
if (metadata is CommentInstanceMirror) {
@@ -795,10 +936,10 @@ abstract class Indexable extends MirrorBased {
/// links to the subclasses's version of the methods.
String _commentToHtml([Indexable resolvingScope]) {
if (resolvingScope == null) resolvingScope = this;
- var commentText = _getCommentText();
+ var commentText = _commentText;
_unresolvedComment = commentText;
- var linkResolver = (name) => resolvingScope.fixReferenceWithScope(name);
+ var linkResolver = (name) => resolvingScope.fixReference(name);
commentText = commentText == null ? '' :
markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver,
inlineSyntaxes: _MARKDOWN_SYNTAXES);
@@ -816,9 +957,7 @@ abstract class Indexable extends MirrorBased {
// with a filter. Issue(#9590).
mirrorMap.forEach((String mirrorName, VariableMirror mirror) {
if (_Generator._includePrivate || !_isHidden(mirror)) {
- var variable = new Variable(mirrorName, mirror, owner);
- entityMap[variable.docName] = variable;
- data[mirrorName] = entityMap[variable.docName];
+ data[mirrorName] = new Variable(mirrorName, mirror, owner);
}
});
return data;
@@ -833,9 +972,7 @@ abstract class Indexable extends MirrorBased {
var group = new Map<String, Method>();
mirrorMap.forEach((String mirrorName, MethodMirror mirror) {
if (_Generator._includePrivate || !mirror.isPrivate) {
- var method = new Method(mirror, owner);
- entityMap[method.docName] = method;
- group[mirror.simpleName] = method;
+ group[mirror.simpleName] = new Method(mirror, owner);
}
});
return group;
@@ -862,8 +999,7 @@ abstract class Indexable extends MirrorBased {
String toString() => "${super.toString()}(${name.toString()})";
/// Return a map representation of this type.
- Map toMap() {}
-
+ Map toMap();
/// A declaration is private if itself is private, or the owner is private.
// Issue(12202) - A declaration is public even if it's owner is private.
@@ -884,8 +1020,9 @@ abstract class Indexable extends MirrorBased {
///
/// An example that starts with _ is _js_helper.
/// An example that contains ._ is dart._collection.dev
- // This is because LibraryMirror.isPrivate returns `false` all the time.
bool _isLibraryPrivate(LibraryMirror mirror) {
+ // This method is needed because LibraryMirror.isPrivate returns `false` all
+ // the time.
var sdkLibrary = LIBRARIES[mirror.simpleName];
if (sdkLibrary != null) {
return !sdkLibrary.documented;
@@ -1011,16 +1148,18 @@ abstract class Indexable extends MirrorBased {
return null;
}
- Map expandMethodMap(Map<String, Method> mapToExpand) => {
- 'setters': recurseMap(_filterMap(new Map(), mapToExpand,
+ /// Expand the method map [mapToExpand] into a more detailed map that
+ /// separates out setters, getters, constructors, operators, and methods.
+ Map _expandMethodMap(Map<String, Method> mapToExpand) => {
+ 'setters': recurseMap(_filterMap(mapToExpand,
(key, val) => val.mirror.isSetter)),
- 'getters': recurseMap(_filterMap(new Map(), mapToExpand,
+ 'getters': recurseMap(_filterMap(mapToExpand,
(key, val) => val.mirror.isGetter)),
- 'constructors': recurseMap(_filterMap(new Map(), mapToExpand,
+ 'constructors': recurseMap(_filterMap(mapToExpand,
(key, val) => val.mirror.isConstructor)),
- 'operators': recurseMap(_filterMap(new Map(), mapToExpand,
+ 'operators': recurseMap(_filterMap(mapToExpand,
(key, val) => val.mirror.isOperator)),
- 'methods': recurseMap(_filterMap(new Map(), mapToExpand,
+ 'methods': recurseMap(_filterMap(mapToExpand,
(key, val) => val.mirror.isRegularMethod && !val.mirror.isOperator))
};
@@ -1037,14 +1176,16 @@ abstract class Indexable extends MirrorBased {
return outputMap;
}
- Map _filterMap(exported, map, test) {
+ Map _filterMap(Map map, Function test) {
+ var exported = new Map();
map.forEach((key, value) {
if (test(key, value)) exported[key] = value;
});
return exported;
}
- bool get _isVisible => _Generator._includePrivate || !isPrivate;
+ /// Accessor to determine if this item and all of its owners are visible.
+ bool get _isVisible => _Generator._isFullChainVisible(this);
/// Given a Dart2jsMirror, find the corresponding Docgen [MirrorBased] object.
///
@@ -1090,6 +1231,8 @@ abstract class Indexable extends MirrorBased {
return new DummyMirror(mirror, owner);
}
+ /// Returns true if [mirror] is the correct type of mirror that this Docgen
+ /// object wraps. (Workaround for the fact that Types are not first class.)
bool _isValidMirror(DeclarationMirror mirror);
}
@@ -1107,7 +1250,7 @@ class Library extends Indexable {
Map<String, Class> errors = {};
String packageName = '';
- bool hasBeenCheckedForPackage = false;
+ bool _hasBeenCheckedForPackage = false;
String packageIntro;
/// Returns the [Library] for the given [mirror] if it has already been
@@ -1133,9 +1276,7 @@ class Library extends Indexable {
// but we don't have visibility to that type.
var mirror = classMirror;
if (_Generator._includePrivate || !mirror.isPrivate) {
- var aTypedef = new Typedef(mirror, this);
- entityMap[Indexable.getDocgenObject(mirror).docName] = aTypedef;
- typedefs[mirror.simpleName] = aTypedef;
+ typedefs[mirror.simpleName] = new Typedef(mirror, this);
}
} else {
var clazz = new Class(classMirror, this);
@@ -1169,14 +1310,16 @@ class Library extends Indexable {
return super.findElementInScope(name);
}
+ String _mdnComment() => '';
+
/// For a library's [mirror], determine the name of the package (if any) we
/// believe it came from (because of its file URI).
///
/// If no package could be determined, we return an empty string.
String _findPackage(LibraryMirror mirror) {
if (mirror == null) return '';
- if (hasBeenCheckedForPackage) return packageName;
- hasBeenCheckedForPackage = true;
+ if (_hasBeenCheckedForPackage) return packageName;
+ _hasBeenCheckedForPackage = true;
if (mirror.uri.scheme != 'file') return '';
// We assume that we are documenting only libraries under package/lib
packageName = _packageName(mirror);
@@ -1221,8 +1364,6 @@ class Library extends Indexable {
return spec["name"];
}
- markdown.Node fixReferenceWithScope(String name) => fixReference(name);
-
String get packagePrefix => packageName == null || packageName.isEmpty ?
'' : '$packageName/';
@@ -1302,9 +1443,8 @@ class Library extends Indexable {
}
/// Checks if the given name is a key for any of the Class Maps.
- bool containsKey(String name) {
- return classes.containsKey(name) || errors.containsKey(name);
- }
+ bool containsKey(String name) =>
+ classes.containsKey(name) || errors.containsKey(name);
/// Generates a map describing the [Library] object.
Map toMap() => {
@@ -1312,7 +1452,7 @@ class Library extends Indexable {
'qualifiedName': qualifiedName,
'comment': comment,
'variables': recurseMap(variables),
- 'functions': expandMethodMap(functions),
+ 'functions': _expandMethodMap(functions),
'classes': {
'class': classes.values.where((c) => c._isVisible)
.map((e) => e.previewMap).toList(),
@@ -1330,14 +1470,40 @@ class Library extends Indexable {
}
abstract class OwnedIndexable extends Indexable {
+ /// The object one scope-level above which this item is defined.
+ ///
+ /// Ex: The owner for a top level class, would be its enclosing library.
+ /// The owner of a local variable in a method would be the enclosing method.
Indexable owner;
+ /// List of the meta annotations on this item.
+ List<Annotation> annotations;
+
/// Returns this object's qualified name, but following the conventions
/// we're using in Dartdoc, which is that library names with dots in them
/// have them replaced with hyphens.
String get docName => owner.docName + '.' + mirror.simpleName;
OwnedIndexable(DeclarationMirror mirror, this.owner) : super(mirror);
+
+ /// Generates MDN comments from database.json.
+ String _mdnComment() {
+ //Check if MDN is loaded.
+ if (Indexable._mdn == null) {
+ // Reading in MDN related json file.
+ var root = _Generator._rootDirectory;
+ var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json');
+ Indexable._mdn = JSON.decode(new File(mdnPath).readAsStringSync());
+ }
+ var domAnnotation = this.annotations.firstWhere(
+ (e) => e.mirror.qualifiedName == 'metadata.DomName',
+ orElse: () => null);
+ if (domAnnotation == null) return '';
+ var domName = domAnnotation.parameters.single;
+ var parts = domName.split('.');
+ if (parts.length == 2) return _mdnMemberComment(parts[0], parts[1]);
+ if (parts.length == 1) return _mdnTypeComment(parts[0]);
+ }
}
/// A class containing contents of a Dart class.
@@ -1366,9 +1532,6 @@ class Class extends OwnedIndexable implements Comparable {
Class superclass;
bool isAbstract;
- /// List of the meta annotations on the class.
- List<Annotation> annotations;
-
/// Make sure that we don't check for inherited comments more than once.
bool _commentsEnsured = false;
@@ -1378,7 +1541,6 @@ class Class extends OwnedIndexable implements Comparable {
var clazz = Indexable.getDocgenObject(mirror, owner);
if (clazz is DummyMirror) {
clazz = new Class._(mirror, owner);
- entityMap[clazz.docName] = clazz;
}
return clazz;
}
@@ -1420,12 +1582,10 @@ class Class extends OwnedIndexable implements Comparable {
isAbstract = classMirror.isAbstract;
inheritedMethods = new Map<String, Method>();
- // Tell all superclasses that you are a subclass, unless you are not
+ // Tell superclass that you are a subclass, unless you are not
// visible or an intermediary mixin class.
- if (!classMirror.isNameSynthetic && _isVisible) {
- parentChain().forEach((parentClass) {
- parentClass.addSubclass(this);
- });
+ if (!classMirror.isNameSynthetic && _isVisible && superclass != null) {
+ superclass.addSubclass(this);
}
if (this.superclass != null) addInherited(superclass);
@@ -1459,17 +1619,8 @@ class Class extends OwnedIndexable implements Comparable {
return result == null ? super.findElementInScope(name) : result;
}
- markdown.Node fixReferenceWithScope(String name) => fixReference(name);
-
String get typeName => 'class';
- /// Returns a list of all the parent classes.
- List<Class> parentChain() {
- // TODO(efortuna): Seems like we can get rid of this method.
- var parent = superclass == null ? [] : [superclass];
- return parent;
- }
-
/// Add all inherited variables and methods from the provided superclass.
/// If [_includePrivate] is true, it also adds the variables and methods from
/// the superclass.
@@ -1577,8 +1728,8 @@ class Class extends OwnedIndexable implements Comparable {
.map((x) => x.qualifiedName).toList(),
'variables': recurseMap(variables),
'inheritedVariables': recurseMap(inheritedVariables),
- 'methods': expandMethodMap(methods),
- 'inheritedMethods': expandMethodMap(inheritedMethods),
+ 'methods': _expandMethodMap(methods),
+ 'inheritedMethods': _expandMethodMap(inheritedMethods),
'annotations': annotations.map((a) => a.toMap()).toList(),
'generics': recurseMap(generics)
};
@@ -1596,9 +1747,6 @@ class Typedef extends OwnedIndexable {
/// Generic information about the typedef.
Map<String, Generic> generics;
- /// List of the meta annotations on the typedef.
- List<Annotation> annotations;
-
/// Returns the [Library] for the given [mirror] if it has already been
/// created, else creates it.
factory Typedef(TypedefMirror mirror, Library owningLibrary) {
@@ -1627,6 +1775,8 @@ class Typedef extends OwnedIndexable {
'generics': recurseMap(generics)
};
+ markdown.Node fixReference(String name) => null;
+
String get typeName => 'typedef';
bool _isValidMirror(DeclarationMirror mirror) => mirror is TypedefMirror;
@@ -1641,9 +1791,6 @@ class Variable extends OwnedIndexable {
Type type;
String _variableName;
- /// List of the meta annotations on the variable.
- List<Annotation> annotations;
-
factory Variable(String variableName, VariableMirror mirror,
Indexable owner) {
var variable = Indexable.getDocgenObject(mirror);
@@ -1688,8 +1835,6 @@ class Variable extends OwnedIndexable {
return super.comment;
}
- markdown.Node fixReferenceWithScope(String name) => fixReference(name);
-
String findElementInScope(String name) {
var lookupFunc = Indexable.determineLookupFunc(name);
var result = lookupFunc(mirror, name);
@@ -1726,10 +1871,7 @@ class Method extends OwnedIndexable {
/// Qualified name to state where the comment is inherited from.
String commentInheritedFrom = "";
- /// List of the meta annotations on the method.
- List<Annotation> annotations;
-
- factory Method(MethodMirror mirror, Indexable owner, // Indexable newOwner.
+ factory Method(MethodMirror mirror, Indexable owner,
[Method methodInheritedFrom]) {
var method = Indexable.getDocgenObject(mirror, owner);
if (method is DummyMirror) {
@@ -1753,8 +1895,6 @@ class Method extends OwnedIndexable {
Method get originallyInheritedFrom => methodInheritedFrom == null ?
this : methodInheritedFrom.originallyInheritedFrom;
- markdown.Node fixReferenceWithScope(String name) => fixReference(name);
-
/// Look for the specified name starting with the current member, and
/// progressively working outward to the current library scope.
String findElementInScope(String name) {
@@ -1838,14 +1978,16 @@ class Method extends OwnedIndexable {
}
var result = super.comment;
if (result == '' && methodInheritedFrom != null) {
- // this should be NOT from the MIRROR, but from the COMMENT
+ // This should be NOT from the MIRROR, but from the COMMENT.
+ methodInheritedFrom.comment; // Ensure comment field has been populated.
_unresolvedComment = methodInheritedFrom._unresolvedComment;
- var linkResolver = (name) => fixReferenceWithScope(name);
+ var linkResolver = (name) => fixReference(name);
comment = _unresolvedComment == null ? '' :
markdown.markdownToHtml(_unresolvedComment.trim(),
linkResolver: linkResolver, inlineSyntaxes: _MARKDOWN_SYNTAXES);
- commentInheritedFrom = methodInheritedFrom.commentInheritedFrom;
+ commentInheritedFrom = comment != '' ?
+ methodInheritedFrom.commentInheritedFrom : '';
result = comment;
}
return result;
« no previous file with comments | « pkg/docgen/bin/docgen.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698