low_type 1.0.5 → 1.0.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: 3961ddca967c11281e439d8909cca6fcbd651c55c58757970c75de8eabd45265
4
- data.tar.gz: 4f570cb1e811ab14d03613fadd017885e9303f2db3ca66d0abee4cef048365aa
3
+ metadata.gz: 6ef30b8ad7d079a95270a664aacb4b28255cad9dcd743451e1f78b1391549222
4
+ data.tar.gz: 4e4329460d20826d604b99d1d7e57cee581cb7c3d8e6ffe2621e7ed383967b57
5
5
  SHA512:
6
- metadata.gz: 3fe326bebb6320cc806228e380ea5d207ec715ade50f804ee9058be352534c4ada8ddae3042d2211ec6c83068e5b1152d194dcf8e1dab946bd7f40fcdf58f43f
7
- data.tar.gz: 3c1c00aaf642cfbe13eea29e35029b2710eaa609959cc117bda00a4023ad569ef21ecee495145317526a55be846ae37a11a8da5ccc0fc47de93a2a738a0bf626
6
+ metadata.gz: c08f01a89a82f293c0320034eceff0831b87a63ec52c45f0bd01ebd23ef067af2099bd8f554c45579ef285284c9afa34713556962a8a2b167d99bf5bc65ce73b
7
+ data.tar.gz: d90226573c175294ecc61258b1ed013f9b2351b4fdea32672bed0cf0786dbbea64341021710d21c0826feb152257fbaf4fc11d24cf180b9b3ac739523afef74a
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../type_expression'
4
+ require_relative '../value_expression'
5
+
6
+ module LowType
7
+ class ExpressionFactory
8
+ class << self
9
+ def type_expression_with_value(type:)
10
+ TypeExpression.new(default_value: ValueExpression.new(value: type))
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../proxies/return_proxy'
4
- require_relative '../file_parser'
4
+ require_relative '../queries/file_parser'
5
5
  require_relative '../type_expression'
6
6
 
7
7
  module LowType
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'proxies/return_proxy'
4
+ require_relative 'queries/type_query'
4
5
  require_relative 'type_expression'
5
6
 
6
7
  module LowType
@@ -50,7 +51,7 @@ module LowType
50
51
  def type_expression(expression)
51
52
  if expression.instance_of?(TypeExpression)
52
53
  expression
53
- elsif ::LowType.type?(expression)
54
+ elsif ::LowType::TypeQuery.type?(expression)
54
55
  TypeExpression.new(type: expression)
55
56
  end
56
57
  end
data/lib/local_types.rb CHANGED
@@ -1,10 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'factories/expression_factory'
3
4
  require_relative 'proxies/file_proxy'
4
5
  require_relative 'proxies/local_proxy'
5
6
  require_relative 'types/error_types'
6
- require_relative 'type_expression'
7
- require_relative 'value_expression'
8
7
 
9
8
  module LowType
10
9
  module LocalTypes
@@ -26,7 +25,7 @@ module LowType
26
25
  alias low_type type
27
26
 
28
27
  def value(type)
29
- LowType.value(type:)
28
+ ExpressionFactory.type_expression_with_value(type:)
30
29
  end
31
30
  alias low_value value
32
31
  end
data/lib/low_type.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'adapters/adapter_loader'
4
+ require_relative 'syntax/syntax'
4
5
  require_relative 'types/complex_types'
6
+ require_relative 'queries/file_parser'
7
+ require_relative 'queries/file_query'
5
8
  require_relative 'instance_types'
6
9
  require_relative 'local_types'
7
10
  require_relative 'redefiner'
8
- require_relative 'syntax/syntax'
9
- require_relative 'type_expression'
10
- require_relative 'value_expression'
11
11
 
12
12
  module LowType
13
13
  # We do as much as possible on class load rather than on instantiation to be thread-safe and efficient.
@@ -20,14 +20,14 @@ module LowType
20
20
  end
21
21
  end
22
22
 
23
- file_path = LowType.file_path
23
+ file_path = FileQuery.file_path(klass:)
24
24
  parser = FileParser.new(klass:, file_path:)
25
25
  line_numbers = parser.line_numbers
26
26
 
27
27
  klass.extend InstanceTypes
28
28
  klass.include LocalTypes
