Skip to content

Commit 8426fa9

Browse files
ochafikOlivier Chafik
authored and
Olivier Chafik
committed
Added bin/devrun.dart, which runs DDC's output with iojs or d8 (issue #225)
1 parent 05c2e9e commit 8426fa9

20 files changed

+577
-269
lines changed

pkg/dev_compiler/bin/devc.dart

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ library dev_compiler.bin.devc;
99

1010
import 'dart:io';
1111

12-
import 'package:dev_compiler/devc.dart';
12+
import 'package:dev_compiler/src/compiler.dart' show validateOptions, compile;
1313
import 'package:dev_compiler/src/options.dart';
1414

1515
void _showUsageAndExit() {
@@ -20,31 +20,10 @@ void _showUsageAndExit() {
2020
exit(1);
2121
}
2222

23-
void main(List<String> args) {
24-
var options = parseOptions(args);
25-
if (options.help) _showUsageAndExit();
23+
main(List<String> args) async {
24+
var options = validateOptions(args);
25+
if (options == null || options.help) _showUsageAndExit();
2626

27-
var srcOpts = options.sourceOptions;
28-
if (!srcOpts.useMockSdk && srcOpts.dartSdkPath == null) {
29-
print('Could not automatically find dart sdk path.');
30-
print('Please pass in explicitly: --dart-sdk <path>');
31-
exit(1);
32-
}
33-
34-
if (options.inputs.length == 0) {
35-
print('Expected filename.');
36-
_showUsageAndExit();
37-
}
38-
39-
setupLogger(options.logLevel, print);
40-
41-
if (options.serverMode) {
42-
new DevServer(options).start();
43-
} else {
44-
var context = createAnalysisContextWithSources(
45-
options.strongOptions, options.sourceOptions);
46-
var reporter = createErrorReporter(context, options);
47-
var success = new BatchCompiler(context, options, reporter: reporter).run();
48-
exit(success ? 0 : 1);
49-
}
27+
bool success = await compile(options);
28+
exit(success ? 0 : 1);
5029
}

pkg/dev_compiler/bin/devrun.dart

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/env dart
2+
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
3+
// for details. All rights reserved. Use of this source code is governed by a
4+
// BSD-style license that can be found in the LICENSE file.
5+
6+
/// Runs io.js with dev_compiler's generated code.
7+
library dev_compiler.bin.devrun;
8+
9+
import 'dart:io';
10+
11+
import 'package:dev_compiler/src/compiler.dart' show validateOptions, compile;
12+
import 'package:dev_compiler/src/options.dart';
13+
import 'package:dev_compiler/src/runner/runtime_utils.dart' show
14+
listOutputFiles, getMainModuleName;
15+
import 'package:dev_compiler/src/runner/v8_runner.dart' show V8Runner;
16+
17+
import 'package:path/path.dart';
18+
19+
20+
void _showUsageAndExit() {
21+
print('usage: dartdevrun [<options>] <file.dart>\n');
22+
print('<file.dart> is a single Dart file to run.\n');
23+
print('<options> include:\n');
24+
print(argParser.usage);
25+
exit(1);
26+
}
27+
28+
main(List<String> args) async {
29+
args = []..add('--arrow-fn-bind-this')..addAll(args);
30+
31+
CompilerOptions options = validateOptions(args, forceOutDir: true);
32+
if (options == null || options.help) {
33+
_showUsageAndExit();
34+
}
35+
if (options.inputs.length != 1) {
36+
stderr.writeln("Please only specify one input to run");
37+
_showUsageAndExit();
38+
}
39+
var runner = new V8Runner(options);
40+
41+
if (!await compile(options)) exit(1);
42+
43+
var files = await listOutputFiles(options);
44+
var startStatement = 'dart_library.start("${getMainModuleName(options)}");';
45+
46+
// TODO(ochafik): Only generate the html when some flag is set.
47+
await _writeHtmlRunner(options, files, startStatement);
48+
49+
// Give our soul (and streams) away to iojs.
50+
Process process = await runner.start(files, startStatement);
51+
stdin.pipe(process.stdin);
52+
stdout.addStream(process.stdout);
53+
stderr.addStream(process.stderr);
54+
exit(await process.exitCode);
55+
}
56+
57+
/// Generates an HTML file that can be used to run the output with Chrome Dev.
58+
_writeHtmlRunner(CompilerOptions options, List<File> files,
59+
String startStatement) async {
60+
String outputDir = options.codegenOptions.outputDir;
61+
String htmlOutput = join(outputDir, "run.html");
62+
await new File(htmlOutput).writeAsString('''
63+
<html><head></head><body>
64+
${files.map((f) =>
65+
'<script src="${relative(f.path, from: outputDir)}"></script>')
66+
.join("\n")}
67+
<script>$startStatement</script>
68+
</body></html>
69+
''');
70+
71+
stderr.writeln(
72+
'Wrote $htmlOutput. It can be opened in Chrome Dev with the following flags:\n'
73+
'--js-flags="--harmony-arrow-functions '
74+
'--harmony-classes '
75+
'--harmony-computed-property-names '
76+
'--harmony-spreadcalls"'
77+
'\n');
78+
}

pkg/dev_compiler/lib/runtime/dart/_isolate_helper.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -916,9 +916,14 @@ dart_library.library('dart/_isolate_helper', null, /* Imports */[
916916
constructors: () => ({_IsolateEvent: [_IsolateEvent, [_IsolateContext, core.Function, core.String]]}),
917917
methods: () => ({process: [dart.void, []]})
918918
});
919+
dart.defineLazyProperties(exports, {
920+
get _global() {
921+
return typeof global == 'undefined' ? self : global;
922+
}
923+
});
919924
class _MainManagerStub extends core.Object {
920925
postMessage(msg) {
921-
self.postMessage(msg);
926+
exports._global.postMessage(msg);
922927
}
923928
}
924929
dart.setSignature(_MainManagerStub, {
@@ -928,13 +933,13 @@ dart_library.library('dart/_isolate_helper', null, /* Imports */[
928933
let _SPAWN_FAILED_SIGNAL = "spawn failed";
929934
dart.copyProperties(exports, {
930935
get globalWindow() {
931-
return self.window;
936+
return exports._global.window;
932937
},
933938
get globalWorker() {
934-
return self.Worker;
939+
return exports._global.Worker;
935940
},
936941
get globalPostMessageDefined() {
937-
return !!self.postMessage;
942+
return !!exports._global.postMessage;
938943
}
939944
});
940945
let _MainFunction = dart.typedef('_MainFunction', () => dart.functionType(dart.dynamic, []));

pkg/dev_compiler/lib/runtime/dart/_js_helper.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -648,10 +648,10 @@ dart_library.library('dart/_js_helper', null, /* Imports */[
648648
Primitives.timerTicks = Primitives.dateNow;
649649
if (typeof window == "undefined")
650650
return;
651-
let window = window;
652-
if (window == null)
651+
let jsWindow = window;
652+
if (jsWindow == null)
653653
return;
654-
let performance = window.performance;
654+
let performance = jsWindow.performance;
655655
if (performance == null)
656656
return;
657657
if (typeof performance.now != "function")

pkg/dev_compiler/lib/runtime/dart_library.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
/* This file defines the module loader for the dart runtime.
66
*/
77

8-
var dart_library;
8+
var dart_library =
9+
typeof module != "undefined" && module.exports || {};
10+
911
(function (dart_library) {
1012
'use strict';
1113

@@ -103,9 +105,7 @@ var dart_library;
103105
function import_(libraryName) {
104106
bootstrap();
105107
let loader = libraries[libraryName];
106-
if (loader == null) {
107-
dart_utils.throwError('library not found: ' + libraryName);
108-
}
108+
if (!loader) dart_utils.throwError('Library not found: ' + libraryName);
109109
return loader.load();
110110
}
111111
dart_library.import = import_;
@@ -132,11 +132,12 @@ var dart_library;
132132

133133
// TODO(vsm): DOM facades?
134134
// See: https://github.com/dart-lang/dev_compiler/issues/173
135-
NodeList.prototype.get = function(i) { return this[i]; };
136-
NamedNodeMap.prototype.get = function(i) { return this[i]; };
137-
DOMTokenList.prototype.get = function(i) { return this[i]; };
138-
HTMLCollection.prototype.get = function(i) { return this[i]; };
139-
135+
if (typeof NodeList !== "undefined") {
136+
NodeList.prototype.get = function(i) { return this[i]; };
137+
NamedNodeMap.prototype.get = function(i) { return this[i]; };
138+
DOMTokenList.prototype.get = function(i) { return this[i]; };
139+
HTMLCollection.prototype.get = function(i) { return this[i]; };
140+
}
140141
}
141142

142-
})(dart_library || (dart_library = {}));
143+
})(dart_library);

pkg/dev_compiler/lib/runtime/dart_runtime.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ dart_library.library('dart_runtime/dart', null, /* Imports */[
2727
}
2828
}
2929

30-
exports.global = window || global;
30+
exports.global = typeof window == "undefined" ? global : window;
3131
exports.JsSymbol = _export(Symbol);
3232

3333
// TODO(vsm): This is referenced (as init.globalState) from

pkg/dev_compiler/lib/runtime/dart_utils.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
* by the Dart runtime.
77
*/
88

9-
var dart_utils;
9+
var dart_utils =
10+
typeof module != "undefined" && module.exports || {};
11+
1012
(function (dart_utils) {
1113
'use strict';
1214

@@ -118,4 +120,4 @@ var dart_utils;
118120
}
119121
dart_utils.instantiate = instantiate;
120122

121-
})(dart_utils || (dart_utils = {}));
123+
})(dart_utils);

pkg/dev_compiler/lib/src/compiler.dart

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import 'codegen/html_codegen.dart' as html_codegen;
3434
import 'codegen/js_codegen.dart';
3535
import 'info.dart'
3636
show AnalyzerMessage, CheckerResults, LibraryInfo, LibraryUnit;
37+
import 'server/server.dart' show DevServer;
3738
import 'options.dart';
3839
import 'report.dart';
3940

@@ -46,6 +47,37 @@ StreamSubscription setupLogger(Level level, printFn) {
4647
});
4748
}
4849

