getsource 0.1.0

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