| Index: pkg/front_end/test/kernel_generator_test.dart
|
| diff --git a/pkg/front_end/test/kernel_generator_test.dart b/pkg/front_end/test/kernel_generator_test.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..831dbaf63c5988368269709197a62acb67955afe
|
| --- /dev/null
|
| +++ b/pkg/front_end/test/kernel_generator_test.dart
|
| @@ -0,0 +1,210 @@
|
| +// 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.
|
| +
|
| +import 'package:front_end/front_end.dart';
|
| +import 'package:front_end/src/fasta/kernel/utils.dart';
|
| +import 'package:front_end/src/testing/compiler_common.dart';
|
| +import 'package:kernel/ast.dart';
|
| +
|
| +import 'package:test/test.dart';
|
| +
|
| +main() {
|
| + group('kernelForProgram', () {
|
| + test('compiler fails if it cannot find sdk sources', () async {
|
| + var errors = [];
|
| + var options = new CompilerOptions()
|
| + ..dartLibraries = invalidCoreLibs
|
| + ..sdkSummary = null
|
| + ..compileSdk = true // To prevent FE from loading an sdk-summary.
|
| + ..onError = (e) => errors.add(e);
|
| +
|
| + var program =
|
| + await compileScript('main() => print("hi");', options: options);
|
| + expect(program, isNull);
|
| + expect(errors, isNotEmpty);
|
| + });
|
| +
|
| + test('compiler fails if it cannot find sdk summary', () async {
|
| + var errors = [];
|
| + var options = new CompilerOptions()
|
| + ..sdkSummary = Uri.parse('file:///not_existing_summary_file')
|
| + ..onError = (e) => errors.add(e);
|
| +
|
| + var program =
|
| + await compileScript('main() => print("hi");', options: options);
|
| + expect(program, isNull);
|
| + expect(errors, isNotEmpty);
|
| + });
|
| +
|
| + test('by default program is compiled using summaries', () async {
|
| + var options = new CompilerOptions()
|
| + // Note: we define [dartLibraries] with broken URIs to ensure we do not
|
| + // attempt to lookup for sources of the sdk directly.
|
| + ..dartLibraries = invalidCoreLibs;
|
| + var program =
|
| + await compileScript('main() => print("hi");', options: options);
|
| + var core = program.libraries.firstWhere(isDartCoreLibrary);
|
| + var printMember = core.members.firstWhere((m) => m.name.name == 'print');
|
| +
|
| + // Note: summaries created by the SDK today contain empty statements as
|
| + // method bodies.
|
| + expect(printMember.function.body is EmptyStatement, isTrue);
|
| + });
|
| +
|
| + test('compiler requires a main method', () async {
|
| + var errors = [];
|
| + var options = new CompilerOptions()..onError = (e) => errors.add(e);
|
| + await compileScript('a() => print("hi");', options: options);
|
| + expect('${errors.first}', contains("No 'main' method found"));
|
| + });
|
| +
|
| + test('default error handler throws', () async {
|
| + var exceptionThrown = false;
|
| + try {
|
| + await compileScript('a() => print("hi");');
|
| + } catch (e) {
|
| + exceptionThrown = true;
|
| + expect('$e', contains("No 'main' method found"));
|
| + }
|
| + expect(exceptionThrown, isTrue);
|
| + });
|
| +
|
| + test('generated program contains source-info', () async {
|
| + var program = await compileScript('a() => print("hi"); main() {}',
|
| + fileName: 'a.dart');
|
| + // Kernel always store an empty '' key in the map, so there is always at
|
| + // least one. Having more means that source-info is added.
|
| + expect(program.uriToSource.keys.length, greaterThan(1));
|
| + expect(program.uriToSource['file:///a/b/c/a.dart'], isNotNull);
|
| + });
|
| +
|
| + test('code from summary dependencies are marked external', () async {
|
| + var program = await compileScript('a() => print("hi"); main() {}',
|
| + fileName: 'a.dart');
|
| + for (var lib in program.libraries) {
|
| + if (lib.importUri.scheme == 'dart') {
|
| + expect(lib.isExternal, isTrue);
|
| + }
|
| + }
|
| +
|
| + // Pretend that the compiled code is a summary
|
| + var bytes = serializeProgram(program);
|
| + program = await compileScript(
|
| + {
|
| + 'b.dart': 'import "a.dart" as m; b() => m.a(); main() {}',
|
| + 'summary.dill': bytes
|
| + },
|
| + fileName: 'b.dart',
|
| + inputSummaries: ['summary.dill']);
|
| +
|
| + var aLib = program.libraries
|
| + .firstWhere((lib) => lib.importUri.path == '/a/b/c/a.dart');
|
| + expect(aLib.isExternal, isTrue);
|
| + });
|
| +
|
| + test('code from linked dependencies are not marked external', () async {
|
| + var program = await compileScript('a() => print("hi"); main() {}',
|
| + fileName: 'a.dart');
|
| + for (var lib in program.libraries) {
|
| + if (lib.importUri.scheme == 'dart') {
|
| + expect(lib.isExternal, isTrue);
|
| + }
|
| + }
|
| +
|
| + var bytes = serializeProgram(program);
|
| + program = await compileScript(
|
| + {
|
| + 'b.dart': 'import "a.dart" as m; b() => m.a(); main() {}',
|
| + 'link.dill': bytes
|
| + },
|
| + fileName: 'b.dart',
|
| + linkedDependencies: ['link.dill']);
|
| +
|
| + var aLib = program.libraries
|
| + .firstWhere((lib) => lib.importUri.path == '/a/b/c/a.dart');
|
| + expect(aLib.isExternal, isFalse);
|
| + });
|
| +
|
| + // TODO(sigmund): add tests discovering libraries.json
|
| + });
|
| +
|
| + group('kernelForBuildUnit', () {
|
| + test('compiler does not require a main method', () async {
|
| + var errors = [];
|
| + var options = new CompilerOptions()..onError = (e) => errors.add(e);
|
| + await compileUnit(['a.dart'], {'a.dart': 'a() => print("hi");'},
|
| + options: options);
|
| + expect(errors, isEmpty);
|
| + });
|
| +
|
| + test('compiler by default is hermetic', () async {
|
| + var errors = [];
|
| + var options = new CompilerOptions()..onError = (e) => errors.add(e);
|
| + var sources = {
|
| + 'a.dart': 'import "b.dart"; a() => print("hi");',
|
| + 'b.dart': ''
|
| + };
|
| + await compileUnit(['a.dart'], sources, options: options);
|
| + expect(errors.first.toString(), contains('Invalid access'));
|
| + errors.clear();
|
| +
|
| + await compileUnit(['a.dart', 'b.dart'], sources, options: options);
|
| + expect(errors, isEmpty);
|
| + });
|
| +
|
| + test('chaseDependencies=true removes hermetic restriction', () async {
|
| + var errors = [];
|
| + var options = new CompilerOptions()
|
| + ..chaseDependencies = true
|
| + ..onError = (e) => errors.add(e);
|
| + await compileUnit([
|
| + 'a.dart'
|
| + ], {
|
| + 'a.dart': 'import "b.dart"; a() => print("hi");',
|
| + 'b.dart': ''
|
| + }, options: options);
|
| + expect(errors, isEmpty);
|
| + });
|
| +
|
| + test('dependencies can be loaded in any order', () async {
|
| + var sources = <String, dynamic>{
|
| + 'a.dart': 'a() => print("hi");',
|
| + 'b.dart': 'import "a.dart"; b() => a();',
|
| + 'c.dart': 'import "b.dart"; c() => b();',
|
| + 'd.dart': 'import "c.dart"; d() => c();',
|
| + };
|
| +
|
| + var unitA = await compileUnit(['a.dart'], sources);
|
| + // Pretend that the compiled code is a summary
|
| + sources['a.dill'] = serializeProgram(unitA);
|
| +
|
| + var unitBC = await compileUnit(['b.dart', 'c.dart'], sources,
|
| + inputSummaries: ['a.dill']);
|
| +
|
| + // Pretend that the compiled code is a summary
|
| + sources['bc.dill'] = serializeProgram(unitBC);
|
| +
|
| + void checkDCallsC(Program program) {
|
| + var dLib = findLibrary(program, 'd.dart');
|
| + var cLib = findLibrary(program, 'c.dart');
|
| + var dMethod = dLib.procedures.first;
|
| + var dBody = dMethod.function.body;
|
| + var dCall = (dBody as ReturnStatement).expression;
|
| + var callTarget =
|
| + (dCall as StaticInvocation).targetReference.asProcedure;
|
| + expect(callTarget, same(cLib.procedures.first));
|
| + }
|
| +
|
| + var unitD1 = await compileUnit(['d.dart'], sources,
|
| + inputSummaries: ['a.dill', 'bc.dill']);
|
| + checkDCallsC(unitD1);
|
| +
|
| + var unitD2 = await compileUnit(['d.dart'], sources,
|
| + inputSummaries: ['bc.dill', 'a.dill']);
|
| + checkDCallsC(unitD2);
|
| + });
|
| +
|
| + // TODO(sigmund): add tests with trimming dependencies
|
| + });
|
| +}
|
|
|