blob: 6b0a75f5813c4efb144c5df4b4c1c15ef750de68 [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.
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/testing/mock_sdk_component.dart';
import 'package:test/test.dart';
import 'package:vm/bytecode/generics.dart';
main() {
Library lib;
Supertype objectSuper;
DartType intType;
Class base;
Class addClass(String name, List<TypeParameter> typeParameters) {
Class cls = new Class(
name: name, supertype: objectSuper, typeParameters: typeParameters);
lib.addClass(cls);
return cls;
}
setUp(() {
// Start with mock SDK libraries.
Component component = createMockSdkComponent();
CoreTypes coreTypes = new CoreTypes(component);
objectSuper = coreTypes.objectClass.asThisSupertype;
intType = new InterfaceType(coreTypes.intClass);
// Add the test library.
lib = new Library(Uri.parse('org-dartlang:///test.dart'), name: 'lib');
lib.parent = component;
component.libraries.add(lib);
// class Base<T>
base = addClass('Base', [new TypeParameter('T')]);
});
tearDown(() {});
test('isRecursiveAfterFlattening-00', () async {
// class Derived<T> extends Base<Derived<T>>
TypeParameter t = new TypeParameter('T');
Class derived = addClass('Derived', [t]);
DartType derivedOfT =
new InterfaceType(derived, [new TypeParameterType(t)]);
DartType derivedOfInt = new InterfaceType(derived, [intType]);
derived.supertype = new Supertype(base, [derivedOfT]);
expect(isRecursiveAfterFlattening(derivedOfT), isTrue);
expect(isRecursiveAfterFlattening(derivedOfInt), isTrue);
});
test('isRecursiveAfterFlattening-01', () async {
// class Derived<T> extends Base<Derived<Derived<int>>>
TypeParameter t = new TypeParameter('T');
Class derived = addClass('Derived', [t]);
DartType derivedOfT =
new InterfaceType(derived, [new TypeParameterType(t)]);
DartType derivedOfInt = new InterfaceType(derived, [intType]);
DartType derivedOfDerivedOfInt = new InterfaceType(derived, [derivedOfInt]);
derived.supertype = new Supertype(base, [derivedOfDerivedOfInt]);
expect(isRecursiveAfterFlattening(derivedOfT), isFalse);
expect(isRecursiveAfterFlattening(derivedOfInt), isTrue);
});
test('isRecursiveAfterFlattening-02', () async {
// class Derived<T> extends Base<Derived<Derived<T>>>
TypeParameter t = new TypeParameter('T');
Class derived = addClass('Derived', [t]);
DartType derivedOfT =
new InterfaceType(derived, [new TypeParameterType(t)]);
DartType derivedOfInt = new InterfaceType(derived, [intType]);
DartType derivedOfDerivedOfT = new InterfaceType(derived, [derivedOfT]);
derived.supertype = new Supertype(base, [derivedOfDerivedOfT]);
expect(isRecursiveAfterFlattening(derivedOfT), isTrue);
expect(isRecursiveAfterFlattening(derivedOfInt), isTrue);
});
test('isRecursiveAfterFlattening-03', () async {
// class Derived1<U> extends Base<Derived2<U>>
// class Derived2<V> extends Base<Derived1<V>>
TypeParameter u = new TypeParameter('U');
Class derived1 = addClass('Derived1', [u]);
TypeParameter v = new TypeParameter('V');
Class derived2 = addClass('Derived2', [v]);
DartType derived2OfU =
new InterfaceType(derived2, [new TypeParameterType(u)]);
derived1.supertype = new Supertype(base, [derived2OfU]);
DartType derived1OfV =
new InterfaceType(derived1, [new TypeParameterType(v)]);
derived2.supertype = new Supertype(base, [derived1OfV]);
DartType derived1OfU =
new InterfaceType(derived1, [new TypeParameterType(u)]);
DartType derived1OfInt = new InterfaceType(derived1, [intType]);
DartType derived2OfV =
new InterfaceType(derived2, [new TypeParameterType(v)]);
DartType derived2OfInt = new InterfaceType(derived2, [intType]);
expect(isRecursiveAfterFlattening(derived1OfU), isTrue);
expect(isRecursiveAfterFlattening(derived1OfInt), isTrue);
expect(isRecursiveAfterFlattening(derived2OfV), isTrue);
expect(isRecursiveAfterFlattening(derived2OfInt), isTrue);
});
}