adlint 3.0.10 → 3.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 (137) hide show
  1. data/ChangeLog +67 -0
  2. data/MANIFEST +2 -0
  3. data/NEWS +10 -3
  4. data/etc/mesg.d/c_builtin/en_US/messages.yml +29 -1
  5. data/etc/mesg.d/c_builtin/ja_JP/messages.yml +29 -1
  6. data/etc/mesg.d/core/en_US/messages.yml +1 -1
  7. data/etc/mesg.d/core/ja_JP/messages.yml +1 -1
  8. data/features/code_check/W0003.feature +5 -0
  9. data/features/code_check/W0023.feature +32 -0
  10. data/features/code_check/W0024.feature +22 -0
  11. data/features/code_check/W0093.feature +71 -0
  12. data/features/code_check/W0097.feature +4 -0
  13. data/features/code_check/W0100.feature +10 -0
  14. data/features/code_check/W0119.feature +8 -0
  15. data/features/code_check/W0133.feature +8 -0
  16. data/features/code_check/W0134.feature +8 -0
  17. data/features/code_check/W0136.feature +8 -0
  18. data/features/code_check/W0138.feature +8 -0
  19. data/features/code_check/W0140.feature +8 -0
  20. data/features/code_check/W0142.feature +8 -0
  21. data/features/code_check/W0143.feature +8 -0
  22. data/features/code_check/W0144.feature +8 -0
  23. data/features/code_check/W0145.feature +8 -0
  24. data/features/code_check/W0146.feature +8 -0
  25. data/features/code_check/W0147.feature +8 -0
  26. data/features/code_check/W0148.feature +8 -0
  27. data/features/code_check/W0149.feature +8 -0
  28. data/features/code_check/W0150.feature +8 -0
  29. data/features/code_check/W0151.feature +8 -0
  30. data/features/code_check/W0152.feature +8 -0
  31. data/features/code_check/W0153.feature +8 -0
  32. data/features/code_check/W0154.feature +8 -0
  33. data/features/code_check/W0155.feature +8 -0
  34. data/features/code_check/W0156.feature +8 -0
  35. data/features/code_check/W0157.feature +8 -0
  36. data/features/code_check/W0158.feature +8 -0
  37. data/features/code_check/W0159.feature +8 -0
  38. data/features/code_check/W0160.feature +8 -0
  39. data/features/code_check/W0161.feature +8 -0
  40. data/features/code_check/W0162.feature +8 -0
  41. data/features/code_check/W0163.feature +8 -0
  42. data/features/code_check/W0164.feature +8 -0
  43. data/features/code_check/W0165.feature +8 -0
  44. data/features/code_check/W0166.feature +8 -0
  45. data/features/code_check/W0167.feature +8 -0
  46. data/features/code_check/W0168.feature +8 -0
  47. data/features/code_check/W0169.feature +8 -0
  48. data/features/code_check/W0170.feature +8 -0
  49. data/features/code_check/W0171.feature +8 -0
  50. data/features/code_check/W0172.feature +8 -0
  51. data/features/code_check/W0173.feature +8 -0
  52. data/features/code_check/W0174.feature +8 -0
  53. data/features/code_check/W0175.feature +8 -0
  54. data/features/code_check/W0176.feature +8 -0
  55. data/features/code_check/W0177.feature +8 -0
  56. data/features/code_check/W0178.feature +8 -0
  57. data/features/code_check/W0179.feature +8 -0
  58. data/features/code_check/W0180.feature +8 -0
  59. data/features/code_check/W0181.feature +8 -0
  60. data/features/code_check/W0250.feature +8 -0
  61. data/features/code_check/W0422.feature +194 -0
  62. data/features/code_check/W0459.feature +16 -0
  63. data/features/code_check/W0460.feature +342 -0
  64. data/features/code_check/W0461.feature +5 -0
  65. data/features/code_check/W0497.feature +12 -0
  66. data/features/code_check/W0499.feature +6 -0
  67. data/features/code_check/W0502.feature +6 -0
  68. data/features/code_check/W0570.feature +47 -0
  69. data/features/code_check/W0573.feature +8 -0
  70. data/features/code_check/W0582.feature +4 -0
  71. data/features/code_check/W0583.feature +4 -0
  72. data/features/code_check/W0584.feature +10 -0
  73. data/features/code_check/W0599.feature +10 -0
  74. data/features/code_check/W0644.feature +2 -0
  75. data/features/code_check/W0649.feature +14 -0
  76. data/features/code_check/W0650.feature +12 -0
  77. data/features/code_check/W0685.feature +10 -0
  78. data/features/code_check/W0686.feature +8 -0
  79. data/features/code_check/W0711.feature +2 -0
  80. data/features/code_check/W0712.feature +2 -0
  81. data/features/code_check/W0713.feature +2 -0
  82. data/features/code_check/W0714.feature +2 -0
  83. data/features/code_check/W0715.feature +2 -0
  84. data/features/code_check/W0718.feature +2 -0
  85. data/features/code_check/W0719.feature +8 -0
  86. data/features/code_check/W0732.feature +18 -0
  87. data/features/code_check/W0733.feature +18 -0
  88. data/features/code_check/W0734.feature +24 -0
  89. data/features/code_check/W0735.feature +24 -0
  90. data/features/code_check/W0747.feature +8 -0
  91. data/features/code_check/W0749.feature +8 -0
  92. data/features/code_check/W0750.feature +8 -0
  93. data/features/code_check/W0753.feature +8 -0
  94. data/features/code_check/W0754.feature +8 -0
  95. data/features/code_check/W0759.feature +8 -0
  96. data/features/code_check/W0760.feature +8 -0
  97. data/features/code_check/W0761.feature +8 -0
  98. data/features/code_check/W0762.feature +8 -0
  99. data/features/code_check/W0794.feature +6 -0
  100. data/features/code_check/W1050.feature +8 -0
  101. data/features/code_check/W1066.feature +8 -0
  102. data/features/code_check/W1067.feature +8 -0
  103. data/features/code_check/W1068.feature +8 -0
  104. data/features/code_check/W1071.feature +4 -0
  105. data/features/code_check/W9003.feature +2 -0
  106. data/lib/adlint/cc1.rb +1 -0
  107. data/lib/adlint/cc1/branch.rb +34 -13
  108. data/lib/adlint/cc1/conv.rb +3 -3
  109. data/lib/adlint/cc1/ctrlexpr.rb +12 -7
  110. data/lib/adlint/cc1/environ.rb +12 -2
  111. data/lib/adlint/cc1/expr.rb +10 -8
  112. data/lib/adlint/cc1/interp.rb +56 -49
  113. data/lib/adlint/cc1/mediator.rb +9 -5
  114. data/lib/adlint/cc1/object.rb +37 -34
  115. data/lib/adlint/cc1/trace.rb +287 -0
  116. data/lib/adlint/cc1/type.rb +15 -15
  117. data/lib/adlint/cc1/value.rb +823 -427
  118. data/lib/adlint/cpp/eval.rb +5 -2
  119. data/lib/adlint/cpp/source.rb +21 -22
  120. data/lib/adlint/exam/c_builtin/cc1_check.rb +1636 -1067
  121. data/lib/adlint/exam/c_builtin/cc1_check_shima.rb +28 -22
  122. data/lib/adlint/exam/c_builtin/cc1_code.rb +4 -4
  123. data/lib/adlint/exam/c_builtin/cc1_metric.rb +14 -14
  124. data/lib/adlint/location.rb +5 -7
  125. data/lib/adlint/metric.rb +2 -2
  126. data/lib/adlint/prelude.rb +6 -2
  127. data/lib/adlint/report.rb +2 -2
  128. data/lib/adlint/version.rb +3 -3
  129. data/share/doc/developers_guide_ja.html +10 -4
  130. data/share/doc/developers_guide_ja.texi +8 -2
  131. data/share/doc/users_guide_en.html +679 -72
  132. data/share/doc/users_guide_en.texi +557 -12
  133. data/share/doc/users_guide_ja.html +678 -74
  134. data/share/doc/users_guide_ja.texi +554 -13
  135. data/spec/adlint/cc1/ctrlexpr_spec.rb +20 -11
  136. data/spec/adlint/cc1/domain_spec.rb +9 -0
  137. metadata +4 -2
@@ -2401,9 +2401,9 @@ module Cc1 #:nodoc:
2401
2401
  end
2402
2402
 
2403
2403
  class FunctionType < Type
2404
- def initialize(type_tbl, retn_type, param_types, have_va_list = false)
2405
- super(type_tbl, create_name(retn_type, param_types, have_va_list))
2406
- @return_type = retn_type
2404
+ def initialize(type_tbl, ret_type, param_types, have_va_list = false)
2405
+ super(type_tbl, create_name(ret_type, param_types, have_va_list))
2406
+ @return_type = ret_type
2407
2407
  @parameter_types = param_types
2408
2408
  @have_va_list = have_va_list
2409
2409
  end
@@ -2933,33 +2933,33 @@ module Cc1 #:nodoc:
2933
2933
  end
2934
2934
 
2935
2935
  private
2936
- def create_name(retn_type, param_types, have_va_list)
2937
- "#{retn_type.name}(" +
2936
+ def create_name(ret_type, param_types, have_va_list)
2937
+ "#{ret_type.name}(" +
2938
2938
  param_types.map { |type| type.name }.join(", ") +
2939
2939
  (have_va_list ? ",...)" : ")")
2940
2940
  end
2941
2941
 
2942
- def create_image(retn_type, param_types, have_va_list)
2943
- "#{retn_type.image}(" +
2942
+ def create_image(ret_type, param_types, have_va_list)
2943
+ "#{ret_type.image}(" +
2944
2944
  param_types.map { |type| type.image }.join(", ") +
2945
2945
  (have_va_list ? ",...)" : ")")
2946
2946
  end
2947
2947
 
2948
- def create_brief_image(retn_type, param_types, have_va_list)
2949
- "#{retn_type.brief_image}(" +
2948
+ def create_brief_image(ret_type, param_types, have_va_list)
2949
+ "#{ret_type.brief_image}(" +
2950
2950
  param_types.map { |type| type.brief_image }.join(", ") +
2951
2951
  (have_va_list ? ",...)" : ")")
2952
2952
  end
2953
2953
  end
2954
2954
 
2955
2955
  class FunctionTypeId < TypeId
2956
- def initialize(retn_type, param_types, have_va_list)
2957
- super(create_value(retn_type, param_types, have_va_list))
2956
+ def initialize(ret_type, param_types, have_va_list)
2957
+ super(create_value(ret_type, param_types, have_va_list))
2958
2958
  end
2959
2959
 
2960
2960
  private
2961
- def create_value(retn_type, param_types, have_va_list)
2962
- "#{retn_type.brief_image}(" +
2961
+ def create_value(ret_type, param_types, have_va_list)
2962
+ "#{ret_type.brief_image}(" +
2963
2963
  param_types.map { |type| type.brief_image }.join(",") +
2964
2964
  (have_va_list ? ",...)" : ")")
2965
2965
  end
@@ -7266,8 +7266,8 @@ module Cc1 #:nodoc:
7266
7266
  ArrayType.new(self, base_type, len)
7267
7267
  end
7268
7268
 
7269
- def function_type(retn_type, param_types, have_va_list = false)
7270
- FunctionType.new(self, retn_type, param_types, have_va_list)
7269
+ def function_type(ret_type, param_types, have_va_list = false)
7270
+ FunctionType.new(self, ret_type, param_types, have_va_list)
7271
7271
  end
7272
7272
 
7273
7273
  def builtin_function_type
@@ -43,6 +43,49 @@ module Cc1 #:nodoc:
43
43
  end
44
44
  end
45
45
 
46
+ # == DESCRIPTION
47
+ # === TestEvidence class hierarchy
48
+ # TestEvidence
49
+ # <-- TrivialTestEvidence
50
+ # <-- NontrivialTestEvidence
51
+ # <-- UndefinableTestEvidence
52
+ # <-- NullabilityTestEvidence
53
+ # <-- DefinableTestEvidence
54
+ class TestEvidence
55
+ def fulfilled?
56
+ subclass_responsibility
57
+ end
58
+
59
+ def emit_context_messages(report, loc)
60
+ subclass_responsibility
61
+ end
62
+ end
63
+
64
+ # == DESCRIPTION
65
+ # === ValueTest class hierarchy
66
+ # ValueTest
67
+ # <-- TrivialValueTest
68
+ # <-- NontrivialValueTest
69
+ class ValueTest
70
+ def initialize(evid)
71
+ @evidence = evid
72
+ end
73
+
74
+ attr_reader :evidence
75
+
76
+ def result
77
+ subclass_responsibility
78
+ end
79
+
80
+ def true?
81
+ !!result
82
+ end
83
+
84
+ def false?
85
+ !true?
86
+ end
87
+ end
88
+
46
89
  # == DESCRIPTION
47
90
  # === Value class hierarchy
48
91
  # Value
@@ -91,7 +134,7 @@ module Cc1 #:nodoc:
91
134
  subclass_responsibility
92
135
  end
93
136
 
