Module: Docscribe::Types::Primitive

Defined in:
lib/docscribe/types/primitive.rb

Overview

Dynamic primitive type detection via RBS core + YARD.

Replaces hardcoded %w[String Integer ...] lists in Returns and GenericCompatibility with RBS environment inspection.

Class Method Summary collapse

Class Method Details

.alias_pattern?(token) ⇒ Boolean

Note:

module_function: defines #alias_pattern? (visibility: private)

Whether token matches alias pattern (lowercase after

or capitalized not in primitives)

Parameters:

  • token (String)

Returns:

  • (Boolean)


26
27
28
29
30
31
32
# File 'lib/docscribe/types/primitive.rb', line 26

def alias_pattern?(token)
  base = normalized_base(token)
  return true if base =~ /\A[a-z]/ || base.include?('::')
  return true if base =~ /\A[A-Z]\z/

  !!(base =~ /\A[A-Z][A-Za-z0-9_]*\z/ && !core_primitives.include?(base))
end

.alias_token?(token) ⇒ Boolean

Note:

module_function: defines #alias_token? (visibility: private)

Whether token is an alias/generic placeholder (Elem, U, ParamTag, MyAlias) vs primitive. Inverse of primitive?.

Parameters:

  • token (String)

    single type token

Returns:

  • (Boolean)

    true if alias



51
52
53
54
55
56
57
58
# File 'lib/docscribe/types/primitive.rb', line 51

def alias_token?(token)
  base = normalized_base(token)
  return false if primitive?(base)
  return true if base =~ /\A[a-z]/ || base.include?('::')
  return true if base =~ /\A[A-Z]\z/

  !!(base =~ /\A[A-Z][A-Za-z0-9_]*\z/ && !core_primitives.include?(base))
end

.alias_type?(type_str) ⇒ Boolean

Note:

module_function: defines #alias_type? (visibility: private)

Whether a type string is an alias (contains alias token inside generic)

Parameters:

  • type_str (String)

Returns:

  • (Boolean)


39
40
41
42
43
# File 'lib/docscribe/types/primitive.rb', line 39

def alias_type?(type_str)
  # Check if any comma-separated inner is alias
  # For "Array<Elem>" or "MyAlias" etc
  type_str.split(',').any? { |part| alias_token?(part.strip) }
end

.core_primitivesArray<String>

Note:

module_function: defines #core_primitives (visibility: private)

All core primitive class/module names from RBS environment (String, Array, etc) plus YARD primitives. Computed once and cached.

Returns:

  • (Array<String>)

    primitive names



90
91
92
# File 'lib/docscribe/types/primitive.rb', line 90

def core_primitives
  @core_primitives ||= load_core_primitives
end

.load_core_primitivesArray<String>

Note:

module_function: defines #load_core_primitives (visibility: private)

Load core primitives from RBS environment. Falls back to minimal hardcoded list if RBS not available (e.g., in test env without rbs gem).

Returns:

  • (Array<String>)


99
100
101
102
103
104
105
# File 'lib/docscribe/types/primitive.rb', line 99

def load_core_primitives
  primitives = Set.new
  load_yard_primitives(primitives)
  load_rbs_core(primitives)
  merge_primitives(primitives)
  primitives.to_a
end

.load_rbs_core(primitives) ⇒ Set<String>

Note:

module_function: defines #load_rbs_core (visibility: private)

Parameters:

  • primitives (Set<String>)

Returns:

  • (Set<String>)
  • (Set<String>)

    if LoadError, StandardError

Raises:

  • (LoadError)
  • (StandardError)


120
121
122
123
124
125
126
127
128
129
130
# File 'lib/docscribe/types/primitive.rb', line 120

def load_rbs_core(primitives)
  require 'rbs'
  loader = RBS::EnvironmentLoader.new
  env = RBS::Environment.new
  loader.load(env: env)
  populate_class_decls(env, primitives)
  populate_interface_decls(env, primitives)
rescue LoadError, StandardError
  primitives.merge(%w[String Integer Float Numeric Symbol Array Hash Range Regexp Proc Method NilClass TrueClass FalseClass BasicObject Kernel Object Class Module IO File Dir Time Date Enumerator
                      Set Enumerable])
end

.load_yard_primitives(primitives) ⇒ Set<String>

Note:

module_function: defines #load_yard_primitives (visibility: private)

Parameters:

  • primitives (Set<String>)

Returns:

  • (Set<String>)


110
111
112
# File 'lib/docscribe/types/primitive.rb', line 110

def load_yard_primitives(primitives)
  primitives.merge(%w[Boolean void untyped nil true false])
end

.merge_primitives(primitives) ⇒ Set<String>

Note:

module_function: defines #merge_primitives (visibility: private)

Parameters:

  • primitives (Set<String>)

Returns:

  • (Set<String>)


155
156
157
# File 'lib/docscribe/types/primitive.rb', line 155

def merge_primitives(primitives)
  primitives.merge(%w[String Integer Float Numeric Symbol Array Hash Range Regexp Proc Method NilClass TrueClass FalseClass BasicObject Kernel Object])
end

.normalized_base(token) ⇒ String

Note:

module_function: defines #normalized_base (visibility: private)

Parameters:

  • token (String)

Returns:

  • (String)


81
82
83
# File 'lib/docscribe/types/primitive.rb', line 81

def normalized_base(token)
  token.split('<').first.split('[').first.strip.delete_suffix('?').strip
end

.populate_class_decls(env, primitives) ⇒ void

Note:

module_function: defines #populate_class_decls (visibility: private)

This method returns an undefined value.

Parameters:

  • env (RBS::Environment)
  • primitives (Set<String>)


136
137
138
139
140
# File 'lib/docscribe/types/primitive.rb', line 136

def populate_class_decls(env, primitives)
  return unless env.respond_to?(:class_decls)

  env.class_decls.each_key { |k| primitives.merge([k.to_s.split('::').last, k.to_s]) }
end

.populate_interface_decls(env, primitives) ⇒ void

Note:

module_function: defines #populate_interface_decls (visibility: private)

This method returns an undefined value.

Parameters:

  • env (RBS::Environment)
  • primitives (Set<String>)


146
147
148
149
150
# File 'lib/docscribe/types/primitive.rb', line 146

def populate_interface_decls(env, primitives)
  return unless env.respond_to?(:interface_decls)

  env.interface_decls.each_key { |k| primitives << k.to_s.split('::').last }
end

.primitive?(token) ⇒ Boolean

Note:

module_function: defines #primitive? (visibility: private)

Whether token is a primitive type (String, Integer, etc) vs alias (Elem, U, ParamTag).

Uses RBS core class declarations + YARD pseudo types (Boolean, void, untyped) to avoid hardcoding the full list. Falls back to a minimal list if RBS unavailable.

Parameters:

  • token (String)

    type token (e.g., "String", "Elem", "ParamTag", "untyped")

Returns:

  • (Boolean)

    true if primitive, false if alias/generic placeholder



68
69
70
71
72
73
74
75
76
# File 'lib/docscribe/types/primitive.rb', line 68

def primitive?(token)
  base = normalized_base(token)
  return false if base.empty?
  return true if %w[untyped void nil].include?(base)
  # YARD pseudo types that are not real RBS classes but considered primitives
  return true if %w[Boolean void untyped nil].include?(base)

  core_primitives.include?(base)
end