d9944433af
Make the constant evaluator take an explicit error reporter so we have to opt in to using the "simple" one that reports errors in an ad hoc way. This is the start of a change to use Fasta-controlled error messages throughout and eventually get rid of the simple error handler, and to continue constant evaluation after the first constant error. Change-Id: If6b1801edab6063754b642cf4a603abf9d63103a Reviewed-on: https://dart-review.googlesource.com/c/89501 Commit-Queue: Kevin Millikin <kmillikin@google.com> Auto-Submit: Kevin Millikin <kmillikin@google.com> Reviewed-by: Peter von der Ahé <ahe@google.com> Reviewed-by: Aske Simon Christensen <askesc@google.com>
139 lines
4.6 KiB
Dart
Executable File
139 lines
4.6 KiB
Dart
Executable File
#!/usr/bin/env dart
|
|
// Copyright (c) 2016, 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.
|
|
|
|
import 'dart:async';
|
|
import 'dart:io';
|
|
|
|
import 'package:args/args.dart';
|
|
import 'package:kernel/class_hierarchy.dart';
|
|
import 'package:kernel/core_types.dart';
|
|
import 'package:kernel/kernel.dart';
|
|
import 'package:kernel/src/tool/batch_util.dart';
|
|
import 'package:kernel/target/targets.dart';
|
|
|
|
import 'package:kernel/transformations/constants.dart' as constants
|
|
show SimpleErrorReporter, transformComponent;
|
|
|
|
import 'package:kernel/transformations/continuation.dart' as cont;
|
|
import 'package:kernel/transformations/empty.dart' as empty;
|
|
import 'package:kernel/transformations/method_call.dart' as method_call;
|
|
import 'package:kernel/transformations/mixin_full_resolution.dart' as mix;
|
|
import 'package:kernel/transformations/treeshaker.dart' as treeshaker;
|
|
import 'package:kernel/transformations/coq.dart' as coq;
|
|
import 'package:kernel/vm/constants_native_effects.dart';
|
|
import 'package:kernel/src/tool/command_line_util.dart';
|
|
|
|
ArgParser parser = new ArgParser()
|
|
..addOption('format',
|
|
abbr: 'f',
|
|
allowed: ['text', 'bin'],
|
|
defaultsTo: 'bin',
|
|
help: 'Output format.')
|
|
..addOption('out', abbr: 'o', help: 'Output file.', defaultsTo: null)
|
|
..addFlag('verbose',
|
|
abbr: 'v',
|
|
negatable: false,
|
|
help: 'Be verbose (e.g. prints transformed main library).',
|
|
defaultsTo: false)
|
|
..addMultiOption('embedder-entry-points-manifest',
|
|
help: 'A path to a file describing entrypoints '
|
|
'(lines of the form `<library>,<class>,<member>`).')
|
|
..addOption('transformation',
|
|
abbr: 't',
|
|
help: 'The transformation to apply.',
|
|
defaultsTo: 'continuation');
|
|
|
|
main(List<String> arguments) async {
|
|
if (arguments.isNotEmpty && arguments[0] == '--batch') {
|
|
if (arguments.length != 1) {
|
|
throw '--batch cannot be used with other arguments';
|
|
}
|
|
await runBatch((arguments) => runTransformation(arguments));
|
|
} else {
|
|
CompilerOutcome outcome = await runTransformation(arguments);
|
|
exit(outcome == CompilerOutcome.Ok ? 0 : 1);
|
|
}
|
|
}
|
|
|
|
Future<CompilerOutcome> runTransformation(List<String> arguments) async {
|
|
ArgResults options = parser.parse(arguments);
|
|
|
|
if (options.rest.length != 1) {
|
|
throw 'Usage:\n${parser.usage}';
|
|
}
|
|
|
|
var input = options.rest.first;
|
|
var output = options['out'];
|
|
var format = options['format'];
|
|
var verbose = options['verbose'];
|
|
|
|
if (output == null) {
|
|
output = '${input.substring(0, input.lastIndexOf('.'))}.transformed.dill';
|
|
}
|
|
|
|
List<String> embedderEntryPointManifests =
|
|
options['embedder-entry-points-manifest'] as List<String>;
|
|
List<treeshaker.ProgramRoot> programRoots =
|
|
parseProgramRoots(embedderEntryPointManifests);
|
|
|
|
var component = loadComponentFromBinary(input);
|
|
|
|
final coreTypes = new CoreTypes(component);
|
|
final hierarchy = new ClassHierarchy(component);
|
|
switch (options['transformation']) {
|
|
case 'continuation':
|
|
component = cont.transformComponent(coreTypes, component);
|
|
break;
|
|
case 'resolve-mixins':
|
|
mix.transformLibraries(
|
|
new NoneTarget(null), coreTypes, hierarchy, component.libraries);
|
|
break;
|
|
case 'coq':
|
|
component = coq.transformComponent(coreTypes, component);
|
|
break;
|
|
case 'constants':
|
|
// We use the -D defines supplied to this VM instead of explicitly using a
|
|
// constructed map of constants.
|
|
final Map<String, String> defines = null;
|
|
final VmConstantsBackend backend =
|
|
new VmConstantsBackend(defines, coreTypes);
|
|
component = constants.transformComponent(
|
|
component, backend, const constants.SimpleErrorReporter(),
|
|
legacyMode: true);
|
|
break;
|
|
case 'treeshake':
|
|
component = treeshaker.transformComponent(coreTypes, hierarchy, component,
|
|
programRoots: programRoots, legacyMode: true);
|
|
break;
|
|
case 'methodcall':
|
|
component =
|
|
method_call.transformComponent(coreTypes, hierarchy, component);
|
|
break;
|
|
case 'empty':
|
|
component = empty.transformComponent(component);
|
|
break;
|
|
default:
|
|
throw 'Unknown transformation';
|
|
}
|
|
|
|
// TODO(30631): Fix the verifier so we can check that the transform produced
|
|
// valid output.
|
|
//
|
|
// verifyComponent(component);
|
|
|
|
if (format == 'text') {
|
|
writeComponentToText(component, path: output);
|
|
} else {
|
|
assert(format == 'bin');
|
|
await writeComponentToBinary(component, output);
|
|
}
|
|
|
|
if (verbose) {
|
|
writeLibraryToText(component.mainMethod.parent as Library);
|
|
}
|
|
|
|
return CompilerOutcome.Ok;
|
|
}
|