Version 2.10.0-132.0.dev
Merge commit '7b0aeb2ac86e4b167a507ce5982c00e23c4fbbe0' into 'dev'
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index a10f7eb..1254bc7 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -7,6 +7,8 @@
import 'dart:core';
import 'package:analysis_server/src/plugin/notification_manager.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_parser.dart';
+import 'package:analyzer/error/listener.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
@@ -328,6 +330,9 @@
/// Class that maintains a mapping from included/excluded paths to a set of
/// folders that should correspond to analysis contexts.
class ContextManagerImpl implements ContextManager {
+ /// The name of the data file used to specify data-driven fixes.
+ static const String dataFileName = 'fix_data.yaml';
+
/// The name of the `doc` directory.
static const String DOC_DIR_NAME = 'doc';
@@ -738,6 +743,30 @@
}
/// Use the given analysis [driver] to analyze the content of the
+ /// data file at the given [path].
+ void _analyzeDataFile(AnalysisDriver driver, String path) {
+ List<protocol.AnalysisError> convertedErrors;
+ try {
+ var content = _readFile(path);
+ var errorListener = RecordingErrorListener();
+ var errorReporter = ErrorReporter(
+ errorListener, resourceProvider.getFile(path).createSource());
+ var parser = TransformSetParser(errorReporter);
+ parser.parse(content);
+ var converter = AnalyzerConverter();
+ convertedErrors = converter.convertAnalysisErrors(errorListener.errors,
+ lineInfo: _computeLineInfo(content), options: driver.analysisOptions);
+ } catch (exception) {
+ // If the file cannot be analyzed, fall through to clear any previous
+ // errors.
+ }
+ callbacks.notificationManager.recordAnalysisErrors(
+ NotificationManager.serverId,
+ path,
+ convertedErrors ?? const <protocol.AnalysisError>[]);
+ }
+
+ /// Use the given analysis [driver] to analyze the content of the
/// AndroidManifest file at the given [path].
void _analyzeManifestFile(AnalysisDriver driver, String path) {
List<protocol.AnalysisError> convertedErrors;
@@ -802,6 +831,19 @@
}
}
+ void _checkForDataFileUpdate(String path, ContextInfo info) {
+ if (_isDataFile(path)) {
+ var driver = info.analysisDriver;
+ if (driver == null) {
+ // I suspect that this happens as a result of a race condition: server
+ // has determined that the file (at [path]) is in a context, but hasn't
+ // yet created a driver for that context.
+ return;
+ }
+ _analyzeDataFile(driver, path);
+ }
+ }
+
void _checkForManifestUpdate(String path, ContextInfo info) {
if (_isManifest(path)) {
var driver = info.analysisDriver;
@@ -949,6 +991,11 @@
if (optionsFile != null) {
_analyzeAnalysisOptionsFile(info.analysisDriver, optionsFile.path);
}
+ var dataFile =
+ folder.getChildAssumingFolder('lib').getChildAssumingFile(dataFileName);
+ if (dataFile.exists) {
+ _analyzeDataFile(info.analysisDriver, dataFile.path);
+ }
var pubspecFile = folder.getChildAssumingFile(PUBSPEC_NAME);
if (pubspecFile.exists) {
_analyzePubspecFile(info.analysisDriver, pubspecFile.path);
@@ -1279,6 +1326,7 @@
}
_checkForPackagespecUpdate(path, info);
_checkForAnalysisOptionsUpdate(path, info);
+ _checkForDataFileUpdate(path, info);
_checkForPubspecUpdate(path, info);
_checkForManifestUpdate(path, info);
}
@@ -1308,6 +1356,10 @@
return false;
}
+ /// Return `true` if the [path] appears to be the name of the data file used
+ /// to specify data-driven fixes.
+ bool _isDataFile(String path) => pathContext.basename(path) == dataFileName;
+
/// Returns `true` if the given [path] is excluded by [excludedPaths].
bool _isExcluded(String path) => _isExcludedBy(excludedPaths, path);
diff --git a/pkg/analysis_server/test/analysis/notification_errors_test.dart b/pkg/analysis_server/test/analysis/notification_errors_test.dart
index b07322c..540323d 100644
--- a/pkg/analysis_server/test/analysis/notification_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_errors_test.dart
@@ -164,6 +164,29 @@
expect(errors, isNull);
}
+ Future<void> test_dataFile() async {
+ var filePath = join(projectPath, 'lib', 'fix_data.yaml');
+ var dataFile = newFile(filePath, content: '''
+version: 1
+transforms:
+''').path;
+
+ var request =
+ AnalysisSetAnalysisRootsParams([projectPath], []).toRequest('0');
+ handleSuccessfulRequest(request);
+ await waitForTasksFinished();
+ await pumpEventQueue();
+ //
+ // Verify the error result.
+ //
+ var errors = filesErrors[dataFile];
+ expect(errors, hasLength(1));
+ var error = errors[0];
+ expect(error.location.file, filePath);
+ expect(error.severity, AnalysisErrorSeverity.ERROR);
+ expect(error.type, AnalysisErrorType.COMPILE_TIME_ERROR);
+ }
+
Future<void> test_dotFolder_priority() async {
// Files inside dotFolders should not generate error notifications even
// if they are added to priority (priority affects only priority, not what
diff --git a/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart b/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
index 21cdd9c..36658b3 100644
--- a/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
@@ -139,10 +139,19 @@
// If `Q` is a legacy type `Q0*` then the match holds under constraint
// set `C`:
- // Only if `P` is a subtype match for `Q?` under constraint set `C`.
if (Q_nullability == NullabilitySuffix.star) {
- var Qq = (Q as TypeImpl).withNullability(NullabilitySuffix.question);
- return trySubtypeMatch(P, Qq, leftSchema);
+ if (identical(P, DynamicTypeImpl.instance) ||
+ identical(P, VoidTypeImpl.instance)) {
+ // If `P` is `dynamic` or `void` and `P` is a subtype match
+ // for `Q0` under constraint set `C`.
+ var Q0 = (Q as TypeImpl).withNullability(NullabilitySuffix.none);
+ return trySubtypeMatch(P, Q0, leftSchema);
+ } else {
+ // Or if `P` is not `dynamic` or `void` and `P` is a subtype match
+ // for `Q0?` under constraint set `C`.
+ var Qq = (Q as TypeImpl).withNullability(NullabilitySuffix.question);
+ return trySubtypeMatch(P, Qq, leftSchema);
+ }
}
// If `Q` is `FutureOr<Q0>` the match holds under constraint set `C`:
@@ -201,6 +210,16 @@
_constraints.length = rewind;
}
+ // Or if `P` is `dynamic` or `void` and `Object` is a subtype match
+ // for `Q0` under constraint set `C`.
+ if (identical(P, DynamicTypeImpl.instance) ||
+ identical(P, VoidTypeImpl.instance)) {
+ if (trySubtypeMatch(_typeSystem.objectNone, Q0, leftSchema)) {
+ return true;
+ }
+ _constraints.length = rewind;
+ }
+
// Or if `P` is a subtype match for `Q0` under non-empty
// constraint set `C`.
var P_matches_Q0 = trySubtypeMatch(P, Q0, leftSchema);
diff --git a/pkg/analyzer/test/src/dart/element/type_constraint_gatherer_test.dart b/pkg/analyzer/test/src/dart/element/type_constraint_gatherer_test.dart
index 87109c8b..63715f5 100644
--- a/pkg/analyzer/test/src/dart/element/type_constraint_gatherer_test.dart
+++ b/pkg/analyzer/test/src/dart/element/type_constraint_gatherer_test.dart
@@ -841,6 +841,29 @@
_checkMatch([T], numStar, T_star, true, ['num <: T <: _']);
}
+ /// If `Q` is a legacy type `Q0*` then the match holds under constraint
+ /// set `C`:
+ /// If `P` is `dynamic` or `void` and `P` is a subtype match for `Q0`
+ /// under constraint set `C`.
+ test_left_top_right_legacy() {
+ var U = typeParameter('U', bound: objectNone);
+ var U_star = typeParameterTypeStar(U);
+
+ _checkMatch([U], dynamicNone, U_star, false, ['dynamic <: U <: _']);
+ _checkMatch([U], voidNone, U_star, false, ['void <: U <: _']);
+ }
+
+ /// If `Q` is `Q0?` the match holds under constraint set `C`:
+ /// Or if `P` is `dynamic` or `void` and `Object` is a subtype match
+ /// for `Q0` under constraint set `C`.
+ test_left_top_right_nullable() {
+ var U = typeParameter('U', bound: objectNone);
+ var U_question = typeParameterTypeQuestion(U);
+
+ _checkMatch([U], dynamicNone, U_question, false, ['Object <: U <: _']);
+ _checkMatch([U], voidNone, U_question, false, ['Object <: U <: _']);
+ }
+
/// If `P` is a type variable `X` in `L`, then the match holds:
/// Under constraint `_ <: X <: Q`.
test_left_typeParameter() {
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index 80975a0..0f36155 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -2600,4 +2600,34 @@
assertType(findNode.cascade('A()'), 'A');
}
+
+ test_typeArgumentTypes_generic_inferred_leftTop_dynamic() async {
+ await assertNoErrorsInCode('''
+void foo<T extends Object>(T? value) {}
+
+void f(dynamic o) {
+ foo(o);
+}
+''');
+
+ assertTypeArgumentTypes(
+ findNode.methodInvocation('foo(o)'),
+ ['Object'],
+ );
+ }
+
+ test_typeArgumentTypes_generic_inferred_leftTop_void() async {
+ await assertNoErrorsInCode('''
+void foo<T extends Object>(List<T?> value) {}
+
+void f(List<void> o) {
+ foo(o);
+}
+''');
+
+ assertTypeArgumentTypes(
+ findNode.methodInvocation('foo(o)'),
+ ['Object'],
+ );
+ }
}
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index a0395e5..d76446b 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -42,6 +42,11 @@
// Experimentally rely on JavaScript ToBoolean conversions.
static const String experimentToBoolean = '--experiment-code-3';
+ // Experiment to make methods that are inferred as unreachable throw an
+ // exception rather than generate suspect code.
+ static const String experimentUnreachableMethodsThrow =
+ '--experiment-unreachable-throw';
+
// Add instrumentation to log every method call.
static const String experimentCallInstrumentation =
'--experiment-call-instrumentation';
diff --git a/pkg/compiler/lib/src/common/names.dart b/pkg/compiler/lib/src/common/names.dart
index 6d9b83a..3cad4cb 100644
--- a/pkg/compiler/lib/src/common/names.dart
+++ b/pkg/compiler/lib/src/common/names.dart
@@ -61,6 +61,9 @@
/// The name of the 'DART_CLOSURE_TO_JS' foreign function.
static const String DART_CLOSURE_TO_JS = 'DART_CLOSURE_TO_JS';
+
+ /// The name of the 'RAW_DART_FUNCTION_REF' foreign function.
+ static const String RAW_DART_FUNCTION_REF = 'RAW_DART_FUNCTION_REF';
}
/// [Name]s commonly used.
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index c1bfac7..2922b61 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -516,6 +516,7 @@
new OptionHandler(Flags.experimentLocalNames, ignoreOption),
new OptionHandler(Flags.experimentStartupFunctions, passThrough),
new OptionHandler(Flags.experimentToBoolean, passThrough),
+ new OptionHandler(Flags.experimentUnreachableMethodsThrow, passThrough),
new OptionHandler(Flags.experimentCallInstrumentation, passThrough),
new OptionHandler(Flags.experimentNewRti, ignoreOption),
diff --git a/pkg/compiler/lib/src/inferrer/closure_tracer.dart b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
index 0a01c9b..809b850 100644
--- a/pkg/compiler/lib/src/inferrer/closure_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
@@ -84,6 +84,8 @@
String name = called.name;
if (name == Identifiers.JS || name == Identifiers.DART_CLOSURE_TO_JS) {
bailout('Used in JS ${info.debugName}');
+ } else if (name == Identifiers.RAW_DART_FUNCTION_REF) {
+ bailout('Escaped raw function reference');
}
}
if (called.isGetter &&
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 1d6bad2..110e36e 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -365,6 +365,10 @@
/// Experimental reliance on JavaScript ToBoolean conversions.
bool experimentToBoolean = false;
+ // Experiment to make methods that are inferred as unreachable throw an
+ // exception rather than generate suspect code.
+ bool experimentUnreachableMethodsThrow = false;
+
/// Experimental instrumentation to investigate code bloat.
///
/// If [true], the compiler will emit code that logs whenever a method is
@@ -487,6 +491,8 @@
..experimentStartupFunctions =
_hasOption(options, Flags.experimentStartupFunctions)
..experimentToBoolean = _hasOption(options, Flags.experimentToBoolean)
+ ..experimentUnreachableMethodsThrow =
+ _hasOption(options, Flags.experimentUnreachableMethodsThrow)
..experimentCallInstrumentation =
_hasOption(options, Flags.experimentCallInstrumentation)
..generateSourceMap = !_hasOption(options, Flags.noSourceMaps)
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index dfc216c..2c6cf53 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -1239,9 +1239,11 @@
parameterStructure: function.parameterStructure,
checks: _checksForFunction(function));
- if (const bool.fromEnvironment('unreachable-throw')) {
- var emptyParameters = parameters.values.where((p) =>
- _abstractValueDomain.isEmpty(p.instructionType).isDefinitelyTrue);
+ if (options.experimentUnreachableMethodsThrow) {
+ var emptyParameters = parameters.values.where((parameter) =>
+ _abstractValueDomain
+ .isEmpty(parameter.instructionType)
+ .isDefinitelyTrue);
if (emptyParameters.length > 0) {
_addComment('${emptyParameters} inferred as [empty]');
add(new HInvokeStatic(
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 b7a9d24..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
@@ -2965,84 +2965,76 @@
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;
- 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) {
+ 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;
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;
- bestSoFar = candidate;
- bestTypeSoFar = candidateType;
- } 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;
- }
- break;
- }
+ 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;
+ }
+ break;
+ }
+ }
+ }
if (bestSoFar == null) {
String name = classBuilder.fullNameForErrors;
int length = classBuilder.isAnonymousMixinApplication ? 1 : name.length;
@@ -3066,16 +3058,16 @@
debug?.log("Combined Member Signature of ${fullNameForErrors}: "
"${bestSoFar.fullName}");
- 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;
- }
+ 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) {
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 b1b6388..5fa02e2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
@@ -11,12 +11,9 @@
Expression,
Field,
FunctionNode,
- FunctionType,
Member,
Name,
NamedExpression,
- NamedType,
- Nullability,
Procedure,
ProcedureKind,
ReturnStatement,
@@ -86,203 +83,6 @@
/// 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
@@ -295,18 +95,6 @@
/// 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 0ca4f6d..a35454f 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -1016,7 +1016,6 @@
equivalence
equivalent
equivalents
-erasure
erroneous
error
errors
@@ -1810,7 +1809,6 @@
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 98fb84a..481479e 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -1235,10 +1235,8 @@
leaveScope(memberScope: true);
_currentlyInNonimplementation = currentlyInNonimplementationSaved;
- assert(
- (node.forwardingStubSuperTarget != null) ||
- !(node.isForwardingStub && node.function.body != null),
- "Invalid forwarding stub $node.");
+ assert((node.forwardingStubSuperTarget != null) ||
+ !(node.isForwardingStub && node.function.body != null));
}
@override
diff --git a/sdk/lib/_internal/js_runtime/lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
index 4faeb51..9c09d3d 100644
--- a/sdk/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
@@ -228,6 +228,7 @@
/// Creates a Completer for an `async` function.
///
/// Used as part of the runtime support for the async/await transformation.
+@pragma('dart2js:assumeDynamic') // Global type inference can't see call site.
Completer<T> _makeAsyncAwaitCompleter<T>() {
return new _AsyncAwaitCompleter<T>();
}
@@ -524,6 +525,7 @@
/// Creates a stream controller for an `async*` function.
///
/// Used as part of the runtime support for the async/await transformation.
+@pragma('dart2js:assumeDynamic') // Global type inference can't see call site.
_makeAsyncStarStreamController<T>(_WrappedAsyncBody body) {
return new _AsyncStarStreamController<T>(body);
}
@@ -681,6 +683,7 @@
/// Creates an Iterable for a `sync*` function.
///
/// Used as part of the runtime support for the async/await transformation.
+@pragma('dart2js:assumeDynamic') // Global type inference can't see call site.
_SyncStarIterable<T> _makeSyncStarIterable<T>(body) {
return new _SyncStarIterable<T>(body);
}
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index b1a7f44..ea0239f 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -2415,22 +2415,28 @@
"${Primitives.objectToHumanReadableString(receiver)}";
}
+ @pragma('dart2js:parameter:trust')
static evalRecipe(BoundClosure closure, String recipe) {
return newRti.evalInInstance(closure._self, recipe);
}
+ @pragma('dart2js:parameter:trust')
static evalRecipeIntercepted(BoundClosure closure, String recipe) {
return newRti.evalInInstance(closure._receiver, recipe);
}
@pragma('dart2js:noInline')
+ @pragma('dart2js:parameter:trust')
static selfOf(BoundClosure closure) => closure._self;
+ @pragma('dart2js:parameter:trust')
static targetOf(BoundClosure closure) => closure._target;
@pragma('dart2js:noInline')
+ @pragma('dart2js:parameter:trust')
static receiverOf(BoundClosure closure) => closure._receiver;
+ @pragma('dart2js:parameter:trust')
static nameOf(BoundClosure closure) => closure._name;
static String? selfFieldNameCache;
diff --git a/tests/language/inference/dynamic_nullable_test.dart b/tests/language/inference/dynamic_nullable_test.dart
index 6bcb121..46b6591 100644
--- a/tests/language/inference/dynamic_nullable_test.dart
+++ b/tests/language/inference/dynamic_nullable_test.dart
@@ -55,7 +55,7 @@
var c = C.list(o);
var f = bar(o);
- var l = o.whereNotNull;
+ var l = o.whereNotNull();
c.expectStaticType<Exactly<C<Object>>>();
Expect.type<C<Object>>(c); // Run-time type is subtype of C<Object>.
diff --git a/tools/VERSION b/tools/VERSION
index 605169e..d005fb6 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 10
PATCH 0
-PRERELEASE 131
+PRERELEASE 132
PRERELEASE_PATCH 0
\ No newline at end of file