pdoc 0.2.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.
Files changed (122) hide show
  1. data/README.markdown +34 -0
  2. data/Rakefile +46 -0
  3. data/bin/pdoc +58 -0
  4. data/lib/pdoc.rb +32 -0
  5. data/lib/pdoc/error.rb +4 -0
  6. data/lib/pdoc/generators.rb +6 -0
  7. data/lib/pdoc/generators/abstract_generator.rb +16 -0
  8. data/lib/pdoc/generators/html.rb +8 -0
  9. data/lib/pdoc/generators/html/helpers.rb +256 -0
  10. data/lib/pdoc/generators/html/page.rb +71 -0
  11. data/lib/pdoc/generators/html/syntax_highlighter.rb +41 -0
  12. data/lib/pdoc/generators/html/template.rb +37 -0
  13. data/lib/pdoc/generators/html/website.rb +194 -0
  14. data/lib/pdoc/generators/json.rb +15 -0
  15. data/lib/pdoc/generators/pythonesque.rb +105 -0
  16. data/lib/pdoc/models.rb +47 -0
  17. data/lib/pdoc/models/argument.rb +37 -0
  18. data/lib/pdoc/models/base.rb +107 -0
  19. data/lib/pdoc/models/callable.rb +19 -0
  20. data/lib/pdoc/models/class.rb +28 -0
  21. data/lib/pdoc/models/class_method.rb +18 -0
  22. data/lib/pdoc/models/class_property.rb +9 -0
  23. data/lib/pdoc/models/constant.rb +9 -0
  24. data/lib/pdoc/models/constructor.rb +14 -0
  25. data/lib/pdoc/models/container.rb +114 -0
  26. data/lib/pdoc/models/entity.rb +54 -0
  27. data/lib/pdoc/models/instance_method.rb +18 -0
  28. data/lib/pdoc/models/instance_property.rb +9 -0
  29. data/lib/pdoc/models/mixin.rb +10 -0
  30. data/lib/pdoc/models/namespace.rb +10 -0
  31. data/lib/pdoc/models/root.rb +27 -0
  32. data/lib/pdoc/models/section.rb +19 -0
  33. data/lib/pdoc/models/signature.rb +27 -0
  34. data/lib/pdoc/models/utility.rb +11 -0
  35. data/lib/pdoc/parser.rb +109 -0
  36. data/lib/pdoc/parser/argument_description_nodes.rb +21 -0
  37. data/lib/pdoc/parser/basic_nodes.rb +31 -0
  38. data/lib/pdoc/parser/description_nodes.rb +42 -0
  39. data/lib/pdoc/parser/documentation_nodes.rb +483 -0
  40. data/lib/pdoc/parser/ebnf_arguments_nodes.rb +58 -0
  41. data/lib/pdoc/parser/ebnf_expression_nodes.rb +227 -0
  42. data/lib/pdoc/parser/fragment.rb +55 -0
  43. data/lib/pdoc/parser/section_content_nodes.rb +19 -0
  44. data/lib/pdoc/parser/tags_nodes.rb +14 -0
  45. data/lib/pdoc/parser/treetop_files/argument_description.treetop +31 -0
  46. data/lib/pdoc/parser/treetop_files/basic.treetop +41 -0
  47. data/lib/pdoc/parser/treetop_files/description.treetop +7 -0
  48. data/lib/pdoc/parser/treetop_files/documentation.treetop +75 -0
  49. data/lib/pdoc/parser/treetop_files/ebnf_arguments.treetop +33 -0
  50. data/lib/pdoc/parser/treetop_files/ebnf_expression.treetop +70 -0
  51. data/lib/pdoc/parser/treetop_files/ebnf_javascript.treetop +54 -0
  52. data/lib/pdoc/parser/treetop_files/events.treetop +17 -0
  53. data/lib/pdoc/parser/treetop_files/section_content.treetop +8 -0
  54. data/lib/pdoc/parser/treetop_files/tags.treetop +31 -0
  55. data/lib/pdoc/runner.rb +110 -0
  56. data/lib/pdoc/treemaker.rb +94 -0
  57. data/pdoc.gemspec +31 -0
  58. data/templates/html/assets/images/pdoc/alias.png +0 -0
  59. data/templates/html/assets/images/pdoc/class.png +0 -0
  60. data/templates/html/assets/images/pdoc/class_deprecated.png +0 -0
  61. data/templates/html/assets/images/pdoc/class_method.png +0 -0
  62. data/templates/html/assets/images/pdoc/class_property.png +0 -0
  63. data/templates/html/assets/images/pdoc/constant.png +0 -0
  64. data/templates/html/assets/images/pdoc/constructor.png +0 -0
  65. data/templates/html/assets/images/pdoc/deprecated.png +0 -0
  66. data/templates/html/assets/images/pdoc/description.png +0 -0
  67. data/templates/html/assets/images/pdoc/information.png +0 -0
  68. data/templates/html/assets/images/pdoc/instance_method.png +0 -0
  69. data/templates/html/assets/images/pdoc/instance_property.png +0 -0
  70. data/templates/html/assets/images/pdoc/method.png +0 -0
  71. data/templates/html/assets/images/pdoc/method_deprecated.png +0 -0
  72. data/templates/html/assets/images/pdoc/mixin.png +0 -0
  73. data/templates/html/assets/images/pdoc/namespace.png +0 -0
  74. data/templates/html/assets/images/pdoc/property.png +0 -0
  75. data/templates/html/assets/images/pdoc/related_to.png +0 -0
  76. data/templates/html/assets/images/pdoc/search-background.png +0 -0
  77. data/templates/html/assets/images/pdoc/section-background.png +0 -0
  78. data/templates/html/assets/images/pdoc/section.png +0 -0
  79. data/templates/html/assets/images/pdoc/selected-section-background.png +0 -0
  80. data/templates/html/assets/images/pdoc/subclass.png +0 -0
  81. data/templates/html/assets/images/pdoc/superclass.png +0 -0
  82. data/templates/html/assets/images/pdoc/utility.png +0 -0
  83. data/templates/html/assets/javascripts/pdoc/application.js +478 -0
  84. data/templates/html/assets/javascripts/pdoc/prototype.js +4874 -0
  85. data/templates/html/assets/javascripts/pdoc/tabs.js +506 -0
  86. data/templates/html/assets/stylesheets/pdoc/api.css +677 -0
  87. data/templates/html/assets/stylesheets/pdoc/pygments.css +62 -0
  88. data/templates/html/helpers.rb +35 -0
  89. data/templates/html/index.erb +18 -0
  90. data/templates/html/item_index.js.erb +6 -0
  91. data/templates/html/layout.erb +67 -0
  92. data/templates/html/leaf.erb +22 -0
  93. data/templates/html/node.erb +30 -0
  94. data/templates/html/partials/class_relationships.erb +19 -0
  95. data/templates/html/partials/classes.erb +7 -0
  96. data/templates/html/partials/constructor.erb +5 -0
  97. data/templates/html/partials/description.erb +5 -0
  98. data/templates/html/partials/link_list.erb +1 -0
  99. data/templates/html/partials/method_signatures.erb +14 -0
  100. data/templates/html/partials/methodized_note.erb +9 -0
  101. data/templates/html/partials/mixins.erb +7 -0
  102. data/templates/html/partials/namespaces.erb +7 -0
  103. data/templates/html/partials/related_utilities.erb +5 -0
  104. data/templates/html/partials/relationships.erb +11 -0
  105. data/templates/html/partials/short_description_list.erb +7 -0
  106. data/templates/html/partials/title.erb +22 -0
  107. data/templates/html/section.erb +18 -0
  108. data/test/unit/parser/argument_description_test.rb +40 -0
  109. data/test/unit/parser/basic_test.rb +55 -0
  110. data/test/unit/parser/description_test.rb +34 -0
  111. data/test/unit/parser/documentation_test.rb +520 -0
  112. data/test/unit/parser/ebnf_arguments_test.rb +81 -0
  113. data/test/unit/parser/ebnf_expression_test.rb +382 -0
  114. data/test/unit/parser/ebnf_javascript_test.rb +37 -0
  115. data/test/unit/parser/events_test.rb +27 -0
  116. data/test/unit/parser/section_content_test.rb +44 -0
  117. data/test/unit/parser/tags_test.rb +39 -0
  118. data/test/unit/parser/test_fragment.rb +80 -0
  119. data/test/unit/parser_test_helper.rb +62 -0
  120. data/test/unit/runner/basic_test.rb +14 -0
  121. data/test/unit/templates/html_helpers_test.rb +25 -0
  122. metadata +222 -0
