low_type 1.1.6 → 1.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 353f89ccc3e77dc8eaa2fe4e8df301fc1c43bda6bfd936ecd92b19e755222fec
4
- data.tar.gz: c19938429cc2a5aed790df108ca1d232650807376c972f680fe161eeca77c072
3
+ metadata.gz: a6cfbec60ebbfe9ff5d9a3dd68a00c201b1b8cc8aea52f08f290c3b34131fb89
4
+ data.tar.gz: 4e745a28edb5c3da913b4fde7e1346ba62352469a27a1b259225ca6df62350fa
5
5
  SHA512:
6
- metadata.gz: 0baaf85c1edffcad962cde102756894d3a2c806ded41f98b442c84a5e79fbefaecbbd19859674839e57bd6357bd850b8a799837919a7b5fcf4481022274ff9f0
7
- data.tar.gz: 83d641896ca7dbf6fe8289d8870941b31a3bdc5327f4a429ba0463d14c4df206179373d4deb77f8330db6e940a84c9154e7d8bb8177f6991cd8a5958414c9cad
6
+ metadata.gz: ee8a741df349ef64d5d133a553339aef6c2ecf8d2238adedc7890c41e3e4b6a2bb71556fc5eac488fdb9d8a875cdee8a251bd78d268fe05ac36ecc71d0d5c31b
7
+ data.tar.gz: 3397ec0c358d4643b3c2ea3cf1a12243ba667ba4ea536c6aaac59eb7b067d5fdfea2850a0d121765f6fbbe3b2da49dc08123320d8e100c53ec2ee3865c0d678a
@@ -2,7 +2,7 @@
2
2
 
3
3
  require_relative 'sinatra_adapter'
4
4
 
5
- module LowType
5
+ module Low
6
6
  module Adapter
7
7
  class Loader
8
8
  class << self
@@ -7,7 +7,7 @@ require_relative '../interfaces/adapter_interface'
7
7
  require_relative '../proxies/return_proxy'
8
8
  require_relative '../types/error_types'
9
9
 
10
- module LowType
10
+ module Low
11
11
  module Adapter
12
12
  # We don't use https://sinatrarb.com/extensions.html because we need to type check all Ruby methods (not just Sinatra) at a lower level.
13
13
  class Sinatra < AdapterInterface
@@ -31,7 +31,7 @@ module LowType
31
31
  next unless (return_proxy = return_proxy(method_node: method_call, pattern:, file:))
32
32
 
33
33
  route = "#{method_call.name.upcase} #{pattern}"
34
- params = [ParamProxy.new(type_expression: nil, name: :route, type: :req, position: 0, file:)]
34
+ params = [ParamProxy.new(expression: nil, name: :route, type: :req, position: 0, file:)]
35
35
  @klass.low_methods[route] = MethodProxy.new(name: method_call.name, params:, return_proxy:)
36
36
  end
37
37
  end
@@ -6,7 +6,7 @@ require_relative '../proxies/method_proxy'
6
6
  require_relative '../queries/type_query'
7
7
  require_relative 'repository'
8
8
 
9
- module LowType
9
+ module Low
10
10
  # Redefine methods to have their arguments and return values type checked.
11
11
  class Redefiner
12
12
  class << self
@@ -21,20 +21,7 @@ module LowType
21
21
  end
22
22
 
23
23
  def redefinable?(method_proxy:, class_proxy:)
24
- # Method has no types.
25
- if method_proxy.params == [] && method_proxy.return_proxy.nil?
26
- LowType::Repository.delete(name: method_proxy.name, klass: class_proxy.klass)
27
- return false
28
- end
29
-
30
- # Method outside class bounds.
31
- within_bounds = method_proxy.start_line > class_proxy.start_line && method_proxy.end_line <= class_proxy.end_line
32
- if method_proxy.lines? && class_proxy.lines? && !within_bounds
33
- LowType::Repository.delete(name: method_proxy.name, klass: class_proxy.klass)
34
- return false
35
- end
36
-
37
- true
24
+ method_has_types?(method_proxy:, class_proxy:) && method_within_class_bounds?(method_proxy:, class_proxy:)
38
25
  end
39
26
 
40
27
  def untyped_args(args:, kwargs:, method_proxy:) # rubocop:disable Metrics/AbcSize
@@ -44,7 +31,7 @@ module LowType
44
31
  next unless value.nil?
