Front end logic for field promotion.

This is the common front end implementation of the new field promotion
feature (https://github.com/dart-lang/language/issues/2020).

There is no behavioral change yet unless the user activates field
promotion by enabling the experiment flag `inference-update-2`.

Change-Id: I0d1e0893af862c3af8a0ef4ea10e803606d48d7e
Bug: https://github.com/dart-lang/language/issues/2020
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/260451
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
Paul Berry 2022-10-19 14:53:51 +00:00 committed by Commit Queue
parent f350c474e7
commit d9a5551af9
52 changed files with 2384 additions and 19 deletions

View file

@ -167,6 +167,7 @@ enum BenchmarkPhases {
outline_checkOverrides,
outline_checkAbstractMembers,
outline_addNoSuchMethodForwarders,
outline_computeFieldPromotability,
outline_checkMixins,
outline_buildOutlineExpressions,
outline_checkTypes,

View file

@ -542,6 +542,10 @@ class KernelTarget extends TargetImplementation {
?.enterPhase(BenchmarkPhases.outline_addNoSuchMethodForwarders);
loader.addNoSuchMethodForwarders(sortedSourceClassBuilders);
benchmarker
?.enterPhase(BenchmarkPhases.outline_computeFieldPromotability);
loader.computeFieldPromotability(sortedSourceClassBuilders);
benchmarker?.enterPhase(BenchmarkPhases.outline_checkMixins);
loader.checkMixins(sortedSourceClassBuilders);

View file

@ -1659,6 +1659,34 @@ class SourceClassBuilder extends ClassBuilderImpl
procedure.stubTarget = null;
}
/// If any private field names in this library are unpromotable due to fields
/// in this class, adds them to [unpromotablePrivateFieldNames].
void addUnpromotablePrivateFieldNames(
Set<String> unpromotablePrivateFieldNames) {
for (Field field in cls.fields) {
// An instance field is unpromotable (and makes other fields with the same
// name unpromotable) if it's not final.
if (field.isInstanceMember &&
!field.isFinal &&
_isPrivateNameInThisLibrary(field.name)) {
unpromotablePrivateFieldNames.add(field.name.text);
}
}
for (Procedure procedure in cls.procedures) {
// An instance getter makes fields with the same name unpromotable if it's
// concrete.
if (procedure.isGetter &&
procedure.isInstanceMember &&
!procedure.isAbstract &&
_isPrivateNameInThisLibrary(procedure.name)) {
unpromotablePrivateFieldNames.add(procedure.name.text);
}
}
}
bool _isPrivateNameInThisLibrary(Name name) =>
name.isPrivate && name.library == libraryBuilder.library;
void _addRedirectingConstructor(
SourceFactoryBuilder constructorBuilder,
SourceLibraryBuilder library,

View file

@ -266,6 +266,13 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
MergedLibraryScope? _mergedScope;
/// If `null`, [SourceLoader.computeFieldPromotability] hasn't been called
/// yet, or field promotion is disabled for this library. If not `null`,
/// field promotion is enabled for this library and this is the set of private
/// field names for which promotion is blocked due to the presence of a
/// non-final field or a concrete getter.
Set<String>? unpromotablePrivateFieldNames;
SourceLibraryBuilder.internal(
SourceLoader loader,
Uri importUri,
@ -516,6 +523,9 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
languageVersion.version >=
libraryFeatures.inferenceUpdate1.enabledVersion;
bool get isInferenceUpdate2Enabled =>
libraryFeatures.inferenceUpdate2.isEnabled;
bool? _isNonNullableByDefault;
@override

View file

@ -2272,6 +2272,21 @@ severity: $severity
ticker.logMs("Added noSuchMethod forwarders");
}
/// Sets [SourceLibraryBuilder.unpromotablePrivateFieldNames] based on all the
/// classes in [sourceClasses].
void computeFieldPromotability(List<SourceClassBuilder> sourceClasses) {
for (SourceClassBuilder builder in sourceClasses) {
SourceLibraryBuilder libraryBuilder = builder.libraryBuilder;
if (!libraryBuilder.isInferenceUpdate2Enabled) continue;
Set<String> unpromotablePrivateFieldNames =
libraryBuilder.unpromotablePrivateFieldNames ??= {};
if (libraryBuilder.loader == this && !builder.isPatch) {
builder.addUnpromotablePrivateFieldNames(unpromotablePrivateFieldNames);
}
}
ticker.logMs("Computed unpromotable private field names");
}
void checkMixins(List<SourceClassBuilder> sourceClasses) {
for (SourceClassBuilder builder in sourceClasses) {
if (!builder.isPatch) {

View file

@ -5011,15 +5011,21 @@ class InferenceVisitorImpl extends InferenceVisitorBase
Name propertyName,
DartType typeContext,
{required bool isThisReceiver,
ObjectAccessTarget? readTarget}) {
ObjectAccessTarget? readTarget,
Expression? propertyGetNode}) {
// ignore: unnecessary_null_comparison
assert(isThisReceiver != null);
Map<DartType, NonPromotionReason> Function() whyNotPromoted =
flowAnalysis.whyNotPromoted(receiver);
readTarget ??= findInterfaceMember(receiverType, propertyName, fileOffset,
includeExtensionMethods: true,
callSiteAccessKind: CallSiteAccessKind.getterInvocation);
DartType readType = readTarget.getGetterType(this);
readType = flowAnalysis.propertyGet(propertyGetNode, receiver,
propertyName.text, readTarget.member, readType) ??
readType;
Expression read;
ExpressionInferenceResult? readResult;
@ -5160,9 +5166,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
read.fileOffset,
propertyName.text.length,
context: getWhyNotPromotedContext(
flowAnalysis.whyNotPromoted(receiver)(),
read,
(type) => !type.isPotentiallyNullable));
whyNotPromoted(), read, (type) => !type.isPotentiallyNullable));
}
return new PropertyGetInferenceResult(readResult, readTarget.member);
}
@ -6175,11 +6179,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase
PropertyGetInferenceResult propertyGetInferenceResult = _computePropertyGet(
node.fileOffset, receiver, receiverType, node.name, typeContext,
isThisReceiver: node.receiver is ThisExpression);
isThisReceiver: node.receiver is ThisExpression, propertyGetNode: node);
ExpressionInferenceResult readResult =
propertyGetInferenceResult.expressionInferenceResult;
flowAnalysis.propertyGet(node, node.receiver, node.name.text,
propertyGetInferenceResult.member, readResult.inferredType);
ExpressionInferenceResult expressionInferenceResult =
createNullAwareExpressionInferenceResult(
readResult.inferredType, readResult.expression, nullAwareGuards);
@ -6282,7 +6284,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
PropertyGetInferenceResult propertyGetInferenceResult =
_computePropertyGet(
node.fileOffset, receiver, receiverType, member.name, typeContext,
isThisReceiver: true, readTarget: target);
isThisReceiver: true, readTarget: target, propertyGetNode: node);
ExpressionInferenceResult readResult =
propertyGetInferenceResult.expressionInferenceResult;
return new ExpressionInferenceResult(

View file

@ -3048,8 +3048,10 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
kind, originalReceiver, originalName,
resultType: calleeType, interfaceTarget: originalTarget)
..fileOffset = fileOffset;
flowAnalysis.propertyGet(originalPropertyGet, originalReceiver,
originalName.text, originalTarget, calleeType);
calleeType = flowAnalysis.propertyGet(originalPropertyGet, originalReceiver,
originalName.text, originalTarget, calleeType) ??
calleeType;
originalPropertyGet.resultType = calleeType;
Expression propertyGet = originalPropertyGet;
if (receiver is! ThisExpression &&
calleeType is! DynamicType &&
@ -3133,8 +3135,8 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
nullAwareAction.receiver == originalPropertyGet) {
invocationResult = new ExpressionInferenceResult(
invocationResult.inferredType,
new InstanceGetterInvocation(originalPropertyGet.kind,
originalReceiver, originalName, nullAwareAction.arguments,
new InstanceGetterInvocation(originalPropertyGet.kind, receiver,
originalName, nullAwareAction.arguments,
interfaceTarget: originalTarget,
functionType: nullAwareAction.functionType)
..fileOffset = nullAwareAction.fileOffset);
@ -3142,16 +3144,16 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
nullAwareAction.receiver == originalPropertyGet) {
invocationResult = new ExpressionInferenceResult(
invocationResult.inferredType,
new InstanceGetterInvocation(originalPropertyGet.kind,
originalReceiver, originalName, nullAwareAction.arguments,
new InstanceGetterInvocation(originalPropertyGet.kind, receiver,
originalName, nullAwareAction.arguments,
interfaceTarget: originalTarget, functionType: null)
..fileOffset = nullAwareAction.fileOffset);
} else if (nullAwareAction is FunctionInvocation &&
nullAwareAction.receiver == originalPropertyGet) {
invocationResult = new ExpressionInferenceResult(
invocationResult.inferredType,
new InstanceGetterInvocation(originalPropertyGet.kind,
originalReceiver, originalName, nullAwareAction.arguments,
new InstanceGetterInvocation(originalPropertyGet.kind, receiver,
originalName, nullAwareAction.arguments,
interfaceTarget: originalTarget,
functionType: nullAwareAction.functionType)
..fileOffset = nullAwareAction.fileOffset);

View file

@ -306,7 +306,15 @@ class OperationsCfe
final bool isNonNullableByDefault;
OperationsCfe(this.typeEnvironment, {required this.isNonNullableByDefault});
/// If `null`, field promotion is disabled for this library. If not `null`,
/// field promotion is enabled for this library and this is the set of private
/// field names for which promotion is blocked due to the presence of a
/// non-final field or a concrete getter.
final Set<String>? unpromotablePrivateFieldNames;
OperationsCfe(this.typeEnvironment,
{required this.isNonNullableByDefault,
this.unpromotablePrivateFieldNames});
@override
TypeClassification classifyType(DartType? type) {
@ -334,7 +342,15 @@ class OperationsCfe
}
@override
bool isPropertyPromotable(Object property) => false;
bool isPropertyPromotable(covariant Member property) {
Set<String>? unpromotablePrivateFieldNames =
this.unpromotablePrivateFieldNames;
if (unpromotablePrivateFieldNames == null) return false;
if (property is! Field) return false;
String name = property.name.text;
if (!name.startsWith('_')) return false;
return !unpromotablePrivateFieldNames.contains(name);
}
// TODO(cstefantsova): Consider checking for mutual subtypes instead of ==.
@override

View file

@ -144,7 +144,9 @@ class TypeInferrerImpl implements TypeInferrer {
instrumentation = isTopLevel ? null : engine.instrumentation,
typeSchemaEnvironment = engine.typeSchemaEnvironment,
operations = new OperationsCfe(engine.typeSchemaEnvironment,
isNonNullableByDefault: libraryBuilder.isNonNullableByDefault);
isNonNullableByDefault: libraryBuilder.isNonNullableByDefault,
unpromotablePrivateFieldNames:
libraryBuilder.unpromotablePrivateFieldNames);
InferenceVisitorBase _createInferenceVisitor(InferenceHelper? helper) {
// For full (non-top level) inference, we need access to the

View file

@ -1050,6 +1050,7 @@ product
profile
progresses
promo
promotability
proof
prop
property's
@ -1551,6 +1552,7 @@ unpaired
unparenthesized
unparsed
unpleasant
unpromotable
unqualified
unreachable
unregister

View file

@ -510,6 +510,7 @@ prematurely
prerequisite
press
pretends
preventing
printouts
processes
processors

View file

@ -0,0 +1,86 @@
// 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 basic field promotion functionality when the feature is enabled.
abstract class C {
final int? _privateFinalField;
final int? publicFinalField;
int? _privateField;
int? publicField;
int? get _privateAbstractGetter;
int? get publicAbstractGetter;
int? get _privateConcreteGetter => 0;
int? get publicConcreteGetter => 0;
C(int? i) : _privateFinalField = i, publicFinalField = i;
}
void acceptsInt(int x) {}
void testPrivateFinalField(C c) {
if (c._privateFinalField != null) {
var x = c._privateFinalField;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testPublicFinalField(C c) {
if (c.publicFinalField != null) {
var x = c.publicFinalField;
// `x` has type `int?` so this is ok
x = null;
}
}
void testPrivateField(C c) {
if (c._privateField != null) {
var x = c._privateField;
// `x` has type `int?` so this is ok
x = null;
}
}
void testPublicField(C c) {
if (c.publicField != null) {
var x = c.publicField;
// `x` has type `int?` so this is ok
x = null;
}
}
void testPrivateAbstractGetter(C c) {
if (c._privateAbstractGetter != null) {
var x = c._privateAbstractGetter;
// `x` has type `int?` so this is ok
x = null;
}
}
void testPublicAbstractGetter(C c) {
if (c.publicAbstractGetter != null) {
var x = c.publicAbstractGetter;
// `x` has type `int?` so this is ok
x = null;
}
}
void testPrivateConcreteGetter(C c) {
if (c._privateConcreteGetter != null) {
var x = c._privateConcreteGetter;
// `x` has type `int?` so this is ok
x = null;
}
}
void testPublicConcreteGetter(C c) {
if (c.publicConcreteGetter != null) {
var x = c.publicConcreteGetter;
// `x` has type `int?` so this is ok
x = null;
}
}
main() {}

View file

@ -0,0 +1,24 @@
abstract class C {
final int? _privateFinalField;
final int? publicFinalField;
int? _privateField;
int? publicField;
int? get _privateAbstractGetter;
int? get publicAbstractGetter;
int? get _privateConcreteGetter => 0;
int? get publicConcreteGetter => 0;
C(int? i)
: _privateFinalField = i,
publicFinalField = i;
}
void acceptsInt(int x) {}
void testPrivateFinalField(C c) {}
void testPublicFinalField(C c) {}
void testPrivateField(C c) {}
void testPublicField(C c) {}
void testPrivateAbstractGetter(C c) {}
void testPublicAbstractGetter(C c) {}
void testPrivateConcreteGetter(C c) {}
void testPublicConcreteGetter(C c) {}
main() {}

View file

@ -0,0 +1,24 @@
abstract class C {
C(int? i)
: _privateFinalField = i,
publicFinalField = i;
final int? _privateFinalField;
final int? publicFinalField;
int? _privateField;
int? get _privateAbstractGetter;
int? get _privateConcreteGetter => 0;
int? get publicAbstractGetter;
int? get publicConcreteGetter => 0;
int? publicField;
}
main() {}
void acceptsInt(int x) {}
void testPrivateAbstractGetter(C c) {}
void testPrivateConcreteGetter(C c) {}
void testPrivateField(C c) {}
void testPrivateFinalField(C c) {}
void testPublicAbstractGetter(C c) {}
void testPublicConcreteGetter(C c) {}
void testPublicField(C c) {}
void testPublicFinalField(C c) {}

View file

@ -0,0 +1,69 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
abstract class C extends core::Object {
final field core::int? _privateFinalField;
final field core::int? publicFinalField;
field core::int? _privateField = null;
field core::int? publicField = null;
constructor •(core::int? i) → self::C
: self::C::_privateFinalField = i, self::C::publicFinalField = i, super core::Object::•()
;
abstract get _privateAbstractGetter() → core::int?;
abstract get publicAbstractGetter() → core::int?;
get _privateConcreteGetter() → core::int?
return 0;
get publicConcreteGetter() → core::int?
return 0;
}
static method acceptsInt(core::int x) → void {}
static method testPrivateFinalField(self::C c) → void {
if(!(c.{self::C::_privateFinalField}{core::int?} == null)) {
core::int x = c.{self::C::_privateFinalField}{core::int};
self::acceptsInt(x);
}
}
static method testPublicFinalField(self::C c) → void {
if(!(c.{self::C::publicFinalField}{core::int?} == null)) {
core::int? x = c.{self::C::publicFinalField}{core::int?};
x = null;
}
}
static method testPrivateField(self::C c) → void {
if(!(c.{self::C::_privateField}{core::int?} == null)) {
core::int? x = c.{self::C::_privateField}{core::int?};
x = null;
}
}
static method testPublicField(self::C c) → void {
if(!(c.{self::C::publicField}{core::int?} == null)) {
core::int? x = c.{self::C::publicField}{core::int?};
x = null;
}
}
static method testPrivateAbstractGetter(self::C c) → void {
if(!(c.{self::C::_privateAbstractGetter}{core::int?} == null)) {
core::int? x = c.{self::C::_privateAbstractGetter}{core::int?};
x = null;
}
}
static method testPublicAbstractGetter(self::C c) → void {
if(!(c.{self::C::publicAbstractGetter}{core::int?} == null)) {
core::int? x = c.{self::C::publicAbstractGetter}{core::int?};
x = null;
}
}
static method testPrivateConcreteGetter(self::C c) → void {
if(!(c.{self::C::_privateConcreteGetter}{core::int?} == null)) {
core::int? x = c.{self::C::_privateConcreteGetter}{core::int?};
x = null;
}
}
static method testPublicConcreteGetter(self::C c) → void {
if(!(c.{self::C::publicConcreteGetter}{core::int?} == null)) {
core::int? x = c.{self::C::publicConcreteGetter}{core::int?};
x = null;
}
}
static method main() → dynamic {}

View file

@ -0,0 +1,69 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
abstract class C extends core::Object {
final field core::int? _privateFinalField;
final field core::int? publicFinalField;
field core::int? _privateField = null;
field core::int? publicField = null;
constructor •(core::int? i) → self::C
: self::C::_privateFinalField = i, self::C::publicFinalField = i, super core::Object::•()
;
abstract get _privateAbstractGetter() → core::int?;
abstract get publicAbstractGetter() → core::int?;
get _privateConcreteGetter() → core::int?
return 0;
get publicConcreteGetter() → core::int?
return 0;
}
static method acceptsInt(core::int x) → void {}
static method testPrivateFinalField(self::C c) → void {
if(!(c.{self::C::_privateFinalField}{core::int?} == null)) {
core::int x = c.{self::C::_privateFinalField}{core::int};
self::acceptsInt(x);
}
}
static method testPublicFinalField(self::C c) → void {
if(!(c.{self::C::publicFinalField}{core::int?} == null)) {
core::int? x = c.{self::C::publicFinalField}{core::int?};
x = null;
}
}
static method testPrivateField(self::C c) → void {
if(!(c.{self::C::_privateField}{core::int?} == null)) {
core::int? x = c.{self::C::_privateField}{core::int?};
x = null;
}
}
static method testPublicField(self::C c) → void {
if(!(c.{self::C::publicField}{core::int?} == null)) {
core::int? x = c.{self::C::publicField}{core::int?};
x = null;
}
}
static method testPrivateAbstractGetter(self::C c) → void {
if(!(c.{self::C::_privateAbstractGetter}{core::int?} == null)) {
core::int? x = c.{self::C::_privateAbstractGetter}{core::int?};
x = null;
}
}
static method testPublicAbstractGetter(self::C c) → void {
if(!(c.{self::C::publicAbstractGetter}{core::int?} == null)) {
core::int? x = c.{self::C::publicAbstractGetter}{core::int?};
x = null;
}
}
static method testPrivateConcreteGetter(self::C c) → void {
if(!(c.{self::C::_privateConcreteGetter}{core::int?} == null)) {
core::int? x = c.{self::C::_privateConcreteGetter}{core::int?};
x = null;
}
}
static method testPublicConcreteGetter(self::C c) → void {
if(!(c.{self::C::publicConcreteGetter}{core::int?} == null)) {
core::int? x = c.{self::C::publicConcreteGetter}{core::int?};
x = null;
}
}
static method main() → dynamic {}

View file

@ -0,0 +1,38 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
abstract class C extends core::Object {
final field core::int? _privateFinalField;
final field core::int? publicFinalField;
field core::int? _privateField;
field core::int? publicField;
constructor •(core::int? i) → self::C
;
abstract get _privateAbstractGetter() → core::int?;
abstract get publicAbstractGetter() → core::int?;
get _privateConcreteGetter() → core::int?
;
get publicConcreteGetter() → core::int?
;
}
static method acceptsInt(core::int x) → void
;
static method testPrivateFinalField(self::C c) → void
;
static method testPublicFinalField(self::C c) → void
;
static method testPrivateField(self::C c) → void
;
static method testPublicField(self::C c) → void
;
static method testPrivateAbstractGetter(self::C c) → void
;
static method testPublicAbstractGetter(self::C c) → void
;
static method testPrivateConcreteGetter(self::C c) → void
;
static method testPublicConcreteGetter(self::C c) → void
;
static method main() → dynamic
;

View file

@ -0,0 +1,69 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
abstract class C extends core::Object {
final field core::int? _privateFinalField;
final field core::int? publicFinalField;
field core::int? _privateField = null;
field core::int? publicField = null;
constructor •(core::int? i) → self::C
: self::C::_privateFinalField = i, self::C::publicFinalField = i, super core::Object::•()
;
abstract get _privateAbstractGetter() → core::int?;
abstract get publicAbstractGetter() → core::int?;
get _privateConcreteGetter() → core::int?
return 0;
get publicConcreteGetter() → core::int?
return 0;
}
static method acceptsInt(core::int x) → void {}
static method testPrivateFinalField(self::C c) → void {
if(!(c.{self::C::_privateFinalField}{core::int?} == null)) {
core::int x = c.{self::C::_privateFinalField}{core::int};
self::acceptsInt(x);
}
}
static method testPublicFinalField(self::C c) → void {
if(!(c.{self::C::publicFinalField}{core::int?} == null)) {
core::int? x = c.{self::C::publicFinalField}{core::int?};
x = null;
}
}
static method testPrivateField(self::C c) → void {
if(!(c.{self::C::_privateField}{core::int?} == null)) {
core::int? x = c.{self::C::_privateField}{core::int?};
x = null;
}
}
static method testPublicField(self::C c) → void {
if(!(c.{self::C::publicField}{core::int?} == null)) {
core::int? x = c.{self::C::publicField}{core::int?};
x = null;
}
}
static method testPrivateAbstractGetter(self::C c) → void {
if(!(c.{self::C::_privateAbstractGetter}{core::int?} == null)) {
core::int? x = c.{self::C::_privateAbstractGetter}{core::int?};
x = null;
}
}
static method testPublicAbstractGetter(self::C c) → void {
if(!(c.{self::C::publicAbstractGetter}{core::int?} == null)) {
core::int? x = c.{self::C::publicAbstractGetter}{core::int?};
x = null;
}
}
static method testPrivateConcreteGetter(self::C c) → void {
if(!(c.{self::C::_privateConcreteGetter}{core::int?} == null)) {
core::int? x = c.{self::C::_privateConcreteGetter}{core::int?};
x = null;
}
}
static method testPublicConcreteGetter(self::C c) → void {
if(!(c.{self::C::publicConcreteGetter}{core::int?} == null)) {
core::int? x = c.{self::C::publicConcreteGetter}{core::int?};
x = null;
}
}
static method main() → dynamic {}

View file

@ -0,0 +1,21 @@
// 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 doesn't happen when the feature is disabled.
// @dart=2.18
abstract class C {
final int? _privateFinalField;
C(int? i) : _privateFinalField = i;
}
void testPrivateFinalField(C c) {
if (c._privateFinalField != null) {
var x = c._privateFinalField;
// `x` has type `int?` so this is ok
x = null;
}
}

View file

@ -0,0 +1,7 @@
// @dart = 2.18
abstract class C {
final int? _privateFinalField;
C(int? i) : _privateFinalField = i;
}
void testPrivateFinalField(C c) {}

View file

@ -0,0 +1,7 @@
// @dart = 2.18
abstract class C {
C(int? i) : _privateFinalField = i;
final int? _privateFinalField;
}
void testPrivateFinalField(C c) {}

View file

@ -0,0 +1,16 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
abstract class C extends core::Object {
final field core::int? _privateFinalField;
constructor •(core::int? i) → self::C
: self::C::_privateFinalField = i, super core::Object::•()
;
}
static method testPrivateFinalField(self::C c) → void {
if(!(c.{self::C::_privateFinalField}{core::int?} == null)) {
core::int? x = c.{self::C::_privateFinalField}{core::int?};
x = null;
}
}

View file

@ -0,0 +1,16 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
abstract class C extends core::Object {
final field core::int? _privateFinalField;
constructor •(core::int? i) → self::C
: self::C::_privateFinalField = i, super core::Object::•()
;
}
static method testPrivateFinalField(self::C c) → void {
if(!(c.{self::C::_privateFinalField}{core::int?} == null)) {
core::int? x = c.{self::C::_privateFinalField}{core::int?};
x = null;
}
}

View file

@ -0,0 +1,11 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
abstract class C extends core::Object {
final field core::int? _privateFinalField;
constructor •(core::int? i) → self::C
;
}
static method testPrivateFinalField(self::C c) → void
;

View file

@ -0,0 +1,16 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
abstract class C extends core::Object {
final field core::int? _privateFinalField;
constructor •(core::int? i) → self::C
: self::C::_privateFinalField = i, super core::Object::•()
;
}
static method testPrivateFinalField(self::C c) → void {
if(!(c.{self::C::_privateFinalField}{core::int?} == null)) {
core::int? x = c.{self::C::_privateFinalField}{core::int?};
x = null;
}
}

View file

@ -0,0 +1,37 @@
class C {
final int? _promotable;
final int? _notPromotable;
C(int i)
: _promotable = i,
_notPromotable = i;
static final staticPromotable =
((C c) => c._promotable != null ? c._promotable : 0)(new C(0));
static final staticNotPromotable =
((C c) => c._notPromotable != null ? c._notPromotable : 0)(new C(0));
final instancePromotable =
((C c) => c._promotable != null ? c._promotable : 0)(new C(0));
final instanceNotPromotable =
((C c) => c._notPromotable != null ? c._notPromotable : 0)(new C(0));
late final instancePromotableViaThis = _promotable != null ? _promotable : 0;
late final instanceNotPromotableViaThis =
_notPromotable != null ? _notPromotable : 0;
}
class D {
int? _notPromotable;
}
final topLevelPromotable =
((C c) => c._promotable != null ? c._promotable : 0)(new C(0));
final topLevelNotPromotable =
((C c) => c._notPromotable != null ? c._notPromotable : 0)(new C(0));
void acceptsInt(int x) {}
void testTopLevelPromotable() {}
void testTopLevelNotPromotable() {}
void testStaticPromotable() {}
void testStaticNotPromotable() {}
void testInstancePromotable(C c) {}
void testInstanceNotPromotable(C c) {}
void testInstancePromotableViaThis(C c) {}
void testInstanceNotPromotableViaThis(C c) {}
main() {}

View file

@ -0,0 +1,37 @@
class C {
C(int i)
: _promotable = i,
_notPromotable = i;
final instanceNotPromotable =
((C c) => c._notPromotable != null ? c._notPromotable : 0)(new C(0));
final instancePromotable =
((C c) => c._promotable != null ? c._promotable : 0)(new C(0));
final int? _notPromotable;
final int? _promotable;
late final instanceNotPromotableViaThis =
_notPromotable != null ? _notPromotable : 0;
late final instancePromotableViaThis = _promotable != null ? _promotable : 0;
static final staticNotPromotable =
((C c) => c._notPromotable != null ? c._notPromotable : 0)(new C(0));
static final staticPromotable =
((C c) => c._promotable != null ? c._promotable : 0)(new C(0));
}
class D {
int? _notPromotable;
}
final topLevelNotPromotable =
((C c) => c._notPromotable != null ? c._notPromotable : 0)(new C(0));
final topLevelPromotable =
((C c) => c._promotable != null ? c._promotable : 0)(new C(0));
main() {}
void acceptsInt(int x) {}
void testInstanceNotPromotable(C c) {}
void testInstanceNotPromotableViaThis(C c) {}
void testInstancePromotable(C c) {}
void testInstancePromotableViaThis(C c) {}
void testStaticNotPromotable() {}
void testStaticPromotable() {}
void testTopLevelNotPromotable() {}
void testTopLevelPromotable() {}

View file

@ -0,0 +1,86 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/inference_update_2/during_top_level_type_inference.dart:42:14: Error: The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
// acceptsInt(x);
// ^
//
// pkg/front_end/testcases/inference_update_2/during_top_level_type_inference.dart:54:14: Error: The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
// acceptsInt(x);
// ^
//
// pkg/front_end/testcases/inference_update_2/during_top_level_type_inference.dart:66:14: Error: The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
// acceptsInt(x);
// ^
//
// pkg/front_end/testcases/inference_update_2/during_top_level_type_inference.dart:78:14: Error: The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
// acceptsInt(x);
// ^
//
import self as self;
import "dart:core" as core;
class C extends core::Object {
final field core::int? _promotable;
final field core::int? _notPromotable;
static final field core::int? staticPromotable = ((self::C c) → core::int => !(c.{self::C::_promotable}{core::int?} == null) ?{core::int} c.{self::C::_promotable}{core::int} : 0)(new self::C::•(0)){(self::C) → core::int};
static final field core::int? staticNotPromotable = ((self::C c) → core::int? => !(c.{self::C::_notPromotable}{core::int?} == null) ?{core::int?} c.{self::C::_notPromotable}{core::int?} : 0)(new self::C::•(0)){(self::C) → core::int?};
final field core::int? instancePromotable = ((self::C c) → core::int => !(c.{self::C::_promotable}{core::int?} == null) ?{core::int} c.{self::C::_promotable}{core::int} : 0)(new self::C::•(0)){(self::C) → core::int};
final field core::int? instanceNotPromotable = ((self::C c) → core::int? => !(c.{self::C::_notPromotable}{core::int?} == null) ?{core::int?} c.{self::C::_notPromotable}{core::int?} : 0)(new self::C::•(0)){(self::C) → core::int?};
late final field core::int? instancePromotableViaThis = !(this.{self::C::_promotable}{core::int?} == null) ?{core::int} this.{self::C::_promotable}{core::int} : 0;
late final field core::int? instanceNotPromotableViaThis = !(this.{self::C::_notPromotable}{core::int?} == null) ?{core::int?} this.{self::C::_notPromotable}{core::int?} : 0;
constructor •(core::int i) → self::C
: self::C::_promotable = i, self::C::_notPromotable = i, super core::Object::•()
;
}
class D extends core::Object {
field core::int? _notPromotable = null;
synthetic constructor •() → self::D
: super core::Object::•()
;
}
static final field core::int? topLevelPromotable = ((self::C c) → core::int => !(c.{self::C::_promotable}{core::int?} == null) ?{core::int} c.{self::C::_promotable}{core::int} : 0)(new self::C::•(0)){(self::C) → core::int};
static final field core::int? topLevelNotPromotable = ((self::C c) → core::int? => !(c.{self::C::_notPromotable}{core::int?} == null) ?{core::int?} c.{self::C::_notPromotable}{core::int?} : 0)(new self::C::•(0)){(self::C) → core::int?};
static method acceptsInt(core::int x) → void {}
static method testTopLevelPromotable() → void {
core::int? x = self::topLevelPromotable;
self::acceptsInt(invalid-expression "pkg/front_end/testcases/inference_update_2/during_top_level_type_inference.dart:42:14: Error: The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
acceptsInt(x);
^" in x as{TypeError,ForNonNullableByDefault} core::int);
}
static method testTopLevelNotPromotable() → void {
core::int? x = self::topLevelNotPromotable;
x = null;
}
static method testStaticPromotable() → void {
core::int? x = self::C::staticPromotable;
self::acceptsInt(invalid-expression "pkg/front_end/testcases/inference_update_2/during_top_level_type_inference.dart:54:14: Error: The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
acceptsInt(x);
^" in x as{TypeError,ForNonNullableByDefault} core::int);
}
static method testStaticNotPromotable() → void {
core::int? x = self::C::staticNotPromotable;
x = null;
}
static method testInstancePromotable(self::C c) → void {
core::int? x = c.{self::C::instancePromotable}{core::int?};
self::acceptsInt(invalid-expression "pkg/front_end/testcases/inference_update_2/during_top_level_type_inference.dart:66:14: Error: The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
acceptsInt(x);
^" in x as{TypeError,ForNonNullableByDefault} core::int);
}
static method testInstanceNotPromotable(self::C c) → void {
core::int? x = c.{self::C::instanceNotPromotable}{core::int?};
x = null;
}
static method testInstancePromotableViaThis(self::C c) → void {
core::int? x = c.{self::C::instancePromotableViaThis}{core::int?};
self::acceptsInt(invalid-expression "pkg/front_end/testcases/inference_update_2/during_top_level_type_inference.dart:78:14: Error: The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
acceptsInt(x);
^" in x as{TypeError,ForNonNullableByDefault} core::int);
}
static method testInstanceNotPromotableViaThis(self::C c) → void {
core::int? x = c.{self::C::instanceNotPromotableViaThis}{core::int?};
x = null;
}
static method main() → dynamic {}

View file

@ -0,0 +1,43 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class C extends core::Object {
final field core::int? _promotable;
final field core::int? _notPromotable;
static final field core::int? staticPromotable;
static final field core::int? staticNotPromotable;
final field core::int? instancePromotable;
final field core::int? instanceNotPromotable;
late final field core::int? instancePromotableViaThis;
late final field core::int? instanceNotPromotableViaThis;
constructor •(core::int i) → self::C
;
}
class D extends core::Object {
field core::int? _notPromotable;
synthetic constructor •() → self::D
;
}
static final field core::int? topLevelPromotable;
static final field core::int? topLevelNotPromotable;
static method acceptsInt(core::int x) → void
;
static method testTopLevelPromotable() → void
;
static method testTopLevelNotPromotable() → void
;
static method testStaticPromotable() → void
;
static method testStaticNotPromotable() → void
;
static method testInstancePromotable(self::C c) → void
;
static method testInstanceNotPromotable(self::C c) → void
;
static method testInstancePromotableViaThis(self::C c) → void
;
static method testInstanceNotPromotableViaThis(self::C c) → void
;
static method main() → dynamic
;

View file

@ -0,0 +1,54 @@
// 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 is prevented if there is a synthetic instance
// getter of the same name in the library that's a noSuchMethod forwarder.
import 'field_promotion_and_no_such_method_lib.dart' as otherLib;
abstract class C {
final int? _f1;
final int? _f2;
C(int? i) : _f1 = i, _f2 = i;
}
abstract class D {
final int? _f1;
D(int? i) : _f1 = i;
}
class E implements D {
// Implicitly implements _f1 as a getter that forwards to noSuchMethod
@override
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class F implements otherLib.C {
// Implicitly implements _f2 as a getter that throws; but the name _f2 comes
// from the other library so it doesn't conflict with the _f2 in this library.
@override
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
void acceptsInt(int x) {}
void testConflictsWithNoSuchMethodForwarder(C c) {
if (c._f1 != null) {
var x = c._f1;
// `x` has type `int?` so this is ok
x = null;
}
}
void testNoConflictWithNoSuchMethodForwarderForDifferentLib(C c) {
if (c._f2 != null) {
var x = c._f2;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}

View file

@ -0,0 +1,28 @@
import 'field_promotion_and_no_such_method_lib.dart' as otherLib;
abstract class C {
final int? _f1;
final int? _f2;
C(int? i)
: _f1 = i,
_f2 = i;
}
abstract class D {
final int? _f1;
D(int? i) : _f1 = i;
}
class E implements D {
@override
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class F implements otherLib.C {
@override
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
void acceptsInt(int x) {}
void testConflictsWithNoSuchMethodForwarder(C c) {}
void testNoConflictWithNoSuchMethodForwarderForDifferentLib(C c) {}

View file

@ -0,0 +1,28 @@
import 'field_promotion_and_no_such_method_lib.dart' as otherLib;
abstract class C {
C(int? i)
: _f1 = i,
_f2 = i;
final int? _f1;
final int? _f2;
}
abstract class D {
D(int? i) : _f1 = i;
final int? _f1;
}
class E implements D {
@override
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class F implements otherLib.C {
@override
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
void acceptsInt(int x) {}
void testConflictsWithNoSuchMethodForwarder(C c) {}
void testNoConflictWithNoSuchMethodForwarderForDifferentLib(C c) {}

View file

@ -0,0 +1,74 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "field_promotion_and_no_such_method_lib.dart" as fie;
import "org-dartlang-testcase:///field_promotion_and_no_such_method_lib.dart" as otherLib;
abstract class C extends core::Object {
final field core::int? _f1;
final field core::int? _f2;
constructor •(core::int? i) → self::C
: self::C::_f1 = i, self::C::_f2 = i, super core::Object::•()
;
}
abstract class D extends core::Object {
final field core::int? _f1;
constructor •(core::int? i) → self::D
: self::D::_f1 = i, super core::Object::•()
;
}
class E extends core::Object implements self::D {
synthetic constructor •() → self::E
: super core::Object::•()
;
@#C1
method noSuchMethod(core::Invocation invocation) → dynamic
return super.{core::Object::noSuchMethod}(invocation);
no-such-method-forwarder get _f1() → core::int?
return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
}
class F extends core::Object implements fie::C {
synthetic constructor •() → self::F
: super core::Object::•()
;
@#C1
method noSuchMethod(core::Invocation invocation) → dynamic
return super.{core::Object::noSuchMethod}(invocation);
no-such-method-forwarder get _f2() → core::int?
return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C6, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
}
static method acceptsInt(core::int x) → void {}
static method testConflictsWithNoSuchMethodForwarder(self::C c) → void {
if(!(c.{self::C::_f1}{core::int?} == null)) {
core::int? x = c.{self::C::_f1}{core::int?};
x = null;
}
}
static method testNoConflictWithNoSuchMethodForwarderForDifferentLib(self::C c) → void {
if(!(c.{self::C::_f2}{core::int?} == null)) {
core::int x = c.{self::C::_f2}{core::int};
self::acceptsInt(x);
}
}
library /*isNonNullableByDefault*/;
import self as fie;
import "dart:core" as core;
class C extends core::Object {
synthetic constructor •() → fie::C
: super core::Object::•()
;
get _f2() → core::int?
return 0;
}
constants {
#C1 = core::_Override {}
#C2 = #org-dartlang-testcase:///field_promotion_and_no_such_method.dart::_f1
#C3 = <core::Type*>[]
#C4 = <dynamic>[]
#C5 = <core::Symbol*, dynamic>{)
#C6 = #org-dartlang-testcase:///field_promotion_and_no_such_method.dart::_f2
}

View file

@ -0,0 +1,74 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "field_promotion_and_no_such_method_lib.dart" as fie;
import "org-dartlang-testcase:///field_promotion_and_no_such_method_lib.dart" as otherLib;
abstract class C extends core::Object {
final field core::int? _f1;
final field core::int? _f2;
constructor •(core::int? i) → self::C
: self::C::_f1 = i, self::C::_f2 = i, super core::Object::•()
;
}
abstract class D extends core::Object {
final field core::int? _f1;
constructor •(core::int? i) → self::D
: self::D::_f1 = i, super core::Object::•()
;
}
class E extends core::Object implements self::D {
synthetic constructor •() → self::E
: super core::Object::•()
;
@#C1
method noSuchMethod(core::Invocation invocation) → dynamic
return super.{core::Object::noSuchMethod}(invocation);
no-such-method-forwarder get _f1() → core::int?
return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
}
class F extends core::Object implements fie::C {
synthetic constructor •() → self::F
: super core::Object::•()
;
@#C1
method noSuchMethod(core::Invocation invocation) → dynamic
return super.{core::Object::noSuchMethod}(invocation);
no-such-method-forwarder get _f2() → core::int?
return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C6, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
}
static method acceptsInt(core::int x) → void {}
static method testConflictsWithNoSuchMethodForwarder(self::C c) → void {
if(!(c.{self::C::_f1}{core::int?} == null)) {
core::int? x = c.{self::C::_f1}{core::int?};
x = null;
}
}
static method testNoConflictWithNoSuchMethodForwarderForDifferentLib(self::C c) → void {
if(!(c.{self::C::_f2}{core::int?} == null)) {
core::int x = c.{self::C::_f2}{core::int};
self::acceptsInt(x);
}
}
library /*isNonNullableByDefault*/;
import self as fie;
import "dart:core" as core;
class C extends core::Object {
synthetic constructor •() → fie::C
: super core::Object::•()
;
get _f2() → core::int?
return 0;
}
constants {
#C1 = core::_Override {}
#C2 = #org-dartlang-testcase:///field_promotion_and_no_such_method.dart::_f1
#C3 = <core::Type*>[]
#C4 = <dynamic>[]
#C5 = <core::Symbol*, dynamic>{)
#C6 = #org-dartlang-testcase:///field_promotion_and_no_such_method.dart::_f2
}

View file

@ -0,0 +1,67 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "field_promotion_and_no_such_method_lib.dart" as fie;
import "org-dartlang-testcase:///field_promotion_and_no_such_method_lib.dart" as otherLib;
abstract class C extends core::Object {
final field core::int? _f1;
final field core::int? _f2;
constructor •(core::int? i) → self::C
;
}
abstract class D extends core::Object {
final field core::int? _f1;
constructor •(core::int? i) → self::D
;
}
class E extends core::Object implements self::D {
synthetic constructor •() → self::E
;
@core::override
method noSuchMethod(core::Invocation invocation) → dynamic
;
no-such-method-forwarder get _f1() → core::int?
return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#_f1, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
}
class F extends core::Object implements fie::C {
synthetic constructor •() → self::F
;
@core::override
method noSuchMethod(core::Invocation invocation) → dynamic
;
no-such-method-forwarder get _f2() → core::int?
return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#_f2, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
}
static method acceptsInt(core::int x) → void
;
static method testConflictsWithNoSuchMethodForwarder(self::C c) → void
;
static method testNoConflictWithNoSuchMethodForwarderForDifferentLib(self::C c) → void
;
library /*isNonNullableByDefault*/;
import self as fie;
import "dart:core" as core;
class C extends core::Object {
synthetic constructor •() → fie::C
;
get _f2() → core::int?
;
}
Extra constant evaluation status:
Evaluated: StaticGet @ org-dartlang-testcase:///field_promotion_and_no_such_method.dart:26:4 -> InstanceConstant(const _Override{})
Evaluated: SymbolLiteral @ org-dartlang-testcase:///field_promotion_and_no_such_method.dart:23:7 -> SymbolConstant(#_f1)
Evaluated: ListLiteral @ org-dartlang-testcase:///field_promotion_and_no_such_method.dart:23:7 -> ListConstant(const <Type*>[])
Evaluated: ListLiteral @ org-dartlang-testcase:///field_promotion_and_no_such_method.dart:23:7 -> ListConstant(const <dynamic>[])
Evaluated: MapLiteral @ org-dartlang-testcase:///field_promotion_and_no_such_method.dart:23:7 -> MapConstant(const <Symbol*, dynamic>{})
Evaluated: StaticGet @ org-dartlang-testcase:///field_promotion_and_no_such_method.dart:34:4 -> InstanceConstant(const _Override{})
Evaluated: SymbolLiteral @ org-dartlang-testcase:///field_promotion_and_no_such_method.dart:30:7 -> SymbolConstant(#_f2)
Evaluated: ListLiteral @ org-dartlang-testcase:///field_promotion_and_no_such_method.dart:30:7 -> ListConstant(const <Type*>[])
Evaluated: ListLiteral @ org-dartlang-testcase:///field_promotion_and_no_such_method.dart:30:7 -> ListConstant(const <dynamic>[])
Evaluated: MapLiteral @ org-dartlang-testcase:///field_promotion_and_no_such_method.dart:30:7 -> MapConstant(const <Symbol*, dynamic>{})
Extra constant evaluation: evaluated: 20, effectively constant: 10

View file

@ -0,0 +1,74 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "field_promotion_and_no_such_method_lib.dart" as fie;
import "org-dartlang-testcase:///field_promotion_and_no_such_method_lib.dart" as otherLib;
abstract class C extends core::Object {
final field core::int? _f1;
final field core::int? _f2;
constructor •(core::int? i) → self::C
: self::C::_f1 = i, self::C::_f2 = i, super core::Object::•()
;
}
abstract class D extends core::Object {
final field core::int? _f1;
constructor •(core::int? i) → self::D
: self::D::_f1 = i, super core::Object::•()
;
}
class E extends core::Object implements self::D {
synthetic constructor •() → self::E
: super core::Object::•()
;
@#C1
method noSuchMethod(core::Invocation invocation) → dynamic
return super.{core::Object::noSuchMethod}(invocation);
no-such-method-forwarder get _f1() → core::int?
return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
}
class F extends core::Object implements fie::C {
synthetic constructor •() → self::F
: super core::Object::•()
;
@#C1
method noSuchMethod(core::Invocation invocation) → dynamic
return super.{core::Object::noSuchMethod}(invocation);
no-such-method-forwarder get _f2() → core::int?
return throw core::NoSuchMethodError::withInvocation(this, new core::_InvocationMirror::_withType(#C6, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
}
static method acceptsInt(core::int x) → void {}
static method testConflictsWithNoSuchMethodForwarder(self::C c) → void {
if(!(c.{self::C::_f1}{core::int?} == null)) {
core::int? x = c.{self::C::_f1}{core::int?};
x = null;
}
}
static method testNoConflictWithNoSuchMethodForwarderForDifferentLib(self::C c) → void {
if(!(c.{self::C::_f2}{core::int?} == null)) {
core::int x = c.{self::C::_f2}{core::int};
self::acceptsInt(x);
}
}
library /*isNonNullableByDefault*/;
import self as fie;
import "dart:core" as core;
class C extends core::Object {
synthetic constructor •() → fie::C
: super core::Object::•()
;
get _f2() → core::int?
return 0;
}
constants {
#C1 = core::_Override {}
#C2 = #org-dartlang-testcase:///field_promotion_and_no_such_method.dart::_f1
#C3 = <core::Type*>[]
#C4 = <dynamic>[]
#C5 = <core::Symbol*, dynamic>{)
#C6 = #org-dartlang-testcase:///field_promotion_and_no_such_method.dart::_f2
}

View file

@ -0,0 +1,10 @@
// 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.
// Library declaring a getter `_f2`, to check that it doesn't prevent promotion
// of a field named `_f2` in `field_promotion_and_no_such_method.dart`.
class C {
int? get _f2 => 0;
}

View file

@ -0,0 +1,159 @@
// 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 is prevented if there is another instance getter
// of the same name in the library that's a non-final field or a concrete
// getter.
part 'field_promotion_name_conflicts_part.dart';
abstract class C {
final int? _f1;
final int? _f2;
final int? _f3;
final int? _f4;
final int? _f5;
final int? _f6;
final int? _f7;
final int? _f8;
final int? _f9;
final int? _f10;
final int? _f11;
final int? _f12;
final int? _f13;
C(int? i) : _f1 = i, _f2 = i, _f3 = i, _f4 = i, _f5 = i, _f6 = i, _f7 = i, _f8 = i, _f9 = i, _f10 = i, _f11 = i, _f12 = i, _f13 = i;
}
abstract class D {
final int? _f1;
int? _f2;
int? get _f3;
int? get _f4 => 0;
set _f5(int? i) {}
static int? _f6;
static int? get _f7 => 0;
D(int? i) : _f1 = i;
}
int? _f8;
int? get _f9 => 0;
extension on String {
int? get _f10 => 0;
}
mixin M {
int? _f12;
int? get _f13 => 0;
}
void acceptsInt(int x) {}
void testFinalField(C c) {
if (c._f1 != null) {
var x = c._f1;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testNonFinalField(C c) {
if (c._f2 != null) {
var x = c._f2;
// `x` has type `int?` so this is ok
x = null;
}
}
void testAbstractGetter(C c) {
if (c._f3 != null) {
var x = c._f3;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testConcreteGetter(C c) {
if (c._f4 != null) {
var x = c._f4;
// `x` has type `int?` so this is ok
x = null;
}
}
void testSetter(C c) {
if (c._f5 != null) {
var x = c._f5;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testStaticField(C c) {
if (c._f6 != null) {
var x = c._f6;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testStaticGetter(C c) {
if (c._f7 != null) {
var x = c._f7;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testTopLevelField(C c) {
if (c._f8 != null) {
var x = c._f8;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testTopLevelGetter(C c) {
if (c._f9 != null) {
var x = c._f9;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testExtensionGetter(C c) {
if (c._f10 != null) {
var x = c._f10;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testGetterInPart(C c) {
if (c._f11 != null) {
var x = c._f11;
// `x` has type `int?` so this is ok
x = null;
}
}
void testFieldInMixin(C c) {
if (c._f12 != null) {
var x = c._f12;
// `x` has type `int?` so this is ok
x = null;
}
}
void testGetterInMixin(C c) {
if (c._f13 != null) {
var x = c._f13;
// `x` has type `int?` so this is ok
x = null;
}
}
main() {}

View file

@ -0,0 +1,69 @@
part 'field_promotion_name_conflicts_part.dart';
abstract class C {
final int? _f1;
final int? _f2;
final int? _f3;
final int? _f4;
final int? _f5;
final int? _f6;
final int? _f7;
final int? _f8;
final int? _f9;
final int? _f10;
final int? _f11;
final int? _f12;
final int? _f13;
C(int? i)
: _f1 = i,
_f2 = i,
_f3 = i,
_f4 = i,
_f5 = i,
_f6 = i,
_f7 = i,
_f8 = i,
_f9 = i,
_f10 = i,
_f11 = i,
_f12 = i,
_f13 = i;
}
abstract class D {
final int? _f1;
int? _f2;
int? get _f3;
int? get _f4 => 0;
set _f5(int? i) {}
static int? _f6;
static int? get _f7 => 0;
D(int? i) : _f1 = i;
}
int? _f8;
int? get _f9 => 0;
extension on String {
int? get _f10 => 0;
}
mixin M {
int? _f12;
int? get _f13 => 0;
}
void acceptsInt(int x) {}
void testFinalField(C c) {}
void testNonFinalField(C c) {}
void testAbstractGetter(C c) {}
void testConcreteGetter(C c) {}
void testSetter(C c) {}
void testStaticField(C c) {}
void testStaticGetter(C c) {}
void testTopLevelField(C c) {}
void testTopLevelGetter(C c) {}
void testExtensionGetter(C c) {}
void testGetterInPart(C c) {}
void testFieldInMixin(C c) {}
void testGetterInMixin(C c) {}
main() {}

View file

@ -0,0 +1,68 @@
part 'field_promotion_name_conflicts_part.dart';
abstract class C {
C(int? i)
: _f1 = i,
_f2 = i,
_f3 = i,
_f4 = i,
_f5 = i,
_f6 = i,
_f7 = i,
_f8 = i,
_f9 = i,
_f10 = i,
_f11 = i,
_f12 = i,
_f13 = i;
final int? _f1;
final int? _f10;
final int? _f11;
final int? _f12;
final int? _f13;
final int? _f2;
final int? _f3;
final int? _f4;
final int? _f5;
final int? _f6;
final int? _f7;
final int? _f8;
final int? _f9;
}
abstract class D {
D(int? i) : _f1 = i;
final int? _f1;
int? _f2;
int? get _f3;
int? get _f4 => 0;
set _f5(int? i) {}
static int? _f6;
static int? get _f7 => 0;
}
extension on String {
int? get _f10 => 0;
}
int? _f8;
int? get _f9 => 0;
main() {}
mixin M {
int? _f12;
int? get _f13 => 0;
}
void acceptsInt(int x) {}
void testAbstractGetter(C c) {}
void testConcreteGetter(C c) {}
void testExtensionGetter(C c) {}
void testFieldInMixin(C c) {}
void testFinalField(C c) {}
void testGetterInMixin(C c) {}
void testGetterInPart(C c) {}
void testNonFinalField(C c) {}
void testSetter(C c) {}
void testStaticField(C c) {}
void testStaticGetter(C c) {}
void testTopLevelField(C c) {}
void testTopLevelGetter(C c) {}

View file

@ -0,0 +1,137 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
part field_promotion_name_conflicts_part.dart;
abstract class C extends core::Object {
final field core::int? _f1;
final field core::int? _f2;
final field core::int? _f3;
final field core::int? _f4;
final field core::int? _f5;
final field core::int? _f6;
final field core::int? _f7;
final field core::int? _f8;
final field core::int? _f9;
final field core::int? _f10;
final field core::int? _f11;
final field core::int? _f12;
final field core::int? _f13;
constructor •(core::int? i) → self::C
: self::C::_f1 = i, self::C::_f2 = i, self::C::_f3 = i, self::C::_f4 = i, self::C::_f5 = i, self::C::_f6 = i, self::C::_f7 = i, self::C::_f8 = i, self::C::_f9 = i, self::C::_f10 = i, self::C::_f11 = i, self::C::_f12 = i, self::C::_f13 = i, super core::Object::•()
;
}
abstract class D extends core::Object {
final field core::int? _f1;
field core::int? _f2 = null;
static field core::int? _f6 = null;
constructor •(core::int? i) → self::D
: self::D::_f1 = i, super core::Object::•()
;
abstract get _f3() → core::int?;
get _f4() → core::int?
return 0;
set _f5(core::int? i) → void {}
static get _f7() → core::int?
return 0;
}
abstract class M extends core::Object /*isMixinDeclaration*/ {
field core::int? _f12 = null;
get _f13() → core::int?
return 0;
}
abstract class E extends core::Object { // from org-dartlang-testcase:///field_promotion_name_conflicts_part.dart
synthetic constructor •() → self::E
: super core::Object::•()
;
get _f11() → core::int?
return 0;
}
extension /* unnamed */ _extension#0 on core::String {
get _f10 = self::_extension#0|get#_f10;
}
static field core::int? _f8;
static get _f9() → core::int?
return 0;
static method _extension#0|get#_f10(lowered final core::String #this) → core::int?
return 0;
static method acceptsInt(core::int x) → void {}
static method testFinalField(self::C c) → void {
if(!(c.{self::C::_f1}{core::int?} == null)) {
core::int x = c.{self::C::_f1}{core::int};
self::acceptsInt(x);
}
}
static method testNonFinalField(self::C c) → void {
if(!(c.{self::C::_f2}{core::int?} == null)) {
core::int? x = c.{self::C::_f2}{core::int?};
x = null;
}
}
static method testAbstractGetter(self::C c) → void {
if(!(c.{self::C::_f3}{core::int?} == null)) {
core::int x = c.{self::C::_f3}{core::int};
self::acceptsInt(x);
}
}
static method testConcreteGetter(self::C c) → void {
if(!(c.{self::C::_f4}{core::int?} == null)) {
core::int? x = c.{self::C::_f4}{core::int?};
x = null;
}
}
static method testSetter(self::C c) → void {
if(!(c.{self::C::_f5}{core::int?} == null)) {
core::int x = c.{self::C::_f5}{core::int};
self::acceptsInt(x);
}
}
static method testStaticField(self::C c) → void {
if(!(c.{self::C::_f6}{core::int?} == null)) {
core::int x = c.{self::C::_f6}{core::int};
self::acceptsInt(x);
}
}
static method testStaticGetter(self::C c) → void {
if(!(c.{self::C::_f7}{core::int?} == null)) {
core::int x = c.{self::C::_f7}{core::int};
self::acceptsInt(x);
}
}
static method testTopLevelField(self::C c) → void {
if(!(c.{self::C::_f8}{core::int?} == null)) {
core::int x = c.{self::C::_f8}{core::int};
self::acceptsInt(x);
}
}
static method testTopLevelGetter(self::C c) → void {
if(!(c.{self::C::_f9}{core::int?} == null)) {
core::int x = c.{self::C::_f9}{core::int};
self::acceptsInt(x);
}
}
static method testExtensionGetter(self::C c) → void {
if(!(c.{self::C::_f10}{core::int?} == null)) {
core::int x = c.{self::C::_f10}{core::int};
self::acceptsInt(x);
}
}
static method testGetterInPart(self::C c) → void {
if(!(c.{self::C::_f11}{core::int?} == null)) {
core::int? x = c.{self::C::_f11}{core::int?};
x = null;
}
}
static method testFieldInMixin(self::C c) → void {
if(!(c.{self::C::_f12}{core::int?} == null)) {
core::int? x = c.{self::C::_f12}{core::int?};
x = null;
}
}
static method testGetterInMixin(self::C c) → void {
if(!(c.{self::C::_f13}{core::int?} == null)) {
core::int? x = c.{self::C::_f13}{core::int?};
x = null;
}
}
static method main() → dynamic {}

View file

@ -0,0 +1,137 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
part field_promotion_name_conflicts_part.dart;
abstract class C extends core::Object {
final field core::int? _f1;
final field core::int? _f2;
final field core::int? _f3;
final field core::int? _f4;
final field core::int? _f5;
final field core::int? _f6;
final field core::int? _f7;
final field core::int? _f8;
final field core::int? _f9;
final field core::int? _f10;
final field core::int? _f11;
final field core::int? _f12;
final field core::int? _f13;
constructor •(core::int? i) → self::C
: self::C::_f1 = i, self::C::_f2 = i, self::C::_f3 = i, self::C::_f4 = i, self::C::_f5 = i, self::C::_f6 = i, self::C::_f7 = i, self::C::_f8 = i, self::C::_f9 = i, self::C::_f10 = i, self::C::_f11 = i, self::C::_f12 = i, self::C::_f13 = i, super core::Object::•()
;
}
abstract class D extends core::Object {
final field core::int? _f1;
field core::int? _f2 = null;
static field core::int? _f6 = null;
constructor •(core::int? i) → self::D
: self::D::_f1 = i, super core::Object::•()
;
abstract get _f3() → core::int?;
get _f4() → core::int?
return 0;
set _f5(core::int? i) → void {}
static get _f7() → core::int?
return 0;
}
abstract class M extends core::Object /*isMixinDeclaration*/ {
field core::int? _f12 = null;
get _f13() → core::int?
return 0;
}
abstract class E extends core::Object { // from org-dartlang-testcase:///field_promotion_name_conflicts_part.dart
synthetic constructor •() → self::E
: super core::Object::•()
;
get _f11() → core::int?
return 0;
}
extension /* unnamed */ _extension#0 on core::String {
get _f10 = self::_extension#0|get#_f10;
}
static field core::int? _f8;
static get _f9() → core::int?
return 0;
static method _extension#0|get#_f10(lowered final core::String #this) → core::int?
return 0;
static method acceptsInt(core::int x) → void {}
static method testFinalField(self::C c) → void {
if(!(c.{self::C::_f1}{core::int?} == null)) {
core::int x = c.{self::C::_f1}{core::int};
self::acceptsInt(x);
}
}
static method testNonFinalField(self::C c) → void {
if(!(c.{self::C::_f2}{core::int?} == null)) {
core::int? x = c.{self::C::_f2}{core::int?};
x = null;
}
}
static method testAbstractGetter(self::C c) → void {
if(!(c.{self::C::_f3}{core::int?} == null)) {
core::int x = c.{self::C::_f3}{core::int};
self::acceptsInt(x);
}
}
static method testConcreteGetter(self::C c) → void {
if(!(c.{self::C::_f4}{core::int?} == null)) {
core::int? x = c.{self::C::_f4}{core::int?};
x = null;
}
}
static method testSetter(self::C c) → void {
if(!(c.{self::C::_f5}{core::int?} == null)) {
core::int x = c.{self::C::_f5}{core::int};
self::acceptsInt(x);
}
}
static method testStaticField(self::C c) → void {
if(!(c.{self::C::_f6}{core::int?} == null)) {
core::int x = c.{self::C::_f6}{core::int};
self::acceptsInt(x);
}
}
static method testStaticGetter(self::C c) → void {
if(!(c.{self::C::_f7}{core::int?} == null)) {
core::int x = c.{self::C::_f7}{core::int};
self::acceptsInt(x);
}
}
static method testTopLevelField(self::C c) → void {
if(!(c.{self::C::_f8}{core::int?} == null)) {
core::int x = c.{self::C::_f8}{core::int};
self::acceptsInt(x);
}
}
static method testTopLevelGetter(self::C c) → void {
if(!(c.{self::C::_f9}{core::int?} == null)) {
core::int x = c.{self::C::_f9}{core::int};
self::acceptsInt(x);
}
}
static method testExtensionGetter(self::C c) → void {
if(!(c.{self::C::_f10}{core::int?} == null)) {
core::int x = c.{self::C::_f10}{core::int};
self::acceptsInt(x);
}
}
static method testGetterInPart(self::C c) → void {
if(!(c.{self::C::_f11}{core::int?} == null)) {
core::int? x = c.{self::C::_f11}{core::int?};
x = null;
}
}
static method testFieldInMixin(self::C c) → void {
if(!(c.{self::C::_f12}{core::int?} == null)) {
core::int? x = c.{self::C::_f12}{core::int?};
x = null;
}
}
static method testGetterInMixin(self::C c) → void {
if(!(c.{self::C::_f13}{core::int?} == null)) {
core::int? x = c.{self::C::_f13}{core::int?};
x = null;
}
}
static method main() → dynamic {}

View file

@ -0,0 +1,85 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
part field_promotion_name_conflicts_part.dart;
abstract class C extends core::Object {
final field core::int? _f1;
final field core::int? _f2;
final field core::int? _f3;
final field core::int? _f4;
final field core::int? _f5;
final field core::int? _f6;
final field core::int? _f7;
final field core::int? _f8;
final field core::int? _f9;
final field core::int? _f10;
final field core::int? _f11;
final field core::int? _f12;
final field core::int? _f13;
constructor •(core::int? i) → self::C
;
}
abstract class D extends core::Object {
final field core::int? _f1;
field core::int? _f2;
static field core::int? _f6;
constructor •(core::int? i) → self::D
;
abstract get _f3() → core::int?;
get _f4() → core::int?
;
set _f5(core::int? i) → void
;
static get _f7() → core::int?
;
}
abstract class M extends core::Object /*isMixinDeclaration*/ {
field core::int? _f12;
get _f13() → core::int?
;
}
abstract class E extends core::Object { // from org-dartlang-testcase:///field_promotion_name_conflicts_part.dart
synthetic constructor •() → self::E
;
get _f11() → core::int?
;
}
extension /* unnamed */ _extension#0 on core::String {
get _f10 = self::_extension#0|get#_f10;
}
static field core::int? _f8;
static get _f9() → core::int?
;
static method _extension#0|get#_f10(lowered final core::String #this) → core::int?
;
static method acceptsInt(core::int x) → void
;
static method testFinalField(self::C c) → void
;
static method testNonFinalField(self::C c) → void
;
static method testAbstractGetter(self::C c) → void
;
static method testConcreteGetter(self::C c) → void
;
static method testSetter(self::C c) → void
;
static method testStaticField(self::C c) → void
;
static method testStaticGetter(self::C c) → void
;
static method testTopLevelField(self::C c) → void
;
static method testTopLevelGetter(self::C c) → void
;
static method testExtensionGetter(self::C c) → void
;
static method testGetterInPart(self::C c) → void
;
static method testFieldInMixin(self::C c) → void
;
static method testGetterInMixin(self::C c) → void
;
static method main() → dynamic
;

View file

@ -0,0 +1,137 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
part field_promotion_name_conflicts_part.dart;
abstract class C extends core::Object {
final field core::int? _f1;
final field core::int? _f2;
final field core::int? _f3;
final field core::int? _f4;
final field core::int? _f5;
final field core::int? _f6;
final field core::int? _f7;
final field core::int? _f8;
final field core::int? _f9;
final field core::int? _f10;
final field core::int? _f11;
final field core::int? _f12;
final field core::int? _f13;
constructor •(core::int? i) → self::C
: self::C::_f1 = i, self::C::_f2 = i, self::C::_f3 = i, self::C::_f4 = i, self::C::_f5 = i, self::C::_f6 = i, self::C::_f7 = i, self::C::_f8 = i, self::C::_f9 = i, self::C::_f10 = i, self::C::_f11 = i, self::C::_f12 = i, self::C::_f13 = i, super core::Object::•()
;
}
abstract class D extends core::Object {
final field core::int? _f1;
field core::int? _f2 = null;
static field core::int? _f6 = null;
constructor •(core::int? i) → self::D
: self::D::_f1 = i, super core::Object::•()
;
abstract get _f3() → core::int?;
get _f4() → core::int?
return 0;
set _f5(core::int? i) → void {}
static get _f7() → core::int?
return 0;
}
abstract class M extends core::Object /*isMixinDeclaration*/ {
field core::int? _f12 = null;
get _f13() → core::int?
return 0;
}
abstract class E extends core::Object { // from org-dartlang-testcase:///field_promotion_name_conflicts_part.dart
synthetic constructor •() → self::E
: super core::Object::•()
;
get _f11() → core::int?
return 0;
}
extension /* unnamed */ _extension#0 on core::String {
get _f10 = self::_extension#0|get#_f10;
}
static field core::int? _f8;
static get _f9() → core::int?
return 0;
static method _extension#0|get#_f10(lowered final core::String #this) → core::int?
return 0;
static method acceptsInt(core::int x) → void {}
static method testFinalField(self::C c) → void {
if(!(c.{self::C::_f1}{core::int?} == null)) {
core::int x = c.{self::C::_f1}{core::int};
self::acceptsInt(x);
}
}
static method testNonFinalField(self::C c) → void {
if(!(c.{self::C::_f2}{core::int?} == null)) {
core::int? x = c.{self::C::_f2}{core::int?};
x = null;
}
}
static method testAbstractGetter(self::C c) → void {
if(!(c.{self::C::_f3}{core::int?} == null)) {
core::int x = c.{self::C::_f3}{core::int};
self::acceptsInt(x);
}
}
static method testConcreteGetter(self::C c) → void {
if(!(c.{self::C::_f4}{core::int?} == null)) {
core::int? x = c.{self::C::_f4}{core::int?};
x = null;
}
}
static method testSetter(self::C c) → void {
if(!(c.{self::C::_f5}{core::int?} == null)) {
core::int x = c.{self::C::_f5}{core::int};
self::acceptsInt(x);
}
}
static method testStaticField(self::C c) → void {
if(!(c.{self::C::_f6}{core::int?} == null)) {
core::int x = c.{self::C::_f6}{core::int};
self::acceptsInt(x);
}
}
static method testStaticGetter(self::C c) → void {
if(!(c.{self::C::_f7}{core::int?} == null)) {
core::int x = c.{self::C::_f7}{core::int};
self::acceptsInt(x);
}
}
static method testTopLevelField(self::C c) → void {
if(!(c.{self::C::_f8}{core::int?} == null)) {
core::int x = c.{self::C::_f8}{core::int};
self::acceptsInt(x);
}
}
static method testTopLevelGetter(self::C c) → void {
if(!(c.{self::C::_f9}{core::int?} == null)) {
core::int x = c.{self::C::_f9}{core::int};
self::acceptsInt(x);
}
}
static method testExtensionGetter(self::C c) → void {
if(!(c.{self::C::_f10}{core::int?} == null)) {
core::int x = c.{self::C::_f10}{core::int};
self::acceptsInt(x);
}
}
static method testGetterInPart(self::C c) → void {
if(!(c.{self::C::_f11}{core::int?} == null)) {
core::int? x = c.{self::C::_f11}{core::int?};
x = null;
}
}
static method testFieldInMixin(self::C c) → void {
if(!(c.{self::C::_f12}{core::int?} == null)) {
core::int? x = c.{self::C::_f12}{core::int?};
x = null;
}
}
static method testGetterInMixin(self::C c) → void {
if(!(c.{self::C::_f13}{core::int?} == null)) {
core::int? x = c.{self::C::_f13}{core::int?};
x = null;
}
}
static method main() → dynamic {}

View file

@ -0,0 +1,11 @@
// 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.
// Part file preventing promotion in `field_promotion_name_conflicts.dart`.
part of 'field_promotion_name_conflicts.dart';
abstract class E {
int? get _f11 => 0;
}

View file

@ -0,0 +1 @@
--enable-experiment=inference-update-2

View file

@ -0,0 +1,90 @@
// 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 basic field promotion functionality when the feature is enabled.
// SharedOptions=--enable-experiment=inference-update-2
abstract class C {
final int? _privateFinalField;
final int? publicFinalField;
int? _privateField;
int? publicField;
int? get _privateAbstractGetter;
int? get publicAbstractGetter;
int? get _privateConcreteGetter => 0;
int? get publicConcreteGetter => 0;
C(int? i)
: _privateFinalField = i,
publicFinalField = i;
}
void acceptsInt(int x) {}
void testPrivateFinalField(C c) {
if (c._privateFinalField != null) {
var x = c._privateFinalField;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testPublicFinalField(C c) {
if (c.publicFinalField != null) {
var x = c.publicFinalField;
// `x` has type `int?` so this is ok
x = null;
}
}
void testPrivateField(C c) {
if (c._privateField != null) {
var x = c._privateField;
// `x` has type `int?` so this is ok
x = null;
}
}
void testPublicField(C c) {
if (c.publicField != null) {
var x = c.publicField;
// `x` has type `int?` so this is ok
x = null;
}
}
void testPrivateAbstractGetter(C c) {
if (c._privateAbstractGetter != null) {
var x = c._privateAbstractGetter;
// `x` has type `int?` so this is ok
x = null;
}
}
void testPublicAbstractGetter(C c) {
if (c.publicAbstractGetter != null) {
var x = c.publicAbstractGetter;
// `x` has type `int?` so this is ok
x = null;
}
}
void testPrivateConcreteGetter(C c) {
if (c._privateConcreteGetter != null) {
var x = c._privateConcreteGetter;
// `x` has type `int?` so this is ok
x = null;
}
}
void testPublicConcreteGetter(C c) {
if (c.publicConcreteGetter != null) {
var x = c.publicConcreteGetter;
// `x` has type `int?` so this is ok
x = null;
}
}
main() {}

View file

@ -0,0 +1,27 @@
// 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 doesn't happen when the feature is disabled.
// @dart=2.18
class C {
final int? _privateFinalField;
C(int? i) : _privateFinalField = i;
}
void testPrivateFinalField(C c) {
if (c._privateFinalField != null) {
var x = c._privateFinalField;
// `x` has type `int?` so this is ok
x = null;
}
}
main() {
for (var c in [C(null), C(0)]) {
testPrivateFinalField(c);
}
}

View file

@ -0,0 +1,10 @@
// 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.
// Library declaring a getter `_f2`, to check that it doesn't prevent promotion
// of a field named `_f2` in `field_promotion_and_no_such_method_test.dart`.
class C {
int? get _f2 => 0;
}

View file

@ -0,0 +1,65 @@
// 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 is prevented if there is a synthetic instance
// getter of the same name in the library that's a noSuchMethod forwarder.
// SharedOptions=--enable-experiment=inference-update-2
import 'field_promotion_and_no_such_method_lib.dart' as otherLib;
class C {
final int? _f1;
final int? _f2;
C(int? i)
: _f1 = i,
_f2 = i;
}
abstract class D {
final int? _f1;
D(int? i) : _f1 = i;
}
class E implements D {
// Implicitly implements _f1 as a getter that forwards to noSuchMethod
@override
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class F implements otherLib.C {
// Implicitly implements _f2 as a getter that throws; but the name _f2 comes
// from the other library so it doesn't conflict with the _f2 in this library.
@override
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
void acceptsInt(int x) {}
void testConflictsWithNoSuchMethodForwarder(C c) {
if (c._f1 != null) {
var x = c._f1;
// `x` has type `int?` so this is ok
x = null;
}
}
void testNoConflictWithNoSuchMethodForwarderForDifferentLib(C c) {
if (c._f2 != null) {
var x = c._f2;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
main() {
for (var c in [C(null), C(0)]) {
testConflictsWithNoSuchMethodForwarder(c);
testNoConflictWithNoSuchMethodForwarderForDifferentLib(c);
}
}

View file

@ -0,0 +1,11 @@
// 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.
// Part file preventing promotion in `field_promotion_name_conflicts_test.dart`.
part of 'field_promotion_name_conflicts_test.dart';
abstract class E {
int? get _f11 => 0;
}

View file

@ -0,0 +1,190 @@
// 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 is prevented if there is another instance getter
// of the same name in the library that's a non-final field or a concrete
// getter.
// SharedOptions=--enable-experiment=inference-update-2
part 'field_promotion_name_conflicts_part.dart';
class C {
final int? _f1;
final int? _f2;
final int? _f3;
final int? _f4;
final int? _f5;
final int? _f6;
final int? _f7;
final int? _f8;
final int? _f9;
final int? _f10;
final int? _f11;
final int? _f12;
final int? _f13;
C(int? i)
: _f1 = i,
_f2 = i,
_f3 = i,
_f4 = i,
_f5 = i,
_f6 = i,
_f7 = i,
_f8 = i,
_f9 = i,
_f10 = i,
_f11 = i,
_f12 = i,
_f13 = i;
}
abstract class D {
final int? _f1;
int? _f2;
int? get _f3;
int? get _f4 => 0;
set _f5(int? i) {}
static int? _f6;
static int? get _f7 => 0;
D(int? i) : _f1 = i;
}
int? _f8;
int? get _f9 => 0;
extension on String {
int? get _f10 => 0;
}
mixin M {
int? _f12;
int? get _f13 => 0;
}
void acceptsInt(int x) {}
void testFinalField(C c) {
if (c._f1 != null) {
var x = c._f1;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testNonFinalField(C c) {
if (c._f2 != null) {
var x = c._f2;
// `x` has type `int?` so this is ok
x = null;
}
}
void testAbstractGetter(C c) {
if (c._f3 != null) {
var x = c._f3;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testConcreteGetter(C c) {
if (c._f4 != null) {
var x = c._f4;
// `x` has type `int?` so this is ok
x = null;
}
}
void testSetter(C c) {
if (c._f5 != null) {
var x = c._f5;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testStaticField(C c) {
if (c._f6 != null) {
var x = c._f6;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testStaticGetter(C c) {
if (c._f7 != null) {
var x = c._f7;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testTopLevelField(C c) {
if (c._f8 != null) {
var x = c._f8;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testTopLevelGetter(C c) {
if (c._f9 != null) {
var x = c._f9;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testExtensionGetter(C c) {
if (c._f10 != null) {
var x = c._f10;
// `x` has type `int` so this is ok
acceptsInt(x);
}
}
void testGetterInPart(C c) {
if (c._f11 != null) {
var x = c._f11;
// `x` has type `int?` so this is ok
x = null;
}
}
void testFieldInMixin(C c) {
if (c._f12 != null) {
var x = c._f12;
// `x` has type `int?` so this is ok
x = null;
}
}
void testGetterInMixin(C c) {
if (c._f13 != null) {
var x = c._f13;
// `x` has type `int?` so this is ok
x = null;
}
}
main() {
for (var c in [C(null), C(0)]) {
testFinalField(c);
testNonFinalField(c);
testAbstractGetter(c);
testConcreteGetter(c);
testSetter(c);
testStaticField(c);
testStaticGetter(c);
testTopLevelField(c);
testTopLevelGetter(c);
testExtensionGetter(c);
testGetterInPart(c);
testFieldInMixin(c);
testGetterInMixin(c);
}
}