@@ -0,0 +1,18 @@
1
+ module PDoc
2
+ module Models
3
+ class InstanceMethod < Entity
4
+ include Callable
5
+ attr_accessor :functionalized_self
6
+ def attach_to_parent(parent)
7
+ parent.instance_methods << self
8
+ end
9
+
10
+ def to_hash
11
+ f = functionalized_self
12
+ super.merge({
13
+ :functionalized_self => f ? f.id : nil
14
+ })
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ module PDoc
2
+ module Models
3
+ class InstanceProperty < Entity
4
+ def attach_to_parent(parent)
5
+ parent.instance_properties << self
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module PDoc
2
+ module Models
3
+ class Mixin < Entity
4
+ include Container
5
+ def attach_to_parent(parent)
6
+ parent.mixins << self
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module PDoc
2
+ module Models
3
+ class Namespace < Entity
4
+ include Container
5
+ def attach_to_parent(parent)
6
+ parent.namespaces << self
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,27 @@
1
+ module PDoc
2
+ module Models
3
+ class Root
4
+ include Container
5
+
6
+ def sections
7
+ @sections ||= []
8
+ end
9
+
10
+ def sections?
11
+ @sections && !@sections.empty?
12
+ end
13
+
14
+ def registry
15
+ @registry ||= {}
16
+ end
17
+
18
+ def find(id)
19
+ registry[id]
20
+ end
21
+
22
+ def parent
23
+ nil
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ module PDoc
2
+ module Models
3
+ class Section < Base
4
+ include Container
5
+
6
+ def attach_to_parent(parent)
7
+ parent.sections << self
8
+ end
9
+
10
+ def name
11
+ @name ||= @id.sub(' section', '')
12
+ end
13
+
14
+ def normalized_name
15
+ super.downcase
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ module PDoc
2
+ module Models
3
+ class Signature < Base
4
+ attr_reader :return_value
5
+ def attach_to_parent(parent)
6
+ parent.signatures << self
7
+ end
8
+
9
+ #TODO API cleanup
10
+
11
+ def to_s
12
+ @signature
13
+ end
14
+
15
+ def name
16
+ @signature
17
+ end
18
+
19
+ def to_hash
20
+ {
21
+ :name => name,
22
+ :return_value => return_value
23
+ }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ module PDoc
2
+ module Models
3
+ class Utility < Entity
4
+ include Callable
5
+
6
+ def attach_to_parent(parent)
7
+ parent.utilities << self
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,109 @@
1
+ require 'rubygems'
2
+ require 'treetop'
3
+
4
+ FILE_NAMES = %w[basic tags argument_description description ebnf_arguments ebnf_expression section_content documentation]
5
+
6
+ FILE_NAMES.each { |file_name| require "#{file_name}_nodes" }
7
+
8
+ %w[ebnf_javascript events].concat(FILE_NAMES).each do |file_name|
9
+ Treetop.load File.expand_path(File.join(PARSER_DIR, "treetop_files", file_name))
10
+ end
11
+
12
+ module PDoc
13
+ class Parser
14
+ def initialize(string)
15
+ @string = string
16
+ @parser = DocumentationParser.new
17
+ @percentage = 0
18
+ end
19
+
20
+ # Parses the preprocessed string. Returns an instance
21
+ # of Documentation::Doc
22
+ def parse
23
+ @finished = false
24
+ result = @parser.parse(pre_process)
25
+ @finished = true
26
+ raise ParseError, @parser unless result
27
+ result
28
+ end
29
+
30
+ # Preprocess the string before parsing.
31
+ # Converts "\r\n" to "\n" and avoids edge case
32
+ # by wrapping the string in line breaks.
33
+ def pre_process
34
+ string = @string.gsub(/\r\n/, "\n")
35
+ string = string.split("\n").map do |line|
36
+ line.gsub(/\s+$/, '')
37
+ end.join("\n")
38
+ "\n#{string}\n"
39
+ end
40
+
41
+ def completion_percentage
42
+ if @parser.index
43
+ ratio = @parser.index.to_f / @parser.input.size.to_f
44
+ percentage = (ratio * 100).floor
45
+ @percentage = percentage if percentage > @percentage
46
+ end
47
+ "#{@percentage}%"
48
+ end
49
+
50
+ def finished?
51
+ @finished
52
+ end
53
+ end
54
+
55
+ # Thrown by PDoc::Parser if the documentation is malformed.
56
+ class ParseError < StandardError
57
+ def initialize(parser)
58
+ @parser = parser
59
+ @lines = @parser.input.split("\n").unshift("")
60
+ end
61
+
62
+ def message
63
+ <<-EOS
64
+
65
+ ParseError: Expected #{expected_string} at line #{line}, column #{column} (byte #{index + 1}) after #{@parser.input[@parser.index...index].inspect}.
66
+
67
+ #{source_code}
68
+
69
+ EOS
70
+ end
71
+
72
+ def line
73
+ @parser.failure_line
74
+ end
75
+
76
+ def column
77
+ @parser.failure_column
78
+ end
79
+
80
+ def failures
81
+ @parser.terminal_failures
82
+ end
83
+
84
+ def index
85
+ @parser.failure_index
86
+ end
87
+
88
+ def source_code
89
+ ((line-2)..(line+2)).map do |index|
90
+ result = index == line ? "-->" : " "
91
+ "#{result} #{index.to_s.rjust(5)} #{@lines[index]}"
92
+ end.join("\n")
93
+ end
94
+
95
+ def failure_reason
96
+ ""
97
+ end
98
+
99
+ def expected_string
100
+ if failures.size == 1
101
+ failures.first.expected_string.inspect
102
+ else
103
+ expected = failures.map { |f| f.expected_string.inspect }.uniq
104
+ last = expected.pop
105
+ "one of #{expected.join(', ')} or #{last}"
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,21 @@
1
+ module ArgumentDescription
2
+ class ArgumentDescription < Treetop::Runtime::SyntaxNode
3
+ def name
4
+ first.argument_name.name.text_value
5
+ end
6
+
7
+ def types
8
+ if first.arg_types.empty?
9
+ []
10
+ else
11
+ args = first.arg_types.elements.last
12
+ [args.argument_type.text_value].concat(args.more.elements.map{ |e| e.argument_type.text_value })
13
+ end
14
+ end
15
+
16
+ def description
17
+ more_lines = more.elements.map{ |l| l.to_s.strip }.reject { |l| l.empty? }
18
+ [first.description.text_value.strip].concat(more_lines).join(" ")
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ module Basic
2
+ class BlankLine < Treetop::Runtime::SyntaxNode
3
+ def to_s
4
+ ""
5
+ end
6
+ end
7
+
8
+ class TextLine < Treetop::Runtime::SyntaxNode
9
+ def to_s
10
+ text.text_value
11
+ end
12
+ end
13
+
14
+ class Line < Treetop::Runtime::SyntaxNode
15
+ end
16
+
17
+ class CommentStart < Treetop::Runtime::SyntaxNode
18
+ end
19
+
20
+ class CommentEnd < Treetop::Runtime::SyntaxNode
21
+ end
22
+
23
+ class LineBreak < Treetop::Runtime::SyntaxNode
24
+ end
25
+
26
+ class Char < Treetop::Runtime::SyntaxNode
27
+ end
28
+
29
+ class Space < Treetop::Runtime::SyntaxNode
30
+ end
31
+ end
@@ -0,0 +1,42 @@
1
+ module Description
2
+ class Text < Treetop::Runtime::SyntaxNode
3
+ include Enumerable
4
+ def each
5
+ elements.map { |e| e.to_s }.each { |tag| yield tag }
6
+ end
7
+
8
+ def join(sep = "\n")
9
+ outdent.join(sep).strip
10
+ end
11
+
12
+ def to_s
13
+ join
14
+ end
15
+
16
+ def excerpt
17
+
18
+ end
19
+
20
+ def inspect
21
+ text = truncate(15).gsub(/\n/, " ").strip.inspect
22
+ "#<#{self.class} #{text}>"
23
+ end
24
+
25
+ def truncate(num = 30)
26
+ to_s.length < num ? to_s : to_s.slice(0..num) << "..."
27
+ end
28
+
29
+ def outdent
30
+ range = tab_length..-1
31
+ map { |l| l.slice(range) }
32
+ end
33
+
34
+ private
35
+ def tab_length
36
+ reject { |l| l =~ /^\s*$/ }.map do |line|
37
+ line = line.slice(/^\s*/)
38
+ line ? line.length : 0
39
+ end.min || 0
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,483 @@
1
+ module Documentation
2
+ class Doc < Treetop::Runtime::SyntaxNode
3
+ include Enumerable
4
+
5
+ def tags
6
+ @tags ||= elements.first.elements.map { |e| e.elements.last }
7
+ end
8
+
9
+ def each
10
+ tags.each { |tag| yield tag }
11
+ end
12
+
13
+ # find_by_name allows you to search through all the documented instances based on the
14
+ # instances Base#full_name.
15
+ # For example:
16
+ #
17
+ # PDoc::Parser.new("prototype.js").parse.root.find_by_name("Element#update")
18
+ #
19
+ # Return an instance of InstanceMethod corresponding to "Element#update".
20
+ def find_by_name(name)
21
+ find { |e| e.full_name == name }
22
+ end
23
+
24
+ def inspect
25
+ to_a.inspect
26
+ end
27
+
28
+ # Returns the total number of documented instances
29
+ def size
30
+ to_a.length
31
+ end
32
+
33
+ def name
34
+ "Home"
35
+ end
36
+
37
+ def serialize(serializer)
38
+ each { |obj| obj.serialize(serializer) }
39
+ end
40
+ end
41
+
42
+ module Memoized
43
+ def method_added(method_name)
44
+ if instance_method(method_name).arity.zero?
45
+ avoid_infinite_method_added_loop do
46
+ memoize(method_name)
47
+ end
48
+ end
49
+ end
50
+
51
+ def memoize(method_name)
52
+ sanitized_name = method_name.to_s
53
+ sanitized_name = sanitized_name.sub(/!$/, '_bang')
54
+ sanitized_name = sanitized_name.sub(/\?$/, '_question_mark')
55
+ complete_name = "#{sanitized_name}_#{object_id.abs}"
56
+
57
+ class_eval(<<-EVAL, __FILE__, __LINE__)
58
+ alias compute_#{complete_name} #{method_name} # alias compute_section_12235760 section
59
+ #
60
+ def #{method_name} # def section
61
+ unless defined?(@#{complete_name}) # unless defined?(@section_12235760)
62
+ @#{complete_name} = compute_#{complete_name} # @section_12235760 = compute_section_12235760
63
+ end # end
64
+ @#{complete_name} # @section_12235760
65
+ end # end
66
+ EVAL
67
+ end
68
+
69
+ def avoid_infinite_method_added_loop
70
+ unless @memoizing
71
+ @memoizing = true
72
+ yield
73
+ @memoizing = false
74
+ end
75
+ end
76
+ end
77
+
78
+ class Base < Treetop::Runtime::SyntaxNode
79
+ extend Memoized
80
+
81
+ # Returns an instance of Doc (the root of the tree outputed by the PDoc::Parser).
82
+ def root
83
+ parent.parent.parent
84
+ end
85
+
86
+ # True if the instance was tagged as deprecated.
87
+ def deprecated?
88
+ tags.include?("deprecated")
89
+ end
90
+
91
+ # If instance is tagged as an alias, alias_of returns the corresponding object.
92
+ # It will return nil otherwise.
93
+ def alias_of
94
+ tag = tags.find { |tag| tag.name == "alias of" }
95
+ tag.value if tag
96
+ end
97
+
98
+ def related_to
99
+ tag = tags.find { |tag| tag.name == "related to" }
100
+ tag.value if tag
101
+ end
102
+
103
+ # Returns an instance of Tags::Tags.
104
+ def tags
105
+ start.elements.last.empty? ? [] : start.elements.last
106
+ end
107
+
108
+ # Returns the instance's class name.
109
+ def klass_name
110
+ ebnf.klass_name
111
+ end
112
+
113
+ # Returns the instance's name. For example:
114
+ # root.find_by_name("Element#update").name
115
+ # # -> "update"
116
+ def name
117
+ ebnf.name
118
+ end
119
+
120
+ # Returns the instance's full_name. For example:
121
+ # root.find_by_name("Element#update").full_name
122
+ # # -> "Element#update"
123
+ def full_name
124
+ ebnf.full_name
125
+ end
126
+
127
+ # Returns the instance's namespace_string. Note that event if the instance is an method or property,
128
+ # the klass_name is not included in that string. So for example:
129
+ #
130
+ # root.find_by_name("Ajax.Request#request").namespace_string
131
+ # # -> "Ajax"
132
+ def namespace_string
133
+ ebnf.namespace
134
+ end
135
+
136
+ # Returns the Klass instance if object is a class, nil otherwise.
137
+ def klass
138
+ nil
139
+ end
140
+
141
+ # Returns the instance's closests namespace or nil when instance or instance's
142
+ # Klass is a global.
143
+ def namespace
144
+ @namespace ||= namespace_string.empty? ? nil : root.find_by_name(namespace_string)
145
+ end
146
+
147
+ # If instance is a global, returns its Section. Else its Namespace.
148
+ def doc_parent
149
+ namespace ? namespace : section
150
+ end
151
+
152
+ def ebnf_expressions
153
+ ebnf.elements.map { |e| e.elements.last }
154
+ end
155
+
156
+ def description
157
+ text.to_s
158
+ end
159
+
160
+ def signature
161
+ ebnf.text_value.strip
162
+ end
163
+
164
+ def inspect
165
+ "#<#{self.class} #{full_name}>"
166
+ end
167
+
168
+ def src_code_line
169
+ input.line_of(interval.last) - 1
170
+ end
171
+
172
+ def parent_id
173
+ namespace_string.empty? ? section_name : namespace_string
174
+ end
175
+
176
+ def section_name
177
+ if tags.include?('section')
178
+ value = tags.find { |tag| tag.name == 'section' }.value
179
+ "#{value} section"
180
+ end
181
+ end
182
+
183
+ def to_yaml
184
+ str = "id: #{full_name.inspect}"
185
+ str << "\nparent_id: #{parent_id.inspect}" if parent_id
186
+ str << "\ntype: #{type}"
187
+ str << "\nsuperclass_id: #{superclass.inspect}" if respond_to?(:superclass) && superclass
188
+ str << "\nincluded: #{mixins.inspect}" if respond_to?(:mixins) && !mixins.empty?
189
+ str << "\nline_number: #{src_code_line}"
190
+ str << "\ndeprecated: true" if deprecated?
191
+ str << "\nalias_of: #{alias_of.inspect}" if respond_to?(:alias_of) && alias_of
192
+ str << "\nrelated_to: #{related_to.inspect}" if respond_to?(:related_to) && related_to
193
+ str << "\ndescription: |\n#{indent(description)}\n"
194
+ end
195
+
196
+ def serialize(serializer)
197
+ serializer << to_yaml
198
+ end
199
+
200
+ private
201
+ def indent(str, prefix = ' ')
202
+ str.split($/).map { |line| "#{prefix}#{line}" } * $/
203
+ end
204
+ end
205
+
206
+ class Section < Base
207
+ # Returns section's name
208
+ def name
209
+ section.name
210
+ end
211
+
212
+ # Returns section's full_name
213
+ def full_name
214
+ "#{section.name} section"
215
+ end
216
+
217
+ # Returns section's title
218
+ def title
219
+ section.title
220
+ end
221
+
222
+ # Returns section's description
223
+ def description
224
+ section.description
225
+ end
226
+
227
+ # Returns section's text
228
+ def text
229
+ section.text
230
+ end
231
+
232
+ # Returns nil.
233
+ def klass_name
234
+ nil
235
+ end
236
+
237
+ # Returns false.
238
+ def global?
239
+ false
240
+ end
241
+
242
+ # Returns nil.
243
+ def namespace
244
+ nil
245
+ end
246
+
247
+ # Returns an empty string.
248
+ def namespace_string
249
+ ""
250
+ end
251
+
252
+ # Returns nil.
253
+ def section
254
+ nil
255
+ end
256
+
257
+ # Returns nil.
258
+ def doc_parent
259
+ nil
260
+ end
261
+
262
+ # Returns "section".
263
+ def type
264
+ "section"
265
+ end
266
+ end
267
+
268
+ class Method < Base
269
+ def klass
270
+ namespace
271
+ end
272
+
273
+ def klass_name
274
+ ebnf_expressions.first.klass_name
275
+ end
276
+
277
+ def full_name
278
+ ebnf_expressions.first.full_name
279
+ end
280
+
281
+ def name
282
+ ebnf_expressions.first.name
283
+ end
284
+
285
+ def methodized?
286
+ ebnf_expressions.first.methodized?
287
+ end
288
+
289
+ def namespace_string
290
+ ebnf_expressions.first.namespace
291
+ end
292
+
293
+ def arguments
294
+ args = argument_descriptions.elements
295
+ args ? args.first.elements : []
296
+ end
297
+
298
+ def signature
299
+ ebnf_expressions.first.signature
300
+ end
301
+
302
+ def returns
303
+ ebnf_expressions.first.returns
304
+ end
305
+
306
+ def fires
307
+ events.empty? ? [] : events.to_a
308
+ end
309
+
310
+ def signatures
311
+ ebnf_expressions
312
+ end
313
+
314
+ def serialize(serializer)
315
+ str = to_yaml
316
+ str << "\nmethodized: true" if respond_to?(:methodized?) && methodized?
317
+
318
+ serialize_signatures(str)
319
+
320
+ serialize_arguments(str) unless arguments.empty?
321
+
322
+ serializer << str
323
+ end
324
+
325
+ def serialize_signatures(str)
326
+ str << "\nsignatures:"
327
+ ebnf_expressions.each do |ebnf|
328
+ str << "\n -"
329
+ str << "\n signature: #{ebnf.signature.inspect}"
330
+ str << "\n return_value: #{ebnf.returns.inspect}" if ebnf.returns
331
+ end
332
+ end
333
+
334
+ def serialize_arguments(str)
335
+ str << "\narguments:"
336
+ arguments.each do |arg|
337
+ str << "\n -"
338
+ str << "\n name: #{arg.name}"
339
+ str << "\n types: [#{arg.types.join(', ')}]" unless arg.types.empty?
340
+ str << "\n description: >"
341
+ str << "\n #{arg.description}\n"
342
+ end
343
+ end
344
+ end
345
+
346
+ class Property < Base
347
+ def klass
348
+ namespace
349
+ end
350
+
351
+ def signature
352
+ ebnf.signature
353
+ end
354
+
355
+ def returns
356
+ ebnf.returns
357
+ end
358
+
359
+ def serialize(serializer)
360
+ str = to_yaml
361
+
362
+ str << "\nsignatures:"
363
+ str << "\n -"
364
+ str << "\n signature: #{signature.inspect}"
365
+ str << "\n return_value: #{returns.inspect}"
366
+
367
+ serializer << str
368
+ end
369
+ end
370
+
371
+ class KlassMethod < Method
372
+ def klass
373
+ namespace.is_a?(Klass) ? namespace : nil
374
+ end
375
+
376
+ def klass_name
377
+ klass ? klass.name : nil
378
+ end
379
+
380
+ def type
381
+ "class method"
382
+ end
383
+ end
384
+
385
+ class Utility < Method
386
+ def type
387
+ "utility"
388
+ end
389
+ end
390
+
391
+ class InstanceMethod < Method
392
+ def type
393
+ "instance method"
394
+ end
395
+ end
396
+
397
+ class Constructor < Method
398
+ def namespace_string
399
+ ebnf_expressions.first.namespace
400
+ end
401
+
402
+ def type
403
+ "constructor"
404
+ end
405
+ end
406
+
407
+ class KlassProperty < Property
408
+ def type
409
+ "class property"
410
+ end
411
+ end
412
+
413
+ class InstanceProperty < Property
414
+ def type
415
+ "instance property"
416
+ end
417
+ end
418
+
419
+ class Constant < Base
420
+ def klass
421
+ namespace.is_a?(Klass) ? namespace : nil
422
+ end
423
+
424
+ def klass_name
425
+ klass ? klass.name : nil
426
+ end
427
+
428
+ def returns
429
+ ebnf.returns
430
+ end
431
+
432
+ def signature
433
+ ebnf.signature
434
+ end
435
+
436
+ def type
437
+ "constant"
438
+ end
439
+ end
440
+
441
+ class Namespace < Base
442
+ def mixins
443
+ ebnf.mixins.map { |m| m.full_name }
444
+ end
445
+
446
+ def mixin?
447
+ false
448
+ end
449
+
450
+ def klass?
451
+ false
452
+ end
453
+
454
+ def type
455
+ "namespace"
456
+ end
457
+ end
458
+
459
+ class Klass < Namespace
460
+ def klass?
461
+ true
462
+ end
463
+
464
+ def superclass
465
+ sc = ebnf.superklass
466
+ sc.text_value if sc
467
+ end
468
+
469
+ def type
470
+ "class"
471
+ end
472
+ end
473
+
474
+ class Mixin < Namespace
475
+ def mixin?
476
+ true
477
+ end
478
+
479
+ def type
480
+ "mixin"
481
+ end
482
+ end
483
+ end