45
32
  raise param_proxy.error_type, param_proxy.error_message(value:) if param_proxy.required?
46
33
 
47
- value = param_proxy.type_expression.default_value # Default value can still be `nil`.
34
+ value = param_proxy.expression.default_value # Default value can still be `nil`.
48
35
  value = value.value if value.is_a?(ValueExpression)
49
36
  param_proxy.position ? args[param_proxy.position] = value : kwargs[param_proxy.name] = value
50
37
  end
@@ -76,7 +63,7 @@ module LowType
76
63
  def typed_methods(method_proxies:, class_proxy:) # rubocop:disable Metrics
77
64
  Module.new do
78
65
  method_proxies.each do |name, method_proxy|
79
- next unless LowType::Redefiner.redefinable?(method_proxy:, class_proxy:)
66
+ next unless Low::Redefiner.redefinable?(method_proxy:, class_proxy:)
80
67
 
81
68
  # You are now in the binding of the includer class (`name` is also available here).
82
69
  define_method(name) do |*args, **kwargs|
@@ -85,9 +72,9 @@ module LowType
85
72
 
86
73
  method_proxy.params.each do |param_proxy|
87
74
  value = param_proxy.position ? args[param_proxy.position] : kwargs[param_proxy.name]
88
- value = param_proxy.type_expression.default_value if value.nil? && !param_proxy.required?
75
+ value = param_proxy.expression.default_value if value.nil? && !param_proxy.required?
89
76
 
90
- param_proxy.type_expression.validate!(value:, proxy: param_proxy)
77
+ param_proxy.expression.validate!(value:, proxy: param_proxy)
91
78
  value = value.value if value.is_a?(ValueExpression)
92
79
  param_proxy.position ? args[param_proxy.position] = value : kwargs[param_proxy.name] = value
93
80
  end
@@ -109,13 +96,13 @@ module LowType
109
96
  def untyped_methods(method_proxies:, class_proxy:)
110
97
  Module.new do
111
98
  method_proxies.each do |name, method_proxy|
112
- next unless LowType::Redefiner.redefinable?(method_proxy:, class_proxy:)
99
+ next unless Low::Redefiner.redefinable?(method_proxy:, class_proxy:)
113
100
 
114
101
  # You are now in the binding of the includer class (`name` is also available here).
115
102
  define_method(name) do |*args, **kwargs|
116
103
  # NOTE: Type checking is currently disabled. See 'config.type_checking'.
117
104
  method_proxy = instance_of?(Class) ? low_methods[name] : self.class.low_methods[name] || Object.low_methods[name]
118
- args, kwargs = LowType::Redefiner.untyped_args(args:, kwargs:, method_proxy:)
105
+ args, kwargs = Low::Redefiner.untyped_args(args:, kwargs:, method_proxy:)
119
106
  super(*args, **kwargs)
120
107
  end
121
108
 
@@ -123,6 +110,25 @@ module LowType
123
110
  end
124
111
  end
125
112
  end
113
+
114
+ def method_has_types?(method_proxy:, class_proxy:)
115
+ if method_proxy.params == [] && method_proxy.return_proxy.nil?
116
+ Low::Repository.delete(name: method_proxy.name, klass: class_proxy.klass)
117
+ return false
118
+ end
119
+
120
+ true
121
+ end
122
+
123
+ def method_within_class_bounds?(method_proxy:, class_proxy:)
124
+ within_bounds = method_proxy.start_line > class_proxy.start_line && method_proxy.end_line <= class_proxy.end_line
125
+ if method_proxy.lines? && class_proxy.lines? && !within_bounds
126
+ Low::Repository.delete(name: method_proxy.name, klass: class_proxy.klass)
127
+ return false
128
+ end
129
+
130
+ true
131
+ end
126
132
  end
127
133
  end
128
134
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module LowType
3
+ module Low
4
4
  class Repository
5
5
  class << self
6
6
  def all(klass:)
@@ -4,36 +4,36 @@ require_relative '../expressions/type_expression'
4
4
  require_relative '../proxies/return_proxy'
5
5
  require_relative '../queries/type_query'
6
6
 
7
- module LowType
7
+ module Low
8
8
  module TypeAccessors
9
9
  def type_reader(named_expressions)
10
- named_expressions.each do |name, expression|
10
+ named_expressions.each do |name, exp|
11
11
  last_caller = caller_locations(1, 1).first
12
- type_expression = type_expression(expression)
13
12
  file = FileProxy.new(path: last_caller.path, start_line: last_caller.lineno, scope: "#{self}##{name}")
14
13
 
15
- @low_methods[name] = MethodProxy.new(name:, return_proxy: ReturnProxy.new(type_expression:, name:, file:))
14
+ expression = expression(exp)
15
+ @low_methods[name] = MethodProxy.new(name:, return_proxy: ReturnProxy.new(type_expression: expression, name:, file:))
16
16
 
17
17
  define_method(name) do
18
18
  method_proxy = self.class.low_methods[name]
19
19
  value = instance_variable_get("@#{name}")
20
- type_expression.validate!(value:, proxy: method_proxy.return_proxy)
20
+ expression.validate!(value:, proxy: method_proxy.return_proxy)
21
21
  value
22
22
  end
23
23
  end
24
24
  end
25
25
 
26
- def type_writer(named_expressions)
27
- named_expressions.each do |name, expression|
26
+ def type_writer(named_expressions) # rubocop:disable Metrics/AbcSize
27
+ named_expressions.each do |name, exp|
28
28
  last_caller = caller_locations(1, 1).first
29
- type_expression = type_expression(expression)
30
29
  file = FileProxy.new(path: last_caller.path, start_line: last_caller.lineno, scope: "#{self}##{name}")
31
30
 
32
- @low_methods["#{name}="] = MethodProxy.new(name:, params: [ParamProxy.new(type_expression:, name:, type: :hashreq, file:)])
31
+ params = [ParamProxy.new(expression: expression(exp), name:, type: :hashreq, file:)]
32
+ @low_methods["#{name}="] = MethodProxy.new(name:, params:)
33
33
 
34
34
  define_method("#{name}=") do |value|
35
35
  method_proxy = self.class.low_methods["#{name}="]
36
- type_expression.validate!(value:, proxy: method_proxy.params.first)
36
+ method_proxy.params.first.expression.validate!(value:, proxy: method_proxy.params.first)
37
37
  instance_variable_set("@#{name}", value)
38
38
  end
39
39
  end
@@ -48,10 +48,10 @@ module LowType
48
48
 
49
49
  private
50
50
 
51
- def type_expression(expression)
52
- if expression.instance_of?(TypeExpression)
51
+ def expression(expression)
52
+ if expression.is_a?(::Expressions::Expression)
53
53
  expression
54
- elsif ::LowType::TypeQuery.type?(expression)
54
+ elsif ::Low::TypeQuery.type?(expression)
55
55
  TypeExpression.new(type: expression)
56
56
  end
57
57
  end
@@ -5,7 +5,7 @@ require_relative '../proxies/file_proxy'
5
5
  require_relative '../proxies/local_proxy'
6
6
  require_relative '../types/error_types'
7
7
 
8
- module LowType
8
+ module Low
9
9
  module Expressions
10
10
  def type(type_expression)
11
11
  value = type_expression.default_value
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'expressions'
4
+
3
5
  require_relative '../proxies/param_proxy'
4
6
  require_relative '../queries/type_query'
5
7
 
6
- module LowType
8
+ module Low
7
9
  root_path = File.expand_path(__dir__)
8
10
  adapter_paths = Dir.chdir(root_path) { Dir.glob('adapters/*') }.map { |path| File.join(root_path, path) }
9
11
  module_paths = %w[expressions/expressions instance_types redefiner].map { |path| File.join(root_path, "#{path}.rb") }
@@ -11,7 +13,7 @@ module LowType
11
13
  HIDDEN_PATHS = [File.expand_path(__FILE__), *adapter_paths, *module_paths].freeze
12
14
 
13
15
  # Represent types and default values as a series of chainable expressions.
14
- class TypeExpression
16
+ class TypeExpression < ::Expressions::Expression
15
17
  attr_reader :types, :default_value
16
18
 
17
19
  # @param type - A literal type or an instance representation of a typed structure.
@@ -23,19 +25,6 @@ module LowType
23
25
  @deep_type_check = LowType.config.deep_type_check
24
26
  end
25
27
 
26
- def |(expression)
27
- if expression.instance_of?(::LowType::TypeExpression)
28
- @types += expression.types
29
- @default_value = expression.default_value
30
- elsif ::LowType::TypeQuery.value?(expression)
31
- @default_value = expression
32
- else
33
- @types << expression
34
- end
35
-
36
- self
37
- end
38
-
39
28
  def required?
