|
| 1 | +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file |
| 2 | +// for details. All rights reserved. Use of this source code is governed by a |
| 3 | +// BSD-style license that can be found in the LICENSE file. |
| 4 | + |
| 5 | +/// Test to ensure that desugaring APIs used by clients like dart2js are |
| 6 | +/// always up to date. |
| 7 | +/// |
| 8 | +/// Desugaring APIs are methods that inspect the kernel output to find |
| 9 | +/// structures that are assumed to always be generated by the CFE. If the CFE |
| 10 | +/// changes its invariants, the desugaring APIs will change together to hide |
| 11 | +/// these changes from clients. |
| 12 | +
|
| 13 | +import 'dart:io'; |
| 14 | + |
| 15 | +import 'package:async_helper/async_helper.dart'; |
| 16 | +import 'package:expect/expect.dart'; |
| 17 | +import 'package:front_end/src/api_unstable/dart2js.dart' as api; |
| 18 | +import 'package:front_end/src/compute_platform_binaries_location.dart'; |
| 19 | +import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent; |
| 20 | +import 'package:front_end/src/testing/compiler_common.dart'; |
| 21 | +import 'package:kernel/ast.dart' as ir; |
| 22 | +import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder; |
| 23 | + |
| 24 | +main() async { |
| 25 | + await asyncTest(() async { |
| 26 | + await testRedirectingFactoryDirect(); |
| 27 | + await testRedirectingFactorySerialized(); |
| 28 | + await testRedirectingFactoryPatchFile(); |
| 29 | + }); |
| 30 | +} |
| 31 | + |
| 32 | +testRedirectingFactoryDirect() async { |
| 33 | + var component = await compileUnit(['a.dart'], {'a.dart': aSource}); |
| 34 | + checkIsRedirectingFactory(component, 'a.dart', 'A', 'foo'); |
| 35 | + checkIsRedirectingFactory(component, 'core', 'Uri', 'file'); |
| 36 | +} |
| 37 | + |
| 38 | +testRedirectingFactorySerialized() async { |
| 39 | + var component = await compileUnit(['a.dart'], {'a.dart': aSource}); |
| 40 | + var bytes = serializeComponent(component); |
| 41 | + component = new ir.Component(); |
| 42 | + new BinaryBuilder(bytes).readComponent(component); |
| 43 | + checkIsRedirectingFactory(component, 'a.dart', 'A', 'foo'); |
| 44 | + checkIsRedirectingFactory(component, 'core', 'Uri', 'file'); |
| 45 | +} |
| 46 | + |
| 47 | +// regression test: redirecting factories from patch files don't have the |
| 48 | +// redirecting-factory flag stored in kernel. |
| 49 | +testRedirectingFactoryPatchFile() async { |
| 50 | + var componentUri = |
| 51 | + computePlatformBinariesLocation().resolve('dart2js_platform.dill'); |
| 52 | + var component = new ir.Component(); |
| 53 | + new BinaryBuilder(new File.fromUri(componentUri).readAsBytesSync()) |
| 54 | + .readComponent(component); |
| 55 | + checkIsRedirectingFactory(component, 'collection', 'HashMap', 'identity', |
| 56 | + isPatch: true); |
| 57 | +} |
| 58 | + |
| 59 | +void checkIsRedirectingFactory(ir.Component component, String uriPath, |
| 60 | + String className, String constructorName, |
| 61 | + {bool isPatch: false}) { |
| 62 | + var lib = |
| 63 | + component.libraries.firstWhere((l) => l.importUri.path.endsWith(uriPath)); |
| 64 | + var cls = lib.classes.firstWhere((c) => c.name == className); |
| 65 | + ir.Procedure member = |
| 66 | + cls.members.firstWhere((m) => m.name.name == constructorName); |
| 67 | + Expect.isTrue( |
| 68 | + member.kind == ir.ProcedureKind.Factory, "$member is not a factory"); |
| 69 | + Expect.isTrue(api.isRedirectingFactory(member)); |
| 70 | + // TODO: this should always be true. Issue #33495 |
| 71 | + Expect.equals(!isPatch, member.isRedirectingFactoryConstructor); |
| 72 | +} |
| 73 | + |
| 74 | +const aSource = ''' |
| 75 | +class A { |
| 76 | + factory A.foo(int x) = _B; |
| 77 | +} |
| 78 | +
|
| 79 | +class _B implements A { |
| 80 | + _B(int x); |
| 81 | +} |
| 82 | +'''; |
0 commit comments