remove docgen source and targets from build

BUG=
R=alanknight@google.com

Review URL: https://codereview.chromium.org//1364553002 .
This commit is contained in:
keertip 2015-09-22 15:10:18 -07:00
parent 5612c202a0
commit c775149a5a
59 changed files with 1 additions and 4684 deletions

View file

@ -1,26 +0,0 @@
Copyright 2014, the Dart project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,140 +0,0 @@
docgen
======
**Deprecated** please use https://pub.dartlang.org/packages/dartdoc instead.
A documentation generator for Dart.
- - -
The docgen tool takes in a file or directory as input and produces documentation
for all `.dart` file it finds as YAML or JSON files. This outputs information
about all classes, variables, functions, and methods defined in the library and
its imported libraries.
### Quick Start: Common Commands
##### To only generate documentation, while standing in the `bin` directory:
`dartdoc.py` generates all documentation and runs a local server with your html
pages.
`dartdoc.py -d` ONLY generates documentation for the SDK and all packages (no
html pages generated and no server).
`dartdoc.py -d -o package/to/document` ONLY generates documenation for the
specified package.
##### To generate documentation and view it through the webpage:
- Install [Google App Engine SDK for Python][GAE] (one time setup) and agree to
add symlinks so that dev\_appserver.py can be found on your PATH.
- Run `dartdoc.py`.
### Generating files & uploading to Cloud Storage
The viewer uses YAML files generated by the docgen package as the data
being displayed. These files are stored in Google Cloud Storage.
- Run `python upload_docgen.py` to generate these files and upload them to
Cloud Storage as a new version.
- - -
These tasks can be done separately if necessary:
#####
#### Generating YAML files
YAML files can be generated using the docgen package in the dart repository.
###### Usage
Run `dart docgen.dart [OPTIONS] <path to directory or file>`
###### Options available
- `-h`, `--help` Prints help and usage information.
- `-v`, `--verbose` Output more logging information.
- `-j`, `--[no-]json` Outputs to JSON. Files are outputted to YAML by default.
If `--append` is used, it takes the file-format of the previous run stated in
library_list.json ignoring the flag.
- `--include-private` Flag to include private declarations.
- `--include-sdk` Flag to parse SDK Library files imported.
- `--parse-sdk` Parses the SDK libraries only. (Ignores the path passed in.)
- `--package-root` Sets the package root of the library being analyzed.
- `--append` Appends to the docs folder, library_list.json, and index.txt.
- `--introduction` Adds the provided markdown text file as the introduction
for the outputted documentation.
###### Output directory
Documented libraries will be located at bin/docs in either YAML or JSON format
depending on options specified. There will also be a library\_list.json,
containing a list of all the libraries inside the docs folder.
To get more information on how to use the outputted documentation with
dartdoc-viewer, please take a look at the
[dartdoc-viewer documentation][dartdoc-viewer].
#### Uploading to Cloud Storage
To push new files to Google Cloud Storage for use by the viewer, use the
`gsutil` tool located at third_party/gsutil/gsutil in the Dart repository.
- Run `python gsutil -m cp -q -a public-read -r <folder> gs://dartlang-docgen`
to upload the specified folder to the viewer's bucket. Be sure to also upload
a new VERSION file if the uploaded folder is to be used.**
**Note that the bucket contains several numbered folders for each version of
the documentation. Run `python gsutil ls gs://dartlang-docgen` to see the file
layout. Follow this convention and update a new VERSION file when uploading
a new version of documentation. You can see the format of the VERSION file
by running `python gsutil cat gs://dartlang-docgen/VERSION`.
### Viewing generated documentation
Docgen's generated YAML files can be used by the
[Dart Documentation Viewer][dartdoc-viewer] for easy viewing and navigation
through a project.
---
#### Using dartdoc.py
The `dartdoc.py` script located in the `bin` directory is a useful tool for
creating documentation for a Dart project and running it locally.
##### Setup
The `dartdoc.py` script makes use of the
[Google App Engine SDK for Python][GAE]'s development server to serve the
documentation viewer. Install a recent version of the SDK before running
`dartdoc.py`.
##### Running dartdoc.py
######Common Options
The following options are the most used:
python dartdoc.py --gae-sdk=<path to SDK>
--options=<path to files>
--options=--parse-sdk
--options='--include-sdk <path to files>'
--options='--append <path to files>'
######All Options
Run `python dartdoc.py -h` from the `bin` directory for all available options.
The two required options are as follows:
1. The `--options` option describes any options being passed into `docgen.dart`.
If more then one option is desired, separate the options with a space
(ex. `--options='--include-sdk files'`).
2. The `--gae-sdk` option gives the absolute path to the
[Google App Engine SDK][GAE].
Running `python dartdoc.py --options=<docgen options> --gae-sdk=<path to SDK>`
will serve files generated by `docgen.dart` in your browser.
[dartdoc-viewer]: https://github.com/dart-lang/dartdoc-viewer "Dartdoc-Viewer"
[GAE]: https://developers.google.com/appengine/downloads#Google_App_Engine_SDK_for_Python "Google App Engine SDK for Python"

View file

@ -1,173 +0,0 @@
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:io';
import 'package:args/args.dart';
import 'package:logging/logging.dart';
import 'package:path/path.dart' as path;
// Must use relative paths because library imports mirrors via relative paths
import '../lib/docgen.dart';
/**
* Analyzes Dart files and generates a representation of included libraries,
* classes, and members.
*/
void main(List<String> arguments) {
var options = _initArgParser().parse(arguments);
var files = options.rest.map(path.normalize).toList();
if (files.isEmpty) _printHelpAndExit();
var startPage = options['start-page'];
if (_singlePackage(files) && startPage == null) {
startPage = _defaultStartPageFor(files);
_printDeprecatedMessage();
print("Using default options for documenting a single package: "
"--start-page=$startPage");
}
var includeSdk = options['parse-sdk'] || options['include-sdk'];
var scriptDir = path.dirname(Platform.script.toFilePath());
var introduction = includeSdk ? '' : options['introduction'];
var pubScript =
options['sdk'] != null ? path.join(options['sdk'], 'bin', 'pub') : 'pub';
var dartBinary = options['sdk'] != null
? path.join(options['sdk'], 'bin', 'dart')
: 'dart';
var excludedLibraries = options['exclude-lib'];
if (excludedLibraries == null) excludedLibraries = [];
var indentJSON = options['indent-json'] as bool;
docgen(files,
packageRoot: options['package-root'],
includePrivate: options['include-private'],
includeSdk: includeSdk,
parseSdk: options['parse-sdk'],
introFileName: introduction,
out: options['out'],
excludeLibraries: excludedLibraries,
includeDependentPackages: options['include-dependent-packages'],
compile: options['compile'],
serve: options['serve'],
dartBinary: dartBinary,
pubScript: pubScript,
noDocs: options['no-docs'],
startPage: startPage,
indentJSON: indentJSON,
sdk: options['sdk']);
}
/**
* Print help if we are passed the help option or invalid arguments.
*/
void _printHelpAndExit() {
_printDeprecatedMessage();
print(_initArgParser().usage);
print('Usage: dartdocgen [OPTIONS] fooDir/barFile');
exit(0);
}
void _printDeprecatedMessage() {
print(
'\nDeprecated: please use https://pub.dartlang.org/packages/dartdoc instead.');
print('Dart SDK 1.12 will be the last release to ship with docgen.\n');
}
/**
* If the user seems to have given us a single package to document, use some
* reasonable arguments for what they probably meant.
*/
bool _singlePackage(List files) {
if (files.length != 1) return false;
var pubspec = new File(path.join(files.first, 'pubspec.yaml'));
if (!pubspec.existsSync()) return false;
return true;
}
/**
* If we've specified just a package and no other command-line options,
* use the single package name as the start page.
*/
String _defaultStartPageFor(files) {
var pubspec = new File(path.join(files.first, 'pubspec.yaml'));
if (!pubspec.existsSync()) return null;
return packageNameFor(files.first);
}
/**
* Creates parser for docgen command line arguments.
*/
ArgParser _initArgParser() {
var parser = new ArgParser();
parser.addFlag('help',
abbr: 'h',
help: 'Prints help and usage information.',
negatable: false, callback: (help) {
if (help) _printHelpAndExit();
});
parser.addFlag('verbose',
abbr: 'v',
help: 'Output more logging information.',
negatable: false, callback: (verbose) {
if (verbose) Logger.root.level = Level.FINEST;
});
parser.addFlag('include-private',
help: 'Flag to include private declarations.', negatable: false);
parser.addFlag('include-sdk',
help: 'Flag to parse SDK Library files.',
defaultsTo: false,
negatable: true);
parser.addFlag('parse-sdk',
help: 'Parses the SDK libraries only.',
defaultsTo: false,
negatable: false);
parser.addOption('package-root',
help: 'Sets the package root of the library being analyzed.');
parser.addFlag('compile',
help: 'Clone the documentation viewer repo locally '
'(if not already present) and compile with dart2js',
defaultsTo: false,
negatable: false);
parser.addFlag('serve',
help: 'Clone the documentation viewer repo locally '
'(if not already present), compile with dart2js, '
'and start a simple server',
defaultsTo: false,
negatable: false);
parser.addFlag('no-docs',
help: 'Do not generate any new documentation',
defaultsTo: false,
negatable: false);
parser.addOption('introduction',
help: 'Adds the provided markdown text file as the introduction'
' for the generated documentation.',
defaultsTo: '');
parser.addOption('out',
help: 'The name of the output directory.', defaultsTo: 'docs');
parser.addOption('exclude-lib',
help: 'Exclude the library by this name from the documentation',
allowMultiple: true);
parser.addFlag('include-dependent-packages',
help: 'Assumes we are documenting a single package and are running '
'in the directory with its pubspec. Includes documentation for all '
'of its dependent packages.',
defaultsTo: true,
negatable: true);
parser.addOption('sdk', help: 'SDK directory', defaultsTo: null);
parser.addOption('start-page',
help: 'By default the viewer will start at the SDK introduction page. '
'To start at some other page, e.g. for a package, provide the name '
'of the package in this argument, e.g. --start-page=intl will make '
'the start page of the viewer be the intl package.',
defaultsTo: null);
parser.addFlag('indent-json',
help: 'Indents each level of JSON output by two spaces',
defaultsTo: false,
negatable: true);
return parser;
}

View file

@ -1,73 +0,0 @@
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
/// **docgen** is a tool for creating machine readable representations of Dart
/// code metadata, including: classes, members, comments and annotations.
///
/// docgen is run on a `.dart` file or a directory containing `.dart` files.
///
/// $ dart docgen.dart [OPTIONS] [FILE/DIR]
///
/// This creates files called `docs/<library_name>.yaml` in your current
/// working directory.
library docgen;
import 'dart:async';
import 'src/generator.dart' as gen;
import 'src/viewer.dart' as viewer;
export 'src/generator.dart' show getMirrorSystem;
export 'src/library_helpers.dart' show getDocgenObject;
export 'src/models.dart';
export 'src/package_helpers.dart' show packageNameFor;
/// Docgen constructor initializes the link resolver for markdown parsing.
/// Also initializes the command line arguments.
///
/// [packageRoot] is the packages directory of the directory being analyzed.
/// If [includeSdk] is `true`, then any SDK libraries explicitly imported will
/// 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 [compile] is `true`, then after generating the documents, compile the
/// viewer with dart2js.
/// 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 includePrivate: false, bool includeSdk: false, bool parseSdk: false,
String introFileName: '', String out: gen.DEFAULT_OUTPUT_DIRECTORY,
List<String> excludeLibraries: const [],
bool includeDependentPackages: false, bool compile: false,
bool serve: false, bool noDocs: false, String startPage,
String pubScript : 'pub', String dartBinary: 'dart',
bool indentJSON: false, String sdk}) {
var result;
if (!noDocs) {
viewer.ensureMovedViewerCode();
result = gen.generateDocumentation(files, packageRoot: packageRoot,
includePrivate: includePrivate,
includeSdk: includeSdk, parseSdk: parseSdk,
introFileName: introFileName, out: out,
excludeLibraries: excludeLibraries,
includeDependentPackages: includeDependentPackages,
startPage: startPage, pubScriptValue: pubScript,
dartBinaryValue: dartBinary, indentJSON: indentJSON, sdk: sdk);
viewer.addBackViewerCode();
if (compile || serve) {
result.then((success) {
if (success) {
viewer.createViewer(serve);
}
});
}
} else if (compile || serve) {
gen.pubScript = pubScript;
gen.dartBinary = dartBinary;
viewer.createViewer(serve);
}
return result;
}

View file

@ -1,7 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.exports.dart2js_mirrors;
export 'package:compiler/src/mirrors/dart2js_mirrors.dart';

View file

@ -1,7 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.exports.libraries;
export 'package:sdk_library_metadata/libraries.dart';

View file

@ -1,7 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.exports.mirrors_util;
export 'package:compiler/src/mirrors/mirrors_util.dart';

View file

@ -1,8 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.exports.source_mirrors;
export 'package:compiler/src/mirrors/source_mirrors.dart'
hide SourceLocation;

View file

