Class: AdLint::Cc1::MultipleValue

Inherits:
Value
  • Object
show all
Defined in:
lib/adlint/cc1/value.rb

Direct Known Subclasses

VersionedValue

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from BuggyValueSampler

#unique_sample

Constructor Details

#initialize(val, ancestor, tag) ⇒ MultipleValue

Returns a new instance of MultipleValue.



2008
2009
2010
2011
2012
# File 'lib/adlint/cc1/value.rb', line 2008

def initialize(val, ancestor, tag)
  @base = Base.new(val.to_single_value, tag)
  @ancestor = ancestor
  @descendants = []
end

Instance Attribute Details

#ancestorObject (readonly)

Returns the value of attribute ancestor.



2014
2015
2016
# File 'lib/adlint/cc1/value.rb', line 2014

def ancestor
  @ancestor
end

Instance Method Details

#!Object



2175
2176
2177
# File 'lib/adlint/cc1/value.rb', line 2175

def !
  !to_single_value
end

#!=(rhs_val) ⇒ Object



2191
2192
2193
# File 'lib/adlint/cc1/value.rb', line 2191

def !=(rhs_val)
  to_single_value != rhs_val.to_single_value
end

#%(rhs_val) ⇒ Object



2151
2152
2153
# File 'lib/adlint/cc1/value.rb', line 2151

def %(rhs_val)
  to_single_value % rhs_val.to_single_value
end

#&(rhs_val) ⇒ Object



2155
2156
2157
# File 'lib/adlint/cc1/value.rb', line 2155

def &(rhs_val)
  to_single_value & rhs_val.to_single_value
end

#*(rhs_val) ⇒ Object



2143
2144
2145
# File 'lib/adlint/cc1/value.rb', line 2143

def *(rhs_val)
  to_single_value * rhs_val.to_single_value
end

#+(rhs_val) ⇒ Object



2135
2136
2137
# File 'lib/adlint/cc1/value.rb', line 2135

def +(rhs_val)
  to_single_value + rhs_val.to_single_value
end

#+@Object



2127
2128
2129
# File 'lib/adlint/cc1/value.rb', line 2127

def +@
  +to_single_value
end

#-(rhs_val) ⇒ Object



2139
2140
2141
# File 'lib/adlint/cc1/value.rb', line 2139

def -(rhs_val)
  to_single_value - rhs_val.to_single_value
end

#-@Object



2131
2132
2133
# File 'lib/adlint/cc1/value.rb', line 2131

def -@
  -to_single_value
end

#/(rhs_val) ⇒ Object



2147
2148
2149
# File 'lib/adlint/cc1/value.rb', line 2147

def /(rhs_val)
  to_single_value / rhs_val.to_single_value
end

#<(rhs_val) ⇒ Object



2179
2180
2181
# File 'lib/adlint/cc1/value.rb', line 2179

def <(rhs_val)
  to_single_value < rhs_val.to_single_value
end

#<<(rhs_val) ⇒ Object



2167
2168
2169
# File 'lib/adlint/cc1/value.rb', line 2167

def <<(rhs_val)
  to_single_value << rhs_val.to_single_value
end

#<=(rhs_val) ⇒ Object



2195
2196
2197
# File 'lib/adlint/cc1/value.rb', line 2195

def <=(rhs_val)
  to_single_value <= rhs_val.to_single_value
end

#==(rhs_val) ⇒ Object



2187
2188
2189
# File 'lib/adlint/cc1/value.rb', line 2187

def ==(rhs_val)
  to_single_value == rhs_val.to_single_value
end

#>(rhs_val) ⇒ Object



2183
2184
2185
# File 'lib/adlint/cc1/value.rb', line 2183

def >(rhs_val)
  to_single_value > rhs_val.to_single_value
end

#>=(rhs_val) ⇒ Object



2199
2200
2201
# File 'lib/adlint/cc1/value.rb', line 2199

def >=(rhs_val)
  to_single_value >= rhs_val.to_single_value
end

#>>(rhs_val) ⇒ Object



2171
2172
2173
# File 'lib/adlint/cc1/value.rb', line 2171

def >>(rhs_val)
  to_single_value >> rhs_val.to_single_value
end

#^(rhs_val) ⇒ Object



2163
2164
2165
# File 'lib/adlint/cc1/value.rb', line 2163

def ^(rhs_val)
  to_single_value ^ rhs_val.to_single_value
end

#_baseObject



2523
2524
2525
2526
# File 'lib/adlint/cc1/value.rb', line 2523

