getsource 0.1.0

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 ADDED
@@ -0,0 +1 @@
1
+ getsource de tario <rseminara@hotmail.com>
@@ -0,0 +1 @@
1
+ 0.1.0: implemented getsource with code extracted from rallhook
data/README ADDED
@@ -0,0 +1,48 @@
1
+ = getsource - Get the source file path of the implementation of a given method =
2
+
3
+ This package cointains getsource, a extension which allows get the path name for the source of a method
4
+
5
+ == Installation
6
+
7
+ gem install getsource
8
+
9
+ == Usage
10
+
11
+ === Basic Example
12
+
13
+
14
+ source1.rb
15
+
16
+ class X
17
+ def foo
18
+ end
19
+ end
20
+
21
+ source2.rb
22
+
23
+ class Y < X
24
+ def foo
25
+ end
26
+ end
27
+
28
+ main.rb
29
+
30
+ require "rallhook"
31
+ require "source1.rb"
32
+ require "source2.rb"
33
+
34
+ x = X.new
35
+ y = Y.new
36
+
37
+ print x.method(:foo).body.file,"\n" # source1.rb
38
+ print y.method(:foo).body.file,"\n" # source2.rb
39
+
40
+ print y.method(X,:foo).body.file,"\n" # source1.rb
41
+ print y.method(Y,:foo).body.file,"\n" # source2.rb
42
+
43
+
44
+ NOTE: See examples directory of the gem installation
45
+
46
+ == Copying
47
+
48
+ Copyright (c) 2010 Dario Seminara, released under the GPL License (see LICENSE)
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/gempackagetask'
6
+
7
+ spec = Gem::Specification.new do |s|
8
+ s.name = 'getsource'
9
+ s.version = '0.1.0'
10
+ s.author = 'Dario Seminara'
11
+ s.email = 'robertodarioseminara@gmail.com'
12
+ s.platform = Gem::Platform::RUBY
13
+ s.summary = 'Get the source file path of the implementation of a given method'
14
+ s.homepage = "http://github.com/tario/getsource"
15
+ s.has_rdoc = true
16
+ s.extra_rdoc_files = [ 'README' ]
17
+ s.rdoc_options << '--main' << 'README'
18
+ s.extensions = FileList["ext/**/extconf.rb"].to_a
19
+ s.files = Dir.glob("{examples,lib,test}/**/*.rb") + Dir.glob("ext/**/*.c") + Dir.glob("ext/**/*.h") + Dir.glob("ext/**/extconf.rb") +
20
+ [ 'AUTHORS', 'CHANGELOG', 'README', 'Rakefile', 'TODO' ]
21
+ end
22
+
23
+ desc 'Run tests'
24
+ task :default => [ :test ]
25
+
26
+ Rake::TestTask.new('test') do |t|
27
+ t.libs << 'test'
28
+ t.pattern = '{test}/**/test_*.rb'
29
+ t.verbose = true
30
+ end
31
+
32
+ desc 'Generate RDoc'
33
+ Rake::RDocTask.new :rdoc do |rd|
34
+ rd.rdoc_dir = 'doc'
35
+ rd.rdoc_files.add 'lib', 'ext', 'README'
36
+ rd.main = 'README'
37
+ end
38
+
39
+ desc 'Build Gem'
40
+ Rake::GemPackageTask.new spec do |pkg|
41
+ pkg.need_tar = true
42
+ end
43
+
44
+ desc 'Clean up'
45
+ task :clean => [ :clobber_rdoc, :clobber_package ]
46
+
47
+ desc 'Clean up'
48
+ task :clobber => [ :clean ]
49
+
data/TODO ADDED
File without changes
@@ -0,0 +1,13 @@
1
+ require "rubygems"
2
+ require "getsource"
3
+ require "source1.rb"
4
+ require "source2.rb"
5
+
6
+ x = X.new
7
+ y = Y.new
8
+
9
+ print "definition of method :foo in #{x}: ", x.method(:foo).body.file,"\n" # source1.rb
10
+ print "definition of method :foo in #{y}: ", y.method(:foo).body.file,"\n" # source2.rb
11
+
12
+ print "definition of method :foo of class X in object #{y}: ", y.specific_method(X,:foo).body.file,"\n" # source1.rb
13
+ print "definition of method :foo of class Y in object #{y}: ", y.specific_method(Y,:foo).body.file,"\n" # source1.rb
@@ -0,0 +1,4 @@
1
+ class X
2
+ def foo
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ class Y < X
2
+ def foo
3
+ end
4
+ end
@@ -0,0 +1,22 @@
1
+ require 'mkmf'
2
+ dir_config('getsource_base')
3
+ CONFIG['CC'] = 'gcc'
4
+
5
+ ruby_version = Config::CONFIG["ruby_version"]
6
+ ruby_version = ruby_version.split(".")[0..1].join(".")
7
+
8
+ if ruby_version == "1.8"
9
+ $CFLAGS = $CFLAGS + " -DRUBY1_8"
10
+ elsif ruby_version == "1.9"
11
+ $CFLAGS = $CFLAGS + " -DRUBY1_9"
12
+ else
13
+ print "ERROR: unknown ruby version: #{ruby_version}\n"
14
+ print "try passing the rubyversion by argument (1.8 or 1.9)\n"
15
+ end
16
+
17
+ $CFLAGS = $CFLAGS + " -o $@"
18
+
19
+ create_makefile('getsource_base')
20
+
21
+
22
+
@@ -0,0 +1,212 @@
1
+ /*
2
+
3
+ This file is part of the getsource project, http://github.com/tario/getsource
4
+
5
+ Copyright (c) 2009-2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ getsource is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ getsource is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with getsource. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ */
21
+
22
+ #include <ruby.h>
23
+
24
+ #ifdef RUBY1_8
25
+ #include <node.h>
26
+ #endif
27
+
28
+ #ifdef RUBY1_9
29
+ #include <node_defs.h>
30
+ #endif
31
+
32
+ #ifndef __USE_GNU
33
+ #define __USE_GNU
34
+ #endif
35
+ #include <dlfcn.h>
36
+
37
+
38
+ VALUE rb_cNode;
39
+ ID intern_owner;
40
+ ID intern_name;
41
+ ID intern_sym;
42
+
43
+ /// from eval.c
44
+ #ifdef RUBY1_8
45
+ struct METHOD {
46
+ VALUE klass, rklass;
47
+
48
+ VALUE recv;
49
+ ID id, oid;
50
+ int safe_level;
51
+ NODE *body;
52
+ };
53
+ unsigned char* base__;
54
+
55
+ #define nd_file(n) n->nd_file
56
+
57
+ #endif
58
+
59
+ #ifdef RUBY1_9
60
+
61
+ // from proc.c
62
+ struct METHOD {
63
+ VALUE oclass; /* class that holds the method */
64
+ VALUE rclass; /* class of the receiver */
65
+ VALUE recv;
66
+ ID id, oid;
67
+ NODE *body;
68
+ };
69
+
70
+ typedef struct rb_iseq_struct__ {
71
+ VALUE type; // instruction sequence type
72
+ VALUE name; // String: iseq name
73
+ VALUE filename; // file information where this sequence from
74
+ } rb_iseq_t__;
75
+
76
+
77
+ typedef VALUE (*MNEW)(VALUE klass, VALUE obj, ID id, VALUE mclass, int scope);
78
+ MNEW mnew_;
79
+ unsigned char* base__;
80
+
81
+ #endif
82
+
83
+ /*
84
+ The node that acts as body of the method
85
+ */
86
+ VALUE rb_method_body(VALUE self) {
87
+
88
+ // VALUE name = rb_funcall(self, intern_name, 0);
89
+ // VALUE sym = rb_funcall(name, intern_sym, 0);
90
+ // VALUE owner = rb_funcall(self, intern_owner, 0);
91
+ // NODE* body = rb_method_node(owner, SYM2ID(sym) );
92
+
93
+ struct METHOD* method;
94
+ Data_Get_Struct(self,struct METHOD,method);
95
+
96
+ if (method->body == 0) return Qnil;
97
+
98
+ #ifdef RUBY1_8
99
+ // nd_defn is only present in ruby_1.8
100
+ if (method->body->nd_defn != 0) {
101
+ return Data_Wrap_Struct(rb_cNode, 0, 0, method->body->nd_defn);
102
+ }
103
+ #endif
104
+
105
+ return Data_Wrap_Struct(rb_cNode, 0, 0, method->body);
106
+ }
107
+
108
+ /*
109
+ The number of the line where the code associated with note are defined in the ruby source file
110
+ */
111
+ VALUE rb_node_line(VALUE self) {
112
+ NODE* _node;
113
+ Data_Get_Struct(self,NODE,_node);
114
+
115
+ #ifdef RUBY1_8
116
+ return INT2FIX(nd_line(_node));
117
+ #endif
118
+
119
+ #ifdef RUBY1_9
120
+ return INT2FIX(0);
121
+ #endif
122
+ }
123
+
124
+ /*
125
+ The name of the ruby source file where the code associated with the node are defined
126
+ */
127
+ VALUE rb_node_file(VALUE self) {
128
+ NODE* _node;
129
+ Data_Get_Struct(self,NODE,_node);
130
+
131
+ #ifdef RUBY1_8
132
+ if (nd_file(_node) == NULL ) {
133
+ return rb_str_new2("");
134
+ }
135
+ return rb_str_new2(nd_file(_node) );
136
+ #endif
137
+
138
+ #ifdef RUBY1_9
139
+
140
+ if (nd_type(_node) == RUBY_VM_METHOD_NODE) {
141
+ VALUE iseqval = (VALUE)(_node->nd_body);
142
+ rb_iseq_t__* ptr;
143
+ Data_Get_Struct(iseqval, rb_iseq_t__, ptr);
144
+
145
+ return ptr->filename;
146
+ }
147
+
148
+ return rb_str_new2("");
149
+
150
+ #endif
151
+
152
+ }
153
+
154
+
155
+ static void
156
+ bm_mark(struct METHOD *data)
157
+ {
158
+ #ifdef RUBY1_8
159
+ rb_gc_mark(data->klass);
160
+ rb_gc_mark(data->rklass);
161
+ rb_gc_mark(data->recv);
162
+ rb_gc_mark((VALUE)data->body);
163
+ #endif
164
+ #ifdef RUBY1_9
165
+ rb_gc_mark(data->rclass);
166
+ rb_gc_mark(data->oclass);
167
+ rb_gc_mark(data->recv);
168
+ rb_gc_mark((VALUE)data->body);
169
+ #endif
170
+
171
+ }
172
+
173
+ static VALUE
174
+ umethod_unchecked_bind(VALUE method, VALUE recv)
175
+ {
176
+ struct METHOD *data, *bound;
177
+
178
+ Data_Get_Struct(method, struct METHOD, data);
179
+
180
+ method = Data_Make_Struct(rb_cMethod, struct METHOD, bm_mark, -1, bound);
181
+ *bound = *data;
182
+ bound->recv = recv;
183
+ #ifdef RUBY1_8
184
+ bound->rklass = CLASS_OF(recv);
185
+ #endif
186
+ #ifdef RUBY1_9
187
+ bound->rclass = CLASS_OF(recv);
188
+ #endif
189
+
190
+ return method;
191
+ }
192
+
193
+
194
+ void Init_getsource_base() {
195
+ rb_define_method(rb_cMethod, "body", rb_method_body,0);
196
+ rb_define_method(rb_cUnboundMethod, "body", rb_method_body,0);
197
+ rb_define_method(rb_cUnboundMethod, "unchecked_bind", umethod_unchecked_bind,1);
198
+
199
+ /*
200
+ The class Node represents the internal ruby node, a node is a piece of ruby code used
201
+ for represent ruby methods in memory and other executable entities, many nodes come from
202
+ the ruby source code and may be associated with a file and line where thats node are defined
203
+ */
204
+ rb_cNode = rb_define_class("Node", rb_cObject);
205
+
206
+ rb_define_method(rb_cNode, "line", rb_node_line, 0);
207
+ rb_define_method(rb_cNode, "file", rb_node_file, 0);
208
+
209
+ intern_owner = rb_intern("owner");
210
+ intern_name = rb_intern("name");
211
+ intern_sym = rb_intern("to_sym");
212
+ }
@@ -0,0 +1,38 @@
1
+ =begin
2
+
3
+ This file is part of the getsource project, http://github.com/tario/getsource
4
+
5
+ Copyright (c) 2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ getsource is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ getsource is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with getsource. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ require "getsource_base"
22
+
23
+ class Object
24
+ def specific_method(arg1, arg2=nil)
25
+ if arg2
26
+ method_name = arg2
27
+ klass = arg1
28
+
29
+ if instance_of? Class
30
+ method(method_name)
31
+ else
32
+ klass.instance_method(method_name).bind(self)
33
+ end
34
+ else
35
+ method(arg1)
36
+ end
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: getsource
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Dario Seminara
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-30 00:00:00 -03:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description:
23
+ email: robertodarioseminara@gmail.com
24
+ executables: []
25
+
26
+ extensions:
27
+ - ext/getsource_base/extconf.rb
28
+ extra_rdoc_files:
29
+ - README
30
+ files:
31
+ - examples/test1/source1.rb
32
+ - examples/test1/main.rb
33
+ - examples/test1/source2.rb
34
+ - lib/getsource.rb
35
+ - ext/getsource_base/getsource_base.c
36
+ - ext/getsource_base/extconf.rb
37
+ - AUTHORS
38
+ - CHANGELOG
39
+ - README
40
+ - Rakefile
41
+ - TODO
42
+ has_rdoc: true
43
+ homepage: http://github.com/tario/getsource
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --main
49
+ - README
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ hash: 3
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 1.3.7
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Get the source file path of the implementation of a given method
77
+ test_files: []
78
+