Version 2.10.0-123.0.dev
Merge commit '291b2dffc0d427bdc348b3c717b6926d8c8493f3' into 'dev'
diff --git a/benchmarks/EventLoopLatencyJson/dart/EventLoopLatencyJson.dart b/benchmarks/EventLoopLatencyJson/dart/EventLoopLatencyJson.dart
index 4261b2b..7a8c5ee 100644
--- a/benchmarks/EventLoopLatencyJson/dart/EventLoopLatencyJson.dart
+++ b/benchmarks/EventLoopLatencyJson/dart/EventLoopLatencyJson.dart
@@ -11,8 +11,7 @@
// Start GC pressure from helper isolate.
final exitPort = ReceivePort();
final exitFuture = exitPort.first;
- final isolate =
- await Isolate.spawn(runSplay, null, onExit: exitPort.sendPort);
+ final isolate = await Isolate.spawn(run, null, onExit: exitPort.sendPort);
// Measure event loop latency.
const tickDuration = const Duration(milliseconds: 1);
@@ -28,7 +27,7 @@
stats.report('EventLoopLatencyJson');
}
-void runSplay(dynamic msg) async {
+void run(dynamic msg) {
while (true) {
JsonRoundTripBenchmark().run();
}
diff --git a/benchmarks/EventLoopLatencyJson/dart2/EventLoopLatencyJson.dart b/benchmarks/EventLoopLatencyJson/dart2/EventLoopLatencyJson.dart
index 4261b2b..7a8c5ee 100644
--- a/benchmarks/EventLoopLatencyJson/dart2/EventLoopLatencyJson.dart
+++ b/benchmarks/EventLoopLatencyJson/dart2/EventLoopLatencyJson.dart
@@ -11,8 +11,7 @@
// Start GC pressure from helper isolate.
final exitPort = ReceivePort();
final exitFuture = exitPort.first;
- final isolate =
- await Isolate.spawn(runSplay, null, onExit: exitPort.sendPort);
+ final isolate = await Isolate.spawn(run, null, onExit: exitPort.sendPort);
// Measure event loop latency.
const tickDuration = const Duration(milliseconds: 1);
@@ -28,7 +27,7 @@
stats.report('EventLoopLatencyJson');
}
-void runSplay(dynamic msg) async {
+void run(dynamic msg) {
while (true) {
JsonRoundTripBenchmark().run();
}
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index a189dc1..1a6eb5d 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -14,24 +14,19 @@
DartType,
DynamicType,
Expression,
- Field,
FunctionNode,
FunctionType,
FutureOrType,
InterfaceType,
- InvalidType,
Member,
MethodInvocation,
Name,
Nullability,
Procedure,
- ProcedureKind,
ReturnStatement,
Supertype,
ThisExpression,
TypeParameter,
- TypeParameterType,
- VariableDeclaration,
VoidType,
getAsTypeArguments;
@@ -39,8 +34,6 @@
import 'package:kernel/core_types.dart' show CoreTypes;
-import 'package:kernel/src/legacy_erasure.dart';
-
import 'package:kernel/text/text_serialization_verifier.dart';
import 'package:kernel/type_algebra.dart' show Substitution, substitute;
@@ -62,9 +55,9 @@
import '../modifier.dart';
-import '../names.dart' show equalsName, noSuchMethodName;
+import '../names.dart' show noSuchMethodName;
-import '../problems.dart' show internalProblem, unhandled, unimplemented;
+import '../problems.dart' show internalProblem, unhandled;
import '../scope.dart';
@@ -201,36 +194,9 @@
bool isSetter,
callback(Member declaredMember, Member interfaceMember, bool isSetter));
- void checkOverride(
- Types types,
- Member declaredMember,
- Member interfaceMember,
- bool isSetter,
- callback(Member declaredMember, Member interfaceMember, bool isSetter),
- {bool isInterfaceCheck = false});
-
bool hasUserDefinedNoSuchMethod(
Class klass, ClassHierarchy hierarchy, Class objectClass);
- /// Returns whether a covariant parameter was seen and more methods thus have
- /// to be checked.
- bool checkMethodOverride(Types types, Procedure declaredMember,
- Procedure interfaceMember, bool isInterfaceCheck);
-
- void checkGetterOverride(Types types, Member declaredMember,
- Member interfaceMember, bool isInterfaceCheck);
-
- /// Returns whether a covariant parameter was seen and more methods thus have
- /// to be checked.
- bool checkSetterOverride(Types types, Member declaredMember,
- Member interfaceMember, bool isInterfaceCheck);
-
- // When the overriding member is inherited, report the class containing
- // the conflict as the main error.
- void reportInvalidOverride(bool isInterfaceCheck, Member declaredMember,
- Message message, int fileOffset, int length,
- {List<LocatedMessage> context});
-
void checkMixinApplication(ClassHierarchy hierarchy, CoreTypes coreTypes);
// Computes the function type of a given redirection target. Returns [null] if
@@ -776,77 +742,6 @@
}
@override
- void checkOverride(
- Types types,
- Member declaredMember,
- Member interfaceMember,
- bool isSetter,
- callback(Member declaredMember, Member interfaceMember, bool isSetter),
- {bool isInterfaceCheck = false}) {
- if (declaredMember == interfaceMember) {
- return;
- }
- if (declaredMember is Constructor || interfaceMember is Constructor) {
- unimplemented(
- "Constructor in override check.", declaredMember.fileOffset, fileUri);
- }
- if (declaredMember is Procedure && interfaceMember is Procedure) {
- if (declaredMember.kind == interfaceMember.kind) {
- if (declaredMember.kind == ProcedureKind.Method ||
- declaredMember.kind == ProcedureKind.Operator) {
- bool seenCovariant = checkMethodOverride(
- types, declaredMember, interfaceMember, isInterfaceCheck);
- if (seenCovariant) {
- handleSeenCovariant(
- types, declaredMember, interfaceMember, isSetter, callback);
- }
- } else if (declaredMember.kind == ProcedureKind.Getter) {
- checkGetterOverride(
- types, declaredMember, interfaceMember, isInterfaceCheck);
- } else if (declaredMember.kind == ProcedureKind.Setter) {
- bool seenCovariant = checkSetterOverride(
- types, declaredMember, interfaceMember, isInterfaceCheck);
- if (seenCovariant) {
- handleSeenCovariant(
- types, declaredMember, interfaceMember, isSetter, callback);
- }
- } else {
- assert(
- false,
- "Unexpected procedure kind in override check: "
- "${declaredMember.kind}");
- }
- }
- } else {
- bool declaredMemberHasGetter = declaredMember is Field ||
- declaredMember is Procedure && declaredMember.isGetter;
- bool interfaceMemberHasGetter = interfaceMember is Field ||
- interfaceMember is Procedure && interfaceMember.isGetter;
- bool declaredMemberHasSetter = (declaredMember is Field &&
- !declaredMember.isFinal &&
- !declaredMember.isConst) ||
- declaredMember is Procedure && declaredMember.isSetter;
- bool interfaceMemberHasSetter = (interfaceMember is Field &&
- !interfaceMember.isFinal &&
- !interfaceMember.isConst) ||
- interfaceMember is Procedure && interfaceMember.isSetter;
- if (declaredMemberHasGetter && interfaceMemberHasGetter) {
- checkGetterOverride(
- types, declaredMember, interfaceMember, isInterfaceCheck);
- }
- if (declaredMemberHasSetter && interfaceMemberHasSetter) {
- bool seenCovariant = checkSetterOverride(
- types, declaredMember, interfaceMember, isInterfaceCheck);
- if (seenCovariant) {
- handleSeenCovariant(
- types, declaredMember, interfaceMember, isSetter, callback);
- }
- }
- }
- // TODO(ahe): Handle other cases: accessors, operators, and fields.
- }
-
- @override
bool hasUserDefinedNoSuchMethod(
Class klass, ClassHierarchy hierarchy, Class objectClass) {
Member noSuchMethod = hierarchy.getDispatchTarget(klass, noSuchMethodName);
@@ -855,8 +750,11 @@
void transformProcedureToNoSuchMethodForwarder(
Member noSuchMethodInterface, KernelTarget target, Procedure procedure) {
- String prefix =
- procedure.isGetter ? 'get:' : procedure.isSetter ? 'set:' : '';
+ String prefix = procedure.isGetter
+ ? 'get:'
+ : procedure.isSetter
+ ? 'set:'
+ : '';
String invocationName = prefix + procedure.name.name;
if (procedure.isSetter) invocationName += '=';
Expression invocation = target.backendTarget.instantiateInvocation(
@@ -892,524 +790,6 @@
procedure.forwardingStubSuperTarget = null;
}
- Uri _getMemberUri(Member member) {
- if (member is Field) return member.fileUri;
- if (member is Procedure) return member.fileUri;
- // Other member types won't be seen because constructors don't participate
- // in override relationships
- return unhandled('${member.runtimeType}', '_getMemberUri', -1, null);
- }
-
- Substitution _computeInterfaceSubstitution(
- Types types,
- Member declaredMember,
- Member interfaceMember,
- FunctionNode declaredFunction,
- FunctionNode interfaceFunction,
- bool isInterfaceCheck) {
- Substitution interfaceSubstitution = Substitution.empty;
- if (interfaceMember.enclosingClass.typeParameters.isNotEmpty) {
- Class enclosingClass = interfaceMember.enclosingClass;
- interfaceSubstitution = Substitution.fromPairs(
- enclosingClass.typeParameters,
- types.hierarchy
- .getTypeArgumentsAsInstanceOf(thisType, enclosingClass));
- }
-
- if (declaredFunction?.typeParameters?.length !=
- interfaceFunction?.typeParameters?.length) {
- reportInvalidOverride(
- isInterfaceCheck,
- declaredMember,
- templateOverrideTypeVariablesMismatch.withArguments(
- "${declaredMember.enclosingClass.name}."
- "${declaredMember.name.name}",
- "${interfaceMember.enclosingClass.name}."
- "${interfaceMember.name.name}"),
- declaredMember.fileOffset,
- noLength,
- context: [
- templateOverriddenMethodCause
- .withArguments(interfaceMember.name.name)
- .withLocation(_getMemberUri(interfaceMember),
- interfaceMember.fileOffset, noLength)
- ]);
- } else if (declaredFunction?.typeParameters != null) {
- Map<TypeParameter, DartType> substitutionMap =
- <TypeParameter, DartType>{};
- for (int i = 0; i < declaredFunction.typeParameters.length; ++i) {
- substitutionMap[interfaceFunction.typeParameters[i]] =
- new TypeParameterType.forAlphaRenaming(
- interfaceFunction.typeParameters[i],
- declaredFunction.typeParameters[i]);
- }
- Substitution substitution = Substitution.fromMap(substitutionMap);
- for (int i = 0; i < declaredFunction.typeParameters.length; ++i) {
- TypeParameter declaredParameter = declaredFunction.typeParameters[i];
- TypeParameter interfaceParameter = interfaceFunction.typeParameters[i];
- if (!interfaceParameter.isGenericCovariantImpl) {
- DartType declaredBound = declaredParameter.bound;
- DartType interfaceBound = interfaceParameter.bound;
- if (interfaceSubstitution != null) {
- declaredBound = interfaceSubstitution.substituteType(declaredBound);
- interfaceBound =
- interfaceSubstitution.substituteType(interfaceBound);
- }
- DartType computedBound = substitution.substituteType(interfaceBound);
- if (!library.isNonNullableByDefault) {
- computedBound =
- legacyErasure(types.hierarchy.coreTypes, computedBound);
- }
- if (!types
- .performNullabilityAwareMutualSubtypesCheck(
- declaredBound, computedBound)
- .isSubtypeWhenUsingNullabilities()) {
- reportInvalidOverride(
- isInterfaceCheck,
- declaredMember,
- templateOverrideTypeVariablesBoundMismatch.withArguments(
- declaredBound,
- declaredParameter.name,
- "${declaredMember.enclosingClass.name}."
- "${declaredMember.name.name}",
- computedBound,
- "${interfaceMember.enclosingClass.name}."
- "${interfaceMember.name.name}",
- library.isNonNullableByDefault),
- declaredMember.fileOffset,
- noLength,
- context: [
- templateOverriddenMethodCause
- .withArguments(interfaceMember.name.name)
- .withLocation(_getMemberUri(interfaceMember),
- interfaceMember.fileOffset, noLength)
- ]);
- }
- }
- }
- interfaceSubstitution =
- Substitution.combine(interfaceSubstitution, substitution);
- }
- return interfaceSubstitution;
- }
-
- Substitution _computeDeclaredSubstitution(
- Types types, Member declaredMember) {
- Substitution declaredSubstitution = Substitution.empty;
- if (declaredMember.enclosingClass.typeParameters.isNotEmpty) {
- Class enclosingClass = declaredMember.enclosingClass;
- declaredSubstitution = Substitution.fromPairs(
- enclosingClass.typeParameters,
- types.hierarchy
- .getTypeArgumentsAsInstanceOf(thisType, enclosingClass));
- }
- return declaredSubstitution;
- }
-
- void _checkTypes(
- Types types,
- Substitution interfaceSubstitution,
- Substitution declaredSubstitution,
- Member declaredMember,
- Member interfaceMember,
- DartType declaredType,
- DartType interfaceType,
- bool isCovariant,
- VariableDeclaration declaredParameter,
- bool isInterfaceCheck,
- {bool asIfDeclaredParameter = false}) {
- if (interfaceSubstitution != null) {
- interfaceType = interfaceSubstitution.substituteType(interfaceType);
- }
- if (declaredSubstitution != null) {
- declaredType = declaredSubstitution.substituteType(declaredType);
- }
-
- if (!declaredMember.isNonNullableByDefault &&
- interfaceMember.isNonNullableByDefault) {
- interfaceType = legacyErasure(types.hierarchy.coreTypes, interfaceType);
- }
-
- bool inParameter = declaredParameter != null || asIfDeclaredParameter;
- DartType subtype = inParameter ? interfaceType : declaredType;
- DartType supertype = inParameter ? declaredType : interfaceType;
-
- if (types.isSubtypeOf(
- subtype, supertype, SubtypeCheckMode.withNullabilities)) {
- // No problem--the proper subtyping relation is satisfied.
- } else if (isCovariant &&
- types.isSubtypeOf(
- supertype, subtype, SubtypeCheckMode.withNullabilities)) {
- // No problem--the overriding parameter is marked "covariant" and has
- // a type which is a subtype of the parameter it overrides.
- } else if (subtype is InvalidType || supertype is InvalidType) {
- // Don't report a problem as something else is wrong that has already
- // been reported.
- } else {
- // Report an error.
- bool isErrorInNnbdOptedOutMode = !types.isSubtypeOf(
- subtype, supertype, SubtypeCheckMode.ignoringNullabilities) &&
- (!isCovariant ||
- !types.isSubtypeOf(
- supertype, subtype, SubtypeCheckMode.ignoringNullabilities));
- if (isErrorInNnbdOptedOutMode || library.isNonNullableByDefault) {
- String declaredMemberName = '${declaredMember.enclosingClass.name}'
- '.${declaredMember.name.name}';
- String interfaceMemberName = '${interfaceMember.enclosingClass.name}'
- '.${interfaceMember.name.name}';
- Message message;
- int fileOffset;
- if (declaredParameter == null) {
- if (asIfDeclaredParameter) {
- // Setter overridden by field
- message = templateOverrideTypeMismatchSetter.withArguments(
- declaredMemberName,
- declaredType,
- interfaceType,
- interfaceMemberName,
- library.isNonNullableByDefault);
- } else {
- message = templateOverrideTypeMismatchReturnType.withArguments(
- declaredMemberName,
- declaredType,
- interfaceType,
- interfaceMemberName,
- library.isNonNullableByDefault);
- }
- fileOffset = declaredMember.fileOffset;
- } else {
- message = templateOverrideTypeMismatchParameter.withArguments(
- declaredParameter.name,
- declaredMemberName,
- declaredType,
- interfaceType,
- interfaceMemberName,
- library.isNonNullableByDefault);
- fileOffset = declaredParameter.fileOffset;
- }
- reportInvalidOverride(
- isInterfaceCheck, declaredMember, message, fileOffset, noLength,
- context: [
- templateOverriddenMethodCause
- .withArguments(interfaceMember.name.name)
- .withLocation(_getMemberUri(interfaceMember),
- interfaceMember.fileOffset, noLength)
- ]);
- }
- }
- }
-
- @override
- bool checkMethodOverride(Types types, Procedure declaredMember,
- Procedure interfaceMember, bool isInterfaceCheck) {
- assert(declaredMember.kind == interfaceMember.kind);
- assert(declaredMember.kind == ProcedureKind.Method ||
- declaredMember.kind == ProcedureKind.Operator);
- bool seenCovariant = false;
- FunctionNode declaredFunction = declaredMember.function;
- FunctionNode interfaceFunction = interfaceMember.function;
-
- Substitution interfaceSubstitution = _computeInterfaceSubstitution(
- types,
- declaredMember,
- interfaceMember,
- declaredFunction,
- interfaceFunction,
- isInterfaceCheck);
-
- Substitution declaredSubstitution =
- _computeDeclaredSubstitution(types, declaredMember);
-
- _checkTypes(
- types,
- interfaceSubstitution,
- declaredSubstitution,
- declaredMember,
- interfaceMember,
- declaredFunction.returnType,
- interfaceFunction.returnType,
- false,
- null,
- isInterfaceCheck);
- if (declaredFunction.positionalParameters.length <
- interfaceFunction.positionalParameters.length) {
- reportInvalidOverride(
- isInterfaceCheck,
- declaredMember,
- templateOverrideFewerPositionalArguments.withArguments(
- "${declaredMember.enclosingClass.name}."
- "${declaredMember.name.name}",
- "${interfaceMember.enclosingClass.name}."
- "${interfaceMember.name.name}"),
- declaredMember.fileOffset,
- noLength,
- context: [
- templateOverriddenMethodCause
- .withArguments(interfaceMember.name.name)
- .withLocation(interfaceMember.fileUri,
- interfaceMember.fileOffset, noLength)
- ]);
- }
- if (interfaceFunction.requiredParameterCount <
- declaredFunction.requiredParameterCount) {
- reportInvalidOverride(
- isInterfaceCheck,
- declaredMember,
- templateOverrideMoreRequiredArguments.withArguments(
- "${declaredMember.enclosingClass.name}."
- "${declaredMember.name.name}",
- "${interfaceMember.enclosingClass.name}."
- "${interfaceMember.name.name}"),
- declaredMember.fileOffset,
- noLength,
- context: [
- templateOverriddenMethodCause
- .withArguments(interfaceMember.name.name)
- .withLocation(interfaceMember.fileUri,
- interfaceMember.fileOffset, noLength)
- ]);
- }
- for (int i = 0;
- i < declaredFunction.positionalParameters.length &&
- i < interfaceFunction.positionalParameters.length;
- i++) {
- VariableDeclaration declaredParameter =
- declaredFunction.positionalParameters[i];
- VariableDeclaration interfaceParameter =
- interfaceFunction.positionalParameters[i];
- if (i == 0 &&
- declaredMember.name == equalsName &&
- declaredParameter.type ==
- types.hierarchy.coreTypes.objectNonNullableRawType &&
- interfaceParameter.type is DynamicType) {
- // TODO(johnniwinther): Add check for opt-in overrides of operator ==.
- // `operator ==` methods in opt-out classes have type
- // `bool Function(dynamic)`.
- continue;
- }
-
- _checkTypes(
- types,
- interfaceSubstitution,
- declaredSubstitution,
- declaredMember,
- interfaceMember,
- declaredParameter.type,
- interfaceParameter.type,
- declaredParameter.isCovariant || interfaceParameter.isCovariant,
- declaredParameter,
- isInterfaceCheck);
- if (declaredParameter.isCovariant) seenCovariant = true;
- }
- if (declaredFunction.namedParameters.isEmpty &&
- interfaceFunction.namedParameters.isEmpty) {
- return seenCovariant;
- }
- if (declaredFunction.namedParameters.length <
- interfaceFunction.namedParameters.length) {
- reportInvalidOverride(
- isInterfaceCheck,
- declaredMember,
- templateOverrideFewerNamedArguments.withArguments(
- "${declaredMember.enclosingClass.name}."
- "${declaredMember.name.name}",
- "${interfaceMember.enclosingClass.name}."
- "${interfaceMember.name.name}"),
- declaredMember.fileOffset,
- noLength,
- context: [
- templateOverriddenMethodCause
- .withArguments(interfaceMember.name.name)
- .withLocation(interfaceMember.fileUri,
- interfaceMember.fileOffset, noLength)
- ]);
- }
- int compareNamedParameters(VariableDeclaration p0, VariableDeclaration p1) {
- return p0.name.compareTo(p1.name);
- }
-
- List<VariableDeclaration> sortedFromDeclared =
- new List.from(declaredFunction.namedParameters)
- ..sort(compareNamedParameters);
- List<VariableDeclaration> sortedFromInterface =
- new List.from(interfaceFunction.namedParameters)
- ..sort(compareNamedParameters);
- Iterator<VariableDeclaration> declaredNamedParameters =
- sortedFromDeclared.iterator;
- Iterator<VariableDeclaration> interfaceNamedParameters =
- sortedFromInterface.iterator;
- outer:
- while (declaredNamedParameters.moveNext() &&
- interfaceNamedParameters.moveNext()) {
- while (declaredNamedParameters.current.name !=
- interfaceNamedParameters.current.name) {
- if (!declaredNamedParameters.moveNext()) {
- reportInvalidOverride(
- isInterfaceCheck,
- declaredMember,
- templateOverrideMismatchNamedParameter.withArguments(
- "${declaredMember.enclosingClass.name}."
- "${declaredMember.name.name}",
- interfaceNamedParameters.current.name,
- "${interfaceMember.enclosingClass.name}."
- "${interfaceMember.name.name}"),
- declaredMember.fileOffset,
- noLength,
- context: [
- templateOverriddenMethodCause
- .withArguments(interfaceMember.name.name)
- .withLocation(interfaceMember.fileUri,
- interfaceMember.fileOffset, noLength)
- ]);
- break outer;
- }
- }
- VariableDeclaration declaredParameter = declaredNamedParameters.current;
- _checkTypes(
- types,
- interfaceSubstitution,
- declaredSubstitution,
- declaredMember,
- interfaceMember,
- declaredParameter.type,
- interfaceNamedParameters.current.type,
- declaredParameter.isCovariant,
- declaredParameter,
- isInterfaceCheck);
- if (declaredMember.isNonNullableByDefault &&
- declaredParameter.isRequired &&
- interfaceMember.isNonNullableByDefault &&
- !interfaceNamedParameters.current.isRequired) {
- reportInvalidOverride(
- isInterfaceCheck,
- declaredMember,
- templateOverrideMismatchRequiredNamedParameter.withArguments(
- declaredParameter.name,
- "${declaredMember.enclosingClass.name}."
- "${declaredMember.name.name}",
- "${interfaceMember.enclosingClass.name}."
- "${interfaceMember.name.name}"),
- declaredParameter.fileOffset,
- noLength,
- context: [
- templateOverriddenMethodCause
- .withArguments(interfaceMember.name.name)
- .withLocation(_getMemberUri(interfaceMember),
- interfaceMember.fileOffset, noLength)
- ]);
- }
- if (declaredParameter.isCovariant) seenCovariant = true;
- }
- return seenCovariant;
- }
-
- void checkGetterOverride(Types types, Member declaredMember,
- Member interfaceMember, bool isInterfaceCheck) {
- Substitution interfaceSubstitution = _computeInterfaceSubstitution(
- types, declaredMember, interfaceMember, null, null, isInterfaceCheck);
- Substitution declaredSubstitution =
- _computeDeclaredSubstitution(types, declaredMember);
- DartType declaredType = declaredMember.getterType;
- DartType interfaceType = interfaceMember.getterType;
- _checkTypes(
- types,
- interfaceSubstitution,
- declaredSubstitution,
- declaredMember,
- interfaceMember,
- declaredType,
- interfaceType,
- false,
- null,
- isInterfaceCheck);
- }
-
- @override
- bool checkSetterOverride(Types types, Member declaredMember,
- Member interfaceMember, bool isInterfaceCheck) {
- Substitution interfaceSubstitution = _computeInterfaceSubstitution(
- types, declaredMember, interfaceMember, null, null, isInterfaceCheck);
- Substitution declaredSubstitution =
- _computeDeclaredSubstitution(types, declaredMember);
- DartType declaredType = declaredMember.setterType;
- DartType interfaceType = interfaceMember.setterType;
- VariableDeclaration declaredParameter =
- declaredMember.function?.positionalParameters?.elementAt(0);
- bool isCovariant = declaredParameter?.isCovariant ?? false;
- if (!isCovariant && declaredMember is Field) {
- isCovariant = declaredMember.isCovariant;
- }
- if (!isCovariant && interfaceMember is Field) {
- isCovariant = interfaceMember.isCovariant;
- }
- _checkTypes(
- types,
- interfaceSubstitution,
- declaredSubstitution,
- declaredMember,
- interfaceMember,
- declaredType,
- interfaceType,
- isCovariant,
- declaredParameter,
- isInterfaceCheck,
- asIfDeclaredParameter: true);
- return isCovariant;
- }
-
- @override
- void reportInvalidOverride(bool isInterfaceCheck, Member declaredMember,
- Message message, int fileOffset, int length,
- {List<LocatedMessage> context}) {
- if (shouldOverrideProblemBeOverlooked(this)) {
- return;
- }
-
- if (declaredMember.enclosingClass == cls) {
- // Ordinary override
- library.addProblem(message, fileOffset, length, declaredMember.fileUri,
- context: context);
- } else {
- context = [
- message.withLocation(declaredMember.fileUri, fileOffset, length),
- ...?context
- ];
- if (isInterfaceCheck) {
- // Interface check
- library.addProblem(
- templateInterfaceCheck.withArguments(
- declaredMember.name.name, cls.name),
- cls.fileOffset,
- cls.name.length,
- cls.fileUri,
- context: context);
- } else {
- if (cls.isAnonymousMixin) {
- // Implicit mixin application class
- String baseName = cls.superclass.demangledName;
- String mixinName = cls.mixedInClass.name;
- int classNameLength = cls.nameAsMixinApplicationSubclass.length;
- library.addProblem(
- templateImplicitMixinOverride.withArguments(
- mixinName, baseName, declaredMember.name.name),
- cls.fileOffset,
- classNameLength,
- cls.fileUri,
- context: context);
- } else {
- // Named mixin application class
- library.addProblem(
- templateNamedMixinOverride.withArguments(
- cls.name, declaredMember.name.name),
- cls.fileOffset,
- cls.name.length,
- cls.fileUri,
- context: context);
- }
- }
- }
- }
-
@override
String get fullNameForErrors {
return isMixinApplication && !isNamedMixinApplication
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 29e6bd3..5b3cbd7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -64,6 +64,7 @@
import '../scope.dart' show Scope;
+import '../source/source_class_builder.dart';
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
import '../source/source_loader.dart' show SourceLoader;
@@ -354,7 +355,7 @@
}
void registerOverrideCheck(
- ClassBuilder classBuilder, ClassMember a, ClassMember b) {
+ SourceClassBuilder classBuilder, ClassMember a, ClassMember b) {
_overrideChecks.add(new DelayedOverrideCheck(classBuilder, a, b));
}
@@ -1719,14 +1720,17 @@
void registerOverrideCheck(
ClassMember member, ClassMember overriddenMember) {
- if (overriddenMember.hasDeclarations &&
- classBuilder == overriddenMember.classBuilder) {
- for (int i = 0; i < overriddenMember.declarations.length; i++) {
+ if (classBuilder is SourceClassBuilder) {
+ if (overriddenMember.hasDeclarations &&
+ classBuilder == overriddenMember.classBuilder) {
+ for (int i = 0; i < overriddenMember.declarations.length; i++) {
+ hierarchy.registerOverrideCheck(
+ classBuilder, member, overriddenMember.declarations[i]);
+ }
+ } else {
hierarchy.registerOverrideCheck(
- classBuilder, member, overriddenMember.declarations[i]);
+ classBuilder, member, overriddenMember);
}
- } else {
- hierarchy.registerOverrideCheck(classBuilder, member, overriddenMember);
}
}
@@ -1960,6 +1964,7 @@
void checkMemberVsSetter(
ClassMember member, ClassMember overriddenMember) {
+ if (classBuilder is! SourceClassBuilder) return;
if (overriddenMember.isStatic) return;
if (member == overriddenMember) return;
if (member.isDuplicate || overriddenMember.isDuplicate) {
@@ -2572,7 +2577,7 @@
}
class DelayedOverrideCheck {
- final ClassBuilder classBuilder;
+ final SourceClassBuilder classBuilder;
final ClassMember declaredMember;
final ClassMember overriddenMember;
@@ -2802,11 +2807,13 @@
return combinedMemberSignatureResult;
}
if (!classBuilder.isAbstract) {
- for (int i = 0; i < declarations.length; i++) {
- if (concreteMember != declarations[i]) {
- new DelayedOverrideCheck(
- classBuilder, concreteMember, declarations[i])
- .check(hierarchy);
+ if (classBuilder is SourceClassBuilder) {
+ for (int i = 0; i < declarations.length; i++) {
+ if (concreteMember != declarations[i]) {
+ new DelayedOverrideCheck(
+ classBuilder, concreteMember, declarations[i])
+ .check(hierarchy);
+ }
}
}
}
@@ -3166,9 +3173,11 @@
_isChecked = true;
if (!classBuilder.isAbstract &&
!hierarchy.nodes[classBuilder.cls].hasNoSuchMethod) {
- new DelayedOverrideCheck(
- classBuilder, concreteImplementation, abstractMember)
- .check(hierarchy);
+ if (classBuilder is SourceClassBuilder) {
+ new DelayedOverrideCheck(
+ classBuilder, concreteImplementation, abstractMember)
+ .check(hierarchy);
+ }
}
ProcedureKind kind = ProcedureKind.Method;
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 53b4d1b..9e55d9d21 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -9,6 +9,8 @@
import 'package:kernel/clone.dart' show CloneProcedureWithoutBody;
import 'package:kernel/reference_from_index.dart' show IndexedClass;
import 'package:kernel/src/bounds_checks.dart';
+import 'package:kernel/src/legacy_erasure.dart';
+import 'package:kernel/src/types.dart' show Types;
import 'package:kernel/type_algebra.dart' show Substitution;
import 'package:kernel/type_algebra.dart' as type_algebra
show getSubstitutionMap;
@@ -43,9 +45,9 @@
import '../kernel/type_algorithms.dart'
show Variance, computeTypeVariableBuilderVariance;
-import '../names.dart' show noSuchMethodName;
+import '../names.dart' show equalsName, noSuchMethodName;
-import '../problems.dart' show unexpected, unhandled;
+import '../problems.dart' show unexpected, unhandled, unimplemented;
import '../scope.dart';
@@ -1129,4 +1131,595 @@
}
return count;
}
+
+ void checkOverride(
+ Types types,
+ Member declaredMember,
+ Member interfaceMember,
+ bool isSetter,
+ callback(Member declaredMember, Member interfaceMember, bool isSetter),
+ {bool isInterfaceCheck = false}) {
+ if (declaredMember == interfaceMember) {
+ return;
+ }
+ if (declaredMember is Constructor || interfaceMember is Constructor) {
+ unimplemented(
+ "Constructor in override check.", declaredMember.fileOffset, fileUri);
+ }
+ if (declaredMember is Procedure && interfaceMember is Procedure) {
+ if (declaredMember.kind == interfaceMember.kind) {
+ if (declaredMember.kind == ProcedureKind.Method ||
+ declaredMember.kind == ProcedureKind.Operator) {
+ bool seenCovariant = checkMethodOverride(
+ types, declaredMember, interfaceMember, isInterfaceCheck);
+ if (seenCovariant) {
+ handleSeenCovariant(
+ types, declaredMember, interfaceMember, isSetter, callback);
+ }
+ } else if (declaredMember.kind == ProcedureKind.Getter) {
+ checkGetterOverride(
+ types, declaredMember, interfaceMember, isInterfaceCheck);
+ } else if (declaredMember.kind == ProcedureKind.Setter) {
+ bool seenCovariant = checkSetterOverride(
+ types, declaredMember, interfaceMember, isInterfaceCheck);
+ if (seenCovariant) {
+ handleSeenCovariant(
+ types, declaredMember, interfaceMember, isSetter, callback);
+ }
+ } else {
+ assert(
+ false,
+ "Unexpected procedure kind in override check: "
+ "${declaredMember.kind}");
+ }
+ }
+ } else {
+ bool declaredMemberHasGetter = declaredMember is Field ||
+ declaredMember is Procedure && declaredMember.isGetter;
+ bool interfaceMemberHasGetter = interfaceMember is Field ||
+ interfaceMember is Procedure && interfaceMember.isGetter;
+ bool declaredMemberHasSetter = (declaredMember is Field &&
+ !declaredMember.isFinal &&
+ !declaredMember.isConst) ||
+ declaredMember is Procedure && declaredMember.isSetter;
+ bool interfaceMemberHasSetter = (interfaceMember is Field &&
+ !interfaceMember.isFinal &&
+ !interfaceMember.isConst) ||
+ interfaceMember is Procedure && interfaceMember.isSetter;
+ if (declaredMemberHasGetter && interfaceMemberHasGetter) {
+ checkGetterOverride(
+ types, declaredMember, interfaceMember, isInterfaceCheck);
+ }
+ if (declaredMemberHasSetter && interfaceMemberHasSetter) {
+ bool seenCovariant = checkSetterOverride(
+ types, declaredMember, interfaceMember, isInterfaceCheck);
+ if (seenCovariant) {
+ handleSeenCovariant(
+ types, declaredMember, interfaceMember, isSetter, callback);
+ }
+ }
+ }
+ // TODO(ahe): Handle other cases: accessors, operators, and fields.
+ }
+
+ Uri _getMemberUri(Member member) {
+ if (member is Field) return member.fileUri;
+ if (member is Procedure) return member.fileUri;
+ // Other member types won't be seen because constructors don't participate
+ // in override relationships
+ return unhandled('${member.runtimeType}', '_getMemberUri', -1, null);
+ }
+
+ Substitution _computeInterfaceSubstitution(
+ Types types,
+ Member declaredMember,
+ Member interfaceMember,
+ FunctionNode declaredFunction,
+ FunctionNode interfaceFunction,
+ bool isInterfaceCheck) {
+ Substitution interfaceSubstitution = Substitution.empty;
+ if (interfaceMember.enclosingClass.typeParameters.isNotEmpty) {
+ Class enclosingClass = interfaceMember.enclosingClass;
+ interfaceSubstitution = Substitution.fromPairs(
+ enclosingClass.typeParameters,
+ types.hierarchy
+ .getTypeArgumentsAsInstanceOf(thisType, enclosingClass));
+ }
+
+ if (declaredFunction?.typeParameters?.length !=
+ interfaceFunction?.typeParameters?.length) {
+ reportInvalidOverride(
+ isInterfaceCheck,
+ declaredMember,
+ templateOverrideTypeVariablesMismatch.withArguments(
+ "${declaredMember.enclosingClass.name}."
+ "${declaredMember.name.name}",
+ "${interfaceMember.enclosingClass.name}."
+ "${interfaceMember.name.name}"),
+ declaredMember.fileOffset,
+ noLength,
+ context: [
+ templateOverriddenMethodCause
+ .withArguments(interfaceMember.name.name)
+ .withLocation(_getMemberUri(interfaceMember),
+ interfaceMember.fileOffset, noLength)
+ ]);
+ } else if (declaredFunction?.typeParameters != null) {
+ Map<TypeParameter, DartType> substitutionMap =
+ <TypeParameter, DartType>{};
+ for (int i = 0; i < declaredFunction.typeParameters.length; ++i) {
+ substitutionMap[interfaceFunction.typeParameters[i]] =
+ new TypeParameterType.forAlphaRenaming(
+ interfaceFunction.typeParameters[i],
+ declaredFunction.typeParameters[i]);
+ }
+ Substitution substitution = Substitution.fromMap(substitutionMap);
+ for (int i = 0; i < declaredFunction.typeParameters.length; ++i) {
+ TypeParameter declaredParameter = declaredFunction.typeParameters[i];
+ TypeParameter interfaceParameter = interfaceFunction.typeParameters[i];
+ if (!interfaceParameter.isGenericCovariantImpl) {
+ DartType declaredBound = declaredParameter.bound;
+ DartType interfaceBound = interfaceParameter.bound;
+ if (interfaceSubstitution != null) {
+ declaredBound = interfaceSubstitution.substituteType(declaredBound);
+ interfaceBound =
+ interfaceSubstitution.substituteType(interfaceBound);
+ }
+ DartType computedBound = substitution.substituteType(interfaceBound);
+ if (!library.isNonNullableByDefault) {
+ computedBound =
+ legacyErasure(types.hierarchy.coreTypes, computedBound);
+ }
+ if (!types
+ .performNullabilityAwareMutualSubtypesCheck(
+ declaredBound, computedBound)
+ .isSubtypeWhenUsingNullabilities()) {
+ reportInvalidOverride(
+ isInterfaceCheck,
+ declaredMember,
+ templateOverrideTypeVariablesBoundMismatch.withArguments(
+ declaredBound,
+ declaredParameter.name,
+ "${declaredMember.enclosingClass.name}."
+ "${declaredMember.name.name}",
+ computedBound,
+ "${interfaceMember.enclosingClass.name}."
+ "${interfaceMember.name.name}",
+ library.isNonNullableByDefault),
+ declaredMember.fileOffset,
+ noLength,
+ context: [
+ templateOverriddenMethodCause
+ .withArguments(interfaceMember.name.name)
+ .withLocation(_getMemberUri(interfaceMember),
+ interfaceMember.fileOffset, noLength)
+ ]);
+ }
+ }
+ }
+ interfaceSubstitution =
+ Substitution.combine(interfaceSubstitution, substitution);
+ }
+ return interfaceSubstitution;
+ }
+
+ Substitution _computeDeclaredSubstitution(
+ Types types, Member declaredMember) {
+ Substitution declaredSubstitution = Substitution.empty;
+ if (declaredMember.enclosingClass.typeParameters.isNotEmpty) {
+ Class enclosingClass = declaredMember.enclosingClass;
+ declaredSubstitution = Substitution.fromPairs(
+ enclosingClass.typeParameters,
+ types.hierarchy
+ .getTypeArgumentsAsInstanceOf(thisType, enclosingClass));
+ }
+ return declaredSubstitution;
+ }
+
+ void _checkTypes(
+ Types types,
+ Substitution interfaceSubstitution,
+ Substitution declaredSubstitution,
+ Member declaredMember,
+ Member interfaceMember,
+ DartType declaredType,
+ DartType interfaceType,
+ bool isCovariant,
+ VariableDeclaration declaredParameter,
+ bool isInterfaceCheck,
+ {bool asIfDeclaredParameter = false}) {
+ if (interfaceSubstitution != null) {
+ interfaceType = interfaceSubstitution.substituteType(interfaceType);
+ }
+ if (declaredSubstitution != null) {
+ declaredType = declaredSubstitution.substituteType(declaredType);
+ }
+
+ if (!declaredMember.isNonNullableByDefault &&
+ interfaceMember.isNonNullableByDefault) {
+ interfaceType = legacyErasure(types.hierarchy.coreTypes, interfaceType);
+ }
+
+ bool inParameter = declaredParameter != null || asIfDeclaredParameter;
+ DartType subtype = inParameter ? interfaceType : declaredType;
+ DartType supertype = inParameter ? declaredType : interfaceType;
+
+ if (types.isSubtypeOf(
+ subtype, supertype, SubtypeCheckMode.withNullabilities)) {
+ // No problem--the proper subtyping relation is satisfied.
+ } else if (isCovariant &&
+ types.isSubtypeOf(
+ supertype, subtype, SubtypeCheckMode.withNullabilities)) {
+ // No problem--the overriding parameter is marked "covariant" and has
+ // a type which is a subtype of the parameter it overrides.
+ } else if (subtype is InvalidType || supertype is InvalidType) {
+ // Don't report a problem as something else is wrong that has already
+ // been reported.
+ } else {
+ // Report an error.
+ bool isErrorInNnbdOptedOutMode = !types.isSubtypeOf(
+ subtype, supertype, SubtypeCheckMode.ignoringNullabilities) &&
+ (!isCovariant ||
+ !types.isSubtypeOf(
+ supertype, subtype, SubtypeCheckMode.ignoringNullabilities));
+ if (isErrorInNnbdOptedOutMode || library.isNonNullableByDefault) {
+ String declaredMemberName = '${declaredMember.enclosingClass.name}'
+ '.${declaredMember.name.name}';
+ String interfaceMemberName = '${interfaceMember.enclosingClass.name}'
+ '.${interfaceMember.name.name}';
+ Message message;
+ int fileOffset;
+ if (declaredParameter == null) {
+ if (asIfDeclaredParameter) {
+ // Setter overridden by field
+ message = templateOverrideTypeMismatchSetter.withArguments(
+ declaredMemberName,
+ declaredType,
+ interfaceType,
+ interfaceMemberName,
+ library.isNonNullableByDefault);
+ } else {
+ message = templateOverrideTypeMismatchReturnType.withArguments(
+ declaredMemberName,
+ declaredType,
+ interfaceType,
+ interfaceMemberName,
+ library.isNonNullableByDefault);
+ }
+ fileOffset = declaredMember.fileOffset;
+ } else {
+ message = templateOverrideTypeMismatchParameter.withArguments(
+ declaredParameter.name,
+ declaredMemberName,
+ declaredType,
+ interfaceType,
+ interfaceMemberName,
+ library.isNonNullableByDefault);
+ fileOffset = declaredParameter.fileOffset;
+ }
+ reportInvalidOverride(
+ isInterfaceCheck, declaredMember, message, fileOffset, noLength,
+ context: [
+ templateOverriddenMethodCause
+ .withArguments(interfaceMember.name.name)
+ .withLocation(_getMemberUri(interfaceMember),
+ interfaceMember.fileOffset, noLength)
+ ]);
+ }
+ }
+ }
+
+ /// Returns whether a covariant parameter was seen and more methods thus have
+ /// to be checked.
+ bool checkMethodOverride(Types types, Procedure declaredMember,
+ Procedure interfaceMember, bool isInterfaceCheck) {
+ assert(declaredMember.kind == interfaceMember.kind);
+ assert(declaredMember.kind == ProcedureKind.Method ||
+ declaredMember.kind == ProcedureKind.Operator);
+ bool seenCovariant = false;
+ FunctionNode declaredFunction = declaredMember.function;
+ FunctionNode interfaceFunction = interfaceMember.function;
+
+ Substitution interfaceSubstitution = _computeInterfaceSubstitution(
+ types,
+ declaredMember,
+ interfaceMember,
+ declaredFunction,
+ interfaceFunction,
+ isInterfaceCheck);
+
+ Substitution declaredSubstitution =
+ _computeDeclaredSubstitution(types, declaredMember);
+
+ _checkTypes(
+ types,
+ interfaceSubstitution,
+ declaredSubstitution,
+ declaredMember,
+ interfaceMember,
+ declaredFunction.returnType,
+ interfaceFunction.returnType,
+ false,
+ null,
+ isInterfaceCheck);
+ if (declaredFunction.positionalParameters.length <
+ interfaceFunction.positionalParameters.length) {
+ reportInvalidOverride(
+ isInterfaceCheck,
+ declaredMember,
+ templateOverrideFewerPositionalArguments.withArguments(
+ "${declaredMember.enclosingClass.name}."
+ "${declaredMember.name.name}",
+ "${interfaceMember.enclosingClass.name}."
+ "${interfaceMember.name.name}"),
+ declaredMember.fileOffset,
+ noLength,
+ context: [
+ templateOverriddenMethodCause
+ .withArguments(interfaceMember.name.name)
+ .withLocation(interfaceMember.fileUri,
+ interfaceMember.fileOffset, noLength)
+ ]);
+ }
+ if (interfaceFunction.requiredParameterCount <
+ declaredFunction.requiredParameterCount) {
+ reportInvalidOverride(
+ isInterfaceCheck,
+ declaredMember,
+ templateOverrideMoreRequiredArguments.withArguments(
+ "${declaredMember.enclosingClass.name}."
+ "${declaredMember.name.name}",
+ "${interfaceMember.enclosingClass.name}."
+ "${interfaceMember.name.name}"),
+ declaredMember.fileOffset,
+ noLength,
+ context: [
+ templateOverriddenMethodCause
+ .withArguments(interfaceMember.name.name)
+ .withLocation(interfaceMember.fileUri,
+ interfaceMember.fileOffset, noLength)
+ ]);
+ }
+ for (int i = 0;
+ i < declaredFunction.positionalParameters.length &&
+ i < interfaceFunction.positionalParameters.length;
+ i++) {
+ VariableDeclaration declaredParameter =
+ declaredFunction.positionalParameters[i];
+ VariableDeclaration interfaceParameter =
+ interfaceFunction.positionalParameters[i];
+ if (i == 0 &&
+ declaredMember.name == equalsName &&
+ declaredParameter.type ==
+ types.hierarchy.coreTypes.objectNonNullableRawType &&
+ interfaceParameter.type is DynamicType) {
+ // TODO(johnniwinther): Add check for opt-in overrides of operator ==.
+ // `operator ==` methods in opt-out classes have type
+ // `bool Function(dynamic)`.
+ continue;
+ }
+
+ _checkTypes(
+ types,
+ interfaceSubstitution,
+ declaredSubstitution,
+ declaredMember,
+ interfaceMember,
+ declaredParameter.type,
+ interfaceParameter.type,
+ declaredParameter.isCovariant || interfaceParameter.isCovariant,
+ declaredParameter,
+ isInterfaceCheck);
+ if (declaredParameter.isCovariant) seenCovariant = true;
+ }
+ if (declaredFunction.namedParameters.isEmpty &&
+ interfaceFunction.namedParameters.isEmpty) {
+ return seenCovariant;
+ }
+ if (declaredFunction.namedParameters.length <
+ interfaceFunction.namedParameters.length) {
+ reportInvalidOverride(
+ isInterfaceCheck,
+ declaredMember,
+ templateOverrideFewerNamedArguments.withArguments(
+ "${declaredMember.enclosingClass.name}."
+ "${declaredMember.name.name}",
+ "${interfaceMember.enclosingClass.name}."
+ "${interfaceMember.name.name}"),
+ declaredMember.fileOffset,
+ noLength,
+ context: [
+ templateOverriddenMethodCause
+ .withArguments(interfaceMember.name.name)
+ .withLocation(interfaceMember.fileUri,
+ interfaceMember.fileOffset, noLength)
+ ]);
+ }
+ int compareNamedParameters(VariableDeclaration p0, VariableDeclaration p1) {
+ return p0.name.compareTo(p1.name);
+ }
+
+ List<VariableDeclaration> sortedFromDeclared =
+ new List.from(declaredFunction.namedParameters)
+ ..sort(compareNamedParameters);
+ List<VariableDeclaration> sortedFromInterface =
+ new List.from(interfaceFunction.namedParameters)
+ ..sort(compareNamedParameters);
+ Iterator<VariableDeclaration> declaredNamedParameters =
+ sortedFromDeclared.iterator;
+ Iterator<VariableDeclaration> interfaceNamedParameters =
+ sortedFromInterface.iterator;
+ outer:
+ while (declaredNamedParameters.moveNext() &&
+ interfaceNamedParameters.moveNext()) {
+ while (declaredNamedParameters.current.name !=
+ interfaceNamedParameters.current.name) {
+ if (!declaredNamedParameters.moveNext()) {
+ reportInvalidOverride(
+ isInterfaceCheck,
+ declaredMember,
+ templateOverrideMismatchNamedParameter.withArguments(
+ "${declaredMember.enclosingClass.name}."
+ "${declaredMember.name.name}",
+ interfaceNamedParameters.current.name,
+ "${interfaceMember.enclosingClass.name}."
+ "${interfaceMember.name.name}"),
+ declaredMember.fileOffset,
+ noLength,
+ context: [
+ templateOverriddenMethodCause
+ .withArguments(interfaceMember.name.name)
+ .withLocation(interfaceMember.fileUri,
+ interfaceMember.fileOffset, noLength)
+ ]);
+ break outer;
+ }
+ }
+ VariableDeclaration declaredParameter = declaredNamedParameters.current;
+ _checkTypes(
+ types,
+ interfaceSubstitution,
+ declaredSubstitution,
+ declaredMember,
+ interfaceMember,
+ declaredParameter.type,
+ interfaceNamedParameters.current.type,
+ declaredParameter.isCovariant,
+ declaredParameter,
+ isInterfaceCheck);
+ if (declaredMember.isNonNullableByDefault &&
+ declaredParameter.isRequired &&
+ interfaceMember.isNonNullableByDefault &&
+ !interfaceNamedParameters.current.isRequired) {
+ reportInvalidOverride(
+ isInterfaceCheck,
+ declaredMember,
+ templateOverrideMismatchRequiredNamedParameter.withArguments(
+ declaredParameter.name,
+ "${declaredMember.enclosingClass.name}."
+ "${declaredMember.name.name}",
+ "${interfaceMember.enclosingClass.name}."
+ "${interfaceMember.name.name}"),
+ declaredParameter.fileOffset,
+ noLength,
+ context: [
+ templateOverriddenMethodCause
+ .withArguments(interfaceMember.name.name)
+ .withLocation(_getMemberUri(interfaceMember),
+ interfaceMember.fileOffset, noLength)
+ ]);
+ }
+ if (declaredParameter.isCovariant) seenCovariant = true;
+ }
+ return seenCovariant;
+ }
+
+ void checkGetterOverride(Types types, Member declaredMember,
+ Member interfaceMember, bool isInterfaceCheck) {
+ Substitution interfaceSubstitution = _computeInterfaceSubstitution(
+ types, declaredMember, interfaceMember, null, null, isInterfaceCheck);
+ Substitution declaredSubstitution =
+ _computeDeclaredSubstitution(types, declaredMember);
+ DartType declaredType = declaredMember.getterType;
+ DartType interfaceType = interfaceMember.getterType;
+ _checkTypes(
+ types,
+ interfaceSubstitution,
+ declaredSubstitution,
+ declaredMember,
+ interfaceMember,
+ declaredType,
+ interfaceType,
+ false,
+ null,
+ isInterfaceCheck);
+ }
+
+ /// Returns whether a covariant parameter was seen and more methods thus have
+ /// to be checked.
+ bool checkSetterOverride(Types types, Member declaredMember,
+ Member interfaceMember, bool isInterfaceCheck) {
+ Substitution interfaceSubstitution = _computeInterfaceSubstitution(
+ types, declaredMember, interfaceMember, null, null, isInterfaceCheck);
+ Substitution declaredSubstitution =
+ _computeDeclaredSubstitution(types, declaredMember);
+ DartType declaredType = declaredMember.setterType;
+ DartType interfaceType = interfaceMember.setterType;
+ VariableDeclaration declaredParameter =
+ declaredMember.function?.positionalParameters?.elementAt(0);
+ bool isCovariant = declaredParameter?.isCovariant ?? false;
+ if (!isCovariant && declaredMember is Field) {
+ isCovariant = declaredMember.isCovariant;
+ }
+ if (!isCovariant && interfaceMember is Field) {
+ isCovariant = interfaceMember.isCovariant;
+ }
+ _checkTypes(
+ types,
+ interfaceSubstitution,
+ declaredSubstitution,
+ declaredMember,
+ interfaceMember,
+ declaredType,
+ interfaceType,
+ isCovariant,
+ declaredParameter,
+ isInterfaceCheck,
+ asIfDeclaredParameter: true);
+ return isCovariant;
+ }
+
+ // When the overriding member is inherited, report the class containing
+ // the conflict as the main error.
+ void reportInvalidOverride(bool isInterfaceCheck, Member declaredMember,
+ Message message, int fileOffset, int length,
+ {List<LocatedMessage> context}) {
+ if (shouldOverrideProblemBeOverlooked(this)) {
+ return;
+ }
+
+ if (declaredMember.enclosingClass == cls) {
+ // Ordinary override
+ library.addProblem(message, fileOffset, length, declaredMember.fileUri,
+ context: context);
+ } else {
+ context = [
+ message.withLocation(declaredMember.fileUri, fileOffset, length),
+ ...?context
+ ];
+ if (isInterfaceCheck) {
+ // Interface check
+ library.addProblem(
+ templateInterfaceCheck.withArguments(
+ declaredMember.name.name, cls.name),
+ cls.fileOffset,
+ cls.name.length,
+ cls.fileUri,
+ context: context);
+ } else {
+ if (cls.isAnonymousMixin) {
+ // Implicit mixin application class
+ String baseName = cls.superclass.demangledName;
+ String mixinName = cls.mixedInClass.name;
+ int classNameLength = cls.nameAsMixinApplicationSubclass.length;
+ library.addProblem(
+ templateImplicitMixinOverride.withArguments(
+ mixinName, baseName, declaredMember.name.name),
+ cls.fileOffset,
+ classNameLength,
+ cls.fileUri,
+ context: context);
+ } else {
+ // Named mixin application class
+ library.addProblem(
+ templateNamedMixinOverride.withArguments(
+ cls.name, declaredMember.name.name),
+ cls.fileOffset,
+ cls.name.length,
+ cls.fileUri,
+ context: context);
+ }
+ }
+ }
+ }
}
diff --git a/pkg/front_end/testcases/value_class/empty.dart.strong.expect b/pkg/front_end/testcases/value_class/empty.dart.strong.expect
index 129465c..e659acf 100644
--- a/pkg/front_end/testcases/value_class/empty.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/empty.dart.strong.expect
@@ -13,6 +13,8 @@
return other is self::EmptyClass;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///empty.dartEmptyClass".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::EmptyClass::•();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/empty.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/empty.dart.strong.transformed.expect
index 129465c..e659acf 100644
--- a/pkg/front_end/testcases/value_class/empty.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/empty.dart.strong.transformed.expect
@@ -13,6 +13,8 @@
return other is self::EmptyClass;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///empty.dartEmptyClass".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::EmptyClass::•();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/empty.dart.weak.expect b/pkg/front_end/testcases/value_class/empty.dart.weak.expect
index 129465c..e659acf 100644
--- a/pkg/front_end/testcases/value_class/empty.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/empty.dart.weak.expect
@@ -13,6 +13,8 @@
return other is self::EmptyClass;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///empty.dartEmptyClass".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::EmptyClass::•();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/empty.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/empty.dart.weak.transformed.expect
index 129465c..e659acf 100644
--- a/pkg/front_end/testcases/value_class/empty.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/empty.dart.weak.transformed.expect
@@ -13,6 +13,8 @@
return other is self::EmptyClass;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///empty.dartEmptyClass".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::EmptyClass::•();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.expect b/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.expect
index c465cf0..6852df4 100644
--- a/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.expect
@@ -13,6 +13,8 @@
return other is self::A;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartA".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::A::•();
}
class B extends core::Object {
synthetic constructor •() → self::B
@@ -42,6 +44,8 @@
return other is self::F;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartF".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::F::•();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.transformed.expect
index 93db2ab..27d97db 100644
--- a/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.transformed.expect
@@ -13,6 +13,8 @@
return other is self::A;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartA".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::A::•();
}
class B extends core::Object {
synthetic constructor •() → self::B
@@ -37,6 +39,8 @@
return other is self::A;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartA".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::A::•();
}
class F extends self::B implements self::C /*isEliminatedMixin*/ {
synthetic constructor •() → self::F
@@ -46,6 +50,8 @@
return other is self::F;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartF".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::F::•();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.expect b/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.expect
index c465cf0..6852df4 100644
--- a/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.expect
@@ -13,6 +13,8 @@
return other is self::A;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartA".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::A::•();
}
class B extends core::Object {
synthetic constructor •() → self::B
@@ -42,6 +44,8 @@
return other is self::F;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartF".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::F::•();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.transformed.expect
index 93db2ab..27d97db 100644
--- a/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.transformed.expect
@@ -13,6 +13,8 @@
return other is self::A;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartA".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::A::•();
}
class B extends core::Object {
synthetic constructor •() → self::B
@@ -37,6 +39,8 @@
return other is self::A;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartA".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::A::•();
}
class F extends self::B implements self::C /*isEliminatedMixin*/ {
synthetic constructor •() → self::F
@@ -46,6 +50,8 @@
return other is self::F;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///explicit_mixin.dartF".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::F::•();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.expect b/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.expect
index 32fe546..ae9077e 100644
--- a/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.expect
@@ -21,6 +21,8 @@
return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_final_field_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+ return new self::Animal::•(numberOfLegs: numberOfLegs);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.transformed.expect
index 32fe546..ae9077e 100644
--- a/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.transformed.expect
@@ -21,6 +21,8 @@
return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_final_field_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+ return new self::Animal::•(numberOfLegs: numberOfLegs);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.expect b/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.expect
index 32fe546..ae9077e 100644
--- a/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.expect
@@ -21,6 +21,8 @@
return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_final_field_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+ return new self::Animal::•(numberOfLegs: numberOfLegs);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.transformed.expect
index 32fe546..ae9077e 100644
--- a/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.transformed.expect
@@ -21,6 +21,8 @@
return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_final_field_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+ return new self::Animal::•(numberOfLegs: numberOfLegs);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.expect b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.expect
index e0bd784..805f287 100644
--- a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.expect
@@ -22,6 +22,8 @@
return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_value_extends_value_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+ return new self::Animal::•(numberOfLegs: numberOfLegs);
}
class Cat extends self::Animal {
synthetic constructor •() → self::Cat
diff --git a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.transformed.expect
index e0bd784..805f287 100644
--- a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.transformed.expect
@@ -22,6 +22,8 @@
return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_value_extends_value_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+ return new self::Animal::•(numberOfLegs: numberOfLegs);
}
class Cat extends self::Animal {
synthetic constructor •() → self::Cat
diff --git a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.expect b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.expect
index e0bd784..805f287 100644
--- a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.expect
@@ -22,6 +22,8 @@
return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_value_extends_value_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+ return new self::Animal::•(numberOfLegs: numberOfLegs);
}
class Cat extends self::Animal {
synthetic constructor •() → self::Cat
diff --git a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.transformed.expect
index e0bd784..805f287 100644
--- a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.transformed.expect
@@ -22,6 +22,8 @@
return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_value_extends_value_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+ return new self::Animal::•(numberOfLegs: numberOfLegs);
}
class Cat extends self::Animal {
synthetic constructor •() → self::Cat
diff --git a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.expect b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.expect
index 67b715f..95373ed 100644
--- a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.expect
@@ -27,6 +27,8 @@
return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_value_implements_value_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+ return new self::Animal::•(numberOfLegs: numberOfLegs);
}
class Cat extends core::Object implements self::Animal {
final field core::int numberOfLegs = null;
diff --git a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.transformed.expect
index 67b715f..95373ed 100644
--- a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.transformed.expect
@@ -27,6 +27,8 @@
return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_value_implements_value_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+ return new self::Animal::•(numberOfLegs: numberOfLegs);
}
class Cat extends core::Object implements self::Animal {
final field core::int numberOfLegs = null;
diff --git a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.expect b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.expect
index 67b715f..95373ed 100644
--- a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.expect
@@ -27,6 +27,8 @@
return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_value_implements_value_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+ return new self::Animal::•(numberOfLegs: numberOfLegs);
}
class Cat extends core::Object implements self::Animal {
final field core::int numberOfLegs = null;
diff --git a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.transformed.expect
index 67b715f..95373ed 100644
--- a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.transformed.expect
@@ -27,6 +27,8 @@
return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///non_value_implements_value_error.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+ return new self::Animal::•(numberOfLegs: numberOfLegs);
}
class Cat extends core::Object implements self::Animal {
final field core::int numberOfLegs = null;
diff --git a/pkg/front_end/testcases/value_class/simple.dart.strong.expect b/pkg/front_end/testcases/value_class/simple.dart.strong.expect
index 218ec9f..862862f 100644
--- a/pkg/front_end/testcases/value_class/simple.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/simple.dart.strong.expect
@@ -43,6 +43,8 @@
return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///simple.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+ return new self::Animal::•(numberOfLegs: numberOfLegs);
}
static method main() → dynamic {
self::Animal firstAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numberOfLegs'.
diff --git a/pkg/front_end/testcases/value_class/simple.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/simple.dart.strong.transformed.expect
index 9845aaa..3213a78 100644
--- a/pkg/front_end/testcases/value_class/simple.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/simple.dart.strong.transformed.expect
@@ -43,6 +43,8 @@
return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///simple.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+ return new self::Animal::•(numberOfLegs: numberOfLegs);
}
static method main() → dynamic {
self::Animal firstAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numberOfLegs'.
diff --git a/pkg/front_end/testcases/value_class/simple.dart.weak.expect b/pkg/front_end/testcases/value_class/simple.dart.weak.expect
index 218ec9f..862862f 100644
--- a/pkg/front_end/testcases/value_class/simple.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/simple.dart.weak.expect
@@ -43,6 +43,8 @@
return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///simple.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+ return new self::Animal::•(numberOfLegs: numberOfLegs);
}
static method main() → dynamic {
self::Animal firstAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numberOfLegs'.
diff --git a/pkg/front_end/testcases/value_class/simple.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/simple.dart.weak.transformed.expect
index 9845aaa..3213a78 100644
--- a/pkg/front_end/testcases/value_class/simple.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/simple.dart.weak.transformed.expect
@@ -43,6 +43,8 @@
return other is self::Animal && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Animal}.{self::Animal::numberOfLegs});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine("org-dartlang-testcase:///simple.dartAnimal".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs}) → dynamic
+ return new self::Animal::•(numberOfLegs: numberOfLegs);
}
static method main() → dynamic {
self::Animal firstAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numberOfLegs'.
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.expect b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.expect
index d3224ed..d02e298 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.expect
@@ -49,6 +49,8 @@
return other is self::Cat && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Animal::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_extends_non_value.dartCat".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+ return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
}
static method main() → dynamic {
self::Cat firstCat = invalid-expression "pkg/front_end/testcases/value_class/value_extends_non_value.dart:18:22: Error: No named parameter with the name 'numberOfLegs'.
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.transformed.expect
index bf869ee..6ed1828 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.transformed.expect
@@ -49,6 +49,8 @@
return other is self::Cat && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Animal::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_extends_non_value.dartCat".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+ return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
}
static method main() → dynamic {
self::Cat firstCat = invalid-expression "pkg/front_end/testcases/value_class/value_extends_non_value.dart:18:22: Error: No named parameter with the name 'numberOfLegs'.
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.expect b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.expect
index d3224ed..d02e298 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.expect
@@ -49,6 +49,8 @@
return other is self::Cat && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Animal::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_extends_non_value.dartCat".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+ return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
}
static method main() → dynamic {
self::Cat firstCat = invalid-expression "pkg/front_end/testcases/value_class/value_extends_non_value.dart:18:22: Error: No named parameter with the name 'numberOfLegs'.
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.transformed.expect
index bf869ee..6ed1828 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.transformed.expect
@@ -49,6 +49,8 @@
return other is self::Cat && this.{self::Animal::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Animal::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_extends_non_value.dartCat".{core::String::hashCode}, this.{self::Animal::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+ return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
}
static method main() → dynamic {
self::Cat firstCat = invalid-expression "pkg/front_end/testcases/value_class/value_extends_non_value.dart:18:22: Error: No named parameter with the name 'numberOfLegs'.
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.expect b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.expect
index b1b9373..240ae96 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.expect
@@ -31,6 +31,8 @@
return other is self::Cat;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_extends_non_value_error.dartCat".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::Cat::•();
}
class Animal2 extends core::Object {
final field core::int numberOfLegs = null;
@@ -46,6 +48,8 @@
return other is self::Cat2;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_extends_non_value_error.dartCat2".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::Cat2::•();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.transformed.expect
index b1b9373..240ae96 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.transformed.expect
@@ -31,6 +31,8 @@
return other is self::Cat;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_extends_non_value_error.dartCat".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::Cat::•();
}
class Animal2 extends core::Object {
final field core::int numberOfLegs = null;
@@ -46,6 +48,8 @@
return other is self::Cat2;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_extends_non_value_error.dartCat2".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::Cat2::•();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.expect b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.expect
index b1b9373..240ae96 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.expect
@@ -31,6 +31,8 @@
return other is self::Cat;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_extends_non_value_error.dartCat".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::Cat::•();
}
class Animal2 extends core::Object {
final field core::int numberOfLegs = null;
@@ -46,6 +48,8 @@
return other is self::Cat2;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_extends_non_value_error.dartCat2".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::Cat2::•();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.transformed.expect
index b1b9373..240ae96 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.transformed.expect
@@ -31,6 +31,8 @@
return other is self::Cat;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_extends_non_value_error.dartCat".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::Cat::•();
}
class Animal2 extends core::Object {
final field core::int numberOfLegs = null;
@@ -46,6 +48,8 @@
return other is self::Cat2;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_extends_non_value_error.dartCat2".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::Cat2::•();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.expect b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.expect
index a0f49ac..81644f5 100644
--- a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.expect
@@ -92,6 +92,8 @@
return other is self::Cat && this.{self::Cat::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_implements_non_value.dartCat".{core::String::hashCode}, this.{self::Cat::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+ return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
}
abstract class Animal2 extends core::Object {
synthetic constructor •() → self::Animal2
@@ -109,6 +111,8 @@
return other is self::Cat2 && this.{self::Cat2::numberOfLegs}.{core::num::==}(other{self::Cat2}.{self::Cat2::numberOfLegs}) && this.{self::Cat2::numberOfWhiskers}.{core::num::==}(other{self::Cat2}.{self::Cat2::numberOfWhiskers});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_implements_non_value.dartCat2".{core::String::hashCode}, this.{self::Cat2::numberOfLegs}.{core::num::hashCode}), this.{self::Cat2::numberOfWhiskers}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+ return new self::Cat2::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
}
static method main() → dynamic {
self::Cat firstCat = invalid-expression "pkg/front_end/testcases/value_class/value_implements_non_value.dart:30:22: Error: No named parameter with the name 'numberOfLegs'.
diff --git a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.transformed.expect
index e412416..bcf2a6e 100644
--- a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.transformed.expect
@@ -92,6 +92,8 @@
return other is self::Cat && this.{self::Cat::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_implements_non_value.dartCat".{core::String::hashCode}, this.{self::Cat::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+ return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
}
abstract class Animal2 extends core::Object {
synthetic constructor •() → self::Animal2
@@ -109,6 +111,8 @@
return other is self::Cat2 && this.{self::Cat2::numberOfLegs}.{core::num::==}(other{self::Cat2}.{self::Cat2::numberOfLegs}) && this.{self::Cat2::numberOfWhiskers}.{core::num::==}(other{self::Cat2}.{self::Cat2::numberOfWhiskers});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_implements_non_value.dartCat2".{core::String::hashCode}, this.{self::Cat2::numberOfLegs}.{core::num::hashCode}), this.{self::Cat2::numberOfWhiskers}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+ return new self::Cat2::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
}
static method main() → dynamic {
self::Cat firstCat = invalid-expression "pkg/front_end/testcases/value_class/value_implements_non_value.dart:30:22: Error: No named parameter with the name 'numberOfLegs'.
diff --git a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.expect b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.expect
index 7ff4c88..5c550c6 100644
--- a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.expect
@@ -92,6 +92,8 @@
return other is self::Cat && this.{self::Cat::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_implements_non_value.dartCat".{core::String::hashCode}, this.{self::Cat::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+ return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
}
abstract class Animal2 extends core::Object {
synthetic constructor •() → self::Animal2
@@ -109,6 +111,8 @@
return other is self::Cat2 && this.{self::Cat2::numberOfLegs}.{core::num::==}(other{self::Cat2}.{self::Cat2::numberOfLegs}) && this.{self::Cat2::numberOfWhiskers}.{core::num::==}(other{self::Cat2}.{self::Cat2::numberOfWhiskers});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_implements_non_value.dartCat2".{core::String::hashCode}, this.{self::Cat2::numberOfLegs}.{core::num::hashCode}), this.{self::Cat2::numberOfWhiskers}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+ return new self::Cat2::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
}
static method main() → dynamic {
self::Cat firstCat = invalid-expression "pkg/front_end/testcases/value_class/value_implements_non_value.dart:30:22: Error: No named parameter with the name 'numberOfLegs'.
diff --git a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.transformed.expect
index 939015f..455ce4f 100644
--- a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.transformed.expect
@@ -92,6 +92,8 @@
return other is self::Cat && this.{self::Cat::numberOfLegs}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfLegs}) && this.{self::Cat::numberOfWhiskers}.{core::num::==}(other{self::Cat}.{self::Cat::numberOfWhiskers});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_implements_non_value.dartCat".{core::String::hashCode}, this.{self::Cat::numberOfLegs}.{core::num::hashCode}), this.{self::Cat::numberOfWhiskers}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+ return new self::Cat::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
}
abstract class Animal2 extends core::Object {
synthetic constructor •() → self::Animal2
@@ -109,6 +111,8 @@
return other is self::Cat2 && this.{self::Cat2::numberOfLegs}.{core::num::==}(other{self::Cat2}.{self::Cat2::numberOfLegs}) && this.{self::Cat2::numberOfWhiskers}.{core::num::==}(other{self::Cat2}.{self::Cat2::numberOfWhiskers});
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish(val::JenkinsSmiHash::combine(val::JenkinsSmiHash::combine("org-dartlang-testcase:///value_implements_non_value.dartCat2".{core::String::hashCode}, this.{self::Cat2::numberOfLegs}.{core::num::hashCode}), this.{self::Cat2::numberOfWhiskers}.{core::num::hashCode}));
+ method /*isNullableByDefault*/ copyWith({core::int numberOfLegs, core::int numberOfWhiskers}) → dynamic
+ return new self::Cat2::•(numberOfLegs: numberOfLegs, numberOfWhiskers: numberOfWhiskers);
}
static method main() → dynamic {
self::Cat firstCat = invalid-expression "pkg/front_end/testcases/value_class/value_implements_non_value.dart:30:22: Error: No named parameter with the name 'numberOfLegs'.
diff --git a/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.expect b/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.expect
index 7e226a5..f0c520b 100644
--- a/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.expect
@@ -13,6 +13,8 @@
return other is self::A;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_mixin_error.dartA".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::A::•();
}
class B extends core::Object {
synthetic constructor •() → self::B
diff --git a/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.transformed.expect
index 6ae17d2..4ea2146 100644
--- a/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.transformed.expect
@@ -13,6 +13,8 @@
return other is self::A;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_mixin_error.dartA".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::A::•();
}
class B extends core::Object {
synthetic constructor •() → self::B
@@ -27,6 +29,8 @@
return other is self::A;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_mixin_error.dartA".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::A::•();
}
class C extends self::_C&B&A {
synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.expect b/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.expect
index 7e226a5..f0c520b 100644
--- a/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.expect
@@ -13,6 +13,8 @@
return other is self::A;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_mixin_error.dartA".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::A::•();
}
class B extends core::Object {
synthetic constructor •() → self::B
diff --git a/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.transformed.expect
index 6ae17d2..4ea2146 100644
--- a/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.transformed.expect
@@ -13,6 +13,8 @@
return other is self::A;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_mixin_error.dartA".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::A::•();
}
class B extends core::Object {
synthetic constructor •() → self::B
@@ -27,6 +29,8 @@
return other is self::A;
get /*isNullableByDefault*/ hashCode() → core::int
return val::JenkinsSmiHash::finish("org-dartlang-testcase:///value_mixin_error.dartA".{core::String::hashCode});
+ method /*isNullableByDefault*/ copyWith() → dynamic
+ return new self::A::•();
}
class C extends self::_C&B&A {
synthetic constructor •() → self::C
diff --git a/pkg/kernel/lib/transformations/value_class.dart b/pkg/kernel/lib/transformations/value_class.dart
index dc2d71a..dfea2de 100644
--- a/pkg/kernel/lib/transformations/value_class.dart
+++ b/pkg/kernel/lib/transformations/value_class.dart
@@ -54,19 +54,7 @@
void transformValueClass(
Class cls, CoreTypes coreTypes, ClassHierarchy hierarchy) {
- addConstructor(cls, coreTypes);
- addEqualsOperator(cls, coreTypes, hierarchy);
- addHashCode(cls, coreTypes, hierarchy);
- // addCopyWith(cls);
-}
-
-void addConstructor(Class cls, CoreTypes coreTypes) {
- Constructor superConstructor = null;
- for (Constructor constructor in cls.superclass.constructors) {
- if (constructor.name.name == "") {
- superConstructor = constructor;
- }
- }
+ List<VariableDeclaration> allVariables = queryAllInstanceVariables(cls);
Constructor syntheticConstructor = null;
for (Constructor constructor in cls.constructors) {
if (constructor.isSynthetic) {
@@ -74,6 +62,21 @@
}
}
+ addConstructor(cls, coreTypes, syntheticConstructor);
+ addEqualsOperator(cls, coreTypes, hierarchy, allVariables.toList());
+ addHashCode(cls, coreTypes, hierarchy, allVariables.toList());
+ addCopyWith(
+ cls, coreTypes, hierarchy, allVariables.toList(), syntheticConstructor);
+}
+
+void addConstructor(
+ Class cls, CoreTypes coreTypes, Constructor syntheticConstructor) {
+ Constructor superConstructor = null;
+ for (Constructor constructor in cls.superclass.constructors) {
+ if (constructor.name.name == "") {
+ superConstructor = constructor;
+ }
+ }
List<VariableDeclaration> superParameters = superConstructor
.function.namedParameters
.map<VariableDeclaration>((e) => VariableDeclaration(e.name, type: e.type)
@@ -117,8 +120,8 @@
cls.annotations.removeAt(valueClassAnnotationIndex);
}
-void addEqualsOperator(
- Class cls, CoreTypes coreTypes, ClassHierarchy hierarchy) {
+void addEqualsOperator(Class cls, CoreTypes coreTypes, ClassHierarchy hierarchy,
+ List<VariableDeclaration> allVariables) {
for (Procedure procedure in cls.procedures) {
if (procedure.kind == ProcedureKind.Operator &&
procedure.name.name == "==") {
@@ -131,21 +134,8 @@
: coreTypes.boolLegacyRawType;
DartType myType = coreTypes.thisInterfaceType(cls, Nullability.nonNullable);
- Constructor superConstructor = null;
- for (Constructor constructor in cls.superclass.constructors) {
- if (constructor.name.name == "") {
- superConstructor = constructor;
- }
- }
VariableDeclaration other = VariableDeclaration("other",
type: coreTypes.objectRawType(Nullability.nonNullable));
- List<VariableDeclaration> allVariables = superConstructor
- .function.namedParameters
- .map<VariableDeclaration>(
- (f) => VariableDeclaration(f.name, type: f.type))
- .toList()
- ..addAll(cls.fields.map<VariableDeclaration>(
- (f) => VariableDeclaration(f.name.name, type: f.type)));
Map<VariableDeclaration, Member> targetsEquals = new Map();
Map<VariableDeclaration, Member> targets = new Map();
@@ -186,7 +176,8 @@
cls.addMember(equalsOperator);
}
-void addHashCode(Class cls, CoreTypes coreTypes, ClassHierarchy hierarchy) {
+void addHashCode(Class cls, CoreTypes coreTypes, ClassHierarchy hierarchy,
+ List<VariableDeclaration> allVariables) {
for (Procedure procedure in cls.procedures) {
if (procedure.kind == ProcedureKind.Getter &&
procedure.name.name == "hashCode") {
@@ -198,13 +189,6 @@
? coreTypes.intNonNullableRawType
: coreTypes.intLegacyRawType;
- Constructor superConstructor = null;
- for (Constructor constructor in cls.superclass.constructors) {
- if (constructor.name.name == "") {
- superConstructor = constructor;
- }
- }
-
Procedure hashCombine, hashFinish;
HashCombineMethodsScanner hashCombineMethodsScanner =
new HashCombineMethodsScanner();
@@ -219,14 +203,6 @@
}
}
- List<VariableDeclaration> allVariables = superConstructor
- .function.namedParameters
- .map<VariableDeclaration>(
- (f) => VariableDeclaration(f.name, type: f.type))
- .toList()
- ..addAll(cls.fields.map<VariableDeclaration>(
- (f) => VariableDeclaration(f.name.name, type: f.type)));
-
Map<VariableDeclaration, Member> targetsHashcode = new Map();
Map<VariableDeclaration, Member> targets = new Map();
for (VariableDeclaration variable in allVariables) {
@@ -269,17 +245,21 @@
..fileOffset = cls.fileOffset);
}
-/*
-void addCopyWith(Class cls) {
- Map<String, VariableDeclaration> environment = Map.fromIterable(cls.fields,
- key: (f) => f.name.name,
- value: (f) => VariableDeclaration(f.name.name, type: f.type));
-
- Constructor syntheticConstructor = null;
- for (Constructor constructor in cls.constructors) {
- if (constructor.isSynthetic) {
- syntheticConstructor = constructor;
+void addCopyWith(Class cls, CoreTypes coreTypes, ClassHierarchy hierarchy,
+ List<VariableDeclaration> allVariables, Constructor syntheticConstructor) {
+ Map<VariableDeclaration, Member> targetsEquals = new Map();
+ Map<VariableDeclaration, Member> targets = new Map();
+ for (VariableDeclaration variable in allVariables) {
+ Member target = coreTypes.objectEquals;
+ Member targetEquals = coreTypes.objectEquals;
+ DartType fieldsType = variable.type;
+ if (fieldsType is InterfaceType) {
+ targetEquals =
+ hierarchy.getInterfaceMember(fieldsType.classNode, Name("=="));
+ target = hierarchy.getInterfaceMember(cls, Name(variable.name));
}
+ targetsEquals[variable] = targetEquals;
+ targets[variable] = target;
}
cls.addMember(Procedure(
@@ -288,15 +268,26 @@
FunctionNode(
ReturnStatement(ConstructorInvocation(
syntheticConstructor,
- Arguments(cls.fields
- .map((f) => ConditionalExpression(
- MethodInvocation(VariableGet(environment[f.name.name]),
- Name('=='), Arguments([NullLiteral()])),
- PropertyGet(ThisExpression(), f.name, f),
- VariableGet(environment[f.name.name]),
- f.type))
- .toList()))),
- namedParameters:
- cls.fields.map((f) => environment[f.name.name]).toList())));
+ Arguments([],
+ named: allVariables
+ .map((f) => NamedExpression(f.name, VariableGet(f)))
+ .toList()))),
+ namedParameters: allVariables),
+ fileUri: cls.fileUri)
+ ..fileOffset = cls.fileOffset);
}
-*/
+
+List<VariableDeclaration> queryAllInstanceVariables(Class cls) {
+ Constructor superConstructor = null;
+ for (Constructor constructor in cls.superclass.constructors) {
+ if (constructor.name.name == "") {
+ superConstructor = constructor;
+ }
+ }
+ return superConstructor.function.namedParameters
+ .map<VariableDeclaration>(
+ (f) => VariableDeclaration(f.name, type: f.type))
+ .toList()
+ ..addAll(cls.fields.map<VariableDeclaration>(
+ (f) => VariableDeclaration(f.name.name, type: f.type)));
+}
diff --git a/tools/VERSION b/tools/VERSION
index 4f2e8ca..8d4e282 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 10
PATCH 0
-PRERELEASE 122
+PRERELEASE 123
PRERELEASE_PATCH 0
\ No newline at end of file