Unverified Commit e7baef08 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Use DiagnosticableMixin instead of Diagnosticable for some conditionals. (#49726)

This PR fixes #49647 by changing DiagnosticableMixin.toDiagnosticsNode and other things to accept DiagnosticableMixin instead of requiring Diagnosticable.
parent 6ee8b654
......@@ -8,7 +8,7 @@ import 'colors.dart';
/// An [IconThemeData] subclass that automatically resolves its [color] when retrieved
/// using [IconTheme.of].
class CupertinoIconThemeData extends IconThemeData with DiagnosticableMixin {
class CupertinoIconThemeData extends IconThemeData with DiagnosticableMixin implements Diagnosticable {
/// Creates a [CupertinoIconThemeData].
///
/// The opacity applies to both explicit and default icon colors. The value
......
......@@ -351,7 +351,7 @@ class FlutterErrorDetails extends Diagnosticable {
return longMessage;
}
Diagnosticable _exceptionToDiagnosticable() {
DiagnosticableMixin _exceptionToDiagnosticable() {
if (exception is FlutterError) {
return exception as FlutterError;
}
......@@ -374,7 +374,7 @@ class FlutterErrorDetails extends Diagnosticable {
if (kReleaseMode) {
return DiagnosticsNode.message(formatException());
}
final Diagnosticable diagnosticable = _exceptionToDiagnosticable();
final DiagnosticableMixin diagnosticable = _exceptionToDiagnosticable();
DiagnosticsNode summary;
if (diagnosticable != null) {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
......@@ -388,7 +388,7 @@ class FlutterErrorDetails extends Diagnosticable {
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
final DiagnosticsNode verb = ErrorDescription('thrown${ context != null ? ErrorDescription(" $context") : ""}');
final Diagnosticable diagnosticable = _exceptionToDiagnosticable();
final DiagnosticableMixin diagnosticable = _exceptionToDiagnosticable();
if (exception is NullThrownError) {
properties.add(ErrorDescription('The null value was $verb.'));
} else if (exception is num) {
......
......@@ -2640,7 +2640,7 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final T v = value;
List<Map<String, Object>> properties;
if (delegate.expandPropertyValues && delegate.includeProperties && v is Diagnosticable && getProperties().isEmpty) {
if (delegate.expandPropertyValues && delegate.includeProperties && v is DiagnosticableMixin && getProperties().isEmpty) {
// Exclude children for expanded nodes to avoid cycles.
delegate = delegate.copyWith(subtreeDepth: 0, includeProperties: false);
properties = DiagnosticsNode.toJsonList(
......@@ -2666,7 +2666,7 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
json['exception'] = exception.toString();
json['propertyType'] = propertyType.toString();
json['defaultLevel'] = describeEnum(_defaultLevel);
if (value is Diagnosticable || value is DiagnosticsNode)
if (value is DiagnosticableMixin || value is DiagnosticsNode)
json['isDiagnosticableValue'] = true;
if (v is num)
// Workaround for https://github.com/flutter/flutter/issues/39937#issuecomment-529558033.
......@@ -2846,7 +2846,7 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
if (object is DiagnosticsNode) {
return object.getProperties();
}
if (object is Diagnosticable) {
if (object is DiagnosticableMixin) {
return object.toDiagnosticsNode(style: style).getProperties();
}
}
......@@ -2860,7 +2860,7 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
if (object is DiagnosticsNode) {
return object.getChildren();
}
if (object is Diagnosticable) {
if (object is DiagnosticableMixin) {
return object.toDiagnosticsNode(style: style).getChildren();
}
}
......@@ -2870,8 +2870,8 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
/// [DiagnosticsNode] that lazily calls the associated [Diagnosticable] [value]
/// to implement [getChildren] and [getProperties].
class DiagnosticableNode<T extends Diagnosticable> extends DiagnosticsNode {
/// Create a diagnostics describing a [Diagnosticable] value.
class DiagnosticableNode<T extends DiagnosticableMixin> extends DiagnosticsNode {
/// Create a diagnostics describing a [DiagnosticableMixin] value.
///
/// The [value] argument must not be null.
DiagnosticableNode({
......@@ -2991,7 +2991,7 @@ String describeEnum(Object enumEntry) {
}
/// Builder to accumulate properties and configuration used to assemble a
/// [DiagnosticsNode] from a [Diagnosticable] object.
/// [DiagnosticsNode] from a [DiagnosticableMixin] object.
class DiagnosticPropertiesBuilder {
/// Creates a [DiagnosticPropertiesBuilder] with [properties] initialize to
/// an empty array.
......@@ -3053,10 +3053,8 @@ abstract class Diagnosticable with DiagnosticableMixin {
const Diagnosticable();
}
/// A mixin class that provides the implementation for [Diagnosticable].
///
/// This mixin can be used to add diagnostics to a class which already has an
/// base class.
/// A mixin class for providing string and [DiagnosticsNode] debug
/// representations describing the properties of an object.
///
/// The string debug representation is generated from the intermediate
/// [DiagnosticsNode] representation. The [DiagnosticsNode] representation is
......@@ -3108,9 +3106,9 @@ mixin DiagnosticableMixin {
/// relationship between the parent and the node. For example, pass
/// [DiagnosticsTreeStyle.offstage] to indicate that a node is offstage.
DiagnosticsNode toDiagnosticsNode({ String name, DiagnosticsTreeStyle style }) {
return DiagnosticableNode<Diagnosticable>(
return DiagnosticableNode<DiagnosticableMixin>(
name: name,
value: this as Diagnosticable,
value: this,
style: style,
);
}
......@@ -3338,8 +3336,8 @@ mixin DiagnosticableMixin {
/// See also:
///
/// * [DiagnosticableTreeMixin], a mixin that implements this class.
/// * [Diagnosticable], which should be used instead of this class to provide
/// diagnostics for objects without children.
/// * [DiagnosticableMixin], which should be used instead of this class to
/// provide diagnostics for objects without children.
abstract class DiagnosticableTree extends Diagnosticable {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
......@@ -3643,7 +3641,7 @@ abstract class DiagnosticsSerializationDelegate {
/// will be included.
bool get includeProperties;
/// Whether properties that have a [Diagnosticable] as value should be
/// Whether properties that have a [DiagnosticableMixin] as value should be
/// expanded.
bool get expandPropertyValues;
......
......@@ -38,7 +38,7 @@ abstract class TickerProvider {
Ticker createTicker(TickerCallback onTick);
}
// TODO(jacobr): make Ticker Diagnosticable to simplify reporting errors
// TODO(jacobr): make Ticker use DiagnosticableMixin to simplify reporting errors
// related to a ticker.
/// Calls its callback once per animation frame.
///
......
......@@ -110,7 +110,7 @@ class KeySet<T extends KeyboardKey> {
/// This is a thin wrapper around a [Set], but changes the equality comparison
/// from an identity comparison to a contents comparison so that non-identical
/// sets with the same keys in them will compare as equal.
class LogicalKeySet extends KeySet<LogicalKeyboardKey> with DiagnosticableMixin {
class LogicalKeySet extends KeySet<LogicalKeyboardKey> with DiagnosticableMixin implements Diagnosticable {
/// A constructor for making a [LogicalKeySet] of up to four keys.
///
/// If you need a set of more than four keys, use [LogicalKeySet.fromSet].
......@@ -201,7 +201,7 @@ class ShortcutMapProperty extends DiagnosticsProperty<Map<LogicalKeySet, Intent>
///
/// A [ShortcutManager] is obtained by calling [Shortcuts.of] on the context of
/// the widget that you want to find a manager for.
class ShortcutManager extends ChangeNotifier with DiagnosticableMixin {
class ShortcutManager extends ChangeNotifier with DiagnosticableMixin implements Diagnosticable {
/// Constructs a [ShortcutManager].
///
/// The [shortcuts] argument must not be null.
......
......@@ -635,7 +635,7 @@ class _DiagnosticsPathNode {
}
List<_DiagnosticsPathNode> _followDiagnosticableChain(
List<Diagnosticable> chain, {
List<DiagnosticableMixin> chain, {
String name,
DiagnosticsTreeStyle style,
}) {
......@@ -644,7 +644,7 @@ List<_DiagnosticsPathNode> _followDiagnosticableChain(
return path;
DiagnosticsNode diagnostic = chain.first.toDiagnosticsNode(name: name, style: style);
for (int i = 1; i < chain.length; i += 1) {
final Diagnosticable target = chain[i];
final DiagnosticableMixin target = chain[i];
bool foundMatch = false;
final List<DiagnosticsNode> children = diagnostic.getChildren();
for (int j = 0; j < children.length; j += 1) {
......@@ -1550,7 +1550,7 @@ mixin WidgetInspectorService {
return true;
}
final Object value = node.value;
if (value is! Diagnosticable) {
if (value is! DiagnosticableMixin) {
return true;
}
if (value is! Element || !isWidgetCreationTracked()) {
......
......@@ -180,7 +180,7 @@ void validatePropertyJsonSerializationHelper(final Map<String, Object> json, Dia
}
expect(json['propertyType'], equals(property.propertyType.toString()));
expect(json.containsKey('defaultLevel'), isTrue);
if (property.value is Diagnosticable) {
if (property.value is DiagnosticableMixin) {
expect(json['isDiagnosticableValue'], isTrue);
} else {
expect(json.containsKey('isDiagnosticableValue'), isFalse);
......
......@@ -322,5 +322,29 @@ void main() {
expect(description.length, equals(1));
expect(description[0], equals('shortcuts: <Debug Label>'));
});
test('Shortcuts diagnostics work when manager specified.', () {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
Shortcuts(
manager: ShortcutManager(),
shortcuts: <LogicalKeySet, Intent>{
LogicalKeySet(
LogicalKeyboardKey.keyA,
LogicalKeyboardKey.keyB,
): const Intent(ActivateAction.key)
},
).debugFillProperties(builder);
final List<String> description = builder.properties
.where((DiagnosticsNode node) {
return !node.isFiltered(DiagnosticLevel.info);
})
.map((DiagnosticsNode node) => node.toString())
.toList();
expect(description.length, equals(2));
expect(description[0], equalsIgnoringHashCodes('manager: ShortcutManager#00000(shortcuts: {})'));
expect(description[1], equalsIgnoringHashCodes('shortcuts: {{Key A + Key B}: Intent#00000(key: [<ActivateAction>])}'));
});
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment