Skip to content

Add color coding for class types. #5030

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 31 commits into from
Jan 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
652bcf5
-
polina-c Jan 11, 2023
b777fb1
-
polina-c Jan 12, 2023
d85bc1d
-
polina-c Jan 12, 2023
f411168
-
polina-c Jan 12, 2023
67e473f
-
polina-c Jan 12, 2023
8c7fc68
-
polina-c Jan 12, 2023
307c849
Update fake_service_manager.dart
polina-c Jan 12, 2023
9c9a84b
Update isolate_state.dart
polina-c Jan 12, 2023
a9c4f28
-
polina-c Jan 12, 2023
812d9bb
Merge branch 'root' into class-types
polina-c Jan 12, 2023
29e808b
-
polina-c Jan 12, 2023
0826c32
Update fake_service_manager.dart
polina-c Jan 12, 2023
dbf9524
Merge branch 'root' into class-types
polina-c Jan 12, 2023
844f0e2
-
polina-c Jan 12, 2023
87ad6e7
Merge branch 'master' of github.com:flutter/devtools into class-types
polina-c Jan 12, 2023
e0ba027
-
polina-c Jan 13, 2023
e4be589
-
polina-c Jan 13, 2023
d3ca5f9
Update class_name.dart
polina-c Jan 13, 2023
829e0bc
Update NEXT_RELEASE_NOTES.md
polina-c Jan 13, 2023
1d9076d
-
polina-c Jan 13, 2023
9eee76a
Update class_name.dart
polina-c Jan 13, 2023
9251a9a
Update icons.dart
polina-c Jan 13, 2023
c0fbd97
Update icons.dart
polina-c Jan 13, 2023
d1ea986
-
polina-c Jan 13, 2023
d5856ba
Update class_name.dart
polina-c Jan 13, 2023
2b0f075
Merge branch 'master' of github.com:flutter/devtools into class-types
polina-c Jan 13, 2023
613a409
-
polina-c Jan 13, 2023
58d328a
Update memory_hover_card.png
polina-c Jan 13, 2023
e2daf4a
-
polina-c Jan 13, 2023
ea5925c
Update memory_hover_card.png
polina-c Jan 14, 2023
b6d40ae
Merge branch 'master' of github.com:flutter/devtools into class-types
polina-c Jan 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/devtools_app/NEXT_RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ TODO: Remove this section if there are not any general updates.

## Memory updates

