Highlight private/protected/public as methods - #8
Merged
Conversation
`private`, `protected` and `public` are `Module` instance methods, not keywords. They take arguments (`private :foo`), accept a `def` expression (`private def foo; end`), can be reached through `send`, and can be shadowed by a local variable. Highlighting them as `@keyword` made them read like `def` or `end` and diverged from how RubyMine and Ruby LSP render them. Capture them as `@function.method.builtin`, matching how this query already treats other well-known method calls such as `require` and `defined?`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
queries/highlights.scmgroupedprivate,protectedandpublicinto the same bracketed list asdef,end,classandmodule, giving them@keyword— the identical capture real keywords get.They are not keywords. They are
Moduleinstance methods:Consequences of being ordinary methods, all of which the
@keywordcapture contradicted:Change
Captures all three as
@function.method.builtin, in two patterns:privateparses as a plainidentifier, so it needs an identifier pattern. That pattern carries#is-not? local, which is what keeps a shadowing local variable out — the query file already uses the same guard on the general@function.methodidentifier pattern directly above it.call, which the general(call method: (identifier) @function.method)pattern already claims. Later patterns win, so covering them takes a second pattern placed after it.!receiverkeeps an unrelated method with a colliding name, such asacl.public, an ordinary call.@function.method.builtinis the capture this query already uses forrequire, and therequirepattern is placed after the general call pattern for exactly the same precedence reason. (defined?also uses it, though that one is Ruby syntax rather than a method call.)Validation
332 corpus parses and 5 highlight files, zero failures.
test/highlight/classes.rbgoes from 14 to 19 assertions:private(bare)function.method.builtinprivate :with_symbolfunction.method.builtinprivate def with_def; endfunction.method.builtinprivate = 1and a later bareprivatevariableacl.publicfunction.methodThe three previously existing bare-form assertions changed from
keywordtofunction.method.builtin. Each new assertion was confirmed to fail without the corresponding pattern — dropping#is-not? localproducesexpected highlight 'variable', actual highlights: 'function.method.builtin'.Relationship to tree-sitter#277
Same three identifiers, same file. That PR proposed
@function.builtin; this uses@function.method.builtinto match the existingrequirecapture, and additionally handles the argument forms and local shadowing, which tree-sitter#277 does not.Note that on
mastera shadowing local was already mis-highlighted, askeyword. That part is a pre-existing bug this PR fixes rather than a regression it introduces.