Skip to content

Support array and inline-def arguments to private_class_method#782

Merged
alexcrocha merged 1 commit into
mainfrom
05-04-support_array_and_inline-def_arguments_to_private_class_method
May 8, 2026
Merged

Support array and inline-def arguments to private_class_method#782
alexcrocha merged 1 commit into
mainfrom
05-04-support_array_and_inline-def_arguments_to_private_class_method

Conversation

@alexcrocha
Copy link
Copy Markdown
Contributor

@alexcrocha alexcrocha commented May 5, 2026

Part of #89 and follows #781. With the basic call shape and resolution wired up, this PR extends the indexer to recognize the two other argument shapes Ruby accepts for private_class_method / public_class_method:

class Foo
  def self.a; end
  def self.b; end

  private_class_method [:a, :b]                  # array literal
  private_class_method def self.foo; end         # inline singleton def
end

Both are common in Ruby code and already supported by ruby-lsp. Parity matters because ruby-lsp's indexing is migrating to Rubydex. Without this PR, these forms silently report the wrong visibility downstream.

Inline def synthesizes a visibility def by name

For private_class_method def self.foo; end the indexer extracts the def's name, builds a MethodVisibilityDefinition for it with the singleton flag, then visits the DefNode so the MethodDefinition is indexed normally. At resolution time the visibility def attaches to the resulting declaration through the existing fully-qualified-name lookup, so no new "inline" definition kind and no new resolution arm are needed. The same path handles def self.x nested inside the array form.

A receiverless def (private_class_method [def x; end] or private_class_method def x; end) is a coding error: the def isn't a singleton method, so the call doesn't apply to it. We diagnose specifically (`private_class_method` requires a singleton method definition) and still visit the DefNode so it's indexed.

Sole-arg guard for the array form

private_class_method [:a] works at runtime because Ruby unwraps a sole array argument; private_class_method [:a], :b doesn't. The match arm guards on arg_count == 1 to mirror that. A multi-arg call with an array falls through to a separate arm with a tailored diagnostic (`private_class_method` array argument must be the only argument).

Why attr_* arguments get their own diagnostic

private attr_reader(:foo) works for instance methods because attr_reader returns the names array and private consumes it. private_class_method attr_reader(:foo) doesn't: attr_reader defines instance methods, so the names don't exist on the singleton, and applying class-method visibility to them is meaningless. Common enough confusion to call out specifically rather than collapse into a generic "non-literal argument" message.

Continue past invalid args, in both loops

Inherited from #780 and extended here to array elements: a bad arg or element produces a diagnostic but the loop keeps going. private_class_method [:a, SOME_CONST, :c] indexes :a and :c and diagnoses SOME_CONST. private_class_method [:a], :b diagnoses the array-not-sole-arg case and still indexes :b. IDEs see partial-valid code constantly during editing; halting on the first bad arg would discard intelligence the user can still benefit from.

In this PR

  • accept ArrayNode (sole-arg) with SymbolNode, StringNode, and DefNode elements
  • accept DefNode as a top-level argument; reject receiverless def with a specific diagnostic
  • diagnose attr_* arguments and array-not-sole-arg with tailored messages
  • continue past invalid args in both the outer arg loop and the inner array-element loop, indexing whatever's still valid
  • factor a create_method_visibility_definition_from_name helper so DefNode and Symbol/String paths share definition construction

Copy link
Copy Markdown
Contributor Author

alexcrocha commented May 5, 2026

@alexcrocha alexcrocha force-pushed the 05-04-support_array_and_inline-def_arguments_to_private_class_method branch from d041f67 to e17bd05 Compare May 6, 2026 00:59
@alexcrocha alexcrocha force-pushed the 05-04-resolve_singleton_method_visibility branch from 299b305 to 0196acc Compare May 7, 2026 04:11
@alexcrocha alexcrocha force-pushed the 05-04-support_array_and_inline-def_arguments_to_private_class_method branch 2 times, most recently from cd8c5c3 to 2ba7006 Compare May 7, 2026 04:15
@alexcrocha alexcrocha force-pushed the 05-04-resolve_singleton_method_visibility branch from 0196acc to 4ee8994 Compare May 7, 2026 04:45
@alexcrocha alexcrocha force-pushed the 05-04-support_array_and_inline-def_arguments_to_private_class_method branch from 2ba7006 to 48f55ed Compare May 7, 2026 04:45
@alexcrocha alexcrocha changed the base branch from 05-04-resolve_singleton_method_visibility to graphite-base/782 May 7, 2026 18:15
@alexcrocha alexcrocha force-pushed the graphite-base/782 branch from 4ee8994 to c476601 Compare May 7, 2026 22:45
@alexcrocha alexcrocha force-pushed the 05-04-support_array_and_inline-def_arguments_to_private_class_method branch from 48f55ed to aa3c92e Compare May 7, 2026 22:45
@alexcrocha alexcrocha changed the base branch from graphite-base/782 to main May 7, 2026 22:45
@alexcrocha alexcrocha marked this pull request as ready for review May 7, 2026 23:15
@alexcrocha alexcrocha requested a review from a team as a code owner May 7, 2026 23:15
@alexcrocha alexcrocha self-assigned this May 7, 2026
@alexcrocha alexcrocha force-pushed the 05-04-support_array_and_inline-def_arguments_to_private_class_method branch from aa3c92e to 94e1421 Compare May 8, 2026 00:11
@alexcrocha alexcrocha merged commit 4afbd88 into main May 8, 2026
36 checks passed
@alexcrocha alexcrocha deleted the 05-04-support_array_and_inline-def_arguments_to_private_class_method branch May 8, 2026 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants