lowtype 1.3.2 → 1.4.0

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: c777de40504eea68870df0ee7936de827b1e5a771aca97e40d1ef2b41d3e38ed
4
- data.tar.gz: cab3b2a605413173922eee3680a18951f19ec28065e0eb320d5d649b99300c34
3
+ metadata.gz: dd21f076ae997541e19b4bd3d405d434a7a3395165afa5084dbe7e2701d591a7
4
+ data.tar.gz: ab3cc40ff0baef867751c9a0c5660cb6340951167c677ab7c4412b389e49f394
5
5
  SHA512:
6
- metadata.gz: 7c4391bb32203a889a6a88ebdbe2895fd19bf8f195caa2a6d890475a5312fbb4b3e184bd5ea7a6d0031d95246411b8c56cf8323f62774aeda7d78b958f6bd2f0
7
- data.tar.gz: d958d6ccd1f5d6c8c328aef5d7a12b2a46dc75253f82ed0f26d31da29666aa81f6e49e06515be901f6bd1ee5c4781e048131ef5d72505fd753da9135a52dee05
6
+ metadata.gz: 906c8a132cbddaf7b907b7933f4a8fe9686c47dad2ad5811c49be40637c8ce4cb63efd88bcb602255610addf80b57421fdde95b5919e5708e5931994a3575c8f
7
+ data.tar.gz: 2e7f57855d2e290a2bc353470bec98af3bbf24550006de66ae265de3ecd99623a75874e47ce57bf9667ecf8efaad843a4d173c219222c35067c52002e50e5a05
@@ -26,25 +26,28 @@ module Low
26
26
  # │ │ │ │ │
27
27
  class Redefiner
28
28
  class << self
29
- # TODO: Pass in "klass" and use it to class_eval/eval methods in the binding of the class that included LowType.
30
- def redefine(method_proxies:, class_proxy:)
31
- if LowType.config.type_checking
32
- typed_methods(method_proxies:, class_proxy:)
33
- else
34
- untyped_methods(method_proxies:, class_proxy:)
29
+ def redefine(method_proxies:, class_proxy:, klass: nil)
30
+ return typed_methods(method_proxies:, class_proxy:) if LowType.config.type_checking
31
+
32
+ case LowType.config.disable_mode
33
+ when :shim
34
+ shimmed_methods(method_proxies:, class_proxy:)
35
+ when :strip
36
+ strip_types(method_proxies:, class_proxy:, klass:)
35
37
  end
36
38
  end
37
39
 
38
- def untyped_args(args:, kwargs:, method_proxy:) # rubocop:disable Metrics/AbcSize
40
+ def untyped_shimmed_args(args:, kwargs:, method_proxy:) # rubocop:disable Metrics/AbcSize
39
41
  method_proxy.params_with_expressions.each do |param_proxy|
40
- value = param_proxy.position ? args[param_proxy.position] : kwargs[param_proxy.name]
42
+ positional = %i[pos_req pos_opt].include?(param_proxy.type)
43
+ value = positional ? args[param_proxy.position] : kwargs[param_proxy.name]
41
44
 
42
45
  next unless value.nil?
43
46
  raise param_proxy.error_type, param_proxy.error_message(value:) if param_proxy.expression.required?
44
47
 
45
48
  value = param_proxy.expression.default_value # Default value can still be `nil`.
46
49
  value = value.value if value.is_a?(ValueExpression)
47
- param_proxy.position ? args[param_proxy.position] = value : kwargs[param_proxy.name] = value
50
+ positional ? args[param_proxy.position] = value : kwargs[param_proxy.name] = value
48
51
  end
49
52
 
50
53
  [args, kwargs]
@@ -82,15 +85,13 @@ module Low
82
85
  end
83
86
  end
84
87
 
85
- def untyped_methods(method_proxies:, class_proxy:)
88
+ def shimmed_methods(method_proxies:, class_proxy:)
86
89
  Module.new do
87
90
  method_proxies.values.filter(&:expressions?).each do |method_proxy|
88
- # You are now in the binding of the includer class.
91
+ # You are now in the binding of both LowType and the includer class.
89
92
  define_method(method_proxy.name) do |*args, **kwargs|
90
- # NOTE: Type checking is currently disabled. See 'config.type_checking'.
91
- method_proxy = Lowkey[class_proxy.file_path][class_proxy.namespace][__method__]
92
-
93
- args, kwargs = Low::Redefiner.untyped_args(args:, kwargs:, method_proxy:)
93
+ # NOTE: Type checking is currently disabled via shim. See 'config.type_checking'.
94
+ args, kwargs = Low::Redefiner.untyped_shimmed_args(args:, kwargs:, method_proxy:)
94
95
  super(*args, **kwargs)
95
96
  end
96
97
 
@@ -98,6 +99,20 @@ module Low
98
99
  end
99
100
  end
100
101
  end
102
+
103
+ def strip_types(method_proxies:, class_proxy:, klass:)
104
+ method_proxies.values.filter(&:expressions?).each do |method_proxy|
105
+ method_proxy.rewrite_signature
106
+
107
+ klass.class_eval(method_proxy.export, method_proxy.file_path, method_proxy.start_line)
108
+
109
+ if class_proxy.private_start_line && method_proxy.start_line > class_proxy.private_start_line
110
+ klass.send(:private, method_proxy.name)
111
+ end
112
+ end
113
+
114
+ nil
115
+ end
101
116
  end
102
117
  end
103
118
  end
@@ -18,7 +18,7 @@ module Low
18
18
  attr_reader :types, :default_value
19
19
 
20
20
  # @param type - A literal type or an instance representation of a typed structure.
21
- def initialize(type: nil, default_value: :LOW_TYPE_UNDEFINED)
21
+ def initialize(type: nil, default_value: :LOWTYPE_UNDEFINED)
22
22
  @types = []
23
23
  @types << type unless type.nil?
24
24
  @default_value = default_value
@@ -27,9 +27,10 @@ module Low
27
27
  end
28
28
 
29
29
  def required?
30
- @default_value == :LOW_TYPE_UNDEFINED
30
+ @default_value == :LOWTYPE_UNDEFINED
31
31
  end
32
32
 
33
+ # TODO: Might need to accept error class here so that type accessors can be disabled and supply ArgumentError.
33
34
  def validate!(value:, proxy:) # rubocop:disable Metrics
34
35
  if value.nil?
35
36
  return true if @default_value.nil?
data/lib/lowtype.rb CHANGED
@@ -52,8 +52,11 @@ module LowType
52
52
 
53
53
  Low::Evaluator.evaluate(method_proxies: class_proxy.keyed_methods, class_binding: class_proxy.class_binding)
54
54
 
55
- klass.prepend Low::Redefiner.redefine(method_proxies: class_proxy.instance_methods, class_proxy:)
56
- klass.singleton_class.prepend Low::Redefiner.redefine(method_proxies: class_proxy.class_methods, class_proxy:)
55
+ result = Low::Redefiner.redefine(method_proxies: class_proxy.instance_methods, class_proxy:, klass:)
56
+ klass.prepend result if result.is_a?(Module)
57
+
58
+ singleton_result = Low::Redefiner.redefine(method_proxies: class_proxy.class_methods, class_proxy:, klass: klass.singleton_class)
59
+ klass.singleton_class.prepend singleton_result if singleton_result.is_a?(Module)
57
60
 
58
61
  Low::Adapter::Loader.load(klass:, class_proxy:)
59
62
 
@@ -65,6 +68,7 @@ module LowType
65
68
 
66
69
  Config = Struct.new(
67
70
  :type_checking,
71
+ :disable_mode,
68
72
  :error_mode,
69
73
  :output_mode,
70
74
  :output_size,
@@ -74,7 +78,7 @@ module LowType
74
78
 
75
79
  class << self
76
80
  def config
77
- @config ||= Config.new(true, :error, :type, 100, true, true)
81
+ @config ||= Config.new(true, :shim, :error, :type, 100, true, true)
78
82
  end
79
83
 
80
84
  def configure
@@ -9,10 +9,14 @@ module ::Lowkey
9
9
  class ParamProxy
10
10
  include ::Low::ErrorHandling
11
11
 
12
+ # Error type should be an ArgumentError when type checking disabled via shim methods.
12
13
  def error_type
13
- ::Low::ArgumentTypeError
14
+ return ::Low::ArgumentTypeError if LowType.config.type_checking
15
+
16
+ ArgumentError
14
17
  end
15
18
 
19
+ # When shimmed the error message will be from LowType, when stripped standard Ruby.
16
20
  def error_message(value:)
17
21
  "Invalid argument type '#{output(value:)}' for parameter '#{@name}'. Valid types: '#{@expression.valid_types}'"
18
22
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Low
4
- class ArgumentTypeError < TypeError; end
4
+ class ArgumentTypeError < ArgumentError; end
5
5
  class LocalTypeError < TypeError; end
6
6
  class ReturnTypeError < TypeError; end
7
7
  class AllowedTypeError < TypeError; end
data/lib/version.rb CHANGED
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Low
4
4
  module Type
5
- VERSION = '1.3.2'
5
+ VERSION = '1.4.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lowtype
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - maedi