ree 1.0.28 → 1.0.30

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9d6451014359adf3959bb738c0af6d7b8409731861230587d9053ff12680a6c
4
- data.tar.gz: 58d5795a1a4053195b62cc8811528f05674f8d1f292d34b59ad50a0b6ac8599a
3
+ metadata.gz: c26bd9f765b493214449328b06c723150c4d64a1a6198836ccdd3e92d6c38ed2
4
+ data.tar.gz: bec255f8119ff87b049000bb758e157d18507568d636fa4e19e6bbe363b9e4f0
5
5
  SHA512:
6
- metadata.gz: '05780d456c3cada1a08ce6c5d9775054215121eb265305ab30a2b7a8b08b08528cbefc9912ea7ad6b4f46265832d5f266432f50788fdbb4fcd923d8e0025ef1d'
7
- data.tar.gz: bade40ae6f6123b55a04d0eaecb9af2c9ece3a3e7b05a0ecde0e9c5bb06344a6616033ce3e236a6fa2c7da4ef3f3c0514b4c53fce84ea19bb58f0e763a67b06d
6
+ metadata.gz: 312e40978d8bec156f2a8bce86a84083045a8034f5436ef7f53c506806ef0044b4c29ca2a09b0233614d20f5198ac6c0babdf2484852816f0d8a3787b4e54461
7
+ data.tar.gz: b8c81dc9707038944f00ddc38ab4a3f269597630b1a05923df292244f4e12d5d9a8e2ceb3651f3f09003a9ed2a1bfd1eb31d47507a6cb6d05bb5a43ad717d2c1
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ree (1.0.28)
4
+ ree (1.0.30)
5
5
  commander (~> 4.6.0)
6
6
 
7
7
  GEM
@@ -1,21 +1,24 @@
1
1
  # frozen_string_literal = true
2
2
 
3
3
  class Ree::ImportDsl
4
+ def initialize
5
+ setup_removed_constants
6
+ end
7
+
4
8
  def execute(klass, proc)
5
- self.class.instance_exec(&proc)
6
- rescue Ree::ImportDsl::UnlinkConstError => e
7
- const_removed = remove_const(klass, e.const)
9
+ class_constant = self.class.instance_exec(&proc)
8
10
 
9
- retry if const_removed
11
+ [
12
+ extract_constants(class_constant),
13
+ get_removed_constants
14
+ ]
15
+ rescue Ree::ImportDsl::UnlinkConstError => e
16
+ retry_after = remove_or_assign_const(klass, e.const)
17
+ retry if retry_after
10
18
  rescue NoMethodError => e
11
- if e.name == :&
12
- const_removed = remove_const(klass, e.receiver)
13
-
14
- if const_removed
15
- retry
16
- else
17
- raise Ree::Error.new("'#{e.receiver}' already linked or defined in '#{klass}'", :invalid_dsl_usage)
18
- end
19
+ if e.name == :& || e.name == :as
20
+ retry_after = remove_or_assign_const(klass, e.receiver)
21
+ retry if retry_after
19
22
  else
20
23
  raise e
21
24
  end
@@ -27,9 +30,30 @@ class Ree::ImportDsl
27
30
  retry
28
31
  end
29
32
 
33
+ private def extract_constants(class_constant)
34
+ [class_constant] + class_constant.constants
35
+ end
36
+
37
+ private def setup_removed_constants
38
+ self.class.instance_variable_set(:@removed_constants, [])
39
+ end
40
+
41
+ private def get_removed_constants
42
+ self.class.instance_variable_get(:@removed_constants)
43
+ end
44
+
45
+ class RemovedConstant
46
+ attr_reader :name, :const
47
+
48
+ def initialize(name, const)
49
+ @name = name
50
+ @const = const
51
+ end
52
+ end
53
+
30
54
  class UnlinkConstError < StandardError
31
55
  attr_reader :const
32
-
56
+
33
57
  def initialize(const)
34
58
  @const = const
35
59
  end
@@ -82,25 +106,72 @@ class Ree::ImportDsl
82
106
 
83
107
  private
84
108
 
85
- def remove_const(klass, constant)
86
- const_removed = false
109
+ def remove_or_assign_const(klass, constant)
110
+ retry_after = false
87
111
 
88
112
  klass.constants.each do |const_sym|
89
113
  const = klass.const_get(const_sym)
114
+ next if const.is_a?(ClassConstant)
90
115
 
91
116
  if constant.is_a?(Class) || constant.is_a?(Module)
92
117
  if (const.is_a?(Class) || const.is_a?(Module)) && const.name == constant.name
93
118
  klass.send(:remove_const, const_sym)
94
- const_removed = true
119
+ store_removed_constant(const_sym, constant)
120
+
121
+ retry_after = true
95
122
  break
96
123
  end
97
124
  elsif const == constant
98
125
  klass.send(:remove_const, const_sym)
99
- const_removed = true
126
+ store_removed_constant(const_sym, constant)
127
+
128
+ retry_after = true
100
129
  break
