adlint 3.0.10 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
  }