50+
CompilerOptions validateOptions(List<String> args, {bool forceOutDir: false}) {
51+
var options = parseOptions(args, forceOutDir: forceOutDir);
52+
if (!options.help) {
53+
var srcOpts = options.sourceOptions;
54+
if (!srcOpts.useMockSdk && srcOpts.dartSdkPath == null) {
55+
print('Could not automatically find dart sdk path.');
56+
print('Please pass in explicitly: --dart-sdk <path>');
57+
exit(1);
58+
}
59+
if (options.inputs.length == 0) {
60+
print('Expected filename.');
61+
return null;
62+
}
63+
}
64+
return options;
65+
}
66+
67+
Future<bool> compile(CompilerOptions options) async {
68+
setupLogger(options.logLevel, print);
69+
70+
if (options.serverMode) {
71+
return new DevServer(options).start();
72+
} else {
73+
var context = createAnalysisContextWithSources(
74+
options.strongOptions, options.sourceOptions);
75+
var reporter = createErrorReporter(context, options);
76+
// Note: run returns a bool, turned into a future since this function is async.
77+
return new BatchCompiler(context, options, reporter: reporter).run();
78+
}
79+
}
80+
4981
class BatchCompiler extends AbstractCompiler {
5082
JSGenerator _jsGen;
5183
LibraryElement _dartCore;
@@ -409,6 +441,7 @@ final defaultRuntimeFiles = () {
409441
'dart_utils.js',
410442
'dart_library.js',
411443
'_errors.js',
444+
'_generators.js',
412445
'_types.js',
413446
'_rtti.js',
414447
'_classes.js',

pkg/dev_compiler/lib/src/options.dart

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,22 @@ class CodegenOptions {
7676
this.arrowFnBindThisWorkaround: false});
7777
}
7878

