looksee 1.0.3-universal-java-1.6 → 2.0.0-universal-java-1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,142 @@
1
+ /**********************************************************************
2
+
3
+ method.h -
4
+
5
+ $Author: tmm1 $
6
+ created at: Wed Jul 15 20:02:33 2009
7
+
8
+ Copyright (C) 2009 Koichi Sasada
9
+
10
+ **********************************************************************/
11
+ #ifndef METHOD_H
12
+ #define METHOD_H
13
+
14
+ #include "internal.h"
15
+
16
+ #ifndef END_OF_ENUMERATION
17
+ # if defined(__GNUC__) &&! defined(__STRICT_ANSI__)
18
+ # define END_OF_ENUMERATION(key)
19
+ # else
20
+ # define END_OF_ENUMERATION(key) END_OF_##key##_PLACEHOLDER = 0
21
+ # endif
22
+ #endif
23
+
24
+ typedef enum {
25
+ NOEX_PUBLIC = 0x00,
26
+ NOEX_NOSUPER = 0x01,
27
+ NOEX_PRIVATE = 0x02,
28
+ NOEX_PROTECTED = 0x04,
29
+ NOEX_MASK = 0x06,
30
+ NOEX_BASIC = 0x08,
31
+ NOEX_UNDEF = NOEX_NOSUPER,
32
+ NOEX_MODFUNC = 0x12,
33
+ NOEX_SUPER = 0x20,
34
+ NOEX_VCALL = 0x40,
35
+ NOEX_RESPONDS = 0x80,
36
+
37
+ NOEX_BIT_WIDTH = 8,
38
+ NOEX_SAFE_SHIFT_OFFSET = ((NOEX_BIT_WIDTH+3)/4)*4 /* round up to nibble */
39
+ } rb_method_flag_t;
40
+
41
+ #define NOEX_SAFE(n) ((int)((n) >> NOEX_SAFE_SHIFT_OFFSET) & 0x0F)
42
+ #define NOEX_WITH(n, s) (((s) << NOEX_SAFE_SHIFT_OFFSET) | (n) | (ruby_running ? 0 : NOEX_BASIC))
43
+ #define NOEX_WITH_SAFE(n) NOEX_WITH((n), rb_safe_level())
44
+
45
+ /* method data type */
46
+
47
+ typedef enum {
48
+ VM_METHOD_TYPE_ISEQ,
49
+ VM_METHOD_TYPE_CFUNC,
50
+ VM_METHOD_TYPE_ATTRSET,
51
+ VM_METHOD_TYPE_IVAR,
52
+ VM_METHOD_TYPE_BMETHOD,
53
+ VM_METHOD_TYPE_ZSUPER,
54
+ VM_METHOD_TYPE_UNDEF,
55
+ VM_METHOD_TYPE_NOTIMPLEMENTED,
56
+ VM_METHOD_TYPE_OPTIMIZED, /* Kernel#send, Proc#call, etc */
57
+ VM_METHOD_TYPE_MISSING, /* wrapper for method_missing(id) */
58
+ VM_METHOD_TYPE_REFINED,
59
+
60
+ END_OF_ENUMERATION(VM_METHOD_TYPE)
61
+ } rb_method_type_t;
62
+
63
+ struct rb_call_info_struct;
64
+
65
+ typedef struct rb_method_cfunc_struct {
66
+ VALUE (*func)(ANYARGS);
67
+ VALUE (*invoker)(VALUE (*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv);
68
+ int argc;
69
+ } rb_method_cfunc_t;
70
+
71
+ typedef struct rb_method_attr_struct {
72
+ ID id;
73
+ const VALUE location;
74
+ } rb_method_attr_t;
75
+
76
+ typedef struct rb_iseq_struct rb_iseq_t;
77
+
78
+ typedef struct rb_method_definition_struct {
79
+ rb_method_type_t type; /* method type */
80
+ ID original_id;
81
+ union {
82
+ rb_iseq_t * const iseq; /* should be mark */
83
+ rb_method_cfunc_t cfunc;
84
+ rb_method_attr_t attr;
85
+ const VALUE proc; /* should be mark */
86
+ enum method_optimized_type {
87
+ OPTIMIZED_METHOD_TYPE_SEND,
88
+ OPTIMIZED_METHOD_TYPE_CALL,
89
+
90
+ OPTIMIZED_METHOD_TYPE__MAX
91
+ } optimize_type;
92
+ struct rb_method_entry_struct *orig_me;
93
+ } body;
94
+ int alias_count;
95
+ } rb_method_definition_t;
96
+
97
+ typedef struct rb_method_entry_struct {
98
+ rb_method_flag_t flag;
99
+ char mark;
100
+ rb_method_definition_t *def;
101
+ ID called_id;
102
+ VALUE klass; /* should be mark */
103
+ } rb_method_entry_t;
104
+
105
+ struct unlinked_method_entry_list_entry {
106
+ struct unlinked_method_entry_list_entry *next;
107
+ rb_method_entry_t *me;
108
+ };
109
+
110
+ #define UNDEFINED_METHOD_ENTRY_P(me) (!(me) || !(me)->def || (me)->def->type == VM_METHOD_TYPE_UNDEF)
111
+
112
+ void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_flag_t noex);
113
+ rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_flag_t noex);
114
+ rb_method_entry_t *rb_method_entry(VALUE klass, ID id, VALUE *define_class_ptr);
115
+ rb_method_entry_t *rb_method_entry_at(VALUE obj, ID id);
116
+ void rb_add_refined_method_entry(VALUE refined_class, ID mid);
117
+ rb_method_entry_t *rb_resolve_refined_method(VALUE refinements,
118
+ const rb_method_entry_t *me,
119
+ VALUE *defined_class_ptr);
120
+ rb_method_entry_t *rb_method_entry_with_refinements(VALUE klass, ID id,
121
+ VALUE *defined_class_ptr);
122
+ rb_method_entry_t *rb_method_entry_without_refinements(VALUE klass, ID id,
123
+ VALUE *defined_class_ptr);
124
+
125
+ rb_method_entry_t *rb_method_entry_get_without_cache(VALUE klass, ID id, VALUE *define_class_ptr);
126
+ rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_flag_t noex);
127
+
128
+ int rb_method_entry_arity(const rb_method_entry_t *me);
129
+ int rb_method_entry_eq(const rb_method_entry_t *m1, const rb_method_entry_t *m2);
130
+ st_index_t rb_hash_method_entry(st_index_t hash, const rb_method_entry_t *me);
131
+
132
+ VALUE rb_method_entry_location(rb_method_entry_t *me);
133
+ VALUE rb_mod_method_location(VALUE mod, ID id);
134
+ VALUE rb_obj_method_location(VALUE obj, ID id);
135
+
136
+ void rb_mark_method_entry(const rb_method_entry_t *me);
137
+ void rb_free_method_entry(rb_method_entry_t *me);
138
+ void rb_sweep_method_entry(void *vm);
139
+ void rb_free_m_tbl(st_table *tbl);
140
+ void rb_free_m_tbl_wrapper(struct method_table_wrapper *wrapper);
141
+
142
+ #endif /* METHOD_H */
data/ext/mri/mri.c CHANGED
@@ -1,10 +1,19 @@
1
1
  #include "ruby.h"
