low_type 0.8.11 → 0.9.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: 2f0c69a8ca233198b383a056a7c78819a2dae7944b73d681846924ef8bfe9355
4
- data.tar.gz: fb04f1df5257523e0a1cb266500ff9d106c30723ee8aa46e66929ffa80198340
3
+ metadata.gz: a340469d2c2f4945b043ab3cd4973f14cf12f9d80336b7939bdb85b0da5b739e
4
+ data.tar.gz: 2e51c25e1b944dff67fb85f4582a2f3f38eca299fe58d4cc464c4b8c162a9d8a
5
5
  SHA512:
6
- metadata.gz: a8eaaeed7102693d813d82fde2da76124b050eba9afa042bfaea2e94f40923629596c4fe613fce66f8cfba3342b86499bd257e14094c40ae8e399962dec2fe74
7
- data.tar.gz: '0519fec1df0f3e1b80403e376aa41cdc2e25a6d1dbd87d85c3c76cc185340c3c937255c84136f3d467bbd63d01ce8bfbc78e0c253e817324338a7a29e12dddae'
6
+ metadata.gz: 8857cb2e301aa2e7f4ddf167fe622d3988d7d28ff223361a50a056f28ea248e4ad81ecc48fc2174f2f8845c7af7e8fad072ac9bf3ed4eea5a0bad37a06ab9b6d
7
+ data.tar.gz: c401324adf4f5aa4b4da5a1c6f19d5b3daa095e7ff28a43a9075f28f4d7a8947a13fcba500bab252eece331b51d65e89fee09efd99e1d61f5e0290faae51dab7
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../proxies/return_proxy'
4
+ require_relative '../parser'
5
+ require_relative '../type_expression'
6
+
7
+ module LowType
8
+ class ProxyFactory
9
+ class << self
10
+ def return_proxy(method_node:, file:)
11
+ return_type = Parser.return_type(method_node:)
12
+ return nil if return_type.nil?
13
+
14
+ # Not a security risk because the code comes from a trusted source; the file that did the include. Does the file trust itself?
15
+ expression = eval(return_type.slice, binding, __FILE__, __LINE__).call # rubocop:disable Security/Eval
16
+ expression = TypeExpression.new(type: expression) unless expression.is_a?(TypeExpression)
17
+
18
+ ReturnProxy.new(type_expression: expression, name: method_node.name, file:)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'proxies/return_proxy'
4
+ require_relative 'type_expression'
5
+
6
+ module LowType
7
+ module InstanceTypes
8
+ def type_reader(named_expressions)
9
+ named_expressions.each do |name, expression|
10
+ last_caller = caller_locations(1, 1).first
11
+ type_expression = type_expression(expression)
12
+ file = FileProxy.new(path: last_caller.path, line: last_caller.lineno, scope: "#{self}##{name}")
13
+
14
+ @low_methods[name] = MethodProxy.new(name:, return_proxy: ReturnProxy.new(type_expression:, name:, file:))
15
+
16
+ define_method(name) do
17
+ method_proxy = self.class.low_methods[name]
18
+ value = instance_variable_get("@#{name}")
19
+ type_expression.validate!(value:, proxy: method_proxy.return_proxy)
20
+ value
21
+ end
22
+ end
23
+ end
24
+
25
+ def type_writer(named_expressions)
26
+ named_expressions.each do |name, expression|
27
+ last_caller = caller_locations(1, 1).first
28
+ type_expression = type_expression(expression)
29
+ file = FileProxy.new(path: last_caller.path, line: last_caller.lineno, scope: "#{self}##{name}")
30
+
31
+ @low_methods["#{name}="] = MethodProxy.new(name:, params: [ParamProxy.new(type_expression:, name:, type: :hashreq, file:)])
32
+
33
+ define_method("#{name}=") do |value|
34
+ method_proxy = self.class.low_methods["#{name}="]
35
+ type_expression.validate!(value:, proxy: method_proxy.params.first)
36
+ instance_variable_set("@#{name}", value)
37
+ end
38
+ end
39
+ end
40
+
41
+ def type_accessor(named_expressions)
42
+ named_expressions.each do |name, expression|
43
+ type_reader({ name => expression })
44
+ type_writer({ name => expression })
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def type_expression(expression)
51
+ if expression.instance_of?(TypeExpression)
52
+ expression
53
+ elsif ::LowType.type?(expression)
54
+ TypeExpression.new(type: expression)
55
+ end
56
+ end
57
+ end
58
+ end
data/lib/low_type.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative 'adapters/adapter_loader'
4
4
  require_relative 'basic_types'