94
- def overwrite!(val)
137
+ def overwrite!(val, tag)
95
138
  subclass_responsibility
96
139
  end
97
140
 
@@ -201,59 +244,67 @@ module Cc1 #:nodoc:
201
244
  subclass_responsibility
202
245
  end
203
246
 
204
- def must_be_equal_to?(val)
247
+ def test_must_be_undefined
248
+ subclass_responsibility
249
+ end
250
+
251
+ def test_may_be_undefined
252
+ subclass_responsibility
253
+ end
254
+
255
+ def test_must_be_equal_to(val)
205
256
  subclass_responsibility
206
257
  end
207
258
 
208
- def may_be_equal_to?(val)
259
+ def test_may_be_equal_to(val)
209
260
  subclass_responsibility
210
261
  end
211
262
 
212
- def must_not_be_equal_to?(val)
263
+ def test_must_not_be_equal_to(val)
213
264
  subclass_responsibility
214
265
  end
215
266
 
216
- def may_not_be_equal_to?(val)
267
+ def test_may_not_be_equal_to(val)
217
268
  subclass_responsibility
218
269
  end
219
270
 
220
- def must_be_less_than?(val)
271
+ def test_must_be_less_than(val)
221
272
  subclass_responsibility
222
273
  end
223
274
 
224
- def may_be_less_than?(val)
275
+ def test_may_be_less_than(val)
225
276
  subclass_responsibility
226
277
  end
227
278
 
228
- def must_be_greater_than?(val)
279
+ def test_must_be_greater_than(val)
229
280
  subclass_responsibility
230
281
  end
231
282
 
232
- def may_be_greater_than?(val)
283
+ def test_may_be_greater_than(val)
233
284
  subclass_responsibility
234
285
  end
235
286
 
236
- def must_be_undefined?
287
+ def test_must_be_null
237
288
  subclass_responsibility
238
289
  end
239
290
 
240
- def may_be_undefined?
291
+ def test_may_be_null
241
292
  subclass_responsibility
242
293
  end
243
294
 
244
- def must_be_true?
295
+ def test_must_be_true
245
296
  subclass_responsibility
246
297
  end
247
298
 
248
- def may_be_true?
299
+ def test_may_be_true
249
300
  subclass_responsibility
250
301
  end
251
302
 
252
- def must_be_false?
303
+ def test_must_be_false
253
304
  subclass_responsibility
254
305
  end
255
306
 
256
- def may_be_false?
307
+ def test_may_be_false
257
308
  subclass_responsibility
258
309
  end
259
310
 
@@ -286,20 +337,41 @@ module Cc1 #:nodoc:
286
337
  end
287
338
  end
288
339
 
340
+ class TrivialTestEvidence < TestEvidence
341
+ def fulfilled?
342
+ true
343
+ end
344
+
345
+ def emit_context_messages(report, loc)
346
+ # NOTE: Evidence of the test result about SingleValue is trivial.
347
+ # So, nothing to be complemented.
348
+ []
349
+ end
350
+ end
351
+
352
+ class TrivialValueTest < ValueTest
353
+ def initialize(rslt)
354
+ super(TrivialTestEvidence.new)
355
+ @result = rslt
356
+ end
357
+
358
+ attr_reader :result
359
+ end
360
+
289
361
  class SingleValue < Value
290
362
  def multiple?
291
363
  false
292
364
  end
293
365
 
294
- def must_be_undefined?
295
- self.undefined?
366
+ def test_must_be_undefined
367
+ TrivialValueTest.new(self.undefined?)
296
368
  end
297
369
 
298
- def may_be_undefined?
370
+ def test_may_be_undefined
299
371
  # NOTE: SingleValue has exactly one value domain.
300
372
  # So, the value of SingleValue may be undefined when the value
301
373
  # must be undefined.
302
- self.must_be_undefined?
374
+ self.test_must_be_undefined
303
375
  end
304
376
 
305
377
  def to_single_value
@@ -307,6 +379,10 @@ module Cc1 #:nodoc:
307
379
  end
308
380
 
309
381
  private
382
+ def scalar_value_of_null
383
+ ScalarValue.of(0, logical_shr?)
384
+ end
385
+
310
386
  def scalar_value_of_true
311
387
  ScalarValue.of_true(logical_shr?)
312
388
  end
@@ -412,9 +488,9 @@ module Cc1 #:nodoc:
412
488
  end
413
489
 
414
490
  def contain?(val)
415
- case single_val = val.to_single_value
491
+ case sval = val.to_single_value
416
492
  when ScalarValue
417
- @domain.contain?(single_val.domain)
493
+ @domain.contain?(sval.domain)
418
494
  else
419
495
  false
420
496
  end
@@ -428,32 +504,28 @@ module Cc1 #:nodoc:
428
504
  @domain.ambiguous?
429
505
  end
430
506
 
431
- def overwrite!(val)
432
- case single_val = val.to_single_value
507
+ def overwrite!(val, *)
508
+ case sval = val.to_single_value
433
509
  when ScalarValue
434
- @domain = single_val.domain
510
+ @domain = sval.domain
435
511
  else
436
512
  raise TypeError, "cannot overwrite scalar with non-scalar."
437
513
  end
438
514
  end
439
515
 
440
516
  def narrow_domain!(op, ope_val)
441
- case ope_single_val = ope_val.to_single_value
517
+ case ope_sval = ope_val.to_single_value
442
518
  when ScalarValue
443
- orig_dom = @domain
444
- @domain = @domain.narrow(op, ope_single_val.domain)
445
- !@domain.equal?(orig_dom)
519
+ @domain = @domain.narrow(op, ope_sval.domain)
446
520
  else
447
521
  raise TypeError, "cannot narrow scalar value domain with non-scalar."
448
522
  end
449
523
  end
450
524
 
451
525
  def widen_domain!(op, ope_val)
452
- case ope_single_val = ope_val.to_single_value
526
+ case ope_sval = ope_val.to_single_value
453
527
  when ScalarValue
454
- orig_dom = @domain
455
- @domain = @domain.widen(op, ope_single_val.domain)
456
- !@domain.equal?(orig_dom)
528
+ @domain = @domain.widen(op, ope_sval.domain)
457
529
  else
458
530
  raise TypeError, "cannot widen scalar value domain with non-scalar."
459
531
  end
@@ -464,9 +536,9 @@ module Cc1 #:nodoc:
464
536
  end
465
537
 
466
538
  def single_value_unified_with(rhs_val)
467
- case rhs_single_val = rhs_val.to_single_value
539
+ case rhs_sval = rhs_val.to_single_value
468
540
  when ScalarValue
469
- ScalarValue.new(@domain.union(rhs_single_val.domain))
541
+ ScalarValue.new(@domain.union(rhs_sval.domain))
470
542
  else
471
543
  raise TypeError, "cannot unify scalar value with non-scalar."
472
544
  end
@@ -485,90 +557,90 @@ module Cc1 #:nodoc:
485
557
  end
486
558
 
487
559
  def +(rhs_val)
488
- case rhs_single_val = rhs_val.to_single_value
560
+ case rhs_sval = rhs_val.to_single_value
489
561
  when ScalarValue
490
- ScalarValue.new(@domain + rhs_single_val.domain)
562
+ ScalarValue.new(@domain + rhs_sval.domain)
491
563
  else
492
564
  raise TypeError, "binary operation between scalar and non-scalar."
493
565
  end
494
566
  end
495
567
 
496
568
  def -(rhs_val)
497
- case rhs_single_val = rhs_val.to_single_value
569
+ case rhs_sval = rhs_val.to_single_value
498
570
  when ScalarValue
499
- ScalarValue.new(@domain - rhs_single_val.domain)
571
+ ScalarValue.new(@domain - rhs_sval.domain)
500
572
  else
501
573
  raise TypeError, "binary operation between scalar and non-scalar."
502
574
  end
503
575
  end
504
576
 
505
577
  def *(rhs_val)
506
- case rhs_single_val = rhs_val.to_single_value
578
+ case rhs_sval = rhs_val.to_single_value
507
579
  when ScalarValue
508
- ScalarValue.new(@domain * rhs_single_val.domain)
580
+ ScalarValue.new(@domain * rhs_sval.domain)
509
581
  else
510
582
  raise TypeError, "binary operation between scalar and non-scalar."
511
583
  end
512
584
  end
513
585
 
514
586
  def /(rhs_val)
515
- case rhs_single_val = rhs_val.to_single_value
587
+ case rhs_sval = rhs_val.to_single_value
516
588
  when ScalarValue
517
- ScalarValue.new(@domain / rhs_single_val.domain)
589
+ ScalarValue.new(@domain / rhs_sval.domain)
518
590
  else
519
591
  raise TypeError, "binary operation between scalar and non-scalar."
520
592
  end
521
593
  end
522
594
 
523
595
  def %(rhs_val)
524
- case rhs_single_val = rhs_val.to_single_value
596
+ case rhs_sval = rhs_val.to_single_value
525
597
  when ScalarValue
526
- ScalarValue.new(@domain % rhs_single_val.domain)
598
+ ScalarValue.new(@domain % rhs_sval.domain)
527
599
  else
528
600
  raise TypeError, "binary operation between scalar and non-scalar."
529
601
  end
530
602
  end
531
603
 
532
604
  def &(rhs_val)
533
- case rhs_single_val = rhs_val.to_single_value
605
+ case rhs_sval = rhs_val.to_single_value
534
606
  when ScalarValue
535
- ScalarValue.new(@domain & rhs_single_val.domain)
607
+ ScalarValue.new(@domain & rhs_sval.domain)
536
608
  else
537
609
  raise TypeError, "binary operation between scalar and non-scalar."
538
610
  end
539
611
  end
540
612
 
541
613
  def |(rhs_val)
542
- case rhs_single_val = rhs_val.to_single_value
614
+ case rhs_sval = rhs_val.to_single_value
543
615
  when ScalarValue
544
- ScalarValue.new(@domain | rhs_single_val.domain)
616
+ ScalarValue.new(@domain | rhs_sval.domain)
545
617
  else
546
618
  raise TypeError, "binary operation between scalar and non-scalar."
547
619
  end
548
620
  end
549
621
 
550
622
  def ^(rhs_val)
551
- case rhs_single_val = rhs_val.to_single_value
623
+ case rhs_sval = rhs_val.to_single_value
552
624
  when ScalarValue
553
- ScalarValue.new(@domain ^ rhs_single_val.domain)
625
+ ScalarValue.new(@domain ^ rhs_sval.domain)
554
626
  else
555
627
  raise TypeError, "binary operation between scalar and non-scalar."
556
628
  end
557
629
  end
558
630
 
559
631
  def <<(rhs_val)
560
- case rhs_single_val = rhs_val.to_single_value
632
+ case rhs_sval = rhs_val.to_single_value
561
633
  when ScalarValue
562
- ScalarValue.new(@domain << rhs_single_val.domain)
634
+ ScalarValue.new(@domain << rhs_sval.domain)
563
635
  else
564
636
  raise TypeError, "binary operation between scalar and non-scalar."
565
637
  end
566
638
  end
567
639
 
568
640
  def >>(rhs_val)
569
- case rhs_single_val = rhs_val.to_single_value
641
+ case rhs_sval = rhs_val.to_single_value
570
642
  when ScalarValue
571
- ScalarValue.new(@domain >> rhs_single_val.domain)
643
+ ScalarValue.new(@domain >> rhs_sval.domain)
572
644
  else
573
645
  raise TypeError, "binary operation between scalar and non-scalar."
574
646
  end
@@ -579,176 +651,193 @@ module Cc1 #:nodoc:
579
651
  end
580
652
 
581
653
  def <(rhs_val)
582
- case rhs_single_val = rhs_val.to_single_value
654
+ case rhs_sval = rhs_val.to_single_value
583
655
  when ScalarValue
584
- ScalarValue.new(@domain < rhs_single_val.domain)
656
+ ScalarValue.new(@domain < rhs_sval.domain)
585
657
  else
586
658
  raise TypeError, "comparison between scalar and non-scalar."
587
659
  end
588
660
  end
589
661
 
590
662
  def >(rhs_val)
591
- case rhs_single_val = rhs_val.to_single_value
663
+ case rhs_sval = rhs_val.to_single_value
592
664
  when ScalarValue
593
- ScalarValue.new(@domain > rhs_single_val.domain)
665
+ ScalarValue.new(@domain > rhs_sval.domain)
594
666
  else
595
667
  raise TypeError, "comparison between scalar and non-scalar."
596
668
  end
597
669
  end
598
670
 
599
671
  def ==(rhs_val)
600
- case rhs_single_val = rhs_val.to_single_value
672
+ case rhs_sval = rhs_val.to_single_value
601
673
  when ScalarValue
602
- ScalarValue.new(@domain == rhs_single_val.domain)
674
+ ScalarValue.new(@domain == rhs_sval.domain)
603
675
  else
604
676
  raise TypeError, "comparison between scalar and non-scalar."
605
677
  end
606
678
  end
607
679
 
608
680
  def !=(rhs_val)
