blob: b5520700e2e701c9ca0a69a8bb97d10343ad7fc7 [file] [log] [blame]
// 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);
}