Support blocks with implicit parameters (_1, it) and backtick commands - #1320
Draft
apiology wants to merge 4 commits into
Draft
Support blocks with implicit parameters (_1, it) and backtick commands#1320apiology wants to merge 4 commits into
apiology wants to merge 4 commits into
Conversation
`xs.any? { x.include?(_1) }` failed to typecheck while the identical
`xs.any? { |s| x.include?(s) }` was clean, and `xs.map { _1.upcase }`
inferred `Enumerator<undefined, Array>` instead of `Array<String>`.
The `parser` gem emits `numblock` rather than `block` for a block that
uses numbered parameters. `:numblock` was not registered with
`Solargraph::Parser::NodeProcessor` and was not recognized anywhere that
tests for `:block`, so no `Pin::Block` was created, the call was chained
as if it had no block, and `_1` resolved to nothing.
- Register `:numblock` with `BlockNode`, which now synthesizes `_1.._N`
parameter pins from the node's numbered-parameter count (a numblock
stores that Integer where a block stores its args node).
- Recognize `:numblock` alongside `:block` in `NodeChainer#generate_links`
and `#passed_block`, in `NodeMethods.call_nodes_from`, in
`DeepInference::FUNCTION_VALUE` and its two open-coded `:block` checks,
and in `TypeChecker#call_problems`.
`it` / `itblock` is a separate node type and is not covered here.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015AsvDi68YqsKoBtS2kg9ch
`xs.map { it.upcase }` reported `Unresolved call to it` while
`xs.map { |s| s.upcase }` was clean, and `@return [Array<Integer>]` on
`xs.map { it }` was accepted where the explicit-parameter form is
correctly rejected.
Prism translates an `it` block into an ordinary :block node with an empty
args node, so nothing on the node records the parameter and ArgsNode has
nothing to build from. The only signal is an `it` local variable
reference in the body, so BlockNode scans for one and synthesizes the
parameter when it finds it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015AsvDi68YqsKoBtS2kg9ch
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015AsvDi68YqsKoBtS2kg9ch
`\`echo hi\`.strip` reported "Unresolved call to strip", and any method returning a backtick result reported "return type could not be inferred". `infer_literal_node_type` had cases for `str` and `dstr` but none for `xstr`, so `NodeChainer#generate_links` fell through to its else branch and pushed a bare `Chain::Link` with no type. Adding `xstr` to the existing String group covers both the literal and interpolated forms, which parse to the same node type and differ only in the xstr's children. The considered alternative was to model an xstr as a send to Kernel#`, which is typed `(String) -> String` in RBS. Not taken: `dstr` is the controlling precedent, since it is also interpolated and also typed as a literal rather than as a call, and every other entry in this method is a node-type-to-class mapping. Routing one node type through call resolution would make it the only exception. This removes the need for the `@sg-ignore Need backtick support` comment and its accompanying manual `@type [String]` in solargraph.gemspec, which typecheck now reports as an unneeded @sg-ignore comment.
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.
Three block and literal forms have no type at
--level strong, so calls onthem are unresolved and enclosing methods lose their return type.
All are clean in explicit form. A wrong tag also passes silently on the
implicit block form:
@return [Array<Integer>]on'a,b'.split(',').map { it }reports nothing._1produces anumblocknode, so the call was chained as though no blockwere passed.
itarrives as an ordinary block missing only its parameter —hence the silent pass. Backticks produce an
xstrnode, absent from theliteral type table. Neither block form records parameters as an args node
does, so both are synthesized; a local named
itstill wins, matching Ruby.This PR was written by Claude Code on behalf of @apiology.