2
2
 
3
- #if RUBY_VERSION >= 193
3
+ #if RUBY_VERSION >= 200
4
+ # include "method.h"
4
5
  # include "internal.h"
6
+ #elif RUBY_VERSION >= 193
7
+ # include "ruby/st.h"
8
+ # ifdef SA_EMPTY
9
+ # include "internal_falcon.h"
10
+ # define Looksee_method_table_foreach sa_foreach
11
+ # define Looksee_method_table_lookup sa_lookup
12
+ # else
13
+ # include "internal.h"
14
+ # endif
5
15
  # include "vm_core.h"
6
16
  # include "method.h"
7
- # include "ruby/st.h"
8
17
  #elif RUBY_VERSION >= 192
9
18
  # include "vm_core.h"
10
19
  # include "method.h"
@@ -17,6 +26,11 @@
17
26
  # include "st.h"
18
27
  #endif
19
28
 
29
+ #ifndef Looksee_method_table_foreach
30
+ # define Looksee_method_table_foreach st_foreach
31
+ # define Looksee_method_table_lookup st_lookup
32
+ #endif
33
+
20
34
  #if RUBY_VERSION < 187
21
35
  # define RCLASS_IV_TBL(c) (RCLASS(c)->iv_tbl)
22
36
  # define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
@@ -77,8 +91,10 @@ typedef struct add_method_if_matching_arg {
77
91
  } add_method_if_matching_arg_t;
