-
Couldn't load subscription status.
- Fork 172
Description
There's currently no easy way to get the location of the = in an "attribute write" like:
self.attr_name = :value
# ^Notice that the PM_CALL_NODE's name has the = (name: :attr_name=), but the message_loc only spans the message (message_loc: (1,5)-(1,14) = "attr_name"):
Example Prism AST
> Prism.parse("self.attr_name = :value").value
@ ProgramNode (location: (1,0)-(1,23))
├── flags: ∅
├── locals: []
└── statements:
@ StatementsNode (location: (1,0)-(1,23))
├── flags: ∅
└── body: (length: 1)
└── @ CallNode (location: (1,0)-(1,23))
├── flags: newline, attribute_write, ignore_visibility
├── receiver:
│ @ SelfNode (location: (1,0)-(1,4))
│ └── flags: ∅
├── call_operator_loc: (1,4)-(1,5) = "."
├── name: :attr_name=
├── message_loc: (1,5)-(1,14) = "attr_name"
├── opening_loc: ∅
├── arguments:
│ @ ArgumentsNode (location: (1,17)-(1,23))
│ ├── flags: ∅
│ └── arguments: (length: 1)
│ └── @ SymbolNode (location: (1,17)-(1,23))
│ ├── flags: static_literal, forced_us_ascii_encoding
│ ├── opening_loc: (1,17)-(1,18) = ":"
│ ├── value_loc: (1,18)-(1,23) = "value"
│ ├── closing_loc: ∅
│ └── unescaped: "value"
├── closing_loc: ∅
└── block: ∅I ran into this while fixing a bug in Sorbet (PR). Sorbet's pipeline needs me to provide a location that spans the whole method name up to (and including) the = (including any amount of possible whitespace in between), like so:
self.attr_name = :value
# ^^^^^^^^^^^The closest thing I could do is start at the end of the message_loc, and scan right until hitting the next =. This works, but it would be nicer to get the value from Prism.
@jez suggests that we could repurpose the opening_loc field, which would otherwise always be null for "attribute write" cases like this.
We'd be happy to implement this, if the approach sounds good. Thoughts?