Unverified Commit eb9160eb authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Extract DiagnosticsNode serializer from WidgetInspector (#34012)

parent 9579f002
...@@ -483,7 +483,7 @@ class CupertinoTextField extends StatefulWidget { ...@@ -483,7 +483,7 @@ class CupertinoTextField extends StatefulWidget {
properties.add(DiagnosticsProperty<bool>('expands', expands, defaultValue: false)); properties.add(DiagnosticsProperty<bool>('expands', expands, defaultValue: false));
properties.add(IntProperty('maxLength', maxLength, defaultValue: null)); properties.add(IntProperty('maxLength', maxLength, defaultValue: null));
properties.add(FlagProperty('maxLengthEnforced', value: maxLengthEnforced, ifTrue: 'max length enforced')); properties.add(FlagProperty('maxLengthEnforced', value: maxLengthEnforced, ifTrue: 'max length enforced'));
properties.add(DiagnosticsProperty<Color>('cursorColor', cursorColor, defaultValue: null)); properties.add(ColorProperty('cursorColor', cursorColor, defaultValue: null));
properties.add(FlagProperty('selectionEnabled', value: selectionEnabled, defaultValue: true, ifFalse: 'selection disabled')); properties.add(FlagProperty('selectionEnabled', value: selectionEnabled, defaultValue: true, ifFalse: 'selection disabled'));
properties.add(DiagnosticsProperty<ScrollController>('scrollController', scrollController, defaultValue: null)); properties.add(DiagnosticsProperty<ScrollController>('scrollController', scrollController, defaultValue: null));
properties.add(DiagnosticsProperty<ScrollPhysics>('scrollPhysics', scrollPhysics, defaultValue: null)); properties.add(DiagnosticsProperty<ScrollPhysics>('scrollPhysics', scrollPhysics, defaultValue: null));
......
...@@ -259,11 +259,11 @@ class CupertinoThemeData extends Diagnosticable { ...@@ -259,11 +259,11 @@ class CupertinoThemeData extends Diagnosticable {
super.debugFillProperties(properties); super.debugFillProperties(properties);
const CupertinoThemeData defaultData = CupertinoThemeData(); const CupertinoThemeData defaultData = CupertinoThemeData();
properties.add(EnumProperty<Brightness>('brightness', brightness, defaultValue: defaultData.brightness)); properties.add(EnumProperty<Brightness>('brightness', brightness, defaultValue: defaultData.brightness));
properties.add(DiagnosticsProperty<Color>('primaryColor', primaryColor, defaultValue: defaultData.primaryColor)); properties.add(ColorProperty('primaryColor', primaryColor, defaultValue: defaultData.primaryColor));
properties.add(DiagnosticsProperty<Color>('primaryContrastingColor', primaryContrastingColor, defaultValue: defaultData.primaryContrastingColor)); properties.add(ColorProperty('primaryContrastingColor', primaryContrastingColor, defaultValue: defaultData.primaryContrastingColor));
properties.add(DiagnosticsProperty<CupertinoTextThemeData>('textTheme', textTheme, defaultValue: defaultData.textTheme)); properties.add(DiagnosticsProperty<CupertinoTextThemeData>('textTheme', textTheme, defaultValue: defaultData.textTheme));
properties.add(DiagnosticsProperty<Color>('barBackgroundColor', barBackgroundColor, defaultValue: defaultData.barBackgroundColor)); properties.add(ColorProperty('barBackgroundColor', barBackgroundColor, defaultValue: defaultData.barBackgroundColor));
properties.add(DiagnosticsProperty<Color>('scaffoldBackgroundColor', scaffoldBackgroundColor, defaultValue: defaultData.scaffoldBackgroundColor)); properties.add(ColorProperty('scaffoldBackgroundColor', scaffoldBackgroundColor, defaultValue: defaultData.scaffoldBackgroundColor));
} }
} }
......
...@@ -1515,7 +1515,8 @@ abstract class DiagnosticsNode { ...@@ -1515,7 +1515,8 @@ abstract class DiagnosticsNode {
String get _separator => showSeparator ? ':' : ''; String get _separator => showSeparator ? ':' : '';
/// Serialize the node excluding its descendants to a JSON map. /// Serialize the node to a JSON map according to the configuration provided
/// in the [DiagnosticsSerializationDelegate].
/// ///
/// Subclasses should override if they have additional properties that are /// Subclasses should override if they have additional properties that are
/// useful for the GUI tools that consume this JSON. /// useful for the GUI tools that consume this JSON.
...@@ -1526,7 +1527,7 @@ abstract class DiagnosticsNode { ...@@ -1526,7 +1527,7 @@ abstract class DiagnosticsNode {
/// by this method and interactive tree views in the Flutter IntelliJ /// by this method and interactive tree views in the Flutter IntelliJ
/// plugin. /// plugin.
@mustCallSuper @mustCallSuper
Map<String, Object> toJsonMap() { Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object> data = <String, Object>{ final Map<String, Object> data = <String, Object>{
'description': toDescription(), 'description': toDescription(),
'type': runtimeType.toString(), 'type': runtimeType.toString(),
...@@ -1561,9 +1562,56 @@ abstract class DiagnosticsNode { ...@@ -1561,9 +1562,56 @@ abstract class DiagnosticsNode {
if (allowNameWrap) if (allowNameWrap)
data['allowNameWrap'] = allowNameWrap; data['allowNameWrap'] = allowNameWrap;
data.addAll(delegate.additionalNodeProperties(this));
if (delegate.includeProperties) {
final List<DiagnosticsNode> properties = getProperties();
data['properties'] = toJsonList(
delegate.filterProperties(properties, this),
this,
delegate,
);
}
if (delegate.subtreeDepth > 0) {
final List<DiagnosticsNode> children = getChildren();
data['children'] = toJsonList(
delegate.filterChildren(children, this),
this,
delegate,
);
}
return data; return data;
} }
/// Serializes a [List] of [DiagnosticsNode]s to a JSON list according to
/// the configuration provided by the [DiagnosticsSerializationDelegate].
///
/// The provided `nodes` may be properties or children of the `parent`
/// [DiagnosticsNode].
static List<Map<String, Object>> toJsonList(
List<DiagnosticsNode> nodes,
DiagnosticsNode parent,
DiagnosticsSerializationDelegate delegate,
) {
bool truncated = false;
if (nodes == null)
return const <Map<String, Object>>[];
final int originalNodeCount = nodes.length;
nodes = delegate.truncateNodesList(nodes, parent);
if (nodes.length != originalNodeCount) {
nodes.add(DiagnosticsNode.message('...'));
truncated = true;
}
final List<Map<String, Object>> json = nodes.map<Map<String, Object>>((DiagnosticsNode node) {
return node.toJsonMap(delegate.delegateForNode(node));
}).toList();
if (truncated)
json.last['truncated'] = true;
return json;
}
/// Returns a string representation of this diagnostic that is compatible with /// Returns a string representation of this diagnostic that is compatible with
/// the style of the parent if the node is not the root. /// the style of the parent if the node is not the root.
/// ///
...@@ -1751,8 +1799,8 @@ class StringProperty extends DiagnosticsProperty<String> { ...@@ -1751,8 +1799,8 @@ class StringProperty extends DiagnosticsProperty<String> {
final bool quoted; final bool quoted;
@override @override
Map<String, Object> toJsonMap() { Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object> json = super.toJsonMap(); final Map<String, Object> json = super.toJsonMap(delegate);
json['quoted'] = quoted; json['quoted'] = quoted;
return json; return json;
} }
...@@ -1824,8 +1872,8 @@ abstract class _NumProperty<T extends num> extends DiagnosticsProperty<T> { ...@@ -1824,8 +1872,8 @@ abstract class _NumProperty<T extends num> extends DiagnosticsProperty<T> {
); );
@override @override
Map<String, Object> toJsonMap() { Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object> json = super.toJsonMap(); final Map<String, Object> json = super.toJsonMap(delegate);
if (unit != null) if (unit != null)
json['unit'] = unit; json['unit'] = unit;
...@@ -2060,8 +2108,8 @@ class FlagProperty extends DiagnosticsProperty<bool> { ...@@ -2060,8 +2108,8 @@ class FlagProperty extends DiagnosticsProperty<bool> {
); );
@override @override
Map<String, Object> toJsonMap() { Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object> json = super.toJsonMap(); final Map<String, Object> json = super.toJsonMap(delegate);
if (ifTrue != null) if (ifTrue != null)
json['ifTrue'] = ifTrue; json['ifTrue'] = ifTrue;
if (ifFalse != null) if (ifFalse != null)
...@@ -2194,8 +2242,8 @@ class IterableProperty<T> extends DiagnosticsProperty<Iterable<T>> { ...@@ -2194,8 +2242,8 @@ class IterableProperty<T> extends DiagnosticsProperty<Iterable<T>> {
} }
@override @override
Map<String, Object> toJsonMap() { Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object> json = super.toJsonMap(); final Map<String, Object> json = super.toJsonMap(delegate);
if (value != null) { if (value != null) {
json['values'] = value.map<String>((T value) => value.toString()).toList(); json['values'] = value.map<String>((T value) => value.toString()).toList();
} }
...@@ -2345,8 +2393,8 @@ class ObjectFlagProperty<T> extends DiagnosticsProperty<T> { ...@@ -2345,8 +2393,8 @@ class ObjectFlagProperty<T> extends DiagnosticsProperty<T> {
} }
@override @override
Map<String, Object> toJsonMap() { Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object> json = super.toJsonMap(); final Map<String, Object> json = super.toJsonMap(delegate);
if (ifPresent != null) if (ifPresent != null)
json['ifPresent'] = ifPresent; json['ifPresent'] = ifPresent;
return json; return json;
...@@ -2472,8 +2520,22 @@ class DiagnosticsProperty<T> extends DiagnosticsNode { ...@@ -2472,8 +2520,22 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
final bool allowNameWrap; final bool allowNameWrap;
@override @override
Map<String, Object> toJsonMap() { Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object> json = super.toJsonMap(); final T v = value;
List<Map<String, Object>> properties;
if (delegate.expandPropertyValues && delegate.includeProperties && v is Diagnosticable && getProperties().isEmpty) {
// Exclude children for expanded nodes to avoid cycles.
delegate = delegate.copyWith(subtreeDepth: 0, includeProperties: false);
properties = DiagnosticsNode.toJsonList(
delegate.filterProperties(v.toDiagnosticsNode().getProperties(), this),
this,
delegate,
);
}
final Map<String, Object> json = super.toJsonMap(delegate);
if (properties != null) {
json['properties'] = properties;
}
if (defaultValue != kNoDefaultValue) if (defaultValue != kNoDefaultValue)
json['defaultValue'] = defaultValue.toString(); json['defaultValue'] = defaultValue.toString();
if (ifEmpty != null) if (ifEmpty != null)
...@@ -2735,8 +2797,9 @@ class DiagnosticableNode<T extends Diagnosticable> extends DiagnosticsNode { ...@@ -2735,8 +2797,9 @@ class DiagnosticableNode<T extends Diagnosticable> extends DiagnosticsNode {
} }
/// [DiagnosticsNode] for an instance of [DiagnosticableTree]. /// [DiagnosticsNode] for an instance of [DiagnosticableTree].
class _DiagnosticableTreeNode extends DiagnosticableNode<DiagnosticableTree> { class DiagnosticableTreeNode extends DiagnosticableNode<DiagnosticableTree> {
_DiagnosticableTreeNode({ /// Creates a [DiagnosticableTreeNode].
DiagnosticableTreeNode({
String name, String name,
@required DiagnosticableTree value, @required DiagnosticableTree value,
@required DiagnosticsTreeStyle style, @required DiagnosticsTreeStyle style,
...@@ -2975,6 +3038,10 @@ mixin DiagnosticableMixin { ...@@ -2975,6 +3038,10 @@ mixin DiagnosticableMixin {
/// * [ObjectFlagProperty], which provides terse descriptions of whether a /// * [ObjectFlagProperty], which provides terse descriptions of whether a
/// property value is present or not. For example, whether an `onClick` /// property value is present or not. For example, whether an `onClick`
/// callback is specified or an animation is in progress. /// callback is specified or an animation is in progress.
/// * [ColorProperty], which must be used if the property value is
/// a [Color] or one of its subclasses.
/// * [IconDataProperty], which must be used if the property value
/// is of type [IconData].
/// ///
/// If none of these subclasses apply, use the [DiagnosticsProperty] /// If none of these subclasses apply, use the [DiagnosticsProperty]
/// constructor or in rare cases create your own [DiagnosticsProperty] /// constructor or in rare cases create your own [DiagnosticsProperty]
...@@ -3201,7 +3268,7 @@ abstract class DiagnosticableTree extends Diagnosticable { ...@@ -3201,7 +3268,7 @@ abstract class DiagnosticableTree extends Diagnosticable {
@override @override
DiagnosticsNode toDiagnosticsNode({ String name, DiagnosticsTreeStyle style }) { DiagnosticsNode toDiagnosticsNode({ String name, DiagnosticsTreeStyle style }) {
return _DiagnosticableTreeNode( return DiagnosticableTreeNode(
name: name, name: name,
value: this, value: this,
style: style, style: style,
...@@ -3268,7 +3335,7 @@ mixin DiagnosticableTreeMixin implements DiagnosticableTree { ...@@ -3268,7 +3335,7 @@ mixin DiagnosticableTreeMixin implements DiagnosticableTree {
@override @override
DiagnosticsNode toDiagnosticsNode({ String name, DiagnosticsTreeStyle style }) { DiagnosticsNode toDiagnosticsNode({ String name, DiagnosticsTreeStyle style }) {
return _DiagnosticableTreeNode( return DiagnosticableTreeNode(
name: name, name: name,
value: this, value: this,
style: style, style: style,
...@@ -3334,3 +3401,159 @@ class DiagnosticsBlock extends DiagnosticsNode { ...@@ -3334,3 +3401,159 @@ class DiagnosticsBlock extends DiagnosticsNode {
@override @override
String toDescription({TextTreeConfiguration parentConfiguration}) => _description; String toDescription({TextTreeConfiguration parentConfiguration}) => _description;
} }
/// A delegate that configures how a hierarchy of [DiagnosticsNode]s should be
/// serialized.
///
/// Implement this class in a subclass to fully configure how [DiagnosticsNode]s
/// get serialized.
abstract class DiagnosticsSerializationDelegate {
/// Creates a simple [DiagnosticsSerializationDelegate] that controls the
/// [subtreeDepth] and whether to [includeProperties].
///
/// For additional configuration options, extend
/// [DiagnosticsSerializationDelegate] and provide custom implementations
/// for the methods of this class.
const factory DiagnosticsSerializationDelegate({
int subtreeDepth,
bool includeProperties,
}) = _DefaultDiagnosticsSerializationDelegate;
/// Returns a serializable map of additional information that will be included
/// in the serialization of the given [DiagnosticsNode].
///
/// This method is called for every [DiagnosticsNode] that's included in
/// the serialization.
Map<String, Object> additionalNodeProperties(DiagnosticsNode node);
/// Filters the list of [DiagnosticsNode]s that will be included as children
/// for the given `owner` node.
///
/// The callback may return a subset of the children in the provided list
/// or replace the entire list with new child nodes.
///
/// See also:
///
/// * [subtreeDepth], which controls how many levels of children will be
/// included in the serialization.
List<DiagnosticsNode> filterChildren(List<DiagnosticsNode> nodes, DiagnosticsNode owner);
/// Filters the list of [DiagnosticsNode]s that will be included as properties
/// for the given `owner` node.
///
/// The callback may return a subset of the properties in the provided list
/// or replace the entire list with new property nodes.
///
/// By default, `nodes` is returned as-is.
///
/// See also:
///
/// * [includeProperties], which controls whether properties will be included
/// at all.
List<DiagnosticsNode> filterProperties(List<DiagnosticsNode> nodes, DiagnosticsNode owner);
/// Truncates the given list of [DiagnosticsNode] that will be added to the
/// serialization as children or properties of the `owner` node.
///
/// The method must return a subset of the provided nodes and may
/// not replace any nodes. While [filterProperties] and [filterChildren]
/// completely hide a node from the serialization, truncating a node will
/// leave a hint in the serialization that there were additional nodes in the
/// result that are not included in the current serialization.
///
/// By default, `nodes` is returned as-is.
List<DiagnosticsNode> truncateNodesList(List<DiagnosticsNode> nodes, DiagnosticsNode owner);
/// Returns the [DiagnosticsSerializationDelegate] to be used
/// for adding the provided [DiagnosticsNode] to the serialization.
///
/// By default, this will return a copy of this delegate, which has the
/// [subtreeDepth] reduced by one.
///
/// This is called for nodes that will be added to the serialization as
/// property or child of another node. It may return the same delegate if no
/// changes to it are necessary.
DiagnosticsSerializationDelegate delegateForNode(DiagnosticsNode node);
/// Controls how many levels of children will be included in the serialized
/// hierarchy of [DiagnosticsNode]s.
///
/// Defaults to zero.
///
/// See also:
///
/// * [filterChildren], which provides a way to filter the children that
/// will be included.
int get subtreeDepth;
/// Whether to include the properties of a [DiagnosticsNode] in the
/// serialization.
///
/// Defaults to false.
///
/// See also:
///
/// * [filterProperties], which provides a way to filter the properties that
/// will be included.
bool get includeProperties;
/// Whether properties that have a [Diagnosticable] as value should be
/// expanded.
bool get expandPropertyValues;
/// Creates a copy of this [DiagnosticsSerializationDelegate] with the
/// provided values.
DiagnosticsSerializationDelegate copyWith({
int subtreeDepth,
bool includeProperties,
});
}
class _DefaultDiagnosticsSerializationDelegate implements DiagnosticsSerializationDelegate {
const _DefaultDiagnosticsSerializationDelegate({
this.includeProperties = false,
this.subtreeDepth = 0,
});
@override
Map<String, Object> additionalNodeProperties(DiagnosticsNode node) {
return const <String, Object>{};
}
@override
DiagnosticsSerializationDelegate delegateForNode(DiagnosticsNode node) {
return subtreeDepth > 0 ? copyWith(subtreeDepth: subtreeDepth - 1) : this;
}
@override
bool get expandPropertyValues => false;
@override
List<DiagnosticsNode> filterChildren(List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
return nodes;
}
@override
List<DiagnosticsNode> filterProperties(List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
return nodes;
}
@override
final bool includeProperties;
@override
final int subtreeDepth;
@override
List<DiagnosticsNode> truncateNodesList(List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
return nodes;
}
@override
DiagnosticsSerializationDelegate copyWith({int subtreeDepth, bool includeProperties}) {
return _DefaultDiagnosticsSerializationDelegate(
subtreeDepth: subtreeDepth ?? this.subtreeDepth,
includeProperties: includeProperties ?? this.includeProperties,
);
}
}
...@@ -141,7 +141,7 @@ class AppBarTheme extends Diagnosticable { ...@@ -141,7 +141,7 @@ class AppBarTheme extends Diagnosticable {
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Brightness>('brightness', brightness, defaultValue: null)); properties.add(DiagnosticsProperty<Brightness>('brightness', brightness, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null));
properties.add(DiagnosticsProperty<double>('elevation', elevation, defaultValue: null)); properties.add(DiagnosticsProperty<double>('elevation', elevation, defaultValue: null));
properties.add(DiagnosticsProperty<IconThemeData>('iconTheme', iconTheme, defaultValue: null)); properties.add(DiagnosticsProperty<IconThemeData>('iconTheme', iconTheme, defaultValue: null));
properties.add(DiagnosticsProperty<IconThemeData>('actionsIconTheme', actionsIconTheme, defaultValue: null)); properties.add(DiagnosticsProperty<IconThemeData>('actionsIconTheme', actionsIconTheme, defaultValue: null));
......
...@@ -101,7 +101,7 @@ class BottomAppBarTheme extends Diagnosticable { ...@@ -101,7 +101,7 @@ class BottomAppBarTheme extends Diagnosticable {
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null));
properties.add(DiagnosticsProperty<double>('elevation', elevation, defaultValue: null)); properties.add(DiagnosticsProperty<double>('elevation', elevation, defaultValue: null));
properties.add(DiagnosticsProperty<NotchedShape>('shape', shape, defaultValue: null)); properties.add(DiagnosticsProperty<NotchedShape>('shape', shape, defaultValue: null));
} }
......
...@@ -104,7 +104,7 @@ class BottomSheetThemeData extends Diagnosticable { ...@@ -104,7 +104,7 @@ class BottomSheetThemeData extends Diagnosticable {
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Color>('backgroundColor', backgroundColor, defaultValue: null)); properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null));
properties.add(DoubleProperty('elevation', elevation, defaultValue: null)); properties.add(DoubleProperty('elevation', elevation, defaultValue: null));
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null)); properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
} }
......
...@@ -925,12 +925,12 @@ class ButtonThemeData extends Diagnosticable { ...@@ -925,12 +925,12 @@ class ButtonThemeData extends Diagnosticable {
defaultValue: defaultTheme.alignedDropdown, defaultValue: defaultTheme.alignedDropdown,
ifTrue: 'dropdown width matches button', ifTrue: 'dropdown width matches button',
)); ));
properties.add(DiagnosticsProperty<Color>('buttonColor', _buttonColor, defaultValue: null)); properties.add(ColorProperty('buttonColor', _buttonColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('disabledColor', _disabledColor, defaultValue: null)); properties.add(ColorProperty('disabledColor', _disabledColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('focusColor', _focusColor, defaultValue: null)); properties.add(ColorProperty('focusColor', _focusColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('hoverColor', _hoverColor, defaultValue: null)); properties.add(ColorProperty('hoverColor', _hoverColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('highlightColor', _highlightColor, defaultValue: null)); properties.add(ColorProperty('highlightColor', _highlightColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('splashColor', _splashColor, defaultValue: null)); properties.add(ColorProperty('splashColor', _splashColor, defaultValue: null));
properties.add(DiagnosticsProperty<ColorScheme>('colorScheme', colorScheme, defaultValue: defaultTheme.colorScheme)); properties.add(DiagnosticsProperty<ColorScheme>('colorScheme', colorScheme, defaultValue: defaultTheme.colorScheme));
properties.add(DiagnosticsProperty<MaterialTapTargetSize>('materialTapTargetSize', _materialTapTargetSize, defaultValue: null)); properties.add(DiagnosticsProperty<MaterialTapTargetSize>('materialTapTargetSize', _materialTapTargetSize, defaultValue: null));
} }
......
...@@ -134,7 +134,7 @@ class CardTheme extends Diagnosticable { ...@@ -134,7 +134,7 @@ class CardTheme extends Diagnosticable {
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Clip>('clipBehavior', clipBehavior, defaultValue: null)); properties.add(DiagnosticsProperty<Clip>('clipBehavior', clipBehavior, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null));
properties.add(DiagnosticsProperty<double>('elevation', elevation, defaultValue: null)); properties.add(DiagnosticsProperty<double>('elevation', elevation, defaultValue: null));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('margin', margin, defaultValue: null)); properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('margin', margin, defaultValue: null));
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null)); properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
......
...@@ -486,13 +486,13 @@ class ChipThemeData extends Diagnosticable { ...@@ -486,13 +486,13 @@ class ChipThemeData extends Diagnosticable {
brightness: defaultTheme.brightness, brightness: defaultTheme.brightness,
labelStyle: defaultTheme.textTheme.body2, labelStyle: defaultTheme.textTheme.body2,
); );
properties.add(DiagnosticsProperty<Color>('backgroundColor', backgroundColor, defaultValue: defaultData.backgroundColor)); properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: defaultData.backgroundColor));
properties.add(DiagnosticsProperty<Color>('deleteIconColor', deleteIconColor, defaultValue: defaultData.deleteIconColor)); properties.add(ColorProperty('deleteIconColor', deleteIconColor, defaultValue: defaultData.deleteIconColor));
properties.add(DiagnosticsProperty<Color>('disabledColor', disabledColor, defaultValue: defaultData.disabledColor)); properties.add(ColorProperty('disabledColor', disabledColor, defaultValue: defaultData.disabledColor));
properties.add(DiagnosticsProperty<Color>('selectedColor', selectedColor, defaultValue: defaultData.selectedColor)); properties.add(ColorProperty('selectedColor', selectedColor, defaultValue: defaultData.selectedColor));
properties.add(DiagnosticsProperty<Color>('secondarySelectedColor', secondarySelectedColor, defaultValue: defaultData.secondarySelectedColor)); properties.add(ColorProperty('secondarySelectedColor', secondarySelectedColor, defaultValue: defaultData.secondarySelectedColor));
properties.add(DiagnosticsProperty<Color>('shadowColor', shadowColor, defaultValue: defaultData.shadowColor)); properties.add(ColorProperty('shadowColor', shadowColor, defaultValue: defaultData.shadowColor));
properties.add(DiagnosticsProperty<Color>('selectedShadowColor', selectedShadowColor, defaultValue: defaultData.selectedShadowColor)); properties.add(ColorProperty('selectedShadowColor', selectedShadowColor, defaultValue: defaultData.selectedShadowColor));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('labelPadding', labelPadding, defaultValue: defaultData.labelPadding)); properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('labelPadding', labelPadding, defaultValue: defaultData.labelPadding));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: defaultData.padding)); properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: defaultData.padding));
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: defaultData.shape)); properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: defaultData.shape));
......
...@@ -307,18 +307,18 @@ class ColorScheme extends Diagnosticable { ...@@ -307,18 +307,18 @@ class ColorScheme extends Diagnosticable {
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
const ColorScheme defaultScheme = ColorScheme.light(); const ColorScheme defaultScheme = ColorScheme.light();
properties.add(DiagnosticsProperty<Color>('primary', primary, defaultValue: defaultScheme.primary)); properties.add(ColorProperty('primary', primary, defaultValue: defaultScheme.primary));
properties.add(DiagnosticsProperty<Color>('primaryVariant', primaryVariant, defaultValue: defaultScheme.primaryVariant)); properties.add(ColorProperty('primaryVariant', primaryVariant, defaultValue: defaultScheme.primaryVariant));
properties.add(DiagnosticsProperty<Color>('secondary', secondary, defaultValue: defaultScheme.secondary)); properties.add(ColorProperty('secondary', secondary, defaultValue: defaultScheme.secondary));
properties.add(DiagnosticsProperty<Color>('secondaryVariant', secondaryVariant, defaultValue: defaultScheme.secondaryVariant)); properties.add(ColorProperty('secondaryVariant', secondaryVariant, defaultValue: defaultScheme.secondaryVariant));
properties.add(DiagnosticsProperty<Color>('surface', surface, defaultValue: defaultScheme.surface)); properties.add(ColorProperty('surface', surface, defaultValue: defaultScheme.surface));
properties.add(DiagnosticsProperty<Color>('background', background, defaultValue: defaultScheme.background)); properties.add(ColorProperty('background', background, defaultValue: defaultScheme.background));
properties.add(DiagnosticsProperty<Color>('error', error, defaultValue: defaultScheme.error)); properties.add(ColorProperty('error', error, defaultValue: defaultScheme.error));
properties.add(DiagnosticsProperty<Color>('onPrimary', onPrimary, defaultValue: defaultScheme.onPrimary)); properties.add(ColorProperty('onPrimary', onPrimary, defaultValue: defaultScheme.onPrimary));
properties.add(DiagnosticsProperty<Color>('onSecondary', onSecondary, defaultValue: defaultScheme.onSecondary)); properties.add(ColorProperty('onSecondary', onSecondary, defaultValue: defaultScheme.onSecondary));
properties.add(DiagnosticsProperty<Color>('onSurface', onSurface, defaultValue: defaultScheme.onSurface)); properties.add(ColorProperty('onSurface', onSurface, defaultValue: defaultScheme.onSurface));
properties.add(DiagnosticsProperty<Color>('onBackground', onBackground, defaultValue: defaultScheme.onBackground)); properties.add(ColorProperty('onBackground', onBackground, defaultValue: defaultScheme.onBackground));
properties.add(DiagnosticsProperty<Color>('onError', onError, defaultValue: defaultScheme.onError)); properties.add(ColorProperty('onError', onError, defaultValue: defaultScheme.onError));
properties.add(DiagnosticsProperty<Brightness>('brightness', brightness, defaultValue: defaultScheme.brightness)); properties.add(DiagnosticsProperty<Brightness>('brightness', brightness, defaultValue: defaultScheme.brightness));
} }
} }
...@@ -120,7 +120,7 @@ class DialogTheme extends Diagnosticable { ...@@ -120,7 +120,7 @@ class DialogTheme extends Diagnosticable {
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Color>('backgroundColor', backgroundColor)); properties.add(ColorProperty('backgroundColor', backgroundColor));
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null)); properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
properties.add(DoubleProperty('elevation', elevation)); properties.add(DoubleProperty('elevation', elevation));
properties.add(DiagnosticsProperty<TextStyle>('titleTextStyle', titleTextStyle, defaultValue: null)); properties.add(DiagnosticsProperty<TextStyle>('titleTextStyle', titleTextStyle, defaultValue: null));
......
...@@ -485,10 +485,10 @@ class FloatingActionButton extends StatelessWidget { ...@@ -485,10 +485,10 @@ class FloatingActionButton extends StatelessWidget {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(ObjectFlagProperty<VoidCallback>('onPressed', onPressed, ifNull: 'disabled')); properties.add(ObjectFlagProperty<VoidCallback>('onPressed', onPressed, ifNull: 'disabled'));
properties.add(StringProperty('tooltip', tooltip, defaultValue: null)); properties.add(StringProperty('tooltip', tooltip, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('foregroundColor', foregroundColor, defaultValue: null)); properties.add(ColorProperty('foregroundColor', foregroundColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('backgroundColor', backgroundColor, defaultValue: null)); properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('focusColor', focusColor, defaultValue: null)); properties.add(ColorProperty('focusColor', focusColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('hoverColor', hoverColor, defaultValue: null)); properties.add(ColorProperty('hoverColor', hoverColor, defaultValue: null));
properties.add(ObjectFlagProperty<Object>('heroTag', heroTag, ifPresent: 'hero')); properties.add(ObjectFlagProperty<Object>('heroTag', heroTag, ifPresent: 'hero'));
properties.add(DiagnosticsProperty<double>('elevation', elevation, defaultValue: null)); properties.add(DiagnosticsProperty<double>('elevation', elevation, defaultValue: null));
properties.add(DiagnosticsProperty<double>('focusElevation', focusElevation, defaultValue: null)); properties.add(DiagnosticsProperty<double>('focusElevation', focusElevation, defaultValue: null));
......
...@@ -175,10 +175,10 @@ class FloatingActionButtonThemeData extends Diagnosticable { ...@@ -175,10 +175,10 @@ class FloatingActionButtonThemeData extends Diagnosticable {
super.debugFillProperties(properties); super.debugFillProperties(properties);
const FloatingActionButtonThemeData defaultData = FloatingActionButtonThemeData(); const FloatingActionButtonThemeData defaultData = FloatingActionButtonThemeData();
properties.add(DiagnosticsProperty<Color>('foregroundColor', foregroundColor, defaultValue: defaultData.foregroundColor)); properties.add(ColorProperty('foregroundColor', foregroundColor, defaultValue: defaultData.foregroundColor));
properties.add(DiagnosticsProperty<Color>('backgroundColor', backgroundColor, defaultValue: defaultData.backgroundColor)); properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: defaultData.backgroundColor));
properties.add(DiagnosticsProperty<Color>('focusColor', focusColor, defaultValue: defaultData.focusColor)); properties.add(ColorProperty('focusColor', focusColor, defaultValue: defaultData.focusColor));
properties.add(DiagnosticsProperty<Color>('hoverColor', hoverColor, defaultValue: defaultData.hoverColor)); properties.add(ColorProperty('hoverColor', hoverColor, defaultValue: defaultData.hoverColor));
properties.add(DoubleProperty('elevation', elevation, defaultValue: defaultData.elevation)); properties.add(DoubleProperty('elevation', elevation, defaultValue: defaultData.elevation));
properties.add(DoubleProperty('focusElevation', focusElevation, defaultValue: defaultData.focusElevation)); properties.add(DoubleProperty('focusElevation', focusElevation, defaultValue: defaultData.focusElevation));
properties.add(DoubleProperty('hoverElevation', hoverElevation, defaultValue: defaultData.hoverElevation)); properties.add(DoubleProperty('hoverElevation', hoverElevation, defaultValue: defaultData.hoverElevation));
......
...@@ -334,12 +334,12 @@ class IconButton extends StatelessWidget { ...@@ -334,12 +334,12 @@ class IconButton extends StatelessWidget {
properties.add(DiagnosticsProperty<Widget>('icon', icon, showName: false)); properties.add(DiagnosticsProperty<Widget>('icon', icon, showName: false));
properties.add(StringProperty('tooltip', tooltip, defaultValue: null, quoted: false)); properties.add(StringProperty('tooltip', tooltip, defaultValue: null, quoted: false));
properties.add(ObjectFlagProperty<VoidCallback>('onPressed', onPressed, ifNull: 'disabled')); properties.add(ObjectFlagProperty<VoidCallback>('onPressed', onPressed, ifNull: 'disabled'));
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('disabledColor', disabledColor, defaultValue: null)); properties.add(ColorProperty('disabledColor', disabledColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('focusColor', focusColor, defaultValue: null)); properties.add(ColorProperty('focusColor', focusColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('hoverColor', hoverColor, defaultValue: null)); properties.add(ColorProperty('hoverColor', hoverColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('highlightColor', highlightColor, defaultValue: null)); properties.add(ColorProperty('highlightColor', highlightColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('splashColor', splashColor, defaultValue: null)); properties.add(ColorProperty('splashColor', splashColor, defaultValue: null));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null)); properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null));
properties.add(DiagnosticsProperty<FocusNode>('focusNode', focusNode, defaultValue: null)); properties.add(DiagnosticsProperty<FocusNode>('focusNode', focusNode, defaultValue: null));
} }
......
...@@ -3456,9 +3456,9 @@ class InputDecorationTheme extends Diagnosticable { ...@@ -3456,9 +3456,9 @@ class InputDecorationTheme extends Diagnosticable {
properties.add(DiagnosticsProperty<TextStyle>('suffixStyle', suffixStyle, defaultValue: defaultTheme.suffixStyle)); properties.add(DiagnosticsProperty<TextStyle>('suffixStyle', suffixStyle, defaultValue: defaultTheme.suffixStyle));
properties.add(DiagnosticsProperty<TextStyle>('counterStyle', counterStyle, defaultValue: defaultTheme.counterStyle)); properties.add(DiagnosticsProperty<TextStyle>('counterStyle', counterStyle, defaultValue: defaultTheme.counterStyle));
properties.add(DiagnosticsProperty<bool>('filled', filled, defaultValue: defaultTheme.filled)); properties.add(DiagnosticsProperty<bool>('filled', filled, defaultValue: defaultTheme.filled));
properties.add(DiagnosticsProperty<Color>('fillColor', fillColor, defaultValue: defaultTheme.fillColor)); properties.add(ColorProperty('fillColor', fillColor, defaultValue: defaultTheme.fillColor));
properties.add(DiagnosticsProperty<Color>('focusColor', focusColor, defaultValue: defaultTheme.focusColor)); properties.add(ColorProperty('focusColor', focusColor, defaultValue: defaultTheme.focusColor));
properties.add(DiagnosticsProperty<Color>('hoverColor', hoverColor, defaultValue: defaultTheme.hoverColor)); properties.add(ColorProperty('hoverColor', hoverColor, defaultValue: defaultTheme.hoverColor));
properties.add(DiagnosticsProperty<InputBorder>('errorBorder', errorBorder, defaultValue: defaultTheme.errorBorder)); properties.add(DiagnosticsProperty<InputBorder>('errorBorder', errorBorder, defaultValue: defaultTheme.errorBorder));
properties.add(DiagnosticsProperty<InputBorder>('focusedBorder', focusedBorder, defaultValue: defaultTheme.focusedErrorBorder)); properties.add(DiagnosticsProperty<InputBorder>('focusedBorder', focusedBorder, defaultValue: defaultTheme.focusedErrorBorder));
properties.add(DiagnosticsProperty<InputBorder>('focusedErrorBorder', focusedErrorBorder, defaultValue: defaultTheme.focusedErrorBorder)); properties.add(DiagnosticsProperty<InputBorder>('focusedErrorBorder', focusedErrorBorder, defaultValue: defaultTheme.focusedErrorBorder));
......
...@@ -289,8 +289,8 @@ class Material extends StatefulWidget { ...@@ -289,8 +289,8 @@ class Material extends StatefulWidget {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(EnumProperty<MaterialType>('type', type)); properties.add(EnumProperty<MaterialType>('type', type));
properties.add(DoubleProperty('elevation', elevation, defaultValue: 0.0)); properties.add(DoubleProperty('elevation', elevation, defaultValue: 0.0));
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('shadowColor', shadowColor, defaultValue: const Color(0xFF000000))); properties.add(ColorProperty('shadowColor', shadowColor, defaultValue: const Color(0xFF000000)));
textStyle?.debugFillProperties(properties, prefix: 'textStyle.'); textStyle?.debugFillProperties(properties, prefix: 'textStyle.');
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null)); properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
properties.add(DiagnosticsProperty<bool>('borderOnForeground', borderOnForeground, defaultValue: true)); properties.add(DiagnosticsProperty<bool>('borderOnForeground', borderOnForeground, defaultValue: true));
...@@ -691,8 +691,8 @@ class _MaterialInterior extends ImplicitlyAnimatedWidget { ...@@ -691,8 +691,8 @@ class _MaterialInterior extends ImplicitlyAnimatedWidget {
super.debugFillProperties(description); super.debugFillProperties(description);
description.add(DiagnosticsProperty<ShapeBorder>('shape', shape)); description.add(DiagnosticsProperty<ShapeBorder>('shape', shape));
description.add(DoubleProperty('elevation', elevation)); description.add(DoubleProperty('elevation', elevation));
description.add(DiagnosticsProperty<Color>('color', color)); description.add(ColorProperty('color', color));
description.add(DiagnosticsProperty<Color>('shadowColor', shadowColor)); description.add(ColorProperty('shadowColor', shadowColor));
} }
} }
......
...@@ -359,14 +359,14 @@ class MaterialButton extends StatelessWidget { ...@@ -359,14 +359,14 @@ class MaterialButton extends StatelessWidget {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(ObjectFlagProperty<VoidCallback>('onPressed', onPressed, ifNull: 'disabled')); properties.add(ObjectFlagProperty<VoidCallback>('onPressed', onPressed, ifNull: 'disabled'));
properties.add(DiagnosticsProperty<ButtonTextTheme>('textTheme', textTheme, defaultValue: null)); properties.add(DiagnosticsProperty<ButtonTextTheme>('textTheme', textTheme, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('textColor', textColor, defaultValue: null)); properties.add(ColorProperty('textColor', textColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('disabledTextColor', disabledTextColor, defaultValue: null)); properties.add(ColorProperty('disabledTextColor', disabledTextColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('disabledColor', disabledColor, defaultValue: null)); properties.add(ColorProperty('disabledColor', disabledColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('focusColor', focusColor, defaultValue: null)); properties.add(ColorProperty('focusColor', focusColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('hoverColor', hoverColor, defaultValue: null)); properties.add(ColorProperty('hoverColor', hoverColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('highlightColor', highlightColor, defaultValue: null)); properties.add(ColorProperty('highlightColor', highlightColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('splashColor', splashColor, defaultValue: null)); properties.add(ColorProperty('splashColor', splashColor, defaultValue: null));
properties.add(DiagnosticsProperty<Brightness>('colorBrightness', colorBrightness, defaultValue: null)); properties.add(DiagnosticsProperty<Brightness>('colorBrightness', colorBrightness, defaultValue: null));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null)); properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null));
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null)); properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
......
...@@ -180,8 +180,8 @@ class OutlineButton extends MaterialButton { ...@@ -180,8 +180,8 @@ class OutlineButton extends MaterialButton {
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<BorderSide>('borderSide', borderSide, defaultValue: null)); properties.add(DiagnosticsProperty<BorderSide>('borderSide', borderSide, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('disabledBorderColor', disabledBorderColor, defaultValue: null)); properties.add(ColorProperty('disabledBorderColor', disabledBorderColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('highlightedBorderColor', highlightedBorderColor, defaultValue: null)); properties.add(ColorProperty('highlightedBorderColor', highlightedBorderColor, defaultValue: null));
} }
} }
......
...@@ -811,20 +811,19 @@ class SliderThemeData extends Diagnosticable { ...@@ -811,20 +811,19 @@ class SliderThemeData extends Diagnosticable {
super.debugFillProperties(properties); super.debugFillProperties(properties);
const SliderThemeData defaultData = SliderThemeData(); const SliderThemeData defaultData = SliderThemeData();
properties.add(DoubleProperty('trackHeight', trackHeight, defaultValue: defaultData.trackHeight)); properties.add(DoubleProperty('trackHeight', trackHeight, defaultValue: defaultData.trackHeight));
properties.add(DiagnosticsProperty<Color>('activeTrackColor', activeTrackColor, defaultValue: defaultData.activeTrackColor)); properties.add(ColorProperty('activeTrackColor', activeTrackColor, defaultValue: defaultData.activeTrackColor));
properties.add(DiagnosticsProperty<Color>('activeTrackColor', activeTrackColor, defaultValue: defaultData.activeTrackColor)); properties.add(ColorProperty('inactiveTrackColor', inactiveTrackColor, defaultValue: defaultData.inactiveTrackColor));
properties.add(DiagnosticsProperty<Color>('inactiveTrackColor', inactiveTrackColor, defaultValue: defaultData.inactiveTrackColor)); properties.add(ColorProperty('disabledActiveTrackColor', disabledActiveTrackColor, defaultValue: defaultData.disabledActiveTrackColor));
properties.add(DiagnosticsProperty<Color>('disabledActiveTrackColor', disabledActiveTrackColor, defaultValue: defaultData.disabledActiveTrackColor)); properties.add(ColorProperty('disabledInactiveTrackColor', disabledInactiveTrackColor, defaultValue: defaultData.disabledInactiveTrackColor));
properties.add(DiagnosticsProperty<Color>('disabledInactiveTrackColor', disabledInactiveTrackColor, defaultValue: defaultData.disabledInactiveTrackColor)); properties.add(ColorProperty('activeTickMarkColor', activeTickMarkColor, defaultValue: defaultData.activeTickMarkColor));
properties.add(DiagnosticsProperty<Color>('activeTickMarkColor', activeTickMarkColor, defaultValue: defaultData.activeTickMarkColor)); properties.add(ColorProperty('inactiveTickMarkColor', inactiveTickMarkColor, defaultValue: defaultData.inactiveTickMarkColor));
properties.add(DiagnosticsProperty<Color>('inactiveTickMarkColor', inactiveTickMarkColor, defaultValue: defaultData.inactiveTickMarkColor)); properties.add(ColorProperty('disabledActiveTickMarkColor', disabledActiveTickMarkColor, defaultValue: defaultData.disabledActiveTickMarkColor));
properties.add(DiagnosticsProperty<Color>('disabledActiveTickMarkColor', disabledActiveTickMarkColor, defaultValue: defaultData.disabledActiveTickMarkColor)); properties.add(ColorProperty('disabledInactiveTickMarkColor', disabledInactiveTickMarkColor, defaultValue: defaultData.disabledInactiveTickMarkColor));
properties.add(DiagnosticsProperty<Color>('disabledInactiveTickMarkColor', disabledInactiveTickMarkColor, defaultValue: defaultData.disabledInactiveTickMarkColor)); properties.add(ColorProperty('thumbColor', thumbColor, defaultValue: defaultData.thumbColor));
properties.add(DiagnosticsProperty<Color>('thumbColor', thumbColor, defaultValue: defaultData.thumbColor)); properties.add(ColorProperty('overlappingShapeStrokeColor', overlappingShapeStrokeColor, defaultValue: defaultData.overlappingShapeStrokeColor));
properties.add(DiagnosticsProperty<Color>('overlappingShapeStrokeColor', overlappingShapeStrokeColor, defaultValue: defaultData.overlappingShapeStrokeColor)); properties.add(ColorProperty('disabledThumbColor', disabledThumbColor, defaultValue: defaultData.disabledThumbColor));
properties.add(DiagnosticsProperty<Color>('disabledThumbColor', disabledThumbColor, defaultValue: defaultData.disabledThumbColor)); properties.add(ColorProperty('overlayColor', overlayColor, defaultValue: defaultData.overlayColor));
properties.add(DiagnosticsProperty<Color>('overlayColor', overlayColor, defaultValue: defaultData.overlayColor)); properties.add(ColorProperty('valueIndicatorColor', valueIndicatorColor, defaultValue: defaultData.valueIndicatorColor));
properties.add(DiagnosticsProperty<Color>('valueIndicatorColor', valueIndicatorColor, defaultValue: defaultData.valueIndicatorColor));
properties.add(DiagnosticsProperty<SliderComponentShape>('overlayShape', overlayShape, defaultValue: defaultData.overlayShape)); properties.add(DiagnosticsProperty<SliderComponentShape>('overlayShape', overlayShape, defaultValue: defaultData.overlayShape));
properties.add(DiagnosticsProperty<SliderTickMarkShape>('tickMarkShape', tickMarkShape, defaultValue: defaultData.tickMarkShape)); properties.add(DiagnosticsProperty<SliderTickMarkShape>('tickMarkShape', tickMarkShape, defaultValue: defaultData.tickMarkShape));
properties.add(DiagnosticsProperty<SliderComponentShape>('thumbShape', thumbShape, defaultValue: defaultData.thumbShape)); properties.add(DiagnosticsProperty<SliderComponentShape>('thumbShape', thumbShape, defaultValue: defaultData.thumbShape));
...@@ -836,7 +835,7 @@ class SliderThemeData extends Diagnosticable { ...@@ -836,7 +835,7 @@ class SliderThemeData extends Diagnosticable {
properties.add(DiagnosticsProperty<RangeSliderValueIndicatorShape>('rangeValueIndicatorShape', rangeValueIndicatorShape, defaultValue: defaultData.rangeValueIndicatorShape)); properties.add(DiagnosticsProperty<RangeSliderValueIndicatorShape>('rangeValueIndicatorShape', rangeValueIndicatorShape, defaultValue: defaultData.rangeValueIndicatorShape));
properties.add(EnumProperty<ShowValueIndicator>('showValueIndicator', showValueIndicator, defaultValue: defaultData.showValueIndicator)); properties.add(EnumProperty<ShowValueIndicator>('showValueIndicator', showValueIndicator, defaultValue: defaultData.showValueIndicator));
properties.add(DiagnosticsProperty<TextStyle>('valueIndicatorTextStyle', valueIndicatorTextStyle, defaultValue: defaultData.valueIndicatorTextStyle)); properties.add(DiagnosticsProperty<TextStyle>('valueIndicatorTextStyle', valueIndicatorTextStyle, defaultValue: defaultData.valueIndicatorTextStyle));
properties.add(DiagnosticsProperty<double>('minThumbSeparation', minThumbSeparation, defaultValue: defaultData.minThumbSeparation)); properties.add(DoubleProperty('minThumbSeparation', minThumbSeparation, defaultValue: defaultData.minThumbSeparation));
properties.add(DiagnosticsProperty<RangeThumbSelector>('thumbSelector', thumbSelector, defaultValue: defaultData.thumbSelector)); properties.add(DiagnosticsProperty<RangeThumbSelector>('thumbSelector', thumbSelector, defaultValue: defaultData.thumbSelector));
} }
} }
......
...@@ -163,9 +163,9 @@ class SnackBarThemeData extends Diagnosticable { ...@@ -163,9 +163,9 @@ class SnackBarThemeData extends Diagnosticable {
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Color>('backgroundColor', backgroundColor, defaultValue: null)); properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('actionTextColor', actionTextColor, defaultValue: null)); properties.add(ColorProperty('actionTextColor', actionTextColor, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('disabledActionTextColor', disabledActionTextColor, defaultValue: null)); properties.add(ColorProperty('disabledActionTextColor', disabledActionTextColor, defaultValue: null));
properties.add(DoubleProperty('elevation', elevation, defaultValue: null)); properties.add(DoubleProperty('elevation', elevation, defaultValue: null));
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null)); properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
properties.add(DiagnosticsProperty<SnackBarBehavior>('behavior', behavior, defaultValue: null)); properties.add(DiagnosticsProperty<SnackBarBehavior>('behavior', behavior, defaultValue: null));
......
...@@ -509,7 +509,7 @@ class TextField extends StatefulWidget { ...@@ -509,7 +509,7 @@ class TextField extends StatefulWidget {
properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null)); properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
properties.add(DoubleProperty('cursorWidth', cursorWidth, defaultValue: 2.0)); properties.add(DoubleProperty('cursorWidth', cursorWidth, defaultValue: 2.0));
properties.add(DiagnosticsProperty<Radius>('cursorRadius', cursorRadius, defaultValue: null)); properties.add(DiagnosticsProperty<Radius>('cursorRadius', cursorRadius, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('cursorColor', cursorColor, defaultValue: null)); properties.add(ColorProperty('cursorColor', cursorColor, defaultValue: null));
properties.add(DiagnosticsProperty<Brightness>('keyboardAppearance', keyboardAppearance, defaultValue: null)); properties.add(DiagnosticsProperty<Brightness>('keyboardAppearance', keyboardAppearance, defaultValue: null));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('scrollPadding', scrollPadding, defaultValue: const EdgeInsets.all(20.0))); properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('scrollPadding', scrollPadding, defaultValue: const EdgeInsets.all(20.0)));
properties.add(FlagProperty('selectionEnabled', value: selectionEnabled, defaultValue: true, ifFalse: 'selection disabled')); properties.add(FlagProperty('selectionEnabled', value: selectionEnabled, defaultValue: true, ifFalse: 'selection disabled'));
......
...@@ -1120,33 +1120,33 @@ class ThemeData extends Diagnosticable { ...@@ -1120,33 +1120,33 @@ class ThemeData extends Diagnosticable {
final ThemeData defaultData = ThemeData.fallback(); final ThemeData defaultData = ThemeData.fallback();
properties.add(EnumProperty<TargetPlatform>('platform', platform, defaultValue: defaultTargetPlatform)); properties.add(EnumProperty<TargetPlatform>('platform', platform, defaultValue: defaultTargetPlatform));
properties.add(EnumProperty<Brightness>('brightness', brightness, defaultValue: defaultData.brightness)); properties.add(EnumProperty<Brightness>('brightness', brightness, defaultValue: defaultData.brightness));
properties.add(DiagnosticsProperty<Color>('primaryColor', primaryColor, defaultValue: defaultData.primaryColor)); properties.add(ColorProperty('primaryColor', primaryColor, defaultValue: defaultData.primaryColor));
properties.add(EnumProperty<Brightness>('primaryColorBrightness', primaryColorBrightness, defaultValue: defaultData.primaryColorBrightness)); properties.add(EnumProperty<Brightness>('primaryColorBrightness', primaryColorBrightness, defaultValue: defaultData.primaryColorBrightness));
properties.add(DiagnosticsProperty<Color>('accentColor', accentColor, defaultValue: defaultData.accentColor)); properties.add(ColorProperty('accentColor', accentColor, defaultValue: defaultData.accentColor));
properties.add(EnumProperty<Brightness>('accentColorBrightness', accentColorBrightness, defaultValue: defaultData.accentColorBrightness)); properties.add(EnumProperty<Brightness>('accentColorBrightness', accentColorBrightness, defaultValue: defaultData.accentColorBrightness));
properties.add(DiagnosticsProperty<Color>('canvasColor', canvasColor, defaultValue: defaultData.canvasColor)); properties.add(ColorProperty('canvasColor', canvasColor, defaultValue: defaultData.canvasColor));
properties.add(DiagnosticsProperty<Color>('scaffoldBackgroundColor', scaffoldBackgroundColor, defaultValue: defaultData.scaffoldBackgroundColor)); properties.add(ColorProperty('scaffoldBackgroundColor', scaffoldBackgroundColor, defaultValue: defaultData.scaffoldBackgroundColor));
properties.add(DiagnosticsProperty<Color>('bottomAppBarColor', bottomAppBarColor, defaultValue: defaultData.bottomAppBarColor)); properties.add(ColorProperty('bottomAppBarColor', bottomAppBarColor, defaultValue: defaultData.bottomAppBarColor));
properties.add(DiagnosticsProperty<Color>('cardColor', cardColor, defaultValue: defaultData.cardColor)); properties.add(ColorProperty('cardColor', cardColor, defaultValue: defaultData.cardColor));
properties.add(DiagnosticsProperty<Color>('dividerColor', dividerColor, defaultValue: defaultData.dividerColor)); properties.add(ColorProperty('dividerColor', dividerColor, defaultValue: defaultData.dividerColor));
properties.add(DiagnosticsProperty<Color>('focusColor', focusColor, defaultValue: defaultData.focusColor)); properties.add(ColorProperty('focusColor', focusColor, defaultValue: defaultData.focusColor));
properties.add(DiagnosticsProperty<Color>('hoverColor', hoverColor, defaultValue: defaultData.hoverColor)); properties.add(ColorProperty('hoverColor', hoverColor, defaultValue: defaultData.hoverColor));
properties.add(DiagnosticsProperty<Color>('highlightColor', highlightColor, defaultValue: defaultData.highlightColor)); properties.add(ColorProperty('highlightColor', highlightColor, defaultValue: defaultData.highlightColor));
properties.add(DiagnosticsProperty<Color>('splashColor', splashColor, defaultValue: defaultData.splashColor)); properties.add(ColorProperty('splashColor', splashColor, defaultValue: defaultData.splashColor));
properties.add(DiagnosticsProperty<Color>('selectedRowColor', selectedRowColor, defaultValue: defaultData.selectedRowColor)); properties.add(ColorProperty('selectedRowColor', selectedRowColor, defaultValue: defaultData.selectedRowColor));
properties.add(DiagnosticsProperty<Color>('unselectedWidgetColor', unselectedWidgetColor, defaultValue: defaultData.unselectedWidgetColor)); properties.add(ColorProperty('unselectedWidgetColor', unselectedWidgetColor, defaultValue: defaultData.unselectedWidgetColor));
properties.add(DiagnosticsProperty<Color>('disabledColor', disabledColor, defaultValue: defaultData.disabledColor)); properties.add(ColorProperty('disabledColor', disabledColor, defaultValue: defaultData.disabledColor));
properties.add(DiagnosticsProperty<Color>('buttonColor', buttonColor, defaultValue: defaultData.buttonColor)); properties.add(ColorProperty('buttonColor', buttonColor, defaultValue: defaultData.buttonColor));
properties.add(DiagnosticsProperty<Color>('secondaryHeaderColor', secondaryHeaderColor, defaultValue: defaultData.secondaryHeaderColor)); properties.add(ColorProperty('secondaryHeaderColor', secondaryHeaderColor, defaultValue: defaultData.secondaryHeaderColor));
properties.add(DiagnosticsProperty<Color>('textSelectionColor', textSelectionColor, defaultValue: defaultData.textSelectionColor)); properties.add(ColorProperty('textSelectionColor', textSelectionColor, defaultValue: defaultData.textSelectionColor));
properties.add(DiagnosticsProperty<Color>('cursorColor', cursorColor, defaultValue: defaultData.cursorColor)); properties.add(ColorProperty('cursorColor', cursorColor, defaultValue: defaultData.cursorColor));
properties.add(DiagnosticsProperty<Color>('textSelectionHandleColor', textSelectionHandleColor, defaultValue: defaultData.textSelectionHandleColor)); properties.add(ColorProperty('textSelectionHandleColor', textSelectionHandleColor, defaultValue: defaultData.textSelectionHandleColor));
properties.add(DiagnosticsProperty<Color>('backgroundColor', backgroundColor, defaultValue: defaultData.backgroundColor)); properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: defaultData.backgroundColor));
properties.add(DiagnosticsProperty<Color>('dialogBackgroundColor', dialogBackgroundColor, defaultValue: defaultData.dialogBackgroundColor)); properties.add(ColorProperty('dialogBackgroundColor', dialogBackgroundColor, defaultValue: defaultData.dialogBackgroundColor));
properties.add(DiagnosticsProperty<Color>('indicatorColor', indicatorColor, defaultValue: defaultData.indicatorColor)); properties.add(ColorProperty('indicatorColor', indicatorColor, defaultValue: defaultData.indicatorColor));
properties.add(DiagnosticsProperty<Color>('hintColor', hintColor, defaultValue: defaultData.hintColor)); properties.add(ColorProperty('hintColor', hintColor, defaultValue: defaultData.hintColor));
properties.add(DiagnosticsProperty<Color>('errorColor', errorColor, defaultValue: defaultData.errorColor)); properties.add(ColorProperty('errorColor', errorColor, defaultValue: defaultData.errorColor));
properties.add(DiagnosticsProperty<Color>('toggleableActiveColor', toggleableActiveColor, defaultValue: defaultData.toggleableActiveColor)); properties.add(ColorProperty('toggleableActiveColor', toggleableActiveColor, defaultValue: defaultData.toggleableActiveColor));
properties.add(DiagnosticsProperty<ButtonThemeData>('buttonTheme', buttonTheme)); properties.add(DiagnosticsProperty<ButtonThemeData>('buttonTheme', buttonTheme));
properties.add(DiagnosticsProperty<TextTheme>('textTheme', textTheme)); properties.add(DiagnosticsProperty<TextTheme>('textTheme', textTheme));
properties.add(DiagnosticsProperty<TextTheme>('primaryTextTheme', primaryTextTheme)); properties.add(DiagnosticsProperty<TextTheme>('primaryTextTheme', primaryTextTheme));
......
...@@ -10,6 +10,7 @@ import 'basic_types.dart'; ...@@ -10,6 +10,7 @@ import 'basic_types.dart';
import 'border_radius.dart'; import 'border_radius.dart';
import 'box_border.dart'; import 'box_border.dart';
import 'box_shadow.dart'; import 'box_shadow.dart';
import 'colors.dart';
import 'decoration.dart'; import 'decoration.dart';
import 'decoration_image.dart'; import 'decoration_image.dart';
import 'edge_insets.dart'; import 'edge_insets.dart';
...@@ -319,7 +320,7 @@ class BoxDecoration extends Decoration { ...@@ -319,7 +320,7 @@ class BoxDecoration extends Decoration {
..defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.whitespace ..defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.whitespace
..emptyBodyDescription = '<no decorations specified>'; ..emptyBodyDescription = '<no decorations specified>';
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null));
properties.add(DiagnosticsProperty<DecorationImage>('image', image, defaultValue: null)); properties.add(DiagnosticsProperty<DecorationImage>('image', image, defaultValue: null));
properties.add(DiagnosticsProperty<BoxBorder>('border', border, defaultValue: null)); properties.add(DiagnosticsProperty<BoxBorder>('border', border, defaultValue: null));
properties.add(DiagnosticsProperty<BorderRadiusGeometry>('borderRadius', borderRadius, defaultValue: null)); properties.add(DiagnosticsProperty<BorderRadiusGeometry>('borderRadius', borderRadius, defaultValue: null));
......
...@@ -460,3 +460,40 @@ class ColorSwatch<T> extends Color { ...@@ -460,3 +460,40 @@ class ColorSwatch<T> extends Color {
@override @override
String toString() => '$runtimeType(primary value: ${super.toString()})'; String toString() => '$runtimeType(primary value: ${super.toString()})';
} }
/// [DiagnosticsProperty] that has an [Color] as value.
class ColorProperty extends DiagnosticsProperty<Color> {
/// Create a diagnostics property for [Color].
///
/// The [showName], [style], and [level] arguments must not be null.
ColorProperty(
String name,
Color value, {
bool showName = true,
Object defaultValue = kNoDefaultValue,
DiagnosticsTreeStyle style = DiagnosticsTreeStyle.singleLine,
DiagnosticLevel level = DiagnosticLevel.info,
}) : assert(showName != null),
assert(style != null),
assert(level != null),
super(name, value,
defaultValue: defaultValue,
showName: showName,
style: style,
level: level,
);
@override
Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object> json = super.toJsonMap(delegate);
if (value != null) {
json['valueProperties'] = <String, Object>{
'red': value.red,
'green': value.green,
'blue': value.blue,
'alpha': value.alpha,
};
}
return json;
}
}
...@@ -10,6 +10,7 @@ import 'box_border.dart'; ...@@ -10,6 +10,7 @@ import 'box_border.dart';
import 'box_decoration.dart'; import 'box_decoration.dart';
import 'box_shadow.dart'; import 'box_shadow.dart';
import 'circle_border.dart'; import 'circle_border.dart';
import 'colors.dart';
import 'decoration.dart'; import 'decoration.dart';
import 'decoration_image.dart'; import 'decoration_image.dart';
import 'edge_insets.dart'; import 'edge_insets.dart';
...@@ -262,7 +263,7 @@ class ShapeDecoration extends Decoration { ...@@ -262,7 +263,7 @@ class ShapeDecoration extends Decoration {
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.whitespace; properties.defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.whitespace;
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null));
properties.add(DiagnosticsProperty<Gradient>('gradient', gradient, defaultValue: null)); properties.add(DiagnosticsProperty<Gradient>('gradient', gradient, defaultValue: null));
properties.add(DiagnosticsProperty<DecorationImage>('image', image, defaultValue: null)); properties.add(DiagnosticsProperty<DecorationImage>('image', image, defaultValue: null));
properties.add(IterableProperty<BoxShadow>('shadows', shadows, defaultValue: null, style: DiagnosticsTreeStyle.whitespace)); properties.add(IterableProperty<BoxShadow>('shadows', shadows, defaultValue: null, style: DiagnosticsTreeStyle.whitespace));
......
...@@ -7,6 +7,7 @@ import 'dart:ui' as ui show ParagraphStyle, TextStyle, StrutStyle, lerpDouble, S ...@@ -7,6 +7,7 @@ import 'dart:ui' as ui show ParagraphStyle, TextStyle, StrutStyle, lerpDouble, S
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'basic_types.dart'; import 'basic_types.dart';
import 'colors.dart';
import 'strut_style.dart'; import 'strut_style.dart';
const String _kDefaultDebugLabel = 'unknown'; const String _kDefaultDebugLabel = 'unknown';
...@@ -1091,8 +1092,8 @@ class TextStyle extends Diagnosticable { ...@@ -1091,8 +1092,8 @@ class TextStyle extends Diagnosticable {
if (debugLabel != null) if (debugLabel != null)
properties.add(MessageProperty('${prefix}debugLabel', debugLabel)); properties.add(MessageProperty('${prefix}debugLabel', debugLabel));
final List<DiagnosticsNode> styles = <DiagnosticsNode>[]; final List<DiagnosticsNode> styles = <DiagnosticsNode>[];
styles.add(DiagnosticsProperty<Color>('${prefix}color', color, defaultValue: null)); styles.add(ColorProperty('${prefix}color', color, defaultValue: null));
styles.add(DiagnosticsProperty<Color>('${prefix}backgroundColor', backgroundColor, defaultValue: null)); styles.add(ColorProperty('${prefix}backgroundColor', backgroundColor, defaultValue: null));
styles.add(StringProperty('${prefix}family', fontFamily, defaultValue: null, quoted: false)); styles.add(StringProperty('${prefix}family', fontFamily, defaultValue: null, quoted: false));
styles.add(IterableProperty<String>('${prefix}familyFallback', fontFamilyFallback, defaultValue: null)); styles.add(IterableProperty<String>('${prefix}familyFallback', fontFamilyFallback, defaultValue: null));
styles.add(DoubleProperty('${prefix}size', fontSize, defaultValue: null)); styles.add(DoubleProperty('${prefix}size', fontSize, defaultValue: null));
...@@ -1124,7 +1125,7 @@ class TextStyle extends Diagnosticable { ...@@ -1124,7 +1125,7 @@ class TextStyle extends Diagnosticable {
// Hide decorationColor from the default text view as it is shown in the // Hide decorationColor from the default text view as it is shown in the
// terse decoration summary as well. // terse decoration summary as well.
styles.add(DiagnosticsProperty<Color>('${prefix}decorationColor', decorationColor, defaultValue: null, level: DiagnosticLevel.fine)); styles.add(ColorProperty('${prefix}decorationColor', decorationColor, defaultValue: null, level: DiagnosticLevel.fine));
if (decorationColor != null) if (decorationColor != null)
decorationDescription.add('$decorationColor'); decorationDescription.add('$decorationColor');
......
...@@ -1780,12 +1780,12 @@ class RenderEditable extends RenderBox { ...@@ -1780,12 +1780,12 @@ class RenderEditable extends RenderBox {
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Color>('cursorColor', cursorColor)); properties.add(ColorProperty('cursorColor', cursorColor));
properties.add(DiagnosticsProperty<ValueNotifier<bool>>('showCursor', showCursor)); properties.add(DiagnosticsProperty<ValueNotifier<bool>>('showCursor', showCursor));
properties.add(IntProperty('maxLines', maxLines)); properties.add(IntProperty('maxLines', maxLines));
properties.add(IntProperty('minLines', minLines)); properties.add(IntProperty('minLines', minLines));
properties.add(DiagnosticsProperty<bool>('expands', expands, defaultValue: false)); properties.add(DiagnosticsProperty<bool>('expands', expands, defaultValue: false));
properties.add(DiagnosticsProperty<Color>('selectionColor', selectionColor)); properties.add(ColorProperty('selectionColor', selectionColor));
properties.add(DoubleProperty('textScaleFactor', textScaleFactor)); properties.add(DoubleProperty('textScaleFactor', textScaleFactor));
properties.add(DiagnosticsProperty<Locale>('locale', locale, defaultValue: null)); properties.add(DiagnosticsProperty<Locale>('locale', locale, defaultValue: null));
properties.add(DiagnosticsProperty<TextSelection>('selection', selection)); properties.add(DiagnosticsProperty<TextSelection>('selection', selection));
......
...@@ -377,7 +377,7 @@ class RenderImage extends RenderBox { ...@@ -377,7 +377,7 @@ class RenderImage extends RenderBox {
properties.add(DoubleProperty('width', width, defaultValue: null)); properties.add(DoubleProperty('width', width, defaultValue: null));
properties.add(DoubleProperty('height', height, defaultValue: null)); properties.add(DoubleProperty('height', height, defaultValue: null));
properties.add(DoubleProperty('scale', scale, defaultValue: 1.0)); properties.add(DoubleProperty('scale', scale, defaultValue: 1.0));
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null));
properties.add(EnumProperty<BlendMode>('colorBlendMode', colorBlendMode, defaultValue: null)); properties.add(EnumProperty<BlendMode>('colorBlendMode', colorBlendMode, defaultValue: null));
properties.add(EnumProperty<BoxFit>('fit', fit, defaultValue: null)); properties.add(EnumProperty<BoxFit>('fit', fit, defaultValue: null));
properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment, defaultValue: null)); properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment, defaultValue: null));
......
...@@ -1607,7 +1607,7 @@ class PhysicalModelLayer extends ContainerLayer { ...@@ -1607,7 +1607,7 @@ class PhysicalModelLayer extends ContainerLayer {
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(DoubleProperty('elevation', elevation)); properties.add(DoubleProperty('elevation', elevation));
properties.add(DiagnosticsProperty<Color>('color', color)); properties.add(ColorProperty('color', color));
} }
} }
......
...@@ -1592,8 +1592,8 @@ abstract class _RenderPhysicalModelBase<T> extends _RenderCustomClip<T> { ...@@ -1592,8 +1592,8 @@ abstract class _RenderPhysicalModelBase<T> extends _RenderCustomClip<T> {
void debugFillProperties(DiagnosticPropertiesBuilder description) { void debugFillProperties(DiagnosticPropertiesBuilder description) {
super.debugFillProperties(description); super.debugFillProperties(description);
description.add(DoubleProperty('elevation', elevation)); description.add(DoubleProperty('elevation', elevation));
description.add(DiagnosticsProperty<Color>('color', color)); description.add(ColorProperty('color', color));
description.add(DiagnosticsProperty<Color>('shadowColor', color)); description.add(ColorProperty('shadowColor', color));
} }
} }
......
...@@ -322,7 +322,7 @@ class Banner extends StatelessWidget { ...@@ -322,7 +322,7 @@ class Banner extends StatelessWidget {
properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null)); properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
properties.add(EnumProperty<BannerLocation>('location', location)); properties.add(EnumProperty<BannerLocation>('location', location));
properties.add(EnumProperty<TextDirection>('layoutDirection', layoutDirection, defaultValue: null)); properties.add(EnumProperty<TextDirection>('layoutDirection', layoutDirection, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('color', color, showName: false)); properties.add(ColorProperty('color', color, showName: false));
textStyle?.debugFillProperties(properties, prefix: 'text '); textStyle?.debugFillProperties(properties, prefix: 'text ');
} }
} }
......
...@@ -907,8 +907,8 @@ class PhysicalModel extends SingleChildRenderObjectWidget { ...@@ -907,8 +907,8 @@ class PhysicalModel extends SingleChildRenderObjectWidget {
properties.add(EnumProperty<BoxShape>('shape', shape)); properties.add(EnumProperty<BoxShape>('shape', shape));
properties.add(DiagnosticsProperty<BorderRadius>('borderRadius', borderRadius)); properties.add(DiagnosticsProperty<BorderRadius>('borderRadius', borderRadius));
properties.add(DoubleProperty('elevation', elevation)); properties.add(DoubleProperty('elevation', elevation));
properties.add(DiagnosticsProperty<Color>('color', color)); properties.add(ColorProperty('color', color));
properties.add(DiagnosticsProperty<Color>('shadowColor', shadowColor)); properties.add(ColorProperty('shadowColor', shadowColor));
} }
} }
...@@ -994,8 +994,8 @@ class PhysicalShape extends SingleChildRenderObjectWidget { ...@@ -994,8 +994,8 @@ class PhysicalShape extends SingleChildRenderObjectWidget {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<CustomClipper<Path>>('clipper', clipper)); properties.add(DiagnosticsProperty<CustomClipper<Path>>('clipper', clipper));
properties.add(DoubleProperty('elevation', elevation)); properties.add(DoubleProperty('elevation', elevation));
properties.add(DiagnosticsProperty<Color>('color', color)); properties.add(ColorProperty('color', color));
properties.add(DiagnosticsProperty<Color>('shadowColor', shadowColor)); properties.add(ColorProperty('shadowColor', shadowColor));
} }
} }
...@@ -5257,7 +5257,7 @@ class RawImage extends LeafRenderObjectWidget { ...@@ -5257,7 +5257,7 @@ class RawImage extends LeafRenderObjectWidget {
properties.add(DoubleProperty('width', width, defaultValue: null)); properties.add(DoubleProperty('width', width, defaultValue: null));
properties.add(DoubleProperty('height', height, defaultValue: null)); properties.add(DoubleProperty('height', height, defaultValue: null));
properties.add(DoubleProperty('scale', scale, defaultValue: 1.0)); properties.add(DoubleProperty('scale', scale, defaultValue: 1.0));
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null));
properties.add(EnumProperty<BlendMode>('colorBlendMode', colorBlendMode, defaultValue: null)); properties.add(EnumProperty<BlendMode>('colorBlendMode', colorBlendMode, defaultValue: null));
properties.add(EnumProperty<BoxFit>('fit', fit, defaultValue: null)); properties.add(EnumProperty<BoxFit>('fit', fit, defaultValue: null));
properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment, defaultValue: null)); properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment, defaultValue: null));
......
...@@ -3520,6 +3520,15 @@ abstract class Element extends DiagnosticableTree implements BuildContext { ...@@ -3520,6 +3520,15 @@ abstract class Element extends DiagnosticableTree implements BuildContext {
return widget != null ? '${widget.toStringShort()}' : '[$runtimeType]'; return widget != null ? '${widget.toStringShort()}' : '[$runtimeType]';
} }
@override
DiagnosticsNode toDiagnosticsNode({ String name, DiagnosticsTreeStyle style }) {
return _ElementDiagnosticableTreeNode(
name: name,
value: this,
style: style,
);
}
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
...@@ -3670,6 +3679,30 @@ abstract class Element extends DiagnosticableTree implements BuildContext { ...@@ -3670,6 +3679,30 @@ abstract class Element extends DiagnosticableTree implements BuildContext {
void performRebuild(); void performRebuild();
} }
class _ElementDiagnosticableTreeNode extends DiagnosticableTreeNode {
_ElementDiagnosticableTreeNode({
String name,
@required Element value,
@required DiagnosticsTreeStyle style,
this.stateful = false,
}) : super(
name: name,
value: value,
style: style,
);
final bool stateful;
@override
Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object> json = super.toJsonMap(delegate);
final Element element = value;
json['widgetRuntimeType'] = element.widget?.runtimeType?.toString();
json['stateful'] = stateful;
return json;
}
}
/// Signature for the constructor that is called when an error occurs while /// Signature for the constructor that is called when an error occurs while
/// building a widget. /// building a widget.
/// ///
...@@ -4075,6 +4108,16 @@ class StatefulElement extends ComponentElement { ...@@ -4075,6 +4108,16 @@ class StatefulElement extends ComponentElement {
_state.didChangeDependencies(); _state.didChangeDependencies();
} }
@override
DiagnosticsNode toDiagnosticsNode({ String name, DiagnosticsTreeStyle style }) {
return _ElementDiagnosticableTreeNode(
name: name,
value: this,
style: style,
stateful: true,
);
}
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
......
...@@ -198,8 +198,8 @@ class Icon extends StatelessWidget { ...@@ -198,8 +198,8 @@ class Icon extends StatelessWidget {
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<IconData>('icon', icon, ifNull: '<empty>', showName: false)); properties.add(IconDataProperty('icon', icon, ifNull: '<empty>', showName: false));
properties.add(DoubleProperty('size', size, defaultValue: null)); properties.add(DoubleProperty('size', size, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null));
} }
} }
...@@ -66,3 +66,37 @@ class IconData { ...@@ -66,3 +66,37 @@ class IconData {
@override @override
String toString() => 'IconData(U+${codePoint.toRadixString(16).toUpperCase().padLeft(5, '0')})'; String toString() => 'IconData(U+${codePoint.toRadixString(16).toUpperCase().padLeft(5, '0')})';
} }
/// [DiagnosticsProperty] that has an [IconData] as value.
class IconDataProperty extends DiagnosticsProperty<IconData> {
/// Create a diagnostics property for [IconData].
///
/// The [showName], [style], and [level] arguments must not be null.
IconDataProperty(
String name,
IconData value, {
String ifNull,
bool showName = true,
DiagnosticsTreeStyle style = DiagnosticsTreeStyle.singleLine,
DiagnosticLevel level = DiagnosticLevel.info,
}) : assert(showName != null),
assert(style != null),
assert(level != null),
super(name, value,
showName: showName,
ifNull: ifNull,
style: style,
level: level,
);
@override
Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object> json = super.toJsonMap(delegate);
if (value != null) {
json['valueProperties'] = <String, Object>{
'codePoint': value.codePoint,
};
}
return json;
}
}
...@@ -6,6 +6,7 @@ import 'dart:ui' show Color, hashValues; ...@@ -6,6 +6,7 @@ import 'dart:ui' show Color, hashValues;
import 'dart:ui' as ui show lerpDouble; import 'dart:ui' as ui show lerpDouble;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
/// Defines the color, opacity, and size of icons. /// Defines the color, opacity, and size of icons.
/// ///
...@@ -94,7 +95,7 @@ class IconThemeData extends Diagnosticable { ...@@ -94,7 +95,7 @@ class IconThemeData extends Diagnosticable {
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null));
properties.add(DoubleProperty('opacity', opacity, defaultValue: null)); properties.add(DoubleProperty('opacity', opacity, defaultValue: null));
properties.add(DoubleProperty('size', size, defaultValue: null)); properties.add(DoubleProperty('size', size, defaultValue: null));
} }
......
...@@ -837,7 +837,7 @@ class Image extends StatefulWidget { ...@@ -837,7 +837,7 @@ class Image extends StatefulWidget {
properties.add(DiagnosticsProperty<Function>('loadingBuilder', loadingBuilder)); properties.add(DiagnosticsProperty<Function>('loadingBuilder', loadingBuilder));
properties.add(DoubleProperty('width', width, defaultValue: null)); properties.add(DoubleProperty('width', width, defaultValue: null));
properties.add(DoubleProperty('height', height, defaultValue: null)); properties.add(DoubleProperty('height', height, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null));
properties.add(EnumProperty<BlendMode>('colorBlendMode', colorBlendMode, defaultValue: null)); properties.add(EnumProperty<BlendMode>('colorBlendMode', colorBlendMode, defaultValue: null));
properties.add(EnumProperty<BoxFit>('fit', fit, defaultValue: null)); properties.add(EnumProperty<BoxFit>('fit', fit, defaultValue: null));
properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment, defaultValue: null)); properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment, defaultValue: null));
......
...@@ -102,6 +102,6 @@ class ImageIcon extends StatelessWidget { ...@@ -102,6 +102,6 @@ class ImageIcon extends StatelessWidget {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<ImageProvider>('image', image, ifNull: '<empty>', showName: false)); properties.add(DiagnosticsProperty<ImageProvider>('image', image, ifNull: '<empty>', showName: false));
properties.add(DoubleProperty('size', size, defaultValue: null)); properties.add(DoubleProperty('size', size, defaultValue: null));
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null));
} }
} }
...@@ -1441,9 +1441,9 @@ class AnimatedPhysicalModel extends ImplicitlyAnimatedWidget { ...@@ -1441,9 +1441,9 @@ class AnimatedPhysicalModel extends ImplicitlyAnimatedWidget {
properties.add(EnumProperty<BoxShape>('shape', shape)); properties.add(EnumProperty<BoxShape>('shape', shape));
properties.add(DiagnosticsProperty<BorderRadius>('borderRadius', borderRadius)); properties.add(DiagnosticsProperty<BorderRadius>('borderRadius', borderRadius));
properties.add(DoubleProperty('elevation', elevation)); properties.add(DoubleProperty('elevation', elevation));
properties.add(DiagnosticsProperty<Color>('color', color)); properties.add(ColorProperty('color', color));
properties.add(DiagnosticsProperty<bool>('animateColor', animateColor)); properties.add(DiagnosticsProperty<bool>('animateColor', animateColor));
properties.add(DiagnosticsProperty<Color>('shadowColor', shadowColor)); properties.add(ColorProperty('shadowColor', shadowColor));
properties.add(DiagnosticsProperty<bool>('animateShadowColor', animateShadowColor)); properties.add(DiagnosticsProperty<bool>('animateShadowColor', animateShadowColor));
} }
} }
......
...@@ -124,7 +124,7 @@ class GlowingOverscrollIndicator extends StatefulWidget { ...@@ -124,7 +124,7 @@ class GlowingOverscrollIndicator extends StatefulWidget {
showDescription = 'neither side (!)'; showDescription = 'neither side (!)';
} }
properties.add(MessageProperty('show', showDescription)); properties.add(MessageProperty('show', showDescription));
properties.add(DiagnosticsProperty<Color>('color', color, showName: false)); properties.add(ColorProperty('color', color, showName: false));
} }
} }
......
...@@ -53,6 +53,6 @@ class Title extends StatelessWidget { ...@@ -53,6 +53,6 @@ class Title extends StatelessWidget {
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(StringProperty('title', title, defaultValue: '')); properties.add(StringProperty('title', title, defaultValue: ''));
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null));
} }
} }
...@@ -33,7 +33,6 @@ import 'binding.dart'; ...@@ -33,7 +33,6 @@ import 'binding.dart';
import 'debug.dart'; import 'debug.dart';
import 'framework.dart'; import 'framework.dart';
import 'gesture_detector.dart'; import 'gesture_detector.dart';
import 'icon_data.dart';
/// Signature for the builder callback used by /// Signature for the builder callback used by
/// [WidgetInspector.selectButtonBuilder]. /// [WidgetInspector.selectButtonBuilder].
...@@ -677,60 +676,6 @@ class _InspectorReferenceData { ...@@ -677,60 +676,6 @@ class _InspectorReferenceData {
int count = 1; int count = 1;
} }
/// Configuration controlling how [DiagnosticsNode] objects are serialized to
/// JSON mainly focused on if and how children are included in the JSON.
class _SerializeConfig {
_SerializeConfig({
this.groupName,
this.summaryTree = false,
this.subtreeDepth = 1,
this.includeProperties = false,
this.expandPropertyValues = true,
this.maxDescendentsTruncatableNode = -1,
});
_SerializeConfig.merge(
_SerializeConfig base, {
int subtreeDepth,
}) : groupName = base.groupName,
summaryTree = base.summaryTree,
subtreeDepth = subtreeDepth ?? base.subtreeDepth,
includeProperties = base.includeProperties,
expandPropertyValues = base.expandPropertyValues,
maxDescendentsTruncatableNode = base.maxDescendentsTruncatableNode;
/// Optional object group name used to manage manage lifetimes of object
/// references in the returned JSON.
///
/// A call to `ext.flutter.inspector.disposeGroup` is required before objects
/// in the tree are garbage collected unless [groupName] is null in
/// which case no object references are included in the JSON payload.
final String groupName;
/// Whether to only include children that would exist in the summary tree.
final bool summaryTree;
/// How many levels of children to include in the JSON payload.
final int subtreeDepth;
/// Include information about properties in the JSON instead of requiring
/// a separate request to determine properties.
final bool includeProperties;
/// Expand children of properties that have values that are themselves
/// Diagnosticable objects.
final bool expandPropertyValues;
/// Whether to include object references to the [DiagnosticsNode] and
/// [DiagnosticsNode.value] objects in the JSON payload.
///
/// If [interactive] is true, a call to `ext.flutter.inspector.disposeGroup`
/// is required before objects in the tree will ever be garbage collected.
bool get interactive => groupName != null;
final int maxDescendentsTruncatableNode;
}
// Production implementation of [WidgetInspectorService]. // Production implementation of [WidgetInspectorService].
class _WidgetInspectorService = Object with WidgetInspectorService; class _WidgetInspectorService = Object with WidgetInspectorService;
...@@ -966,12 +911,13 @@ mixin WidgetInspectorService { ...@@ -966,12 +911,13 @@ mixin WidgetInspectorService {
void _reportError(FlutterErrorDetails details) { void _reportError(FlutterErrorDetails details) {
postEvent('Flutter.Error', _nodeToJson( postEvent('Flutter.Error', _nodeToJson(
details.toDiagnosticsNode(), details.toDiagnosticsNode(),
_SerializeConfig( _SerializationDelegate(
groupName: _consoleObjectGroup, groupName: _consoleObjectGroup,
subtreeDepth: 5, subtreeDepth: 5,
includeProperties: true, includeProperties: true,
expandPropertyValues: true, expandPropertyValues: true,
maxDescendentsTruncatableNode: 5, maxDescendentsTruncatableNode: 5,
service: this,
), ),
)); ));
} }
...@@ -1390,16 +1336,16 @@ mixin WidgetInspectorService { ...@@ -1390,16 +1336,16 @@ mixin WidgetInspectorService {
return path.map<Object>((_DiagnosticsPathNode node) => _pathNodeToJson( return path.map<Object>((_DiagnosticsPathNode node) => _pathNodeToJson(
node, node,
_SerializeConfig(groupName: groupName), _SerializationDelegate(groupName: groupName, service: this),
)).toList(); )).toList();
} }
Map<String, Object> _pathNodeToJson(_DiagnosticsPathNode pathNode, _SerializeConfig config) { Map<String, Object> _pathNodeToJson(_DiagnosticsPathNode pathNode, _SerializationDelegate delegate) {
if (pathNode == null) if (pathNode == null)
return null; return null;
return <String, Object>{ return <String, Object>{
'node': _nodeToJson(pathNode.node, config), 'node': _nodeToJson(pathNode.node, delegate),
'children': _nodesToJson(pathNode.children, config, parent: pathNode.node), 'children': _nodesToJson(pathNode.children, delegate, parent: pathNode.node),
'childIndex': pathNode.childIndex, 'childIndex': pathNode.childIndex,
}; };
} }
...@@ -1437,90 +1383,9 @@ mixin WidgetInspectorService { ...@@ -1437,90 +1383,9 @@ mixin WidgetInspectorService {
Map<String, Object> _nodeToJson( Map<String, Object> _nodeToJson(
DiagnosticsNode node, DiagnosticsNode node,
_SerializeConfig config, _SerializationDelegate delegate,
) { ) {
if (node == null) return node?.toJsonMap(delegate);
return null;
final Map<String, Object> json = node.toJsonMap();
final Object value = node.value;
if (config.interactive) {
json['objectId'] = toId(node, config.groupName);
json['valueId'] = toId(value, config.groupName);
}
if (value is Element) {
if (value is StatefulElement) {
json['stateful'] = true;
}
json['widgetRuntimeType'] = value.widget?.runtimeType.toString();
}
if (config.summaryTree) {
json['summaryTree'] = true;
}
final _Location creationLocation = _getCreationLocation(value);
bool createdByLocalProject = false;
if (creationLocation != null) {
json['locationId'] = _toLocationId(creationLocation);
json['creationLocation'] = creationLocation.toJsonMap();
if (_isLocalCreationLocation(creationLocation)) {
createdByLocalProject = true;
json['createdByLocalProject'] = true;
}
}
if (config.subtreeDepth > 0) {
json['children'] = _nodesToJson(_getChildrenHelper(node, config), config, parent: node);
}
if (config.includeProperties) {
final List<DiagnosticsNode> properties = node.getProperties();
if (properties.isEmpty && node is DiagnosticsProperty
&& config.expandPropertyValues && value is Diagnosticable) {
// Special case to expand property values.
json['properties'] = _nodesToJson(
value.toDiagnosticsNode().getProperties().where(
(DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info),
),
_SerializeConfig(groupName: config.groupName,
subtreeDepth: 0,
expandPropertyValues: false,
),
parent: node,
);
} else {
json['properties'] = _nodesToJson(
properties.where(
(DiagnosticsNode node) => !node.isFiltered(
createdByLocalProject ? DiagnosticLevel.fine : DiagnosticLevel
.info),
),
_SerializeConfig.merge(
config, subtreeDepth: math.max(0, config.subtreeDepth - 1)),
parent: node,
);
}
}
if (node is DiagnosticsProperty) {
// Add additional information about properties needed for graphical
// display of properties.
if (value is Color) {
json['valueProperties'] = <String, Object>{
'red': value.red,
'green': value.green,
'blue': value.blue,
'alpha': value.alpha,
};
} else if (value is IconData) {
json['valueProperties'] = <String, Object>{
'codePoint': value.codePoint,
};
}
}
return json;
} }
bool _isValueCreatedByLocalProject(Object value) { bool _isValueCreatedByLocalProject(Object value) {
...@@ -1560,7 +1425,7 @@ mixin WidgetInspectorService { ...@@ -1560,7 +1425,7 @@ mixin WidgetInspectorService {
return jsonString; return jsonString;
} }
List<DiagnosticsNode> _truncateNodes(Iterable<DiagnosticsNode> nodes, _SerializeConfig config) { List<DiagnosticsNode> _truncateNodes(Iterable<DiagnosticsNode> nodes, int maxDescendentsTruncatableNode) {
if (nodes.every((DiagnosticsNode node) => node.value is Element) && isWidgetCreationTracked()) { if (nodes.every((DiagnosticsNode node) => node.value is Element) && isWidgetCreationTracked()) {
final List<DiagnosticsNode> localNodes = nodes.where((DiagnosticsNode node) => final List<DiagnosticsNode> localNodes = nodes.where((DiagnosticsNode node) =>
_isValueCreatedByLocalProject(node.value)).toList(); _isValueCreatedByLocalProject(node.value)).toList();
...@@ -1568,37 +1433,15 @@ mixin WidgetInspectorService { ...@@ -1568,37 +1433,15 @@ mixin WidgetInspectorService {
return localNodes; return localNodes;
} }
} }
return nodes.take(config.maxDescendentsTruncatableNode).toList(); return nodes.take(maxDescendentsTruncatableNode).toList();
} }
List<Map<String, Object>> _nodesToJson( List<Map<String, Object>> _nodesToJson(
Iterable<DiagnosticsNode> nodes, Iterable<DiagnosticsNode> nodes,
_SerializeConfig config, { _SerializationDelegate delegate, {
@required DiagnosticsNode parent, @required DiagnosticsNode parent,
}) { }) {
bool truncated = false; return DiagnosticsNode.toJsonList(nodes, parent, delegate);
if (nodes == null)
return <Map<String, Object>>[];
if (config.maxDescendentsTruncatableNode >= 0 && parent?.allowTruncate == true && nodes.length > config.maxDescendentsTruncatableNode) {
nodes = _truncateNodes(nodes, config)..add(DiagnosticsNode.message('...'));
truncated = true;
}
final List<Map<String, Object>> json = nodes.map<Map<String, Object>>(
(DiagnosticsNode node) {
// The tricky special case here is that when in the detailsTree,
// we keep subtreeDepth from going down to zero until we reach nodes
// that also exist in the summary tree. This ensures that every time
// you expand a node in the details tree, you expand the entire subtree
// up until you reach the next nodes shared with the summary tree.
return _nodeToJson(
node,
config.summaryTree || config.subtreeDepth > 1 || _shouldShowInSummaryTree(node) ?
_SerializeConfig.merge(config, subtreeDepth: config.subtreeDepth - 1) : config,
);
}).toList();
if (truncated)
json.last['truncated'] = true;
return json;
} }
/// Returns a JSON representation of the properties of the [DiagnosticsNode] /// Returns a JSON representation of the properties of the [DiagnosticsNode]
...@@ -1610,7 +1453,7 @@ mixin WidgetInspectorService { ...@@ -1610,7 +1453,7 @@ mixin WidgetInspectorService {
List<Object> _getProperties(String diagnosticsNodeId, String groupName) { List<Object> _getProperties(String diagnosticsNodeId, String groupName) {
final DiagnosticsNode node = toObject(diagnosticsNodeId); final DiagnosticsNode node = toObject(diagnosticsNodeId);
return _nodesToJson(node == null ? const <DiagnosticsNode>[] : node.getProperties(), _SerializeConfig(groupName: groupName), parent: node); return _nodesToJson(node == null ? const <DiagnosticsNode>[] : node.getProperties(), _SerializationDelegate(groupName: groupName, service: this), parent: node);
} }
/// Returns a JSON representation of the children of the [DiagnosticsNode] /// Returns a JSON representation of the children of the [DiagnosticsNode]
...@@ -1621,8 +1464,8 @@ mixin WidgetInspectorService { ...@@ -1621,8 +1464,8 @@ mixin WidgetInspectorService {
List<Object> _getChildren(String diagnosticsNodeId, String groupName) { List<Object> _getChildren(String diagnosticsNodeId, String groupName) {
final DiagnosticsNode node = toObject(diagnosticsNodeId); final DiagnosticsNode node = toObject(diagnosticsNodeId);
final _SerializeConfig config = _SerializeConfig(groupName: groupName); final _SerializationDelegate delegate = _SerializationDelegate(groupName: groupName, service: this);
return _nodesToJson(node == null ? const <DiagnosticsNode>[] : _getChildrenHelper(node, config), config, parent: node); return _nodesToJson(node == null ? const <DiagnosticsNode>[] : _getChildrenFiltered(node, delegate), delegate, parent: node);
} }
/// Returns a JSON representation of the children of the [DiagnosticsNode] /// Returns a JSON representation of the children of the [DiagnosticsNode]
...@@ -1643,8 +1486,8 @@ mixin WidgetInspectorService { ...@@ -1643,8 +1486,8 @@ mixin WidgetInspectorService {
List<Object> _getChildrenSummaryTree(String diagnosticsNodeId, String groupName) { List<Object> _getChildrenSummaryTree(String diagnosticsNodeId, String groupName) {
final DiagnosticsNode node = toObject(diagnosticsNodeId); final DiagnosticsNode node = toObject(diagnosticsNodeId);
final _SerializeConfig config = _SerializeConfig(groupName: groupName, summaryTree: true); final _SerializationDelegate delegate = _SerializationDelegate(groupName: groupName, summaryTree: true, service: this);
return _nodesToJson(node == null ? const <DiagnosticsNode>[] : _getChildrenHelper(node, config), config, parent: node); return _nodesToJson(node == null ? const <DiagnosticsNode>[] : _getChildrenFiltered(node, delegate), delegate, parent: node);
} }
/// Returns a JSON representation of the children of the [DiagnosticsNode] /// Returns a JSON representation of the children of the [DiagnosticsNode]
...@@ -1660,12 +1503,8 @@ mixin WidgetInspectorService { ...@@ -1660,12 +1503,8 @@ mixin WidgetInspectorService {
List<Object> _getChildrenDetailsSubtree(String diagnosticsNodeId, String groupName) { List<Object> _getChildrenDetailsSubtree(String diagnosticsNodeId, String groupName) {
final DiagnosticsNode node = toObject(diagnosticsNodeId); final DiagnosticsNode node = toObject(diagnosticsNodeId);
// With this value of minDepth we only expand one extra level of important nodes. // With this value of minDepth we only expand one extra level of important nodes.
final _SerializeConfig config = _SerializeConfig(groupName: groupName, subtreeDepth: 1, includeProperties: true); final _SerializationDelegate delegate = _SerializationDelegate(groupName: groupName, subtreeDepth: 1, includeProperties: true, service: this);
return _nodesToJson(node == null ? const <DiagnosticsNode>[] : _getChildrenHelper(node, config), config, parent: node); return _nodesToJson(node == null ? const <DiagnosticsNode>[] : _getChildrenFiltered(node, delegate), delegate, parent: node);
}
List<DiagnosticsNode> _getChildrenHelper(DiagnosticsNode node, _SerializeConfig config) {
return _getChildrenFiltered(node, config).toList();
} }
bool _shouldShowInSummaryTree(DiagnosticsNode node) { bool _shouldShowInSummaryTree(DiagnosticsNode node) {
...@@ -1686,16 +1525,21 @@ mixin WidgetInspectorService { ...@@ -1686,16 +1525,21 @@ mixin WidgetInspectorService {
List<DiagnosticsNode> _getChildrenFiltered( List<DiagnosticsNode> _getChildrenFiltered(
DiagnosticsNode node, DiagnosticsNode node,
_SerializeConfig config, _SerializationDelegate delegate,
) { ) {
final List<DiagnosticsNode> children = <DiagnosticsNode>[]; return _filterChildren(node.getChildren(), delegate);
final List<DiagnosticsNode> rawChildren = node.getChildren(); }
for (DiagnosticsNode child in rawChildren) { List<DiagnosticsNode> _filterChildren(
if (!config.summaryTree || _shouldShowInSummaryTree(child)) { List<DiagnosticsNode> nodes,
_SerializationDelegate delegate,
) {
final List<DiagnosticsNode> children = <DiagnosticsNode>[];
for (DiagnosticsNode child in nodes) {
if (!delegate.summaryTree || _shouldShowInSummaryTree(child)) {
children.add(child); children.add(child);
} else { } else {
children.addAll(_getChildrenFiltered(child, config)); children.addAll(_getChildrenFiltered(child, delegate));
} }
} }
return children; return children;
...@@ -1708,7 +1552,7 @@ mixin WidgetInspectorService { ...@@ -1708,7 +1552,7 @@ mixin WidgetInspectorService {
} }
Map<String, Object> _getRootWidget(String groupName) { Map<String, Object> _getRootWidget(String groupName) {
return _nodeToJson(WidgetsBinding.instance?.renderViewElement?.toDiagnosticsNode(), _SerializeConfig(groupName: groupName)); return _nodeToJson(WidgetsBinding.instance?.renderViewElement?.toDiagnosticsNode(), _SerializationDelegate(groupName: groupName, service: this));
} }
/// Returns a JSON representation of the [DiagnosticsNode] for the root /// Returns a JSON representation of the [DiagnosticsNode] for the root
...@@ -1720,7 +1564,7 @@ mixin WidgetInspectorService { ...@@ -1720,7 +1564,7 @@ mixin WidgetInspectorService {
Map<String, Object> _getRootWidgetSummaryTree(String groupName) { Map<String, Object> _getRootWidgetSummaryTree(String groupName) {
return _nodeToJson( return _nodeToJson(
WidgetsBinding.instance?.renderViewElement?.toDiagnosticsNode(), WidgetsBinding.instance?.renderViewElement?.toDiagnosticsNode(),
_SerializeConfig(groupName: groupName, subtreeDepth: 1000000, summaryTree: true), _SerializationDelegate(groupName: groupName, subtreeDepth: 1000000, summaryTree: true, service: this),
); );
} }
...@@ -1732,7 +1576,7 @@ mixin WidgetInspectorService { ...@@ -1732,7 +1576,7 @@ mixin WidgetInspectorService {
} }
Map<String, Object> _getRootRenderObject(String groupName) { Map<String, Object> _getRootRenderObject(String groupName) {
return _nodeToJson(RendererBinding.instance?.renderView?.toDiagnosticsNode(), _SerializeConfig(groupName: groupName)); return _nodeToJson(RendererBinding.instance?.renderView?.toDiagnosticsNode(), _SerializationDelegate(groupName: groupName, service: this));
} }
/// Returns a JSON representation of the subtree rooted at the /// Returns a JSON representation of the subtree rooted at the
...@@ -1754,11 +1598,12 @@ mixin WidgetInspectorService { ...@@ -1754,11 +1598,12 @@ mixin WidgetInspectorService {
} }
return _nodeToJson( return _nodeToJson(
root, root,
_SerializeConfig( _SerializationDelegate(
groupName: groupName, groupName: groupName,
summaryTree: false, summaryTree: false,
subtreeDepth: 2, // TODO(jacobr): make subtreeDepth configurable. subtreeDepth: 2, // TODO(jacobr): make subtreeDepth configurable.
includeProperties: true, includeProperties: true,
service: this,
), ),
); );
} }
...@@ -1777,7 +1622,7 @@ mixin WidgetInspectorService { ...@@ -1777,7 +1622,7 @@ mixin WidgetInspectorService {
Map<String, Object> _getSelectedRenderObject(String previousSelectionId, String groupName) { Map<String, Object> _getSelectedRenderObject(String previousSelectionId, String groupName) {
final DiagnosticsNode previousSelection = toObject(previousSelectionId); final DiagnosticsNode previousSelection = toObject(previousSelectionId);
final RenderObject current = selection?.current; final RenderObject current = selection?.current;
return _nodeToJson(current == previousSelection?.value ? previousSelection : current?.toDiagnosticsNode(), _SerializeConfig(groupName: groupName)); return _nodeToJson(current == previousSelection?.value ? previousSelection : current?.toDiagnosticsNode(), _SerializationDelegate(groupName: groupName, service: this));
} }
/// Returns a [DiagnosticsNode] representing the currently selected [Element]. /// Returns a [DiagnosticsNode] representing the currently selected [Element].
...@@ -1864,7 +1709,7 @@ mixin WidgetInspectorService { ...@@ -1864,7 +1709,7 @@ mixin WidgetInspectorService {
Map<String, Object> _getSelectedWidget(String previousSelectionId, String groupName) { Map<String, Object> _getSelectedWidget(String previousSelectionId, String groupName) {
final DiagnosticsNode previousSelection = toObject(previousSelectionId); final DiagnosticsNode previousSelection = toObject(previousSelectionId);
final Element current = selection?.currentElement; final Element current = selection?.currentElement;
return _nodeToJson(current == previousSelection?.value ? previousSelection : current?.toDiagnosticsNode(), _SerializeConfig(groupName: groupName)); return _nodeToJson(current == previousSelection?.value ? previousSelection : current?.toDiagnosticsNode(), _SerializationDelegate(groupName: groupName, service: this));
} }
/// Returns a [DiagnosticsNode] representing the currently selected [Element] /// Returns a [DiagnosticsNode] representing the currently selected [Element]
...@@ -1895,7 +1740,7 @@ mixin WidgetInspectorService { ...@@ -1895,7 +1740,7 @@ mixin WidgetInspectorService {
} }
current = firstLocal; current = firstLocal;
} }
return _nodeToJson(current == previousSelection?.value ? previousSelection : current?.toDiagnosticsNode(), _SerializeConfig(groupName: groupName)); return _nodeToJson(current == previousSelection?.value ? previousSelection : current?.toDiagnosticsNode(), _SerializationDelegate(groupName: groupName, service: this));
} }
/// Returns whether [Widget] creation locations are available. /// Returns whether [Widget] creation locations are available.
...@@ -2888,3 +2733,104 @@ int _toLocationId(_Location location) { ...@@ -2888,3 +2733,104 @@ int _toLocationId(_Location location) {
_locationToId[location] = id; _locationToId[location] = id;
return id; return id;
} }
class _SerializationDelegate implements DiagnosticsSerializationDelegate {
_SerializationDelegate({
this.groupName,
this.summaryTree = false,
this.maxDescendentsTruncatableNode = -1,
this.expandPropertyValues = true,
this.subtreeDepth = 1,
this.includeProperties = false,
@required this.service,
});
final WidgetInspectorService service;
final String groupName;
final bool summaryTree;
final int maxDescendentsTruncatableNode;
@override
final bool includeProperties;
@override
final int subtreeDepth;
@override
final bool expandPropertyValues;
final List<DiagnosticsNode> _nodesCreatedByLocalProject = <DiagnosticsNode>[];
bool get interactive => groupName != null;
@override
Map<String, Object> additionalNodeProperties(DiagnosticsNode node) {
final Map<String, Object> result = <String, Object>{};
final Object value = node.value;
if (interactive) {
result['objectId'] = service.toId(node, groupName);
result['valueId'] = service.toId(value, groupName);
}
if (summaryTree) {
result['summaryTree'] = true;
}
final _Location creationLocation = _getCreationLocation(value);
if (creationLocation != null) {
result['locationId'] = _toLocationId(creationLocation);
result['creationLocation'] = creationLocation.toJsonMap();
if (service._isLocalCreationLocation(creationLocation)) {
_nodesCreatedByLocalProject.add(node);
result['createdByLocalProject'] = true;
}
}
return result;
}
@override
DiagnosticsSerializationDelegate delegateForNode(DiagnosticsNode node) {
// The tricky special case here is that when in the detailsTree,
// we keep subtreeDepth from going down to zero until we reach nodes
// that also exist in the summary tree. This ensures that every time
// you expand a node in the details tree, you expand the entire subtree
// up until you reach the next nodes shared with the summary tree.
return summaryTree || subtreeDepth > 1 || service._shouldShowInSummaryTree(node)
? copyWith(subtreeDepth: subtreeDepth - 1)
: this;
}
@override
List<DiagnosticsNode> filterChildren(List<DiagnosticsNode> children, DiagnosticsNode owner) {
return service._filterChildren(children, this);
}
@override
List<DiagnosticsNode> filterProperties(List<DiagnosticsNode> properties, DiagnosticsNode owner) {
final bool createdByLocalProject = _nodesCreatedByLocalProject.contains(owner);
return properties.where((DiagnosticsNode node) {
return !node.isFiltered(createdByLocalProject ? DiagnosticLevel.fine : DiagnosticLevel.info);
}).toList();
}
@override
List<DiagnosticsNode> truncateNodesList(List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
if (maxDescendentsTruncatableNode >= 0 &&
owner?.allowTruncate == true &&
nodes.length > maxDescendentsTruncatableNode) {
nodes = service._truncateNodes(nodes, maxDescendentsTruncatableNode);
}
return nodes;
}
@override
DiagnosticsSerializationDelegate copyWith({int subtreeDepth, bool includeProperties}) {
return _SerializationDelegate(
groupName: groupName,
summaryTree: summaryTree,
maxDescendentsTruncatableNode: maxDescendentsTruncatableNode,
expandPropertyValues: expandPropertyValues,
subtreeDepth: subtreeDepth ?? this.subtreeDepth,
includeProperties: includeProperties ?? this.includeProperties,
service: service,
);
}
}
// Copyright 2019 The Chromium Authors. 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:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
test('Element diagnostics json includes widgetRuntimeType', () async {
final Element element = _TestElement();
final Map<String, Object> json = element.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate());
expect(json['widgetRuntimeType'], 'Placeholder');
expect(json['stateful'], isFalse);
});
test('StatefulElement diganostics are stateful', () {
final Element element = StatefulElement(const Tooltip(message: 'foo'));
final Map<String, Object> json = element.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate());
expect(json['widgetRuntimeType'], 'Tooltip');
expect(json['stateful'], isTrue);
});
group('Serialization', () {
final TestTree testTree = TestTree(
properties: <DiagnosticsNode>[
StringProperty('stringProperty1', 'value1', quoted: false),
DoubleProperty('doubleProperty1', 42.5),
DoubleProperty('roundedProperty', 1.0 / 3.0),
StringProperty('DO_NOT_SHOW', 'DO_NOT_SHOW', level: DiagnosticLevel.hidden, quoted: false),
DiagnosticsProperty<Object>('DO_NOT_SHOW_NULL', null, defaultValue: null),
DiagnosticsProperty<Object>('nullProperty', null),
StringProperty('node_type', '<root node>', showName: false, quoted: false),
],
children: <TestTree>[
TestTree(name: 'node A'),
TestTree(
name: 'node B',
properties: <DiagnosticsNode>[
StringProperty('p1', 'v1', quoted: false),
StringProperty('p2', 'v2', quoted: false),
],
children: <TestTree>[
TestTree(name: 'node B1'),
TestTree(
name: 'node B2',
properties: <DiagnosticsNode>[StringProperty('property1', 'value1', quoted: false)],
),
TestTree(
name: 'node B3',
properties: <DiagnosticsNode>[
StringProperty('node_type', '<leaf node>', showName: false, quoted: false),
IntProperty('foo', 42),
],
),
],
),
TestTree(
name: 'node C',
properties: <DiagnosticsNode>[
StringProperty('foo', 'multi\nline\nvalue!', quoted: false),
],
),
],
);
test('default', () {
final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate());
expect(result.containsKey('properties'), isFalse);
expect(result.containsKey('children'), isFalse);
});
test('subtreeDepth 1', () {
final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(subtreeDepth: 1));
expect(result.containsKey('properties'), isFalse);
final List<Map<String, Object>> children = result['children'];
expect(children[0].containsKey('children'), isFalse);
expect(children[1].containsKey('children'), isFalse);
expect(children[2].containsKey('children'), isFalse);
});
test('subtreeDepth 5', () {
final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(subtreeDepth: 5));
expect(result.containsKey('properties'), isFalse);
final List<Map<String, Object>> children = result['children'];
expect(children[0]['children'], hasLength(0));
expect(children[1]['children'], hasLength(3));
expect(children[2]['children'], hasLength(0));
});
test('includeProperties', () {
final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(includeProperties: true));
expect(result.containsKey('children'), isFalse);
expect(result['properties'], hasLength(7));
});
test('includeProperties with subtreedepth 1', () {
final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(
includeProperties: true,
subtreeDepth: 1,
));
expect(result['properties'], hasLength(7));
final List<Map<String, Object>> children = result['children'];
expect(children, hasLength(3));
expect(children[0]['properties'], hasLength(0));
expect(children[1]['properties'], hasLength(2));
expect(children[2]['properties'], hasLength(1));
});
test('additionalNodeProperties', () {
final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(const TestDiagnosticsSerializationDelegate(
includeProperties: true,
subtreeDepth: 1,
additionalNodePropertiesMap: <String, Object>{
'foo': true,
},
));
expect(result['foo'], isTrue);
final List<Map<String, Object>> properties = result['properties'];
expect(properties, hasLength(7));
expect(properties.every((Map<String, Object> property) => property['foo'] == true), isTrue);
final List<Map<String, Object>> children = result['children'];
expect(children, hasLength(3));
expect(children.every((Map<String, Object> child) => child['foo'] == true), isTrue);
});
test('filterProperties - sublist', () {
final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate(
includeProperties: true,
propertyFilter: (List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
return nodes.whereType<StringProperty>().toList();
}
));
final List<Map<String, Object>> properties = result['properties'];
expect(properties, hasLength(3));
expect(properties.every((Map<String, Object> property) => property['type'] == 'StringProperty'), isTrue);
});
test('filterProperties - replace', () {
bool replaced = false;
final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate(
includeProperties: true,
propertyFilter: (List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
if (replaced) {
return nodes;
}
replaced = true;
return <DiagnosticsNode>[
StringProperty('foo', 'bar'),
];
}
));
final List<Map<String, Object>> properties = result['properties'];
expect(properties, hasLength(1));
expect(properties.single['name'], 'foo');
});
test('filterChildren - sublist', () {
final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate(
subtreeDepth: 1,
childFilter: (List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
return nodes.where((DiagnosticsNode node) => node.getProperties().isEmpty).toList();
}
));
final List<Map<String, Object>> children = result['children'];
expect(children, hasLength(1));
});
test('filterChildren - replace', () {
final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate(
subtreeDepth: 1,
childFilter: (List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
final List<DiagnosticsNode> result = <DiagnosticsNode>[];
for (DiagnosticsNode node in nodes) {
result.addAll(node.getChildren());
}
return result;
}
));
final List<Map<String, Object>> children = result['children'];
expect(children, hasLength(3));
expect(children.first['name'], 'child node B1');
});
test('nodeTruncator', () {
final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate(
subtreeDepth: 5,
includeProperties: true,
nodeTruncator: (List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
return nodes.take(2).toList();
}
));
final List<Map<String, Object>> children = result['children'];
expect(children, hasLength(3));
expect(children.last['truncated'], isTrue);
final List<Map<String, Object>> properties = result['properties'];
expect(properties, hasLength(3));
expect(properties.last['truncated'], isTrue);
});
test('delegateForAddingNodes', () {
final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate(
subtreeDepth: 5,
includeProperties: true,
nodeDelegator: (DiagnosticsNode node, DiagnosticsSerializationDelegate delegate) {
return delegate.copyWith(includeProperties: false);
}
));
final List<Map<String, Object>> properties = result['properties'];
expect(properties, hasLength(7));
expect(properties.every((Map<String, Object> property) => !property.containsKey('properties')), isTrue);
final List<Map<String, Object>> children = result['children'];
expect(children, hasLength(3));
expect(children.every((Map<String, Object> child) => !child.containsKey('properties')), isTrue);
});
});
}
class _TestElement extends Element {
_TestElement() : super(const Placeholder());
@override
void forgetChild(Element child) {
// Intentionally left empty.
}
@override
void performRebuild() {
// Intentionally left empty.
}
}
class TestTree extends Object with DiagnosticableTreeMixin {
TestTree({
this.name,
this.style,
this.children = const <TestTree>[],
this.properties = const <DiagnosticsNode>[],
});
final String name;
final List<TestTree> children;
final List<DiagnosticsNode> properties;
final DiagnosticsTreeStyle style;
@override
List<DiagnosticsNode> debugDescribeChildren() {
final List<DiagnosticsNode> children = <DiagnosticsNode>[];
for (TestTree child in this.children) {
children.add(child.toDiagnosticsNode(
name: 'child ${child.name}',
style: child.style,
));
}
return children;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
if (style != null)
properties.defaultDiagnosticsTreeStyle = style;
this.properties.forEach(properties.add);
}
}
class TestDiagnosticsSerializationDelegate implements DiagnosticsSerializationDelegate {
const TestDiagnosticsSerializationDelegate({
this.includeProperties = false,
this.subtreeDepth = 0,
this.additionalNodePropertiesMap = const <String, Object>{},
this.childFilter,
this.propertyFilter,
this.nodeTruncator,
this.nodeDelegator,
});
final Map<String, Object> additionalNodePropertiesMap;
final Function childFilter;
final Function propertyFilter;
final Function nodeTruncator;
final Function nodeDelegator;
@override
Map<String, Object> additionalNodeProperties(DiagnosticsNode node) {
return additionalNodePropertiesMap;
}
@override
DiagnosticsSerializationDelegate delegateForNode(DiagnosticsNode node) {
if (nodeDelegator != null) {
return nodeDelegator(node, this);
}
return subtreeDepth > 0 ? copyWith(subtreeDepth: subtreeDepth - 1) : this;
}
@override
bool get expandPropertyValues => false;
@override
List<DiagnosticsNode> filterChildren(List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
return childFilter != null ? childFilter(nodes, owner) : nodes;
}
@override
List<DiagnosticsNode> filterProperties(List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
return propertyFilter != null ? propertyFilter(nodes, owner) : nodes;
}
@override
final bool includeProperties;
@override
final int subtreeDepth;
@override
List<DiagnosticsNode> truncateNodesList(List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
return nodeTruncator != null ? nodeTruncator(nodes, owner) : nodes;
}
@override
DiagnosticsSerializationDelegate copyWith({int subtreeDepth, bool includeProperties}) {
return TestDiagnosticsSerializationDelegate(
includeProperties: includeProperties ?? this.includeProperties,
subtreeDepth: subtreeDepth ?? this.subtreeDepth,
additionalNodePropertiesMap: additionalNodePropertiesMap,
childFilter: childFilter,
propertyFilter: propertyFilter,
nodeTruncator: nodeTruncator,
nodeDelegator: nodeDelegator,
);
}
}
...@@ -52,7 +52,7 @@ enum ExampleEnum { ...@@ -52,7 +52,7 @@ enum ExampleEnum {
/// Encode and decode to JSON to make sure all objects in the JSON for the /// Encode and decode to JSON to make sure all objects in the JSON for the
/// [DiagnosticsNode] are valid JSON. /// [DiagnosticsNode] are valid JSON.
Map<String, Object> simulateJsonSerialization(DiagnosticsNode node) { Map<String, Object> simulateJsonSerialization(DiagnosticsNode node) {
return json.decode(json.encode(node.toJsonMap())); return json.decode(json.encode(node.toJsonMap(const DiagnosticsSerializationDelegate())));
} }
void validateNodeJsonSerialization(DiagnosticsNode node) { void validateNodeJsonSerialization(DiagnosticsNode node) {
......
...@@ -68,7 +68,6 @@ void main() { ...@@ -68,7 +68,6 @@ void main() {
expect(description, <String>[ expect(description, <String>[
'trackHeight: 7.0', 'trackHeight: 7.0',
'activeTrackColor: Color(0xff000001)', 'activeTrackColor: Color(0xff000001)',
'activeTrackColor: Color(0xff000001)',
'inactiveTrackColor: Color(0xff000002)', 'inactiveTrackColor: Color(0xff000002)',
'disabledActiveTrackColor: Color(0xff000003)', 'disabledActiveTrackColor: Color(0xff000003)',
'disabledInactiveTrackColor: Color(0xff000004)', 'disabledInactiveTrackColor: Color(0xff000004)',
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
...@@ -424,4 +425,17 @@ void main() { ...@@ -424,4 +425,17 @@ void main() {
expect(greens1['2259 C'], const Color(0xFF027223)); expect(greens1['2259 C'], const Color(0xFF027223));
expect(greens1.value, 0xFF027223); expect(greens1.value, 0xFF027223);
}); });
test('ColorDiagnosticsProperty includes valueProperties in JSON', () {
ColorProperty property = ColorProperty('foo', const Color.fromARGB(10, 20, 30, 40));
final Map<String, Object> valueProperties = property.toJsonMap(const DiagnosticsSerializationDelegate())['valueProperties'];
expect(valueProperties['alpha'], 10);
expect(valueProperties['red'], 20);
expect(valueProperties['green'], 30);
expect(valueProperties['blue'], 40);
property = ColorProperty('foo', null);
final Map<String, Object> json = property.toJsonMap(const DiagnosticsSerializationDelegate());
expect(json.containsKey('valueProperties'), isFalse);
});
} }
// Copyright 2019 The Chromium Authors. 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:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
test('IconDataDiagnosticsProperty includes valueProperties in JSON', () {
IconDataProperty property = IconDataProperty('foo', const IconData(101010));
final Map<String, Object> valueProperties = property.toJsonMap(const DiagnosticsSerializationDelegate())['valueProperties'];
print(valueProperties);
expect(valueProperties['codePoint'], 101010);
property = IconDataProperty('foo', null);
final Map<String, Object> json = property.toJsonMap(const DiagnosticsSerializationDelegate());
expect(json.containsKey('valueProperties'), isFalse);
});
}
...@@ -2361,6 +2361,63 @@ class TestWidgetInspectorService extends Object with WidgetInspectorService { ...@@ -2361,6 +2361,63 @@ class TestWidgetInspectorService extends Object with WidgetInspectorService {
expect(box1.localToGlobal(Offset.zero), equals(position1)); expect(box1.localToGlobal(Offset.zero), equals(position1));
expect(box2.localToGlobal(Offset.zero), equals(position2)); expect(box2.localToGlobal(Offset.zero), equals(position2));
}, skip: isBrowser); }, skip: isBrowser);
testWidgets('getChildrenDetailsSubtree', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
title: 'Hello, World',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: const Text('Hello, World'),
),
body: const Center(
child: Text('Hello, World!'),
),
),
),
);
// Figure out the pubRootDirectory
final Map<String, Object> jsonObject = await service.testExtension(
'getSelectedWidget',
<String, String>{'arg': null, 'objectGroup': 'my-group'},
);
final Map<String, Object> creationLocation =
jsonObject['creationLocation'];
expect(creationLocation, isNotNull);
final String file = creationLocation['file'];
expect(file, endsWith('widget_inspector_test.dart'));
final List<String> segments = Uri.parse(file).pathSegments;
// Strip a couple subdirectories away to generate a plausible pub rootdirectory.
final String pubRootTest = '/' + segments.take(segments.length - 2).join('/');
service.setPubRootDirectories(<String>[pubRootTest]);
final String summary = service.getRootWidgetSummaryTree('foo1');
final List<dynamic> childrenOfRoot = json.decode(summary)['children'];
final List<dynamic> childrenOfMaterialApp = childrenOfRoot.first['children'];
final Map<String, Object> scaffold = childrenOfMaterialApp.first;
expect(scaffold['description'], 'Scaffold');
final String objectId = scaffold['objectId'];
final String details = service.getDetailsSubtree(objectId, 'foo2');
final List<dynamic> detailedChildren = json.decode(details)['children'];
final List<Map<String, Object>> appBars = <Map<String, Object>>[];
void visitChildren(List<dynamic> children) {
for (Map<String, Object> child in children) {
if (child['description'] == 'AppBar') {
appBars.add(child);
}
if (child.containsKey('children')) {
visitChildren(child['children']);
}
}
}
visitChildren(detailedChildren);
expect(appBars.single.containsKey('children'), isFalse);
}, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // Test requires --track-widget-creation flag.
} }
} }
......
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