Skip to content

Commit

Permalink
Added bin/devrun.dart, which runs DDC's output with iojs or d8 (issue #…
Browse files Browse the repository at this point in the history
  • Loading branch information
ochafik committed Jul 29, 2015
1 parent 05c2e9e commit 8426fa9
Show file tree
Hide file tree
Showing 20 changed files with 577 additions and 269 deletions.
33 changes: 6 additions & 27 deletions pkg/dev_compiler/bin/devc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ library dev_compiler.bin.devc;

import 'dart:io';

import 'package:dev_compiler/devc.dart';
import 'package:dev_compiler/src/compiler.dart' show validateOptions, compile;
import 'package:dev_compiler/src/options.dart';

void _showUsageAndExit() {
Expand All @@ -20,31 +20,10 @@ void _showUsageAndExit() {
exit(1);
}

void main(List<String> args) {
var options = parseOptions(args);
if (options.help) _showUsageAndExit();
main(List<String> args) async {
var options = validateOptions(args);
if (options == null || options.help) _showUsageAndExit();

var srcOpts = options.sourceOptions;
if (!srcOpts.useMockSdk && srcOpts.dartSdkPath == null) {
print('Could not automatically find dart sdk path.');
print('Please pass in explicitly: --dart-sdk <path>');
exit(1);
}

if (options.inputs.length == 0) {
print('Expected filename.');
_showUsageAndExit();
}

setupLogger(options.logLevel, print);

if (options.serverMode) {
new DevServer(options).start();
} else {
var context = createAnalysisContextWithSources(
options.strongOptions, options.sourceOptions);
var reporter = createErrorReporter(context, options);
var success = new BatchCompiler(context, options, reporter: reporter).run();
exit(success ? 0 : 1);
}
bool success = await compile(options);
exit(success ? 0 : 1);
}
78 changes: 78 additions & 0 deletions pkg/dev_compiler/bin/devrun.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env dart
// Copyright (c) 2015, 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.

/// Runs io.js with dev_compiler's generated code.
library dev_compiler.bin.devrun;

import 'dart:io';

import 'package:dev_compiler/src/compiler.dart' show validateOptions, compile;
import 'package:dev_compiler/src/options.dart';
import 'package:dev_compiler/src/runner/runtime_utils.dart' show
listOutputFiles, getMainModuleName;
import 'package:dev_compiler/src/runner/v8_runner.dart' show V8Runner;

import 'package:path/path.dart';


void _showUsageAndExit() {
print('usage: dartdevrun [<options>] <file.dart>\n');
print('<file.dart> is a single Dart file to run.\n');
print('<options> include:\n');
print(argParser.usage);
exit(1);
}

main(List<String> args) async {
args = []..add('--arrow-fn-bind-this')..addAll(args);

CompilerOptions options = validateOptions(args, forceOutDir: true);
if (options == null || options.help) {
_showUsageAndExit();
}
if (options.inputs.length != 1) {
stderr.writeln("Please only specify one input to run");
_showUsageAndExit();
}
var runner = new V8Runner(options);

if (!await compile(options)) exit(1);

var files = await listOutputFiles(options);
var startStatement = 'dart_library.start("${getMainModuleName(options)}");';

// TODO(ochafik): Only generate the html when some flag is set.
await _writeHtmlRunner(options, files, startStatement);

// Give our soul (and streams) away to iojs.
Process process = await runner.start(files, startStatement);
stdin.pipe(process.stdin);
stdout.addStream(process.stdout);
stderr.addStream(process.stderr);
exit(await process.exitCode);
}

/// Generates an HTML file that can be used to run the output with Chrome Dev.
_writeHtmlRunner(CompilerOptions options, List<File> files,
String startStatement) async {
String outputDir = options.codegenOptions.outputDir;
String htmlOutput = join(outputDir, "run.html");
await new File(htmlOutput).writeAsString('''
<html><head></head><body>
${files.map((f) =>
'<script src="${relative(f.path, from: outputDir)}"></script>')
.join("\n")}
<script>$startStatement</script>
</body></html>
''');

stderr.writeln(
'Wrote $htmlOutput. It can be opened in Chrome Dev with the following flags:\n'
'--js-flags="--harmony-arrow-functions '
'--harmony-classes '
'--harmony-computed-property-names '
'--harmony-spreadcalls"'
'\n');
}
13 changes: 9 additions & 4 deletions pkg/dev_compiler/lib/runtime/dart/_isolate_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -916,9 +916,14 @@ dart_library.library('dart/_isolate_helper', null, /* Imports */[
constructors: () => ({_IsolateEvent: [_IsolateEvent, [_IsolateContext, core.Function, core.String]]}),
methods: () => ({process: [dart.void, []]})
});
dart.defineLazyProperties(exports, {
get _global() {
return typeof global == 'undefined' ? self : global;
}
});
class _MainManagerStub extends core.Object {
postMessage(msg) {
self.postMessage(msg);
exports._global.postMessage(msg);
}
}
dart.setSignature(_MainManagerStub, {
Expand All @@ -928,13 +933,13 @@ dart_library.library('dart/_isolate_helper', null, /* Imports */[
let _SPAWN_FAILED_SIGNAL = "spawn failed";
dart.copyProperties(exports, {
get globalWindow() {
return self.window;
return exports._global.window;
},
get globalWorker() {
return self.Worker;
return exports._global.Worker;
},
get globalPostMessageDefined() {
return !!self.postMessage;
return !!exports._global.postMessage;
}
});
let _MainFunction = dart.typedef('_MainFunction', () => dart.functionType(dart.dynamic, []));
Expand Down
6 changes: 3 additions & 3 deletions pkg/dev_compiler/lib/runtime/dart/_js_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -648,10 +648,10 @@ dart_library.library('dart/_js_helper', null, /* Imports */[
Primitives.timerTicks = Primitives.dateNow;
if (typeof window == "undefined")
return;
let window = window;
if (window == null)
let jsWindow = window;
if (jsWindow == null)
return;
let performance = window.performance;
let performance = jsWindow.performance;
if (performance == null)
return;
if (typeof performance.now != "function")
Expand Down
21 changes: 11 additions & 10 deletions pkg/dev_compiler/lib/runtime/dart_library.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
/* This file defines the module loader for the dart runtime.
*/

var dart_library;
var dart_library =
typeof module != "undefined" && module.exports || {};

(function (dart_library) {
'use strict';

Expand Down Expand Up @@ -103,9 +105,7 @@ var dart_library;
function import_(libraryName) {
bootstrap();
let loader = libraries[libraryName];
if (loader == null) {
dart_utils.throwError('library not found: ' + libraryName);
}
if (!loader) dart_utils.throwError('Library not found: ' + libraryName);
return loader.load();
}
dart_library.import = import_;
Expand All @@ -132,11 +132,12 @@ var dart_library;

// TODO(vsm): DOM facades?
// See: https://github.com/dart-lang/dev_compiler/issues/173
NodeList.prototype.get = function(i) { return this[i]; };
NamedNodeMap.prototype.get = function(i) { return this[i]; };
DOMTokenList.prototype.get = function(i) { return this[i]; };
HTMLCollection.prototype.get = function(i) { return this[i]; };

if (typeof NodeList !== "undefined") {
NodeList.prototype.get = function(i) { return this[i]; };
NamedNodeMap.prototype.get = function(i) { return this[i]; };
DOMTokenList.prototype.get = function(i) { return this[i]; };
HTMLCollection.prototype.get = function(i) { return this[i]; };
}
}

})(dart_library || (dart_library = {}));
})(dart_library);
2 changes: 1 addition & 1 deletion pkg/dev_compiler/lib/runtime/dart_runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ dart_library.library('dart_runtime/dart', null, /* Imports */[
}
}

exports.global = window || global;
exports.global = typeof window == "undefined" ? global : window;
exports.JsSymbol = _export(Symbol);

// TODO(vsm): This is referenced (as init.globalState) from
Expand Down
6 changes: 4 additions & 2 deletions pkg/dev_compiler/lib/runtime/dart_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
* by the Dart runtime.
*/

var dart_utils;
var dart_utils =
typeof module != "undefined" && module.exports || {};

(function (dart_utils) {
'use strict';

Expand Down Expand Up @@ -118,4 +120,4 @@ var dart_utils;
}
dart_utils.instantiate = instantiate;

})(dart_utils || (dart_utils = {}));
})(dart_utils);
33 changes: 33 additions & 0 deletions pkg/dev_compiler/lib/src/compiler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import 'codegen/html_codegen.dart' as html_codegen;
import 'codegen/js_codegen.dart';
import 'info.dart'
show AnalyzerMessage, CheckerResults, LibraryInfo, LibraryUnit;
import 'server/server.dart' show DevServer;
import 'options.dart';
import 'report.dart';

Expand All @@ -46,6 +47,37 @@ StreamSubscription setupLogger(Level level, printFn) {
});
}

