Version 2.10.0-124.0.dev
Merge commit 'a08054586cf7ccf6e2be33592ff7232a052f94af' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
index adab85b..df90a5f 100644
--- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
@@ -1218,12 +1218,13 @@
/// are assumed to be unpromoted and already assigned, so joining another
/// state with this one will have no effect on it.
FlowModel(bool reachable)
- : this._(
+ : this.withInfo(
reachable,
const {},
);
- FlowModel._(this.reachable, this.variableInfo)
+ @visibleForTesting
+ FlowModel.withInfo(this.reachable, this.variableInfo)
: _freshVariableInfo = new VariableModel.fresh() {
assert(() {
for (VariableModel<Variable, Type> value in variableInfo.values) {
@@ -1285,7 +1286,7 @@
FlowModel<Variable, Type> result = newVariableInfo == null
? this
- : new FlowModel<Variable, Type>._(reachable, newVariableInfo);
+ : new FlowModel<Variable, Type>.withInfo(reachable, newVariableInfo);
return result;
}
@@ -1308,6 +1309,41 @@
VariableModel<Variable, Type> infoFor(Variable variable) =>
variableInfo[variable] ?? _freshVariableInfo;
+ /// Builds a [FlowModel] based on `this`, but extending the `tested` set to
+ /// include types from [other]. This is used at the bottom of certain kinds
+ /// of loops, to ensure that types tested within the body of the loop are
+ /// consistently treated as "of interest" in code that follows the loop,
+ /// regardless of the type of loop.
+ @visibleForTesting
+ FlowModel<Variable, Type> inheritTested(
+ TypeOperations<Variable, Type> typeOperations,
+ FlowModel<Variable, Type> other) {
+ Map<Variable, VariableModel<Variable, Type>> newVariableInfo =
+ <Variable, VariableModel<Variable, Type>>{};
+ Map<Variable, VariableModel<Variable, Type>> otherVariableInfo =
+ other.variableInfo;
+ bool changed = false;
+ for (MapEntry<Variable, VariableModel<Variable, Type>> entry
+ in variableInfo.entries) {
+ Variable variable = entry.key;
+ VariableModel<Variable, Type> variableModel = entry.value;
+ VariableModel<Variable, Type> otherVariableModel =
+ otherVariableInfo[variable];
+ VariableModel<Variable, Type> newVariableModel =
+ otherVariableModel == null
+ ? variableModel
+ : VariableModel.inheritTested(
+ typeOperations, variableModel, otherVariableModel.tested);
+ newVariableInfo[variable] = newVariableModel;
+ if (!identical(newVariableModel, variableModel)) changed = true;
+ }
+ if (changed) {
+ return new FlowModel<Variable, Type>.withInfo(reachable, newVariableInfo);
+ } else {
+ return this;
+ }
+ }
+
/// Updates the state to indicate that variables that are not definitely
/// unassigned in the [other], are also not definitely unassigned in the
/// result.
@@ -1335,7 +1371,7 @@
if (newVariableInfo == null) return this;
- return new FlowModel<Variable, Type>._(reachable, newVariableInfo);
+ return new FlowModel<Variable, Type>.withInfo(reachable, newVariableInfo);
}
/// Updates the state to reflect a control path that is known to have
@@ -1409,7 +1445,7 @@
FlowModel<Variable, Type> setReachable(bool reachable) {
if (this.reachable == reachable) return this;
- return new FlowModel<Variable, Type>._(reachable, variableInfo);
+ return new FlowModel<Variable, Type>.withInfo(reachable, variableInfo);
}
@override
@@ -1586,7 +1622,7 @@
Map<Variable, VariableModel<Variable, Type>> newVariableInfo =
new Map<Variable, VariableModel<Variable, Type>>.from(variableInfo);
newVariableInfo[variable] = model;
- return new FlowModel<Variable, Type>._(reachable, newVariableInfo);
+ return new FlowModel<Variable, Type>.withInfo(reachable, newVariableInfo);
}
/// Forms a new state to reflect a control flow path that might have come from
@@ -1675,7 +1711,8 @@
return second;
}
- return new FlowModel<Variable, Type>._(newReachable, newVariableInfo);
+ return new FlowModel<Variable, Type>.withInfo(
+ newReachable, newVariableInfo);
}
/// Determines whether the given "variableInfo" maps are equivalent.
@@ -2139,6 +2176,22 @@
return promotedTypes;
}
+ /// Builds a [VariableModel] based on [model], but extending the [tested] set
+ /// to include types from [tested]. This is used at the bottom of certain
+ /// kinds of loops, to ensure that types tested within the body of the loop
+ /// are consistently treated as "of interest" in code that follows the loop,
+ /// regardless of the type of loop.
+ @visibleForTesting
+ static VariableModel<Variable, Type> inheritTested<Variable, Type>(
+ TypeOperations<Variable, Type> typeOperations,
+ VariableModel<Variable, Type> model,
+ List<Type> tested) {
+ List<Type> newTested = joinTested(tested, model.tested, typeOperations);
+ if (identical(newTested, model.tested)) return model;
+ return new VariableModel<Variable, Type>(model.promotedTypes, newTested,
+ model.assigned, model.unassigned, model.writeCaptured);
+ }
+
/// Joins two variable models. See [FlowModel.join] for details.
static VariableModel<Variable, Type> join<Variable, Type>(
TypeOperations<Variable, Type> typeOperations,
@@ -2583,7 +2636,8 @@
FlowModel<Variable, Type> breakState = context._breakModel;
FlowModel<Variable, Type> falseCondition = context._conditionInfo.ifFalse;
- _current = _join(falseCondition, breakState);
+ _current = _join(falseCondition, breakState)
+ .inheritTested(typeOperations, _current);
}
@override
@@ -2996,7 +3050,8 @@
void whileStatement_end() {
_WhileContext<Variable, Type> context =
_stack.removeLast() as _WhileContext<Variable, Type>;
- _current = _join(context._conditionInfo.ifFalse, context._breakModel);
+ _current = _join(context._conditionInfo.ifFalse, context._breakModel)
+ .inheritTested(typeOperations, _current);
}
@override
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
index 7aee101..92c7bae 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
@@ -3408,6 +3408,47 @@
});
});
});
+ group('inheritTested', () {
+ var x = _Var('x', _Type('Object?'));
+ var intType = _Type('int');
+ var stringType = _Type('String');
+ const emptyMap = const <_Var, VariableModel<_Var, _Type>>{};
+
+ VariableModel<_Var, _Type> model(List<_Type> typesOfInterest) =>
+ VariableModel<_Var, _Type>(null, typesOfInterest, true, false, false);
+
+ test('inherits types of interest from other', () {
+ var h = _Harness();
+ var m1 = FlowModel.withInfo(true, {
+ x: model([intType])
+ });
+ var m2 = FlowModel.withInfo(true, {
+ x: model([stringType])
+ });
+ expect(m1.inheritTested(h, m2).variableInfo[x].tested,
+ _matchOfInterestSet(['int', 'String']));
+ });
+
+ test('handles variable missing from other', () {
+ var h = _Harness();
+ var m1 = FlowModel.withInfo(true, {
+ x: model([intType])
+ });
+ var m2 = FlowModel.withInfo(true, emptyMap);
+ expect(m1.inheritTested(h, m2), same(m1));
+ });
+
+ test('returns identical model when no changes', () {
+ var h = _Harness();
+ var m1 = FlowModel.withInfo(true, {
+ x: model([intType])
+ });
+ var m2 = FlowModel.withInfo(true, {
+ x: model([intType])
+ });
+ expect(m1.inheritTested(h, m2), same(m1));
+ });
+ });
}
/// Returns the appropriate matcher for expecting an assertion error to be
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/loop_type_of_interest.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/loop_type_of_interest.dart
new file mode 100644
index 0000000..81cb1b1
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/loop_type_of_interest.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test verifies that a type comparison happening in the body of a loop
+// causes the type to be of interest after the loop, regardless of the type of
+// loop.
+
+doLoop(Object o, bool f()) {
+ do {
+ if (o is int) print('');
+ } while (f());
+ o = 1;
+ /*int*/ o;
+}
+
+forEachLoop(Object o, List values) {
+ for (var _ in values) {
+ if (o is int) print('');
+ }
+ o = 1;
+ /*int*/ o;
+}
+
+forLoop(Object o, int count) {
+ for (int i = 0; i < count; i++) {
+ if (o is int) print('');
+ }
+ o = 1;
+ /*int*/ o;
+}
+
+whileloop(Object o, bool f()) {
+ while (f()) {
+ if (o is int) print('');
+ }
+ o = 1;
+ /*int*/ o;
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
index a533fdc..8063ce5 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
@@ -173,13 +173,7 @@
if (parameter != null) {
var type = parameter.type;
if (type is InterfaceType) {
- if (type.isDartCoreBool) {
- return DefaultArgument('false');
- } else if (type.isDartCoreDouble) {
- return DefaultArgument('0.0');
- } else if (type.isDartCoreInt) {
- return DefaultArgument('0');
- } else if (type.isDartCoreList) {
+ if (type.isDartCoreList) {
return DefaultArgument('[]', cursorPosition: 1);
} else if (type.isDartCoreMap) {
return DefaultArgument('{}', cursorPosition: 1);
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index 08fc72b..ac0d56c 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -9,6 +9,7 @@
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/dart/add_await.dart';
import 'package:analysis_server/src/services/correction/dart/add_const.dart';
+import 'package:analysis_server/src/services/correction/dart/add_diagnostic_property_reference.dart';
import 'package:analysis_server/src/services/correction/dart/add_override.dart';
import 'package:analysis_server/src/services/correction/dart/convert_add_all_to_spread.dart';
import 'package:analysis_server/src/services/correction/dart/convert_conditional_expression_to_if_element.dart';
@@ -79,6 +80,8 @@
LintNames.await_only_futures: RemoveAwait.newInstance,
LintNames.curly_braces_in_flow_control_structures:
UseCurlyBraces.newInstance,
+ LintNames.diagnostic_describe_all_properties:
+ AddDiagnosticPropertyReference.newInstance,
LintNames.empty_catches: RemoveEmptyCatch.newInstance,
LintNames.empty_constructor_bodies: RemoveEmptyConstructorBody.newInstance,
LintNames.empty_statements: RemoveEmptyStatement.newInstance,
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart
index cbd9a2d..ee07bf4 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart
@@ -8,7 +8,6 @@
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
@@ -80,14 +79,6 @@
}
}
var defaultValue = getDefaultStringParameterValue(missingParameter);
- if (defaultValue == null &&
- libraryElement.isNonNullableByDefault &&
- missingParameter.type.nullabilitySuffix == NullabilitySuffix.none) {
- // In a library opted in to Null Safety we don't want to propose an
- // argument value of `null` for a parameter whose type doesn't allow
- // `null`.
- return;
- }
await builder.addDartFileEdit(file, (builder) {
builder.addInsertion(offset, (builder) {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_descriptor.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_descriptor.dart
index c34212d..a0db646 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_descriptor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_descriptor.dart
@@ -10,7 +10,7 @@
final List<String> libraryUris;
/// The kind of element that was changed.
- final String kind;
+ final String _kind;
/// The components that uniquely identify the element within its library.
final List<String> components;
@@ -21,8 +21,12 @@
/// element is represented by the key used in the data file.
ElementDescriptor(
{@required this.libraryUris,
- @required this.kind,
- @required this.components});
+ @required String kind,
+ @required this.components})
+ : _kind = kind;
+
+ /// Return `true` if the described element is a constructor.
+ bool get isConstructor => _kind == 'constructor';
/// Return `true` if this descriptor matches an element with the given [name]
/// in a library that imports the [importedUris].
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename.dart
index 326122e..13b32f3 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename.dart
@@ -21,7 +21,7 @@
@override
void apply(DartFileEditBuilder builder, DataDrivenFix fix,
SimpleIdentifier nameNode) {
- if (fix.element.kind == 'constructor') {
+ if (fix.element.isConstructor) {
var parent = nameNode.parent;
if (parent is ConstructorName) {
if (nameNode != null && newName.isEmpty) {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
index f44c739..2cdeb92 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
@@ -20,6 +20,13 @@
/**
* Parameters:
+ * 0: the missing key
+ */
+ static const TransformSetErrorCode missingKey =
+ TransformSetErrorCode('missingKey', "Missing the required key '{0}'.");
+
+ /**
+ * Parameters:
* 0: the unsupported key
*/
static const TransformSetErrorCode unsupportedKey =
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
index e07d6b4..974b9ac 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
@@ -14,8 +14,23 @@
import 'package:analysis_server/src/services/correction/fix/data_driven/value_extractor.dart';
import 'package:analysis_server/src/utilities/extensions/yaml.dart';
import 'package:analyzer/error/listener.dart';
+import 'package:meta/meta.dart';
import 'package:yaml/yaml.dart';
+/// Information used to report errors when translating a node.
+class ErrorContext {
+ /// The name of the key used to identify the node that has an error associated
+ /// with it.
+ final String key;
+
+ /// The node that should be used to compute the highlight region for the
+ /// diagnostic.
+ final YamlNode parentNode;
+
+ /// Initialize a newly created error context.
+ ErrorContext({@required this.key, @required this.parentNode});
+}
+
/// A parser used to read a transform set from a file.
class TransformSetParser {
static const String _argumentValueKey = 'argumentValue';
@@ -139,6 +154,23 @@
code, span.start.offset, span.length, arguments);
}
+ /// Report that the value represented by the [node] does not have the
+ /// [expectedType], using the [context] to get the key to use in the message.
+ Null _reportInvalidValue(
+ YamlNode node, ErrorContext context, String expectedType) {
+ _reportError(TransformSetErrorCode.invalidValue, node,
+ [context.key, expectedType, _nodeType(node)]);
+ return null;
+ }
+
+ /// Report that a required key is missing, using the [context] to locate the
+ /// node associated with the diagnostic and the key to use in the message.
+ Null _reportMissingKey(ErrorContext context) {
+ _reportError(
+ TransformSetErrorCode.missingKey, context.parentNode, [context.key]);
+ return null;
+ }
+
/// Report any keys in the [map] whose values are not in [validKeys].
void _reportUnsupportedKeys(YamlMap map, Set<String> validKeys) {
for (var keyNode in map.nodes.keys) {
@@ -158,9 +190,7 @@
/// is in the map and return it. If more than one of the keys is in the map,
/// report a diagnostic.
String _singleKey(YamlMap map, List<String> validKeys) {
- if (validKeys == null) {
- return null;
- }
+ assert(validKeys != null);
var foundKeys = <String>[];
var keyToNodeMap = <String, YamlNode>{};
for (var keyNode in map.nodes.keys) {
@@ -173,6 +203,7 @@
}
}
if (foundKeys.isEmpty) {
+ // TODO(brianwilkerson) Report the problem.
return null;
}
for (var i = 1; i < foundKeys.length; i++) {
@@ -184,18 +215,20 @@
/// Translate the [node] into a add-parameter modification.
void _translateAddParameterChange(YamlMap node) {
- _singleKey(node, [_indexKey, _nameKey]);
_reportUnsupportedKeys(node,
const {_argumentValueKey, _indexKey, _kindKey, _nameKey, _styleKey});
- var index = _translateInteger(node.valueAt(_indexKey), _indexKey);
+ var index = _translateInteger(node.valueAt(_indexKey),
+ ErrorContext(key: _indexKey, parentNode: node));
if (index == null) {
return;
}
- var name = _translateString(node.valueAt(_nameKey), _nameKey);
+ var name = _translateString(
+ node.valueAt(_nameKey), ErrorContext(key: _nameKey, parentNode: node));
if (name == null) {
return;
}
- var style = _translateString(node.valueAt(_styleKey), _styleKey);
+ var style = _translateString(node.valueAt(_styleKey),
+ ErrorContext(key: _styleKey, parentNode: node));
if (style == null) {
return;
} else if (!validStyles.contains(style)) {
@@ -205,7 +238,8 @@
var isRequired = style.startsWith('required_');
var isPositional = style.endsWith('_positional');
var argumentValue = _translateValueExtractor(
- node.valueAt(_argumentValueKey), _argumentValueKey);
+ node.valueAt(_argumentValueKey),
+ ErrorContext(key: _argumentValueKey, parentNode: node));
// TODO(brianwilkerson) We really ought to require an argument value for
// optional positional parameters too for the case where the added
// parameter is being added before the end of the list and call sites might
@@ -228,16 +262,14 @@
AddTypeParameter _translateAddTypeParameterChange(YamlMap node) {
_reportUnsupportedKeys(
node, const {_indexKey, _kindKey, _nameKey, _valueKey});
- var index = _translateInteger(node.valueAt(_indexKey), _indexKey);
- if (index == null) {
- return null;
- }
- var name = _translateString(node.valueAt(_nameKey), _nameKey);
- if (name == null) {
- return null;
- }
- var value = _translateValueExtractor(node.valueAt(_valueKey), _valueKey);
- if (value == null) {
+ var index = _translateInteger(node.valueAt(_indexKey),
+ ErrorContext(key: _indexKey, parentNode: node));
+ var name = _translateString(
+ node.valueAt(_nameKey), ErrorContext(key: _nameKey, parentNode: node));
+ var value = _translateValueExtractor(node.valueAt(_valueKey),
+ ErrorContext(key: _valueKey, parentNode: node));
+ if (index == null || name == null || value == null) {
+ // The error has already been reported.
return null;
}
return AddTypeParameter(index: index, name: name, value: value);
@@ -250,7 +282,8 @@
var indexNode = node.valueAt(_indexKey);
if (indexNode != null) {
_reportUnsupportedKeys(node, const {_indexKey, _kindKey});
- var index = _translateInteger(indexNode, _indexKey);
+ var index = _translateInteger(
+ indexNode, ErrorContext(key: _indexKey, parentNode: node));
if (index == null) {
// The error has already been reported.
return null;
@@ -260,7 +293,8 @@
var nameNode = node.valueAt(_nameKey);
if (nameNode != null) {
_reportUnsupportedKeys(node, const {_nameKey, _kindKey});
- var name = _translateString(nameNode, _nameKey);
+ var name = _translateString(
+ nameNode, ErrorContext(key: _nameKey, parentNode: node));
if (name == null) {
// The error has already been reported.
return null;
@@ -273,10 +307,12 @@
/// Translate the [node] into a change. Return the resulting change, or `null`
/// if the [node] does not represent a valid change. If the [node] is not
- /// valid, use the name of the associated [key] to report the error.
- Change _translateChange(YamlNode node, String key) {
+ /// valid, use the [context] to report the error.
+ Change _translateChange(YamlNode node, ErrorContext context) {
+ assert(node != null);
if (node is YamlMap) {
- var kind = _translateString(node.valueAt(_kindKey), _kindKey);
+ var kind = _translateString(node.valueAt(_kindKey),
+ ErrorContext(key: _kindKey, parentNode: node));
if (kind == _addTypeParameterKind) {
return _translateAddTypeParameterChange(node);
} else if (kind == _renameKind) {
@@ -290,20 +326,15 @@
}
// TODO(brianwilkerson) Report the invalid change kind.
return null;
- } else if (node == null) {
- // TODO(brianwilkerson) Report the missing YAML.
- return null;
} else {
- _reportError(TransformSetErrorCode.invalidValue, node,
- [key, 'Map', _nodeType(node)]);
- return null;
+ return _reportInvalidValue(node, context, 'Map');
}
}
/// Translate the [node] into a date. Return the resulting date, or `null`
/// if the [node] does not represent a valid date. If the [node] is not
- /// valid, use the name of the associated [key] to report the error.
- DateTime _translateDate(YamlNode node, String key) {
+ /// valid, use the [context] to report the error.
+ DateTime _translateDate(YamlNode node, ErrorContext context) {
if (node is YamlScalar) {
var value = node.value;
if (value is String) {
@@ -313,35 +344,23 @@
// Fall through to report the invalid value.
}
}
- _reportError(TransformSetErrorCode.invalidValue, node,
- [key, 'Date', _nodeType(node)]);
- return null;
+ return _reportInvalidValue(node, context, 'Date');
} else if (node == null) {
- // TODO(brianwilkerson) Report the missing YAML. For the best UX we
- // probably need to pass in the code to report.
- return null;
+ return _reportMissingKey(context);
} else {
- _reportError(TransformSetErrorCode.invalidValue, node,
- [key, 'Date', _nodeType(node)]);
- return null;
+ return _reportInvalidValue(node, context, 'Date');
}
}
/// Translate the [node] into an element descriptor. Return the resulting
/// descriptor, or `null` if the [node] does not represent a valid element
- /// descriptor. If the [node] is not valid, use the name of the associated
- /// [key] to report the error.
- ElementDescriptor _translateElement(YamlNode node, String key) {
+ /// descriptor. If the [node] is not valid, use the [context] to report the
+ /// error.
+ ElementDescriptor _translateElement(YamlNode node, ErrorContext context) {
if (node is YamlMap) {
- var uris =
- _translateList(node.valueAt(_urisKey), _urisKey, _translateString);
- if (uris == null) {
- // The error has already been reported.
- // TODO(brianwilkerson) Returning here prevents other errors from being
- // reported.
- return null;
- }
- var elementKey = _singleKey(node, [
+ var uris = _translateList(node.valueAt(_urisKey),
+ ErrorContext(key: _urisKey, parentNode: node), _translateString);
+ var elementKey = _singleKey(node, const [
_classKey,
_constantKey,
_constructorKey,
@@ -355,96 +374,107 @@
_setterKey,
_typedefKey
]);
- var elementName = _translateString(node.valueAt(elementKey), elementKey);
+ if (elementKey == null) {
+ // The error has already been reported.
+ return null;
+ }
+ var elementName = _translateString(node.valueAt(elementKey),
+ ErrorContext(key: elementKey, parentNode: node));
if (elementName == null) {
// The error has already been reported.
return null;
}
var components = [elementName];
- var containerKey = _singleKey(node, _containerKeyMap[elementKey]);
- var containerName =
- _translateString(node.valueAt(containerKey), containerKey);
- if (containerName == null) {
- if ([_constructorKey, _constantKey, _methodKey, _fieldKey]
- .contains(elementKey)) {
- // TODO(brianwilkerson) Report that no container was found.
- return null;
+ if (_containerKeyMap.containsKey(elementKey)) {
+ var containerKey = _singleKey(node, _containerKeyMap[elementKey]);
+ var containerName = _translateString(node.valueAt(containerKey),
+ ErrorContext(key: containerKey, parentNode: node),
+ required: false);
+ if (containerName == null) {
+ if ([_constructorKey, _constantKey, _methodKey, _fieldKey]
+ .contains(elementKey)) {
+ // TODO(brianwilkerson) Report that no container was found.
+ return null;
+ }
+ } else {
+ components.insert(0, containerName);
}
- } else {
- components.insert(0, containerName);
+ }
+ if (uris == null) {
+ // The error has already been reported.
+ return null;
}
return ElementDescriptor(
libraryUris: uris, kind: elementKey, components: components);
} else if (node == null) {
- // TODO(brianwilkerson) Report the missing YAML.
- return null;
+ return _reportMissingKey(context);
} else {
- _reportError(TransformSetErrorCode.invalidValue, node,
- [key, 'Map', _nodeType(node)]);
- return null;
+ return _reportInvalidValue(node, context, 'Map');
}
}
/// Translate the [node] into an integer. Return the resulting integer, or
/// `null` if the [node] does not represent a valid integer. If the [node] is
- /// not valid, use the name of the associated [key] to report the error.
- int _translateInteger(YamlNode node, String key) {
+ /// not valid, use the [context] to report the error.
+ int _translateInteger(YamlNode node, ErrorContext context) {
if (node is YamlScalar) {
var value = node.value;
if (value is int) {
return value;
}
- _reportError(TransformSetErrorCode.invalidValue, node,
- [key, 'int', _nodeType(node)]);
- return null;
+ return _reportInvalidValue(node, context, 'int');
} else if (node == null) {
- // TODO(brianwilkerson) Report the missing YAML. For the best UX we
- // probably need to pass in the code to report.
- return null;
+ return _reportMissingKey(context);
} else {
- _reportError(TransformSetErrorCode.invalidValue, node,
- [key, 'int', _nodeType(node)]);
- return null;
+ return _reportInvalidValue(node, context, 'int');
}
}
/// Translate the [node] into a list of objects using the [elementTranslator].
/// Return the resulting list, or `null` if the [node] does not represent a
/// valid list. If any of the elements of the list can't be translated, they
- /// will be omitted from the list, the name of the associated [key] will be
- /// used to report the error, and the valid elements will be returned.
- List<R> _translateList<R>(YamlNode node, String key,
- R Function(YamlNode, String) elementTranslator) {
+ /// will be omitted from the list, the [context] will be used to report the
+ /// error, and the valid elements will be returned.
+ List<R> _translateList<R>(YamlNode node, ErrorContext context,
+ R Function(YamlNode, ErrorContext) elementTranslator) {
if (node is YamlList) {
var translatedList = <R>[];
for (var element in node.nodes) {
- var result = elementTranslator(element, key);
+ var result = elementTranslator(element, context);
if (result != null) {
translatedList.add(result);
}
}
return translatedList;
} else if (node == null) {
- // TODO(brianwilkerson) Report the missing YAML.
- return null;
+ return _reportMissingKey(context);
} else {
- _reportError(TransformSetErrorCode.invalidValue, node,
- [key, 'List', _nodeType(node)]);
- return null;
+ return _reportInvalidValue(node, context, 'List');
}
}
/// Translate the [node] into a remove-parameter modification.
void _translateRemoveParameterChange(YamlMap node) {
- _singleKey(node, [_indexKey, _nameKey]);
_reportUnsupportedKeys(node, const {_indexKey, _kindKey, _nameKey});
ParameterReference reference;
- var index = _translateInteger(node.valueAt(_indexKey), _indexKey);
- if (index != null) {
+ var parameterSpecKey = _singleKey(node, const [_nameKey, _indexKey]);
+ if (parameterSpecKey == null) {
+ // The error has already been reported.
+ return null;
+ }
+ if (parameterSpecKey == _indexKey) {
+ var index = _translateInteger(node.valueAt(_indexKey),
+ ErrorContext(key: _indexKey, parentNode: node));
+ if (parameterSpecKey == null) {
+ // The error has already been reported.
+ return null;
+ }
reference = PositionalParameterReference(index);
} else {
- var name = _translateString(node.valueAt(_nameKey), _nameKey);
+ var name = _translateString(node.valueAt(_nameKey),
+ ErrorContext(key: _nameKey, parentNode: node));
if (name == null) {
+ // The error has already been reported.
return;
}
reference = NamedParameterReference(name);
@@ -457,7 +487,8 @@
/// `null` if the [node] does not represent a valid rename change.
Rename _translateRenameChange(YamlMap node) {
_reportUnsupportedKeys(node, const {_kindKey, _newNameKey});
- var newName = _translateString(node.valueAt(_newNameKey), _newNameKey);
+ var newName = _translateString(node.valueAt(_newNameKey),
+ ErrorContext(key: _newNameKey, parentNode: node));
if (newName == null) {
return null;
}
@@ -466,44 +497,42 @@
/// Translate the [node] into a string. Return the resulting string, or `null`
/// if the [node] does not represent a valid string. If the [node] is not
- /// valid, use the name of the associated [key] to report the error.
- String _translateString(YamlNode node, String key) {
+ /// valid, use the [context] to report the error.
+ String _translateString(YamlNode node, ErrorContext context,
+ {bool required = true}) {
if (node is YamlScalar) {
var value = node.value;
if (value is String) {
return value;
}
- _reportError(TransformSetErrorCode.invalidValue, node,
- [key, 'String', _nodeType(node)]);
- return null;
+ return _reportInvalidValue(node, context, 'String');
} else if (node == null) {
- // TODO(brianwilkerson) Report the missing YAML. For the best UX we
- // probably need to pass in the code to report.
+ if (required) {
+ return _reportMissingKey(context);
+ }
return null;
} else {
- _reportError(TransformSetErrorCode.invalidValue, node,
- [key, 'String', _nodeType(node)]);
- return null;
+ return _reportInvalidValue(node, context, 'String');
}
}
/// Translate the [node] into a transform. Return the resulting transform, or
/// `null` if the [node] does not represent a valid transform. If the [node]
- /// is not valid, use the name of the associated [key] to report the error.
- Transform _translateTransform(YamlNode node, String key) {
+ /// is not valid, use the [context] to report the error.
+ Transform _translateTransform(YamlNode node, ErrorContext context) {
+ assert(node != null);
if (node is YamlMap) {
_reportUnsupportedKeys(
node, const {_changesKey, _dateKey, _elementKey, _titleKey});
- var title = _translateString(node.valueAt(_titleKey), _titleKey);
- var date = _translateDate(node.valueAt(_dateKey), _dateKey);
- var element = _translateElement(node.valueAt(_elementKey), _elementKey);
- if (element == null) {
- // The error has already been reported.
- return null;
- }
- var changes = _translateList(
- node.valueAt(_changesKey), _changesKey, _translateChange);
- if (changes == null) {
+ var title = _translateString(node.valueAt(_titleKey),
+ ErrorContext(key: _titleKey, parentNode: node));
+ var date = _translateDate(node.valueAt(_dateKey),
+ ErrorContext(key: _dateKey, parentNode: node));
+ var element = _translateElement(node.valueAt(_elementKey),
+ ErrorContext(key: _elementKey, parentNode: node));
+ var changes = _translateList(node.valueAt(_changesKey),
+ ErrorContext(key: _changesKey, parentNode: node), _translateChange);
+ if (title == null || date == null || element == null || changes == null) {
// The error has already been reported.
return null;
}
@@ -513,22 +542,19 @@
}
return Transform(
title: title, date: date, element: element, changes: changes);
- } else if (node == null) {
- // TODO(brianwilkerson) Report the missing YAML.
- return null;
} else {
- _reportError(TransformSetErrorCode.invalidValue, node,
- [key, 'Map', _nodeType(node)]);
- return null;
+ return _reportInvalidValue(node, context, 'Map');
}
}
/// Translate the [node] into a transform set. Return the resulting transform
/// set, or `null` if the [node] does not represent a valid transform set.
TransformSet _translateTransformSet(YamlNode node) {
+ assert(node != null);
if (node is YamlMap) {
_reportUnsupportedKeys(node, const {_transformsKey, _versionKey});
- var version = _translateInteger(node.valueAt(_versionKey), _versionKey);
+ var version = _translateInteger(node.valueAt(_versionKey),
+ ErrorContext(key: _versionKey, parentNode: node));
if (version == null) {
// The error has already been reported.
return null;
@@ -539,7 +565,9 @@
// TODO(brianwilkerson) Version information is currently being ignored,
// but needs to be used to select a translator.
var transformations = _translateList(
- node.valueAt(_transformsKey), _transformsKey, _translateTransform);
+ node.valueAt(_transformsKey),
+ ErrorContext(key: _transformsKey, parentNode: node),
+ _translateTransform);
if (transformations == null) {
// The error has already been reported.
return null;
@@ -549,10 +577,9 @@
set.addTransform(transform);
}
return set;
- } else if (node == null) {
- // TODO(brianwilkerson) Report the missing YAML.
- return null;
} else {
+ // TODO(brianwilkerson) Consider having a different error code for the
+ // top-level node (instead of using 'file' as the "key").
_reportError(TransformSetErrorCode.invalidValue, node,
['file', 'Map', _nodeType(node)]);
return null;
@@ -561,23 +588,21 @@
/// Translate the [node] into a value extractor. Return the resulting
/// extractor, or `null` if the [node] does not represent a valid value
- /// extractor. If the [node] is not valid, use the name of the associated
- /// [key] to report the error.
- ValueExtractor _translateValueExtractor(YamlNode node, String key) {
+ /// extractor. If the [node] is not valid, use the [context] to report the
+ /// error.
+ ValueExtractor _translateValueExtractor(YamlNode node, ErrorContext context) {
if (node is YamlMap) {
- var kind = _translateString(node.valueAt(_kindKey), _kindKey);
+ var kind = _translateString(node.valueAt(_kindKey),
+ ErrorContext(key: _kindKey, parentNode: node));
if (kind == _argumentKind) {
return _translateArgumentExtractor(node);
}
// TODO(brianwilkerson) Report the invalid extractor kind.
return null;
} else if (node == null) {
- // TODO(brianwilkerson) Report the missing YAML.
- return null;
+ return _reportMissingKey(context);
} else {
- _reportError(TransformSetErrorCode.invalidValue, node,
- [key, 'Map', _nodeType(node)]);
- return null;
+ return _reportInvalidValue(node, context, 'Map');
}
}
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_missing_required_argument_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_missing_required_argument_test.dart
index 9dc2245..fb1e129 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_missing_required_argument_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_missing_required_argument_test.dart
@@ -74,7 +74,7 @@
}
build() {
- return new MyWidget(a: 1, b: 0,);
+ return new MyWidget(a: 1, b: null,);
}
''');
}
@@ -101,7 +101,7 @@
}
void f() {
- A a = new A.named(a: 0);
+ A a = new A.named(a: null);
print(a);
}
''');
@@ -128,7 +128,7 @@
import 'package:test/a.dart';
main() {
- A a = new A(a: 0);
+ A a = new A(a: null);
print(a);
}
''');
@@ -292,7 +292,7 @@
test({@required int a, @required int bcd}) {}
main() {
- test(a: 3, bcd: 0);
+ test(a: 3, bcd: null);
}
''');
}
@@ -312,7 +312,7 @@
test({@required int a, @required int bcd}) {}
main() {
- test(a: 0);
+ test(a: null);
}
''', errorFilter: (error) => error.message.contains("'a'"));
}
@@ -332,7 +332,7 @@
test({@required int a, @required int bcd}) {}
main() {
- test(bcd: 0);
+ test(bcd: null);
}
''', errorFilter: (error) => error.message.contains("'bcd'"));
}
@@ -420,10 +420,10 @@
test({@required int abc}) {}
main() {
- test(abc: 0);
+ test(abc: null);
}
''');
- assertLinkedGroup(change.linkedEditGroups[0], ['0);']);
+ assertLinkedGroup(change.linkedEditGroups[0], ['null);']);
}
Future<void> test_single_normal() async {
@@ -441,7 +441,7 @@
test(String x, {@required int abc}) {}
main() {
- test("foo", abc: 0);
+ test("foo", abc: null);
}
''');
}
@@ -461,7 +461,7 @@
test({@Required("Really who doesn't need an abc?") int abc}) {}
main() {
- test(abc: 0);
+ test(abc: null);
}
''');
}
@@ -475,7 +475,7 @@
@override
FixKind get kind => DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT;
- Future<void> test_nonNullable_supported() async {
+ Future<void> test_nonNullable() async {
await resolveTestUnit('''
void f({required int x}) {}
void g() {
@@ -485,22 +485,12 @@
await assertHasFix('''
void f({required int x}) {}
void g() {
- f(x: 0);
+ f(x: null);
}
''');
}
- Future<void> test_nonNullable_unsupported() async {
- await resolveTestUnit('''
-void f({required DateTime d}) {}
-void g() {
- f();
-}
-''');
- await assertNoFix();
- }
-
- Future<void> test_nullable_supported() async {
+ Future<void> test_nullable() async {
await resolveTestUnit('''
void f({required int? x}) {}
void g() {
@@ -510,21 +500,6 @@
await assertHasFix('''
void f({required int? x}) {}
void g() {
- f(x: 0);
-}
-''');
- }
-
- Future<void> test_nullable_unsupported() async {
- await resolveTestUnit('''
-void f({required DateTime? x}) {}
-void g() {
- f();
-}
-''');
- await assertHasFix('''
-void f({required DateTime? x}) {}
-void g() {
f(x: null);
}
''');
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/add_diagnostic_property_reference_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/add_diagnostic_property_reference_test.dart
new file mode 100644
index 0000000..cda5640
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/add_diagnostic_property_reference_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddDiagnosticPropertyReferenceTest);
+ });
+}
+
+@reflectiveTest
+class AddDiagnosticPropertyReferenceTest extends BulkFixProcessorTest {
+ @override
+ String get lintCode => LintNames.diagnostic_describe_all_properties;
+
+ Future<void> test_singleFile() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/foundation.dart';
+import 'package:flutter/widgets.dart';
+
+class C extends Widget with Diagnosticable {
+ bool get absorbing => _absorbing;
+ bool _absorbing;
+ bool ignoringSemantics;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties.add(DiagnosticsProperty<bool>('absorbing', absorbing));
+ }
+}
+
+class D extends Widget with Diagnosticable {
+ bool ignoringSemantics;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ }
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/foundation.dart';
+import 'package:flutter/widgets.dart';
+
+class C extends Widget with Diagnosticable {
+ bool get absorbing => _absorbing;
+ bool _absorbing;
+ bool ignoringSemantics;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties.add(DiagnosticsProperty<bool>('absorbing', absorbing));
+ properties.add(DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics));
+ }
+}
+
+class D extends Widget with Diagnosticable {
+ bool ignoringSemantics;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ properties.add(DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics));
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
index 7c7d235..4d7e35b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
@@ -6,6 +6,8 @@
import 'add_await_test.dart' as add_await;
import 'add_const_test.dart' as add_const;
+import 'add_diagnostic_property_reference_test.dart'
+ as add_diagnostic_property_reference;
import 'add_override_test.dart' as add_override;
import 'convert_documentation_into_line_test.dart'
as convert_documentation_into_line;
@@ -59,6 +61,7 @@
defineReflectiveSuite(() {
add_await.main();
add_const.main();
+ add_diagnostic_property_reference.main();
add_override.main();
convert_documentation_into_line.main();
convert_map_from_iterable_to_for_literal.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_test.dart
index c2b365e..40aa4d0 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_test.dart
@@ -20,13 +20,14 @@
version: 1
transforms:
- title: 'Rename A'
+ date: 2020-09-08
element:
uris: ['test.dart']
class: 'A'
changes:
- 'rename'
''', [
- error(TransformSetErrorCode.invalidValue, 110, 8),
+ error(TransformSetErrorCode.invalidValue, 129, 8),
]);
}
@@ -35,12 +36,13 @@
version: 1
transforms:
- title: 'Rename A'
+ date: 2020-09-08
element: 5
changes:
- kind: 'rename'
newName: 'B'
''', [
- error(TransformSetErrorCode.invalidValue, 54, 1),
+ error(TransformSetErrorCode.invalidValue, 73, 1),
]);
}
@@ -90,6 +92,7 @@
version: 1
transforms:
- title: 0
+ date: 2020-09-08
element:
uris: ['test.dart']
class: 'A'
@@ -106,6 +109,7 @@
version: 1
transforms:
- title: []
+ date: 2020-09-08
element:
uris: ['test.dart']
class: 'A'
@@ -140,6 +144,7 @@
version: 1
transforms:
- title: 'Rename A'
+ date: 2020-09-08
element:
uris: ['test.dart']
class: 'A'
@@ -149,7 +154,7 @@
name: 'T'
value: 'int'
''', [
- error(TransformSetErrorCode.invalidValue, 179, 5),
+ error(TransformSetErrorCode.invalidValue, 198, 5),
]);
}
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_key_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_key_test.dart
new file mode 100644
index 0000000..8080470
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_key_test.dart
@@ -0,0 +1,273 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../transform_set_parser_test_support.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(MissingKeyTest);
+ });
+}
+
+@reflectiveTest
+class MissingKeyTest extends AbstractTransformSetParserTest {
+ void test_addParameterChange_argumentValue() {
+ assertErrors('''
+version: 1
+transforms:
+- title: ''
+ date: 2020-09-14
+ element:
+ uris: ['test.dart']
+ function: 'f'
+ changes:
+ - kind: 'addParameter'
+ index: 0
+ name: 'a'
+ style: required_positional
+''', [
+ error(TransformSetErrorCode.missingKey, 124, 85),
+ ]);
+ }
+
+ void test_addParameterChange_index() {
+ assertErrors('''
+version: 1
+transforms:
+- title: ''
+ date: 2020-09-14
+ element:
+ uris: ['test.dart']
+ function: 'f'
+ changes:
+ - kind: 'addParameter'
+ name: 'a'
+ style: required_positional
+ argumentValue:
+ kind: 'argument'
+ index: 0
+''', [
+ error(TransformSetErrorCode.missingKey, 124, 133),
+ ]);
+ }
+
+ void test_addParameterChange_name() {
+ assertErrors('''
+version: 1
+transforms:
+- title: ''
+ date: 2020-09-14
+ element:
+ uris: ['test.dart']
+ function: 'f'
+ changes:
+ - kind: 'addParameter'
+ index: 0
+ style: required_positional
+ argumentValue:
+ kind: 'argument'
+ index: 0
+''', [
+ error(TransformSetErrorCode.missingKey, 124, 132),
+ ]);
+ }
+
+ void test_addParameterChange_style() {
+ assertErrors('''
+version: 1
+transforms:
+- title: ''
+ date: 2020-09-14
+ element:
+ uris: ['test.dart']
+ function: 'f'
+ changes:
+ - kind: 'addParameter'
+ index: 0
+ name: 'a'
+ argumentValue:
+ kind: 'argument'
+ index: 0
+''', [
+ error(TransformSetErrorCode.missingKey, 124, 115),
+ ]);
+ }
+
+ void test_addTypeParameterChange_index() {
+ assertErrors('''
+version: 1
+transforms:
+- title: ''
+ date: 2020-09-14
+ element:
+ uris: ['test.dart']
+ function: 'f'
+ changes:
+ - kind: 'addTypeParameter'
+ name: 'a'
+ value:
+ kind: 'argument'
+ index: 0
+''', [
+ error(TransformSetErrorCode.missingKey, 124, 96),
+ ]);
+ }
+
+ void test_addTypeParameterChange_name() {
+ assertErrors('''
+version: 1
+transforms:
+- title: ''
+ date: 2020-09-14
+ element:
+ uris: ['test.dart']
+ function: 'f'
+ changes:
+ - kind: 'addTypeParameter'
+ index: 0
+ value:
+ kind: 'argument'
+ index: 0
+''', [
+ error(TransformSetErrorCode.missingKey, 124, 95),
+ ]);
+ }
+
+ void test_addTypeParameterChange_value() {
+ assertErrors('''
+version: 1
+transforms:
+- title: ''
+ date: 2020-09-14
+ element:
+ uris: ['test.dart']
+ function: 'f'
+ changes:
+ - kind: 'addTypeParameter'
+ index: 0
+ name: 'a'
+''', [
+ error(TransformSetErrorCode.missingKey, 124, 56),
+ ]);
+ }
+
+ void test_change_kind() {
+ assertErrors('''
+version: 1
+transforms:
+- title: ''
+ date: 2020-09-14
+ element:
+ uris: ['test.dart']
+ function: 'f'
+ changes:
+ - index: 0
+''', [
+ error(TransformSetErrorCode.missingKey, 124, 9),
+ ]);
+ }
+
+ void test_element_uris() {
+ assertErrors('''
+version: 1
+transforms:
+- title: ''
+ date: 2020-09-14
+ element:
+ function: 'f'
+ changes: []
+''', [
+ error(TransformSetErrorCode.missingKey, 69, 16),
+ ]);
+ }
+
+ void test_renameChange_newName() {
+ assertErrors('''
+version: 1
+transforms:
+- title: ''
+ date: 2020-09-14
+ element:
+ uris: ['test.dart']
+ function: 'f'
+ changes:
+ - kind: 'rename'
+''', [
+ error(TransformSetErrorCode.missingKey, 124, 15),
+ ]);
+ }
+
+ void test_transform_changes() {
+ assertErrors('''
+version: 1
+transforms:
+- title: ''
+ date: 2020-09-14
+ element:
+ uris: ['test.dart']
+ function: 'f'
+''', [
+ error(TransformSetErrorCode.missingKey, 25, 82),
+ ]);
+ }
+
+ void test_transform_date() {
+ assertErrors('''
+version: 1
+transforms:
+- title: ''
+ element:
+ uris: ['test.dart']
+ function: 'f'
+ changes: []
+''', [
+ error(TransformSetErrorCode.missingKey, 25, 77),
+ ]);
+ }
+
+ void test_transform_element() {
+ assertErrors('''
+version: 1
+transforms:
+- title: ''
+ date: 2020-09-14
+ changes: []
+''', [
+ error(TransformSetErrorCode.missingKey, 25, 43),
+ ]);
+ }
+
+ void test_transform_title() {
+ assertErrors('''
+version: 1
+transforms:
+- date: 2020-09-14
+ element:
+ uris: ['test.dart']
+ function: 'f'
+ changes: []
+''', [
+ error(TransformSetErrorCode.missingKey, 25, 84),
+ ]);
+ }
+
+ void test_transformSet_transforms() {
+ assertErrors('''
+version: 1
+''', [
+ error(TransformSetErrorCode.missingKey, 0, 11),
+ ]);
+ }
+
+ void test_transformSet_version() {
+ assertErrors('''
+transforms: []
+''', [
+ error(TransformSetErrorCode.missingKey, 0, 15),
+ ]);
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart
index a570f51..dc7a598 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart
@@ -5,12 +5,14 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'invalid_value_test.dart' as invalid_value;
+import 'missing_key_test.dart' as missing_key;
import 'unsupported_key_test.dart' as unsupported_key;
import 'yaml_syntax_error_test.dart' as yaml_syntax_error;
void main() {
defineReflectiveSuite(() {
invalid_value.main();
+ missing_key.main();
unsupported_key.main();
yaml_syntax_error.main();
});
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unsupported_key_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unsupported_key_test.dart
index fb5d68c..64d724e 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unsupported_key_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unsupported_key_test.dart
@@ -20,6 +20,7 @@
version: 1
transforms:
- title: 'Rename A'
+ date: 2020-08-21
element:
uris:
- 'test.dart'
@@ -29,7 +30,7 @@
oldName: 'A'
newName: 'B'
''', [
- error(TransformSetErrorCode.unsupportedKey, 137, 7),
+ error(TransformSetErrorCode.unsupportedKey, 156, 7),
]);
}
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/end_to_end_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/end_to_end_test.dart
index b5ae21c..36e1c68 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/end_to_end_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/end_to_end_test.dart
@@ -24,6 +24,7 @@
version: 1
transforms:
- title: 'Add parameter'
+ date: 2020-09-09
element:
uris: ['$importUri']
method: 'm'
@@ -63,6 +64,7 @@
version: 1
transforms:
- title: 'Add type argument'
+ date: 2020-09-03
element:
uris:
- '$importUri'
@@ -102,6 +104,7 @@
version: 1
transforms:
- title: 'Add argument'
+ date: 2020-09-09
element:
uris: ['$importUri']
method: 'm'
@@ -134,6 +137,7 @@
version: 1
transforms:
- title: 'Rename to New'
+ date: 2020-09-01
element:
uris:
- '$importUri'
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
index eefe855..16dc6a9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
@@ -27,6 +27,7 @@
version: 1
transforms:
- title: 'Add'
+ date: 2020-09-09
element:
uris: ['test.dart']
function: 'f'
@@ -62,6 +63,7 @@
version: 1
transforms:
- title: 'Add'
+ date: 2020-09-09
element:
uris: ['test.dart']
function: 'f'
@@ -91,6 +93,7 @@
version: 1
transforms:
- title: 'Add'
+ date: 2020-09-09
element:
uris: ['test.dart']
function: 'f'
@@ -126,6 +129,7 @@
version: 1
transforms:
- title: 'Add'
+ date: 2020-09-09
element:
uris: ['test.dart']
function: 'f'
@@ -161,6 +165,7 @@
version: 1
transforms:
- title: 'Add'
+ date: 2020-09-03
element:
uris:
- 'test.dart'
@@ -191,6 +196,7 @@
version: 1
transforms:
- title: 'Add'
+ date: 2020-09-03
element:
uris:
- 'test.dart'
@@ -239,6 +245,7 @@
version: 1
transforms:
- title: 'Rename g'
+ date: 2020-09-02
element:
uris: ['test.dart']
getter: 'g'
@@ -257,6 +264,7 @@
version: 1
transforms:
- title: 'Rename g'
+ date: 2020-09-02
element:
uris: ['test.dart']
getter: 'g'
@@ -274,6 +282,7 @@
version: 1
transforms:
- title: 'Rename m'
+ date: 2020-09-02
element:
uris: ['test.dart']
method: 'm'
@@ -313,6 +322,7 @@
version: 1
transforms:
- title: 'Remove'
+ date: 2020-09-09
element:
uris: ['test.dart']
function: 'f'
@@ -338,6 +348,7 @@
version: 1
transforms:
- title: 'Remove'
+ date: 2020-09-09
element:
uris: ['test.dart']
function: 'f'
@@ -363,6 +374,7 @@
version: 1
transforms:
- title: 'Rename A'
+ date: 2020-08-21
element:
uris:
- 'test.dart'
diff --git a/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
index 1a4c879..311d391 100644
--- a/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
@@ -161,21 +161,22 @@
}
}
- void _resolve1(AssignmentExpressionImpl node, DartType leftType) {
- Token operator = node.operator;
- TokenType operatorType = operator.type;
- Expression leftHandSide = node.leftHandSide;
+ void _resolve1(AssignmentExpressionImpl node) {
+ var leftHandSide = node.leftHandSide;
+ var operator = node.operator;
+ var operatorType = operator.type;
+ var leftType = node.readType;
if (identical(leftType, NeverTypeImpl.instance)) {
return;
}
_assignmentShared.checkFinalAlreadyAssigned(leftHandSide);
- // For any compound assignments to a void or nullable variable, report it.
- // Example: `y += voidFn()`, not allowed.
+ // Values of the type void cannot be used.
+ // Example: `y += 0`, is not allowed.
if (operatorType != TokenType.EQ) {
- if (leftType != null && leftType.isVoid) {
+ if (leftType.isVoid) {
_errorReporter.reportErrorForToken(
CompileTimeErrorCode.USE_OF_VOID_RESULT,
operator,
@@ -184,31 +185,30 @@
}
}
- if (operatorType != TokenType.AMPERSAND_AMPERSAND_EQ &&
- operatorType != TokenType.BAR_BAR_EQ &&
- operatorType != TokenType.EQ &&
- operatorType != TokenType.QUESTION_QUESTION_EQ) {
- operatorType = operatorFromCompoundAssignment(operatorType);
- if (leftHandSide != null) {
- String methodName = operatorType.lexeme;
- // TODO(brianwilkerson) Change the [methodNameNode] from the left hand
- // side to the operator.
- var result = _typePropertyResolver.resolve(
- receiver: leftHandSide,
- receiverType: leftType,
- name: methodName,
- receiverErrorNode: leftHandSide,
- nameErrorNode: leftHandSide,
- );
- node.staticElement = result.getter;
- if (_shouldReportInvalidMember(leftType, result)) {
- _errorReporter.reportErrorForToken(
- CompileTimeErrorCode.UNDEFINED_OPERATOR,
- operator,
- [methodName, leftType],
- );
- }
- }
+ if (operatorType == TokenType.AMPERSAND_AMPERSAND_EQ ||
+ operatorType == TokenType.BAR_BAR_EQ ||
+ operatorType == TokenType.EQ ||
+ operatorType == TokenType.QUESTION_QUESTION_EQ) {
+ return;
+ }
+
+ var binaryOperatorType = operatorFromCompoundAssignment(operatorType);
+ var methodName = binaryOperatorType.lexeme;
+
+ var result = _typePropertyResolver.resolve(
+ receiver: leftHandSide,
+ receiverType: leftType,
+ name: methodName,
+ receiverErrorNode: leftHandSide,
+ nameErrorEntity: operator,
+ );
+ node.staticElement = result.getter;
+ if (_shouldReportInvalidMember(leftType, result)) {
+ _errorReporter.reportErrorForToken(
+ CompileTimeErrorCode.UNDEFINED_OPERATOR,
+ operator,
+ [methodName, leftType],
+ );
}
}
@@ -270,7 +270,7 @@
void _resolve3(AssignmentExpressionImpl node, Expression left,
TokenType operator, Expression right) {
- _resolve1(node, node.readType);
+ _resolve1(node);
{
var leftType = node.writeType;
diff --git a/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
index ddab194..8addd0d 100644
--- a/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
@@ -339,7 +339,7 @@
receiverType: leftType,
name: methodName,
receiverErrorNode: leftOperand,
- nameErrorNode: node,
+ nameErrorEntity: node,
);
node.staticElement = result.getter;
diff --git a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
index 59e5543..a35cc79 100644
--- a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/syntactic_entity.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/scope.dart';
import 'package:analyzer/dart/element/type.dart';
@@ -40,12 +41,12 @@
///
/// If no applicable extensions, return [ResolutionResult.none].
///
- /// If the match is ambiguous, report an error and return
- /// [ResolutionResult.ambiguous].
+ /// If the match is ambiguous, report an error on the [nameEntity], and
+ /// return [ResolutionResult.ambiguous].
ResolutionResult findExtension(
DartType type,
+ SyntacticEntity nameEntity,
String name,
- Expression target,
) {
var extensions = _getApplicable(type, name);
@@ -62,9 +63,10 @@
return extension.asResolutionResult;
}
- _errorReporter.reportErrorForNode(
+ _errorReporter.reportErrorForOffset(
CompileTimeErrorCode.AMBIGUOUS_EXTENSION_MEMBER_ACCESS,
- target,
+ nameEntity.offset,
+ nameEntity.length,
[
name,
extensions[0].extension.name,
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart
index b87deb7..9c98040 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart
@@ -121,7 +121,7 @@
receiverType: receiverType,
name: FunctionElement.CALL_METHOD_NAME,
receiverErrorNode: function,
- nameErrorNode: function,
+ nameErrorEntity: function,
);
var callElement = result.getter;
diff --git a/pkg/analyzer/lib/src/dart/resolver/lexical_lookup.dart b/pkg/analyzer/lib/src/dart/resolver/lexical_lookup.dart
index 19e6a7e..9e2cd18 100644
--- a/pkg/analyzer/lib/src/dart/resolver/lexical_lookup.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/lexical_lookup.dart
@@ -58,7 +58,7 @@
receiverType: thisType,
name: id,
receiverErrorNode: node,
- nameErrorNode: node,
+ nameErrorEntity: node,
);
if (setter) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index a0725e4..c462243 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -638,7 +638,7 @@
receiverType: receiverType,
name: name,
receiverErrorNode: receiverErrorNode,
- nameErrorNode: nameNode,
+ nameErrorEntity: nameNode,
);
if (result.isAmbiguous) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/postfix_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/postfix_expression_resolver.dart
index ebe40fd..230f66b4 100644
--- a/pkg/analyzer/lib/src/dart/resolver/postfix_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/postfix_expression_resolver.dart
@@ -158,7 +158,7 @@
receiverType: receiverType,
name: methodName,
receiverErrorNode: operand,
- nameErrorNode: operand,
+ nameErrorEntity: operand,
);
node.staticElement = result.getter;
if (_shouldReportInvalidMember(receiverType, result)) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart
index cd5deb0..a723362 100644
--- a/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart
@@ -192,7 +192,7 @@
receiverType: readType,
name: methodName,
receiverErrorNode: operand,
- nameErrorNode: operand,
+ nameErrorEntity: operand,
);
node.staticElement = result.getter;
if (_shouldReportInvalidMember(readType, result)) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
index 70dcfbf..d4ecd63 100644
--- a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
@@ -27,14 +27,29 @@
ExtensionMemberResolver get _extensionResolver => _resolver.extensionResolver;
- PropertyElementResolverResult resolve2({
- @required Expression target,
- @required bool isCascaded,
- @required bool isNullAware,
- @required SimpleIdentifier propertyName,
+ PropertyElementResolverResult resolvePrefixedIdentifier({
+ @required PrefixedIdentifier node,
@required bool hasRead,
@required bool hasWrite,
}) {
+ return _resolve(
+ target: node.prefix,
+ isCascaded: false,
+ isNullAware: false,
+ propertyName: node.identifier,
+ hasRead: hasRead,
+ hasWrite: hasWrite,
+ );
+ }
+
+ PropertyElementResolverResult resolvePropertyAccess({
+ @required PropertyAccess node,
+ @required bool hasRead,
+ @required bool hasWrite,
+ }) {
+ var target = node.realTarget;
+ var propertyName = node.propertyName;
+
if (target is ExtensionOverride) {
return _resolveTargetExtensionOverride(
target: target,
@@ -44,6 +59,63 @@
);
}
+ if (target is SuperExpression) {
+ return _resolveTargetSuperExpression(
+ target: target,
+ propertyName: propertyName,
+ hasRead: hasRead,
+ hasWrite: hasWrite,
+ );
+ }
+
+ return _resolve(
+ target: target,
+ isCascaded: node.target == null,
+ isNullAware: node.isNullAware,
+ propertyName: propertyName,
+ hasRead: hasRead,
+ hasWrite: hasWrite,
+ );
+ }
+
+ void _checkExtensionOverrideStaticMember(
+ SimpleIdentifier propertyName,
+ ExecutableElement element,
+ ) {
+ if (element != null && element.isStatic) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER,
+ propertyName,
+ );
+ }
+ }
+
+ /// If the [element] is not static, report the error on the [identifier].
+ void _checkForStaticAccessToInstanceMember(
+ SimpleIdentifier identifier,
+ ExecutableElement element,
+ ) {
+ if (element.isStatic) return;
+
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.STATIC_ACCESS_TO_INSTANCE_MEMBER,
+ identifier,
+ [identifier.name],
+ );
+ }
+
+ bool _isAccessible(ExecutableElement element) {
+ return element.isAccessibleIn(_definingLibrary);
+ }
+
+ PropertyElementResolverResult _resolve({
+ @required Expression target,
+ @required bool isCascaded,
+ @required bool isNullAware,
+ @required SimpleIdentifier propertyName,
+ @required bool hasRead,
+ @required bool hasWrite,
+ }) {
//
// If this property access is of the form 'C.m' where 'C' is a class,
// then we don't call resolveProperty(...) which walks up the class
@@ -82,15 +154,6 @@
}
}
- if (target is SuperExpression) {
- return _resolveTargetSuperExpression(
- target: target,
- propertyName: propertyName,
- hasRead: hasRead,
- hasWrite: hasWrite,
- );
- }
-
var targetType = target.staticType;
targetType = _resolveTypeParameter(targetType);
@@ -111,7 +174,7 @@
receiverType: targetType,
name: propertyName.name,
receiverErrorNode: target,
- nameErrorNode: propertyName,
+ nameErrorEntity: propertyName,
);
if (targetType is DynamicTypeImpl || targetType is NeverTypeImpl) {
@@ -154,66 +217,6 @@
);
}
- PropertyElementResolverResult resolvePrefixedIdentifier({
- @required PrefixedIdentifier node,
- @required bool hasRead,
- @required bool hasWrite,
- }) {
- return resolve2(
- target: node.prefix,
- isCascaded: false,
- isNullAware: false,
- propertyName: node.identifier,
- hasRead: hasRead,
- hasWrite: hasWrite,
- );
- }
-
- PropertyElementResolverResult resolvePropertyAccess({
- @required PropertyAccess node,
- @required bool hasRead,
- @required bool hasWrite,
- }) {
- return resolve2(
- target: node.realTarget,
- isCascaded: node.target == null,
- isNullAware: node.isNullAware,
- propertyName: node.propertyName,
- hasRead: hasRead,
- hasWrite: hasWrite,
- );
- }
-
- void _checkExtensionOverrideStaticMember(
- SimpleIdentifier propertyName,
- ExecutableElement element,
- ) {
- if (element != null && element.isStatic) {
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER,
- propertyName,
- );
- }
- }
-
- /// If the [element] is not static, report the error on the [identifier].
- void _checkForStaticAccessToInstanceMember(
- SimpleIdentifier identifier,
- ExecutableElement element,
- ) {
- if (element.isStatic) return;
-
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.STATIC_ACCESS_TO_INSTANCE_MEMBER,
- identifier,
- [identifier.name],
- );
- }
-
- bool _isAccessible(ExecutableElement element) {
- return element.isAccessibleIn(_definingLibrary);
- }
-
PropertyElementResolverResult _resolveTargetClassElement({
@required ClassElement typeReference,
@required SimpleIdentifier propertyName,
diff --git a/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
index dbbcb96..49df1af 100644
--- a/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/syntactic_entity.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
@@ -24,8 +25,8 @@
final ExtensionMemberResolver _extensionResolver;
Expression _receiver;
+ SyntacticEntity _nameErrorEntity;
String _name;
- AstNode _nameErrorNode;
ResolutionResult _result = ResolutionResult.none;
@@ -43,18 +44,18 @@
/// The [receiverErrorNode] is the node to report nullable dereference,
/// if the [receiverType] is potentially nullable.
///
- /// The [nameErrorNode] is used to report the ambiguous extension issue.
+ /// The [nameErrorEntity] is used to report the ambiguous extension issue.
ResolutionResult resolve({
@required Expression receiver,
@required DartType receiverType,
@required String name,
@required AstNode receiverErrorNode,
- @required Expression nameErrorNode,
+ @required SyntacticEntity nameErrorEntity,
}) {
assert(receiverType != null);
_receiver = receiver;
_name = name;
- _nameErrorNode = nameErrorNode;
+ _nameErrorEntity = nameErrorEntity;
_result = ResolutionResult.none;
receiverType = _resolveTypeParameter(receiverType);
@@ -95,7 +96,7 @@
}
void _lookupExtension(DartType type) {
- _result = _extensionResolver.findExtension(type, _name, _nameErrorNode);
+ _result = _extensionResolver.findExtension(type, _nameErrorEntity, _name);
}
void _lookupInterfaceType(InterfaceType type) {
@@ -139,8 +140,6 @@
void _lookupType(DartType type) {
if (type is InterfaceType) {
_lookupInterfaceType(type);
- } else if (type is FunctionType) {
- _lookupInterfaceType(_typeProvider.functionType);
}
}
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 469a0ce..e7adf8a 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -418,7 +418,7 @@
receiverType: targetType,
name: getterMethodName,
receiverErrorNode: target,
- nameErrorNode: target,
+ nameErrorEntity: target,
);
}
@@ -761,7 +761,7 @@
receiverType: enclosingType,
name: node.name,
receiverErrorNode: node,
- nameErrorNode: node,
+ nameErrorEntity: node,
);
node.auxiliaryElements = AuxiliaryElements(
result.getter,
@@ -1275,7 +1275,7 @@
receiverType: enclosingClass.thisType,
name: identifier.name,
receiverErrorNode: identifier,
- nameErrorNode: identifier,
+ nameErrorEntity: identifier,
);
setter = result.setter;
}
@@ -1316,7 +1316,7 @@
receiverType: enclosingType,
name: identifier.name,
receiverErrorNode: identifier,
- nameErrorNode: identifier,
+ nameErrorEntity: identifier,
);
if (identifier.inSetterContext() ||
identifier.parent is CommentReference) {
diff --git a/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart b/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
index 8fc046c..d4bc4a4 100644
--- a/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
@@ -144,7 +144,6 @@
}
test_operator_binary() async {
- // There is no error reported.
await assertErrorsInCode('''
class A {}
@@ -162,6 +161,26 @@
]);
}
+ test_operator_binary_compoundAssignment() async {
+ await assertErrorsInCode('''
+class A {}
+
+extension E1 on A {
+ A operator +(_) => this;
+}
+
+extension E2 on A {
+ A operator +(_) => this;
+}
+
+void f(A a) {
+ a += 0;
+}
+''', [
+ error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_MEMBER_ACCESS, 130, 2),
+ ]);
+ }
+
test_operator_index_index() async {
await assertErrorsInCode('''
class A {}
diff --git a/pkg/vm/lib/bytecode/declarations.dart b/pkg/vm/lib/bytecode/declarations.dart
index c30f096..9b247c9 100644
--- a/pkg/vm/lib/bytecode/declarations.dart
+++ b/pkg/vm/lib/bytecode/declarations.dart
@@ -533,6 +533,7 @@
static const hasCustomScriptFlag = 1 << 22;
static const hasAttributesFlag = 1 << 23;
static const isExtensionMemberFlag = 1 << 24;
+ static const hasParameterFlagsFlag = 1 << 25;
final int flags;
final ObjectHandle name;
@@ -542,6 +543,8 @@
final TypeParametersDeclaration typeParameters;
final int numRequiredParameters;
final List<ParameterDeclaration> parameters;
+ // Only contains the required flag for parameters when present.
+ final List<int> parameterFlags;
final ObjectHandle returnType;
final ObjectHandle nativeName;
final Code code;
@@ -557,6 +560,7 @@
this.typeParameters,
this.numRequiredParameters,
this.parameters,
+ this.parameterFlags,
this.returnType,
this.nativeName,
this.code,
@@ -584,6 +588,10 @@
for (var param in parameters) {
param.write(writer);
}
+ if ((flags & hasParameterFlagsFlag) != 0) {
+ writer.writePackedUInt30(parameterFlags.length);
+ parameterFlags.forEach((flags) => writer.writePackedUInt30(flags));
+ }
writer.writePackedObject(returnType);
if ((flags & isNativeFlag) != 0) {
writer.writePackedObject(nativeName);
@@ -624,6 +632,10 @@
final parameters = new List<ParameterDeclaration>.generate(
numParameters, (_) => new ParameterDeclaration.read(reader));
+ final parameterFlags = ((flags & hasParameterFlagsFlag) != 0)
+ ? List<int>.generate(
+ reader.readPackedUInt30(), (_) => reader.readPackedUInt30())
+ : null;
final returnType = reader.readPackedObject();
final nativeName =
((flags & isNativeFlag) != 0) ? reader.readPackedObject() : null;
@@ -643,6 +655,7 @@
typeParameters,
numRequiredParameters,
parameters,
+ parameterFlags,
returnType,
nativeName,
code,
@@ -725,6 +738,9 @@
sb.write(' type-params $typeParameters\n');
}
sb.write(' parameters $parameters (required: $numRequiredParameters)\n');
+ if ((flags & hasParameterFlagsFlag) != 0) {
+ sb.write(' parameter-flags $parameterFlags\n');
+ }
sb.write(' return-type $returnType\n');
if ((flags & hasAnnotationsFlag) != 0) {
sb.write(' annotations $annotations\n');
@@ -820,6 +836,8 @@
final LocalVariableTable localVariables;
final List<ObjectHandle> nullableFields;
final List<ClosureDeclaration> closures;
+ // Contains all parameter flags except for the required flags, which are
+ // kept instead in the FunctionDeclaration and ClosureDeclaration.
final List<int> parameterFlags;
final int forwardingStubTargetCpIndex;
final int defaultFunctionTypeArgsCpIndex;
@@ -983,6 +1001,7 @@
final int numRequiredParams;
final int numNamedParams;
final List<NameAndType> parameters;
+ // Only contains the required flag for parameters when present.
final List<int> parameterFlags;
final ObjectHandle returnType;
ObjectHandle attributes;
@@ -1105,6 +1124,21 @@
attributes);
}
+ void _writeParamsToBuffer(
+ StringBuffer sb, List<NameAndType> params, List<int> flags) {
+ assert(flags == null || (params.length == flags.length));
+ for (int i = 0; i < params.length; i++) {
+ if (i != 0) {
+ sb.write(', ');
+ }
+ // We only store the required flag for ClosureDeclarations.
+ if (flags != null && flags[i] != 0) {
+ sb.write('required ');
+ }
+ sb.write(params[i]);
+ }
+ }
+
@override
String toString() {
final StringBuffer sb = new StringBuffer();
@@ -1125,16 +1159,22 @@
sb.write(' <${typeParams.join(', ')}>');
}
sb.write(' (');
- sb.write(parameters.sublist(0, numRequiredParams).join(', '));
+ final requiredFlags = (flags & hasParameterFlagsFlag) != 0
+ ? parameterFlags.sublist(0, numRequiredParams)
+ : null;
+ _writeParamsToBuffer(
+ sb, parameters.sublist(0, numRequiredParams), requiredFlags);
if (numRequiredParams != parameters.length) {
if (numRequiredParams > 0) {
sb.write(', ');
}
- if (numNamedParams > 0) {
- sb.write('{ ${parameters.sublist(numRequiredParams).join(', ')} }');
- } else {
- sb.write('[ ${parameters.sublist(numRequiredParams).join(', ')} ]');
- }
+ sb.write(numNamedParams > 0 ? '{ ' : '[ ');
+ final optionalFlags = (flags & hasParameterFlagsFlag) != 0
+ ? parameterFlags.sublist(numRequiredParams)
+ : null;
+ _writeParamsToBuffer(
+ sb, parameters.sublist(numRequiredParams), optionalFlags);
+ sb.write(numNamedParams > 0 ? ' }' : ' ]');
}
sb.write(') -> ');
sb.writeln(returnType);
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index e2ddd4d..b44d6ad 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -794,6 +794,12 @@
for (var param in function.namedParameters) {
parameters.add(getParameterDeclaration(param));
}
+ // We only need the required flags when loading the function declaration.
+ final parameterFlags =
+ getParameterFlags(function, mask: ParameterDeclaration.isRequiredFlag);
+ if (parameterFlags != null) {
+ flags |= FunctionDeclaration.hasParameterFlagsFlag;
+ }
return new FunctionDeclaration(
flags,
@@ -804,6 +810,7 @@
typeParameters,
function.requiredParameterCount,
parameters,
+ parameterFlags,
objectTable.getHandle(function.returnType),
nativeName,
code,
@@ -857,8 +864,11 @@
return new ParameterDeclaration(nameHandle, typeHandle);
}
- List<int> getParameterFlags(FunctionNode function) {
- int getFlags(VariableDeclaration variable) {
+ // Most uses of parameter flags in the VM only nee a subset of the flags,
+ // so the optional [mask] argument allows the caller to specify the subset
+ // that should be retained.
+ List<int> getParameterFlags(FunctionNode function, {int mask = -1}) {
+ int getFlags(VariableDeclaration variable, int mask) {
int flags = 0;
if (variable.isCovariant) {
flags |= ParameterDeclaration.isCovariantFlag;
@@ -872,15 +882,15 @@
if (variable.isRequired) {
flags |= ParameterDeclaration.isRequiredFlag;
}
- return flags;
+ return flags & mask;
}
final List<int> paramFlags = <int>[];
for (var param in function.positionalParameters) {
- paramFlags.add(getFlags(param));
+ paramFlags.add(getFlags(param, mask));
}
for (var param in function.namedParameters) {
- paramFlags.add(getFlags(param));
+ paramFlags.add(getFlags(param, mask));
}
for (int flags in paramFlags) {
@@ -1880,10 +1890,16 @@
int forwardingStubTargetCpIndex = null;
int defaultFunctionTypeArgsCpIndex = null;
+ // We don't need the required flag when loading the code, but do need
+ // all other parameter flags.
+ final parameterFlagMask = ~ParameterDeclaration.isRequiredFlag;
+
if (node is Constructor) {
- parameterFlags = getParameterFlags(node.function);
+ parameterFlags =
+ getParameterFlags(node.function, mask: parameterFlagMask);
} else if (node is Procedure) {
- parameterFlags = getParameterFlags(node.function);
+ parameterFlags =
+ getParameterFlags(node.function, mask: parameterFlagMask);
if (node.isForwardingStub) {
forwardingStubTargetCpIndex =
@@ -2657,7 +2673,9 @@
flags |= ClosureDeclaration.hasTypeParamsFlag;
}
- final List<int> parameterFlags = getParameterFlags(function);
+ // We only need the required flags when loading the closure declaration.
+ final parameterFlags =
+ getParameterFlags(function, mask: ParameterDeclaration.isRequiredFlag);
if (parameterFlags != null) {
flags |= ClosureDeclaration.hasParameterFlagsFlag;
}
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index accf0d4..ce97313 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -201,7 +201,7 @@
[ $arch != simarm && $arch != simarm64 && $compiler == dartk ]
complex_reload_test: RuntimeError
-[ $compiler == dartkb && ($builder_tag == bytecode_interpreter || $builder_tag == bytecode_mixed) ]
+[ $compiler == dartkb && ($builder_tag == bytecode_interpreter || $builder_tag == bytecode_interpreter_nnbd || $builder_tag == bytecode_mixed || $builder_tag == bytecode_mixed_nnbd) ]
*: Skip # There are still timeouts in the interpreter and mixed modes which cause infra timeouts.
[ $mode == debug && $system == windows ]
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 7f379ab..002795d 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -67,12 +67,6 @@
dart_2/regress_40462_test: SkipSlow
dart_2/trigger_gc_in_native_test: Skip # This test crashes on the bot, but not locally, and infrastructure repeatly fails to locate its coredump.
-[ $builder_tag == vm_nnbd ]
-dart_2/*: SkipByDesign # Legacy tests are not supposed to run on NNBD bots.
-
-[ $builder_tag != vm_nnbd ]
-dart/*: SkipByDesign # Migrated tests are not supposed to run on non-NNBD bots.
-
[ $compiler == app_jitk ]
dart/redirection_type_shuffling_test/none: RuntimeError
dart/snapshot_version_test: RuntimeError
@@ -375,10 +369,16 @@
dart/thread_priority_linux_test: SkipByDesign
dart_2/thread_priority_linux_test: SkipByDesign
-[ $builder_tag == bytecode_interpreter || $hot_reload || $hot_reload_rollback || $compiler != dartk && $compiler != dartkb && $compiler != dartkp ]
+[ $builder_tag == bytecode_interpreter || $builder_tag == bytecode_interpreter_nnbd || $hot_reload || $hot_reload_rollback || $compiler != dartk && $compiler != dartkb && $compiler != dartkp ]
dart/entrypoints/*: SkipByDesign # These tests are for compiler optimizations and very sensitive to when functions are optimized, so they are disabled on hotreload and optcounter bots.
dart_2/entrypoints/*: SkipByDesign # These tests are for compiler optimizations and very sensitive to when functions are optimized, so they are disabled on hotreload and optcounter bots.
+[ $builder_tag == bytecode_interpreter_nnbd || $builder_tag == bytecode_mixed_nnbd || $builder_tag == vm_nnbd ]
+dart_2/*: SkipByDesign # Legacy tests are not supposed to run on NNBD bots.
+
+[ $builder_tag != bytecode_interpreter_nnbd || $builder_tag != bytecode_mixed_nnbd || $builder_tag != vm_nnbd ]
+dart/*: SkipByDesign # Migrated tests are not supposed to run on non-NNBD bots.
+
[ $builder_tag == crossword || $builder_tag == crossword_ast ]
dart/bytecode_with_ast_in_aot_test: SkipByDesign # The test doesn't know location of cross-platform gen_snapshot
dart/emit_aot_size_info_flag_test: SkipByDesign # The test itself cannot determine the location of gen_snapshot (only tools/test.py knows where it is).
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index 4fc79f6..84b121f 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -1034,9 +1034,23 @@
void ConstantPropagator::VisitInstantiateTypeArguments(
InstantiateTypeArgumentsInstr* instr) {
- TypeArguments& instantiator_type_args = TypeArguments::Handle(Z);
- TypeArguments& function_type_args = TypeArguments::Handle(Z);
- if (!instr->type_arguments().IsInstantiated(kCurrentClass)) {
+ const auto& type_arguments_obj =
+ instr->type_arguments()->definition()->constant_value();
+ if (!IsConstant(type_arguments_obj)) {
+ if (IsNonConstant(type_arguments_obj)) {
+ SetValue(instr, non_constant_);
+ }
+ return;
+ }
+ ASSERT(!type_arguments_obj.IsNull());
+ const auto& type_arguments = TypeArguments::Cast(type_arguments_obj);
+ if (type_arguments.IsInstantiated()) {
+ ASSERT(type_arguments.IsCanonical());
+ SetValue(instr, type_arguments);
+ return;
+ }
+ auto& instantiator_type_args = TypeArguments::Handle(Z);
+ if (!type_arguments.IsInstantiated(kCurrentClass)) {
// Type arguments refer to class type parameters.
const Object& instantiator_type_args_obj =
instr->instantiator_type_arguments()->definition()->constant_value();
@@ -1046,7 +1060,8 @@
}
if (IsConstant(instantiator_type_args_obj)) {
instantiator_type_args ^= instantiator_type_args_obj.raw();
- if (instr->type_arguments().CanShareInstantiatorTypeArguments(
+ ASSERT(!instr->instantiator_class().IsNull());
+ if (type_arguments.CanShareInstantiatorTypeArguments(
instr->instantiator_class())) {
SetValue(instr, instantiator_type_args);
return;
@@ -1055,7 +1070,8 @@
return;
}
}
- if (!instr->type_arguments().IsInstantiated(kFunctions)) {
+ auto& function_type_args = TypeArguments::Handle(Z);
+ if (!type_arguments.IsInstantiated(kFunctions)) {
// Type arguments refer to function type parameters.
const Object& function_type_args_obj =
instr->function_type_arguments()->definition()->constant_value();
@@ -1065,8 +1081,8 @@
}
if (IsConstant(function_type_args_obj)) {
function_type_args ^= function_type_args_obj.raw();
- if (instr->type_arguments().CanShareFunctionTypeArguments(
- instr->function())) {
+ ASSERT(!instr->function().IsNull());
+ if (type_arguments.CanShareFunctionTypeArguments(instr->function())) {
SetValue(instr, function_type_args);
return;
}
@@ -1074,8 +1090,8 @@
return;
}
}
- TypeArguments& result = TypeArguments::Handle(
- Z, instr->type_arguments().InstantiateFrom(
+ auto& result = TypeArguments::Handle(
+ Z, type_arguments.InstantiateFrom(
instantiator_type_args, function_type_args, kAllFree, Heap::kOld));
ASSERT(result.IsInstantiated());
result = result.Canonicalize();
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 2d73e68..eac73c3 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -6497,32 +6497,38 @@
DISALLOW_COPY_AND_ASSIGN(InstantiateTypeInstr);
};
-class InstantiateTypeArgumentsInstr : public TemplateDefinition<2, Throws> {
+class InstantiateTypeArgumentsInstr : public TemplateDefinition<3, Throws> {
public:
InstantiateTypeArgumentsInstr(TokenPosition token_pos,
- const TypeArguments& type_arguments,
- const Class& instantiator_class,
- const Function& function,
Value* instantiator_type_arguments,
Value* function_type_arguments,
+ Value* type_arguments,
+ const Class& instantiator_class,
+ const Function& function,
intptr_t deopt_id)
: TemplateDefinition(deopt_id),
token_pos_(token_pos),
- type_arguments_(type_arguments),
instantiator_class_(instantiator_class),
function_(function) {
- ASSERT(type_arguments.IsZoneHandle());
+ // These asserts hold for current uses.
+ ASSERT(type_arguments->BindsToConstant());
+ // Note: Non-dynamic uses never provide a null TypeArguments value.
+ ASSERT(!type_arguments->BoundConstant().IsNull());
+ ASSERT(type_arguments->BoundConstant().IsTypeArguments());
ASSERT(instantiator_class.IsZoneHandle());
+ ASSERT(!instantiator_class.IsNull());
ASSERT(function.IsZoneHandle());
+ ASSERT(!function.IsNull());
SetInputAt(0, instantiator_type_arguments);
SetInputAt(1, function_type_arguments);
+ SetInputAt(2, type_arguments);
}
DECLARE_INSTRUCTION(InstantiateTypeArguments)
Value* instantiator_type_arguments() const { return inputs_[0]; }
Value* function_type_arguments() const { return inputs_[1]; }
- const TypeArguments& type_arguments() const { return type_arguments_; }
+ Value* type_arguments() const { return inputs_[2]; }
const Class& instantiator_class() const { return instantiator_class_; }
const Function& function() const { return function_; }
virtual TokenPosition token_pos() const { return token_pos_; }
@@ -6537,12 +6543,18 @@
const Code& GetStub() const {
bool with_runtime_check;
- if (type_arguments().CanShareInstantiatorTypeArguments(
- instantiator_class(), &with_runtime_check)) {
+ ASSERT(!instantiator_class().IsNull());
+ ASSERT(!function().IsNull());
+ ASSERT(type_arguments()->BindsToConstant());
+ ASSERT(type_arguments()->BoundConstant().IsTypeArguments());
+ const auto& type_args =
+ TypeArguments::Cast(type_arguments()->BoundConstant());
+ if (type_args.CanShareInstantiatorTypeArguments(instantiator_class(),
+ &with_runtime_check)) {
ASSERT(with_runtime_check);
return StubCode::InstantiateTypeArgumentsMayShareInstantiatorTA();
- } else if (type_arguments().CanShareFunctionTypeArguments(
- function(), &with_runtime_check)) {
+ } else if (type_args.CanShareFunctionTypeArguments(function(),
+ &with_runtime_check)) {
ASSERT(with_runtime_check);
return StubCode::InstantiateTypeArgumentsMayShareFunctionTA();
}
@@ -6553,7 +6565,6 @@
private:
const TokenPosition token_pos_;
- const TypeArguments& type_arguments_;
const Class& instantiator_class_;
const Function& function_;
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 8aec81f..f678487 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -3492,7 +3492,7 @@
LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
Zone* zone,
bool opt) const {
- const intptr_t kNumInputs = 2;
+ const intptr_t kNumInputs = 3;
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
@@ -3500,6 +3500,8 @@
InstantiationABI::kInstantiatorTypeArgumentsReg));
locs->set_in(1, Location::RegisterLocation(
InstantiationABI::kFunctionTypeArgumentsReg));
+ locs->set_in(2, Location::RegisterLocation(
+ InstantiationABI::kUninstantiatedTypeArgumentsReg));
locs->set_out(
0, Location::RegisterLocation(InstantiationABI::kResultTypeArgumentsReg));
return locs;
@@ -3514,14 +3516,19 @@
// 'instantiator_type_args_reg' is a TypeArguments object (or null).
// 'function_type_args_reg' is a TypeArguments object (or null).
+ compiler::Label type_arguments_instantiated;
+ ASSERT(!instantiator_class().IsNull());
+ ASSERT(type_arguments()->BindsToConstant());
+ const auto& type_args =
+ TypeArguments::Cast(type_arguments()->BoundConstant());
+
// If both the instantiator and function type arguments are null and if the
// type argument vector instantiated from null becomes a vector of dynamic,
// then use null as the type arguments.
- compiler::Label type_arguments_instantiated;
const bool can_function_type_args_be_null =
function_type_arguments()->CanBe(Object::null_object());
- const intptr_t len = type_arguments().Length();
- if (type_arguments().IsRawWhenInstantiatedFromRaw(len) &&
+ const intptr_t len = type_args.Length();
+ if (type_args.IsRawWhenInstantiatedFromRaw(len) &&
can_function_type_args_be_null) {
ASSERT(result_reg != instantiator_type_args_reg &&
result_reg != function_type_args_reg);
@@ -3533,8 +3540,6 @@
__ b(&type_arguments_instantiated, EQ);
}
// Lookup cache in stub before calling runtime.
- __ LoadObject(InstantiationABI::kUninstantiatedTypeArgumentsReg,
- type_arguments());
compiler->GenerateStubCall(token_pos(), GetStub(),
PcDescriptorsLayout::kOther, locs());
__ Bind(&type_arguments_instantiated);
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 563bbe7..fc84e13 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -2982,7 +2982,7 @@
LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
Zone* zone,
bool opt) const {
- const intptr_t kNumInputs = 2;
+ const intptr_t kNumInputs = 3;
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
@@ -2990,6 +2990,8 @@
InstantiationABI::kInstantiatorTypeArgumentsReg));
locs->set_in(1, Location::RegisterLocation(
InstantiationABI::kFunctionTypeArgumentsReg));
+ locs->set_in(2, Location::RegisterLocation(
+ InstantiationABI::kUninstantiatedTypeArgumentsReg));
locs->set_out(
0, Location::RegisterLocation(InstantiationABI::kResultTypeArgumentsReg));
return locs;
@@ -3001,17 +3003,21 @@
const Register function_type_args_reg = locs()->in(1).reg();
const Register result_reg = locs()->out(0).reg();
+ compiler::Label type_arguments_instantiated;
+ ASSERT(!instantiator_class().IsNull());
+ ASSERT(type_arguments()->BindsToConstant());
+ const auto& type_args =
+ TypeArguments::Cast(type_arguments()->BoundConstant());
// 'instantiator_type_args_reg' is a TypeArguments object (or null).
// 'function_type_args_reg' is a TypeArguments object (or null).
// If both the instantiator and function type arguments are null and if the
// type argument vector instantiated from null becomes a vector of dynamic,
// then use null as the type arguments.
- compiler::Label type_arguments_instantiated;
- const intptr_t len = type_arguments().Length();
+ const intptr_t len = type_args.Length();
const bool can_function_type_args_be_null =
function_type_arguments()->CanBe(Object::null_object());
- if (type_arguments().IsRawWhenInstantiatedFromRaw(len) &&
+ if (type_args.IsRawWhenInstantiatedFromRaw(len) &&
can_function_type_args_be_null) {
compiler::Label non_null_type_args;
ASSERT(result_reg != instantiator_type_args_reg &&
@@ -3026,8 +3032,6 @@
__ Bind(&non_null_type_args);
}
// Lookup cache in stub before calling runtime.
- __ LoadObject(InstantiationABI::kUninstantiatedTypeArgumentsReg,
- type_arguments());
compiler->GenerateStubCall(token_pos(), GetStub(),
PcDescriptorsLayout::kOther, locs());
__ Bind(&type_arguments_instantiated);
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 767fb3f..a7bc3b3 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -2766,7 +2766,7 @@
LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
Zone* zone,
bool opt) const {
- const intptr_t kNumInputs = 2;
+ const intptr_t kNumInputs = 3;
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
@@ -2774,6 +2774,8 @@
InstantiationABI::kInstantiatorTypeArgumentsReg));
locs->set_in(1, Location::RegisterLocation(
InstantiationABI::kFunctionTypeArgumentsReg));
+ locs->set_in(2, Location::RegisterLocation(
+ InstantiationABI::kUninstantiatedTypeArgumentsReg));
locs->set_out(
0, Location::RegisterLocation(InstantiationABI::kResultTypeArgumentsReg));
return locs;
@@ -2785,17 +2787,21 @@
Register function_type_args_reg = locs()->in(1).reg();
Register result_reg = locs()->out(0).reg();
+ compiler::Label type_arguments_instantiated;
+ ASSERT(!instantiator_class().IsNull());
+ ASSERT(type_arguments()->BindsToConstant());
+ const auto& type_args =
+ TypeArguments::Cast(type_arguments()->BoundConstant());
// 'instantiator_type_args_reg' is a TypeArguments object (or null).
// 'function_type_args_reg' is a TypeArguments object (or null).
// If both the instantiator and function type arguments are null and if the
// type argument vector instantiated from null becomes a vector of dynamic,
// then use null as the type arguments.
- compiler::Label type_arguments_instantiated;
- const intptr_t len = type_arguments().Length();
+ const intptr_t len = type_args.Length();
const bool can_function_type_args_be_null =
function_type_arguments()->CanBe(Object::null_object());
- if (type_arguments().IsRawWhenInstantiatedFromRaw(len) &&
+ if (type_args.IsRawWhenInstantiatedFromRaw(len) &&
can_function_type_args_be_null) {
compiler::Label non_null_type_args;
ASSERT(result_reg != instantiator_type_args_reg &&
@@ -2810,8 +2816,6 @@
__ Bind(&non_null_type_args);
}
// Lookup cache in stub before calling runtime.
- __ LoadObject(InstantiationABI::kUninstantiatedTypeArgumentsReg,
- type_arguments());
compiler->GenerateStubCall(token_pos(), GetStub(),
PcDescriptorsLayout::kOther, locs());
__ Bind(&type_arguments_instantiated);
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc
index 3f921d2..62b7000 100644
--- a/runtime/vm/compiler/backend/il_printer.cc
+++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -688,13 +688,15 @@
}
void InstantiateTypeArgumentsInstr::PrintOperandsTo(BaseTextBuffer* f) const {
- const String& type_args = String::Handle(type_arguments().Name());
- f->Printf("%s,", type_args.ToCString());
- f->AddString(" instantiator_type_args(");
+ type_arguments()->PrintTo(f);
+ f->AddString(", instantiator_type_args(");
instantiator_type_arguments()->PrintTo(f);
f->AddString("), function_type_args(");
function_type_arguments()->PrintTo(f);
- f->Printf("), instantiator_class(%s)", instantiator_class().ToCString());
+ f->Printf(")");
+ if (!instantiator_class().IsNull()) {
+ f->Printf(", instantiator_class(%s)", instantiator_class().ToCString());
+ }
}
void AllocateContextInstr::PrintOperandsTo(BaseTextBuffer* f) const {
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 70f492c..d3842d1 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -3016,7 +3016,7 @@
LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
Zone* zone,
bool opt) const {
- const intptr_t kNumInputs = 2;
+ const intptr_t kNumInputs = 3;
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
@@ -3024,6 +3024,8 @@
InstantiationABI::kInstantiatorTypeArgumentsReg));
locs->set_in(1, Location::RegisterLocation(
InstantiationABI::kFunctionTypeArgumentsReg));
+ locs->set_in(2, Location::RegisterLocation(
+ InstantiationABI::kUninstantiatedTypeArgumentsReg));
locs->set_out(
0, Location::RegisterLocation(InstantiationABI::kResultTypeArgumentsReg));
return locs;
@@ -3035,17 +3037,21 @@
Register function_type_args_reg = locs()->in(1).reg();
Register result_reg = locs()->out(0).reg();
+ compiler::Label type_arguments_instantiated;
+ ASSERT(!instantiator_class().IsNull());
+ ASSERT(type_arguments()->BindsToConstant());
+ const auto& type_args =
+ TypeArguments::Cast(type_arguments()->BoundConstant());
// 'instantiator_type_args_reg' is a TypeArguments object (or null).
// 'function_type_args_reg' is a TypeArguments object (or null).
// If both the instantiator and function type arguments are null and if the
// type argument vector instantiated from null becomes a vector of dynamic,
// then use null as the type arguments.
- compiler::Label type_arguments_instantiated;
- const intptr_t len = type_arguments().Length();
+ const intptr_t len = type_args.Length();
const bool can_function_type_args_be_null =
function_type_arguments()->CanBe(Object::null_object());
- if (type_arguments().IsRawWhenInstantiatedFromRaw(len) &&
+ if (type_args.IsRawWhenInstantiatedFromRaw(len) &&
can_function_type_args_be_null) {
compiler::Label non_null_type_args;
ASSERT(result_reg != instantiator_type_args_reg &&
@@ -3059,8 +3065,7 @@
__ j(EQUAL, &type_arguments_instantiated, compiler::Assembler::kNearJump);
__ Bind(&non_null_type_args);
}
- __ LoadObject(InstantiationABI::kUninstantiatedTypeArgumentsReg,
- type_arguments());
+ // Lookup cache in stub before calling runtime.
compiler->GenerateStubCall(token_pos(), GetStub(),
PcDescriptorsLayout::kOther, locs());
__ Bind(&type_arguments_instantiated);
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index 8f00b30..8d750b7 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -941,15 +941,20 @@
}
Fragment BaseFlowGraphBuilder::InstantiateTypeArguments(
- const TypeArguments& type_arguments) {
+ const TypeArguments& type_arguments_value) {
+ Fragment instructions;
+ instructions += Constant(type_arguments_value);
+
+ Value* type_arguments = Pop();
Value* function_type_args = Pop();
Value* instantiator_type_args = Pop();
const Class& instantiator_class = Class::ZoneHandle(Z, function_.Owner());
InstantiateTypeArgumentsInstr* instr = new (Z) InstantiateTypeArgumentsInstr(
- TokenPosition::kNoSource, type_arguments, instantiator_class, function_,
- instantiator_type_args, function_type_args, GetNextDeoptId());
+ TokenPosition::kNoSource, instantiator_type_args, function_type_args,
+ type_arguments, instantiator_class, function_, GetNextDeoptId());
Push(instr);
- return Fragment(instr);
+ instructions += Fragment(instr);
+ return instructions;
}
Fragment BaseFlowGraphBuilder::LoadClassId() {
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 3d9cb93..449f1d9 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -199,26 +199,18 @@
const bool has_local_variables = (flags & Code::kHasLocalVariablesFlag) != 0;
const bool has_nullable_fields = (flags & Code::kHasNullableFieldsFlag) != 0;
const bool has_closures = (flags & Code::kHasClosuresFlag) != 0;
- const bool has_parameters_flags = (flags & Code::kHasParameterFlagsFlag) != 0;
+ const bool has_parameter_flags = (flags & Code::kHasParameterFlagsFlag) != 0;
const bool has_forwarding_stub_target =
(flags & Code::kHasForwardingStubTargetFlag) != 0;
const bool has_default_function_type_args =
(flags & Code::kHasDefaultFunctionTypeArgsFlag) != 0;
- if (has_parameters_flags) {
- intptr_t num_params = reader_.ReadUInt();
- ASSERT(num_params ==
- function.NumParameters() - function.NumImplicitParameters());
- for (intptr_t i = function.NumImplicitParameters();
- i < function.NumParameters(); ++i) {
- const intptr_t flags = reader_.ReadUInt();
- if ((flags & Parameter::kIsRequiredFlag) != 0) {
- RELEASE_ASSERT(i >= function.num_fixed_parameters());
- function.SetIsRequiredAt(i);
- }
+ if (has_parameter_flags) {
+ intptr_t num_flags = reader_.ReadUInt();
+ for (intptr_t i = 0; i < num_flags; ++i) {
+ reader_.ReadUInt();
}
}
- function.TruncateUnusedParameterFlags();
if (has_forwarding_stub_target) {
reader_.ReadUInt();
}
@@ -353,22 +345,19 @@
AlternativeReadingScope alt(&reader_, function.bytecode_offset());
const intptr_t flags = reader_.ReadUInt();
- const bool has_parameters_flags =
+ const bool has_parameter_flags =
(flags & Code::kHasParameterFlagsFlag) != 0;
const bool has_forwarding_stub_target =
(flags & Code::kHasForwardingStubTargetFlag) != 0;
const bool has_default_function_type_args =
(flags & Code::kHasDefaultFunctionTypeArgsFlag) != 0;
- if (has_parameters_flags) {
- intptr_t num_params = reader_.ReadUInt();
- ASSERT(num_params ==
- function.NumParameters() - function.NumImplicitParameters());
- for (intptr_t i = 0; i < num_params; ++i) {
+ if (has_parameter_flags) {
+ intptr_t num_flags = reader_.ReadUInt();
+ for (intptr_t i = 0; i < num_flags; ++i) {
reader_.ReadUInt();
}
}
-
if (has_forwarding_stub_target) {
reader_.ReadUInt();
}
@@ -2245,6 +2234,7 @@
const int kHasCustomScriptFlag = 1 << 22;
const int kHasAttributesFlag = 1 << 23;
const int kIsExtensionMemberFlag = 1 << 24;
+ const int kHasParameterFlagsFlag = 1 << 25;
const intptr_t num_functions = reader_.ReadListLength();
ASSERT(function_index_ + num_functions == functions_->Length());
@@ -2395,6 +2385,20 @@
function.SetParameterTypeAt(param_index, type);
}
+ if ((flags & kHasParameterFlagsFlag) != 0) {
+ const intptr_t length = reader_.ReadUInt();
+ const intptr_t offset = function.NumImplicitParameters();
+ for (intptr_t i = 0; i < length; i++) {
+ const intptr_t param_flags = reader_.ReadUInt();
+ if ((param_flags & Parameter::kIsRequiredFlag) != 0) {
+ RELEASE_ASSERT(function.HasOptionalNamedParameters());
+ RELEASE_ASSERT(i + offset >= function.num_fixed_parameters());
+ function.SetIsRequiredAt(i + offset);
+ }
+ }
+ }
+ function.TruncateUnusedParameterFlags();
+
type ^= ReadObject();
function.set_result_type(type);
@@ -3054,7 +3058,7 @@
AlternativeReadingScope alt(&reader_, target.bytecode_offset());
const intptr_t flags = reader_.ReadUInt();
- const bool has_parameters_flags = (flags & Code::kHasParameterFlagsFlag) != 0;
+ const bool has_parameter_flags = (flags & Code::kHasParameterFlagsFlag) != 0;
const bool has_forwarding_stub_target =
(flags & Code::kHasForwardingStubTargetFlag) != 0;
const bool has_default_function_type_args =
@@ -3066,22 +3070,15 @@
const bool body_has_generic_covariant_impl_type_checks =
proc_attrs.has_non_this_uses || proc_attrs.has_tearoff_uses;
- if (has_parameters_flags) {
+ if (has_parameter_flags) {
const intptr_t num_params = reader_.ReadUInt();
const intptr_t num_implicit_params = function.NumImplicitParameters();
- const intptr_t num_fixed_params = function.num_fixed_parameters();
for (intptr_t i = 0; i < num_params; ++i) {
const intptr_t flags = reader_.ReadUInt();
bool is_covariant = (flags & Parameter::kIsCovariantFlag) != 0;
bool is_generic_covariant_impl =
(flags & Parameter::kIsGenericCovariantImplFlag) != 0;
- bool is_required = (flags & Parameter::kIsRequiredFlag) != 0;
-
- if (is_required) {
- RELEASE_ASSERT(num_implicit_params + i >= num_fixed_params);
- function.SetIsRequiredAt(num_implicit_params + i);
- }
LocalVariable* variable =
parsed_function->ParameterVariable(num_implicit_params + i);
@@ -3101,7 +3098,6 @@
}
}
}
- function.TruncateUnusedParameterFlags();
if (has_forwarding_stub_target) {
const intptr_t cp_index = reader_.ReadUInt();
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
index 8f5f57c..c68f655 100644
--- a/runtime/vm/type_testing_stubs.cc
+++ b/runtime/vm/type_testing_stubs.cc
@@ -523,8 +523,8 @@
// type_arguments <- Constant(#TypeArguments: [ ... ])
//
// Case b)
- // type_arguments <- InstantiateTypeArguments(
- // <type-expr-with-parameters>, ita, fta)
+ // type_arguments <- InstantiateTypeArguments(ita, fta, uta)
+ // (where uta may or may not be a constant TypeArguments object)
//
// Case c)
// type_arguments <- LoadField(vx)
@@ -543,8 +543,10 @@
type_usage_info->UseTypeArgumentsInInstanceCreation(klass, type_arguments);
} else if (InstantiateTypeArgumentsInstr* instantiate =
type_arguments->AsInstantiateTypeArguments()) {
- const TypeArguments& ta = instantiate->type_arguments();
- ASSERT(!ta.IsNull());
+ ASSERT(instantiate->type_arguments()->BindsToConstant());
+ ASSERT(!instantiate->type_arguments()->BoundConstant().IsNull());
+ const auto& ta =
+ TypeArguments::Cast(instantiate->type_arguments()->BoundConstant());
type_usage_info->UseTypeArgumentsInInstanceCreation(klass, ta);
} else if (LoadFieldInstr* load_field = type_arguments->AsLoadField()) {
Definition* instance = load_field->instance()->definition();
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index d25eeaa..f9dadb3 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -2,11 +2,6 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
-[ $builder_tag == bytecode_interpreter ]
-LibTest/collection/ListBase/ListBase_class_A01_t04: Slow, Pass
-LibTest/collection/ListBase/ListBase_class_A01_t05: Slow, Pass
-LibTest/collection/ListBase/ListBase_class_A01_t06: Slow, Pass
-
[ $compiler == dartkb ]
LibTest/isolate/Isolate/kill_A01_t01: Skip # Issue 37699
LibTest/isolate/Isolate/pause_A01_t01: Skip # Issue 37699
@@ -348,6 +343,11 @@
[ $runtime != vm && ($compiler == dartk || $compiler == dartkb) ]
Language/Classes/Constructors/Constant_Constructors/potentially_constant_expression_t01: Crash
+[ $builder_tag == bytecode_interpreter || $builder_tag == bytecode_interpreter_nnbd ]
+LibTest/collection/ListBase/ListBase_class_A01_t04: Slow, Pass
+LibTest/collection/ListBase/ListBase_class_A01_t05: Slow, Pass
+LibTest/collection/ListBase/ListBase_class_A01_t06: Slow, Pass
+
[ $compiler == dartk || $compiler == dartkb ]
Language/Libraries_and_Scripts/Scripts/top_level_main_t01: Crash
LibTest/isolate/SendPort/send_A01_t02: Crash
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index 8aa80ab..1a224c7 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -2,11 +2,6 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
-[ $builder_tag == bytecode_interpreter ]
-LibTest/collection/ListBase/ListBase_class_A01_t04: Slow, Pass
-LibTest/collection/ListBase/ListBase_class_A01_t05: Slow, Pass
-LibTest/collection/ListBase/ListBase_class_A01_t06: Slow, Pass
-
[ $compiler == dartkb ]
LibTest/isolate/Isolate/kill_A01_t01: Skip # Issue 37699
LibTest/isolate/Isolate/pause_A01_t01: Skip # Issue 37699
@@ -192,6 +187,11 @@
[ $runtime != vm && ($compiler == dartk || $compiler == dartkb) ]
Language/Classes/Constructors/Constant_Constructors/potentially_constant_expression_t01: Crash
+[ $builder_tag == bytecode_interpreter || $builder_tag == bytecode_interpreter_nnbd ]
+LibTest/collection/ListBase/ListBase_class_A01_t04: Slow, Pass
+LibTest/collection/ListBase/ListBase_class_A01_t05: Slow, Pass
+LibTest/collection/ListBase/ListBase_class_A01_t06: Slow, Pass
+
[ $compiler == dartk || $compiler == dartkb ]
Language/Libraries_and_Scripts/Scripts/top_level_main_t01: Crash
LibTest/isolate/SendPort/send_A01_t02: Crash
diff --git a/tests/standalone/standalone_kernel.status b/tests/standalone/standalone_kernel.status
index 1134509..199fb5a 100644
--- a/tests/standalone/standalone_kernel.status
+++ b/tests/standalone/standalone_kernel.status
@@ -8,9 +8,6 @@
fragmentation_typed_data_test: Pass, Slow # GC heavy
io/process_sync_test: Pass, Slow # Spawns synchronously subprocesses in sequence.
-[ $builder_tag == bytecode_interpreter ]
-io/http_big_header_test: SkipSlow # Timeout
-
[ $compiler == dartkb ]
no_lazy_dispatchers_test: SkipByDesign # KBC interpreter doesn't support --no_lazy_dispatchers
@@ -114,5 +111,8 @@
io/web_socket_compression_test: Skip # Timeout
io/web_socket_test: Skip # Timeout
+[ $builder_tag == bytecode_interpreter || $builder_tag == bytecode_interpreter_nnbd ]
+io/http_big_header_test: SkipSlow # Timeout
+
[ $compiler != dartk && $compiler != dartkb && $compiler != dartkp || $compiler == dartkp && $system == windows ]
entrypoints_verification_test: SkipByDesign # Requires VM to run. Cannot run in precompiled Windows because the DLL is linked against dart.exe instead of dart_precompiled_runtime.exe.
diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status
index 1134509..199fb5a 100644
--- a/tests/standalone_2/standalone_2_kernel.status
+++ b/tests/standalone_2/standalone_2_kernel.status
@@ -8,9 +8,6 @@
fragmentation_typed_data_test: Pass, Slow # GC heavy
io/process_sync_test: Pass, Slow # Spawns synchronously subprocesses in sequence.
-[ $builder_tag == bytecode_interpreter ]
-io/http_big_header_test: SkipSlow # Timeout
-
[ $compiler == dartkb ]
no_lazy_dispatchers_test: SkipByDesign # KBC interpreter doesn't support --no_lazy_dispatchers
@@ -114,5 +111,8 @@
io/web_socket_compression_test: Skip # Timeout
io/web_socket_test: Skip # Timeout
+[ $builder_tag == bytecode_interpreter || $builder_tag == bytecode_interpreter_nnbd ]
+io/http_big_header_test: SkipSlow # Timeout
+
[ $compiler != dartk && $compiler != dartkb && $compiler != dartkp || $compiler == dartkp && $system == windows ]
entrypoints_verification_test: SkipByDesign # Requires VM to run. Cannot run in precompiled Windows because the DLL is linked against dart.exe instead of dart_precompiled_runtime.exe.
diff --git a/tools/VERSION b/tools/VERSION
index 8d4e282..f2e2efb 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 10
PATCH 0
-PRERELEASE 123
+PRERELEASE 124
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index d540f0f..2b30212 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -944,6 +944,80 @@
]
}
},
+ "dartkb-interpret-strong-(linux|mac|win)-product-(ia32|x64|arm|arm64|simarm|simarm64)": {
+ "options": {
+ "builder-tag": "bytecode_interpreter_nnbd",
+ "enable-experiment": [
+ "non-nullable"
+ ],
+ "gen-kernel-options": [
+ "--gen-bytecode",
+ "--drop-ast",
+ "--bytecode-options=source-positions,annotations",
+ "--sound-null-safety"
+ ],
+ "vm-options": [
+ "--enable_interpreter",
+ "--compilation-counter-threshold=-1",
+ "--sound-null-safety"
+ ]
+ }
+ },
+ "dartkb-interpret-strong-(linux|mac|win)-(debug|release)-(ia32|x64|arm|arm64|simarm|simarm64)": {
+ "options": {
+ "builder-tag": "bytecode_interpreter_nnbd",
+ "enable-experiment": [
+ "non-nullable"
+ ],
+ "gen-kernel-options": [
+ "--gen-bytecode",
+ "--drop-ast",
+ "--bytecode-options=source-positions,annotations,local-var-info,debugger-stops",
+ "--sound-null-safety"
+ ],
+ "vm-options": [
+ "--enable_interpreter",
+ "--compilation-counter-threshold=-1",
+ "--sound-null-safety"
+ ]
+ }
+ },
+ "dartkb-mixed-strong-(linux|mac|win)-(debug|release)-(ia32|x64|arm|arm64|simarm|simarm64)": {
+ "options": {
+ "builder-tag": "bytecode_mixed_nnbd",
+ "enable-experiment": [
+ "non-nullable"
+ ],
+ "gen-kernel-options": [
+ "--gen-bytecode",
+ "--drop-ast",
+ "--bytecode-options=source-positions,annotations,local-var-info,debugger-stops",
+ "--sound-null-safety"
+ ],
+ "vm-options": [
+ "--enable_interpreter",
+ "--sound-null-safety"
+ ]
+ }
+ },
+ "dartkb-mixed-strong-(linux|mac|win)-product-(ia32|x64|arm|arm64|simarm|simarm64)": {
+ "options": {
+ "builder-tag": "bytecode_mixed_nnbd",
+ "enable-experiment": [
+ "non-nullable"
+ ],
+ "gen-kernel-options": [
+ "--gen-bytecode",
+ "--drop-ast",
+ "--bytecode-options=source-positions,annotations",
+ "--sound-null-safety"
+ ],
+ "vm-options": [
+ "--enable_interpreter",
+ "--sound-null-safety"
+ ]
+ }
+ },
"dartdevk-checked-(linux|mac|win)-(debug|product|release)-(chrome|firefox)": {
"options": {
"checked": true,