609
- case rhs_single_val = rhs_val.to_single_value
681
+ case rhs_sval = rhs_val.to_single_value
610
682
  when ScalarValue
611
- ScalarValue.new(@domain != rhs_single_val.domain)
683
+ ScalarValue.new(@domain != rhs_sval.domain)
612
684
  else
613
685
  raise TypeError, "comparison between scalar and non-scalar."
614
686
  end
615
687
  end
616
688
 
617
689
  def <=(rhs_val)
618
- case rhs_single_val = rhs_val.to_single_value
690
+ case rhs_sval = rhs_val.to_single_value
619
691
  when ScalarValue
620
- ScalarValue.new(@domain <= rhs_single_val.domain)
692
+ ScalarValue.new(@domain <= rhs_sval.domain)
621
693
  else
622
694
  raise TypeError, "comparison between scalar and non-scalar."
623
695
  end
624
696
  end
625
697
 
626
698
  def >=(rhs_val)
627
- case rhs_single_val = rhs_val.to_single_value
699
+ case rhs_sval = rhs_val.to_single_value
628
700
  when ScalarValue
629
- ScalarValue.new(@domain >= rhs_single_val.domain)
701
+ ScalarValue.new(@domain >= rhs_sval.domain)
630
702
  else
631
703
  raise TypeError, "comparison between scalar and non-scalar."
632
704
  end
633
705
  end
634
706
 
635
707
  def logical_and(rhs_val)
636
- case rhs_single_val = rhs_val.to_single_value
708
+ case rhs_sval = rhs_val.to_single_value
637
709
  when ScalarValue
638
- ScalarValue.new(@domain.logical_and(rhs_single_val.domain))
710
+ ScalarValue.new(@domain.logical_and(rhs_sval.domain))
639
711
  else
640
712
  raise TypeError, "comparison between scalar and non-scalar."
641
713
  end
642
714
  end
643
715
 
644
716
  def logical_or(rhs_val)
645
- case rhs_single_val = rhs_val.to_single_value
717
+ case rhs_sval = rhs_val.to_single_value
646
718
  when ScalarValue
647
- ScalarValue.new(@domain.logical_or(rhs_single_val.domain))
719
+ ScalarValue.new(@domain.logical_or(rhs_sval.domain))
648
720
  else
649
721
  raise TypeError, "comparison between scalar and non-scalar."
650
722
  end
651
723
  end
652
724
 
653
- def must_be_equal_to?(val)
654
- case single_val = val.to_single_value.dup
725
+ def test_must_be_equal_to(val)
726
+ case sval = val.to_single_value.dup
655
727
  when ScalarValue
656
- comp_val = (self == single_val)
657
- single_val.invert_domain!
658
- single_val.narrow_domain!(Operator::EQ, self)
659
- comp_val.domain.intersect?(scalar_value_of_true.domain) &&
728
+ comp_val = (self == sval)
729
+ sval.invert_domain!
730
+ sval.narrow_domain!(Operator::EQ, self)
731
+ TrivialValueTest.new(
732
+ comp_val.domain.intersect?(scalar_value_of_true.domain) &&
660
733
  !comp_val.domain.contain?(scalar_value_of_false.domain) &&
661
- !@domain.intersect?(single_val.domain)
734
+ !@domain.intersect?(sval.domain))
662
735
  else
663
736
  raise TypeError, "comparison between scalar and non-scalar."
664
737
  end
665
738
  end
666
739
 
667
- def may_be_equal_to?(val)
668
- case single_val = val.to_single_value
740
+ def test_may_be_equal_to(val)
741
+ case sval = val.to_single_value
669
742
  when ScalarValue
670
- (self == single_val).domain.intersect?(scalar_value_of_true.domain)
743
+ TrivialValueTest.new(
744
+ (self == sval).domain.intersect?(scalar_value_of_true.domain))
671
745
  else
672
746
  raise TypeError, "comparison between scalar and non-scalar."
673
747
  end
674
748
  end
675
749
 
676
- def must_not_be_equal_to?(val)
677
- case single_val = val.to_single_value
750
+ def test_must_not_be_equal_to(val)
751
+ case sval = val.to_single_value
678
752
  when ScalarValue
679
- comp_val = (self != single_val)
680
- comp_val.domain.intersect?(scalar_value_of_true.domain) &&
753
+ comp_val = (self != sval)
754
+ TrivialValueTest.new(
755
+ comp_val.domain.intersect?(scalar_value_of_true.domain) &&
681
756
  !comp_val.domain.contain?(scalar_value_of_false.domain) &&
682
- !@domain.intersect?(single_val.domain)
757
+ !@domain.intersect?(sval.domain))
683
758
  else
684
759
  raise TypeError, "comparison between scalar and non-scalar."
685
760
  end
686
761
  end
687
762
 
688
- def may_not_be_equal_to?(val)
689
- case single_val = val.to_single_value
763
+ def test_may_not_be_equal_to(val)
764
+ case sval = val.to_single_value
690
765
  when ScalarValue
691
- (self != single_val).domain.intersect?(scalar_value_of_true.domain)
766
+ TrivialValueTest.new(
767
+ (self != sval).domain.intersect?(scalar_value_of_true.domain))
692
768
  else
693
769
  raise TypeError, "comparison between scalar and non-scalar."
694
770
  end
695
771
  end
696
772
 
697
- def must_be_less_than?(val)
698
- case single_val = val.to_single_value
773
+ def test_must_be_less_than(val)
774
+ case sval = val.to_single_value
699
775
  when ScalarValue
700
- comp_val = (self < single_val)
701
- comp_val.domain.intersect?(scalar_value_of_true.domain) &&
702
- !comp_val.domain.contain?(scalar_value_of_false.domain)
776
+ comp_val = (self < sval)
777
+ TrivialValueTest.new(
778
+ comp_val.domain.intersect?(scalar_value_of_true.domain) &&
779
+ !comp_val.domain.contain?(scalar_value_of_false.domain))
703
780
  else
704
781
  raise TypeError, "comparison between scalar and non-scalar."
705
782
  end
706
783
  end
707
784
 
708
- def may_be_less_than?(val)
709
- case single_val = val.to_single_value
785
+ def test_may_be_less_than(val)
786
+ case sval = val.to_single_value
710
787
  when ScalarValue
711
- (self < single_val).domain.intersect?(scalar_value_of_true.domain)
788
+ TrivialValueTest.new(
789
+ (self < sval).domain.intersect?(scalar_value_of_true.domain))
712
790
  else
713
791
  raise TypeError, "comparison between scalar and non-scalar."
714
792
  end
715
793
  end
716
794
 
717
- def must_be_greater_than?(val)
718
- case single_val = val.to_single_value
795
+ def test_must_be_greater_than(val)
796
+ case sval = val.to_single_value
719
797
  when ScalarValue
720
- comp_val = (self > single_val)
721
- comp_val.domain.intersect?(scalar_value_of_true.domain) &&
722
- !comp_val.domain.contain?(scalar_value_of_false.domain)
798
+ comp_val = (self > sval)
799
+ TrivialValueTest.new(
800
+ comp_val.domain.intersect?(scalar_value_of_true.domain) &&
801
+ !comp_val.domain.contain?(scalar_value_of_false.domain))
723
802
  else
724
803
  raise TypeError, "comparison between scalar and non-scalar."
725
804
  end
726
805
  end
727
806
 
728
- def may_be_greater_than?(val)
729
- case single_val = val.to_single_value
807
+ def test_may_be_greater_than(val)
808
+ case sval = val.to_single_value
730
809
  when ScalarValue
731
- (self > single_val).domain.intersect?(scalar_value_of_true.domain)
810
+ TrivialValueTest.new(
811
+ (self > sval).domain.intersect?(scalar_value_of_true.domain))
732
812
  else
733
813
  raise TypeError, "comparison between scalar and non-scalar."
734
814
  end
735
815
  end
736
816
 
737
- def must_be_true?
738
- self.may_be_equal_to?(scalar_value_of_true) &&
739
- self.must_not_be_equal_to?(scalar_value_of_false)
817
+ def test_must_be_null
818
+ test_must_be_equal_to(scalar_value_of_null)
740
819
  end
741
820
 
742
- def may_be_true?
743
- self.may_be_equal_to?(scalar_value_of_true)
821
+ def test_may_be_null
822
+ test_may_be_equal_to(scalar_value_of_null)
744
823
  end
745
824
 
746
- def must_be_false?
747
- self.must_be_equal_to?(scalar_value_of_false)
825
+ def test_must_be_true
826
+ TrivialValueTest.new(
827
+ test_may_be_equal_to(scalar_value_of_true).true? &&
828
+ test_must_not_be_equal_to(scalar_value_of_false).true?)
748
829
  end
749
830
 
750
- def may_be_false?
751
- self.may_be_equal_to?(scalar_value_of_false)
831
+ def test_may_be_true
832
+ test_may_be_equal_to(scalar_value_of_true)
833
+ end
834
+
835
+ def test_must_be_false
836
+ test_must_be_equal_to(scalar_value_of_false)
837
+ end
838
+
839
+ def test_may_be_false
840
+ test_may_be_equal_to(scalar_value_of_false)
752
841
  end
753
842
 
754
843
  def coerce_to(type)
@@ -812,12 +901,10 @@ module Cc1 #:nodoc:
812
901
  end
813
902
 
814
903
  def contain?(val)
815
- case single_val = val.to_single_value
904
+ case sval = val.to_single_value
816
905
  when ArrayValue
817
- if @values.size == single_val.values.size
818
- @values.zip(single_val.values).all? do |lhs, rhs|
819
- lhs.contain?(rhs)
820
- end
906
+ if @values.size == sval.values.size
907
+ @values.zip(sval.values).all? { |lhs, rhs| lhs.contain?(rhs) }
821
908
  else
822
909
  false
823
910
  end
@@ -834,11 +921,11 @@ module Cc1 #:nodoc:
834
921
  @values.empty? ? false : @values.all? { |val| val.ambiguous? }
835
922
  end
836
923
 
837
- def overwrite!(val)
838
- case single_val = val.to_single_value
924
+ def overwrite!(val, tag)
925
+ case sval = val.to_single_value
839
926
  when ArrayValue
840
- @values.zip(single_val.values).each do |lhs, rhs|
841
- rhs && lhs.overwrite!(rhs)
927
+ @values.zip(sval.values).each do |lhs, rhs|
928
+ rhs && lhs.overwrite!(rhs, tag)
842
929
  end
843
930
  else
844
931
  raise TypeError, "cannot overwrite array with non-array."
@@ -846,30 +933,30 @@ module Cc1 #:nodoc:
846
933
  end
847
934
 
848
935
  def narrow_domain!(op, ope_val)
849
- case ope_single_val = ope_val.to_single_value
936
+ case ope_sval = ope_val.to_single_value
850
937
  when ArrayValue
851
- @values.zip(ope_single_val.values).map { |lhs, rhs|
938
+ @values.zip(ope_sval.values).each do |lhs, rhs|
852
939
  if rhs
853
940
  lhs.narrow_domain!(op, rhs)
854
941
  else
855
942
  next
856
943
  end
857
- }.any?
944
+ end
858
945
  else
859
946
  raise TypeError, "cannot narrow array value domain with non-array."
860
947
  end
861
948
  end
862
949
 
863
950
  def widen_domain!(op, ope_val)
864
- case ope_single_val = ope_val.to_single_value
951
+ case ope_sval = ope_val.to_single_value
865
952
  when ArrayValue
866
- @values.zip(ope_single_val.values).map { |lhs, rhs|
953
+ @values.zip(ope_sval.values).each do |lhs, rhs|
867
954
  if rhs
868
955
  lhs.widen_domain!(op, rhs)
869
956
  else
870
957
  next
871
958
  end
872
- }.any?
959
+ end
873
960
  else
874
961
  raise TypeError, "cannot widen array value domain with non-array."
875
962
  end
@@ -880,9 +967,9 @@ module Cc1 #:nodoc:
880
967
  end
881
968
 
882
969
  def single_value_unified_with(rhs_val)
883
- case rhs_single_val = rhs_val.to_single_value
970
+ case rhs_sval = rhs_val.to_single_value
884
971
  when ArrayValue
