// 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.9 /// 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:async_helper/async_helper.dart'; import 'package:expect/expect.dart'; import 'package:front_end/src/api_unstable/dart2js.dart' as api; import 'package:front_end/src/compute_platform_binaries_location.dart'; import 'package:front_end/src/fasta/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; main() async { await asyncTest(() async { await testRedirectingFactoryDirect(); await testRedirectingFactorySerialized(); await testRedirectingFactoryPatchFile(); }); } testRedirectingFactoryDirect() async { var component = await compileUnit(['a.dart'], {'a.dart': aSource}); checkIsRedirectingFactory(component, 'a.dart', 'A', 'foo'); checkIsRedirectingFactory(component, 'core', 'Uri', 'file'); } 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. testRedirectingFactoryPatchFile() async { 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'); } 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); Expect.isTrue( member.kind == ir.ProcedureKind.Factory, "$member is not a factory"); Expect.isTrue(api.isRedirectingFactory(member)); Expect.isTrue(member.isRedirectingFactoryConstructor); } const aSource = ''' class A { factory A.foo(int x) = _B; } class _B implements A { _B(int x); } ''';