remove docgen remnants from repo, update CHANGELOG

BUG=
R=alanknight@google.com, whesse@google.com

Review URL: https://codereview.chromium.org//1361163002 .
This commit is contained in:
keertip 2015-09-23 10:27:15 -07:00
parent 5fd8b38737
commit 18b68f7290
28 changed files with 6 additions and 3410 deletions

View file

@ -16,6 +16,11 @@
callback now forward stack traces along with errors to the resulting
streams.
### Tool changes
* `docgen` and 'dartdocgen' no longer ship in the sdk. The `docgen` sources have
been removed from the repository.
## 1.12.0
### Language changes

View file

@ -14,9 +14,6 @@
# Analyzer2dart is not maintained anymore.
analyzer2dart/test/*: Skip
[ $compiler != dartanalyzer && $compiler != dart2analyzer ]
docgen/test/inherited_comments_test: Fail # issue 22233
[ $compiler == none && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
mutation_observer: Skip # Issue 21149
unittest/*: Skip # Issue 21949
@ -31,7 +28,6 @@ analysis_server/test/integration/*: SkipSlow # Times out
analysis_server/tool/spec/check_all_test: SkipSlow # Times out
analyzer/test/generated/element_test: SkipSlow # Times out
analyzer/test/generated/parser_test: SkipSlow # Times out
docgen/test/*: SkipSlow
[ $runtime == vm && $system == windows]
analysis_server/test/analysis/get_errors_test: Skip # runtime error, Issue 22180
@ -43,7 +39,6 @@ collection/test/equality_test/03: Fail # Issue 1533
collection/test/equality_test/04: Fail # Issue 1533
collection/test/equality_test/05: Fail # Issue 1533
collection/test/equality_test/none: Pass, Fail # Issue 14348
docgen/test/*: SkipSlow # Far too slow
typed_data/test/typed_buffers_test/01: Fail # Not supporting Int64List, Uint64List.
analyzer/test/generated/engine_test: SkipSlow
analyzer/test/generated/static_type_warning_code_test: Pass, Slow
@ -149,7 +144,6 @@ analysis_server/test/*: SkipByDesign # Uses dart:io.
analysis_server/tool/spec/check_all_test: SkipByDesign # Uses dart:io.
analyzer/test/*: SkipByDesign # Uses dart:io.
analyzer2dart/*: SkipByDesign # Uses dart:io.
docgen/test/*: SkipByDesign # Uses dart:io.
http_server/test/*: Fail, OK # Uses dart:io.
observe/test/transformer_test: Fail, OK # Uses dart:io.
observe/test/unique_message_test: SkipByDesign # Uses dart:io.

View file

@ -4,7 +4,6 @@
samples/third_party/dromaeo: Pass, Slow
samples/searchable_list: Pass, Slow
pkg/docgen: Pass, Slow
[ $use_repository_packages ]
pkg/analyzer: PubGetError

View file

@ -1,7 +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.
echo "The 'docgen' name is deprecated. Prefer 'dartdocgen' instead."
dartdocgen "$@"

View file

@ -1,7 +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.
echo "The 'docgen.bat' name is deprecated. Prefer 'dartdocgen.bat' instead."
dartdocgen %*

View file

@ -169,7 +169,7 @@ class Dart < Formula
def install
libexec.install Dir['*']
bin.install_symlink "#{libexec}/bin/dart"
bin.write_exec_script Dir["#{libexec}/bin/{pub,docgen,dart?*}"]
bin.write_exec_script Dir["#{libexec}/bin/{pub,dart?*}"]
if build.with? 'dartium'
dartium_binary = 'Chromium.app/Contents/MacOS/Chromium'

View file

@ -1,22 +0,0 @@
/Makefile
/out
/runtime
/xcodebuild
/*.Makefile
/*.sln
/*.target.mk
/*.vcproj
/*.vcxproj
/*.vcxproj.filters
/*.vcxproj.user
/*.xcodeproj
/Debug
/DebugARM
/DebugIA32
/DebugSIMARM
/DebugX64
/Release
/ReleaseARM
/ReleaseIA32
/ReleaseSIMARM
/ReleaseX64

View file

@ -1,86 +0,0 @@
Apidoc is a specialization of Dartdoc.
Dartdoc generates static HTML documentation from Dart code.
Apidoc wraps the dartdoc output with official dartlang.org skin, comments, etc.
To use it, from the top level dart directory, run:
$ dart utils/apidoc/apidoc.dart [--out=<output directory>]
This will create a "docs" directory with the docs for your libraries.
How docs are generated
----------------------
To make beautiful docs from your library, dartdoc parses it and every library it
imports (recursively). From each library, it parses all classes and members,
finds the associated doc comments and builds crosslinked docs from them.
"Doc comments" can be in one of a few forms:
/**
* JavaDoc style block comments.
*/
/** Which can also be single line. */
/// Triple-slash line comments.
/// Which can be multiple lines.
The body of a doc comment will be parsed as markdown which means you can apply
most of the formatting and structuring you want while still having docs that
look nice in plain text. For example:
/// This is a doc comment. This is the first paragraph in the comment. It
/// can span multiple lines.
///
/// A blank line starts a new paragraph like this one.
///
/// * Unordered lists start with `*` or `-` or `+`.
/// * And can have multiple items.
/// 1. You can nest lists.
/// 2. Like this numbered one.
///
/// ---
///
/// Three dashes, underscores, or tildes on a line by themselves create a
/// horizontal rule.
///
/// to.get(a.block + of.code) {
/// indent(it, 4.lines);
/// like(this);
/// }
///
/// There are a few inline styles you can apply: *emphasis*, **strong**,
/// and `inline code`. You can also use underscores for _emphasis_ and
/// __strong__.
///
/// An H1 header using equals on the next line
/// ==========================================
///
/// And an H2 in that style using hyphens
/// -------------------------------------
///
/// # Or an H1 - H6 using leading hashes
/// ## H2
/// ### H3
/// #### H4 you can also have hashes at then end: ###
/// ##### H5
/// ###### H6
There is also an extension to markdown specific to dartdoc: A name inside
square brackets that is not a markdown link (i.e. doesn't have square brackets
or parentheses following it) like:
Calls [someMethod], passing in [arg].
is understood to be the name of some member or type that's in the scope of the
member where that comment appears. Dartdoc will automatically figure out what
the name refers to and generate an approriate link to that member or type.
Attribution
-----------
dartdoc uses the delightful Silk icon set by Mark James.
http://www.famfamfam.com/lab/icons/silk/

View file

