beda5c3e62
Revert "Revert "Don't skip front-end tests"" This reverts commitb4556e646e. Reason for revert: <INSERT REASONING HERE> Original change's description: > Revert "Don't skip front-end tests" > > This reverts commit62d2255719. > > Reason for revert: Broke analyzer bots > > Original change's description: > > Don't skip front-end tests > > > > Change-Id: Ibbd0d63e8c23d045a898e52185fe55e5c53dd6b3 > > Reviewed-on: https://dart-review.googlesource.com/34621 > > Reviewed-by: Jens Johansen <jensj@google.com> > > TBR=ahe@google.com,jensj@google.com > > Change-Id: I6519e0c551dd79d3bd98345925c2db888e892123 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Reviewed-on: https://dart-review.googlesource.com/35020 > Reviewed-by: Paul Berry <paulberry@google.com> > Commit-Queue: Paul Berry <paulberry@google.com> TBR=paulberry@google.com,ahe@google.com,jensj@google.com Change-Id: I7ff6fd587912fd8a2aba113eb7c765c7b16c5eda No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/35120 Reviewed-by: Peter von der Ahé <ahe@google.com> Commit-Queue: Peter von der Ahé <ahe@google.com>
249 lines
8.6 KiB
Dart
249 lines
8.6 KiB
Dart
// 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:kernel/ast.dart'
|
|
show EmptyStatement, Program, ReturnStatement, StaticInvocation;
|
|
|
|
import 'package:test/test.dart'
|
|
show
|
|
contains,
|
|
expect,
|
|
greaterThan,
|
|
group,
|
|
isEmpty,
|
|
isFalse,
|
|
isNotEmpty,
|
|
isNotNull,
|
|
isNull,
|
|
isTrue,
|
|
same,
|
|
test;
|
|
|
|
import 'package:front_end/src/api_prototype/front_end.dart'
|
|
show CompilerOptions;
|
|
|
|
import 'package:front_end/src/fasta/deprecated_problems.dart'
|
|
show deprecated_InputError;
|
|
|
|
import 'package:front_end/src/fasta/fasta_codes.dart' show messageMissingMain;
|
|
|
|
import 'package:front_end/src/fasta/kernel/utils.dart' show serializeProgram;
|
|
|
|
import 'package:front_end/src/testing/compiler_common.dart'
|
|
show
|
|
compileScript,
|
|
compileUnit,
|
|
findLibrary,
|
|
invalidCoreLibsSpecUri,
|
|
isDartCoreLibrary;
|
|
|
|
main() {
|
|
group('kernelForProgram', () {
|
|
test('compiler fails if it cannot find sdk sources', () async {
|
|
var errors = [];
|
|
var options = new CompilerOptions()
|
|
..librariesSpecificationUri = invalidCoreLibsSpecUri
|
|
..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('org-dartlang-test:///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 [librariesSpecificationUri] with a specification that
|
|
// contains broken URIs to ensure we do not attempt to lookup for
|
|
// sources of the sdk directly.
|
|
..librariesSpecificationUri = invalidCoreLibsSpecUri;
|
|
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.message, messageMissingMain.message);
|
|
});
|
|
|
|
// TODO(ahe): This test is wrong at least with respect to expecting that
|
|
// [deprecated_InputError] leaks through the API. Furthermore, the default
|
|
// behavior should be to recover from errors, as this is the most important
|
|
// use case we have.
|
|
test('default error handler throws on errors', () async {
|
|
var options = new CompilerOptions();
|
|
var exceptionThrown = false;
|
|
try {
|
|
await compileScript('a() => print("hi");', options: options);
|
|
} on deprecated_InputError catch (e) {
|
|
exceptionThrown = true;
|
|
expect('${e.error}', contains("Compilation aborted"));
|
|
}
|
|
expect(exceptionThrown, isTrue);
|
|
}, skip: true /* Issue 30194 */);
|
|
|
|
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[Uri.parse('org-dartlang-test:///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.message, 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
|
|
});
|
|
}
|