low_type 1.0.1 → 1.0.2
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/file_parser.rb +26 -9
- data/lib/low_type.rb +8 -10
- data/lib/redefiner.rb +12 -5
- data/lib/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9a921b130ff71b7911409536acb53ad6ef7abebf91d789ce7ce27fde24b90e95
|
|
4
|
+
data.tar.gz: 9138f98a23846c1bb2474d2bb7b163dd0b0575e7c5911dd4b7ba05fc9deacb48
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a440d93c18f7e444293f6987b5655644856d15ebba9a32b6d01818e9546339d48d8b48f5b09023e3039271195c790ce6ec713ca2b05498202cfd45d628c12e2a
|
|
7
|
+
data.tar.gz: '039ca399f75d3ee60be9c73399dfb15cadaf62d200254cdc1c873130b595c7715917eda4fa2e926e986c66817e6de972701c5b21cdc2e68ec282da71d040b46a'
|
data/lib/file_parser.rb
CHANGED
|
@@ -4,25 +4,25 @@ require 'prism'
|
|
|
4
4
|
|
|
5
5
|
module LowType
|
|
6
6
|
class FileParser
|
|
7
|
-
attr_reader :parent_map, :instance_methods, :class_methods, :
|
|
7
|
+
attr_reader :parent_map, :instance_methods, :class_methods, :line_numbers
|
|
8
8
|
|
|
9
|
-
def initialize(file_path:)
|
|
9
|
+
def initialize(klass:, file_path:)
|
|
10
10
|
@root_node = Prism.parse_file(file_path).value
|
|
11
11
|
|
|
12
12
|
parent_mapper = ParentMapper.new
|
|
13
13
|
parent_mapper.visit(@root_node)
|
|
14
14
|
@parent_map = parent_mapper.parent_map
|
|
15
15
|
|
|
16
|
-
method_visitor = MethodDefVisitor.new(@parent_map)
|
|
16
|
+
method_visitor = MethodDefVisitor.new(root_node: @root_node, parent_map:, klass:)
|
|
17
17
|
@root_node.accept(method_visitor)
|
|
18
18
|
|
|
19
19
|
@instance_methods = method_visitor.instance_methods
|
|
20
20
|
@class_methods = method_visitor.class_methods
|
|
21
|
-
@
|
|
21
|
+
@line_numbers = method_visitor.line_numbers
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def method_calls(method_names:)
|
|
25
|
-
block_visitor = MethodCallVisitor.new(parent_map
|
|
25
|
+
block_visitor = MethodCallVisitor.new(parent_map:, method_names:)
|
|
26
26
|
@root_node.accept(block_visitor)
|
|
27
27
|
block_visitor.method_calls
|
|
28
28
|
end
|
|
@@ -54,14 +54,15 @@ module LowType
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
class MethodDefVisitor < Prism::Visitor
|
|
57
|
-
attr_reader :class_methods, :instance_methods, :
|
|
57
|
+
attr_reader :class_methods, :instance_methods, :line_numbers
|
|
58
58
|
|
|
59
|
-
def initialize(parent_map)
|
|
59
|
+
def initialize(root_node:, parent_map:, klass:)
|
|
60
60
|
@parent_map = parent_map
|
|
61
|
+
@klass = klass
|
|
61
62
|
|
|
62
63
|
@instance_methods = []
|
|
63
64
|
@class_methods = []
|
|
64
|
-
@
|
|
65
|
+
@line_numbers = { class_start: 0, class_end: root_node.end_line }
|
|
65
66
|
end
|
|
66
67
|
|
|
67
68
|
def visit_def_node(node)
|
|
@@ -75,7 +76,23 @@ module LowType
|
|
|
75
76
|
end
|
|
76
77
|
|
|
77
78
|
def visit_call_node(node)
|
|
78
|
-
|
|
79
|
+
start_line = node.name == :private && node.respond_to?(:start_line) && node.start_line || nil
|
|
80
|
+
class_start = @line_numbers[:class_start]
|
|
81
|
+
class_end = @line_numbers[:class_end]
|
|
82
|
+
|
|
83
|
+
if start_line && class_start && class_end && start_line > class_start && start_line < class_end
|
|
84
|
+
@line_numbers[:private_start] = node.start_line
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
super
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def visit_class_node(node)
|
|
91
|
+
if node.name == @klass.to_s.to_sym
|
|
92
|
+
@line_numbers = { class_start: node.class_keyword_loc.start_line, class_end: node.end_keyword_loc.end_line }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
super
|
|
79
96
|
end
|
|
80
97
|
|
|
81
98
|
private
|
data/lib/low_type.rb
CHANGED
|
@@ -18,14 +18,14 @@ module LowType
|
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
file_path = LowType.file_path
|
|
22
|
-
parser = FileParser.new(file_path:)
|
|
23
|
-
|
|
21
|
+
file_path = LowType.file_path
|
|
22
|
+
parser = FileParser.new(klass:, file_path:)
|
|
23
|
+
line_numbers = parser.line_numbers
|
|
24
24
|
|
|
25
25
|
klass.extend InstanceTypes
|
|
26
26
|
klass.include LocalTypes
|
|
27
|
-
klass.prepend LowType::Redefiner.redefine(method_nodes: parser.instance_methods, klass:,
|
|
28
|
-
klass.singleton_class.prepend LowType::Redefiner.redefine(method_nodes: parser.class_methods, klass:,
|
|
27
|
+
klass.prepend LowType::Redefiner.redefine(method_nodes: parser.instance_methods, klass:, line_numbers:, file_path:)
|
|
28
|
+
klass.singleton_class.prepend LowType::Redefiner.redefine(method_nodes: parser.class_methods, klass:, line_numbers:, file_path:)
|
|
29
29
|
|
|
30
30
|
if (adapter = Adapter::Loader.load(klass:, parser:, file_path:))
|
|
31
31
|
adapter.process
|
|
@@ -47,11 +47,9 @@ module LowType
|
|
|
47
47
|
|
|
48
48
|
# Internal API.
|
|
49
49
|
|
|
50
|
-
def file_path
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
# The first class found regardless of namespace will be the class that did the include.
|
|
54
|
-
caller.find { |callee| callee.end_with?("<class:#{class_name}>'") }.split(':').first
|
|
50
|
+
def file_path
|
|
51
|
+
includer_file = caller.find { |callee| callee.end_with?("in 'Module#include'") || callee.end_with?("in 'include'") }
|
|
52
|
+
includer_file.split(':').first
|
|
55
53
|
end
|
|
56
54
|
|
|
57
55
|
# TODO: Unit test.
|
data/lib/redefiner.rb
CHANGED
|
@@ -13,9 +13,9 @@ module LowType
|
|
|
13
13
|
using Syntax
|
|
14
14
|
|
|
15
15
|
class << self
|
|
16
|
-
def redefine(method_nodes:, klass:,
|
|
16
|
+
def redefine(method_nodes:, klass:, line_numbers:, file_path:)
|
|
17
17
|
create_proxies(method_nodes:, klass:, file_path:)
|
|
18
|
-
define_methods(method_nodes:,
|
|
18
|
+
define_methods(method_nodes:, line_numbers:)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
private
|
|
@@ -32,13 +32,20 @@ module LowType
|
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
def define_methods(method_nodes:,
|
|
35
|
+
def define_methods(method_nodes:, line_numbers:) # rubocop:disable Metrics
|
|
36
|
+
class_start = line_numbers[:class_start]
|
|
37
|
+
class_end = line_numbers[:class_end]
|
|
38
|
+
private_start = line_numbers[:private_start]
|
|
39
|
+
|
|
36
40
|
Module.new do
|
|
37
41
|
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
|
|
44
|
+
|
|
38
45
|
name = method_node.name
|
|
39
46
|
|
|
40
47
|
define_method(name) do |*args, **kwargs|
|
|
41
|
-
method_proxy = instance_of?(Class) ? low_methods[name] : self.class.low_methods[name]
|
|
48
|
+
method_proxy = instance_of?(Class) ? low_methods[name] : self.class.low_methods[name] || Object.low_methods[name]
|
|
42
49
|
|
|
43
50
|
method_proxy.params.each do |param_proxy|
|
|
44
51
|
# Get argument value or default value.
|
|
@@ -61,7 +68,7 @@ module LowType
|
|
|
61
68
|
super(*args, **kwargs)
|
|
62
69
|
end
|
|
63
70
|
|
|
64
|
-
private name if
|
|
71
|
+
private name if private_start && method_start > private_start
|
|
65
72
|
end
|
|
66
73
|
end
|
|
67
74
|
end
|
data/lib/version.rb
CHANGED