@ -1,477 +0,0 @@
// Copyright (c) 2012, 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 generates the reference documentation for the core libraries that come
* with dart. It is built on top of dartdoc, which is a general-purpose library
* for generating docs from any Dart code. This library extends that to include
* additional information and styling specific to our standard library.
*
* Usage:
*
* $ dart apidoc.dart [--out=<output directory>]
*/
library apidoc;
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'html_diff.dart';
import 'package:compiler/src/mirrors/source_mirrors.dart';
import 'package:compiler/src/mirrors/mirrors_util.dart';
import 'package:compiler/src/filenames.dart';
import 'package:dartdoc/dartdoc.dart';
import 'package:sdk_library_metadata/libraries.dart';
import 'package:path/path.dart' as path;
HtmlDiff _diff;
void main(List<String> args) {
int mode = MODE_STATIC;
String outputDir = 'docs';
bool generateAppCache = false;
List<String> excludedLibraries = <String>[];
// For libraries that have names matching the package name,
// such as library unittest in package unittest, we just give
// the package name with a --include-lib argument, such as:
// --include-lib=unittest. These arguments are collected in
// includedLibraries.
List<String> includedLibraries = <String>[];
// For libraries that lie within packages but have a different name,
// such as the matcher library in package unittest, we can use
// --extra-lib with a full relative path under pkg, such as
// --extra-lib=unittest/lib/matcher.dart. These arguments are
// collected in extraLibraries.
List<String> extraLibraries = <String>[];
String packageRoot;
String version;
// Parse the command-line arguments.
for (int i = 0; i < args.length; i++) {
final arg = args[i];
switch (arg) {
case '--mode=static':
mode = MODE_STATIC;
break;
case '--mode=live-nav':
mode = MODE_LIVE_NAV;
break;
case '--generate-app-cache=true':
generateAppCache = true;
break;
default:
if (arg.startsWith('--exclude-lib=')) {
excludedLibraries.add(arg.substring('--exclude-lib='.length));
} else if (arg.startsWith('--include-lib=')) {
includedLibraries.add(arg.substring('--include-lib='.length));
} else if (arg.startsWith('--extra-lib=')) {
extraLibraries.add(arg.substring('--extra-lib='.length));
} else if (arg.startsWith('--out=')) {
outputDir = arg.substring('--out='.length);
} else if (arg.startsWith('--package-root=')) {
packageRoot = arg.substring('--package-root='.length);
} else if (arg.startsWith('--version=')) {
version = arg.substring('--version='.length);
} else {
print('Unknown option: $arg');
return;
}
break;
}
}
final libPath = path.join(scriptDir, '..', '..', 'sdk/');
cleanOutputDirectory(outputDir);
print('Copying static files...');
// The basic dartdoc-provided static content.
final copiedStatic = copyDirectory(
path.join(scriptDir,
'..', '..', 'sdk', 'lib', '_internal', 'dartdoc', 'static'),
outputDir);
// The apidoc-specific static content.
final copiedApiDocStatic = copyDirectory(
path.join(scriptDir, 'static'),
outputDir);
print('Parsing MDN data...');
final mdnFile = new File(path.join(scriptDir, 'mdn', 'database.json'));
final mdn = JSON.decode(mdnFile.readAsStringSync());
print('Cross-referencing dart:html...');
// TODO(amouravski): move HtmlDiff inside of the future chain below to re-use
// the MirrorSystem already analyzed.
_diff = new HtmlDiff(printWarnings:false);
Future htmlDiff = _diff.run(currentDirectory.resolveUri(path.toUri(libPath)));
// TODO(johnniwinther): Libraries for the compilation seem to be more like
// URIs. Perhaps Path should have a toURI() method.
// Add all of the core libraries.
final apidocLibraries = <Uri>[];
LIBRARIES.forEach((String name, LibraryInfo info) {
if (info.documented) {
apidocLibraries.add(Uri.parse('dart:$name'));
}
});
// TODO(amouravski): This code is really wonky.
var lister = new Directory(path.join(scriptDir, '..', '..', 'pkg')).list();
lister.listen((entity) {
if (entity is Directory) {
var libName = path.basename(entity.path);
var libPath = path.join(entity.path, 'lib', '${libName}.dart');
// Ignore some libraries.
if (excludedLibraries.contains(libName)) {
return;
}
// Ignore hidden directories (like .svn) as well as pkg.xcodeproj.
if (libName.startsWith('.') || libName.endsWith('.xcodeproj')) {
return;
}
if (new File(libPath).existsSync()) {
apidocLibraries.add(path.toUri(libPath));
includedLibraries.add(libName);
} else {
print('Warning: could not find package at ${entity.path}');
}
}
}, onDone: () {
// Add any --extra libraries that had full pkg paths.
// TODO(gram): if the handling of --include-lib libraries in the
// listen() block above is cleaned up, then this will need to be
// too, as it is a special case of the above.
for (var lib in extraLibraries) {
var libPath = '../../$lib';
if (new File(libPath).existsSync()) {
apidocLibraries.add(path.toUri(libPath));
var libName = path.basename(libPath).replaceAll('.dart', '');
includedLibraries.add(libName);
}
}
final apidoc = new Apidoc(mdn, outputDir, mode, generateAppCache,
excludedLibraries, version);
apidoc.dartdocPath =
path.join(scriptDir, '..', '..', 'sdk', 'lib', '_internal', 'dartdoc');
// Select the libraries to include in the produced documentation:
apidoc.includeApi = true;
apidoc.includedLibraries = includedLibraries;
// TODO(amouravski): make apidoc use roughly the same flow as bin/dartdoc.
Future.wait([copiedStatic, copiedApiDocStatic, htmlDiff])
.then((_) => apidoc.documentLibraries(apidocLibraries, libPath,
packageRoot))
.then((_) => compileScript(mode, outputDir, libPath, apidoc.tmpPath))
.then((_) => print(apidoc.status))
.catchError((e, trace) {
print('Error: generation failed: ${e}');
if (trace != null) print("StackTrace: $trace");
apidoc.cleanup();
exit(1);
})
.whenComplete(() => apidoc.cleanup());
});
}
class Apidoc extends Dartdoc {
/** Big ball of JSON containing the scraped MDN documentation. */
final Map mdn;
// A set of type names (TypeMirror.simpleName values) to ignore while
// looking up information from MDN data. TODO(eub, jacobr): fix up the MDN
// import scripts so they run correctly and generate data that doesn't have
// any entries that need to be ignored.
static Set<String> _mdnTypeNamesToSkip = null;
/**
* The URL to the page on MDN that content was pulled from for the current
* type being documented. Will be `null` if the type doesn't use any MDN
* content.
*/
String mdnUrl = null;
Apidoc(this.mdn, String outputDir, int mode, bool generateAppCache,
[List<String> excludedLibraries, String version]) {
if (excludedLibraries != null) this.excludedLibraries = excludedLibraries;
this.version = version;
this.outputDir = outputDir;
this.mode = mode;
this.generateAppCache = generateAppCache;
// Skip bad entries in the checked-in mdn/database.json:
// * UnknownElement has a top-level Gecko DOM page in German.
if (_mdnTypeNamesToSkip == null)
_mdnTypeNamesToSkip = new Set.from(['UnknownElement']);
mainTitle = 'Dart API Reference';
mainUrl = 'http://dartlang.org';
final note = 'http://code.google.com/policies.html#restrictions';
final cca = 'http://creativecommons.org/licenses/by/3.0/';
final bsd = 'http://code.google.com/google_bsd_license.html';
final tos = 'http://www.dartlang.org/tos.html';
final privacy = 'http://www.google.com/intl/en/privacy/privacy-policy.html';
footerText =
'''
<p>Except as otherwise <a href="$note">noted</a>, the content of this
page is licensed under the <a href="$cca">Creative Commons Attribution
3.0 License</a>, and code samples are licensed under the
<a href="$bsd">BSD License</a>.</p>
<p><a href="$tos">Terms of Service</a> |
<a href="$privacy">Privacy Policy</a></p>
''';
searchEngineId = '011220921317074318178:i4mscbaxtru';
searchResultsUrl = 'http://www.dartlang.org/search.html';
}
void writeHeadContents(String title) {
super.writeHeadContents(title);
// Include the apidoc-specific CSS.
// TODO(rnystrom): Use our CSS pre-processor to combine these.
writeln(
'''
<link rel="stylesheet" type="text/css"
href="${relativePath('apidoc-styles.css')}" />
''');
// Add the analytics code.
writeln(
'''
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(["_setAccount", "UA-26406144-9"]);
_gaq.push(["_trackPageview"]);
(function() {
var ga = document.createElement("script");
ga.type = "text/javascript"; ga.async = true;
ga.src = ("https:" == document.location.protocol ?
"https://ssl" : "http://www") + ".google-analytics.com/ga.js";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(ga, s);
})();
</script>
''');
}
void docIndexLibrary(LibraryMirror library) {
// TODO(rnystrom): Hackish. The IO libraries reference this but we don't
// want it in the docs.
if (displayName(library) == 'dart:nativewrappers') return;
super.docIndexLibrary(library);
}
void docLibraryNavigationJson(LibraryMirror library, List libraryList) {
// TODO(rnystrom): Hackish. The IO libraries reference this but we don't
// want it in the docs.
if (displayName(library) == 'dart:nativewrappers') return;
super.docLibraryNavigationJson(library, libraryList);
}
void docLibrary(LibraryMirror library) {
// TODO(rnystrom): Hackish. The IO libraries reference this but we don't
// want it in the docs.
if (displayName(library) == 'dart:nativewrappers') return;
super.docLibrary(library);
}
DocComment getLibraryComment(LibraryMirror library) {
return super.getLibraryComment(library);
}
DocComment getTypeComment(TypeMirror type) {
return _mergeDocs(
includeMdnTypeComment(type), super.getTypeComment(type));
}
DocComment getMemberComment(DeclarationMirror member) {
return _mergeDocs(
includeMdnMemberComment(member), super.getMemberComment(member));
}
DocComment _mergeDocs(MdnComment mdnComment,
DocComment fileComment) {
// Otherwise, prefer comment from the (possibly generated) Dart file.
if (fileComment != null) return fileComment;
// Finally, fallback on MDN if available.
if (mdnComment != null) {
mdnUrl = mdnComment.mdnUrl;
return mdnComment;
}
// We got nothing!
return null;
}
void docType(TypeMirror type) {
// Track whether we've inserted MDN content into this page.
mdnUrl = null;
super.docType(type);
}
void writeTypeFooter() {
if (mdnUrl != null) {
final MOZ = 'http://www.mozilla.org/';
final MDN = 'https://developer.mozilla.org';
final CCA = 'http://creativecommons.org/licenses/by-sa/2.5/';
final CONTRIB = 'https://developer.mozilla.org/Project:en/How_to_Help';
writeln(
'''
<p class="mdn-attribution">
<a href="$MDN">
<img src="${relativePath('mdn-logo-tiny.png')}" class="mdn-logo" />
</a>
This page includes <a href="$mdnUrl">content</a> from the
<a href="$MOZ">Mozilla Foundation</a> that is graciously
<a href="$MDN/Project:Copyrights">licensed</a> under a
<a href="$CCA">Creative Commons: Attribution-Sharealike license</a>.
Mozilla has no other association with Dart or dartlang.org. We
encourage you to improve the web by
<a href="$CONTRIB">contributing</a> to
<a href="$MDN">The Mozilla Developer Network</a>.
</p>
''');
}
}
MdnComment lookupMdnComment(Mirror mirror) {
if (mirror is TypeMirror) {
return includeMdnTypeComment(mirror);
} else if (mirror is MethodMirror || mirror is VariableMirror) {
return includeMdnMemberComment(mirror);
} else {
return null;
}
}
/**
* Gets the MDN-scraped docs for [type], or `null` if this type isn't
* scraped from MDN.
*/
MdnComment includeMdnTypeComment(TypeMirror type) {
if (_mdnTypeNamesToSkip.contains(type.simpleName)) {
return null;
}
var typeString = '';
if (HTML_LIBRARY_URIS.contains(getLibrary(type).uri)) {
// If it's an HTML type, try to map it to a base DOM type so we can find
// the MDN docs.
final domTypes = _diff.htmlTypesToDom[type.qualifiedName];
// Couldn't find a DOM type.
if ((domTypes == null) || (domTypes.length != 1)) return null;
// Use the corresponding DOM type when searching MDN.
// TODO(rnystrom): Shame there isn't a simpler way to get the one item
// out of a singleton Set.
// TODO(floitsch): switch to domTypes.first, once that's implemented.
var iter = domTypes.iterator;
iter.moveNext();
typeString = iter.current;
} else {
// Not a DOM type.
return null;
}
final mdnType = mdn[typeString];
if (mdnType == null) return null;
if (mdnType['skipped'] != null) return null;
if (mdnType['summary'] == null) return null;
if (mdnType['summary'].trim().isEmpty) return null;
// Remember which MDN page we're using so we can attribute it.
return new MdnComment(mdnType['summary'], mdnType['srcUrl']);
}
/**
* Gets the MDN-scraped docs for [member], or `null` if this type isn't
* scraped from MDN.
*/
MdnComment includeMdnMemberComment(DeclarationMirror member) {
var library = getLibrary(member);
var memberString = '';
if (HTML_LIBRARY_URIS.contains(library.uri)) {
// If it's an HTML type, try to map it to a DOM type name so we can find
// the MDN docs.
final domMembers = _diff.htmlToDom[member.qualifiedName];
// Couldn't find a DOM type.
if ((domMembers == null) || (domMembers.length != 1)) return null;
// Use the corresponding DOM member when searching MDN.
// TODO(rnystrom): Shame there isn't a simpler way to get the one item
// out of a singleton Set.
// TODO(floitsch): switch to domTypes.first, once that's implemented.
var iter = domMembers.iterator;
iter.moveNext();
memberString = iter.current;
} else {
// Not a DOM type.
return null;
}
// Ignore top-level functions.
if (member.isTopLevel) return null;
var mdnMember = null;
var mdnType = null;
var pieces = memberString.split('.');
if (pieces.length == 2) {
mdnType = mdn[pieces[0]];
if (mdnType == null) return null;
var nameToFind = pieces[1];
for (final candidateMember in mdnType['members']) {
if (candidateMember['name'] == nameToFind) {
mdnMember = candidateMember;
break;
}
}
}
if (mdnMember == null) return null;
if (mdnMember['help'] == null) return null;
if (mdnMember['help'].trim().isEmpty) return null;
// Remember which MDN page we're using so we can attribute it.
return new MdnComment(mdnMember['help'], mdnType['srcUrl']);
}
/**
* Returns a link to [member], relative to a type page that may be in a
* different library than [member].
*/
String _linkMember(DeclarationMirror member) {
final typeName = member.owner.simpleName;
var memberName = '$typeName.${member.simpleName}';
if (member is MethodMirror && member.isConstructor) {
final separator = member.constructorName == '' ? '' : '.';
memberName = 'new $typeName$separator${member.constructorName}';
}
return a(memberUrl(member), memberName);
}
}

