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 +4 -4
- data/lib/factories/proxy_factory.rb +22 -0
- data/lib/instance_types.rb +58 -0
- data/lib/low_type.rb +2 -0
- data/lib/redefiner.rb +3 -15
- data/lib/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a340469d2c2f4945b043ab3cd4973f14cf12f9d80336b7939bdb85b0da5b739e
|
|
4
|
+
data.tar.gz: 2e51c25e1b944dff67fb85f4582a2f3f38eca299fe58d4cc464c4b8c162a9d8a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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 =
|
|
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:)
|
|
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
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.
|
|
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
|