Project

General

Profile

Feature #21998

Updated by Eregon (Benoit Daloze) 3 months ago

I'm using matz's suggestion almost as-is from https://bugs.ruby-lang.org/issues/6012#note-53. 
 The only change is the proposed class name. 

 ## Use Cases 

 My main motivation here is to be able to implement `Prism.find(Method|UnboundMethod|Proc)` precisely and cleanly on any Ruby implementation, in a way which does not depend on implementation details like `node_id`. 
 For that we need the start/end line/column and the `absolute_path`, which is exactly what `Ruby::SourceRange` provides. 

 Use cases have been discussed extensively in https://bugs.ruby-lang.org/issues/6012#note-53 and matz said: 
 > The use cases are real and I want to support them 

 So I think we don't need to discuss that anymore :) 

 ## Background 

 Adding column and last line information to `#source_location` is deemed too incompatible given the usages of `obj.source_location.last` which expect the start line (they would get the end column instead). 

 ## Proposal 

 So instead we add a new method, `{Method,UnboundMethod,Proc}#source_range`, 
 which returns a `Ruby::SourceRange` and has these methods: 
 * `start_line`: 1-indexed (same as `source_location.first`) 
 * `end_line`: 1-indexed 
 * `start_column`: in bytes, 0-indexed, I think `start_byte_column` could be good for extra clarity 
 * `end_column`: in bytes, 0-indexed, I think `end_byte_column` could be good for extra clarity 
 * `inspect` which shows something like `#<Ruby::SourceRange (1,0)-(2,10)>`. 

 For the edge case of a heredoc spanning further than the end of a method/block, we would not include it in the `end_line` & `end_column` methods, but instead document it and provide a small code snippet in the docs to compute that if desired with Prism. 

 ## Alternative 

 An alternative could be a `Ruby::SourceLocation` class and `obj.source_location(object: true)`/`obj.source_location(extended: true)` but it feels less nice. Since we are designing something new I think it's best to go for the cleanest design. 

 ## Consistency 

 The above methods match the name of methods on `Prism::Node` and have the same semantics, which is good for consistency and to avoid confusion. 

 ## Scope 

 The scope is intentionally minimal to keep the discussion focused. 

 ## Implementation 

 I'm happy to implement this, it should be pretty trivial and very similar to the extended `source_location`. 
 I would prefer to get an approval for this feature before implementing.

Back