summaryrefslogtreecommitdiff
path: root/sources/scalac/CompilerCommand.java
blob: b67cf14b26e7c586e48d286049e64dc056b6cb5e (plain) (blame)
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
/*     ____ ____  ____ ____  ______                                     *\
**    / __// __ \/ __// __ \/ ____/    SOcos COmpiles Scala             **
**  __\_ \/ /_/ / /__/ /_/ /\_ \       (c) 2002, LAMP/EPFL              **
** /_____/\____/\___/\____/____/                                        **
\*                                                                      */

// $Id$

package scalac;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import scalac.util.ClassPath;
import scalac.util.Reporter;
import scalac.util.CommandParser;
import scalac.util.ArgumentParser;
import scalac.util.OptionParser;
import scalac.util.BooleanOptionParser;
import scalac.util.StringOptionParser;
import scalac.util.ChoiceOptionParser;
import scalac.util.HelpOptionParser;
import scalac.util.VersionOptionParser;
//import scalac.util.OptimizeOptionParser;
import scalac.util.PhaseSetOptionParser;
import scalac.util.PrintOptionParser;
import scalac.util.UnknownOptionParser;
import scalac.util.ScalaFileArgumentParser;
import scalac.util.UnknownArgumentParser;
import scalac.util.Strings;

/**
 * Class <code>CompilerCommand</code> describes the options
 * passed as arguments to the compiler command.
 */
public class CompilerCommand extends CommandParser {

    //########################################################################
    // Public Fields

    public final CompilerPhases phases;

    public final BooleanOptionParser nowarn;
    public final BooleanOptionParser verbose;
    public final BooleanOptionParser debug;
    public final BooleanOptionParser explaintypes;
    public final BooleanOptionParser uniqid;
    public final BooleanOptionParser types;
    public final BooleanOptionParser prompt;
    public final ChoiceOptionParser separate;
    //public final OptimizeOptionParser optimize;
    public final StringOptionParser classpath;
    public final StringOptionParser sourcepath;
    public final StringOptionParser bootclasspath;
    public final StringOptionParser extdirs;
    public final StringOptionParser outpath;
    public final ChoiceOptionParser target;
    public final BooleanOptionParser noimports;
    public final BooleanOptionParser nopredefs;
    public final PhaseSetOptionParser skip;
    public final PhaseSetOptionParser check;
    public final PrintOptionParser print;
    public final ChoiceOptionParser printer;
    public final StringOptionParser printfile;
    public final PhaseSetOptionParser graph;
    public final PhaseSetOptionParser stop;
    public final PhaseSetOptionParser log;
    public final VersionOptionParser version;
    public final HelpOptionParser help;
    public final UnknownOptionParser unknown_options;
    public final ScalaFileArgumentParser files;
    public final UnknownArgumentParser unknown_arguments;

    /*
     * Non-standard options (starting with prefix "-X")
     * are subject to change without notice.
     */
    public final BooleanOptionParser Xshortname;

    //########################################################################
    // Public Constructors

    /**
     * Creates an instance variable.
     *
     * @param product
     * @param version
     * @param reporter
     * @param phases
     */
    public CompilerCommand(String product, String version,
        Reporter reporter, CompilerPhases phases)
    {
        this(product, version, "<source files>", reporter, phases);
    }