40
29
  @default_value == :LOW_TYPE_UNDEFINED
41
30
  end
@@ -62,7 +51,7 @@ module LowType
62
51
  if type.is_a?(Array)
63
52
  "[#{type.map { |subtype| valid_subtype(subtype:) }.join(', ')}]"
64
53
  else
65
- type.inspect.to_s.delete_prefix('LowType::')
54
+ type.inspect.to_s.delete_prefix('Low::')
66
55
  end
67
56
  end
68
57
 
@@ -72,13 +61,31 @@ module LowType
72
61
 
73
62
  private
74
63
 
64
+ def union_expression(expression)
65
+ @types += expression.types
66
+ @default_value = expression.default_value
67
+ end
68
+
69
+ def union_type(type)
70
+ @types << type
71
+ end
72
+
73
+ def union_value(value)
74
+ @default_value = value
75
+ end
76
+
77
+ # Override Expressions as LowType supports complex types which are implemented as values.
78
+ def value?(expression)
79
+ ::Low::TypeQuery.value?(expression) || expression.nil?
80
+ end
81
+
75
82
  def valid_subtype(subtype:)
76
83
  if subtype.is_a?(TypeExpression)
77
84
  types = subtype.types
78
85
  types << 'nil' if subtype.default_value.nil?
79
86
  types.join(' | ')
80
87
  else
81
- subtype.to_s.delete_prefix('LowType::')
88
+ subtype.to_s.delete_prefix('Low::')
82
89
  end
83
90
  end
84
91
 
@@ -122,10 +129,10 @@ module LowType
122
129
 
123
130
  def type_matches_value?(type:, value:, proxy:)
124
131
  if type.instance_of?(Class)
125
- return type.match?(value:) if LowType::TypeQuery.complex_type?(expression: type)
132
+ return type.match?(value:) if Low::TypeQuery.complex_type?(expression: type)
126
133
 
127
134
  return type == value.class
128
- elsif type.instance_of?(::LowType::TypeExpression)
135
+ elsif type.instance_of?(::Low::TypeExpression)
129
136
  type.validate!(value:, proxy:)
130
137
  return true
131
138
  end
@@ -3,7 +3,7 @@
3
3
  require_relative '../expressions/type_expression'
4
4
  require_relative '../expressions/value_expression'
5
5
 
6
- module LowType
6
+ module Low
7
7
  class ExpressionFactory
8
8
  class << self
9
9
  def type_expression_with_value(type:)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'expressions'
4
+
3
5
  require_relative '../expressions/expressions'
4
6
  require_relative '../expressions/type_expression'
5
7
  require_relative '../proxies/file_proxy'
@@ -8,7 +10,7 @@ require_relative '../proxies/return_proxy'
8
10
  require_relative '../queries/file_parser'
9
11
  require_relative '../syntax/syntax'
10
12
 
11
- module LowType
13
+ module Low
12
14
  class ProxyFactory
13
15
  using ::LowType::Syntax
14
16
 
@@ -22,25 +24,24 @@ module LowType
22
24
  FileProxy.new(path:, start_line:, end_line:, scope:)
23
25
  end
24
26
 
27
+ # The evals below aren't a security risk because the code comes from a trusted source; the file itself that did the include.
25
28
  def param_proxies(method_node:, file:)
26
29
  return [] if method_node.parameters.nil?
27
30
 
28
31
  params_without_block = method_node.parameters.slice.delete_suffix(', &block')
29
32
 
30
- # Not a security risk because the code comes from a trusted source; the file that did the include. Does the file trust itself?
31
33
  ruby_method = eval("-> (#{params_without_block}) {}", binding, __FILE__, __LINE__) # rubocop:disable Security/Eval
32
34
 
33
- # Not a security risk because the code comes from a trusted source; the file that did the include. Does the file trust itself?
34
- # Local variable names are prefixed with __lt or __rb where necessary to avoid being overridden by method parameters.
35
+ # Local variable names are prefixed with __lt or __rb where needed to avoid being overridden by method parameters.
35
36
  typed_method = <<~RUBY