@ -1,487 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.generator;
import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'dart:io';
import 'package:markdown/markdown.dart' as markdown;
import 'package:path/path.dart' as path;
import 'package:compiler/compiler.dart' as api;
import 'package:compiler/src/filenames.dart';
import 'package:compiler/src/mirrors/analyze.dart'
as dart2js;
import 'package:compiler/src/source_file_provider.dart';
import 'exports/dart2js_mirrors.dart' as dart2js_mirrors;
import 'exports/libraries.dart';
import 'exports/mirrors_util.dart' as dart2js_util;
import 'exports/source_mirrors.dart';
import 'io.dart';
import 'library_helpers.dart';
import 'models.dart';
import 'package_helpers.dart';
const String DEFAULT_OUTPUT_DIRECTORY = 'docs';
/// The directory where the output docs are generated.
String get outputDirectory => _outputDirectory;
String _outputDirectory;
/// Library names to explicitly exclude.
///
/// Set from the command line option
/// --exclude-lib.
List<String> _excluded;
/// The path of the pub script.
String pubScript;
/// The path of Dart binary.
String dartBinary;
/// Docgen constructor initializes the link resolver for markdown parsing.
/// Also initializes the command line arguments.
///
/// [packageRoot] is the packages directory of the directory being analyzed.
/// If [includeSdk] is `true`, then any SDK libraries explicitly imported will
/// 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.
///
/// Returned Future completes with true if document generation is successful.
Future<bool> generateDocumentation(List<String> files, {String packageRoot,
bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false,
bool parseSdk: false, String introFileName: '',
out: DEFAULT_OUTPUT_DIRECTORY, List<String> excludeLibraries: const [], bool
includeDependentPackages: false, String startPage, String dartBinaryValue,
String pubScriptValue, bool indentJSON: false, String sdk}) {
_excluded = excludeLibraries;
dartBinary = dartBinaryValue;
pubScript = pubScriptValue;
logger.onRecord.listen((record) => print(record.message));
_ensureOutputDirectory(out);
var updatedPackageRoot = _obtainPackageRoot(packageRoot, parseSdk, files);
var requestedLibraries = _findLibrariesToDocument(files,
includeDependentPackages);
var allLibraries = []..addAll(requestedLibraries);
if (includeSdk) {
allLibraries.addAll(_listSdk());
}
return getMirrorSystem(allLibraries, includePrivate,
packageRoot: updatedPackageRoot, parseSdk: parseSdk, sdkRoot: sdk)
.then((MirrorSystem mirrorSystem) {
if (mirrorSystem.libraries.isEmpty) {
throw new StateError('No library mirrors were created.');
}
initializeTopLevelLibraries(mirrorSystem);
var availableLibraries = mirrorSystem.libraries.values
.where((each) => each.uri.scheme == 'file');
var availableLibrariesByPath =
new Map.fromIterables(availableLibraries.map((each) => each.uri),
availableLibraries);
var librariesToDocument = requestedLibraries
.map((each) {
return availableLibrariesByPath
.putIfAbsent(each, () => throw "Missing library $each");
}).toList();
librariesToDocument.addAll((includeSdk || parseSdk) ? sdkLibraries : []);
librariesToDocument.removeWhere((x) => _excluded.contains(
dart2js_util.nameOf(x)));
_documentLibraries(librariesToDocument, includeSdk, parseSdk, introFileName,
startPage, indentJSON);
return true;
});
}
/// Analyzes set of libraries by getting a mirror system and triggers the
/// documentation of the libraries.
Future<MirrorSystem> getMirrorSystem(List<Uri> libraries,
bool includePrivate, {String packageRoot, bool parseSdk: false,
String sdkRoot}) {
if (libraries.isEmpty) throw new StateError('No Libraries.');
includePrivateMembers = includePrivate;
// Finds the root of SDK library based off the location of docgen.
// We have two different places to look, depending if we're in a development
// repo or in a built SDK, either sdk or dart-sdk respectively
if (sdkRoot == null) {
var root = rootDirectory;
sdkRoot = path.normalize(path.absolute(path.join(root, 'sdk')));
if (!new Directory(sdkRoot).existsSync()) {
sdkRoot = path.normalize(path.absolute(path.join(root, 'dart-sdk')));
}
}
logger.info('SDK Root: ${sdkRoot}');
return analyzeLibraries(libraries, sdkRoot, packageRoot: packageRoot);
}
/// Writes [text] to a file in the output directory.
void _writeToFile(String text, String filename) {
if (text == null) return;
var filePath = path.join(_outputDirectory, filename);
var parentDir = new Directory(path.dirname(filePath));
if (!parentDir.existsSync()) parentDir.createSync(recursive: true);
try {
new File(filePath)
.writeAsStringSync(text, mode: FileMode.WRITE);
} on FileSystemException catch (e) {
print('Failed to write to the path $filePath. Do you have write '
'permissions to that directory? If not, please specify a different '
'output directory using the --out option.');
exit(1);
}
}
/// Resolve all the links in the introductory comments for a given library or
/// package as specified by [filename].
String _readIntroductionFile(String fileName, bool includeSdk) {
var linkResolver = (name) => 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);
}
int _indexableComparer(Indexable a, Indexable b) {
if (a is Library && b is Library) {
var compare = a.packageName.compareTo(b.packageName);
if (compare == 0) {
compare = a.name.compareTo(b.name);
}
return compare;
}
if (a is Library) return -1;
if (b is Library) return 1;
return a.qualifiedName.compareTo(b.qualifiedName);
}
/// Creates documentation for filtered libraries.
void _documentLibraries(List<LibraryMirror> libs, bool includeSdk,
bool parseSdk, String introFileName, String startPage, bool indentJson) {
libs.forEach((lib) {
// Files belonging to the SDK have a uri that begins with 'dart:'.
if (includeSdk || !lib.uri.toString().startsWith('dart:')) {
generateLibrary(lib);
}
});
var filteredEntities = new SplayTreeSet<Indexable>(_indexableComparer);
for (Indexable item in allIndexables) {
if (isFullChainVisible(item)) {
if (item is! Method ||
(item is Method && item.methodInheritedFrom == null)) {
filteredEntities.add(item);
}
}
}
// Outputs a JSON file with all libraries and their preview comments.
// This will help the viewer know what libraries are available to read in.
Map<String, dynamic> libraryMap = {
'libraries': filteredEntities.where((e) => e is Library).map((e) =>
e.previewMap).toList(),
'introduction': _readIntroductionFile(introFileName, includeSdk),
'filetype': 'json',
'sdkVersion': packageVersion(coreLibrary.mirror)
};
var encoder = new JsonEncoder.withIndent(indentJson ? ' ' : null);
_writeOutputFiles(libraryMap, filteredEntities, startPage, encoder);
}
/// Output all of the libraries and classes into json files for consumption by a
/// viewer.
void _writeOutputFiles(Map<String, dynamic> libraryMap, Iterable<Indexable>
filteredEntities, String startPage, JsonEncoder encoder) {
if (startPage != null) libraryMap['start-page'] = startPage;
_writeToFile(encoder.convert(libraryMap), 'library_list.json');
// Output libraries and classes to file after all information is generated.
filteredEntities.where((e) => e is Class || e is Library).forEach((output) {
_writeIndexableToFile(output, encoder);
});
// Outputs all the qualified names documented with their type.
// This will help generate search results.
var sortedEntities = filteredEntities
.map((e) => '${e.qualifiedName} ${e.typeName}')
.toList();
sortedEntities.sort();
var buffer = new StringBuffer()
..writeAll(sortedEntities, '\n')
..write('\n');
_writeToFile(buffer.toString(), 'index.txt');
var index = new SplayTreeMap.fromIterable(filteredEntities,
key: (e) => e.qualifiedName, value: (e) => e.typeName);
_writeToFile(encoder.convert(index), 'index.json');
}
/// Helper method to serialize the given Indexable out to a file.
void _writeIndexableToFile(Indexable result, JsonEncoder encoder) {
var outputFile = result.fileName + '.json';
var output = encoder.convert(result.toMap());
_writeToFile(output, outputFile);
}
/// Set the location of the ouput directory, and ensure that the location is
/// available on the file system.
void _ensureOutputDirectory(String outputDirectory) {
_outputDirectory = outputDirectory;
var dir = new Directory(_outputDirectory);
if (dir.existsSync()) dir.deleteSync(recursive: true);
}
/// Analyzes set of libraries and provides a mirror system which can be used
/// for static inspection of the source code.
Future<MirrorSystem> analyzeLibraries(List<Uri> libraries, String
libraryRoot, {String packageRoot}) {
SourceFileProvider provider = new CompilerSourceFileProvider();
api.DiagnosticHandler diagnosticHandler = new FormattingDiagnosticHandler(
provider)
..showHints = false
..showWarnings = false;
Uri libraryUri = new Uri.file(appendSlash(libraryRoot));
Uri packageUri = null;
if (packageRoot == null) {
packageRoot = Platform.packageRoot;
}
packageUri = new Uri.file(appendSlash(packageRoot));
return dart2js.analyze(libraries, libraryUri, packageUri,
provider.readStringFromUri, diagnosticHandler, ['--preserve-comments',
'--categories=Client,Server'])..catchError((error) {
logger.severe('Error: Failed to create mirror system. ');
// TODO(janicejl): Use the stack trace package when bug is resolved.
// Currently, a string is thrown when it fails to create a mirror
// system, and it is not possible to use the stack trace. BUG(#11622)
// To avoid printing the stack trace.
exit(1);
});
}
/// For this run of docgen, determine the packageRoot value.
///
/// If packageRoot is not explicitly passed, we examine the files we're
/// documenting to attempt to find a package root.
String _obtainPackageRoot(String packageRoot, bool parseSdk,
List<String> files) {
if (packageRoot == null && !parseSdk) {
var type = FileSystemEntity.typeSync(files.first);
if (type == FileSystemEntityType.DIRECTORY) {
var files2 = listDir(files.first, recursive: true);
// Return '' means that there was no pubspec.yaml and therefore no
// packageRoot.
packageRoot = files2.firstWhere((f) => f.endsWith(
'${path.separator}pubspec.yaml'), orElse: () => '');
if (packageRoot != '') {
packageRoot = path.join(path.dirname(packageRoot), 'packages');
}
} else if (type == FileSystemEntityType.FILE) {
logger.warning('WARNING: No package root defined. If Docgen fails, try '
'again by setting the --package-root option.');
}
}
logger.info('Package Root: ${packageRoot}');
return path.normalize(path.absolute(packageRoot));
}
/// Given the user provided list of items to document, expand all directories
/// to document out into specific files and add any dependent packages for
/// documentation if desired.
List<Uri> _findLibrariesToDocument(List<String> args, bool
includeDependentPackages) {
if (includeDependentPackages) {
args.addAll(_allDependentPackageDirs(args.first));
}
var libraries = new List<Uri>();
for (var arg in args) {
if (FileSystemEntity.typeSync(arg) == FileSystemEntityType.FILE) {
if (arg.endsWith('.dart')) {
var lib = new Uri.file(path.absolute(arg));
libraries.add(lib);
logger.info('Added to libraries: $lib');
}
} else {
libraries.addAll(_findFilesToDocumentInPackage(arg));
}
}
return libraries;
}
/// Given a package name, explore the directory and pull out all top level
/// library files in the "lib" directory to document.
List<Uri> _findFilesToDocumentInPackage(String packageDir) {
var libraries = [];
// To avoid anaylzing package files twice, only files with paths not
// containing '/packages' will be added. The only exception is if the file
// to analyze already has a '/package' in its path.
var files = listDir(packageDir, recursive: true, listDir: _packageDirList)
.where((f) => f.endsWith('.dart') &&
(!f.contains('${path.separator}packages') ||
packageDir.contains('${path.separator}packages')))
.toList();
var packageLibDir = path.join(packageDir, 'lib');
var packageLibSrcDir = path.join(packageLibDir, 'src');
files.forEach((String lib) {
// Only include libraries within the lib dir that are not in lib/src
if (path.isWithin(packageLibDir, lib) &&
!path.isWithin(packageLibSrcDir, lib)) {
// Only add the file if it does not contain 'part of'
// TODO(janicejl): Remove when Issue(12406) is resolved.
var contents = new File(lib).readAsStringSync();
if (contents.contains(new RegExp('\npart of ')) ||
contents.startsWith(new RegExp('part of '))) {
logger.warning('Skipping part "$lib". '
'Part files should be in "lib/src".');
} else {
libraries.add(new Uri.file(path.normalize(path.absolute(lib))));
logger.info('Added to libraries: $lib');
}
}
});
return libraries;
}
/// If [dir] contains both a `lib` directory and a `pubspec.yaml` file treat
/// it like a package and only return the `lib` dir.
///
/// This ensures that packages don't have non-`lib` content documented.
List<FileSystemEntity> _packageDirList(Directory dir) {
var entities = dir.listSync();
var pubspec = entities.firstWhere((e) => e is File &&
path.basename(e.path) == 'pubspec.yaml', orElse: () => null);
var libDir = entities.firstWhere((e) => e is Directory &&
path.basename(e.path) == 'lib', orElse: () => null);
if (pubspec != null && libDir != null) {
return [libDir];
} else {
return entities;
}
}
/// All of the directories for our dependent packages
/// If this is not a package, return an empty list.
List<String> _allDependentPackageDirs(String packageDirectory) {
var packageName = packageNameFor(packageDirectory);
if (packageName == '') return [];
var dependentsJson = Process.runSync(pubScript, ['list-package-dirs'],
workingDirectory: packageDirectory, runInShell: true);
if (dependentsJson.exitCode != 0) {
print(dependentsJson.stderr);
}
var dependents = JSON.decode(dependentsJson.stdout)['packages'];
return dependents != null ? dependents.values.toList() : [];
}
/// For all the libraries, return a list of the libraries that are part of
/// the SDK.
List<Uri> _listSdk() {
var sdk = new List<Uri>();
LIBRARIES.forEach((String name, LibraryInfo info) {
if (info.documented) {
sdk.add(Uri.parse('dart:$name'));
logger.info('Add to SDK: ${sdk.last}');
}
});
return sdk;
}
/// Currently left public for testing purposes. :-/
void generateLibrary(dart2js_mirrors.Dart2JsLibraryMirror library) {
var result = new Library(library);
result.updateLibraryPackage(library);
logger.fine('Generated library for ${result.name}');
}
/// If we can't find the SDK introduction text, which will happen if running
/// from a snapshot and using --parse-sdk or --include-sdk, then use this
/// hard-coded version. This should be updated to be consistent with the text
/// in docgen/doc/sdk-introduction.md
// TODO(alanknight): It would be better if we could resolve the references to
// dart:core etc. at load-time in the viewer. dartbug.com/20112
const _DEFAULT_SDK_INTRODUCTION =
"""
Welcome to the Dart API reference documentation,
covering the official Dart API libraries.
Some of the most fundamental Dart libraries include:
* [dart:core](./dart:core):
Core functionality such as strings, numbers, collections, errors,
dates, and URIs.
* [dart:html](./dart:html):
DOM manipulation for web apps.
* [dart:io](./dart:io):
I/O for command-line apps.
Except for dart:core, you must import a library before you can use it.
Here's an example of importing dart:html, dart:math, and a
third popular library called
[polymer.dart](http://www.dartlang.org/polymer-dart/):
import 'dart:html';
import 'dart:math';
import 'package:polymer/polymer.dart';
Polymer.dart is an example of a library that isn't
included in the Dart download,
but is easy to get and update using the _pub package manager_.
For information on finding, using, and publishing libraries (and more)
with pub, see
[pub.dartlang.org](http://pub.dartlang.org).
The main site for learning and using Dart is
[www.dartlang.org](http://www.dartlang.org).
Check out these pages:
* [Dart homepage](http://www.dartlang.org)
* [Tutorials](http://www.dartlang.org/docs/tutorials/)
* [Programmer's Guide](http://www.dartlang.org/docs/)
* [Samples](http://www.dartlang.org/samples/)
* [A Tour of the Dart Libraries](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html)
This API reference is automatically generated from the source code in the
[Dart project](https://code.google.com/p/dart/).
If you'd like to contribute to this documentation, see
[Contributing](https://code.google.com/p/dart/wiki/Contributing)
and
[Writing API Documentation](https://code.google.com/p/dart/wiki/WritingApiDocumentation).
""";

View file

@ -1,61 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
/// This is a helper library to make working with io easier.
library docgen.io;
// TODO(janicejl): listDir, canonicalize, resolveLink, and linkExists are from
// pub/lib/src/io.dart. If the io.dart file becomes a package, should remove
// copy of the functions.
import 'dart:io';
import 'package:path/path.dart' as path;
/// Lists the contents of [dir].
///
/// If [recursive] is `true`, lists subdirectory contents (defaults to `false`).
///
/// Excludes files and directories beginning with `.`
///
/// The returned paths are guaranteed to begin with [dir].
List<String> listDir(String dir, {bool recursive: false,
List<FileSystemEntity> listDir(Directory dir)}) {
if (listDir == null) listDir = (Directory dir) => dir.listSync();
return _doList(dir, new Set<String>(), recursive, listDir);
}
List<String> _doList(String dir, Set<String> listedDirectories, bool recurse,
List<FileSystemEntity> listDir(Directory dir)) {
var contents = <String>[];
// Avoid recursive symlinks.
var resolvedPath = new Directory(dir).resolveSymbolicLinksSync();
if (listedDirectories.contains(resolvedPath)) return [];
listedDirectories = new Set<String>.from(listedDirectories);
listedDirectories.add(resolvedPath);
var children = <String>[];
for (var entity in listDir(new Directory(dir))) {
// Skip hidden files and directories
if (path.basename(entity.path).startsWith('.')) {
continue;
}
contents.add(entity.path);
if (entity is Directory) {
// TODO(nweiz): don't manually recurse once issue 4794 is fixed.
// Note that once we remove the manual recursion, we'll need to
// explicitly filter out files in hidden directories.
if (recurse) {
children.addAll(_doList(entity.path, listedDirectories, recurse,
listDir));
}
}
}
contents.addAll(children);
return contents;
}

View file