    protected CompilerCommand(String product, String version, String syntax,
        Reporter reporter, CompilerPhases phases)
    {
        super(product, version, syntax, reporter);
        this.phases = phases;

        ArgumentParser[] parsers = new ArgumentParser[] {

        this.nowarn = new BooleanOptionParser(this,
            "nowarn", "Generate no warnings",
            false),

        this.verbose = new BooleanOptionParser(this,
            "verbose", "Output messages about what the compiler is doing",
            false),

        this.debug = new BooleanOptionParser(this,
            "debug", "Output debugging messages",
            false),

        this.explaintypes = new BooleanOptionParser(this,
            "explaintypes", "Explain type errors in more detail",
            false),

        this.uniqid = new BooleanOptionParser(this,
            "uniqid", "Print identifiers with unique names (debugging option)",
            false),

        this.types = new BooleanOptionParser(this,
            "types", "Print tree types (debugging option)",
            false),

        this.prompt = new BooleanOptionParser(this,
            "prompt", "Display a prompt after each error (debugging option)",
            false),

        this.separate = new ChoiceOptionParser(this,
            "separate", "read symbol files for separate compilation: (yes, no)",
            "separate", new String[]{"yes", "no"}, "default"),

        //this.optimize = new OptimizeOptionParser(this,
        //    "optimize", "optimize bytecode (-optimize:help for option list)",
	//    null /* todo: uncomment: phases.OPTIMIZE */),

        this.classpath = new StringOptionParser(this,
            "classpath", "Specify where to find user class files",
            "path", ClassPath.CLASS_PATH),

        this.sourcepath = new StringOptionParser(this,
            "sourcepath", "Specify where to find input source files",
            "path", ClassPath.SOURCE_PATH),

        this.bootclasspath = new StringOptionParser(this,
            "bootclasspath", "Override location of bootstrap class files",
            "path", ClassPath.BOOT_PATH),

        this.extdirs = new StringOptionParser(this,
            "extdirs", "Override location of installed extensions",
            "dirs", ClassPath.EXTENSION_PATH),

        this.outpath = new StringOptionParser(this,
            "d", "Specify where to place generated class files",
            "directory", "."),

        this.target = new ChoiceOptionParser(this,
            "target", "Specify which bakend to use (jvm, msil)",
            "target", Global.TARGETS, Global.TARGET_JVM),

        this.noimports = new BooleanOptionParser(this,
            "noimports", "Compile without any implicit imports",
            false),

        this.nopredefs = new BooleanOptionParser(this,
            "nopredefs", "Compile without any implicit predefined values",
            false),

        this.skip = new PhaseSetOptionParser(this,
            "skip", "Skip <phases> (see below)",
            phases.phases(), PhaseDescriptor.SKIP),

        this.check = new PhaseSetOptionParser(this,
            "check", "Check the tree after <phases> (see below)",
            phases.phases(), PhaseDescriptor.CHECK),

        this.print = new PrintOptionParser(this,
            "print", "Print out program after <phases> (see below)",
            phases.phases(), PhaseDescriptor.PRINT),

        this.printer = new ChoiceOptionParser(this,
            "printer", "Printer to use",
            "printer", Global.PRINTERS, Global.PRINTER_TEXT),

        this.printfile = new StringOptionParser(this,
            "print-file", "Specify file in which to print trees",
            "file", "-"),

        this.graph = new PhaseSetOptionParser(this,
            "graph", "Graph the program after <phases> (see below)",
            phases.phases(), PhaseDescriptor.GRAPH),

        this.stop = new PhaseSetOptionParser(this,
            "stop", "Stop after first phase in <phases> (see below)",
            phases.phases(), PhaseDescriptor.STOP),

        this.log = new PhaseSetOptionParser(this,
            "log", "Log operations in <phases> (see below)",
            phases.phases(), PhaseDescriptor.LOG),

        this.version = new VersionOptionParser(this,
            "version", "Print product version and exit",
            product() + " " + version() + " -- (c) 2002-03 LAMP/EPFL"),

        this.help = new HelpOptionParser(this,
            "help", "Print a synopsis of standard options"),

        this.Xshortname = new BooleanOptionParser(this,
            "Xshortname", "Display short file names in error reports",
            false),

        this.unknown_options = new UnknownOptionParser(this),

        this.files = new ScalaFileArgumentParser(this),

        this.unknown_arguments = new UnknownArgumentParser(this),

        };

        for (int i = 0; i < parsers.length; i++) add(parsers[i]);
    }

    //########################################################################
    // Public Methods

    /**
     * ..
     *
     * @param args
     */
    public boolean parse(String[] args) {
        boolean result = super.parse(args);
        reporter().nowarn = nowarn.value;
        reporter().verbose = verbose.value;
        reporter().prompt = prompt.value;
        reporter().shortname = Xshortname.value;
        return result;
    }

    private boolean containsPhaseOptions() {
        List parsers = parsers();
        for (int i = 0; i < parsers.size(); i++) {
            if (parsers.get(i) instanceof PhaseSetOptionParser) return true;
        }
        return false;
    }

    /**
     * Returns the help message for this compiler command.
     *
     * @return a formatted string containing the help message.
     */
    public String getHelpMessage() {
        StringBuffer buffer = new StringBuffer(super.getHelpMessage());
        if (containsPhaseOptions()) {
            buffer.append(Strings.EOL);
            buffer.append("and possible compilation phases include:");
            buffer.append(Strings.EOL);
            PhaseDescriptor[] array = phases.phases();
            List lines = new ArrayList(array.length);
            for (int i = 0; i < array.length; i++) {
                PhaseDescriptor phase = array[i];
                lines.add("  " + phase.name() + "\t  " + phase.description());
            }
            lines.add("  " + "all" + "\t  " + "matches all phases");
            buffer.append(Strings.format(lines));
        }
        return buffer.toString();
    }

    /**
     * Returns the class path for this compiler command.
     *
     * @return the class path.
     */
    public ClassPath classpath() {
        return new ClassPath(classpath.value, sourcepath.value,
            bootclasspath.value, extdirs.value);
    }

    /**
     * Returns the output path for this compiler command.
     *
     * @return the output path terminated by .
     */
    public String outpath() {
        return outpath.value + (
            outpath.value.endsWith(File.separator) ? "" : File.separator
        );
    }

    //########################################################################
}