36
37
  -> (#{params_without_block}, __rb_method:, __lt_file:) {
37
- param_proxies_for_type_expressions(ruby_method: __rb_method, file: __lt_file, method_binding: binding)
38
+ param_proxies_for_expressions(ruby_method: __rb_method, file: __lt_file, method_binding: binding)
38
39
  }
39
40
  RUBY
40
41
 
41
- # Called with only required args (as nil) and optional args omitted, to evaluate type expressions (from default values).
42
- # Passes internal variables with namespaced names to avoid conflicts with the method parameters.
43
42
  required_args, required_kwargs = required_args(ruby_method:)
43
+
44
+ # Called with only required args (as nil) and optional args omitted, to evaluate expressions stored as default values.
44
45
  eval(typed_method, binding, __FILE__, __LINE__) # rubocop:disable Security/Eval
45
46
  .call(*required_args, **required_kwargs, __rb_method: ruby_method, __lt_file: file)
46
47
 
@@ -85,22 +86,28 @@ module LowType
85
86
  [required_args, required_kwargs]
86
87
  end
87
88
 
88
- def param_proxies_for_type_expressions(ruby_method:, file:, method_binding:)
89
+ def param_proxies_for_expressions(ruby_method:, file:, method_binding:)
89
90
  param_proxies = []
90
91
 
91
92
  ruby_method.parameters.each_with_index do |param, position|
92
93
  type, name = param
93
- position = nil unless %i[opt req rest].include?(type)
94
- expression = method_binding.local_variable_get(name)
95
-
96
- type_expression = nil
97
- if expression.is_a?(TypeExpression)
98
- type_expression = expression
99
- elsif ::LowType::TypeQuery.type?(expression)
100
- type_expression = TypeExpression.new(type: expression)
94
+
95
+ # We don't support splatted *positional and **keyword arguments as by definition they are untyped.
96
+ next if type == :rest
97
+
98
+ position = nil unless %i[opt req].include?(type)
99
+ local_variable = method_binding.local_variable_get(name)
100
+
101
+ expression = nil
102
+ if local_variable.is_a?(::Expressions::Expression)
103
+ expression = local_variable
104
+ elsif local_variable.instance_of?(Class) && local_variable < ::Expressions::Expression
105
+ expression = local_variable.new(provider_key: name)
106
+ elsif ::Low::TypeQuery.type?(local_variable)
107
+ expression = TypeExpression.new(type: local_variable)
101
108
  end
102
109
 
103
- param_proxies << ParamProxy.new(type_expression:, name:, type:, position:, file:) if type_expression
110
+ param_proxies << ParamProxy.new(expression:, name:, type:, position:, file:) if expression
104
111
  end
105
112
 
106
113
  param_proxies
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module LowType
3
+ module Low
4
4
  class TypeFactory
5
5
  class << self
6
6
  def complex_type(parent_type)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module LowType
3
+ module Low
4
4
  class AdapterInterface
5
5
  def process
6
6
  raise NotImplementedError
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module LowType
3
+ module Low
4
4
  class ErrorInterface
5
5
  attr_reader :file
6
6
 
data/lib/low_type.rb CHANGED
@@ -20,25 +20,32 @@ module LowType
20
20
  end
21
21
  end
22
22
 
23
- file_path = FileQuery.file_path(klass:)
23
+ file_path = Low::FileQuery.file_path(klass:)
24
24
  return unless File.exist?(file_path)
25
25
 
26
- parser = FileParser.new(klass:, file_path:)
26
+ parser = Low::FileParser.new(klass:, file_path:)
27
27
 
28
- klass.extend TypeAccessors
29
- klass.include Expressions
30
- klass.prepend Redefiner.redefine(method_nodes: parser.instance_methods, class_proxy: parser.class_proxy, file_path:)
31
- klass.singleton_class.prepend Redefiner.redefine(method_nodes: parser.class_methods, class_proxy: parser.class_proxy, file_path:)
28
+ klass.extend Low::TypeAccessors
29
+ klass.include Low::Expressions
30
+ klass.prepend Low::Redefiner.redefine(method_nodes: parser.instance_methods, class_proxy: parser.class_proxy, file_path:)
31
+ klass.singleton_class.prepend Low::Redefiner.redefine(method_nodes: parser.class_methods, class_proxy: parser.class_proxy, file_path:)
32
32
 
33
- if (adapter = Adapter::Loader.load(klass:, parser:, file_path:))
33
+ if (adapter = Low::Adapter::Loader.load(klass:, parser:, file_path:))
34
34
  adapter.process
