low_type 0.6.0 → 0.7.1
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/errors.rb +3 -0
- data/lib/interfaces/proxy_interface.rb +11 -0
- data/lib/proxies/local_proxy.rb +21 -0
- data/lib/proxies/method_proxy.rb +11 -0
- data/lib/proxies/param_proxy.rb +23 -0
- data/lib/proxies/return_proxy.rb +21 -0
- data/lib/redefiner.rb +11 -12
- data/lib/type_assignment.rb +9 -4
- data/lib/type_expression.rb +12 -3
- data/lib/version.rb +1 -1
- metadata +7 -3
- data/lib/method_proxy.rb +0 -11
- data/lib/param_proxy.rb +0 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: af6b3684e92cdf1cd8276d6c06b93d7a83667fdc8ebe32590c26a992d64cfb89
|
|
4
|
+
data.tar.gz: fb341f9d4ec022a3e2aeda982a30646b44d1a2389ed5d0e473cf8d3c4846fa2b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 57df3e2a9db8a10f2008c7e7d14ff66cf24562bd80266676ad56c176277eafb76982401db097c3ce98f759fe318d5052095a55366742915c76967449ec22abfc
|
|
7
|
+
data.tar.gz: cccd7db020ccabd34684347b4e67182ac40b0425acdc23e31a99bd78369c575f2b80a8deabe6ba0c67ae900f2c775e2fe020b0097ce9147aad47aa04d5c3e858
|
data/lib/errors.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require_relative '../interfaces/proxy_interface'
|
|
2
|
+
require_relative '../errors'
|
|
3
|
+
|
|
4
|
+
module LowType
|
|
5
|
+
class LocalProxy < ProxyInterface
|
|
6
|
+
attr_reader :type_expression, :name
|
|
7
|
+
|
|
8
|
+
def initialize(type_expression:, name:)
|
|
9
|
+
@type_expression = type_expression
|
|
10
|
+
@name = name
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def error_type
|
|
14
|
+
LocalTypeError
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def error_message(value:, line:)
|
|
18
|
+
"Invalid variable type #{value.class} in '#{@name.class}' on line #{line}. Valid types: '#{@type_expression.valid_types}'"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require_relative '../interfaces/proxy_interface'
|
|
2
|
+
require_relative '../errors'
|
|
3
|
+
|
|
4
|
+
module LowType
|
|
5
|
+
class ParamProxy < ProxyInterface
|
|
6
|
+
attr_reader :type_expression, :name, :type, :position
|
|
7
|
+
|
|
8
|
+
def initialize(type_expression:, name:, type:, position: nil)
|
|
9
|
+
@type_expression = type_expression
|
|
10
|
+
@name = name
|
|
11
|
+
@type = type
|
|
12
|
+
@position = position
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def error_type
|
|
16
|
+
ArgumentTypeError
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def error_message(value:, line: nil)
|
|
20
|
+
"Invalid argument type '#{value.class}' for parameter '#{@name}'. Valid types: '#{@type_expression.valid_types}'"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require_relative '../interfaces/proxy_interface'
|
|
2
|
+
require_relative '../errors'
|
|
3
|
+
|
|
4
|
+
module LowType
|
|
5
|
+
class ReturnProxy < ProxyInterface
|
|
6
|
+
attr_reader :type_expression, :name
|
|
7
|
+
|
|
8
|
+
def initialize(type_expression:, name:)
|
|
9
|
+
@type_expression = type_expression
|
|
10
|
+
@name = name
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def error_type
|
|
14
|
+
ReturnTypeError
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def error_message(value:, line: nil)
|
|
18
|
+
"Invalid return type '#{value.class}' for method '#{@name}'. Valid types: '#{@type_expression.valid_types}'"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/lib/redefiner.rb
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
require_relative 'method_proxy'
|
|
2
|
-
require_relative 'param_proxy'
|
|
1
|
+
require_relative 'proxies/method_proxy'
|
|
2
|
+
require_relative 'proxies/param_proxy'
|
|
3
|
+
require_relative 'proxies/return_proxy'
|
|
3
4
|
require_relative 'parser'
|
|
4
5
|
require_relative 'type_expression'
|
|
5
6
|
|
|
6
7
|
module LowType
|
|
7
|
-
class ReturnError < StandardError; end
|
|
8
|
-
|
|
9
8
|
class Redefiner
|
|
10
9
|
class << self
|
|
11
10
|
def redefine_methods(method_nodes:, private_start_line:, klass:)
|
|
@@ -13,9 +12,9 @@ module LowType
|
|
|
13
12
|
method_nodes.each do |method_node|
|
|
14
13
|
name = method_node.name
|
|
15
14
|
params = Redefiner.params_with_type_expressions(method_node:)
|
|
16
|
-
|
|
15
|
+
return_proxy = Redefiner.return_proxy(method_node:)
|
|
17
16
|
|
|
18
|
-
klass.low_methods[name] = MethodProxy.new(name:, params:,
|
|
17
|
+
klass.low_methods[name] = MethodProxy.new(name:, params:, return_proxy:)
|
|
19
18
|
|
|
20
19
|
define_method(name) do |*args, **kwargs|
|
|
21
20
|
klass.low_methods[name].params.each do |param_proxy|
|
|
@@ -23,16 +22,16 @@ module LowType
|
|
|
23
22
|
value = param_proxy.position ? args[param_proxy.position] : kwargs[param_proxy.name]
|
|
24
23
|
value = param_proxy.type_expression.default_value if value.nil? && param_proxy.type_expression.default_value != :LOW_TYPE_UNDEFINED
|
|
25
24
|
# Validate argument type.
|
|
26
|
-
param_proxy.type_expression.validate!(value:,
|
|
25
|
+
param_proxy.type_expression.validate!(value:, proxy: param_proxy)
|
|
27
26
|
# Handle value(type) special case.
|
|
28
27
|
value = value.value if value.is_a?(ValueExpression)
|
|
29
28
|
# Redefine argument value.
|
|
30
29
|
param_proxy.position ? args[param_proxy.position] = value : kwargs[param_proxy.name] = value
|
|
31
30
|
end
|
|
32
31
|
|
|
33
|
-
if
|
|
32
|
+
if return_proxy
|
|
34
33
|
return_value = super(*args, **kwargs)
|
|
35
|
-
|
|
34
|
+
return_proxy.type_expression.validate!(value: return_value, proxy: klass.low_methods[name].return_proxy)
|
|
36
35
|
return return_value
|
|
37
36
|
end
|
|
38
37
|
|
|
@@ -84,14 +83,14 @@ module LowType
|
|
|
84
83
|
raise ArgumentError, "Incorrect param syntax: #{e.message}"
|
|
85
84
|
end
|
|
86
85
|
|
|
87
|
-
def
|
|
86
|
+
def return_proxy(method_node:)
|
|
88
87
|
return_node = Parser.return_node(method_node:)
|
|
89
88
|
return nil if return_node.nil?
|
|
90
89
|
|
|
91
90
|
expression = eval(return_node.slice).call
|
|
91
|
+
expression = TypeExpression.new(type: expression) unless expression.is_a?(TypeExpression)
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
TypeExpression.new(type: expression)
|
|
93
|
+
ReturnProxy.new(type_expression: expression, name: method_node.name)
|
|
95
94
|
end
|
|
96
95
|
|
|
97
96
|
private
|
data/lib/type_assignment.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require_relative 'proxies/local_proxy'
|
|
1
2
|
require_relative 'type_expression'
|
|
2
3
|
require_relative 'value_expression'
|
|
3
4
|
|
|
@@ -11,13 +12,17 @@ module TypeAssignment
|
|
|
11
12
|
raise AssignmentError, "Single-instance objects like #{object} are not supported"
|
|
12
13
|
end
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
local_proxy = LowType::LocalProxy.new(type_expression:, name: self)
|
|
16
|
+
object.instance_variable_set('@local_proxy', local_proxy)
|
|
17
|
+
|
|
18
|
+
type_expression.validate!(value: object, proxy: local_proxy, line: caller_locations(1, 1).first.lineno)
|
|
15
19
|
|
|
16
20
|
def object.with_type=(value)
|
|
17
|
-
|
|
18
|
-
type_expression
|
|
21
|
+
local_proxy = self.instance_variable_get('@local_proxy')
|
|
22
|
+
type_expression = local_proxy.type_expression
|
|
23
|
+
type_expression.validate!(value:, proxy: local_proxy, line: caller_locations(1, 1).first.lineno)
|
|
19
24
|
|
|
20
|
-
# We can't
|
|
25
|
+
# We can't reassign self in Ruby so we reassign instance variables instead.
|
|
21
26
|
value.instance_variables.each do |variable|
|
|
22
27
|
self.instance_variable_set(variable, value.instance_variable_get(variable))
|
|
23
28
|
end
|
data/lib/type_expression.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require_relative 'proxies/param_proxy'
|
|
2
|
+
|
|
1
3
|
module LowType
|
|
2
4
|
class TypeExpression
|
|
3
5
|
attr_reader :types, :default_value
|
|
@@ -25,10 +27,10 @@ module LowType
|
|
|
25
27
|
@default_value == :LOW_TYPE_UNDEFINED
|
|
26
28
|
end
|
|
27
29
|
|
|
28
|
-
def validate!(value:,
|
|
30
|
+
def validate!(value:, proxy:, line: nil)
|
|
29
31
|
if value.nil?
|
|
30
32
|
return true if @default_value.nil?
|
|
31
|
-
raise error_type,
|
|
33
|
+
raise proxy.error_type, proxy.error_message(value:, line:) if required?
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
@types.each do |type|
|
|
@@ -40,7 +42,14 @@ module LowType
|
|
|
40
42
|
end
|
|
41
43
|
end
|
|
42
44
|
|
|
43
|
-
raise
|
|
45
|
+
raise proxy.error_type, proxy.error_message(value:, line:)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def valid_types
|
|
49
|
+
types = @types.map { |type| type.inspect.to_s }
|
|
50
|
+
types = types + ['nil'] if @default_value.nil?
|
|
51
|
+
|
|
52
|
+
types.join(' | ')
|
|
44
53
|
end
|
|
45
54
|
end
|
|
46
55
|
end
|
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.7.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- maedi
|
|
@@ -17,10 +17,14 @@ executables: []
|
|
|
17
17
|
extensions: []
|
|
18
18
|
extra_rdoc_files: []
|
|
19
19
|
files:
|
|
20
|
+
- lib/errors.rb
|
|
21
|
+
- lib/interfaces/proxy_interface.rb
|
|
20
22
|
- lib/low_type.rb
|
|
21
|
-
- lib/method_proxy.rb
|
|
22
|
-
- lib/param_proxy.rb
|
|
23
23
|
- lib/parser.rb
|
|
24
|
+
- lib/proxies/local_proxy.rb
|
|
25
|
+
- lib/proxies/method_proxy.rb
|
|
26
|
+
- lib/proxies/param_proxy.rb
|
|
27
|
+
- lib/proxies/return_proxy.rb
|
|
24
28
|
- lib/redefiner.rb
|
|
25
29
|
- lib/type_assignment.rb
|
|
26
30
|
- lib/type_expression.rb
|
data/lib/method_proxy.rb
DELETED
data/lib/param_proxy.rb
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
module LowType
|
|
2
|
-
class ParamProxy
|
|
3
|
-
attr_reader :type_expression, :name, :type, :position
|
|
4
|
-
|
|
5
|
-
def initialize(type_expression:, name:, type:, position: nil)
|
|
6
|
-
@type_expression = type_expression
|
|
7
|
-
@name = name
|
|
8
|
-
@type = type
|
|
9
|
-
@position = position
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|