@ -1,220 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.library_helpers;
import 'package:logging/logging.dart';
import 'package:markdown/markdown.dart' as markdown;
import 'exports/source_mirrors.dart';
import 'exports/mirrors_util.dart' as dart2js_util;
import 'models/indexable.dart';
import 'models/library.dart';
import 'models/dummy_mirror.dart';
typedef DeclarationMirror LookupFunction(DeclarationSourceMirror declaration,
String name);
/// Support for [:foo:]-style code comments to the markdown parser.
final List<markdown.InlineSyntax> MARKDOWN_SYNTAXES =
[new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')];
bool get includePrivateMembers {
if (_includePrivate == null) {
throw new StateError('includePrivate has not been set');
}
return _includePrivate;
}
void set includePrivateMembers(bool value) {
if (value == null) throw new ArgumentError('includePrivate cannot be null');
_includePrivate = value;
}
bool _includePrivate;
/// Return true if this item and all of its owners are all visible.
bool isFullChainVisible(Indexable item) {
return includePrivateMembers || (!item.isPrivate && (item.owner != null ?
isFullChainVisible(item.owner) : true));
}
/// Logger for printing out progress of documentation generation.
final Logger logger = new Logger('Docgen');
/// The dart:core library, which contains all types that are always available
/// without import.
Library coreLibrary;
/// Set of libraries declared in the SDK, so libraries that can be accessed
/// when running dart by default.
Iterable<LibraryMirror> get sdkLibraries => _sdkLibraries;
Iterable<LibraryMirror> _sdkLibraries;
////// Top level resolution functions
/// Converts all [foo] references in comments to <a>libraryName.foo</a>.
markdown.Node globalFixReference(String name) {
// Attempt the look up the whole name up in the scope.
String elementName = findElementInScopeWithPrefix(name, '');
if (elementName != null) {
return new markdown.Element.text('a', elementName);
}
return fixComplexReference(name);
}
/// This is a more complex reference. Try to break up if its of the form A<B>
/// where A is an alphanumeric string and B is an A, a list of B ("B, B, B"),
/// or of the form A<B>. Note: unlike other the other markdown-style links,
/// all text inside the square brackets is treated as part of the link (aka
/// the * is interpreted literally as a *, not as a indicator for bold <em>.
///
/// Example: [foo&lt;_bar_>] will produce
/// <a>resolvedFoo</a>&lt;<a>resolved_bar_</a>> rather than an italicized
/// version of resolvedBar.
markdown.Node fixComplexReference(String name) {
// Parse into multiple elements we can try to resolve.
var tokens = _tokenizeComplexReference(name);
// Produce an html representation of our elements. Group unresolved and
// plain text are grouped into "link" elements so they display as code.
final textElements = [' ', ',', '>', _LESS_THAN];
var accumulatedHtml = '';
for (var token in tokens) {
bool added = false;
if (!textElements.contains(token)) {
String elementName = findElementInScopeWithPrefix(token, '');
if (elementName != null) {
accumulatedHtml += markdown.renderToHtml([new markdown.Element.text('a',
elementName)]);
added = true;
}
}
if (!added) {
accumulatedHtml += token;
}
}
return new markdown.Text(accumulatedHtml);
}
String findElementInScopeWithPrefix(String name, String packagePrefix) {
var lookupFunc = determineLookupFunc(name);
// Look in the dart core library scope.
var coreScope = coreLibrary == null ? null : lookupFunc(coreLibrary.mirror,
name);
if (coreScope != null) return packagePrefix + coreLibrary.docName;
// If it's a reference that starts with a another library name, then it
// looks for a match of that library name in the other sdk libraries.
if (name.contains('.')) {
var index = name.indexOf('.');
var libraryName = name.substring(0, index);
var remainingName = name.substring(index + 1);
foundLibraryName(library) => library.uri.pathSegments[0] == libraryName;
if (_sdkLibraries.any(foundLibraryName)) {
var library = _sdkLibraries.singleWhere(foundLibraryName);
// Look to see if it's a fully qualified library name.
var scope = determineLookupFunc(remainingName)(library, remainingName);
if (scope != null) {
var result = getDocgenObject(scope);
if (result is DummyMirror) {
return packagePrefix + result.docName;
} else {
return result.packagePrefix + result.docName;
}
}
}
}
return null;
}
/// Given a Dart2jsMirror, find the corresponding Docgen [MirrorBased] object.
///
/// We have this global lookup function to avoid re-implementing looking up
/// the scoping rules for comment resolution here (it is currently done in
/// mirrors). If no corresponding MirrorBased object is found, we return a
/// [DummyMirror] that simply returns the original mirror's qualifiedName
/// while behaving like a MirrorBased object.
Indexable getDocgenObject(DeclarationMirror mirror, [Indexable owner]) {
Map<String, Indexable> docgenObj = lookupIndexableMap(mirror);
if (docgenObj == null) {
return new DummyMirror(mirror, owner);
}
var setToExamine = new Set();
if (owner != null) {
var firstSet = docgenObj[owner.docName];
if (firstSet != null) setToExamine.add(firstSet);
if (coreLibrary != null && docgenObj[coreLibrary.docName] != null) {
setToExamine.add(docgenObj[coreLibrary.docName]);
}
} else {
setToExamine.addAll(docgenObj.values);
}
Set<Indexable> results = new Set<Indexable>();
for (Indexable indexable in setToExamine) {
if (indexable.mirror.qualifiedName == mirror.qualifiedName &&
indexable.isValidMirror(mirror)) {
results.add(indexable);
}
}
if (results.length > 0) {
// This might occur if we didn't specify an "owner."
return results.first;
}
return new DummyMirror(mirror, owner);
}
void initializeTopLevelLibraries(MirrorSystem mirrorSystem) {
_sdkLibraries = mirrorSystem.libraries.values.where(
(each) => each.uri.scheme == 'dart');
coreLibrary = new Library(_sdkLibraries.singleWhere((lib) =>
lib.uri.toString().startsWith('dart:core')));
}
/// For a given name, determine if we need to resolve it as a qualified name
/// or a simple name in the source mirors.
LookupFunction determineLookupFunc(String name) => name.contains('.') ?
dart2js_util.lookupQualifiedInScope :
(mirror, name) => mirror.lookupInScope(name);
/// Chunk the provided name into individual parts to be resolved. We take a
/// simplistic approach to chunking, though, we break at " ", ",", "&lt;"
/// and ">". All other characters are grouped into the name to be resolved.
/// As a result, these characters will all be treated as part of the item to
/// be resolved (aka the * is interpreted literally as a *, not as an
/// indicator for bold <em>.
List<String> _tokenizeComplexReference(String name) {
var tokens = [];
var append = false;
var index = 0;
while (index < name.length) {
if (name.indexOf(_LESS_THAN, index) == index) {
tokens.add(_LESS_THAN);
append = false;
index += _LESS_THAN.length;
} else if (name[index] == ' ' || name[index] == ',' || name[index] == '>') {
tokens.add(name[index]);
append = false;
index++;
} else {
if (append) {
tokens[tokens.length - 1] = tokens.last + name[index];
} else {
tokens.add(name[index]);
append = true;
}
index++;
}
}
return tokens;
}
// HTML escaped version of '<' character.
const _LESS_THAN = '&lt;';

View file

@ -1,65 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.mdn;
import 'dart:convert';
import 'dart:io';
import 'package:logging/logging.dart';
import 'package:path/path.dart' as p;
// TODO(janicejl): Make MDN content generic or pluggable.
/// Map of all the comments for dom elements from MDN.
Map<String, dynamic> _mdn;
/// Generates MDN comments from database.json.
String mdnComment(String root, Logger logger, String domName) {
//Check if MDN is loaded.
if (_mdn == null) {
// Reading in MDN related json file.
var mdnPath = p.join(root, 'utils/apidoc/mdn/database.json');
var mdnFile = new File(mdnPath);
if (mdnFile.existsSync()) {
_mdn = JSON.decode(mdnFile.readAsStringSync());
} else {
logger.warning("Cannot find MDN docs expected at $mdnPath");
_mdn = {};
}
}
var parts = domName.split('.');
if (parts.length == 2) return _mdnMemberComment(parts[0], parts[1]);
if (parts.length == 1) return _mdnTypeComment(parts[0]);
throw new StateError('More than two items is not supported: $parts');
}
/// Generates the MDN Comment for variables and method DOM elements.
String _mdnMemberComment(String type, String member) {
var mdnType = _mdn[type];
if (mdnType == null) return '';
var mdnMember = mdnType['members'].firstWhere((e) => e['name'] == member,
orElse: () => null);
if (mdnMember == null) return '';
if (mdnMember['help'] == null || mdnMember['help'] == '') return '';
if (mdnMember['url'] == null) return '';
return _htmlifyMdn(mdnMember['help'], mdnMember['url']);
}
/// Generates the MDN Comment for class DOM elements.
String _mdnTypeComment(String type) {
var mdnType = _mdn[type];
if (mdnType == null) return '';
if (mdnType['summary'] == null || mdnType['summary'] == "") return '';
if (mdnType['srcUrl'] == null) return '';
return _htmlifyMdn(mdnType['summary'], mdnType['srcUrl']);
}
/// 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>';
}

View file

@ -1,13 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.models;
export 'models/class.dart';
export 'models/indexable.dart';
export 'models/library.dart';
export 'models/method.dart';
export 'models/parameter.dart';
export 'models/typedef.dart';
export 'models/variable.dart';

View file

@ -1,32 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.models.annotation;
import '../exports/source_mirrors.dart';
import '../library_helpers.dart';
import 'library.dart';
import 'mirror_based.dart';
import 'dart:mirrors';
/// Holds the name of the annotation, and its parameters.
class Annotation extends MirrorBased<ClassMirror> {
/// The class of this annotation.
DeclarationMirror mirror;
final Library owningLibrary;
List<String> parameters;
Annotation(this.owningLibrary, this.mirror,
[List<String> this.parameters = const <String>[]]);
Map toMap() => {
'name': owningLibrary.packagePrefix +
getDocgenObject(mirror, owningLibrary).docName,
'parameters': parameters
};
}

View file

@ -1,245 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.models.clazz;
import '../exports/dart2js_mirrors.dart' as dart2js_mirrors;
import '../exports/mirrors_util.dart' as dart2js_util;
import '../exports/source_mirrors.dart';
import '../library_helpers.dart';
import 'dummy_mirror.dart';
import 'generic.dart';
import 'library.dart';
import 'method.dart';
import 'model_helpers.dart';
import 'owned_indexable.dart';
import 'variable.dart';
/// A class containing contents of a Dart class.
class Class extends OwnedIndexable<dart2js_mirrors.Dart2JsInterfaceTypeMirror>
implements Comparable<Class> {
/// List of the names of interfaces that this class implements.
List<Class> interfaces = [];
/// Names of classes that extends or implements this class.
Set<Class> subclasses = new Set<Class>();
/// Top-level variables in the class.
Map<String, Variable> variables;
/// Inherited variables in the class.
final Map<String, Variable> inheritedVariables = {};
/// Methods in the class.
Map<String, Method> methods;
final Map<String, Method> inheritedMethods = new Map<String, Method>();
/// Generic infomation about the class.
final Map<String, Generic> generics;
Class _superclass;
bool get isAbstract => mirror.isAbstract;
/// Make sure that we don't check for inherited comments more than once.
bool _commentsEnsured = false;
/// Returns the [Class] for the given [mirror] if it has already been created,
/// else creates it.
factory Class(ClassMirror mirror, Library owner) {
var clazz = getDocgenObject(mirror, owner);
if (clazz is DummyMirror) {
clazz = new Class._(mirror, owner);
}
return clazz;
}
/// Called when we are constructing a superclass or interface class, but it
/// is not known if it belongs to the same owner as the original class. In
/// this case, we create an object whose owner is what the original mirror
/// says it is.
factory Class._possiblyDifferentOwner(ClassMirror mirror,
Library originalOwner) {
var realOwner = getDocgenObject(mirror.owner);
if (realOwner is Library) {
return new Class(mirror, realOwner);
} else {
return new Class(mirror, originalOwner);
}
}
Class._(ClassSourceMirror classMirror, Library owner)
: generics = createGenerics(classMirror),
super(classMirror, owner) {
// The reason we do this madness is the superclass and interface owners may
// not be this class's owner!! Example: BaseClient in http pkg.
var superinterfaces = classMirror.superinterfaces.map(
(interface) => new Class._possiblyDifferentOwner(interface, owner));
this._superclass = classMirror.superclass == null? null :
new Class._possiblyDifferentOwner(classMirror.superclass, owner);
interfaces = superinterfaces.toList();
variables = createVariables(
dart2js_util.variablesOf(classMirror.declarations), this);
methods = createMethods(dart2js_util.anyMethodOf(classMirror.declarations),
this);
// Tell superclass that you are a subclass, unless you are not
// visible or an intermediary mixin class.
if (!classMirror.isNameSynthetic && isVisible && _superclass != null) {
_superclass.addSubclass(this);
}
if (this._superclass != null) addInherited(_superclass);
interfaces.forEach((interface) => addInherited(interface));
}
String _lookupInClassAndSuperclasses(String name) {
var lookupFunc = determineLookupFunc(name);
var classScope = this;
while (classScope != null) {
var classFunc = lookupFunc(classScope.mirror, name);
if (classFunc != null) {
return packagePrefix + getDocgenObject(classFunc, owner).docName;
}
classScope = classScope._superclass;
}
return null;
}
/// Look for the specified name starting with the current member, and
/// progressively working outward to the current library scope.
String findElementInScope(String name) {
var lookupFunc = determineLookupFunc(name);
var result = _lookupInClassAndSuperclasses(name);
if (result != null) {
return result;
}
result = owner.findElementInScope(name);
return result == null ? super.findElementInScope(name) : result;
}
String get typeName => 'class';
/// Add all inherited variables and methods from the provided superclass.
/// If [_includePrivate] is true, it also adds the variables and methods from
/// the superclass.
void addInherited(Class superclass) {
inheritedVariables.addAll(superclass.inheritedVariables);
inheritedVariables.addAll(_allButStatics(superclass.variables));
addInheritedMethod(superclass, this);
}
/** [newParent] refers to the actual class is currently using these methods.
* which may be different because with the mirror system, we only point to the
* original canonical superclasse's method.
*/
void addInheritedMethod(Class parent, Class newParent) {
parent.inheritedMethods.forEach((name, method) {
if (!method.mirror.isConstructor) {
inheritedMethods[name] = new Method(method.mirror, newParent, method);
}
});
_allButStatics(parent.methods).forEach((name, method) {
if (!method.mirror.isConstructor) {
inheritedMethods[name] = new Method(method.mirror, newParent, method);
}
});
}
/// Remove statics from the map of inherited items before adding them.
Map _allButStatics(Map items) {
var result = {};
items.forEach((name, item) {
if (!item.isStatic) {
result[name] = item;
}
});
return result;
}
/// Add the subclass to the class.
///
/// If [this] is private (or an intermediary mixin class), it will add the
/// subclass to the list of subclasses in the superclasses.
void addSubclass(Class subclass) {
if (docName == 'dart:core.Object') return;
if (!includePrivateMembers && isPrivate || mirror.isNameSynthetic) {
if (_superclass != null) _superclass.addSubclass(subclass);
interfaces.forEach((interface) {
interface.addSubclass(subclass);
});
} else {
subclasses.add(subclass);
}
}
/// Check if this [Class] is an error or exception.
bool isError() {
if (qualifiedName == 'dart:core.Error' ||
qualifiedName == 'dart:core.Exception')
return true;
for (var interface in interfaces) {
if (interface.isError()) return true;
}
if (_superclass == null) return false;
return _superclass.isError();
}
/// Makes sure that all methods with inherited equivalents have comments.
void ensureComments() {
if (_commentsEnsured) return;
_commentsEnsured = true;
if (_superclass != null) _superclass.ensureComments();
inheritedMethods.forEach((qualifiedName, inheritedMethod) {
var method = methods[qualifiedName];
if (method != null) {
// if we have overwritten this method in this class, we still provide
// the opportunity to inherit the comments.
method.ensureCommentFor(inheritedMethod);
}
});
// we need to populate the comments for all methods. so that the subclasses
// can get for their inherited versions the comments.
methods.forEach((qualifiedName, method) {
if (!method.mirror.isConstructor) method.ensureCommentFor(method);
});
}
/// If a class extends a private superclass, find the closest public
/// superclass of the private superclass.
String validSuperclass() {
if (_superclass == null) return 'dart:core.Object';
if (_superclass.isVisible) return _superclass.qualifiedName;
return _superclass.validSuperclass();
}
/// Generates a map describing the [Class] object.
Map toMap() => {
'name': name,
'qualifiedName': qualifiedName,
'comment': comment,
'isAbstract' : isAbstract,
'superclass': validSuperclass(),
'implements': interfaces.where((i) => i.isVisible)
.map((e) => e.qualifiedName).toList(),
'subclass': (subclasses.toList()..sort())
.map((x) => x.qualifiedName).toList(),
'variables': recurseMap(variables),
'inheritedVariables': recurseMap(inheritedVariables),
'methods': expandMethodMap(methods),
'inheritedMethods': expandMethodMap(inheritedMethods),
'annotations': annotations.map((a) => a.toMap()).toList(),
'generics': recurseMap(generics)
};
int compareTo(Class other) => name.compareTo(other.name);
bool isValidMirror(DeclarationMirror mirror) => mirror is ClassMirror;
}

View file

@ -1,35 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.models.closure;
import '../exports/source_mirrors.dart';
import 'doc_gen_type.dart';
import 'indexable.dart';
import 'mirror_based.dart';
import 'model_helpers.dart';
import 'parameter.dart';
/// A class containing the properties of a function to be called (used in our
/// case specifically to illustrate evidence of the type of function for a
/// parameter).
class Closure extends MirrorBased<FunctionTypeMirror> {
/// Parameters for this method.
final Map<String, Parameter> parameters;
final DocGenType returnType;
final FunctionTypeMirror mirror;
Closure(FunctionTypeMirror mirror, Indexable owner)
: returnType = new DocGenType(mirror.returnType, owner.owningLibrary),
parameters = createParameters(mirror.parameters, owner),
mirror = mirror;
/// Generates a map describing the [Method] object.
Map toMap() => {
'return': [returnType.toMap()],
'parameters': recurseMap(parameters),
};
}

View file