35
- klass.prepend Adapter::Methods
35
+ klass.prepend Low::Adapter::Methods
36
36
  end
37
37
  end
38
38
 
39
39
  class << self
40
40
  def config
41
- config = Struct.new(:type_checking, :error_mode, :output_mode, :output_size, :deep_type_check, :union_type_expressions)
41
+ config = Struct.new(
42
+ :type_checking,
43
+ :error_mode,
44
+ :output_mode,
45
+ :output_size,
46
+ :deep_type_check,
47
+ :union_type_expressions
48
+ )
42
49
  @config ||= config.new(true, :error, :type, 100, false, true)
43
50
  end
44
51
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'forwardable'
4
4
 
5
- module LowType
5
+ module Low
6
6
  class ClassProxy
7
7
  extend Forwardable
8
8
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module LowType
3
+ module Low
4
4
  class FileProxy
5
5
  attr_reader :path, :scope
6
6
  attr_accessor :start_line, :end_line
@@ -3,7 +3,7 @@
3
3
  require_relative '../interfaces/error_interface'
4
4
  require_relative '../types/error_types'
5
5
 
6
- module LowType
6
+ module Low
7
7
  class LocalProxy < ErrorInterface
8
8
  attr_reader :type_expression, :name
9
9
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'forwardable'
4
4
 
5
- module LowType
5
+ module Low
6
6
  class MethodProxy
7
7
  extend Forwardable
8
8
 
@@ -3,14 +3,14 @@
3
3
  require_relative '../interfaces/error_interface'
4
4
  require_relative '../types/error_types'
5
5
 
6
- module LowType
6
+ module Low
7
7
  class ParamProxy < ErrorInterface
8
- attr_reader :type_expression, :name, :type, :position
8
+ attr_reader :expression, :name, :type, :position
9
9
 
10
- def initialize(type_expression:, name:, type:, file:, position: nil)
10
+ def initialize(expression:, name:, type:, file:, position: nil)
11
11
  super()
12
12
 
13
- @type_expression = type_expression
13
+ @expression = expression
14
14
  @name = name
15
15
  @type = type
16
16
  @position = position
@@ -18,7 +18,7 @@ module LowType
18
18
  end
19
19
 
20
20
  def required?
21
- @type_expression.default_value == :LOW_TYPE_UNDEFINED
21
+ @expression.required?
22
22
  end
23
23
 
24
24
  def error_type
@@ -26,7 +26,7 @@ module LowType
26
26
  end
27
27
 
28
28
  def error_message(value:)
29
- "Invalid argument type '#{output(value:)}' for parameter '#{@name}'. Valid types: '#{@type_expression.valid_types}'"
29
+ "Invalid argument type '#{output(value:)}' for parameter '#{@name}'. Valid types: '#{@expression.valid_types}'"
30
30
  end
31
31
  end
32
32
  end
@@ -3,7 +3,7 @@
3
3
  require_relative '../interfaces/error_interface'
4
4
  require_relative '../types/error_types'
5
5
 
6
- module LowType
6
+ module Low
7
7
  class ReturnProxy < ErrorInterface
8
8
  attr_reader :type_expression, :name
9
9
 
@@ -3,7 +3,7 @@
3
3
  require 'prism'
4
4
  require_relative '../proxies/class_proxy'
5
5
 
6
- module LowType
6
+ module Low
7
7
  class FileParser
8
8
  attr_reader :parent_map, :instance_methods, :class_methods, :class_proxy
9
9
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module LowType
3
+ module Low
4
4
  class FileQuery
5
5
  class << self
6
6
  def file_path(klass:)
@@ -2,7 +2,7 @@
2
2
 
3
3
  require_relative '../expressions/type_expression'
4
4
 
5
- module LowType
5
+ module Low
6
6
  # TODO: Unit test.
7
7
  class TypeQuery
8
8
  class << self
@@ -19,7 +19,7 @@ module LowType
19
19
  end
20
20
 
21
21
  def complex_type?(expression:)
22
- LowType::COMPLEX_TYPES.include?(expression) || typed_array?(expression:) || typed_hash?(expression:)
22
+ Low::COMPLEX_TYPES.include?(expression) || typed_array?(expression:) || typed_hash?(expression:)
23
23
  end
24
24
 
25
25
  private
