-
-
Notifications
You must be signed in to change notification settings - Fork 10.1k
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
Remove use of hidden-definitions in favor of Tapioca compilers #16586
Conversation
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.
Looks good so far!
a7961a5
to
515b9bc
Compare
# This is an autogenerated file for dynamic methods in `RuboCop::Cop::FormulaAudit::AssertStatements`. | ||
# Please instead update this file by running `bin/tapioca dsl RuboCop::Cop::FormulaAudit::AssertStatements`. | ||
|
||
class RuboCop::Cop::FormulaAudit::AssertStatements; end |
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.
Note that there are 21 rbi files that are useless that are introduced in this PR. It might be possible to make the dsl compiler logic smarter (I would need a class source API, like the method_source
gem we rely on for methods) to avoid this. (The initial attempt used a hard-coded list to avoid this, which I also don't like.)
I think that tapioca should maybe not create rbi files when no action is taken in the decorator, so I might try filing an issue upstream first.
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 that tapioca should maybe not create rbi files when no action is taken in the decorator, so I might try filing an issue upstream first.
That's what I would expect it to do too.
@@ -1,319 +0,0 @@ | |||
# typed: false |
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.
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.
Code looks good and it's great that we don't have to exclude and/or create by hand as many RBI files anymore. I left a bunch of nits but, of course, feel free to ignore them.
# This is an autogenerated file for dynamic methods in `RuboCop::Cop::FormulaAudit::AssertStatements`. | ||
# Please instead update this file by running `bin/tapioca dsl RuboCop::Cop::FormulaAudit::AssertStatements`. | ||
|
||
class RuboCop::Cop::FormulaAudit::AssertStatements; end |
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 that tapioca should maybe not create rbi files when no action is taken in the decorator, so I might try filing an issue upstream first.
That's what I would expect it to do too.
if source.start_with?("def_node_matcher") | ||
# https://github.com/Shopify/tapioca/blob/3341a9b/lib/tapioca/rbi_ext/model.rb#L89 | ||
klass.create_method( | ||
method_name.to_s, | ||
parameters: [ | ||
create_rest_param("node", type: "RuboCop::AST::Node"), | ||
create_kw_rest_param("kwargs", type: "T.untyped"), | ||
create_block_param("block", type: "T.untyped"), | ||
], | ||
return_type: "T.untyped", | ||
) | ||
elsif source.start_with?("def_node_search") | ||
klass.create_method( | ||
method_name.to_s, | ||
parameters: [ | ||
create_rest_param("node", type: "T.untyped"), | ||
create_block_param("block", type: "T.untyped"), | ||
], | ||
return_type: method_name.to_s.end_with?("?") ? "T::Boolean" : "T.untyped", | ||
) | ||
end |
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.
if source.start_with?("def_node_matcher") | |
# https://github.com/Shopify/tapioca/blob/3341a9b/lib/tapioca/rbi_ext/model.rb#L89 | |
klass.create_method( | |
method_name.to_s, | |
parameters: [ | |
create_rest_param("node", type: "RuboCop::AST::Node"), | |
create_kw_rest_param("kwargs", type: "T.untyped"), | |
create_block_param("block", type: "T.untyped"), | |
], | |
return_type: "T.untyped", | |
) | |
elsif source.start_with?("def_node_search") | |
klass.create_method( | |
method_name.to_s, | |
parameters: [ | |
create_rest_param("node", type: "T.untyped"), | |
create_block_param("block", type: "T.untyped"), | |
], | |
return_type: method_name.to_s.end_with?("?") ? "T::Boolean" : "T.untyped", | |
) | |
end | |
case source | |
when /^def_node_matcher/ | |
# https://github.com/Shopify/tapioca/blob/3341a9b/lib/tapioca/rbi_ext/model.rb#L89 | |
klass.create_method( | |
method_name.to_s, | |
parameters: [ | |
create_rest_param("node", type: "RuboCop::AST::Node"), | |
create_kw_rest_param("kwargs", type: "T.untyped"), | |
create_block_param("block", type: "T.untyped"), | |
], | |
return_type: "T.untyped", | |
) | |
when /^def_node_search/ | |
klass.create_method( | |
method_name.to_s, | |
parameters: [ | |
create_rest_param("node", type: "T.untyped"), | |
create_block_param("block", type: "T.untyped"), | |
], | |
return_type: method_name.to_s.end_with?("?") ? "T::Boolean" : "T.untyped", | |
) | |
end |
Nit: Use a case statement here for readability.
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 version without regexes is more readable IMO, but sure 😛
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.
Yeah, either way. It's personal preference I guess.
@@ -192,7 +192,7 @@ def depends_on(spec) | |||
def uses_from_macos(deps, bounds = {}) | |||
if deps.is_a?(Hash) | |||
bounds = deps.dup | |||
deps = [bounds.shift].to_h | |||
deps = [T.unsafe(bounds).shift].to_h |
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.
Can we just add a sig
here instead?
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.
LMK if you have ideas, but i think it gets gnarly with type parameters and union types (and I think it would need to be in an rbi file due to the former). I think it's something I'd prefer to leave to a future PR (I'm thinking of doing a sweep over the T.unsafe call sites at some point anyway).
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 you can use multiple sig
s.
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.
sig { params(deps: String, bounds: T::Hash[String, T.any(Symbol, T::Array[Symbol])]).void }
sig { params(deps: T::Hash[String, T.any(Symbol, T::Array[Symbol])]).void }
def uses_from_macos(deps, bounds = {})
Actually, I think we don't even need the bounds
parameter:
sig { params(deps: T.any(String, T::Hash[String, T.any(Symbol, T::Array[Symbol])])).void }
def uses_from_macos(deps)
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.
Overloading a method (by providing multiple signatures for the method) is only allowed for methods defined in the Ruby standard library.
Also, all params must be present in a sig
.
(As a favor to the PR author, it would be appreciated to validate suggested changes before publishing them. Again, I also worry that there is excessive focus on this line, given the scope of this PR, and it may be better to refine in a future PR.)
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.
As a favor to the PR author, it would be appreciated to validate suggested changes before publishing them.
I usually do, however I reviewed this on mobile.
de332d8
to
d122fdd
Compare
ed48801
to
9d7cdc0
Compare
9d7cdc0
to
6e6f590
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.
Looks good. Feel free to ignore uses_from_macos
in favour of handling this in a future PR.
klass.create_method( | ||
method_name.to_s, | ||
parameters: [ | ||
create_rest_param("node", type: "T.untyped"), |
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.
Is there a reason this node is untyped but def_node_matcher
's isn't?
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.
Thanks for the nudge here, I was able to tighten up the types in both branches in 439c8c18
6e6f590
to
439c8c1
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.
Makes sense to me so far!
brew style
with your changes locally?brew typecheck
with your changes locally?brew tests
with your changes locally?Resolves #16557:
This also reduces the time to run
brew typecheck --update-all
by > 30% (5m7s → 3m31s on an M1 Pro, n=4)