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
Inspector Implementation #120
Conversation
High level notes: InspectorController is a port of the InspectorPanel class from the Java code base with refactors to make it a true controller. InspectorController tests can be run with a regular dart vm. InspectorTree holds most of the functionality for a very inspector specific tree renderer. Renamed DiagnosticsNode to RemoteDiagnosticsNode as I wanted to pull in the real local DiagnosticsNode class from Flutter as it is really handy for ascii art string dumps for tests. |
I may take a few passes through this PR, but will defer to @kenzieschmoll for a full review. Can you post some screenshots of the UI in the meantime? |
👍 screenshots look great |
|
||
/// Reference the actual Dart DiagnosticsNode object this object is referencing. | ||
InspectorInstanceRef getDartDiagnosticRef() { | ||
InspectorInstanceRef get dartDiagnosticRef { | ||
return InspectorInstanceRef(json['objectId']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you inline this?
InspectorInstanceRef get dartDiagnosticRef => InspectorInstanceRef(json['objectId']);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to but the line length is above 80 and => blocks shouldn't wrap.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really, really fantastic! I made a quick pass through; comments in-line.
lib/inspector/diagnostics_node.dart
Outdated
@@ -725,12 +657,12 @@ class InspectorSourceLocation { | |||
final Map<String, Object> json; | |||
final InspectorSourceLocation parent; | |||
|
|||
String getPath() { | |||
String get path { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use =>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
: super( | ||
name: 'Inspector', | ||
id: 'inspector', | ||
iconClass: 'octicon-device-mobile', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no trailing comma may make this particular instance format better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without the trailing comma, dartfmt generates
InspectorScreen()
: super(
name: 'Inspector',
id: 'inspector',
iconClass: 'octicon-device-mobile');
which I feel makes the end paren less obvious.
As an aside, I would personally be a fan of setting the line length to 100 for this code base
in case this line would just be a natural one liner.
div()..flex(), | ||
div(c: 'btn-group collapsible') | ||
..add(<CoreElement>[ | ||
ServiceExtensionButton(extensions.performanceOverlay).button, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
possibly put these into ~2 separate button groups, instead of having 7 buttons in a row?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inspectorContainer.add(elements); | ||
splitterSubscription = flexSplitBidirectional(elements); | ||
|
||
// TODO(jacobr): update visibility based on whether the screen is visible. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When you do get ready to do this, we have entering()
and exiting()
calls you can override for Screens.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great!
await group.dispose(); | ||
return null; | ||
} | ||
// TODO(jacobr): use the list of loaded scripts to determine the appropriate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think Isolate.rootLib
is what you want - I don't think you'll need the full list of scripts (it's also available now however, as part of the new getScripts()
call).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the todo to use Isolate.rootLib. TLDR; I need to cleanup the --track-widget-creation transformer to stop using absolute paths.
@terrylucas maybe you are interested in helping fix that in the transformer as you need to tweak the transformer code for some memory tracking items.
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
library inspector_tree_canvas; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious if we need library
directives? I normally only add them if I need someplace to hang dartdoc comments off of.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no idea. I've been adding them out of habit. Removed the low value ones.
web/index.html
Outdated
@@ -21,7 +21,7 @@ | |||
<link rel="stylesheet" href="styles.css"> | |||
<link rel="stylesheet" href="packages/devtools/debugger/debugger.css"> | |||
<link rel="stylesheet" href="packages/devtools/logging/logging.css"> | |||
|
|||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that all the rest of our deps are in-lined into the package - that they could be served w/o an internet connection (including the octicons icons). Perhaps open an issue to in-line the material icons font?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't seem to make a comment down there, but right after <!-- add the known pages -->
, can you add a place for the Inspector page, and remove the one for the Device page? We have an approximation of the final UI in static html so that there's less flashing and re-layout when the app launches.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. I'd thought that part of static HTML was cruft to cleanup rather than server side rendering./
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Loaded the flutter icons locally.
web/styles.css
Outdated
@@ -232,6 +232,35 @@ input:disabled+label { | |||
opacity: 0.5; | |||
} | |||
|
|||
.inspector-tree { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd create an inspector specific style sheet, lib/inspector/inspector.css
, and move things into there that won't be shared. We do this for the debugging and logging pages, just so this css file doesn't grow unbounded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -651,6 +680,26 @@ nav.menu li { | |||
color: #ccc; | |||
} | |||
|
|||
/* | |||
We have to do something with the scrollbars as they flicker due to DOM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want this for all of our scrollbars or just the inspector ones?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this impacts the infinite scrolling table as well so yes.
We can tweak this style so we still fade in and out on hover but I think this is at least a non-flickery default.
web/styles.css
Outdated
@@ -686,3 +735,23 @@ nav.menu li { | |||
bottom: 30px; | |||
z-index: 10; | |||
} | |||
|
|||
@media all and (max-width: 1280px) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 this is great
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More comments (around testing)!
@@ -1041,6 +1041,7 @@ class BreakpointsView { | |||
|
|||
Stream<Breakpoint> get onDoubleClick => _items.onDoubleClick; | |||
|
|||
@override |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 ; there are ~4 more places in this file I believe where we could make the same change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great. I've updated them all to implement the CoreElementView interface.
test/inspector_controller_test.dart
Outdated
expect( | ||
detailsTree.toStringDeep(), | ||
equalsIgnoringHashCodes( | ||
'▼[S] Scaffold <-- selected\n' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we keep this golden output in a txt file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm torn about this. On one hand a text file makes rebaselining easy but on the other hand inline makes the intent of the test much clearer. As a middle ground I plan to fixup the output here so most of these tests are truncated output only highlighting the relevant details so rebaselining won't be needed much or at all and the forest is easier to see from the trees.
note that there are a number of inline golden style text output tests in flutter proper and they rarely break.
test/inspector_controller_test.dart
Outdated
expect( | ||
detailsTree.toStringDeep(), | ||
equalsIgnoringHashCodes('▼[S] Scaffold \n' | ||
'│ ▼state: ScaffoldState#00000(tickers: tracking 1 ticker)\n' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps this output as well (in a separate file), given the size?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this dump will be made a pleasant size by the tweaks alluded to above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
correction. added reasonably nice golden file and rebaseline goldens functionality and used it i all the details cases. ended up adding a more verbose golden format that include styles as well and used it to catch a bug where we were emitting some pointless styled empty blocks.
@@ -0,0 +1,438 @@ | |||
// Copyright 2019 The Chromium Authors. All rights reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some of these files, are there cooresponding Java file in the flutter-intellij repo (or dart files in the flutter repo) that we should be keeping them up-to-date with? If so, we should call that out in comments in order to help future maintainers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
test/inspector_service_test.dart
Outdated
import 'dart:async'; | ||
import 'dart:io'; | ||
|
||
import 'package:devtools/inspector/diagnostics_node.dart'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
organize imports?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
test/inspector_controller_test.dart
Outdated
import 'dart:async'; | ||
import 'dart:io'; | ||
|
||
import 'package:devtools/inspector/flutter_widget.dart'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
organize imports?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
test/inspector_service_test.dart
Outdated
expect( | ||
treeToDebugString(nodeInDetailsTree), | ||
equalsIgnoringHashCodes('MaterialApp\n' | ||
' │ state: _MaterialAppState#00000\n' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
have a separate golden master file for this test expectation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
import 'package:devtools/inspector/flutter_widget.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
import 'package:devtools/globals.dart'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like some portion of the devtools codebase will need to run in the VM (not an issue, just noting it). I expect that the tests on travis will keep us honest, if we start referencing dart:html code from portions of the app that need to be able to run on the cli.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. these tests along with the one @kenzieschmoll already added keep us honest about not adding dart:html imports to our business logic code which is a great thing. When I'd first added the inspector code but let a few dart:html tests sneak in, @kenzieschmoll's tests started failing locally with complains about my deart:html deps.
lib/inspector/inspector.dart
Outdated
detailsInspectorTree.element.element | ||
]; | ||
inspectorContainer.add(elements); | ||
splitterSubscription = flexSplitBidirectional(elements); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would use defaultSplitterWidth
for the splitter width. I see that this version of the method doesn't take preferred ratios for the child sizes, but if we can add it you may try out a 40/60 or 33/66 split (see if giving more weight to the RHS looks good).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added default size options for the bidirectional splitter which is a bit tricky as it can be both horizontal and vertical depending on the window size.
Agreed that a 60/40 split looks much better. Use 65/35 split in the other direction in the vertical layout case as in that case the details panel should be smaller not larger.
case DiagnosticsTreeStyle.truncateChildren: | ||
return null; | ||
} | ||
return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could put this in a default case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this code isn't for review here. it is just forked from package flutter so ignoring your valid comments :)
_debugPrintBuffer.isNotEmpty) { | ||
final String line = _debugPrintBuffer.removeFirst(); | ||
_debugPrintedCharacters += | ||
line.length; // TODO(ianh): Use the UTF-8 byte length instead |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably remove this todo for ianh@?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there is value for us just porting files wholesale instead of trying to cleanup as these files will be ported more cleanly at some later point for hummingbird. all we want for them now is that we can reasonably bring in new versions from package:flutter without odd diffs.
6419b3c
to
4bda7f0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
7717d57
to
de15da8
Compare
this matches intellij ui and solves problem where render objects in tests had different dimensions than on the bots.
wow! |
Sorry about the large size. Good news is a few of the files are just additional clones from flutter and there are tests.