gitlab-rdoc 6.3.2
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 +7 -0
- data/CONTRIBUTING.rdoc +220 -0
- data/CVE-2013-0256.rdoc +49 -0
- data/ExampleMarkdown.md +37 -0
- data/ExampleRDoc.rdoc +208 -0
- data/Gemfile +12 -0
- data/History.rdoc +1666 -0
- data/LEGAL.rdoc +50 -0
- data/LICENSE.rdoc +57 -0
- data/README.rdoc +133 -0
- data/RI.rdoc +57 -0
- data/Rakefile +101 -0
- data/TODO.rdoc +59 -0
- data/bin/console +7 -0
- data/bin/setup +6 -0
- data/exe/rdoc +44 -0
- data/exe/ri +12 -0
- data/lib/rdoc/alias.rb +112 -0
- data/lib/rdoc/anon_class.rb +11 -0
- data/lib/rdoc/any_method.rb +361 -0
- data/lib/rdoc/attr.rb +176 -0
- data/lib/rdoc/class_module.rb +802 -0
- data/lib/rdoc/code_object.rb +421 -0
- data/lib/rdoc/code_objects.rb +6 -0
- data/lib/rdoc/comment.rb +250 -0
- data/lib/rdoc/constant.rb +187 -0
- data/lib/rdoc/context/section.rb +232 -0
- data/lib/rdoc/context.rb +1266 -0
- data/lib/rdoc/cross_reference.rb +202 -0
- data/lib/rdoc/encoding.rb +136 -0
- data/lib/rdoc/erb_partial.rb +19 -0
- data/lib/rdoc/erbio.rb +42 -0
- data/lib/rdoc/extend.rb +10 -0
- data/lib/rdoc/generator/darkfish.rb +790 -0
- data/lib/rdoc/generator/json_index.rb +300 -0
- data/lib/rdoc/generator/markup.rb +160 -0
- data/lib/rdoc/generator/pot/message_extractor.rb +68 -0
- data/lib/rdoc/generator/pot/po.rb +84 -0
- data/lib/rdoc/generator/pot/po_entry.rb +141 -0
- data/lib/rdoc/generator/pot.rb +98 -0
- data/lib/rdoc/generator/ri.rb +31 -0
- data/lib/rdoc/generator/template/darkfish/.document +0 -0
- data/lib/rdoc/generator/template/darkfish/_footer.rhtml +5 -0
- data/lib/rdoc/generator/template/darkfish/_head.rhtml +22 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml +19 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml +9 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +15 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml +9 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +15 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +15 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml +12 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml +11 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +12 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml +11 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml +14 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +11 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +18 -0
- data/lib/rdoc/generator/template/darkfish/class.rhtml +172 -0
- data/lib/rdoc/generator/template/darkfish/css/fonts.css +167 -0
- data/lib/rdoc/generator/template/darkfish/css/rdoc.css +639 -0
- data/lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttf +0 -0
- data/lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttf +0 -0
- data/lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttf +0 -0
- data/lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttf +0 -0
- data/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf +0 -0
- data/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf +0 -0
- data/lib/rdoc/generator/template/darkfish/images/add.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/arrow_up.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/brick.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/brick_link.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/bug.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/bullet_black.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/date.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/delete.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/find.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif +0 -0
- data/lib/rdoc/generator/template/darkfish/images/macFFBgHack.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/package.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/page_green.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/page_white_text.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/page_white_width.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/plugin.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/ruby.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/tag_blue.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/tag_green.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/transparent.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/wrench.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/wrench_orange.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/zoom.png +0 -0
- data/lib/rdoc/generator/template/darkfish/index.rhtml +22 -0
- data/lib/rdoc/generator/template/darkfish/js/darkfish.js +84 -0
- data/lib/rdoc/generator/template/darkfish/js/search.js +110 -0
- data/lib/rdoc/generator/template/darkfish/page.rhtml +18 -0
- data/lib/rdoc/generator/template/darkfish/servlet_not_found.rhtml +18 -0
- data/lib/rdoc/generator/template/darkfish/servlet_root.rhtml +62 -0
- data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +58 -0
- data/lib/rdoc/generator/template/json_index/.document +1 -0
- data/lib/rdoc/generator/template/json_index/js/navigation.js +105 -0
- data/lib/rdoc/generator/template/json_index/js/searcher.js +229 -0
- data/lib/rdoc/generator.rb +51 -0
- data/lib/rdoc/ghost_method.rb +7 -0
- data/lib/rdoc/i18n/locale.rb +102 -0
- data/lib/rdoc/i18n/text.rb +126 -0
- data/lib/rdoc/i18n.rb +10 -0
- data/lib/rdoc/include.rb +10 -0
- data/lib/rdoc/known_classes.rb +73 -0
- data/lib/rdoc/markdown/entities.rb +2132 -0
- data/lib/rdoc/markdown/literals.kpeg +23 -0
- data/lib/rdoc/markdown/literals.rb +417 -0
- data/lib/rdoc/markdown.kpeg +1237 -0
- data/lib/rdoc/markdown.rb +16685 -0
- data/lib/rdoc/markup/attr_changer.rb +23 -0
- data/lib/rdoc/markup/attr_span.rb +36 -0
- data/lib/rdoc/markup/attribute_manager.rb +409 -0
- data/lib/rdoc/markup/attributes.rb +71 -0
- data/lib/rdoc/markup/blank_line.rb +28 -0
- data/lib/rdoc/markup/block_quote.rb +15 -0
- data/lib/rdoc/markup/document.rb +165 -0
- data/lib/rdoc/markup/formatter.rb +266 -0
- data/lib/rdoc/markup/hard_break.rb +32 -0
- data/lib/rdoc/markup/heading.rb +79 -0
- data/lib/rdoc/markup/include.rb +43 -0
- data/lib/rdoc/markup/indented_paragraph.rb +48 -0
- data/lib/rdoc/markup/list.rb +102 -0
- data/lib/rdoc/markup/list_item.rb +100 -0
- data/lib/rdoc/markup/paragraph.rb +29 -0
- data/lib/rdoc/markup/parser.rb +575 -0
- data/lib/rdoc/markup/pre_process.rb +296 -0
- data/lib/rdoc/markup/raw.rb +70 -0
- data/lib/rdoc/markup/regexp_handling.rb +41 -0
- data/lib/rdoc/markup/rule.rb +21 -0
- data/lib/rdoc/markup/table.rb +47 -0
- data/lib/rdoc/markup/to_ansi.rb +94 -0
- data/lib/rdoc/markup/to_bs.rb +77 -0
- data/lib/rdoc/markup/to_html.rb +444 -0
- data/lib/rdoc/markup/to_html_crossref.rb +176 -0
- data/lib/rdoc/markup/to_html_snippet.rb +285 -0
- data/lib/rdoc/markup/to_joined_paragraph.rb +47 -0
- data/lib/rdoc/markup/to_label.rb +75 -0
- data/lib/rdoc/markup/to_markdown.rb +192 -0
- data/lib/rdoc/markup/to_rdoc.rb +362 -0
- data/lib/rdoc/markup/to_table_of_contents.rb +89 -0
- data/lib/rdoc/markup/to_test.rb +70 -0
- data/lib/rdoc/markup/to_tt_only.rb +121 -0
- data/lib/rdoc/markup/verbatim.rb +84 -0
- data/lib/rdoc/markup.rb +867 -0
- data/lib/rdoc/meta_method.rb +7 -0
- data/lib/rdoc/method_attr.rb +419 -0
- data/lib/rdoc/mixin.rb +121 -0
- data/lib/rdoc/normal_class.rb +93 -0
- data/lib/rdoc/normal_module.rb +74 -0
- data/lib/rdoc/options.rb +1285 -0
- data/lib/rdoc/parser/c.rb +1225 -0
- data/lib/rdoc/parser/changelog.rb +335 -0
- data/lib/rdoc/parser/markdown.rb +24 -0
- data/lib/rdoc/parser/rd.rb +23 -0
- data/lib/rdoc/parser/ripper_state_lex.rb +590 -0
- data/lib/rdoc/parser/ruby.rb +2327 -0
- data/lib/rdoc/parser/ruby_tools.rb +167 -0
- data/lib/rdoc/parser/simple.rb +61 -0
- data/lib/rdoc/parser/text.rb +12 -0
- data/lib/rdoc/parser.rb +277 -0
- data/lib/rdoc/rd/block_parser.rb +1056 -0
- data/lib/rdoc/rd/block_parser.ry +639 -0
- data/lib/rdoc/rd/inline.rb +72 -0
- data/lib/rdoc/rd/inline_parser.rb +1208 -0
- data/lib/rdoc/rd/inline_parser.ry +593 -0
- data/lib/rdoc/rd.rb +100 -0
- data/lib/rdoc/rdoc.rb +579 -0
- data/lib/rdoc/require.rb +52 -0
- data/lib/rdoc/ri/driver.rb +1572 -0
- data/lib/rdoc/ri/formatter.rb +6 -0
- data/lib/rdoc/ri/paths.rb +171 -0
- data/lib/rdoc/ri/store.rb +7 -0
- data/lib/rdoc/ri/task.rb +71 -0
- data/lib/rdoc/ri.rb +21 -0
- data/lib/rdoc/rubygems_hook.rb +246 -0
- data/lib/rdoc/servlet.rb +451 -0
- data/lib/rdoc/single_class.rb +26 -0
- data/lib/rdoc/stats/normal.rb +58 -0
- data/lib/rdoc/stats/quiet.rb +60 -0
- data/lib/rdoc/stats/verbose.rb +46 -0
- data/lib/rdoc/stats.rb +462 -0
- data/lib/rdoc/store.rb +979 -0
- data/lib/rdoc/task.rb +329 -0
- data/lib/rdoc/text.rb +304 -0
- data/lib/rdoc/token_stream.rb +119 -0
- data/lib/rdoc/tom_doc.rb +263 -0
- data/lib/rdoc/top_level.rb +289 -0
- data/lib/rdoc/version.rb +8 -0
- data/lib/rdoc.rb +201 -0
- data/man/ri.1 +247 -0
- data/rdoc.gemspec +249 -0
- metadata +279 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# A ChangeLog file parser.
|
|
5
|
+
#
|
|
6
|
+
# This parser converts a ChangeLog into an RDoc::Markup::Document. When
|
|
7
|
+
# viewed as HTML a ChangeLog page will have an entry for each day's entries in
|
|
8
|
+
# the sidebar table of contents.
|
|
9
|
+
#
|
|
10
|
+
# This parser is meant to parse the MRI ChangeLog, but can be used to parse any
|
|
11
|
+
# {GNU style Change
|
|
12
|
+
# Log}[http://www.gnu.org/prep/standards/html_node/Style-of-Change-Logs.html].
|
|
13
|
+
|
|
14
|
+
class RDoc::Parser::ChangeLog < RDoc::Parser
|
|
15
|
+
|
|
16
|
+
include RDoc::Parser::Text
|
|
17
|
+
|
|
18
|
+
parse_files_matching(/(\/|\\|\A)ChangeLog[^\/\\]*\z/)
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# Attaches the +continuation+ of the previous line to the +entry_body+.
|
|
22
|
+
#
|
|
23
|
+
# Continued function listings are joined together as a single entry.
|
|
24
|
+
# Continued descriptions are joined to make a single paragraph.
|
|
25
|
+
|
|
26
|
+
def continue_entry_body entry_body, continuation
|
|
27
|
+
return unless last = entry_body.last
|
|
28
|
+
|
|
29
|
+
if last =~ /\)\s*\z/ and continuation =~ /\A\(/ then
|
|
30
|
+
last.sub!(/\)\s*\z/, ',')
|
|
31
|
+
continuation = continuation.sub(/\A\(/, '')
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if last =~ /\s\z/ then
|
|
35
|
+
last << continuation
|
|
36
|
+
else
|
|
37
|
+
last << ' ' + continuation
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
##
|
|
42
|
+
# Creates an RDoc::Markup::Document given the +groups+ of ChangeLog entries.
|
|
43
|
+
|
|
44
|
+
def create_document groups
|
|
45
|
+
doc = RDoc::Markup::Document.new
|
|
46
|
+
doc.omit_headings_below = 2
|
|
47
|
+
doc.file = @top_level
|
|
48
|
+
|
|
49
|
+
doc << RDoc::Markup::Heading.new(1, File.basename(@file_name))
|
|
50
|
+
doc << RDoc::Markup::BlankLine.new
|
|
51
|
+
|
|
52
|
+
groups.sort_by do |day,| day end.reverse_each do |day, entries|
|
|
53
|
+
doc << RDoc::Markup::Heading.new(2, day.dup)
|
|
54
|
+
doc << RDoc::Markup::BlankLine.new
|
|
55
|
+
|
|
56
|
+
doc.concat create_entries entries
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
doc
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
##
|
|
63
|
+
# Returns a list of ChangeLog entries an RDoc::Markup nodes for the given
|
|
64
|
+
# +entries+.
|
|
65
|
+
|
|
66
|
+
def create_entries entries
|
|
67
|
+
out = []
|
|
68
|
+
|
|
69
|
+
entries.each do |entry, items|
|
|
70
|
+
out << RDoc::Markup::Heading.new(3, entry)
|
|
71
|
+
out << RDoc::Markup::BlankLine.new
|
|
72
|
+
|
|
73
|
+
out << create_items(items)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
out
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
##
|
|
80
|
+
# Returns an RDoc::Markup::List containing the given +items+ in the
|
|
81
|
+
# ChangeLog
|
|
82
|
+
|
|
83
|
+
def create_items items
|
|
84
|
+
list = RDoc::Markup::List.new :NOTE
|
|
85
|
+
|
|
86
|
+
items.each do |item|
|
|
87
|
+
item =~ /\A(.*?(?:\([^)]+\))?):\s*/
|
|
88
|
+
|
|
89
|
+
title = $1
|
|
90
|
+
body = $'
|
|
91
|
+
|
|
92
|
+
paragraph = RDoc::Markup::Paragraph.new body
|
|
93
|
+
list_item = RDoc::Markup::ListItem.new title, paragraph
|
|
94
|
+
list << list_item
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
list
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
##
|
|
101
|
+
# Groups +entries+ by date.
|
|
102
|
+
|
|
103
|
+
def group_entries entries
|
|
104
|
+
@time_cache ||= {}
|
|
105
|
+
entries.group_by do |title, _|
|
|
106
|
+
begin
|
|
107
|
+
time = @time_cache[title]
|
|
108
|
+
(time || parse_date(title)).strftime '%Y-%m-%d'
|
|
109
|
+
rescue NoMethodError, ArgumentError
|
|
110
|
+
time, = title.split ' ', 2
|
|
111
|
+
parse_date(time).strftime '%Y-%m-%d'
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
##
|
|
117
|
+
# Parse date in ISO-8601, RFC-2822, or default of Git
|
|
118
|
+
|
|
119
|
+
def parse_date(date)
|
|
120
|
+
case date
|
|
121
|
+
when /\A\s*(\d+)-(\d+)-(\d+)(?:[ T](\d+):(\d+):(\d+) *([-+]\d\d):?(\d\d))?\b/
|
|
122
|
+
Time.new($1, $2, $3, $4, $5, $6, ("#{$7}:#{$8}" if $7))
|
|
123
|
+
when /\A\s*\w{3}, +(\d+) (\w{3}) (\d+) (\d+):(\d+):(\d+) *(?:([-+]\d\d):?(\d\d))\b/
|
|
124
|
+
Time.new($3, $2, $1, $4, $5, $6, ("#{$7}:#{$8}" if $7))
|
|
125
|
+
when /\A\s*\w{3} (\w{3}) +(\d+) (\d+) (\d+):(\d+):(\d+) *(?:([-+]\d\d):?(\d\d))\b/
|
|
126
|
+
Time.new($3, $1, $2, $4, $5, $6, ("#{$7}:#{$8}" if $7))
|
|
127
|
+
when /\A\s*\w{3} (\w{3}) +(\d+) (\d+):(\d+):(\d+) (\d+)\b/
|
|
128
|
+
Time.new($6, $1, $2, $3, $4, $5)
|
|
129
|
+
else
|
|
130
|
+
raise ArgumentError, "bad date: #{date}"
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
##
|
|
135
|
+
# Parses the entries in the ChangeLog.
|
|
136
|
+
#
|
|
137
|
+
# Returns an Array of each ChangeLog entry in order of parsing.
|
|
138
|
+
#
|
|
139
|
+
# A ChangeLog entry is an Array containing the ChangeLog title (date and
|
|
140
|
+
# committer) and an Array of ChangeLog items (file and function changed with
|
|
141
|
+
# description).
|
|
142
|
+
#
|
|
143
|
+
# An example result would be:
|
|
144
|
+
#
|
|
145
|
+
# [ 'Tue Dec 4 08:33:46 2012 Eric Hodel <drbrain@segment7.net>',
|
|
146
|
+
# [ 'README.EXT: Converted to RDoc format',
|
|
147
|
+
# 'README.EXT.ja: ditto']]
|
|
148
|
+
|
|
149
|
+
def parse_entries
|
|
150
|
+
@time_cache ||= {}
|
|
151
|
+
|
|
152
|
+
if /\A((?:.*\n){,3})commit\s/ =~ @content
|
|
153
|
+
class << self; prepend Git; end
|
|
154
|
+
parse_info($1)
|
|
155
|
+
return parse_entries
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
entries = []
|
|
159
|
+
entry_name = nil
|
|
160
|
+
entry_body = []
|
|
161
|
+
|
|
162
|
+
@content.each_line do |line|
|
|
163
|
+
case line
|
|
164
|
+
when /^\s*$/ then
|
|
165
|
+
next
|
|
166
|
+
when /^\w.*/ then
|
|
167
|
+
entries << [entry_name, entry_body] if entry_name
|
|
168
|
+
|
|
169
|
+
entry_name = $&
|
|
170
|
+
|
|
171
|
+
begin
|
|
172
|
+
time = parse_date entry_name
|
|
173
|
+
@time_cache[entry_name] = time
|
|
174
|
+
rescue ArgumentError
|
|
175
|
+
entry_name = nil
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
entry_body = []
|
|
179
|
+
when /^(\t| {8})?\*\s*(.*)/ then # "\t* file.c (func): ..."
|
|
180
|
+
entry_body << $2.dup
|
|
181
|
+
when /^(\t| {8})?\s*(\(.*)/ then # "\t(func): ..."
|
|
182
|
+
entry = $2
|
|
183
|
+
|
|
184
|
+
if entry_body.last =~ /:/ then
|
|
185
|
+
entry_body << entry.dup
|
|
186
|
+
else
|
|
187
|
+
continue_entry_body entry_body, entry
|
|
188
|
+
end
|
|
189
|
+
when /^(\t| {8})?\s*(.*)/ then
|
|
190
|
+
continue_entry_body entry_body, $2
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
entries << [entry_name, entry_body] if entry_name
|
|
195
|
+
|
|
196
|
+
entries.reject! do |(entry,_)|
|
|
197
|
+
entry == nil
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
entries
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
##
|
|
204
|
+
# Converts the ChangeLog into an RDoc::Markup::Document
|
|
205
|
+
|
|
206
|
+
def scan
|
|
207
|
+
@time_cache = {}
|
|
208
|
+
|
|
209
|
+
entries = parse_entries
|
|
210
|
+
grouped_entries = group_entries entries
|
|
211
|
+
|
|
212
|
+
doc = create_document grouped_entries
|
|
213
|
+
|
|
214
|
+
@top_level.comment = doc
|
|
215
|
+
|
|
216
|
+
@top_level
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
module Git
|
|
220
|
+
def parse_info(info)
|
|
221
|
+
/^\s*base-url\s*=\s*(.*\S)/ =~ info
|
|
222
|
+
@base_url = $1
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def parse_entries
|
|
226
|
+
entries = []
|
|
227
|
+
|
|
228
|
+
@content.scan(/^commit\s+(\h{20})\h*\n((?:.+\n)*)\n((?: {4}.*\n+)*)/) do
|
|
229
|
+
entry_name, header, entry_body = $1, $2, $3.gsub(/^ {4}/, '')
|
|
230
|
+
# header = header.scan(/^ *(\S+?): +(.*)/).to_h
|
|
231
|
+
# date = header["CommitDate"] || header["Date"]
|
|
232
|
+
date = header[/^ *(?:Author)?Date: +(.*)/, 1]
|
|
233
|
+
author = header[/^ *Author: +(.*)/, 1]
|
|
234
|
+
begin
|
|
235
|
+
time = parse_date(header[/^ *CommitDate: +(.*)/, 1] || date)
|
|
236
|
+
@time_cache[entry_name] = time
|
|
237
|
+
author.sub!(/\s*<(.*)>/, '')
|
|
238
|
+
email = $1
|
|
239
|
+
entries << [entry_name, [author, email, date, entry_body]]
|
|
240
|
+
rescue ArgumentError
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
entries
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def create_entries entries
|
|
248
|
+
# git log entries have no strictly itemized style like the old
|
|
249
|
+
# style, just assume Markdown.
|
|
250
|
+
entries.map do |commit, entry|
|
|
251
|
+
LogEntry.new(@base_url, commit, *entry)
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
LogEntry = Struct.new(:base, :commit, :author, :email, :date, :contents) do
|
|
256
|
+
HEADING_LEVEL = 3
|
|
257
|
+
|
|
258
|
+
def initialize(base, commit, author, email, date, contents)
|
|
259
|
+
case contents
|
|
260
|
+
when String
|
|
261
|
+
contents = RDoc::Markdown.parse(contents).parts.each do |body|
|
|
262
|
+
case body
|
|
263
|
+
when RDoc::Markup::Heading
|
|
264
|
+
body.level += HEADING_LEVEL + 1
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
case first = contents[0]
|
|
268
|
+
when RDoc::Markup::Paragraph
|
|
269
|
+
contents[0] = RDoc::Markup::Heading.new(HEADING_LEVEL + 1, first.text)
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
super
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def level
|
|
276
|
+
HEADING_LEVEL
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def aref
|
|
280
|
+
"label-#{commit}"
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def label context = nil
|
|
284
|
+
aref
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def text
|
|
288
|
+
case base
|
|
289
|
+
when nil
|
|
290
|
+
"#{date}"
|
|
291
|
+
when /%s/
|
|
292
|
+
"{#{date}}[#{base % commit}]"
|
|
293
|
+
else
|
|
294
|
+
"{#{date}}[#{base}#{commit}]"
|
|
295
|
+
end + " {#{author}}[mailto:#{email}]"
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def accept visitor
|
|
299
|
+
visitor.accept_heading self
|
|
300
|
+
begin
|
|
301
|
+
if visitor.respond_to?(:code_object=)
|
|
302
|
+
code_object = visitor.code_object
|
|
303
|
+
visitor.code_object = self
|
|
304
|
+
end
|
|
305
|
+
contents.each do |body|
|
|
306
|
+
body.accept visitor
|
|
307
|
+
end
|
|
308
|
+
ensure
|
|
309
|
+
if visitor.respond_to?(:code_object)
|
|
310
|
+
visitor.code_object = code_object
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
def pretty_print q # :nodoc:
|
|
316
|
+
q.group(2, '[log_entry: ', ']') do
|
|
317
|
+
q.text commit
|
|
318
|
+
q.text ','
|
|
319
|
+
q.breakable
|
|
320
|
+
q.group(2, '[date: ', ']') { q.text date }
|
|
321
|
+
q.text ','
|
|
322
|
+
q.breakable
|
|
323
|
+
q.group(2, '[author: ', ']') { q.text author }
|
|
324
|
+
q.text ','
|
|
325
|
+
q.breakable
|
|
326
|
+
q.group(2, '[email: ', ']') { q.text email }
|
|
327
|
+
q.text ','
|
|
328
|
+
q.breakable
|
|
329
|
+
q.pp contents
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
##
|
|
3
|
+
# Parse a Markdown format file. The parsed RDoc::Markup::Document is attached
|
|
4
|
+
# as a file comment.
|
|
5
|
+
|
|
6
|
+
class RDoc::Parser::Markdown < RDoc::Parser
|
|
7
|
+
|
|
8
|
+
include RDoc::Parser::Text
|
|
9
|
+
|
|
10
|
+
parse_files_matching(/\.(md|markdown)(?:\.[^.]+)?$/)
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
# Creates an Markdown-format TopLevel for the given file.
|
|
14
|
+
|
|
15
|
+
def scan
|
|
16
|
+
comment = RDoc::Comment.new @content, @top_level
|
|
17
|
+
comment.format = 'markdown'
|
|
18
|
+
|
|
19
|
+
@top_level.comment = comment
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
##
|
|
3
|
+
# Parse a RD format file. The parsed RDoc::Markup::Document is attached as a
|
|
4
|
+
# file comment.
|
|
5
|
+
|
|
6
|
+
class RDoc::Parser::RD < RDoc::Parser
|
|
7
|
+
|
|
8
|
+
include RDoc::Parser::Text
|
|
9
|
+
|
|
10
|
+
parse_files_matching(/\.rd(?:\.[^.]+)?$/)
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
# Creates an rd-format TopLevel for the given file.
|
|
14
|
+
|
|
15
|
+
def scan
|
|
16
|
+
comment = RDoc::Comment.new @content, @top_level
|
|
17
|
+
comment.format = 'rd'
|
|
18
|
+
|
|
19
|
+
@top_level.comment = comment
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'ripper'
|
|
3
|
+
|
|
4
|
+
class RDoc::Parser::RipperStateLex
|
|
5
|
+
# TODO: Remove this constants after Ruby 2.4 EOL
|
|
6
|
+
RIPPER_HAS_LEX_STATE = Ripper::Filter.method_defined?(:state)
|
|
7
|
+
|
|
8
|
+
Token = Struct.new(:line_no, :char_no, :kind, :text, :state)
|
|
9
|
+
|
|
10
|
+
EXPR_NONE = 0
|
|
11
|
+
EXPR_BEG = 1
|
|
12
|
+
EXPR_END = 2
|
|
13
|
+
EXPR_ENDARG = 4
|
|
14
|
+
EXPR_ENDFN = 8
|
|
15
|
+
EXPR_ARG = 16
|
|
16
|
+
EXPR_CMDARG = 32
|
|
17
|
+
EXPR_MID = 64
|
|
18
|
+
EXPR_FNAME = 128
|
|
19
|
+
EXPR_DOT = 256
|
|
20
|
+
EXPR_CLASS = 512
|
|
21
|
+
EXPR_LABEL = 1024
|
|
22
|
+
EXPR_LABELED = 2048
|
|
23
|
+
EXPR_FITEM = 4096
|
|
24
|
+
EXPR_VALUE = EXPR_BEG
|
|
25
|
+
EXPR_BEG_ANY = (EXPR_BEG | EXPR_MID | EXPR_CLASS)
|
|
26
|
+
EXPR_ARG_ANY = (EXPR_ARG | EXPR_CMDARG)
|
|
27
|
+
EXPR_END_ANY = (EXPR_END | EXPR_ENDARG | EXPR_ENDFN)
|
|
28
|
+
|
|
29
|
+
class InnerStateLex < Ripper::Filter
|
|
30
|
+
attr_accessor :lex_state
|
|
31
|
+
|
|
32
|
+
def initialize(code)
|
|
33
|
+
@lex_state = EXPR_BEG
|
|
34
|
+
@in_fname = false
|
|
35
|
+
@continue = false
|
|
36
|
+
reset
|
|
37
|
+
super(code)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def reset
|
|
41
|
+
@command_start = false
|
|
42
|
+
@cmd_state = @command_start
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def on_nl(tok, data)
|
|
46
|
+
case @lex_state
|
|
47
|
+
when EXPR_FNAME, EXPR_DOT
|
|
48
|
+
@continue = true
|
|
49
|
+
else
|
|
50
|
+
@continue = false
|
|
51
|
+
@lex_state = EXPR_BEG unless (EXPR_LABEL & @lex_state) != 0
|
|
52
|
+
end
|
|
53
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def on_ignored_nl(tok, data)
|
|
57
|
+
case @lex_state
|
|
58
|
+
when EXPR_FNAME, EXPR_DOT
|
|
59
|
+
@continue = true
|
|
60
|
+
else
|
|
61
|
+
@continue = false
|
|
62
|
+
@lex_state = EXPR_BEG unless (EXPR_LABEL & @lex_state) != 0
|
|
63
|
+
end
|
|
64
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def on_op(tok, data)
|
|
68
|
+
case tok
|
|
69
|
+
when '&', '|', '!', '!=', '!~'
|
|
70
|
+
case @lex_state
|
|
71
|
+
when EXPR_FNAME, EXPR_DOT
|
|
72
|
+
@lex_state = EXPR_ARG
|
|
73
|
+
else
|
|
74
|
+
@lex_state = EXPR_BEG
|
|
75
|
+
end
|
|
76
|
+
when '<<'
|
|
77
|
+
# TODO next token?
|
|
78
|
+
case @lex_state
|
|
79
|
+
when EXPR_FNAME, EXPR_DOT
|
|
80
|
+
@lex_state = EXPR_ARG
|
|
81
|
+
else
|
|
82
|
+
@lex_state = EXPR_BEG
|
|
83
|
+
end
|
|
84
|
+
when '?'
|
|
85
|
+
@lex_state = EXPR_BEG
|
|
86
|
+
when '&&', '||', '+=', '-=', '*=', '**=',
|
|
87
|
+
'&=', '|=', '^=', '<<=', '>>=', '||=', '&&='
|
|
88
|
+
@lex_state = EXPR_BEG
|
|
89
|
+
when '::'
|
|
90
|
+
case @lex_state
|
|
91
|
+
when EXPR_ARG, EXPR_CMDARG
|
|
92
|
+
@lex_state = EXPR_DOT
|
|
93
|
+
when EXPR_FNAME, EXPR_DOT
|
|
94
|
+
@lex_state = EXPR_ARG
|
|
95
|
+
else
|
|
96
|
+
@lex_state = EXPR_BEG
|
|
97
|
+
end
|
|
98
|
+
else
|
|
99
|
+
case @lex_state
|
|
100
|
+
when EXPR_FNAME, EXPR_DOT
|
|
101
|
+
@lex_state = EXPR_ARG
|
|
102
|
+
else
|
|
103
|
+
@lex_state = EXPR_BEG
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def on_kw(tok, data)
|
|
110
|
+
case tok
|
|
111
|
+
when 'class'
|
|
112
|
+
@lex_state = EXPR_CLASS
|
|
113
|
+
@in_fname = true
|
|
114
|
+
when 'def'
|
|
115
|
+
@lex_state = EXPR_FNAME
|
|
116
|
+
@continue = true
|
|
117
|
+
@in_fname = true
|
|
118
|
+
when 'if', 'unless', 'while', 'until'
|
|
119
|
+
if ((EXPR_MID | EXPR_END | EXPR_ENDARG | EXPR_ENDFN | EXPR_ARG | EXPR_CMDARG) & @lex_state) != 0 # postfix if
|
|
120
|
+
@lex_state = EXPR_BEG | EXPR_LABEL
|
|
121
|
+
else
|
|
122
|
+
@lex_state = EXPR_BEG
|
|
123
|
+
end
|
|
124
|
+
when 'begin', 'case', 'when'
|
|
125
|
+
@lex_state = EXPR_BEG
|
|
126
|
+
when 'return', 'break'
|
|
127
|
+
@lex_state = EXPR_MID
|
|
128
|
+
else
|
|
129
|
+
if @lex_state == EXPR_FNAME
|
|
130
|
+
@lex_state = EXPR_END
|
|
131
|
+
else
|
|
132
|
+
@lex_state = EXPR_END
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def on_tstring_beg(tok, data)
|
|
139
|
+
@lex_state = EXPR_BEG
|
|
140
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def on_tstring_end(tok, data)
|
|
144
|
+
@lex_state = EXPR_END | EXPR_ENDARG
|
|
145
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def on_CHAR(tok, data)
|
|
149
|
+
@lex_state = EXPR_END
|
|
150
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def on_period(tok, data)
|
|
154
|
+
@lex_state = EXPR_DOT
|
|
155
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def on_int(tok, data)
|
|
159
|
+
@lex_state = EXPR_END | EXPR_ENDARG
|
|
160
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def on_float(tok, data)
|
|
164
|
+
@lex_state = EXPR_END | EXPR_ENDARG
|
|
165
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def on_rational(tok, data)
|
|
169
|
+
@lex_state = EXPR_END | EXPR_ENDARG
|
|
170
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def on_imaginary(tok, data)
|
|
174
|
+
@lex_state = EXPR_END | EXPR_ENDARG
|
|
175
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def on_symbeg(tok, data)
|
|
179
|
+
@lex_state = EXPR_FNAME
|
|
180
|
+
@continue = true
|
|
181
|
+
@in_fname = true
|
|
182
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
private def on_variables(event, tok, data)
|
|
186
|
+
if @in_fname
|
|
187
|
+
@lex_state = EXPR_ENDFN
|
|
188
|
+
@in_fname = false
|
|
189
|
+
@continue = false
|
|
190
|
+
elsif @continue
|
|
191
|
+
case @lex_state
|
|
192
|
+
when EXPR_DOT
|
|
193
|
+
@lex_state = EXPR_ARG
|
|
194
|
+
else
|
|
195
|
+
@lex_state = EXPR_ENDFN
|
|
196
|
+
@continue = false
|
|
197
|
+
end
|
|
198
|
+
else
|
|
199
|
+
@lex_state = EXPR_CMDARG
|
|
200
|
+
end
|
|
201
|
+
data << Token.new(lineno, column, event, tok, @lex_state)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def on_ident(tok, data)
|
|
205
|
+
on_variables(__method__, tok, data)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def on_ivar(tok, data)
|
|
209
|
+
@lex_state = EXPR_END
|
|
210
|
+
on_variables(__method__, tok, data)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def on_cvar(tok, data)
|
|
214
|
+
@lex_state = EXPR_END
|
|
215
|
+
on_variables(__method__, tok, data)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def on_gvar(tok, data)
|
|
219
|
+
@lex_state = EXPR_END
|
|
220
|
+
on_variables(__method__, tok, data)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def on_backref(tok, data)
|
|
224
|
+
@lex_state = EXPR_END
|
|
225
|
+
on_variables(__method__, tok, data)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def on_lparen(tok, data)
|
|
229
|
+
@lex_state = EXPR_LABEL | EXPR_BEG
|
|
230
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def on_rparen(tok, data)
|
|
234
|
+
@lex_state = EXPR_ENDFN
|
|
235
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def on_lbrace(tok, data)
|
|
239
|
+
@lex_state = EXPR_LABEL | EXPR_BEG
|
|
240
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def on_rbrace(tok, data)
|
|
244
|
+
@lex_state = EXPR_ENDARG
|
|
245
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def on_lbracket(tok, data)
|
|
249
|
+
@lex_state = EXPR_LABEL | EXPR_BEG
|
|
250
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def on_rbracket(tok, data)
|
|
254
|
+
@lex_state = EXPR_ENDARG
|
|
255
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def on_const(tok, data)
|
|
259
|
+
case @lex_state
|
|
260
|
+
when EXPR_FNAME
|
|
261
|
+
@lex_state = EXPR_ENDFN
|
|
262
|
+
when EXPR_CLASS, EXPR_CMDARG, EXPR_MID
|
|
263
|
+
@lex_state = EXPR_ARG
|
|
264
|
+
else
|
|
265
|
+
@lex_state = EXPR_CMDARG
|
|
266
|
+
end
|
|
267
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def on_sp(tok, data)
|
|
271
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def on_comma(tok, data)
|
|
275
|
+
@lex_state = EXPR_BEG | EXPR_LABEL if (EXPR_ARG_ANY & @lex_state) != 0
|
|
276
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def on_comment(tok, data)
|
|
280
|
+
@lex_state = EXPR_BEG unless (EXPR_LABEL & @lex_state) != 0
|
|
281
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def on_ignored_sp(tok, data)
|
|
285
|
+
@lex_state = EXPR_BEG unless (EXPR_LABEL & @lex_state) != 0
|
|
286
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def on_heredoc_beg(tok, data)
|
|
290
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
291
|
+
@lex_state = EXPR_END
|
|
292
|
+
data
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def on_heredoc_end(tok, data)
|
|
296
|
+
data << Token.new(lineno, column, __method__, tok, @lex_state)
|
|
297
|
+
@lex_state = EXPR_BEG
|
|
298
|
+
data
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
def on_default(event, tok, data)
|
|
302
|
+
reset
|
|
303
|
+
data << Token.new(lineno, column, event, tok, @lex_state)
|
|
304
|
+
end
|
|
305
|
+
end unless RIPPER_HAS_LEX_STATE
|
|
306
|
+
|
|
307
|
+
class InnerStateLex < Ripper::Filter
|
|
308
|
+
def initialize(code)
|
|
309
|
+
super(code)
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def on_default(event, tok, data)
|
|
313
|
+
data << Token.new(lineno, column, event, tok, state)
|
|
314
|
+
end
|
|
315
|
+
end if RIPPER_HAS_LEX_STATE
|
|
316
|
+
|
|
317
|
+
def get_squashed_tk
|
|
318
|
+
if @buf.empty?
|
|
319
|
+
tk = @tokens.shift
|
|
320
|
+
else
|
|
321
|
+
tk = @buf.shift
|
|
322
|
+
end
|
|
323
|
+
return nil if tk.nil?
|
|
324
|
+
case tk[:kind]
|
|
325
|
+
when :on_symbeg then
|
|
326
|
+
tk = get_symbol_tk(tk)
|
|
327
|
+
when :on_tstring_beg then
|
|
328
|
+
tk = get_string_tk(tk)
|
|
329
|
+
when :on_backtick then
|
|
330
|
+
if (tk[:state] & (EXPR_FNAME | EXPR_ENDFN)) != 0
|
|
331
|
+
@inner_lex.lex_state = EXPR_ARG unless RIPPER_HAS_LEX_STATE
|
|
332
|
+
tk[:kind] = :on_ident
|
|
333
|
+
tk[:state] = Ripper::Lexer.const_defined?(:State) ? Ripper::Lexer::State.new(EXPR_ARG) : EXPR_ARG
|
|
334
|
+
else
|
|
335
|
+
tk = get_string_tk(tk)
|
|
336
|
+
end
|
|
337
|
+
when :on_regexp_beg then
|
|
338
|
+
tk = get_regexp_tk(tk)
|
|
339
|
+
when :on_embdoc_beg then
|
|
340
|
+
tk = get_embdoc_tk(tk)
|
|
341
|
+
when :on_heredoc_beg then
|
|
342
|
+
@heredoc_queue << retrieve_heredoc_info(tk)
|
|
343
|
+
@inner_lex.lex_state = EXPR_END unless RIPPER_HAS_LEX_STATE
|
|
344
|
+
when :on_nl, :on_ignored_nl, :on_comment, :on_heredoc_end then
|
|
345
|
+
if !@heredoc_queue.empty?
|
|
346
|
+
get_heredoc_tk(*@heredoc_queue.shift)
|
|
347
|
+
elsif tk[:text].nil? # :on_ignored_nl sometimes gives nil
|
|
348
|
+
tk[:text] = ''
|
|
349
|
+
end
|
|
350
|
+
when :on_words_beg then
|
|
351
|
+
tk = get_words_tk(tk)
|
|
352
|
+
when :on_qwords_beg then
|
|
353
|
+
tk = get_words_tk(tk)
|
|
354
|
+
when :on_symbols_beg then
|
|
355
|
+
tk = get_words_tk(tk)
|
|
356
|
+
when :on_qsymbols_beg then
|
|
357
|
+
tk = get_words_tk(tk)
|
|
358
|
+
when :on_op then
|
|
359
|
+
if '&.' == tk[:text]
|
|
360
|
+
tk[:kind] = :on_period
|
|
361
|
+
else
|
|
362
|
+
tk = get_op_tk(tk)
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
tk
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
private def get_symbol_tk(tk)
|
|
369
|
+
is_symbol = true
|
|
370
|
+
symbol_tk = Token.new(tk.line_no, tk.char_no, :on_symbol)
|
|
371
|
+
if ":'" == tk[:text] or ':"' == tk[:text]
|
|
372
|
+
tk1 = get_string_tk(tk)
|
|
373
|
+
symbol_tk[:text] = tk1[:text]
|
|
374
|
+
symbol_tk[:state] = tk1[:state]
|
|
375
|
+
else
|
|
376
|
+
case (tk1 = get_squashed_tk)[:kind]
|
|
377
|
+
when :on_ident
|
|
378
|
+
symbol_tk[:text] = ":#{tk1[:text]}"
|
|
379
|
+
symbol_tk[:state] = tk1[:state]
|
|
380
|
+
when :on_tstring_content
|
|
381
|
+
symbol_tk[:text] = ":#{tk1[:text]}"
|
|
382
|
+
symbol_tk[:state] = get_squashed_tk[:state] # skip :on_tstring_end
|
|
383
|
+
when :on_tstring_end
|
|
384
|
+
symbol_tk[:text] = ":#{tk1[:text]}"
|
|
385
|
+
symbol_tk[:state] = tk1[:state]
|
|
386
|
+
when :on_op
|
|
387
|
+
symbol_tk[:text] = ":#{tk1[:text]}"
|
|
388
|
+
symbol_tk[:state] = tk1[:state]
|
|
389
|
+
when :on_ivar
|
|
390
|
+
symbol_tk[:text] = ":#{tk1[:text]}"
|
|
391
|
+
symbol_tk[:state] = tk1[:state]
|
|
392
|
+
when :on_cvar
|
|
393
|
+
symbol_tk[:text] = ":#{tk1[:text]}"
|
|
394
|
+
symbol_tk[:state] = tk1[:state]
|
|
395
|
+
when :on_gvar
|
|
396
|
+
symbol_tk[:text] = ":#{tk1[:text]}"
|
|
397
|
+
symbol_tk[:state] = tk1[:state]
|
|
398
|
+
when :on_const
|
|
399
|
+
symbol_tk[:text] = ":#{tk1[:text]}"
|
|
400
|
+
symbol_tk[:state] = tk1[:state]
|
|
401
|
+
when :on_kw
|
|
402
|
+
symbol_tk[:text] = ":#{tk1[:text]}"
|
|
403
|
+
symbol_tk[:state] = tk1[:state]
|
|
404
|
+
else
|
|
405
|
+
is_symbol = false
|
|
406
|
+
tk = tk1
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
if is_symbol
|
|
410
|
+
tk = symbol_tk
|
|
411
|
+
end
|
|
412
|
+
tk
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
private def get_string_tk(tk)
|
|
416
|
+
string = tk[:text]
|
|
417
|
+
state = nil
|
|
418
|
+
kind = :on_tstring
|
|
419
|
+
loop do
|
|
420
|
+
inner_str_tk = get_squashed_tk
|
|
421
|
+
if inner_str_tk.nil?
|
|
422
|
+
break
|
|
423
|
+
elsif :on_tstring_end == inner_str_tk[:kind]
|
|
424
|
+
string = string + inner_str_tk[:text]
|
|
425
|
+
state = inner_str_tk[:state]
|
|
426
|
+
break
|
|
427
|
+
elsif :on_label_end == inner_str_tk[:kind]
|
|
428
|
+
string = string + inner_str_tk[:text]
|
|
429
|
+
state = inner_str_tk[:state]
|
|
430
|
+
kind = :on_symbol
|
|
431
|
+
break
|
|
432
|
+
else
|
|
433
|
+
string = string + inner_str_tk[:text]
|
|
434
|
+
if :on_embexpr_beg == inner_str_tk[:kind] then
|
|
435
|
+
kind = :on_dstring if :on_tstring == kind
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
Token.new(tk.line_no, tk.char_no, kind, string, state)
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
private def get_regexp_tk(tk)
|
|
443
|
+
string = tk[:text]
|
|
444
|
+
state = nil
|
|
445
|
+
loop do
|
|
446
|
+
inner_str_tk = get_squashed_tk
|
|
447
|
+
if inner_str_tk.nil?
|
|
448
|
+
break
|
|
449
|
+
elsif :on_regexp_end == inner_str_tk[:kind]
|
|
450
|
+
string = string + inner_str_tk[:text]
|
|
451
|
+
state = inner_str_tk[:state]
|
|
452
|
+
break
|
|
453
|
+
else
|
|
454
|
+
string = string + inner_str_tk[:text]
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
Token.new(tk.line_no, tk.char_no, :on_regexp, string, state)
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
private def get_embdoc_tk(tk)
|
|
461
|
+
string = tk[:text]
|
|
462
|
+
until :on_embdoc_end == (embdoc_tk = get_squashed_tk)[:kind] do
|
|
463
|
+
string = string + embdoc_tk[:text]
|
|
464
|
+
end
|
|
465
|
+
string = string + embdoc_tk[:text]
|
|
466
|
+
Token.new(tk.line_no, tk.char_no, :on_embdoc, string, embdoc_tk.state)
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
private def get_heredoc_tk(heredoc_name, indent)
|
|
470
|
+
string = ''
|
|
471
|
+
start_tk = nil
|
|
472
|
+
prev_tk = nil
|
|
473
|
+
until heredoc_end?(heredoc_name, indent, tk = @tokens.shift) do
|
|
474
|
+
start_tk = tk unless start_tk
|
|
475
|
+
if (prev_tk.nil? or "\n" == prev_tk[:text][-1]) and 0 != tk[:char_no]
|
|
476
|
+
string = string + (' ' * tk[:char_no])
|
|
477
|
+
end
|
|
478
|
+
string = string + tk[:text]
|
|
479
|
+
prev_tk = tk
|
|
480
|
+
end
|
|
481
|
+
start_tk = tk unless start_tk
|
|
482
|
+
prev_tk = tk unless prev_tk
|
|
483
|
+
@buf.unshift tk # closing heredoc
|
|
484
|
+
heredoc_tk = Token.new(start_tk.line_no, start_tk.char_no, :on_heredoc, string, prev_tk.state)
|
|
485
|
+
@buf.unshift heredoc_tk
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
private def retrieve_heredoc_info(tk)
|
|
489
|
+
name = tk[:text].gsub(/\A<<[-~]?(['"`]?)(.+)\1\z/, '\2')
|
|
490
|
+
indent = tk[:text] =~ /\A<<[-~]/
|
|
491
|
+
[name, indent]
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
private def heredoc_end?(name, indent, tk)
|
|
495
|
+
result = false
|
|
496
|
+
if :on_heredoc_end == tk[:kind] then
|
|
497
|
+
tk_name = tk[:text].chomp
|
|
498
|
+
tk_name.lstrip! if indent
|
|
499
|
+
if name == tk_name
|
|
500
|
+
result = true
|
|
501
|
+
end
|
|
502
|
+
end
|
|
503
|
+
result
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
private def get_words_tk(tk)
|
|
507
|
+
string = ''
|
|
508
|
+
start_token = tk[:text]
|
|
509
|
+
start_quote = tk[:text].rstrip[-1]
|
|
510
|
+
line_no = tk[:line_no]
|
|
511
|
+
char_no = tk[:char_no]
|
|
512
|
+
state = tk[:state]
|
|
513
|
+
end_quote =
|
|
514
|
+
case start_quote
|
|
515
|
+
when ?( then ?)
|
|
516
|
+
when ?[ then ?]
|
|
517
|
+
when ?{ then ?}
|
|
518
|
+
when ?< then ?>
|
|
519
|
+
else start_quote
|
|
520
|
+
end
|
|
521
|
+
end_token = nil
|
|
522
|
+
loop do
|
|
523
|
+
tk = get_squashed_tk
|
|
524
|
+
if tk.nil?
|
|
525
|
+
end_token = end_quote
|
|
526
|
+
break
|
|
527
|
+
elsif :on_tstring_content == tk[:kind] then
|
|
528
|
+
string += tk[:text]
|
|
529
|
+
elsif :on_words_sep == tk[:kind] or :on_tstring_end == tk[:kind] then
|
|
530
|
+
if end_quote == tk[:text].strip then
|
|
531
|
+
end_token = tk[:text]
|
|
532
|
+
break
|
|
533
|
+
else
|
|
534
|
+
string += tk[:text]
|
|
535
|
+
end
|
|
536
|
+
else
|
|
537
|
+
string += tk[:text]
|
|
538
|
+
end
|
|
539
|
+
end
|
|
540
|
+
text = "#{start_token}#{string}#{end_token}"
|
|
541
|
+
Token.new(line_no, char_no, :on_dstring, text, state)
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
private def get_op_tk(tk)
|
|
545
|
+
redefinable_operators = %w[! != !~ % & * ** + +@ - -@ / < << <= <=> == === =~ > >= >> [] []= ^ ` | ~]
|
|
546
|
+
if redefinable_operators.include?(tk[:text]) and tk[:state] == EXPR_ARG then
|
|
547
|
+
@inner_lex.lex_state = EXPR_ARG unless RIPPER_HAS_LEX_STATE
|
|
548
|
+
tk[:state] = Ripper::Lexer.const_defined?(:State) ? Ripper::Lexer::State.new(EXPR_ARG) : EXPR_ARG
|
|
549
|
+
tk[:kind] = :on_ident
|
|
550
|
+
elsif tk[:text] =~ /^[-+]$/ then
|
|
551
|
+
tk_ahead = get_squashed_tk
|
|
552
|
+
case tk_ahead[:kind]
|
|
553
|
+
when :on_int, :on_float, :on_rational, :on_imaginary then
|
|
554
|
+
tk[:text] += tk_ahead[:text]
|
|
555
|
+
tk[:kind] = tk_ahead[:kind]
|
|
556
|
+
tk[:state] = tk_ahead[:state]
|
|
557
|
+
when :on_heredoc_beg, :on_tstring, :on_dstring # frozen/non-frozen string literal
|
|
558
|
+
tk[:text] += tk_ahead[:text]
|
|
559
|
+
tk[:kind] = tk_ahead[:kind]
|
|
560
|
+
tk[:state] = tk_ahead[:state]
|
|
561
|
+
else
|
|
562
|
+
@buf.unshift tk_ahead
|
|
563
|
+
end
|
|
564
|
+
end
|
|
565
|
+
tk
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
def initialize(code)
|
|
569
|
+
@buf = []
|
|
570
|
+
@heredoc_queue = []
|
|
571
|
+
@inner_lex = InnerStateLex.new(code)
|
|
572
|
+
@tokens = @inner_lex.parse([])
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
def self.parse(code)
|
|
576
|
+
lex = self.new(code)
|
|
577
|
+
tokens = []
|
|
578
|
+
begin
|
|
579
|
+
while tk = lex.get_squashed_tk
|
|
580
|
+
tokens.push tk
|
|
581
|
+
end
|
|
582
|
+
rescue StopIteration
|
|
583
|
+
end
|
|
584
|
+
tokens
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
def self.end?(token)
|
|
588
|
+
(token[:state] & EXPR_END)
|
|
589
|
+
end
|
|
590
|
+
end
|