def _base
  # NOTE: This method will be invoked only from this file.
  @base
end

#ambiguous?Boolean

Returns:

  • (Boolean)


2032
2033
2034
# File 'lib/adlint/cc1/value.rb', line 2032

def ambiguous?
  effective_values.all? { |mval| mval._base.value.ambiguous? }
end

#array?Boolean

Returns:

  • (Boolean)


2020
2021
2022
# File 'lib/adlint/cc1/value.rb', line 2020

def array?
  _base.value.array?
end

#coerce_to(type) ⇒ Object



2478
2479
2480
2481
# File 'lib/adlint/cc1/value.rb', line 2478

def coerce_to(type)
  sval = to_single_value.coerce_to(type)
  MultipleValue.new(sval, nil, _base.tag.dup)
end

#composite?Boolean

Returns:

  • (Boolean)


2024
2025
2026
# File 'lib/adlint/cc1/value.rb', line 2024

def composite?
  _base.value.composite?
end

#contain?(val) ⇒ Boolean

Returns:

  • (Boolean)


2044
2045
2046
2047
# File 'lib/adlint/cc1/value.rb', line 2044

def contain?(val)
  sval = val.to_single_value
  effective_values.any? { |mval| mval._base.value.contain?(sval) }
end

#definite?Boolean

Returns:

  • (Boolean)


2040
2041
2042
# File 'lib/adlint/cc1/value.rb', line 2040

def definite?
  effective_values.all? { |mval| mval._base.value.definite? }
end

#delete_descendants!Object



2119
2120
2121
# File 'lib/adlint/cc1/value.rb', line 2119

def delete_descendants!
  @descendants.clear
end

#descendantsObject



2515
2516
2517
2518
2519
2520
2521
# File 'lib/adlint/cc1/value.rb', line 2515

def descendants
  if @descendants.empty?
    [self]
  else
    @descendants.map { |mval| mval.descendants }.flatten
  end
end

#dupObject



2507
2508
2509
# File 'lib/adlint/cc1/value.rb', line 2507

def dup
  MultipleValue.new(to_single_value.dup, nil, _base.tag.dup)
end

#effective_valuesObject



2511
2512
2513
# File 'lib/adlint/cc1/value.rb', line 2511

def effective_values
  @descendants.empty? ? [self] : @descendants
end

#eql?(rhs_val) ⇒ Boolean

Returns:

  • (Boolean)


2499
2500
2501
# File 'lib/adlint/cc1/value.rb', line 2499

def eql?(rhs_val)
  to_single_value.eql?(rhs_val.to_single_value)
end

#exist?Boolean

Returns:

  • (Boolean)


2036
2037
2038
# File 'lib/adlint/cc1/value.rb', line 2036

def exist?
  effective_values.any? { |mval| mval._base.value.exist? }
end

#forkObject



2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
# File 'lib/adlint/cc1/value.rb', line 2102

def fork
  same_val = @descendants.find { |desc| desc.eql?(_base.value) }
  if same_val
    same_val._base.tag.by = _base.tag.by + same_val._base.tag.by
    same_val._base.tag.at = _base.tag.at + same_val._base.tag.at
    same_val
  else
    MultipleValue.new(_base.value.dup, self, _base.tag.dup).tap do |desc|
      @descendants.push(desc)
    end
  end
end

#hashObject



2503
2504
2505
# File 'lib/adlint/cc1/value.rb', line 2503

def hash
  to_single_value.hash
end

#invert_domain!Object



2092
2093
2094
2095
2096
# File 'lib/adlint/cc1/value.rb', line 2092

def invert_domain!
  effective_values.each do |mval|
    mval._base.value.invert_domain!
  end
end

#logical_and(rhs_val) ⇒ Object



2203
2204
2205
# File 'lib/adlint/cc1/value.rb', line 2203

def logical_and(rhs_val)
  to_single_value.logical_and(rhs_val.to_single_value)
end

#logical_or(rhs_val) ⇒ Object



2207
2208
2209
# File 'lib/adlint/cc1/value.rb', line 2207

def logical_or(rhs_val)
  to_single_value.logical_or(rhs_val.to_single_value)
end

#multiple?Boolean

Returns:

  • (Boolean)


2049
2050
2051
# File 'lib/adlint/cc1/value.rb', line 2049

def multiple?
  true
end

#narrow_domain!(op, ope_val) ⇒ Object



2061
2062
2063
2064
2065
2066
2067
2068
2069
# File 'lib/adlint/cc1/value.rb', line 2061

