Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect nodes end location for some nodes #381

Open
Morriar opened this issue Jun 1, 2023 · 1 comment
Open

Incorrect nodes end location for some nodes #381

Morriar opened this issue Jun 1, 2023 · 1 comment

Comments

@Morriar
Copy link
Contributor

Morriar commented Jun 1, 2023

Looking at this simple snippet:

class Foo
end

It seems the end column location is incorrect for a few nodes:

SyntaxTree::Program: 1:0-2:0 # should it be 1:0-2:3?
SyntaxTree::Statements: 1:0-2:0 # should it be 1:0-2:3?
SyntaxTree::ClassDeclaration: 1:0-2:3
SyntaxTree::ConstRef: 1:6-1:9
SyntaxTree::Const: 1:6-1:9
SyntaxTree::BodyStmt: 1:9-1:0 # should it be 1:9-2:0?
SyntaxTree::Statements: 1:9-1:0 # should it be 1:9-2:0?
SyntaxTree::VoidStmt: 1:9-1:0 # should it be 1:9-1:9?
@etiennebarrie
Copy link
Contributor

I'm seeing similar weird behavior regarding locations around rescue/else.

Here's a snippet that shows location ranges on a line, with some examples (all the whitespace is added so that char_pos is a multiple of 10 when on_stmts_new and on_stmts_add is called by Ripper):

require "bundler/setup"
require "syntax_tree"

def loc(node, comment = nil)
  location = node.location
  puts " " * (location.start_char - 0).clamp(0..) +
    "^" +
    "-" * (location.end_char - location.start_char - 2).clamp(0..) +
    "^" * (location.end_char - location.start_char - 1).clamp(0..1) +
    " " * (70 - location.end_char - (location.end_char > location.start_char ? 0 : 1)).clamp(0..) +
    "#{node.class} #{comment}"
end

def locations(code)
  code
    .tap { puts _1 }
    .then { SyntaxTree.parse _1 }
    .then { _1.statements.body.first }
    .tap { loc _1 }
    .then { _1.bodystmt }
    .tap { loc _1 }
    .tap { loc _1.rescue_clause }
    .tap { loc _1.rescue_clause.statements, "rescue statements" }
    .tap { loc _1.else_clause, "else clause" if _1.else_clause }
    .tap { loc _1.ensure_clause }
end

locations("begin    ; rescue;                          ensure         ; end     ;")
puts
locations("begin    ; rescue       ; else         ;      ensure       ; end     ;")

This outputs:

begin    ; rescue;                          ensure         ; end     ;
^--------------------------------------------------------------^      SyntaxTree::Begin 
     ^---------------------------------------------------------^      SyntaxTree::BodyStmt 
           ^-------------------------------^                          SyntaxTree::Rescue 
                 ^-------------------------^                          SyntaxTree::Statements rescue statements
                                            ^------------------^      SyntaxTree::Ensure 

which looks pretty much correct
and

begin    ; rescue       ; else         ;      ensure       ; end     ;
^--------------------------------------------------------------^      SyntaxTree::Begin 
     ^---------------------------------------------------------^      SyntaxTree::BodyStmt 
           ^---------------------------^                              SyntaxTree::Rescue 
                 ^---------------------^                              SyntaxTree::Statements rescue statements
                                        ^                             SyntaxTree::Statements else clause
                                              ^----------------^      SyntaxTree::Ensure 

which shows that something's wrong about the rescue statements and the else clause.

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

No branches or pull requests

2 participants