101
130
  end
102
131
  end
103
132
 
104
- const_removed
133
+ return true if retry_after
134
+
135
+ const_name = if constant.is_a?(String)
136
+ constant.to_sym
137
+ elsif constant.is_a?(Class) || constant.is_a?(Module)
138
+ constant.name
139
+ else
140
+ raise ArgumentError.new("unknown constant: #{constant.inspect}")
141
+ end
142
+
143
+ if parent_constant?(klass, const_name)
144
+ klass.const_set(const_name, ClassConstant.new(const_name.to_s))
145
+ retry_after = true
146
+ end
147
+
148
+ retry_after
149
+ end
150
+
151
+ private
152
+
153
+ def store_removed_constant(name, constant)
154
+ return if constant.is_a?(ClassConstant)
155
+ get_removed_constants << RemovedConstant.new(name, constant.dup)
156
+ end
157
+
158
+ def parent_constant?(klass, const_name)
159
+ modules = klass.to_s.split("::")[0..-2]
160
+
161
+ result = modules.each_with_index.any? do |mod, index|
162
+ mod = Object.const_get(modules[0..index].join("::"))
163
+ mod.constants.include?(const_name)
164
+ end
165
+
166
+ result || acnchestor_constant?(klass, const_name)
167
+ end
168
+
169
+ def acnchestor_constant?(klass, const_name)
170
+ return false if klass.ancestors.include?(klass) && klass.ancestors.size == 1
171
+
172
+ klass.ancestors.any? do |anchestor|
173
+ next if anchestor == klass
174
+ anchestor.constants.include?(const_name) || acnchestor_constant?(anchestor, const_name)
175
+ end
105
176
  end
106
177
  end
@@ -11,14 +11,13 @@ class Ree::LinkImportBuilder
11
11
  # @param [Proc] proc
12
12
  # @return [ArrayOf[String]] List of names of imported constants
13
13
  def build(klass, package_name, object_name, proc)
14
- result = Ree::ImportDsl.new.execute(klass, proc)
14
+ const_list, removed_constants = Ree::ImportDsl.new.execute(klass, proc)
15
15
 
16
16
  @packages_facade.load_package_object(package_name, object_name)
17
17
 
18
18
  package = @packages_facade.get_package(package_name)
19
19
  object = package.get_object(object_name)
20
- const_list = [result] + result.constants
21
-
20
+
22
21
  const_list.each do |const_obj|
23
22
  if object.klass.const_defined?(const_obj.name)
24
23
  set_const(klass, object.klass.const_get(const_obj.name), const_obj)
@@ -29,6 +28,8 @@ class Ree::LinkImportBuilder
29
28
  end
30
29
  end
31
30
 
31
+ assign_removed_constants(klass, removed_constants)
32
+
32
33
  const_list.map(&:name)
33
34
  end
34
35
 
@@ -37,9 +38,8 @@ class Ree::LinkImportBuilder
37
38
  # @param [Proc] proc
38
39
  # @return [ArrayOf[String]] List of names of imported constants
39
40
  def build_for_const(klass, source_const, proc)
40
- result = Ree::ImportDsl.new.execute(klass, proc)
41
+ const_list, removed_constants = Ree::ImportDsl.new.execute(klass, proc)
41
42
  mod_const = Object.const_get(source_const.name.split("::").first)
42
- const_list = [result] + result.constants
43
43
 
44
44
  const_list.each do |const_obj|
45
45
  if source_const.const_defined?(const_obj.name)
@@ -50,14 +50,28 @@ class Ree::LinkImportBuilder
50
50
  raise Ree::Error.new("'#{const_obj.name}' is not found in '#{source_const}'")
51
51
  end
52
52
  end
53
+
54
+ assign_removed_constants(klass, removed_constants)
55
+ nil
53
56
  end
54
57
 
55
58
  private
56
59
 
60
+ def assign_removed_constants(klass, removed_constants)
61
+ removed_constants.each do |removed_const|
62
+ next if klass.const_defined?(removed_const.name)
63
+ klass.const_set(removed_const.name, removed_const.const)
64
+ end
65
+ end
66
+
57
67
  def set_const(target_klass, ref_class, const_obj)
58
68
  if const_obj.get_as
59
69
  target_klass.send(:remove_const, const_obj.get_as.name) rescue nil
60
70
  target_klass.const_set(const_obj.get_as.name, ref_class)
71
+
72
+ if target_klass.const_get(const_obj.name).is_a?(Ree::ImportDsl::ClassConstant)
73
+ target_klass.send(:remove_const, const_obj.name)
74
+ end
61
75
  else
62
76
  target_klass.send(:remove_const, const_obj.name) rescue nil
63
77
  target_klass.const_set(const_obj.name, ref_class)
data/lib/ree/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ree
4
- VERSION = "1.0.28"
4
+ VERSION = "1.0.30"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ree
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.28
4
+ version: 1.0.30
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruslan Gatiyatov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-05 00:00:00.000000000 Z
11
+ date: 2023-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: commander