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

Unified Diff: lib/src/compiler/compiler.dart

Issue 2249233002: fix #626, add AMD module format and make it default (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: merged Created 4 years, 4 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 | « lib/src/compiler/command.dart ('k') | lib/src/compiler/module_builder.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/compiler/compiler.dart
diff --git a/lib/src/compiler/compiler.dart b/lib/src/compiler/compiler.dart
index 77d03f06001903d13721d8df95cad6b419dd1298..d9b6b9630283595e72a25147f74b18daa4671e59 100644
--- a/lib/src/compiler/compiler.dart
+++ b/lib/src/compiler/compiler.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:collection' show HashSet, Queue;
+import 'dart:convert' show JSON;
+import 'dart:io' show File;
import 'package:analyzer/dart/element/element.dart' show LibraryElement;
import 'package:analyzer/analyzer.dart'
show AnalysisError, CompilationUnit, ErrorSeverity;
@@ -17,12 +19,17 @@ import 'package:args/args.dart' show ArgParser, ArgResults;
import 'package:args/src/usage_exception.dart' show UsageException;
import 'package:func/func.dart' show Func1;
import 'package:path/path.dart' as path;
+import 'package:source_maps/source_maps.dart';
import '../analyzer/context.dart'
show AnalyzerOptions, createAnalysisContextWithSources;
-import 'extension_types.dart' show ExtensionTypeSet;
+import '../js_ast/js_ast.dart' as JS;
import 'code_generator.dart' show CodeGenerator;
import 'error_helpers.dart' show errorSeverity, formatError, sortErrors;
+import 'extension_types.dart' show ExtensionTypeSet;
+import 'js_names.dart' as JS;
+import 'module_builder.dart' show transformModuleFormat, ModuleFormat;
+import 'source_map_printer.dart' show SourceMapPrintingContext;
/// Compiles a set of Dart files into a single JavaScript module.
///
@@ -135,7 +142,7 @@ class ModuleCompiler {
if (!options.unsafeForceCompile &&
errors.any((e) => errorSeverity(context, e) == ErrorSeverity.ERROR)) {
- return new JSModuleFile.invalid(unit.name, messages);
+ return new JSModuleFile.invalid(unit.name, messages, options);
}
var codeGenerator = new CodeGenerator(context, options, _extensionTypes);
@@ -143,14 +150,6 @@ class ModuleCompiler {
}
}
-enum ModuleFormat { es6, legacy, node }
-
-ModuleFormat parseModuleFormat(String s) => {
- 'es6': ModuleFormat.es6,
- 'node': ModuleFormat.node,
- 'legacy': ModuleFormat.legacy
- }[s];
-
class CompilerOptions {
/// Whether to emit the source mapping file.
///
@@ -209,10 +208,6 @@ class CompilerOptions {
// TODO(ochafik): Simplify this code when our target platforms catch up.
final bool destructureNamedParams;
- /// Which module format to support.
- /// Currently 'es6' and 'legacy' are supported.
- final ModuleFormat moduleFormat;
-
const CompilerOptions(
{this.sourceMap: true,
this.sourceMapComment: true,
@@ -222,7 +217,6 @@ class CompilerOptions {
this.emitMetadata: false,
this.closure: false,
this.destructureNamedParams: false,
- this.moduleFormat: ModuleFormat.legacy,
this.hoistInstanceCreation: true,
this.hoistSignatureTypes: false,
this.nameTypeTests: true,
@@ -238,7 +232,6 @@ class CompilerOptions {
emitMetadata = args['emit-metadata'],
closure = args['closure-experimental'],
destructureNamedParams = args['destructure-named-params'],
- moduleFormat = parseModuleFormat(args['modules']),
hoistInstanceCreation = args['hoist-instance-creation'],
hoistSignatureTypes = args['hoist-signature-types'],
nameTypeTests = args['name-type-tests'],
@@ -258,15 +251,6 @@ class CompilerOptions {
'disable if using X-SourceMap header',
defaultsTo: true,
hide: true)
- ..addOption('modules',
- help: 'module pattern to emit',
- allowed: ['es6', 'legacy', 'node'],
- allowedHelp: {
- 'es6': 'es6 modules',
- 'legacy': 'a custom format used by dartdevc, similar to AMD',
- 'node': 'node.js modules (https://nodejs.org/api/modules.html)'
- },
- defaultsTo: 'legacy')
..addFlag('emit-metadata',
help: 'emit metadata annotations queriable via mirrors',
defaultsTo: false)
@@ -301,7 +285,7 @@ class BuildUnit {
/// The name of this module.
final String name;
- /// Library root. All library names are relative to this path/prefix.
+ /// All library names are relative to this path/prefix.
final String libraryRoot;
/// The list of sources in this module.
@@ -331,46 +315,107 @@ class JSModuleFile {
/// The list of messages (errors and warnings)
final List<String> errors;
- /// The JavaScript code for this module.
- ///
- /// If a [sourceMap] is available, this will include the `sourceMappingURL`
- /// comment at end of the file.
- final String code;
+ /// The AST that will be used to generate the [code] and [sourceMap] for this
+ /// module.
+ final JS.Program moduleTree;
- /// The JSON of the source map, if generated, otherwise `null`.
- ///
- /// The source paths will initially be absolute paths. They can be adjusted
- /// using [placeSourceMap].
- final Map sourceMap;
+ /// The compiler options used to generate this module.
+ final CompilerOptions options;
/// The binary contents of the API summary file, including APIs from each of
- /// the [libraries] in this module.
+ /// the libraries in this module.
final List<int> summaryBytes;
JSModuleFile(
- this.name, this.errors, this.code, this.sourceMap, this.summaryBytes);
+ this.name, this.errors, this.options, this.moduleTree, this.summaryBytes);
- JSModuleFile.invalid(this.name, this.errors)
- : code = null,
- sourceMap = null,
+ JSModuleFile.invalid(this.name, this.errors, this.options)
+ : moduleTree = null,
summaryBytes = null;
/// True if this library was successfully compiled.
- bool get isValid => code != null;
+ bool get isValid => moduleTree != null;
- /// Adjusts the source paths in [sourceMap] to be relative to [sourceMapPath],
- /// and returns the new map.
+ /// Gets the source code and source map for this JS module, given the
+ /// locations where the JS file and map file will be served from.
///
- /// See also [writeSourceMap].
- Map placeSourceMap(String sourceMapPath) {
- var dir = path.dirname(sourceMapPath);
-
- var map = new Map.from(this.sourceMap);
- List list = new List.from(map['sources']);
- map['sources'] = list;
- for (int i = 0; i < list.length; i++) {
- list[i] = path.relative(list[i], from: dir);
+ /// Relative URLs will be used to point from the .js file to the .map file
+ //
+ // TODO(jmesserly): this should match our old logic, but I'm not sure we are
+ // correctly handling the pointer from the .js file to the .map file.
+ JSModuleCode getCode(ModuleFormat format, String jsUrl, String mapUrl) {
+ var opts = new JS.JavaScriptPrintingOptions(
+ emitTypes: options.closure,
+ allowKeywordsInProperties: true,
+ allowSingleLineIfStatements: true);
+ JS.SimpleJavaScriptPrintingContext printer;
+ SourceMapBuilder sourceMap;
+ if (options.sourceMap) {
+ var sourceMapContext = new SourceMapPrintingContext();
+ sourceMap = sourceMapContext.sourceMap;
+ printer = sourceMapContext;
+ } else {
+ printer = new JS.SimpleJavaScriptPrintingContext();
+ }
+
+ var tree = transformModuleFormat(format, moduleTree);
+ tree.accept(
+ new JS.Printer(opts, printer, localNamer: new JS.TemporaryNamer(tree)));
+
+ if (options.sourceMap && options.sourceMapComment) {
+ printer.emit('\n//# sourceMappingURL=$mapUrl\n');
}
- return map;
+
+ Map builtMap;
+ if (sourceMap != null) {
+ builtMap = placeSourceMap(sourceMap.build(jsUrl), mapUrl);
+ }
+ return new JSModuleCode(printer.getText(), builtMap);
+ }
+
+ /// Similar to [getCode] but immediately writes the resulting files.
+ ///
+ /// If [mapPath] is not supplied but [options.sourceMap] is set, mapPath
+ /// will default to [jsPath].map.
+ void writeCodeSync(ModuleFormat format, String jsPath, [String mapPath]) {
+ if (mapPath == null) mapPath = jsPath + '.map';
+ var code = getCode(format, jsPath, mapPath);
+ new File(jsPath).writeAsStringSync(code.code);
+ if (code.sourceMap != null) {
+ new File(mapPath).writeAsStringSync(JSON.encode(code.sourceMap));
+ }
+ }
+}
+
+/// The output of compiling a JavaScript module in a particular format.
+class JSModuleCode {
+ /// The JavaScript code for this module.
+ ///
+ /// If a [sourceMap] is available, this will include the `sourceMappingURL`
+ /// comment at end of the file.
+ final String code;
+
+ /// The JSON of the source map, if generated, otherwise `null`.
+ ///
+ /// The source paths will initially be absolute paths. They can be adjusted
+ /// using [placeSourceMap].
+ final Map sourceMap;
+
+ JSModuleCode(this.code, this.sourceMap);
+}
+
+/// Adjusts the source paths in [sourceMap] to be relative to [sourceMapPath],
+/// and returns the new map.
+// TODO(jmesserly): find a new home for this.
+Map placeSourceMap(Map sourceMap, String sourceMapPath) {
+ var dir = path.dirname(sourceMapPath);
+
+ var map = new Map.from(sourceMap);
+ List list = new List.from(map['sources']);
+ map['sources'] = list;
+ for (int i = 0; i < list.length; i++) {
+ list[i] =
+ path.toUri(path.relative(path.fromUri(list[i]), from: dir)).toString();
}
+ return map;
}
« no previous file with comments | « lib/src/compiler/command.dart ('k') | lib/src/compiler/module_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698