def narrow_domain!(op, ope_val)
  ope_sval = ope_val.to_single_value
  effective_values.each do |mval|
    if anc = mval.ancestor
      anc._base.value.narrow_domain!(op.for_complement, ope_sval)
    end
    mval._base.value.narrow_domain!(op, ope_sval)
  end
end

#overwrite!(val, tag) ⇒ Object



2053
2054
2055
2056
2057
2058
2059
# File 'lib/adlint/cc1/value.rb', line 2053

def overwrite!(val, tag)
  sval = val.to_single_value
  effective_values.each do |mval|
    mval._base.value.overwrite!(sval, nil)
    mval._base.tag.merge!(tag)
  end
end

#rollback!Object



2115
2116
2117
# File 'lib/adlint/cc1/value.rb', line 2115

def rollback!
  @descendants.pop
end

#scalar?Boolean

Returns:

  • (Boolean)


2016
2017
2018
# File 'lib/adlint/cc1/value.rb', line 2016

def scalar?
  _base.value.scalar?
end

#single_value_unified_with(rhs_val) ⇒ Object



2098
2099
2100
# File 'lib/adlint/cc1/value.rb', line 2098

def single_value_unified_with(rhs_val)
  to_single_value.single_value_unified_with(rhs_val)
end

#test_may_be_equal_to(val) ⇒ Object



2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
# File 'lib/adlint/cc1/value.rb', line 2257

def test_may_be_equal_to(val)
  sval = val.to_single_value
  pred = lambda { |v| v.test_may_be_equal_to(sval).true? }
  evid = DefinableTestEvidence.new(pred, false)
  effective_values.each do |mval|
    if pred.call(mval._base.value)
      evid.add_positive_contributor(mval)
    else
      evid.add_negative_contributor(mval)
    end
    break if evid.fulfilled?
  end
  NontrivialValueTest.new(evid, false)
end

#test_may_be_falseObject



2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
# File 'lib/adlint/cc1/value.rb', line 2460

def test_may_be_false
  pred = lambda { |val| val.test_may_be_false.true? }
  evid = DefinableTestEvidence.new(pred, false)
  effective_values.each do |mval|
    if pred.call(mval._base.value)
      evid.add_positive_contributor(mval)
    else
      evid.add_negative_contributor(mval)
    end
    break if evid.fulfilled?
  end
  NontrivialValueTest.new(evid, false)
end

#test_may_be_greater_than(val) ⇒ Object



2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
# File 'lib/adlint/cc1/value.rb', line 2362

def test_may_be_greater_than(val)
  sval = val.to_single_value
  pred = lambda { |v| v.test_may_be_greater_than(sval).true? }
  evid = DefinableTestEvidence.new(pred, false)
  effective_values.any? do |mval|
    if pred.call(mval._base.value)
      evid.add_positive_contributor(mval)
    else
      evid.add_negative_contributor(mval)
    end
    break if evid.fulfilled?
  end
  NontrivialValueTest.new(evid, false)
end

#test_may_be_less_than(val) ⇒ Object



2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
# File 'lib/adlint/cc1/value.rb', line 2327

def test_may_be_less_than(val)
  sval = val.to_single_value
  pred = lambda { |v| v.test_may_be_less_than(sval).true? }
  evid = DefinableTestEvidence.new(pred, false)
  effective_values.each do |mval|
    if pred.call(mval._base.value)
      evid.add_positive_contributor(mval)
    else
      evid.add_negative_contributor(mval)
    end
    break if evid.fulfilled?
  end
  NontrivialValueTest.new(evid, false)
end

#test_may_be_nullObject



2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
# File 'lib/adlint/cc1/value.rb', line 2395

def test_may_be_null
  evid = NullabilityTestEvidence.new(false)
  effective_values.each do |mval|
    if mval._base.value.test_may_be_null.true?
      evid.add_positive_contributor(mval)
    else
      evid.add_negative_contributor(mval)
    end
    break if evid.fulfilled?
  end
  NontrivialValueTest.new(evid, false)
end

#test_may_be_trueObject



2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
# File 'lib/adlint/cc1/value.rb', line 2427

def test_may_be_true
  pred = lambda { |val| val.test_may_be_true.true? }
  evid = DefinableTestEvidence.new(pred, false)
  effective_values.each do |mval|
    if pred.call(mval._base.value)
      evid.add_positive_contributor(mval)
    else
      evid.add_negative_contributor(mval)
    end
    break if evid.fulfilled?
  end
  NontrivialValueTest.new(evid, false)