29
- klass.prepend LowType::Redefiner.redefine(method_nodes: parser.instance_methods, klass:, line_numbers:, file_path:)
30
- klass.singleton_class.prepend LowType::Redefiner.redefine(method_nodes: parser.class_methods, klass:, line_numbers:, file_path:)
29
+ klass.prepend Redefiner.redefine(method_nodes: parser.instance_methods, klass:, line_numbers:, file_path:)
30
+ klass.singleton_class.prepend Redefiner.redefine(method_nodes: parser.class_methods, klass:, line_numbers:, file_path:)
31
31
 
32
32
  if (adapter = Adapter::Loader.load(klass:, parser:, file_path:))
33
33
  adapter.process
@@ -36,8 +36,6 @@ module LowType
36
36
  end
37
37
 
38
38
  class << self
39
- # Public API.
40
-
41
39
  def config
42
40
  config = Struct.new(:deep_type_check, :severity_level, :union_type_expressions)
43
41
  @config ||= config.new(false, :error, true)
@@ -46,37 +44,5 @@ module LowType
46
44
  def configure
47
45
  yield(config)
48
46
  end
49
-
50
- # Internal API.
51
-
52
- def file_path
53
- includer_file = caller.find { |callee| callee.end_with?("include'") }
54
- includer_file.split(':').first
55
- end
56
-
57
- # TODO: Unit test.
58
- def type?(type)
59
- LowType.basic_type?(type:) || LowType.complex_type?(type:)
60
- end
61
-
62
- def basic_type?(type:)
63
- type.class == Class
64
- end
65
-
66
- def complex_type?(type:)
67
- !basic_type?(type:) && LowType.typed_hash?(type:)
68
- end
69
-
70
- def typed_hash?(type:)
71
- type.is_a?(::Hash) && LowType.basic_type?(type: type.keys.first) && LowType.basic_type?(type: type.values.first)
72
- end
73
-
74
- def value?(expression)
75
- !expression.respond_to?(:new) && expression != Integer
76
- end
77
-
78
- def value(type:)
79
- TypeExpression.new(default_value: ValueExpression.new(value: type))
80
- end
81
47
  end
82
48
  end
@@ -62,7 +62,7 @@ module LowType
62
62
 
63
63
  @instance_methods = []
64
64
  @class_methods = []
65
- @line_numbers = { class_start: 0, class_end: root_node.respond_to?(:end_line) ? root_node.end_line : 1}
65
+ @line_numbers = { class_start: 0, class_end: root_node.respond_to?(:end_line) ? root_node.end_line : nil}
66
66
  end
67
67
 
68
68
  def visit_def_node(node)
@@ -0,0 +1,21 @@
1
+ module LowType
2
+ class FileQuery
3
+ class << self
4
+ def file_path(klass:)
5
+ includer_line = line_with_class(klass:) || line_with_include || ''
6
+ includer_line.split(':').first || ''
7
+ end
8
+
9
+ private
10
+
11
+ def line_with_class(klass:)
12
+ class_name = klass.to_s.split(':').last # Also remove the module namespaces from the class.
13
+ caller.find { |callee| callee.end_with?("<class:#{class_name}>'") }
14
+ end
15
+
16
+ def line_with_include
17
+ caller.find { |callee| callee.end_with?("include'") }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ module LowType
2
+ # TODO: Unit test.
3
+ class TypeQuery
4
+ class << self
5
+ def type?(type)
6
+ basic_type?(type:) || complex_type?(type:)
7
+ end
8
+
9
+ def basic_type?(type:)
10
+ type.class == Class
11
+ end
12
+
13
+ def complex_type?(type:)
14
+ !basic_type?(type:) && typed_hash?(type:)
15
+ end
16
+
17
+ def typed_hash?(type:)
18
+ type.is_a?(::Hash) && basic_type?(type: type.keys.first) && basic_type?(type: type.values.first)
19
+ end
20
+
21
+ def value?(expression)
22
+ !expression.respond_to?(:new) && expression != Integer
23
+ end
24
+ end
25
+ end
26
+ end
data/lib/redefiner.rb CHANGED
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'factories/expression_factory'
3
4
  require_relative 'factories/proxy_factory'
4
5
  require_relative 'proxies/file_proxy'
5
6
  require_relative 'proxies/method_proxy'
6
7
  require_relative 'proxies/param_proxy'
7
8
  require_relative 'syntax/syntax'
9
+ require_relative 'queries/type_query'
8
10
  require_relative 'type_expression'
11
+ require_relative 'value_expression'
9
12
 
10
13
  module LowType
11
14
  # Redefine methods to have their arguments and return values type checked.
@@ -39,8 +42,12 @@ module LowType
39
42
 
40
43
  Module.new do