79+
/// Options for devrun.
80+
class RunnerOptions {
81+
/// V8-based binary to be used to run the .js output (d8, iojs, node).
82+
/// Can be just the executable name if it's in the path, or a path to the
83+
/// executable.
84+
final String v8Binary;
85+
86+
const RunnerOptions({this.v8Binary: 'iojs'});
87+
}
88+
7989
/// General options used by the dev compiler and server.
8090
class CompilerOptions {
8191
final StrongModeOptions strongOptions;
8292
final SourceResolverOptions sourceOptions;
8393
final CodegenOptions codegenOptions;
94+
final RunnerOptions runnerOptions;
8495

8596
/// Whether to check the sdk libraries.
8697
final bool checkSdk;
@@ -132,6 +143,7 @@ class CompilerOptions {
132143
{this.strongOptions: const StrongModeOptions(),
133144
this.sourceOptions: const SourceResolverOptions(),
134145
this.codegenOptions: const CodegenOptions(),
146+
this.runnerOptions: const RunnerOptions(),
135147
this.checkSdk: false,
136148
this.dumpInfo: false,
137149
this.dumpInfoFile,
@@ -149,7 +161,7 @@ class CompilerOptions {
149161
}
150162

151163
/// Parses options from the command-line
152-
CompilerOptions parseOptions(List<String> argv) {
164+
CompilerOptions parseOptions(List<String> argv, {bool forceOutDir: false}) {
153165
ArgResults args = argParser.parse(argv);
154166
bool showUsage = args['help'];
155167

@@ -176,12 +188,15 @@ CompilerOptions parseOptions(List<String> argv) {
176188
runtimeDir = _computeRuntimeDir();
177189
}
178190
var outputDir = args['out'];
179-
if (outputDir == null && serverMode) {
191+
if (outputDir == null && (serverMode || forceOutDir)) {
180192
outputDir = Directory.systemTemp.createTempSync("dev_compiler_out_").path;
181193
}
182194
var dumpInfo = args['dump-info'];
183195
if (dumpInfo == null) dumpInfo = serverMode;
184196

197+
var v8Binary = args['v8-binary'];
198+
if (v8Binary == null) v8Binary = 'iojs';
199+
185200
var customUrlMappings = <String, String>{};
186201
for (var mapping in args['url-mapping']) {
187202
var splitMapping = mapping.split(',');
@@ -213,6 +228,7 @@ CompilerOptions parseOptions(List<String> argv) {
213228
resources:
214229
args['resources'].split(',').where((s) => s.isNotEmpty).toList()),
215230
strongOptions: new StrongModeOptions.fromArguments(args),
231+
runnerOptions: new RunnerOptions(v8Binary: v8Binary),
216232
checkSdk: args['sdk-check'],
217233
dumpInfo: dumpInfo,
218234
dumpInfoFile: args['dump-info-file'],
@@ -283,6 +299,9 @@ final ArgParser argParser = StrongModeOptions.addArguments(new ArgParser()
283299
..addOption('log', abbr: 'l', help: 'Logging level (defaults to severe)')
284300
..addFlag('dump-info',
285301
abbr: 'i', help: 'Dump summary information', defaultsTo: null)
302+
..addOption('v8-binary',
303+
help: 'V8-based binary to run JavaScript output with (iojs, node, d8)',
304+
defaultsTo: 'iojs')
286305
..addOption('dump-info-file',
287306
abbr: 'f',
288307
help: 'Dump info json file (requires dump-info)',
@@ -308,7 +327,9 @@ String _computeRuntimeDir() {
308327
if (!new File(lockfile).existsSync()) return null;
309328

310329
// If running from sources we found it!
311-
if (file == 'devc.dart') return path.join(dir, 'lib', 'runtime');
330+
if (file == 'devc.dart' || file == 'devrun.dart') {
331+
return path.join(dir, 'lib', 'runtime');
332+
}
312333

313334
// If running from a pub global snapshot, we need to read the lock file to
314335
// find where the actual sources are located in the pub cache.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// File-listing utils used by dartdevrun.
6+
library dev_compiler.src.runner.file_utils;
7+
8+
import 'dart:async';
9+
import 'dart:io';
10+
11+
Future<List<File>> listJsFiles(Directory dir) async {
12+
var list = [];
13+
await for (var file in dir.list(recursive: true, followLinks: true)) {
14+
if (file is File && file.path.endsWith(".js")) list.add(file.absolute);
15+
}
16+
return list;
17+
}

0 commit comments

Comments
 (0)