运行srb rbi hidden-definitions会产生不清楚的错误

问题描述

上下文

  • 我们的团队最近将Rails从5.2升级到了Rails 6。 AFAIK,到目前为止,一切都进行得很好。
  • 我们的文件结构有点非常规,因此我们选择使用:classic rails loader来代替:zeitwerk

问题

每当我们运行srb rbi hidden-deFinitions时,我们都会得到以下信息:

Got LoadError when trying to get nested name Tilt::PandocTemplate
Got LoadError when trying to get nested name Tilt::asciidoctorTemplate
Got LoadError when trying to get nested name Tilt::CreoleTemplate
Got LoadError when trying to get nested name Tilt::Lesstemplate
Got LoadError when trying to get nested name Tilt::LiquidTemplate
Got LoadError when trying to get nested name Tilt::LiveScriptTemplate
Got LoadError when trying to get nested name Tilt::MarkabyTemplate
Got LoadError when trying to get nested name Tilt::PrawnTemplate
Got LoadError when trying to get nested name Tilt::Radiustemplate
Got LoadError when trying to get nested name Tilt::RedClothTemplate
Got LoadError when trying to get nested name Tilt::RstPandocTemplate
Got LoadError when trying to get nested name Tilt::TypeScriptTemplate
Got LoadError when trying to get nested name Tilt::WikiClothTemplate
Got LoadError when trying to get nested name Tilt::YajlTemplate
Naming WebConsoleGot NameError when trying to get nested name WebConsole::SourceLocation_
Generating /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi with 20603 modules and 305 aliases
Printing your code's symbol table into /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/from-source.json
Printing /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi's symbol table into /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.json
Traceback (most recent call last):
        5: from /usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/bin/srb-rbi:237:in `<main>'
        4: from /usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/bin/srb-rbi:224:in `main'
        3: from /usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/bin/srb-rbi:232:in `block in make_step'
        2: from /usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/lib/hidden-deFinition-finder.rb:38:in `main'
        1: from /usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/lib/hidden-deFinition-finder.rb:47:in `main'
/usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/lib/hidden-deFinition-finder.rb:151:in `write_constants': /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi had unexpected errors. Check this file for a clue: /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.json.err (RuntimeError)

reflection.json.err(错误指向的地方)到处都是无数的错误,它们看起来都像这样:

/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707623: dynamic constant assignment https://srb.help/2001
      707623 |  REFERENCE = ::T.let(nil,::T.untyped)
                ^^^^^^^^^

/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707624: dynamic constant assignment https://srb.help/2001
      707624 |  SETUTITSBUS = ::T.let(nil,::T.untyped)
                ^^^^^^^^^^^

/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707625: dynamic constant assignment https://srb.help/2001
      707625 |  SLAICEPS = ::T.let(nil,::T.untyped)
                ^^^^^^^^

/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707626: dynamic constant assignment https://srb.help/2001
      707626 |  SPECIALS = ::T.let(nil,::T.untyped)
                ^^^^^^^^

/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707627: dynamic constant assignment https://srb.help/2001
      707627 |  SUBSTITUTES = ::T.let(nil,::T.untyped)
                ^^^^^^^^^^^

/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707628: dynamic constant assignment https://srb.help/2001
      707628 |  VALID_CHAR = ::T.let(nil,::T.untyped)
                ^^^^^^^^^^

/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707629: dynamic constant assignment https://srb.help/2001
      707629 |  VALID_XML_CHARS = ::T.let(nil,::T.untyped)
                ^^^^^^^^^^^^^^^

/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707618: class deFinition in method body https://srb.help/2001
      707618 |class REXML::Text < REXML::Child
              ^^^^^

/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707801: class deFinition in method body https://srb.help/2001
      707801 |class REXML::UndefinednamespaceException < REXML::ParseException
              ^^^^^

/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707813: module deFinition in method body https://srb.help/2001
      707813 |module REXML::Validation
              ^^^^^^

/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707817: class deFinition in method body https://srb.help/2001
      707817 |class REXML::Validation::ValidationException < RuntimeError
              ^^^^^

/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707829: dynamic constant assignment https://srb.help/2001
      707829 |  DEFAULT_ENCODING = ::T.let(nil,::T.untyped)
                ^^^^^^^^^^^^^^^^

/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707830: dynamic constant assignment https://srb.help/2001
      707830 |  DEFAULT_STANDALONE = ::T.let(nil,::T.untyped)
                ^^^^^^^^^^^^^^^^^^

/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707831: dynamic constant assignment https://srb.help/2001
      707831 |  DEFAULT_VERSION = ::T.let(nil,::T.untyped)
                ^^^^^^^^^^^^^^^

问题

关于前进的任何建议?直觉是我们需要迁移到:zeitwerk解决此问题,但这对我们来说是一个很大的重构,因此我在不确认这是导致此失败的潜在原因的情况下犹豫不决。

解决方法

编辑:此修补程序的一个变体具有now been upstreamed into Sorbet,将在> = 0.5.5911的版本中可用。对于使用这些版本的任何人,此答案不再相关。


我怀疑您看到的错误是由任何Rails配置引起的。您从reflection.json.err发布的行也没有显示任何实际错误。

看来您使用的是Ruby 2.7,所以我怀疑您看到的错误是由于在2.7中通过def foo(...)方法定义进行参数转发的原因。在运行时,它们在Ruby中变成了def foo(**,&&),当Sorbet尝试生成参数名称时,它失败了,因为*&是无效的参数名称。

您可以尝试使用下面包含的差异来修补sorbet gem中的相关方法:

diff --git a/lib/serialize.rb b/lib/serialize.rb
index aec19ccb2..301793856 100644
--- a/lib/serialize.rb
+++ b/lib/serialize.rb
@@ -337,6 +337,14 @@ class Sorbet::Private::Serialize
           uniq += 1
         end
       end
+
+      # Sanitize parameter names that are not valid
+      name = name.to_s.gsub(/[^a-zA-Z0-9_]/) do
+        result = '_' + (uniq == 0 ? '' : uniq.to_s)
+        uniq += 1
+        result
+      end
+
       [kind,name]
     end
   end

您可以使用bundle open sorbet在编辑器中打开作为sorbet的一部分安装的Gemfile gem,应用上面的diff并重新运行隐藏的定义生成器。如果可以解决您的问题,我很乐意将其上游PR以便在下一个冰糕释放中使用。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...