CompilerOptions validateOptions(List<String> args, {bool forceOutDir: false}) {
var options = parseOptions(args, forceOutDir: forceOutDir);
if (!options.help) {
var srcOpts = options.sourceOptions;
if (!srcOpts.useMockSdk && srcOpts.dartSdkPath == null) {
print('Could not automatically find dart sdk path.');
print('Please pass in explicitly: --dart-sdk <path>');
exit(1);
}
if (options.inputs.length == 0) {
print('Expected filename.');
return null;
}
}
return options;
}

Future<bool> compile(CompilerOptions options) async {
setupLogger(options.logLevel, print);

if (options.serverMode) {
return new DevServer(options).start();
} else {
var context = createAnalysisContextWithSources(
options.strongOptions, options.sourceOptions);
var reporter = createErrorReporter(context, options);
// Note: run returns a bool, turned into a future since this function is async.
return new BatchCompiler(context, options, reporter: reporter).run();
}
}

class BatchCompiler extends AbstractCompiler {
JSGenerator _jsGen;
LibraryElement _dartCore;
Expand Down Expand Up @@ -409,6 +441,7 @@ final defaultRuntimeFiles = () {
'dart_utils.js',
'dart_library.js',
'_errors.js',
'_generators.js',
'_types.js',
'_rtti.js',
'_classes.js',
Expand Down
27 changes: 24 additions & 3 deletions pkg/dev_compiler/lib/src/options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,22 @@ class CodegenOptions {
this.arrowFnBindThisWorkaround: false});
}