885
- ArrayValue.new(@values.zip(rhs_single_val.values).map { |lhs, rhs|
972
+ ArrayValue.new(@values.zip(rhs_sval.values).map { |lhs, rhs|
886
973
  lhs.single_value_unified_with(rhs)
887
974
  })
888
975
  else
@@ -993,10 +1080,10 @@ module Cc1 #:nodoc:
993
1080
  # of an array variable should be evaluated into a pointer to the
994
1081
  # array body.
995
1082
  # So, this comparison operator should not be reached.
996
- case rhs_single_val = rhs_val.to_single_value
1083
+ case rhs_sval = rhs_val.to_single_value
997
1084
  when ArrayValue
998
- if @values.size == rhs_single_val.values.size
999
- zipped = @values.zip(rhs_single_val.values)
1085
+ if @values.size == rhs_sval.values.size
1086
+ zipped = @values.zip(rhs_sval.values)
1000
1087
  zipped.reduce(scalar_value_of_nil) do |rslt_val, (lhs, rhs)|
1001
1088
  rslt_val.single_value_unified_with(lhs < rhs)
1002
1089
  end
@@ -1013,10 +1100,10 @@ module Cc1 #:nodoc:
1013
1100
  # of an array variable should be evaluated into a pointer to the
1014
1101
  # array body.
1015
1102
  # So, this comparison operator should not be reached.
1016
- case rhs_single_val = rhs_val.to_single_value
1103
+ case rhs_sval = rhs_val.to_single_value
1017
1104
  when ArrayValue
1018
- if @values.size == rhs_single_val.values.size
1019
- zipped = @values.zip(rhs_single_val.values)
1105
+ if @values.size == rhs_sval.values.size
1106
+ zipped = @values.zip(rhs_sval.values)
1020
1107
  zipped.reduce(scalar_value_of_nil) do |rslt_val, (lhs, rhs)|
1021
1108
  rslt_val.single_value_unified_with(lhs > rhs)
1022
1109
  end
@@ -1033,10 +1120,10 @@ module Cc1 #:nodoc:
1033
1120
  # of an array variable should be evaluated into a pointer to the
1034
1121
  # array body.
1035
1122
  # So, this comparison operator should not be reached.
1036
- case rhs_single_val = rhs_val.to_single_value
1123
+ case rhs_sval = rhs_val.to_single_value
1037
1124
  when ArrayValue
1038
- if @values.size == rhs_single_value.values.size
1039
- zipped = @values.zip(rhs_single_val.values)
1125
+ if @values.size == rhs_sval.values.size
1126
+ zipped = @values.zip(rhs_sval.values)
1040
1127
  zipped.reduce(scalar_value_of_nil) do |rslt_val, (lhs, rhs)|
1041
1128
  rslt_val.single_value_unified_with(lhs == rhs)
1042
1129
  end
@@ -1053,10 +1140,10 @@ module Cc1 #:nodoc:
1053
1140
  # of an array variable should be evaluated into a pointer to the
1054
1141
  # array body.
1055
1142
  # So, this comparison operator should not be reached.
1056
- case rhs_single_val = rhs_val.to_single_value
1143
+ case rhs_sval = rhs_val.to_single_value
1057
1144
  when ArrayValue
1058
- if @values.size == rhs_single_val.values.size
1059
- zipped = @values.zip(rhs_single_val.values)
1145
+ if @values.size == rhs_sval.values.size
1146
+ zipped = @values.zip(rhs_sval.values)
1060
1147
  zipped.reduce(scalar_value_of_nil) do |rslt_val, (lhs, rhs)|
1061
1148
  rslt_val.single_value_unified_with(lhs != rhs)
1062
1149
  end
@@ -1073,10 +1160,10 @@ module Cc1 #:nodoc:
1073
1160
  # of an array variable should be evaluated into a pointer to the
1074
1161
  # array body.
1075
1162
  # So, this comparison operator should not be reached.
1076
- case rhs_single_val = rhs_val.to_single_value
1163
+ case rhs_sval = rhs_val.to_single_value
1077
1164
  when ArrayValue
1078
- if @values.size == rhs_single_val.values.size
1079
- zipped = @values.zip(rhs_single_val.values)
1165
+ if @values.size == rhs_sval.values.size
1166
+ zipped = @values.zip(rhs_sval.values)
1080
1167
  zipped.reduce(scalar_value_of_nil) do |rslt_val, (lhs, rhs)|
1081
1168
  rslt_val.single_value_unified_with(lhs <= rhs)
1082
1169
  end
@@ -1093,10 +1180,10 @@ module Cc1 #:nodoc:
1093
1180
  # of an array variable should be evaluated into a pointer to the
1094
1181
  # array body.
1095
1182
  # So, this comparison operator should not be reached.
1096
- case rhs_single_val = rhs_val.to_single_value
1183
+ case rhs_sval = rhs_val.to_single_value
1097
1184
  when ArrayValue
1098
- if @values.size == rhs_single_value.values.size
1099
- zipped = @values.zip(rhs_single_val.values)
1185
+ if @values.size == rhs_sval.values.size
1186
+ zipped = @values.zip(rhs_sval.values)
1100
1187
  zipped.reduce(scalar_value_of_nil) do |rslt_val, (lhs, rhs)|
1101
1188
  rslt_val.single_value_unified_with(lhs >= rhs)
1102
1189
  end
@@ -1113,10 +1200,10 @@ module Cc1 #:nodoc:
1113
1200
  # of an array variable should be evaluated into a pointer to the
1114
1201
  # array body.
1115
1202
  # So, this comparison operator should not be reached.
1116
- case rhs_single_val = rhs_val.to_single_value
1203
+ case rhs_sval = rhs_val.to_single_value
1117
1204
  when ArrayValue
1118
- if @values.size == rhs_single_val.values.size
1119
- zipped = @values.zip(rhs_single_val.values)
1205
+ if @values.size == rhs_sval.values.size
1206
+ zipped = @values.zip(rhs_sval.values)
1120
1207
  zipped.reduce(scalar_value_of_nil) do |rslt_val, (lhs, rhs)|
1121
1208
  rslt_val.single_value_unified_with(lhs.logical_and(rhs))
1122
1209
  end
@@ -1133,10 +1220,10 @@ module Cc1 #:nodoc:
1133
1220
  # of an array variable should be evaluated into a pointer to the
1134
1221
  # array body.
1135
1222
  # So, this comparison operator should not be reached.
1136
- case rhs_single_val = rhs_val.to_single_value
1223
+ case rhs_sval = rhs_val.to_single_value
1137
1224
  when ArrayValue
1138
- if @values.size == rhs_single_val.values.size
1139
- zipped = @values.zip(rhs_single_val.values)
1225
+ if @values.size == rhs_sval.values.size
1226
+ zipped = @values.zip(rhs_sval.values)
1140
1227
  zipped.reduce(scalar_value_of_nil) do |rslt_val, (lhs, rhs)|
1141
1228
  rslt_val.single_value_unified_with(lhs.logical_or(rhs))
1142
1229
  end
@@ -1148,108 +1235,117 @@ module Cc1 #:nodoc:
1148
1235
  end
1149
1236
  end
1150
1237
 
1151
- def must_be_equal_to?(val)
1152
- case single_val = val.to_single_value
1238
+ def test_must_be_equal_to(val)
1239
+ case sval = val.to_single_value
1153
1240
  when ArrayValue
1154
- (self == single_val).must_be_true?
1241
+ TrivialValueTest.new((self == sval).test_must_be_true.result)
1155
1242
  else
1156
1243
  raise TypeError, "comparison between array and non-array."
1157
1244
  end
1158
1245
  end
1159
1246
 
1160
- def may_be_equal_to?(val)
1161
- case single_val = val.to_single_value
1247
+ def test_may_be_equal_to(val)
1248
+ case sval = val.to_single_value
1162
1249
  when ArrayValue
1163
- (self == single_val).may_be_true?
1250
+ TrivialValueTest.new((self == sval).test_may_be_true.result)
1164
1251
  else
1165
1252
  raise TypeError, "comparison between array and non-array."
1166
1253
  end
1167
1254
  end
1168
1255
 
1169
- def must_not_be_equal_to?(val)
1170
- case single_val = val.to_single_value
1256
+ def test_must_not_be_equal_to(val)
1257
+ case sval = val.to_single_value
1171
1258
  when ArrayValue
1172
- (self != single_val).must_be_true?
1259
+ TrivialValueTest.new((self != sval).test_must_be_true.result)
1173
1260
  else
1174
1261
  raise TypeError, "comparison between array and non-array."
1175
1262
  end
1176
1263
  end
1177
1264
 
1178
- def may_not_be_equal_to?(val)
1179
- case single_val = val.to_single_value
1265
+ def test_may_not_be_equal_to(val)
1266
+ case sval = val.to_single_value
1180
1267
  when ArrayValue
1181
- (self != single_val).may_be_true?
1268
+ TrivialValueTest.new((self != sval).test_may_be_true.result)
1182
1269
  else
1183
1270
  raise TypeError, "comparison between array and non-array."
1184
1271
  end
1185
1272
  end
1186
1273
 
1187
- def must_be_less_than?(val)
1188
- case single_val = value.to_single_value
1274
+ def test_must_be_less_than(val)
1275
+ case sval = value.to_single_value
1189
1276
  when ArrayValue
1190
- (self < single_val).must_be_true?
1277
+ TrivialValueTest.new((self < sval).test_must_be_true.result)
1191
1278
  else
1192
1279
  raise TypeError, "comparison between array and non-array."
1193
1280
  end
1194
1281
  end
1195
1282
 
1196
- def may_be_less_than?(val)
1197
- case single_val = val.to_single_value
1283
+ def test_may_be_less_than(val)
1284
+ case sval = val.to_single_value
1198
1285
  when ArrayValue
1199
- (self < single_val).may_be_true?
1286
+ TrivialValueTest.new((self < sval).test_may_be_true.result)
1200
1287
  else
1201
1288
  raise TypeError, "comparison between array and non-array."
1202
1289
  end
1203
1290
  end
1204
1291
 
1205
- def must_be_greater_than?(val)
1206
- case single_val = val.to_single_value
1292
+ def test_must_be_greater_than(val)
1293
+ case sval = val.to_single_value
1207
1294
  when ArrayValue
1208
- (self > single_val).must_be_true?
1295
+ TrivialValueTest.new((self > sval).test_must_be_true.result)
1209
1296
  else
1210
1297
  raise TypeError, "comparison between array and non-array."
1211
1298
  end
1212
1299
  end
1213
1300
 
1214
- def may_be_greater_than?(val)
1215
- case single_val = val.to_single_value
1301
+ def test_may_be_greater_than(val)
1302
+ case sval = val.to_single_value
1216
1303
  when ArrayValue
1217
- (self > single_val).may_be_true?
1304
+ TrivialValueTest.new((self > sval).test_may_be_true.result)
1218
1305
  else
1219
1306
  raise TypeError, "comparison between array and non-array."
1220
1307
  end
1221
1308
  end
1222
1309
 
1223
- def must_be_true?
1310
+ def test_must_be_null
1311
+ TrivialValueTest.new(@values.all? { |val| val.test_must_be_null.result })
1312
+ end
1313
+
1314
+ def test_may_be_null
1315
+ TrivialValueTest.new(@values.all? { |val| val.test_may_be_null.result })
1316
+ end
1317
+
1318
+ def test_must_be_true
1224
1319
  # NOTE: When an array variable appears in expressions, object-specifier
1225
1320
  # of an array variable should be evaluated into a pointer to the
1226
1321
  # array body.
1227
1322
  # So, this method should not be reached.
1228
- @values.all? { |val| val.must_be_true? }
1323
+ TrivialValueTest.new(@values.all? { |val| val.test_must_be_true.result })
1229
1324
  end
1230
1325
 
1231
- def may_be_true?
1326
+ def test_may_be_true
1232
1327
  # NOTE: When an array variable appears in expressions, object-specifier
1233
1328
  # of an array variable should be evaluated into a pointer to the
1234
1329
  # array body.
1235
1330
  # So, this method should not be reached.
1236
- @values.all? { |val| val.may_be_true? }
1331
+ TrivialValueTest.new(@values.all? { |val| val.test_may_be_true.result })
1237
1332
  end
1238
1333
 
1239
- def must_be_false?
1334
+ def test_must_be_false
1240
1335
  # NOTE: When an array variable appears in expressions, object-specifier
1241
1336
  # of an array variable should be evaluated into a pointer to the
1242
1337
  # array body.
1243
1338
  # So, this method should not be reached.
1244
- @values.all? { |val| val.must_be_false? }
1339
+ TrivialValueTest.new(
1340
+ @values.all? { |val| val.test_must_be_false.result })
1245
1341
  end
1246
1342
 
1247
- def may_be_false?
1343
+ def test_may_be_false
1248
1344
  # NOTE: When an array variable appears in expressions, object-specifier
1249
1345
  # of an array variable should be evaluated into a pointer to the
1250
1346
  # array body.
1251
1347
  # So, this method should not be reached.
1252
- @values.all? { |val| val.may_be_false? }
1348
+ TrivialValueTest.new(@values.all? { |val| val.test_may_be_false.result })
1253
1349
  end
1254
1350
 
1255
1351
  def coerce_to(type)
@@ -1312,12 +1408,10 @@ module Cc1 #:nodoc:
1312
1408
  end
1313
1409
 
1314
1410
  def contain?(val)
1315
- case single_val = val.to_single_value
1411
+ case sval = val.to_single_value
1316
1412
  when CompositeValue
1317
- if @values.size == single_val.values.size
1318
- @values.zip(single_val.values).all? do |lhs, rhs|
1319
- lhs.contain?(rhs)
1320
- end
1413
+ if @values.size == sval.values.size
1414
+ @values.zip(sval.values).all? { |lhs, rhs| lhs.contain?(rhs) }
1321
1415
  else
1322
1416
  false
1323
1417
  end
@@ -1334,11 +1428,11 @@ module Cc1 #:nodoc:
1334
1428
  @values.empty? ? false : @values.all? { |val| val.ambiguous? }
1335
1429
  end
1336
1430
 
1337
- def overwrite!(val)
1338
- case single_val = val.to_single_value
1431
+ def overwrite!(val, tag)
1432
+ case sval = val.to_single_value
1339
1433
  when CompositeValue
1340
- @values.zip(single_val.values).each do |lhs, rhs|
1341
- rhs && lhs.overwrite!(rhs)
1434
+ @values.zip(sval.values).each do |lhs, rhs|
1435
+ rhs && lhs.overwrite!(rhs, tag)
1342
1436
  end
1343
1437
  else
1344
1438
  raise TypeError, "cannot overwrite composite with non-composite."
@@ -1346,15 +1440,15 @@ module Cc1 #:nodoc:
1346
1440
  end
1347
1441
 
1348
1442
  def narrow_domain!(op, ope_val)
1349
- case ope_single_val = ope_val.to_single_value
1443
+ case ope_sval = ope_val.to_single_value
1350
1444
  when CompositeValue
1351
- @values.zip(ope_single_val.values).map { |lhs, rhs|
1445
+ @values.zip(ope_sval.values).each do |lhs, rhs|
1352
1446
  if rhs
1353
1447
  lhs.narrow_domain!(op, rhs)
1354
1448
  else
1355
1449
  next
1356
1450
  end
1357
- }.any?
1451
+ end
1358
1452
  else
1359
1453
  raise TypeError,
1360
1454
  "cannot narrow composite value domain with non-composite."
@@ -1362,15 +1456,15 @@ module Cc1 #:nodoc:
1362
1456
  end
1363
1457
 
1364
1458
  def widen_domain!(op, ope_val)
1365
- case ope_single_val = ope_val.to_single_value
1459
+ case ope_sval = ope_val.to_single_value
1366
1460
  when CompositeValue
1367
- @values.zip(ope_single_val.values).map { |lhs, rhs|
1461
+ @values.zip(ope_sval.values).each do |lhs, rhs|
1368
1462
  if rhs
1369
1463
  lhs.widen_domain!(op, rhs)
1370
1464
  else
1371
1465
  next
1372
1466
  end
1373
- }.any?
1467
+ end
1374
1468
  else
1375
1469
  raise TypeError,
1376
1470
  "cannot widen composite value domain with non-composite."
@@ -1382,10 +1476,10 @@ module Cc1 #:nodoc:
1382
1476
  end
1383
1477
 
1384
1478
  def single_value_unified_with(rhs_val)
1385
- case rhs_single_val = rhs_val.to_single_value
1479
+ case rhs_sval = rhs_val.to_single_value
1386
1480
  when CompositeValue
1387
1481
  CompositeValue.new(
1388
- @values.zip(rhs_single_val.values).map { |lhs, rhs|
1482
+ @values.zip(rhs_sval.values).map { |lhs, rhs|
1389
1483
  lhs.single_value_unified_with(rhs)
1390
1484
  })
1391
1485
  else
@@ -1480,10 +1574,10 @@ module Cc1 #:nodoc:
1480
1574
  def <(rhs_val)
1481
1575
  # NOTE: A composite variable cannot appear in expressions except the
1482
1576
  # primary-expression(object-specifier followed by `.').
1483
- case rhs_single_val = rhs_val.to_single_value
1577
+ case rhs_sval = rhs_val.to_single_value
1484
1578
  when CompositeValue
1485
- if @values.size == rhs_single_val.values.size
1486
- zipped = @values.zip(rhs_single_val.values)
1579
+ if @values.size == rhs_sval.values.size
1580
+ zipped = @values.zip(rhs_sval.values)
1487
1581
  zipped.reduce(scalar_value_of_nil) do |rslt_val, (lhs, rhs)|
1488
1582
  rslt_val.single_value_unified_with(lhs < rhs)
1489
1583
  end
@@ -1498,10 +1592,10 @@ module Cc1 #:nodoc:
1498
1592
  def >(rhs_val)
1499
1593
  # NOTE: A composite variable cannot appear in expressions except the
1500
1594
  # primary-expression(object-specifier followed by `.').
1501
- case rhs_single_val = rhs_val.to_single_value
1595
+ case rhs_sval = rhs_val.to_single_value
1502
1596
  when CompositeValue
1503
- if @values.size == rhs_single_val.values.size
1504
- zipped = @values.zip(rhs_single_val.values)
1597
+ if @values.size == rhs_sval.values.size
1598
+ zipped = @values.zip(rhs_sval.values)
1505
1599
  zipped.reduce(scalar_value_of_nil) do |rslt_val, (lhs, rhs)|
1506
1600
  rslt_val.single_value_unified_with(lhs > rhs)
1507
1601
  end
@@ -1516,10 +1610,10 @@ module Cc1 #:nodoc:
1516
1610
  def ==(rhs_val)
1517
1611
  # NOTE: A composite variable cannot appear in expressions except the
1518
1612
  # primary-expression(object-specifier followed by `.').
1519
- case rhs_single_val = rhs_val.to_single_value
1613
+ case rhs_sval = rhs_val.to_single_value
1520
1614
  when CompositeValue
1521
- if @values.size == rhs_single_val.values.size
1522
- zipped = @values.zip(rhs_single_val.values)
1615
+ if @values.size == rhs_sval.values.size
1616
+ zipped = @values.zip(rhs_sval.values)
1523
1617
  zipped.reduce(scalar_value_of_nil) do |rslt_val, (lhs, rhs)|
1524
1618
  rslt_val.single_value_unified_with(lhs == rhs)
1525
1619
  end
@@ -1534,10 +1628,10 @@ module Cc1 #:nodoc:
1534
1628
  def !=(rhs_val)
1535
1629
  # NOTE: A composite variable cannot appear in expressions except the
1536
1630
  # primary-expression(object-specifier followed by `.').
1537
- case rhs_single_val = rhs_val.to_single_value
1631
+ case rhs_sval = rhs_val.to_single_value
1538
1632
  when CompositeValue
1539
- if @values.size == rhs_single_val.values.size
1540
- zipped = @values.zip(rhs_single_val.values)
1633
+ if @values.size == rhs_sval.values.size
1634
+ zipped = @values.zip(rhs_sval.values)
1541
1635
  zipped.reduce(scalar_value_of_nil) do |rslt_val, (lhs, rhs)|
1542
1636
  rslt_val.single_value_unified_with(lhs != rhs)
1543
1637
  end
@@ -1552,10 +1646,10 @@ module Cc1 #:nodoc:
1552
1646
  def <=(rhs_val)
1553
1647
  # NOTE: A composite variable cannot appear in expressions except the
1554
1648
  # primary-expression(object-specifier followed by `.').
1555
- case rhs_single_val = rhs_val.to_single_value
1649
+ case rhs_sval = rhs_val.to_single_value
1556
1650
  when CompositeValue
1557
- if @values.size == rhs_single_val.values.size
1558
- zipped = @values.zip(rhs_single_val.values)
1651
+ if @values.size == rhs_sval.values.size
1652
+ zipped = @values.zip(rhs_sval.values)
1559
1653
  zipped.reduce(scalar_value_of_nil) do |rslt_val, (lhs, rhs)|
1560
1654
  rslt_val.single_value_unified_with(lhs <= rhs)
1561
1655
  end
@@ -1570,10 +1664,10 @@ module Cc1 #:nodoc:
1570
1664
  def >=(rhs_val)
1571
1665
  # NOTE: A composite variable cannot appear in expressions except the
1572
1666
  # primary-expression(object-specifier followed by `.').
1573
- case rhs_single_val = rhs_val.to_single_value
1667
+ case rhs_sval = rhs_val.to_single_value
1574
1668
  when CompositeValue
1575
- if @values.size == rhs_single_val.values.size
1576
- zipped = @values.zip(rhs_single_val.values)
1669
+ if @values.size == rhs_sval.values.size
1670
+ zipped = @values.zip(rhs_sval.values)
1577
1671
  zipped.reduce(scalar_value_of_nil) do |rslt_val, (lhs, rhs)|
1578
1672
  rslt_val.single_value_unified_with(lhs >= rhs)
1579
1673
  end
@@ -1588,10 +1682,10 @@ module Cc1 #:nodoc:
1588
1682
  def logical_and(rhs_val)
1589
1683
  # NOTE: A composite variable cannot appear in expressions except the
1590
1684
  # primary-expression(object-specifier followed by `.').
1591
- case rhs_single_val = rhs_val.to_single_value
1685
+ case rhs_sval = rhs_val.to_single_value
1592
1686
  when CompositeValue
1593
- if @values.size == rhs_single_val.values.size
1594
- zipped = @values.zip(rhs_single_val.values)
1687
+ if @values.size == rhs_sval.values.size
1688
+ zipped = @values.zip(rhs_sval.values)
1595
1689
  zipped.reduce(scalar_value_of_nil) do |rslt_val, (lhs, rhs)|
1596
1690
  rslt_val.single_value_unified_with(lhs.logical_and(rhs))
1597
1691
  end
@@ -1606,10 +1700,10 @@ module Cc1 #:nodoc:
1606
1700
  def logical_or(rhs_val)
1607
1701
  # NOTE: A composite variable cannot appear in expressions except the
1608
1702
  # primary-expression(object-specifier followed by `.').
1609
- case rhs_single_val = rhs_val.to_single_value
1703
+ case rhs_sval = rhs_val.to_single_value
1610
1704
  when CompositeValue
1611
- if @values.size == rhs_single_val.values.size
1612
- zipped = @values.zip(rhs_single_val.values)
1705
+ if @values.size == rhs_sval.values.size
1706
+ zipped = @values.zip(rhs_sval.values)
1613
1707
  zipped.reduce(scalar_value_of_nil) do |rslt_val, (lhs, rhs)|
1614
1708
  rslt_val.single_value_unified_with(lhs.logical_or(rhs))
1615
1709
  end
@@ -1621,100 +1715,109 @@ module Cc1 #:nodoc:
1621
1715
  end
1622
1716
  end
1623
1717
 
1624
- def must_be_equal_to?(val)
1625
- case single_val = val.to_single_value
1718
+ def test_must_be_equal_to(val)
1719
+ case sval = val.to_single_value
1626
1720
  when CompositeValue
1627
- (self == single_val).must_be_true?
1721
+ TrivialValueTest.new((self == sval).test_must_be_true.result)
1628
1722
  else
1629
1723
  raise TypeError, "comparison between composite and non-composite."
1630
1724
  end
1631
1725
  end
1632
1726
 
1633
- def may_be_equal_to?(val)
1634
- case single_val = val.to_single_value
1727
+ def test_may_be_equal_to(val)
1728
+ case sval = val.to_single_value
1635
1729
  when CompositeValue
1636
- (self == single_val).may_be_true?
1730
+ TrivialValueTest.new((self == sval).test_may_be_true.result)
1637
1731
  else
1638
1732
  raise TypeError, "comparison between composite and non-composite."
1639
1733
  end
1640
1734
  end
1641
1735
 
1642
- def must_not_be_equal_to?(val)
1643
- case single_val = val.to_single_value
1736
+ def test_must_not_be_equal_to(val)
1737
+ case sval = val.to_single_value
1644
1738
  when CompositeValue
1645
- (self != single_val).must_be_true?
1739
+ TrivialValueTest.new((self != sval).test_must_be_true.result)
1646
1740
  else
1647
1741
  raise TypeError, "comparison between composite and non-composite."
1648
1742
  end
1649
1743
  end
1650
1744
 
1651
- def may_not_be_equal_to?(val)
1652
- case single_val = val.to_single_value
1745
+ def test_may_not_be_equal_to(val)
1746
+ case sval = val.to_single_value
1653
1747
  when CompositeValue
1654
- (self != single_val).may_be_true?
1748
+ TrivialValueTest.new((self != sval).test_may_be_true.result)
1655
1749
  else
1656
1750
  raise TypeError, "comparison between composite and non-composite."
1657
1751
  end
1658
1752
  end
1659
1753
 
1660
- def must_be_less_than?(val)
1661
- case single_val = val.to_single_value
1754
+ def test_must_be_less_than(val)
1755
+ case sval = val.to_single_value
1662
1756
  when CompositeValue
1663
- (self < single_val).must_be_true?
1757
+ TrivialValueTest.new((self < sval).test_must_be_true.result)
1664
1758
  else
1665
1759
  raise TypeError, "comparison between composite and non-composite."
1666
1760
  end
1667
1761
  end
1668
1762
 
1669
- def may_be_less_than?(val)
1670
- case single_val = val.to_single_value
1763
+ def test_may_be_less_than(val)
1764
+ case sval = val.to_single_value
1671
1765
  when CompositeValue
1672
- (self < single_val).may_be_true?
1766
+ TrivialValueTest.new((self < sval).test_may_be_true.result)
1673
1767
  else
1674
1768
  raise TypeError, "comparison between composite and non-composite."
1675
1769
  end
1676
1770
  end
1677
1771
 
1678
- def must_be_greater_than?(val)
1679
- case single_val = val.to_single_value
1772
+ def test_must_be_greater_than(val)
1773
+ case sval = val.to_single_value
1680
1774
  when CompositeValue
1681
- (self > single_val).must_be_true?
1775
+ TrivialValueTest.new((self > sval).test_must_be_true.result)
1682
1776
  else
1683
1777
  raise TypeError, "comparison between composite and non-composite."
1684
1778
  end
1685
1779
  end
1686
1780
 
1687
- def may_be_greater_than?(val)
1688
- case single_val = val.to_single_value
1781
+ def test_may_be_greater_than(val)
1782
+ case sval = val.to_single_value
1689
1783
  when CompositeValue
1690
- (self > single_val).may_be_true?
1784
+ TrivialValueTest.new((self > sval).test_may_be_true.result)
1691
1785
  else
1692
1786
  raise TypeError, "comparison between composite and non-composite."
1693
1787
  end
1694
1788
  end
1695
1789
 
1696
- def must_be_true?
1790
+ def test_must_be_null
1791
+ TrivialValueTest.new(@values.all? { |val| val.test_must_be_null.result })
1792
+ end
1793
+
1794
+ def test_may_be_null
1795
+ TrivialValueTest.new(@values.all? { |val| val.test_may_be_null.result })
1796
+ end
1797
+
1798
+ def test_must_be_true
1697
1799
  # NOTE: A composite variable cannot appear in expressions except the
1698
1800
  # primary-expression(object-specifier followed by `.').
1699
- @values.all? { |val| val.must_be_true? }
1801
+ TrivialValueTest.new(@values.all? { |val| val.test_must_be_true.result })
1700
1802
  end
1701
1803
 
1702
- def may_be_true?
1804
+ def test_may_be_true
1703
1805
  # NOTE: A composite variable cannot appear in expressions except the
1704
1806
  # primary-expression(object-specifier followed by `.').
1705
- @values.all? { |val| val.may_be_true? }
1807
+ TrivialValueTest.new(@values.all? { |val| val.test_may_be_true.result })
1706
1808
  end
1707
1809
 
1708
- def must_be_false?
1810
+ def test_must_be_false
1709
1811
  # NOTE: A composite variable cannot appear in expressions except the
1710
1812
  # primary-expression(object-specifier followed by `.').
1711
- @values.all? { |val| val.must_be_false? }
1813
+ TrivialValueTest.new(
1814
+ @values.all? { |val| val.test_must_be_false.result })
1712
1815
  end
1713
1816
 
1714
- def may_be_false?
1817
+ def test_may_be_false
1715
1818
  # NOTE: A composite variable cannot appear in expressions except the
1716
1819
  # primary-expression(object-specifier followed by `.').
1717
- @values.all? { |val| val.may_be_false? }
1820
+ TrivialValueTest.new(@values.all? { |val| val.test_may_be_false.result })
1718
1821
  end
1719
1822
 
1720
1823
  def coerce_to(type)
@@ -1749,78 +1852,240 @@ module Cc1 #:nodoc:
1749
1852
  memoize :logical_shr?
1750
1853
  end
1751
1854
 
1855
+ class NontrivialTestEvidence < TestEvidence
1856
+ def initialize(exact)
1857
+ @exact = exact
1858
+ @positive_contribs = []
1859
+ @negative_contribs = []
1860
+ end
1861
+
1862
+ attr_reader :positive_contribs
1863
+ attr_reader :negative_contribs
1864
+
1865
+ def fulfilled?
1866
+ if @exact
1867
+ @negative_contribs.any? { |mval| mval._base.tag.traceable? }
1868
+ else
1869
+ @positive_contribs.any? { |mval| mval._base.tag.traceable? } &&
1870
+ @negative_contribs.any? { |mval| mval._base.tag.traceable? }
1871
+ end
1872
+ end
1873
+
1874
+ def add_positive_contributor(mval)
1875
+ @positive_contribs.push(mval)
1876
+ end
1877
+
1878
+ def add_negative_contributor(mval)
1879
+ @negative_contribs.push(mval)
1880
+ end
1881
+ end
1882
+
1883
+ class UndefinableTestEvidence < NontrivialTestEvidence
1884
+ # NOTE: Context tracing feature will be mixed-in at trace.rb later.
1885
+ end
1886
+
1887
+ class NullabilityTestEvidence < NontrivialTestEvidence
1888
+ # NOTE: Context tracing feature will be mixed-in at trace.rb later.
1889
+ end
1890
+
1891
+ class DefinableTestEvidence < NontrivialTestEvidence
1892
+ # NOTE: Context tracing feature will be mixed-in at trace.rb later.
1893
+
1894
+ def initialize(pred, exact)
1895
+ super(exact)
1896
+ @predicate = pred
1897
+ end
1898
+ end
1899
+
1900
+ class NontrivialValueTest < ValueTest
1901
+ def initialize(evid, exact)
1902
+ super(evid)
1903
+ @exact = exact
1904
+ end
1905
+
1906
+ def result
1907
+ # NOTE: TestEvidence of an NontrivialValueTest must be a kind of
1908
+ # NontrivialTestEvidence.
1909
+ if @exact
1910
+ !evidence.positive_contribs.empty? && evidence.negative_contribs.empty?
1911
+ else
1912
+ !evidence.positive_contribs.empty?
1913
+ end
1914
+ end
1915
+ end
1916
+
1917
+ class TransitionTag
1918
+ def initialize(by = nil, at = nil)
1919
+ self.by = by
1920
+ self.at = at
1921
+ end
1922
+
1923
+ # NOTE: This value is generated by `by' points to AST nodes.
1924
+ attr_reader :by
1925
+
1926
+ def by=(by)
1927
+ @by = by ? by.dup.compact.uniq : []
1928
+ end
1929
+
1930
+ # NOTE: This value is generated in `at' points to branch trees.
1931
+ attr_reader :at
1932
+
1933
+ def at=(at)
1934
+ @at = at ? at.dup.compact.uniq : []
1935
+ end
1936
+
1937
+ def traceable?
1938
+ !@by.empty?
1939
+ end
1940
+
1941
+ def merge!(tag)
1942
+ if tag
1943
+ if at == tag.at
1944
+ self.by = tag.by + by
1945
+ self.at = tag.at + at
1946
+ else
1947
+ self.by = tag.by
1948
+ self.at = tag.at
1949
+ end
1950
+ end
1951
+ end
1952
+
1953
+ def pretty_print(pp)
1954
+ {
1955
+ by: @by.map(&:location),
1956
+ at: @at.map { |br| br.ctrlexpr.to_expr }.compact.map(&:location)
1957
+ }.pretty_print(pp)
1958
+ end
1959
+ end
1960
+
1961
+ class ValueTransition
1962
+ include Enumerable
1963
+
1964
+ Snapshot = Struct.new(:value, :tag)
1965
+ private_constant :Snapshot
1966
+
1967
+ def initialize(mval)
1968
+ @ordered_snapshots = create_ordered_snapshots(mval)
1969
+ end
1970
+
1971
+ def first
1972
+ @ordered_snapshots.first
1973
+ end
1974
+
1975
+ def last
1976
+ @ordered_snapshots.last
1977
+ end
1978
+
1979
+ def each(&block)
1980
+ if block_given?
1981
+ @ordered_snapshots.each(&block)
1982
+ else
1983
+ to_enum(:each)
1984
+ end
1985
+ end
1986
+
1987
+ private
1988
+ def create_ordered_snapshots(mval)
1989
+ if mval.ancestor
1990
+ older = create_ordered_snapshots(mval.ancestor)
1991
+ else
1992
+ older = []
1993
+ end
1994
+ older.push(Snapshot.new(mval._base.value, mval._base.tag))
1995
+ end
1996
+ end
1997
+
1752
1998
  class MultipleValue < Value
1753
- def initialize(val, ancestor)
1754
- @base_value = val.to_single_value
1999
+ Base = Struct.new(:value, :tag)
2000
+ private_constant :Base
2001
+
2002
+ def initialize(val, ancestor, tag)
2003
+ @base = Base.new(val.to_single_value, tag)
1755
2004
  @ancestor = ancestor
1756
2005
  @descendants = []
1757
2006
  end
1758
2007
 
1759
- attr_reader :base_value
2008
+ attr_reader :ancestor
2009
+
2010
+ def scalar?
2011
+ _base.value.scalar?
2012
+ end
1760
2013
 
1761
- extend Forwardable
2014
+ def array?
2015
+ _base.value.array?
2016
+ end
1762
2017
 
1763
- def_delegator :@base_value, :scalar?
1764
- def_delegator :@base_value, :array?
1765
- def_delegator :@base_value, :composite?
2018
+ def composite?
2019
+ _base.value.composite?
2020
+ end
1766
2021
 
1767
2022
  def undefined?
1768
- effective_values.all? { |multi_val| multi_val.base_value.undefined? }
2023
+ effective_values.all? { |mval| mval._base.value.undefined? }
1769
2024
  end
1770
2025
 
1771
2026
  def ambiguous?
1772
- effective_values.all? { |multi_val| multi_val.base_value.ambiguous? }
2027
+ effective_values.all? { |mval| mval._base.value.ambiguous? }
1773
2028
  end
1774
2029
 
1775
2030
  def exist?
1776
- effective_values.any? { |multi_val| multi_val.base_value.exist? }
2031
+ effective_values.any? { |mval| mval._base.value.exist? }
1777
2032
  end
1778
2033
 
1779
2034
  def definite?
1780
- effective_values.all? { |multi_val| multi_val.base_value.definite? }
2035
+ effective_values.all? { |mval| mval._base.value.definite? }
1781
2036
  end
1782
2037
 
1783
2038
  def contain?(val)
1784
- single_val = val.to_single_value
1785
- effective_values.all? do |multi_val|
1786
- multi_val.base_value.contain?(single_val)
1787
- end
2039
+ sval = val.to_single_value
2040
+ effective_values.any? { |mval| mval._base.value.contain?(sval) }
1788
2041
  end
1789
2042
 
1790
2043
  def multiple?
1791
2044
  true
1792
2045
  end
1793
2046
 
1794
- def overwrite!(val)
1795
- single_val = val.to_single_value
1796
- effective_values.each do |multi_val|
1797
- multi_val.base_value.overwrite!(single_val)
2047
+ def overwrite!(val, tag)
2048
+ sval = val.to_single_value
2049
+ effective_values.each do |mval|
2050
+ mval._base.value.overwrite!(sval, nil)
2051
+ mval._base.tag.merge!(tag)
1798
2052
  end
1799
2053
  end
1800
2054
 
1801
2055
  def narrow_domain!(op, ope_val)
1802
- ope_single_val = ope_val.to_single_value
1803
- effective_values.map { |multi_val|
1804
- if anc = multi_val.ancestor
1805
- anc.base_value.narrow_domain!(op.for_complement, ope_single_val)
2056
+ ope_sval = ope_val.to_single_value
2057
+ effective_values.each do |mval|
2058
+ if anc = mval.ancestor
2059
+ anc._base.value.narrow_domain!(op.for_complement, ope_sval)
1806
2060
  end
1807
- multi_val.base_value.narrow_domain!(op, ope_single_val)
1808
- }.any?
2061
+ mval._base.value.narrow_domain!(op, ope_sval)
2062
+ end
1809
2063
  end
1810
2064
 
1811
2065
  def widen_domain!(op, ope_val)
1812
- ope_single_val = ope_val.to_single_value
1813
- effective_values.map { |multi_val|
1814
- if anc = multi_val.ancestor
1815
- anc.base_value.narrow_domain!(op.for_complement, ope_single_val)
1816
- end
1817
- multi_val.base_value.widen_domain!(op, ope_single_val)
1818
- }.any?
2066
+ ope_sval = ope_val.to_single_value
2067
+ effective_values.each do |mval|
2068
+ # NOTE: Value domain widening is used to widen the controlling
2069
+ # variables's value only when the interpreter simulates an
2070
+ # iteration statement.
2071
+ # So, domain complementing is unnecessary for this purpose.
2072
+ #
2073
+ # if anc = mval.ancestor
2074
+ # anc._base.value.narrow_domain!(op.for_complement, ope_sval)
2075
+ # end
2076
+
2077
+ mval._base.value.widen_domain!(op, ope_sval)
2078
+
2079
+ # NOTE: No code is corresponding to the controlling variable's value
2080
+ # widenning.
2081
+ mval._base.tag.by = nil
2082
+ mval._base.tag.at = nil
2083
+ end
1819
2084
  end
1820
2085
 
1821
2086
  def invert_domain!
1822
- effective_values.each do |multi_val|
1823
- multi_val.base_value.invert_domain!
2087
+ effective_values.each do |mval|
2088
+ mval._base.value.invert_domain!
1824
2089
  end
1825
2090
  end
1826
2091
 
@@ -1829,13 +2094,15 @@ module Cc1 #:nodoc:
1829
2094
  end
1830
2095
 
1831
2096
  def fork
1832
- same_val = @descendants.find { |multi_val| multi_val.eql?(@base_value) }
2097
+ same_val = @descendants.find { |desc| desc.eql?(_base.value) }
1833
2098
  if same_val
2099
+ same_val._base.tag.by = _base.tag.by + same_val._base.tag.by
2100
+ same_val._base.tag.at = _base.tag.at + same_val._base.tag.at
1834
2101
  same_val
1835
2102
  else
1836
- new_descendant = MultipleValue.new(@base_value.dup, self)
1837
- @descendants.push(new_descendant)
1838
- new_descendant
2103
+ MultipleValue.new(_base.value.dup, self, _base.tag.dup).tap do |desc|
2104
+ @descendants.push(desc)
2105
+ end
1839
2106
  end
1840
2107
  end
1841
2108
 
@@ -1935,143 +2202,276 @@ module Cc1 #:nodoc:
1935
2202
  to_single_value.logical_or(rhs_val.to_single_value)
1936
2203
  end
1937
2204
 
1938
- def must_be_equal_to?(val)
1939
- single_val = val.to_single_value
1940
- non_nil_vals = effective_values.select { |multi_val|
1941
- multi_val.base_value.exist?
1942
- }
2205
+ def test_must_be_undefined
2206
+ evid = UndefinableTestEvidence.new(true)
2207
+ effective_values.each do |mval|
2208
+ if mval._base.value.test_must_be_undefined.true?
2209
+ evid.add_positive_contributor(mval)
2210
+ else
2211
+ evid.add_negative_contributor(mval)
2212
+ end
2213
+ break if evid.fulfilled?
2214
+ end
2215
+ NontrivialValueTest.new(evid, true)
2216
+ end
2217
+
2218
+ def test_may_be_undefined
2219
+ evid = UndefinableTestEvidence.new(false)
2220
+ effective_values.each do |mval|
2221
+ if mval._base.value.test_may_be_undefined.true?
2222
+ evid.add_positive_contributor(mval)
2223
+ else
2224
+ evid.add_negative_contributor(mval)
2225
+ end
2226
+ break if evid.fulfilled?
2227
+ end
2228
+ NontrivialValueTest.new(evid, false)
2229
+ end
1943
2230
 
2231
+ def test_must_be_equal_to(val)
2232
+ sval = val.to_single_value
2233
+ non_nil_vals = effective_values.select { |mval| mval._base.value.exist? }
1944
2234
  if non_nil_vals.empty?
1945
- false
2235
+ TrivialValueTest.new(false)
1946
2236
  else
1947
- non_nil_vals.all? do |multi_val|
1948
- multi_val.base_value.must_be_equal_to?(single_val)
2237
+ pred = lambda { |v| v.test_must_be_equal_to(sval).true? }
2238
+ evid = DefinableTestEvidence.new(pred, true)
2239
+ non_nil_vals.each do |mval|
2240
+ if pred.call(mval._base.value)
2241
+ evid.add_positive_contributor(mval)
2242
+ else
2243
+ evid.add_negative_contributor(mval)
2244
+ end
2245
+ break if evid.fulfilled?
1949
2246
  end
2247
+ NontrivialValueTest.new(evid, true)
1950
2248
  end
1951
2249
  end
1952
2250
 
1953
- def may_be_equal_to?(val)
1954
- single_val = val.to_single_value
1955
- effective_values.any? do |multi_val|
1956
- multi_val.base_value.may_be_equal_to?(single_val)
2251
+ def test_may_be_equal_to(val)
2252
+ sval = val.to_single_value
2253
+ pred = lambda { |v| v.test_may_be_equal_to(sval).true? }
2254
+ evid = DefinableTestEvidence.new(pred, false)
2255
+ effective_values.each do |mval|
2256
+ if pred.call(mval._base.value)
2257
+ evid.add_positive_contributor(mval)
2258
+ else
2259
+ evid.add_negative_contributor(mval)
2260
+ end
2261
+ break if evid.fulfilled?
1957
2262
  end
2263
+ NontrivialValueTest.new(evid, false)
1958
2264
  end
1959
2265
 
1960
- def must_not_be_equal_to?(val)
1961
- single_val = val.to_single_value
1962
- non_nil_vals = effective_values.select { |multi_val|
1963
- multi_val.base_value.exist?
1964
- }
2266
+ def test_must_not_be_equal_to(val)
2267
+ sval = val.to_single_value
2268
+ non_nil_vals = effective_values.select { |mval| mval._base.value.exist? }
1965
2269
  if non_nil_vals.empty?
1966
- false
2270
+ TrivialValueTest.new(false)
1967
2271
  else
1968
- non_nil_vals.all? do |multi_val|
1969
- multi_val.base_value.must_not_be_equal_to?(single_val)
2272
+ pred = lambda { |v| v.test_must_not_be_equal_to(sval).true? }
2273
+ evid = DefinableTestEvidence.new(pred, true)
2274
+ non_nil_vals.each do |mval|
2275
+ if pred.call(mval._base.value)
2276
+ evid.add_positive_contributor(mval)
2277
+ else
2278
+ evid.add_negative_contributor(mval)
2279
+ end
2280
+ break if evid.fulfilled?
1970
2281
  end
2282
+ NontrivialValueTest.new(evid, true)
1971
2283
  end
1972
2284
  end
1973
2285
 
1974
- def may_not_be_equal_to?(val)
1975
- single_val = val.to_single_value
1976
- effective_values.any? do |multi_val|
1977
- multi_val.base_value.may_not_be_equal_to?(single_val)
2286
+ def test_may_not_be_equal_to(val)
2287
+ sval = val.to_single_value
2288
+ pred = lambda { |v| v.test_may_not_be_equal_to(sval).true? }
2289
+ evid = DefinableTestEvidence.new(pred, false)
2290
+ effective_values.each do |mval|
2291
+ if pred.call(mval._base.value)
2292
+ evid.add_positive_contributor(mval)
2293
+ else
2294
+ evid.add_negative_contributor(mval)
2295
+ end
2296
+ break if evid.fulfilled?
1978
2297
  end
2298
+ NontrivialValueTest.new(evid, false)
1979
2299
  end
1980
2300
 
1981
- def must_be_less_than?(val)
1982
- single_val = val.to_single_value
1983
- non_nil_vals = effective_values.select { |multi_val|
1984
- multi_val.base_value.exist?
1985
- }
2301
+ def test_must_be_less_than(val)
2302
+ sval = val.to_single_value
2303
+ non_nil_vals = effective_values.select { |mval| mval._base.value.exist? }
1986
2304
  if non_nil_vals.empty?
1987
- false
2305
+ TrivialValueTest.new(false)
1988
2306
  else
1989
- non_nil_vals.all? do |multi_val|
1990
- multi_val.base_value.must_be_less_than?(single_val)
2307
+ pred = lambda { |v| v.test_must_be_less_than(sval).true? }
2308
+ evid = DefinableTestEvidence.new(pred, true)
2309
+ non_nil_vals.each do |mval|
2310
+ if pred.call(mval._base.value)
2311
+ evid.add_positive_contributor(mval)
2312
+ else
2313
+ evid.add_negative_contributor(mval)
2314
+ end
2315
+ break if evid.fulfilled?
1991
2316
  end
2317
+ NontrivialValueTest.new(evid, true)
1992
2318
  end
1993
2319
  end
1994
2320
 
1995
- def may_be_less_than?(val)
1996
- single_val = val.to_single_value
1997
- effective_values.any? do |multi_val|
1998
- multi_val.base_value.may_be_less_than?(single_val)
2321
+ def test_may_be_less_than(val)
2322
+ sval = val.to_single_value
2323
+ pred = lambda { |v| v.test_may_be_less_than(sval).true? }
2324
+ evid = DefinableTestEvidence.new(pred, false)
2325
+ effective_values.each do |mval|
2326
+ if pred.call(mval._base.value)
2327
+ evid.add_positive_contributor(mval)
2328
+ else
2329
+ evid.add_negative_contributor(mval)
2330
+ end
2331
+ break if evid.fulfilled?
1999
2332
  end
2333
+ NontrivialValueTest.new(evid, false)
2000
2334
  end
2001
2335
 
2002
- def must_be_greater_than?(val)
2003
- single_val = val.to_single_value
2004
- non_nil_vals = effective_values.select { |multi_val|
2005
- multi_val.base_value.exist?
2006
- }
2336
+ def test_must_be_greater_than(val)
2337
+ sval = val.to_single_value
2338
+ non_nil_vals = effective_values.select { |mval| mval._base.value.exist? }
2007
2339
  if non_nil_vals.empty?
2008
- false
2340
+ TrivialValueTest.new(false)
2009
2341
  else
2010
- non_nil_vals.all? do |multi_val|
2011
- multi_val.base_value.must_be_greater_than?(single_val)
2342
+ pred = lambda { |v| v.test_must_be_greater_than(sval).true? }
2343
+ evid = DefinableTestEvidence.new(pred, true)
2344
+ non_nil_vals.each do |mval|
2345
+ if pred.call(mval._base.value)
2346
+ evid.add_positive_contributor(mval)
2347
+ else
2348
+ evid.add_negative_contributor(mval)
2349
+ end
2350
+ break if evid.fulfilled?
2012
2351
  end
2352
+ NontrivialValueTest.new(evid, true)
2013
2353
  end
2014
2354
  end
2015
2355
 
2016
- def may_be_greater_than?(val)
2017
- single_val = val.to_single_value
2018
- effective_values.any? do |multi_val|
2019
- multi_val.base_value.may_be_greater_than?(single_val)
2356
+ def test_may_be_greater_than(val)
2357
+ sval = val.to_single_value
2358
+ pred = lambda { |v| v.test_may_be_greater_than(sval).true? }
2359
+ evid = DefinableTestEvidence.new(pred, false)
2360
+ effective_values.any? do |mval|
2361
+ if pred.call(mval._base.value)
2362
+ evid.add_positive_contributor(mval)
2363
+ else
2364
+ evid.add_negative_contributor(mval)
2365
+ end
2366
+ break if evid.fulfilled?
2020
2367
  end
2368
+ NontrivialValueTest.new(evid, false)
2021
2369
  end
2022
2370
 
2023
- def must_be_undefined?
2024
- effective_values.all? do |multi_val|
2025
- multi_val.base_value.must_be_undefined?
2371
+ def test_must_be_null
2372
+ non_nil_vals = effective_values.select { |mval| mval._base.value.exist? }
2373
+ if non_nil_vals.empty?
2374
+ TrivialValueTest.new(false)
2375
+ else
2376
+ evid = NullabilityTestEvidence.new(true)
2377
+ non_nil_vals.each do |mval|
2378
+ if mval._base.value.test_must_be_null.true?
2379
+ evid.add_positive_contributor(mval)
2380
+ else
2381
+ evid.add_negative_contributor(mval)
2382
+ end
2383
+ break if evid.fulfilled?
2384
+ end
2385
+ NontrivialValueTest.new(evid, true)
2026
2386
  end
2027
2387
  end
2028
2388
 
2029
- def may_be_undefined?
2030
- effective_values.any? do |multi_val|
2031
- multi_val.base_value.may_be_undefined?
2389
+ def test_may_be_null
2390
+ evid = NullabilityTestEvidence.new(false)
2391
+ effective_values.each do |mval|
2392
+ if mval._base.value.test_may_be_null.true?
2393
+ evid.add_positive_contributor(mval)
2394
+ else
2395
+ evid.add_negative_contributor(mval)
2396
+ end
2397
+ break if evid.fulfilled?
2032
2398
  end
2399
+ NontrivialValueTest.new(evid, false)
2033
2400
  end
2034
2401
 
2035
- def must_be_true?
2036
- non_nil_vals = effective_values.select { |multi_val|
2037
- multi_val.base_value.exist?
2038
- }
2402
+ def test_must_be_true
2403
+ non_nil_vals = effective_values.select { |mval| mval._base.value.exist? }
2039
2404
  if non_nil_vals.empty?
2040
- false
2405
+ TrivialValueTest.new(false)
2041
2406
  else
2042
- non_nil_vals.all? do |multi_val|
2043
- multi_val.base_value.must_be_true?
2407
+ pred = lambda { |val| val.test_must_be_true.true? }
2408
+ evid = DefinableTestEvidence.new(pred, true)
2409
+ non_nil_vals.each do |mval|
2410
+ if pred.call(mval._base.value)
2411
+ evid.add_positive_contributor(mval)
2412
+ else
2413
+ evid.add_negative_contributor(mval)
2414
+ end
2415
+ break if evid.fulfilled?
2044
2416
  end
2417
+ NontrivialValueTest.new(evid, true)
2045
2418
  end
2046
2419
  end
2047
2420
 
2048
- def may_be_true?
2049
- effective_values.any? do |multi_val|
2050
- multi_val.base_value.may_be_true?
2421
+ def test_may_be_true
2422
+ pred = lambda { |val| val.test_may_be_true.true? }
2423
+ evid = DefinableTestEvidence.new(pred, false)
2424
+ effective_values.each do |mval|
2425
+ if pred.call(mval._base.value)
2426
+ evid.add_positive_contributor(mval)
2427
+ else
2428
+ evid.add_negative_contributor(mval)
2429
+ end
2430
+ break if evid.fulfilled?
2051
2431
  end
2432
+ NontrivialValueTest.new(evid, false)
2052
2433
  end
2053
2434
 
2054
- def must_be_false?
2055
- non_nil_vals = effective_values.select { |multi_val|
2056
- multi_val.base_value.exist?
2057
- }
2435
+ def test_must_be_false
2436
+ non_nil_vals = effective_values.select { |mval| mval._base.value.exist? }
2058
2437
  if non_nil_vals.empty?
2059
- false
2438
+ TrivialValueTest.new(false)
2060
2439
  else
2061
- non_nil_vals.all? do |multi_val|
2062
- multi_val.base_value.must_be_false?
2440
+ pred = lambda { |val| val.test_must_be_false.true? }
2441
+ evid = DefinableTestEvidence.new(pred, true)
2442
+ non_nil_vals.each do |mval|
2443
+ if pred.call(mval._base.value)
2444
+ evid.add_positive_contributor(mval)
2445
+ else
2446
+ evid.add_negative_contributor(mval)
2447
+ end
2448
+ break if evid.fulfilled?
2063
2449
  end
2450
+ NontrivialValueTest.new(evid, true)
2064
2451
  end
2065
2452
  end
2066
2453
 
2067
- def may_be_false?
2068
- effective_values.any? do |multi_val|
2069
- multi_val.base_value.may_be_false?
2454
+ def test_may_be_false
2455
+ pred = lambda { |val| val.test_may_be_false.true? }
2456
+ evid = DefinableTestEvidence.new(pred, false)
2457
+ effective_values.each do |mval|
2458
+ if pred.call(mval._base.value)
2459
+ evid.add_positive_contributor(mval)
2460
+ else
2461
+ evid.add_negative_contributor(mval)
2462
+ end
2463
+ break if evid.fulfilled?
2070
2464
  end
2465
+ NontrivialValueTest.new(evid, false)
2466
+ end
2467
+
2468
+ def transition
2469
+ ValueTransition.new(self)
2071
2470
  end
2072
2471
 
2073
2472
  def coerce_to(type)
2074
- MultipleValue.new(to_single_value.coerce_to(type), nil)
2473
+ sval = to_single_value.coerce_to(type)
2474
+ MultipleValue.new(sval, nil, _base.tag.dup)
2075
2475
  end
2076
2476
 
2077
2477
  def to_enum
@@ -2079,12 +2479,11 @@ module Cc1 #:nodoc:
2079
2479
  end
2080
2480
 
2081
2481
  def to_single_value
2082
- # NOTE: The base_value of the MultipleValue object must be a SingleValue.
2083
- effective_values.map { |multi_val|
2084
- multi_val.base_value
2085
- }.reduce do |unified_val, single_val|
2086
- unified_val.single_value_unified_with(single_val)
2087
- end
2482
+ # NOTE: The _base.value of the MultipleValue object must be a
2483
+ # SingleValue.
2484
+ effective_values.map { |mval| mval._base.value }.reduce { |unified, sval|
2485
+ unified.single_value_unified_with(sval)
2486
+ }
2088
2487
  end
2089
2488
 
2090
2489
  def to_defined_value
@@ -2100,7 +2499,7 @@ module Cc1 #:nodoc:
2100
2499
  end
2101
2500
 
2102
2501
  def dup
2103
- MultipleValue.new(to_single_value.dup, nil)
2502
+ MultipleValue.new(to_single_value.dup, nil, _base.tag.dup)
2104
2503
  end
2105
2504
 
2106
2505
  def effective_values
@@ -2111,19 +2510,21 @@ module Cc1 #:nodoc:
2111
2510
  if @descendants.empty?
2112
2511
  [self]
2113
2512
  else
2114
- @descendants.map { |multi_val| multi_val.descendants }.flatten.uniq
2513
+ @descendants.map { |mval| mval.descendants }.flatten
2115
2514
  end
2116
2515
  end
2117
2516
 
2118
- protected
2119
- attr_reader :ancestor
2517
+ def _base
2518
+ # NOTE: This method will be invoked only from this file.
2519
+ @base
2520
+ end
2120
2521
  end
2121
2522
 
2122
2523
  class VersionedValue < MultipleValue
2123
- def initialize(orig_val)
2524
+ def initialize(orig_val, tag)
2124
2525
  # NOTE: `orig_val.to_single_value' will be done in
2125
2526
  # MultipleValue#initialize.
2126
- super(orig_val, nil)
2527
+ super(orig_val, nil, tag)
2127
2528
 
2128
2529
  @version_controller = ValueVersionController.new(self)
2129
2530
  end
@@ -2157,14 +2558,14 @@ module Cc1 #:nodoc:
2157
2558
  delete_descendants!
2158
2559
  orig_val = @version_controller.original_value
2159
2560
  @version_controller = nil
2160
- _orig_overwrite!(orig_val)
2561
+ _orig_overwrite!(orig_val, TransitionTag.new)
2161
2562
  @version_controller = ValueVersionController.new(self)
2162
2563
  invalidate_memo!
2163
2564
  end
2164
2565
 
2165
2566
  alias :_orig_overwrite! :overwrite!
2166
2567
 
2167
- def overwrite!(val)
2568
+ def overwrite!(val, tag)
2168
2569
  @version_controller.fork_current_version
2169
2570
  super
2170
2571
  @version_controller.mark_current_versioning_group_as_sticky
@@ -2173,9 +2574,9 @@ module Cc1 #:nodoc:
2173
2574
 
2174
2575
  def force_overwrite!(val)
2175
2576
  # NOTE: This method will be invoked only from VariableTable#define.
2176
- single_val = val.to_single_value
2177
- @version_controller.original_value.overwrite!(single_val)
2178
- _orig_overwrite!(single_val)
2577
+ sval = val.to_single_value
2578
+ @version_controller.original_value.overwrite!(sval, nil)
2579
+ _orig_overwrite!(sval, nil)
2179
2580
  invalidate_memo!
2180
2581
  end
2181
2582
 
@@ -2188,6 +2589,7 @@ module Cc1 #:nodoc:
2188
2589
  def widen_domain!(op, ope_val)
2189
2590
  @version_controller.fork_current_version
2190
2591
  super
2592
+ @version_controller.mark_current_versioning_group_as_sticky
2191
2593
  invalidate_memo!
2192
2594
  end
2193
2595
 
@@ -2198,7 +2600,7 @@ module Cc1 #:nodoc:
2198
2600
  end
2199
2601
 
2200
2602
  def coerce_to(type)
2201
- VersionedValue.new(to_single_value.coerce_to(type))
2603
+ VersionedValue.new(to_single_value.coerce_to(type), _base.tag.dup)
2202
2604
  end
2203
2605
 
2204
2606
  def effective_values
@@ -2213,8 +2615,8 @@ module Cc1 #:nodoc:
2213
2615
 
2214
2616
  private
2215
2617
  def compact_descendants!
2216
- @descendants = @version_controller.current_values.reject { |multi_val|
2217
- multi_val.equal?(self)
2618
+ @descendants = @version_controller.current_values.reject { |mval|
2619
+ mval.equal?(self)
2218
2620
  }.uniq
2219
2621
  end
2220
2622
  end
@@ -2262,17 +2664,15 @@ module Cc1 #:nodoc:
2262
2664
  initial_vals = current_version.initial_values
2263
2665
  current_versioning_group.delete_current_version_completely
2264
2666
  base_vals = current_versioning_group.base_values
2265
- base_vals.zip(initial_vals).each do |multi_val, initial_val|
2266
- multi_val.rollback! if forked
2267
- multi_val.overwrite!(initial_val) if initial_val
2667
+ base_vals.zip(initial_vals).each do |mval, init_val|
2668
+ mval.rollback! if forked
2669
+ mval.overwrite!(init_val, TransitionTag.new) if init_val
2268
2670
  end
2269
2671
  begin_forking
2270
2672
  else
2271
2673
  current_versioning_group.delete_current_version
2272
2674
  if forked
2273
- current_versioning_group.base_values.each do |multi_val|
2274
- multi_val.rollback!
2275
- end
2675
+ current_versioning_group.base_values.each { |mval| mval.rollback! }
2276
2676
  end
2277
2677
  end
2278
2678
 
@@ -2290,16 +2690,10 @@ module Cc1 #:nodoc:
2290
2690
  end
2291
2691
 
2292
2692
  def copy_current_version
2293
- return unless current_versioning_group.sticky?
2294
-
2295
2693
  # NOTE: This method must be called between ending of the forking section
2296
2694
  # and ending of the versioning group.
2297
- current_values.each do |multi_val|
2298
- base_val = multi_val.base_value
2299
- already_exist = multi_val.descendants.any? { |desc_multi_val|
2300
- !desc_multi_val.equal?(multi_val) && desc_multi_val.eql?(base_val)
2301
- }
2302
- multi_val.fork unless already_exist
2695
+ if current_versioning_group.sticky?
2696
+ current_values.each { |mval| mval.fork }
2303
2697
  end
2304
2698
  end
2305
2699
 
@@ -2311,22 +2705,28 @@ module Cc1 #:nodoc:
2311
2705
  case
2312
2706
  when current_versioning_group.sticky?
2313
2707
  fork_all_versions
2314
- base_ver.values = base_ver.values.map { |base_multi_val|
2315
- base_multi_val.descendants
2316
- }.flatten.uniq
2708
+ base_vals = base_ver.values.map { |mval| mval.descendants }.flatten
2709
+ base_ver.values = base_vals.each_with_object({}) { |mval, hash|
2710
+ if eql_mval = hash[mval]
2711
+ eql_mval._base.tag.by = mval._base.tag.by + eql_mval._base.tag.by
2712
+ eql_mval._base.tag.at = mval._base.tag.at + eql_mval._base.tag.at
2713
+ else
2714
+ hash[mval] = mval
2715
+ end
2716
+ }.keys
2317
2717
  when current_versioning_group.versions_forked?
2318
2718
  # NOTE: When versions in the current versioning group have been forked,
2319
2719
  # base_version of the current versioning group has already been
2320
2720
  # forked. So, it is safe to overwrite the base_version's values
2321
2721
  # with the current versioning group's initial snapshot values.
2322
- initial_vals = current_versioning_group.initial_values
2323
- vals = base_ver.values.zip(initial_vals)
2324
- vals.each do |base_multi_val, initial_single_val|
2325
- base_multi_val.delete_descendants!
2326
- if base_multi_val.kind_of?(VersionedValue)
2327
- base_multi_val._orig_overwrite!(initial_single_val)
2722
+ init_vals = current_versioning_group.initial_values
2723
+ vals = base_ver.values.zip(init_vals)
2724
+ vals.each do |base_mval, init_sval|
2725
+ base_mval.delete_descendants!
2726
+ if base_mval.kind_of?(VersionedValue)
2727
+ base_mval._orig_overwrite!(init_sval, TransitionTag.new)
2328
2728
  else
2329
- base_multi_val.overwrite!(initial_single_val)
2729
+ base_mval.overwrite!(init_sval, TransitionTag.new)
2330
2730
  end
2331
2731
  end
2332
2732
  else
@@ -2365,11 +2765,8 @@ module Cc1 #:nodoc:
2365
2765
  def initialize(base_ver, sticky = false)
2366
2766
  @base_version = base_ver
2367
2767
  @sticky = sticky
2368
-
2369
- @initial_values = base_ver.values.map { |multi_val|
2370
- multi_val.base_value.dup
2371
- }
2372
- @version_stack = []
2768
+ @initial_values = base_ver.values.map { |mval| mval._base.value.dup }
2769
+ @current_version = nil
2373
2770
  @all_versions = []
2374
2771
  end
2375
2772
 
@@ -2390,7 +2787,7 @@ module Cc1 #:nodoc:
2390
2787
  end
2391
2788
 
2392
2789
  def current_version
2393
- @version_stack.empty? ? @base_version : @version_stack.last
2790
+ @current_version || @base_version
2394
2791
  end
2395
2792
 
2396
2793
  def current_values
@@ -2398,13 +2795,12 @@ module Cc1 #:nodoc:
2398
2795
  end
2399
2796
 
2400
2797
  def begin_new_version
2401
- new_ver = Version.new(base_values)
2402
- @version_stack.push(new_ver)
2403
- @all_versions.push(new_ver)
2798
+ @current_version = Version.new(base_values)
2799
+ @all_versions.push(@current_version)
2404
2800
  end
2405
2801
 
2406
2802
  def end_current_version
2407
- @version_stack.pop
2803
+ @current_version = nil
2408
2804
  end
2409
2805
 
2410
2806
  def delete_current_version_completely
@@ -2453,7 +2849,7 @@ module Cc1 #:nodoc:
2453
2849
 
2454
2850
  def fork_from(base_ver)
2455
2851
  if forking?
2456
- @values = base_ver.values.map { |multi_val| multi_val.fork }
2852
+ @values = base_ver.values.map { |mval| mval.fork }
2457
2853
  @initial_values = @values.each_with_object([]) { |val, ary|
2458
2854
  ary.push(val.to_single_value.dup)
2459
2855
  }