mirror of
https://github.com/dart-lang/sdk
synced 2024-10-04 19:18:27 +00:00
remove docgen source and targets from build
BUG= R=alanknight@google.com Review URL: https://codereview.chromium.org//1364553002 .
This commit is contained in:
parent
5612c202a0
commit
c775149a5a
|
@ -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.
|
|
@ -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"
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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';
|
|
@ -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';
|
|
@ -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';
|
|
@ -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;
|
|
@ -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).
|
||||
""";
|
|
@ -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;
|
||||
}
|
|
@ -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<_bar_>] will produce
|
||||
/// <a>resolvedFoo</a><<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 " ", ",", "<"
|
||||
/// 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 = '<';
|
|
@ -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>';
|
||||
}
|
|
@ -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';
|
|
@ -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
|
||||
};
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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),
|
||||
};
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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)
|
||||
};
|
||||
}
|
|
@ -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)];
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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";
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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'));
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -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'
|
|
@ -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));
|
||||
});
|
||||
});
|
||||
}
|
|
@ -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"
|
||||
];
|
|
@ -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":""';
|
|
@ -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";
|
|
@ -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));
|
||||
});
|
||||
});
|
||||
}
|
|
@ -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());
|
||||
});
|
||||
});
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
library internal_lib;
|
||||
|
||||
part 'src_lib_part.dart';
|
||||
|
||||
class InternalLibClass {}
|
|
@ -1,3 +0,0 @@
|
|||
part of internal_lib;
|
||||
|
||||
class InternalLibPart {}
|
|
@ -1,5 +0,0 @@
|
|||
library sub_lib;
|
||||
|
||||
part 'sub_lib_part.dart';
|
||||
|
||||
class SubLibClass {}
|
|
@ -1,3 +0,0 @@
|
|||
part of sub_lib;
|
||||
|
||||
class SubLibPart {}
|
|
@ -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;
|
||||
}
|
|
@ -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';
|
|
@ -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 {
|
||||
|
||||
}
|
|
@ -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');
|
||||
}
|
|
@ -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);
|
|
@ -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;
|
||||
}
|
|
@ -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'));
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
}
|
|
@ -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));
|
||||
});
|
||||
});
|
||||
}
|
|
@ -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();
|
||||
|
||||
});
|
||||
}
|
|
@ -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));
|
||||
});
|
||||
});
|
||||
}
|
|
@ -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><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><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><A> for param listOfA is not '
|
||||
'empty.</p>';
|
|
@ -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');
|
|
@ -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
|
|
@ -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
|
|
@ -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/',
|
||||
],
|
||||
},
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
Loading…
Reference in a new issue