| Index: utils/dartdoc/dartdoc.dart
|
| diff --git a/utils/dartdoc/dartdoc.dart b/utils/dartdoc/dartdoc.dart
|
| index a85f25fdf9946481bf88f91caab47f3f7f8139dc..7bdc2266e202054cff07f6ee2d94f245370c2513 100644
|
| --- a/utils/dartdoc/dartdoc.dart
|
| +++ b/utils/dartdoc/dartdoc.dart
|
| @@ -21,6 +21,8 @@
|
| #import('../markdown/lib.dart', prefix: 'md');
|
|
|
| #source('classify.dart');
|
| +#source('files.dart');
|
| +#source('utils.dart');
|
|
|
| /** Path to corePath library. */
|
| final corePath = 'lib';
|
| @@ -29,17 +31,11 @@ final corePath = 'lib';
|
| final outdir = 'docs';
|
|
|
| /** Set to `true` to include the source code in the generated docs. */
|
| -bool includeSource = true;
|
| +bool includeSource = false;
|
|
|
| /** Special comment position used to store the library-level doc comment. */
|
| final _libraryDoc = -1;
|
|
|
| -/** The path to the file currently being written to, relative to [outdir]. */
|
| -String _filePath;
|
| -
|
| -/** The file currently being written to. */
|
| -StringBuffer _file;
|
| -
|
| /** The library that we're currently generating docs for. */
|
| Library _currentLibrary;
|
|
|
| @@ -62,8 +58,6 @@ int _totalLibraries = 0;
|
| int _totalTypes = 0;
|
| int _totalMembers = 0;
|
|
|
| -FileSystem files;
|
| -
|
| /**
|
| * Run this from the `utils/dartdoc` directory.
|
| */
|
| @@ -102,17 +96,6 @@ void main() {
|
| world.processDartScript(libPath);
|
| world.resolveAll();
|
|
|
| - // Clean the output directory.
|
| - if (files.fileExists(outdir)) {
|
| - files.removeDirectory(outdir, recursive: true);
|
| - }
|
| - files.createDirectory(outdir, recursive: true);
|
| -
|
| - // Copy over the static files.
|
| - for (final file in ['interact.js', 'styles.css']) {
|
| - copyStatic(file);
|
| - }
|
| -
|
| // Generate the docs.
|
| for (final library in world.libraries.getValues()) {
|
| docLibrary(library);
|
| @@ -129,47 +112,6 @@ void initializeDartDoc() {
|
| _comments = <String, Map<int, String>>{};
|
| }
|
|
|
| -/** Copies the static file at 'static/file' to the output directory. */
|
| -copyStatic(String file) {
|
| - var contents = files.readAll(joinPaths('static', file));
|
| - files.writeString(joinPaths(outdir, file), contents);
|
| -}
|
| -
|
| -num time(callback()) {
|
| - // Unlike world.withTiming, returns the elapsed time.
|
| - final watch = new Stopwatch();
|
| - watch.start();
|
| - callback();
|
| - watch.stop();
|
| - return watch.elapsedInMs();
|
| -}
|
| -
|
| -startFile(String path) {
|
| - _filePath = path;
|
| - _file = new StringBuffer();
|
| -}
|
| -
|
| -write(String s) {
|
| - _file.add(s);
|
| -}
|
| -
|
| -writeln(String s) {
|
| - write(s);
|
| - write('\n');
|
| -}
|
| -
|
| -endFile() {
|
| - String outPath = '$outdir/$_filePath';
|
| - files.createDirectory(dirname(outPath), recursive: true);
|
| -
|
| - world.files.writeString(outPath, _file.toString());
|
| - _filePath = null;
|
| - _file = null;
|
| -}
|
| -
|
| -/** Turns a library name into something that's safe to use as a file name. */
|
| -sanitize(String name) => name.replaceAll(':', '_').replaceAll('/', '_');
|
| -
|
| docIndex(List<Library> libraries) {
|
| startFile('index.html');
|
| // TODO(rnystrom): Need to figure out what this should look like.
|
| @@ -204,53 +146,6 @@ docIndex(List<Library> libraries) {
|
| endFile();
|
| }
|
|
|
| -/** Returns the number of times [search] occurs in [text]. */
|
| -int countOccurrences(String text, String search) {
|
| - int start = 0;
|
| - int count = 0;
|
| -
|
| - while (true) {
|
| - start = text.indexOf(search, start);
|
| - if (start == -1) break;
|
| - count++;
|
| - // Offsetting by needle length means overlapping needles are not counted.
|
| - start += search.length;
|
| - }
|
| -
|
| - return count;
|
| -}
|
| -
|
| -/** Repeats [text] [count] times, separated by [separator] if given. */
|
| -String repeat(String text, int count, [String separator]) {
|
| - // TODO(rnystrom): Should be in corelib.
|
| - final buffer = new StringBuffer();
|
| - for (int i = 0; i < count; i++) {
|
| - buffer.add(text);
|
| - if ((i < count - 1) && (separator !== null)) buffer.add(separator);
|
| - }
|
| -
|
| - return buffer.toString();
|
| -}
|
| -
|
| -/**
|
| - * Converts [absolute] which is understood to be a full path from the root of
|
| - * the generated docs to one relative to the current file.
|
| - */
|
| -String relativePath(String absolute) {
|
| - // TODO(rnystrom): Walks all the way up to root each time. Shouldn't do this
|
| - // if the paths overlap.
|
| - return repeat('../', countOccurrences(_filePath, '/')) + absolute;
|
| -}
|
| -
|
| -/**
|
| - * Creates a hyperlink. Handles turning the [href] into an appropriate relative
|
| - * path from the current file.
|
| - */
|
| -String a(String href, String contents, [String class]) {
|
| - final css = class == null ? '' : ' class="$class"';
|
| - return '<a href="${relativePath(href)}"$css>$contents</a>';
|
| -}
|
| -
|
| writeHeader(String title) {
|
| writeln(
|
| '''
|
| @@ -265,21 +160,68 @@ writeHeader(String title) {
|
| <script src="${relativePath('interact.js')}"></script>
|
| </head>
|
| <body>
|
| - <div class="content">
|
| + <div class="page">
|
| ''');
|
| + docNavigation();
|
| + writeln('<div class="content">');
|
| }
|
|
|
| writeFooter() {
|
| writeln(
|
| '''
|
| </div>
|
| + <div class="footer"</div>
|
| </body></html>
|
| ''');
|
| }
|
|
|
| +docNavigation() {
|
| + writeln(
|
| + '''
|
| + <div class="nav">
|
| + <h1>Libraries</h1>
|
| + ''');
|
| +
|
| + for (final library in orderValuesByKeys(world.libraries)) {
|
| + write('<h2><div class="icon-library"></div> ');
|
| +
|
| + if ((_currentLibrary == library) && (_currentType == null)) {
|
| + write('<strong>${library.name}</strong>');
|
| + } else {
|
| + write('${a(libraryUrl(library), library.name)}');
|
| + }
|
| + write('</h2>');
|
| +
|
| + final types = orderValuesByKeys(library.types);
|
| + if (types.length > 0) {
|
| + writeln('<ul>');
|
| + for (final type in types) {
|
| + if (type.isTop) continue;
|
| + if (type.name.startsWith('_')) continue;
|
| +
|
| + var icon = type.isClass ? 'icon-class' : 'icon-interface';
|
| + write('<li><div class="$icon"></div> ');
|
| +
|
| + if (_currentType == type) {
|
| + write('<strong>${type.name}</strong>');
|
| + } else {
|
| + write('${a(typeUrl(type), type.name)}');
|
| + }
|
| +
|
| + writeln('</li>');
|
| + }
|
| +
|
| + writeln('</ul>');
|
| + }
|
| + }
|
| +
|
| + writeln('</div>');
|
| +}
|
| +
|
| docLibrary(Library library) {
|
| _totalLibraries++;
|
| _currentLibrary = library;
|
| + _currentType = null;
|
|
|
| startFile(libraryUrl(library));
|
| writeHeader(library.name);
|
| @@ -300,6 +242,7 @@ docLibrary(Library library) {
|
|
|
| for (final type in orderValuesByKeys(library.types)) {
|
| if (type.isTop) continue;
|
| + if (type.name.startsWith('_')) continue;
|
| writeln(
|
| '''
|
| <div class="type">
|
| @@ -469,10 +412,10 @@ docMethod(Type type, MethodMember method, [String constructorName = null]) {
|
|
|
| // Translate specially-named methods: getters, setters, operators.
|
| var name = method.name;
|
| - if (name.startsWith('get\$')) {
|
| + if (name.startsWith('get:')) {
|
| // Getter.
|
| name = 'get ${name.substring(4)}';
|
| - } else if (name.startsWith('set\$')) {
|
| + } else if (name.startsWith('set:')) {
|
| // Setter.
|
| name = 'set ${name.substring(4)}';
|
| } else {
|
| @@ -542,6 +485,15 @@ docField(Type type, FieldMember field) {
|
| writeln('</div>');
|
| }
|
|
|
| +/**
|
| + * Creates a hyperlink. Handles turning the [href] into an appropriate relative
|
| + * path from the current file.
|
| + */
|
| +String a(String href, String contents, [String class]) {
|
| + final css = class == null ? '' : ' class="$class"';
|
| + return '<a href="${relativePath(href)}"$css>$contents</a>';
|
| +}
|
| +
|
| /** Generates a human-friendly string representation for a type. */
|
| typeName(Type type) {
|
| // See if it's a generic type.
|
| @@ -562,27 +514,6 @@ typeName(Type type) {
|
| return type.name;
|
| }
|
|
|
| -/** Gets the URL to the documentation for [library]. */
|
| -libraryUrl(Library library) {
|
| - return '${sanitize(library.name)}.html';
|
| -}
|
| -
|
| -/** Gets the URL for the documentation for [type]. */
|
| -typeUrl(Type type) {
|
| - // Always get the generic type to strip off any type parameters or arguments.
|
| - // If the type isn't generic, genericType returns `this`, so it works for
|
| - // non-generic types too.
|
| - return '${sanitize(type.library.name)}/${type.genericType.name}.html';
|
| -}
|
| -
|
| -/** Gets the URL for the documentation for [member]. */
|
| -memberUrl(Member member) {
|
| - return '${typeUrl(member.declaringType)}#${member.name}';
|
| -}
|
| -
|
| -/** Gets the anchor id for the document for [member]. */
|
| -memberAnchor(Member member) => '${member.name}';
|
| -
|
| /** Writes a linked cross reference to [type]. */
|
| typeReference(Type type) {
|
| // TODO(rnystrom): Do we need to handle ParameterTypes here like
|
| @@ -780,17 +711,6 @@ int getSpanColumn(SourceSpan span) {
|
| return span.file.getColumn(line, span.start);
|
| }
|
|
|
| -/** Removes up to [indentation] leading whitespace characters from [text]. */
|
| -unindent(String text, int indentation) {
|
| - var start;
|
| - for (start = 0; start < Math.min(indentation, text.length); start++) {
|
| - // Stop if we hit a non-whitespace character.
|
| - if (text[start] != ' ') break;
|
| - }
|
| -
|
| - return text.substring(start);
|
| -}
|
| -
|
| /**
|
| * Pulls the raw text out of a doc comment (i.e. removes the comment
|
| * characters).
|
|
|