data/lib/syntax/syntax.rb CHANGED
@@ -6,7 +6,9 @@ module LowType
6
6
  module Syntax
7
7
  refine Array.singleton_class do
8
8
  def [](*expression)
9
- return TypeExpression.new(type: [*expression]) if TypeQuery.type?(expression.first) || TypeQuery.typed_array?(expression:)
9
+ if Low::TypeQuery.type?(expression.first) || Low::TypeQuery.typed_array?(expression:)
10
+ return Low::TypeExpression.new(type: [*expression])
11
+ end
10
12
 
11
13
  super
12
14
  end
@@ -14,7 +16,7 @@ module LowType
14
16
 
15
17
  refine Hash.singleton_class do
16
18
  def [](type)
17
- return TypeExpression.new(type:) if TypeQuery.type?(type)
19
+ return Low::TypeExpression.new(type:) if Low::TypeQuery.type?(type)
18
20
 
19
21
  super
20
22
  end
@@ -8,21 +8,13 @@
8
8
  # @see LowType.config.union_type_expressions
9
9
  ###
10
10
  class Object
11
- # For "Type | [type_expression/type/value]" situations, redirecting to or generating a type expression from types.
11
+ # For "Type | [type_expression/type/value]" situations, convert type into a type expression to continue the chain.
12
12
  # "|" is not defined on Object class and this is the most compute-efficient way to achieve our goal (world peace).
13
13
  # "|" is overridable by any child object. While we could def/undef this method, this approach is actually lighter.
14
14
  # "|" bitwise operator on Integer is not defined when the receiver is an Integer class, so we are not in conflict.
15
15
  class << self
16
16
  def |(expression)
17
- if expression.instance_of?(::LowType::TypeExpression)
18
- # We pass our type into their type expression.
19
- expression | self
20
- expression
21
- else
22
- # We turn our type into a type expression and pass in their type/value.
23
- type_expression = ::LowType::TypeExpression.new(type: self)
24
- type_expression | expression
25
- end
17
+ ::Low::TypeExpression.new(type: self) | expression
26
18
  end
27
19
  end
28
20
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module LowType
3
+ module Low
4
4
  module ComplexType
5
5
  def match?(value:)
6
6
  return true if value.instance_of?(self.class) || value.instance_of?(superclass)
@@ -3,7 +3,7 @@
3
3
  require_relative '../factories/type_factory'
4
4
  require_relative 'status'
5
5
 
6
- module LowType
6
+ module Low
7
7
  COMPLEX_TYPES = [
8
8
  Boolean = TypeFactory.complex_type(Object),
9
9
  Headers = TypeFactory.complex_type(Hash),
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module LowType
3
+ module Low
4
4
  class ArgumentTypeError < TypeError; end
5
5
  class LocalTypeError < TypeError; end
6
6
  class ReturnTypeError < TypeError; end
data/lib/types/status.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require_relative 'complex_type'
4
4
  require_relative 'error_types'
5
5
 
6
- module LowType
6
+ module Low
7
7
  # Status is an Integer for type checking, but an instance of StatusCode for advanced functionality.
8
8
  class Status < Integer
9
9
  extend ComplexType
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module LowType
4
- VERSION = '1.1.6'
3
+ module Low
4
+ TYPE_VERSION = '1.1.7'
5
5
  end
metadata CHANGED
@@ -1,14 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: low_type
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.6
4
+ version: 1.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - maedi
8
8
  bindir: exe
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
- dependencies: []
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: expressions
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '0.1'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '0.1'
12
26
  description: An elegant and simple way to define types in Ruby, only when you need
13
27
  them.
14
28
  email:
@@ -47,11 +61,11 @@ files:
47
61
  - lib/types/error_types.rb
48
62
  - lib/types/status.rb
49
63
  - lib/version.rb
50
- homepage: https://codeberg.org/low_ruby/low_type
64
+ homepage: https://github.com/low-rb/low_type
51
65
  licenses: []
52
66
  metadata:
53
- homepage_uri: https://codeberg.org/low_ruby/low_type
54
- source_code_uri: https://codeberg.org/low_ruby/low_type/src/branch/main
67
+ homepage_uri: https://github.com/low-rb/low_type
68
+ source_code_uri: https://github.com/low-rb/low_type/src/branch/main
55
69
  rdoc_options: []
56
70
  require_paths:
57
71
  - lib