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.
This commit is contained in:
parent
d24b6ee153
commit
403540b3ca
@ -1,4 +1,19 @@
|
|||||||
module Ruby
|
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
|
# This RubyCompiler compiles incoming ruby (string) into a typed
|
||||||
# version of theast, with the help of the parser gem.
|
# version of theast, with the help of the parser gem.
|
||||||
# The parser outputs an abstract ast (nodes)
|
# The parser outputs an abstract ast (nodes)
|
||||||
@ -10,16 +25,22 @@ module Ruby
|
|||||||
# simpler, and then finally to compile
|
# simpler, and then finally to compile
|
||||||
# to the next level down, MOM (Minimal Object Machine)
|
# to the next level down, MOM (Minimal Object Machine)
|
||||||
class RubyCompiler < AST::Processor
|
class RubyCompiler < AST::Processor
|
||||||
include AST::Sexp
|
include AST::Sexp
|
||||||
|
|
||||||
def self.compile(input)
|
def self.compile(input)
|
||||||
ast = Parser::Ruby22.parse( input )
|
ast = Parser::Ruby22.parse( input )
|
||||||
self.new.process(ast)
|
self.new.process(ast)
|
||||||
end
|
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
|
# default to error, so non implemented stuff shows early
|
||||||
def handler_missing(node)
|
def handler_missing(node)
|
||||||
raise "Not implemented #{node.type} #{node}"
|
not_implemented(node)
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_class( statement )
|
def on_class( statement )
|
||||||
@ -83,8 +104,8 @@ module Ruby
|
|||||||
end
|
end
|
||||||
alias :on_string :on_str
|
alias :on_string :on_str
|
||||||
|
|
||||||
def on_dstr expression
|
def on_dstr( expression )
|
||||||
raise "Not implemented dynamic strings (with interpolation)"
|
not_implemented(expression)
|
||||||
end
|
end
|
||||||
alias :on_xstr :on_dstr
|
alias :on_xstr :on_dstr
|
||||||
|
|
||||||
@ -93,8 +114,8 @@ module Ruby
|
|||||||
end
|
end
|
||||||
alias :on_string :on_str
|
alias :on_string :on_str
|
||||||
|
|
||||||
def on_dsym
|
def on_dsym(expression)
|
||||||
raise "Not implemented dynamix symbols (with interpolation)"
|
not_implemented(expression)
|
||||||
end
|
end
|
||||||
def on_kwbegin statement
|
def on_kwbegin statement
|
||||||
ScopeStatement.new process_all( statement.children )
|
ScopeStatement.new process_all( statement.children )
|
||||||
@ -131,7 +152,7 @@ module Ruby
|
|||||||
def on_const expression
|
def on_const expression
|
||||||
scope = expression.children.first
|
scope = expression.children.first
|
||||||
if scope
|
if scope
|
||||||
raise "Only unscoped Names implemented #{scope}" unless scope.type == :cbase
|
not_implemented(expression) unless scope.type == :cbase
|
||||||
end
|
end
|
||||||
ModuleName.new(expression.children[1])
|
ModuleName.new(expression.children[1])
|
||||||
end
|
end
|
||||||
@ -213,7 +234,7 @@ module Ruby
|
|||||||
end
|
end
|
||||||
|
|
||||||
def handler_missing(node)
|
def handler_missing(node)
|
||||||
raise "Handler missing #{node}"
|
not_implemented(node)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -33,8 +33,8 @@ module Ruby
|
|||||||
assert_equal SymbolConstant , lst.class , lst.inspect
|
assert_equal SymbolConstant , lst.class , lst.inspect
|
||||||
end
|
end
|
||||||
def test_dstr
|
def test_dstr
|
||||||
assert_raises RuntimeError do
|
assert_raises Ruby::ProcessError do
|
||||||
compile( '"dstr#{self}"')
|
compile( '"interpolate #{self}"')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
20
test/ruby/test_not_implemented.rb
Normal file
20
test/ruby/test_not_implemented.rb
Normal file
@ -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
|
@ -51,9 +51,6 @@ module Ruby
|
|||||||
assert_equal ModuleName , lst.class
|
assert_equal ModuleName , lst.class
|
||||||
assert_equal :Module , lst.name
|
assert_equal :Module , lst.name
|
||||||
end
|
end
|
||||||
def test_module_module_scoped
|
|
||||||
assert_raises {compile( "M::Module" ) }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
class TestVariablesVool < MiniTest::Test
|
class TestVariablesVool < MiniTest::Test
|
||||||
include RubyTests
|
include RubyTests
|
||||||
|
Loading…
Reference in New Issue
Block a user