tapioca 0.16.3 → 0.16.4

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: 61d9bbc2b60ce6dda54eea3d826374ca132938ddcdcc8185a731124bbad31704
4
- data.tar.gz: 35aec9d2e19694a7737ff32b7a1d1863b24e255f327d87adbc42e435bcef048c
3
+ metadata.gz: 80c01f44b0600c3a471756da73e43322f23a951c8f3ebc15c922173a0ccf4d3c
4
+ data.tar.gz: c778cfa78b0494513f5ad329e432c534486c3ba75fcf83969462a874c7dc7654
5
5
  SHA512:
6
- metadata.gz: 0d09845c43897689c8b04ca565d22a9dc817fd8100276624ffc21a83538d3584e70909df6007aee6d360abbd63ff2842132db1346483d1faf9615500e4b3c988
7
- data.tar.gz: b6ec214e91ed9b14fea2eefc00e396c4ea45157995dfdc52f98494da9498025bfa033b807324757f877768819e68ff04ff32dd0e10f93642dbb48e89dcd77451
6
+ metadata.gz: f12a7fbe0d64109a5de03d8a98f564413bee79dc0db1ced8c1eaeae8dae73e68c73e8e76a188a06ddfefa333b11024d606359b7f706d13e15dacea081b0a19ea
7
+ data.tar.gz: 99ef8194c8dab5e776b591992aefa8b59b0b8e2d8927caecfc68d63bf7bb4c7687a92af772c6f8ac5fcfbdd8ebe1f9c1b748a2334b8207d233939d35d02d2b26
@@ -69,6 +69,17 @@ module Tapioca
69
69
  T::Array[String],
70
70
  )
71
71
 
72
+ TRANSITION_CALLBACKS =
73
+ T.let(
74
+ [
75
+ "on_transition",
76
+ "guard",
77
+ "after",
78
+ "success",
79
+ ].freeze,
80
+ T::Array[String],
81
+ )
82
+
72
83
  ConstantType = type_member { { fixed: T.all(T::Class[::AASM], ::AASM::ClassMethods) } }
73
84
 
74
85
  sig { override.void }
@@ -162,8 +173,37 @@ module Tapioca
162
173
  method,
163
174
  parameters: [
164
175
  create_opt_param("symbol", type: "T.nilable(Symbol)", default: "nil"),
165
- create_block_param("block", type: "T.nilable(T.proc.bind(#{constant_name}).void)"),
176
+ create_block_param(
177
+ "block",
178
+ type: "T.nilable(T.proc.bind(#{constant_name}).params(opts: T.untyped).void)",
179
+ ),
180
+ ],
181
+ )
182
+ end
183
+
184
+ event.create_method(
185
+ "transitions",
186
+ parameters: [
187
+ create_opt_param("definitions", default: "nil", type: "T.untyped"),
188
+ create_block_param("block", type: "T.nilable(T.proc.bind(PrivateAASMTransition).void)"),
189
+ ],
190
+ )
191
+ end
192
+
193
+ machine.create_class("PrivateAASMTransition", superclass_name: "AASM::Core::Transition") do |transition|
194
+ TRANSITION_CALLBACKS.each do |method|
195
+ return_type = "T.untyped"
196
+ return_type = "T::Boolean" if method == "guard"
197
+
198
+ transition.create_method(
199
+ method,
200
+ parameters: [
201
+ create_block_param(
202
+ "block",
203
+ type: "T.nilable(T.proc.bind(#{constant_name}).params(opts: T.untyped).void)",
204
+ ),
166
205
  ],
206
+ return_type: return_type,
167
207
  )
168
208
  end
169
209
  end
@@ -107,36 +107,12 @@ module Tapioca
107
107
 
108
108
  sig { params(name: String).returns(T::Boolean) }
109
109
  def valid_method_name?(name)