end

#test_may_be_undefinedObject



2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
# File 'lib/adlint/cc1/value.rb', line 2224

def test_may_be_undefined
  evid = UndefinableTestEvidence.new(false)
  effective_values.each do |mval|
    if mval._base.value.test_may_be_undefined.true?
      evid.add_positive_contributor(mval)
    else
      evid.add_negative_contributor(mval)
    end
    break if evid.fulfilled?
  end
  NontrivialValueTest.new(evid, false)
end

#test_may_not_be_equal_to(val) ⇒ Object



2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
# File 'lib/adlint/cc1/value.rb', line 2292

def test_may_not_be_equal_to(val)
  sval = val.to_single_value
  pred = lambda { |v| v.test_may_not_be_equal_to(sval).true? }
  evid = DefinableTestEvidence.new(pred, false)
  effective_values.each do |mval|
    if pred.call(mval._base.value)
      evid.add_positive_contributor(mval)
    else
      evid.add_negative_contributor(mval)
    end
    break if evid.fulfilled?
  end
  NontrivialValueTest.new(evid, false)
end

#test_must_be_equal_to(val) ⇒ Object



2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
# File 'lib/adlint/cc1/value.rb', line 2237

def test_must_be_equal_to(val)
  sval = val.to_single_value
  non_nil_vals = effective_values.select { |mval| mval._base.value.exist? }
  if non_nil_vals.empty?
    TrivialValueTest.new(false)
  else
    pred = lambda { |v| v.test_must_be_equal_to(sval).true? }
    evid = DefinableTestEvidence.new(pred, true)
    non_nil_vals.each do |mval|
      if pred.call(mval._base.value)
        evid.add_positive_contributor(mval)
      else
        evid.add_negative_contributor(mval)
      end
      break if evid.fulfilled?
    end
    NontrivialValueTest.new(evid, true)
  end
end

#test_must_be_falseObject



2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
# File 'lib/adlint/cc1/value.rb', line 2441

def test_must_be_false
  non_nil_vals = effective_values.select { |mval| mval._base.value.exist? }
  if non_nil_vals.empty?
    TrivialValueTest.new(false)
  else
    pred = lambda { |val| val.test_must_be_false.true? }
    evid = DefinableTestEvidence.new(pred, true)
    non_nil_vals.each do |mval|
      if pred.call(mval._base.value)
        evid.add_positive_contributor(mval)
      else
        evid.add_negative_contributor(mval)
      end
      break if evid.fulfilled?
    end
    NontrivialValueTest.new(evid, true)
  end
end

#test_must_be_greater_than(val) ⇒ Object



2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
# File 'lib/adlint/cc1/value.rb', line 2342

def test_must_be_greater_than(val)
  sval = val.to_single_value
  non_nil_vals = effective_values.select { |mval| mval._base.value.exist? }
  if non_nil_vals.empty?
    TrivialValueTest.new(false)
  else
    pred = lambda { |v| v.test_must_be_greater_than(sval).true? }
    evid = DefinableTestEvidence.new(pred, true)
    non_nil_vals.each do |mval|
      if pred.call(mval._base.value)
        evid.add_positive_contributor(mval)
      else
        evid.add_negative_contributor(mval)
      end
      break if evid.fulfilled?
    end
    NontrivialValueTest.new(evid, true)
  end
end

#test_must_be_less_than(val) ⇒ Object



2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
# File 'lib/adlint/cc1/value.rb', line 2307

def test_must_be_less_than(val)
  sval = val.to_single_value
  non_nil_vals = effective_values.select { |mval| mval._base.value.exist? }
  if non_nil_vals.empty?
    TrivialValueTest.new(false)
  else
    pred = lambda { |v| v.test_must_be_less_than(sval).true? }
    evid = DefinableTestEvidence.new(pred, true)
    non_nil_vals.each do |mval|
      if pred.call(mval._base.value)
        evid.add_positive_contributor(mval)
      else
        evid.add_negative_contributor(mval)
      end
      break if evid.fulfilled?
    end
    NontrivialValueTest.new(evid, true)
  end
end

#test_must_be_nullObject



2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
# File 'lib/adlint/cc1/value.rb', line 2377