/// Options for devrun.
class RunnerOptions {
/// V8-based binary to be used to run the .js output (d8, iojs, node).
/// Can be just the executable name if it's in the path, or a path to the
/// executable.
final String v8Binary;

const RunnerOptions({this.v8Binary: 'iojs'});
}

/// General options used by the dev compiler and server.
class CompilerOptions {
final StrongModeOptions strongOptions;
final SourceResolverOptions sourceOptions;
final CodegenOptions codegenOptions;
final RunnerOptions runnerOptions;

/// Whether to check the sdk libraries.
final bool checkSdk;
Expand Down Expand Up @@ -132,6 +143,7 @@ class CompilerOptions {
{this.strongOptions: const StrongModeOptions(),
this.sourceOptions: const SourceResolverOptions(),
this.codegenOptions: const CodegenOptions(),
this.runnerOptions: const RunnerOptions(),
this.checkSdk: false,
this.dumpInfo: false,
this.dumpInfoFile,
Expand All @@ -149,7 +161,7 @@ class CompilerOptions {
}

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

Expand All @@ -176,12 +188,15 @@ CompilerOptions parseOptions(List<String> argv) {
runtimeDir = _computeRuntimeDir();
}
var outputDir = args['out'];
if (outputDir == null && serverMode) {
if (outputDir == null && (serverMode || forceOutDir)) {
outputDir = Directory.systemTemp.createTempSync("dev_compiler_out_").path;
}
var dumpInfo = args['dump-info'];
if (dumpInfo == null) dumpInfo = serverMode;

var v8Binary = args['v8-binary'];
if (v8Binary == null) v8Binary = 'iojs';

var customUrlMappings = <String, String>{};
for (var mapping in args['url-mapping']) {
var splitMapping = mapping.split(',');
Expand Down Expand Up @@ -213,6 +228,7 @@ CompilerOptions parseOptions(List<String> argv) {
resources:
args['resources'].split(',').where((s) => s.isNotEmpty).toList()),
strongOptions: new StrongModeOptions.fromArguments(args),
runnerOptions: new RunnerOptions(v8Binary: v8Binary),
checkSdk: args['sdk-check'],
dumpInfo: dumpInfo,
dumpInfoFile: args['dump-info-file'],
Expand Down Expand Up @@ -283,6 +299,9 @@ final ArgParser argParser = StrongModeOptions.addArguments(new ArgParser()
..addOption('log', abbr: 'l', help: 'Logging level (defaults to severe)')
..addFlag('dump-info',
abbr: 'i', help: 'Dump summary information', defaultsTo: null)
..addOption('v8-binary',
help: 'V8-based binary to run JavaScript output with (iojs, node, d8)',
defaultsTo: 'iojs')
..addOption('dump-info-file',
abbr: 'f',
help: 'Dump info json file (requires dump-info)',
Expand All @@ -308,7 +327,9 @@ String _computeRuntimeDir() {
if (!new File(lockfile).existsSync()) return null;

// If running from sources we found it!
if (file == 'devc.dart') return path.join(dir, 'lib', 'runtime');
if (file == 'devc.dart' || file == 'devrun.dart') {
return path.join(dir, 'lib', 'runtime');
}

// If running from a pub global snapshot, we need to read the lock file to
// find where the actual sources are located in the pub cache.
Expand Down
17 changes: 17 additions & 0 deletions pkg/dev_compiler/lib/src/runner/file_utils.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2015, 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.

/// File-listing utils used by dartdevrun.
library dev_compiler.src.runner.file_utils;

import 'dart:async';
import 'dart:io';

Future<List<File>> listJsFiles(Directory dir) async {
var list = [];
await for (var file in dir.list(recursive: true, followLinks: true)) {
if (file is File && file.path.endsWith(".js")) list.add(file.absolute);
}
return list;
}
Loading

0 comments on commit 8426fa9

Please sign in to comment.