class TypeProf::Type
Constants
- Builtin
- DummySubstitution
Public Class Methods
any()
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 427 def self.any Thread.current[:any] ||= Any.new end
bool()
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 435 def self.bool Thread.current[:bool] ||= Union.new(Utils::Set[ Instance.new(Type::Builtin[:true]), Instance.new(Type::Builtin[:false]) ], nil) end
bot()
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 431 def self.bot Thread.current[:bot] ||= Union.new(Utils::Set[], nil) end
builtin_global_variable_type(var)
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 814 def self.builtin_global_variable_type(var) case var when :$_, :$/, :$\, :$,, :$; Type.optional(Type::Instance.new(Type::Builtin[:str])) when :$0, :$PROGRAM_NAME Type::Instance.new(Type::Builtin[:str]) when :$~ # optional type is tentatively disabled; it is too conservative #Type.optional(Type::Instance.new(Type::Builtin[:matchdata])) Type::Instance.new(Type::Builtin[:matchdata]) when :$., :$$ Type::Instance.new(Type::Builtin[:int]) when :$? Type.optional(Type::Instance.new(Type::Builtin[:int])) when :$! Type.optional(Type::Instance.new(Type::Builtin[:exc])) when :$@ str = Type::Instance.new(Type::Builtin[:str]) base_ty = Type::Instance.new(Type::Builtin[:ary]) Type.optional(Type::Array.new(Type::Array::Elements.new([], str), base_ty)) when :$*, :$:, :$LOAD_PATH, :$", :$LOADED_FEATURES str = Type::Instance.new(Type::Builtin[:str]) base_ty = Type::Instance.new(Type::Builtin[:ary]) Type::Array.new(Type::Array::Elements.new([], str), base_ty) when :$< :ARGF when :$> :STDOUT when :$DEBUG Type.bool when :$FILENAME Type::Instance.new(Type::Builtin[:str]) when :$stdin :STDIN when :$stdout :STDOUT when :$stderr :STDERR when :$VERBOSE Type.bool.union(Type.nil) else nil end end
gen_hash(base_ty = Type::Instance.new(Type::Builtin[:hash])) { |hg| ... }
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 755 def self.gen_hash(base_ty = Type::Instance.new(Type::Builtin[:hash])) hg = HashGenerator.new yield hg Type::Hash.new(Type::Hash::Elements.new(hg.map_tys), base_ty) end
guess_literal_type(obj)
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 761 def self.guess_literal_type(obj) case obj when ::Symbol Type::Symbol.new(obj, Type::Instance.new(Type::Builtin[:sym])) when ::Integer Type::Literal.new(obj, Type::Instance.new(Type::Builtin[:int])) when ::Rational Type::Literal.new(obj, Type::Instance.new(Type::Builtin[:rational])) when ::Complex Type::Literal.new(obj, Type::Instance.new(Type::Builtin[:complex])) when ::Float Type::Literal.new(obj, Type::Instance.new(Type::Builtin[:float])) when ::Class return Type.any if obj < Exception case obj when ::Object Type::Builtin[:obj] when ::Array Type::Builtin[:ary] else raise "unknown class: #{ obj.inspect }" end when ::TrueClass Type::Instance.new(Type::Builtin[:true]) when ::FalseClass Type::Instance.new(Type::Builtin[:false]) when ::Array base_ty = Type::Instance.new(Type::Builtin[:ary]) lead_tys = obj.map {|arg| guess_literal_type(arg) } Type::Array.new(Type::Array::Elements.new(lead_tys), base_ty) when ::Hash Type.gen_hash do |h| obj.each do |k, v| k_ty = guess_literal_type(k).globalize(nil, {}, Config.current.options[:type_depth_limit]) v_ty = guess_literal_type(v) h[k_ty] = v_ty end end when ::String Type::Literal.new(obj, Type::Instance.new(Type::Builtin[:str])) when ::Regexp Type::Literal.new(obj, Type::Instance.new(Type::Builtin[:regexp])) when ::NilClass Type.nil when ::Range Type::Literal.new(obj, Type::Instance.new(Type::Builtin[:range])) when ::Encoding Type::Literal.new(obj, Type::Instance.new(Type::Builtin[:encoding])) else raise "unknown object: #{ obj.inspect }" end end
match?(ty1, ty2)
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 23 def self.match?(ty1, ty2) # both ty1 and ty2 should be global # ty1 is always concrete; it should not have type variables # ty2 might be abstract; it may have type variables case ty2 when Type::Var { ty2 => ty1 } when Type::Any {} when Type::Union subst = nil ty2.each_child_global do |ty2| # this is very conservative to create subst: # Type.match?( int | str, int | X) creates { X => int | str } but should be { X => str }??? subst2 = Type.match?(ty1, ty2) next unless subst2 subst = Type.merge_substitution(subst, subst2) end subst else case ty1 when Type::Var then raise "should not occur" when Type::Any subst = {} ty2.each_free_type_variable do |tyvar| subst[tyvar] = Type.any end subst when Type::Union subst = nil ty1.each_child_global do |ty1| subst2 = Type.match?(ty1, ty2) next unless subst2 subst = Type.merge_substitution(subst, subst2) end subst else if ty2.is_a?(Type::ContainerType) # ty2 may have type variables if ty1.class == ty2.class ty1.match?(ty2) else Type.match?(ty1, ty2.base_type) end elsif ty1.is_a?(Type::ContainerType) Type.match?(ty1.base_type, ty2) else ty1.consistent?(ty2) ? {} : nil end end end end
merge_substitution(subst1, subst2)
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 76 def self.merge_substitution(subst1, subst2) if subst1 subst1 = subst1.dup subst2.each do |tyvar, ty| if subst1[tyvar] subst1[tyvar] = subst1[tyvar].union(ty) else subst1[tyvar] = ty end end subst1 else subst2 end end
new()
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 5 def initialize raise "cannot instantiate abstract type" end
nil()
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 442 def self.nil Thread.current[:nil] ||= Instance.new(Type::Builtin[:nil]) end
optional(ty)
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 446 def self.optional(ty) ty.union(Type.nil) end
Public Instance Methods
each_child() { |self| ... }
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 92 def each_child yield self end
each_child_global() { |self| ... }
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 96 def each_child_global yield self end
each_free_type_variable()
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 100 def each_free_type_variable end
generate_substitution()
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 164 def generate_substitution {} end
globalize(_env, _visited, _depth)
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 11 def globalize(_env, _visited, _depth) self end
include_untyped?(_scratch)
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 177 def include_untyped?(_scratch) false end
limit_size(limit)
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 19 def limit_size(limit) self end
localize(env, _alloc_site, _depth)
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 15 def localize(env, _alloc_site, _depth) return env, self end
remove_type_vars()
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 173 def remove_type_vars substitute(DummySubstitution, Config.current.options[:type_depth_limit]) end
substitute(_subst, _depth)
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 160 def substitute(_subst, _depth) raise "cannot substitute abstract type: #{ self.class }" end
union(other)
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 103 def union(other) return self if self == other # fastpath ty1, ty2 = self, other case when ty1.is_a?(Union) ty1_types = ty1.types ty1_elems = ty1.elems when ty1.is_a?(Array) || ty1.is_a?(Hash) ty1_types = Utils::Set[] ty1_elems = {[ty1.class, ty1.base_type] => ty1.elems} else ty1_types = ty1_elems = nil end case when ty2.is_a?(Union) ty2_types = ty2.types ty2_elems = ty2.elems when ty2.is_a?(Array) || ty2.is_a?(Hash) ty2_types = Utils::Set[] ty2_elems = {[ty2.class, ty2.base_type] => ty2.elems} else ty2_types = ty2_elems = nil end if ty1_types && ty2_types ty = ty1_types.sum(ty2_types) all_elems = ty1_elems.dup || {} ty2_elems&.each do |key, elems| all_elems[key] = union_elems(all_elems[key], elems) end all_elems = nil if all_elems.empty? Type::Union.create(ty, all_elems) elsif ty1_types Type::Union.create(ty1_types.add(ty2), ty1_elems) elsif ty2_types Type::Union.create(ty2_types.add(ty1), ty2_elems) else Type::Union.create(Utils::Set[ty1, ty2], nil) end end
Private Instance Methods
union_elems(e1, e2)
click to toggle source
# File typeprof-0.21.9/lib/typeprof/type.rb, line 148 def union_elems(e1, e2) if e1 if e2 e1.union(e2) else e1 end else e2 end end