| // Copyright (c) 2021, 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:io' show Directory, File; |
| |
| import 'package:dev_compiler/src/compiler/module_builder.dart' |
| show ModuleFormat; |
| import 'package:dev_compiler/src/compiler/shared_command.dart' |
| show SharedCompilerOptions; |
| import 'package:dev_compiler/src/kernel/command.dart'; |
| import 'package:dev_compiler/src/kernel/compiler.dart' show ProgramCompiler; |
| import 'package:dev_compiler/src/kernel/module_symbols.dart'; |
| import 'package:kernel/ast.dart' show Component, Library; |
| |
| import '../shared_test_options.dart'; |
| |
| class TestCompiler { |
| final SetupCompilerOptions setup; |
| |
| TestCompiler(this.setup); |
| |
| Future<JSCode> compile({required Uri input, required Uri packages}) async { |
| // Initialize incremental compiler and create component. |
| setup.options.packagesFileUri = packages; |
| var compiler = DevelopmentIncrementalCompiler(setup.options, input); |
| var compilerResult = await compiler.computeDelta(); |
| var component = compilerResult.component; |
| component.computeCanonicalNames(); |
| var errors = setup.errors.where((e) => e.contains('Error')); |
| if (errors.isNotEmpty) { |
| throw Exception('Compilation failed: \n${errors.join('\n')}'); |
| } |
| |
| // Initialize DDC. |
| var moduleName = 'foo.dart'; |
| var classHierarchy = compilerResult.classHierarchy!; |
| var compilerOptions = SharedCompilerOptions( |
| replCompile: true, |
| moduleName: moduleName, |
| soundNullSafety: setup.soundNullSafety, |
| moduleFormats: [setup.moduleFormat], |
| emitDebugSymbols: true); |
| var coreTypes = compilerResult.coreTypes; |
| |
| final importToSummary = Map<Library, Component>.identity(); |
| final summaryToModule = Map<Component, String>.identity(); |
| for (var lib in component.libraries) { |
| importToSummary[lib] = component; |
| } |
| summaryToModule[component] = moduleName; |
| |
| // Compile Kernel AST to JS AST. |
| var kernel2jsCompiler = ProgramCompiler(component, classHierarchy, |
| compilerOptions, importToSummary, summaryToModule, |
| coreTypes: coreTypes); |
| var moduleTree = kernel2jsCompiler.emitModule(component); |
| |
| // Compile JS AST to code. |
| return jsProgramToCode(moduleTree, ModuleFormat.amd, |
| emitDebugSymbols: true, |
| compiler: kernel2jsCompiler, |
| component: component); |
| } |
| } |
| |
| class TestDriver { |
| final SetupCompilerOptions options; |
| late final Directory tempDir; |
| late final Uri input; |
| late final Uri packages; |
| |
| TestDriver(this.options, String source) { |
| var systemTempDir = Directory.systemTemp; |
| tempDir = systemTempDir.createTempSync('foo bar'); |
| |
| input = tempDir.uri.resolve('foo.dart'); |
| var file = File.fromUri(input)..createSync(); |
| file.writeAsStringSync(source); |
| |
| packages = tempDir.uri.resolve('package_config.json'); |
| file = File.fromUri(packages)..createSync(); |
| file.writeAsStringSync(''' |
| { |
| "configVersion": 2, |
| "packages": [ |
| { |
| "name": "foo", |
| "rootUri": "./", |
| "packageUri": "./" |
| } |
| ] |
| } |
| '''); |
| } |
| |
| Future<ModuleSymbols> compileAndGetSymbols() async { |
| var result = |
| await TestCompiler(options).compile(input: input, packages: packages); |
| var symbols = result.symbols; |
| if (symbols == null) { |
| throw Exception('No symbols found in compilation result.'); |
| } |
| return symbols; |
| } |
| |
| void cleanUp() { |
| tempDir.delete(recursive: true); |
| options.errors.clear(); |
| } |
| } |
| |
| class NullSafetyTestOption { |
| final String description; |
| final bool soundNullSafety; |
| |
| NullSafetyTestOption(this.description, this.soundNullSafety); |
| } |