aye_var 0.1.0 → 0.2.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/README.md +11 -5
- data/lib/aye_var/version.rb +1 -1
- data/lib/aye_var.rb +94 -35
- metadata +15 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1738b022486bc41367e9dee76d2fc4a0792a47dccb5059ac872a479b192ab8c
|
4
|
+
data.tar.gz: 41ba0ed417967bea1af88f4c828a7bae04b586d4749e93b50ce91972ad4e55bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9626b16ccb6c22998e885816359a0c304db95adff5657c69e59cdc83d3549717928b8425f69beee37269e69b8f1152c43330153c88267b0e701faa7b378ab84b
|
7
|
+
data.tar.gz: '089409f803c9dbae0d834795c373617088eef192a1f12bbb719fec2af28cb810884f8c4c3b90275b34fd92f88b04c0152f3c1a400094a3121d5734156033d288'
|
data/README.md
CHANGED
@@ -1,14 +1,20 @@
|
|
1
|
-
|
1
|
+
# AyeVar 🏴☠️
|
2
2
|
|
3
|
-
|
3
|
+
Avast ye, this gem be fresh off th’ plunderin’ an’ experimental as a new recruit, me hearties! Th’ API be shiftin’ like th’ treacherous seas beneath yer barnacled hull.
|
4
4
|
|
5
|
-
|
5
|
+
## What does it do?
|
6
|
+
|
7
|
+
It keelhauls them scurvy undefined instance variables by transformin’ yer code as it loads into th’ hold, savvy? Davy Jones ’imself would approve!
|
8
|
+
|
9
|
+
## Setup
|
10
|
+
|
11
|
+
Add this precious booty to yer gemfile, shiver me timbers!
|
6
12
|
|
7
13
|
```ruby
|
8
14
|
gem "aye_var", require: false
|
9
15
|
```
|
10
16
|
|
11
|
-
Then
|
17
|
+
Then be requirin’ an’ initializin’ it in yer galleon as early as ye can hoist sail, ye scallywag! If ye be usin’ Bootsnap, place it right after, or by the powers, ye’ll be swimmin’ with th’ fishes!
|
12
18
|
|
13
19
|
```ruby
|
14
20
|
require "aye_var"
|
@@ -16,4 +22,4 @@ require "aye_var"
|
|
16
22
|
AyeVar.init(include: ["#{Dir.pwd}/**/*"])
|
17
23
|
```
|
18
24
|
|
19
|
-
|
25
|
+
Ye can pass an array o’ globs to `include:` an’ `exclude:`, or I’ll feed ye to th’ kraken, ye mangy bilge-suckin’ swab!
|
data/lib/aye_var/version.rb
CHANGED
data/lib/aye_var.rb
CHANGED
@@ -1,77 +1,136 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "require-hooks/setup"
|
4
|
+
require "prism"
|
4
5
|
|
5
6
|
module AyeVar
|
7
|
+
NameError = Class.new(::NameError)
|
8
|
+
|
9
|
+
def self.init(include: [], exclude: [])
|
10
|
+
RequireHooks.source_transform(patterns: include, exclude_patterns: exclude) do |path, source|
|
11
|
+
source ||= File.read(path)
|
12
|
+
Processor.call(source)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
6
16
|
class Processor < Prism::Visitor
|
7
17
|
def self.call(source)
|
8
|
-
|
9
|
-
|
18
|
+
visitor = new
|
19
|
+
visitor.visit(Prism.parse(source).value)
|
10
20
|
|
11
21
|
buffer = source.dup
|
12
22
|
|
13
|
-
|
23
|
+
visitor.annotations.sort_by(&:first).reverse_each do |offset, action, name|
|
14
24
|
case action
|
15
25
|
when :start
|
16
|
-
buffer.insert(offset, "((raise ::AyeVar::NameError.new('Undefined instance variable #{name}') unless defined?(#{name}));")
|
26
|
+
buffer.insert(offset, "((raise ::AyeVar::NameError.new('Undefined instance variable #{name}') unless defined?(#{name})); ")
|
17
27
|
when :end
|
18
28
|
buffer.insert(offset, ")")
|
29
|
+
else
|
30
|
+
raise "Invalid annotation"
|
19
31
|
end
|
20
32
|
end
|
21
33
|
|
22
34
|
buffer
|
23
35
|
end
|
24
36
|
|
25
|
-
def initialize
|
26
|
-
@
|
27
|
-
@
|
37
|
+
def initialize
|
38
|
+
@this = nil
|
39
|
+
@context = Set[]
|
40
|
+
@annotations = []
|
41
|
+
end
|
42
|
+
|
43
|
+
attr_reader :annotations
|
44
|
+
|
45
|
+
def visit_class_node(node)
|
46
|
+
new_context(node) { super }
|
47
|
+
end
|
48
|
+
|
49
|
+
def visit_module_node(node)
|
50
|
+
new_context(node) { super }
|
51
|
+
end
|
52
|
+
|
53
|
+
def visit_block_node(node)
|
54
|
+
new_context(node) { super }
|
55
|
+
end
|
56
|
+
|
57
|
+
def visit_singleton_class_node(node)
|
58
|
+
new_context(node) { super }
|
28
59
|
end
|
29
60
|
|
30
|
-
|
61
|
+
def visit_defined_node(node)
|
62
|
+
if Prism::InstanceVariableReadNode === node.value
|
63
|
+
context << node.value.name
|
64
|
+
end
|
65
|
+
|
66
|
+
super
|
67
|
+
end
|
31
68
|
|
32
69
|
def visit_def_node(node)
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
70
|
+
new_context(node) { super }
|
71
|
+
end
|
72
|
+
|
73
|
+
def visit_if_node(node)
|
74
|
+
visit(node.predicate)
|
75
|
+
|
76
|
+
branch { visit(node.statements) }
|
77
|
+
branch { visit(node.subsequent) }
|
78
|
+
end
|
79
|
+
|
80
|
+
def visit_case_node(node)
|
81
|
+
visit(node.predicate)
|
82
|
+
|
83
|
+
node.conditions.each do |condition|
|
84
|
+
branch { visit(condition) }
|
42
85
|
end
|
86
|
+
|
87
|
+
branch { visit(node.else_clause) }
|
43
88
|
end
|
44
89
|
|
45
90
|
def visit_instance_variable_read_node(node)
|
46
|
-
location = node.location
|
47
91
|
name = node.name
|
48
92
|
|
49
|
-
|
50
|
-
@ivars << [location.end_character_offset, :end, name]
|
51
|
-
super
|
52
|
-
end
|
53
|
-
|
54
|
-
def visit_instance_variable_write_node(node)
|
55
|
-
unless @initializer
|
93
|
+
unless context.include?(name)
|
56
94
|
location = node.location
|
57
|
-
name = node.name
|
58
95
|
|
59
|
-
|
60
|
-
|
96
|
+
context << name
|
97
|
+
|
98
|
+
@annotations << [location.start_character_offset, :start, name]
|
99
|
+
@annotations << [location.end_character_offset, :end, name]
|
61
100
|
end
|
62
101
|
|
63
102
|
super
|
64
103
|
end
|
65
|
-
end
|
66
104
|
|
67
|
-
|
105
|
+
private def new_context(this)
|
106
|
+
original_this = @this
|
107
|
+
original_context = @context
|
68
108
|
|
69
|
-
|
109
|
+
@this = this
|
110
|
+
@context = Set[]
|
70
111
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
112
|
+
begin
|
113
|
+
yield
|
114
|
+
ensure
|
115
|
+
@this = original_this
|
116
|
+
@context = original_context
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
private def branch
|
121
|
+
original_context = @context
|
122
|
+
@context = original_context.dup
|
123
|
+
|
124
|
+
begin
|
125
|
+
yield
|
126
|
+
ensure
|
127
|
+
@context = original_context
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# The current context on the stack
|
132
|
+
private def context
|
133
|
+
@context
|
75
134
|
end
|
76
135
|
end
|
77
136
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aye_var
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Drapper
|
@@ -23,6 +23,20 @@ dependencies:
|
|
23
23
|
- - ">="
|
24
24
|
- !ruby/object:Gem::Version
|
25
25
|
version: '0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: prism
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
26
40
|
description: Raise an exception when using undefined instance variables.
|
27
41
|
email:
|
28
42
|
- joel@drapper.me
|