rubybreaker 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS +7 -0
- data/LICENSE +26 -0
- data/README.md +403 -0
- data/Rakefile +90 -0
- data/TODO +30 -0
- data/bin/gen_stub_rubylib +64 -0
- data/bin/rubybreaker +67 -0
- data/lib/rubybreaker/context.rb +122 -0
- data/lib/rubybreaker/debug.rb +48 -0
- data/lib/rubybreaker/error.rb +59 -0
- data/lib/rubybreaker/rubylib/core.rb +2316 -0
- data/lib/rubybreaker/rubylib.rb +3 -0
- data/lib/rubybreaker/runtime/inspector.rb +57 -0
- data/lib/rubybreaker/runtime/monitor.rb +235 -0
- data/lib/rubybreaker/runtime/object_wrapper.rb +77 -0
- data/lib/rubybreaker/runtime/overrides.rb +42 -0
- data/lib/rubybreaker/runtime/pluggable.rb +57 -0
- data/lib/rubybreaker/runtime/type_placeholder.rb +27 -0
- data/lib/rubybreaker/runtime/type_system.rb +228 -0
- data/lib/rubybreaker/runtime/typesig_parser.rb +45 -0
- data/lib/rubybreaker/runtime.rb +103 -0
- data/lib/rubybreaker/test/testcase.rb +39 -0
- data/lib/rubybreaker/test.rb +1 -0
- data/lib/rubybreaker/type/type.rb +241 -0
- data/lib/rubybreaker/type/type_comparer.rb +143 -0
- data/lib/rubybreaker/type/type_grammar.treetop +285 -0
- data/lib/rubybreaker/type/type_unparser.rb +142 -0
- data/lib/rubybreaker/type.rb +2 -0
- data/lib/rubybreaker/typing/rubytype.rb +47 -0
- data/lib/rubybreaker/typing/subtyping.rb +480 -0
- data/lib/rubybreaker/typing.rb +3 -0
- data/lib/rubybreaker/util.rb +31 -0
- data/lib/rubybreaker.rb +193 -0
- data/test/integrated/tc_method_missing.rb +30 -0
- data/test/integrated/tc_simple1.rb +77 -0
- data/test/runtime/tc_obj_wrapper.rb +73 -0
- data/test/runtime/tc_typesig_parser.rb +33 -0
- data/test/ts_integrated.rb +4 -0
- data/test/ts_runtime.rb +5 -0
- data/test/ts_type.rb +5 -0
- data/test/ts_typing.rb +4 -0
- data/test/type/tc_comparer.rb +211 -0
- data/test/type/tc_parser.rb +219 -0
- data/test/type/tc_unparser.rb +276 -0
- data/test/typing/tc_rubytype.rb +63 -0
- data/test/typing/tc_typing.rb +219 -0
- data/webpage/footer.html +5 -0
- data/webpage/generated_toc.js +319 -0
- data/webpage/header.html +14 -0
- data/webpage/images/logo.png +0 -0
- data/webpage/index.html +439 -0
- data/webpage/rubybreaker.css +53 -0
- metadata +119 -0
@@ -0,0 +1,122 @@
|
|
1
|
+
#--
|
2
|
+
# This file defines code location as well as runtime location and context
|
3
|
+
# which is made up of one or more locations.
|
4
|
+
|
5
|
+
require "prettyprint"
|
6
|
+
|
7
|
+
module RubyBreaker
|
8
|
+
|
9
|
+
# This class represents a position of the type acquired from either the
|
10
|
+
# type signature or code during runtime. It can also be used for internal
|
11
|
+
# error checking or debuging purpose.
|
12
|
+
class Position
|
13
|
+
|
14
|
+
attr_accessor :file
|
15
|
+
attr_accessor :line
|
16
|
+
attr_accessor :col
|
17
|
+
attr_accessor :method
|
18
|
+
|
19
|
+
@@file = ""
|
20
|
+
@@line = -1
|
21
|
+
@@col = -1
|
22
|
+
|
23
|
+
def initialize(file="",line=-1,col=-1,meth="")
|
24
|
+
@file = file
|
25
|
+
@line = line
|
26
|
+
@col = col
|
27
|
+
@method = meth
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s()
|
31
|
+
return "#{@file}:(#{@line},#{@col}):in #{@method}"
|
32
|
+
end
|
33
|
+
|
34
|
+
# This class method is to set the current parsing position.
|
35
|
+
def self.set(file,line,col)
|
36
|
+
@@file = file
|
37
|
+
@@line = line
|
38
|
+
@@col = col
|
39
|
+
end
|
40
|
+
|
41
|
+
# This class method returns a new position object for the current
|
42
|
+
# parsing position.
|
43
|
+
def self.get()
|
44
|
+
return Position.new(@@file,@@line,@@col)
|
45
|
+
end
|
46
|
+
|
47
|
+
# This class method is a utility function to convert a string in the
|
48
|
+
# caller() array.
|
49
|
+
def self.convert_caller_to_pos(caller_ary, idx=0)
|
50
|
+
tokens = caller_ary[idx].split(":")
|
51
|
+
return self.new(tokens[0],tokens[1],-1,tokens[2]) # no col
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# This class represents a position with respect to an object and the name
|
56
|
+
# of a method being invoked.
|
57
|
+
class ObjectPosition
|
58
|
+
attr_accessor :obj
|
59
|
+
attr_accessor :meth_name
|
60
|
+
|
61
|
+
def initialize(obj, meth_name)
|
62
|
+
@obj = obj
|
63
|
+
@meth_name = meth_name
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_s()
|
67
|
+
m_delim = @obj.kind_of?(Module) ? "." : "#"
|
68
|
+
return "> #{@obj.class}#{m_delim}#{@meth_name}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# This class represents a context which consists of one or more positions.
|
73
|
+
# A position can refer to a physical file/line position or a virtual
|
74
|
+
# position with respect to an object. A context is commonly used to
|
75
|
+
# represent a chain of positions for types.
|
76
|
+
class Context
|
77
|
+
|
78
|
+
attr_accessor :pos # location is either Position or ObjectPosition
|
79
|
+
attr_accessor :child
|
80
|
+
|
81
|
+
def initialize(pos)
|
82
|
+
@pos = pos
|
83
|
+
@child = nil
|
84
|
+
end
|
85
|
+
|
86
|
+
def push(pos)
|
87
|
+
if @child
|
88
|
+
@child.push(pos)
|
89
|
+
else
|
90
|
+
@child = Context.new(pos)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def pop
|
95
|
+
if @child && @child.child
|
96
|
+
@child.pop
|
97
|
+
elsif @child
|
98
|
+
@child = nil
|
99
|
+
else
|
100
|
+
# root; don't do anything
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def format_with_msg(pp,msg="")
|
105
|
+
pp.text(@pos.to_s)
|
106
|
+
pp.breakable()
|
107
|
+
if @child
|
108
|
+
pp.group(2) {
|
109
|
+
pp.breakable()
|
110
|
+
@child.format_with_msg(pp,msg)
|
111
|
+
}
|
112
|
+
elsif msg != ""
|
113
|
+
pp.group(2) do
|
114
|
+
pp.breakable()
|
115
|
+
pp.text("> #{msg}",79)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#--
|
2
|
+
# This file is for debugging RubyBreaker.
|
3
|
+
|
4
|
+
require "prettyprint"
|
5
|
+
require_relative "context"
|
6
|
+
|
7
|
+
module RubyBreaker
|
8
|
+
|
9
|
+
# This module is for internal purpose only - to help ourselves find bugs
|
10
|
+
# and fix them with more informative error messages.
|
11
|
+
module Debug
|
12
|
+
|
13
|
+
OUTPUT = ""
|
14
|
+
|
15
|
+
def self.msg(text,context=nil)
|
16
|
+
return unless RubyBreaker::OPTIONS[:debug]
|
17
|
+
pp = PrettyPrint.new(OUTPUT)
|
18
|
+
msg = "[DEBUG] #{text}"
|
19
|
+
if context
|
20
|
+
context.format_with_msg(pp,msg)
|
21
|
+
else
|
22
|
+
pp.text(msg,79)
|
23
|
+
pp.breakable()
|
24
|
+
end
|
25
|
+
pp.flush
|
26
|
+
puts OUTPUT
|
27
|
+
OUTPUT.replace("")
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.short_msg(text)
|
31
|
+
return unless RubyBreaker::OPTIONS[:debug]
|
32
|
+
msg = "[DEBUG] #{text}"
|
33
|
+
print msg
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.token(msg)
|
37
|
+
return unless RubyBreaker::OPTIONS[:debug]
|
38
|
+
print msg
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.feed_line()
|
42
|
+
return unless RubyBreaker::OPTIONS[:debug]
|
43
|
+
puts ""
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
#--
|
2
|
+
# This file defines various errors that are used by RubyBreaker both
|
3
|
+
# internally and externally.
|
4
|
+
|
5
|
+
module RubyBreaker
|
6
|
+
|
7
|
+
# This module contains errors used by RubyBreaker.
|
8
|
+
module Errors
|
9
|
+
|
10
|
+
########### INTERNAL ERRORS
|
11
|
+
|
12
|
+
# This class is a base class for any internal errors. It should be used to
|
13
|
+
# inform the faults within the program and not related to user programs.
|
14
|
+
class InternalError < ::Exception
|
15
|
+
def initialize(msg)
|
16
|
+
@level = :FATAL if @level == nil
|
17
|
+
msg = "[#{@level}] #{msg} at #{@pos}"
|
18
|
+
super(msg)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# This error is thrown when a type is constructed with invalid elements.
|
23
|
+
class InvalidTypeConstruction < InternalError
|
24
|
+
end
|
25
|
+
|
26
|
+
# This error is thrown when a subtype check is not even appropriate for
|
27
|
+
# two given types. It should NOT BE USED for any check failures.
|
28
|
+
class InvalidSubtypeCheck < InternalError
|
29
|
+
def initialize(msg,pos=nil)
|
30
|
+
@level = :FATAL
|
31
|
+
@pos = pos ? pos : Position.convert_caller_to_pos(caller(1))
|
32
|
+
super("InvalidSubtypingCheck: #{msg}")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
########### USER ERRORS
|
37
|
+
|
38
|
+
# This class is a base class for any user errors. Unlike internal error,
|
39
|
+
# it should use a Context to inform the source of the error rather than a
|
40
|
+
# Position since user errors tend to generate over multiple points in the
|
41
|
+
# program.
|
42
|
+
class UserError < ::Exception
|
43
|
+
|
44
|
+
def initialize(msg, ctx)
|
45
|
+
super(msg)
|
46
|
+
@ctx = ctx
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
class TypeError < ::UserError
|
52
|
+
end
|
53
|
+
|
54
|
+
class SubtypeFailure < TypeError
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|