Version 2.10.0-129.0.dev
Merge commit '52794e61417df36b96f54228cf014b15cb258954' into 'dev'
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 5b3cbd7..b7a9d24 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
@@ -2965,76 +2965,84 @@
return combinedMemberSignatureResult =
declarations.first.getMember(hierarchy);
}
- bool isNonNullableByDefault = classBuilder.library.isNonNullableByDefault;
- DartType thisType = hierarchy.coreTypes
- .thisInterfaceType(classBuilder.cls, classBuilder.library.nonNullable);
- List<DartType> candidateTypes = new List<DartType>(declarations.length);
ClassMember bestSoFar;
int bestSoFarIndex;
- DartType bestTypeSoFar;
Map<DartType, int> mutualSubtypes;
- for (int candidateIndex = declarations.length - 1;
- candidateIndex >= 0;
- candidateIndex--) {
- ClassMember candidate = declarations[candidateIndex];
- Member target = candidate.getMember(hierarchy);
- assert(target != null,
- "No member computed for ${candidate} (${candidate.runtimeType})");
- DartType candidateType = computeMemberType(hierarchy, thisType, target);
- if (!isNonNullableByDefault) {
- candidateType = legacyErasure(hierarchy.coreTypes, candidateType);
- }
- candidateTypes[candidateIndex] = candidateType;
- if (bestSoFar == null) {
- bestSoFar = candidate;
- bestTypeSoFar = candidateType;
- bestSoFarIndex = candidateIndex;
- } else {
- if (isMoreSpecific(hierarchy, candidateType, bestTypeSoFar)) {
- debug?.log("Combined Member Signature: ${candidate.fullName} "
- "${candidateType} <: ${bestSoFar.fullName} ${bestTypeSoFar}");
- if (isNonNullableByDefault &&
- isMoreSpecific(hierarchy, bestTypeSoFar, candidateType)) {
- if (mutualSubtypes == null) {
- mutualSubtypes = {
- bestTypeSoFar: bestSoFarIndex,
- candidateType: candidateIndex
- };
- } else {
- mutualSubtypes[candidateType] = candidateIndex;
- }
- } else {
- mutualSubtypes = null;
- }
- bestSoFarIndex = candidateIndex;
+ if (declarations.length == 1) {
+ bestSoFar = declarations[0];
+ bestSoFarIndex = 0;
+ } else {
+ DartType thisType = hierarchy.coreTypes.thisInterfaceType(
+ classBuilder.cls, classBuilder.library.nonNullable);
+ bool isNonNullableByDefault = classBuilder.library.isNonNullableByDefault;
+
+ DartType bestTypeSoFar;
+ List<DartType> candidateTypes = new List<DartType>(declarations.length);
+ for (int candidateIndex = declarations.length - 1;
+ candidateIndex >= 0;
+ candidateIndex--) {
+ ClassMember candidate = declarations[candidateIndex];
+ Member target = candidate.getMember(hierarchy);
+ assert(target != null,
+ "No member computed for ${candidate} (${candidate.runtimeType})");
+ DartType candidateType = computeMemberType(hierarchy, thisType, target);
+ if (!isNonNullableByDefault) {
+ candidateType = legacyErasure(hierarchy.coreTypes, candidateType);
+ }
+ candidateTypes[candidateIndex] = candidateType;
+ if (bestSoFar == null) {
bestSoFar = candidate;
bestTypeSoFar = candidateType;
+ bestSoFarIndex = candidateIndex;
} else {
- debug?.log("Combined Member Signature: "
- "${candidate.fullName} !<: ${bestSoFar.fullName}");
- }
- }
- }
- if (bestSoFar != null) {
- debug?.log("Combined Member Signature bestSoFar: ${bestSoFar.fullName}");
- for (int candidateIndex = 0;
- candidateIndex < declarations.length;
- candidateIndex++) {
- ClassMember candidate = declarations[candidateIndex];
- DartType candidateType = candidateTypes[candidateIndex];
- if (!isMoreSpecific(hierarchy, bestTypeSoFar, candidateType)) {
- debug?.log("Combined Member Signature: "
- "${bestSoFar.fullName} !<: ${candidate.fullName}");
-
- if (!shouldOverrideProblemBeOverlooked(classBuilder)) {
- bestSoFar = null;
- bestTypeSoFar = null;
- mutualSubtypes = null;
+ if (isMoreSpecific(hierarchy, candidateType, bestTypeSoFar)) {
+ debug?.log("Combined Member Signature: ${candidate.fullName} "
+ "${candidateType} <: ${bestSoFar.fullName} ${bestTypeSoFar}");
+ if (isNonNullableByDefault &&
+ isMoreSpecific(hierarchy, bestTypeSoFar, candidateType)) {
+ if (mutualSubtypes == null) {
+ mutualSubtypes = {
+ bestTypeSoFar: bestSoFarIndex,
+ candidateType: candidateIndex
+ };
+ } else {
+ mutualSubtypes[candidateType] = candidateIndex;
+ }
+ } else {
+ mutualSubtypes = null;
+ }
+ bestSoFarIndex = candidateIndex;
+ bestSoFar = candidate;
+ bestTypeSoFar = candidateType;
+ } else {
+ debug?.log("Combined Member Signature: "
+ "${candidate.fullName} !<: ${bestSoFar.fullName}");
}
- break;
+ }
+ }
+ if (bestSoFar != null) {
+ debug?.log("Combined Member Signature bestSoFar: "
+ "${bestSoFar.fullName}");
+ for (int candidateIndex = 0;
+ candidateIndex < declarations.length;
+ candidateIndex++) {
+ ClassMember candidate = declarations[candidateIndex];
+ DartType candidateType = candidateTypes[candidateIndex];
+ if (!isMoreSpecific(hierarchy, bestTypeSoFar, candidateType)) {
+ debug?.log("Combined Member Signature: "
+ "${bestSoFar.fullName} !<: ${candidate.fullName}");
+
+ if (!shouldOverrideProblemBeOverlooked(classBuilder)) {
+ bestSoFar = null;
+ bestTypeSoFar = null;
+ mutualSubtypes = null;
+ }
+ break;
+ }
}
}
}
+
if (bestSoFar == null) {
String name = classBuilder.fullNameForErrors;
int length = classBuilder.isAnonymousMixinApplication ? 1 : name.length;
@@ -3058,16 +3066,16 @@
debug?.log("Combined Member Signature of ${fullNameForErrors}: "
"${bestSoFar.fullName}");
- ProcedureKind kind = ProcedureKind.Method;
- Member bestMemberSoFar = bestSoFar.getMember(hierarchy);
- if (bestSoFar.isProperty) {
- kind = isSetter ? ProcedureKind.Setter : ProcedureKind.Getter;
- } else if (bestMemberSoFar is Procedure &&
- bestMemberSoFar.kind == ProcedureKind.Operator) {
- kind = ProcedureKind.Operator;
- }
-
if (modifyKernel) {
+ ProcedureKind kind = ProcedureKind.Method;
+ Member bestMemberSoFar = bestSoFar.getMember(hierarchy);
+ if (bestSoFar.isProperty) {
+ kind = isSetter ? ProcedureKind.Setter : ProcedureKind.Getter;
+ } else if (bestMemberSoFar is Procedure &&
+ bestMemberSoFar.kind == ProcedureKind.Operator) {
+ kind = ProcedureKind.Operator;
+ }
+
debug?.log("Combined Member Signature of ${fullNameForErrors}: new "
"ForwardingNode($classBuilder, $bestSoFar, $declarations, $kind)");
Member stub = new ForwardingNode(
diff --git a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
index 5fa02e2..b1b6388 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
@@ -11,9 +11,12 @@
Expression,
Field,
FunctionNode,
+ FunctionType,
Member,
Name,
NamedExpression,
+ NamedType,
+ Nullability,
Procedure,
ProcedureKind,
ReturnStatement,
@@ -83,6 +86,203 @@
/// forwarding stubs if necessary.
Member finalize() => _computeCovarianceFixes();
+ /// Creates a getter member signature for [interfaceMember] with the given
+ /// [type].
+ Member _createGetterMemberSignature(Member interfaceMember, DartType type) {
+ Procedure referenceFrom;
+ if (classBuilder.referencesFromIndexed != null) {
+ referenceFrom = classBuilder.referencesFromIndexed
+ .lookupProcedureNotSetter(name.name);
+ }
+ return new Procedure(name, kind, new FunctionNode(null, returnType: type),
+ isAbstract: true,
+ isMemberSignature: true,
+ fileUri: enclosingClass.fileUri,
+ memberSignatureOrigin: interfaceMember,
+ reference: referenceFrom?.reference)
+ ..startFileOffset = enclosingClass.fileOffset
+ ..fileOffset = enclosingClass.fileOffset
+ ..parent = enclosingClass;
+ }
+
+ /// Creates a setter member signature for [interfaceMember] with the given
+ /// [type]. The flags of parameter is set according to [isCovariant] and
+ /// [isGenericCovariantImpl] and the [parameterName] is used, if provided.
+ Member _createSetterMemberSignature(Member interfaceMember, DartType type,
+ {bool isCovariant, bool isGenericCovariantImpl, String parameterName}) {
+ assert(isCovariant != null);
+ assert(isGenericCovariantImpl != null);
+ Procedure referenceFrom;
+ if (classBuilder.referencesFromIndexed != null) {
+ referenceFrom =
+ classBuilder.referencesFromIndexed.lookupProcedureSetter(name.name);
+ }
+ return new Procedure(
+ name,
+ kind,
+ new FunctionNode(null,
+ returnType: const VoidType(),
+ positionalParameters: [
+ new VariableDeclaration(parameterName ?? '_',
+ type: type, isCovariant: isCovariant)
+ ..isGenericCovariantImpl = isGenericCovariantImpl
+ ]),
+ isAbstract: true,
+ isMemberSignature: true,
+ fileUri: enclosingClass.fileUri,
+ memberSignatureOrigin: interfaceMember,
+ reference: referenceFrom?.reference)
+ ..startFileOffset = enclosingClass.fileOffset
+ ..fileOffset = enclosingClass.fileOffset
+ ..parent = enclosingClass;
+ }
+
+ /// Creates a legacy member signature for the field [interfaceMember] if the
+ /// type of [interfaceMember] contains non-legacy nullabilities.
+ Member _createLegacyMemberSignatureForField(Field interfaceMember) {
+ DartType type = interfaceMember.type;
+ if (interfaceMember.enclosingClass.typeParameters.isNotEmpty) {
+ Substitution substitution =
+ _substitutionFor(null, interfaceMember, enclosingClass);
+ type = substitution.substituteType(type);
+ }
+ DartType legacyType = rawLegacyErasure(hierarchy.coreTypes, type);
+ if (legacyType == null) {
+ return interfaceMember;
+ } else {
+ // We base the decision to add a member signature on whether the legacy
+ // erasure of the declared type is different from the declared type, i.e.
+ // whether the declared type contained non-legacy nullabilities.
+ //
+ // This is slightly different from checking whether the legacy erasure of
+ // the inherited type is different from the
+ if (kind == ProcedureKind.Getter) {
+ return _createGetterMemberSignature(interfaceMember, legacyType);
+ } else {
+ assert(kind == ProcedureKind.Setter);
+ return _createSetterMemberSignature(interfaceMember, legacyType,
+ isCovariant: interfaceMember.isCovariant,
+ isGenericCovariantImpl: interfaceMember.isGenericCovariantImpl);
+ }
+ }
+ }
+
+ /// Creates a legacy member signature for procedure [interfaceMember] if the
+ /// type of [interfaceMember] contains non-legacy nullabilities.
+ Member _createLegacyMemberSignatureForProcedure(Procedure interfaceMember) {
+ if (interfaceMember.kind == ProcedureKind.Getter) {
+ DartType type = interfaceMember.getterType;
+ if (interfaceMember.enclosingClass.typeParameters.isNotEmpty) {
+ Substitution substitution =
+ _substitutionFor(null, interfaceMember, enclosingClass);
+ type = substitution.substituteType(type);
+ }
+ DartType legacyType = rawLegacyErasure(hierarchy.coreTypes, type);
+ if (legacyType == null) {
+ return interfaceMember;
+ } else {
+ return _createGetterMemberSignature(interfaceMember, legacyType);
+ }
+ } else if (interfaceMember.kind == ProcedureKind.Setter) {
+ DartType type = interfaceMember.setterType;
+ if (interfaceMember.enclosingClass.typeParameters.isNotEmpty) {
+ Substitution substitution =
+ _substitutionFor(null, interfaceMember, enclosingClass);
+ type = substitution.substituteType(type);
+ }
+ DartType legacyType = rawLegacyErasure(hierarchy.coreTypes, type);
+ if (legacyType == null) {
+ return interfaceMember;
+ } else {
+ VariableDeclaration parameter =
+ interfaceMember.function.positionalParameters.first;
+ return _createSetterMemberSignature(interfaceMember, legacyType,
+ isCovariant: parameter.isCovariant,
+ isGenericCovariantImpl: parameter.isGenericCovariantImpl,
+ parameterName: parameter.name);
+ }
+ } else {
+ FunctionNode function = interfaceMember.function;
+ FunctionType type = function.computeFunctionType(Nullability.legacy);
+ if (interfaceMember.enclosingClass.typeParameters.isNotEmpty) {
+ Substitution substitution =
+ _substitutionFor(null, interfaceMember, enclosingClass);
+ type = substitution.substituteType(type);
+ }
+ FunctionType legacyType = rawLegacyErasure(hierarchy.coreTypes, type);
+ if (legacyType == null) {
+ return interfaceMember;
+ }
+ Procedure referenceFrom;
+ if (classBuilder.referencesFromIndexed != null) {
+ referenceFrom = classBuilder.referencesFromIndexed
+ .lookupProcedureNotSetter(name.name);
+ }
+ List<VariableDeclaration> positionalParameters = [];
+ for (int i = 0; i < function.positionalParameters.length; i++) {
+ VariableDeclaration parameter = function.positionalParameters[i];
+ DartType parameterType = legacyType.positionalParameters[i];
+ if (i == 0 && interfaceMember == hierarchy.coreTypes.objectEquals) {
+ // In legacy code we special case `Object.==` to infer `dynamic`
+ // instead `Object!`.
+ parameterType = const DynamicType();
+ }
+ positionalParameters.add(new VariableDeclaration(parameter.name,
+ type: parameterType, isCovariant: parameter.isRequired)
+ ..isGenericCovariantImpl = parameter.isGenericCovariantImpl);
+ }
+ List<VariableDeclaration> namedParameters = [];
+ int namedParameterCount = function.namedParameters.length;
+ if (namedParameterCount == 1) {
+ NamedType namedType = legacyType.namedParameters.first;
+ VariableDeclaration parameter = function.namedParameters.first;
+ namedParameters.add(new VariableDeclaration(parameter.name,
+ type: namedType.type, isCovariant: parameter.isCovariant)
+ ..isGenericCovariantImpl = parameter.isGenericCovariantImpl);
+ } else if (namedParameterCount > 1) {
+ Map<String, DartType> namedTypes = {};
+ for (NamedType namedType in legacyType.namedParameters) {
+ namedTypes[namedType.name] = namedType.type;
+ }
+ for (int i = 0; i < namedParameterCount; i++) {
+ VariableDeclaration parameter = function.namedParameters[i];
+ DartType parameterType = namedTypes[parameter.name];
+ namedParameters.add(new VariableDeclaration(parameter.name,
+ type: parameterType, isCovariant: parameter.isCovariant)
+ ..isGenericCovariantImpl = parameter.isGenericCovariantImpl);
+ }
+ }
+ return new Procedure(
+ name,
+ kind,
+ new FunctionNode(null,
+ typeParameters: legacyType.typeParameters,
+ returnType: legacyType.returnType,
+ positionalParameters: positionalParameters,
+ namedParameters: namedParameters,
+ requiredParameterCount: function.requiredParameterCount),
+ isAbstract: true,
+ isMemberSignature: true,
+ fileUri: enclosingClass.fileUri,
+ memberSignatureOrigin: interfaceMember,
+ reference: referenceFrom?.reference)
+ ..startFileOffset = enclosingClass.fileOffset
+ ..fileOffset = enclosingClass.fileOffset
+ ..parent = enclosingClass;
+ }
+ }
+
+ /// Creates a legacy member signature for [interfaceMember] if the type of
+ /// [interfaceMember] contains non-legacy nullabilities.
+ Member _createLegacyMemberSignature(Member interfaceMember) {
+ if (interfaceMember is Field) {
+ return _createLegacyMemberSignatureForField(interfaceMember);
+ } else {
+ assert(interfaceMember is Procedure);
+ return _createLegacyMemberSignatureForProcedure(interfaceMember);
+ }
+ }
+
/// Tag the parameters of [interfaceMember] that need type checks
///
/// Parameters can need type checks for calls coming from statically typed
@@ -95,6 +295,18 @@
/// stub is introduced as a place to put the checks.
Member _computeCovarianceFixes() {
Member interfaceMember = combinedMemberSignatureResult.getMember(hierarchy);
+ if (_candidates.length == 1) {
+ // Covariance can only come from [interfaceMember] so we never need a
+ // forwarding stub.
+ if (interfaceMember.isNonNullableByDefault &&
+ !classBuilder.library.isNonNullableByDefault) {
+ // Create a member signature with the legacy erasure type.
+ return _createLegacyMemberSignature(interfaceMember);
+ } else {
+ // Nothing to do.
+ return interfaceMember;
+ }
+ }
List<TypeParameter> interfaceMemberTypeParameters =
interfaceMember.function?.typeParameters ?? [];
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index 5882a79..0073a80 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -1016,6 +1016,7 @@
equivalence
equivalent
equivalents
+erasure
erroneous
error
errors
@@ -1809,6 +1810,7 @@
meant
measurably
measure
+measurements
mechanism
medium
meet
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 481479e..98fb84a 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -1235,8 +1235,10 @@
leaveScope(memberScope: true);
_currentlyInNonimplementation = currentlyInNonimplementationSaved;
- assert((node.forwardingStubSuperTarget != null) ||
- !(node.isForwardingStub && node.function.body != null));
+ assert(
+ (node.forwardingStubSuperTarget != null) ||
+ !(node.isForwardingStub && node.function.body != null),
+ "Invalid forwarding stub $node.");
}
@override
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index ae81ef8..c121a26 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -591,11 +591,11 @@
outputs =
[ "$root_out_dir/dart-sdk/bin/third_party/wasmer/{{source_file_part}}" ]
if (is_win) {
- sources = [ "$target_out_dir/../../wasmer_wrapper.dll" ]
+ sources = [ "$root_out_dir/wasmer_wrapper.dll" ]
} else if (is_mac) {
- sources = [ "$target_out_dir/../../libwasmer_wrapper.dylib" ]
+ sources = [ "$root_out_dir/libwasmer_wrapper.dylib" ]
} else {
- sources = [ "$target_out_dir/../../libwasmer_wrapper.so" ]
+ sources = [ "$root_out_dir/libwasmer_wrapper.so" ]
}
}
diff --git a/tools/VERSION b/tools/VERSION
index 255ff78..14a7a99 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 10
PATCH 0
-PRERELEASE 128
+PRERELEASE 129
PRERELEASE_PATCH 0
\ No newline at end of file