Skip to content
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

Show static types in tooltips #1160

Closed
DanTup opened this issue Aug 19, 2018 · 9 comments
Closed

Show static types in tooltips #1160

DanTup opened this issue Aug 19, 2018 · 9 comments
Labels
in editor Relates to code editing or language features in lsp/analysis server Something to be fixed in the Dart analysis server is enhancement
Milestone

Comments

@DanTup
Copy link
Member

DanTup commented Aug 19, 2018

If I hover over "object" inside this if block it says Object object, but the type here is known to be Instance (and the set method is declared on Instance).

screen shot 2018-08-19 at 10 10 08

@DanTup DanTup added is bug in editor Relates to code editing or language features labels Aug 19, 2018
@DanTup DanTup added this to the v2.18.0 milestone Aug 19, 2018
@DanTup
Copy link
Member Author

DanTup commented Aug 20, 2018

We're using the elementDescription for display here, though the result does have the correct type in staticType:

{
	"id": "36",
	"result": {
		"hovers": [
			{
				"offset": 6559,
				"length": 6,
				"elementDescription": "Object object",
				"elementKind": "local variable",
				"isDeprecated": false,
				"staticType": "Instance"
			}
		]
	}
}

@bwilkerson Is there value in showing Object to the user here? I could add the staticType in addition but it might be weird if the tooltip shows both Object and Instance. However, I can't (nicely) remove Object because of it being embedded in elementDescription.

@bwilkerson
Copy link

It certainly makes sense to tell the user that the static type is "Instance" here, but there might be some value in also telling them how it was declared. Maybe it's largely a question of presentation. I don't know what the current hover text looks like, but perhaps something like this would make sense:

The static type is Instance.
It was declared as Object object.

(I say "like this" because I don't think the above is either attractive or readable.)

What I'd really like us to be able to display is the information to explain the difference in these two types (something like "because of the 'is' check on line lineNumber").

But it's possible that we ought to make the declared type and the element name be two different fields for ease of composition. (We have yet to find the sweet spot between making it flexible by having lots of fields and reducing the work on the client side by pre-formatting the output.)

@DanTup
Copy link
Member Author

DanTup commented Aug 20, 2018

We have yet to find the sweet spot between making it flexible by having lots of fields and reducing the work on the client side by pre-formatting the output

Yeah, this comes up now and I was reminded of it when I saw this.

The tooltip for this currently looks kinda sparse, because it's a local variable with no docs or anything:

screen shot 2018-08-20 at 3 18 33 pm

What I'd really like us to be able to display is the information to explain the difference in these two types (something like "because of the 'is' check on line lineNumber").

Yeah, that'd be neat. I'd love to show it as something like this:

screen shot 2018-08-20 at 3 26 41 pm

I think putting the static type first makes sense since it's probably the one the user cares most about here, but with a note about the declared type and why it's different.

Looking in our hover code, I noticed we have something called the propagatedType:

if (propagatedType) displayString += `propagated type: ${propagatedType.trim()}`;

I'm not sure I remember every seeing that rendered, so not sure what it is (the server docs just say it's the propagated type, but I'm none the wiser). For now, I'm gonna stick the static type on the end in parens:

Object object (Instance)

And I'm moving propagated type to the same (since where it's currently rendered the label is fixed-with and looks wonky if I force it to show). Hopefully both won't appear at the same time as that'll be a little confusing!

@DanTup
Copy link
Member Author

DanTup commented Aug 20, 2018

Ugh, the static type is provided even when it matches the start of elementDescription which means I end up with String a (String) on a normal string. In order to show the static type (and not look redundant), I'd need to know whether it's different, and I don't think I can do that reliably (I could check it starts with the static type then a space, but I think that might not be reliable since there could be spaces in function types?).

I think this may need a server change before we can really improve it.

