decode 0.13.0 → 0.14.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/bake/decode/index.rb +1 -1
- data/lib/decode/comment/attribute.rb +61 -0
- data/lib/decode/comment/node.rb +90 -0
- data/lib/decode/comment/parameter.rb +62 -0
- data/lib/decode/comment/pragma.rb +50 -0
- data/lib/decode/comment/raises.rb +32 -0
- data/lib/decode/comment/returns.rb +32 -0
- data/lib/decode/comment/tag.rb +50 -0
- data/lib/decode/comment/tags.rb +80 -0
- data/lib/decode/comment/text.rb +37 -0
- data/lib/decode/comment/throws.rb +32 -0
- data/lib/decode/comment/yields.rb +52 -0
- data/lib/decode/definition.rb +18 -17
- data/lib/decode/documentation.rb +21 -66
- data/lib/decode/index.rb +7 -7
- data/lib/decode/language/generic.rb +2 -2
- data/lib/decode/language/reference.rb +11 -3
- data/lib/decode/language/ruby.rb +35 -6
- data/lib/decode/language/ruby/class.rb +2 -2
- data/lib/decode/language/ruby/definition.rb +1 -1
- data/lib/decode/language/ruby/parser.rb +9 -1
- data/lib/decode/language/ruby/segment.rb +1 -1
- data/lib/decode/segment.rb +4 -4
- data/lib/decode/trie.rb +12 -12
- data/lib/decode/version.rb +1 -1
- metadata +15 -11
- data/.github/workflows/development.yml +0 -50
- data/.gitignore +0 -13
- data/.rspec +0 -2
- data/README.md +0 -47
- data/decode.gemspec +0 -33
- data/gems.rb +0 -3
- data/guides/extract-symbols/extract.rb +0 -26
@@ -0,0 +1,37 @@
|
|
1
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'node'
|
22
|
+
|
23
|
+
module Decode
|
24
|
+
module Comment
|
25
|
+
# A structured comment.
|
26
|
+
class Text
|
27
|
+
def initialize(line)
|
28
|
+
@line = line
|
29
|
+
end
|
30
|
+
|
31
|
+
attr :line
|
32
|
+
|
33
|
+
def traverse
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'attribute'
|
22
|
+
|
23
|
+
module Decode
|
24
|
+
module Comment
|
25
|
+
# Identifies that a method might throw a specific symbol.
|
26
|
+
#
|
27
|
+
# - `@throws [:skip] To skip recursion.`
|
28
|
+
#
|
29
|
+
class Throws < Attribute
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'tag'
|
22
|
+
|
23
|
+
module Decode
|
24
|
+
module Comment
|
25
|
+
# Describes a block parameter.
|
26
|
+
#
|
27
|
+
# - `@yields {|person| ... } If a block is given.`
|
28
|
+
#
|
29
|
+
# Should contain nested parameters.
|
30
|
+
class Yields < Tag
|
31
|
+
PATTERN = /\A(?<block>{.*?})(\s+(?<details>.*?))?\Z/
|
32
|
+
|
33
|
+
def self.build(directive, match)
|
34
|
+
node = self.new(directive, match[:block])
|
35
|
+
|
36
|
+
if details = match[:details]
|
37
|
+
node.add(Text.new(details))
|
38
|
+
end
|
39
|
+
|
40
|
+
return node
|
41
|
+
end
|
42
|
+
|
43
|
+
def initialize(directive, block)
|
44
|
+
super(directive)
|
45
|
+
|
46
|
+
@block = block
|
47
|
+
end
|
48
|
+
|
49
|
+
attr :block
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/decode/definition.rb
CHANGED
@@ -22,10 +22,10 @@ module Decode
|
|
22
22
|
# A symbol with attached documentation.
|
23
23
|
class Definition
|
24
24
|
# Initialize the symbol.
|
25
|
-
# @
|
26
|
-
# @
|
27
|
-
# @
|
28
|
-
# @
|
25
|
+
# @parameter name [Symbol] The name of the definition.
|
26
|
+
# @parameter parent [Symbol] The parent lexical scope.
|
27
|
+
# @parameter language [Language] The language in which the symbol is defined in.
|
28
|
+
# @parameter comments [Array(String)] The comments associated with the definition.
|
29
29
|
def initialize(name, parent: nil, language: parent.language, comments: nil)
|
30
30
|
@name = name
|
31
31
|
|
@@ -53,11 +53,11 @@ module Decode
|
|
53
53
|
attr :language
|
54
54
|
|
55
55
|
# The comment lines which directly preceeded the definition.
|
56
|
-
# @
|
56
|
+
# @attribute [Array(String)]
|
57
57
|
attr :comments
|
58
58
|
|
59
59
|
# The qualified name is an absolute name which includes any and all namespacing.
|
60
|
-
# @
|
60
|
+
# @returns [String]
|
61
61
|
def qualified_name
|
62
62
|
@qualified_name ||= begin
|
63
63
|
if @parent
|
@@ -69,7 +69,7 @@ module Decode
|
|
69
69
|
end
|
70
70
|
|
71
71
|
# The name of this definition plus the nesting prefix.
|
72
|
-
# @
|
72
|
+
# @returns [String]
|
73
73
|
def nested_name
|
74
74
|
"::#{@name}"
|
75
75
|
end
|
@@ -78,12 +78,13 @@ module Decode
|
|
78
78
|
self.nested_name.start_with?(prefix)
|
79
79
|
end
|
80
80
|
|
81
|
+
# Convert this definition into another kind of definition.
|
81
82
|
def convert(kind)
|
82
83
|
raise ArgumentError, "Unable to convert #{self} into #{kind}!"
|
83
84
|
end
|
84
85
|
|
85
86
|
# The lexical scope which is an array of lexical {Key} instances as generated by {key}.
|
86
|
-
# @
|
87
|
+
# @returns [Array]
|
87
88
|
def path
|
88
89
|
if @path
|
89
90
|
# Cached version:
|
@@ -102,14 +103,14 @@ module Decode
|
|
102
103
|
# A short form of the definition.
|
103
104
|
# e.g. `def short_form`.
|
104
105
|
#
|
105
|
-
# @
|
106
|
+
# @returns [String | nil]
|
106
107
|
def short_form
|
107
108
|
end
|
108
109
|
|
109
110
|
# A long form of the definition.
|
110
111
|
# e.g. `def initialize(kind, name, comments, **options)`.
|
111
112
|
#
|
112
|
-
# @
|
113
|
+
# @returns [String | nil]
|
113
114
|
def long_form
|
114
115
|
self.short_form
|
115
116
|
end
|
@@ -117,44 +118,44 @@ module Decode
|
|
117
118
|
# A long form which uses the qualified name if possible.
|
118
119
|
# Defaults to {long_form}.
|
119
120
|
#
|
120
|
-
# @
|
121
|
+
# @returns [String | nil]
|
121
122
|
def qualified_form
|
122
123
|
self.long_form
|
123
124
|
end
|
124
125
|
|
125
126
|
# Whether the definition spans multiple lines.
|
126
127
|
#
|
127
|
-
# @
|
128
|
+
# @returns [Boolean]
|
128
129
|
def multiline?
|
129
130
|
false
|
130
131
|
end
|
131
132
|
|
132
133
|
# The full text of the definition.
|
133
134
|
#
|
134
|
-
# @
|
135
|
+
# @returns [String | nil]
|
135
136
|
def text
|
136
137
|
end
|
137
138
|
|
138
139
|
# Whether this definition can contain nested definitions.
|
139
140
|
#
|
140
|
-
# @
|
141
|
+
# @returns [Boolean]
|
141
142
|
def container?
|
142
143
|
false
|
143
144
|
end
|
144
145
|
|
145
146
|
# Whether this represents a single entity to be documented (along with it's contents).
|
146
147
|
#
|
147
|
-
# @
|
148
|
+
# @returns [Boolean]
|
148
149
|
def nested?
|
149
150
|
container?
|
150
151
|
end
|
151
152
|
|
152
153
|
# Structured access to the definitions comments.
|
153
154
|
#
|
154
|
-
# @
|
155
|
+
# @returns [Documentation | Nil] A {Documentation} instance if this definition has comments.
|
155
156
|
def documentation
|
156
157
|
if @comments&.any?
|
157
|
-
@documentation ||= Documentation.new(@comments)
|
158
|
+
@documentation ||= Documentation.new(@comments, @language)
|
158
159
|
end
|
159
160
|
end
|
160
161
|
end
|
data/lib/decode/documentation.rb
CHANGED
@@ -18,83 +18,38 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
+
require_relative 'comment/node'
|
22
|
+
|
23
|
+
require_relative 'comment/attribute'
|
24
|
+
require_relative 'comment/parameter'
|
25
|
+
require_relative 'comment/pragma'
|
26
|
+
require_relative 'comment/raises'
|
27
|
+
require_relative 'comment/returns'
|
28
|
+
require_relative 'comment/throws'
|
29
|
+
require_relative 'comment/yields'
|
30
|
+
|
21
31
|
module Decode
|
22
32
|
# Structured access to a set of comment lines.
|
23
|
-
class Documentation
|
33
|
+
class Documentation < Comment::Node
|
24
34
|
# Initialize the documentation with an array of comments, within a specific language.
|
25
35
|
#
|
26
|
-
# @
|
27
|
-
# @
|
36
|
+
# @parameter comments [Array(String)] An array of comment lines.
|
37
|
+
# @parameter language [Language] The language in which the comments were extracted.
|
28
38
|
def initialize(comments, language = nil)
|
29
39
|
@comments = comments
|
30
40
|
@language = language
|
31
|
-
end
|
32
|
-
|
33
|
-
# The language in which the documentation was extracted from.
|
34
|
-
attr :language
|
35
|
-
|
36
|
-
DESCRIPTION = /\A\s*([^@\s].*)?\z/
|
37
|
-
|
38
|
-
# The text-only lines of the comment block.
|
39
|
-
#
|
40
|
-
# @yield [String]
|
41
|
-
# @return [Enumerable]
|
42
|
-
def description
|
43
|
-
return to_enum(:description) unless block_given?
|
44
|
-
|
45
|
-
# We track empty lines and only yield a single empty line when there is another line of text:
|
46
|
-
gap = false
|
47
|
-
|
48
|
-
@comments.each do |comment|
|
49
|
-
if match = comment.match(DESCRIPTION)
|
50
|
-
if match[1]
|
51
|
-
if gap
|
52
|
-
yield ""
|
53
|
-
gap = false
|
54
|
-
end
|
55
|
-
|
56
|
-
yield match[1]
|
57
|
-
else
|
58
|
-
gap = true
|
59
|
-
end
|
60
|
-
else
|
61
|
-
break
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
ATTRIBUTE = /\A\s*@(?<name>.*?)\s+(?<value>.*?)\z/
|
67
|
-
|
68
|
-
# The attribute lines of the comment block.
|
69
|
-
# e.g. `@return [String]`.
|
70
|
-
#
|
71
|
-
# @yield [String]
|
72
|
-
# @return [Enumerable]
|
73
|
-
def attributes
|
74
|
-
return to_enum(:attributes) unless block_given?
|
75
41
|
|
76
|
-
@comments.
|
77
|
-
|
78
|
-
yield match
|
79
|
-
end
|
42
|
+
language.tags.parse(@comments.dup) do |node|
|
43
|
+
self.add(node)
|
80
44
|
end
|
81
45
|
end
|
82
46
|
|
83
|
-
|
47
|
+
# The underlying comments from which the documentation is extracted.
|
48
|
+
# @attribute [Array(String)]
|
49
|
+
attr :comments
|
84
50
|
|
85
|
-
# The
|
86
|
-
#
|
87
|
-
|
88
|
-
# @yield [String]
|
89
|
-
# @return [Enumerable]
|
90
|
-
def parameters
|
91
|
-
return to_enum(:parameters) unless block_given?
|
92
|
-
|
93
|
-
@comments.each do |comment|
|
94
|
-
if match = comment.match(PARAMETER)
|
95
|
-
yield match
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
51
|
+
# The language in which the documentation was extracted from.
|
52
|
+
# @attribute [Language]
|
53
|
+
attr :language
|
99
54
|
end
|
100
55
|
end
|
data/lib/decode/index.rb
CHANGED
@@ -38,26 +38,26 @@ module Decode
|
|
38
38
|
end
|
39
39
|
|
40
40
|
# All supported languages for this index.
|
41
|
-
# @
|
41
|
+
# @attribute [Languages]
|
42
42
|
attr :languages
|
43
43
|
|
44
44
|
# All source files that have been parsed.
|
45
|
-
# @
|
45
|
+
# @attribute [Array(Source)]
|
46
46
|
attr :sources
|
47
47
|
|
48
48
|
# All definitions which have been parsed.
|
49
|
-
# @
|
49
|
+
# @attribute [Array(Symbol)]
|
50
50
|
attr :definitions
|
51
51
|
|
52
52
|
# A (prefix) trie of lexically scoped definitions.
|
53
|
-
# @
|
53
|
+
# @attribute [Trie]
|
54
54
|
|
55
55
|
attr :trie
|
56
56
|
|
57
57
|
# Updates the index by parsing the specified files.
|
58
58
|
# All extracted definitions are merged into the existing index.
|
59
59
|
#
|
60
|
-
# @
|
60
|
+
# @parameter paths [Array(String)] The source file paths.
|
61
61
|
def update(paths)
|
62
62
|
paths.each do |path|
|
63
63
|
if source = @languages.source_for(path)
|
@@ -75,8 +75,8 @@ module Decode
|
|
75
75
|
|
76
76
|
# Lookup the specified reference and return matching definitions.
|
77
77
|
#
|
78
|
-
# @
|
79
|
-
# @
|
78
|
+
# @parameter reference [Language::Reference] The reference to match.
|
79
|
+
# @parameter relative_to [Definition] Lookup the reference relative to the scope of this definition.
|
80
80
|
def lookup(reference, relative_to: nil)
|
81
81
|
if reference.absolute? || relative_to.nil?
|
82
82
|
lexical_path = []
|
@@ -36,13 +36,13 @@ module Decode
|
|
36
36
|
end
|
37
37
|
|
38
38
|
# Parse the input yielding definitions.
|
39
|
-
# @block
|
39
|
+
# @block {|definition| ... }
|
40
40
|
# @yield definition [Definition]
|
41
41
|
def definitions_for(input, &block)
|
42
42
|
end
|
43
43
|
|
44
44
|
# Parse the input yielding interleaved comments and code segments.
|
45
|
-
# @block
|
45
|
+
# @block {|segment| ... }
|
46
46
|
# @yield segment [Segment]
|
47
47
|
def segments_for(input, &block)
|
48
48
|
end
|
@@ -23,7 +23,7 @@ module Decode
|
|
23
23
|
# An reference which can be resolved to zero or more definitions.
|
24
24
|
class Reference
|
25
25
|
# Initialize the reference.
|
26
|
-
# @
|
26
|
+
# @parameter identifier [String] The identifier part of the reference.
|
27
27
|
def initialize(identifier, language)
|
28
28
|
@identifier = identifier
|
29
29
|
@language = language
|
@@ -32,8 +32,16 @@ module Decode
|
|
32
32
|
@path = nil
|
33
33
|
end
|
34
34
|
|
35
|
+
def to_s
|
36
|
+
"{#{self.language} #{self.identifier}}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def inspect
|
40
|
+
"\#<#{self.class} {#{self.identifier}}>"
|
41
|
+
end
|
42
|
+
|
35
43
|
# The identifier part of the reference.
|
36
|
-
# @
|
44
|
+
# @attribute [String]
|
37
45
|
attr :identifier
|
38
46
|
|
39
47
|
# The language associated with this reference.
|
@@ -69,7 +77,7 @@ module Decode
|
|
69
77
|
end
|
70
78
|
|
71
79
|
# The lexical path of the reference.
|
72
|
-
# @
|
80
|
+
# @returns [Array(String)]
|
73
81
|
def path
|
74
82
|
@path ||= self.lexical_path.map{|_, name| name.to_sym}
|
75
83
|
end
|
data/lib/decode/language/ruby.rb
CHANGED
@@ -21,9 +21,14 @@
|
|
21
21
|
require_relative 'ruby/reference'
|
22
22
|
require_relative 'ruby/parser'
|
23
23
|
|
24
|
+
require_relative '../comment/tags'
|
25
|
+
require_relative '../comment/parameter'
|
26
|
+
require_relative '../comment/yields'
|
27
|
+
require_relative '../comment/returns'
|
28
|
+
|
24
29
|
module Decode
|
25
30
|
module Language
|
26
|
-
#
|
31
|
+
# An interface for extracting information from Ruby source code.
|
27
32
|
module Ruby
|
28
33
|
# The canoical name of the language for use in output formatting.
|
29
34
|
# e.g. source code highlighting.
|
@@ -39,21 +44,45 @@ module Decode
|
|
39
44
|
['.rb', '.ru']
|
40
45
|
end
|
41
46
|
|
47
|
+
TAGS = Comment::Tags.build do |tags|
|
48
|
+
tags['attribute'] = Comment::Attribute
|
49
|
+
tags['parameter'] = Comment::Parameter
|
50
|
+
tags['yields'] = Comment::Yields
|
51
|
+
tags['returns'] = Comment::Returns
|
52
|
+
tags['raises'] = Comment::Raises
|
53
|
+
tags['throws'] = Comment::Throws
|
54
|
+
|
55
|
+
tags['reentrant'] = Comment::Pragma
|
56
|
+
tags['deprecated'] = Comment::Pragma
|
57
|
+
tags['blocking'] = Comment::Pragma
|
58
|
+
tags['asynchronous'] = Comment::Pragma
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.tags
|
62
|
+
TAGS
|
63
|
+
end
|
64
|
+
|
42
65
|
# Generate a language-specific reference.
|
66
|
+
# @parameter identifier [String] A valid identifier.
|
43
67
|
def self.reference_for(identifier)
|
44
68
|
Reference.new(identifier, self)
|
45
69
|
end
|
46
70
|
|
47
71
|
# Parse the input yielding definitions.
|
48
|
-
# @
|
49
|
-
# @
|
72
|
+
# @parameter input [File] The input file which contains the source code.
|
73
|
+
# @yields {|definition| ...} Receives the definitions extracted from the source code.
|
74
|
+
# @parameter definition [Definition] The source code definition including methods, classes, etc.
|
75
|
+
# @returns [Enumerator(Segment)] If no block given.
|
50
76
|
def self.definitions_for(input, &block)
|
51
77
|
Parser.new.definitions_for(input, &block)
|
52
78
|
end
|
53
79
|
|
54
|
-
# Parse the input yielding
|
55
|
-
#
|
56
|
-
# @
|
80
|
+
# Parse the input yielding segments.
|
81
|
+
# Segments are constructed from a block of top level comments followed by a block of code.
|
82
|
+
# @parameter input [File] The input file which contains the source code.
|
83
|
+
# @yields {|segment| ...}
|
84
|
+
# @parameter segment [Segment]
|
85
|
+
# @returns [Enumerator(Segment)] If no block given.
|
57
86
|
def self.segments_for(input, &block)
|
58
87
|
Parser.new.segments_for(input, &block)
|
59
88
|
end
|