110
- # try to parse a method definition with this name
111
- iseq = RubyVM::InstructionSequence.compile("def #{name}; end", nil, nil, 0, false)
112
- # pull out the first operation in the instruction sequence and its first argument
113
- op, arg, _data = iseq.to_a.dig(-1, 0)
114
- # make sure that the operation is a method definition and the method that was
115
- # defined has the expected name, for example, for `def !foo; end` we don't get
116
- # a syntax error but instead get a method defined as `"foo"`
117
- op == :definemethod && arg == name.to_sym
118
- rescue SyntaxError
119
- false
110
+ Prism.parse_success?("def self.#{name}(a); end")
120
111
  end
121
112
 
122
113
  sig { params(name: String).returns(T::Boolean) }
123
114
  def valid_parameter_name?(name)
124
- sentinel_method_name = :sentinel_method_name
125
- # try to parse a method definition with this name as the name of a
126
- # keyword parameter. If we use a positional parameter, then parameter names
127
- # like `&` (and maybe others) will be treated like `def foo(&); end` and will
128
- # thus be considered valid. Using a required keyword parameter prevents that
129
- # confusion between Ruby syntax and parameter name.
130
- iseq = RubyVM::InstructionSequence.compile("def #{sentinel_method_name}(#{name}:); end", nil, nil, 0, false)
131
- # pull out the first operation in the instruction sequence and its first argument and data
132
- op, arg, data = iseq.to_a.dig(-1, 0)
133
- # make sure that:
134
- # 1. a method was defined, and
135
- # 2. the method has the expected method name, and
136
- # 3. the method has a keyword parameter with the expected name
137
- op == :definemethod && arg == sentinel_method_name && data.dig(11, :keyword, 0) == name.to_sym
138
- rescue SyntaxError
139
- false
115
+ Prism.parse_success?("def sentinel_method_name(#{name}:); end")
140
116
  end
141
117
  end
142
118
  end
@@ -23,6 +23,7 @@ require "tempfile"
23
23
  require "thor"
24
24
  require "yaml"
25
25
  require "yard-sorbet"
26
+ require "prism"
26
27
 
27
28
  require "tapioca/runtime/dynamic_mixin_compiler"
28
29
  require "tapioca/sorbet_ext/backcompat_patches"
@@ -178,13 +178,19 @@ module Tapioca
178
178
  end
179
179
 
180
180
  # Examines the call stack to identify the closest location where a "require" is performed
181
- # by searching for the label "<top (required)>". If none is found, it returns the location
181
+ # by searching for the label "<top (required)>" or "block in <class:...>" in the
182
+ # case of an ActiveSupport.on_load hook. If none is found, it returns the location
182
183
  # labeled "<main>", which is the original call site.
183
184
  sig { params(locations: T.nilable(T::Array[Thread::Backtrace::Location])).returns(String) }
184
185
  def resolve_loc(locations)
185
186
  return "" unless locations
186
187
 
187
- resolved_loc = locations.find { |loc| REQUIRED_FROM_LABELS.include?(loc.label) }
188
+ resolved_loc = locations.find do |loc|
189
+ label = loc.label
190
+ next unless label
191
+
192
+ REQUIRED_FROM_LABELS.include?(label) || label.start_with?("block in <class:")
193
+ end
188
194
  return "" unless resolved_loc
189
195
 
190
196
  resolved_loc.absolute_path || ""
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Tapioca
5
- VERSION = "0.16.3"
5
+ VERSION = "0.16.4"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tapioca
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.3
4
+ version: 0.16.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ufuk Kayserilioglu
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2024-10-03 00:00:00.000000000 Z
14
+ date: 2024-11-07 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -284,7 +284,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
284
284
  - !ruby/object:Gem::Version
285
285
  version: '0'
286
286
  requirements: []
287
- rubygems_version: 3.5.20
287
+ rubygems_version: 3.5.23
288
288
  signing_key:
289
289
  specification_version: 4
290
290
  summary: A Ruby Interface file generator for gems, core types and the Ruby standard