@ -1,66 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.models.doc_gen_type;
import '../exports/source_mirrors.dart';
import '../library_helpers.dart';
import 'library.dart';
import 'mirror_based.dart';
/// Docgen wrapper around the mirror for a return type, and/or its generic
/// type parameters.
///
/// Return types are of a form [outer]<[inner]>.
/// If there is no [inner] part, [inner] will be an empty list.
///
/// For example:
/// int size()
/// "return" :
/// - "outer" : "dart:core.int"
/// "inner" :
///
/// List<String> toList()
/// "return" :
/// - "outer" : "dart:core.List"
/// "inner" :
/// - "outer" : "dart:core.String"
/// "inner" :
///
/// Map<String, List<int>>
/// "return" :
/// - "outer" : "dart:core.Map"
/// "inner" :
/// - "outer" : "dart:core.String"
/// "inner" :
/// - "outer" : "dart:core.List"
/// "inner" :
/// - "outer" : "dart:core.int"
/// "inner" :
class DocGenType extends MirrorBased {
final TypeMirror mirror;
final Library owningLibrary;
DocGenType(this.mirror, this.owningLibrary);
Map toMap() {
var result = getDocgenObject(mirror, owningLibrary);
return {
// We may encounter types whose corresponding library has not been
// processed yet, so look up with the owningLibrary at the last moment.
'outer': result.packagePrefix + result.docName,
'inner': _createTypeGenerics(mirror).map((e) => e.toMap()).toList(),
};
}
/// Returns a list of [DocGenType] objects constructed from TypeMirrors.
List<DocGenType> _createTypeGenerics(TypeMirror mirror) {
if (mirror is! ClassMirror) return [];
return mirror.typeArguments
.map((e) => new DocGenType(e, owningLibrary))
.toList();
}
}

View file

@ -1,66 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.models.dummy_mirror;
import '../exports/mirrors_util.dart' as dart2js_util;
import '../exports/source_mirrors.dart';
import '../library_helpers.dart';
import 'indexable.dart';
import 'model_helpers.dart';
/// For types that we do not explicitly create or have not yet created in our
/// entity map (like core types).
class DummyMirror implements Indexable {
final DeclarationMirror mirror;
/// The library that contains this element, if any. Used as a hint to help
/// determine which object we're referring to when looking up this mirror in
/// our map.
final Indexable owner;
DummyMirror(this.mirror, [this.owner]);
String get docName {
if (mirror is LibraryMirror) {
return getLibraryDocName(mirror);
}
var mirrorOwner = mirror.owner;
if (mirrorOwner == null) return dart2js_util.qualifiedNameOf(mirror);
var simpleName = dart2js_util.nameOf(mirror);
if (mirror is MethodMirror && (mirror as MethodMirror).isConstructor) {
// We name constructors specially -- repeating the class name and a
// "-" to separate the constructor from its name (if any).
simpleName = '${dart2js_util.nameOf(mirrorOwner)}-$simpleName';
}
return getDocgenObject(mirrorOwner, owner).docName + '.' +
simpleName;
}
bool get isPrivate => mirror.isPrivate;
String get packageName {
var libMirror = _getOwningLibraryFromMirror(mirror);
if (libMirror != null) {
return getPackageName(libMirror);
}
return '';
}
String get packagePrefix => packageName == null || packageName.isEmpty ?
'' : '$packageName/';
// This is a known incomplete implementation of Indexable
// overriding noSuchMethod to remove static warnings
noSuchMethod(Invocation invocation) {
throw new UnimplementedError(invocation.memberName.toString());
}
}
LibraryMirror _getOwningLibraryFromMirror(DeclarationMirror mirror) {
if (mirror == null) return null;
if (mirror is LibraryMirror) return mirror;
return _getOwningLibraryFromMirror(mirror.owner);
}

View file

@ -1,22 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.models.generic;
import '../exports/source_mirrors.dart';
import '../exports/mirrors_util.dart' as dart2js_util;
import 'mirror_based.dart';
/// A Docgen wrapper around the dart2js mirror for a generic type.
class Generic extends MirrorBased<TypeVariableMirror> {
final TypeVariableMirror mirror;
Generic(this.mirror);
Map toMap() => {
'name': dart2js_util.nameOf(mirror),
'type': dart2js_util.qualifiedNameOf(mirror.upperBound)
};
}

View file

@ -1,221 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.models.indexable;
import 'dart:collection';
import 'package:markdown/markdown.dart' as markdown;
import '../exports/mirrors_util.dart' as dart2js_util;
import '../exports/source_mirrors.dart';
import '../library_helpers.dart';
import 'library.dart';
import 'mirror_based.dart';
import 'model_helpers.dart';
/// An item that is categorized in our mirrorToDocgen map, as a distinct,
/// searchable element.
///
/// These are items that refer to concrete entities (a Class, for example,
/// but not a Type, which is a "pointer" to a class) that we wish to be
/// globally resolvable. This includes things such as class methods and
/// variables, but parameters for methods are not "Indexable" as we do not want
/// the user to be able to search for a method based on its parameter names!
/// The set of indexable items also includes Typedefs, since the user can refer
/// to them as concrete entities in a particular scope.
abstract class Indexable<TMirror extends DeclarationMirror>
extends MirrorBased<TMirror> {
Library get owningLibrary => owner.owningLibrary;
/// 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 qualifiedName => packagePrefix + ownerPrefix + name;
/// The name of the file we write this object's data into. The same as the
/// qualified name but with leading colons (i.e. dart:)
/// replaced by hyphens because of Windows.
String get fileName => qualifiedName.replaceFirst(":", "-");
final TMirror mirror;
final bool isPrivate;
/// The comment text pre-resolution. We keep this around because inherited
/// methods need to resolve links differently from the superclass.
String unresolvedComment = '';
Indexable(TMirror mirror)
: this.mirror = mirror,
this.isPrivate = isHidden(mirror as DeclarationSourceMirror) {
var mirrorQualifiedName = dart2js_util.qualifiedNameOf(this.mirror);
var map = _mirrorToDocgen.putIfAbsent(mirrorQualifiedName,
() => new HashMap<String, Indexable>());
var added = false;
map.putIfAbsent(owner.docName, () {
added = true;
return this;
});
if (!added) {
throw new StateError('An indexable has already been stored for '
'${owner.docName}');
}
}
/// 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;
/// 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.
String elementName = findElementInScope(name);
if (elementName != null) {
return new markdown.Element.text('a', elementName);
}
return fixComplexReference(name);
}
/// Look for the specified name starting with the current member, and
/// progressively working outward to the current library scope.
String findElementInScope(String name) =>
findElementInScopeWithPrefix(name, packagePrefix);
/// 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 and all links resolved.
String commentField;
/// Accessor to documentation comment with markdown converted to html and all
/// links resolved.
String get comment {
if (commentField != null) return commentField;
commentField = commentToHtml();
if (commentField.isEmpty) {
commentField = getMdnComment();
}
return commentField;
}
void set comment(x) {
commentField = x;
}
/// The simple name to refer to this item.
String get name => dart2js_util.nameOf(mirror);
/// 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;
/// Generates MDN comments from database.json.
String getMdnComment();
/// The type of this member to be used in index.txt.
String get typeName;
/// Creates a [Map] with this [Indexable]'s name and a preview comment.
Map get previewMap {
var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName };
var pre = preview;
if (pre != null) finalMap['preview'] = pre;
return finalMap;
}
String get preview {
if (comment != '') {
var index = comment.indexOf('</p>');
return index > 0 ?
'${comment.substring(0, index)}</p>' :
'<p><i>Comment preview not available</i></p>';
}
return null;
}
/// 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) {
CommentInstanceMirror comment = metadata;
if (comment.isDocComment) {
if (commentText == null) {
commentText = comment.trimmedText;
} else {
commentText = '$commentText\n${comment.trimmedText}';
}
}
}
});
return commentText;
}
/// Returns any documentation comments associated with a mirror with
/// simple markdown converted to html.
///
/// By default we resolve any comment references within our own scope.
/// However, if a method is inherited, we want the inherited comments, but
/// links to the subclasses's version of the methods.
String commentToHtml([Indexable resolvingScope]) {
if (resolvingScope == null) resolvingScope = this;
var commentText = _commentText;
unresolvedComment = commentText;
commentText = commentText == null ? '' :
markdown.markdownToHtml(commentText.trim(),
linkResolver: resolvingScope.fixReference,
inlineSyntaxes: MARKDOWN_SYNTAXES);
return commentText;
}
/// Return a map representation of this type.
Map toMap();
/// Accessor to determine if this item and all of its owners are visible.
bool get isVisible => isFullChainVisible(this);
/// 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);
}
/// Index of all the dart2js mirrors examined to corresponding MirrorBased
/// docgen objects.
///
/// Used for lookup because of the dart2js mirrors exports
/// issue. The second level map is indexed by owner docName for faster lookup.
/// Why two levels of lookup? Speed, man. Speed.
final Map<String, Map<String, Indexable>> _mirrorToDocgen =
new HashMap<String, Map<String, Indexable>>();
Iterable<Indexable> get allIndexables =>
_mirrorToDocgen.values.expand((map) => map.values);
Map<String, Indexable> lookupIndexableMap(DeclarationMirror mirror) {
return _mirrorToDocgen[dart2js_util.qualifiedNameOf(mirror)];
}

View file

@ -1,192 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.models.library;
import 'dart:io';
import 'package:markdown/markdown.dart' as markdown;
import '../exports/source_mirrors.dart';
import '../exports/mirrors_util.dart' as dart2js_util;
import '../library_helpers.dart';
import '../package_helpers.dart';
import 'class.dart';
import 'dummy_mirror.dart';
import 'indexable.dart';
import 'method.dart';
import 'model_helpers.dart';
import 'typedef.dart';
import 'variable.dart';
/// A class containing contents of a Dart library.
class Library extends Indexable {
final Map<String, Class> classes = {};
final Map<String, Typedef> typedefs = {};
final Map<String, Class> errors = {};
/// Top-level variables in the library.
Map<String, Variable> variables;
/// Top-level functions in the library.
Map<String, Method> functions;
String packageName = '';
bool _hasBeenCheckedForPackage = false;
String packageIntro;
Indexable get owner => const _LibraryOwner();
Library get owningLibrary => this;
/// Returns the [Library] for the given [mirror] if it has already been
/// created, else creates it.
factory Library(LibraryMirror mirror) {
var library = getDocgenObject(mirror);
if (library is DummyMirror) {
library = new Library._(mirror);
}
return library;
}
Library._(LibraryMirror libraryMirror) : super(libraryMirror) {
var exported = calcExportedItems(libraryMirror, {});
var exportedClasses = addAll(exported['classes'],
dart2js_util.typesOf(libraryMirror.declarations));
updateLibraryPackage(mirror);
exportedClasses.forEach((String mirrorName, TypeMirror mirror) {
if (mirror is TypedefMirror) {
// This is actually a Dart2jsTypedefMirror, and it does define value,
// but we don't have visibility to that type.
if (includePrivateMembers || !mirror.isPrivate) {
typedefs[dart2js_util.nameOf(mirror)] = new Typedef(mirror, this);
}
} else if (mirror is ClassMirror) {
var clazz = new Class(mirror, this);
if (clazz.isError()) {
errors[dart2js_util.nameOf(mirror)] = clazz;
} else {
classes[dart2js_util.nameOf(mirror)] = clazz;
}
} else {
throw new ArgumentError(
'${dart2js_util.nameOf(mirror)} - no class type match. ');
}
});
this.functions = createMethods(addAll(exported['methods'],
libraryMirror.declarations.values.where(
(mirror) => mirror is MethodMirror)).values, this);
this.variables = createVariables(addAll(exported['variables'],
dart2js_util.variablesOf(libraryMirror.declarations)).values, this);
}
/// Look for the specified name starting with the current member, and
/// progressively working outward to the current library scope.
String findElementInScope(String name) {
var lookupFunc = determineLookupFunc(name);
var libraryScope = lookupFunc(mirror, name);
if (libraryScope != null) {
var result = getDocgenObject(libraryScope, this);
if (result is DummyMirror) return packagePrefix + result.docName;
return result.packagePrefix + result.docName;
}
return super.findElementInScope(name);
}
String getMdnComment() => '';
/// 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.
void updateLibraryPackage(LibraryMirror mirror) {
if (mirror == null) return;
if (_hasBeenCheckedForPackage) return;
_hasBeenCheckedForPackage = true;
if (mirror.uri.scheme != 'file') return;
packageName = getPackageName(mirror);
// Associate the package readme with all the libraries. This is a bit
// wasteful, but easier than trying to figure out which partial match
// is best.
packageIntro = _packageIntro(getPackageDirectory(mirror));
}
String _packageIntro(packageDir) {
if (packageDir == null) return null;
var dir = new Directory(packageDir);
var files = dir.listSync();
var readmes = files.where((FileSystemEntity each) => (each is File &&
each.path.substring(packageDir.length + 1, each.path.length)
.startsWith('README'))).toList();
if (readmes.isEmpty) return '';
// If there are multiples, pick the shortest name.
readmes.sort((a, b) => a.path.length.compareTo(b.path.length));
var readme = readmes.first;
var linkResolver = (name) => globalFixReference(name);
var contents = markdown.markdownToHtml(readme
.readAsStringSync(), linkResolver: linkResolver,
inlineSyntaxes: MARKDOWN_SYNTAXES);
return contents;
}
String get packagePrefix => packageName == null || packageName.isEmpty ?
'' : '$packageName/';
Map get previewMap {
var map = {'packageName': packageName};
map.addAll(super.previewMap);
if (packageIntro != null) {
map['packageIntro'] = packageIntro;
}
var version = packageVersion(mirror);
if (version != '' && version != null) map['version'] = version;
return map;
}
String get name => docName;
String get docName => getLibraryDocName(mirror);
/// Generates a map describing the [Library] object.
Map toMap() => {
'name': name,
'qualifiedName': qualifiedName,
'comment': comment,
'variables': recurseMap(variables),
'functions': expandMethodMap(functions),
'classes': {
'class': classes.values.where((c) => c.isVisible)
.map((e) => e.previewMap).toList(),
'typedef': recurseMap(typedefs),
'error': errors.values.where((e) => e.isVisible)
.map((e) => e.previewMap).toList()
},
'packageName': packageName,
'packageIntro': packageIntro
};
String get typeName => 'library';
bool isValidMirror(DeclarationMirror mirror) => mirror is LibraryMirror;
}
/// Dummy implementation of Indexable to represent the owner of a Library.
class _LibraryOwner implements Indexable {
const _LibraryOwner();
String get docName => '';
bool get isPrivate => false;
Indexable get owner => null;
// This is a known incomplete implementation of Indexable
// overriding noSuchMethod to remove static warnings
noSuchMethod(Invocation invocation) {
throw new UnimplementedError(invocation.memberName.toString());
}
}

View file

