| // Copyright (c) 2017, 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. |
| |
| // Partial test that the closed world computed from [WorldImpact]s derived from |
| // kernel is equivalent to the original computed from resolution. |
| library dart2js.kernel.compiler_helper; |
| |
| import 'dart:async'; |
| import 'dart:io'; |
| |
| import 'package:compiler/compiler_new.dart'; |
| import 'package:compiler/src/commandline_options.dart'; |
| import 'package:compiler/src/common.dart'; |
| import 'package:compiler/src/common/tasks.dart'; |
| import 'package:compiler/src/compiler.dart'; |
| import 'package:compiler/src/kernel/element_map.dart'; |
| import 'package:compiler/src/library_loader.dart'; |
| import 'package:compiler/src/universe/world_builder.dart'; |
| import 'package:compiler/src/util/util.dart'; |
| import 'package:kernel/ast.dart' as ir; |
| import '../memory_compiler.dart'; |
| |
| typedef Future<Compiler> CompileFunction(); |
| |
| /// Create multiple compilations for a list of [sources]. |
| /// |
| /// This methods speeds up testing kernel based compilation by creating the IR |
| /// nodes for all [sources] at the same time. The returned list of |
| /// [CompileFunction]s compiles one of the [source] at a time using the kernel |
| /// based compiler. |
| /// |
| /// Currently, the returned compile function only runs with '--analyze-only' |
| /// flag. |
| Future<List<CompileFunction>> compileMultiple(List<String> sources) async { |
| Uri entryPoint = Uri.parse('memory:main.dart'); |
| |
| List<CompileFunction> compilers = <CompileFunction>[]; |
| for (String source in sources) { |
| compilers.add(() async { |
| Compiler compiler = compilerFor( |
| entryPoint: entryPoint, |
| memorySourceFiles: { |
| 'main.dart': source |
| }, |
| options: [ |
| Flags.analyzeOnly, |
| Flags.enableAssertMessage, |
| Flags.useKernel |
| ]); |
| ElementResolutionWorldBuilder.useInstantiationMap = true; |
| compiler.impactCacheDeleter.retainCachesForTesting = true; |
| await compiler.run(entryPoint); |
| return compiler; |
| }); |
| } |
| return compilers; |
| } |
| |
| /// Analyze [memorySourceFiles] with [entryPoint] as entry-point using the |
| /// kernel based element model. The returned [Pair] contains the compiler used |
| /// to create the IR and the kernel based compiler. |
| Future<Pair<Compiler, Compiler>> analyzeOnly( |
| Uri entryPoint, Map<String, String> memorySourceFiles, |
| {bool printSteps: false}) async { |
| if (printSteps) { |
| print('---- analyze-all -------------------------------------------------'); |
| } |
| Compiler compiler = compilerFor( |
| entryPoint: entryPoint, |
| memorySourceFiles: memorySourceFiles, |
| options: [Flags.analyzeAll, Flags.enableAssertMessage]); |
| compiler.impactCacheDeleter.retainCachesForTesting = true; |
| await compiler.run(entryPoint); |
| |
| if (printSteps) { |
| print('---- closed world from kernel ------------------------------------'); |
| } |
| Compiler compiler2 = compilerFor( |
| entryPoint: entryPoint, |
| memorySourceFiles: memorySourceFiles, |
| options: [Flags.analyzeOnly, Flags.enableAssertMessage, Flags.useKernel]); |
| ElementResolutionWorldBuilder.useInstantiationMap = true; |
| compiler2.impactCacheDeleter.retainCachesForTesting = true; |
| await compiler2.run(entryPoint); |
| return new Pair<Compiler, Compiler>(compiler, compiler2); |
| } |
| |
| class MemoryKernelLibraryLoaderTask extends KernelLibraryLoaderTask { |
| final ir.Program program; |
| |
| MemoryKernelLibraryLoaderTask(KernelToElementMapForImpact elementMap, |
| DiagnosticReporter reporter, Measurer measurer, this.program) |
| : super(null, null, elementMap, null, reporter, measurer); |
| |
| Future<LoadedLibraries> loadLibrary(Uri resolvedUri, |
| {bool skipFileWithPartOfTag: false}) async { |
| return createLoadedLibraries(program); |
| } |
| } |
| |
| Future createTemp(Uri entryPoint, Map<String, String> memorySourceFiles, |
| {bool printSteps: false}) async { |
| if (memorySourceFiles.isNotEmpty) { |
| Directory dir = await Directory.systemTemp.createTemp('dart2js-with-dill'); |
| if (printSteps) { |
| print('--- create temp directory $dir -------------------------------'); |
| } |
| memorySourceFiles.forEach((String name, String source) { |
| new File.fromUri(dir.uri.resolve(name)).writeAsStringSync(source); |
| }); |
| entryPoint = dir.uri.resolve(entryPoint.path); |
| } |
| return entryPoint; |
| } |
| |
| Future<Compiler> compileWithDill( |
| {Uri entryPoint, |
| Map<String, String> memorySourceFiles: const <String, String>{}, |
| List<String> options: const <String>[], |
| CompilerDiagnostics diagnosticHandler, |
| bool printSteps: false, |
| CompilerOutput compilerOutput, |
| void beforeRun(Compiler compiler)}) async { |
| if (printSteps) { |
| print('---- compile from dill -------------------------------------------'); |
| } |
| Compiler compiler = compilerFor( |
| entryPoint: entryPoint, |
| memorySourceFiles: memorySourceFiles, |
| options: [Flags.useKernel]..addAll(options), |
| diagnosticHandler: diagnosticHandler, |
| outputProvider: compilerOutput); |
| ElementResolutionWorldBuilder.useInstantiationMap = true; |
| compiler.impactCacheDeleter.retainCachesForTesting = true; |
| if (beforeRun != null) { |
| beforeRun(compiler); |
| } |
| await compiler.run(entryPoint); |
| return compiler; |
| } |