View file

@ -1,102 +0,0 @@
# Copyright (c) 2012, 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.
{
'variables' : {
'script_suffix%': '',
},
'conditions' : [
['OS=="win"', {
'variables' : {
'script_suffix': '.bat',
},
}],
],
'targets': [
{
'target_name': 'dartdocgen',
'type': 'none',
'dependencies': [
'../../create_sdk.gyp:create_sdk_internal',
'../../pkg/pkg.gyp:pkg_packages',
'../../pkg/pkg_files.gyp:pkg_files_stamp',
],
'includes': [
'../../sdk/lib/core/core_sources.gypi',
],
'actions': [
{
'action_name': 'run_docgen',
# The 'inputs' list records the files whose timestamps are
# compared to the files listed in 'outputs'. If a file
# 'outputs' doesn't exist or if a file in 'inputs' is newer
# than a file in 'outputs', this action is executed. Notice
# that the dependencies listed above has nothing to do with
# when this action is executed. You must list a file in
# 'inputs' to make sure that it exists before the action is
# executed, or to make sure this action is re-run.
#
# We want to build the platform documentation whenever
# dartdoc, apidoc, or its dependency changes. This prevents
# people from accidentally breaking apidoc when making
# changes to the platform libraries and or when modifying
# dart2js or the VM.
#
# In addition, we want to make sure that the platform
# documentation is regenerated when the platform sources
# changes.
#
# So we want this action to be re-run when a dart file
# changes in this directory, or in the SDK library (we may
# no longer need to list the files in ../../runtime/lib and
# ../../runtime/bin, as most of them has moved to
# ../../sdk/lib).
#
'inputs': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
'<(SHARED_INTERMEDIATE_DIR)/utils_wrapper.dart.snapshot',
'<!@(["python", "../../tools/list_files.py", "\\.(css|ico|js|json|png|sh|txt|yaml|py)$", ".", "../../sdk/lib/_internal/dartdoc"])',
# We implicitly depend on the sdk/lib and vm runtime files by depending on the dart binary above.
'<!@(["python", "../../tools/list_files.py", "\\.dart$", "."])',
'../../sdk/bin/dart',
'../../sdk/bin/dart.bat',
'../../sdk/bin/dart2js',
'../../sdk/bin/dart2js.bat',
# TODO(alanknight): The docgen name is deprecated in favour of
# dartdocgen, and should be removed eventually.
'../../sdk/bin/docgen',
'../../sdk/bin/dartdocgen',
'../../sdk/bin/docgen.bat',
'../../sdk/bin/dartdocgen.bat',
'../../tools/only_in_release_mode.py',
'<(PRODUCT_DIR)/dart-sdk/README',
'<(SHARED_INTERMEDIATE_DIR)/pkg_files.stamp',
],
'outputs': [
'<(PRODUCT_DIR)/api_docs/docgen/index.json',
],
'action': [
'python',
'../../tools/only_in_release_mode.py',
'<@(_outputs)',
'--',
'<(PRODUCT_DIR)/dart-sdk/bin/dartdocgen<(script_suffix)',
'--out=<(PRODUCT_DIR)/api_docs/docgen',
'--include-sdk',
'--no-include-dependent-packages',
'--package-root=<(PRODUCT_DIR)/packages',
'--exclude-lib=async_helper',
'--exclude-lib=compiler',
'--exclude-lib=dart2js_incremental',
'--exclude-lib=docgen',
'--exclude-lib=expect',
'--exclude-lib=try',
'../../pkg'
],
'message': 'Running dartdocgen: <(_action)',
},
],
}
],
}

View file

