rubymirrors 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.
Files changed (60) hide show
  1. data/Gemfile +7 -0
  2. data/README.md +30 -0
  3. data/Rakefile +13 -0
  4. data/lib/abstract_reflection.rb +112 -0
  5. data/lib/abstract_reflection/class_mirror.rb +150 -0
  6. data/lib/abstract_reflection/compiler_mirror.rb +31 -0
  7. data/lib/abstract_reflection/field_mirror.rb +35 -0
  8. data/lib/abstract_reflection/gc_mirror.rb +19 -0
  9. data/lib/abstract_reflection/method_mirror.rb +253 -0
  10. data/lib/abstract_reflection/mirror.rb +108 -0
  11. data/lib/abstract_reflection/object_mirror.rb +48 -0
  12. data/lib/abstract_reflection/stack_frame_mirror.rb +61 -0
  13. data/lib/abstract_reflection/thread_mirror.rb +64 -0
  14. data/lib/maglev/reflection.rb +49 -0
  15. data/lib/maglev/reflection/class_mirror.rb +157 -0
  16. data/lib/maglev/reflection/core_ext/class_organizer.rb +20 -0
  17. data/lib/maglev/reflection/core_ext/maglev.rb +5 -0
  18. data/lib/maglev/reflection/core_ext/method.rb +154 -0
  19. data/lib/maglev/reflection/core_ext/module.rb +41 -0
  20. data/lib/maglev/reflection/core_ext/object.rb +4 -0
  21. data/lib/maglev/reflection/core_ext/thread.rb +226 -0
  22. data/lib/maglev/reflection/field_mirror.rb +39 -0
  23. data/lib/maglev/reflection/field_mirror/fixed_instance_variable_mirror.rb +25 -0
  24. data/lib/maglev/reflection/method_mirror.rb +149 -0
  25. data/lib/maglev/reflection/mirror.rb +6 -0
  26. data/lib/maglev/reflection/object_mirror.rb +18 -0
  27. data/lib/maglev/reflection/stack_frame_mirror.rb +104 -0
  28. data/lib/maglev/reflection/thread_mirror.rb +116 -0
  29. data/lib/rubinius/reflection.rb +6 -0
  30. data/lib/ruby/reflection.rb +74 -0
  31. data/lib/ruby/reflection/class_mirror.rb +89 -0
  32. data/lib/ruby/reflection/field_mirror.rb +32 -0
  33. data/lib/ruby/reflection/field_mirror/class_variable_mirror.rb +25 -0
  34. data/lib/ruby/reflection/field_mirror/constant_mirror.rb +36 -0
  35. data/lib/ruby/reflection/field_mirror/instance_variable_mirror.rb +25 -0
  36. data/lib/ruby/reflection/method_mirror.rb +122 -0
  37. data/lib/ruby/reflection/mirror.rb +12 -0
  38. data/lib/ruby/reflection/object_mirror.rb +25 -0
  39. data/lib/ruby/reflection/stack_frame_mirror.rb +49 -0
  40. data/lib/ruby/reflection/support/shift_reset.rb +29 -0
  41. data/lib/ruby/reflection/thread_mirror.rb +47 -0
  42. data/rubymirrors.gemspec +12 -0
  43. data/spec/class_spec.rb +92 -0
  44. data/spec/field_spec.rb +119 -0
  45. data/spec/fixtures/class_spec.rb +29 -0
  46. data/spec/fixtures/field_spec.rb +9 -0
  47. data/spec/fixtures/method_spec.rb +14 -0
  48. data/spec/fixtures/object_spec.rb +5 -0
  49. data/spec/fixtures/reflect_spec.rb +14 -0
  50. data/spec/fixtures/stack_frame_spec.rb +5 -0
  51. data/spec/fixtures/thread_spec.rb +5 -0
  52. data/spec/frame_spec.rb +80 -0
  53. data/spec/method_spec.rb +166 -0
  54. data/spec/object_spec.rb +18 -0
  55. data/spec/reflection_spec.rb +74 -0
  56. data/spec/spec_helper.rb +16 -0
  57. data/spec/spec_helper/mspec_patch.rb +29 -0
  58. data/spec/spec_helper/multiple_reflections.rb +14 -0
  59. data/spec/thread_spec.rb +142 -0
  60. metadata +173 -0
