KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > tools > ajc > Main


1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * This file is part of the compiler and core tools for the AspectJ(tm)
4  * programming language; see http://aspectj.org
5  *
6  * The contents of this file are subject to the Mozilla Public License
7  * Version 1.1 (the "License"); you may not use this file except in
8  * compliance with the License. You may obtain a copy of the License at
9  * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is AspectJ.
17  *
18  * The Initial Developer of the Original Code is Xerox Corporation. Portions
19  * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
20  * All Rights Reserved.
21  *
22  * Contributor(s):
23  */

24
25 package org.aspectj.tools.ajc;
26
27 import org.aspectj.compiler.Version;
28
29 import org.aspectj.compiler.base.*;
30 import org.aspectj.compiler.crosscuts.AspectJCompiler;
31 import org.aspectj.util.*;
32
33 import java.io.*;
34 import java.util.*;
35 import java.text.DateFormat JavaDoc;
36
37 /**
38  * The main method of this class is the entrypoint to the weaver.
39  *
40  * This parses all command line arguments and passes the results on
41  * to Weaver class to do the actual work.
42  *
43  */

44 public class Main {
45     static final String JavaDoc usage =
46         "Usage: ajc <options> <source files>\n" +
47         "\n" +
48         "where <options> includes:\n"+
49 // " -threads <n> How many concurrent threads to use for compilation\n"+
50
// " <n> defaults to 0 -- multi-threading disabled\n"+
51
// " set <n> to 2 for reasonable multi-threaded compilation\n"+
52
" -verbose Output messages about what ajc is doing\n"+
53         " -version Print the version of ajc \n"+
54         " -nocomments Don't generate any comments into the woven code\n"+
55         " -emacssym Generate symbols used by AJDE for Emacs\n" +
56         //" -nosymbols Don't generate .ajsym or .ajsline files\n"+
57
" -usejavac Use javac to generate .class files\n"+
58         " -preprocess Generate regular Java code into <workingdir>\n"+
59         " Don't try to generate any .class files\n"+
60         " -workingdir <dir> Only relevant with -usejavac or -preprocess modes\n"+
61         " Specify where to place intermediate .java files\n"+
62         " <dir> defaults to ./ajworkingdir\n"+
63
64         " -O Optimize; may hinder debugging or enlarge class files\n"+
65         //!!!" -deprecation Output source locations where deprecated APIs are used\n"+
66
" -d <directory> Specify where to place generated .class files\n"+
67         " <directory> defaults to the current working dir\n"+
68
69         " -classpath <path> Specify where to find user class files\n"+
70         " -bootclasspath <path> Override location of bootstrap class files\n"+
71         " -extdirs <dirs> Override location of installed extensions\n"+
72         " -argfile <file> the file is a line-delimited list of arguments\n"+
73         " these arguments are inserted into the argument list\n"+
74         " -encoding <encoding> Specify character encoding used by source files\n"+
75         " -source 1.4 Support assertions as defined in JLS-1.4\n"+
76         " -lenient Be extra-lenient in interpreting the java specification\n"+
77         " -strict Be extra-strict in interpreting the java specification\n"+
78         " -porting Make the use of some features from pre-1.0 versions\n" +
79         " of AspectJ be warnings to ease porting old code\n" +
80         "\n"+
81         "If an argument is of the form @<filename>, the file will be interpreted as\n"+
82         "a line delimited set of arguments to insert into the argument list.";
83
84     protected List filenames;
85     //protected File currentWorkingDir = null;
86
protected JavaCompiler compiler;
87     //protected boolean isIncremental = false;
88

89     /** The ErrorHandler to pass to the JavaCompiler */
90     protected ErrorHandler errorHandler;
91
92     public static void main(String JavaDoc[] args) throws java.io.IOException JavaDoc {
93         new Main().realMain(args);
94     }
95
96     /**
97      * Constructs the compiler using <code>errorHandler</code>.
98      * @param errorHandler The errorHandler to pass to the JavaCompiler. If
99      * this is null, the JavaCompiler will use the default
100      * ErrorHandler.
101      */

102     public Main(ErrorHandler errorHandler) {
103         this.errorHandler = errorHandler;
104     }
105
106     /**
107      * Construct the compiler using the default ErrorHandler.
108      */

109     public Main() {
110         this(null);
111     }
112
113     public void checkJavaVersion() {
114         try {
115             Class JavaDoc c = Class.forName("java.util.Map");
116         } catch (ClassNotFoundException JavaDoc cnfe) {
117             fail("Java 2 or later required to run ajc (jdk1.2 or 1.3); not java " +
118                  System.getProperty("java.version"));
119         }
120
121         try {
122             Class JavaDoc c = Class.forName("java.lang.CharSequence");
123             //!!! insert jdk1.4 warning here
124
} catch (ClassNotFoundException JavaDoc cnfe) {
125         }
126     }
127
128     public void realMain(String JavaDoc[] args) {
129         int exitCode = -1;
130         while(true) {
131             compiler = null;
132             exitCode = compile(args);
133             if (!shouldRecompile()) break;
134         }
135         exit(exitCode);
136     }
137
138     public Options getOptions() {
139         return getCompiler().getOptions();
140     }
141
142     public int compile(String JavaDoc[] args) {
143         try {
144             checkJavaVersion();
145             return run(args);
146         } catch (CompilerErrors errs) {
147             return -1;
148         } catch (InternalCompilerError compilerError) {
149             handleInternalError(compilerError.uncaughtThrowable, compilerError);
150             //System.err.println("showing where: "+compilerError.where);
151
return -2;
152         } catch (ExitRequestException exitException) {
153             return exitException.getValue();
154         } catch (Throwable JavaDoc e) {
155             handleInternalError(e, null);
156             return -2;
157         }
158     }
159
160     /**
161      * Returns an <code>AspectJCompiler</code> constructed from <code>errorHandler</code>
162      * if it's non-null.
163      * @return An <code>AspectJCompiler</code> using <code>errorHandler</code> if it's non-null.
164      */

165     protected JavaCompiler getCompiler() {
166         if (compiler != null) return compiler;
167         if (compiler == null) {
168             if (errorHandler == null) {
169                 compiler = new AspectJCompiler();
170             } else {
171                 compiler = new AspectJCompiler(errorHandler);
172             }
173         }
174         return compiler;
175     }
176
177     public void clearState() {
178         if (compiler != null) {
179             compiler.clearState();
180         }
181     }
182
183
184     public int run(String JavaDoc[] args) {
185         filenames = new LinkedList();
186         parseCommandLine(args);
187         getCompiler().compile(filenames);
188         return 0;
189     }
190
191
192     public boolean shouldRecompile() {
193         if (!getCompiler().getOptions().incremental) return false;
194
195         System.out.print("ajc> ");
196         System.out.flush();
197         byte[] buffer = new byte[2048];
198         int n = 0;
199         try {
200             n = System.in.read(buffer);
201             if (n <= 0) throw new java.io.IOException JavaDoc();
202         } catch (Throwable JavaDoc e) {
203             System.out.println("bye!");
204             exit(0);
205         }
206         if (buffer[0] >= 'a' && buffer[0] <= 'z') return false;
207         return true;
208     }
209
210     private class AjcConfigParser extends ConfigParser {
211         protected void parseOption(String JavaDoc arg, LinkedList args) {
212             if (arg.equals("-d")) {
213                 getOptions().outputDir = makeFile(removeStringArg(args));
214             } else if (arg.equals("-workingdir")) {
215                 getOptions().workingDir = makeFile(removeStringArg(args));
216             } else if (arg.equals("-version")) {
217                 printVersion();
218                 internalExit(0);
219             } else if (arg.equals("-showversion")) {
220                 printVersion();
221             } else if (arg.startsWith("-")) {
222                 String JavaDoc key = arg.substring(1);
223                 Object JavaDoc value = Boolean.TRUE;
224                 if (getOptions().isStringOption(key)) {
225                     value = removeStringArg(args);
226                 } else if (getOptions().isIntegerOption(key)) {
227                     value = Integer.valueOf(removeStringArg(args));
228                 }
229                 if (!getOptions().set(key, value)) {
230                     showWarning("invalid flag: " + key);
231                     displayHelpAndExit(null);
232                 }
233             } else {
234                 showWarning(arg+" is an invalid option or argument.");
235                 displayHelpAndExit(null);
236             }
237         }
238
239         protected void showError(String JavaDoc message) {
240             showWarning(message);
241             internalExit(1);
242         }
243     }
244
245     protected void parseCommandLine(String JavaDoc[] args) {
246         if (args.length == 0) displayHelpAndExit(null);
247         
248         AjcConfigParser configParser = new AjcConfigParser();
249         configParser.parseCommandLine(args);
250         filenames = configParser.getFiles();
251
252         if (filenames.size() == 0) {
253             displayHelpAndExit("Nothing to compile.");
254         }
255     }
256
257     protected void printVersion() {
258         DateFormat JavaDoc formatter = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT);
259         TimeZone tz = TimeZone.getTimeZone("PST");
260         formatter.setTimeZone(tz);
261         Date buildDate = new Date(getCompiler().getBuildTime());
262         String JavaDoc dateString = formatter.format(buildDate) + " " + tz.getDisplayName(false, TimeZone.SHORT);
263         System.err.print("ajc version " + getCompiler().getVersion() +
264                          " (built " + dateString + ")");
265         System.err.println(" running on java " + System.getProperty("java.version"));
266     }
267
268     /* This section of code handles errors that occur during compilation */
269     static final String JavaDoc internalErrorMessage =
270         "Please copy the following text into an email message and send it,\n" +
271         "along with any additional information you can add to: \n" +
272         " \n" +
273         " support@aspectj.org \n" +
274         " \n";
275
276     static final String JavaDoc outOfMemoryMessage =
277         "The compiler ran out of memory while trying to compile your system.\n" +
278         "By default, only 64MB are available to ajc. You can increase\n" +
279         "this amount by editing the ajc launch script to pass -Xmx128M or\n" +
280         "some larger amount of memory to the JVM used to run ajc.\n" +
281         "More information about this issue can be found in the FAQ at\n" +
282         "http://aspectj.org/faq by searching for \"OutOfMemoryError\".\n";
283
284     static final String JavaDoc generalCodeRequest =
285         "If possible, please include a small fragment of code that can \n"+
286         "reproduce the error, provided that code isn't confidential. \n";
287
288
289     public void handleInternalError(Throwable JavaDoc uncaughtThrowable,
290                                     InternalCompilerError compilerError)
291     {
292         if (uncaughtThrowable instanceof OutOfMemoryError JavaDoc) {
293             System.err.println(outOfMemoryMessage);
294             return;
295         }
296
297         System.err.println("An internal error occured in AspectJ-"+getCompiler().getVersion());
298         System.err.println(internalErrorMessage);
299         System.err.println(uncaughtThrowable.toString());
300         uncaughtThrowable.printStackTrace();
301         System.err.println();
302
303         if (compilerError != null) {
304             compilerError.showWhere(new PrintWriter(System.err));
305         }
306         System.err.println(generalCodeRequest);
307     }
308
309
310     protected void displayHelpAndExit(String JavaDoc message) {
311         if (message != null) System.err.println(message);
312         System.err.println();
313         System.err.println(usage);
314         internalExit(0);
315     }
316
317     protected void fail(Exception JavaDoc e) {
318         fail(e.toString());
319     }
320
321     protected void fail(String JavaDoc message) {
322         System.err.println(message);
323         internalExit(1);
324     }
325
326     void internalExit(int value) {
327         System.out.flush();
328         System.err.flush();
329         throw new ExitRequestException(value);
330     }
331
332     protected void exit(int value) {
333         System.out.flush();
334         System.err.flush();
335         System.exit(value);
336     }
337 }
338
Popular Tags