rubybreaker 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|