From 403540b3cae101c510166297e87b703c9b5a754d Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Sun, 10 Feb 2019 21:02:16 +0200 Subject: [PATCH] slightly better messages for unsupported ruby Very slightly unfortunately, just just enought to find the error. Also testing what is unsupported, so it's documented. --- lib/ruby/ruby_compiler.rb | 37 ++++++++++++++++++++++++------- test/ruby/test_basic_values.rb | 4 ++-- test/ruby/test_not_implemented.rb | 20 +++++++++++++++++ test/ruby/test_variables.rb | 3 --- 4 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 test/ruby/test_not_implemented.rb diff --git a/lib/ruby/ruby_compiler.rb b/lib/ruby/ruby_compiler.rb index f839fee6..f352aa32 100644 --- a/lib/ruby/ruby_compiler.rb +++ b/lib/ruby/ruby_compiler.rb @@ -1,4 +1,19 @@ module Ruby + class ProcessError < Exception + attr_reader :node + + def initialize(msg , node) + super(msg) + @node = node + end + def message + super + node_tos + end + def node_tos + return "" unless @node + @node.to_s[0 ... 200] + end + end # This RubyCompiler compiles incoming ruby (string) into a typed # version of theast, with the help of the parser gem. # The parser outputs an abstract ast (nodes) @@ -10,16 +25,22 @@ module Ruby # simpler, and then finally to compile # to the next level down, MOM (Minimal Object Machine) class RubyCompiler < AST::Processor - include AST::Sexp + include AST::Sexp def self.compile(input) ast = Parser::Ruby22.parse( input ) self.new.process(ast) end + # raise a ProcessError. This means ruby-x doesn't know how to handle it. + # Parser itself throws SyntaxError + def not_implemented(node) + raise ProcessError.new("Not implemented #{node.type}", node) + end + # default to error, so non implemented stuff shows early def handler_missing(node) - raise "Not implemented #{node.type} #{node}" + not_implemented(node) end def on_class( statement ) @@ -83,8 +104,8 @@ module Ruby end alias :on_string :on_str - def on_dstr expression - raise "Not implemented dynamic strings (with interpolation)" + def on_dstr( expression ) + not_implemented(expression) end alias :on_xstr :on_dstr @@ -93,8 +114,8 @@ module Ruby end alias :on_string :on_str - def on_dsym - raise "Not implemented dynamix symbols (with interpolation)" + def on_dsym(expression) + not_implemented(expression) end def on_kwbegin statement ScopeStatement.new process_all( statement.children ) @@ -131,7 +152,7 @@ module Ruby def on_const expression scope = expression.children.first if scope - raise "Only unscoped Names implemented #{scope}" unless scope.type == :cbase + not_implemented(expression) unless scope.type == :cbase end ModuleName.new(expression.children[1]) end @@ -213,7 +234,7 @@ module Ruby end def handler_missing(node) - raise "Handler missing #{node}" + not_implemented(node) end private diff --git a/test/ruby/test_basic_values.rb b/test/ruby/test_basic_values.rb index b5b2c8d3..398321a7 100644 --- a/test/ruby/test_basic_values.rb +++ b/test/ruby/test_basic_values.rb @@ -33,8 +33,8 @@ module Ruby assert_equal SymbolConstant , lst.class , lst.inspect end def test_dstr - assert_raises RuntimeError do - compile( '"dstr#{self}"') + assert_raises Ruby::ProcessError do + compile( '"interpolate #{self}"') end end diff --git a/test/ruby/test_not_implemented.rb b/test/ruby/test_not_implemented.rb new file mode 100644 index 00000000..7dac9b0c --- /dev/null +++ b/test/ruby/test_not_implemented.rb @@ -0,0 +1,20 @@ +require_relative "helper" + +module Ruby + class NotImplemented < Minitest::Test + include RubyTests + + def assert_handler_missing(input) + assert_raises(Ruby::ProcessError){ compile(input) } + end + + def test_module + assert_handler_missing "module Name ; end" + end + + def test_module_module_scoped + assert_handler_missing( "M::Module" ) + end + + end +end diff --git a/test/ruby/test_variables.rb b/test/ruby/test_variables.rb index 859b5842..754f91c0 100644 --- a/test/ruby/test_variables.rb +++ b/test/ruby/test_variables.rb @@ -51,9 +51,6 @@ module Ruby assert_equal ModuleName , lst.class assert_equal :Module , lst.name end - def test_module_module_scoped - assert_raises {compile( "M::Module" ) } - end end class TestVariablesVool < MiniTest::Test include RubyTests