blob: ad21d34fc35305125c1875525ce8424ce3e33453 [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.
/// Test to ensure that desugaring APIs used by clients like dart2js are
/// always up to date.
///
/// Desugaring APIs are methods that inspect the kernel output to find
/// structures that are assumed to always be generated by the CFE. If the CFE
/// changes its invariants, the desugaring APIs will change together to hide
/// these changes from clients.
import 'dart:io';
import 'package:expect/async_helper.dart';
import 'package:expect/expect.dart';
import 'package:front_end/src/compute_platform_binaries_location.dart';
import 'package:front_end/src/kernel/utils.dart' show serializeComponent;
import 'package:front_end/src/testing/compiler_common.dart';
import 'package:kernel/ast.dart' as ir;
import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
Future<void> main() async {
await asyncTest(() async {
await testRedirectingFactoryDirect();
await testRedirectingFactorySerialized();
await testRedirectingFactoryPatchFile();
});
}
Future<void> testRedirectingFactoryDirect() async {
var component = await compileUnit(['a.dart'], {'a.dart': aSource});
checkIsRedirectingFactory(component!, 'a.dart', 'A', 'foo');
checkIsRedirectingFactory(component, 'core', 'Uri', 'file');
}
Future<void> testRedirectingFactorySerialized() async {
var component = await compileUnit(['a.dart'], {'a.dart': aSource});
var bytes = serializeComponent(component!);
component = new ir.Component();
new BinaryBuilder(bytes).readComponent(component);
checkIsRedirectingFactory(component, 'a.dart', 'A', 'foo');
checkIsRedirectingFactory(component, 'core', 'Uri', 'file');
}
// regression test: redirecting factories from patch files don't have the
// redirecting-factory flag stored in kernel.
Future<void> testRedirectingFactoryPatchFile() {
var componentUri = computePlatformBinariesLocation().resolve(
'dart2js_platform.dill',
);
var component = new ir.Component();
new BinaryBuilder(
new File.fromUri(componentUri).readAsBytesSync(),
).readComponent(component);
checkIsRedirectingFactory(component, 'collection', 'HashMap', 'identity');
return new Future.value();
}
void checkIsRedirectingFactory(
ir.Component component,
String uriPath,
String className,
String constructorName,
) {
var lib = component.libraries.firstWhere(
(l) => l.importUri.path.endsWith(uriPath),
);
var cls = lib.classes.firstWhere((c) => c.name == className);
ir.Procedure member =
cls.members.firstWhere((m) => m.name.text == constructorName)
as ir.Procedure;
Expect.isTrue(
member.kind == ir.ProcedureKind.Factory,
"$member is not a factory",
);
Expect.isTrue(member.isRedirectingFactory);
}
const aSource = '''
class A {
factory A.foo(int x) = _B;
}
class _B implements A {
_B(int x);
}
''';