@@ -8,6 +8,7 @@ import caseapp.core.{Arg, Error}
8
8
import com .github .plokhotnyuk .jsoniter_scala .core .*
9
9
import com .github .plokhotnyuk .jsoniter_scala .macros .*
10
10
11
+ import scala .build .options .ScalacOpt .noDashPrefixes
11
12
import scala .cli .commands .tags
12
13
13
14
// format: off
@@ -26,6 +27,13 @@ final case class ScalacOptions(
26
27
// format: on
27
28
28
29
object ScalacOptions {
30
+ extension (opt : String ) {
31
+ private def hasValidScalacOptionDashes : Boolean =
32
+ opt.startsWith(" -" ) && opt.length > 1 && (
33
+ if opt.length > 2 then opt.charAt(2 ) != '-'
34
+ else opt.charAt(1 ) != '-'
35
+ )
36
+ }
29
37
30
38
private val scalacOptionsArg = Arg (" scalacOption" ).copy(
31
39
extraNames = Seq (Name (" scala-opt" ), Name (" O" ), Name (" scala-option" )),
@@ -37,56 +45,54 @@ object ScalacOptions {
37
45
origin = Some (" ScalacOptions" )
38
46
)
39
47
// .withIsFlag(true) // The scalac options we handle accept no value after the -… argument
40
- val YScriptRunnerOption = " -Yscriptrunner"
41
- private val scalacOptionsPurePrefixes =
42
- Set (" -V" , " -W" , " -X" , " -Y" )
43
- private val scalacOptionsPrefixes =
44
- Set (" -P" ) ++ scalacOptionsPurePrefixes
48
+ val YScriptRunnerOption = " Yscriptrunner"
49
+ private val scalacOptionsPurePrefixes = Set (" V" , " W" , " X" , " Y" )
50
+ private val scalacOptionsPrefixes = Set (" P" ) ++ scalacOptionsPurePrefixes
45
51
private val scalacAliasedOptions = // these options don't require being passed after -O and accept an arg
46
52
Set (
47
- " - encoding" ,
48
- " - release" ,
49
- " - color" ,
50
- " - g" ,
51
- " - language" ,
52
- " - opt" ,
53
- " - target" ,
54
- " - source" ,
53
+ " encoding" ,
54
+ " release" ,
55
+ " color" ,
56
+ " g" ,
57
+ " language" ,
58
+ " opt" ,
59
+ " target" ,
60
+ " source" ,
55
61
YScriptRunnerOption
56
62
)
57
63
private val scalacNoArgAliasedOptions = // these options don't require being passed after -O and don't accept an arg
58
64
Set (
59
- " - unchecked" ,
60
- " - nowarn" ,
61
- " - feature" ,
62
- " - deprecation" ,
63
- " - rewrite" ,
64
- " - old-syntax" ,
65
- " - new-syntax" ,
66
- " - indent" ,
67
- " - no-indent"
65
+ " unchecked" ,
66
+ " nowarn" ,
67
+ " feature" ,
68
+ " deprecation" ,
69
+ " rewrite" ,
70
+ " old-syntax" ,
71
+ " new-syntax" ,
72
+ " indent" ,
73
+ " no-indent"
68
74
)
69
75
70
76
/** This includes all the scalac options which disregard inputs and print a help and/or context
71
77
* message instead.
72
78
*/
73
79
val ScalacPrintOptions : Set [String ] =
74
80
scalacOptionsPurePrefixes ++ Set (
75
- " - help" ,
76
- " - opt:help" ,
77
- " - Xshow-phases" ,
78
- " - Xsource:help" ,
79
- " - Xplugin-list" ,
80
- " - Xmixin-force-forwarders:help" ,
81
- " - Xlint:help" ,
82
- " - Vphases"
81
+ " help" ,
82
+ " opt:help" ,
83
+ " Xshow-phases" ,
84
+ " Xsource:help" ,
85
+ " Xplugin-list" ,
86
+ " Xmixin-force-forwarders:help" ,
87
+ " Xlint:help" ,
88
+ " Vphases"
83
89
)
84
90
85
91
/** This includes all the scalac options which are redirected to native Scala CLI options. */
86
- val ScalaCliRedirectedOptions = Set (
87
- " - classpath" ,
88
- " - cp" , // redirected to --extra-jars
89
- " - d" // redirected to --compilation-output
92
+ val ScalaCliRedirectedOptions : Set [ String ] = Set (
93
+ " classpath" ,
94
+ " cp" , // redirected to --extra-jars
95
+ " d" // redirected to --compilation-output
90
96
)
91
97
val ScalacDeprecatedOptions : Set [String ] = Set (
92
98
YScriptRunnerOption // old 'scala' runner specific, no longer supported
@@ -109,15 +115,20 @@ object ScalacOptions {
109
115
): Either [(Error , List [String ]), Option [(Option [List [String ]], List [String ])]] =
110
116
args match {
111
117
case h :: t
112
- if scalacOptionsPrefixes.exists(h.startsWith) &&
113
- ! ScalacDeprecatedOptions .contains(h) =>
118
+ if h.hasValidScalacOptionDashes &&
119
+ scalacOptionsPrefixes.exists(h.noDashPrefixes.startsWith) &&
120
+ ! ScalacDeprecatedOptions .contains(h.noDashPrefixes) =>
114
121
Right (Some ((Some (acc.getOrElse(Nil ) :+ h), t)))
115
- case h :: t if scalacNoArgAliasedOptions.contains(h) =>
122
+ case h :: t
123
+ if h.hasValidScalacOptionDashes &&
124
+ scalacNoArgAliasedOptions.contains(h.noDashPrefixes) =>
116
125
Right (Some ((Some (acc.getOrElse(Nil ) :+ h), t)))
117
126
case h :: t
118
- if scalacAliasedOptions.exists(o => h.startsWith(o + " :" )) &&
127
+ if h.hasValidScalacOptionDashes &&
128
+ scalacAliasedOptions.exists(o => h.noDashPrefixes.startsWith(o + " :" )) &&
119
129
h.count(_ == ':' ) == 1 => Right (Some ((Some (acc.getOrElse(Nil ) :+ h), t)))
120
- case h :: t if scalacAliasedOptions.contains(h) =>
130
+ case h :: t
131
+ if h.hasValidScalacOptionDashes && scalacAliasedOptions.contains(h.noDashPrefixes) =>
121
132
// check if the next scalac arg is a different option or a param to the current option
122
133
val maybeOptionArg = t.headOption.filter(! _.startsWith(" -" ))
123
134
// if it's a param, it'll be treated as such and considered already parsed
@@ -131,8 +142,8 @@ object ScalacOptions {
131
142
}
132
143
133
144
implicit lazy val parser : Parser [ScalacOptions ] = {
134
- val baseParser = scalacOptionsArgument :: NilParser
135
- implicit val p = ArgFileOption .parser
145
+ val baseParser = scalacOptionsArgument :: NilParser
146
+ implicit val p : Parser [ List [ ArgFileOption ]] = ArgFileOption .parser
136
147
baseParser.addAll[List [ArgFileOption ]].to[ScalacOptions ]
137
148
}
138
149
@@ -143,7 +154,7 @@ object ScalacOptions {
143
154
case class ArgFileOption (file : String ) extends AnyVal
144
155
145
156
object ArgFileOption {
146
- val arg = Arg (
157
+ val arg : Arg = Arg (
147
158
name = Name (" args-file" ),
148
159
valueDescription = Some (ValueDescription (" @arguments-file" )),
149
160
helpMessage = Some (HelpMessage (" File with scalac options." )),
0 commit comments