fancy 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +38 -86
- data/bin/fdoc +2 -22
- data/bin/fspec +8 -3
- data/bin/ifancy +1 -1
- data/boot/fancy_ext.rb +1 -0
- data/boot/fancy_ext/array.rb +19 -0
- data/boot/fancy_ext/class.rb +2 -4
- data/boot/fancy_ext/module.rb +2 -0
- data/boot/fancy_ext/object.rb +0 -17
- data/boot/rbx-compiler/compiler/ast/method_def.rb +0 -4
- data/boot/rbx-compiler/compiler/ast/singleton_method_def.rb +0 -7
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/fancy_parser.c +1 -0
- data/doc/api/fancy.css +10 -1
- data/doc/api/fancy.jsonp +1 -1
- data/doc/api/fdoc.js +22 -9
- data/doc/api/octocat.png +0 -0
- data/doc/features.md +1 -2
- data/examples/actors.fy +1 -2
- data/examples/armstrong_numbers.fy +7 -3
- data/examples/blocks.fy +3 -3
- data/examples/distributing_proxy.fy +31 -0
- data/examples/future_sends.fy +15 -0
- data/examples/person.fy +1 -2
- data/lib/argv.fy +1 -7
- data/lib/array.fy +7 -11
- data/lib/block.fy +15 -0
- data/lib/boot.fy +4 -3
- data/lib/class.fy +354 -10
- data/lib/compiler.fy +1 -1
- data/lib/compiler/ast/assign.fy +4 -8
- data/lib/compiler/ast/async_send.fy +1 -2
- data/lib/compiler/ast/block.fy +5 -0
- data/lib/compiler/ast/class_def.fy +2 -1
- data/lib/compiler/ast/expression_list.fy +1 -2
- data/lib/compiler/ast/future_send.fy +1 -2
- data/lib/compiler/ast/identifier.fy +34 -17
- data/lib/compiler/ast/literals.fy +31 -19
- data/lib/compiler/ast/match.fy +5 -4
- data/lib/compiler/ast/message_send.fy +3 -5
- data/lib/compiler/ast/method_def.fy +0 -3
- data/lib/compiler/ast/range.fy +2 -4
- data/lib/compiler/ast/return.fy +2 -4
- data/lib/compiler/ast/script.fy +2 -4
- data/lib/compiler/ast/singleton_method_def.fy +0 -3
- data/lib/compiler/ast/string_interpolation.fy +2 -2
- data/lib/compiler/ast/super.fy +2 -4
- data/lib/compiler/ast/try_catch.fy +13 -9
- data/lib/compiler/ast/tuple_literal.fy +1 -2
- data/lib/compiler/compiler.fy +2 -2
- data/lib/compiler/stages.fy +3 -6
- data/lib/contracts.fy +89 -57
- data/lib/dynamic_slot_object.fy +21 -3
- data/lib/enumerable.fy +140 -4
- data/lib/enumerator.fy +1 -1
- data/lib/eval.fy +23 -9
- data/lib/exception.fy +16 -0
- data/lib/false_class.fy +36 -5
- data/lib/fancy_spec.fy +64 -34
- data/lib/fdoc.fy +85 -24
- data/lib/file.fy +19 -0
- data/lib/future.fy +4 -46
- data/lib/hash.fy +113 -0
- data/lib/integer.fy +25 -6
- data/lib/iteration.fy +3 -3
- data/lib/main.fy +5 -0
- data/lib/matchers.fy +79 -0
- data/lib/nil_class.fy +8 -0
- data/lib/object.fy +109 -18
- data/lib/option_parser.fy +118 -0
- data/lib/package/dependency.fy +4 -8
- data/lib/package/dependency_installer.fy +1 -1
- data/lib/package/handler.fy +6 -0
- data/lib/package/installer.fy +43 -16
- data/lib/package/list.fy +1 -2
- data/lib/package/specification.fy +5 -5
- data/lib/package/uninstaller.fy +9 -2
- data/lib/parser.fy +1 -3
- data/lib/parser/ext/ext.c +1 -0
- data/lib/parser/ext/lexer.lex +5 -0
- data/lib/parser/methods.fy +48 -46
- data/lib/proxies.fy +151 -0
- data/lib/rbx.fy +1 -0
- data/lib/rbx/actor.fy +16 -18
- data/lib/rbx/array.fy +18 -3
- data/lib/rbx/block.fy +1 -7
- data/lib/rbx/class.fy +54 -9
- data/lib/rbx/code_loader.fy +2 -5
- data/lib/rbx/compiled_method.fy +31 -0
- data/lib/rbx/debugger.fy +66 -0
- data/lib/rbx/directory.fy +8 -3
- data/lib/rbx/documentation.fy +1 -1
- data/lib/rbx/file.fy +22 -0
- data/lib/rbx/integer.fy +1 -1
- data/lib/rbx/match_data.fy +2 -1
- data/lib/rbx/method.fy +26 -0
- data/lib/rbx/object.fy +8 -3
- data/lib/rbx/regexp.fy +6 -3
- data/lib/rbx/string.fy +9 -1
- data/lib/rbx/stringio.fy +12 -0
- data/lib/rbx/symbol.fy +4 -0
- data/lib/stack.fy +1 -1
- data/lib/string.fy +34 -0
- data/lib/stringio.fy +1 -1
- data/lib/symbol.fy +6 -2
- data/lib/system.fy +15 -1
- data/lib/tuple.fy +5 -2
- data/lib/version.fy +1 -1
- data/ruby_lib/fdoc +2 -22
- data/tests/array.fy +3 -17
- data/tests/class.fy +312 -10
- data/tests/contracts.fy +51 -0
- data/tests/distributing_proxy.fy +28 -0
- data/tests/enumerable.fy +104 -1
- data/tests/exception.fy +35 -0
- data/tests/fixnum.fy +1 -1
- data/tests/hash.fy +81 -1
- data/tests/integer.fy +9 -0
- data/tests/matchers.fy +18 -0
- data/tests/method.fy +8 -14
- data/tests/object.fy +76 -2
- data/tests/option_parser.fy +80 -0
- data/tests/string.fy +21 -0
- data/tests/stringio.fy +1 -1
- data/tests/tuple.fy +1 -1
- metadata +21 -44
- data/examples/arithmetic.fy +0 -7
- data/examples/array.fy +0 -50
- data/examples/boolean.fy +0 -24
- data/examples/class.fy +0 -68
- data/examples/constant_access.fy +0 -15
- data/examples/default_args.fy +0 -20
- data/examples/define_methods.fy +0 -15
- data/examples/dynamic_output.fy +0 -15
- data/examples/empty_catch.fy +0 -4
- data/examples/exception.fy +0 -9
- data/examples/files.fy +0 -23
- data/examples/finally.fy +0 -5
- data/examples/future.fy +0 -30
- data/examples/future_composition.fy +0 -20
- data/examples/futures.fy +0 -9
- data/examples/game_of_life.fy +0 -148
- data/examples/html_generator.fy +0 -84
- data/examples/implicit_return.fy +0 -3
- data/examples/matchers.fy +0 -6
- data/examples/nested_try.fy +0 -9
- data/examples/numbers.fy +0 -12
- data/examples/rbx/and_or.fy +0 -7
- data/examples/rbx/blocks.fy +0 -22
- data/examples/rbx/classes.fy +0 -32
- data/examples/rbx/hello.fy +0 -8
- data/examples/rbx/include.fy +0 -12
- data/examples/rbx/inherit.fy +0 -11
- data/examples/rbx/methods.fy +0 -15
- data/examples/rbx/nested_classes.fy +0 -9
- data/examples/rbx/require.fy +0 -3
- data/examples/rbx/strings.fy +0 -5
- data/examples/require.fy +0 -7
- data/examples/return.fy +0 -13
- data/examples/singleton_methods.fy +0 -21
- data/examples/threads.fy +0 -18
- data/examples/tuple.fy +0 -8
- data/examples/webserver/webserver.fy +0 -15
- data/lib/proxy.fy +0 -86
- data/lib/thread_pool.fy +0 -102
data/lib/enumerator.fy
CHANGED
data/lib/eval.fy
CHANGED
@@ -1,28 +1,42 @@
|
|
1
1
|
require: "compiler"
|
2
2
|
|
3
|
-
def Fancy eval: code binding:
|
4
|
-
|
5
|
-
|
3
|
+
def Fancy eval: code binding: binding (nil) file: file ("(fancy-eval)") line: line (1) {
|
4
|
+
"""
|
5
|
+
@code @String@ of Fancy code to be evaluated.
|
6
|
+
@binding @Binding@ to evaluate @code in.
|
7
|
+
@file @String that is the name of @File@ from which @code is evaluated from (if any).
|
8
|
+
@line Starting line, defaults to 1.
|
9
|
+
"""
|
10
|
+
|
11
|
+
binding if_nil: {
|
12
|
+
binding = Binding setup(Rubinius VariableScope of_sender(),
|
6
13
|
Rubinius CompiledMethod of_sender(),
|
7
14
|
Rubinius StaticScope of_sender())
|
8
15
|
}
|
9
16
|
|
10
17
|
# The compiled method
|
11
|
-
cm = Fancy Compiler compile_code: code vars: (
|
12
|
-
|
18
|
+
cm = Fancy Compiler compile_code: code vars: (binding variables()) file: file line: line
|
19
|
+
|
20
|
+
# Binding#static_scope was renamed to Binding#constant_scope a while ago.
|
21
|
+
# if the new version fails, retry with the old name for backwards compatibility (for now).
|
22
|
+
try {
|
23
|
+
cm scope=(binding constant_scope() dup())
|
24
|
+
} catch NoMethodError {
|
25
|
+
cm scope=(binding static_scope() dup())
|
26
|
+
}
|
13
27
|
cm name=('__fancy_eval__)
|
14
28
|
|
15
29
|
script = Rubinius CompiledMethod Script new(cm, file, true)
|
16
|
-
script eval_binding=(
|
30
|
+
script eval_binding=(binding)
|
17
31
|
script eval_source=(code)
|
18
32
|
|
19
33
|
cm scope() script=(script)
|
20
34
|
|
21
35
|
be = Rubinius BlockEnvironment new()
|
22
|
-
be under_context(
|
36
|
+
be under_context(binding variables(), cm)
|
23
37
|
|
24
|
-
if: (
|
25
|
-
be proc_environment=(
|
38
|
+
if: (binding from_proc?()) then: {
|
39
|
+
be proc_environment=(binding proc_environment)
|
26
40
|
}
|
27
41
|
|
28
42
|
be from_eval!()
|
data/lib/exception.fy
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
class StandardError {
|
2
|
+
def self raise: message {
|
3
|
+
"""
|
4
|
+
Raises new @Exception@ with @message.
|
5
|
+
|
6
|
+
Example:
|
7
|
+
StandardError raise: \"Error!\"
|
8
|
+
ArgumentError raise: \"Missing argument!\"
|
9
|
+
# is the same as:
|
10
|
+
StandardError new: \"Error!\” . raise!
|
11
|
+
ArgumentError new: \"Missing argument!\" . raise!
|
12
|
+
"""
|
13
|
+
|
14
|
+
new: message . raise!
|
15
|
+
}
|
16
|
+
}
|
data/lib/false_class.fy
CHANGED
@@ -10,45 +10,76 @@ class FalseClass {
|
|
10
10
|
}
|
11
11
|
|
12
12
|
def if_true: block {
|
13
|
-
"
|
13
|
+
"""
|
14
|
+
@return @nil.
|
15
|
+
"""
|
16
|
+
|
14
17
|
nil
|
15
18
|
}
|
16
19
|
|
17
20
|
def if_true: then_block else: else_block {
|
18
|
-
"
|
21
|
+
"""
|
22
|
+
Calls @else_block.
|
23
|
+
"""
|
24
|
+
|
19
25
|
else_block call
|
20
26
|
}
|
21
27
|
|
22
28
|
def if_false: block {
|
29
|
+
"""
|
30
|
+
Calls @block with @self.
|
31
|
+
"""
|
32
|
+
|
23
33
|
block call: [self]
|
24
34
|
}
|
25
35
|
|
26
36
|
def if_false: then_block else: else_block {
|
37
|
+
"""
|
38
|
+
Calls @then_block with @self.
|
39
|
+
"""
|
40
|
+
|
27
41
|
then_block call: [self]
|
28
42
|
}
|
29
43
|
|
30
44
|
def if_nil: then_block {
|
45
|
+
"""
|
46
|
+
@return @nil.
|
47
|
+
"""
|
48
|
+
|
31
49
|
nil
|
32
50
|
}
|
33
51
|
|
34
52
|
def if_nil: then_block else: else_block {
|
53
|
+
"""
|
54
|
+
Calls @else_block with @self.
|
55
|
+
"""
|
56
|
+
|
35
57
|
else_block call: [self]
|
36
58
|
}
|
37
59
|
|
38
60
|
def false? {
|
39
|
-
"
|
61
|
+
"""
|
62
|
+
@return @true.
|
63
|
+
"""
|
64
|
+
|
40
65
|
true
|
41
66
|
}
|
42
67
|
|
43
68
|
def to_s {
|
44
|
-
"
|
69
|
+
"""
|
70
|
+
@return @false as a @String@.
|
71
|
+
"""
|
72
|
+
|
45
73
|
"false"
|
46
74
|
}
|
47
75
|
|
48
76
|
alias_method: 'inspect for: 'to_s
|
49
77
|
|
50
78
|
def to_a {
|
51
|
-
"
|
79
|
+
"""
|
80
|
+
@return An empty @Array@.
|
81
|
+
"""
|
82
|
+
|
52
83
|
[]
|
53
84
|
}
|
54
85
|
|
data/lib/fancy_spec.fy
CHANGED
@@ -20,6 +20,7 @@ class FancySpec {
|
|
20
20
|
Factory method for creating FancySpec instances.
|
21
21
|
Calls @block with the new FancySpec instance as the receiver, then runs it.
|
22
22
|
|
23
|
+
Example:
|
23
24
|
FancySpec describe: MyTestClass with: {
|
24
25
|
# test cases using it:for:when: here.
|
25
26
|
}
|
@@ -32,8 +33,9 @@ class FancySpec {
|
|
32
33
|
|
33
34
|
def FancySpec describe: description for: test_obj with: block {
|
34
35
|
"""
|
35
|
-
Similar to FancySpec
|
36
|
+
Similar to @FancySpec~describe:with:@ but also taking an explicit @test_obj.
|
36
37
|
|
38
|
+
Example:
|
37
39
|
FancySpec describe: \"My cool class\" for: MyCoolClass with: {
|
38
40
|
# test cases using it:for:when: here.
|
39
41
|
}
|
@@ -53,7 +55,7 @@ class FancySpec {
|
|
53
55
|
it: \"should be an empty Array\" when: {
|
54
56
|
arr = [1,2,3]
|
55
57
|
3 times: { arr pop }
|
56
|
-
arr empty? is
|
58
|
+
arr empty? is: true
|
57
59
|
}
|
58
60
|
"""
|
59
61
|
|
@@ -71,19 +73,23 @@ class FancySpec {
|
|
71
73
|
it: \"should be an empty Array\" with: 'empty? when: {
|
72
74
|
arr = [1,2,3]
|
73
75
|
3 times: { arr pop }
|
74
|
-
arr empty? is
|
76
|
+
arr empty? is: true
|
75
77
|
}
|
76
78
|
"""
|
77
79
|
|
78
80
|
test = SpecTest new: spec_info_string block: spec_block
|
79
|
-
|
80
|
-
# @test_obj method: method_name . if_true: |method| {
|
81
|
-
# method tests << test
|
82
|
-
# }
|
83
|
-
# } catch MethodNotFoundError => e {
|
84
|
-
# # ignore errors
|
85
|
-
# }
|
81
|
+
|
86
82
|
@spec_tests << test
|
83
|
+
|
84
|
+
match @test_obj {
|
85
|
+
case Class ->
|
86
|
+
has_method? = @test_obj has_method?: method_name
|
87
|
+
{ has_method? = @test_obj metaclass has_method?: method_name } unless: has_method?
|
88
|
+
|
89
|
+
unless: has_method? do: {
|
90
|
+
SpecTest method_not_found: method_name for: @test_obj
|
91
|
+
}
|
92
|
+
}
|
87
93
|
}
|
88
94
|
|
89
95
|
alias_method: 'it:for:when: for: 'it:with:when:
|
@@ -142,6 +148,7 @@ class FancySpec {
|
|
142
148
|
@@failed_count = 0
|
143
149
|
@@total_tests = 0
|
144
150
|
@@total_expectations = 0
|
151
|
+
@@methods_not_found = <[]>
|
145
152
|
|
146
153
|
def SpecTest add_expectation {
|
147
154
|
@@total_expectations = @@total_expectations + 1
|
@@ -171,29 +178,43 @@ class FancySpec {
|
|
171
178
|
@@failed_count = @@failed_count + 1
|
172
179
|
}
|
173
180
|
|
181
|
+
def SpecTest method_not_found: method_name for: type {
|
182
|
+
{ @@methods_not_found[type]: []} unless: $ @@methods_not_found[type]
|
183
|
+
@@methods_not_found[type] << method_name
|
184
|
+
}
|
185
|
+
|
174
186
|
def SpecTest current {
|
175
187
|
@@current
|
176
188
|
}
|
177
189
|
|
178
190
|
def SpecTest print_failures: start_time no_failures: ok_block else: error_block {
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
191
|
+
let: '*stdout* be: *stderr* in: {
|
192
|
+
@@failed_positive each: |test_obj failed_tests| {
|
193
|
+
failed_tests each: |t| {
|
194
|
+
"\n> FAILED: " ++ test_obj ++ " " ++ (t info_str) print
|
195
|
+
t print_failed_positive
|
196
|
+
}
|
184
197
|
}
|
185
|
-
}
|
186
198
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
199
|
+
@@failed_negative each: |test_obj failed_tests| {
|
200
|
+
failed_tests each: |t| {
|
201
|
+
"\n> FAILED: " ++ test_obj ++ " " ++ (t info_str) print
|
202
|
+
t print_failed_negative
|
203
|
+
}
|
192
204
|
}
|
205
|
+
|
206
|
+
unless: (@@methods_not_found empty? ) do: {
|
207
|
+
"The following methods were referenced in tests but could not be found:" println
|
208
|
+
max_size = @@methods_not_found keys map: @{ to_s size } . max
|
209
|
+
@@methods_not_found each: |type, methods| {
|
210
|
+
*stdout* printf("%-#{max_size}s : ", type)
|
211
|
+
methods map: @{ to_fancy_message } . join: ", " . println
|
212
|
+
}
|
213
|
+
}
|
214
|
+
|
215
|
+
"\nRan #{@@total_tests} tests (#{@@total_expectations} expectations) with #{@@failed_count} failures in #{Time now - start_time} seconds." println
|
193
216
|
}
|
194
217
|
|
195
|
-
Console newline
|
196
|
-
"Ran #{@@total_tests} tests (#{@@total_expectations} expectations) with #{@@failed_count} failures in #{Time now - start_time} seconds." println
|
197
218
|
if: (@@failed_count == 0) then: ok_block else: error_block
|
198
219
|
}
|
199
220
|
|
@@ -210,8 +231,8 @@ class FancySpec {
|
|
210
231
|
@@total_tests = @@total_tests + 1
|
211
232
|
try {
|
212
233
|
@block call_with_receiver: self
|
213
|
-
} catch
|
214
|
-
failed: (e, "No Exception")
|
234
|
+
} catch StandardError => e {
|
235
|
+
failed: (e, "No Exception") location: (e backtrace)
|
215
236
|
}
|
216
237
|
|
217
238
|
if: failed? then: {
|
@@ -221,14 +242,18 @@ class FancySpec {
|
|
221
242
|
}
|
222
243
|
}
|
223
244
|
|
224
|
-
def failed: actual_and_expected {
|
225
|
-
|
245
|
+
def failed: actual_and_expected location: location (nil) {
|
246
|
+
unless: location do: {
|
247
|
+
location = caller() find: |l| { l =~ /__script__/ }
|
248
|
+
}
|
249
|
+
@failed_positive << (actual_and_expected, location)
|
226
250
|
SpecTest failed_test: self
|
227
251
|
}
|
228
252
|
|
229
253
|
def failed_negative: value {
|
230
254
|
{ value = [value, 'negative_failure] } unless: $ value responds_to?: 'at:
|
231
|
-
|
255
|
+
location = caller() find: |l| { l =~ /__script__/ }
|
256
|
+
@failed_negative << (value, location)
|
232
257
|
SpecTest failed_negative_test: self
|
233
258
|
}
|
234
259
|
|
@@ -251,10 +276,15 @@ class FancySpec {
|
|
251
276
|
def print_failed_common: failures {
|
252
277
|
failures each: |f| {
|
253
278
|
actual, expected = f first
|
254
|
-
|
255
|
-
|
279
|
+
locations = f second
|
280
|
+
|
281
|
+
locations to_a map: |loc| {
|
282
|
+
loc = loc gsub(/:(\d+):in `[^']+'/, " +\1")
|
283
|
+
file, line = loc split: " +"
|
284
|
+
loc = "#{file} +#{line to_i - 1}" # somehow line is off by +1
|
285
|
+
loc = loc split: (Directory pwd + "/") . second
|
286
|
+
} . compact println
|
256
287
|
|
257
|
-
location println
|
258
288
|
unless: (expected == 'negative_failure) do: {
|
259
289
|
" Expected: #{expected inspect}" println
|
260
290
|
" Received: #{actual inspect}" println
|
@@ -296,7 +326,7 @@ class FancySpec {
|
|
296
326
|
SpecTest current failed: (nil, exception_class)
|
297
327
|
} catch exception_class {
|
298
328
|
# ok
|
299
|
-
} catch
|
329
|
+
} catch StandardError => e {
|
300
330
|
SpecTest current failed: (e class, exception_class)
|
301
331
|
}
|
302
332
|
}
|
@@ -309,7 +339,7 @@ class FancySpec {
|
|
309
339
|
} catch exception_class => e {
|
310
340
|
block call: [e]
|
311
341
|
# ok
|
312
|
-
} catch
|
342
|
+
} catch StandardError => e {
|
313
343
|
SpecTest current failed: (e class, exception_class)
|
314
344
|
}
|
315
345
|
}
|
@@ -360,7 +390,7 @@ class FancySpec {
|
|
360
390
|
@actual_value call
|
361
391
|
} catch exception_class {
|
362
392
|
SpecTest current failed_negative: (exception_class, nil)
|
363
|
-
} catch
|
393
|
+
} catch StandardError {
|
364
394
|
true
|
365
395
|
# ok
|
366
396
|
}
|
data/lib/fdoc.fy
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
# Load all of fancy.
|
2
|
+
require: "rbx/documentation"
|
3
|
+
require: "fdoc_hook"
|
2
4
|
require: "boot"
|
5
|
+
require: "option_parser"
|
6
|
+
require: "fancy_spec"
|
3
7
|
|
4
8
|
class Fancy FDoc {
|
5
9
|
"""
|
6
|
-
|
7
10
|
FDoc is a tool to generate API documentation from Fancy source.
|
8
11
|
|
9
12
|
Works as follows:
|
@@ -18,30 +21,72 @@ class Fancy FDoc {
|
|
18
21
|
4. Generate output file.
|
19
22
|
Currently the plan is to output a json formatted object.
|
20
23
|
To be loaded by an html file and use jquery to build a GUI from it.
|
21
|
-
|
22
24
|
"""
|
23
25
|
|
24
26
|
OUTPUT_DIR = "doc/api/"
|
27
|
+
FANCY_ROOT_DIR = __FILE__ relative_path: "../"
|
25
28
|
|
26
29
|
def self main {
|
27
30
|
"""
|
28
|
-
|
29
|
-
|
31
|
+
FDoc will load all .fy files you give to it, and optionally run
|
32
|
+
any specified FancySpec, and later produce documentation output.
|
30
33
|
"""
|
31
34
|
|
32
35
|
output_dir = OUTPUT_DIR
|
33
|
-
|
36
|
+
with_stdlib = false
|
37
|
+
add_github_links = false
|
38
|
+
github_repo = "bakkdoor/fancy"
|
39
|
+
|
40
|
+
OptionParser new: @{
|
41
|
+
remove_after_parsed: true
|
42
|
+
banner: "Usage: fdoc [options] [source_files]\nOptions:"
|
43
|
+
|
44
|
+
with: "-o [output_dir]" doc: "Sets output directory of generated documentation page, defaults to #{output_dir}" do: |dir| {
|
45
|
+
output_dir = dir
|
46
|
+
}
|
47
|
+
|
48
|
+
with: "-github-repo [repo_url]" doc: "Sets the Github repository to link to method definitions. Example: -github-repo bakkdoor/redis.fy" do: |url| {
|
49
|
+
github_repo = url
|
50
|
+
add_github_links = true
|
51
|
+
}
|
52
|
+
|
53
|
+
with: "--with-stdlib" doc: "Include Fancy's standard library in generated documentation" do: {
|
54
|
+
with_stdlib = true
|
55
|
+
}
|
56
|
+
} . parse: ARGV
|
57
|
+
|
58
|
+
output_dir = File absolute_path: output_dir . + "/"
|
59
|
+
|
34
60
|
require("fileutils")
|
35
61
|
FileUtils mkdir_p(output_dir)
|
36
62
|
|
63
|
+
# check if we're in Fancy's root dir
|
64
|
+
# if not, copy fdoc related files over to output_dir
|
65
|
+
if: (output_dir relative_path: "../" == FANCY_ROOT_DIR) then: {
|
66
|
+
# add stdlib by default when in FANCY_ROOT_DIR
|
67
|
+
with_stdlib = true
|
68
|
+
add_github_links = true
|
69
|
+
} else: {
|
70
|
+
files = Dir list: "#{FANCY_ROOT_DIR}/doc/api/*" . reject: |f| { f =~ /fancy\.jsonp$/ }
|
71
|
+
FileUtils cp(files, output_dir)
|
72
|
+
}
|
73
|
+
|
74
|
+
if: with_stdlib then: {
|
75
|
+
@objects_to_remove = <[]>
|
76
|
+
} else: {
|
77
|
+
@objects_to_remove = @documented_objects dup
|
78
|
+
}
|
79
|
+
|
37
80
|
# Currently we just load any files given on ARGV.
|
38
81
|
ARGV each: |file| { Fancy CodeLoader load_compiled_file(file) }
|
39
82
|
|
83
|
+
@documented_objects = @documented_objects select_keys: |k| { @objects_to_remove includes?: k . not }
|
84
|
+
|
40
85
|
# by now simply produce a apidoc/fancy.jsonp file.
|
41
|
-
json = JSON new: @documented_objects
|
86
|
+
json = JSON new: @documented_objects add_github_links: add_github_links github_repo: github_repo
|
42
87
|
json write: (File expand_path("fancy.jsonp", output_dir))
|
43
88
|
|
44
|
-
["Open your browser at " ++ output_dir ++ "index.html
|
89
|
+
["Open your browser at " ++ output_dir ++ "index.html ",
|
45
90
|
" " ++ (json classes size) ++ " classes. ",
|
46
91
|
" " ++ (json methods size) ++ " methods. ",
|
47
92
|
" " ++ (json objects size) ++ " other objects. "] println
|
@@ -49,10 +94,9 @@ class Fancy FDoc {
|
|
49
94
|
|
50
95
|
|
51
96
|
class JSON {
|
52
|
-
|
53
97
|
read_slots: ['classes, 'methods, 'blocks, 'objects]
|
54
98
|
|
55
|
-
def initialize: documented {
|
99
|
+
def initialize: documented add_github_links: @add_github_links github_repo: @github_repo {
|
56
100
|
@documented_objects = documented
|
57
101
|
|
58
102
|
is_class = |o| { o kind_of?: Module }
|
@@ -68,8 +112,13 @@ class Fancy FDoc {
|
|
68
112
|
@objects = @documented_objects keys select: all_other
|
69
113
|
}
|
70
114
|
|
71
|
-
def string_to_json: obj {
|
72
|
-
|
115
|
+
def string_to_json: obj {
|
116
|
+
obj to_s inspect
|
117
|
+
}
|
118
|
+
|
119
|
+
def symbol_to_json: obj {
|
120
|
+
obj to_s
|
121
|
+
}
|
73
122
|
|
74
123
|
def array_to_json: obj {
|
75
124
|
str = ["["]
|
@@ -125,7 +174,7 @@ class Fancy FDoc {
|
|
125
174
|
mattr['file]: $ relative_file
|
126
175
|
# TODO calculate line numbers from compiled method
|
127
176
|
# right now we only use the first line of code in the body.
|
128
|
-
mattr['lines]: $ [
|
177
|
+
mattr['lines]: $ [exec definition_line, exec last_line]
|
129
178
|
}
|
130
179
|
attr[(type ++ "s") intern()] [n]: mattr
|
131
180
|
}
|
@@ -170,17 +219,14 @@ class Fancy FDoc {
|
|
170
219
|
map
|
171
220
|
}
|
172
221
|
|
173
|
-
|
174
222
|
def write: filename call: name ("fancy.fdoc") {
|
175
223
|
map = generate_map
|
176
224
|
json = to_json: map
|
177
|
-
js = "(function() {
|
225
|
+
js = "(function() { #{name}(#{@add_github_links}, #{@github_repo inspect}, #{json}); })();"
|
178
226
|
File open: filename modes: ['write] with: |out| { out print: js }
|
179
227
|
}
|
180
|
-
|
181
228
|
}
|
182
229
|
|
183
|
-
|
184
230
|
class Formatter {
|
185
231
|
"""
|
186
232
|
A documentation formater intended to be used by @FDoc@.
|
@@ -191,7 +237,6 @@ class Fancy FDoc {
|
|
191
237
|
|
192
238
|
Fancy Documentation formatter: 'fdoc is: |d| { format: d }
|
193
239
|
|
194
|
-
|
195
240
|
def self format: doc {
|
196
241
|
str = doc to_s
|
197
242
|
tags = <[ ]>
|
@@ -200,8 +245,8 @@ class Fancy FDoc {
|
|
200
245
|
str = create_tags: str with: tags
|
201
246
|
str = create_class_references: str
|
202
247
|
str = create_method_references: str
|
203
|
-
str = create_code: str
|
204
248
|
str = htmlize: str
|
249
|
+
str = create_code: str
|
205
250
|
str
|
206
251
|
}
|
207
252
|
|
@@ -240,6 +285,7 @@ class Fancy FDoc {
|
|
240
285
|
A singleton method:
|
241
286
|
@Fancy::FDoc::Formatter~format:@
|
242
287
|
"""
|
288
|
+
|
243
289
|
str gsub(/@[A-Z][^\r\n\s]+?@/) |cstr| {
|
244
290
|
names = cstr slice(1, cstr size() - 2) split("::")
|
245
291
|
refs = []
|
@@ -296,18 +342,35 @@ class Fancy FDoc {
|
|
296
342
|
}
|
297
343
|
|
298
344
|
def self create_tags: str with: map {
|
345
|
+
max_width = map map: @{ first size } . max
|
299
346
|
tags = map map: |pair| {
|
300
347
|
name = pair[0]
|
301
348
|
value = pair[1]
|
302
|
-
|
303
|
-
|
349
|
+
# make argument names all align nicely:
|
350
|
+
name = name + (" " * (max_width - (name size)))
|
351
|
+
"<div class=\"doctag\"><label> @#{name} </label><div>#{value}</div></div>"
|
304
352
|
}
|
305
353
|
str ++ "\n<div class=\"doctags\">" ++ (tags join()) ++ "</div>"
|
306
354
|
}
|
307
355
|
|
308
356
|
def self create_code: str {
|
309
|
-
str
|
310
|
-
|
357
|
+
md = /<pre>/ match: str
|
358
|
+
if: md then: {
|
359
|
+
md = /<pre>/ match: str
|
360
|
+
pre_code = md pre_match
|
361
|
+
md = /</pre>/ match: $ md post_match
|
362
|
+
code, post_code = md pre_match, md post_match
|
363
|
+
|
364
|
+
pre_code = pre_code gsub(/@([^\s,@\]\)\{\}\.]+)/,
|
365
|
+
"<code data-lang=\"fancy\">\\1</code>")
|
366
|
+
post_code = post_code gsub(/@([^\s,@\]\)\{\}\.]+)/,
|
367
|
+
"<code data-lang=\"fancy\">\\1</code>")
|
368
|
+
|
369
|
+
"#{pre_code}<pre>#{code}</pre>#{post_code}"
|
370
|
+
} else: {
|
371
|
+
str gsub(/@([^\s,@\]\)\{\}\.]+)/,
|
372
|
+
"<code data-lang=\"fancy\">\\1</code>")
|
373
|
+
}
|
311
374
|
}
|
312
375
|
|
313
376
|
def self htmlize: str {
|
@@ -324,9 +387,7 @@ class Fancy FDoc {
|
|
324
387
|
gsub(/@:([a-z_]+)@/,
|
325
388
|
"<code data-lang=\"fancy\" data-method=\":\\1\" class=\"selectable\">\\1</code>")
|
326
389
|
}
|
327
|
-
|
328
390
|
}
|
329
|
-
|
330
391
|
}
|
331
392
|
|
332
393
|
Fancy FDoc main
|