fast_method_source 0.3.1 → 0.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +23 -25
- data/VERSION +1 -1
- data/ext/fast_method_source/extconf.rb +3 -1
- data/ext/fast_method_source/fast_method_source.c +251 -147
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0cd70578b6aaaef59d7671494865a18c5e86de0
|
4
|
+
data.tar.gz: 247ab14fe91beb917dd9d136682707594c3d3e47
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b799a52825b9e85e26a8084138240e37f5cf75db475d72935b6f0eb63464293685a89bf2e783f549a87666568bf086a9ea2a3afc536c218c9dddd6afedf62ab8
|
7
|
+
data.tar.gz: 385239928c2a382550889de7dfdcb3547f44b5e8b11c0c63cafc061887bd6b6a64d095a96af2e817d84f56716b18db5f0146143b0437989b183f405e483cfd49
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
Fast Method Source changelog
|
2
2
|
============================
|
3
3
|
|
4
|
+
### v0.4.0 (June 18, 2015)
|
5
|
+
|
6
|
+
* _Significantly_ improve speed of both `#soruce` and `#comment`. The trade-off
|
7
|
+
is that you must indent methods properly.
|
8
|
+
* Decrease memeory consumption
|
9
|
+
|
4
10
|
### v0.3.1 (June 11, 2015)
|
5
11
|
|
6
12
|
* Considerable speed improvements
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
<a name="Back_to_top">
|
2
2
|
# Fast Method Source
|
3
3
|
|
4
|
+
[](https://travis-ci.org/kyrylo/fast_method_source)
|
5
|
+
|
4
6
|
* Repository: [https://github.com/kyrylo/fast_method_source/][repo]
|
5
7
|
|
6
8
|
Table of Contents
|
@@ -24,7 +26,6 @@ Table of Contents
|
|
24
26
|
* <a href="#rubies">Rubies</a>
|
25
27
|
* <a href="#operation-systems">Operation Systems</a>
|
26
28
|
* <a href="#roadmap">Roadmap</a>
|
27
|
-
* <a href="#further-speed-improvements">Further Speed Improvements</a>
|
28
29
|
* <a href="#optional-memoization">Optional Memoization</a>
|
29
30
|
* <a href="#licence">Licence</a>
|
30
31
|
|
@@ -91,15 +92,15 @@ does not support it at the moment.
|
|
91
92
|
Processor: Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz
|
92
93
|
Platform: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
|
93
94
|
Counting the number of sample methods...
|
94
|
-
Sample methods:
|
95
|
+
Sample methods: 19280
|
95
96
|
Rehearsal -----------------------------------------------------------
|
96
|
-
FastMethodSource#source
|
97
|
-
MethodSource#source
|
98
|
-
------------------------------------------------- total:
|
97
|
+
FastMethodSource#source 0.760000 0.240000 1.000000 ( 1.104455)
|
98
|
+
MethodSource#source 53.240000 0.250000 53.490000 ( 59.304424)
|
99
|
+
------------------------------------------------- total: 54.490000sec
|
99
100
|
|
100
101
|
user system total real
|
101
|
-
FastMethodSource#source
|
102
|
-
MethodSource#source
|
102
|
+
FastMethodSource#source 0.610000 0.190000 0.800000 ( 0.890971)
|
103
|
+
MethodSource#source 51.770000 0.230000 52.000000 ( 57.640986)
|
103
104
|
```
|
104
105
|
|
105
106
|
#### #comment
|
@@ -109,15 +110,15 @@ MethodSource#source 80.470000 0.310000 80.780000 ( 89.864366)
|
|
109
110
|
Processor: Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz
|
110
111
|
Platform: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
|
111
112
|
Counting the number of sample methods...
|
112
|
-
Sample methods:
|
113
|
+
Sample methods: 19437
|
113
114
|
Rehearsal ------------------------------------------------------------
|
114
|
-
FastMethodSource#comment
|
115
|
-
MethodSource#comment
|
116
|
-
-------------------------------------------------- total:
|
115
|
+
FastMethodSource#comment 0.180000 0.170000 0.350000 ( 0.395569)
|
116
|
+
MethodSource#comment 19.860000 0.230000 20.090000 ( 36.373289)
|
117
|
+
-------------------------------------------------- total: 20.440000sec
|
117
118
|
|
118
119
|
user system total real
|
119
|
-
FastMethodSource#comment
|
120
|
-
MethodSource#comment
|
120
|
+
FastMethodSource#comment 0.270000 0.190000 0.460000 ( 0.520414)
|
121
|
+
MethodSource#comment 19.360000 0.020000 19.380000 ( 21.726528)
|
121
122
|
```
|
122
123
|
|
123
124
|
#### #comment_and_source
|
@@ -129,9 +130,9 @@ This is a convenience method, and method_source doesn't have it.
|
|
129
130
|
Processor: Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz
|
130
131
|
Platform: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
|
131
132
|
Counting the number of sample methods...
|
132
|
-
Sample methods:
|
133
|
+
Sample methods: 19435
|
133
134
|
user system total real
|
134
|
-
FastMethodSource#comment_and_source_for
|
135
|
+
FastMethodSource#comment_and_source_for 0.810000 0.420000 1.230000 ( 1.374435)
|
135
136
|
```
|
136
137
|
|
137
138
|
### Correctness Of Output
|
@@ -163,8 +164,9 @@ expected. Feel free to file issues.
|
|
163
164
|
### RAM Consumption
|
164
165
|
|
165
166
|
The [`comment_and_source`](/benchmarks/comment_and_source_for.rb) benchmark
|
166
|
-
shows that the library uses about
|
167
|
-
|
167
|
+
shows that the library uses about 10 MB of RES RAM for computing information for
|
168
|
+
19K methods. I measure with `htop`, manually. If you know a better way to
|
169
|
+
measure RAM, please drop a letter here: `silin@kyrylo.org`.
|
168
170
|
|
169
171
|
API
|
170
172
|
---
|
@@ -247,7 +249,8 @@ Limitations
|
|
247
249
|
|
248
250
|
### Rubies
|
249
251
|
|
250
|
-
* CRuby 2.
|
252
|
+
* CRuby 2.1.x
|
253
|
+
* CRuby 2.2.x
|
251
254
|
* CRuby 2.3.0dev and higher
|
252
255
|
|
253
256
|
Rubies below 2.2.2 were not tested, so in theory if it quacks like Ruby 2, it
|
@@ -261,13 +264,6 @@ may work.
|
|
261
264
|
Roadmap
|
262
265
|
-------
|
263
266
|
|
264
|
-
### Further Speed Improvements
|
265
|
-
|
266
|
-
Although Fast Method Source is faster than any of its competitors, it's still
|
267
|
-
very slow. On average, a mature Rails 4 application has at least 45K
|
268
|
-
methods. The goal of the project is to be able to query 50K methods in less than
|
269
|
-
15 seconds.
|
270
|
-
|
271
267
|
### Optional Memoization
|
272
268
|
|
273
269
|
I'm not sure about this, if it's really needed, but it will speed up further
|
@@ -278,6 +274,8 @@ should be optional and configurable like this:
|
|
278
274
|
FastMethodSource.memoization = true # or `false`
|
279
275
|
```
|
280
276
|
|
277
|
+
So far I'm happy about the speed of the library.
|
278
|
+
|
281
279
|
Licence
|
282
280
|
-------
|
283
281
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
@@ -3,6 +3,9 @@
|
|
3
3
|
|
4
4
|
#include <stdio.h>
|
5
5
|
#include <stdlib.h>
|
6
|
+
#include <sys/mman.h>
|
7
|
+
#include <sys/stat.h>
|
8
|
+
#include <fcntl.h>
|
6
9
|
#include <ruby.h>
|
7
10
|
|
8
11
|
#include "node.h"
|
@@ -19,9 +22,28 @@ static const char *null_filename = "/dev/null";
|
|
19
22
|
#define DUP2(fd, newfd) dup2(fd, newfd)
|
20
23
|
#endif
|
21
24
|
|
22
|
-
#
|
25
|
+
#ifndef HAVE_RB_SYM2STR
|
26
|
+
# define rb_sym2str(obj) rb_id2str(SYM2ID(obj))
|
27
|
+
#endif
|
23
28
|
|
24
|
-
#
|
29
|
+
#ifdef __APPLE__
|
30
|
+
void *
|
31
|
+
memrchr(const void *s, int c, size_t n)
|
32
|
+
{
|
33
|
+
const unsigned char *cp;
|
34
|
+
|
35
|
+
if (n != 0) {
|
36
|
+
cp = (unsigned char *)s + n;
|
37
|
+
do {
|
38
|
+
if (*(--cp) == (unsigned char)c)
|
39
|
+
return((void *)cp);
|
40
|
+
} while (--n != 0);
|
41
|
+
}
|
42
|
+
return NULL;
|
43
|
+
}
|
44
|
+
#else
|
45
|
+
void *memrchr(const void *s, int c, size_t n);
|
46
|
+
#endif
|
25
47
|
|
26
48
|
typedef struct {
|
27
49
|
int source : 1;
|
@@ -39,18 +61,19 @@ static VALUE read_lines_before(struct method_data *data);
|
|
39
61
|
static VALUE read_lines_after(struct method_data *data);
|
40
62
|
static VALUE find_method_comment(struct method_data *data);
|
41
63
|
static VALUE find_method_source(struct method_data *data);
|
64
|
+
static VALUE find_comment_expression(struct method_data *data);
|
65
|
+
static VALUE find_source_expression(struct method_data *data);
|
42
66
|
static NODE *parse_expr(VALUE rb_str);
|
43
67
|
static NODE *parse_with_silenced_stderr(VALUE rb_str);
|
44
|
-
static void
|
45
|
-
static int
|
68
|
+
static void restore_ch(char *line, char ch, int last_ch_idx);
|
69
|
+
static void close_map(int fd, char *map, size_t map_size, const char *filename);
|
70
|
+
static void nulify_ch(char *line, char *ch, int last_ch_idx);
|
46
71
|
static int contains_end_kw(const char *line);
|
47
72
|
static int is_comment(const char *line, const size_t line_len);
|
48
|
-
static int
|
49
|
-
static int
|
50
|
-
static
|
51
|
-
static int is_dangling_literal_begin(const char *line);
|
73
|
+
static int is_definition_end(const char *line);
|
74
|
+
static int is_static_definition_start(const char *line);
|
75
|
+
static size_t count_prefix_spaces(const char *line);
|
52
76
|
static void raise_if_nil(VALUE val, VALUE method_name);
|
53
|
-
static void realloc_expression(char **expression, size_t len);
|
54
77
|
static void method_data_init(VALUE self, struct method_data *data);
|
55
78
|
static VALUE mMethodExtensions_source(VALUE self);
|
56
79
|
|
@@ -83,118 +106,192 @@ read_lines_before(struct method_data *data)
|
|
83
106
|
}
|
84
107
|
|
85
108
|
static VALUE
|
86
|
-
|
109
|
+
find_comment_expression(struct method_data *data)
|
87
110
|
{
|
88
|
-
|
111
|
+
struct stat filestat;
|
112
|
+
int fd;
|
113
|
+
char *map;
|
114
|
+
|
115
|
+
VALUE comment = Qnil;
|
89
116
|
|
90
|
-
if ((
|
91
|
-
rb_raise(rb_eIOError, "
|
117
|
+
if ((fd = open(data->filename, O_RDONLY)) == -1) {
|
118
|
+
rb_raise(rb_eIOError, "failed to read - %s", data->filename);
|
92
119
|
}
|
93
120
|
|
94
|
-
|
95
|
-
|
121
|
+
if (fstat(fd, &filestat) == -1) {
|
122
|
+
rb_raise(rb_eIOError, "filestat failed for %s", data->filename);
|
123
|
+
}
|
124
|
+
|
125
|
+
map = mmap(NULL, filestat.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
126
|
+
if (map == MAP_FAILED) {
|
127
|
+
rb_raise(rb_eIOError, "mmap failed for %s", data->filename);
|
128
|
+
}
|
96
129
|
|
97
|
-
|
98
|
-
|
130
|
+
char *rest = map;
|
131
|
+
unsigned line_count = 0;
|
99
132
|
|
100
|
-
|
101
|
-
|
133
|
+
while (line_count++ != data->method_location - 1) {
|
134
|
+
rest = (char *) memchr(rest, '\n', filestat.st_size) + 1;
|
135
|
+
}
|
102
136
|
|
103
|
-
|
104
|
-
|
137
|
+
size_t end = filestat.st_size - strlen(rest);
|
138
|
+
map[end] = '\0';
|
105
139
|
|
106
|
-
|
107
|
-
|
140
|
+
size_t offset = end;
|
141
|
+
char *prev = NULL;
|
108
142
|
|
109
|
-
|
110
|
-
|
143
|
+
while (line_count-- != 0) {
|
144
|
+
rest = memrchr(map, '\n', offset - 2);
|
111
145
|
|
112
|
-
|
146
|
+
if (rest == NULL) {
|
147
|
+
rest = memrchr(map, '\n', offset);
|
148
|
+
} else {
|
149
|
+
rest++;
|
150
|
+
}
|
113
151
|
|
114
|
-
|
115
|
-
line_count++;
|
152
|
+
offset = end - strlen(rest);
|
116
153
|
|
117
|
-
if (
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
154
|
+
if (is_comment(rest, offset)) {
|
155
|
+
prev = rest;
|
156
|
+
} else {
|
157
|
+
if (prev == NULL) {
|
158
|
+
comment = rb_str_new("", 0);
|
159
|
+
} else {
|
160
|
+
comment = rb_str_new2(prev);
|
122
161
|
}
|
123
|
-
strncat(expression, current_line, cl_len);
|
124
162
|
|
125
|
-
|
126
|
-
|
127
|
-
|
163
|
+
break;
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
if (munmap (map, filestat.st_size) == -1) {
|
168
|
+
rb_raise(rb_eIOError, "munmap failed for %s", data->filename);
|
169
|
+
}
|
170
|
+
close(fd);
|
171
|
+
|
172
|
+
return comment;
|
173
|
+
}
|
174
|
+
|
175
|
+
static VALUE
|
176
|
+
find_source_expression(struct method_data *data)
|
177
|
+
{
|
178
|
+
struct stat filestat;
|
179
|
+
int fd;
|
180
|
+
char *map;
|
181
|
+
|
182
|
+
VALUE source = Qnil;
|
183
|
+
|
184
|
+
if ((fd = open(data->filename, O_RDONLY)) == -1) {
|
185
|
+
rb_raise(rb_eIOError, "failed to read - %s", data->filename);
|
186
|
+
}
|
187
|
+
|
188
|
+
if (fstat(fd, &filestat) == -1) {
|
189
|
+
rb_raise(rb_eIOError, "filestat failed for %s", data->filename);
|
190
|
+
}
|
191
|
+
|
192
|
+
map = mmap(NULL, filestat.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
193
|
+
if (map == MAP_FAILED) {
|
194
|
+
rb_raise(rb_eIOError, "mmap failed for %s", data->filename);
|
195
|
+
}
|
196
|
+
|
197
|
+
char *expr_start = map;
|
198
|
+
char *expr_end, *next_expr, *line;
|
199
|
+
unsigned line_count = 0;
|
200
|
+
|
201
|
+
while (line_count++ != data->method_location - 1) {
|
202
|
+
expr_start = (char *) memchr(expr_start, '\n', filestat.st_size) + 1;
|
203
|
+
}
|
204
|
+
|
205
|
+
size_t last_ch_idx;
|
206
|
+
char ch, next_ch;
|
207
|
+
next_expr = expr_end = expr_start;
|
208
|
+
size_t leftover_size = filestat.st_size - strlen(expr_end);
|
209
|
+
size_t offset = filestat.st_size - leftover_size;
|
210
|
+
size_t next_offset;
|
211
|
+
size_t prefix_len = 0;
|
212
|
+
int inside_static_def = 0;
|
213
|
+
int should_parse = 0;
|
214
|
+
VALUE rb_expr;
|
215
|
+
|
216
|
+
while (offset != 0) {
|
217
|
+
next_expr = (char *) memchr(expr_end, '\n', offset) + 1;
|
218
|
+
next_offset = strlen(next_expr);
|
219
|
+
line = expr_end;
|
220
|
+
|
221
|
+
last_ch_idx = offset - next_offset - 1;
|
222
|
+
|
223
|
+
nulify_ch(line, &ch, last_ch_idx);
|
224
|
+
|
225
|
+
expr_end = next_expr;
|
226
|
+
offset = next_offset;
|
227
|
+
|
228
|
+
if (is_static_definition_start(line) && !inside_static_def) {
|
229
|
+
inside_static_def = 1;
|
230
|
+
prefix_len = count_prefix_spaces(line);
|
128
231
|
|
129
|
-
if (
|
130
|
-
if (
|
131
|
-
|
232
|
+
if (contains_end_kw(line)) {
|
233
|
+
if (parse_expr(rb_str_new2(line)) != NULL) {
|
234
|
+
restore_ch(line, ch, last_ch_idx);
|
235
|
+
rb_expr = rb_str_new2(expr_start);
|
236
|
+
|
237
|
+
close_map(fd, map, filestat.st_size, data->filename);
|
238
|
+
return rb_expr;
|
132
239
|
}
|
133
240
|
}
|
241
|
+
}
|
134
242
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
} else if (dangling_literal) {
|
140
|
-
continue;
|
141
|
-
}
|
243
|
+
if (line[0] == '\n' || is_comment(line, strlen(line))) {
|
244
|
+
line[last_ch_idx] = ch;
|
245
|
+
continue;
|
246
|
+
}
|
142
247
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
248
|
+
if (inside_static_def) {
|
249
|
+
if (is_definition_end(line) &&
|
250
|
+
count_prefix_spaces(line) == prefix_len)
|
251
|
+
{
|
252
|
+
restore_ch(line, ch, last_ch_idx);
|
253
|
+
rb_expr = rb_str_new2(expr_start);
|
254
|
+
|
255
|
+
close_map(fd, map, filestat.st_size, data->filename);
|
256
|
+
return rb_expr;
|
257
|
+
} else {
|
258
|
+
line[last_ch_idx] = ch;
|
259
|
+
continue;
|
148
260
|
}
|
149
|
-
|
261
|
+
} else {
|
262
|
+
should_parse = 1;
|
263
|
+
}
|
150
264
|
|
151
|
-
|
152
|
-
|
265
|
+
if (should_parse) {
|
266
|
+
line[last_ch_idx] = ch;
|
267
|
+
nulify_ch(line, &next_ch, last_ch_idx + 1);
|
153
268
|
|
154
|
-
if (
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
} else if (finder.comment) {
|
161
|
-
if (line_count < data->method_location) {
|
162
|
-
if (is_comment(current_line, cl_len)) {
|
163
|
-
future_bufsize = strlen(expression) + cl_len;
|
164
|
-
if (future_bufsize >= bufsize) {
|
165
|
-
bufsize = future_bufsize + EXPRESSION_SIZE + 1;
|
166
|
-
realloc_expression(&expression, bufsize);
|
167
|
-
}
|
168
|
-
strncat(expression, current_line, cl_len);
|
169
|
-
} else {
|
170
|
-
expression[0] = '\0';
|
171
|
-
bufsize = EXPRESSION_SIZE;
|
172
|
-
}
|
173
|
-
} else if (line_count == data->method_location) {
|
174
|
-
found_expression = 1;
|
175
|
-
break;
|
269
|
+
if (parse_expr(rb_str_new2(expr_start)) != NULL) {
|
270
|
+
rb_expr = rb_str_new2(expr_start);
|
271
|
+
close_map(fd, map, filestat.st_size, data->filename);
|
272
|
+
return rb_expr;
|
273
|
+
} else {
|
274
|
+
line[last_ch_idx+1] = next_ch;
|
176
275
|
}
|
177
276
|
}
|
178
|
-
}
|
179
277
|
|
180
|
-
|
181
|
-
rb_expr = rb_str_new2(expression);
|
182
|
-
} else {
|
183
|
-
rb_expr = Qnil;
|
278
|
+
line[last_ch_idx] = ch;
|
184
279
|
}
|
280
|
+
close_map(fd, map, filestat.st_size, data->filename);
|
185
281
|
|
186
|
-
|
187
|
-
xfree(expression);
|
188
|
-
free(current_line);
|
189
|
-
fclose(fp);
|
190
|
-
return (rb_expr);
|
282
|
+
return source;
|
191
283
|
}
|
192
284
|
|
193
|
-
static
|
194
|
-
|
285
|
+
static VALUE
|
286
|
+
read_lines(finder finder, struct method_data *data)
|
195
287
|
{
|
196
|
-
|
197
|
-
|
288
|
+
if (finder.comment) {
|
289
|
+
return find_comment_expression(data);
|
290
|
+
} else if (finder.source) {
|
291
|
+
return find_source_expression(data);
|
292
|
+
}
|
293
|
+
|
294
|
+
return Qnil;
|
198
295
|
}
|
199
296
|
|
200
297
|
static NODE *
|
@@ -228,52 +325,59 @@ parse_expr(VALUE rb_str) {
|
|
228
325
|
}
|
229
326
|
|
230
327
|
static void
|
231
|
-
|
328
|
+
restore_ch(char *line, char ch, int last_ch_idx)
|
232
329
|
{
|
233
|
-
|
330
|
+
line[last_ch_idx] = ch;
|
331
|
+
line[last_ch_idx + 1] = '\0';
|
332
|
+
}
|
234
333
|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
334
|
+
static void
|
335
|
+
close_map(int fd, char *map, size_t map_size, const char *filename)
|
336
|
+
{
|
337
|
+
close(fd);
|
338
|
+
if (munmap(map, map_size) == -1) {
|
339
|
+
rb_raise(rb_eIOError, "munmap failed for %s", filename);
|
340
|
+
}
|
341
|
+
}
|
239
342
|
|
240
|
-
|
343
|
+
static void
|
344
|
+
nulify_ch(char *line, char *ch, int last_ch_idx)
|
345
|
+
{
|
346
|
+
*ch = line[last_ch_idx];
|
347
|
+
line[last_ch_idx] = '\0';
|
348
|
+
}
|
241
349
|
|
242
|
-
|
243
|
-
|
244
|
-
|
350
|
+
static size_t
|
351
|
+
count_prefix_spaces(const char *line)
|
352
|
+
{
|
353
|
+
int i = 0;
|
354
|
+
size_t spaces = 0;
|
355
|
+
|
356
|
+
do {
|
357
|
+
if (line[i] == ' ') {
|
358
|
+
spaces++;
|
359
|
+
} else {
|
360
|
+
break;
|
245
361
|
}
|
362
|
+
} while (line[i++] != '\n');
|
246
363
|
|
247
|
-
|
248
|
-
brackets--;
|
249
|
-
|
250
|
-
if (brackets == 0) {
|
251
|
-
line[i] = SAFE_CHAR;
|
252
|
-
}
|
253
|
-
} else if (brackets > 0) {
|
254
|
-
line[i] = SAFE_CHAR;
|
255
|
-
}
|
256
|
-
}
|
364
|
+
return spaces;
|
257
365
|
}
|
258
366
|
|
259
367
|
static int
|
260
|
-
|
368
|
+
is_definition_end(const char *line)
|
261
369
|
{
|
370
|
+
int i = 0;
|
262
371
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
" while ", " = ", " == ", " === ", " > ", " < ", " >= ", " <= ",
|
268
|
-
" << ", " += ", "\"", "'", ":", ",", ".", " % ", "!", "?",
|
269
|
-
" until ", "(&", "|", "(", ")", "~", " * ", " - ", " + ", " / ",
|
270
|
-
" {", " raise ", " fail ", " begin ", " rescue ", " ensure ",
|
271
|
-
".new", "@", " lambda", " proc", " ->", "[", "]", "$"};
|
272
|
-
|
273
|
-
for (unsigned short i = 0; i < len; i++) {
|
274
|
-
if (strstr(line, skippables[i]) != NULL)
|
372
|
+
do {
|
373
|
+
if (line[i] == ' ') {
|
374
|
+
continue;
|
375
|
+
} else if (strncmp((line + i), "end", 3) == 0) {
|
275
376
|
return 1;
|
276
|
-
|
377
|
+
} else {
|
378
|
+
return 0;
|
379
|
+
}
|
380
|
+
} while (line[i++] != '\0');
|
277
381
|
|
278
382
|
return 0;
|
279
383
|
}
|
@@ -292,20 +396,13 @@ contains_end_kw(const char *line)
|
|
292
396
|
}
|
293
397
|
}
|
294
398
|
|
295
|
-
static int
|
296
|
-
is_accessor(const char *line)
|
297
|
-
{
|
298
|
-
return strstr(line, "attr_reader") != NULL ||
|
299
|
-
strstr(line, "attr_writer") != NULL ||
|
300
|
-
strstr(line, "attr_accessor") != NULL;
|
301
|
-
}
|
302
|
-
|
303
399
|
static int
|
304
400
|
is_comment(const char *line, const size_t line_len)
|
305
401
|
{
|
306
402
|
for (size_t i = 0; i < line_len; i++) {
|
307
403
|
if (line[i] == ' ')
|
308
404
|
continue;
|
405
|
+
|
309
406
|
return line[i] == '#' && line[i + 1] != '{';
|
310
407
|
}
|
311
408
|
|
@@ -313,29 +410,36 @@ is_comment(const char *line, const size_t line_len)
|
|
313
410
|
}
|
314
411
|
|
315
412
|
static int
|
316
|
-
|
413
|
+
is_static_definition_start(const char *line)
|
317
414
|
{
|
318
|
-
|
319
|
-
}
|
415
|
+
int i = 0;
|
320
416
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
417
|
+
do {
|
418
|
+
if (line[i] == ' ') {
|
419
|
+
continue;
|
420
|
+
} else if (strncmp((line + i), "def ", 4) == 0) {
|
421
|
+
return 1;
|
422
|
+
} else if (strncmp((line + i), "class ", 6) == 0) {
|
423
|
+
return 1;
|
424
|
+
} else {
|
425
|
+
return 0;
|
426
|
+
}
|
427
|
+
} while (line[i++] != '\0');
|
326
428
|
|
327
|
-
|
328
|
-
is_dangling_literal_begin(const char *line)
|
329
|
-
{
|
330
|
-
return strstr(line, "%{") != NULL && strstr(line, "}") == NULL;
|
429
|
+
return 0;
|
331
430
|
}
|
332
431
|
|
333
432
|
static void
|
334
433
|
raise_if_nil(VALUE val, VALUE method_name)
|
335
434
|
{
|
336
435
|
if (NIL_P(val)) {
|
337
|
-
|
338
|
-
|
436
|
+
if (SYMBOL_P(method_name)) {
|
437
|
+
rb_raise(rb_eSourceNotFoundError, "could not locate source for %s",
|
438
|
+
RSTRING_PTR(rb_sym2str(method_name)));
|
439
|
+
} else {
|
440
|
+
rb_raise(rb_eSourceNotFoundError, "could not locate source for %s",
|
441
|
+
RSTRING_PTR(method_name));
|
442
|
+
}
|
339
443
|
}
|
340
444
|
}
|
341
445
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fast_method_source
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyrylo Silin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|