Merge pull request #1630 from Hixie/debug

Improve debugging output
This commit is contained in:
Ian Hickson 2015-10-15 11:31:20 -07:00
commit 3a00fbbd77
7 changed files with 160 additions and 35 deletions

View File

@ -11,6 +11,7 @@ import 'dart:ui' as ui;
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/rendering.dart';
import 'stock_data.dart';

View File

@ -112,7 +112,7 @@ class StockHomeState extends State<StockHome> {
),
new DrawerItem(
icon: 'device/dvr',
onPressed: () { debugDumpApp(); },
onPressed: () { debugDumpApp(); debugDumpRenderTree(); },
child: new Text('Dump App to Console')
),
new DrawerDivider(),

View File

@ -252,25 +252,131 @@ class TextStyle {
List<String> result = <String>[];
if (color != null)
result.add('${prefix}color: $color');
// TODO(hansmuller): escape the fontFamily string.
if (fontFamily != null)
result.add('${prefix}fontFamily: "$fontFamily"');
result.add('${prefix}family: "$fontFamily"');
if (fontSize != null)
result.add('${prefix}fontSize: $fontSize');
if (fontWeight != null)
result.add('${prefix}fontWeight: $fontWeight');
if (fontStyle != null)
result.add('${prefix}fontStyle: $fontStyle');
if (textAlign != null)
result.add('${prefix}textAlign: $textAlign');
if (textBaseline != null)
result.add('${prefix}textBaseline: $textBaseline');
if (decoration != null)
result.add('${prefix}decoration: $decoration');
if (decorationColor != null)
result.add('${prefix}decorationColor: $decorationColor');
if (decorationStyle != null)
result.add('${prefix}decorationStyle: $decorationStyle');
result.add('${prefix}size: $fontSize');
if (fontWeight != null) {
switch (fontWeight) {
case FontWeight.w100:
result.add('${prefix}weight: 100');
break;
case FontWeight.w200:
result.add('${prefix}weight: 200');
break;
case FontWeight.w300:
result.add('${prefix}weight: 300');
break;
case FontWeight.w400:
result.add('${prefix}weight: 400');
break;
case FontWeight.w500:
result.add('${prefix}weight: 500');
break;
case FontWeight.w600:
result.add('${prefix}weight: 600');
break;
case FontWeight.w700:
result.add('${prefix}weight: 700');
break;
case FontWeight.w800:
result.add('${prefix}weight: 800');
break;
case FontWeight.w900:
result.add('${prefix}weight: 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 (textAlign != null) {
switch (textAlign) {
case TextAlign.left:
result.add('${prefix}align: left');
break;
case TextAlign.right:
result.add('${prefix}align: right');
break;
case TextAlign.center:
result.add('${prefix}align: center');
break;
}
}
if (textBaseline != null) {
switch (textBaseline) {
case TextBaseline.alphabetic:
result.add('${prefix}baseline: alphabetic');
break;
case TextBaseline.ideographic:
result.add('${prefix}baseline: ideographic');
break;
}
}
if (decoration != null || decorationColor != null || decorationStyle != null) {
String decorationDescription = '${prefix}decoration: ';
bool haveDecorationDescription = false;
if (decorationStyle != null) {
switch (decorationStyle) {
case TextDecorationStyle.solid:
decorationDescription += 'solid';
break;
case TextDecorationStyle.double:
decorationDescription += 'double';
break;
case TextDecorationStyle.dotted:
decorationDescription += 'dotted';
break;
case TextDecorationStyle.dashed:
decorationDescription += 'dashed';
break;
case TextDecorationStyle.wavy:
decorationDescription += 'wavy';
break;
}
haveDecorationDescription = true;
}
if (decorationColor != null) {
if (haveDecorationDescription)
decorationDescription += ' ';
decorationDescription += '$decorationColor';
haveDecorationDescription = true;
}
if (decoration != null) {
if (haveDecorationDescription)
decorationDescription += ' ';
bool multipleDecorations = false;
for (TextDecoration value in decoration) {
if (multipleDecorations)
decorationDescription += '+';
switch (value) {
case TextDecoration.none:
decorationDescription += 'none';
break;
case TextDecoration.underline:
decorationDescription += 'underline';
break;
case TextDecoration.overline:
decorationDescription += 'overline';
break;
case TextDecoration.lineThrough:
decorationDescription += 'line-through';
break;
}
multipleDecorations = true;
}
haveDecorationDescription = true;
}
assert(haveDecorationDescription);
result.add(decorationDescription);
}
if (result.isEmpty)
return '$prefix<no style specified>';
return result.join('\n');

View File

@ -1139,11 +1139,18 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
/// Returns a description of the tree rooted at this node.
/// If the prefix argument is provided, then every line in the output
/// will be prefixed by that string.
String toStringDeep([String prefix = '']) {
String toStringDeep([String prefixLineOne = '', String prefixOtherLines = '']) {
RenderObject debugPreviousActiveLayout = _debugActiveLayout;
_debugActiveLayout = null;
prefix += ' ';
String result = '$this\n${debugDescribeSettings(prefix)}${debugDescribeChildren(prefix)}';
String result = '$prefixLineOne$this\n';
final String childrenDescription = debugDescribeChildren(prefixOtherLines);
final String settingsPrefix = childrenDescription != '' ? '$prefixOtherLines \u2502 ' : '$prefixOtherLines ';
result += debugDescribeSettings(settingsPrefix);
if (childrenDescription != '')
result += '$prefixOtherLines \u2502\n';
else
result += '$prefixOtherLines\n';
result += childrenDescription;
_debugActiveLayout = debugPreviousActiveLayout;
return result;
}
@ -1198,7 +1205,7 @@ abstract class RenderObjectWithChildMixin<ChildType extends RenderObject> implem
}
String debugDescribeChildren(String prefix) {
if (child != null)
return '${prefix}child: ${child.toStringDeep(prefix)}';
return '${child.toStringDeep("$prefix \u2514\u2500child: ", "$prefix ")}';
return '';
}
}
@ -1442,13 +1449,19 @@ abstract class ContainerRenderObjectMixin<ChildType extends RenderObject, Parent
String debugDescribeChildren(String prefix) {
String result = '';
int count = 1;
ChildType child = _firstChild;
while (child != null) {
result += '${prefix}child $count: ${child.toStringDeep(prefix)}';
count += 1;
final ParentDataType childParentData = child.parentData;
child = childParentData.nextSibling;
if (_firstChild != null) {
ChildType child = _firstChild;
int count = 1;
while (child != _lastChild) {
result += '${child.toStringDeep("$prefix \u251C\u2500child $count: ", "$prefix \u2502")}';
count += 1;
final ParentDataType childParentData = child.parentData;
child = childParentData.nextSibling;
}
if (child != null) {
assert(child == _lastChild);
result += '${child.toStringDeep("$prefix \u2514\u2500child $count: ", "$prefix ")}';
}
}
return result;
}

View File

@ -883,6 +883,7 @@ class FractionalOffset {
value = 37 * value + y.hashCode;
return value;
}
String toString() => '$runtimeType($x, $y)';
}
/// Applies a transformation before painting its child
@ -1016,7 +1017,7 @@ class RenderTransform extends RenderProxyBox {
String debugDescribeSettings(String prefix) {
List<String> result = _transform.toString().split('\n').map((String s) => '$prefix $s\n').toList();
result.removeLast();
return '${super.debugDescribeSettings(prefix)}${prefix}transform matrix:\n${result.join()}\n${prefix}origin: $origin\n';
return '${super.debugDescribeSettings(prefix)}${prefix}transform matrix:\n${result.join()}\n${prefix}origin: $origin\nalignment: $alignment\n';
}
}

View File

@ -92,6 +92,9 @@ void runApp(Widget app) {
void debugDumpApp() {
assert(WidgetFlutterBinding.instance != null);
assert(WidgetFlutterBinding.instance.renderViewElement != null);
String mode = 'RELEASE MODE';
assert(() { mode = 'CHECKED MODE'; return true; });
print('${WidgetFlutterBinding.instance.runtimeType} - $mode');
WidgetFlutterBinding.instance.renderViewElement.toStringDeep().split('\n').forEach(print);
}

View File

@ -394,8 +394,11 @@ abstract class State<T extends StatefulComponent> {
void debugFillDescription(List<String> description) {
description.add('$hashCode');
if (_debugLifecycleState != _StateLifecycle.ready)
description.add('$_debugLifecycleState');
assert(() {
if (_debugLifecycleState != _StateLifecycle.ready)
description.add('$_debugLifecycleState');
return true;
});
if (_config == null)
description.add('no config');
if (_element == null)
@ -829,9 +832,7 @@ abstract class Element<T extends Widget> implements BuildContext {
String toStringDeep([String prefixLineOne = '', String prefixOtherLines = '']) {
String result = '$prefixLineOne$this\n';
List<Element> children = <Element>[];
visitChildren((Element child) {
children.add(child);
});
visitChildren(children.add);
if (children.length > 0) {
Element last = children.removeLast();
for (Element child in children)