Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(822)

Unified Diff: utils/import_mapper/import_mapper.dart

Issue 9369006: First prototype of import map generator. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | utils/import_mapper/passthrough_hook.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: utils/import_mapper/import_mapper.dart
diff --git a/utils/import_mapper/import_mapper.dart b/utils/import_mapper/import_mapper.dart
new file mode 100644
index 0000000000000000000000000000000000000000..f389df3d8366a68f691efda81cffcae6c5c4ec6e
--- /dev/null
+++ b/utils/import_mapper/import_mapper.dart
@@ -0,0 +1,116 @@
+// 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.
+
+#library('import_mapper');
+
+#import('dart:io');
+#import('../../client/json/dart_json.dart');
Jennifer Messerly 2012/02/09 01:09:24 heh heh :)
Bob Nystrom 2012/02/09 02:05:44 :)
+#import('../../frog/lang.dart');
+#import('../../frog/file_system.dart');
+#import('../../frog/file_system_vm.dart');
+
+typedef String ImportHook(ImportContext context, String name);
+
+/**
+ * Provides contextual information about the current import and environment
+ * that the import hook can use to resolve an import.
+ */
+class ImportContext {
+ // TODO(rnystrom): Fill in context here as we figure out what we want.
+}
+
+/** The generated import map. */
+Map<String, String> _importMap;
+
+ImportHook _hook;
+
+/**
+ * Uses the given import hook to generate an import map for all of the
+ * libraries used by a given entrypoint. The entrypoint is assumed to be
+ * provided as the first VM command line argument.
+ *
+ * Prints the import map data (a JSON object) to stdout.
+ */
+void generateImportMap(ImportHook hook) {
+ _hook = hook;
+
+ // Initialize frog.
+ final files = new VMFileSystem();
+ parseOptions('../../frog', ['', '', '--libdir=../../frog/lib'], files);
+ initializeWorld(files);
+ _importMap = {};
+
+ // The entrypoint of the library to generate an import map for.
+ final argv = (new Options()).arguments;
+ final entrypoint = argv[argv.length - 1];
+ _walkLibrary(entrypoint);
+
+ print(JSON.stringify(_importMap));
+}
+
+/**
+ * Recursively traverses all of the `#import()` directives in the given library
+ * entrypoint and runs the import hook on them. [entrypoint] should be a path
+ * to a library file.
+ */
+void _walkLibrary(String entrypoint) {
+ // TODO(rnystrom): Do more here when there's context we care about.
+ final context = new ImportContext();
+
+ final text = readFile(entrypoint);
+ final source = new SourceFile(entrypoint, text);
+ final parser = new Parser(source, true);
Siggi Cherem (dart-lang) 2012/02/09 01:21:57 => Parser(source, diet: true);
Bob Nystrom 2012/02/09 02:05:44 Done.
+
+ final definitions = parser.compilationUnit();
+
+ for (final definition in definitions) {
+ if (definition is DirectiveDefinition) {
Jennifer Messerly 2012/02/09 01:09:24 perhaps: if (definition is! DirectiveDefinition)
Bob Nystrom 2012/02/09 02:05:44 Done.
+ DirectiveDefinition directive = definition;
+ if (directive.name.name == 'import') {
+ // The first argument is expected to be a string literal.
+ final name = directive.arguments[0].value.value.actualValue;
+
+ // Only map a given import once.
+ // TODO(rnystrom): Should invoke the hook again and ensure that it gets
Jennifer Messerly 2012/02/09 01:09:24 maybe in debug mode, or something like that
Bob Nystrom 2012/02/09 02:05:44 Agreed.
+ // the same result. It should be an error if the hook isn't
+ // referentially transparent.
+ if (!_importMap.containsKey(name)) {
+ final uri = _hook(context, name);
+ _importMap[name] = uri;
+
+ // Recurse into this library.
+ // TODO(rnystrom): Hackish. How should we handle corelib stuff?
Siggi Cherem (dart-lang) 2012/02/09 01:21:57 have a map file for corelibs and import mappings f
Bob Nystrom 2012/02/09 02:05:44 The way this works is that the import hook *does*
+ if (!uri.startsWith('dart:')) {
+ _walkLibrary(_getFullPath(entrypoint, uri));
+ }
+ }
+ }
+ }
+ }
+}
+
+// TODO(rnystrom): Copied from frog/library.dart (makeFullPath).
+/**
+ * Given the path to a library containing an #import() and the resolved URI for
+ * that import, gives the full path to that library.
+ */
+String _getFullPath(String importingLibrary, String filename) {
+ if (filename.startsWith('dart:')) return filename;
+ // TODO(jmesserly): replace with node.js path.resolve
+ if (filename.startsWith('/')) return filename;
+ if (filename.startsWith('file:///')) return filename;
+ if (filename.startsWith('http://')) return filename;
+ if (const RegExp('^[a-zA-Z]:/').hasMatch(filename)) return filename;
+ return joinPaths(dirname(importingLibrary), filename);
+}
+
+String readFile(String filename) {
+ // TODO(rnystrom): There must be an easier way than this.
+ var file = (new File(filename)).openSync();
+ var length = file.lengthSync();
+ var buffer = new List<int>(length);
+ var bytes = file.readListSync(buffer, 0, length);
+ file.closeSync();
+ return new String.fromCharCodes(buffer);
+}
« no previous file with comments | « no previous file | utils/import_mapper/passthrough_hook.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698