@ -1,231 +0,0 @@
// Copyright (c) 2012, 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.
/**
* A script to assist in documenting the difference between the dart:html API
* and the old DOM API.
*/
library html_diff;
import 'dart:async';
import 'lib/metadata.dart';
// TODO(rnystrom): Use "package:" URL (#4968).
import '../../pkg/compiler/lib/src/mirrors/analyze.dart';
import '../../pkg/compiler/lib/src/mirrors/source_mirrors.dart';
import '../../pkg/compiler/lib/src/mirrors/mirrors_util.dart';
import '../../pkg/compiler/lib/src/source_file_provider.dart';
// TODO(amouravski): There is currently magic that looks at dart:* libraries
// rather than the declared library names. This changed due to recent syntax
// changes. We should only need to look at the library 'html'.
final List<Uri> HTML_LIBRARY_URIS = [
new Uri(scheme: 'dart', path: 'html'),
new Uri(scheme: 'dart', path: 'indexed_db'),
new Uri(scheme: 'dart', path: 'svg'),
new Uri(scheme: 'dart', path: 'web_audio')];
/**
* A class for computing a many-to-many mapping between the types and
* members in `dart:html` and the MDN DOM types. This mapping is
* based on two indicators:
*
* 1. Auto-detected wrappers. Most `dart:html` types correspond
* straightforwardly to a single `@DomName` type, and
* have the same name. In addition, most `dart:html` methods
* just call a single `@DomName` method. This class
* detects these simple correspondences automatically.
*
* 2. Manual annotations. When it's not clear which
* `@DomName` items a given `dart:html` item
* corresponds to, the `dart:html` item can be annotated in the
* documentation comments using the `@DomName` annotation.
*
* The `@DomName` annotations for types and members are of the form
* `@DomName NAME(, NAME)*`, where the `NAME`s refer to the
* `@DomName` types/members that correspond to the
* annotated `dart:html` type/member. `NAME`s on member annotations
* can refer to either fully-qualified member names (e.g.
* `Document.createElement`) or unqualified member names
* (e.g. `createElement`). Unqualified member names are assumed to
* refer to members of one of the corresponding `@DomName`
* types.
*/
class HtmlDiff {
/**
* A map from `dart:html` members to the corresponding fully qualified
* `@DomName` member(s).
*/
final Map<String, Set<String>> htmlToDom;
/** A map from `dart:html` types to corresponding `@DomName` types. */
final Map<String, Set<String>> htmlTypesToDom;
/** If true, then print warning messages. */
final bool _printWarnings;
static LibraryMirror dom;
HtmlDiff({bool printWarnings: false}) :
_printWarnings = printWarnings,
htmlToDom = new Map<String, Set<String>>(),
htmlTypesToDom = new Map<String, Set<String>>();
void warn(String s) {
if (_printWarnings) {
print('Warning: $s');
}
}
/**
* Computes the `@DomName` to `dart:html` mapping, and
* places it in [htmlToDom] and [htmlTypesToDom]. Before this is run, dart2js
* should be initialized (via [parseOptions] and [initializeWorld]) and
* [HtmlDiff.initialize] should be called.
*/
Future run(Uri libraryRoot) {
var result = new Completer();
var provider = new CompilerSourceFileProvider();
var handler = new FormattingDiagnosticHandler(provider);
Future<MirrorSystem> analysis = analyze(
HTML_LIBRARY_URIS, libraryRoot, null,
provider.readStringFromUri,
handler.diagnosticHandler);
analysis.then((MirrorSystem mirrors) {
for (var libraryUri in HTML_LIBRARY_URIS) {
var library = mirrors.libraries[libraryUri];
if (library == null) {
warn('Could not find $libraryUri');
result.complete(false);
}
for (ClassMirror type in classesOf(library.declarations)) {
final domTypes = htmlToDomTypes(type);
if (domTypes.isEmpty) continue;
htmlTypesToDom.putIfAbsent(qualifiedNameOf(type),
() => new Set()).addAll(domTypes);
membersOf(type.declarations).forEach(
(m) => _addMemberDiff(m, domTypes, nameOf(library)));
}
}
result.complete(true);
});
return result.future;
}
/**
* Records the `@DomName` to `dart:html` mapping for
* [htmlMember] (from `dart:html`). [domTypes] are the
* `@DomName` type values that correspond to [htmlMember]'s
* defining type.
*/
void _addMemberDiff(DeclarationMirror htmlMember, List<String> domTypes,
String libraryName) {
var domMembers = htmlToDomMembers(htmlMember, domTypes);
if (htmlMember == null && !domMembers.isEmpty) {
warn('$libraryName member '
'${htmlMember.owner.simpleName}.'
'${htmlMember.simpleName} has no corresponding '
'$libraryName member.');
}
if (htmlMember == null) return;
if (!domMembers.isEmpty) {
htmlToDom[qualifiedNameOf(htmlMember)] = domMembers;
}
}
/**
* Returns the `@DomName` type values that correspond to
* [htmlType] from `dart:html`. This can be the empty list if no
* correspondence is found.
*/
List<String> htmlToDomTypes(ClassMirror htmlType) {
if (htmlType.simpleName == null) return <String>[];
final domNameMetadata = findMetadata(htmlType.metadata, 'DomName');
if (domNameMetadata != null) {
var domNames = <String>[];
var names = domNameMetadata.getField(symbolOf('name'));
for (var s in names.reflectee.split(',')) {
domNames.add(s.trim());
}
if (domNames.length == 1 && domNames[0] == 'none') return <String>[];
return domNames;
}
return <String>[];
}
/**
* Returns the `@DomName` member values that correspond to
* [htmlMember] from `dart:html`. This can be the empty set if no
* correspondence is found. [domTypes] are the
* `@DomName` type values that correspond to [htmlMember]'s
* defining type.
*/
Set<String> htmlToDomMembers(DeclarationMirror htmlMember,
List<String> domTypes) {
if (htmlMember.isPrivate) return new Set();
final domNameMetadata = findMetadata(htmlMember.metadata, 'DomName');
if (domNameMetadata != null) {
var domNames = <String>[];
var names = domNameMetadata.getField(symbolOf('name'));
for (var s in names.reflectee.split(',')) {
domNames.add(s.trim());
}
if (domNames.length == 1 && domNames[0] == 'none') return new Set();
final members = new Set();
domNames.forEach((name) {
var nameMembers = _membersFromName(name, domTypes);
if (nameMembers.isEmpty) {
if (name.contains('.')) {
warn('no member $name');
} else {
final options = <String>[];
for (var t in domTypes) {
options.add('$t.$name');
}
options.join(' or ');
warn('no member $options');
}
}
members.addAll(nameMembers);
});
return members;
}
return new Set();
}
/**
* Returns the `@DomName` strings that are indicated by
* [name]. [name] can be either an unqualified member name
* (e.g. `createElement`), in which case it's treated as the name of
* a member of one of [defaultTypes], or a fully-qualified member
* name (e.g. `Document.createElement`), in which case it's treated as a
* member of the @DomName element (`Document` in this case).
*/
Set<String> _membersFromName(String name, List<String> defaultTypes) {
if (!name.contains('.', 0)) {
if (defaultTypes.isEmpty) {
warn('no default type for $name');
return new Set();
}
final members = new Set<String>();
defaultTypes.forEach((t) { members.add('$t.$name'); });
return members;
}
if (name.split('.').length != 2) {
warn('invalid member name ${name}');
return new Set();
}
return new Set.from([name]);
}
}

View file

@ -1,15 +0,0 @@
library metadata;
import '../../../pkg/compiler/lib/src/mirrors/source_mirrors.dart';
import '../../../pkg/compiler/lib/src/mirrors/mirrors_util.dart';
/// Returns the metadata for the given string or null if not found.
InstanceMirror findMetadata(List<InstanceMirror> metadataList, String find) {
return metadataList.firstWhere(
(metadata) {
if (metadata is TypeInstanceMirror) {
return nameOf(metadata.representedType) == find;
}
return nameOf(metadata.type) == find;
}, orElse: () => null);
}

View file

