YkLib 0.1.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 (125) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +6 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +7 -0
  7. data/Gemfile.lock +34 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +44 -0
  10. data/Rakefile +6 -0
  11. data/YkLib.gemspec +29 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/lib/YkLib/Yk/__advance__.rb +151 -0
  15. data/lib/YkLib/Yk/__defun__.rb +44 -0
  16. data/lib/YkLib/Yk/__hook__.rb +244 -0
  17. data/lib/YkLib/Yk/__minmax__.rb +123 -0
  18. data/lib/YkLib/Yk/__stdlog.rb +329 -0
  19. data/lib/YkLib/Yk/adhocLiterals/email.rb +119 -0
  20. data/lib/YkLib/Yk/adhocLiterals/path.rb +402 -0
  21. data/lib/YkLib/Yk/adhocLiterals/tag.rb +19 -0
  22. data/lib/YkLib/Yk/adhocLiterals/url.rb +36 -0
  23. data/lib/YkLib/Yk/adhocLiterals.rb +199 -0
  24. data/lib/YkLib/Yk/auto_escseq.rb +5 -0
  25. data/lib/YkLib/Yk/auto_pstore.rb +179 -0
  26. data/lib/YkLib/Yk/bsearch.rb +120 -0
  27. data/lib/YkLib/Yk/clambda.rb +309 -0
  28. data/lib/YkLib/Yk/confLine.rb +423 -0
  29. data/lib/YkLib/Yk/create_tty_width_available.rb +24 -0
  30. data/lib/YkLib/Yk/crypt.rb +26 -0
  31. data/lib/YkLib/Yk/debug2 +1 -0
  32. data/lib/YkLib/Yk/debug2.rb +473 -0
  33. data/lib/YkLib/Yk/debugout.rb +139 -0
  34. data/lib/YkLib/Yk/email_tz.rb +533 -0
  35. data/lib/YkLib/Yk/enum_expect.rb +170 -0
  36. data/lib/YkLib/Yk/errlog.rb +5 -0
  37. data/lib/YkLib/Yk/escseq.rb +59 -0
  38. data/lib/YkLib/Yk/eval_alt.rb +281 -0
  39. data/lib/YkLib/Yk/expector.rb +93 -0
  40. data/lib/YkLib/Yk/fetch.rb +556 -0
  41. data/lib/YkLib/Yk/fetch_old.rb +290 -0
  42. data/lib/YkLib/Yk/fib.rb +158 -0
  43. data/lib/YkLib/Yk/file_aux.rb +843 -0
  44. data/lib/YkLib/Yk/file_aux2.rb +919 -0
  45. data/lib/YkLib/Yk/file_aux_old.rb +160 -0
  46. data/lib/YkLib/Yk/filemod.rb +19 -0
  47. data/lib/YkLib/Yk/force_escseq.rb +3 -0
  48. data/lib/YkLib/Yk/generator__.rb +144 -0
  49. data/lib/YkLib/Yk/generator__.rb.org +139 -0
  50. data/lib/YkLib/Yk/indenter/argless_case.rb +46 -0
  51. data/lib/YkLib/Yk/indenter/each_token.rb +671 -0
  52. data/lib/YkLib/Yk/indenter/free_case.rb +313 -0
  53. data/lib/YkLib/Yk/indenter/if_less.rb +53 -0
  54. data/lib/YkLib/Yk/indenter/independent_ensure.rb +23 -0
  55. data/lib/YkLib/Yk/indenter/independent_rescue.rb +23 -0
  56. data/lib/YkLib/Yk/indenter/operand_circumflex.rb +0 -0
  57. data/lib/YkLib/Yk/indenter/operand_period.rb +16 -0
  58. data/lib/YkLib/Yk/indenter/parenless_and.rb +37 -0
  59. data/lib/YkLib/Yk/indenter/post_test.rb +48 -0
  60. data/lib/YkLib/Yk/indenter/token.rb +1525 -0
  61. data/lib/YkLib/Yk/indenter.rb +1382 -0
  62. data/lib/YkLib/Yk/inot.rb +265 -0
  63. data/lib/YkLib/Yk/intf.rb +815 -0
  64. data/lib/YkLib/Yk/io_aux.rb +1332 -0
  65. data/lib/YkLib/Yk/ioctl.rb +60 -0
  66. data/lib/YkLib/Yk/ipcc.rb +87 -0
  67. data/lib/YkLib/Yk/ipcountry.rb +207 -0
  68. data/lib/YkLib/Yk/ipv4adr.rb +318 -0
  69. data/lib/YkLib/Yk/localmail.rb +276 -0
  70. data/lib/YkLib/Yk/method_chain.rb +359 -0
  71. data/lib/YkLib/Yk/misc_tz.rb +1716 -0
  72. data/lib/YkLib/Yk/missing_method.rb +50 -0
  73. data/lib/YkLib/Yk/mojiConv.rb +257 -0
  74. data/lib/YkLib/Yk/nostdlog.rb +4 -0
  75. data/lib/YkLib/Yk/on_marshal.rb +20 -0
  76. data/lib/YkLib/Yk/overrider.rb +47 -0
  77. data/lib/YkLib/Yk/path.rb +293 -0
  78. data/lib/YkLib/Yk/path_aux.rb +883 -0
  79. data/lib/YkLib/Yk/path_aux_alt.rb +0 -0
  80. data/lib/YkLib/Yk/path_rep.rb +1267 -0
  81. data/lib/YkLib/Yk/pg_setup.rb +917 -0
  82. data/lib/YkLib/Yk/procinfo.rb +314 -0
  83. data/lib/YkLib/Yk/proclist.rb +492 -0
  84. data/lib/YkLib/Yk/property.rb +863 -0
  85. data/lib/YkLib/Yk/ranger.rb +606 -0
  86. data/lib/YkLib/Yk/resolv_tz.rb +88 -0
  87. data/lib/YkLib/Yk/rlprompt.rb +73 -0
  88. data/lib/YkLib/Yk/rootexec.rb +48 -0
  89. data/lib/YkLib/Yk/rpm-packageproxy.rb +784 -0
  90. data/lib/YkLib/Yk/rpm-packageproxy2.rb +1430 -0
  91. data/lib/YkLib/Yk/rwhen.rb +21 -0
  92. data/lib/YkLib/Yk/selector.rb +124 -0
  93. data/lib/YkLib/Yk/set.rb +170 -0
  94. data/lib/YkLib/Yk/shellquote.rb +300 -0
  95. data/lib/YkLib/Yk/sio.rb +1001 -0
  96. data/lib/YkLib/Yk/sio0.rb +835 -0
  97. data/lib/YkLib/Yk/sio_aux.rb +1524 -0
  98. data/lib/YkLib/Yk/sio_inot.rb +86 -0
  99. data/lib/YkLib/Yk/sock_aux.rb +42 -0
  100. data/lib/YkLib/Yk/spipe.rb +843 -0
  101. data/lib/YkLib/Yk/sql_table.rb +565 -0
  102. data/lib/YkLib/Yk/stdlog.rb +4 -0
  103. data/lib/YkLib/Yk/syscommand.rb +173 -0
  104. data/lib/YkLib/Yk/sysinit.rb +75 -0
  105. data/lib/YkLib/Yk/ttyFontWidth.rb +46113 -0
  106. data/lib/YkLib/Yk/tty_char.dump +0 -0
  107. data/lib/YkLib/Yk/tty_char.rb +47 -0
  108. data/lib/YkLib/Yk/tty_char_create.rb +437031 -0
  109. data/lib/YkLib/Yk/tty_char_static.rb +437016 -0
  110. data/lib/YkLib/Yk/tty_rewrite.rb +142 -0
  111. data/lib/YkLib/Yk/tty_str.rb +461 -0
  112. data/lib/YkLib/Yk/tty_width.dat.rb +114 -0
  113. data/lib/YkLib/Yk/tty_width.rb +180 -0
  114. data/lib/YkLib/Yk/tty_width_available +569 -0
  115. data/lib/YkLib/Yk/tty_width_list +0 -0
  116. data/lib/YkLib/Yk/tty_width_list.linux +280 -0
  117. data/lib/YkLib/Yk/tty_width_list.windows +324 -0
  118. data/lib/YkLib/Yk/tz_tty +0 -0
  119. data/lib/YkLib/Yk/tz_tty.rb +0 -0
  120. data/lib/YkLib/Yk/uprepos.rb +94 -0
  121. data/lib/YkLib/Yk/userinfo.rb +91 -0
  122. data/lib/YkLib/Yk/with.rb +109 -0
  123. data/lib/YkLib/version.rb +3 -0
  124. data/lib/YkLib.rb +6 -0
  125. metadata +170 -0