def test_must_be_null
  non_nil_vals = effective_values.select { |mval| mval._base.value.exist? }
  if non_nil_vals.empty?
    TrivialValueTest.new(false)
  else
    evid = NullabilityTestEvidence.new(true)
    non_nil_vals.each do |mval|
      if mval._base.value.test_must_be_null.true?
        evid.add_positive_contributor(mval)
      else
        evid.add_negative_contributor(mval)
      end
      break if evid.fulfilled?
    end
    NontrivialValueTest.new(evid, true)
  end
end

#test_must_be_trueObject



2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
# File 'lib/adlint/cc1/value.rb', line 2408

def test_must_be_true
  non_nil_vals = effective_values.select { |mval| mval._base.value.exist? }
  if non_nil_vals.empty?
    TrivialValueTest.new(false)
  else
    pred = lambda { |val| val.test_must_be_true.true? }
    evid = DefinableTestEvidence.new(pred, true)
    non_nil_vals.each do |mval|
      if pred.call(mval._base.value)
        evid.add_positive_contributor(mval)
      else
        evid.add_negative_contributor(mval)
      end
      break if evid.fulfilled?
    end
    NontrivialValueTest.new(evid, true)
  end
end

#test_must_be_undefinedObject



2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
# File 'lib/adlint/cc1/value.rb', line 2211

def test_must_be_undefined
  evid = UndefinableTestEvidence.new(true)
  effective_values.each do |mval|
    if mval._base.value.test_must_be_undefined.true?
      evid.add_positive_contributor(mval)
    else
      evid.add_negative_contributor(mval)
    end
    break if evid.fulfilled?
  end
  NontrivialValueTest.new(evid, true)
end

#test_must_not_be_equal_to(val) ⇒ Object



2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
# File 'lib/adlint/cc1/value.rb', line 2272

def test_must_not_be_equal_to(val)
  sval = val.to_single_value
  non_nil_vals = effective_values.select { |mval| mval._base.value.exist? }
  if non_nil_vals.empty?
    TrivialValueTest.new(false)
  else
    pred = lambda { |v| v.test_must_not_be_equal_to(sval).true? }
    evid = DefinableTestEvidence.new(pred, true)
    non_nil_vals.each do |mval|
      if pred.call(mval._base.value)
        evid.add_positive_contributor(mval)
      else
        evid.add_negative_contributor(mval)
      end
      break if evid.fulfilled?
    end
    NontrivialValueTest.new(evid, true)
  end
end

#to_defined_valueObject



2495
2496
2497
# File 'lib/adlint/cc1/value.rb', line 2495

def to_defined_value
  to_single_value.to_defined_value
end

#to_enumObject



2483
2484
2485
# File 'lib/adlint/cc1/value.rb', line 2483

def to_enum
  to_single_value.to_enum
end

#to_single_valueObject



2487
2488
2489
2490
2491
2492
2493
# File 'lib/adlint/cc1/value.rb', line 2487

def to_single_value
  # NOTE: The _base.value of the MultipleValue object must be a
  #       SingleValue.
  effective_values.map { |mval| mval._base.value }.reduce { |unified, sval|
    unified.single_value_unified_with(sval)
  }
end

#transitionObject



2474
2475
2476
# File 'lib/adlint/cc1/value.rb', line 2474

def transition
  ValueTransition.new(self)
end

#undefined?Boolean

Returns:

  • (Boolean)


2028
2029
2030
# File 'lib/adlint/cc1/value.rb', line 2028

def undefined?
  effective_values.all? { |mval| mval._base.value.undefined? }
end

#widen_domain!(op, ope_val) ⇒ Object



2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
# File 'lib/adlint/cc1/value.rb', line 2071

def widen_domain!(op, ope_val)
  ope_sval = ope_val.to_single_value
  effective_values.each do |mval|
    # NOTE: Value domain widening is used to widen the controlling
    #       variables's value only when the interpreter simulates an
    #       iteration statement.
    #       So, domain complementing is unnecessary for this purpose.
    #
    # if anc = mval.ancestor
    #   anc._base.value.narrow_domain!(op.for_complement, ope_sval)
    # end

    mval._base.value.widen_domain!(op, ope_sval)

    # NOTE: No code is corresponding to the controlling variable's value
    #       widenning.
    mval._base.tag.by = nil
    mval._base.tag.at = nil
  end
end

#|(rhs_val) ⇒ Object



2159
2160
2161
# File 'lib/adlint/cc1/value.rb', line 2159

def |(rhs_val)
  to_single_value | rhs_val.to_single_value
end

#~Object



2123
2124
2125
# File 'lib/adlint/cc1/value.rb', line 2123

def ~
  ~to_single_value
end