@ -1,76 +0,0 @@
***** Current status
Currently it runs all the way through, but the database.json has all
members[] lists empty. Most entries are skipped for "Suspect title";
some have ".pageText not found".
Currently only works on Linux; OS X (or other) will need minor path changes.
You will need a reasonably modern node.js installed.
0.5.9 is too old; 0.8.8 is not too old.
I needed to add my own "DumpRenderTree_resources/missingImage.gif",
for some reason.
For the reasons above, we're currently just using the checked-in
database.json from Feb 2012, but it has some bogus entries. In
particular, the one for UnknownElement would inject irrelevant German
text into our docs. So a hack in apidoc.dart (_mdnTypeNamesToSkip)
works around this.
***** Overview
Here's a rough walkthrough of how this works. The ultimate output file is
database.filtered.json.
full_run.sh executes all of the scripts in the correct order.
search.js
- read data/domTypes.json
- for each dom type:
- search for page on www.googleapis.com
- write search results to output/search/<type>.json
. this is a list of search results and urls to pages
crawl.js
- read data/domTypes.json
- for each dom type:
- for each output/search/<type>.json:
- for each result in the file:
- try to scrape that cached MDN page from webcache.googleusercontent.com
- write mdn page to output/crawl/<type><index of result>.html
- write output/crawl/cache.json
. it maps types -> search result page urls and titles
extract.sh
- compile extract.dart to js
- run extractRunner.js
- read data/domTypes.json
- read output/crawl/cache.json
- read data/dartIdl.json
- for each scraped search result page:
- create a cleaned up html page in output/extract/<type><index>.html that
contains the scraped content + a script tag that includes extract.dart.js.
- create an args file in output/extract/<type><index>.html.json with some
data on how that file should be processed
- invoke dump render tree on that file
- when that returns, parse the console output and add it to database.json
- add any errors to output/errors.json
- save output/database.json
extract.dart
- xhr output/extract/<type><index>.html.json
- all sorts of shenanigans to actually pull the content out of the html
- build a JSON object with the results
- do a postmessage with that object so extractRunner.js can pull it out
- run postProcess.dart
- go through the results for each type looking for the best match
- write output/database.html
- write output/examples.html
- write output/obsolete.html
- write output/database.filtered.json which is the best matches
***** Process for updating database.json using these scripts.
TODO(eub) when I get the scripts to work all the way through.

View file

@ -1,120 +0,0 @@
// TODO(jacobr): convert this file to Dart once Dart supports all of the
// nodejs functionality used here. For example, search for all occurences of
// "http." and "fs."
var http = require('http');
var fs = require('fs');
try {
fs.mkdirSync('output/crawl');
} catch (e) {
// It doesn't matter if the directories already exist.
}
var domTypes = JSON.parse(fs.readFileSync('data/domTypes.json', 'utf8'));
var cacheData = {};
function scrape(filename, link) {
console.log(link);
var httpsPrefix = "https://";
var prefix = 'https://developer.mozilla.org/';
var notFoundPrefix = 'https://developer.mozilla.org/Article_not_found?uri=';
if (link.indexOf(prefix) != 0 ) {
throw "Unexpected url: " + link;
}
var scrapePath = "/search?q=cache:" + link;
// We crawl content from googleusercontent.com so we don't have to worry about
// crawler politeness like we would have to if scraping developer.mozilla.org
// directly.
var options = {
host: 'webcache.googleusercontent.com',
path: scrapePath,
port: 80,
method: 'GET'
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
var data='';
res.on('data', function(d) {
data += d;
});
var onClose = function(e) {
console.log("Writing crawl result for " + link);
fs.writeFileSync("output/crawl/" + filename + ".html", data, 'utf8');
}
res.on('close', onClose);
res.on('end', onClose);
});
req.end();
req.on('error', function(e) {
throw "Error " + e + " scraping " + link;
});
}
for (var i = 0; i < domTypes.length; i++) {
var type = domTypes[i];
// Json containing the search results for the current type.
var data = fs.readFileSync("output/search/" + type + ".json");
json = JSON.parse(data);
if (!('items' in json)) {
console.warn("No search results for " + type);
continue;
}
var items = json['items'];
var entry = [];
cacheData[type] = entry;
// Hardcode the correct matching url for a few types where the search engine
// gets the wrong answer.
var link = null;
if (type == 'Screen') {
link = 'https://developer.mozilla.org/en/DOM/window.screen';
} else if (type == 'Text') {
link = 'https://developer.mozilla.org/en/DOM/Text';
} else if (type == 'Touch') {
link = 'https://developer.mozilla.org/en/DOM/Touch';
} else if (type == 'TouchEvent' || type == 'webkitTouchEvent' || type == 'WebkitTouchEvent' || type == 'WebKitTouchEvent') {
link = 'https://developer.mozilla.org/en/DOM/TouchEvent';
} else if (type == 'HTMLSpanElement') {
link = 'https://developer.mozilla.org/en/HTML/Element/span';
} else if (type == 'HTMLPreElement') {
link = 'https://developer.mozilla.org/en/HTML/Element/pre';
} else if (type == 'HTMLFrameElement') {
link = 'https://developer.mozilla.org/en/HTML/Element/frame';
} else if (type == 'HTMLFrameSetElement') {
link = 'https://developer.mozilla.org/en/HTML/Element/frameset';
} else if (type == 'Geolocation') {
link = 'https://developer.mozilla.org/en/nsIDOMGeolocation;'
} else if (type == 'Notification') {
link = 'https://developer.mozilla.org/en/DOM/notification';
} else if (type == 'IDBDatabase') {
link = 'https://developer.mozilla.org/en/IndexedDB/IDBDatabase'
}
if (link != null) {
entry.push({index: 0, link: link, title: type});
scrape(type + 0, link);
continue;
}
for (j = 0; j < items.length; j++) {
var item = items[j];
var prefix = 'https://developer.mozilla.org/';
var notFoundPrefix = 'https://developer.mozilla.org/Article_not_found?uri=';
// Be optimistic and replace article not found links with links to where the
// article should be.
link = item['link'];
if (link.indexOf(notFoundPrefix) == 0) {
link = prefix + link.substr(notFoundPrefix.length);
}
entry.push({index: j, link: link, title: item['title']});
scrape(type + j, link);
}
}
fs.writeFileSync('output/crawl/cache.json', JSON.stringify(cacheData, null, ' '), 'utf8');

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -1,19 +0,0 @@
BUILT_DIR=../../../out/ReleaseIA32
DART2JS=$BUILT_DIR/dart2js
DARTVM=$BUILT_DIR/dart
$DART2JS -ooutput/extract.dart.js -c extract.dart
node extractRunner.js
# Read database.json,
# write database.filtered.json (with "best" entries)
# and obsolete.json (with entries marked obsolete).
$DARTVM postProcess.dart
# Create database.html, examples.html, and obsolete.html.
$DARTVM prettyPrint.dart
# Copy up the final output to the main MDN directory so we can check it in.
cp output/database.filtered.json database.json
cp output/obsolete.json .

View file