5
+ require_relative 'instance_types'
5
6
  require_relative 'redefiner'
6
7
  require_relative 'type_expression'
7
8
  require_relative 'value_expression'
@@ -25,6 +26,7 @@ module LowType
25
26
  parser = LowType::Parser.new(file_path:)
26
27
  private_start_line = parser.private_start_line
27
28
 
29
+ klass.extend InstanceTypes
28
30
  klass.prepend LowType::Redefiner.redefine(method_nodes: parser.instance_methods, klass:, private_start_line:, file_path:)
29
31
  klass.singleton_class.prepend LowType::Redefiner.redefine(method_nodes: parser.class_methods, klass:, private_start_line:, file_path:)
30
32
 
data/lib/redefiner.rb CHANGED
@@ -1,10 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'factories/proxy_factory'
3
4
  require_relative 'proxies/file_proxy'
4
5
  require_relative 'proxies/method_proxy'
5
6
  require_relative 'proxies/param_proxy'
6
- require_relative 'proxies/return_proxy'
7
- require_relative 'parser'
8
7
  require_relative 'type_expression'
9
8
 
10
9
  module LowType
@@ -18,7 +17,7 @@ module LowType
18
17
  line = Parser.line_number(node: method_node)
19
18
  file = FileProxy.new(path: file_path, line:, scope: "#{klass}##{method_node.name}")
20
19
  params = Redefiner.params_with_type_expressions(method_node:, file:)
21
- return_proxy = Redefiner.return_proxy(method_node:, file:)
20
+ return_proxy = ProxyFactory.return_proxy(method_node:, file:)
22
21
 
23
22
  klass.low_methods[name] = MethodProxy.new(name:, params:, return_proxy:)
24
23
 
@@ -51,7 +50,7 @@ module LowType
51
50
  end
52
51
  end
53
52
 
54
- def params_with_type_expressions(method_node:, file:) # rubocop:disable Metrics/MethodLength
53
+ def params_with_type_expressions(method_node:, file:)
55
54
  return [] if method_node.parameters.nil?
56
55
 
57
56
  params = method_node.parameters.slice
@@ -88,17 +87,6 @@ module LowType
88
87
  raise ArgumentError, "Incorrect param syntax: #{e.message}"
89
88
  end
90
89
 
91
- def return_proxy(method_node:, file:)
92
- return_type = Parser.return_type(method_node:)
93
- return nil if return_type.nil?
94
-
95
- # Not a security risk because the code comes from a trusted source; the file that did the include. Does the file trust itself?
96
- expression = eval(return_type.slice).call # rubocop:disable Security/Eval
97
- expression = TypeExpression.new(type: expression) unless expression.is_a?(TypeExpression)
98
-
99
- ReturnProxy.new(type_expression: expression, name: method_node.name, file:)
100
- end
101
-
102
90
  private
103
91
 
104
92
  def required_args(proxy_method:)
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LowType
4
- VERSION = '0.8.11'
4
+ VERSION = '0.9.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: low_type
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.11
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - maedi
@@ -21,6 +21,8 @@ files:
21
21
  - lib/adapters/sinatra_adapter.rb
22
22
  - lib/basic_types.rb
23
23
  - lib/error_types.rb
24
+ - lib/factories/proxy_factory.rb
25
+ - lib/instance_types.rb
24
26
  - lib/interfaces/adapter_interface.rb
25
27
  - lib/interfaces/error_interface.rb
26
28
  - lib/local_types.rb