@@ -0,0 +1,671 @@
1
+
2
+ class Token
3
+
4
+ Starters = %i{
5
+ begin
6
+ def
7
+ class
8
+ module
9
+ if
10
+ unless
11
+ loop_for
12
+
13
+ ensure
14
+ rescue
15
+ when
16
+ free_in
17
+ free_for
18
+ free_when
19
+ }
20
+ StartersMayBrace = %i{
21
+ }
22
+
23
+ def closeBeginner pi
24
+ ""
25
+ end
26
+
27
+ Modules :Begin, :Def, :Class, :Module, :If, :Unless, :LoopFor do
28
+ def closeBeginner pi
29
+ ins = (requireArg? ?
30
+ (closeSentence(pi); argEnd = pi; ?;)
31
+ : ' ') + "end"
32
+ end
33
+ end
34
+
35
+ class ForWithoutIn < Exception
36
+ def initialize
37
+ super "new line or semicolon is not allowed after 'for' arguments"
38
+ end
39
+ end
40
+
41
+ class WhenWithoutArg < Exception
42
+ def initialize (k)
43
+ super "new line or semicolon is not allowed after '#{k}' arguments"
44
+ end
45
+ end
46
+
47
+ class CaseWithoutArg < Exception
48
+ def initialize
49
+ super "missing argment for 'case'"
50
+ end
51
+ end
52
+
53
+ module OnSemicolon
54
+ def onClassify
55
+ case parent.kind
56
+ when :on_lbrace
57
+ parent.kind = :lbrace_clause
58
+ end
59
+ end
60
+ end
61
+
62
+ module OnNl
63
+ def closeBeginner pi
64
+ c = iteratorMethod
65
+ addModPrev, "do"
66
+ c.trySetupIterator(:preset, self) || "end"
67
+ end
68
+ end
69
+
70
+ def checkRequireArgStarterWithoutArg
71
+ case parent.kind
72
+ when *%i{if elsif unless while until on_tlambda post_test_while post_test_until \\ =}
73
+ raise Error.new("missing argument for '#{parent.str}'")
74
+ when :for
75
+ if parent.in
76
+ raise Error.new("missing argument for 'in'")
77
+ end
78
+ raise WhenWithoutArg.new(parent.str)
79
+ when :when
80
+ raise WhenWithoutArg.new(parent.str)
81
+ when :in
82
+ raise Error.new("missing argument for 'in'")
83
+ end
84
+ end
85
+
86
+ def checkRequireArgStarterWithArg
87
+ case parent.kind
88
+ when :for
89
+ if !parent.in?
90
+ raise ForWithoutIn.new
91
+ end
92
+ when :on_tlambda
93
+ if !defined?(Endless) || kind == :on_semicolon
94
+ raise Error.new("new line or semicolon is not allowed after '->' arguments")
95
+ end
96
+ when :"=" # for one line method
97
+ spop
98
+ when :post_test_while, :post_test_until
99
+ postTestFinalize self
100
+ end
101
+ end
102
+
103
+ Modules :OnSemicolon, :OnNl do
104
+ MethodChain.override do
105
+ def onClassify
106
+ t.parent.closeSentence self
107
+ t.parent.iteratorCand = nil
108
+ begin
109
+ super #raise ForWithoutIn
110
+ if parent.requireArg? # including for, in
111
+ if !parent.argStart
112
+ if defined?(Endless) || kind == :on_semicolon
113
+ checkRequireArgStarterWithoutArg
114
+ end
115
+ else
116
+ checkRequireArgStarterWithArg
117
+ end
118
+ end
119
+ ensure
120
+ parent.argEnd = self # :rescue is unconditionally close argument
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ attr_accessor :firstRightAssign
127
+ attr_accessor_predicate :maybeRightMatch
128
+ def addComma t
129
+ (@commas ||= []).push t
130
+ end
131
+ module OnComma
132
+ def onClassify
133
+ if idx = [:on_lbrace, :on_lparen].find_index(parent.kind)
134
+ if !parent.iteratorCand
135
+ parent.addComma self
136
+ end
137
+ if idx == 0
138
+ if parent.firstRightAssign # '=>' as in '{ foo => ...'
139
+ parent.maybeRightMatch = true
140
+ end
141
+ end
142
+ end
143
+ # seup hash
144
+ if parent.kind == :on_lbrace && parent.interatorCand == nil && parent.next.kind == :on_label
145
+ parent.kind = :hash_beg
146
+ end
147
+ end
148
+ end
149
+
150
+
151
+ def ambiguousPeriodTheme?
152
+ found = false
153
+ eachParent do |t|
154
+ case t.kind
155
+ when :on_period, :"&."
156
+ if (tmp = s.prev).kind == :on_rparen && tmp.beginner.isOperand? && tmp.beginner.multiArgument?
157
+ return true
158
+ end
159
+ found ? return(true) : found = true
160
+ when :on_lbrace
161
+ if t.inserted?
162
+ found ? return(true) : found = true
163
+ end
164
+ end
165
+ end
166
+ return false
167
+ end
168
+
169
+ def implementOpener
170
+ .....
171
+ end
172
+
173
+ module RightAssignOpn
174
+ ::Token.registerModule self, :'=>'
175
+ def onClassify
176
+ # seup hash
177
+ if parent.kind == :on_lbrace && parent.iteratorCand == nil
178
+ if parent.firstRightAssign
179
+ parent.kind = :hash_beg
180
+ else
181
+ parent.firstRightAssign = t
182
+ end
183
+ parent.kind = :hash_beg
184
+ end
185
+ end
186
+ end
187
+
188
+ module VerticalBarOp
189
+ ::Token.registerModule self, :|
190
+ def onClassify
191
+ if [:do, :on_lbrace].include?(prev) && parent == prev
192
+ if parent == :on_lbrace
193
+ parent = :lbrace_clause
194
+ end
195
+ implementOpener
196
+ reserve_spush
197
+ elsif parent.kind == :|
198
+ reserve_spop
199
+ else
200
+ raise Error.new("unclosed iterator arguments")
201
+ end
202
+ end
203
+ end
204
+
205
+ attr_accessor :body
206
+ module OnLambeg
207
+ def onClassify
208
+ if parent.kind == :on_tlambda && !parent.body
209
+ parent.body = self
210
+ end
211
+ end
212
+ end
213
+
214
+ Modules :OnLparen, :OnLbracket,
215
+ :OnRegexpBeg, :OnBacktick, :OnEmbexprBeg,
216
+ :OnTstringBeg, :OnQwordsBeg,:OnWordsBeg, :OnSymbeg, :OnQsymbolsBeg, :OnSymbolsBeg do
217
+ def onClassify
218
+ reserve_spush
219
+ end
220
+ end
221
+ Modules :OnRparen, :OnRbracket, :OnRbrace, :OnEmbexprEnd do
222
+ def onClassify
223
+ first = true
224
+ if !parent.opponent?(self)
225
+ toInsert = ""
226
+ while parent.isStarter?
227
+ toInsert = (!parent.requireArg? ? ' ' : ?;) + "end" + toInsert
228
+ reserve_spop
229
+ end
230
+ if !parent.opponent?(self)
231
+ raise Error.new("#{parent.str} is not closed")
232
+ end
233
+ if !toInsert.empty?
234
+ @expr[range] = toInsert + @expr[range]
235
+ raise Restart.new
236
+ end
237
+ end
238
+ reserve_spop
239
+ case @kind
240
+ when :on_rparen, :on_rbracket
241
+ beginner.checkAndOp
242
+ when :on_rbrace
243
+ if @@cur.parStack.size == 0 && RBRACE_MODE.include?(@@ebmode)
244
+ if @@ebmode == :bare
245
+ if AdhocLiterals[:url]
246
+ checkUrl first do |led|
247
+ yield first, :url #back track
248
+ end
249
+ end
250
+ if AdhocLiterals[:email]
251
+ checkEmail first do |led|
252
+ yield first, :email #back track
253
+ end
254
+ end
255
+ if AdhocLiterals[:path]
256
+ checkPath first do |led, pstack|
257
+ yield first, :path, led, pstack #back track
258
+ end
259
+ end
260
+ else
261
+ yield first, @@emode
262
+ end
263
+ # do not return : raise Restart.new
264
+ else
265
+ if beginner.kind == :hash_beg
266
+ beginner.addModPrev, " ("
267
+ addModAfter, ")"
268
+ elsif [:on_lbrace, :lbrace_clause].include? beginner.kind # check iterator
269
+ if [:"&.", :on_period, :"::"].include?((tbp = beginner.prev).kind)
270
+ tbp.closeBeginner self
271
+ else
272
+ case (tt = beginner.prev).kind
273
+ when :on_rparen
274
+ case (ttt = tt.beginner.prev).kind
275
+ when :"&.", :on_period # foo&.(...){...}, foo.(...){...}
276
+ ######## (Table1, Table2)::{....}
277
+ beginner.iterator_method = ttt
278
+ # &.(...){...} -> NG
279
+ # .(...){...} -> OK
280
+ when :"::" #foo::(...){...}
281
+ raise Error.new("foo::(...){...} is not implemented")
282
+ else
283
+ unless beginner.iterator_method = ttt.trySetupIterator(:back, beginner.argEnd, self) # foo:label(...){...}
284
+ raise Error.new("cannot find iterator method like 'foo' in 'foo(...){...}'") # foo(...){...}
285
+ end
286
+ end
287
+ # foo'(...){...}
288
+ # foo"(...){...}
289
+ # foo."(...)(...){...}
290
+ # .(...){...}
291
+ when :on_rbracket
292
+ beginner.iterator_method = tt.beginner # a[...]{...} ':[]' is iterator method
293
+ else
294
+ beginner.iterator_method = tt.trySetupIterator(:back, beginner.argEnd, self) # foo:label{...}
295
+ raise Error.new("cannot find iterator method like 'foo' in 'foo{...}'") # foo {...}
296
+ end
297
+ end
298
+ end
299
+ end
300
+ end
301
+ end
302
+ end
303
+ end
304
+ module OnHeredocEnd
305
+ def onClassify
306
+ reserve_spop
307
+ end
308
+ end
309
+ SET_LINE = ".__set_line_num__()"
310
+ module OnTstringEnd
311
+ def onClassify
312
+ case parent.kind
313
+ when :on_tstring_beg
314
+ addModAfter SET_LINE
315
+ reserve_spop
316
+ when :on_qwords_beg, :on_words_beg, :on_symbeg, :on_qsymbols_beg, :on_symbols_beg, :on_backtick
317
+ reserve_spop
318
+ else
319
+ raise Error.new("ERROR: String content closing at #{t.pos} is missing beginning\n")
320
+ end
321
+ if cur.parStack.size == 0 && mode.to_s =~ /_quote$/
322
+ yield first # do not return : raise Retart.new
323
+ end
324
+ end
325
+ end
326
+ module OnLabelEnd
327
+ def onClassify
328
+ if parent.kind == :on_tstring_beg
329
+ reserve_spop
330
+ else
331
+ raise Error.new("ERROR: String content closing at #{t.pos} is missing beginning\n")
332
+ end
333
+ end
334
+ end
335
+ module OnRegexpEnd
336
+ def onClassify
337
+ if parent.kind == :on_regexp_beg
338
+ reserve_spop
339
+ else
340
+ raise Error.new("ERROR: Reglar expression closing at #{t.pos} is missing beginning\n")
341
+ end
342
+ end
343
+ end
344
+
345
+ module BackSlashOp
346
+ ::Token.registerModule self, :"\\"
347
+ def closeBeginner pi
348
+ c = iteratorMethod
349
+ barg_op = argRange ? "|" : ""
350
+ addModReplace "do #{barg_op}"
351
+ argEnd.addModPrev barg_op
352
+ if c
353
+ ins = c.trySetupIterator(:preset, self) || "end"
354
+ else
355
+ addModReplace " ::Kernel::proc do #{barg_op}\n"
356
+ argEnd.addModPrev barg_op
357
+ ins = "end"
358
+ if isSentenceHead?
359
+ if !argRange
360
+ ins += ".call"
361
+ else
362
+ raise Error.new("orphan proc with argumnents")
363
+ end
364
+ end
365
+ end
366
+ ins
367
+ end
368
+ def checkStarter
369
+ if prev.continues? || isSentenceHead?
370
+ reserve_spush # without method
371
+ else
372
+ if (iteratorMethod = parent&.iteratorCand)&.setupIteratorLabel
373
+ parent.iteratorCand = nil
374
+ reserve_spush
375
+ else
376
+ raise Error.new("cannot find iterator method")
377
+ end
378
+ end
379
+ end
380
+ end
381
+
382
+ module OnPeriod
383
+ ::Token.registerModule self, :"&.", :"::"
384
+ def themeExpr tk
385
+ case tk
386
+ when :"&."
387
+ "___theme_period"
388
+ when :"::"
389
+ "___theme_double_colon"
390
+ when :on_period
391
+ "___theme_period"
392
+ end
393
+ end
394
+ private :themeExpr
395
+ def closeBeginner pi
396
+ bOpener, bCloser = if pi.kind != :on_rbrace
397
+ "{", "}"
398
+ else
399
+ "", ""
400
+ end
401
+ if prev.kind == :on_rparen && prev.beginner.isOperand?
402
+ if kind == :"&." && prev.beginner.multiArgument?
403
+ raise Error.new("multiple theme for &. is not allowed")
404
+ end
405
+ # (Table1, Table2)::\n ... -> ____theme_double_colon___(Table1, Table2){ ... }
406
+ prev.beginner.addModPrev themeExpr(kind)
407
+ addModReplace bOpener
408
+ else # a::\n ... -> a::____theme_double_colon___{ ... }
409
+ addModAfter, themeExpr(kind) + bOpener
410
+ end
411
+ ############ implement ".", "@foo", "&&"
412
+ ins = bCloser
413
+ end
414
+ end
415
+
416
+ module OnTlambda
417
+ def onClassify
418
+ reserve_spush
419
+ end
420
+ def closeBeginner pi
421
+ case @body
422
+ when :on_lambeg
423
+ "}"
424
+ when :do
425
+ "end"
426
+ when nil
427
+ if argEnd != :on_nl
428
+ raise Error.new("descrepant -> args")
429
+ end
430
+ argEnd.addModAfter "{"
431
+ ins = "}"
432
+ end
433
+ end
434
+ end
435
+
436
+ module Do
437
+ def onClassify
438
+ if !isOperand?
439
+ t = self
440
+ @parent.instance_eval do
441
+ case @kind
442
+ when :while, :until, :for_in
443
+ if !@do && @argStart
444
+ @do = t
445
+ @argEnd ||= t
446
+ return
447
+ end
448
+ when :on_tlambda
449
+ if !@body
450
+ @body = t
451
+ return
452
+ end
453
+ end
454
+ end
455
+ @iteratorMethod = parent.iteratorCand
456
+ end
457
+ reserve_spush
458
+ end
459
+ def setPostTest t
460
+ @wrapped.changeEntity t
461
+ kind = :post_test_do
462
+ t.kind = ("post_test_" + t.kind.to_s).intern
463
+ end
464
+ def closeBeginner pi
465
+ if c = iteratorMethod
466
+ if parent.iteratorCand == c
467
+ parent.iteratorCand = nil
468
+ end
469
+ c.setupIteratorLabel
470
+ c.trySetupIterator(:preset, self, pi) || "end"
471
+ else
472
+ k = (lop = prev).kind
473
+ if k == :on_rbracket && lop.beginner.prev.terminal? # foo [...] do
474
+ @iteratorMethod = lop.beginner
475
+ "end"
476
+ elsif k == :on_rparen && (tt = lop.beginner.prev).invoker? # foo:label(...), (foo)":label(...), foo'(...)
477
+ tt.trySetupIterator(:back, self, pi) || "end" #tt.dprev = label of foo:label(...)
478
+ else
479
+ ins = "end"
480
+ end
481
+ end
482
+ end
483
+ end
484
+
485
+ Modules :While, :Until do
486
+ def closeBeginner pi
487
+ trySetupIterator(:forward, self, pi) || "end"
488
+ end
489
+ end
490
+
491
+
492
+ def thenRelated? t
493
+ if [:if, :elsif, :rescue, :unless, :when, :in].include?(@kind)
494
+ if @argStarted
495
+ (!@argEnd || @argEnd == t && t.kind == :on_semicolon || @argEnd.kind == :on_nl && @argEnd.prev == t)
496
+ end
497
+ end
498
+ end
499
+ def setThen t
500
+ if @then
501
+ raise Error.new("duplicated then")
502
+ end
503
+ @then = t
504
+ @argEnd ||= t
505
+ end
506
+ class OrphanContClause < ::Exception
507
+ def initialize msg
508
+ super "orphan #{msg}"
509
+ end
510
+ end
511
+ module Then
512
+ def onClassify
513
+ if parent.thenRelated?(prev_non_sp) # prev_non_sp : ';' or '\n'
514
+ parent.setThen self
515
+ else
516
+ raise OrphanContCause.new(str)
517
+ end
518
+ end
519
+ end
520
+
521
+ def clauseCont t
522
+ if requireArg?
523
+ raise Error.new("#{t.str} cluase without '#{@kind}' arguments or semicolon, new line")
524
+ end
525
+ @wrapped.changeEntity t
526
+ end
527
+ [:Else, :Elsif].each do |mod|
528
+ %{
529
+ module #{mod}
530
+ def onClassify
531
+ if continuedClause?
532
+ parent.clauseCont self
533
+ else
534
+ raise OrphanContClause.new(str)
535
+ end
536
+ end
537
+ end
538
+ }
539
+ end
540
+
541
+ Modules :If, :Unless, :Case, :Module, :Begin, :For, :Def do
542
+ def onClassify
543
+ reserve_spush
544
+ end
545
+ end
546
+
547
+ module Class
548
+ def onClassify
549
+ mth = findParent{%i{module class def origin}.include? _1.kind}
550
+ if defined?(Endless)
551
+ n = self.next
552
+ else
553
+ n = next_non_sp
554
+ end
555
+ if (if mth.kind == :def
556
+ n.kind == :<<
557
+ else
558
+ %i{<< on_const ::}.include? n.kind
559
+ end)
560
+ then
561
+ reserve_spush # singleton class
562
+ else # self.class
563
+ kind = :on_ident
564
+ addModPrev "self."
565
+ end
566
+ end
567
+ end
568
+
569
+ class ForWhen < Exception
570
+ def initialize arg
571
+ @whenOrIn = arg
572
+ super "'#{arg.str}' is directly placed after 'for'"
573
+ end
574
+ end
575
+
576
+ module In
577
+ def onClassify
578
+ if continuedClause?
579
+ t = self
580
+ @parent.instance_eval do
581
+ case @kind
582
+ when :in
583
+ if !@argEnd
584
+ raise Error.new("'in' clause started inside previous 'in' clause without arguments or semicolon, new line")
585
+ end
586
+ when :case
587
+ @kind = :non_free_case
588
+ if !@argStart
589
+ raise Error.new("'in' clause started inside previous 'case' clause without arguments or semicolon, new line")
590
+ end
591
+ @argEnd ||= t
592
+ end
593
+ @wrapped.changeEntity t
594
+ end
595
+ elsif parent.kind == :for && cur.idtStack.last == parent
596
+ if parent.argStart
597
+ parent.argEnd = self
598
+ parent.in = self
599
+ parent.kind = :loop_for
600
+ parent.wrapped.changeEntity self
601
+ @kind = :loop_for_in
602
+ else # for in ....
603
+ raise ForWhen.new(self)
604
+ end
605
+ else
606
+ raise OrphanContClause.new(str)
607
+ end
608
+ end
609
+ end
610
+
611
+ module When
612
+ def onClassify
613
+ if continuedClause?
614
+ t = self
615
+ @parent.instance_eval do
616
+ case @kind
617
+ when :when
618
+ if !@argEnd
619
+ raise Error.new("'when' clause started inside previous 'when' clause without arguments or semicolon, new line")
620
+ end
621
+ when :case
622
+ @kind = :non_free_case
623
+ if !@argStart
624
+ raise Error.new("'when' clause started inside previous 'case' clause without arguments or semicolon, new line")
625
+ end
626
+ @argEnd ||= t
627
+ end
628
+ @wrapped.changeEntity t
629
+ end
630
+ elsif parent.kind == :for && cur.idtStack.last == parent && !parent.argStart # for when ....
631
+ raise ForWhen.new(self)
632
+ else
633
+ raise OrphanContClause.new(str)
634
+ end
635
+ end
636
+ end
637
+
638
+ Modules :Rescue, :Ensure do
639
+ def onClassify
640
+ if continuedClause?
641
+ t = self
642
+ @parent.instance_eval do
643
+ case @kind
644
+ when :def, :class, :module, :rescue
645
+ if !@argEnd
646
+ raise Error.new("else cluase without '#{@kind}' arguments or semicolon, new line")
647
+ end
648
+ when :begin
649
+ end
650
+ @wrapped.changeEntity t
651
+ end
652
+ else #independent rescue
653
+ raise OrphanContClause.new(str)
654
+ end
655
+ end
656
+ end
657
+
658
+ module NonFreeCase
659
+ def closeBeginner pi
660
+ "end"
661
+ end
662
+ end
663
+
664
+ module Case
665
+ def closeBeginner pi
666
+ raise ArgumentError.new("'case' missing 'when' or 'in'")
667
+ end
668
+ end
669
+
670
+ end
671
+