@DanTup DanTup modified the milestones: v2.18.0, Backlog Aug 20, 2018
@DanTup DanTup closed this as completed in 41d18b2 Aug 20, 2018
@DanTup DanTup added the blocked on dart / flutter Requires a change in Dart or Flutter to progress label Aug 20, 2018
@DanTup DanTup reopened this Aug 20, 2018
@bwilkerson
Copy link

... I noticed we have something called the propagatedType ...

As of Dart 2, there shouldn't be any propagated type information (I need to deprecate the field). The propagated type was an early, analyzer-only, attempt to have better type information than the spec allowed for at that time. Now that we have type inference, we no longer compute a propagated type.

Ugh, the static type is provided even when it matches the start of elementDescription ...

I can think of three ways to resolve that problem, two of which I'd already mentioned. First, we could split the elementDescription into a declaredType and name pair. Second, we could provide a single description field that combined all of the information for clients so that they don't need to compose it for themselves. Third, we could omit the staticType field when there's no useful information.

We need to think about cases where there is no declared type (such as var x = ...), cases like the one above where the declared and static type are significantly different (Object vs Instance), and cases where the static type is just a refinement (List vs List<String>). And, of course, we shouldn't forget the cases where the variable isn't declared at all.

@DanTup
Copy link
Member Author

DanTup commented Aug 20, 2018

As of Dart 2, there shouldn't be any propagated type information (I need to deprecate the field). The propagated type was an early, analyzer-only, attempt to have better type information than the spec allowed for at that time.

Ah, makes sense (and why I haven't seen it lately).

I can think of three ways to resolve that problem, two of which I'd already mentioned.

I don't have any strong preferences on this. Having separate fields is more flexible, but I also like that giving us formatted strings gives a consistency across tools (and also I think people working on the server have a much better understanding of Dart than I, so are likely to format things better than me mashing a bunch of fields together). Any implementation that allows the user to see this extra info - which is a really neat feature of Dart (though it slightly bugs me that it doesn't work if in invert the condition - not sure if that's a bug?) - would be great. I can open an SDK bug if you think it should be tracked over there.

@bwilkerson
Copy link

... though it slightly bugs me that it doesn't work if in invert the condition - not sure if that's a bug?

You and a lot of people :-). There was an effort started to enhance the flow of type information through code structures, but it keeps not being at the top of the language team's list. I keep hoping we can enhance this part of the type system some day.

I can open an SDK bug if you think it should be tracked over there.

Probably a good idea. I don't know when we'll have the resources to fix it, and I'd rather we didn't forget about it.

@DanTup
Copy link
Member Author

DanTup commented Aug 20, 2018

I've opened dart-lang/sdk#34196 with some notes from this issue.

@DanTup DanTup changed the title Tooltip doesn't show promoted type Tooltip doesn't show static type Feb 18, 2021
@DanTup DanTup removed the blocked on dart / flutter Requires a change in Dart or Flutter to progress label Jan 19, 2022
@DanTup DanTup modified the milestones: Backlog, v3.34.0 Jan 19, 2022
@DanTup DanTup added in lsp/analysis server Something to be fixed in the Dart analysis server is enhancement and removed is bug labels Jan 19, 2022
@DanTup DanTup changed the title Tooltip doesn't show static type Show static types in tooltips Jan 19, 2022
copybara-service bot pushed a commit to dart-lang/sdk that referenced this issue Jan 19, 2022
Fixes #48147.
Fixes Dart-Code/Dart-Code#1160.

Change-Id: Icc4bbb5b89a75a14579f72b2c74929e7a05ac688
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/228840
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
@DanTup
Copy link
Member Author

DanTup commented Jan 19, 2022

Fixed by dart-lang/sdk@5bf643b.

@DanTup DanTup closed this as completed Jan 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in editor Relates to code editing or language features in lsp/analysis server Something to be fixed in the Dart analysis server is enhancement
Projects
None yet
Development

No branches or pull requests

2 participants