Skip to content

Commit

Permalink
[dartdevc] add --kernel option, deprecate bin/dartdevk
Browse files Browse the repository at this point in the history
`dartdevc --kernel` is now equivalent to the old `dartdevk` command.
This will make migration easier, as it's now just a flag to enable
CFE/Kernel. `dartdevk` is now deprecated, but it can be supported for
a while as it just calls `dartdevc --kernel`.

Change-Id: Ib8d09f74556740a3af11c753f80cd87bd4a09044
Reviewed-on: https://dart-review.googlesource.com/76566
Reviewed-by: Vijay Menon <vsm@google.com>
Commit-Queue: Jenny Messerly <jmesserly@google.com>
  • Loading branch information
Jenny Messerly authored and commit-bot@chromium.org committed Sep 26, 2018
1 parent 79d639a commit d673847
Show file tree
Hide file tree
Showing 8 changed files with 302 additions and 232 deletions.
73 changes: 43 additions & 30 deletions pkg/dev_compiler/bin/dartdevc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,65 +9,78 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/command_line/arguments.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
import 'package:bazel_worker/bazel_worker.dart';
import 'package:dev_compiler/src/analyzer/command.dart';
import 'package:dev_compiler/src/compiler/shared_command.dart';

Future main(List<String> args) async {
// Always returns a new modifiable list.
args = preprocessArgs(PhysicalResourceProvider.INSTANCE, args);
var parsedArgs = ParsedArguments.from(args);

if (args.contains('--persistent_worker')) {
await _CompilerWorker(args..remove('--persistent_worker')).run();
} else if (args.isNotEmpty && args.last == "--batch") {
await runBatch(args.sublist(0, args.length - 1));
if (parsedArgs.isWorker) {
await _CompilerWorker(parsedArgs).run();
} else if (parsedArgs.isBatch) {
await runBatch(parsedArgs);
} else {
exitCode = compile(args);
var result = await compile(parsedArgs);
exitCode = result.exitCode;
}
}

/// Runs the compiler worker loop.
class _CompilerWorker extends AsyncWorkerLoop {
/// The original args supplied to the executable.
final List<String> _startupArgs;
final ParsedArguments _startupArgs;
InitializedCompilerState _compilerState;

_CompilerWorker(this._startupArgs) : super();

/// Performs each individual work request.
Future<WorkResponse> performRequest(WorkRequest request) async {
var args = _startupArgs.toList()..addAll(request.arguments);

var args = _startupArgs.merge(request.arguments);
var output = StringBuffer();
var exitCode = compile(args, printFn: output.writeln);
AnalysisEngine.instance.clearCaches();
var result = await runZoned(
() => compile(args, compilerState: _compilerState), zoneSpecification:
ZoneSpecification(print: (self, parent, zone, message) {
output.writeln(message.toString());
}));
_compilerState = result.compilerState;
return WorkResponse()
..exitCode = exitCode
..exitCode = result.success ? 0 : 1
..output = output.toString();
}
}

runBatch(List<String> batchArgs) async {
int totalTests = 0;
int testsFailed = 0;
/// Runs dartdevk in batch mode for test.dart.
Future runBatch(ParsedArguments batchArgs) async {
var totalTests = 0;
var failedTests = 0;
var watch = Stopwatch()..start();

print('>>> BATCH START');

String line;
while ((line = stdin.readLineSync(encoding: utf8)).isNotEmpty) {
InitializedCompilerState compilerState;

while ((line = stdin.readLineSync(encoding: utf8))?.isNotEmpty == true) {
totalTests++;
var args = batchArgs.toList()..addAll(line.split(RegExp(r'\s+')));
var args = batchArgs.merge(line.split(RegExp(r'\s+')));

String outcome;
try {
var result = await compile(args, compilerState: compilerState);
compilerState = result.compilerState;
outcome = result.success ? 'PASS' : (result.crashed ? 'CRASH' : 'FAIL');
} catch (e, s) {
outcome = 'CRASH';
print('Unhandled exception:');
print(e);
print(s);
}

// We don't try/catch here, since `compile` should handle that.
var compileExitCode = compile(args);
AnalysisEngine.instance.clearCaches();
stderr.writeln('>>> EOF STDERR');
var outcome = compileExitCode == 0
? 'PASS'
: compileExitCode == 70 ? 'CRASH' : 'FAIL';
print('>>> TEST $outcome ${watch.elapsedMilliseconds}ms');
}
int time = watch.elapsedMilliseconds;
print('>>> BATCH END '
'(${totalTests - testsFailed})/$totalTests ${time}ms');

var time = watch.elapsedMilliseconds;
print('>>> BATCH END (${totalTests - failedTests})/$totalTests ${time}ms');
}
137 changes: 3 additions & 134 deletions pkg/dev_compiler/bin/dartdevk.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,139 +3,8 @@
// 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.

import 'dartdevc.dart' as dartdevc;

/// Experimental command line entry point for Dart Development Compiler.
/// Unlike `dartdevc` this version uses the shared front end and IR.
import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:bazel_worker/bazel_worker.dart';
import 'package:dev_compiler/src/kernel/command.dart';
import 'package:front_end/src/api_unstable/ddc.dart' as fe;

Future main(List<String> args) async {
var parsedArgs = _preprocessArgs(args);
if (parsedArgs.isBatch) {
await runBatch(parsedArgs.args);
} else if (parsedArgs.isWorker) {
await _CompilerWorker(parsedArgs.args).run();
} else {
var result = await compile(parsedArgs.args);
exitCode = result.success ? 0 : 1;
}
}

/// Runs dartdevk in batch mode for test.dart.
Future runBatch(List<String> batchArgs) async {
var tests = 0;
var failed = 0;
var watch = Stopwatch()..start();

print('>>> BATCH START');

String line;
fe.InitializedCompilerState compilerState;

while ((line = stdin.readLineSync(encoding: utf8))?.isNotEmpty == true) {
tests++;
var args = batchArgs.toList()..addAll(line.split(RegExp(r'\s+')));

String outcome;
try {
var result = await compile(args, compilerState: compilerState);
compilerState = result.compilerState;
outcome = result.success ? 'PASS' : 'FAIL';
} catch (e, s) {
outcome = 'CRASH';
print('Unhandled exception:');
print(e);
print(s);
}

// TODO(rnystrom): If kernel has any internal static state that needs to
// be cleared, do it here.

stderr.writeln('>>> EOF STDERR');
print('>>> TEST $outcome ${watch.elapsedMilliseconds}ms');
}

var time = watch.elapsedMilliseconds;
print('>>> BATCH END (${tests - failed})/$tests ${time}ms');
}

/// Runs the compiler worker loop.
class _CompilerWorker extends AsyncWorkerLoop {
/// The original args supplied to the executable.
final List<String> _startupArgs;

_CompilerWorker(this._startupArgs) : super();

/// Performs each individual work request.
Future<WorkResponse> performRequest(WorkRequest request) async {
var args = _startupArgs.toList()..addAll(request.arguments);

var output = StringBuffer();
var result = await runZoned(() => compile(args), zoneSpecification:
ZoneSpecification(print: (self, parent, zone, message) {
output.writeln(message.toString());
}));
return WorkResponse()
..exitCode = result.success ? 0 : 1
..output = output.toString();
}
}

/// Preprocess arguments to determine whether DDK is used in batch mode or as a
/// persistent worker.
///
/// When used in batch mode, we expect a `--batch` parameter last.
///
/// When used as a persistent bazel worker, the `--persistent_worker` might be
/// present, and an argument of the form `@path/to/file` might be provided. The
/// latter needs to be replaced by reading all the contents of the
/// file and expanding them into the resulting argument list.
_ParsedArgs _preprocessArgs(List<String> args) {
if (args.isEmpty) return _ParsedArgs(false, false, args);

String lastArg = args.last;
if (lastArg == '--batch') {
return _ParsedArgs(true, false, args.sublist(0, args.length - 1));
}

var newArgs = <String>[];
bool isWorker = false;
var len = args.length;
for (int i = 0; i < len; i++) {
var arg = args[i];
if (i == len - 1 && arg.startsWith('@')) {
newArgs.addAll(_readLines(arg.substring(1)));
} else if (arg == '--persistent_worker') {
isWorker = true;
} else {
newArgs.add(arg);
}
}
return _ParsedArgs(false, isWorker, newArgs);
}

/// Return all lines in a file found at [path].
Iterable<String> _readLines(String path) {
try {
return File(path)
.readAsStringSync()
.replaceAll('\r\n', '\n')
.replaceAll('\r', '\n')
.split('\n')
.where((String line) => line.isNotEmpty);
} on FileSystemException catch (e) {
throw Exception('Failed to read $path: $e');
}
}

class _ParsedArgs {
final bool isBatch;
final bool isWorker;
final List<String> args;

_ParsedArgs(this.isBatch, this.isWorker, this.args);
}
main(List<String> args) => dartdevc.main(args.toList()..add('--kernel'));
7 changes: 3 additions & 4 deletions pkg/dev_compiler/lib/src/analyzer/context.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import 'package:analyzer/src/generated/source.dart'
import 'package:analyzer/src/summary/package_bundle_reader.dart'
show InSummaryUriResolver, SummaryDataStore;
import 'package:args/args.dart' show ArgParser, ArgResults;
import 'package:cli_util/cli_util.dart' show getSdkDir;
import 'package:cli_util/cli_util.dart' show getSdkPath;
import 'package:path/path.dart' as path;

// ignore_for_file: deprecated_member_use
Expand Down Expand Up @@ -46,7 +46,7 @@ class AnalyzerOptions {
{this.contextBuilderOptions,
String dartSdkPath,
this.customUrlMappings = const {}})
: dartSdkPath = dartSdkPath ?? getSdkDir().path {
: dartSdkPath = dartSdkPath ?? getSdkPath() {
contextBuilderOptions.declaredVariables ??= const {};
}

Expand All @@ -65,8 +65,7 @@ class AnalyzerOptions {
createContextBuilderOptions(args, trackCacheDependencies: false);
(contextOpts.defaultOptions as AnalysisOptionsImpl).previewDart2 = true;

var dartSdkPath = args['dart-sdk'] as String ?? getSdkDir().path;

var dartSdkPath = args['dart-sdk'] as String ?? getSdkPath();
dartSdkSummaryPath ??= contextOpts.dartSdkSummaryPath ??
path.join(dartSdkPath, 'lib', '_internal', 'ddc_sdk.sum');
// For building the SDK, we explicitly set the path to none.
Expand Down
Loading

0 comments on commit d673847

Please sign in to comment.