@@ -13,24 +13,81 @@ module SorbetHelper
1313
1414 SPOOM_CONTEXT = Spoom ::Context . new ( "." ) #: Spoom::Context
1515
16+ # Represents the `sorbet/config` file, and provides access to its options. https://sorbet.org/docs/cli-ref
17+ # If the file doesn't exist, this object will still exist, but will return default values for all options.
18+ class SorbetConfig
19+ class << self
20+ #: (Spoom::Context spoom_context) -> SorbetConfig
21+ def parse_from ( spoom_context )
22+ config_path = File . join ( spoom_context . absolute_path , "sorbet" , "config" )
23+ content = File . exist? ( config_path ) ? File . read ( config_path ) : ""
24+ parse ( content )
25+ end
26+
27+ #: (String content) -> SorbetConfig
28+ def parse ( content )
29+ lines = content . lines . map ( &:strip ) . reject ( &:empty? )
30+
31+ options = lines . filter_map do |line |
32+ next if line . start_with? ( "#" ) # Skip comments
33+ next unless line . start_with? ( "--" )
34+
35+ key , value = line . split ( "=" , 2 )
36+ key = key #: as !nil
37+
38+ [ key , value ]
39+ end . to_h #: Hash[String, String | bool | nil]
40+
41+ new (
42+ parser : options [ "--parser" ] == "prism" ? :prism : :original ,
43+ )
44+ end
45+ end
46+
47+ #: (parser: Symbol) -> void
48+ def initialize ( parser :)
49+ @parser = parser #: Symbol
50+ end
51+
52+ #: Symbol
53+ attr_reader :parser
54+
55+ #: -> bool
56+ def parse_with_prism? = @parser == :prism
57+ end
58+
1659 FEATURE_REQUIREMENTS = {
1760 # feature_name: ::Gem::Requirement.new(">= ___"), # https://github.com/sorbet/sorbet/pull/___
61+
62+ prism_syntax_check_with_stop_after_parser : ::Gem ::Requirement . new ( "> 0.6.13073" ) , # https://github.com/sorbet/sorbet/pull/10076
1863 } . freeze #: Hash[Symbol, ::Gem::Requirement]
1964
2065 #: (*String sorbet_args) -> Spoom::ExecResult
2166 def sorbet ( *sorbet_args )
67+ if sorbet_config . parse_with_prism?
68+ sorbet_args << "--parser=prism"
69+ end
70+
2271 SPOOM_CONTEXT . srb ( sorbet_args . join ( " " ) , sorbet_bin : sorbet_path )
2372 end
2473
2574 #: (String, rbi_mode: bool) { (String stderr) -> void } -> void
2675 def sorbet_syntax_check! ( source , rbi_mode :, &on_failure )
2776 quoted_source = "\" #{ source } \" "
2877
78+ stop_after = "--stop-after=parser"
79+
80+ # This version of Sorbet doesn't report parse errors until the desugarer, so we need to modify the
81+ # stop-after argument to get far enough to get those errors (and a non-zero exit code).
82+ if sorbet_config . parse_with_prism? && !sorbet_supports? ( :prism_syntax_check_with_stop_after_parser )
83+ stop_after = "--stop-after=desugarer"
84+ end
85+
2986 result = if rbi_mode
3087 # --e-rbi cannot be used on its own, so we pass a dummy value like `-e ""`
31- sorbet ( "--no-config" , "--stop-after=parser" , "-e" , '""' , "--e-rbi" , quoted_source )
88+ sorbet ( "--no-config" , stop_after , "-e" , '""' , "--e-rbi" , quoted_source )
3289 else
33- sorbet ( "--no-config" , "--stop-after=parser" , "-e" , quoted_source )
90+ sorbet ( "--no-config" , stop_after , "-e" , quoted_source )
3491 end
3592
3693 unless result . status
@@ -41,6 +98,11 @@ def sorbet_syntax_check!(source, rbi_mode:, &on_failure)
4198 nil
4299 end
43100
101+ #: -> SorbetConfig
102+ def sorbet_config
103+ @sorbet_config ||= SorbetConfig . parse_from ( SPOOM_CONTEXT ) #: SorbetConfig?
104+ end
105+
44106 #: -> String
45107 def sorbet_path
46108 sorbet_path = ENV . fetch ( SORBET_EXE_PATH_ENV_VAR , SORBET_BIN )
0 commit comments