blob: be05289fb2842ecbb6e96c41bd282c0739a55aae [file] [log] [blame]
// Copyright (c) 2022, 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.
// Tests that promotion of a field narrows the types of methods, getters,
// and operators that are also exposed from the unpromoted type.
import '../static_type_helper.dart';
class A {
Object get getter => 0;
num method(int value) => 0;
num call(int value) => 0;
num operator [](int index) => 0;
operator []=(int index, int value) {}
num operator +(int other) => 0;
}
class B extends A {
int Function(num) get getter => (_) => 0;
int method(num value) => 0;
int call(num value) => 0;
int operator [](num index) => 0;
operator []=(num index, num value) {}
int operator +(num other) => 0;
}
class C {
final A _a;
C(this._a);
void testThisAccess() {
if (_a is B) {
_a.getter.expectStaticType<Exactly<int Function(num)>>();
_a
.getter(contextType(0)..expectStaticType<Exactly<num>>())
.expectStaticType<Exactly<int>>();
_a.method.expectStaticType<Exactly<int Function(num)>>();
_a
.method(contextType(0)..expectStaticType<Exactly<num>>())
.expectStaticType<Exactly<int>>();
_a(contextType(0)..expectStaticType<Exactly<num>>())
.expectStaticType<Exactly<int>>();
_a[contextType(0)..expectStaticType<Exactly<num>>()]
.expectStaticType<Exactly<int>>();
_a[contextType(0)..expectStaticType<Exactly<num>>()] = contextType(0)
..expectStaticType<Exactly<num>>();
(_a + (contextType(0)..expectStaticType<Exactly<num>>()))
.expectStaticType<Exactly<int>>();
}
}
}
class D extends C {
D(super._a);
void testSuperAccess() {
if (super._a is B) {
super._a.getter.expectStaticType<Exactly<int Function(num)>>();
super
._a
.getter(contextType(0)..expectStaticType<Exactly<num>>())
.expectStaticType<Exactly<int>>();
super._a.method.expectStaticType<Exactly<int Function(num)>>();
super
._a
.method(contextType(0)..expectStaticType<Exactly<num>>())
.expectStaticType<Exactly<int>>();
super
._a(contextType(0)..expectStaticType<Exactly<num>>())
.expectStaticType<Exactly<int>>();
super
._a[contextType(0)..expectStaticType<Exactly<num>>()]
.expectStaticType<Exactly<int>>();
super._a[contextType(0)..expectStaticType<Exactly<num>>()] =
contextType(0)..expectStaticType<Exactly<num>>();
(super._a + (contextType(0)..expectStaticType<Exactly<num>>()))
.expectStaticType<Exactly<int>>();
}
}
}
void testPrefixedIdentifier(C c) {
if (c._a is B) {
c._a.getter.expectStaticType<Exactly<int Function(num)>>();
c._a
.getter(contextType(0)..expectStaticType<Exactly<num>>())
.expectStaticType<Exactly<int>>();
c._a.method.expectStaticType<Exactly<int Function(num)>>();
c._a
.method(contextType(0)..expectStaticType<Exactly<num>>())
.expectStaticType<Exactly<int>>();
c
._a(contextType(0)..expectStaticType<Exactly<num>>())
.expectStaticType<Exactly<int>>();
c._a[contextType(0)..expectStaticType<Exactly<num>>()]
.expectStaticType<Exactly<int>>();
c._a[contextType(0)..expectStaticType<Exactly<num>>()] = contextType(0)
..expectStaticType<Exactly<num>>();
(c._a + (contextType(0)..expectStaticType<Exactly<num>>()))
.expectStaticType<Exactly<int>>();
}
}
void testGeneralPropertyAccess(C c) {
// The analyzer uses a special data structure for `IDENTIFIER.IDENTIFIER`, so
// we need to test the general case of property accesses as well.
if ((c)._a is B) {
(c)._a.getter.expectStaticType<Exactly<int Function(num)>>();
(c)
._a
.getter(contextType(0)..expectStaticType<Exactly<num>>())
.expectStaticType<Exactly<int>>();
(c)._a.method.expectStaticType<Exactly<int Function(num)>>();
(c)
._a
.method(contextType(0)..expectStaticType<Exactly<num>>())
.expectStaticType<Exactly<int>>();
(c)
._a(contextType(0)..expectStaticType<Exactly<num>>())
.expectStaticType<Exactly<int>>();
(c)
._a[contextType(0)..expectStaticType<Exactly<num>>()]
.expectStaticType<Exactly<int>>();
(c)._a[contextType(0)..expectStaticType<Exactly<num>>()] = contextType(0)
..expectStaticType<Exactly<num>>();
((c)._a + (contextType(0)..expectStaticType<Exactly<num>>()))
.expectStaticType<Exactly<int>>();
}
}
main() {
var d = D(B());
d.testThisAccess();
d.testSuperAccess();
testPrefixedIdentifier(d);
testGeneralPropertyAccess(d);
}