@@ -0,0 +1,6 @@
1
+ require 'ruby/reflection'
2
+
3
+ module Rubinius
4
+ class Reflection < Ruby::Reflection
5
+ end
6
+ end
@@ -0,0 +1,74 @@
1
+ require 'abstract_reflection'
2
+ require 'ruby/reflection/mirror'
3
+ require 'ruby/reflection/object_mirror'
4
+ require 'ruby/reflection/class_mirror'
5
+ require 'ruby/reflection/field_mirror'
6
+ require 'ruby/reflection/thread_mirror'
7
+ require 'ruby/reflection/stack_frame_mirror'
8
+ require 'ruby/reflection/method_mirror'
9
+
10
+ module Ruby
11
+ class Reflection
12
+ include AbstractReflection
13
+
14
+ def self.codebase
15
+ nil.class
16
+ end
17
+
18
+ def initialize(ignored = nil)
19
+ end
20
+
21
+ def modules
22
+ instances_of(Module)
23
+ end
24
+
25
+ def classes
26
+ instances_of(Class)
27
+ end
28
+
29
+ def instances_of(klass)
30
+ mirrors ObjectSpace.each_object(klass).select {|obj| obj.class == klass }
31
+ end
32
+
33
+ def object_by_id(id)
34
+ if obj = ObjectSpace._id2ref(id)
35
+ reflect obj
36
+ else
37
+ nil
38
+ end
39
+ end
40
+
41
+ def threads
42
+ instances_of(Thread)
43
+ end
44
+
45
+ def platform
46
+ Object::RUBY_PLATFORM
47
+ end
48
+
49
+ def engine
50
+ Object::RUBY_ENGINE
51
+ end
52
+
53
+ def version
54
+ Object.const_get("#{engine.upcase}_VERSION")
55
+ end
56
+
57
+ def implementations_of(str)
58
+ mirrors methods.select {|m| m.name.to_s == str.to_s }
59
+ end
60
+
61
+ private
62
+ def methods
63
+ ObjectSpace.each_object(Module).collect do |m|
64
+ ims = m.instance_methods(false).collect {|s| m.instance_method(s) }
65
+ cms = m.methods(false).collect {|s| m.method(s) }
66
+ ims + cms
67
+ end.flatten
68
+ end
69
+
70
+ def mirrors(list)
71
+ list.collect {|each| reflect each }
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,89 @@
1
+ module Ruby
2
+ class Reflection
3
+ class ClassMirror < ObjectMirror
4
+ include AbstractReflection::ClassMirror
5
+ reflect! Module
6
+
7
+ def class_variables
8
+ field_mirrors @subject.class_variables
9
+ end
10
+
11
+ def class_instance_variables
12
+ field_mirrors @subject.instance_variables
13
+ end
14
+
15
+ def source_files
16
+ locations = @subject.instance_methods(false).collect do |name|
17
+ method = @subject.instance_method(name)
18
+ file = method.source_location if method.respond_to? :source_location
19
+ file.first if file
20
+ end
21
+ locations.compact.uniq
22
+ end
23
+
24
+ def singleton_class
25
+ reflection.reflect @subject.singleton_class
26
+ end
27
+
28
+ def singleton_class?
29
+ self.name =~ /^\#<Class:.*>$/
30
+ end
31
+
32
+ def mixins
33
+ mirrors @subject.ancestors.reject {|m| m.is_a? Class }
34
+ end
35
+
36
+ def superclass
37
+ reflection.reflect @subject.superclass
38
+ end
39
+
40
+ def subclasses
41
+ l = ObjectSpace.each_object(Class).select {|a| a.superclass == @subject }
42
+ mirrors l
43
+ end
44
+
45
+ def ancestors
46
+ mirrors @subject.ancestors
47
+ end
48
+
49
+ def constants
50
+ field_mirrors @subject.constants
51
+ end
52
+
53
+ def constant(str)
54
+ path = str.to_s.split("::")
55
+ c = path[0..-2].inject(@subject) {|klass,str| klass.const_get(str) }
56
+ field_mirror (c || @subject), path.last
57
+ rescue NameError => e
58
+ p e
59
+ nil
60
+ end
61
+
62
+ def nesting
63
+ ary = []
64
+ @subject.name.split("::").inject(Object) do |klass,str|
65
+ ary << klass.const_get(str)
66
+ ary.last
67
+ end
68
+ ary.reverse
69
+ rescue NameError => e
70
+ [@subject]
71
+ end
72
+
73
+ def nested_classes
74
+ nc = @subject.constants.collect do |c|
75
+ @subject.const_get(c) if @subject.const_defined? c
76
+ end.compact.select {|c| Module === c }
77
+ mirrors nc
78
+ end
79
+
80
+ def methods
81
+ @subject.instance_methods(false).collect(&:to_s)
82
+ end
83
+
84
+ def method(name)
85
+ reflection.reflect @subject.instance_method(name)
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,32 @@
1
+ module Ruby
2
+ class Reflection
3
+ class FieldMirror < Mirror
4
+ include AbstractReflection::FieldMirror
5
+ Field = Struct.new(:object, :name)
6
+ reflect! Field
7
+
8
+ def self.mirror_class(field)
9
+ return unless reflects? field
10
+ case field.name.to_s
11
+ when /^@@/ then ClassVariableMirror
12
+ when /^@/ then InstanceVariableMirror
13
+ else ConstantMirror
14
+ end
15
+ end
16
+
17
+ def initialize(obj)
18
+ super
19
+ @object = obj.object
20
+ @name = obj.name.to_s
21
+ end
22
+
23
+ def name
24
+ @name
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ require 'ruby/reflection/field_mirror/class_variable_mirror'
31
+ require 'ruby/reflection/field_mirror/instance_variable_mirror'
32
+ require 'ruby/reflection/field_mirror/constant_mirror'
@@ -0,0 +1,25 @@
1
+ module Ruby
2
+ class Reflection
3
+ class ClassVariableMirror < FieldMirror
4
+ def value
5
+ reflection.reflect @object.class_variable_get(@name)
6
+ end
7
+
8
+ def value=(o)
9
+ @object.class_variable_set(@name, o)
10
+ end
11
+
12
+ def public?
13
+ false
14
+ end
15
+
16
+ def protected?
17
+ false
18
+ end
19
+
20
+ def private?
21
+ true
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,36 @@
1
+ module Ruby
2
+ class Reflection
3
+ class ConstantMirror < FieldMirror
4
+ def value
5
+ if path = @object.autoload?(@name)
6
+ unless $LOADED_FEATURES.include?(path) ||
7
+ $LOADED_FEATURES.include?(File.expand_path(path))
8
+ # Do not trigger autoload
9
+ return nil
10
+ end
11
+ end
12
+ reflection.reflect @object.const_get(@name)
13
+ end
14
+
15
+ def value=(o)
16
+ @object.const_set(@name, o)
17
+ end
18
+
19
+ def public?
20
+ true
21
+ end
22
+
23
+ def protected?
24
+ false
25
+ end
26
+
27
+ def private?
28
+ false
29
+ end
30
+
31
+ def delete
32
+ @object.send(:remove_const, @name)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,25 @@
1
+ module Ruby
2
+ class Reflection
3
+ class InstanceVariableMirror < FieldMirror
4
+ def value
5
+ reflection.reflect @object.instance_variable_get(@name)
6
+ end
7
+
8
+ def value=(o)
9
+ @object.instance_variable_set(@name, o)
10
+ end
11
+
12
+ def public?
13
+ false
14
+ end
15
+
16
+ def protected?
17
+ false
18
+ end
19
+
20
+ def private?
21
+ true
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,122 @@
1
+ begin
2
+ require 'method_source'
3
+ rescue LoadError
4
+ end
5
+ begin
6
+ require 'ruby_parser' unless defined? RubyParser
7
+ rescue LoadError
8
+ end
9
+
10
+ module Ruby
11
+ class Reflection
12
+ class MethodMirror < Mirror
13
+ include AbstractReflection::MethodMirror
14
+ reflect! Method, UnboundMethod
15
+
16
+ def file
17
+ source_location.first
18
+ end
19
+
20
+ def file=(name)
21
+ defining_class.reflectee.class_eval(source, name, line)
22
+ @subject = defining_class.method(selector)
23
+ end
24
+
25
+ def line
26
+ source_location.last
27
+ end
28
+
29
+ def line=(num)
30
+ defining_class.reflectee.class_eval(source, file, num)
31
+ @subject = defining_class.method(selector)
32
+ end
33
+
34
+ def selector
35
+ @subject.name.to_s
36
+ end
37
+
38
+ def defining_class
39
+ reflection.reflect try_send(:owner)
40
+ end
41
+
42
+ def delete
43
+ try_send(:owner).send(:remove_method, @subject.name)
44
+ end
45
+
46
+ def block_argument
47
+ args(:block).first
48
+ end
49
+
50
+ def splat_argument
51
+ args(:rest).first
52
+ end
53
+
54
+ def optional_arguments
55
+ args(:opt)
56
+ end
57
+
58
+ def required_arguments
59
+ args(:req)
60
+ end
61
+
62
+ def arguments
63
+ try_send(:parameters).map { |t,a| a.to_s }
64
+ end
65
+
66
+ def protected?
67
+ visibility? :protected
68
+ end
69
+
70
+ def public?
71
+ visibility? :public
72
+ end
73
+
74
+ def private?
75
+ visibility? :private
76
+ end
77
+
78
+ def source
79
+ try_send(:source) or raise(CapabilitiesExceeded)
80
+ end
81
+
82
+ def step_offsets
83
+ [1, *send_offsets.values]
84
+ end
85
+
86
+ def send_offsets
87
+ sexp = RubyParser.new.process(source).flatten
88
+ sends = sexp.each_with_index.map {|e,i| sexp[i-1] if e == :arglist }
89
+ sends = sends.compact.collect(&:to_s)
90
+
91
+ offsets = [0]
92
+ sends.each do |name|
93
+ offsets << (source[offsets.last..-1] =~ /#{Regexp.escape(name)}/)
94
+ end
95
+ offsets.shift
96
+ Hash[*sends.zip(offsets).flatten]
97
+ end
98
+
99
+ private
100
+
101
+ def visibility?(type)
102
+ list = try_send(:owner).send("#{type}_instance_methods")
103
+ list.any? { |m| m.to_s == selector }
104
+ end
105
+
106
+ def try_send(method)
107
+ raise CapabilitiesExceeded unless @subject.respond_to? method
108
+ @subject.send(method)
109
+ end
110
+
111
+ def args(type)
112
+ args = []
113
+ try_send(:parameters).select { |t,n| args << n.to_s if t == type }
114
+ args
115
+ end
116
+
117
+ def source_location
118
+ try_send(:source_location) or raise(CapabilitiesExceeded)
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,12 @@
1
+ module Ruby
2
+ class Reflection
3
+ class Mirror
4
+ include AbstractReflection::Mirror
5
+
6
+ private
7
+ def mirrors(list)
8
+ list.collect {|each| reflection.reflect each }
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ module Ruby
2
+ class Reflection
3
+ class ObjectMirror < Mirror
4
+ include AbstractReflection::ObjectMirror
5
+ reflect! (defined?(BasicObject) ? BasicObject : Object)
6
+
7
+ def variables
8
+ field_mirrors @subject.instance_variables
9
+ end
10
+
11
+ def target_class
12
+ reflection.reflect @subject.class
13
+ end
14
+
15
+ private
16
+ def field_mirrors(list, subject = @subject)
17
+ list.collect {|name| field_mirror subject, name }
18
+ end
19
+
20
+ def field_mirror(subject, name)
21
+ reflection.reflect FieldMirror::Field.new(subject, name)
22
+ end
23
+ end
24
+ end
25
+ end