Commit 9f510ebd authored by Jacob Richman's avatar Jacob Richman Committed by GitHub

Refactor RenderObject.toStringDeep and Widget.toStringDeep code to use DiagnosticsNode (#11359)

Refactor RenderObject.toStringDeep and Widget.toStringDeep code to use DiagnosticsNode.
parent 5278588d
...@@ -102,10 +102,10 @@ class _StatusBarPaddingSliver extends SingleChildRenderObjectWidget { ...@@ -102,10 +102,10 @@ class _StatusBarPaddingSliver extends SingleChildRenderObjectWidget {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('maxHeight: $maxHeight'); description.add(new DoubleProperty('maxHeight', maxHeight));
description.add('scrollFactor: $scrollFactor'); description.add(new DoubleProperty('scrollFactor', scrollFactor));
} }
} }
......
...@@ -101,10 +101,9 @@ class CupertinoButton extends StatefulWidget { ...@@ -101,10 +101,9 @@ class CupertinoButton extends StatefulWidget {
_CupertinoButtonState createState() => new _CupertinoButtonState(); _CupertinoButtonState createState() => new _CupertinoButtonState();
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
if (!enabled) description.add(new FlagProperty('enabled', value: enabled, ifFalse: 'disabled'));
description.add('disabled');
} }
} }
......
...@@ -422,6 +422,22 @@ class _CupertinoEdgeShadowDecoration extends Decoration { ...@@ -422,6 +422,22 @@ class _CupertinoEdgeShadowDecoration extends Decoration {
int get hashCode { int get hashCode {
return edgeGradient.hashCode; return edgeGradient.hashCode;
} }
@override
DiagnosticsNode toDiagnosticsNode({
String name,
DiagnosticsTreeStyle style: DiagnosticsTreeStyle.singleLine,
}) {
return new DiagnosticsNode.lazy(
name: name,
object: this,
style: style,
description: '$runtimeType',
fillProperties: (List<DiagnosticsNode> properties) {
properties.add(new DiagnosticsProperty<LinearGradient>('edgeGradient', edgeGradient));
},
);
}
} }
/// A [BoxPainter] used to draw the page transition shadow using gradients. /// A [BoxPainter] used to draw the page transition shadow using gradients.
......
...@@ -111,11 +111,11 @@ class CupertinoSlider extends StatefulWidget { ...@@ -111,11 +111,11 @@ class CupertinoSlider extends StatefulWidget {
_CupertinoSliderState createState() => new _CupertinoSliderState(); _CupertinoSliderState createState() => new _CupertinoSliderState();
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('value: ${value.toStringAsFixed(1)}'); description.add(new DoubleProperty('value', value));
description.add('min: $min'); description.add(new DoubleProperty('min', min));
description.add('max: $max'); description.add(new DoubleProperty('max', max));
} }
} }
......
...@@ -88,11 +88,10 @@ class CupertinoSwitch extends StatefulWidget { ...@@ -88,11 +88,10 @@ class CupertinoSwitch extends StatefulWidget {
_CupertinoSwitchState createState() => new _CupertinoSwitchState(); _CupertinoSwitchState createState() => new _CupertinoSwitchState();
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('value: ${value ? "on" : "off"}'); description.add(new FlagProperty('value', value: value, ifTrue: 'on', ifFalse: 'off', showName: true));
if (onChanged == null) description.add(new ObjectFlagProperty<ValueChanged<bool>>('onChanged', onChanged, ifNull: 'disabled'));
description.add('disabled');
} }
} }
...@@ -420,10 +419,9 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox implements SemanticsAc ...@@ -420,10 +419,9 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox implements SemanticsAc
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('value: ${value ? "checked" : "unchecked"}'); description.add(new FlagProperty('value', value: value, ifTrue: 'checked', ifFalse: 'unchecked', showName: true));
if (!isInteractive) description.add(new FlagProperty('isInteractive', value: isInteractive, ifTrue: 'enabled', ifFalse: 'disabled', showName: true, defaultValue: true));
description.add('disabled');
} }
} }
...@@ -249,10 +249,9 @@ class MaterialButton extends StatefulWidget { ...@@ -249,10 +249,9 @@ class MaterialButton extends StatefulWidget {
_MaterialButtonState createState() => new _MaterialButtonState(); _MaterialButtonState createState() => new _MaterialButtonState();
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
if (!enabled) description.add(new FlagProperty('enabled', value: enabled, ifFalse: 'disabled'));
description.add('disabled');
} }
} }
......
...@@ -203,12 +203,10 @@ class IconButton extends StatelessWidget { ...@@ -203,12 +203,10 @@ class IconButton extends StatelessWidget {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('$icon'); description.add(new DiagnosticsProperty<Widget>('icon', icon, showName: false));
if (onPressed == null) description.add(new ObjectFlagProperty<VoidCallback>('onPressed', onPressed, ifNull: 'disabled'));
description.add('disabled'); description.add(new StringProperty('tooltip', tooltip, defaultValue: null, quoted: false));
if (tooltip != null)
description.add('tooltip: "$tooltip"');
} }
} }
...@@ -222,8 +222,8 @@ class InkResponse extends StatefulWidget { ...@@ -222,8 +222,8 @@ class InkResponse extends StatefulWidget {
_InkResponseState<InkResponse> createState() => new _InkResponseState<InkResponse>(); _InkResponseState<InkResponse> createState() => new _InkResponseState<InkResponse>();
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
final List<String> gestures = <String>[]; final List<String> gestures = <String>[];
if (onTap != null) if (onTap != null)
gestures.add('tap'); gestures.add('tap');
...@@ -233,8 +233,14 @@ class InkResponse extends StatefulWidget { ...@@ -233,8 +233,14 @@ class InkResponse extends StatefulWidget {
gestures.add('long press'); gestures.add('long press');
if (gestures.isEmpty) if (gestures.isEmpty)
gestures.add('<none>'); gestures.add('<none>');
description.add('gestures: ${gestures.join(", ")}'); description.add(new IterableProperty<String>('gestures', gestures));
description.add('${containedInkWell ? "clipped to " : ""}$highlightShape'); description.add(new DiagnosticsProperty<bool>('containedInkWell', containedInkWell, hidden: true));
description.add(new DiagnosticsProperty<BoxShape>(
'highlightShape',
highlightShape,
description: '${containedInkWell ? "clipped to " : ""}$highlightShape',
showName: false,
));
} }
} }
......
...@@ -372,12 +372,12 @@ class InputDecorator extends StatelessWidget { ...@@ -372,12 +372,12 @@ class InputDecorator extends StatelessWidget {
final Widget child; final Widget child;
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('decoration: $decoration'); description.add(new DiagnosticsProperty<InputDecoration>('decoration', decoration));
description.add('baseStyle: $baseStyle'); description.add(new EnumProperty<TextStyle>('baseStyle', baseStyle));
description.add('isFocused: $isFocused'); description.add(new DiagnosticsProperty<bool>('isFocused', isFocused));
description.add('isEmpty: $isEmpty'); description.add(new DiagnosticsProperty<bool>('isEmpty', isEmpty));
} }
Color _getActiveColor(ThemeData themeData) { Color _getActiveColor(ThemeData themeData) {
...@@ -615,9 +615,9 @@ class _AnimatedLabel extends ImplicitlyAnimatedWidget { ...@@ -615,9 +615,9 @@ class _AnimatedLabel extends ImplicitlyAnimatedWidget {
_AnimatedLabelState createState() => new _AnimatedLabelState(); _AnimatedLabelState createState() => new _AnimatedLabelState();
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
'$style'.split('\n').forEach(description.add); style?.debugFillProperties(description);
} }
} }
......
...@@ -175,18 +175,13 @@ class Material extends StatefulWidget { ...@@ -175,18 +175,13 @@ class Material extends StatefulWidget {
_MaterialState createState() => new _MaterialState(); _MaterialState createState() => new _MaterialState();
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('$type'); description.add(new EnumProperty<MaterialType>('type', type));
description.add('elevation: ${elevation.toStringAsFixed(1)}'); description.add(new DoubleProperty('elevation', elevation));
if (color != null) description.add(new DiagnosticsProperty<Color>('color', color, defaultValue: null));
description.add('color: $color'); textStyle?.debugFillProperties(description, prefix: 'textStyle.');
if (textStyle != null) { description.add(new EnumProperty<BorderRadius>('borderRadius', borderRadius, defaultValue: null));
for (String entry in '$textStyle'.split('\n'))
description.add('textStyle.$entry');
}
if (borderRadius != null)
description.add('borderRadius: $borderRadius');
} }
/// The default radius of an ink splash in logical pixels. /// The default radius of an ink splash in logical pixels.
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'dart:math' as math; import 'dart:math' as math;
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'material.dart'; import 'material.dart';
...@@ -60,13 +61,9 @@ abstract class ProgressIndicator extends StatefulWidget { ...@@ -60,13 +61,9 @@ abstract class ProgressIndicator extends StatefulWidget {
Color _getValueColor(BuildContext context) => valueColor?.value ?? Theme.of(context).accentColor; Color _getValueColor(BuildContext context) => valueColor?.value ?? Theme.of(context).accentColor;
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
if (value != null) { description.add(new PercentProperty('value', value, showName: false, ifNull: '<indeterminate>'));
description.add('${(value.clamp(0.0, 1.0) * 100.0).toStringAsFixed(1)}%');
} else {
description.add('<indeterminate>');
}
} }
} }
......
...@@ -161,11 +161,11 @@ class Slider extends StatefulWidget { ...@@ -161,11 +161,11 @@ class Slider extends StatefulWidget {
_SliderState createState() => new _SliderState(); _SliderState createState() => new _SliderState();
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('value: ${value.toStringAsFixed(1)}'); description.add(new DoubleProperty('value', value));
description.add('min: $min'); description.add(new DoubleProperty('min', min));
description.add('max: $max'); description.add(new DoubleProperty('max', max));
} }
} }
......
...@@ -99,11 +99,10 @@ class Switch extends StatefulWidget { ...@@ -99,11 +99,10 @@ class Switch extends StatefulWidget {
_SwitchState createState() => new _SwitchState(); _SwitchState createState() => new _SwitchState();
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('value: ${value ? "on" : "off"}'); description.add(new FlagProperty('value', value: value, ifTrue: 'on', ifFalse: 'off', showName: true));
if (onChanged == null) description.add(new ObjectFlagProperty<ValueChanged<bool>>('onChanged', onChanged, ifNull: 'disabled'));
description.add('disabled');
} }
} }
......
...@@ -89,12 +89,10 @@ class Tab extends StatelessWidget { ...@@ -89,12 +89,10 @@ class Tab extends StatelessWidget {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
if (text != null) description.add(new StringProperty('text', text, defaultValue: null));
description.add('text: $text'); description.add(new DiagnosticsProperty<Widget>('icon', icon, defaultValue: null));
if (icon != null)
description.add('icon: $icon');
} }
} }
......
...@@ -176,25 +176,17 @@ class TextField extends StatefulWidget { ...@@ -176,25 +176,17 @@ class TextField extends StatefulWidget {
_TextFieldState createState() => new _TextFieldState(); _TextFieldState createState() => new _TextFieldState();
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
if (controller != null) description.add(new DiagnosticsProperty<TextEditingController>('controller', controller, defaultValue: null));
description.add('controller: $controller'); description.add(new DiagnosticsProperty<FocusNode>('focusNode', focusNode, defaultValue: null));
if (focusNode != null) description.add(new DiagnosticsProperty<InputDecoration>('decoration', decoration));
description.add('focusNode: $focusNode'); description.add(new EnumProperty<TextInputType>('keyboardType', keyboardType, defaultValue: TextInputType.text));
description.add('decoration: $decoration'); description.add(new DiagnosticsProperty<TextStyle>('style', style, defaultValue: null));
if (keyboardType != TextInputType.text) description.add(new DiagnosticsProperty<bool>('autofocus', autofocus, defaultValue: false));
description.add('keyboardType: $keyboardType'); description.add(new DiagnosticsProperty<bool>('obscureText', obscureText, defaultValue: false));
if (style != null) description.add(new DiagnosticsProperty<bool>('autocorrect', autocorrect, defaultValue: false));
description.add('style: $style'); description.add(new IntProperty('maxLines', maxLines, defaultValue: 1));
if (autofocus)
description.add('autofocus: $autofocus');
if (obscureText)
description.add('obscureText: $obscureText');
if (autocorrect)
description.add('autocorrect: $autocorrect');
if (maxLines != 1)
description.add('maxLines: $maxLines');
} }
} }
......
...@@ -138,9 +138,9 @@ class Theme extends StatelessWidget { ...@@ -138,9 +138,9 @@ class Theme extends StatelessWidget {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('$data'); description.add(new DiagnosticsProperty<ThemeData>('data', data, showName: false));
} }
} }
...@@ -235,9 +235,8 @@ class _AnimatedThemeState extends AnimatedWidgetBaseState<AnimatedTheme> { ...@@ -235,9 +235,8 @@ class _AnimatedThemeState extends AnimatedWidgetBaseState<AnimatedTheme> {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
if (_data != null) description.add(new DiagnosticsProperty<ThemeDataTween>('data', _data, showName: false, defaultValue: null));
description.add('$_data');
} }
} }
...@@ -303,10 +303,9 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic ...@@ -303,10 +303,9 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('value: ${value ? "checked" : "unchecked"}'); description.add(new FlagProperty('value', value: value, ifTrue: 'checked', ifFalse: 'unchecked', showName: true));
if (!isInteractive) description.add(new FlagProperty('isInteractive', value: isInteractive, ifTrue: 'enabled', ifFalse: 'disabled', defaultValue: true));
description.add('disabled');
} }
} }
...@@ -86,11 +86,11 @@ class Tooltip extends StatefulWidget { ...@@ -86,11 +86,11 @@ class Tooltip extends StatefulWidget {
_TooltipState createState() => new _TooltipState(); _TooltipState createState() => new _TooltipState();
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('"$message"'); description.add(new StringProperty('message', message, showName: false));
description.add('vertical offset: $verticalOffset'); description.add(new DoubleProperty('vertical offset', verticalOffset));
description.add('position: ${preferBelow ? "below" : "above"}'); description.add(new FlagProperty('position', value: preferBelow, ifTrue: 'below', ifFalse: 'above', showName: true));
} }
} }
......
...@@ -1601,38 +1601,24 @@ class BoxDecoration extends Decoration { ...@@ -1601,38 +1601,24 @@ class BoxDecoration extends Decoration {
); );
} }
/// Stringifies the BoxDecoration. By default, the output will be on one line.
/// If the method is passed a non-empty string argument, then the output will
/// span multiple lines, each prefixed by that argument.
@override @override
String toString([String prefix = '', String indentPrefix]) { DiagnosticsNode toDiagnosticsNode({ String name, DiagnosticsTreeStyle style: DiagnosticsTreeStyle.whitespace }) {
final List<String> result = <String>[]; return new DiagnosticsNode.lazy(
if (color != null) name: name,
result.add('${prefix}color: $color'); object: this,
if (image != null) description: '',
result.add('${prefix}image: $image'); style: style,
if (border != null) emptyBodyDescription: '<no decorations specified>',
result.add('${prefix}border: $border'); fillProperties: (List<DiagnosticsNode> properties) {
if (borderRadius != null) properties.add(new DiagnosticsProperty<Color>('color', color, defaultValue: null));
result.add('${prefix}borderRadius: $borderRadius'); properties.add(new DiagnosticsProperty<DecorationImage>('image', image, defaultValue: null));
if (boxShadow != null) { properties.add(new DiagnosticsProperty<Border>('border', border, defaultValue: null));
if (indentPrefix != null && boxShadow.length > 1) { properties.add(new DiagnosticsProperty<BorderRadius>('borderRadius', borderRadius, defaultValue: null));
result.add('${prefix}boxShadow:'); properties.add(new IterableProperty<BoxShadow>('boxShadow', boxShadow, defaultValue: null, style: style));
for (BoxShadow shadow in boxShadow) properties.add(new DiagnosticsProperty<Gradient>('gradient', gradient, defaultValue: null));
result.add('$indentPrefix$shadow'); properties.add(new EnumProperty<BoxShape>('shape', shape, defaultValue: BoxShape.rectangle));
} else { },
result.add('${prefix}boxShadow: ${boxShadow.map((BoxShadow shadow) => shadow.toString()).join(", ")}'); );
}
}
if (gradient != null)
result.add('${prefix}gradient: $gradient');
if (shape != BoxShape.rectangle)
result.add('${prefix}shape: $shape');
if (prefix == '')
return '$runtimeType(${result.join(', ')})';
if (result.isEmpty)
return '$prefix<no decorations specified>';
return result.join('\n');
} }
@override @override
......
...@@ -25,7 +25,7 @@ export 'edge_insets.dart' show EdgeInsets; ...@@ -25,7 +25,7 @@ export 'edge_insets.dart' show EdgeInsets;
/// shared between boxes; [BoxPainter] objects can cache resources to /// shared between boxes; [BoxPainter] objects can cache resources to
/// make painting on a particular surface faster. /// make painting on a particular surface faster.
@immutable @immutable
abstract class Decoration { abstract class Decoration extends TreeDiagnostics {
/// Abstract const constructor. This constructor enables subclasses to provide /// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions. /// const constructors so that they can be used in const expressions.
const Decoration(); const Decoration();
...@@ -81,16 +81,10 @@ abstract class Decoration { ...@@ -81,16 +81,10 @@ abstract class Decoration {
/// if it is a [BoxDecoration] with definitely no [DecorationImage]). /// if it is a [BoxDecoration] with definitely no [DecorationImage]).
BoxPainter createBoxPainter([VoidCallback onChanged]); BoxPainter createBoxPainter([VoidCallback onChanged]);
/// Returns a string representation of this object.
///
/// Every line of the output should be prefixed by `prefix`.
///
/// If `indentPrefix` is non-null, then the description can be further split
/// into sublines, and each subline should be prefixed with `indentPrefix`
/// (rather that `prefix`). This is used, for example, by [BoxDecoration] for
/// the otherwise quite verbose [BoxShadow] descriptions.
@override @override
String toString([String prefix = '', String indentPrefix ]) => '$prefix$runtimeType'; String toString() {
return toDiagnosticsNode(style: DiagnosticsTreeStyle.singleLine).toStringDeep();
}
} }
/// A stateful class that can paint a particular [Decoration]. /// A stateful class that can paint a particular [Decoration].
......
...@@ -7,6 +7,7 @@ import 'dart:typed_data'; ...@@ -7,6 +7,7 @@ import 'dart:typed_data';
import 'dart:ui' as ui show Gradient, TextBox, lerpDouble; import 'dart:ui' as ui show Gradient, TextBox, lerpDouble;
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/foundation.dart';
import 'basic_types.dart'; import 'basic_types.dart';
import 'box_fit.dart'; import 'box_fit.dart';
...@@ -210,9 +211,19 @@ class FlutterLogoDecoration extends Decoration { ...@@ -210,9 +211,19 @@ class FlutterLogoDecoration extends Decoration {
} }
@override @override
String toString([String prefix = '', String prefixIndent ]) { DiagnosticsNode toDiagnosticsNode({ String name, DiagnosticsTreeStyle style }) {
final String extra = _inTransition ? ', transition $_position:$_opacity' : ''; return new DiagnosticsNode.lazy(
return '$prefix$runtimeType($lightColor/$darkColor on $textColor, $style$extra)'; name: name,
description: '$runtimeType',
object: this,
style: style,
fillProperties: (List<DiagnosticsNode> properties) {
properties.add(new DiagnosticsNode.message('$lightColor/$darkColor on $textColor'));
properties.add(new EnumProperty<FlutterLogoStyle>('style', this.style));
if (_inTransition)
properties.add(new DiagnosticsNode.message('transition $_position:$_opacity'));
}
);
} }
} }
......
...@@ -47,7 +47,7 @@ import 'text_style.dart'; ...@@ -47,7 +47,7 @@ import 'text_style.dart';
/// * [RichText], a widget for finer control of text rendering. /// * [RichText], a widget for finer control of text rendering.
/// * [TextPainter], a class for painting [TextSpan] objects on a [Canvas]. /// * [TextPainter], a class for painting [TextSpan] objects on a [Canvas].
@immutable @immutable
class TextSpan { class TextSpan implements TreeDiagnostics {
/// Creates a [TextSpan] with the given values. /// Creates a [TextSpan] with the given values.
/// ///
/// For the object to be useful, at least one of [text] or /// For the object to be useful, at least one of [text] or
...@@ -250,27 +250,7 @@ class TextSpan { ...@@ -250,27 +250,7 @@ class TextSpan {
@override @override
String toString([String prefix = '']) { String toString([String prefix = '']) {
final StringBuffer buffer = new StringBuffer(); return toStringDeep(prefix, prefix);
buffer.writeln('$prefix$runtimeType:');
final String indent = '$prefix ';
if (style != null)
buffer.writeln(style.toString(indent));
if (recognizer != null)
buffer.writeln('${indent}recognizer: ${recognizer.runtimeType}');
if (text != null)
buffer.writeln('$indent"$text"');
if (children != null) {
for (TextSpan child in children) {
if (child != null) {
buffer.write(child.toString(indent));
} else {
buffer.writeln('$indent<null>');
}
}
}
if (style == null && text == null && children == null)
buffer.writeln('$indent(empty)');
return buffer.toString();
} }
/// In checked mode, throws an exception if the object is not in a /// In checked mode, throws an exception if the object is not in a
...@@ -337,6 +317,11 @@ class TextSpan { ...@@ -337,6 +317,11 @@ class TextSpan {
return result; return result;
} }
@override
String toStringDeep([String prefixLineOne = '', String prefixOtherLines = '']) {
return toDiagnosticsNode().toStringDeep(prefixLineOne, prefixOtherLines);
}
@override @override
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
if (identical(this, other)) if (identical(this, other))
...@@ -352,4 +337,37 @@ class TextSpan { ...@@ -352,4 +337,37 @@ class TextSpan {
@override @override
int get hashCode => hashValues(style, text, recognizer, hashList(children)); int get hashCode => hashValues(style, text, recognizer, hashList(children));
@override
DiagnosticsNode toDiagnosticsNode({
String name,
DiagnosticsTreeStyle style: DiagnosticsTreeStyle.whitespace,
}) {
return new DiagnosticsNode.lazy(
name: name,
object: this,
description: '$runtimeType',
style: style,
fillProperties: (List<DiagnosticsNode> properties) {
// Properties on style are added as if they were properties directly on
// this TextSpan.
if (this.style != null)
this.style.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<GestureRecognizer>(
'recognizer', recognizer,
description: recognizer?.runtimeType?.toString(),
defaultValue: null,
));
properties.add(new StringProperty('text', text, showName: false, defaultValue: null));
if (this.style == null && text == null && children == null)
properties.add(new DiagnosticsNode.message('(empty)'));
},
getChildren: () {
return children == null ?
<DiagnosticsNode>[] :
children.map((TextSpan child) => child?.toDiagnosticsNode()).toList();
},
);
}
} }
...@@ -131,7 +131,7 @@ import 'basic_types.dart'; ...@@ -131,7 +131,7 @@ import 'basic_types.dart';
/// * [TextSpan], the class that wraps a [TextStyle] for the purposes of /// * [TextSpan], the class that wraps a [TextStyle] for the purposes of
/// passing it to a [RichText]. /// passing it to a [RichText].
@immutable @immutable
class TextStyle { class TextStyle extends TreeDiagnostics {
/// Creates a text style. /// Creates a text style.
const TextStyle({ const TextStyle({
this.inherit: true, this.inherit: true,
...@@ -456,112 +456,100 @@ class TextStyle { ...@@ -456,112 +456,100 @@ class TextStyle {
} }
@override @override
String toString([String prefix = '']) { DiagnosticsNode toDiagnosticsNode({
final List<String> result = <String>[]; String name,
result.add('${prefix}inherit: $inherit'); DiagnosticsTreeStyle style: DiagnosticsTreeStyle.singleLine,
if (color != null) }) {
result.add('${prefix}color: $color'); return new DiagnosticsNode.lazy(
if (fontFamily != null) name: name,
result.add('${prefix}family: "$fontFamily"'); object: this,
if (fontSize != null) style: style,
result.add('${prefix}size: $fontSize'); description: '$runtimeType',
fillProperties: debugFillProperties,
);
}
@override
String toString() => toDiagnosticsNode().toString();
/// Adds all properties prefixing property names with the optional `prefix`.
void debugFillProperties(List<DiagnosticsNode> properties, { String prefix: '' }) {
final List<DiagnosticsNode> styles = <DiagnosticsNode>[];
styles.add(new DiagnosticsProperty<Color>('${prefix}color', color, defaultValue: null));
styles.add(new StringProperty('${prefix}family', fontFamily, defaultValue: null, quoted: false));
styles.add(new DoubleProperty('${prefix}size', fontSize, defaultValue: null));
String weightDescription;
if (fontWeight != null) { if (fontWeight != null) {
switch (fontWeight) { switch (fontWeight) {
case FontWeight.w100: case FontWeight.w100:
result.add('${prefix}weight: 100'); weightDescription = '100';
break; break;
case FontWeight.w200: case FontWeight.w200:
result.add('${prefix}weight: 200'); weightDescription = '200';
break; break;
case FontWeight.w300: case FontWeight.w300:
result.add('${prefix}weight: 300'); weightDescription = '300';
break; break;
case FontWeight.w400: case FontWeight.w400:
result.add('${prefix}weight: 400'); weightDescription = '400';
break; break;
case FontWeight.w500: case FontWeight.w500:
result.add('${prefix}weight: 500'); weightDescription = '500';
break; break;
case FontWeight.w600: case FontWeight.w600:
result.add('${prefix}weight: 600'); weightDescription = '600';
break; break;
case FontWeight.w700: case FontWeight.w700:
result.add('${prefix}weight: 700'); weightDescription = '700';
break; break;
case FontWeight.w800: case FontWeight.w800:
result.add('${prefix}weight: 800'); weightDescription = '800';
break; break;
case FontWeight.w900: case FontWeight.w900:
result.add('${prefix}weight: 900'); weightDescription = '900';
break;
}
}
if (fontStyle != null) {
switch (fontStyle) {
case FontStyle.normal:
result.add('${prefix}style: normal');
break;
case FontStyle.italic:
result.add('${prefix}style: italic');
break;
}
}
if (letterSpacing != null)
result.add('${prefix}letterSpacing: ${letterSpacing}x');
if (wordSpacing != null)
result.add('${prefix}wordSpacing: ${wordSpacing}x');
if (textBaseline != null) {
switch (textBaseline) {
case TextBaseline.alphabetic:
result.add('${prefix}baseline: alphabetic');
break;
case TextBaseline.ideographic:
result.add('${prefix}baseline: ideographic');
break; break;
} }
} }
if (height != null) // TODO(jacobr): switch this to use enumProperty which will either cause the
result.add('${prefix}height: ${height}x'); // weight description to change to w600 from 600 or require existing
// enumProperty to handle this special case.
styles.add(new DiagnosticsProperty<FontWeight>(
'${prefix}weight',
fontWeight,
description: weightDescription,
defaultValue: null,
));
styles.add(new EnumProperty<FontStyle>('${prefix}style', fontStyle, defaultValue: null));
styles.add(new DoubleProperty('${prefix}letterSpacing', letterSpacing, unit: 'x', defaultValue: null));
styles.add(new DoubleProperty('${prefix}wordSpacing', wordSpacing, unit: 'x', defaultValue: null));
styles.add(new EnumProperty<TextBaseline>('${prefix}baseline', textBaseline, defaultValue: null));
styles.add(new DoubleProperty('${prefix}height', height, unit: 'x', defaultValue: null));
if (decoration != null || decorationColor != null || decorationStyle != null) { if (decoration != null || decorationColor != null || decorationStyle != null) {
String decorationDescription = '${prefix}decoration: '; final List<String> decorationDescription = <String>[];
bool haveDecorationDescription = false; if (decorationStyle != null)
if (decorationStyle != null) { decorationDescription.add(describeEnum((decorationStyle)));
switch (decorationStyle) {
case TextDecorationStyle.solid: // Hide decorationColor from the default text view as it is shown in the
decorationDescription += 'solid'; // terse decoration summary as well.
break; styles.add(new DiagnosticsProperty<Color>('${prefix}decorationColor', decorationColor, defaultValue: null, hidden: true));
case TextDecorationStyle.double:
decorationDescription += 'double'; if (decorationColor != null)
break; decorationDescription.add('$decorationColor');
case TextDecorationStyle.dotted:
decorationDescription += 'dotted'; // Intentionally collide with the property 'decoration' added below.
break; // Tools that show hidden properties could choose the first property
case TextDecorationStyle.dashed: // matching the name to disambiguate.
decorationDescription += 'dashed'; styles.add(new DiagnosticsProperty<TextDecoration>('${prefix}decoration', decoration, defaultValue: null, hidden: true));
break; if (decoration != null)
case TextDecorationStyle.wavy: decorationDescription.add('$decoration');
decorationDescription += 'wavy'; assert(decorationDescription.isNotEmpty);
break; styles.add(new MessageProperty('${prefix}decoration', decorationDescription.join(' ')));
}
haveDecorationDescription = true;
}
if (decorationColor != null) {
if (haveDecorationDescription)
decorationDescription += ' ';
decorationDescription += '$decorationColor';
haveDecorationDescription = true;
}
if (decoration != null) {
if (haveDecorationDescription)
decorationDescription += ' ';
decorationDescription += '$decoration';
haveDecorationDescription = true;
}
assert(haveDecorationDescription);
result.add(decorationDescription);
} }
if (result.isEmpty)
return '$prefix<no style specified>'; final bool styleSpecified = styles.any((DiagnosticsNode n) => !n.hidden);
return result.join('\n'); properties.add(new DiagnosticsProperty<bool>('${prefix}inherit', inherit, hidden: !styleSpecified && inherit));
properties.addAll(styles);
if (!styleSpecified)
properties.add(new FlagProperty('inherit', value: inherit, ifTrue: '$prefix<all styles inherited>', ifFalse: '$prefix<no style specified>'));
} }
} }
...@@ -156,9 +156,9 @@ class RenderListBody extends RenderBox ...@@ -156,9 +156,9 @@ class RenderListBody extends RenderBox
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('mainAxis: $mainAxis'); description.add(new EnumProperty<Axis>('mainAxis', mainAxis));
} }
double _getIntrinsicCrossAxis(_ChildSizingFunction childSize) { double _getIntrinsicCrossAxis(_ChildSizingFunction childSize) {
......
...@@ -836,9 +836,8 @@ class _IntrinsicDimensionsCacheEntry { ...@@ -836,9 +836,8 @@ class _IntrinsicDimensionsCacheEntry {
/// * Implement the [visitChildren] method such that it calls its argument for /// * Implement the [visitChildren] method such that it calls its argument for
/// each child, typically in paint order (back-most to front-most). /// each child, typically in paint order (back-most to front-most).
/// ///
/// * Implement [debugDescribeChildren] such that it outputs a string that /// * Implement [debugDescribeChildren] such that it outputs a [DiagnosticNode]
/// describes all the children. In principle, for each child you want to /// for each child.
/// include the results of that child's [toStringDeep] function.
/// ///
/// Implementing these seven bullet points is essentially all that the two /// Implementing these seven bullet points is essentially all that the two
/// aforementioned mixins do. /// aforementioned mixins do.
...@@ -1667,22 +1666,17 @@ abstract class RenderBox extends RenderObject { ...@@ -1667,22 +1666,17 @@ abstract class RenderBox extends RenderObject {
while (!node.constraints.hasBoundedWidth && node.parent is RenderBox) while (!node.constraints.hasBoundedWidth && node.parent is RenderBox)
node = node.parent; node = node.parent;
information.writeln('The nearest ancestor providing an unbounded width constraint is:'); information.writeln('The nearest ancestor providing an unbounded width constraint is:');
information.writeln(' $node'); information.write(' ');
final List<String> description = <String>[]; information.writeln(node.toStringShallow('\n '));
node.debugFillDescription(description); }
for (String line in description)
information.writeln(' $line');
}
if (!constraints.hasBoundedHeight) { if (!constraints.hasBoundedHeight) {
RenderBox node = this; RenderBox node = this;
while (!node.constraints.hasBoundedHeight && node.parent is RenderBox) while (!node.constraints.hasBoundedHeight && node.parent is RenderBox)
node = node.parent; node = node.parent;
information.writeln('The nearest ancestor providing an unbounded height constraint is:'); information.writeln('The nearest ancestor providing an unbounded height constraint is:');
information.writeln(' $node'); information.write(' ');
final List<String> description = <String>[]; information.writeln(node.toStringShallow('\n '));
node.debugFillDescription(description);
for (String line in description)
information.writeln(' $line');
} }
throw new FlutterError( throw new FlutterError(
'$runtimeType object was given an infinite size during layout.\n' '$runtimeType object was given an infinite size during layout.\n'
...@@ -2094,9 +2088,9 @@ abstract class RenderBox extends RenderObject { ...@@ -2094,9 +2088,9 @@ abstract class RenderBox extends RenderObject {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('size: ${ hasSize ? size : "MISSING" }'); description.add(new DiagnosticsProperty<Size>('size', _size, ifNull: 'MISSING'));
} }
} }
......
...@@ -156,7 +156,7 @@ bool debugProfilePaintsEnabled = false; ...@@ -156,7 +156,7 @@ bool debugProfilePaintsEnabled = false;
/// Returns a list of strings representing the given transform in a format /// Returns a list of strings representing the given transform in a format
/// useful for [RenderObject.debugFillDescription]. /// useful for [TransformProperty].
/// ///
/// If the argument is null, returns a list with the single string "null". /// If the argument is null, returns a list with the single string "null".
List<String> debugDescribeTransform(Matrix4 transform) { List<String> debugDescribeTransform(Matrix4 transform) {
...@@ -167,6 +167,20 @@ List<String> debugDescribeTransform(Matrix4 transform) { ...@@ -167,6 +167,20 @@ List<String> debugDescribeTransform(Matrix4 transform) {
return matrix; return matrix;
} }
/// Property which handles [Matrix4] that represent transforms.
class TransformProperty extends DiagnosticsProperty<Matrix4> {
TransformProperty(String name, Matrix4 value, {
Object defaultValue: kNoDefaultValue,
}) : super(
name,
value,
defaultValue: defaultValue,
);
@override
String valueToString() => debugDescribeTransform(value).join('\n');
}
void _debugDrawDoubleRect(Canvas canvas, Rect outerRect, Rect innerRect, Color color) { void _debugDrawDoubleRect(Canvas canvas, Rect outerRect, Rect innerRect, Color color) {
final Path path = new Path() final Path path = new Path()
..fillType = PathFillType.evenOdd ..fillType = PathFillType.evenOdd
......
...@@ -546,22 +546,24 @@ class RenderEditable extends RenderBox { ...@@ -546,22 +546,24 @@ class RenderEditable extends RenderBox {
Rect describeApproximatePaintClip(RenderObject child) => _hasVisualOverflow ? Offset.zero & size : null; Rect describeApproximatePaintClip(RenderObject child) => _hasVisualOverflow ? Offset.zero & size : null;
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('cursorColor: $cursorColor'); description.add(new DiagnosticsProperty<Color>('cursorColor', cursorColor));
description.add('showCursor: $showCursor'); description.add(new DiagnosticsProperty<ValueNotifier<bool>>('showCursor', showCursor));
description.add('maxLines: $maxLines'); description.add(new IntProperty('maxLines', maxLines));
description.add('selectionColor: $selectionColor'); description.add(new DiagnosticsProperty<Color>('selectionColor', selectionColor));
description.add('textScaleFactor: $textScaleFactor'); description.add(new DoubleProperty('textScaleFactor', textScaleFactor));
description.add('selection: $selection'); description.add(new DiagnosticsProperty<TextSelection>('selection', selection));
description.add('offset: $offset'); description.add(new DiagnosticsProperty<ViewportOffset>('offset', offset));
} }
@override @override
String debugDescribeChildren(String prefix) { List<DiagnosticsNode> debugDescribeChildren() {
return '$prefix \u2558\u2550\u2566\u2550\u2550 text \u2550\u2550\u2550\n' return <DiagnosticsNode>[
'${text.toString("$prefix \u2551 ")}' // TextSpan includes a newline text.toDiagnosticsNode(
'$prefix \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n' name: 'text',
'${prefix.trimRight()}\n'; style: DiagnosticsTreeStyle.transition,
),
];
} }
} }
...@@ -490,9 +490,9 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl ...@@ -490,9 +490,9 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
if (node != null) { if (node != null) {
information.writeln('The nearest ancestor providing an unbounded width constraint is:'); information.writeln('The nearest ancestor providing an unbounded width constraint is:');
information.writeln(' $node'); information.writeln(' $node');
final List<String> description = <String>[]; final List<DiagnosticsNode> description = <DiagnosticsNode>[];
node.debugFillDescription(description); node.debugFillProperties(description);
for (String line in description) for (DiagnosticsNode line in description)
information.writeln(' $line'); information.writeln(' $line');
} }
information.writeln('See also: https://flutter.io/layout/'); information.writeln('See also: https://flutter.io/layout/');
...@@ -784,13 +784,13 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl ...@@ -784,13 +784,13 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('direction: $_direction'); description.add(new EnumProperty<Axis>('direction', _direction));
description.add('mainAxisAlignment: $_mainAxisAlignment'); description.add(new EnumProperty<MainAxisAlignment>('mainAxisAlignment', _mainAxisAlignment));
description.add('mainAxisSize: $_mainAxisSize'); description.add(new EnumProperty<MainAxisSize>('mainAxisSize', _mainAxisSize));
description.add('crossAxisAlignment: $_crossAxisAlignment'); description.add(new EnumProperty<CrossAxisAlignment>('crossAxisAlignment', _crossAxisAlignment));
description.add('textBaseline: $_textBaseline'); description.add(new EnumProperty<TextBaseline>('textBaseline', _textBaseline));
} }
} }
...@@ -259,26 +259,17 @@ class RenderImage extends RenderBox { ...@@ -259,26 +259,17 @@ class RenderImage extends RenderBox {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('image: $image'); description.add(new DiagnosticsProperty<ui.Image>('image', image));
if (width != null) description.add(new DoubleProperty('width', width, defaultValue: null));
description.add('width: $width'); description.add(new DoubleProperty('height', height, defaultValue: null));
if (height != null) description.add(new DoubleProperty('scale', scale, defaultValue: 1.0));
description.add('height: $height'); description.add(new DiagnosticsProperty<Color>('color', color, defaultValue: null));
if (scale != 1.0) description.add(new EnumProperty<BlendMode>('colorBlendMode', colorBlendMode, defaultValue: null));
description.add('scale: $scale'); description.add(new EnumProperty<BoxFit>('fit', fit, defaultValue: null));
if (color != null) description.add(new DiagnosticsProperty<FractionalOffset>('alignment', alignment, defaultValue: null));
description.add('color: $color'); description.add(new EnumProperty<ImageRepeat>('repeat', repeat, defaultValue: ImageRepeat.noRepeat));
if (colorBlendMode != null) description.add(new DiagnosticsProperty<Rect>('centerSlice', centerSlice, defaultValue: null));
description.add('colorBlendMode: $colorBlendMode');
if (fit != null)
description.add('fit: $fit');
if (alignment != null)
description.add('alignment: $alignment');
if (repeat != ImageRepeat.noRepeat)
description.add('repeat: $repeat');
if (centerSlice != null)
description.add('centerSlice: $centerSlice');
} }
} }
...@@ -105,12 +105,10 @@ abstract class Layer extends AbstractNode with TreeDiagnosticsMixin { ...@@ -105,12 +105,10 @@ abstract class Layer extends AbstractNode with TreeDiagnosticsMixin {
String toString() => '${super.toString()}${ owner == null ? " DETACHED" : ""}'; String toString() => '${super.toString()}${ owner == null ? " DETACHED" : ""}';
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
if (parent == null && owner != null) description.add(new DiagnosticsProperty<Object>('owner', owner, hidden: parent != null, defaultValue: null));
description.add('owner: $owner'); description.add(new DiagnosticsProperty<dynamic>('creator', debugCreator, defaultValue: null));
if (debugCreator != null)
description.add('creator: $debugCreator');
} }
} }
...@@ -164,9 +162,9 @@ class PictureLayer extends Layer { ...@@ -164,9 +162,9 @@ class PictureLayer extends Layer {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('paint bounds: $canvasBounds'); description.add(new DiagnosticsProperty<Rect>('paint bounds', canvasBounds));
} }
} }
...@@ -414,24 +412,20 @@ class ContainerLayer extends Layer { ...@@ -414,24 +412,20 @@ class ContainerLayer extends Layer {
} }
@override @override
String debugDescribeChildren(String prefix) { List<DiagnosticsNode> debugDescribeChildren() {
final List<DiagnosticsNode> children = <DiagnosticsNode>[];
if (firstChild == null) if (firstChild == null)
return ''; return children;
final StringBuffer result = new StringBuffer()
..write(prefix)
..write(' \u2502\n');
Layer child = firstChild; Layer child = firstChild;
int count = 1; int count = 1;
while (child != lastChild) { while (true) {
result.write(child.toStringDeep("$prefix \u251C\u2500child $count: ", "$prefix \u2502")); children.add(child.toDiagnosticsNode(name: 'child $count'));
if (child == lastChild)
break;
count += 1; count += 1;
child = child.nextSibling; child = child.nextSibling;
} }
if (child != null) { return children;
assert(child == lastChild);
result.write(child.toStringDeep("$prefix \u2514\u2500child $count: ", "$prefix "));
}
return result.toString();
} }
} }
...@@ -466,9 +460,9 @@ class OffsetLayer extends ContainerLayer { ...@@ -466,9 +460,9 @@ class OffsetLayer extends ContainerLayer {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('offset: $offset'); description.add(new DiagnosticsProperty<Offset>('offset', offset));
} }
} }
...@@ -494,9 +488,9 @@ class ClipRectLayer extends ContainerLayer { ...@@ -494,9 +488,9 @@ class ClipRectLayer extends ContainerLayer {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('clipRect: $clipRect'); description.add(new DiagnosticsProperty<Rect>('clipRect', clipRect));
} }
} }
...@@ -522,9 +516,9 @@ class ClipRRectLayer extends ContainerLayer { ...@@ -522,9 +516,9 @@ class ClipRRectLayer extends ContainerLayer {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('clipRRect: $clipRRect'); description.add(new DiagnosticsProperty<RRect>('clipRRect', clipRRect));
} }
} }
...@@ -550,9 +544,9 @@ class ClipPathLayer extends ContainerLayer { ...@@ -550,9 +544,9 @@ class ClipPathLayer extends ContainerLayer {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('clipPath: $clipPath'); description.add(new DiagnosticsProperty<Path>('clipPath', clipPath));
} }
} }
...@@ -602,10 +596,9 @@ class TransformLayer extends OffsetLayer { ...@@ -602,10 +596,9 @@ class TransformLayer extends OffsetLayer {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('transform:'); description.add(new TransformProperty('transform', transform));
description.addAll(debugDescribeTransform(transform));
} }
} }
...@@ -634,9 +627,9 @@ class OpacityLayer extends ContainerLayer { ...@@ -634,9 +627,9 @@ class OpacityLayer extends ContainerLayer {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('alpha: $alpha'); description.add(new IntProperty('alpha', alpha));
} }
} }
...@@ -674,11 +667,11 @@ class ShaderMaskLayer extends ContainerLayer { ...@@ -674,11 +667,11 @@ class ShaderMaskLayer extends ContainerLayer {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('shader: $shader'); description.add(new DiagnosticsProperty<Shader>('shader', shader));
description.add('maskRect: $maskRect'); description.add(new DiagnosticsProperty<Rect>('maskRect', maskRect));
description.add('blendMode: $blendMode'); description.add(new DiagnosticsProperty<BlendMode>('blendMode', blendMode));
} }
} }
...@@ -752,11 +745,11 @@ class PhysicalModelLayer extends ContainerLayer { ...@@ -752,11 +745,11 @@ class PhysicalModelLayer extends ContainerLayer {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('clipRRect: $clipRRect'); description.add(new DiagnosticsProperty<RRect>('clipRRect', clipRRect));
description.add('elevation: $elevation'); description.add(new DoubleProperty('elevation', elevation));
description.add('color: $color'); description.add(new DiagnosticsProperty<Color>('color', color));
} }
} }
...@@ -778,7 +771,7 @@ class LayerLink { ...@@ -778,7 +771,7 @@ class LayerLink {
LeaderLayer _leader; LeaderLayer _leader;
@override @override
String toString() => '$runtimeType#$hashCode(${ _leader != null ? "<linked>" : "<dangling>" })'; String toString() => '${describeIdentity(this)}(${ _leader != null ? "<linked>" : "<dangling>" })';
} }
/// A composited layer that can be followed by a [FollowerLayer]. /// A composited layer that can be followed by a [FollowerLayer].
...@@ -861,10 +854,10 @@ class LeaderLayer extends ContainerLayer { ...@@ -861,10 +854,10 @@ class LeaderLayer extends ContainerLayer {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('offset: $offset'); description.add(new DiagnosticsProperty<Offset>('offset', offset));
description.add('link: $link'); description.add(new DiagnosticsProperty<LayerLink>('link', link));
} }
} }
...@@ -1050,12 +1043,9 @@ class FollowerLayer extends ContainerLayer { ...@@ -1050,12 +1043,9 @@ class FollowerLayer extends ContainerLayer {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('link: $link'); description.add(new DiagnosticsProperty<LayerLink>('link', link));
if (_lastTransform != null) { description.add(new TransformProperty('transform', getLastTransform(), defaultValue: null));
description.add('transform:');
description.addAll(debugDescribeTransform(getLastTransform()));
}
} }
} }
...@@ -17,7 +17,7 @@ import 'layer.dart'; ...@@ -17,7 +17,7 @@ import 'layer.dart';
import 'node.dart'; import 'node.dart';
import 'semantics.dart'; import 'semantics.dart';
export 'package:flutter/foundation.dart' show FlutterError, InformationCollector; export 'package:flutter/foundation.dart' show FlutterError, InformationCollector, DiagnosticsNode, DiagnosticsProperty, StringProperty, DoubleProperty, EnumProperty, IntProperty;
export 'package:flutter/gestures.dart' show HitTestEntry, HitTestResult; export 'package:flutter/gestures.dart' show HitTestEntry, HitTestResult;
export 'package:flutter/painting.dart'; export 'package:flutter/painting.dart';
...@@ -1318,7 +1318,7 @@ class PipelineOwner { ...@@ -1318,7 +1318,7 @@ class PipelineOwner {
/// [RenderObject.markNeedsLayout] so that if a parent has queried the intrinsic /// [RenderObject.markNeedsLayout] so that if a parent has queried the intrinsic
/// or baseline information, it gets marked dirty whenever the child's geometry /// or baseline information, it gets marked dirty whenever the child's geometry
/// changes. /// changes.
abstract class RenderObject extends AbstractNode implements HitTestTarget { abstract class RenderObject extends AbstractNode with TreeDiagnosticsMixin implements HitTestTarget {
/// Initializes internal fields for subclasses. /// Initializes internal fields for subclasses.
RenderObject() { RenderObject() {
_needsCompositing = isRepaintBoundary || alwaysNeedsCompositing; _needsCompositing = isRepaintBoundary || alwaysNeedsCompositing;
...@@ -2748,25 +2748,13 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -2748,25 +2748,13 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
/// Returns a description of the tree rooted at this node. /// Returns a description of the tree rooted at this node.
/// If the prefix argument is provided, then every line in the output /// If the prefix argument is provided, then every line in the output
/// will be prefixed by that string. /// will be prefixed by that string.
@override
String toStringDeep([String prefixLineOne = '', String prefixOtherLines = '']) { String toStringDeep([String prefixLineOne = '', String prefixOtherLines = '']) {
final RenderObject debugPreviousActiveLayout = _debugActiveLayout; final RenderObject debugPreviousActiveLayout = _debugActiveLayout;
_debugActiveLayout = null; _debugActiveLayout = null;
String result = '$prefixLineOne$this\n';
final String childrenDescription = debugDescribeChildren(prefixOtherLines); final String result = super.toStringDeep(prefixLineOne, prefixOtherLines);
final String descriptionPrefix = childrenDescription != '' ? '$prefixOtherLines \u2502 ' : '$prefixOtherLines ';
final List<String> description = <String>[];
debugFillDescription(description);
result += description
.expand((String description) => debugWordWrap(description, 65, wrapIndent: ' '))
.map<String>((String line) => "$descriptionPrefix$line\n")
.join();
if (childrenDescription == '') {
final String prefix = prefixOtherLines.trimRight();
if (prefix != '')
result += '$prefix\n';
} else {
result += childrenDescription;
}
_debugActiveLayout = debugPreviousActiveLayout; _debugActiveLayout = debugPreviousActiveLayout;
return result; return result;
} }
...@@ -2776,42 +2764,35 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -2776,42 +2764,35 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
/// ///
/// This includes the same information for this RenderObject as given by /// This includes the same information for this RenderObject as given by
/// [toStringDeep], but does not recurse to any children. /// [toStringDeep], but does not recurse to any children.
@override
String toStringShallow([String joiner = '; ']) { String toStringShallow([String joiner = '; ']) {
final RenderObject debugPreviousActiveLayout = _debugActiveLayout; final RenderObject debugPreviousActiveLayout = _debugActiveLayout;
_debugActiveLayout = null; _debugActiveLayout = null;
final StringBuffer result = new StringBuffer(); final String result = super.toStringShallow(joiner);
result.write('${this}$joiner'); // TODO(ianh): https://github.com/dart-lang/sdk/issues/28206
final List<String> description = <String>[];
debugFillDescription(description);
result.write(description.join(joiner));
_debugActiveLayout = debugPreviousActiveLayout; _debugActiveLayout = debugPreviousActiveLayout;
return result.toString(); return result;
} }
/// Accumulates a list of strings describing the current node's fields, one
/// field per string. Subclasses should override this to have their
/// information included in [toStringDeep].
@protected @protected
void debugFillDescription(List<String> description) { @override
if (debugCreator != null) void debugFillProperties(List<DiagnosticsNode> description) {
description.add('creator: $debugCreator'); description.add(new DiagnosticsProperty<dynamic>('creator', debugCreator, defaultValue: null));
description.add('parentData: $parentData${ _debugCanParentUseSize == true ? " (can use size)" : ""}'); description.add(new DiagnosticsProperty<ParentData>('parentData', parentData, tooltip: _debugCanParentUseSize == true ? "can use size" : null));
description.add('constraints: $constraints'); description.add(new DiagnosticsProperty<Constraints>('constraints', constraints));
if (_layer != null) // don't access it via the "layer" getter since that's only valid when we don't need paint // don't access it via the "layer" getter since that's only valid when we don't need paint
description.add('layer: $_layer'); description.add(new DiagnosticsProperty<OffsetLayer>('layer', _layer, defaultValue: null));
if (_semantics != null) description.add(new DiagnosticsProperty<SemanticsNode>('_semantics', _semantics, defaultValue: null));
description.add('semantics: $_semantics'); description.add(new FlagProperty(
if (isBlockingSemanticsOfPreviouslyPaintedNodes) 'isBlockingSemanticsOfPreviouslyPaintedNodes',
description.add('blocks semantics of earlier render objects below the common boundary'); value: isBlockingSemanticsOfPreviouslyPaintedNodes,
if (isSemanticBoundary) ifTrue: 'blocks semantics of earlier render objects below the common boundary',
description.add('semantic boundary'); ));
description.add(new FlagProperty('isSemanticBoundary', value: isSemanticBoundary, ifTrue: 'semantic boundary'));
} }
/// Returns a string describing the current node's descendants. Each line of
/// the subtree in the output should be indented by the prefix argument.
@protected @protected
String debugDescribeChildren(String prefix) => ''; @override
List<DiagnosticsNode> debugDescribeChildren() => <DiagnosticsNode>[];
/// Attempt to make this or a descendant RenderObject visible on screen. /// Attempt to make this or a descendant RenderObject visible on screen.
/// ///
...@@ -2901,10 +2882,8 @@ abstract class RenderObjectWithChildMixin<ChildType extends RenderObject> extend ...@@ -2901,10 +2882,8 @@ abstract class RenderObjectWithChildMixin<ChildType extends RenderObject> extend
} }
@override @override
String debugDescribeChildren(String prefix) { List<DiagnosticsNode> debugDescribeChildren() {
if (child != null) return child != null ? <DiagnosticsNode>[child.toDiagnosticsNode(name: 'child')] : <DiagnosticsNode>[];
return '$prefix \u2502\n${child.toStringDeep('$prefix \u2514\u2500child: ', '$prefix ')}';
return '';
} }
} }
...@@ -3204,26 +3183,21 @@ abstract class ContainerRenderObjectMixin<ChildType extends RenderObject, Parent ...@@ -3204,26 +3183,21 @@ abstract class ContainerRenderObjectMixin<ChildType extends RenderObject, Parent
} }
@override @override
String debugDescribeChildren(String prefix) { List<DiagnosticsNode> debugDescribeChildren() {
final List<DiagnosticsNode> children = <DiagnosticsNode>[];
if (firstChild != null) { if (firstChild != null) {
final StringBuffer result = new StringBuffer()
..write(prefix)
..write(' \u2502\n');
ChildType child = firstChild; ChildType child = firstChild;
int count = 1; int count = 1;
while (child != lastChild) { while (true) {
result.write(child.toStringDeep("$prefix \u251C\u2500child $count: ", "$prefix \u2502")); children.add(child.toDiagnosticsNode(name: 'child $count'));
if (child == lastChild)
break;
count += 1; count += 1;
final ParentDataType childParentData = child.parentData; final ParentDataType childParentData = child.parentData;
child = childParentData.nextSibling; child = childParentData.nextSibling;
} }
if (child != null) {
assert(child == lastChild);
result.write(child.toStringDeep("$prefix \u2514\u2500child $count: ", "$prefix "));
}
return result.toString();
} }
return ''; return children;
} }
} }
......
...@@ -8,6 +8,7 @@ import 'package:flutter/foundation.dart'; ...@@ -8,6 +8,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'box.dart'; import 'box.dart';
import 'debug.dart'; import 'debug.dart';
import 'object.dart'; import 'object.dart';
...@@ -369,10 +370,7 @@ class RenderParagraph extends RenderBox { ...@@ -369,10 +370,7 @@ class RenderParagraph extends RenderBox {
} }
@override @override
String debugDescribeChildren(String prefix) { List<DiagnosticsNode> debugDescribeChildren() {
return '$prefix \u2558\u2550\u2566\u2550\u2550 text \u2550\u2550\u2550\n' return <DiagnosticsNode>[text.toDiagnosticsNode(name: 'text', style: DiagnosticsTreeStyle.transition)];
'${text.toString("$prefix \u2551 ")}' // TextSpan includes a newline
'$prefix \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n'
'${prefix.trimRight()}\n';
} }
} }
...@@ -177,9 +177,9 @@ class RenderPadding extends RenderShiftedBox { ...@@ -177,9 +177,9 @@ class RenderPadding extends RenderShiftedBox {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('padding: $padding'); description.add(new DiagnosticsProperty<EdgeInsets>('padding', padding));
} }
} }
...@@ -236,9 +236,9 @@ abstract class RenderAligningShiftedBox extends RenderShiftedBox { ...@@ -236,9 +236,9 @@ abstract class RenderAligningShiftedBox extends RenderShiftedBox {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('alignment: $alignment'); description.add(new DiagnosticsProperty<FractionalOffset>('alignment', alignment));
} }
} }
...@@ -366,10 +366,10 @@ class RenderPositionedBox extends RenderAligningShiftedBox { ...@@ -366,10 +366,10 @@ class RenderPositionedBox extends RenderAligningShiftedBox {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('widthFactor: ${_widthFactor ?? "expand"}'); description.add(new DoubleProperty('widthFactor', _widthFactor, ifNull: 'expand'));
description.add('heightFactor: ${_heightFactor ?? "expand"}'); description.add(new DoubleProperty('heightFactor', _heightFactor, ifNull: 'expand'));
} }
} }
...@@ -479,12 +479,12 @@ class RenderConstrainedOverflowBox extends RenderAligningShiftedBox { ...@@ -479,12 +479,12 @@ class RenderConstrainedOverflowBox extends RenderAligningShiftedBox {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('minWidth: ${minWidth ?? "use parent minWidth constraint"}'); description.add(new DoubleProperty('minWidth', minWidth, ifNull: 'use parent minWidth constraint'));
description.add('maxWidth: ${maxWidth ?? "use parent maxWidth constraint"}'); description.add(new DoubleProperty('maxWidth', maxWidth, ifNull: 'use parent maxWidth constraint'));
description.add('minHeight: ${minHeight ?? "use parent minHeight constraint"}'); description.add(new DoubleProperty('minHeight', minHeight, ifNull: 'use parent minHeight constraint'));
description.add('maxHeight: ${maxHeight ?? "use parent maxHeight constraint"}'); description.add(new DoubleProperty('maxHeight', maxHeight, ifNull: 'use parent maxHeight constraint'));
} }
} }
...@@ -689,10 +689,10 @@ class RenderFractionallySizedOverflowBox extends RenderAligningShiftedBox { ...@@ -689,10 +689,10 @@ class RenderFractionallySizedOverflowBox extends RenderAligningShiftedBox {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('widthFactor: ${_widthFactor ?? "pass-through"}'); description.add(new DoubleProperty('widthFactor', _widthFactor, ifNull: 'pass-through'));
description.add('heightFactor: ${_heightFactor ?? "pass-through"}'); description.add(new DoubleProperty('heightFactor', _heightFactor, ifNull: 'pass-through'));
} }
} }
...@@ -945,9 +945,9 @@ class RenderBaseline extends RenderShiftedBox { ...@@ -945,9 +945,9 @@ class RenderBaseline extends RenderShiftedBox {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('baseline: $baseline'); description.add(new DoubleProperty('baseline', baseline));
description.add('baselineType: $baselineType'); description.add(new EnumProperty<TextBaseline>('baselineType', baselineType));
} }
} }
...@@ -467,7 +467,7 @@ class SliverConstraints extends Constraints { ...@@ -467,7 +467,7 @@ class SliverConstraints extends Constraints {
/// A sliver can occupy space in several different ways, which is why this class /// A sliver can occupy space in several different ways, which is why this class
/// contains multiple values. /// contains multiple values.
@immutable @immutable
class SliverGeometry { class SliverGeometry implements TreeDiagnostics {
/// Creates an object that describes the amount of space occupied by a sliver. /// Creates an object that describes the amount of space occupied by a sliver.
/// ///
/// If the [layoutExtent] argument is null, [layoutExtent] defaults to the /// If the [layoutExtent] argument is null, [layoutExtent] defaults to the
...@@ -621,37 +621,45 @@ class SliverGeometry { ...@@ -621,37 +621,45 @@ class SliverGeometry {
@override @override
String toString() { String toString() {
final StringBuffer buffer = new StringBuffer(); return toDiagnosticsNode(style: DiagnosticsTreeStyle.singleLine).toStringDeep();
buffer.write('SliverGeometry('); }
buffer.write('scrollExtent: ${scrollExtent.toStringAsFixed(1)}, ');
if (paintExtent > 0.0) { @override
if (visible) { String toStringDeep([String prefix = '', String indentPrefix ]) {
buffer.write('paintExtent: ${paintExtent.toStringAsFixed(1)}, '); return toDiagnosticsNode().toStringDeep(prefix, indentPrefix);
} else { }
buffer.write('paintExtent: ${paintExtent.toStringAsFixed(1)} but not painting, ');
} @override
} else if (paintExtent == 0.0) { DiagnosticsNode toDiagnosticsNode({
if (visible) { String name,
buffer.write('paintExtent: ${paintExtent.toStringAsFixed(1)} but visible, '); DiagnosticsTreeStyle style: DiagnosticsTreeStyle.whitespace,
}) {
return new DiagnosticsNode.lazy(
name: name,
object: this,
description: 'SliverGeometry',
style: style,
emptyBodyDescription: '<no decorations specified>',
fillProperties: (List<DiagnosticsNode> properties) {
properties.add(new DoubleProperty('scrollExtent', scrollExtent));
if (paintExtent > 0.0) {
properties.add(new DoubleProperty('paintExtent', paintExtent, unit : visible ? null : ' but not painting'));
} else if (paintExtent == 0.0) {
if (visible) {
properties.add(new DoubleProperty('paintExtent', paintExtent, unit: visible ? null : ' but visible'));
}
properties.add(new FlagProperty('visible', value: visible, ifFalse: 'hidden'));
} else { } else {
buffer.write('hidden, '); // Negative paintExtent!
properties.add(new DoubleProperty('paintExtent', paintExtent, tooltip: '!'));
} }
} else { properties.add(new DoubleProperty('paintOrigin', paintOrigin, defaultValue: 0.0));
buffer.write('paintExtent: ${paintExtent.toStringAsFixed(1)} (!), '); properties.add(new DoubleProperty('layoutExtent', layoutExtent, defaultValue: paintExtent));
} properties.add(new DoubleProperty('maxPaintExtent', maxPaintExtent));
if (paintOrigin != 0.0) properties.add(new DoubleProperty('hitTestExtent', hitTestExtent, defaultValue: paintExtent));
buffer.write('paintOrigin: ${paintOrigin.toStringAsFixed(1)}, '); properties.add(new DiagnosticsProperty<bool>('hasVisualOverflow', hasVisualOverflow, defaultValue: false));
if (layoutExtent != paintExtent) properties.add(new DoubleProperty('scrollOffsetCorrection', scrollOffsetCorrection, defaultValue: null));
buffer.write('layoutExtent: ${layoutExtent.toStringAsFixed(1)}, '); });
buffer.write('maxPaintExtent: ${maxPaintExtent.toStringAsFixed(1)}, ');
if (hitTestExtent != paintExtent)
buffer.write('hitTestExtent: ${hitTestExtent.toStringAsFixed(1)}, ');
if (hasVisualOverflow)
buffer.write('hasVisualOverflow: true, ');
if (scrollOffsetCorrection != null)
buffer.write('scrollOffsetCorrection: ${scrollOffsetCorrection.toStringAsFixed(1)}');
buffer.write(')');
return buffer.toString();
} }
} }
...@@ -1321,9 +1329,9 @@ abstract class RenderSliver extends RenderObject { ...@@ -1321,9 +1329,9 @@ abstract class RenderSliver extends RenderObject {
void handleEvent(PointerEvent event, SliverHitTestEntry entry) { } void handleEvent(PointerEvent event, SliverHitTestEntry entry) { }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('geometry: $geometry'); description.add(new DiagnosticsProperty<SliverGeometry>('geometry', geometry));
} }
} }
......
...@@ -517,13 +517,9 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver ...@@ -517,13 +517,9 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
if (firstChild != null) { description.add(new DiagnosticsNode.message(firstChild != null ? 'currently live children: ${indexOf(firstChild)} to ${indexOf(lastChild)}' : 'no children current live'));
description.add('currently live children: ${indexOf(firstChild)} to ${indexOf(lastChild)}');
} else {
description.add('no children current live');
}
} }
/// Asserts that the reified child list is not empty and has a contiguous /// Asserts that the reified child list is not empty and has a contiguous
...@@ -546,40 +542,27 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver ...@@ -546,40 +542,27 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver
} }
@override @override
String debugDescribeChildren(String prefix) { List<DiagnosticsNode> debugDescribeChildren() {
StringBuffer result; final List<DiagnosticsNode> children = <DiagnosticsNode>[];
if (firstChild != null) { if (firstChild != null) {
result = new StringBuffer()
..write(prefix)
..write(' \u2502\n');
RenderBox child = firstChild; RenderBox child = firstChild;
while (child != lastChild) { while (true) {
final SliverMultiBoxAdaptorParentData childParentData = child.parentData; final SliverMultiBoxAdaptorParentData childParentData = child.parentData;
result.write(child.toStringDeep("$prefix \u251C\u2500child with index ${childParentData.index}: ", "$prefix \u2502")); children.add(child.toDiagnosticsNode(name: "child with index ${childParentData.index}"));
if (child == lastChild)
break;
child = childParentData.nextSibling; child = childParentData.nextSibling;
} }
if (child != null) {
assert(child == lastChild);
final SliverMultiBoxAdaptorParentData childParentData = child.parentData;
if (_keepAliveBucket.isEmpty) {
result.write(child.toStringDeep("$prefix \u2514\u2500child with index ${childParentData.index}: ", "$prefix "));
} else {
result.write(child.toStringDeep("$prefix \u251C\u2500child with index ${childParentData.index}: ", "$prefix \u254E"));
}
}
} }
if (_keepAliveBucket.isNotEmpty) { if (_keepAliveBucket.isNotEmpty) {
result ??= new StringBuffer()
..write(prefix)
..write(' \u254E\n');
final List<int> indices = _keepAliveBucket.keys.toList()..sort(); final List<int> indices = _keepAliveBucket.keys.toList()..sort();
final int lastIndex = indices.removeLast(); for (int index in indices) {
if (indices.isNotEmpty) { children.add(_keepAliveBucket[index].toDiagnosticsNode(
for (int index in indices) name: "child with index $index (kept alive offstage)",
result.write(_keepAliveBucket[index].toStringDeep("$prefix \u251C\u2500child with index $index (kept alive offstage): ", "$prefix \u254E")); style: DiagnosticsTreeStyle.offstage,
));
} }
result.write(_keepAliveBucket[lastIndex].toStringDeep("$prefix \u2514\u2500child with index $lastIndex (kept alive offstage): ", "$prefix "));
} }
return result?.toString() ?? ''; return children;
} }
} }
...@@ -204,18 +204,10 @@ abstract class RenderSliverPersistentHeader extends RenderSliver with RenderObje ...@@ -204,18 +204,10 @@ abstract class RenderSliverPersistentHeader extends RenderSliver with RenderObje
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
try { description.add(new DoubleProperty.lazy('maxExtent', () => maxExtent));
description.add('maxExtent: ${maxExtent.toStringAsFixed(1)}'); description.add(new DoubleProperty.lazy('child position', () => childMainAxisPosition(child)));
} catch (e) {
description.add('maxExtent: EXCEPTION (${e.runtimeType})');
}
try {
description.add('child position: ${childMainAxisPosition(child).toStringAsFixed(1)}');
} catch (e) {
description.add('child position: EXCEPTION (${e.runtimeType})');
}
} }
} }
...@@ -465,9 +457,9 @@ abstract class RenderSliverFloatingPersistentHeader extends RenderSliverPersiste ...@@ -465,9 +457,9 @@ abstract class RenderSliverFloatingPersistentHeader extends RenderSliverPersiste
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('effective scroll offset: ${_effectiveScrollOffset?.toStringAsFixed(1)}'); description.add(new DoubleProperty('effective scroll offset', _effectiveScrollOffset));
} }
} }
......
...@@ -524,11 +524,11 @@ class RenderStack extends RenderBox ...@@ -524,11 +524,11 @@ class RenderStack extends RenderBox
Rect describeApproximatePaintClip(RenderObject child) => _hasVisualOverflow ? Offset.zero & size : null; Rect describeApproximatePaintClip(RenderObject child) => _hasVisualOverflow ? Offset.zero & size : null;
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('alignment: $alignment'); description.add(new DiagnosticsProperty<FractionalOffset>('alignment', alignment));
description.add('fit: $fit'); description.add(new EnumProperty<StackFit>('fit', fit));
description.add('overflow: $overflow'); description.add(new EnumProperty<Overflow>('overflow', overflow));
} }
} }
...@@ -600,8 +600,8 @@ class RenderIndexedStack extends RenderStack { ...@@ -600,8 +600,8 @@ class RenderIndexedStack extends RenderStack {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('index: $index'); description.add(new IntProperty('index', index));
} }
} }
...@@ -1278,46 +1278,34 @@ class RenderTable extends RenderBox { ...@@ -1278,46 +1278,34 @@ class RenderTable extends RenderBox {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
if (border != null) description.add(new DiagnosticsProperty<TableBorder>('border', border, defaultValue: null));
description.add('border: $border'); description.add(new DiagnosticsProperty<Map<int, TableColumnWidth>>('specified column widths', _columnWidths, hidden: _columnWidths.isEmpty));
if (_columnWidths.isNotEmpty) description.add(new DiagnosticsProperty<TableColumnWidth>('default column width', defaultColumnWidth));
description.add('specified column widths: $_columnWidths'); description.add(new MessageProperty('table size', '$columns\u00D7$rows'));
description.add('default column width: $defaultColumnWidth'); description.add(new IterableProperty<double>('column offsets', _columnLefts, ifNull: 'unknown'));
description.add('table size: $columns\u00D7$rows'); description.add(new IterableProperty<double>('row offsets', _rowTops, ifNull: "unknown"));
description.add('column offsets: ${ _columnLefts ?? "unknown" }');
description.add('row offsets: ${ _rowTops ?? "unknown" }');
} }
@override @override
String debugDescribeChildren(String prefix) { List<DiagnosticsNode> debugDescribeChildren() {
final StringBuffer result = new StringBuffer(); if (_children.isEmpty) {
result.writeln('$prefix \u2502'); return <DiagnosticsNode>[new DiagnosticsNode.message('table is empty')];
final int lastIndex = _children.length - 1; }
if (lastIndex < 0) {
result.writeln('$prefix \u2514\u2500table is empty'); final List<DiagnosticsNode> children = <DiagnosticsNode>[];
} else { for (int y = 0; y < rows; y += 1) {
for (int y = 0; y < rows; y += 1) { for (int x = 0; x < columns; x += 1) {
for (int x = 0; x < columns; x += 1) { final int xy = x + y * columns;
final int xy = x + y * columns; final RenderBox child = _children[xy];
final RenderBox child = _children[xy]; final String name = 'child ($x, $y)';
if (child != null) { if (child != null)
if (xy < lastIndex) { children.add(child.toDiagnosticsNode(name: name));
result.write('${child.toStringDeep("$prefix \u251C\u2500child ($x, $y): ", "$prefix \u2502")}'); else
} else { children.add(new DiagnosticsProperty<Object>(name, null, ifNull: 'is null', showSeparator: false));
result.write('${child.toStringDeep("$prefix \u2514\u2500child ($x, $y): ", "$prefix ")}');
}
} else {
if (xy < lastIndex) {
result.writeln('$prefix \u251C\u2500child ($x, $y) is null');
} else {
result.writeln('$prefix \u2514\u2500child ($x, $y) is null');
}
}
}
} }
} }
return result.toString(); return children;
} }
} }
...@@ -211,16 +211,18 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox> ...@@ -211,16 +211,18 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
// call to ${super.debugFillDescription(prefix)} is omitted because the root superclasses don't include any interesting information for this class // call to ${super.debugFillProperties(description)} is omitted because the
// root superclasses don't include any interesting information for this
// class
assert(() { assert(() {
description.add('debug mode enabled - ${Platform.operatingSystem}'); description.add(new DiagnosticsNode.message('debug mode enabled - ${Platform.operatingSystem}'));
return true; return true;
}); });
description.add('window size: ${ui.window.physicalSize} (in physical pixels)'); description.add(new DiagnosticsProperty<Size>('window size', ui.window.physicalSize, tooltip: 'in physical pixels'));
description.add('device pixel ratio: ${ui.window.devicePixelRatio} (physical pixels per logical pixel)'); description.add(new DoubleProperty('device pixel ratio', ui.window.devicePixelRatio, tooltip: 'physical pixels per logical pixel'));
description.add('configuration: $configuration (in logical pixels)'); description.add(new DiagnosticsProperty<ViewConfiguration>('configuration', configuration, tooltip: 'in logical pixels'));
if (ui.window.semanticsEnabled) if (ui.window.semanticsEnabled)
description.add('semantics enabled'); description.add(new DiagnosticsNode.message('semantics enabled'));
} }
} }
...@@ -468,29 +468,28 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix ...@@ -468,29 +468,28 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
// TODO(ianh): semantics - shouldn't walk the invisible children // TODO(ianh): semantics - shouldn't walk the invisible children
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('$axisDirection'); description.add(new EnumProperty<AxisDirection>('axisDirection', axisDirection));
description.add('offset: $offset'); description.add(new DiagnosticsProperty<ViewportOffset>('offset', offset));
} }
@override @override
String debugDescribeChildren(String prefix) { List<DiagnosticsNode> debugDescribeChildren() {
if (firstChild == null) final List<DiagnosticsNode> children = <DiagnosticsNode>[];
return '$prefix\n';
int count = indexOfFirstChild;
final StringBuffer result = new StringBuffer()
..write(prefix)
..write(' \u2502\n');
RenderSliver child = firstChild; RenderSliver child = firstChild;
while (child != lastChild) { if (child == null)
result.write(child.toStringDeep("$prefix \u251C\u2500${labelForChild(count)}: ", "$prefix \u2502")); return children;
int count = indexOfFirstChild;
while (true) {
children.add(child.toDiagnosticsNode(name: labelForChild(count)));
if (child == lastChild)
break;
count += 1; count += 1;
child = childAfter(child); child = childAfter(child);
} }
assert(child == lastChild); return children;
result.write(child.toStringDeep("$prefix \u2514\u2500${labelForChild(count)}: ", "$prefix "));
return result.toString();
} }
// API TO BE IMPLEMENTED BY SUBCLASSES // API TO BE IMPLEMENTED BY SUBCLASSES
...@@ -1046,9 +1045,9 @@ class RenderViewport extends RenderViewportBase<SliverPhysicalContainerParentDat ...@@ -1046,9 +1045,9 @@ class RenderViewport extends RenderViewportBase<SliverPhysicalContainerParentDat
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('anchor: $anchor'); description.add(new DoubleProperty('anchor', anchor));
} }
} }
......
...@@ -593,13 +593,13 @@ class RenderWrap extends RenderBox with ContainerRenderObjectMixin<RenderBox, Wr ...@@ -593,13 +593,13 @@ class RenderWrap extends RenderBox with ContainerRenderObjectMixin<RenderBox, Wr
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('direction: $direction'); description.add(new EnumProperty<Axis>('direction', direction));
description.add('alignment: $alignment'); description.add(new EnumProperty<WrapAlignment>('alignment', alignment));
description.add('spacing: $spacing'); description.add(new DoubleProperty('spacing', spacing));
description.add('runAlignment: $runAlignment'); description.add(new EnumProperty<WrapAlignment>('runAlignment', runAlignment));
description.add('runSpacing: $runSpacing'); description.add(new DoubleProperty('runSpacing', runSpacing));
description.add('crossAxisAlignment: $runSpacing'); description.add(new DoubleProperty('crossAxisAlignment', runSpacing));
} }
} }
...@@ -215,11 +215,10 @@ class AnimatedCrossFade extends StatefulWidget { ...@@ -215,11 +215,10 @@ class AnimatedCrossFade extends StatefulWidget {
_AnimatedCrossFadeState createState() => new _AnimatedCrossFadeState(); _AnimatedCrossFadeState createState() => new _AnimatedCrossFadeState();
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('$crossFadeState'); description.add(new EnumProperty<CrossFadeState>('crossFadeState', crossFadeState));
if (alignment != FractionalOffset.topCenter) description.add(new DiagnosticsProperty<FractionalOffset>('alignment', alignment, defaultValue: FractionalOffset.topCenter));
description.add('alignment: $alignment');
} }
} }
...@@ -353,11 +352,10 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> with TickerProvid ...@@ -353,11 +352,10 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> with TickerProvid
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('${widget.crossFadeState}'); description.add(new EnumProperty<CrossFadeState>('crossFadeState', widget.crossFadeState));
description.add('$_controller'); description.add(new DiagnosticsProperty<AnimationController>('controller', _controller, showName: false));
if (widget.alignment != FractionalOffset.topCenter) description.add(new DiagnosticsProperty<FractionalOffset>('alignment', widget.alignment, defaultValue: FractionalOffset.topCenter));
description.add('alignment: ${widget.alignment}');
} }
} }
...@@ -198,15 +198,17 @@ class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> { ...@@ -198,15 +198,17 @@ class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> {
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
if (_keepingAlive) description.add(new FlagProperty('_keepingAlive', value: _keepingAlive, ifTrue: 'keeping subtree alive'));
description.add('keeping subtree alive'); description.add(new DiagnosticsProperty<Map<Listenable, VoidCallback>>(
if (_handles == null) { 'handles',
description.add('no notifications ever received'); _handles,
} else { description: _handles != null ?
description.add('${_handles.length} active client${ _handles.length == 1 ? "" : "s" }'); '${_handles.length} active client${ _handles.length == 1 ? "" : "s" }' :
} null,
ifNull: 'no notifications ever received',
));
} }
} }
......
...@@ -207,12 +207,12 @@ class Banner extends StatelessWidget { ...@@ -207,12 +207,12 @@ class Banner extends StatelessWidget {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('"$message"'); description.add(new StringProperty('message', message, showName: false));
description.add('$location'); description.add(new EnumProperty<BannerLocation>('location', location));
description.add('$color'); description.add(new DiagnosticsProperty<Color>('color', color, showName: false));
'$textStyle'.split('\n').map((String value) => 'text $value').forEach(description.add); textStyle?.debugFillProperties(description, prefix: 'text ');
} }
} }
...@@ -243,13 +243,13 @@ class CheckedModeBanner extends StatelessWidget { ...@@ -243,13 +243,13 @@ class CheckedModeBanner extends StatelessWidget {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
String message = 'disabled'; String message = 'disabled';
assert(() { assert(() {
message = '"SLOW MODE"'; message = '"SLOW MODE"';
return true; return true;
}); });
description.add(message); description.add(new DiagnosticsNode.message(message));
} }
} }
This diff is collapsed.
...@@ -84,8 +84,8 @@ class DecoratedBox extends SingleChildRenderObjectWidget { ...@@ -84,8 +84,8 @@ class DecoratedBox extends SingleChildRenderObjectWidget {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
String label; String label;
if (position != null) { if (position != null) {
switch (position) { switch (position) {
...@@ -97,10 +97,15 @@ class DecoratedBox extends SingleChildRenderObjectWidget { ...@@ -97,10 +97,15 @@ class DecoratedBox extends SingleChildRenderObjectWidget {
break; break;
} }
} else { } else {
description.add('position: NULL');
label = 'decoration'; label = 'decoration';
} }
description.add(decoration != null ? '$label: $decoration' : 'no decoration'); description.add(new EnumProperty<DecorationPosition>('position', position, hidden: position != null));
description.add(new DiagnosticsProperty<Decoration>(
label,
decoration,
ifNull: 'no decoration',
showName: decoration != null,
));
} }
} }
...@@ -355,21 +360,14 @@ class Container extends StatelessWidget { ...@@ -355,21 +360,14 @@ class Container extends StatelessWidget {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
if (alignment != null) description.add(new DiagnosticsProperty<FractionalOffset>('alignment', alignment, showName: false, defaultValue: null));
description.add('$alignment'); description.add(new DiagnosticsProperty<EdgeInsets>('padding', padding, defaultValue: null));
if (padding != null) description.add(new DiagnosticsProperty<Decoration>('bg', decoration, defaultValue: null));
description.add('padding: $padding'); description.add(new DiagnosticsProperty<Decoration>('fg', foregroundDecoration, defaultValue: null));
if (decoration != null) description.add(new DiagnosticsProperty<BoxConstraints>('constraints', constraints, defaultValue: null));
description.add('bg: $decoration'); description.add(new DiagnosticsProperty<EdgeInsets>('margin', margin, defaultValue: null));
if (foregroundDecoration != null) description.add(new ObjectFlagProperty<Matrix4>.has('transform', transform));
description.add('fg: $foregroundDecoration');
if (constraints != null)
description.add('$constraints');
if (margin != null)
description.add('margin: $margin');
if (transform != null)
description.add('has transform');
} }
} }
...@@ -254,25 +254,18 @@ class EditableText extends StatefulWidget { ...@@ -254,25 +254,18 @@ class EditableText extends StatefulWidget {
EditableTextState createState() => new EditableTextState(); EditableTextState createState() => new EditableTextState();
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('controller: $controller'); description.add(new DiagnosticsProperty<TextEditingController>('controller', controller));
description.add('focusNode: $focusNode'); description.add(new DiagnosticsProperty<FocusNode>('focusNode', focusNode));
if (obscureText != false) description.add(new DiagnosticsProperty<bool>('obscureText', obscureText, defaultValue: false));
description.add('obscureText: $obscureText'); description.add(new DiagnosticsProperty<bool>('autocorrect', autocorrect, defaultValue: true));
if (autocorrect != true) style?.debugFillProperties(description);
description.add('autocorrect: $autocorrect'); description.add(new EnumProperty<TextAlign>('textAlign', textAlign, defaultValue: null));
description.add('${style.toString().split("\n").join(", ")}'); description.add(new DoubleProperty('textScaleFactor', textScaleFactor, defaultValue: null));
if (textAlign != null) description.add(new IntProperty('maxLines', maxLines, defaultValue: 1));
description.add('$textAlign'); description.add(new DiagnosticsProperty<bool>('autofocus', autofocus, defaultValue: false));
if (textScaleFactor != null) description.add(new EnumProperty<TextInputType>('keyboardType', keyboardType, defaultValue: null));
description.add('textScaleFactor: $textScaleFactor');
if (maxLines != 1)
description.add('maxLines: $maxLines');
if (autofocus != false)
description.add('autofocus: $autofocus');
if (keyboardType != null)
description.add('keyboardType: $keyboardType');
} }
} }
......
...@@ -354,29 +354,27 @@ class FocusScopeNode extends Object with TreeDiagnosticsMixin { ...@@ -354,29 +354,27 @@ class FocusScopeNode extends Object with TreeDiagnosticsMixin {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
if (_focus != null) if (_focus != null)
description.add('focus: $_focus'); description.add(new DiagnosticsProperty<FocusNode>('focus', _focus));
} }
@override @override
String debugDescribeChildren(String prefix) { List<DiagnosticsNode> debugDescribeChildren() {
final StringBuffer buffer = new StringBuffer(); final List<DiagnosticsNode> children = <DiagnosticsNode>[];
if (_firstChild != null) { if (_firstChild != null) {
FocusScopeNode child = _firstChild; FocusScopeNode child = _firstChild;
int count = 1; int count = 1;
while (child != _lastChild) { while (true) {
buffer.write(child.toStringDeep("$prefix \u251C\u2500child $count: ", "$prefix \u2502")); children.add(child.toDiagnosticsNode(name: "child $count"));
count += 1; if (child == _lastChild)
break;
child = child._nextSibling; child = child._nextSibling;
} count += 1;
if (child != null) {
assert(child == _lastChild);
buffer.write(child.toStringDeep("$prefix \u2514\u2500child $count: ", "$prefix "));
} }
} }
return buffer.toString(); return children;
} }
} }
......
...@@ -613,27 +613,17 @@ class RawGestureDetectorState extends State<RawGestureDetector> { ...@@ -613,27 +613,17 @@ class RawGestureDetectorState extends State<RawGestureDetector> {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
if (_recognizers == null) { if (_recognizers == null) {
description.add('DISPOSED'); description.add(new DiagnosticsNode.message('DISPOSED'));
} else { } else {
final List<String> gestures = _recognizers.values.map<String>((GestureRecognizer recognizer) => recognizer.toStringShort()).toList(); final List<String> gestures = _recognizers.values.map<String>((GestureRecognizer recognizer) => recognizer.toStringShort()).toList();
if (gestures.isEmpty) if (gestures.isEmpty)
gestures.add('<none>'); gestures.add('<none>');
description.add('gestures: ${gestures.join(", ")}'); description.add(new IterableProperty<String>('gestures', gestures));
}
switch (widget.behavior) {
case HitTestBehavior.translucent:
description.add('behavior: translucent');
break;
case HitTestBehavior.opaque:
description.add('behavior: opaque');
break;
case HitTestBehavior.deferToChild:
description.add('behavior: defer-to-child');
break;
} }
description.add(new EnumProperty<HitTestBehavior>('behavior', widget.behavior, defaultValue: null));
} }
} }
......
...@@ -114,16 +114,10 @@ class Icon extends StatelessWidget { ...@@ -114,16 +114,10 @@ class Icon extends StatelessWidget {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
if (icon != null) { description.add(new DiagnosticsProperty<IconData>('icon', icon, ifNull: '<empty>', showName: false));
description.add('$icon'); description.add(new DoubleProperty('size', size, defaultValue: null));
} else { description.add(new DiagnosticsProperty<Color>('color', color, defaultValue: null));
description.add('<empty>');
}
if (size != null)
description.add('size: $size');
if (color != null)
description.add('color: $color');
} }
} }
...@@ -71,8 +71,8 @@ class IconTheme extends InheritedWidget { ...@@ -71,8 +71,8 @@ class IconTheme extends InheritedWidget {
bool updateShouldNotify(IconTheme old) => data != old.data; bool updateShouldNotify(IconTheme old) => data != old.data;
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('$data'); description.add(new DiagnosticsProperty<IconThemeData>('data', data, showName: false));
} }
} }
...@@ -284,25 +284,17 @@ class Image extends StatefulWidget { ...@@ -284,25 +284,17 @@ class Image extends StatefulWidget {
_ImageState createState() => new _ImageState(); _ImageState createState() => new _ImageState();
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('image: $image'); description.add(new DiagnosticsProperty<ImageProvider>('image', image));
if (width != null) description.add(new DoubleProperty('width', width, defaultValue: null));
description.add('width: $width'); description.add(new DoubleProperty('height', height, defaultValue: null));
if (height != null) description.add(new DiagnosticsProperty<Color>('color', color, defaultValue: null));
description.add('height: $height'); description.add(new EnumProperty<BlendMode>('colorBlendMode', colorBlendMode, defaultValue: null));
if (color != null) description.add(new EnumProperty<BoxFit>('fit', fit, defaultValue: null));
description.add('color: $color'); description.add(new DiagnosticsProperty<FractionalOffset>('alignment', alignment, defaultValue: null));
if (colorBlendMode != null) description.add(new EnumProperty<ImageRepeat>('repeat', repeat, defaultValue: ImageRepeat.noRepeat));
description.add('colorBlendMode: $colorBlendMode'); description.add(new DiagnosticsProperty<Rect>('centerSlice', centerSlice, defaultValue: null));
if (fit != null)
description.add('fit: $fit');
if (alignment != null)
description.add('alignment: $alignment');
if (repeat != ImageRepeat.noRepeat)
description.add('repeat: $repeat');
if (centerSlice != null)
description.add('centerSlice: $centerSlice');
} }
} }
...@@ -374,9 +366,9 @@ class _ImageState extends State<Image> { ...@@ -374,9 +366,9 @@ class _ImageState extends State<Image> {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
description.add('stream: $_imageStream'); description.add(new DiagnosticsProperty<ImageStream>('stream', _imageStream));
description.add('pixels: $_imageInfo'); description.add(new DiagnosticsProperty<ImageInfo>('pixels', _imageInfo));
} }
} }
...@@ -80,16 +80,10 @@ class ImageIcon extends StatelessWidget { ...@@ -80,16 +80,10 @@ class ImageIcon extends StatelessWidget {
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillProperties(List<DiagnosticsNode> description) {
super.debugFillDescription(description); super.debugFillProperties(description);
if (image != null) { description.add(new DiagnosticsProperty<ImageProvider>('image', image, ifNull: '<empty>', showName: false));
description.add('$image'); description.add(new DoubleProperty('size', size, defaultValue: null));
} else { description.add(new DiagnosticsProperty<Color>('color', color, defaultValue: null));
description.add('<empty>');
}
if (size != null)
description.add('size: $size');
if (color != null)
description.add('color: $color');
} }
} }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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