lowkey 0.1.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 +7 -0
- data/lib/lowkey.rb +49 -0
- data/lib/maps/parent_map.rb +31 -0
- data/lib/proxies/class_proxy.rb +36 -0
- data/lib/proxies/file_proxy.rb +35 -0
- data/lib/version.rb +5 -0
- data/lib/visitors/method_call_visitor.rb +20 -0
- data/lib/visitors/method_class_visitor.rb +14 -0
- data/lib/visitors/method_def_visitor.rb +20 -0
- data/lib/visitors/visitor.rb +30 -0
- metadata +65 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 3c9ed7172b4b3902649abd82140869b7d97bb285f12a81283548f2c38c1b15ce
|
|
4
|
+
data.tar.gz: 1d85f8da175513ebea0bc9ba487654f4b1b7275068ac5f1e1d4ae768c196849c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 2192b79de007545b2f01e66967f171fb0aa19fcf1aa3253eb79505169d802c3f8bad2e122b7e393ee2829250dc1992482b5593434d4b20d899ea641bbeeb6705
|
|
7
|
+
data.tar.gz: 0c8e064e9a70f7b6580e3f94058a77371df69cbc744a871207fc466911cd607c9fc48f34f1bedab048a250da6ad1dc4228f553c4832a52edc27bdb5c3ae5a5af
|
data/lib/lowkey.rb
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'prism'
|
|
4
|
+
|
|
5
|
+
require_relative 'visitors/visitor'
|
|
6
|
+
require_relative 'proxies/file_proxy'
|
|
7
|
+
|
|
8
|
+
module Lowkey
|
|
9
|
+
class << self
|
|
10
|
+
def keys
|
|
11
|
+
@keys ||= {}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def [](key)
|
|
15
|
+
keys[key]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def load(file_path:)
|
|
19
|
+
root_node = Prism.parse_file(file_path).value
|
|
20
|
+
file_proxy = FileProxy.new(path: file_path, root_node:)
|
|
21
|
+
|
|
22
|
+
parent_map = ParentMap.new(root_node:)
|
|
23
|
+
visitor = Visitor.new(file_proxy:, parent_map:)
|
|
24
|
+
root_node.accept(visitor)
|
|
25
|
+
|
|
26
|
+
map_file_path(file_proxy:)
|
|
27
|
+
map_definitions(file_proxy:)
|
|
28
|
+
|
|
29
|
+
file_proxy
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def clear
|
|
33
|
+
keys.clear
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def map_file_path(file_proxy:)
|
|
39
|
+
keys[file_proxy.path] = file_proxy
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def map_definitions(file_proxy:)
|
|
43
|
+
file_proxy.definitions.each_key do |namespace|
|
|
44
|
+
keys[namespace] ||= []
|
|
45
|
+
keys[namespace] << file_proxy
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lowkey
|
|
4
|
+
class ParentMap
|
|
5
|
+
def initialize(root_node:)
|
|
6
|
+
@parent_map = {}
|
|
7
|
+
@current_parent = nil
|
|
8
|
+
|
|
9
|
+
map(root_node)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def [](node)
|
|
13
|
+
@parent_map[node]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def map(node)
|
|
19
|
+
@parent_map[node] = @current_parent
|
|
20
|
+
|
|
21
|
+
old_parent = @current_parent
|
|
22
|
+
@current_parent = node
|
|
23
|
+
|
|
24
|
+
node.compact_child_nodes.each do |n|
|
|
25
|
+
map(n)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
@current_parent = old_parent
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
|
|
5
|
+
module Lowkey
|
|
6
|
+
class ClassProxy
|
|
7
|
+
attr_reader :namespace, :file_proxy, :start_line, :end_line
|
|
8
|
+
attr_accessor :private_start_line, :class_methods, :instance_methods, :method_calls
|
|
9
|
+
|
|
10
|
+
def initialize(node:, namespace:, file_proxy:)
|
|
11
|
+
@namespace = namespace
|
|
12
|
+
@file_proxy = file_proxy
|
|
13
|
+
|
|
14
|
+
@start_line = node.class_keyword_loc.start_line
|
|
15
|
+
@end_line = node.end_keyword_loc.end_line # class_keyword_loc ?
|
|
16
|
+
@private_start_line = nil
|
|
17
|
+
|
|
18
|
+
@class_methods = {}
|
|
19
|
+
@instance_methods = {}
|
|
20
|
+
@method_calls = []
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def class_method?(node)
|
|
26
|
+
return true if node.is_a?(::Prism::DefNode) && node.receiver.instance_of?(Prism::SelfNode) # self.method_name
|
|
27
|
+
return true if node.is_a?(::Prism::SingletonClassNode) # class << self
|
|
28
|
+
|
|
29
|
+
if (parent_node = parent_map.parent(node:))
|
|
30
|
+
return class_method?(parent_node)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
false
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../maps/parent_map'
|
|
4
|
+
require_relative '../proxies/class_proxy'
|
|
5
|
+
|
|
6
|
+
module Lowkey
|
|
7
|
+
class FileProxy
|
|
8
|
+
attr_reader :path, :start_line, :end_line
|
|
9
|
+
attr_accessor :definitions, :dependencies
|
|
10
|
+
|
|
11
|
+
def initialize(path:, root_node:)
|
|
12
|
+
@path = path
|
|
13
|
+
@start_line = 0
|
|
14
|
+
@end_line = root_node.respond_to?(:end_line) ? root_node.end_line : nil
|
|
15
|
+
|
|
16
|
+
@definitions = {}
|
|
17
|
+
@dependencies = []
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def class_proxy(node:, parent_map:)
|
|
21
|
+
namespace = namespace(node:, parent_map:).reverse.join('::')
|
|
22
|
+
@definitions[namespace] ||= ClassProxy.new(node:, namespace:, file_proxy: self)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def namespace(node:, parent_map:, namespace: [])
|
|
28
|
+
return namespace if parent_map[node].nil?
|
|
29
|
+
|
|
30
|
+
namespace << node.constant_path.name.to_s if node.respond_to?(:constant_path)
|
|
31
|
+
|
|
32
|
+
namespace(node: parent_map[node], parent_map:, namespace:)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/lib/version.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class MethodCallVisitor
|
|
4
|
+
attr_reader :parent_map
|
|
5
|
+
|
|
6
|
+
def initialize(file_proxy:, parent_map:)
|
|
7
|
+
@file_proxy = file_proxy
|
|
8
|
+
@parent_map = parent_map
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def visit(node)
|
|
12
|
+
class_proxy = @file_proxy.class_proxy(node:, parent_map:)
|
|
13
|
+
class_proxy.method_calls << node
|
|
14
|
+
|
|
15
|
+
return unless node.name == :private && node.respond_to?(:start_line) && class_proxy.start_line && class_proxy.end_line
|
|
16
|
+
return unless node.start_line > class_proxy.start_line && node.start_line < class_proxy.end_line
|
|
17
|
+
|
|
18
|
+
class_proxy.private_start_line = node.start_line
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class MethodClassVisitor
|
|
4
|
+
attr_reader :parent_map
|
|
5
|
+
|
|
6
|
+
def initialize(file_proxy:, parent_map:)
|
|
7
|
+
@file_proxy = file_proxy
|
|
8
|
+
@parent_map = parent_map
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def visit(node)
|
|
12
|
+
@file_proxy.class_proxy(node:, parent_map:)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class MethodDefVisitor
|
|
4
|
+
attr_reader :parent_map
|
|
5
|
+
|
|
6
|
+
def initialize(file_proxy:, parent_map:)
|
|
7
|
+
@file_proxy = file_proxy
|
|
8
|
+
@parent_map = parent_map
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def visit(node)
|
|
12
|
+
class_proxy = @file_proxy.class_proxy(node:, parent_map:)
|
|
13
|
+
|
|
14
|
+
if class_proxy.class_method?(node:, parent_map:)
|
|
15
|
+
class_proxy.class_methods[node.name] = node
|
|
16
|
+
else
|
|
17
|
+
class_proxy.instance_methods[node.name] = node
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'method_call_visitor'
|
|
4
|
+
require_relative 'method_class_visitor'
|
|
5
|
+
require_relative 'method_def_visitor'
|
|
6
|
+
|
|
7
|
+
module Lowkey
|
|
8
|
+
class Visitor < Prism::Visitor
|
|
9
|
+
def initialize(file_proxy:, parent_map:)
|
|
10
|
+
@method_call_visitor = MethodCallVisitor.new(file_proxy:, parent_map:)
|
|
11
|
+
@method_class_visitor = MethodClassVisitor.new(file_proxy:, parent_map:)
|
|
12
|
+
@method_def_visitor = MethodDefVisitor.new(file_proxy:, parent_map:)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def visit_call_node(node)
|
|
16
|
+
@method_call_visitor.visit(node)
|
|
17
|
+
super
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def visit_class_node(node)
|
|
21
|
+
@method_class_visitor.visit(node)
|
|
22
|
+
super
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def visit_def_node(node)
|
|
26
|
+
@method_def_visitor.visit(node)
|
|
27
|
+
super
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: lowkey
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- maedi
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: prism
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
26
|
+
description: PRISM is amazing but we need to use it responsibly and only load the
|
|
27
|
+
AST once, do that with Lowkey!
|
|
28
|
+
email:
|
|
29
|
+
- maediprichard@gmail.com
|
|
30
|
+
executables: []
|
|
31
|
+
extensions: []
|
|
32
|
+
extra_rdoc_files: []
|
|
33
|
+
files:
|
|
34
|
+
- lib/lowkey.rb
|
|
35
|
+
- lib/maps/parent_map.rb
|
|
36
|
+
- lib/proxies/class_proxy.rb
|
|
37
|
+
- lib/proxies/file_proxy.rb
|
|
38
|
+
- lib/version.rb
|
|
39
|
+
- lib/visitors/method_call_visitor.rb
|
|
40
|
+
- lib/visitors/method_class_visitor.rb
|
|
41
|
+
- lib/visitors/method_def_visitor.rb
|
|
42
|
+
- lib/visitors/visitor.rb
|
|
43
|
+
homepage: https://github.com/low-rb/lowkey
|
|
44
|
+
licenses: []
|
|
45
|
+
metadata:
|
|
46
|
+
homepage_uri: https://github.com/low-rb/lowkey
|
|
47
|
+
source_code_uri: https://github.com/low-rb/lowkey/src/branch/main
|
|
48
|
+
rdoc_options: []
|
|
49
|
+
require_paths:
|
|
50
|
+
- lib
|
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
52
|
+
requirements:
|
|
53
|
+
- - ">="
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: 3.3.0
|
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
requirements: []
|
|
62
|
+
rubygems_version: 3.7.2
|
|
63
|
+
specification_version: 4
|
|
64
|
+
summary: An API for accessing PRISM metadata easily and efficiently
|
|
65
|
+
test_files: []
|