-
-
Notifications
You must be signed in to change notification settings - Fork 159
Add support for Ruby Structs #939
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
Add support for Ruby Structs #939
Conversation
This reverts commit 2432024218132f7d06a3b1600ebc17a2e87df260.
- Move classes into it's own file - Fix nil errors - Add TODO comments
@@ -2630,4 +2630,117 @@ def foo | |||
clip = api_map.clip_at('test.rb', [13, 12]) | |||
expect(clip.infer.to_s).to eq('Integer') | |||
end | |||
|
|||
it 'completes Struct methods' do |
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.
Are clip_specs the right place for these specs?
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.
The Clip
specs are pretty heavy, but I can understand why. They're fine here for now. I'm planning updates to Chain
that make it less reliant on Clip
features. Part of that change will probably include moving some tests from clip_spec
to chain_spec
or the various link specs.
@@ -8,6 +8,17 @@ class CasgnNode < Parser::NodeProcessor::Base | |||
include ParserGem::NodeMethods | |||
|
|||
def process | |||
if Convention::StructDefinition::StructAssignmentNode.valid?(node) |
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 don't like the fact that I had to change the node processor classes - do you see a better way to avoid that?
My initial attempt was to allow multiple node processors, as I explained in the PR description.
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 suspect that any solution would have required some sort of change to node processors. At the very least, they would need a mechanism to map anonymous class pins for declarations like class Foo < Struct.new
. I'm good with handling it like this for now. We can try exploring more general solutions when we look into adding support for Data
.
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.
Sounds good 🙌!
👍 |
Hi,
This PR adds support for Ruby Struct class definitions both via inheritance and const assignment:
It completes:
keyword_init
option@param
yard tags on class definition to infer attribute types.@!attribute
usage, which kind of defeats the purpose ofStruct
usage to avoid defining them by hand in the first place.Approach
So I thought for quite a while, where this code could live, and I went back and forth many times between:
lib/solargraph/parser/parser_gem/node_processors
Struct.new
is not a language construct, ie, node per se.lib/solargraph/convention
(direction I went with)Solargraph::Convention
interface.So, as we see, each approach has its upside/downside. I ultimately went with the second approach because while working on the solargraph-rspec plugin, I always felt a need for Solargraph to provide a way to hook into the parsing phase. Something that would prevent plugins from parsing the same code twice!
While I attempted to allow supporting multiple node processers, I stumbled over some issues with having "duplicate pins", which I couldn't find a good solution to, so I ended up with this "hybrid solution", hoping that we get to solve that problem eventually (which is why I left the
TODO
comments are for)I plan to add support similarly for Data classes too, before jumping to that I wanted to got some feedback from you on the proposed approach and whether this any sense at all to you?
Thanks in advance for your thoughts and guidance!