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

Type based completion using Prism and RBS #708

Merged
merged 21 commits into from
Nov 8, 2023

Conversation

tompng
Copy link
Member

@tompng tompng commented Sep 8, 2023

Implement type based autocompletion #734 using Prism and RBS

Default completor is still :regexp. To enable :type completor, write IRB.conf[:COMPLETOR] = :type to irbrc.

When Prism is available
without_rbs

When Prism and RBS is available
with_rbs

When Prism is not available, it fallbacks to RegexpCompletor

This pull request will port gem katakata_irb's completion(https://github.com/tompng/katakata_irb/) to IRB.

@tompng tompng force-pushed the yarp_rbs_completor branch 2 times, most recently from a8d1547 to 46ae44b Compare September 9, 2023 21:53
@Morriar
Copy link
Contributor

Morriar commented Sep 13, 2023

Using static analysis to provide auto-completion is a surprising direction for IRB which already has access to a lot of dynamic information.

It seems like you are reimplementing features that belong more to a static type checker such as Steep or Sorbet or IDE features already covered by the Ruby LSP. I wonder if IRB is the right place for this?

@tompng
Copy link
Member Author

tompng commented Sep 18, 2023

It seems like you are reimplementing features that belong more to a static type checker

Yes, it's a reimplemention but has some difference from other static type checker.

  • Few static information and many runtime information
    In IRB, most of the thing is dynamically defined. It doesn't analyze the whole project code but only analyze code in current input buffer.
    It is tightly coupled with binding by design to use many runtime information.
  • Focuses on loose completion, not strict type check

So I think it is worth making a static + dynamic type analyzer specialized for REPL.

@st0012
Copy link
Member

st0012 commented Sep 18, 2023

So I think it is worth making a static + dynamic type analyzer specialized for REPL.

Since we're going to need a full analyzer with dependency on rbs, could it be a standalone gem instead, and IRB just has an completion adapter for it? Similar to how Rails define adapters for background job libraries like resque, sidekiq....etc. but not directly including them.

@tompng tompng force-pushed the yarp_rbs_completor branch 11 times, most recently from 14ca0bb to 92d2639 Compare October 18, 2023 18:41
@tompng tompng force-pushed the yarp_rbs_completor branch 2 times, most recently from 7fe5db3 to 121ae29 Compare October 25, 2023 16:45
@tompng tompng marked this pull request as ready for review October 25, 2023 17:03
lib/irb/type_completion/completor.rb Outdated Show resolved Hide resolved
lib/irb/type_completion/completor.rb Outdated Show resolved Hide resolved
Copy link
Contributor

@kddnewton kddnewton left a comment

Choose a reason for hiding this comment

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

Honestly this looks great. It's super impressive how much work you've put in.

Please let me know if there's anything in the prism API that could be added to help you.

lib/irb/type_completion/completor.rb Outdated Show resolved Hide resolved
lib/irb/context.rb Outdated Show resolved Hide resolved
lib/irb/input-method.rb Outdated Show resolved Hide resolved
lib/irb/type_completion/completor.rb Show resolved Hide resolved
lib/irb/type_completion/completor.rb Show resolved Hide resolved
lib/irb/type_completion/completor.rb Outdated Show resolved Hide resolved
lib/irb/type_completion/types.rb Outdated Show resolved Hide resolved
lib/irb/type_completion/types.rb Outdated Show resolved Hide resolved
lib/irb/type_completion/scope.rb Show resolved Hide resolved
lib/irb/type_completion/scope.rb Outdated Show resolved Hide resolved
test/irb/type_completion/test_scope.rb Outdated Show resolved Hide resolved
lib/irb/type_completion/types.rb Outdated Show resolved Hide resolved
end
end

def self.type_from_object_recursive(object, max_level:)
Copy link
Member

Choose a reason for hiding this comment

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

Yeah let's just do 1 level for now + limit it to 50 samples maybe. In Rails console it's not rare to call users = User.some_scope.to_a, which could have thousands of objects.

test/irb/type_completion/test_type_completor.rb Outdated Show resolved Hide resolved
@st0012 st0012 added the enhancement New feature or request label Nov 6, 2023
Copy link
Member

@st0012 st0012 left a comment

Choose a reason for hiding this comment

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

Amazing work 👍

@st0012 st0012 changed the title Type based completion using YARP and RBS Type based completion using Prism and RBS Nov 6, 2023
Copy link
Collaborator

@hasumikin hasumikin left a comment

Choose a reason for hiding this comment

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

I'd agree with shipping this feature with Ruby 3.3

Functions I would like to add gradually:

  • Freely change the completer within the IRB session
  • To display a kind of a "backtrace" of how the completion candidates are created with one simple command

Copy link
Member

@ima1zumi ima1zumi left a comment

Choose a reason for hiding this comment

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

@tompng tompng merged commit 1048c7e into ruby:master Nov 8, 2023
24 checks passed
@tompng tompng deleted the yarp_rbs_completor branch November 8, 2023 02:46
matzbot pushed a commit to ruby/ruby that referenced this pull request Nov 8, 2023
(ruby/irb#708)

* Add completor using prism and rbs

* Add TypeCompletion test

* Switchable completors: RegexpCompletor and TypeCompletion::Completor

* Add completion info to irb_info

* Complete reserved words

* Fix [*] (*) {**} and prism's change of KeywordParameterNode

* Fix require, frozen_string_literal

* Drop prism<=0.16.0 support

* Add Completor.last_completion_error for debug report

* Retrieve `self` and `Module.nesting` in more safe way

* Support BasicObject

* Handle lvar and ivar get exception correctly

* Skip ivar reference test of non-self object in ruby < 3.2

* BaseScope to RootScope, move method objects constant under Methods

* Remove unused Splat struct

* Drop deeply nested array/hash type calculation from actual object. Now, calculation depth is 1

* Refactor loading rbs in test, change preload_in_thread not to cache Thread object

* Use new option added in prism 0.17.1 to parse code with localvars

* Add Prism version check and warn when :type completor cannot be enabled

* build_type_completor should skip truffleruby (because endless method definition is not supported)

ruby/irb@1048c7ed7a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Development

Successfully merging this pull request may close these issues.

None yet

7 participants