@ -1,156 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.models.method;
import 'package:markdown/markdown.dart' as markdown;
import '../exports/mirrors_util.dart' as dart2js_util;
import '../exports/source_mirrors.dart';
import '../library_helpers.dart';
import 'class.dart';
import 'doc_gen_type.dart';
import 'dummy_mirror.dart';
import 'indexable.dart';
import 'model_helpers.dart';
import 'owned_indexable.dart';
import 'parameter.dart';
/// A class containing properties of a Dart method.
class Method extends OwnedIndexable<MethodMirror> {
/// Parameters for this method.
final Map<String, Parameter> parameters;
final bool isStatic;
final bool isAbstract;
final bool isConst;
final DocGenType returnType;
Method methodInheritedFrom;
/// Qualified name to state where the comment is inherited from.
String commentInheritedFrom = "";
factory Method(MethodMirror mirror, Indexable owner,
[Method methodInheritedFrom]) {
var method = getDocgenObject(mirror, owner);
if (method is DummyMirror) {
method = new Method._(mirror, owner, methodInheritedFrom);
}
return method;
}
Method._(MethodMirror mirror, Indexable owner, this.methodInheritedFrom)
: returnType = new DocGenType(mirror.returnType, owner.owningLibrary),
isStatic = mirror.isStatic,
isAbstract = mirror.isAbstract,
isConst = mirror.isConstConstructor,
parameters = createParameters(mirror.parameters, owner),
super(mirror, owner);
Method get originallyInheritedFrom => methodInheritedFrom == null ?
this : methodInheritedFrom.originallyInheritedFrom;
/// Look for the specified name starting with the current member, and
/// progressively working outward to the current library scope.
String findElementInScope(String name) {
var lookupFunc = determineLookupFunc(name);
var memberScope = lookupFunc(this.mirror, name);
if (memberScope != null) {
// do we check for a dummy mirror returned here and look up with an owner
// higher ooooor in getDocgenObject do we include more things in our
// lookup
var result = getDocgenObject(memberScope, owner);
if (result is DummyMirror && owner.owner != null
&& owner.owner is! DummyMirror) {
var aresult = getDocgenObject(memberScope, owner.owner);
if (aresult is! DummyMirror) result = aresult;
}
if (result is DummyMirror) return packagePrefix + result.docName;
return result.packagePrefix + result.docName;
}
if (owner != null) {
var result = owner.findElementInScope(name);
if (result != null) return result;
}
return super.findElementInScope(name);
}
String get docName {
if (mirror.isConstructor) {
// We name constructors specially -- including the class name again and a
// "-" to separate the constructor from its name (if any).
return '${owner.docName}.${dart2js_util.nameOf(mirror.owner)}-'
'${dart2js_util.nameOf(mirror)}';
}
return super.docName;
}
String get qualifiedName => packagePrefix + docName;
/// Makes sure that the method with an inherited equivalent have comments.
void ensureCommentFor(Method inheritedMethod) {
if (comment.isNotEmpty) return;
comment = inheritedMethod.commentToHtml(this);
unresolvedComment = inheritedMethod.unresolvedComment;
commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ?
new DummyMirror(inheritedMethod.mirror).docName :
inheritedMethod.commentInheritedFrom;
}
/// Generates a map describing the [Method] object.
Map toMap() => {
'name': name,
'qualifiedName': qualifiedName,
'comment': comment,
'commentFrom': (methodInheritedFrom != null &&
commentInheritedFrom == methodInheritedFrom.docName ? ''
: commentInheritedFrom),
'inheritedFrom': (methodInheritedFrom == null? '' :
originallyInheritedFrom.docName),
'static': isStatic,
'abstract': isAbstract,
'constant': isConst,
'return': [returnType.toMap()],
'parameters': recurseMap(parameters),
'annotations': annotations.map((a) => a.toMap()).toList()
};
String get typeName {
if (mirror.isConstructor) return 'constructor';
if (mirror.isGetter) return 'getter';
if (mirror.isSetter) return 'setter';
if (mirror.isOperator) return 'operator';
return 'method';
}
String get comment {
if (commentField != null) return commentField;
if (owner is Class) {
(owner as Class).ensureComments();
}
var result = super.comment;
if (result == '' && methodInheritedFrom != null) {
// This should be NOT from the MIRROR, but from the COMMENT.
methodInheritedFrom.comment; // Ensure comment field has been populated.
unresolvedComment = methodInheritedFrom.unresolvedComment;
comment = unresolvedComment == null ? '' :
markdown.markdownToHtml(unresolvedComment.trim(),
linkResolver: fixReference, inlineSyntaxes: MARKDOWN_SYNTAXES);
commentInheritedFrom = comment != '' ?
methodInheritedFrom.commentInheritedFrom : '';
result = comment;
}
return result;
}
bool isValidMirror(DeclarationMirror mirror) => mirror is MethodMirror;
}

View file

@ -1,17 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.models.mirror_based;
import '../exports/source_mirrors.dart';
/// Docgen representation of an item to be documented, that wraps around a
/// dart2js mirror.
abstract class MirrorBased<TMirror extends DeclarationMirror> {
/// The original dart2js mirror around which this object wraps.
TMirror get mirror;
/// Return an informative [Object.toString] for debugging.
String toString() => "${super.toString()} - $mirror";
}

View file

