| Index: tools/testing/dart/compiler_configuration.dart
 | 
| diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
 | 
| index 49368ce1cc60234084f1e0b2310966c7de4bd1df..2ad03e4cab92b70a7f77fc6adc97de16626bdd58 100644
 | 
| --- a/tools/testing/dart/compiler_configuration.dart
 | 
| +++ b/tools/testing/dart/compiler_configuration.dart
 | 
| @@ -89,6 +89,19 @@ abstract class CompilerConfiguration {
 | 
|              arch: configuration['arch'],
 | 
|              useBlobs: useBlobs,
 | 
|              isAndroid: configuration['system'] == 'android');
 | 
| +      case 'dartk':
 | 
| +        return ComposedCompilerConfiguration.createDartKConfiguration(
 | 
| +            isHostChecked: isHostChecked,
 | 
| +            kernel_transformers: configuration['kernel_transformers'],
 | 
| +            useSdk: useSdk);
 | 
| +      case 'dartkp':
 | 
| +        return ComposedCompilerConfiguration.createDartKPConfiguration(
 | 
| +            isHostChecked: isHostChecked,
 | 
| +            arch: configuration['arch'],
 | 
| +            useBlobs: useBlobs,
 | 
| +            isAndroid: configuration['system'] == 'android',
 | 
| +            kernel_transformers: configuration['kernel_transformers'],
 | 
| +            useSdk: useSdk);
 | 
|        case 'none':
 | 
|          return new NoneCompilerConfiguration(
 | 
|              isDebug: isDebug,
 | 
| @@ -199,6 +212,257 @@ class NoneCompilerConfiguration extends CompilerConfiguration {
 | 
|    }
 | 
|  }
 | 
|  
 | 
| +/// The "dartk" compiler.
 | 