78
92
 
79
93
  static int add_method_if_matching(ID method_name, rb_method_entry_t *me, add_method_if_matching_arg_t *arg) {
94
+ # ifdef ID_ALLOCATOR
80
95
  if (method_name == ID_ALLOCATOR)
81
96
  return ST_CONTINUE;
97
+ # endif
82
98
 
83
99
  if (UNDEFINED_METHOD_ENTRY_P(me))
84
100
  return ST_CONTINUE;
@@ -90,6 +106,12 @@ static int add_method_if_matching(ID method_name, rb_method_entry_t *me, add_met
90
106
  }
91
107
 
92
108
  static int add_method_if_undefined(ID method_name, rb_method_entry_t *me, VALUE *names) {
109
+ # ifdef ID_ALLOCATOR
110
+ /* The allocator can be undefined with rb_undef_alloc_func, e.g. Struct. */
111
+ if (method_name == ID_ALLOCATOR)
112
+ return ST_CONTINUE;
113
+ # endif
114
+
93
115
  if (UNDEFINED_METHOD_ENTRY_P(me))
94
116
  rb_ary_push(*names, ID2SYM(method_name));
95
117
  return ST_CONTINUE;
@@ -111,9 +133,11 @@ typedef struct add_method_if_matching_arg {
111
133
  } add_method_if_matching_arg_t;
112
134
 
113
135
  static int add_method_if_matching(ID method_name, NODE *body, add_method_if_matching_arg_t *arg) {
136
+ # ifdef ID_ALLOCATOR
114
137
  /* This entry is for the internal allocator function. */
115
138
  if (method_name == ID_ALLOCATOR)
116
139
  return ST_CONTINUE;
140
+ # endif
117
141
 
118
142
  /* Module#undef_method:
119
143
  * * sets body->nd_body to NULL in ruby <= 1.8
@@ -128,6 +152,12 @@ static int add_method_if_matching(ID method_name, NODE *body, add_method_if_matc
128
152
  }
129
153
 
130
154
  static int add_method_if_undefined(ID method_name, NODE *body, VALUE *names) {
155
+ # ifdef ID_ALLOCATOR
156
+ /* The allocator can be undefined with rb_undef_alloc_func, e.g. Struct. */
157
+ if (method_name == ID_ALLOCATOR)
158
+ return ST_CONTINUE;
159
+ # endif
160
+
131
161
  if (!body || !body->nd_body)
132
162
  rb_ary_push(*names, ID2SYM(method_name));
133
163
  return ST_CONTINUE;
@@ -139,7 +169,8 @@ static VALUE internal_instance_methods(VALUE klass, VISIBILITY_TYPE visibility)
139
169
  add_method_if_matching_arg_t arg;
140
170
  arg.names = rb_ary_new();
141
171
  arg.visibility = visibility;
142
- st_foreach(RCLASS_M_TBL(klass), add_method_if_matching, (st_data_t)&arg);
172
+
173
+ Looksee_method_table_foreach(RCLASS_M_TBL(klass), add_method_if_matching, (st_data_t)&arg);
143
174
  return arg.names;
144
175
  }
145
176
 
@@ -173,7 +204,7 @@ VALUE Looksee_internal_private_instance_methods(VALUE self, VALUE klass) {
173
204
  */
174
205
  VALUE Looksee_internal_undefined_instance_methods(VALUE self, VALUE klass) {
175
206
  VALUE names = rb_ary_new();
176
- st_foreach(RCLASS_M_TBL(klass), add_method_if_undefined, (st_data_t)&names);
207
+ Looksee_method_table_foreach(RCLASS_M_TBL(klass), add_method_if_undefined, (st_data_t)&names);
177
208
  return names;
178
209
  }
179
210
 
@@ -184,7 +215,7 @@ VALUE Looksee_singleton_class_p(VALUE self, VALUE object) {
184
215
  VALUE Looksee_singleton_instance(VALUE self, VALUE singleton_class) {
185
216
  if (BUILTIN_TYPE(singleton_class) == T_CLASS && FL_TEST(singleton_class, FL_SINGLETON)) {
186
217
  VALUE object;
187
- if (!st_lookup(RCLASS_IV_TBL(singleton_class), rb_intern("__attached__"), (st_data_t *)&object))
218
+ if (!Looksee_method_table_lookup(RCLASS_IV_TBL(singleton_class), rb_intern("__attached__"), (st_data_t *)&object))
188
219
  rb_raise(rb_eRuntimeError, "[looksee bug] can't find singleton object");
189
220
  return object;
190
221
  } else {
Binary file
@@ -30,26 +30,31 @@ module Looksee
30
30
 
31
31
  def internal_undefined_instance_methods(mod)
32
32
  names = []
33
- mod.method_table.each_entry do |entry|
34
- names << entry.name if entry.visibility.equal?(:undef)
33
+ mod.method_table.entries.each do |(name, method, visibility)|
34
+ names << name if visibility.equal?(:undef)
35
35
  end
36
36
  names
37
37
  end
38
38
 
39
39
  def singleton_class?(object)
40
- object.is_a?(Class) && object.__metaclass_object__
40
+ object.is_a?(Class) && !!::Rubinius::Type.singleton_class_object(object)
41
41
  end
42
42
 
43
43
  def singleton_instance(singleton_class)
44
44
  singleton_class?(singleton_class) or
45
45
  raise TypeError, "expected singleton class, got #{singleton_class.class}"
46
- singleton_class.__metaclass_object__
46
+ ::Rubinius::Type.singleton_class_object(singleton_class)
47
47
  end
48
48
 
49
49
  def module_name(mod)
50
50
  mod.is_a?(Module) or
51
51
  raise TypeError, "expected module, got #{mod.class}"
52
- mod.__name__
52
+
53
+ if ::Rubinius::Type.respond_to?(:module_name)
54
+ ::Rubinius::Type.module_name(mod) || ''
55
+ else
56
+ mod.__name__
57
+ end
53
58
  end
54
59
 
55
60
  def source_location(method)
data/lib/looksee/clean.rb CHANGED
@@ -4,6 +4,10 @@ require 'set'
4
4
  module Looksee
5
5
  Config = Object.const_defined?(:RbConfig) ? ::RbConfig : ::Config
6
6
 
7
+ NoMethodError = Class.new(RuntimeError)
8
+ NoSourceLocationError = Class.new(RuntimeError)
9
+ NoSourceFileError = Class.new(RuntimeError)
10
+
7
11
  autoload :VERSION, 'looksee/version'
8
12
  autoload :Adapter, 'looksee/adapter'
9
13
  autoload :Columnizer, 'looksee/columnizer'
@@ -42,38 +42,31 @@ module Looksee
42
42
  Inspector.new(lookup_path, options)
43
43
  end
44
44
 
45
- #
46
- # Open an editor at the named method's definition.
47
- #
48
- # Uses Looksee.editor to determine the editor command to run.
49
- #
50
- # Only works for methods for which file and line numbers are
51
- # accessible.
52
- #
53
- def edit(name)
54
- Editor.new(Looksee.editor).edit(self, name)
55
- end
56
-
57
- def self.rename(renamings) # :nodoc:
58
- renamings.each do |old_name, new_name|
59
- alias_method new_name, old_name
60
- remove_method old_name
61
- end
45
+ def self.rename(name) # :nodoc:
46
+ name = name[:ls] if name.is_a?(Hash)
47
+ alias_method name, :ls
48
+ remove_method :ls
62
49
  end
63
50
  end
64
51
 
65
52
  #
66
- # Rename the methods added to every object. Example:
53
+ # Rename the #ls method, added to every object. Example:
54
+ #
55
+ # rename :_ls
56
+ #
57
+ # This renames Looksee's #ls method to #_ls.
67
58
  #
68
- # rename :ls => :_ls, :edit => :_edit
59
+ # For backward compatibility, the old-style invocation is also
60
+ # supported. Please note this is deprecated.
69
61
  #
70
- def self.rename(renamings)
71
- ObjectMixin.rename(renamings)
62
+ # rename :ls => :_ls
63
+ #
64
+ def self.rename(name)
65
+ ObjectMixin.rename(name)
72
66
  end
73
67
 
74
- (ENV['LOOKSEE_METHODS'] || '').scan(/([\w_]+)=([\w_]+)/) do
75
- rename $1.to_sym => $2.to_sym
76
- end
68
+ name = ENV['LOOKSEE_METHOD'] and
69
+ rename name
77
70
 
78
71
  Object.send :include, ObjectMixin
79
72
  end
@@ -14,9 +14,15 @@ module Looksee
14
14
  #
15
15
  def edit(object, method_name)
16
16
  method = LookupPath.new(object).find(method_name.to_s) or
17
- return
17
+ raise NoMethodError, "no method `#{method_name}' in lookup path of #{object.class} instance"
18
18
  file, line = Looksee.adapter.source_location(method)
19
- run(file, line) unless line.nil?
19
+ if !file
20
+ raise NoSourceLocationError, "no source location for #{method.owner}##{method.name}"
21
+ elsif !File.exist?(file)
22
+ raise NoSourceFileError, "cannot find source file: #{file}"
23
+ else
24
+ run(file, line)
25
+ end
20
26
  end
21
27
 
22
28
  #
data/lib/looksee/help.rb CHANGED
@@ -40,7 +40,7 @@ module Looksee
40
40
  | ...
41
41
  | }
42
42
  |
43
- | object.edit(method)
43
+ | object.ls.edit(method)
44
44
  |
45
45
  | Jump to the source of the given method. Set your editor
46
46
  | with Looksee.editor or the LOOKSEE_EDITOR environment
@@ -11,12 +11,27 @@ module Looksee
11
11
  attr_reader :visibilities
12
12
  attr_reader :filters
13
13
 
14
+ #
15
+ # Print the method lookup path of self. See the README for details.
16
+ #
14
17
  def inspect
15
18
  lookup_path.entries.reverse.map do |entry|
16
19
  inspect_entry(entry)
17
20
  end.join("\n")
18
21
  end
19
22
 
23
+ #
24
+ # Open an editor at the named method's definition.
25
+ #
26
+ # Uses Looksee.editor to determine the editor command to run.
27
+ #
28
+ # Only works for methods for which file and line numbers are
29
+ # accessible.
30
+ #
31
+ def edit(name)
32
+ Editor.new(Looksee.editor).edit(lookup_path.object, name)
33
+ end
34
+
20
35
  private
21
36
 
22
37
  def inspect_entry(entry)
@@ -1,5 +1,5 @@
1
1
  module Looksee
2
- VERSION = [1, 0, 3]
2
+ VERSION = [2, 0, 0]
3
3
 
4
4
  class << VERSION
5
5
  include Comparable
data/spec/adapter_spec.rb CHANGED
@@ -95,33 +95,33 @@ describe "Looksee.adapter" do
95
95
  def self.it_should_list_methods_with_visibility(visibility)
96
96
  it "should return the list of #{visibility} instance methods defined directly on a class" do
97
97
  temporary_class :C
98
- replace_methods C, visibility => [:one, :two]
98
+ add_methods C, visibility => [:one, :two]
99
99
  @adapter.send(target_method, C).to_set.should == Set[:one, :two]
100
100
  end
101
101
 
102
102
  it "should return the list of #{visibility} instance methods defined directly on a module" do
103
103
  temporary_module :M
104
- replace_methods M, visibility => [:one, :two]
104
+ add_methods M, visibility => [:one, :two]
105
105
  @adapter.send(target_method, M).to_set.should == Set[:one, :two]
106
106
  end
107
107
 
108
108
  it "should return the list of #{visibility} instance methods defined directly on a singleton class" do
109
109
  temporary_class :C
110
110
  c = C.new
111
- replace_methods c.singleton_class, visibility => [:one, :two]
111
+ add_methods c.singleton_class, visibility => [:one, :two]
112
112
  @adapter.send(target_method, c.singleton_class).to_set.should == Set[:one, :two]
113
113
  end
114
114
 
115
115
  it "should return the list of #{visibility} instance methods defined directly on a class' singleton class" do
116
116
  temporary_class :C
117
- replace_methods C.singleton_class, visibility => [:one, :two], :class_singleton => true
117
+ add_methods C.singleton_class, visibility => [:one, :two], :class_singleton => true
118
118
  @adapter.send(target_method, C.singleton_class).to_set.should == Set[:one, :two]
119
119
  end
120
120
 
121
121
  # Worth checking as ruby keeps undef'd methods in method tables.
122
122
  it "should not return undefined methods" do
123
123
  temporary_class :C
124
- replace_methods C, visibility => [:removed]
124
+ add_methods C, visibility => [:removed]
125
125
  C.send(:undef_method, :removed)
126
126
  @adapter.send(target_method, C).to_set.should == Set[]
127
127
  end
@@ -130,7 +130,7 @@ describe "Looksee.adapter" do
130
130
  def self.it_should_not_list_methods_with_visibility(visibility1, visibility2)
131
131
  it "should not return any #{visibility1} or #{visibility2} instance methods" do
132
132
  temporary_class :C
133
- replace_methods C, {visibility1 => [:a], visibility2 => [:b]}
133
+ add_methods C, {visibility1 => [:a], visibility2 => [:b]}
134
134
  @adapter.send(target_method, C).to_set.should == Set[]
135
135
  end
136
136
  end
@@ -195,6 +195,11 @@ describe "Looksee.adapter" do
195
195
  C.send(:remove_method, :f)
196
196
  @adapter.internal_undefined_instance_methods(C).should == []
197
197
  end
198
+
199
+ it "should handle the MRI allocator being undefined (e.g. Struct)" do
200
+ struct_singleton_class = (class << Struct; self; end)
201
+ @adapter.internal_undefined_instance_methods(struct_singleton_class).should == []
202
+ end
198
203
  end
199
204
  end
200
205
 
@@ -431,7 +436,8 @@ describe "Looksee.adapter" do
431
436
  describe "#source_location" do
432
437
  def load_source(source)
433
438
  @tmp = "#{ROOT}/spec/tmp"
434
- @source_path = "#@tmp/c.rb"
439
+ # rbx 1.2.3 caches the file content by file name - ensure file names are different.
440
+ @source_path = "#@tmp/c#{__id__}.rb"
435
441
  FileUtils.mkdir_p @tmp
436
442
  open(@source_path, 'w') { |f| f.print source }
437
443
  load @source_path