@ -1,443 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.model_helpers;
import 'dart:collection';
import 'package:compiler/src/constants/expressions.dart';
import '../exports/dart2js_mirrors.dart' as dart2js_mirrors;
import '../exports/mirrors_util.dart' as dart2js_util;
import '../exports/source_mirrors.dart';
import '../exports/libraries.dart';
import '../library_helpers.dart' show includePrivateMembers;
import '../package_helpers.dart';
import 'annotation.dart';
import 'generic.dart';
import 'indexable.dart';
import 'library.dart';
import 'method.dart';
import 'parameter.dart';
import 'variable.dart';
String getLibraryDocName(LibraryMirror mirror) {
var dotsFixed = dart2js_util.qualifiedNameOf(mirror).replaceAll('.', '-');
if (dotsFixed.startsWith('dart-dom-')) {
return dotsFixed.replaceFirst("dart-dom-", "dart:");
} else if (dotsFixed.startsWith("dart-")) {
return dotsFixed.replaceFirst("dart-", "dart:");
} else {
return dotsFixed;
}
}
/// 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(mapToExpand,
(key, val) => val.mirror.isGetter)),
'constructors': recurseMap(_filterMap(mapToExpand,
(key, val) => val.mirror.isConstructor)),
'operators': recurseMap(_filterMap(mapToExpand,
(key, val) => val.mirror.isOperator)),
'methods': recurseMap(_filterMap(mapToExpand,
(key, val) => val.mirror.isRegularMethod && !val.mirror.isOperator))
};
String getDefaultValue(ParameterMirror mirror) {
if (!mirror.hasDefaultValue) return null;
return '${mirror.defaultValue}';
}
/// Returns a list of meta annotations assocated with a mirror.
List<Annotation> createAnnotations(DeclarationMirror mirror,
Library owningLibrary) {
var annotations = [];
var info = new AnnotationInfo(mirror, owningLibrary);
for (var expr in dart2js_mirrors.BackDoor.metadataSyntaxOf(mirror)) {
var docgenAnnotation = expr.accept(const AnnotationCreator(), info);
if (docgenAnnotation != null &&
!_SKIPPED_ANNOTATIONS.contains(
dart2js_util.qualifiedNameOf(docgenAnnotation.mirror))) {
annotations.add(docgenAnnotation);
}
}
return annotations;
}
class AnnotationInfo {
final Mirror mirror;
final Library owningLibrary;
AnnotationInfo(this.mirror, this.owningLibrary);
}
class AnnotationCreator
extends ConstantExpressionVisitor<Annotation, AnnotationInfo> {
const AnnotationCreator();
Annotation createAnnotation(var element,
AnnotationInfo context,
[List<String> parameters = const <String>[]]) {
var mirror =
dart2js_mirrors.BackDoor.getMirrorFromElement(context.mirror, element);
if (mirror != null) {
return new Annotation(context.owningLibrary, mirror, parameters);
}
return null;
}
@override
Annotation visitBinary(BinaryConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitIdentical(IdenticalConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitConcatenate(ConcatenateConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitConditional(ConditionalConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitConstructed(ConstructedConstantExpression exp,
AnnotationInfo context) {
return createAnnotation(exp.target, context,
exp.arguments.map((a) => a.getText()).toList());
}
@override
Annotation visitFunction(FunctionConstantExpression exp,
AnnotationInfo context) {
return createAnnotation(exp.element, context);
}
@override
Annotation visitList(ListConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitMap(MapConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitSymbol(SymbolConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitType(TypeConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitUnary(UnaryConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitVariable(VariableConstantExpression exp,
AnnotationInfo context) {
return createAnnotation(exp.element, context);
}
@override
Annotation visitBool(BoolConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitBoolFromEnvironment(BoolFromEnvironmentConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitDouble(DoubleConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitInt(IntConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitIntFromEnvironment(IntFromEnvironmentConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitNamed(NamedArgumentReference exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitNull(NullConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitPositional(PositionalArgumentReference exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitString(StringConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitStringFromEnvironment(
StringFromEnvironmentConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitStringLength(StringLengthConstantExpression exp,
AnnotationInfo context) {
return null;
}
@override
Annotation visitDeferred(DeferredConstantExpression exp,
AnnotationInfo context) {
return exp.expression.accept(this, context);
}
}
/// A declaration is private if itself is private, or the owner is private.
bool isHidden(DeclarationSourceMirror mirror) {
if (mirror is LibraryMirror) {
return _isLibraryPrivate(mirror);
} else if (mirror.owner is LibraryMirror) {
return (mirror.isPrivate || _isLibraryPrivate(mirror.owner) ||
mirror.isNameSynthetic);
} else {
return (mirror.isPrivate || isHidden(mirror.owner) ||
mirror.isNameSynthetic);
}
}
/// Transforms the map by calling toMap on each value in it.
Map recurseMap(Map inputMap) {
var outputMap = new LinkedHashMap();
inputMap.forEach((key, value) {
if (value is Map) {
outputMap[key] = recurseMap(value);
} else {
outputMap[key] = value.toMap();
}
});
return outputMap;
}
/// Read a pubspec and return the library name given a [LibraryMirror].
String getPackageName(LibraryMirror mirror) {
if (mirror.uri.scheme != 'file') return '';
var rootdir = getPackageDirectory(mirror);
if (rootdir == null) return '';
return packageNameFor(rootdir);
}
/// Helper that maps [mirrors] to their simple name in map.
Map addAll(Map map, Iterable<DeclarationMirror> mirrors) {
for (var mirror in mirrors) {
map[dart2js_util.nameOf(mirror)] = mirror;
}
return map;
}
/// For the given library determine what items (if any) are exported.
///
/// Returns a Map with three keys: "classes", "methods", and "variables" the
/// values of which point to a map of exported name identifiers with values
/// corresponding to the actual DeclarationMirror.
Map<String, Map<String, DeclarationMirror>> calcExportedItems(
LibrarySourceMirror library, Map visited) {
var exports = {};
visited[library] = exports;
exports['classes'] = new SplayTreeMap();
exports['methods'] = new SplayTreeMap();
exports['variables'] = new SplayTreeMap();
// Determine the classes, variables and methods that are exported for a
// specific dependency.
void _populateExports(LibraryDependencyMirror export, bool showExport) {
if (visited[export.targetLibrary] != null) return;
var transitiveExports = calcExportedItems(export.targetLibrary, visited);
exports['classes'].addAll(transitiveExports['classes']);
exports['methods'].addAll(transitiveExports['methods']);
exports['variables'].addAll(transitiveExports['variables']);
// If there is a show in the export, add only the show items to the
// library. Ex: "export foo show bar"
// Otherwise, add all items, and then remove the hidden ones.
// Ex: "export foo hide bar"
if (!showExport) {
// Add all items, and then remove the hidden ones.
// Ex: "export foo hide bar"
addAll(exports['classes'],
dart2js_util.typesOf(export.targetLibrary.declarations));
addAll(exports['methods'],
export.targetLibrary.declarations.values.where(
(mirror) => mirror is MethodMirror));
addAll(exports['variables'],
dart2js_util.variablesOf(export.targetLibrary.declarations));
}
for (CombinatorMirror combinator in export.combinators) {
for (String identifier in combinator.identifiers) {
var librarySourceMirror =
export.targetLibrary as DeclarationSourceMirror;
var declaration = librarySourceMirror.lookupInScope(identifier);
if (declaration == null) {
// Technically this should be a bug, but some of our packages
// (such as the polymer package) are curently broken in this
// way, so we just produce a warning.
print('Warning identifier $identifier not found in library '
'${dart2js_util.qualifiedNameOf(export.targetLibrary)}');
} else {
var subMap = exports['classes'];
if (declaration is MethodMirror) {
subMap = exports['methods'];
} else if (declaration is VariableMirror) {
subMap = exports['variables'];
}
if (showExport) {
subMap[identifier] = declaration;
} else {
subMap.remove(identifier);
}
}
}
}
}
Iterable<LibraryDependencyMirror> exportList =
library.libraryDependencies.where((lib) => lib.isExport);
for (LibraryDependencyMirror export in exportList) {
_populateExports(export,
export.combinators.any((combinator) => combinator.isShow));
}
return exports;
}
/// Returns a map of [Variable] objects constructed from [mirrorMap].
/// The optional parameter [containingLibrary] is contains data for variables
/// defined at the top level of a library (potentially for exporting
/// purposes).
Map<String, Variable> createVariables(Iterable<VariableMirror> mirrors,
Indexable owner) {
var data = new SplayTreeMap<String, Variable>();
// TODO(janicejl): When map to map feature is created, replace the below
// with a filter. Issue(#9590).
mirrors.forEach((dart2js_mirrors.Dart2JsFieldMirror mirror) {
if (includePrivateMembers || !isHidden(mirror)) {
var mirrorName = dart2js_util.nameOf(mirror);
data[mirrorName] = new Variable(mirrorName, mirror, owner);
}
});
return data;
}
/// Returns a map of [Method] objects constructed from [mirrorMap].
/// The optional parameter [containingLibrary] is contains data for variables
/// defined at the top level of a library (potentially for exporting
/// purposes).
Map<String, Method> createMethods(Iterable<MethodMirror> mirrors,
Indexable owner) {
var group = new SplayTreeMap<String, Method>();
mirrors.forEach((MethodMirror mirror) {
if (includePrivateMembers || !mirror.isPrivate) {
group[dart2js_util.nameOf(mirror)] = new Method(mirror, owner);
}
});
return group;
}
/// Returns a map of [Parameter] objects constructed from [mirrorList].
Map<String, Parameter> createParameters(List<ParameterMirror> mirrorList,
Indexable owner) {
var data = {};
mirrorList.forEach((ParameterMirror mirror) {
data[dart2js_util.nameOf(mirror)] =
new Parameter(mirror, owner.owningLibrary);
});
return data;
}
/// Returns a map of [Generic] objects constructed from the class mirror.
Map<String, Generic> createGenerics(TypeMirror mirror) {
return new Map.fromIterable(mirror.typeVariables,
key: (e) => dart2js_util.nameOf(e),
value: (e) => new Generic(e));
}
Map _filterMap(Map map, bool test(k, v)) {
var exported = new SplayTreeMap();
map.forEach((key, value) {
if (test(key, value)) exported[key] = value;
});
return exported;
}
/// Annotations that we do not display in the viewer.
const List<String> _SKIPPED_ANNOTATIONS = const [
'metadata.DocsEditable', '_js_helper.JSName', '_js_helper.Creates',
'_js_helper.Returns'
];
/// Returns true if a library name starts with an underscore, and false
/// otherwise.
///
/// An example that starts with _ is _js_helper.
/// An example that contains ._ is dart._collection.dev
bool _isLibraryPrivate(dart2js_mirrors.Dart2JsLibraryMirror mirror) {
// This method is needed because LibraryMirror.isPrivate returns `false` all
// the time.
var sdkLibrary = LIBRARIES[dart2js_util.nameOf(mirror)];
if (sdkLibrary != null) {
return !sdkLibrary.documented;
} else if (dart2js_util.nameOf(mirror).startsWith('_') || dart2js_util.nameOf(
mirror).contains('._')) {
return true;
}
return false;
}

View file

@ -1,70 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.models.owned_indexable;
import '../exports/mirrors_util.dart' as dart2js_util;
import '../exports/source_mirrors.dart';
import '../library_helpers.dart';
import '../mdn.dart';
import '../package_helpers.dart';
import 'annotation.dart';
import 'dummy_mirror.dart';
import 'indexable.dart';
import 'model_helpers.dart';
abstract class OwnedIndexable<TMirror extends DeclarationMirror>
extends Indexable<TMirror> {
/// List of the meta annotations on this item.
final List<Annotation> annotations;
/// 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.
final Indexable owner;
/// 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 + '.' + dart2js_util.nameOf(mirror);
OwnedIndexable(DeclarationMirror mirror, Indexable owner)
: annotations = createAnnotations(mirror, owner.owningLibrary),
this.owner = owner,
super(mirror);
/// Generates MDN comments from database.json.
String getMdnComment() {
var domAnnotation = this.annotations.firstWhere(
(e) => e.mirror.qualifiedName == #metadata.DomName,
orElse: () => null);
if (domAnnotation == null) return '';
var domName = domAnnotation.parameters.single;
return mdnComment(rootDirectory, logger, domName);
}
String get packagePrefix => owner.packagePrefix;
String findElementInScope(String name) {
var lookupFunc = determineLookupFunc(name);
var result = lookupFunc(mirror, name);
if (result != null) {
result = getDocgenObject(result);
if (result is DummyMirror) return packagePrefix + result.docName;
return result.packagePrefix + result.docName;
}
if (owner != null) {
var result = owner.findElementInScope(name);
if (result != null) {
return result;
}
}
return super.findElementInScope(name);
}
}

View file

@ -1,65 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.models.parameter;
import '../exports/mirrors_util.dart' as dart2js_util;
import '../exports/source_mirrors.dart';
import 'annotation.dart';
import 'closure.dart';
import 'doc_gen_type.dart';
import 'library.dart';
import 'mirror_based.dart';
import 'model_helpers.dart';
/// Docgen wrapper around the dart2js mirror for a Dart
/// method/function parameter.
class Parameter extends MirrorBased {
final ParameterMirror mirror;
final String name;
final bool isOptional;
final bool isNamed;
final bool hasDefaultValue;
final DocGenType type;
final String defaultValue;
/// List of the meta annotations on the parameter.
final List<Annotation> annotations;
final Library owningLibrary;
// Only non-null if this parameter is a function declaration.
Closure functionDeclaration;
Parameter(ParameterMirror mirror, Library owningLibrary)
: this.mirror = mirror,
name = dart2js_util.nameOf(mirror),
isOptional = mirror.isOptional,
isNamed = mirror.isNamed,
hasDefaultValue = mirror.hasDefaultValue,
defaultValue = getDefaultValue(mirror),
type = new DocGenType(mirror.type, owningLibrary),
annotations = createAnnotations(mirror, owningLibrary),
owningLibrary = owningLibrary {
if (mirror.type is FunctionTypeMirror) {
functionDeclaration =
new Closure(mirror.type as FunctionTypeMirror, owningLibrary);
}
}
/// Generates a map describing the [Parameter] object.
Map toMap() {
var map = {
'name': name,
'optional': isOptional,
'named': isNamed,
'default': hasDefaultValue,
'type': new List.filled(1, type.toMap()),
'value': defaultValue,
'annotations': annotations.map((a) => a.toMap()).toList()
};
if (functionDeclaration != null) {
map['functionDeclaration'] = functionDeclaration.toMap();
}
return map;
}
}

View file

@ -1,65 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.models.typedef;
import '../exports/source_mirrors.dart';
import '../library_helpers.dart';
import 'dummy_mirror.dart';
import 'library.dart';
import 'model_helpers.dart';
import 'generic.dart';
import 'parameter.dart';
import 'owned_indexable.dart';
class Typedef extends OwnedIndexable<TypedefMirror> {
final String returnType;
final Map<String, Parameter> parameters;
/// Generic information about the typedef.
final Map<String, Generic> generics;
/// Returns the [Library] for the given [mirror] if it has already been
/// created, else creates it.
factory Typedef(TypedefMirror mirror, Library owningLibrary) {
var aTypedef = getDocgenObject(mirror, owningLibrary);
if (aTypedef is DummyMirror) {
aTypedef = new Typedef._(mirror, owningLibrary);
}
return aTypedef;
}
Typedef._(TypedefMirror mirror, Library owningLibrary)
: returnType = getDocgenObject(mirror.referent.returnType).docName,
generics = createGenerics(mirror),
parameters = createParameters(mirror.referent.parameters,
owningLibrary),
super(mirror, owningLibrary);
Map toMap() {
var map = {
'name': name,
'qualifiedName': qualifiedName,
'comment': comment,
'return': returnType,
'parameters': recurseMap(parameters),
'annotations': annotations.map((a) => a.toMap()).toList(),
'generics': recurseMap(generics)
};
// Typedef is displayed on the library page as a class, so a preview is
// added manually
var pre = preview;
if (pre != null) map['preview'] = pre;
return map;
}
String get typeName => 'typedef';
bool isValidMirror(DeclarationMirror mirror) => mirror is TypedefMirror;
}

View file

@ -1,64 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.models.variable;
import '../exports/source_mirrors.dart';
import '../library_helpers.dart';
import 'class.dart';
import 'doc_gen_type.dart';
import 'dummy_mirror.dart';
import 'indexable.dart';
import 'owned_indexable.dart';
/// A class containing properties of a Dart variable.
class Variable extends OwnedIndexable<VariableMirror> {
final bool isFinal;
final bool isStatic;
final bool isConst;
final DocGenType type;
final String name;
factory Variable(String name, VariableMirror mirror, Indexable owner) {
var variable = getDocgenObject(mirror, owner);
if (variable is DummyMirror) {
return new Variable._(name, mirror, owner);
}
return variable;
}
Variable._(this.name, VariableMirror mirror, Indexable owner)
: isFinal = mirror.isFinal,
isStatic = mirror.isStatic,
isConst = mirror.isConst,
type = new DocGenType(mirror.type, owner.owningLibrary),
super(mirror, owner);
/// Generates a map describing the [Variable] object.
Map toMap() => {
'name': name,
'qualifiedName': qualifiedName,
'comment': comment,
'final': isFinal,
'static': isStatic,
'constant': isConst,
'type': new List.filled(1, type.toMap()),
'annotations': annotations.map((a) => a.toMap()).toList()
};
String get typeName => 'property';
String get comment {
if (commentField != null) return commentField;
if (owner is Class) {
(owner as Class).ensureComments();
}
return super.comment;
}
bool isValidMirror(DeclarationMirror mirror) => mirror is VariableMirror;
}

View file

@ -1,126 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.package_helpers;
import 'exports/source_mirrors.dart';
import 'generator.dart' show pubScript;
import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:yaml/yaml.dart';
/// Helper accessor to determine the full pathname of the root of the dart
/// checkout if we are running without the --sdk parameter specified. That
/// normally means we are running directly from source, and we expect to
/// find the root as the directory above 'pkg'. The only other time this
/// would happen is running a snapshot directly, rather than from the
/// dartdocgen script, where we look for the dart-sdk directory. If not
/// using the script and not in a normal directory structure, you'll need
/// to pass the --sdk parameter.
String get rootDirectory {
if (_rootDirectoryCache != null) return _rootDirectoryCache;
var scriptDir = path.absolute(path.dirname(Platform.script.toFilePath()));
var root = scriptDir;
var base = path.basename(root);
while (base != 'dart-sdk' && base != 'pkg') {
root = path.dirname(root);
base = path.basename(root);
if (root == base) {
// We have reached the root of the filesystem without finding anything.
throw new FileSystemException("Cannot find SDK directory starting from ",
scriptDir);
}
}
_rootDirectoryCache = path.dirname(root);
return _rootDirectoryCache;
}
String _rootDirectoryCache;
/// Given a LibraryMirror that is a library, return the name of the directory
/// holding the package information for that library. If the library is not
/// part of a package, return null.
String getPackageDirectory(LibraryMirror mirror) {
var file = mirror.uri.toFilePath();
// Any file that's in a package will be in a directory of the form
// packagename/lib/.../filename.dart, so we know that a possible
// package directory is at least in the directory above the one containing
// [file]
var directoryAbove = path.dirname(path.dirname(file));
var possiblePackage = _packageDirectoryFor(directoryAbove);
// We only want components that are somewhere underneath the lib directory.
var subPath = path.relative(file, from: possiblePackage);
var subPathComponents = path.split(subPath);
if (subPathComponents.isNotEmpty && subPathComponents.first == 'lib') {
return possiblePackage;
} else {
return null;
}
}
Map _getPubspec(String directoryName) {
var pubspecName = path.join(directoryName, 'pubspec.yaml');
File pubspec = new File(pubspecName);
if (!pubspec.existsSync()) return {'name': ''};
var contents = pubspec.readAsStringSync();
return loadYaml(contents);
}
/// Read a pubspec and return the library name, given a directory
String packageNameFor(String directoryName) =>
_getPubspec(directoryName)['name'];
/// Read a pubspec and return the library name, given a directory
String _packageVersionFor(String directoryName) {
var spec = _getPubspec(directoryName);
return '${spec['name']}-${spec['version']}';
}
/// Look in the pubspec.lock to determine what version of a package we are
/// documenting (null if not applicable).
String packageVersion(LibraryMirror mirror) {
if (mirror.uri.scheme == 'file') {
String packageDirectory = getPackageDirectory(mirror);
if (packageDirectory == null) return '';
if (packageDirectory.contains('.pub-cache')) {
return path.basename(packageDirectory);
}
String packageName = packageNameFor(packageDirectory);
return _packageVersionFor(packageDirectory);
} else if (mirror.uri.scheme == 'dart') {
// If this item is from the SDK, use what version of pub we're running to
// ascertain the SDK version.
var pubVersion = Process.runSync(pubScript, ['--version'],
runInShell: true);
if (pubVersion.exitCode != 0) {
print(pubVersion.stderr);
}
return pubVersion.stdout.replaceAll('Pub ', '').trim();
}
return '';
}
String _packageVersionHelper(String packageDirectory, String packageName) {
var publockName = path.join(packageDirectory, 'pubspec.lock');
File publock = new File(publockName);
if (!publock.existsSync()) return '';
var contents = publock.readAsStringSync();
var spec = loadYaml(contents);
return spec['packages'][packageName];
}
/// Recursively walk up from directory name looking for a pubspec. Return
/// the directory that contains it, or null if none is found.
String _packageDirectoryFor(String directoryName) {
var dir = directoryName;
while (!_pubspecFor(dir).existsSync()) {
var newDir = path.dirname(dir);
if (newDir == dir) return null;
dir = newDir;
}
return dir;
}
File _pubspecFor(String directoryName) =>
new File(path.join(directoryName, 'pubspec.yaml'));

View file

@ -1,201 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
/// Convenience methods wrapped up in a class to pull down the docgen viewer for
/// a viewable website, and start up a server for viewing.
library docgen.viewer;
import 'dart:io';
import 'package:path/path.dart' as path;
import 'generator.dart' as gen;
import 'package_helpers.dart' show rootDirectory;
final String _dartdocViewerString =
path.join(Directory.current.path, 'dartdoc-viewer');
final Directory _dartdocViewerDir = new Directory(_dartdocViewerString);
Directory _topLevelTempDir;
Directory _webDocsDir;
bool _movedViewerCode = false;
void createViewer(bool serve) {
_clone();
_compile();
if (serve) {
_runServer();
}
}
/*
* dartdoc-viewer currently has the web app code under a 'client' directory
*
* This is confusing for folks that want to clone and modify the code.
* It also includes a number of python files and other content related to
* app engine hosting that are not needed.
*
* This logic exists to support the current model and a (future) updated
* dartdoc-viewer repo where the 'client' content exists at the root of the
* project and the other content is removed.
*/
String get _viewerCodePath {
if (_viewerCodePathCache == null) {
var pubspecFileName = 'pubspec.yaml';
var thePath = _dartdocViewerDir.path;
if (!FileSystemEntity.isFileSync(path.join(thePath, pubspecFileName))) {
thePath = path.join(thePath, 'client');
if (!FileSystemEntity.isFileSync(path.join(thePath, pubspecFileName))) {
throw new StateError('Could not find a pubspec file');
}
}
_viewerCodePathCache = thePath;
}
return _viewerCodePathCache;
}
String _viewerCodePathCache;
/// 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.
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(rootDirectory).createTempSync();
_dartdocViewerDir.renameSync(_topLevelTempDir.path);
}
}
/// Move the dartdoc-viewer code back into place for "webpage deployment."
void addBackViewerCode() {
if (_movedViewerCode) _dartdocViewerDir.renameSync(_dartdocViewerString);
}
/// Serve up our generated documentation for viewing in a browser.
void _clone() {
// 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',
'https://github.com/dart-lang/dartdoc-viewer.git'], runInShell: true);
if (processResult.exitCode == 0) {
/// Move the generated json/yaml docs directory to the dartdoc-viewer
/// directory, to run as a webpage.
var processResult = Process.runSync(gen.pubScript, ['get'],
runInShell: true, workingDirectory: _viewerCodePath);
print('process output: ${processResult.stdout}');
print('process stderr: ${processResult.stderr}');
var dir = new Directory(gen.outputDirectory == null ? 'docs' :
gen.outputDirectory);
_webDocsDir = new Directory(path.join(_viewerCodePath, 'web', 'docs'));
if (dir.existsSync()) {
// Move the docs folder to dartdoc-viewer/client/web/docs
dir.renameSync(_webDocsDir.path);
}
} 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.
void _moveDirectoryAndServe() {
var processResult = Process.runSync(gen.pubScript, ['upgrade'], runInShell:
true, workingDirectory: path.join(_dartdocViewerDir.path, 'client'));
print('process output: ${processResult.stdout}');
print('process stderr: ${processResult.stderr}');
var dir = new Directory(gen.outputDirectory == null ? 'docs' :
gen.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('Compiling the app to JavaScript.');
var processResult = Process.runSync(gen.dartBinary, ['deploy.dart'],
workingDirectory: path.join(_dartdocViewerDir.path, 'client'),
runInShell: true);
print('process output: ${processResult.stdout}');
print('process stderr: ${processResult.stderr}');
_runServer();
}
}
void _compile() {
if (_webDocsDir.existsSync()) {
// Compile the code to JavaScript so we can run on any browser.
print('Compiling the app to JavaScript.');
var processResult = Process.runSync(gen.dartBinary, ['deploy.dart'],
workingDirectory: _viewerCodePath, runInShell: true);
print('process output: ${processResult.stdout}');
print('process stderr: ${processResult.stderr}');
var outputDir = path.join(_viewerCodePath, 'out', 'web');
print('Docs are available at $outputDir');
}
}
/// A simple HTTP server. Implemented here because this is part of the SDK,
/// so it shouldn't have any external dependencies.
void _runServer() {
// Launch a server to serve out of the directory dartdoc-viewer/client/web.
HttpServer.bind(InternetAddress.ANY_IP_V6, 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(_viewerCodePath, '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');
});
});
}

View file

@ -1,13 +0,0 @@
name: docgen
author: Dart Team <misc@dartlang.org>
description: A documentation generator for the Dart repository.
homepage: https://www.dartlang.org/
dependencies:
args: '>=0.9.0 <0.14.0'
logging: '>=0.9.0 <0.12.0'
markdown: ^0.7.1+2
path: '>=0.9.0 <2.0.0'
yaml: '>=0.9.0 <3.0.0'
dev_dependencies:
scheduled_test: '>=0.10.0 <0.12.0'
unittest: '>=0.9.0 <0.12.0'

View file

@ -1,150 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library async_await_test;
import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:unittest/unittest.dart';
import '../lib/src/exports/mirrors_util.dart' as dart2js_util;
import '../lib/docgen.dart';
const String DART_LIBRARY = '''
library test;
/**
* Doc comment for class [A].
*
* Multiline Test
*/
/*
* Normal comment for class A.
*/
class A {
m1() sync* {
yield 0;
}
m2() async {
await 0;
await for (var e in m1()) {}
}
m3() async* {
yield* m1();
}
}
m1() sync* {
yield 0;
}
m2() async {
await 0;
await for (var e in m1()) {}
}
m3() async* {
yield* m1();
}
main() {
m1();
m2();
m3();
A a = new A();
a.m1();
a.m2();
a.m3();
}
''';
main() {
group('Generate docs for', () {
test('file with async/await.', () {
var temporaryDir = Directory.systemTemp.createTempSync('single_library_');
var fileName = path.join(temporaryDir.path, 'temp.dart');
var file = new File(fileName);
file.writeAsStringSync(DART_LIBRARY);
return getMirrorSystem([new Uri.file(fileName)], false)
.then((mirrorSystem) {
var testLibraryUri = new Uri.file(path.absolute(fileName),
windows: Platform.isWindows);
var library = new Library(mirrorSystem.libraries[testLibraryUri]);
expect(library is Library, isTrue);
var classTypes = library.classes;
var classes = [];
classes.addAll(classTypes.values);
classes.addAll(library.errors.values);
expect(classes.every((e) => e is Class), isTrue);
expect(library.typedefs.values.every((e) => e is Typedef), isTrue);
var classMethodTypes = [];
classes.forEach((e) {
classMethodTypes.add(e.methods);
classMethodTypes.add(e.inheritedMethods);
});
expect(classMethodTypes.every((e) => e is Map<String, Method>),
isTrue);
var classMethods = [];
classMethodTypes.forEach((e) {
classMethods.addAll(e.values);
});
expect(classMethods.every((e) => e is Method), isTrue);
var methodParameters = [];
classMethods.forEach((e) {
methodParameters.addAll(e.parameters.values);
});
expect(methodParameters.every((e) => e is Parameter), isTrue);
var functionTypes = library.functions;
expect(functionTypes is Map<String, Method>, isTrue);
var functions = [];
functions.addAll(functionTypes.values);
expect(functions.every((e) => e is Method), isTrue);
var functionParameters = [];
functions.forEach((e) {
functionParameters.addAll(e.parameters.values);
});
expect(functionParameters.every((e) => e is Parameter), isTrue);
var variables = library.variables.values;
expect(variables.every((e) => e is Variable), isTrue);
/// Testing fixReference
// Testing Doc comment for class [A].
var libraryMirror = mirrorSystem.libraries[testLibraryUri];
var classMirror =
dart2js_util.classesOf(libraryMirror.declarations).first;
var classDocComment = library.fixReference('A').children.first.text;
expect(classDocComment, 'test.A');
// Test for linking to parameter [A]
var method = getDocgenObject(
classMirror.declarations[dart2js_util.symbolOf('m1')]);
// Testing trying to refer to m1 method
var methodDocComment = method.fixReference(
'm1').children.first.text;
expect(methodDocComment, 'test.A.m1');
// Testing something with no reference
var libraryDocComment = method.fixReference('foobar').text;
expect(libraryDocComment, 'foobar');
// Testing trying to refer to m1 function
libraryDocComment = library.fixReference('m1').children.first.text;
expect(libraryDocComment, 'test.m1');
}).whenComplete(() => temporaryDir.deleteSync(recursive: true));
});
});
}

View file

@ -1,80 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.test.typedef;
import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as p;
import 'package:scheduled_test/descriptor.dart' as d;
import 'package:scheduled_test/scheduled_test.dart';
import 'util.dart';
import '../lib/docgen.dart' as dg;
void main() {
setUp(() {
scheduleTempDir();
});
test('argument default values', () {
schedule(() {
var codeDir = getMultiLibraryCodePath();
expect(FileSystemEntity.isDirectorySync(codeDir), isTrue);
return dg.docgen([codeDir], out: p.join(d.defaultRoot, 'docs'));
});
schedule(() {
var path = p.join(d.defaultRoot, 'docs', 'test_lib.json');
var dartCoreJson = new File(path).readAsStringSync();
var testLibBar = JSON.decode(dartCoreJson) as Map<String, dynamic>;
//
// Validate function doc references
//
var functionDef =
testLibBar['functions']['methods']['positionalDefaultValues']
as Map<String, dynamic>;
var params = functionDef['parameters'] as Map<String, dynamic>;
expect(params.keys, orderedEquals(_PARAM_NAME_ORDER),
reason: 'parameter order must be maintained');
var vals = {};
params.forEach((paramName, paramHash) {
expect(_PARAM_VALUES, contains(paramName));
expect(paramHash['value'], _PARAM_VALUES[paramName],
reason: 'Value for $paramName should match expected');
});
});
});
}
final _PARAM_VALUES = {
"intConst": "42",
"boolConst": "true",
"listConst": 'const [true, 42, "Shanna", null, 3.14, const []]',
"stringConst": "\"Shanna\"",
"mapConst": 'const {"a": 1, 2: true, "c": const [1, null, true]}',
"emptyMap": 'const {}',
"referencedConst": "INT_CONST",
"constructedConstant1": "const ConstClass<int>(0, true)",
"constructedConstant2": 'const ConstClass(1, false, str: "str")'
};
const _PARAM_NAME_ORDER = const [
"intConst",
"boolConst",
"listConst",
"stringConst",
"mapConst",
"emptyMap",
"referencedConst",
"constructedConstant1",
"constructedConstant2"
];

View file

@ -1,50 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.generate_json_test;
import 'dart:io';
import 'package:path/path.dart' as p;
import 'package:scheduled_test/descriptor.dart' as d;
import 'package:scheduled_test/scheduled_test.dart';
import 'util.dart';
import '../lib/docgen.dart' as dg;
void main() {
setUp(() {
scheduleTempDir();
});
test('json output', () {
schedule(() {
var codeDir = getMultiLibraryCodePath();
expect(FileSystemEntity.isDirectorySync(codeDir), isTrue);
return dg.docgen([codeDir], out: p.join(d.defaultRoot, 'docs'));
});
d.dir('docs', [
d.matcherFile('index.json', isJsonMap),
d.matcherFile('index.txt', hasSortedLines),
d.matcherFile('library_list.json', isJsonMap),
d.matcherFile('library_list.json',
startsWith(_LIBRARY_LIST_UNINDENT_START)),
d.matcherFile('sub_lib.json', isJsonMap),
d.matcherFile('sub_lib.SubLibClass.json', isJsonMap),
d.matcherFile('sub_lib.SubLibPart.json', isJsonMap),
d.matcherFile('test_lib-bar.C.json', isJsonMap),
d.matcherFile('test_lib-bar.json', isJsonMap),
d.matcherFile('test_lib-foo.B.json', isJsonMap),
d.matcherFile('test_lib-foo.json', isJsonMap),
d.matcherFile('test_lib.A.json', isJsonMap),
d.matcherFile('test_lib.B.json', isJsonMap),
d.matcherFile('test_lib.C.json', isJsonMap),
d.matcherFile('test_lib.json', isJsonMap),
]).validate();
});
}
const _LIBRARY_LIST_UNINDENT_START = '{"libraries":[{"packageName":""';

View file

@ -1,49 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.test.inherited_comments;
import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as p;
import 'package:scheduled_test/descriptor.dart' as d;
import 'package:scheduled_test/scheduled_test.dart';
import 'util.dart';
import '../lib/docgen.dart' as dg;
void main() {
setUp(() {
scheduleTempDir();
});
test('inherited comments', () {
schedule(() {
var codeDir = getMultiLibraryCodePath();
expect(FileSystemEntity.isDirectorySync(codeDir), isTrue);
return dg.docgen([codeDir], out: p.join(d.defaultRoot, 'docs'));
});
schedule(() {
var path = p.join(d.defaultRoot, 'docs', 'dart-core.Set.json');
var dartCoreSetJson = new File(path).readAsStringSync();
var dartCoreSet = JSON.decode(dartCoreSetJson) as Map<String, dynamic>;
var toListDetails = dartCoreSet['inheritedMethods']['methods']['toList']
as Map<String, dynamic>;
expect(toListDetails, containsPair('comment', _TO_LIST_COMMENT));
expect(toListDetails, containsPair('commentFrom', _TO_LIST_COMMENT_FROM));
});
});
}
const _TO_LIST_COMMENT = "<p>Creates a <a>dart:core.List</a> containing the "
"elements of this <a>dart:core.Iterable</a>.</p>\n<p>The elements are in "
"iteration order. The list is fixed-length\nif "
"<a>dart:core.Set.toList.growable</a> is false.</p>";
const _TO_LIST_COMMENT_FROM = "dart:core.Iterable.toList";

View file

@ -1,65 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library async_await_test;
import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:unittest/unittest.dart';
import '../lib/src/exports/mirrors_util.dart' as dart2js_util;
import '../lib/src/models/annotation.dart';
import '../lib/docgen.dart';
const Map<String, String> SOURCES = const <String, String>{
'main.dart': '''
import 'lib.dart' as lib;
@lib.Annotation("foo", 42)
main() {
}
''',
'lib.dart': '''
class Annotation {
final String arg1;
final int arg2;
const Annotation(this.arg1, this.arg2);
}
'''};
main() {
group('Generate docs for', () {
test('files with annotations', () {
var temporaryDir = Directory.systemTemp.createTempSync('metadata_');
var uris = <Uri>[];
SOURCES.forEach((name, code) {
var fileName = path.join(temporaryDir.path, name);
var file = new File(fileName);
file.writeAsStringSync(code);
uris.add(new Uri.file(fileName));
});
return getMirrorSystem(uris, false).then((mirrorSystem) {
var library = new Library(mirrorSystem.libraries[uris[0]]);
expect(library is Library, isTrue);
var main = library.functions['main'];
expect(main is Method, isTrue);
var annotations = main.annotations;
expect(annotations.length, equals(1));
var annotation = annotations[0];
expect(annotation is Annotation, isTrue);
var map = annotation.toMap();
expect(map['name'], equals('lib-dart.Annotation.Annotation-'));
expect(map['parameters'].length, equals(2));
expect(map['parameters'][0], equals('"foo"'));
expect(map['parameters'][1], equals('42'));
}).whenComplete(() => temporaryDir.deleteSync(recursive: true));
});
});
}

View file

@ -1,28 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.test.method_param;
import 'package:path/path.dart' as path;
import 'package:scheduled_test/scheduled_test.dart';
import 'util.dart';
import '../lib/docgen.dart' as gen;
void main() {
test('method function parameters', () {
var lib_file = path.toUri(path.join(getMultiLibraryCodePath(), 'lib',
'test_lib2.dart'));
return gen.getMirrorSystem([lib_file], false)
.then((mirrorSystem) {
var library = new gen.Library(mirrorSystem.libraries[lib_file]);
// Test that libraries do recursive exports correctly.
var funcParams = library.functions['fooFunc'].parameters;
expect('Symbol("dart.core.int")', library.functions['fooFunc']
.parameters['fooFuncParam'].functionDeclaration.parameters['x']
.type.mirror.qualifiedName.toString());
});
});
}

View file

@ -1,38 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library library.name.wiith.dots.init;
/// This library is purely for testing purposes, to ensure
/// that we have a library that has dots in its name and
/// that it works properly
///
/// In addition, it's nice to have something which has paragraph
/// breaks inside a triple-slash doc comment.
///
/// Like this.
/// This is a top level field holding the number three;
int topLevelInt = 3;
/// This is a class with various ways of getting the number three.
///
/// It also has a comment with paragraph breaks.
class SomeClass {
/// This is a method that returns the number three. See
/// [three]
someMethod() => 3;
/// This is a symbolic representation of the number three.
int three = 3;
}
/// This is another class.
class AnotherClass {
/// This method returns [List<int>] containing the number
/// three three times. Compare with [SomeClass.someMethod].
List<int> anotherMethod() {
return const [3, 3, 3];
}
}

View file

@ -1,13 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library root_lib;
export 'test_lib.dart';
export 'test_lib_foo.dart';
export 'test_lib_bar.dart';
class RootClass {
RootClass(int a, int b);
}

View file

@ -1,5 +0,0 @@
library internal_lib;
part 'src_lib_part.dart';
class InternalLibClass {}

View file

@ -1,3 +0,0 @@
part of internal_lib;
class InternalLibPart {}

View file

@ -1,5 +0,0 @@
library sub_lib;
part 'sub_lib_part.dart';
class SubLibClass {}

View file

@ -1,3 +0,0 @@
part of sub_lib;
class SubLibPart {}

View file

@ -1,65 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library test_lib;
import 'test_lib_foo.dart';
import 'test_lib_bar.dart';
export 'test_lib_foo.dart';
export 'test_lib_bar.dart';
/**
* Doc comment for class [A].
*
* Multiline Test
*/
/*
* Normal comment for class A.
*/
class A {
int _someNumber;
A() {
_someNumber = 12;
}
A.customConstructor();
/**
* Test for linking to parameter [A]
*/
void doThis(int A) {
print(A);
}
}
// A trivial use of `B` and `C` to eliminate import warnings
B sampleMethod(C cInstance) {
throw new UnimplementedError();
}
int positionalDefaultValues([
int intConst = 42,
bool boolConst = true,
List listConst = const [true, 42, 'Shanna', null, 3.14, const []],
String stringConst = 'Shanna',
Map mapConst = const {'a':1, 2: true, 'c': const [1,null,true]},
Map emptyMap = const {},
int referencedConst = INT_CONST,
ConstClass constructedConstant1 = const ConstClass<int>(0, true),
ConstClass constructedConstant2 = const ConstClass(1, false, str: "str")]) {
throw new UnimplementedError();
}
const int INT_CONST = 42;
class ConstClass<T> {
final bool boolField;
final int intField;
final String stringField;
const ConstClass(this.intField, this.boolField, {String str: 'default'})
: this.stringField = str;
}

View file

@ -1,9 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library test_lib2;
export 'test_lib2_foo.dart';
String fooFunc(bool fooFuncParam(int x)) => 'hi';

View file

@ -1,9 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library test_lib2_bar;
class Bar {
}

View file

@ -1,15 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library test_lib2_foo;
export 'test_lib2_bar.dart';
class Foo {
}
main() {
print('hello world');
}

View file

@ -1,30 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library test_lib.bar;
import 'test_lib.dart';
import 'test_lib_foo.dart';
/*
* Normal comment for class C.
*/
class C {
}
/// Processes an [input] of type [C] instance for testing.
///
/// To eliminate import warnings for [A] and to test typedefs.
///
/// It's important that the [List<A>] for param [listOfA] is not empty.
A testMethod(C input, List<A> listOfA, B aBee) {
throw 'noop';
}
/// Processes an [input] of type [C] instance for testing.
///
/// To eliminate import warnings for [A] and to test typedefs.
///
/// It's important that the [List<A>] for param [listOfA] is not empty.
typedef A testTypedef(C other, List<A> listOfA, B aBee);

View file

@ -1,41 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library test_lib.foo;
import 'test_lib.dart';
/**
* Doc comment for class [B].
*
* Multiline Test
*/
/*
* Normal comment for class B.
*/
class B extends A {
B();
B.fooBar();
/**
* Test for linking to super
*/
int doElse(int b) {
print(b);
return b;
}
/**
* Test for linking to parameter [c]
*/
void doThis(int c) {
print(c);
}
}
int testFunc(int a) {
return a;
}

View file

@ -1,106 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library single_library_test;
import 'package:path/path.dart' as p;
import 'package:unittest/unittest.dart';
import '../lib/docgen.dart';
import '../lib/src/exports/mirrors_util.dart' as dart2js_util;
import 'util.dart';
List<Uri> _writeLibFiles() {
var codePath = getMultiLibraryCodePath();
codePath = p.join(codePath, 'lib');
return ['test_lib.dart', 'test_lib_bar.dart', 'test_lib_foo.dart']
.map((name) => p.join(codePath, name))
.map(p.toUri)
.toList();
}
void main() {
group('Generate docs for', () {
test('multiple libraries.', () {
var files = _writeLibFiles();
return getMirrorSystem(files, false)
.then((mirrorSystem) {
var test_libraryUri = files[0];
var library = new Library(mirrorSystem.libraries[test_libraryUri]);
/// Testing fixReference
// Testing Doc comment for class [B].
var libraryMirror = mirrorSystem.libraries[test_libraryUri];
var classDocComment = library.fixReference('B').children.first.text;
expect(classDocComment, 'test_lib.B');
// Test for linking to parameter [c]
var importedLib = libraryMirror.libraryDependencies.firstWhere(
(dep) => dep.isImport).targetLibrary;
var aClassMirror =
dart2js_util.classesOf(importedLib.declarations).first;
expect(dart2js_util.qualifiedNameOf(aClassMirror),
'test_lib.foo.B');
var exportedClass = getDocgenObject(aClassMirror, library);
expect(exportedClass is Class, isTrue);
var method = exportedClass.methods['doThis'];
expect(method is Method, isTrue);
var methodParameterDocComment = method.fixReference(
'c').children.first.text;
expect(methodParameterDocComment, 'test_lib.B.doThis.c');
expect(method.fixReference('A').children.first.text, 'test_lib.A');
// Testing trying to refer to doThis function
expect(method.fixReference('doThis').children.first.text,
'test_lib.B.doThis');
// Testing trying to refer to doThis function
expect(method.fixReference('doElse').children.first.text,
'test_lib.B.doElse');
// Test a third library referencing another exported library in a
// separate file.
importedLib = libraryMirror.libraryDependencies.firstWhere(
(dep) => dep.isImport &&
dart2js_util.qualifiedNameOf(dep.targetLibrary) ==
'test_lib.bar').targetLibrary;
aClassMirror = dart2js_util.classesOf(importedLib.declarations).first;
expect(dart2js_util.qualifiedNameOf(aClassMirror),
'test_lib.bar.C');
exportedClass = getDocgenObject(aClassMirror, library);
expect(exportedClass is Class, isTrue);
expect(exportedClass.docName, 'test_lib.C');
methodParameterDocComment = exportedClass.fixReference(
'B').children.first.text;
expect(methodParameterDocComment, 'test_lib.B');
methodParameterDocComment = exportedClass.fixReference(
'testFunc').children.first.text;
expect(methodParameterDocComment, 'test_lib.testFunc');
});
});
test('multiple exported libraries.', () {
var lib_file = p.toUri(p.join(getMultiLibraryCodePath(), 'lib',
'test_lib2.dart'));
return getMirrorSystem([lib_file], false)
.then((mirrorSystem) {
var library = new Library(mirrorSystem.libraries[lib_file]);
// Test that libraries do recursive exports correctly.
expect(true, library.classes.keys.contains('Bar'));
});
});
});
}

View file

@ -1,100 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library native_extensions_test;
import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:unittest/unittest.dart';
import '../lib/src/exports/mirrors_util.dart' as dart2js_util;
import '../lib/docgen.dart';
const String DART_LIBRARY = '''
library sample_synchronous_extension;
import 'dart-ext:sample_extension';
// The simplest way to call native code: top-level functions.
int systemRand() native "SystemRand";
bool systemSrand(int seed) native "SystemSrand";
void main() {
systemRand();
systemSrand(4);
}
''';
main() {
group('Generate docs for', () {
test('file with native extensions.', () {
var temporaryDir = Directory.systemTemp.createTempSync('native_ext_');
var fileName = path.join(temporaryDir.path, 'temp.dart');
var file = new File(fileName);
file.writeAsStringSync(DART_LIBRARY);
return getMirrorSystem([new Uri.file(fileName)], false)
.then((mirrorSystem) {
var testLibraryUri = new Uri.file(path.absolute(fileName),
windows: Platform.isWindows);
var library = new Library(mirrorSystem.libraries[testLibraryUri]);
expect(library is Library, isTrue);
var classTypes = library.classes;
var classes = [];
classes.addAll(classTypes.values);
classes.addAll(library.errors.values);
expect(classes.every((e) => e is Class), isTrue);
expect(library.typedefs.values.every((e) => e is Typedef), isTrue);
var classMethodTypes = [];
classes.forEach((e) {
classMethodTypes.add(e.methods);
classMethodTypes.add(e.inheritedMethods);
});
expect(classMethodTypes.every((e) => e is Map<String, Method>),
isTrue);
var classMethods = [];
classMethodTypes.forEach((e) {
classMethods.addAll(e.values);
});
expect(classMethods.every((e) => e is Method), isTrue);
var methodParameters = [];
classMethods.forEach((e) {
methodParameters.addAll(e.parameters.values);
});
expect(methodParameters.every((e) => e is Parameter), isTrue);
var functionTypes = library.functions;
expect(functionTypes is Map<String, Method>, isTrue);
var functions = [];
functions.addAll(functionTypes.values);
expect(functions.every((e) => e is Method), isTrue);
var functionParameters = [];
functions.forEach((e) {
functionParameters.addAll(e.parameters.values);
});
expect(functionParameters.every((e) => e is Parameter), isTrue);
var variables = library.variables.values;
expect(variables.every((e) => e is Variable), isTrue);
// Testing trying to refer to m1 function
var libraryDocComment =
library.fixReference('systemRand').children.first.text;
expect(libraryDocComment, 'sample_synchronous_extension.systemRand');
libraryDocComment =
library.fixReference('systemSrand').children.first.text;
expect(libraryDocComment, 'sample_synchronous_extension.systemSrand');
}).whenComplete(() => temporaryDir.deleteSync(recursive: true));
});
});
}

View file

@ -1,51 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.test.only_lib_content_in_pkg;
import 'dart:io';
import 'package:path/path.dart' as p;
import 'package:scheduled_test/descriptor.dart' as d;
import 'package:scheduled_test/scheduled_test.dart';
import '../lib/docgen.dart' as dg;
import 'util.dart';
void main() {
setUp(() {
scheduleTempDir();
});
test('exclude non-lib code from package docs', () {
schedule(() {
var thisScript = Platform.script;
var thisPath = p.fromUri(thisScript);
expect(p.basename(thisPath), 'only_lib_content_in_pkg_test.dart');
expect(p.dirname(thisPath), endsWith('test'));
var packageRoot = Platform.packageRoot;
if (packageRoot == '') packageRoot = null;
var codeDir = p.normalize(p.join(thisPath, '..', '..'));
expect(FileSystemEntity.isDirectorySync(codeDir), isTrue);
return dg.docgen(['$codeDir/'], out: p.join(d.defaultRoot, 'docs'),
packageRoot: packageRoot);
});
d.dir('docs', [
d.dir('docgen', [
d.matcherFile('docgen.json', isJsonMap)
]),
d.matcherFile('index.json', isJsonMap),
d.matcherFile('index.txt', hasSortedLines),
d.matcherFile('library_list.json', isJsonMap),
d.nothing('test_lib.json'),
d.nothing('test_lib-bar.json'),
d.nothing('test_lib-foo.json')
]).validate();
});
}

View file

@ -1,131 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library single_library_test;
import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:unittest/unittest.dart';
import '../lib/src/exports/mirrors_util.dart' as dart2js_util;
import '../lib/docgen.dart';
const String DART_LIBRARY = '''
library test;
/**
* Doc comment for class [A].
*
* Multiline Test
*/
/*
* Normal comment for class A.
*/
class A {
int _someNumber;
A() {
_someNumber = 12;
}
/**
* Test for linking to parameter [A]
*/
void doThis(int A) {
print(A);
}
}
main() {
A a = new A();
a.doThis(5);
}
''';
main() {
group('Generate docs for', () {
test('one simple file.', () {
var temporaryDir = Directory.systemTemp.createTempSync('single_library_');
var fileName = path.join(temporaryDir.path, 'temp.dart');
var file = new File(fileName);
file.writeAsStringSync(DART_LIBRARY);
return getMirrorSystem([new Uri.file(fileName)], false)
.then((mirrorSystem) {
var testLibraryUri = new Uri.file(path.absolute(fileName),
windows: Platform.isWindows);
var library = new Library(mirrorSystem.libraries[testLibraryUri]);
expect(library is Library, isTrue);
var classTypes = library.classes;
var classes = [];
classes.addAll(classTypes.values);
classes.addAll(library.errors.values);
expect(classes.every((e) => e is Class), isTrue);
expect(library.typedefs.values.every((e) => e is Typedef), isTrue);
var classMethodTypes = [];
classes.forEach((e) {
classMethodTypes.add(e.methods);
classMethodTypes.add(e.inheritedMethods);
});
expect(classMethodTypes.every((e) => e is Map<String, Method>), isTrue);
var classMethods = [];
classMethodTypes.forEach((e) {
classMethods.addAll(e.values);
});
expect(classMethods.every((e) => e is Method), isTrue);
var methodParameters = [];
classMethods.forEach((e) {
methodParameters.addAll(e.parameters.values);
});
expect(methodParameters.every((e) => e is Parameter), isTrue);
var functionTypes = library.functions;
expect(functionTypes is Map<String, Method>, isTrue);
var functions = [];
functions.addAll(functionTypes.values);
expect(functions.every((e) => e is Method), isTrue);
var functionParameters = [];
functions.forEach((e) {
functionParameters.addAll(e.parameters.values);
});
expect(functionParameters.every((e) => e is Parameter), isTrue);
var variables = library.variables.values;
expect(variables.every((e) => e is Variable), isTrue);
/// Testing fixReference
// Testing Doc comment for class [A].
var libraryMirror = mirrorSystem.libraries[testLibraryUri];
var classMirror =
dart2js_util.classesOf(libraryMirror.declarations).first;
var classDocComment = library.fixReference('A').children.first.text;
expect(classDocComment, 'test.A');
// Test for linking to parameter [A]
var method = getDocgenObject(
classMirror.declarations[dart2js_util.symbolOf('doThis')]);
var methodParameterDocComment = method.fixReference(
'A').children.first.text;
expect(methodParameterDocComment, 'test.A.doThis.A');
// Testing trying to refer to doThis function
var methodDocComment = method.fixReference(
'doThis').children.first.text;
expect(methodDocComment, 'test.A.doThis');
// Testing something with no reference
var libraryDocComment = method.fixReference('foobar').text;
expect(libraryDocComment, 'foobar');
}).whenComplete(() => temporaryDir.deleteSync(recursive: true));
});
});
}

View file

@ -1,105 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.test.typedef;
import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as p;
import 'package:scheduled_test/descriptor.dart' as d;
import 'package:scheduled_test/scheduled_test.dart';
import 'util.dart';
import '../lib/docgen.dart' as dg;
void main() {
setUp(() {
scheduleTempDir();
});
test('typedef gen', () {
schedule(() {
var codeDir = getMultiLibraryCodePath();
expect(FileSystemEntity.isDirectorySync(codeDir), isTrue);
return dg.docgen([codeDir], out: p.join(d.defaultRoot, 'docs'));
});
schedule(() {
var path = p.join(d.defaultRoot, 'docs', 'root_lib.json');
var rootLibJson = new File(path).readAsStringSync();
var rootLib = JSON.decode(rootLibJson) as Map<String, dynamic>;
//
// Validate function doc references
//
//var testMethod =
// rootLib['functions']['methods']['testMethod'] as Map<String, dynamic>;
// test commented out
// TODO: figure out why test is failing after upgrade to markdown 0.7.2
// Expected: '<p>Processes an <a>root_lib.testMethod.input</a> of type <a>root_lib.C</a> instance for testing.</p>\n'
// '<p>To eliminate import warnings for <a>root_lib.A</a> and to test typedefs.</p>\n'
// '<p>It\'s important that the <a>dart:core</a>&lt;A> for param <a>root_lib.testMethod.listOfA</a> is not empty.</p>'
// Actual: '<p>Processes an <a>root_lib.testMethod.input</a> of type <a>root_lib.C</a> instance for testing.</p>\n'
// '<p>To eliminate import warnings for <a>root_lib.A</a> and to test typedefs.</p>\n'
// '<p>It\'s important that the List<A> for param <a>root_lib.testMethod.listOfA</a> is not empty.</p>'
// Which: is different.
// Expected: ... that the <a>dart:co ...
// Actual: ... that the List<A> fo ...
// ^
// Differ at offset 210
//
// expect(testMethod['comment'], _TEST_METHOD_COMMENT);
// var classes = rootLib['classes'] as Map<String, dynamic>;
//
// expect(classes, hasLength(3));
//
// expect(classes['class'], isList);
// expect(classes['error'], isList);
//
// var typeDefs = classes['typedef'] as Map<String, dynamic>;
// var comparator = typeDefs['testTypedef'] as Map<String, dynamic>;
//
// expect(comparator['preview'], _TEST_TYPEDEF_PREVIEW);
//
// expect(comparator['comment'], _TEST_TYPEDEF_COMMENT);
});
schedule(() {
var path = p.join(d.defaultRoot, 'docs', 'root_lib.RootClass.json');
var rootClassJson = new File(path).readAsStringSync();
var rootClass = JSON.decode(rootClassJson) as Map<String, dynamic>;
var defaultCtor = rootClass['methods']['constructors'][''] as Map;
expect(defaultCtor['qualifiedName'], 'root_lib.RootClass.RootClass-');
});
});
}
// TOOD: [List<A>] is not formatted correctly - issue 16771
const _TEST_METHOD_COMMENT = '<p>Processes an '
'<a>root_lib.testMethod.input</a> of type <a>root_lib.C</a> '
'instance for testing.</p>\n<p>To eliminate import warnings for '
'<a>root_lib.A</a> and to test typedefs.</p>\n<p>It\'s important that the'
' <a>dart:core</a>&lt;A> for param <a>root_lib.testMethod.listOfA</a> '
'is not empty.</p>';
// TODO: [input] is not turned into a param refenece
// TODO(kevmoo): <a>test_lib.C</a> should be <a>root_lib.C</a> - Issues 18352
const _TEST_TYPEDEF_PREVIEW = '<p>Processes an input of type '
'<a>test_lib.C</a> instance for testing.</p>';
// TOOD: [List<A>] is not formatted correctly - issue 16771
// TODO: [listOfA] is not turned into a param reference
// TODO(kevmoo): <a>test_lib.C</a> should be <a>root_lib.C</a> - Issues 18352
final _TEST_TYPEDEF_COMMENT = _TEST_TYPEDEF_PREVIEW +
'\n<p>To eliminate import'
' warnings for <a>test_lib.A</a> and to test typedefs.</p>\n<p>It\'s '
'important that the <a>dart:core</a>&lt;A> for param listOfA is not '
'empty.</p>';

View file

@ -1,54 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library docgen.test.util;
import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as p;
import 'package:scheduled_test/descriptor.dart' as d;
import 'package:scheduled_test/scheduled_test.dart';
void scheduleTempDir() {
var tempDir;
schedule(() {
return Directory.systemTemp
.createTemp('docgen_test-')
.then((dir) {
tempDir = dir;
d.defaultRoot = tempDir.path;
});
});
currentSchedule.onComplete.schedule(() {
d.defaultRoot = null;
return tempDir.delete(recursive: true);
});
}
String getMultiLibraryCodePath() {
var currentScript = p.fromUri(Platform.script);
var codeDir = p.join(p.dirname(currentScript), 'multi_library_code');
assert(FileSystemEntity.isDirectorySync(codeDir));
return codeDir;
}
final Matcher hasSortedLines = predicate((String input) {
var lines = new LineSplitter().convert(input);
var sortedLines = new List.from(lines)..sort();
var orderedMatcher = orderedEquals(sortedLines);
return orderedMatcher.matches(lines, {});
}, 'String has sorted lines');
final Matcher isJsonMap = predicate((input) {
try {
return JSON.decode(input) is Map;
} catch (e) {
return false;
}
}, 'Output is JSON encoded Map');

View file

@ -1,36 +0,0 @@
#!/bin/bash
# Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
function follow_links() {
file="$1"
while [ -h "$file" ]; do
# On Mac OS, readlink -f doesn't work.
file="$(readlink "$file")"
done
echo "$file"
}
# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
PROG_NAME="$(follow_links "$BASH_SOURCE")"
# Handle the case where dart-sdk/bin has been symlinked to.
BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
unset SNAPSHOT
SNAPSHOT="$BIN_DIR/snapshots/utils_wrapper.dart.snapshot"
if test -f "$SNAPSHOT"; then
exec "$BIN_DIR"/dart \
"--package-root=$BIN_DIR/../packages/" "--old_gen_heap_size=1024" \
"$SNAPSHOT" \
docgen "--sdk=$SDK_DIR" "$@"
else
exec "$BIN_DIR"/dart \
"--package-root=$BIN_DIR/../packages/" "--old_gen_heap_size=1024" \
"$BIN_DIR/../../pkg/docgen/bin/docgen.dart" "--sdk=$SDK_DIR" "$@"
fi

View file

@ -1,49 +0,0 @@
@echo off
REM Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
REM for details. All rights reserved. Use of this source code is governed by a
REM BSD-style license that can be found in the LICENSE file.
setlocal
rem Handle the case where dart-sdk/bin has been symlinked to.
set DIR_NAME_WITH_SLASH=%~dp0
set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%%
call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR
rem Get rid of surrounding quotes.
for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi
rem Get absolute full name for SDK_DIR.
for %%i in ("%BIN_DIR%\..\") do set SDK_DIR=%%~fi
rem Remove trailing backslash if there is one
IF %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1%
set DOCGEN=%SDK_DIR%\pkg\docgen\bin\docgen.dart
set DART=%BIN_DIR%\dart
set SNAPSHOT=%BIN_DIR%\snapshots\utils_wrapper.dart.snapshot
if not defined DART_CONFIGURATION set DART_CONFIGURATION=ReleaseIA32
set BUILD_DIR=%SDK_DIR%\..\build\%DART_CONFIGURATION%
if exist "%SNAPSHOT%" (
"%DART%" "%SNAPSHOT%" "docgen" "--sdk=%SDK_DIR%" %*
) else (
"%BUILD_DIR%\dart-sdk\bin\dart" "--package-root=%BUILD_DIR%\packages" "%DOCGEN%" "--sdk=%SDK_DIR%" %*
)
endlocal
exit /b %errorlevel%
:follow_links
setlocal
for %%i in (%1) do set result=%%~fi
set current=
for /f "tokens=2 delims=[]" %%i in ('dir /a:l ^"%~dp1^" 2^>nul ^
^| find "> %~n1 ["') do (
set current=%%i
)
if not "%current%"=="" call :follow_links "%current%", result
endlocal & set %~2=%result%
goto :eof
:end

View file

@ -36,7 +36,6 @@
'create_snapshot.dart',
'--output_dir=<(SHARED_INTERMEDIATE_DIR)',
'--dart2js_main=pkg/compiler/lib/src/dart2js.dart',
'--docgen_main=pkg/docgen/bin/docgen.dart',
'--package_root=<(PRODUCT_DIR)/packages/',
],
},

View file

@ -18,12 +18,10 @@ Future<String> getVersion(var rootPath) {
Future<String> getSnapshotGenerationFile(var args, var rootPath) {
var dart2js = rootPath.resolve(args["dart2js_main"]);
var docgen = rootPath.resolve(args["docgen_main"]);
return getVersion(rootPath).then((version) {
var snapshotGenerationText =
"""
import '${dart2js.toFilePath(windows: false)}' as dart2jsMain;
import '${docgen.toFilePath(windows: false)}' as docgenMain;
import 'dart:io';
void main(List<String> arguments) {
@ -32,8 +30,6 @@ void main(List<String> arguments) {
if (tool == "dart2js") {
dart2jsMain.BUILD_ID = "$version";
dart2jsMain.main(arguments.skip(1).toList());
} else if (tool == "docgen") {
docgenMain.main(arguments.skip(1).toList());
}
}
@ -84,12 +80,11 @@ Future createSnapshot(var dart_file, var packageRoot) {
* Takes the following arguments:
* --output_dir=val The full path to the output_dir.
* --dart2js_main=val The path to the dart2js main script relative to root.
* --docgen_main=val The path to the docgen main script relative to root.
* --package-root=val The package-root used to find packages for the snapshot.
*/
void main(List<String> arguments) {
var validArguments = ["--output_dir", "--dart2js_main",
"--docgen_main", "--package_root"];
"--package_root"];
var args = {};
for (var argument in arguments) {
var argumentSplit = argument.split("=");
@ -100,7 +95,6 @@ void main(List<String> arguments) {
args[argumentSplit[0].substring(2)] = argumentSplit[1];
}
if (!args.containsKey("dart2js_main")) throw "Please specify dart2js_main";
if (!args.containsKey("docgen_main")) throw "Please specify docgen_main";
if (!args.containsKey("output_dir")) throw "Please specify output_dir";
if (!args.containsKey("package_root")) throw "Please specify package_root";