@ -1,194 +0,0 @@
var fs = require('fs');
var util = require('util');
var exec = require('child_process').exec;
var path = require('path');
// We have numProcesses extraction tasks running simultaneously to improve
// performance. If your machine is slow, you may need to dial back the
// parallelism.
var numProcesses = 8;
var db = {};
var metadata = {};
var USE_VM = false;
// Warning: START_DART_MESSAGE must match the value hardcoded in extract.dart
// TODO(jacobr): figure out a cleaner way to parse this data.
var START_DART_MESSAGE = "START_DART_MESSAGE_UNIQUE_IDENTIFIER";
var END_DART_MESSAGE = "END_DART_MESSAGE_UNIQUE_IDENTIFIER";
var domTypes = JSON.parse(fs.readFileSync('data/domTypes.json',
'utf8').toString());
var cacheData = JSON.parse(fs.readFileSync('output/crawl/cache.json',
'utf8').toString());
var dartIdl = JSON.parse(fs.readFileSync('data/dartIdl.json',
'utf8').toString());
try {
fs.mkdirSync('output/extract');
} catch (e) {
// It doesn't matter if the directories already exist.
}
var errorFiles = [];
// TODO(jacobr): blacklist these types as we can't get good docs for them.
// ["Performance"]
function parseFile(type, onDone, entry, file, searchResultIndex) {
var inputFile;
try {
inputFile = fs.readFileSync("output/crawl/" + file, 'utf8').toString();
} catch (e) {
console.warn("Couldn't read: " + file);
onDone();
return;
}
var inputFileRaw = inputFile;
// Cached pages have multiple DOCTYPE tags. Strip off the first one so that
// we have valid HTML.
// TODO(jacobr): use a regular expression instead of indexOf.
if (inputFile.toLowerCase().indexOf("<!doctype") == 0) {
var matchIndex = inputFile.toLowerCase().indexOf("<!doctype", 1);
if (matchIndex == -1) {
// not a cached page.
inputFile = inputFileRaw;
} else {
inputFile = inputFile.substr(matchIndex);
}
}
// Disable all existing javascript in the input file to speed up parsing and
// avoid conflicts between our JS and the JS in the file.
inputFile = inputFile.replace(/<script type="text\/javascript"/g,
'<script type="text/ignored"');
var endBodyIndex = inputFile.lastIndexOf("</body>");
if (endBodyIndex == -1) {
// Some files are missing a closing body tag.
endBodyIndex = inputFile.lastIndexOf("</html>");
}
if (endBodyIndex == -1) {
if (inputFile.indexOf("Error 404 (Not Found)") != -1) {
console.warn("Skipping 404 file: " + file);
onDone();
return;
}
throw "Unexpected file format for " + file;
}
inputFile = inputFile.substring(0, endBodyIndex) +
'<script type="text/javascript">\n' +
' if (window.layoutTestController) {\n' +
' var controller = window.layoutTestController;\n' +
' controller.dumpAsText();\n' +
' controller.waitUntilDone();\n' +
' }\n' +
'window.addEventListener("message", receiveMessage, false);\n' +
'function receiveMessage(event) {\n' +
' if (event.data.indexOf("' + START_DART_MESSAGE + '") != 0) return;\n' +
' console.log(event.data + "' + END_DART_MESSAGE + '");\n' +
// We feature detect whether the browser supports layoutTestController
// so we only clear the document content when running in the test shell
// and not when debugging using a normal browser.
' if (window.layoutTestController) {\n' +
' document.documentElement.textContent = "";\n' +
' window.layoutTestController.notifyDone();\n' +
' }\n' +
'}\n' +
'</script>\n' +
(USE_VM ?
'<script type="application/dart" src="../../extract.dart"></script>' :
'<script type="text/javascript" src="../../output/extract.dart.js">' +
'</script>') +
'\n' + inputFile.substring(endBodyIndex);
console.log("Processing: " + file);
var absoluteDumpFileName = path.resolve("output/extract/" + file);
fs.writeFileSync(absoluteDumpFileName, inputFile, 'utf8');
var parseArgs = {
type: type,
searchResult: entry,
dartIdl: dartIdl[type]
};
fs.writeFileSync(absoluteDumpFileName + ".json", JSON.stringify(parseArgs),
'utf8');
/*
// TODO(jacobr): Make this run on platforms other than OS X.
var cmd = '../../../client/tests/drt/Content Shell.app/Contents/MacOS/' +
Content Shell' + absoluteDumpFileName;
*/
// TODO(eub): Make this run on platforms other than Linux.
var cmd = '../../../client/tests/drt/content_shell ' + absoluteDumpFileName;
console.log(cmd);
exec(cmd,
function (error, stdout, stderr) {
var msgIndex = stdout.indexOf(START_DART_MESSAGE);
console.log('all: ' + stdout);
console.log('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
// TODO(jacobr): use a regexp.
var msg = stdout.substring(msgIndex + START_DART_MESSAGE.length);
msg = msg.substring(0, msg.indexOf(END_DART_MESSAGE));
if (!(type in db)) {
db[type] = [];
}
try {
db[type][searchResultIndex] = JSON.parse(msg);
} catch(e) {
// Write the errors file every time there is an error so that if the
// user aborts the script, the error file is valid.
console.warn("error parsing result for " + type + " file= "+ file);
errorFiles.push(file);
fs.writeFileSync("output/errors.json",
JSON.stringify(errorFiles, null, ' '), 'utf8');
}
onDone();
});
}
var tasks = [];
var numPending = numProcesses;
function processNextTask() {
numPending--;
if (tasks.length > 0) {
numPending++;
var task = tasks.pop();
task();
} else {
if (numPending <= 0) {
console.log("Successfully completed all tasks");
fs.writeFileSync("output/database.json",
JSON.stringify(db, null, ' '), 'utf8');
}
}
}
function createTask(type, entry, index) {
return function () {
var file = type + index + '.html';
parseFile(type, processNextTask, entry, file, index);
};
}
for (var i = 0; i < domTypes.length; i++) {
var type = domTypes[i];
var entries = cacheData[type];
if (entries != null) {
for (var j = 0; j < entries.length; j++) {
tasks.push(createTask(type, entries[j], j));
}
} else {
console.warn("No crawled files for " + type);
}
}
for (var p = 0; p < numProcesses; p++) {
processNextTask();
}

View file

@ -1,8 +0,0 @@
# This script goes from the input data in data/ all the way to the output data
# in database.filtered.json
# See output/database.html for a human readable view of the extracted data.
rm -rf output
node search.js
node crawl.js
./extract.sh

View file

@ -1 +0,0 @@
[{"type":"HTMLDListElement","member":"compact"},{"type":"HTMLSelectElement","member":"tabIndex"},{"type":"HTMLAreaElement","member":"accessKey"},{"type":"HTMLAreaElement","member":"tabIndex"},{"type":"HTMLAreaElement","member":"noHref"},{"type":"HTMLParagraphElement","member":"align"},{"type":"CanvasRenderingContext2D","member":"webkitTextStyle"},{"type":"HTMLDivElement","member":"align"},{"type":"HTMLLegendElement","member":"accessKey"},{"type":"HTMLLegendElement","member":"align"},{"type":"KeyboardEvent","member":"keyCode"},{"type":"KeyboardEvent","member":"which"},{"type":"KeyboardEvent","member":"charCode"},{"type":"HTMLObjectElement","member":"declare"},{"type":"HTMLObjectElement","member":"codeBase"},{"type":"HTMLObjectElement","member":"code"},{"type":"HTMLObjectElement","member":"archive"},{"type":"HTMLObjectElement","member":"hspace"},{"type":"HTMLObjectElement","member":"border"},{"type":"HTMLObjectElement","member":"tabIndex"},{"type":"HTMLObjectElement","member":"vspace"},{"type":"HTMLObjectElement","member":"align"},{"type":"HTMLObjectElement","member":"codeType"},{"type":"HTMLObjectElement","member":"standby"},{"type":"HTMLImageElement","member":"longDesc"},{"type":"HTMLImageElement","member":"align"},{"type":"HTMLImageElement","member":"vspace"},{"type":"HTMLImageElement","member":"hspace"},{"type":"HTMLImageElement","member":"border"},{"type":"HTMLTableCaptionElement","member":"align"},{"type":"HTMLIFrameElement","member":"align"},{"type":"HTMLTableColElement","member":"align"},{"type":"HTMLTableColElement","member":"width"},{"type":"HTMLTableColElement","member":"ch"},{"type":"HTMLTableColElement","member":"vAlign"},{"type":"HTMLTableColElement","member":"chOff"},{"type":"HTMLHRElement","member":"width"},{"type":"HTMLHRElement","member":"align"},{"type":"HTMLHRElement","member":"noshade"},{"type":"HTMLHRElement","member":"size"},{"type":"HTMLHeadingElement","member":"align"},{"type":"HTMLBodyElement","member":"vLink"},{"type":"HTMLBodyElement","member":"background"},{"type":"HTMLBodyElement","member":"text"},{"type":"HTMLBodyElement","member":"link"},{"type":"HTMLBodyElement","member":"bgColor"},{"type":"HTMLBodyElement","member":"aLink"},{"type":"Document","member":"width"},{"type":"Document","member":"bgColor"},{"type":"Document","member":"all"},{"type":"Document","member":"xmlStandalone"},{"type":"Document","member":"xmlEncoding"},{"type":"Document","member":"applets"},{"type":"Document","member":"vlinkColor"},{"type":"Document","member":"linkColor"},{"type":"Document","member":"fgColor"},{"type":"Document","member":"height"},{"type":"Document","member":"alinkColor"},{"type":"Document","member":"xmlVersion"},{"type":"HTMLHtmlElement","member":"version"},{"type":"HTMLHeadElement","member":"profile"},{"type":"HTMLTextAreaElement","member":"accessKey"},{"type":"HTMLTextAreaElement","member":"tabIndex"},{"type":"HTMLTextAreaElement","member":"blur"},{"type":"HTMLTextAreaElement","member":"focus"},{"type":"XMLHttpRequest","member":"webkitResponseArrayBuffer"},{"type":"File","member":"fileName"},{"type":"File","member":"fileSize"},{"type":"HTMLInputElement","member":"accessKey"},{"type":"HTMLInputElement","member":"tabIndex"},{"type":"HTMLInputElement","member":"useMap"},{"type":"HTMLInputElement","member":"align"},{"type":"IDBVersionChangeEvent","member":"version"},{"type":"HTMLBRElement","member":"clear"},{"type":"HTMLAnchorElement","member":"accessKey"},{"type":"HTMLAnchorElement","member":"name"},{"type":"HTMLAnchorElement","member":"charset"},{"type":"HTMLAnchorElement","member":"rev"},{"type":"HTMLAnchorElement","member":"coords"},{"type":"HTMLAnchorElement","member":"tabIndex"},{"type":"HTMLAnchorElement","member":"shape"}]

View file

@ -1,38 +0,0 @@
/**
* Read database.json,
* write database.filtered.json (with "best" entries)
* and obsolete.json (with entries marked obsolete).
*/
library postProcess;
import 'dart:convert';
import 'dart:io';
import 'util.dart';
void main() {
// Database of code documentation.
Map<String, List> database = JSON.decode(
new File('output/database.json').readAsStringSync());
final filteredDb = {};
final obsolete = [];
for (String type in database.keys) {
final entry = pickBestEntry(database[type], type);
if (entry == null) {
print("Can't find ${type} in database. Skipping.");
continue;
}
filteredDb[type] = entry;
if (entry.containsKey("members")) {
Map members = getMembersMap(entry);
for (String name in members.keys) {
Map memberData = members[name];
if (memberData['obsolete'] == true) {
obsolete.add({'type': type, 'member' : name});
}
}
}
}
writeFileSync("output/database.filtered.json", JSON.encode(filteredDb));
writeFileSync("output/obsolete.json", JSON.encode(obsolete));
}

View file

@ -1,430 +0,0 @@
/**
* Creates database.html, examples.html, and obsolete.html.
*/
library prettyPrint;
import 'dart:convert';
import 'dart:io';
import 'util.dart';
String orEmpty(String str) {
return str == null ? "" : str;
}
List<String> sortStringCollection(Iterable<String> collection) {
final out = <String>[];
out.addAll(collection);
out.sort((String a, String b) => a.compareTo(b));
return out;
}
int addMissing(StringBuffer sb, String type, Map members) {
int total = 0;
/**
* Add all missing members to the string output and return the number of
* missing members.
*/
void addMissingHelper(String propType) {
Map expected = allProps[type][propType];
if (expected != null) {
for(final name in sortStringCollection(expected.keys)) {
if (!members.containsKey(name)) {
total++;
sb.write("""
<tr class="missing">
<td>$name</td>
<td></td>
<td>Could not find documentation for $propType</td>
</tr>
""");
}
}
}
}
addMissingHelper('properties');
addMissingHelper('methods');
addMissingHelper('constants');
return total;
}
void main() {
// Database of code documentation.
final Map<String, Map> database = JSON.decode(
new File('output/database.filtered.json').readAsStringSync());
// Types we have documentation for.
matchedTypes = new Set<String>();
int numMissingMethods = 0;
int numFoundMethods = 0;
int numExtraMethods = 0;
int numGen = 0;
int numSkipped = 0;
final sbSkipped = new StringBuffer();
final sbAllExamples = new StringBuffer();
// Table rows for all obsolete members.
final sbObsolete = new StringBuffer();
// Main documentation file.
final sb = new StringBuffer();
// TODO(jacobr): switch to using a real template system instead of string
// interpolation combined with StringBuffers.
sb.write("""
<html>
<head>
<style type="text/css">
body {
background-color: #eee;
margin: 10px;
font: 14px/1.428 "Lucida Grande", "Lucida Sans Unicode", Lucida,
Arial, Helvetica, sans-serif;
}
.debug {
color: #888;
}
.compatibility, .links, .see-also, .summary, .members, .example {
border: 1px solid #CCC;
margin: 5px;
padding: 5px;
}
.type, #dart_summary {
border: 1px solid;
margin-top: 10px;
margin-bottom: 10px;
padding: 10px;
overflow: hidden;
background-color: white;
-moz-box-shadow: 5px 5px 5px #888;
-webkit-box-shadow: 5px 5px 5px #888;
box-shadow: 5px 5px 5px #888;
}
#dart_summary {
border: 2px solid #00F;
margin: 5px;
padding: 5px;
}
th {
background-color:#ccc;
font-weight: bold;
}
tr:nth-child(odd) {
background-color:#eee;
}
tr:nth-child(even) {
background-color:#fff;
}
tr:nth-child(odd).unknown {
background-color:#dd0;
}
tr:nth-child(even).unknown {
background-color:#ff0;
}
tr:nth-child(odd).missing {
background-color:#d88;
}
tr:nth-child(even).missing {
background-color:#faa;
}
li.unknown {
color: #f00;
}
td, th {
vertical-align: top;
}
</style>
<title>Doc Dump</title>
</head>
<body>
<h1>Doc Dump</h1>
<ul>
<li><a href="#dart_summary">Summary</a></li>
</li>
""");
for (String type in sortStringCollection(database.keys)) {
final entry = database[type];
if (entry == null || entry.containsKey('skipped')) {
numSkipped++;
sbSkipped.write("""
<li id="$type">
<a target="_blank" href="http://www.google.com/cse?cx=017193972565947830266%3Awpqsk6dy6ee&ie=UTF-8&q=$type">
$type
</a>
--
Title: ${entry == null ? "???" : entry["title"]} -- Issue:
${entry == null ? "???" : entry['cause']}
--
<a target="_blank" href="${entry == null ? "???" : entry["srcUrl"]}">
scraped url
</a>
</li>""");
continue;
}
matchedTypes.add(type);
numGen++;
StringBuffer sbSections = new StringBuffer();
StringBuffer sbMembers = new StringBuffer();
StringBuffer sbExamples = new StringBuffer();
if (entry.containsKey("members")) {
Map members = getMembersMap(entry);
sbMembers.write("""
<div class="members">
<h3><span class="debug">[dart]</span> Members</h3>
<table>
<tbody>
<tr>
<th>Name</th><th>Description</th><th>IDL</th><th>Status</th>
</tr>
""");
for (String name in sortStringCollection(members.keys)) {
Map memberData = members[name];
bool unknown = !hasAny(type, name);
StringBuffer classes = new StringBuffer();
if (unknown) classes.write("unknown ");
if (unknown) {
numExtraMethods++;
} else {
numFoundMethods++;
}
final sbMember = new StringBuffer();
if (memberData.containsKey('url')) {
sbMember.write("""
<td><a href="${memberData['url']}">$name</a></td>
""");
} else {
sbMember.write("""
<td>$name</td>
""");
}
sbMember.write("""
<td>${memberData['help']}</td>
<td>
<pre>${orEmpty(memberData['idl'])}</pre>
</td>
<td>${memberData['obsolete'] == true ? "Obsolete" : ""}</td>
""");
if (memberData['obsolete'] == true) {
sbObsolete.write("<tr class='$classes'><td>$type</td>$sbMember</tr>");
}
sbMembers.write("<tr class='$classes'>$sbMember</tr>");
}
numMissingMethods += addMissing(sbMembers, type, members);
sbMembers.write("""
</tbody>
</table>
</div>
""");
}
for (String sectionName in
["summary", "constructor", "compatibility", "specification",
"seeAlso"]) {
if (entry.containsKey(sectionName)) {
sbSections.write("""
<div class="$sectionName">
<h3><span class="debug">[Dart]</span> $sectionName</h3>
${entry[sectionName]}
</div>
""");
}
}
if (entry.containsKey("links")) {
sbSections.write("""
<div class="links">
<h3><span class="debug">[Dart]</span> Specification</h3>
<ul>
""");
List links = entry["links"];
for (Map link in links) {
sbSections.write("""
<li><a href="${link['href']}">${link['title']}</a></li>
""");
}
sbSections.write("""
</ul>
</div>
""");
}
if (entry.containsKey("examples")) {
for (String example in entry["examples"]) {
sbExamples.write("""
<div class="example">
<h3><span class="debug">[Dart]</span> Example</h3>
$example
</div>
""");
}
}
String title = entry['title'];
if (title != type) {
title = '<h4>Dart type: $type</h4><h2>$title</h2>';
} else {
title = '<h2>$title</h2>';
}
sb.write("""
<div class='type' id="$type">
<a href='${entry['srcUrl']}'>$title</a>
$sbSections
$sbExamples
$sbMembers
</div>
""");
if (sbExamples.length > 0) {
sbAllExamples.write("""
<div class='type' id="$type">
<a href='${entry['srcUrl']}'>$title</a>
$sbExamples
</div>
""");
}
}
for (String type in sortStringCollection(allProps.keys)) {
if (!matchedTypes.contains(type) &&
!database.containsKey(type)) {
numSkipped++;
sbSkipped.write("""
<li class="unknown" id="$type">
<a target="_blank" href="http://www.google.com/cse?cx=017193972565947830266%3Awpqsk6dy6ee&ie=UTF-8&q=$type">
$type
</a>
</li>
""");
}
}
sb.write("""
<div id="#dart_summary">
<h2>Summary</h2>
<h3>
Generated docs for $numGen classes out of a possible
${allProps.keys.length}
</h3>
<h3>Found documentation for $numFoundMethods methods listed in WebKit</h3>
<h3>
Found documentation for $numExtraMethods methods not listed in WebKit
</h3>
<h3>
Unable to find documentation for $numMissingMethods methods present in
WebKit
</h3>
<h3>
Skipped generating documentation for $numSkipped classes due to no
plausible matching files
</h3>
<ul>
$sbSkipped
</ul>
</div>
""");
sb.write("""
</body>
</html>
""");
writeFileSync("output/database.html", sb.toString());
writeFileSync("output/examples.html", """
<html>
<head>
<style type="text/css">
body {
background-color: #eee;
margin: 10px;
font: 14px/1.428 "Lucida Grande", "Lucida Sans Unicode", Lucida, Arial,
Helvetica, sans-serif;
}
.debug {
color: #888;
}
.example {
border: 1px solid #CCC;
margin: 5px;
padding: 5px;
}
.type {
border: 1px solid;
margin-top: 10px;
margin-bottom: 10px;
padding: 10px;
overflow: hidden;
background-color: white;
-moz-box-shadow: 5px 5px 5px #888;
-webkit-box-shadow: 5px 5px 5px #888;
box-shadow: 5px 5px 5px #888;
}
</style>
<title>All examples</title>
</head>
<body>
<h1>All examples</h1>
$sbAllExamples
</body>
</html>
""");
writeFileSync("output/obsolete.html", """
<html>
<head>
<style type="text/css">
body {
background-color: #eee;
margin: 10px;
font: 14px/1.428 "Lucida Grande", "Lucida Sans Unicode", Lucida,
Arial, Helvetica, sans-serif;
}
.debug {
color: #888;
}
.type {
border: 1px solid;
margin-top: 10px;
margin-bottom: 10px;
padding: 10px;
overflow: hidden;
background-color: white;
-moz-box-shadow: 5px 5px 5px #888;
-webkit-box-shadow: 5px 5px 5px #888;
box-shadow: 5px 5px 5px #888;
}
</style>
<title>Methods marked as obsolete</title>
</head>
<body>
<h1>Methods marked as obsolete</h1>
<table>
<tbody>
<tr>
<th>Type</th>
<th>Name</th>
<th>Description</th>
<th>IDL</th>
<th>Status</th>
</tr>
$sbObsolete
</tbody>
</table>
</body>
</html>
""");
}

View file

@ -1,58 +0,0 @@
/**
* Uses a Google Custom Search Engine to find pages on
* developer.mozilla.org that appear to match types from the Webkit IDL
*/
var https = require('https');
var fs = require('fs');
var domTypes = JSON.parse(fs.readFileSync('data/domTypes.json', 'utf8'));
try {
fs.mkdirSync('output');
fs.mkdirSync('output/search');
} catch (e) {
// It doesn't matter if the directories already exist.
}
function searchForType(type) {
// Strip off WebKit specific prefixes from type names to increase the chances
// of getting matches on developer.mozilla.org.
var shortType = type.replace(/^WebKit/, "");
// We use a Google Custom Search Engine provisioned for 10,000 API based
// queries per day that limits search results to developer.mozilla.org.
// You shouldn't need to, but if you want to create your own Google Custom
// Search Engine, visit http://www.google.com/cse/
var options = {
host: 'www.googleapis.com',
path: '/customsearch/v1?key=AIzaSyDN1RhE5FafLzLfErGpoYhHlLHeyEkxTkM&' +
'cx=017193972565947830266:wpqsk6dy6ee&num=5&q=' + shortType,
port: 443,
method: 'GET'
};
var req = https.request(options, function(res) {
res.setEncoding('utf8');
var data = '';
res.on('data', function(d) {
data += d;
});
var onClose = function(e) {
fs.writeFile("output/search/" + type + ".json", data, function(err) {
if (err) throw err;
console.log('Done searching for ' + type);
});
}
res.on('close', onClose);
res.on('end', onClose);
});
req.end();
req.on('error', function(e) {
console.error(e);
});
}
for (var i = 0; i < domTypes.length; i++) {
searchForType(domTypes[i]);
}

View file

@ -1,95 +0,0 @@
library util;
import 'dart:io';
Map<String, Map> _allProps;
Map<String, Map> get allProps {
if (_allProps == null) {
// Database of expected property names for each type in WebKit.
_allProps = parse.parse(
new File('data/dartIdl.json').readAsStringSync());
}
return _allProps;
}
Set<String> matchedTypes;
/** Returns whether the type has any member matching the specified name. */
bool hasAny(String type, String prop) {
final data = allProps[type];
return data['properties'].containsKey(prop) ||
data['methods'].containsKey(prop) ||
data['constants'].containsKey(prop);
}
/**
* Return the members from an [entry] as Map of member names to member
* objects.
*/
Map getMembersMap(Map entry) {
List<Map> rawMembers = entry["members"];
final members = {};
for (final entry in rawMembers) {
members[entry['name']] = entry;
}
return members;
}
/**
* Score entries using similarity heuristics calculated from the observed and
* expected list of members. We could be much less naive and penalize spurious
* methods, prefer entries with class level comments, etc. This method is
* needed becase we extract entries for each of the top search results for
* each class name and rely on these scores to determine which entry was
* best. Typically all scores but one will be zero. Multiple pages have
* non-zero scores when MDN has multiple pages on the same class or pages on
* similar classes (e.g. HTMLElement and Element), or pages on Mozilla
* specific classes that are similar to DOM classes (Console).
*/
num scoreEntry(Map entry, String type) {
num score = 0;
// TODO(jacobr): consider removing skipped entries completely instead of
// just giving them lower scores.
if (!entry.containsKey('skipped')) {
score++;
}
if (entry.containsKey("members")) {
Map members = getMembersMap(entry);
for (String name in members.keys) {
if (hasAny(type, name)) {
score++;
}
}
}
return score;
}
/**
* Given a list of candidates for the documentation for a type, find the one
* that is the best.
*/
Map pickBestEntry(List entries, String type) {
num bestScore = -1;
Map bestEntry;
for (Map entry in entries) {
if (entry != null) {
num score = scoreEntry(entry, type);
if (score > bestScore) {
bestScore = score;
bestEntry = entry;
}
}
}
return bestEntry;
}
/**
* Helper for sync creation of a whole file from a string.
*/
void writeFileSync(String filename, String data) {
File f = new File(filename);
RandomAccessFile raf = f.openSync(FileMode.WRITE);
raf.writeStringSync(data);
raf.closeSync();
}

View file

@ -1,92 +0,0 @@
#comments {
width: 1000px;
margin: 0 auto 22px auto;
}
.mdn {
border: solid 1px hsl(10, 80%, 90%);
border-radius: 4px;
font-size: 16px;
line-height: 22px;
margin: 22px 0;
padding: 21px 21px 0 21px;
}
/* Try to massage the MDN content a bit to look nicer. This makes sure we don't
double pad the insides of the box. */
.mdn > *:first-child {
margin-top: 0;
}
.mdn > *:last-child {
margin-bottom: 0;
}
.mdn .note {
background: hsl(220, 80%, 93%);
font: 400 14px/22px 'Open Sans', 'Lucida Sans Unicode', 'Lucida Grande',
sans-serif;
color: hsl(220, 40%, 40%);
border-radius: 4px;
padding: 11px;
}
.mdn .warning {
background: hsl(40, 80%, 90%);
font: 400 14px/22px 'Open Sans', 'Lucida Sans Unicode', 'Lucida Grande',
sans-serif;
color: hsl(40, 40%, 30%);
border-radius: 4px;
padding: 11px;
}
.mdn h6 {
font: 600 14px/22px 'Open Sans', 'Lucida Sans Unicode', 'Lucida Grande',
sans-serif;
color: #999;
margin: 22px 0 0 0;
}
/* End MDN massage. */
.mdn-note {
font: 600 11px/22px 'Open Sans', 'Lucida Sans Unicode', 'Lucida Grande',
sans-serif;
color: hsl(10, 60%, 80%);
text-align: right;
line-height: 21px; /* To absorb bottom border 1px. */
margin-right: -14px;
}
.mdn-note a {
color: hsl(10, 60%, 80%);
}
.mdn-note a:hover {
color: hsl(10, 60%, 60%);
}
.mdn-attribution {
background: hsl(10, 80%, 95%);
border-radius: 4px;
font: 400 13px/22px 'Open Sans', 'Lucida Sans Unicode', 'Lucida Grande',
sans-serif;
color: hsl(10, 30%, 30%);
padding: 22px 22px 22px 75px;
}
.mdn-logo {
float: left;
margin-left: -53px;
/*padding-right: 11px;*/
}
.correspond {
font: italic 400 14px/22px 'Open Sans', 'Lucida Sans Unicode',
'Lucida Grande', sans-serif;
color: #666;
}
.correspond .crossref {
font: inherit;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 971 B