* Improve usability of snapshot diffing - [#5015](https://github.com/flutter/devtools/pull/5015)
* Improve usability of snapshot diffing [#5015](https://github.com/flutter/devtools/pull/5015)
* UI polish and cleanup - [#4855](https://github.com/flutter/devtools/pull/4855)
* Color code classes [#5030](https://github.com/flutter/devtools/pull/5030)

## Debugger updates

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import '../../../../shared/theme.dart';
import '../../../../shared/utils.dart';
import '../../shared/primitives/simple_elements.dart';

import '../../shared/shared_memory_widgets.dart';
import 'allocation_profile_table_view_controller.dart';
import 'model.dart';

Expand All @@ -27,7 +28,8 @@ import 'model.dart';
/// instances, memory).
const _defaultNumberFieldWidth = 90.0;

class _FieldClassNameColumn extends ColumnData<AllocationProfileRecord> {
class _FieldClassNameColumn extends ColumnData<AllocationProfileRecord>
implements ColumnRenderer<AllocationProfileRecord> {
_FieldClassNameColumn()
: super(
'Class',
Expand All @@ -38,12 +40,32 @@ class _FieldClassNameColumn extends ColumnData<AllocationProfileRecord> {
String? getValue(AllocationProfileRecord dataObject) =>
dataObject.heapClass.className;

// We are removing the tooltip, because it is provided by [HeapClassView].
@override
String getTooltip(AllocationProfileRecord dataObject) =>
dataObject.heapClass.fullName;
String getTooltip(AllocationProfileRecord dataObject) => '';

@override
bool get supportsSorting => true;

@override
Widget? build(
BuildContext context,
AllocationProfileRecord data, {
bool isRowSelected = false,
VoidCallback? onPressed,
}) {
if (data.isTotal) return null;

final theme = Theme.of(context);
return HeapClassView(
theClass: data.heapClass,
showCopyButton: isRowSelected,
copyGaItem: gac.MemoryEvent.diffClassSingleCopy,
textStyle:
isRowSelected ? theme.selectedTextStyle : theme.regularTextStyle,
rootPackage: serviceManager.rootInfoNow().package,
);
}
}

/// For more information on the Dart GC implementation, see:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import 'package:flutter/material.dart';
import '../../../../shared/analytics/analytics.dart' as ga;
import '../../../../shared/analytics/constants.dart' as gac;
import '../../../../shared/common_widgets.dart';
import '../../../../shared/globals.dart';
import '../../../../shared/primitives/utils.dart';
import '../../../../shared/table/table.dart';
import '../../../../shared/table/table_controller.dart';
import '../../../../shared/table/table_data.dart';
import '../../../../shared/theme.dart';
import '../../../../shared/utils.dart';
import '../../shared/shared_memory_widgets.dart';
import 'allocation_profile_tracing_view_controller.dart';

/// The default width for columns containing *mostly* numeric data (e.g.,
Expand Down Expand Up @@ -65,14 +67,37 @@ class _TraceCheckBoxColumn extends ColumnData<TracedClass>
}
}

class _ClassNameColumn extends ColumnData<TracedClass> {
class _ClassNameColumn extends ColumnData<TracedClass>
implements ColumnRenderer<TracedClass> {
_ClassNameColumn() : super.wide('Class');

@override
String? getValue(TracedClass stats) => stats.cls.name;

// We are removing the tooltip, because it is provided by [HeapClassView].
@override
String getTooltip(TracedClass dataObject) => '';

@override
bool get supportsSorting => true;

@override
Widget build(
BuildContext context,
TracedClass data, {
bool isRowSelected = false,
VoidCallback? onPressed,
}) {
final theme = Theme.of(context);
return HeapClassView(
theClass: data.name,
showCopyButton: isRowSelected,
copyGaItem: gac.MemoryEvent.diffClassSingleCopy,
textStyle:
isRowSelected ? theme.selectedTextStyle : theme.regularTextStyle,
rootPackage: serviceManager.rootInfoNow().package,
);
}
}

class _InstancesColumn extends ColumnData<TracedClass> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import '../../../../shared/primitives/utils.dart';
import '../../../../shared/table/table_data.dart';
import '../../../profiler/cpu_profile_model.dart';
import '../../../profiler/cpu_profile_transformer.dart';
import '../../shared/primitives/class_name.dart';

// TODO(bkonyi): make compatible with ClassHeapDetailStats for serialization /
// deserialization support.
Expand All @@ -20,13 +21,14 @@ class TracedClass with PinnableListEntry {
TracedClass({
required this.cls,
}) : traceAllocations = false,
instances = 0;
instances = 0,
name = HeapClassName.fromClassRef(cls);

TracedClass._({
required this.cls,
required this.instances,
required this.traceAllocations,
});
}) : name = HeapClassName.fromClassRef(cls);

TracedClass copyWith({
ClassRef? cls,
Expand All @@ -40,6 +42,7 @@ class TracedClass with PinnableListEntry {
);
}

final HeapClassName name;
final ClassRef cls;
final int instances;
final bool traceAllocations;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:flutter/foundation.dart';
import '../../../../../shared/analytics/analytics.dart' as ga;
import '../../../../../shared/analytics/constants.dart' as gac;
import '../../../../../shared/config_specific/import_export/import_export.dart';
import '../../../../../shared/globals.dart';
import '../../../../../shared/primitives/auto_dispose.dart';
import '../../../../../shared/primitives/utils.dart';
import '../../../shared/heap/class_filter.dart';
Expand Down Expand Up @@ -149,6 +150,8 @@ class DiffPaneController extends DisposableController {
/// Widgets should not update the fields directly, they should use
/// [DiffPaneController] or [DerivedData] for this.
class CoreData {
late final rootPackage = serviceManager.rootInfoNow().package;

/// The list contains one item that show information and all others
/// are snapshots.
ValueListenable<List<SnapshotItem>> get snapshots => _snapshots;
Expand Down Expand Up @@ -283,14 +286,14 @@ class DerivedData extends DisposableController with AutoDisposeControllerMixin {
}) {
final filter = _core.classFilter.value;
if (classes is SingleHeapClasses) {
_singleClassesToShow.value = classes.filtered(filter);
_singleClassesToShow.value = classes.filtered(filter, _core.rootPackage);
_diffClassesToShow.value = null;
selectedSingleClassStats.value =
_filter(classes.classesByName[className]);
selectedDiffClassStats.value = null;
} else if (classes is DiffHeapClasses) {
_singleClassesToShow.value = null;
_diffClassesToShow.value = classes.filtered(filter);
_diffClassesToShow.value = classes.filtered(filter, _core.rootPackage);
selectedSingleClassStats.value = null;
selectedDiffClassStats.value = _filter(classes.classesByName[className]);
} else if (classes == null) {
Expand All @@ -306,7 +309,12 @@ class DerivedData extends DisposableController with AutoDisposeControllerMixin {
/// Returns [classStats] if it matches the current filter.
T? _filter<T extends ClassStats>(T? classStats) {
if (classStats == null) return null;
if (_core.classFilter.value.apply(classStats.heapClass)) return classStats;
if (_core.classFilter.value.apply(
classStats.heapClass,
_core.rootPackage,
)) {
return classStats;
}
return null;
}

Expand Down Expand Up @@ -394,10 +402,16 @@ class DerivedData extends DisposableController with AutoDisposeControllerMixin {
// Get class with max retained size.
final ClassStats theClass;
if (classes is SingleHeapClasses) {
final classStatsList = classes.filtered(_core.classFilter.value);
final classStatsList = classes.filtered(
_core.classFilter.value,
_core.rootPackage,
);
theClass = classStatsList.reduce(singleWithMaxRetainedSize);
} else if (classes is DiffHeapClasses) {
final classStatsList = classes.filtered(_core.classFilter.value);
final classStatsList = classes.filtered(
_core.classFilter.value,
_core.rootPackage,
);
theClass = classStatsList.reduce(diffWithMaxRetainedSize);
} else {
throw StateError('Unexpected type ${classes.runtimeType}');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import '../../../../../shared/dialogs.dart';
import '../../../../../shared/theme.dart';
import '../../../../../shared/utils.dart';
import '../../../shared/heap/class_filter.dart';
import '../../../shared/primitives/class_name.dart';

String _adaptRootPackageForFilter(String? rootPackage) {
if (rootPackage == null || rootPackage.isEmpty) return '';
Expand Down Expand Up @@ -130,7 +131,7 @@ class _ClassFilterDialogState extends State<ClassFilterDialog> {

return StateUpdateDialog(
title: 'Filter Classes and Packages',
helpText: _helpText,
helpBuilder: _helpBuilder,
onResetDefaults: () {
ga.select(
gac.memory,
Expand Down Expand Up @@ -167,11 +168,38 @@ class _ClassFilterDialogState extends State<ClassFilterDialog> {
}
}

Widget _helpBuilder(BuildContext context) {
final textStyle = DialogHelpText.textStyle(context);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(_helpText, style: textStyle),
...ClassType.values.map(
(t) => Column(
children: [
Row(
children: [
t.icon,
Text(
' ${t.alias} - for ${t.aliasDescription}',
style: textStyle,
),
CopyToClipboardControl(
dataProvider: () => t.alias,
size: tableIconSize,
)
],
),
],
),
),
],
);
}

const _helpText = 'Choose and customize the filter.\n'
'List full or partial class names separated by new lines. For example:\n\n'
' package:myPackage/src/myFolder/myLibrary.dart/MyClass\n'
' MyClass\n'
' package:myPackage/src/\n\n'
'Specify:\n'
' - ${ClassFilter.dartInternalAlias} for dart internal objects, not assigned to any package\n'
' - ${ClassFilter.dartAndFlutterLibrariesAlias} for most "dart:" and "package:" libraries published by Dart and Flutter orgs.';
'Use aliases to filter classes by type:\n';
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:flutter/material.dart';

import '../../../../../shared/analytics/analytics.dart' as ga;
import '../../../../../shared/analytics/constants.dart' as gac;
import '../../../../../shared/globals.dart';
import '../../../../../shared/primitives/utils.dart';
import '../../../../../shared/table/table.dart';
import '../../../../../shared/table/table_data.dart';
Expand Down Expand Up @@ -34,7 +35,7 @@ class _ClassNameColumn extends ColumnData<DiffClassStats>
: super(
'Class',
titleTooltip: 'Class name',
fixedWidthPx: scaleByFontFactor(180.0),
fixedWidthPx: scaleByFontFactor(200.0),
alignment: ColumnAlignment.left,
);

Expand Down Expand Up @@ -64,6 +65,7 @@ class _ClassNameColumn extends ColumnData<DiffClassStats>
copyGaItem: gac.MemoryEvent.diffClassDiffCopy,
textStyle:
isRowSelected ? theme.selectedTextStyle : theme.regularTextStyle,
rootPackage: serviceManager.rootInfoNow().package,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
import '../../../../../shared/analytics/analytics.dart' as ga;
import '../../../../../shared/analytics/constants.dart' as gac;
import '../../../../../shared/feature_flags.dart';
import '../../../../../shared/globals.dart';
import '../../../../../shared/primitives/utils.dart';
import '../../../../../shared/table/table.dart';
import '../../../../../shared/table/table_data.dart';
Expand All @@ -26,7 +27,7 @@ class _ClassNameColumn extends ColumnData<SingleClassStats>
: super(
'Class',
titleTooltip: 'Class name',
fixedWidthPx: scaleByFontFactor(180.0),
fixedWidthPx: scaleByFontFactor(200.0),
alignment: ColumnAlignment.left,
);

Expand Down Expand Up @@ -57,6 +58,7 @@ class _ClassNameColumn extends ColumnData<SingleClassStats>
copyGaItem: gac.MemoryEvent.diffClassSingleCopy,
textStyle:
isRowSelected ? theme.selectedTextStyle : theme.regularTextStyle,
rootPackage: serviceManager.rootInfoNow().package,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,13 @@ class ClassFilter {
ClassFilter.empty()
: this(
filterType: ClassFilterType.showAll,
except: '$dartInternalAlias\n$dartAndFlutterLibrariesAlias',
except: '${ClassType.runtime.alias}\n${ClassType.sdk.alias}',
only: null,
);

static String _trimByLine(String value) =>
value.split('\n').map((e) => e.trim()).join('\n');

static const String dartAndFlutterLibrariesAlias = '\$dart-flutter-libraries';
static const String dartInternalAlias = '\$dart-internal-objects';

final ClassFilterType filterType;
final String except;

Expand Down Expand Up @@ -124,25 +121,24 @@ class ClassFilter {
}
}

bool apply(HeapClassName className) {
bool apply(HeapClassName className, String? rootPackage) {
if (className.isRoot) return false;

if (filterType == ClassFilterType.showAll) return true;

for (var filter in filters) {
if (_isMatch(className, filter)) {
if (_isMatch(className, filter, rootPackage)) {
return filterType == ClassFilterType.only;
}
}

return filterType == ClassFilterType.except;
}

bool _isMatch(HeapClassName className, String filter) {
bool _isMatch(HeapClassName className, String filter, String? rootPackage) {
if (className.fullName.contains(filter)) return true;
if (filter == dartAndFlutterLibrariesAlias && className.isDartOrFlutter)
return true;
if (filter == dartInternalAlias && className.isPackageless) return true;
return false;

final classType = className.classType(rootPackage);
return filter == classType.alias;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ mixin FilterableHeapClasses<T extends ClassStats> on HeapClasses<T> {
ClassFilter? _appliedFilter;
List<T>? _filtered;

List<T> filtered(ClassFilter newFilter) {
List<T> filtered(ClassFilter newFilter, String? rootPackage) {
final oldFilter = _appliedFilter;
final oldFiltered = _filtered;
_appliedFilter = newFilter;
Expand All @@ -69,8 +69,9 @@ mixin FilterableHeapClasses<T extends ClassStats> on HeapClasses<T> {
throw StateError('Unexpected task: $task.');
}

final result =
dataToFilter.where((e) => newFilter.apply(e.heapClass)).toList();
final result = dataToFilter
.where((e) => newFilter.apply(e.heapClass, rootPackage))
.toList();
return _filtered = result;
}
}
Expand Down
Loading