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

core(tsc): update debugger protocol type checking #5836

Merged
merged 8 commits into from
Sep 1, 2018
Merged

core(tsc): update debugger protocol type checking #5836

merged 8 commits into from
Sep 1, 2018

Conversation

brendankenny
Copy link
Member

@brendankenny brendankenny commented Aug 15, 2018

Blocked on ChromeDevTools/devtools-protocol#113

The new tuple types in TypeScript 3.0 allow us to better represent protocol payloads whether an object, an optional object, or empty. See ChromeDevTools/devtools-protocol#113 for details. This allows us to get rid of a bunch of fiddly bits and simplify our StrictEventEmitter type to just a few lines.

We can also now

One possibly controversial thing: I basically reverted the silent option from #2279 as it makes the sendCommand interface difficult to define. If we really want to, I think we can make it work (in a super ugly way), but based on the on-going #1091 it didn't seem to help the Tracing.start issue. Open to thoughts there.

@brendankenny
Copy link
Member Author

✂️ ✂️ ✂️ ✂️ ✂️
screen shot 2018-08-14 at 18 12 40

this._eventEmitter.emit(event.method, event.params);
} else {
this._eventEmitter.emit(event.method);
}
Copy link
Member Author

Choose a reason for hiding this comment

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

only slightly annoying thing the compiler makes us do, and I think the best choice (it's difficult to go from optional object property to function argument and back to optional property in current JS and express it elegantly, regardless of type checking).

Another way might be to make StrictEventEmitter.emit() less strict (allowing undefined even if the event has no params) than the callbacks themselves since we only use it internally to Driver and Connection.

Copy link
Member

@paulirish paulirish left a comment

Choose a reason for hiding this comment

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

this looks rad.

i'm ok with dropping the endTraceIfStarted, btw.

@@ -43,6 +43,9 @@ const RESOURCE_TYPES = {
WebSocket: 'WebSocket',
Other: 'Other',
Manifest: 'Manifest',
SignedExchange: 'SignedExchange',
Ping: 'Ping',
CSPViolationReport: 'CSPViolationReport',
Copy link
Member

Choose a reason for hiding this comment

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

nice!

while i do see these here https://chromedevtools.github.io/devtools-protocol/tot/Page#type-ResourceType

i don't see them here: https://github.com/ChromeDevTools/devtools-frontend/blob/master/front_end/common/ResourceType.js

but i guess that's because we're now ahead of the frontend. :)

Copy link
Collaborator

Choose a reason for hiding this comment

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

but i guess that's because we're now ahead of the frontend. :)

🎉 💣 💥 💯 💃 🕺 🥇

music to my ears!!!

@denar90
Copy link
Contributor

denar90 commented Aug 31, 2018

Can we expect to have this merged before next release?

@brendankenny
Copy link
Member Author

Yes, when ChromeDevTools/devtools-protocol#113 ships to npm I just need to update and we should be able to land it

@denar90
Copy link
Contributor

denar90 commented Aug 31, 2018

Thanks for the info :)

@brendankenny brendankenny changed the title WIP: core(tsc): update debugger protocol type checking core(tsc): update debugger protocol type checking Aug 31, 2018
@brendankenny
Copy link
Member Author

no longer a WIP :)


// @ts-ignore TODO(bckenny): tsc can't type event.params correctly yet,
// typing as property of union instead of narrowing from union of
// properties. See https://github.com/Microsoft/TypeScript/pull/22348.
Copy link
Member Author

@brendankenny brendankenny Sep 1, 2018

Choose a reason for hiding this comment

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

this is unfortunate to ignore, but will have to wait on the ts team for the fix.

Basically _eventEmitter.emit() correctly checks that for every protocol event method name (e.g. 'Profiler.consoleProfileStarted'), it will have a matching event params (e.g. LH.Crdp.Profiler.ConsoleProfileStartedEvent).

The event object passed into this function is a giant union of possible method/pair objects like:

{method: 'Profiler.consoleProfileStarted', params: LH.Crdp.Profiler.ConsoleProfileStartedEvent} |
{method: 'Runtime.bindingCalled', params: LH.Crdp.Runtime.BindingCalledEvent} |
{method: 'CSS.fontsUpdated', params: LH.Crdp.CSS.FontsUpdatedEvent} |
...

It's a discriminated union, so in theory the compiler could check each union member separately, which would pass the _eventEmitter.emit() check.

Currently, however, the compiler doesn't narrow the type based on method, so instead of taking each union member separately, it takes the union of all possible property values. The second argument passed to _eventEmitter.emit() ends up being LH.Crdp.Profiler.ConsoleProfileStartedEvent | LH.Crdp.Runtime.BindingCalledEvent | LH.Crdp.CSS.FontsUpdatedEvent | ....

When _eventEmitter.emit() starts checking that for every method ('Profiler.consoleProfileStarted') there is the correct params (LH.Crdp.Profiler.ConsoleProfileStartedEvent), it sees that full union instead and so rightly shows an error since only one member of the union would have been the correct type.

As noted, this will hopefully be fixed by microsoft/TypeScript#22348, currently aimed at the typescript 3.2ish timeframe.

Copy link
Member Author

@brendankenny brendankenny Sep 1, 2018

Choose a reason for hiding this comment

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

Also, it's slightly confusing, but the similar checks in the surrounding methods (e.g. other uses of eventEmitter) are correctly type checked. The key is that here event is an object with method and params as properties. If method and params had come in as separate function parameters (as they do elsewhere) or as a tuple, the compiler would be able to correctly type them.

@paulirish
Copy link
Member

LETS DO THIS

@paulirish paulirish merged commit e07a94b into master Sep 1, 2018
@paulirish paulirish deleted the crdp branch September 1, 2018 00:59
@denar90
Copy link
Contributor

denar90 commented Sep 1, 2018

thanks 💃

@denar90
Copy link
Contributor

denar90 commented Sep 4, 2018

@brendankenny @paulirish one more thing
do you have any info about next (maybe small/minor/teeny-tiny) release? :)

@denar90
Copy link
Contributor

denar90 commented Sep 7, 2018

Not relevant question, thanks it's already released)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants