Skip to content

Conversation

schneems
Copy link
Contributor

@schneems schneems commented Sep 15, 2021

This commit adds the dead_end syntax error display tool to Ruby through the same mechanism as error_highlight and did_you_mean.

What is dead_end?

When a syntax error is raised by requiring a file, dead_end will use a combination of indentation and lexing to identify the problem.

Demo

Generate a file with a syntax error:

$ echo "require_relative 'syntax_error'" > test.rb
$ cat > syntax_error.rb <<EOF
class Dog < Animal
  def sit
    super
  end

  def bark
    puts "woof"

  def happy
    tail.wag
  end
end
EOF

Build and run ruby:

$ make
$ make runruby
generating vm_call_iseq_optimized.inc
vm_call_iseq_optimized.inc unchanged
RUBY_ON_BUG='gdb -x ./.gdbinit -p' ./miniruby -I./lib -I. -I.ext/common  ./tool/runruby.rb --extout=.ext  -- --disable-gems  ./test.rb
Run `$ dead_end /Users/rschneeman/Documents/projects/ruby/syntax_error.rb` for more options

DeadEnd: Missing `end` detected

This code has a missing `end`. Ensure that all
syntax keywords (`def`, `do`, etc.) have a matching `end`.

file: /Users/rschneeman/Documents/projects/ruby/syntax_error.rb
simplified:

       1  class Dog < Animal
    ❯  6    def bark
    ❯  9    def happy
    ❯ 11    end
      12  end



/Users/rschneeman/Documents/projects/ruby/lib/dead_end/auto.rb:30:in `require': /Users/rschneeman/Documents/projects/ruby/syntax_error.rb:12: syntax error, unexpected end-of-input, expecting `end' (SyntaxError)

Status

This commit is a proof of concept spike (https://en.wikipedia.org/wiki/Spike_(software_development)). If core likes this approach, then I can refine and improve it.

Known issues

  • This implementation did not wire up any code that updates the vendored gem version from the source. It would be not difficult to add https://github.com/ruby/ruby/blob/41867532ac07515543e4d7e75094edeff09de743/tool/sync_default_gems.rb
  • This implementation does not add dead_end as a feature to be enabled yet:

    ruby/ruby.c

    Line 97 in cb4e2cb

    X(error_highlight) \
    .
  • DeadEnd's approach of showing syntax errors only works through integration with require, load, autoload, and require_relative (since it monkeypatches them to detect syntax errors). It does not work with direct Ruby file invocations Doesn't work direct from Ruby CLI syntax_suggest#31.
    • We could extend or modify the Ruby API to hook into a better place with guidance and approval.
  • The current release of dead_end also annotates no method errors. I will turn this off in favor of error_highlight gem.

This commit adds the `dead_end` syntax error display tool to Ruby through the same mechanism as `error_highlight` and `did_you_mean`.

## What is dead_end?

When a syntax error is raised by requiring a file, dead_end will use a combination of indentation and lexing to identify the problem.

## Demo

Generate a file with a syntax error:

```
$ echo "require_relative 'syntax_error'" > test.rb
$ cat > syntax_error.rb <<EOF
class Dog < Animal
  def sit
    super
  end

  def bark
    puts "woof"

  def happy
    tail.wag
  end
end
EOF
```

Build and run ruby:

```
$ make
$ make runruby
generating vm_call_iseq_optimized.inc
vm_call_iseq_optimized.inc unchanged
RUBY_ON_BUG='gdb -x ./.gdbinit -p' ./miniruby -I./lib -I. -I.ext/common  ./tool/runruby.rb --extout=.ext  -- --disable-gems  ./test.rb
Run `$ dead_end /Users/rschneeman/Documents/projects/ruby/syntax_error.rb` for more options

DeadEnd: Missing `end` detected

This code has a missing `end`. Ensure that all
syntax keywords (`def`, `do`, etc.) have a matching `end`.

file: /Users/rschneeman/Documents/projects/ruby/syntax_error.rb
simplified:

       1  class Dog < Animal
    ❯  6    def bark
    ❯  9    def happy
    ❯ 11    end
      12  end



/Users/rschneeman/Documents/projects/ruby/lib/dead_end/auto.rb:30:in `require': /Users/rschneeman/Documents/projects/ruby/syntax_error.rb:12: syntax error, unexpected end-of-input, expecting `end' (SyntaxError)
```

## Status

This commit is a proof of concept spike (https://en.wikipedia.org/wiki/Spike_(software_development)). If core likes this approach, then I can refine and improve it.

## Known issues

- This implementation did not wire up any code that updates the vendored gem version from the source. It would be not difficult to add https://github.com/ruby/ruby/blob/41867532ac07515543e4d7e75094edeff09de743/tool/sync_default_gems.rb
- This implementation does not add `dead_end` as a feature to be enabled yet: https://github.com/ruby/ruby/blob/cb4e2cb55a59833fc4f1f6db2f3082d1ffcafc80/ruby.c#L97.
- DeadEnd's approach of showing syntax errors only works through integration with `require`, `load`, `autoload`, and `require_relative` (since it monkeypatches them to detect syntax errors). It does not work with direct Ruby file invocations ruby/syntax_suggest#31.
  - We could extend or modify the Ruby API to hook into a better place with guidance and approval.
schneems added a commit to schneems/ruby that referenced this pull request Apr 28, 2022
Adds the `dead_end` syntax error display tool to Ruby through the same mechanism as `error_highlight` and `did_you_mean`. Reference ticket: https://bugs.ruby-lang.org/issues/18159

close ruby#4845

## What is dead_end?

When a syntax error is raised by requiring a file, dead_end will use a combination of indentation and lexing to identify the problem.

## Demo

Generate a file with a syntax error:

```
$ echo "require_relative 'syntax_error'" > test.rb
$ cat > syntax_error.rb <<EOF
class Dog < Animal
  def sit
    super
  end

  def bark
    puts "woof"

  def happy
    tail.wag
  end
end
EOF
```

## Known issues

- DeadEnd's approach of showing syntax errors only works through integration with `require`, `load`, `autoload`, and `require_relative` (since it monkeypatches them to detect syntax errors). It does not work with direct Ruby file invocations ruby/syntax_suggest#31.
  - We could extend or modify the Ruby API to hook into a better place with guidance and approval.
schneems added a commit to schneems/ruby that referenced this pull request Apr 28, 2022
Adds the `dead_end` syntax error display tool to Ruby through the same mechanism as `error_highlight` and `did_you_mean`. Reference ticket: https://bugs.ruby-lang.org/issues/18159

close ruby#4845

## What is dead_end?

When a syntax error is raised by requiring a file, dead_end will use a combination of indentation and lexing to identify the problem.

## Demo

Generate a file with a syntax error:

```
$ echo "require_relative 'syntax_error'" > test.rb
$ cat > syntax_error.rb <<EOF
class Dog < Animal
  def sit
    super
  end

  def bark
    puts "woof"

  def happy
    tail.wag
  end
end
EOF
```

## Known issues

- DeadEnd's approach of showing syntax errors only works through integration with `require`, `load`, `autoload`, and `require_relative` (since it monkeypatches them to detect syntax errors). It does not work with direct Ruby file invocations ruby/syntax_suggest#31.
  - We could extend or modify the Ruby API to hook into a better place with guidance and approval.
schneems added a commit to schneems/ruby that referenced this pull request Apr 28, 2022
Adds the `dead_end` syntax error display tool to Ruby through the same mechanism as `error_highlight` and `did_you_mean`.

close ruby#4845

## What is dead_end?

When a syntax error is raised by requiring a file, dead_end will use a combination of indentation and lexing to identify the problem.

## Demo

Generate a file with a syntax error:

```
$ echo "require_relative 'syntax_error'" > test.rb
$ cat > syntax_error.rb <<EOF
class Dog < Animal
  def sit
    super
  end

  def bark
    puts "woof"

  def happy
    tail.wag
  end
end
EOF
```

Build and run ruby:

```
$ make
$ make runruby
generating vm_call_iseq_optimized.inc
vm_call_iseq_optimized.inc unchanged
RUBY_ON_BUG='gdb -x ./.gdbinit -p' ./miniruby -I./lib -I. -I.ext/common  ./tool/runruby.rb --extout=.ext  -- --disable-gems  ./test.rb
Run `$ dead_end /Users/rschneeman/Documents/projects/ruby/syntax_error.rb` for more options

DeadEnd: Missing `end` detected

This code has a missing `end`. Ensure that all
syntax keywords (`def`, `do`, etc.) have a matching `end`.

file: /Users/rschneeman/Documents/projects/ruby/syntax_error.rb
simplified:

       1  class Dog < Animal
    ❯  6    def bark
    ❯  9    def happy
    ❯ 11    end
      12  end

/Users/rschneeman/Documents/projects/ruby/lib/dead_end/auto.rb:30:in `require': /Users/rschneeman/Documents/projects/ruby/syntax_error.rb:12: syntax error, unexpected end-of-input, expecting `end' (SyntaxError)
```

## Known issues

- DeadEnd's approach of showing syntax errors only works through integration with `require`, `load`, `autoload`, and `require_relative` (since it monkeypatches them to detect syntax errors). It does not work with direct Ruby file invocations ruby/syntax_suggest#31.
  - We could extend or modify the Ruby API to hook into a better place with guidance and approval.
@schneems
Copy link
Contributor Author

I've opened a non-spike PR #5859

@schneems schneems closed this Apr 28, 2022
schneems added a commit to schneems/ruby that referenced this pull request May 23, 2022
Adds the `dead_end` syntax error display tool to Ruby through the same mechanism as `error_highlight` and `did_you_mean`.

close ruby#4845

## What is dead_end?

When a syntax error is raised by requiring a file, dead_end will use a combination of indentation and lexing to identify the problem.

## Demo

Generate a file with a syntax error:

```
$ echo "require_relative 'syntax_error'" > test.rb
$ cat > syntax_error.rb <<EOF
class Dog < Animal
  def sit
    super
  end

  def bark
    puts "woof"

  def happy
    tail.wag
  end
end
EOF
```

Build and run ruby:

```
$ make
$ make runruby
generating vm_call_iseq_optimized.inc
vm_call_iseq_optimized.inc unchanged
RUBY_ON_BUG='gdb -x ./.gdbinit -p' ./miniruby -I./lib -I. -I.ext/common  ./tool/runruby.rb --extout=.ext  -- --disable-gems  ./test.rb
Run `$ dead_end /Users/rschneeman/Documents/projects/ruby/syntax_error.rb` for more options

DeadEnd: Missing `end` detected

This code has a missing `end`. Ensure that all
syntax keywords (`def`, `do`, etc.) have a matching `end`.

file: /Users/rschneeman/Documents/projects/ruby/syntax_error.rb
simplified:

       1  class Dog < Animal
    ❯  6    def bark
    ❯  9    def happy
    ❯ 11    end
      12  end

/Users/rschneeman/Documents/projects/ruby/lib/dead_end/auto.rb:30:in `require': /Users/rschneeman/Documents/projects/ruby/syntax_error.rb:12: syntax error, unexpected end-of-input, expecting `end' (SyntaxError)
```

## Known issues

- DeadEnd's approach of showing syntax errors only works through integration with `require`, `load`, `autoload`, and `require_relative` (since it monkeypatches them to detect syntax errors). It does not work with direct Ruby file invocations ruby/syntax_suggest#31.
  - We could extend or modify the Ruby API to hook into a better place with guidance and approval.
schneems added a commit to schneems/ruby that referenced this pull request May 24, 2022
Adds the `dead_end` syntax error display tool to Ruby through the same mechanism as `error_highlight` and `did_you_mean`.

close ruby#4845

## What is dead_end?

When a syntax error is raised by requiring a file, dead_end will use a combination of indentation and lexing to identify the problem.

## Demo

Generate a file with a syntax error:

```
$ echo "require_relative 'syntax_error'" > test.rb
$ cat > syntax_error.rb <<EOF
class Dog < Animal
  def sit
    super
  end

  def bark
    puts "woof"

  def happy
    tail.wag
  end
end
EOF
```

Build and run ruby:

```
$ make
$ make runruby
generating vm_call_iseq_optimized.inc
vm_call_iseq_optimized.inc unchanged
RUBY_ON_BUG='gdb -x ./.gdbinit -p' ./miniruby -I./lib -I. -I.ext/common  ./tool/runruby.rb --extout=.ext  -- --disable-gems  ./test.rb
Run `$ dead_end /Users/rschneeman/Documents/projects/ruby/syntax_error.rb` for more options

DeadEnd: Missing `end` detected

This code has a missing `end`. Ensure that all
syntax keywords (`def`, `do`, etc.) have a matching `end`.

file: /Users/rschneeman/Documents/projects/ruby/syntax_error.rb
simplified:

       1  class Dog < Animal
    ❯  6    def bark
    ❯  9    def happy
    ❯ 11    end
      12  end

/Users/rschneeman/Documents/projects/ruby/lib/dead_end/auto.rb:30:in `require': /Users/rschneeman/Documents/projects/ruby/syntax_error.rb:12: syntax error, unexpected end-of-input, expecting `end' (SyntaxError)
```

## Known issues

- DeadEnd's approach of showing syntax errors only works through integration with `require`, `load`, `autoload`, and `require_relative` (since it monkeypatches them to detect syntax errors). It does not work with direct Ruby file invocations ruby/syntax_suggest#31.
  - We could extend or modify the Ruby API to hook into a better place with guidance and approval.
schneems added a commit to schneems/ruby that referenced this pull request Jun 4, 2022
Adds the `dead_end` syntax error display tool to Ruby through the same mechanism as `error_highlight` and `did_you_mean`.

close ruby#4845

## What is dead_end?

When a syntax error is raised by requiring a file, dead_end will use a combination of indentation and lexing to identify the problem.

## Demo

Generate a file with a syntax error:

```
$ echo "require_relative 'syntax_error'" > test.rb
$ cat > syntax_error.rb <<EOF
class Dog < Animal
  def sit
    super
  end

  def bark
    puts "woof"

  def happy
    tail.wag
  end
end
EOF
```

Build and run ruby:

```
$ make
$ make runruby
generating vm_call_iseq_optimized.inc
vm_call_iseq_optimized.inc unchanged
RUBY_ON_BUG='gdb -x ./.gdbinit -p' ./miniruby -I./lib -I. -I.ext/common  ./tool/runruby.rb --extout=.ext  -- --disable-gems  ./test.rb
Run `$ dead_end /Users/rschneeman/Documents/projects/ruby/syntax_error.rb` for more options

DeadEnd: Missing `end` detected

This code has a missing `end`. Ensure that all
syntax keywords (`def`, `do`, etc.) have a matching `end`.

file: /Users/rschneeman/Documents/projects/ruby/syntax_error.rb
simplified:

       1  class Dog < Animal
    ❯  6    def bark
    ❯  9    def happy
    ❯ 11    end
      12  end

/Users/rschneeman/Documents/projects/ruby/lib/dead_end/auto.rb:30:in `require': /Users/rschneeman/Documents/projects/ruby/syntax_error.rb:12: syntax error, unexpected end-of-input, expecting `end' (SyntaxError)
```

## Known issues

- DeadEnd's approach of showing syntax errors only works through integration with `require`, `load`, `autoload`, and `require_relative` (since it monkeypatches them to detect syntax errors). It does not work with direct Ruby file invocations ruby/syntax_suggest#31.
  - We could extend or modify the Ruby API to hook into a better place with guidance and approval.
schneems added a commit to schneems/ruby that referenced this pull request Jul 27, 2022
Adds the `syntax_suggest` syntax error display tool to Ruby through the same mechanism as `error_highlight` and `did_you_mean`. Reference ticket: https://bugs.ruby-lang.org/issues/18159

close ruby#4845

## What is syntax_suggest?

When a syntax error is raised by requiring a file, dead_end will use a combination of indentation and lexing to identify the problem.

> Note: Previously this tool was named `dead_end`. 

## Known issues

- SyntaxSearch's approach of showing syntax errors only works through integration with `require`, `load`, `autoload`, and `require_relative` (since it monkeypatches them to detect syntax errors). It does not work with direct Ruby file invocations ruby/syntax_suggest#31.
  - This causes failure in the test suite (test_expected_backtrace_location_when_inheriting_from_basic_object_and_including_kernel) and confusion when inspecting backtraces if there's a different error when trying to require a file such as measuring memory (ruby/syntax_suggest#124 (comment)).
  - Discussed fix. We previously talked about opening up `SyntaxError` to be monkeypatched in the same way that other gems hook into `NoMethodError`. This is currently not possible and requires development work. When we last talked about it at RubyKaigi Nobu expressed an ability to make such a change.
hsbt pushed a commit that referenced this pull request Aug 19, 2022
Adds the `syntax_suggest` syntax error display tool to Ruby through the same mechanism as `error_highlight` and `did_you_mean`. Reference ticket: https://bugs.ruby-lang.org/issues/18159

close #4845

## What is syntax_suggest?

When a syntax error is raised by requiring a file, dead_end will use a combination of indentation and lexing to identify the problem.

> Note: Previously this tool was named `dead_end`. 

## Known issues

- SyntaxSearch's approach of showing syntax errors only works through integration with `require`, `load`, `autoload`, and `require_relative` (since it monkeypatches them to detect syntax errors). It does not work with direct Ruby file invocations ruby/syntax_suggest#31.
  - This causes failure in the test suite (test_expected_backtrace_location_when_inheriting_from_basic_object_and_including_kernel) and confusion when inspecting backtraces if there's a different error when trying to require a file such as measuring memory (ruby/syntax_suggest#124 (comment)).
  - Discussed fix. We previously talked about opening up `SyntaxError` to be monkeypatched in the same way that other gems hook into `NoMethodError`. This is currently not possible and requires development work. When we last talked about it at RubyKaigi Nobu expressed an ability to make such a change.
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.

1 participant