1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
package dotty.tools.dotc
package config
import java.io.File
import Settings._
import core.Contexts._
import util.DotClass
import Properties._
object CompilerCommand extends DotClass {
/** The name of the command */
def cmdName = "scalac"
private def explainAdvanced = "\n" + """
|-- Notes on option parsing --
|Boolean settings are always false unless set.
|Where multiple values are accepted, they should be comma-separated.
| example: -Xplugin:plugin1,plugin2
|<phases> means one or a comma-separated list of:
| - (partial) phase names with an optional "+" suffix to include the next phase
| - the string "all"
| example: -Xprint:all prints all phases.
| example: -Xprint:front,mixin prints the frontend and mixin phases.
| example: -Ylog:erasure+ logs the erasure phase and the phase after the erasure phase.
| This is useful because during the tree transform of phase X, we often
| already are in phase X + 1.
""".stripMargin.trim + "\n"
def shortUsage = s"Usage: $cmdName <options> <source files>"
def versionMsg = s"Dotty compiler $versionString -- $copyrightString"
/** Distill arguments into summary detailing settings, errors and files to compiler */
def distill(args: Array[String])(implicit ctx: Context): ArgsSummary = {
/**
* Expands all arguments starting with @ to the contents of the
* file named like each argument.
*/
def expandArg(arg: String): List[String] = unsupported("expandArg")/*{
def stripComment(s: String) = s takeWhile (_ != '#')
val file = File(arg stripPrefix "@")
if (!file.exists)
throw new java.io.FileNotFoundException("argument file %s could not be found" format file.name)
settings splitParams (file.lines() map stripComment mkString " ")
}*/
// expand out @filename to the contents of that filename
def expandedArguments = args.toList flatMap {
case x if x startsWith "@" => expandArg(x)
case x => List(x)
}
ctx.settings.processArguments(expandedArguments, processAll = true)
}
/** Provide usage feedback on argument summary, assuming that all settings
* are already applied in context.
* @return The list of files to compile.
*/
def checkUsage(summary: ArgsSummary)(implicit ctx: Context): List[String] = {
val settings = ctx.settings
/** Creates a help message for a subset of options based on cond */
def availableOptionsMsg(cond: Setting[_] => Boolean): String = {
val ss = (ctx.settings.allSettings filter cond).toList sortBy (_.name)
val width = (ss map (_.name.length)).max
def format(s: String) = ("%-" + width + "s") format s
def helpStr(s: Setting[_]) = s"${format(s.name)} ${s.description}"
ss map helpStr mkString "\n"
}
def createUsageMsg(label: String, shouldExplain: Boolean, cond: Setting[_] => Boolean): String = {
val prefix = List(
Some(shortUsage),
Some(explainAdvanced) filter (_ => shouldExplain),
Some(label + " options include:")
).flatten mkString "\n"
prefix + "\n" + availableOptionsMsg(cond)
}
def isStandard(s: Setting[_]): Boolean = !isAdvanced(s) && !isPrivate(s)
def isAdvanced(s: Setting[_]): Boolean = s.name startsWith "-X"
def isPrivate(s: Setting[_]) : Boolean = s.name startsWith "-Y"
/** Messages explaining usage and options */
def usageMessage = createUsageMsg("where possible standard", shouldExplain = false, isStandard)
def xusageMessage = createUsageMsg("Possible advanced", shouldExplain = true, isAdvanced)
def yusageMessage = createUsageMsg("Possible private", shouldExplain = true, isPrivate)
def shouldStopWithInfo = {
import settings._
Set(help, Xhelp, Yhelp, showPlugins, showPhases) exists (_.value)
}
def infoMessage: String = {
import settings._
if (help.value) usageMessage
else if (Xhelp.value) xusageMessage
else if (Yhelp.value) yusageMessage
// else if (showPlugins.value) global.pluginDescriptions
// else if (showPhases.value) global.phaseDescriptions + (
// if (debug.value) "\n" + global.phaseFlagDescriptions else ""
// )
else ""
}
if (summary.errors.nonEmpty) {
summary.errors foreach (ctx.error(_))
ctx.println(" dotc -help gives more information")
Nil
}
else if (settings.version.value) {
ctx.println(versionMsg)
Nil
}
else if (shouldStopWithInfo) {
ctx.println(infoMessage)
Nil
} else {
if (summary.arguments.isEmpty && !settings.resident.value)
ctx.println(usageMessage)
summary.arguments
}
}
}
|