-
Notifications
You must be signed in to change notification settings - Fork 170
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
Decouple request and listener logic #1247
Conversation
733dccd
to
01e610b
Compare
e90f3e2
to
1fee1f8
Compare
b7797c9
to
4c73499
Compare
563e29c
to
38d6ff2
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.
Once all requests are proper descendants of Request
you should be able to enforce overrides on provider
:
class Request
extend T::Sig
extend T::Helpers
abstract!
class << self
extend T::Sig
sig { abstract.returns(T.attached_class) }
def provider; end
end
end
class RequestA < Request
class << self
sig { override.returns(T.attached_class) }
def provider
new
end
end
end
class RequestB < Request # Error: Missing definition for abstract method `Request.provider`
end
38d6ff2
to
7883aa2
Compare
@Morriar But provider is not to return the request itself. It's for options like |
e14645b
to
c84b26c
Compare
c84b26c
to
885c4ed
Compare
# reference | ||
first_entry = T.must(entries.first) | ||
return if first_entry.visibility == :private && first_entry.name != "#{@nesting.join("::")}::#{name}" | ||
# TODO: other_responses should never be nil. Check Sorbet |
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 this comment be removed? I think the T.must
below addresses it, right?
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 the comment means that we shouldn't need to wrap T.must
around other_responses
as it's a splat assignment:
first_response, *other_responses = responses
It should always be an array regardless of responses
's value:
ruby-lsp(main):008> x, *y = a; y
=> []
ruby-lsp(main):009> a = nil
=> nil
ruby-lsp(main):010> x, *y = a; y
=> []
ruby-lsp(main):011>
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.
Indeed, Sorbet is incorrect in this case (unless I'm missing something). I tried a bunch of variations and in the a, *b =
pattern, b
is always an array and never nilable.
Can we please check if there's an issue for that and, if not, create one? Feels like something that shouldn't be too hard to address (famous last words).
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 there's an 4-year old issue for it: sorbet/sorbet#2020
To be fair, it was fixed but then the fix was reverted.
885c4ed
to
5193d9f
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.
Caught one bug while tophatting
false | ||
sig { override.returns(ResponseType) } | ||
def response | ||
@dispatcher.dispatch_once(@target) |
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 line is failing because @dispatcher
is nil
on certain conditions due to the early returns in initialize
.
I think we should move most of the code in the initialize
method to response
and ensure that the key instance variables are always set.
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 prefer not moving most of them into response
as it means we'd need to initialise listeners there too, which doesn't align with other requests.
I've rearranged the ordering in initialize
a bit instead so all the ivars used in response
should always be defined.
5193d9f
to
b4667df
Compare
Motivation
Currently, we treat listener-based requests as both a listener and a request. For example, the
Hover
request handles the instantiation of addon's hover listeners, while being a listener itself to process dispatcher events. This coupling limits the change we can make to improve the interface for addons or more complicated response merging logic.Implementation
Request
class as the parent, which currently only makes sure the response method is calledresponse
(instead ofrun
).ListenerBasedRequest < Request
(name to be improved) class was also created to help listener-based requests define and use listeners. This means:ExtensibleListener
is not needed anymore.executor.rb
are moved to individual request classes as well.Notes
response
anymore. But changing it would break addons and makes this already giant PR even bigger. So I decide to do it later.ResponseType
on both the listener and request classes. But similar to the above, it'll be a huge change on its own and IMO it's better to implement in a follow up PR.Feedback Needed
executor.rb
, like:Automated Tests
All existing tests should still pass.
Manual Tests