fast_method_source 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/kyrylo/fast_method_source.svg?branch=master)](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
|