Class: RDL::Type::PreciseStringType

Inherits:
Type show all
Defined in:
lib/rdl/types/string.rb

Overview

A specialized precise type for Strings

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Type

leq, #nil_type?, #optional?, #to_contract, #vararg?

Constructor Details

#initialize(*vals) ⇒ PreciseStringType

For interpolated strings, it will include strings and RDL types, in order, where the types represent the types of the interpolated portions, and the strings represent the surrounding string parts.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/rdl/types/string.rb', line 10

def initialize(*vals)
  @interp = false
  vals.each { |v|
    case v
    when String
      ## do nothing
    when Type
      ## interpolated string
      @interp = true
    else
      raise RuntimeError, "Attempt to create precise string type with non-string or non-type value #{v}" unless vals.all? { |val| val.is_a?(Type) || val.is_a?(String) }
    end
  }
  vals = [vals.join] if !@interp && vals.size > 1 ## if all elements of `vals` are strings, join them into one
  
  @vals = vals
  @ubounds = []
  @lbounds = []
  @promoted = false
  @cant_promote = false
  super()
end

Instance Attribute Details

#interpObject

Returns the value of attribute interp.



5
6
7
# File 'lib/rdl/types/string.rb', line 5

def interp
  @interp
end

#lboundsObject

Returns the value of attribute lbounds.



5
6
7
# File 'lib/rdl/types/string.rb', line 5

def lbounds
  @lbounds
end

#uboundsObject

Returns the value of attribute ubounds.



5
6
7
# File 'lib/rdl/types/string.rb', line 5

def ubounds
  @ubounds
end

#valsObject

Returns the value of attribute vals.



4
5
6
# File 'lib/rdl/types/string.rb', line 4

def vals
  @vals
end

Instance Method Details

#<=(other, no_constraint = false) ⇒ Object



80
81
82
# File 'lib/rdl/types/string.rb', line 80

def <=(other, no_constraint=false)
  return Type.leq(self, other, no_constraint: no_constraint)
end

#==(other) ⇒ Object



52
53
54
55
56
57
# File 'lib/rdl/types/string.rb', line 52

def ==(other)
  return false if other.nil?
  return RDL::Globals.types[:string] == other if @promoted
  other = other.canonical
  return (other.instance_of? PreciseStringType) && (other.vals == @vals)
end

#canonicalObject



33
34
35
36
# File 'lib/rdl/types/string.rb', line 33

def canonical
  return RDL::Globals.types[:string] if @promoted
  return self
end

#cant_promote!Object

Raises:

  • (RuntimeError)


75
76
77
78
# File 'lib/rdl/types/string.rb', line 75

def cant_promote!
  raise RuntimeError, "already promoted!" if @promoted
  @cant_promote = true
end

#check_boundsObject



71
72
73
# File 'lib/rdl/types/string.rb', line 71

def check_bounds
  return (@lbounds.all? { |lbound| lbound <= self }) && (@ubounds.all? { |ubound| self <= ubound } )
end

#copyObject



95
96
97
# File 'lib/rdl/types/string.rb', line 95

def copy
  return PreciseStringType.new(*@vals.map { |v| if v.is_a?(String) then v.clone else v.copy end })
end

#hashObject



99
100
101
# File 'lib/rdl/types/string.rb', line 99

def hash
  99 * @vals.hash
end

#instantiate(inst) ⇒ Object



84
85
86
87
88
# File 'lib/rdl/types/string.rb', line 84

def instantiate(inst)
  return RDL::Globals.types[:string] if @promoted
  @vals.map! { |v| if v.is_a?(Type) then v.instantiate(inst) else v end }
  self
end

#member?(obj, *args) ⇒ Boolean

Returns:

  • (Boolean)


59
60
61
62
63
# File 'lib/rdl/types/string.rb', line 59

def member?(obj, *args)
  return false unless obj.is_a?(String)
  raise "Checking membership of PreciseStringType not currently supported for interpolated strings." unless @vals.all? { |v| v.is_a?(String) }
  return (@vals.join == obj)
end

#promote!Object



65
66
67
68
69
# File 'lib/rdl/types/string.rb', line 65

def promote!
  return false if @cant_promote
  @promoted = true
  check_bounds
end

#to_sObject



38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/rdl/types/string.rb', line 38

def to_s
  return RDL::Globals.types[:string].to_s if @promoted
  printed_vals = @vals.map { |v|
    case v
    when String
      "'"+v+"'"
    when Type
      #'#{' + v.to_s.gsub('"',"'") + '}'
      return "String"
    end
  }
  return printed_vals.join
end

#widenObject



90
91
92
93
# File 'lib/rdl/types/string.rb', line 90

def widen
  @vals.map! { |v| if v.is_a?(Type) then v.widen else v end }
  self
end