| +class DartKCompilerConfiguration extends CompilerConfiguration {
 | 
| +  DartKCompilerConfiguration({bool isHostChecked, bool useSdk})
 | 
| +      : super._subclass(isHostChecked: isHostChecked, useSdk: useSdk);
 | 
| +
 | 
| +  @override
 | 
| +  String computeCompilerPath(String buildDir) {
 | 
| +    return 'third_party/pkg/kernel/bin/dartk.dart';
 | 
| +  }
 | 
| +
 | 
| +  CompilationCommand computeCompilationCommand(
 | 
| +      String outputFileName,
 | 
| +      String buildDir,
 | 
| +      CommandBuilder commandBuilder,
 | 
| +      List arguments,
 | 
| +      Map<String, String> environmentOverrides) {
 | 
| +    var extraArguments = [
 | 
| +      '--sdk',
 | 
| +      '$buildDir/obj/gen/patched_sdk',
 | 
| +      '--link',
 | 
| +      '--target=vm',
 | 
| +      '--out',
 | 
| +      outputFileName
 | 
| +    ];
 | 
| +    return commandBuilder.getKernelCompilationCommand(
 | 
| +        'dartk',
 | 
| +        outputFileName,
 | 
| +        true,
 | 
| +        bootstrapDependencies(buildDir),
 | 
| +        computeCompilerPath(buildDir),
 | 
| +        []..addAll(arguments)..addAll(extraArguments),
 | 
| +        environmentOverrides);
 | 
| +  }
 | 
| +
 | 
| +  CommandArtifact computeCompilationArtifact(
 | 
| +      String buildDir,
 | 
| +      String tempDir,
 | 
| +      CommandBuilder commandBuilder,
 | 
| +      List arguments,
 | 
| +      Map<String, String> environmentOverrides) {
 | 
| +    return new CommandArtifact(<Command>[
 | 
| +      this.computeCompilationCommand('$tempDir/out.dill', buildDir,
 | 
| +          CommandBuilder.instance, arguments, environmentOverrides)
 | 
| +    ], '$tempDir/out.dill', 'application/dart');
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +typedef List<String> CompilerArgumentsFunction(
 | 
| +    List<String> globalArguments,
 | 
| +    String previousCompilerOutput);
 | 
| +
 | 
| +class PipelineCommand {
 | 
| +  final CompilerConfiguration compilerConfiguration;
 | 
| +  final CompilerArgumentsFunction _argumentsFunction;
 | 
| +
 | 
| +  PipelineCommand._(this.compilerConfiguration, this._argumentsFunction);
 | 
| +
 | 
| +  factory PipelineCommand.runWithGlobalArguments(CompilerConfiguration conf) {
 | 
| +    return new PipelineCommand._(conf, (List<String> globalArguments,
 | 
| +                                        String previousOutput) {
 | 
| +      assert(previousOutput == null);
 | 
| +      return globalArguments;
 | 
| +    });
 | 
| +  }
 | 
| +
 | 
| +  factory PipelineCommand.runWithDartOrKernelFile(CompilerConfiguration conf) {
 | 
| +    return new PipelineCommand._(conf, (List<String> globalArguments,
 | 
| +                                        String previousOutput) {
 | 
| +      var filtered = globalArguments
 | 
| +        .where((String name) => name.endsWith('.dart') ||
 | 
| +                                name.endsWith('.dill'))
 | 
| +        .toList();
 | 
| +      assert(filtered.length == 1);
 | 
| +      return filtered;
 | 
| +    });
 | 
| +  }
 | 
| +
 | 
| +  factory PipelineCommand.runWithPreviousKernelOutput(
 | 
| +      CompilerConfiguration conf) {
 | 
| +    return new PipelineCommand._(conf, (List<String> globalArguments,
 | 
| +                                        String previousOutput) {
 | 
| +      assert(previousOutput.endsWith('.dill'));
 | 
| +      return [previousOutput];
 | 
| +    });
 | 
| +  }
 | 
| +
 | 
| +  List<String> extractArguments(List<String> globalArguments,
 | 
| +                                String previousOutput) {
 | 
| +    return _argumentsFunction(globalArguments, previousOutput);
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +class ComposedCompilerConfiguration extends CompilerConfiguration {
 | 
| +  final List<PipelineCommand> pipelineCommands;
 | 
| +
 | 
| +  ComposedCompilerConfiguration(this.pipelineCommands)
 | 
| +      : super._subclass();
 | 
| +
 | 
| +  CommandArtifact computeCompilationArtifact(
 | 
| +      String buildDir,
 | 
| +      String tempDir,
 | 
| +      CommandBuilder commandBuilder,
 | 
| +      List globalArguments,
 | 
| +      Map<String, String> environmentOverrides) {
 | 
| +
 | 
| +    List<Command> allCommands = [];
 | 
| +
 | 
| +    // The first compilation command is as usual.
 | 
| +    var arguments = pipelineCommands[0].extractArguments(globalArguments, null);
 | 
| +    CommandArtifact artifact =
 | 
| +        pipelineCommands[0].compilerConfiguration.computeCompilationArtifact(
 | 
| +          buildDir, tempDir, commandBuilder, arguments, environmentOverrides);
 | 
| +    allCommands.addAll(artifact.commands);
 | 
| +
 | 
| +    // The following compilation commands are based on the output of the
 | 
| +    // previous one.
 | 
| +    for (int i = 1; i < pipelineCommands.length; i++) {
 | 
| +      PipelineCommand pc = pipelineCommands[i];
 | 
| +
 | 
| +      arguments = pc.extractArguments(globalArguments, artifact.filename);
 | 
| +      artifact = pc.compilerConfiguration.computeCompilationArtifact(
 | 
| +          buildDir, tempDir, commandBuilder, arguments, environmentOverrides);
 | 
| +
 | 
| +      allCommands.addAll(artifact.commands);
 | 
| +    }
 | 
| +
 | 
| +    return new CommandArtifact(
 | 
| +        allCommands, artifact.filename, artifact.mimeType);
 | 
| +  }
 | 
| +
 | 
| +  List<String> computeCompilerArguments(vmOptions, sharedOptions, args) {
 | 
| +    // The result will be passed as an input to [extractArguments]
 | 
| +    // (i.e. the arguments to the [PipelineCommand]).
 | 
| +    return new List<String>.from(sharedOptions)..addAll(args);
 | 
| +  }
 | 
| +
 | 
| +  List<String> computeRuntimeArguments(
 | 
| +      RuntimeConfiguration runtimeConfiguration,
 | 
| +      String buildDir,
 | 
| +      TestInformation info,
 | 
| +      List<String> vmOptions,
 | 
| +      List<String> sharedOptions,
 | 
| +      List<String> originalArguments,
 | 
| +      CommandArtifact artifact) {
 | 
| +    return <String>[artifact.filename];
 | 
| +  }
 | 
| +
 | 
| +  static ComposedCompilerConfiguration createDartKPConfiguration(
 | 
| +      {bool isHostChecked, String arch, bool useBlobs, bool isAndroid,
 | 
| +       String kernel_transformers, bool useSdk}) {
 | 
| +    var nested = [];
 | 
| +
 | 
| +    // Compile with dartk.
 | 
| +    nested.add(new PipelineCommand.runWithGlobalArguments(
 | 
| +        new DartKCompilerConfiguration(isHostChecked: isHostChecked,
 | 
| +            useSdk: useSdk)));
 | 
| +
 | 
| +    // Run zero or more transformations.
 | 
| +    addKernelTransformations(nested, kernel_transformers);
 | 
| +
 | 
| +    // Run the normal precompiler.
 | 
| +    nested.add(new PipelineCommand.runWithPreviousKernelOutput(
 | 
| +        new PrecompilerCompilerConfiguration(
 | 
| +          arch: arch, useBlobs: useBlobs, isAndroid: isAndroid)));
 | 
| +
 | 
| +    return new ComposedCompilerConfiguration(nested);
 | 
| +  }
 | 
| +
 | 
| +  static ComposedCompilerConfiguration createDartKConfiguration(
 | 
| +      {bool isHostChecked, bool useSdk, String kernel_transformers}) {
 | 
| +    var nested = [];
 | 
| +
 | 
| +    // Compile with dartk.
 | 
| +    nested.add(new PipelineCommand.runWithGlobalArguments(
 | 
| +        new DartKCompilerConfiguration(isHostChecked: isHostChecked,
 | 
| +            useSdk: useSdk)));
 | 
| +
 | 
| +    // Run zero or more transformations.
 | 
| +    addKernelTransformations(nested, kernel_transformers);
 | 
| +
 | 
| +    return new ComposedCompilerConfiguration(nested);
 | 
| +  }
 | 
| +
 | 
| +  static void addKernelTransformations(List<PipelineCommand> nested,
 | 
| +                                       String kernel_transformers) {
 | 
| +    if (kernel_transformers != null && kernel_transformers.length > 0) {
 | 
| +      List<String> names = kernel_transformers.split(',');
 | 
| +      for (var name in names) {
 | 
| +        var transformation = new KernelTransformation(name);
 | 
| +        nested.add(nested.isEmpty
 | 
| +            ? new PipelineCommand.runWithDartOrKernelFile(transformation)
 | 
| +            : new PipelineCommand.runWithPreviousKernelOutput(transformation));
 | 
| +      }
 | 
| +    }
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +class KernelTransformation extends CompilerConfiguration {
 | 
| +  final String transformation;
 | 
| +
 | 
| +  KernelTransformation(this.transformation) : super._subclass();
 | 
| +
 | 
| +  CommandArtifact computeCompilationArtifact(
 | 
| +      String buildDir,
 | 
| +      String tempDir,
 | 
| +      CommandBuilder commandBuilder,
 | 
| +      List arguments,
 | 
| +      Map<String, String> environmentOverrides) {
 | 
| +    assert(arguments.length == 1);
 | 
| +    assert(arguments.last.contains('/'));
 | 
| +    assert(arguments.last.endsWith('.dill'));
 | 
| +
 | 
| +    // The --kernel-transformers=a,b can be specified as
 | 
| +    //    a = <name>
 | 
| +    //    a = <name>:<path-to-transformer-executable>
 | 
| +    int colonIndex = transformation.indexOf(':');
 | 
| +    String transformationName = transformation;
 | 
| +    String executable;
 | 
| +    if (colonIndex > 0) {
 | 
| +      executable = transformation.substring(colonIndex + 1);
 | 
| +      transformationName = transformation.substring(0, colonIndex);
 | 
| +    }
 | 
| +
 | 
| +    // The transformed output will be always written to a new file in the
 | 
| +    // test-specific temporary directory.
 | 
| +    var inputFile = arguments.last;
 | 
| +    var baseInputFilename = inputFile.substring(
 | 
| +        inputFile.lastIndexOf('/') + 1, inputFile.length - '.dill'.length);
 | 
| +    var outputFile = '$tempDir/$baseInputFilename.$transformationName.dill';
 | 
| +
 | 
| +    // Use the user-supplied transformer or fall back to `transformer.dart`.
 | 
| +    List<String> transformerArguments;
 | 
| +    bool useBatchMode = false;
 | 
| +    if (executable == null) {
 | 
| +      executable = 'third_party/pkg/kernel/bin/transform.dart';
 | 
| +      transformerArguments =
 | 
| +          ['-f', 'bin', '-t', transformation, '-o', outputFile, inputFile];
 | 
| +      useBatchMode = true;
 | 
| +    } else {
 | 
| +      transformerArguments = [inputFile, outputFile];
 | 
| +    }
 | 
| +
 | 
| +    var command = commandBuilder.getKernelTransformationCommand(
 | 
| +        transformationName, executable, transformerArguments, outputFile,
 | 
| +        environmentOverrides, useBatchMode);
 | 
| +
 | 
| +    return new CommandArtifact(
 | 
| +        <Command>[ command ], outputFile, 'application/dart');
 | 
| +  }
 | 
| +}
 | 
| +
 | 
|  /// Common configuration for dart2js-based tools, such as, dart2js
 | 
|  class Dart2xCompilerConfiguration extends CompilerConfiguration {
 | 
|    final String moniker;
 | 
| 
 |