blob: b5819f07c73609a267effcd44e3d88cc2102bdc3 [file] [log] [blame]
// Copyright (c) 2019, 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.
// @dart = 2.7
import '../helpers/memory_compiler.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/apiimpl.dart' show CompilerImpl;
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/elements/entities.dart'
show LibraryEntity, ClassEntity;
import 'package:compiler/src/kernel/dart2js_target.dart';
import 'package:compiler/src/kernel/loader.dart';
import 'package:expect/expect.dart';
import 'package:front_end/src/api_prototype/front_end.dart';
import 'package:front_end/src/api_prototype/memory_file_system.dart';
import 'package:front_end/src/api_prototype/standard_file_system.dart';
import 'package:front_end/src/api_unstable/dart2js.dart';
import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent;
import 'package:kernel/ast.dart';
import 'package:kernel/target/targets.dart' show TargetFlags;
/// Test that the compiler can load kernel in modular fragments.
main() {
asyncTest(() async {
var aDill = await compileUnit(['a0.dart'], {'a0.dart': sourceA});
var bDill = await compileUnit(
['b1.dart'], {'b1.dart': sourceB, 'a.dill': aDill},
deps: ['a.dill']);
var cDill = await compileUnit(
['c2.dart'], {'c2.dart': sourceC, 'a.dill': aDill, 'b.dill': bDill},
deps: ['a.dill', 'b.dill']);
DiagnosticCollector diagnostics = DiagnosticCollector();
OutputCollector output = OutputCollector();
Uri entryPoint = Uri.parse('org-dartlang-test:///c2.dart');
CompilerImpl compiler = compilerFor(
entryPoint: entryPoint,
options: [
'--input-dill=memory:c.dill',
'--dill-dependencies=memory:a.dill,memory:b.dill'
],
memorySourceFiles: {'a.dill': aDill, 'b.dill': bDill, 'c.dill': cDill},
diagnosticHandler: diagnostics,
outputProvider: output);
KernelResult result = await compiler.kernelLoader.load();
compiler.frontendStrategy.registerLoadedLibraries(result);
Expect.equals(0, diagnostics.errors.length);
Expect.equals(0, diagnostics.warnings.length);
ElementEnvironment environment =
compiler.frontendStrategy.elementEnvironment;
LibraryEntity library = environment.lookupLibrary(toTestUri('b1.dart'));
Expect.isNotNull(library);
ClassEntity clss = environment.lookupClass(library, 'B1');
Expect.isNotNull(clss);
var member = environment.lookupClassMember(clss, 'foo');
Expect.isNotNull(member);
});
}
/// Generate a component for a modular complation unit.
Future<List<int>> compileUnit(List<String> inputs, Map<String, dynamic> sources,
{List<String> deps: const []}) async {
var fs = MemoryFileSystem(_defaultDir);
sources.forEach((name, data) {
var entity = fs.entityForUri(toTestUri(name));
if (data is String) {
entity.writeAsStringSync(data);
} else {
entity.writeAsBytesSync(data);
}
});
List<Uri> additionalDills = [
computePlatformBinariesLocation().resolve("dart2js_platform.dill"),
]..addAll(deps.map(toTestUri));
fs.entityForUri(toTestUri('.packages')).writeAsStringSync('');
var options = CompilerOptions()
..target = Dart2jsTarget("dart2js", TargetFlags(enableNullSafety: true))
..fileSystem = TestFileSystem(fs)
..nnbdMode = NnbdMode.Strong
..additionalDills = additionalDills
..packagesFileUri = toTestUri('.packages')
..explicitExperimentalFlags = {ExperimentalFlag.nonNullable: true};
var inputUris = inputs.map(toTestUri).toList();
var inputUriSet = inputUris.toSet();
var component = (await kernelForModule(inputUris, options)).component;
for (var lib in component.libraries) {
if (!inputUriSet.contains(lib.importUri)) {
component.root.getChildFromUri(lib.importUri).bindTo(lib.reference);
lib.computeCanonicalNames();
}
}
return serializeComponent(component,
filter: (Library lib) => inputUriSet.contains(lib.importUri));
}
Uri _defaultDir = Uri.parse('org-dartlang-test:///');
Uri toTestUri(String relativePath) => _defaultDir.resolve(relativePath);
class TestFileSystem implements FileSystem {
final MemoryFileSystem memory;
final FileSystem physical = StandardFileSystem.instance;
TestFileSystem(this.memory);
@override
FileSystemEntity entityForUri(Uri uri) {
if (uri.scheme == 'file') return physical.entityForUri(uri);
return memory.entityForUri(uri);
}
}
const sourceA = '''
class A0 {
StringBuffer buffer = StringBuffer();
}
''';
const sourceB = '''
import 'a0.dart';
class B1 extends A0 {
A0? get foo => null;
}
A0 createA0() => A0();
''';
const sourceC = '''
import 'b1.dart';
class C2 extends B1 {
final foo = createA0();
}
main() => print(C2().foo.buffer.toString());
''';