Skip to content
3 changes: 2 additions & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,10 @@ dart_code_metrics:
# TODO(https://github.com/flutter/devtools/issues/9906) remove these
# excludes as findings are resolved.
- integration_test/**
# Investigate internal usages of inspector_controller before removing.
- lib/src/screens/inspector/**_controller.dart
- lib/src/extensions/**
- lib/src/framework/**
- lib/src/screens/**
- lib/src/service/**
- lib/src/shared/**
- lib/src/standalone_ui/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class EmbeddedExtensionControllerImpl extends EmbeddedExtensionController
final extensionPostEventStream =
StreamController<DevToolsExtensionEvent>.broadcast();

// ignore: unused-code, TODO(https://github.com/flutter/devtools/issues/9907): false positive.
bool _initialized = false;

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import 'package:flutter/material.dart';
import 'controller.dart';

class EmbeddedExtension extends StatelessWidget {
const EmbeddedExtension({super.key, required this.controller});

final EmbeddedExtensionController controller;
const EmbeddedExtension({
super.key,
required EmbeddedExtensionController controller,
});

@override
Widget build(BuildContext context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class ExtensionService extends DisposableController
///
/// This set of extensions will include one version of a DevTools extension
/// per package.
@visibleForTesting
List<DevToolsExtensionConfig> get availableExtensions =>
_currentExtensions.value.availableExtensions;

Expand Down
7 changes: 1 addition & 6 deletions packages/devtools_app/lib/src/framework/home_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ class HomeScreen extends Screen {
titleGenerator: () => devToolsTitle.value,
);

static final id = ScreenMetaData.home.id;

final List<DevToolsJsonFile> sampleData;

@override
Expand Down Expand Up @@ -165,10 +163,7 @@ class _ConnectInputState extends State<ConnectInput> with BlockingActionMixin {
void initState() {
super.initState();
connectDialogController = TextEditingController();
assert(() {
_debugInitVmServiceCache();
return true;
}());
if (kDebugMode) _debugInitVmServiceCache();
}

void _debugInitVmServiceCache() async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ bool debugTestReleaseNotes = false;
// from the flutter/website PR, which has a GitHub action that automatically
// stages commits to firebase. Example:
// https://flutter-docs-prod--pr12652-devtools-release-notes-2-52-3bbb8c0u.web.app/tools/devtools/release-notes/release-notes-2.52.0.md.
// ignore: unused-code, debug-only feature.
String? _debugReleaseNotesUrl;

const releaseNotesKey = Key('release_notes');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ class StatusLine extends StatelessWidget {
/// Whether to highlight the footer when DevTools is connected to an app.
final bool highlightForConnection;

static const deviceInfoTooltip = 'Device Info';

/// The padding around the footer in the DevTools UI.
EdgeInsets get padding => const EdgeInsets.symmetric(
horizontal: defaultSpacing,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ export 'semantics_tree_pane.dart';
class AccessibilityScreen extends Screen {
AccessibilityScreen() : super.fromMetaData(ScreenMetaData.accessibility);

static final id = ScreenMetaData.accessibility.id;

@override
Widget buildScreenBody(BuildContext context) =>
const AccessibilityScreenBody();
Expand All @@ -36,11 +34,13 @@ class AccessibilityScreenBody extends StatefulWidget {

class _AccessibilityScreenBodyState extends State<AccessibilityScreenBody>
with AutoDisposeMixin {
// ignore: unused-code, temporarily ignore since this screen is under active development.
late AccessibilityController controller;

@override
void initState() {
super.initState();
// ignore: unused-code, temporarily ignore since this screen is under active development.
controller = screenControllers.lookup<AccessibilityController>();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ class _AppSizeBodyState extends State<AppSizeBody>
if (currentTab.key == AppSizeScreen.diffTabKey) ...[
const SizedBox(width: defaultSpacing),
DiffTreeTypeDropdown(
value: controller.activeDiffTreeType.value,
onChanged: (newDiffTreeType) {
controller.changeActiveDiffTreeType(newDiffTreeType!);
},
Expand Down Expand Up @@ -279,11 +278,9 @@ class AppUnitDropdown extends StatelessWidget {
class DiffTreeTypeDropdown extends StatelessWidget {
const DiffTreeTypeDropdown({
super.key,
required this.value,
required this.onChanged,
});

final DiffTreeType value;
final ValueChanged<DiffTreeType?>? onChanged;
Comment on lines 278 to 284

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

[MUST-FIX] Removing the value parameter from DiffTreeTypeDropdown is likely a logical bug.

Since DiffTreeTypeDropdown is a StatelessWidget, it has no internal state and must receive the currently selected value from its parent to display the correct selection. If the value field was flagged as unused by the lint, it is highly probable that the build method of DiffTreeTypeDropdown was missing the binding of value to the underlying dropdown widget (e.g., DropdownButton or DevToolsDropdown).

Instead of deleting the value field and parameter, please restore them and ensure that value is properly bound to the dropdown widget inside the build method:

@override
Widget build(BuildContext context) {
  return DevToolsDropdown<DiffTreeType>(
    value: value, // <-- Ensure this is bound!
    onChanged: onChanged,
    ...
  );
}
References
  1. Categorize Severity: Prefix every comment with a severity: [MUST-FIX] for logical bugs. (link)


@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ class BreakpointManager with DisposerMixin {

final _breakPositionsMap = <String, List<SourcePosition>>{};

ValueListenable<List<Breakpoint>> get breakpoints => _breakpoints;
final _breakpoints = ValueNotifier<List<Breakpoint>>([]);

ValueListenable<List<BreakpointAndSourcePosition>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,7 @@ class CodeViewSourceLocationNavigationState extends DevToolsNavigationState {
DevToolsNavigationState state,
) : super(kind: type, state: state.state);

@visibleForTesting
static CodeViewSourceLocationNavigationState? fromState(
DevToolsNavigationState? state,
) {
Expand Down
15 changes: 2 additions & 13 deletions packages/devtools_app/lib/src/screens/debugger/span_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -589,19 +589,6 @@ class ScopeStack {
/// Location where the next produced span should begin.
ScopeStackLocation _nextLocation = ScopeStackLocation.zero;

/// Adds a scope for a given region.
///
/// This method is the same as calling [push] and then [pop] with the same
/// args.
void add(
String? scope, {
required ScopeStackLocation start,
required ScopeStackLocation end,
}) {
push(scope, start);
pop(scope, end);
}

/// Pushes a new scope onto the stack starting at [location].
void push(String? scope, ScopeStackLocation location) {
if (scope == null) return;
Expand Down Expand Up @@ -721,6 +708,8 @@ class ScopeStackItem {
ScopeStackItem(this.scope, this.location);

final String scope;

// ignore: unused-code, foundational to this data class.
final ScopeStackLocation location;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ final _log = Logger('syntax_highlighter');
class SyntaxHighlighter {
SyntaxHighlighter({String? source}) : source = source ?? '';

@visibleForTesting
SyntaxHighlighter.withGrammar({Grammar? grammar, String? source})
: source = source ?? '' {
_grammar = grammar;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,12 @@ class DeepLinkListView extends StatefulWidget {
}

class _DeepLinkListViewState extends State<DeepLinkListView> {
late DeepLinksController controller;

@override
void initState() {
super.initState();
controller = screenControllers.lookup<DeepLinksController>()
..firstLoadWithDefaultConfigurations();
screenControllers
.lookup<DeepLinksController>()
.firstLoadWithDefaultConfigurations();
}

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,6 @@ class AASAfileFormatSubCheck extends CommonError {
),
);

static final defaultsCaseSensitiveFormat = AASAfileFormatSubCheck(
'Applinks defaults case sensitive format',
propertyTypeMessage(
property: 'applinks.defaults.caseSensitive',
expectedType: 'boolean',
),
);

static const detailsFormat = AASAfileFormatSubCheck(
'Applinks details format',
'This test checks that the `applinks.details` property is formatted properly. Ref - '
Expand Down Expand Up @@ -402,6 +394,7 @@ class Path {
final String path;

// TODO(hangyujin): display queryParams in path table.
// ignore: unused-code, outstanding TODO.
final Map<String, String> queryParams;

/// A Boolean value that indicates whether to stop pattern matching and prevent the universal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ class DeepLinksScreen extends Screen {

static final id = ScreenMetaData.deepLinks.id;

// TODO(https://github.com/flutter/devtools/issues/6013): write documentation.
// @override
// String get docPageId => id;
@override
String get docPageId => id;

@override
String get docsUrl => 'https://flutter.dev/to/deep-link-tool';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ final aasaFileFormatSubCheck = {

class ValidateIosDomainResult {
ValidateIosDomainResult(this.errorCode, this.domainErrors, this.paths);
// ignore: unused-code, this is addressed in a TODO below.
final String errorCode;
final Map<String, List<DomainError>> domainErrors;
final Map<String, List<Path>> paths;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@ class DtdServiceMethod implements Comparable<DtdServiceMethod> {
const DtdServiceMethod({
required this.service,
required this.method,
this.capabilities,
});

final String? service;
final String method;
final Map<String, Object?>? capabilities;

String get displayName => [service, method].nonNulls.join('.');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ import 'shared.dart';
class DTDToolsScreen extends Screen {
DTDToolsScreen() : super.fromMetaData(ScreenMetaData.dtdTools);

static final id = ScreenMetaData.dtdTools.id;

@override
Widget buildScreenBody(BuildContext _) => const DTDToolsScreenBody();
}
Expand Down
1 change: 0 additions & 1 deletion packages/devtools_app/lib/src/screens/dtd/services.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ class ServicesController extends FeatureController {
DtdServiceMethod(
service: service.name,
method: method.name,
capabilities: method.capabilities,
),
],
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import 'inspector_screen_controller.dart';
class InspectorScreen extends Screen {
InspectorScreen() : super.fromMetaData(ScreenMetaData.inspector);

static const minScreenWidthForText = 900.0;

static final id = ScreenMetaData.inspector.id;

// There is not enough room to safely show the console in the embed view of
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ class InspectorScreenBodyState extends State<InspectorScreenBody>
SearchTargetType searchTarget = SearchTargetType.widget;

static const inspectorTreeKey = Key('Inspector Tree');
static const minScreenWidthForText = 900.0;

@override
void initState() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import 'package:flutter/material.dart';

import '../../../../shared/diagnostics/diagnostics_node.dart';
import '../../../../shared/primitives/utils.dart';
import '../../inspector_controller.dart';
import '../../inspector_data_models.dart';
import '../ui/free_space.dart';
import '../ui/theme.dart';
Expand All @@ -15,14 +14,12 @@ import '../ui/widget_constraints.dart';
import '../ui/widgets_theme.dart';

class BoxLayoutExplorerWidget extends StatelessWidget {
const BoxLayoutExplorerWidget(
this.inspectorController, {
const BoxLayoutExplorerWidget({
super.key,
required this.layoutProperties,
required this.selectedNode,
});

final InspectorController inspectorController;
final LayoutProperties? layoutProperties;
final RemoteDiagnosticsNode? selectedNode;

Expand Down Expand Up @@ -230,56 +227,6 @@ class BoxLayoutExplorerWidget extends StatelessWidget {
String _describeBoxName(LayoutProperties properties) =>
properties.node.description ?? '';

/// Represents a box widget and its surrounding padding.
class BoxChildAndPaddingVisualizer extends StatelessWidget {
const BoxChildAndPaddingVisualizer({
super.key,
required this.layoutProperties,
required this.renderProperties,
required this.isSelected,
});

final bool isSelected;
final LayoutProperties layoutProperties;
final RenderProperties renderProperties;

LayoutProperties? get properties => renderProperties.layoutProperties;

@override
Widget build(BuildContext context) {
final renderSize = renderProperties.size;
final renderOffset = renderProperties.offset;

final propertiesLocal = properties!;

return Positioned(
top: renderOffset.dy,
left: renderOffset.dx,
child: SizedBox(
width: safePositiveDouble(renderSize.width),
height: safePositiveDouble(renderSize.height),
child: WidgetVisualizer(
isSelected: isSelected,
layoutProperties: layoutProperties,
title: _describeBoxName(propertiesLocal),
// TODO(jacobr): consider surfacing the overflow size information
// if we determine
// overflowSide: properties.overflowSide,

// We only show one child at a time so a large title is safe.
largeTitle: true,
child: VisualizeWidthAndHeightWithConstraints(
arrowHeadSize: arrowHeadSize,
properties: propertiesLocal,
warnIfUnconstrained: false,
child: const SizedBox.shrink(),
),
),
),
);
}
}

/// Widget that represents and visualize a direct child of Flex widget.
class BoxChildVisualizer extends StatelessWidget {
const BoxChildVisualizer({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,6 @@ const overflowBackgroundColorLight = Color(0xFFB00020);
const overflowTextColorDark = Color(0xfff5846b);
const overflowTextColorLight = Color(0xffdea089);

const backgroundColorSelectedDark = Color(
0x4d474747,
); // TODO(jacobr): we would like Color(0x4dedeeef) but that makes the background show through.
const backgroundColorSelectedLight = Color(0x4dedeeef);

extension LayoutExplorerColorScheme on ColorScheme {
Color get mainAxisColor => isLight ? mainAxisLightColor : mainAxisDarkColor;

Expand All @@ -93,16 +88,10 @@ extension LayoutExplorerColorScheme on ColorScheme {
Color get overflowTextColor =>
isLight ? overflowTextColorLight : overflowTextColorDark;

Color get backgroundColorSelected =>
isLight ? backgroundColorSelectedLight : backgroundColorSelectedDark;

Color get unconstrainedColor =>
isLight ? unconstrainedLightColor : unconstrainedDarkColor;
}

const backgroundColorDark = Color(0xff30302f);
const backgroundColorLight = Color(0xffffffff);

const unconstrainedDarkColor = Color(0xffdea089);
const unconstrainedLightColor = Color(0xfff5846b);

Expand Down
Loading
Loading