Index: lib/dartdoc/mirrors/dart2js_mirror.dart |
diff --git a/lib/dartdoc/mirrors/dart2js_mirror.dart b/lib/dartdoc/mirrors/dart2js_mirror.dart |
index 5bc3a9cf79e07d2e69251c96f838ce69cfe6ad57..d86c6eea6806769d473324b38a637d75780a9f39 100644 |
--- a/lib/dartdoc/mirrors/dart2js_mirror.dart |
+++ b/lib/dartdoc/mirrors/dart2js_mirror.dart |
@@ -170,6 +170,109 @@ class Dart2jsDiagnosticListener implements DiagnosticListener { |
} |
//------------------------------------------------------------------------------ |
+// Compiler extension for apidoc |
kasperl
2012/07/06 12:40:41
Terminate comment with .
Johnni Winther
2012/07/09 14:57:18
Done.
|
+//------------------------------------------------------------------------------ |
+ |
+/** |
+ * Extension of the compiler that enables the analysis of several libraries with |
+ * no particular entry point. |
+ */ |
+class LibraryCompiler extends api.Compiler { |
+ LibraryCompiler(diagnostics.ReadStringFromUri provider, |
+ diagnostics.DiagnosticHandler handler, |
+ Uri libraryRoot, Uri packageRoot, |
+ List<String> options) |
+ : super(provider, handler, libraryRoot, packageRoot, options) { |
+ checker = new LibraryTypeCheckerTask(this); |
+ resolver = new LibraryResolverTask(this); |
+ } |
+ |
+ // TODO(johnniwinther): The following methods are added to enable the analysis |
+ // of a collection of libraries to be used for apidoc. Most of the methods |
+ // are based on copies of existing methods and could probably be implemented |
+ // such that the duplicate code is avoided. Not to affect the correctness and |
+ // speed of dart2js as is, the redundancy is accepted temporarily. |
+ |
+ /** |
+ * Run the compiler on a list of libraries. No entry point is used. |
+ */ |
+ bool runList(List<Uri> uriList) { |
+ bool success = _runList(uriList); |
+ for (final task in tasks) { |
+ log('${task.name} took ${task.timing}msec'); |
+ } |
+ return success; |
+ } |
+ |
+ bool _runList(List<Uri> uriList) { |
+ try { |
+ runCompilerList(uriList); |
+ } catch (CompilerCancelledException exception) { |
+ log(exception.toString()); |
+ log('compilation failed'); |
+ return false; |
+ } |
+ tracer.close(); |
+ log('compilation succeeded'); |
+ return true; |
+ } |
+ |
+ void runCompilerList(List<Uri> uriList) { |
+ scanBuiltinLibraries(); |
+ var elementList = <LibraryElement>[]; |
+ for (var uri in uriList) { |
+ elementList.add(scanner.loadLibrary(uri, null)); |
+ } |
+ |
+ world.populate(this, libraries.getValues()); |
+ |
+ log('Resolving...'); |
+ phase = Compiler.PHASE_RESOLVING; |
+ backend.enqueueHelpers(enqueuer.resolution); |
+ processQueueList(enqueuer.resolution, elementList); |
+ log('Resolved ${enqueuer.resolution.resolvedElements.length} elements.'); |
+ } |
+ |
+ void processQueueList(Enqueuer world, List<LibraryElement> elements) { |
+ backend.processNativeClasses(world, libraries.getValues()); |
+ for (var library in elements) { |
+ library.elements.forEach((_, element) { |
+ world.addToWorkList(element); |
+ }); |
+ } |
+ progress.reset(); |
+ world.forEach((WorkItem work) { |
+ withCurrentElement(work.element, () => work.run(this, world)); |
+ }); |
+ //world.queueIsClosed = true; |
+ assert(world.checkNoEnqueuedInvokedInstanceMethods()); |
+ world.registerFieldClosureInvocations(); |
+ } |
+ |
+ String codegen(WorkItem work, Enqueuer world) { |
+ return null; |
+ } |
+} |
+ |
+// TODO(johnniwinther): The source for the apidoc includes calls to methods on |
+// for instance [MathPrimitives] which are not resolved by dart2js. Since we |
+// do not need to analyse the body of functions to produce the documenation |
+// we use a specialized resolver which bypasses method bodies. |
Lasse Reichstein Nielsen
2012/07/09 10:39:33
Good choice. I expect to see MathNatives go away f
|
+class LibraryResolverTask extends ResolverTask { |
+ LibraryResolverTask(api.Compiler compiler) : super(compiler); |
+ |
+ void visitBody(ResolverVisitor visitor, Statement body) {} |
+} |
+ |
+// TODO(johnniwinther): As a side-effect of bypassing method bodies in |
+// [LibraryResolveTask] we can not perform the typecheck. |
+class LibraryTypeCheckerTask extends TypeCheckerTask { |
+ LibraryTypeCheckerTask(api.Compiler compiler) : super(compiler); |
+ |
+ void check(Node tree, TreeElements elements) {} |
+} |
+ |
+//------------------------------------------------------------------------------ |
// Compilation implementation |
//------------------------------------------------------------------------------ |
@@ -230,6 +333,28 @@ class Dart2jsCompilation implements Compilation { |
_compiler.run(scriptUri); |
} |
+ Dart2jsCompilation.library(List<String> libraries, String libraryRoot, |
+ [String packageRoot, List<String> opts = const []]) |
+ : cwd = getCurrentDirectory(), |
+ sourceFiles = <SourceFile>{} |
+ { |
Lasse Reichstein Nielsen
2012/07/09 10:39:33
Brace on previous line.
Johnni Winther
2012/07/09 14:57:18
Done.
|
+ var libraryUri = cwd.resolve(nativeToUriPath(libraryRoot)); |
+ var packageUri; |
+ if (packageRoot !== null) { |
+ packageUri = cwd.resolve(nativeToUriPath(packageRoot)); |
+ } else { |
+ packageUri = libraryUri; |
+ } |
+ _compiler = new LibraryCompiler(provider, handler, |
+ libraryUri, packageUri, <String>[]); |
+ var librariesUri = <Uri>[]; |
+ for (var library in libraries) { |
+ librariesUri.add(cwd.resolve(nativeToUriPath(library))); |
+ // TODO(johnniwinther): Detect file not found |
+ } |
+ _compiler.runList(librariesUri); |
+ } |
+ |
void addLibrary(String path) { |
var uri = cwd.resolve(nativeToUriPath(path)); |
_compiler.scanner.loadLibrary(uri, null); |
@@ -275,12 +400,16 @@ abstract class Dart2jsElementMirror implements Dart2jsMirror { |
system.compiler.spanFromElement(_element)); |
String toString() => _element.toString(); |
+ |
+ int hashCode() => qualifiedName().hashCode(); |
} |
abstract class Dart2jsProxyMirror implements Dart2jsMirror { |
final Dart2jsMirrorSystem system; |
Dart2jsProxyMirror(this.system); |
+ |
+ int hashCode() => qualifiedName().hashCode(); |
} |
/////////////////////////////////////////////////////// |
@@ -321,6 +450,9 @@ class Dart2jsMirrorSystem implements MirrorSystem, Dart2jsMirror { |
String qualifiedName() => simpleName(); |
String get canonicalName() => simpleName(); |
+ |
+ // TODO(johnniwinther): Hack! Dart2jsMirrorSystem need not be a Mirror. |
+ int hashCode() => qualifiedName().hashCode(); |
} |
abstract class Dart2jsObjectMirror extends Dart2jsElementMirror |
@@ -339,6 +471,8 @@ class Dart2jsLibraryMirror extends Dart2jsObjectMirror |
LibraryElement get _library() => _element; |
+ LibraryMirror library() => this; |
+ |
String get canonicalName() => simpleName(); |
/** |