41
44
  method_nodes.each do |method_node|
42
- method_start = method_node.start_line
43
- next unless method_start > class_start && method_node.end_line <= class_end
45
+ method_start = method_node.respond_to?(:start_line) ? method_node.start_line : nil
46
+ method_end = method_node.respond_to?(:end_line) ? method_node.end_line : nil
47
+
48
+ if method_start && method_end && class_end
49
+ next unless method_start > class_start && method_end <= class_end
50
+ end
44
51
 
45
52
  name = method_node.name
46
53
 
@@ -92,7 +99,7 @@ module LowType
92
99
 
93
100
  if expression.is_a?(TypeExpression)
94
101
  param_proxies << ParamProxy.new(type_expression: expression, name:, type:, position:, file:)
95
- elsif ::LowType.type?(expression)
102
+ elsif ::LowType::TypeQuery.type?(expression)
96
103
  param_proxies << ParamProxy.new(type_expression: TypeExpression.new(type: expression), name:, type:, position:, file:)
97
104
  end
98
105
  end
@@ -135,7 +142,7 @@ module LowType
135
142
 
136
143
  # Value expressions are eval()'d in the context of this module class (the instance doesn't exist yet) so alias API.
137
144
  def value(type)
138
- LowType.value(type:)
145
+ ExpressionFactory.type_expression_with_value(type:)
139
146
  end
140
147
  end
141
148
  end
data/lib/syntax/syntax.rb CHANGED
@@ -1,17 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative '../queries/type_query'
4
+
3
5
  module LowType
4
6
  module Syntax
5
7
  refine Array.singleton_class do
6
8
  def [](*types)
7
- return LowType::TypeExpression.new(type: [*types]) if types.all? { |type| LowType.type?(type) }
9
+ return LowType::TypeExpression.new(type: [*types]) if types.all? { |type| LowType::TypeQuery.type?(type) }
8
10
  super
9
11
  end
10
12
  end
11
13
 
12
14
  refine Hash.singleton_class do
13
15
  def [](type)
14
- return LowType::TypeExpression.new(type:) if LowType.type?(type)
16
+ return LowType::TypeExpression.new(type:) if LowType::TypeQuery.type?(type)
15
17
  super
16
18
  end
17
19
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'proxies/param_proxy'
4
+ require_relative 'queries/type_query'
4
5
 
5
6
  module LowType
6
7
  root_path = File.expand_path(__dir__)
@@ -24,7 +25,7 @@ module LowType
24
25
  if expression.instance_of?(::LowType::TypeExpression)
25
26
  @types += expression.types
26
27
  @default_value = expression.default_value
27
- elsif ::LowType.value?(expression)
28
+ elsif ::LowType::TypeQuery.value?(expression)
28
29
  @default_value = expression
29
30
  else
30
31
  @types << expression
@@ -45,7 +46,7 @@ module LowType
45
46
 
46
47
  @types.each do |type|
47
48
  # Example: HTML is a subclass of String and should pass as a String.
48
- return true if LowType.basic_type?(type:) && type <= value.class
49
+ return true if LowType::TypeQuery.basic_type?(type:) && type <= value.class
49
50
  return true if type.is_a?(::Array) && value.is_a?(::Array) && array_types_match_values?(types: type, values: value)
50
51
  return true if type.is_a?(::Hash) && value.is_a?(::Hash) && hash_types_match_values?(type:, value:)
51
52
  end
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LowType
4
- VERSION = '1.0.5'
4
+ VERSION = '1.0.7'
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: 1.0.5
4
+ version: 1.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - maedi
@@ -19,8 +19,8 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - lib/adapters/adapter_loader.rb
21
21
  - lib/adapters/sinatra_adapter.rb
22
+ - lib/factories/expression_factory.rb
22
23
  - lib/factories/proxy_factory.rb
23
- - lib/file_parser.rb
24
24
  - lib/instance_types.rb
25
25
  - lib/interfaces/adapter_interface.rb
26
26
  - lib/interfaces/error_interface.rb
@@ -31,6 +31,9 @@ files:
31
31
  - lib/proxies/method_proxy.rb
32
32
  - lib/proxies/param_proxy.rb
33
33
  - lib/proxies/return_proxy.rb
34
+ - lib/queries/file_parser.rb
35
+ - lib/queries/file_query.rb
36
+ - lib/queries/type_query.rb
34
37
  - lib/redefiner.rb
35
38
  - lib/syntax/syntax.rb
36
39
  - lib/syntax/union_types.rb