|  | // 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 field promotion logic properly handles abstract fields. | 
|  |  | 
|  | abstract class C { | 
|  | abstract final int? _f1; | 
|  | abstract int? _f2; | 
|  | } | 
|  |  | 
|  | class D { | 
|  | final int? _f1; | 
|  | final int? _f2; | 
|  |  | 
|  | D(int i) : _f1 = i, _f2 = i; | 
|  | } | 
|  |  | 
|  | void acceptsInt(int x) {} | 
|  |  | 
|  | void testAbstractFinalFieldIsPromotable(C c) { | 
|  | if (c._f1 != null) { | 
|  | var x = c._f1; | 
|  | // `x` has type `int` so this is ok | 
|  | acceptsInt(x); | 
|  | } | 
|  | } | 
|  |  | 
|  | void testAbstractNonFinalFieldIsNotPromotable(C c) { | 
|  | // Technically, it would be sound to promote an abstract non-final field, but | 
|  | // there's no point because it's just going to be implemented by a concrete | 
|  | // non-final field or a getter/setter pair, which will prevent promotion.  So | 
|  | // we might as well prevent promotion even in the absence of an | 
|  | // implementation. | 
|  | if (c._f2 != null) { | 
|  | var x = c._f2; | 
|  | // `x` has type `int?` so this is ok | 
|  | x = null; | 
|  | } | 
|  | } | 
|  |  | 
|  | void testAbstractFinalFieldDoesNotBlockPromotionElsewhere(D d) { | 
|  | if (d._f1 != null) { | 
|  | var x = d._f1; | 
|  | // `x` has type `int` so this is ok | 
|  | acceptsInt(x); | 
|  | } | 
|  | } | 
|  |  | 
|  | void testAbstractNonFinalFieldBlocksPromotionElsewhere(D d) { | 
|  | // Technically, it would be sound if an abstract non-final field didn't block | 
|  | // promotion, but there's no point because it's just going to be implemented | 
|  | // by a concrete non-final field or a getter/setter pair, which will block | 
|  | // promotion.  So we might as well block promotion even in the absence of an | 
|  | // implementation. | 
|  | if (d._f2 != null) { | 
|  | var x = d._f2; | 
|  | // `x` has type `int?` so this is ok | 
|  | x = null; | 
|  | } | 
|  | } | 
|  |  | 
|  | main() {} |