1 | /*
|
---|
2 | * Copyright 2000-2004 The Apache Software Foundation
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
---|
5 | * you may not use this file except in compliance with the License.
|
---|
6 | * You may obtain a copy of the License at
|
---|
7 | *
|
---|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
---|
9 | *
|
---|
10 | * Unless required by applicable law or agreed to in writing, software
|
---|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
13 | * See the License for the specific language governing permissions and
|
---|
14 | * limitations under the License.
|
---|
15 | *
|
---|
16 | */
|
---|
17 | package org.apache.tools.ant.taskdefs.optional;
|
---|
18 |
|
---|
19 | import java.io.BufferedReader;
|
---|
20 | import java.io.File;
|
---|
21 | import java.io.IOException;
|
---|
22 | import java.io.PrintWriter;
|
---|
23 | import java.io.StringReader;
|
---|
24 | import java.io.StringWriter;
|
---|
25 | import java.util.Enumeration;
|
---|
26 | import java.util.Hashtable;
|
---|
27 | import java.util.Properties;
|
---|
28 | import java.util.StringTokenizer;
|
---|
29 | import java.util.Vector;
|
---|
30 | import netrexx.lang.Rexx;
|
---|
31 | import org.apache.tools.ant.BuildException;
|
---|
32 | import org.apache.tools.ant.DirectoryScanner;
|
---|
33 | import org.apache.tools.ant.Project;
|
---|
34 | import org.apache.tools.ant.taskdefs.MatchingTask;
|
---|
35 | import org.apache.tools.ant.types.EnumeratedAttribute;
|
---|
36 |
|
---|
37 | /**
|
---|
38 | * Compiles NetRexx source files.
|
---|
39 | * This task can take the following
|
---|
40 | * arguments:
|
---|
41 | * <ul>
|
---|
42 | * <li>binary</li>
|
---|
43 | * <li>classpath</li>
|
---|
44 | * <li>comments</li>
|
---|
45 | * <li>compile</li>
|
---|
46 | * <li>console</li>
|
---|
47 | * <li>crossref</li>
|
---|
48 | * <li>decimal</li>
|
---|
49 | * <li>destdir</li>
|
---|
50 | * <li>diag</li>
|
---|
51 | * <li>explicit</li>
|
---|
52 | * <li>format</li>
|
---|
53 | * <li>keep</li>
|
---|
54 | * <li>logo</li>
|
---|
55 | * <li>replace</li>
|
---|
56 | * <li>savelog</li>
|
---|
57 | * <li>srcdir</li>
|
---|
58 | * <li>sourcedir</li>
|
---|
59 | * <li>strictargs</li>
|
---|
60 | * <li>strictassign</li>
|
---|
61 | * <li>strictcase</li>
|
---|
62 | * <li>strictimport</li>
|
---|
63 | * <li>symbols</li>
|
---|
64 | * <li>time</li>
|
---|
65 | * <li>trace</li>
|
---|
66 | * <li>utf8</li>
|
---|
67 | * <li>verbose</li>
|
---|
68 | * <li>suppressMethodArgumentNotUsed</li>
|
---|
69 | * <li>suppressPrivatePropertyNotUsed</li>
|
---|
70 | * <li>suppressVariableNotUsed</li>
|
---|
71 | * <li>suppressExceptionNotSignalled</li>
|
---|
72 | * <li>suppressDeprecation</li>
|
---|
73 | * </ul>
|
---|
74 | * Of these arguments, the <b>srcdir</b> argument is required.
|
---|
75 | *
|
---|
76 | * <p>When this task executes, it will recursively scan the srcdir
|
---|
77 | * looking for NetRexx source files to compile. This task makes its
|
---|
78 | * compile decision based on timestamp.
|
---|
79 | * <p>Before files are compiled they and any other file in the
|
---|
80 | * srcdir will be copied to the destdir allowing support files to be
|
---|
81 | * located properly in the classpath. The reason for copying the source files
|
---|
82 | * before the compile is that NetRexxC has only two destinations for classfiles:
|
---|
83 | * <ol>
|
---|
84 | * <li>The current directory, and,</li>
|
---|
85 | * <li>The directory the source is in (see sourcedir option)
|
---|
86 | * </ol>
|
---|
87 | *
|
---|
88 | */
|
---|
89 | public class NetRexxC extends MatchingTask {
|
---|
90 |
|
---|
91 | // variables to hold arguments
|
---|
92 | private boolean binary;
|
---|
93 | private String classpath;
|
---|
94 | private boolean comments;
|
---|
95 | private boolean compact = true;// should be the default, as it integrates better in ant.
|
---|
96 | private boolean compile = true;
|
---|
97 | private boolean console;
|
---|
98 | private boolean crossref;
|
---|
99 | private boolean decimal = true;
|
---|
100 | private File destDir;
|
---|
101 | private boolean diag;
|
---|
102 | private boolean explicit;
|
---|
103 | private boolean format;
|
---|
104 | private boolean keep;
|
---|
105 | private boolean logo = true;
|
---|
106 | private boolean replace;
|
---|
107 | private boolean savelog;
|
---|
108 | private File srcDir;
|
---|
109 | private boolean sourcedir = true;// ?? Should this be the default for ant?
|
---|
110 | private boolean strictargs;
|
---|
111 | private boolean strictassign;
|
---|
112 | private boolean strictcase;
|
---|
113 | private boolean strictimport;
|
---|
114 | private boolean strictprops;
|
---|
115 | private boolean strictsignal;
|
---|
116 | private boolean symbols;
|
---|
117 | private boolean time;
|
---|
118 | private String trace = "trace2";
|
---|
119 | private boolean utf8;
|
---|
120 | private String verbose = "verbose3";
|
---|
121 | private boolean suppressMethodArgumentNotUsed = false;
|
---|
122 | private boolean suppressPrivatePropertyNotUsed = false;
|
---|
123 | private boolean suppressVariableNotUsed = false;
|
---|
124 | private boolean suppressExceptionNotSignalled = false;
|
---|
125 | private boolean suppressDeprecation = false;
|
---|
126 |
|
---|
127 | // constants for the messages to suppress by flags and their corresponding properties
|
---|
128 | static final String MSG_METHOD_ARGUMENT_NOT_USED
|
---|
129 | = "Warning: Method argument is not used";
|
---|
130 | static final String MSG_PRIVATE_PROPERTY_NOT_USED
|
---|
131 | = "Warning: Private property is defined but not used";
|
---|
132 | static final String MSG_VARIABLE_NOT_USED
|
---|
133 | = "Warning: Variable is set but not used";
|
---|
134 | static final String MSG_EXCEPTION_NOT_SIGNALLED
|
---|
135 | = "is in SIGNALS list but is not signalled within the method";
|
---|
136 | static final String MSG_DEPRECATION = "has been deprecated";
|
---|
137 |
|
---|
138 | // other implementation variables
|
---|
139 | private Vector compileList = new Vector();
|
---|
140 | private Hashtable filecopyList = new Hashtable();
|
---|
141 |
|
---|
142 | /**
|
---|
143 | * Set whether literals are treated as binary, rather than NetRexx types
|
---|
144 | */
|
---|
145 | public void setBinary(boolean binary) {
|
---|
146 | this.binary = binary;
|
---|
147 | }
|
---|
148 |
|
---|
149 |
|
---|
150 | /** Set the classpath used for NetRexx compilation */
|
---|
151 | public void setClasspath(String classpath) {
|
---|
152 | this.classpath = classpath;
|
---|
153 | }
|
---|
154 |
|
---|
155 |
|
---|
156 | /**
|
---|
157 | * Set whether comments are passed through to the generated java source.
|
---|
158 | * Valid true values are "on" or "true". Anything else sets the flag to
|
---|
159 | * false. The default value is false
|
---|
160 | */
|
---|
161 | public void setComments(boolean comments) {
|
---|
162 | this.comments = comments;
|
---|
163 | }
|
---|
164 |
|
---|
165 |
|
---|
166 | /**
|
---|
167 | * Set whether error messages come out in compact or verbose format. Valid
|
---|
168 | * true values are "on" or "true". Anything else sets the flag to false.
|
---|
169 | * The default value is false
|
---|
170 | */
|
---|
171 | public void setCompact(boolean compact) {
|
---|
172 | this.compact = compact;
|
---|
173 | }
|
---|
174 |
|
---|
175 |
|
---|
176 | /**
|
---|
177 | * Set whether the NetRexx compiler should compile the generated java code
|
---|
178 | * Valid true values are "on" or "true". Anything else sets the flag to
|
---|
179 | * false. The default value is true. Setting this flag to false, will
|
---|
180 | * automatically set the keep flag to true.
|
---|
181 | */
|
---|
182 | public void setCompile(boolean compile) {
|
---|
183 | this.compile = compile;
|
---|
184 | if (!this.compile && !this.keep) {
|
---|
185 | this.keep = true;
|
---|
186 | }
|
---|
187 | }
|
---|
188 |
|
---|
189 |
|
---|
190 | /**
|
---|
191 | * Set whether or not messages should be displayed on the 'console' Valid
|
---|
192 | * true values are "on" or "true". Anything else sets the flag to false.
|
---|
193 | * The default value is true.
|
---|
194 | */
|
---|
195 | public void setConsole(boolean console) {
|
---|
196 | this.console = console;
|
---|
197 | }
|
---|
198 |
|
---|
199 |
|
---|
200 | /** Whether variable cross references are generated */
|
---|
201 | public void setCrossref(boolean crossref) {
|
---|
202 | this.crossref = crossref;
|
---|
203 | }
|
---|
204 |
|
---|
205 |
|
---|
206 | /**
|
---|
207 | * Set whether decimal arithmetic should be used for the netrexx code.
|
---|
208 | * Binary arithmetic is used when this flag is turned off. Valid true
|
---|
209 | * values are "on" or "true". Anything else sets the flag to false. The
|
---|
210 | * default value is true.
|
---|
211 | */
|
---|
212 | public void setDecimal(boolean decimal) {
|
---|
213 | this.decimal = decimal;
|
---|
214 | }
|
---|
215 |
|
---|
216 |
|
---|
217 | /**
|
---|
218 | * Set the destination directory into which the NetRexx source files
|
---|
219 | * should be copied and then compiled.
|
---|
220 | */
|
---|
221 | public void setDestDir(File destDirName) {
|
---|
222 | destDir = destDirName;
|
---|
223 | }
|
---|
224 |
|
---|
225 |
|
---|
226 | /**
|
---|
227 | * Whether diagnostic information about the compile is generated
|
---|
228 | */
|
---|
229 | public void setDiag(boolean diag) {
|
---|
230 | this.diag = diag;
|
---|
231 | }
|
---|
232 |
|
---|
233 |
|
---|
234 | /**
|
---|
235 | * Sets whether variables must be declared explicitly before use. Valid
|
---|
236 | * true values are "on" or "true". Anything else sets the flag to false.
|
---|
237 | * The default value is false.
|
---|
238 | */
|
---|
239 | public void setExplicit(boolean explicit) {
|
---|
240 | this.explicit = explicit;
|
---|
241 | }
|
---|
242 |
|
---|
243 |
|
---|
244 | /**
|
---|
245 | * Whether the generated java code is formatted nicely or left to match
|
---|
246 | * NetRexx line numbers for call stack debugging
|
---|
247 | */
|
---|
248 | public void setFormat(boolean format) {
|
---|
249 | this.format = format;
|
---|
250 | }
|
---|
251 |
|
---|
252 |
|
---|
253 | /**
|
---|
254 | * Whether the generated java code is produced Valid true values are "on"
|
---|
255 | * or "true". Anything else sets the flag to false. The default value is
|
---|
256 | * false.
|
---|
257 | */
|
---|
258 | public void setJava(boolean java) {
|
---|
259 | log("The attribute java is currently unused.", Project.MSG_WARN);
|
---|
260 | }
|
---|
261 |
|
---|
262 |
|
---|
263 | /**
|
---|
264 | * Sets whether the generated java source file should be kept after
|
---|
265 | * compilation. The generated files will have an extension of .java.keep,
|
---|
266 | * <b>not</b> .java Valid true values are "on" or "true". Anything else
|
---|
267 | * sets the flag to false. The default value is false.
|
---|
268 | */
|
---|
269 | public void setKeep(boolean keep) {
|
---|
270 | this.keep = keep;
|
---|
271 | }
|
---|
272 |
|
---|
273 |
|
---|
274 | /** Whether the compiler text logo is displayed when compiling */
|
---|
275 | public void setLogo(boolean logo) {
|
---|
276 | this.logo = logo;
|
---|
277 | }
|
---|
278 |
|
---|
279 |
|
---|
280 | /**
|
---|
281 | * Whether the generated .java file should be replaced when compiling
|
---|
282 | * Valid true values are "on" or "true". Anything else sets the flag to
|
---|
283 | * false. The default value is false.
|
---|
284 | */
|
---|
285 | public void setReplace(boolean replace) {
|
---|
286 | this.replace = replace;
|
---|
287 | }
|
---|
288 |
|
---|
289 |
|
---|
290 | /**
|
---|
291 | * Sets whether the compiler messages will be written to NetRexxC.log as
|
---|
292 | * well as to the console Valid true values are "on" or "true". Anything
|
---|
293 | * else sets the flag to false. The default value is false.
|
---|
294 | */
|
---|
295 | public void setSavelog(boolean savelog) {
|
---|
296 | this.savelog = savelog;
|
---|
297 | }
|
---|
298 |
|
---|
299 |
|
---|
300 | /**
|
---|
301 | * Tells the NetRexx compiler to store the class files in the same
|
---|
302 | * directory as the source files. The alternative is the working directory
|
---|
303 | * Valid true values are "on" or "true". Anything else sets the flag to
|
---|
304 | * false. The default value is true.
|
---|
305 | */
|
---|
306 | public void setSourcedir(boolean sourcedir) {
|
---|
307 | this.sourcedir = sourcedir;
|
---|
308 | }
|
---|
309 |
|
---|
310 |
|
---|
311 | /** Set the source dir to find the source Java files. */
|
---|
312 | public void setSrcDir(File srcDirName) {
|
---|
313 | srcDir = srcDirName;
|
---|
314 | }
|
---|
315 |
|
---|
316 |
|
---|
317 | /**
|
---|
318 | * Tells the NetRexx compiler that method calls always need parentheses,
|
---|
319 | * even if no arguments are needed, e.g. <code>aStringVar.getBytes</code>
|
---|
320 | * vs. <code>aStringVar.getBytes()</code> Valid true values are "on" or
|
---|
321 | * "true". Anything else sets the flag to false. The default value is
|
---|
322 | * false.
|
---|
323 | */
|
---|
324 | public void setStrictargs(boolean strictargs) {
|
---|
325 | this.strictargs = strictargs;
|
---|
326 | }
|
---|
327 |
|
---|
328 |
|
---|
329 | /**
|
---|
330 | * Tells the NetRexx compile that assignments must match exactly on type
|
---|
331 | */
|
---|
332 | public void setStrictassign(boolean strictassign) {
|
---|
333 | this.strictassign = strictassign;
|
---|
334 | }
|
---|
335 |
|
---|
336 |
|
---|
337 | /**
|
---|
338 | * Specifies whether the NetRexx compiler should be case sensitive or not
|
---|
339 | */
|
---|
340 | public void setStrictcase(boolean strictcase) {
|
---|
341 | this.strictcase = strictcase;
|
---|
342 | }
|
---|
343 |
|
---|
344 |
|
---|
345 | /**
|
---|
346 | * Sets whether classes need to be imported explicitly using an <code>import</code>
|
---|
347 | * statement. By default the NetRexx compiler will import certain packages
|
---|
348 | * automatically Valid true values are "on" or "true". Anything else sets
|
---|
349 | * the flag to false. The default value is false.
|
---|
350 | */
|
---|
351 | public void setStrictimport(boolean strictimport) {
|
---|
352 | this.strictimport = strictimport;
|
---|
353 | }
|
---|
354 |
|
---|
355 |
|
---|
356 | /**
|
---|
357 | * Sets whether local properties need to be qualified explicitly using
|
---|
358 | * <code>this</code> Valid true values are "on" or "true". Anything else
|
---|
359 | * sets the flag to false. The default value is false.
|
---|
360 | */
|
---|
361 | public void setStrictprops(boolean strictprops) {
|
---|
362 | this.strictprops = strictprops;
|
---|
363 | }
|
---|
364 |
|
---|
365 |
|
---|
366 | /**
|
---|
367 | * Whether the compiler should force catching of exceptions by explicitly
|
---|
368 | * named types
|
---|
369 | */
|
---|
370 | public void setStrictsignal(boolean strictsignal) {
|
---|
371 | this.strictsignal = strictsignal;
|
---|
372 | }
|
---|
373 |
|
---|
374 |
|
---|
375 | /**
|
---|
376 | * Sets whether debug symbols should be generated into the class file
|
---|
377 | * Valid true values are "on" or "true". Anything else sets the flag to
|
---|
378 | * false. The default value is false.
|
---|
379 | */
|
---|
380 | public void setSymbols(boolean symbols) {
|
---|
381 | this.symbols = symbols;
|
---|
382 | }
|
---|
383 |
|
---|
384 |
|
---|
385 | /**
|
---|
386 | * Asks the NetRexx compiler to print compilation times to the console
|
---|
387 | * Valid true values are "on" or "true". Anything else sets the flag to
|
---|
388 | * false. The default value is false.
|
---|
389 | */
|
---|
390 | public void setTime(boolean time) {
|
---|
391 | this.time = time;
|
---|
392 | }
|
---|
393 |
|
---|
394 |
|
---|
395 | public void setTrace(TraceAttr trace) {
|
---|
396 | this.trace = trace.getValue();
|
---|
397 | }
|
---|
398 |
|
---|
399 |
|
---|
400 | /**
|
---|
401 | * Turns on or off tracing and directs the resultant trace output Valid
|
---|
402 | * values are: "trace", "trace1", "trace2" and "notrace". "trace" and
|
---|
403 | * "trace2"
|
---|
404 | */
|
---|
405 | public void setTrace(String trace) {
|
---|
406 | TraceAttr t = new TraceAttr();
|
---|
407 |
|
---|
408 | t.setValue(trace);
|
---|
409 | setTrace(t);
|
---|
410 | }
|
---|
411 |
|
---|
412 |
|
---|
413 | /**
|
---|
414 | * Tells the NetRexx compiler that the source is in UTF8 Valid true values
|
---|
415 | * are "on" or "true". Anything else sets the flag to false. The default
|
---|
416 | * value is false.
|
---|
417 | */
|
---|
418 | public void setUtf8(boolean utf8) {
|
---|
419 | this.utf8 = utf8;
|
---|
420 | }
|
---|
421 |
|
---|
422 |
|
---|
423 | /**
|
---|
424 | * Whether lots of warnings and error messages should be generated
|
---|
425 | */
|
---|
426 | public void setVerbose(VerboseAttr verbose) {
|
---|
427 | this.verbose = verbose.getValue();
|
---|
428 | }
|
---|
429 |
|
---|
430 |
|
---|
431 | /**
|
---|
432 | * Whether lots of warnings and error messages should be generated
|
---|
433 | */
|
---|
434 | public void setVerbose(String verbose) {
|
---|
435 | VerboseAttr v = new VerboseAttr();
|
---|
436 |
|
---|
437 | v.setValue(verbose);
|
---|
438 | setVerbose(v);
|
---|
439 | }
|
---|
440 |
|
---|
441 |
|
---|
442 | /**
|
---|
443 | * Whether the task should suppress the "Method argument is not used" in
|
---|
444 | * strictargs-Mode, which can not be suppressed by the compiler itself.
|
---|
445 | * The warning is logged as verbose message, though.
|
---|
446 | */
|
---|
447 | public void setSuppressMethodArgumentNotUsed(boolean suppressMethodArgumentNotUsed) {
|
---|
448 | this.suppressMethodArgumentNotUsed = suppressMethodArgumentNotUsed;
|
---|
449 | }
|
---|
450 |
|
---|
451 |
|
---|
452 | /**
|
---|
453 | * Whether the task should suppress the "Private property is defined but
|
---|
454 | * not used" in strictargs-Mode, which can be quite annoying while
|
---|
455 | * developing. The warning is logged as verbose message, though.
|
---|
456 | */
|
---|
457 | public void setSuppressPrivatePropertyNotUsed(boolean suppressPrivatePropertyNotUsed) {
|
---|
458 | this.suppressPrivatePropertyNotUsed = suppressPrivatePropertyNotUsed;
|
---|
459 | }
|
---|
460 |
|
---|
461 |
|
---|
462 | /**
|
---|
463 | * Whether the task should suppress the "Variable is set but not used" in
|
---|
464 | * strictargs-Mode. Be careful with this one! The warning is logged as
|
---|
465 | * verbose message, though.
|
---|
466 | */
|
---|
467 | public void setSuppressVariableNotUsed(boolean suppressVariableNotUsed) {
|
---|
468 | this.suppressVariableNotUsed = suppressVariableNotUsed;
|
---|
469 | }
|
---|
470 |
|
---|
471 |
|
---|
472 | /**
|
---|
473 | * Whether the task should suppress the "FooException is in SIGNALS list
|
---|
474 | * but is not signalled within the method", which is sometimes rather
|
---|
475 | * useless. The warning is logged as verbose message, though.
|
---|
476 | */
|
---|
477 | public void setSuppressExceptionNotSignalled(boolean suppressExceptionNotSignalled) {
|
---|
478 | this.suppressExceptionNotSignalled = suppressExceptionNotSignalled;
|
---|
479 | }
|
---|
480 |
|
---|
481 |
|
---|
482 | /**
|
---|
483 | * Tells whether we should filter out any deprecation-messages
|
---|
484 | * of the compiler out.
|
---|
485 | */
|
---|
486 | public void setSuppressDeprecation(boolean suppressDeprecation) {
|
---|
487 | this.suppressDeprecation = suppressDeprecation;
|
---|
488 | }
|
---|
489 |
|
---|
490 |
|
---|
491 | /**
|
---|
492 | * init-Method sets defaults from Properties. That way, when ant is called
|
---|
493 | * with arguments like -Dant.netrexxc.verbose=verbose5 one can easily take
|
---|
494 | * control of all netrexxc-tasks.
|
---|
495 | */
|
---|
496 | public void init() {
|
---|
497 | String p;
|
---|
498 |
|
---|
499 | if ((p = getProject().getProperty("ant.netrexxc.binary")) != null) {
|
---|
500 | this.binary = Project.toBoolean(p);
|
---|
501 | }
|
---|
502 | // classpath makes no sense
|
---|
503 | if ((p = getProject().getProperty("ant.netrexxc.comments")) != null) {
|
---|
504 | this.comments = Project.toBoolean(p);
|
---|
505 | }
|
---|
506 | if ((p = getProject().getProperty("ant.netrexxc.compact")) != null) {
|
---|
507 | this.compact = Project.toBoolean(p);
|
---|
508 | }
|
---|
509 | if ((p = getProject().getProperty("ant.netrexxc.compile")) != null) {
|
---|
510 | this.compile = Project.toBoolean(p);
|
---|
511 | }
|
---|
512 | if ((p = getProject().getProperty("ant.netrexxc.console")) != null) {
|
---|
513 | this.console = Project.toBoolean(p);
|
---|
514 | }
|
---|
515 | if ((p = getProject().getProperty("ant.netrexxc.crossref")) != null) {
|
---|
516 | this.crossref = Project.toBoolean(p);
|
---|
517 | }
|
---|
518 | if ((p = getProject().getProperty("ant.netrexxc.decimal")) != null) {
|
---|
519 | this.decimal = Project.toBoolean(p);
|
---|
520 | // destDir
|
---|
521 | }
|
---|
522 | if ((p = getProject().getProperty("ant.netrexxc.diag")) != null) {
|
---|
523 | this.diag = Project.toBoolean(p);
|
---|
524 | }
|
---|
525 | if ((p = getProject().getProperty("ant.netrexxc.explicit")) != null) {
|
---|
526 | this.explicit = Project.toBoolean(p);
|
---|
527 | }
|
---|
528 | if ((p = getProject().getProperty("ant.netrexxc.format")) != null) {
|
---|
529 | this.format = Project.toBoolean(p);
|
---|
530 | }
|
---|
531 | if ((p = getProject().getProperty("ant.netrexxc.keep")) != null) {
|
---|
532 | this.keep = Project.toBoolean(p);
|
---|
533 | }
|
---|
534 | if ((p = getProject().getProperty("ant.netrexxc.logo")) != null) {
|
---|
535 | this.logo = Project.toBoolean(p);
|
---|
536 | }
|
---|
537 | if ((p = getProject().getProperty("ant.netrexxc.replace")) != null) {
|
---|
538 | this.replace = Project.toBoolean(p);
|
---|
539 | }
|
---|
540 | if ((p = getProject().getProperty("ant.netrexxc.savelog")) != null) {
|
---|
541 | this.savelog = Project.toBoolean(p);
|
---|
542 | // srcDir
|
---|
543 | }
|
---|
544 | if ((p = getProject().getProperty("ant.netrexxc.sourcedir")) != null) {
|
---|
545 | this.sourcedir = Project.toBoolean(p);
|
---|
546 | }
|
---|
547 | if ((p = getProject().getProperty("ant.netrexxc.strictargs")) != null) {
|
---|
548 | this.strictargs = Project.toBoolean(p);
|
---|
549 | }
|
---|
550 | if ((p = getProject().getProperty("ant.netrexxc.strictassign")) != null) {
|
---|
551 | this.strictassign = Project.toBoolean(p);
|
---|
552 | }
|
---|
553 | if ((p = getProject().getProperty("ant.netrexxc.strictcase")) != null) {
|
---|
554 | this.strictcase = Project.toBoolean(p);
|
---|
555 | }
|
---|
556 | if ((p = getProject().getProperty("ant.netrexxc.strictimport")) != null) {
|
---|
557 | this.strictimport = Project.toBoolean(p);
|
---|
558 | }
|
---|
559 | if ((p = getProject().getProperty("ant.netrexxc.strictprops")) != null) {
|
---|
560 | this.strictprops = Project.toBoolean(p);
|
---|
561 | }
|
---|
562 | if ((p = getProject().getProperty("ant.netrexxc.strictsignal")) != null) {
|
---|
563 | this.strictsignal = Project.toBoolean(p);
|
---|
564 | }
|
---|
565 | if ((p = getProject().getProperty("ant.netrexxc.symbols")) != null) {
|
---|
566 | this.symbols = Project.toBoolean(p);
|
---|
567 | }
|
---|
568 | if ((p = getProject().getProperty("ant.netrexxc.time")) != null) {
|
---|
569 | this.time = Project.toBoolean(p);
|
---|
570 | }
|
---|
571 | if ((p = getProject().getProperty("ant.netrexxc.trace")) != null) {
|
---|
572 | setTrace(p);
|
---|
573 | }
|
---|
574 | if ((p = getProject().getProperty("ant.netrexxc.utf8")) != null) {
|
---|
575 | this.utf8 = Project.toBoolean(p);
|
---|
576 | }
|
---|
577 | if ((p = getProject().getProperty("ant.netrexxc.verbose")) != null) {
|
---|
578 | setVerbose(p);
|
---|
579 | }
|
---|
580 | if ((p = getProject().getProperty("ant.netrexxc.suppressMethodArgumentNotUsed")) != null) {
|
---|
581 | this.suppressMethodArgumentNotUsed = Project.toBoolean(p);
|
---|
582 | }
|
---|
583 | if ((p = getProject().getProperty("ant.netrexxc.suppressPrivatePropertyNotUsed")) != null) {
|
---|
584 | this.suppressPrivatePropertyNotUsed = Project.toBoolean(p);
|
---|
585 | }
|
---|
586 | if ((p = getProject().getProperty("ant.netrexxc.suppressVariableNotUsed")) != null) {
|
---|
587 | this.suppressVariableNotUsed = Project.toBoolean(p);
|
---|
588 | }
|
---|
589 | if ((p = getProject().getProperty("ant.netrexxc.suppressExceptionNotSignalled")) != null) {
|
---|
590 | this.suppressExceptionNotSignalled = Project.toBoolean(p);
|
---|
591 | }
|
---|
592 | if ((p = getProject().getProperty("ant.netrexxc.suppressDeprecation")) != null) {
|
---|
593 | this.suppressDeprecation = Project.toBoolean(p);
|
---|
594 | }
|
---|
595 | }
|
---|
596 |
|
---|
597 |
|
---|
598 | /** Executes the task - performs the actual compiler call. */
|
---|
599 | public void execute() throws BuildException {
|
---|
600 |
|
---|
601 | // first off, make sure that we've got a srcdir and destdir
|
---|
602 | if (srcDir == null || destDir == null) {
|
---|
603 | throw new BuildException("srcDir and destDir attributes must be set!");
|
---|
604 | }
|
---|
605 |
|
---|
606 | // scan source and dest dirs to build up both copy lists and
|
---|
607 | // compile lists
|
---|
608 | // scanDir(srcDir, destDir);
|
---|
609 | DirectoryScanner ds = getDirectoryScanner(srcDir);
|
---|
610 |
|
---|
611 | String[] files = ds.getIncludedFiles();
|
---|
612 |
|
---|
613 | scanDir(srcDir, destDir, files);
|
---|
614 |
|
---|
615 | // copy the source and support files
|
---|
616 | copyFilesToDestination();
|
---|
617 |
|
---|
618 | // compile the source files
|
---|
619 | if (compileList.size() > 0) {
|
---|
620 | log("Compiling " + compileList.size() + " source file"
|
---|
621 | + (compileList.size() == 1 ? "" : "s")
|
---|
622 | + " to " + destDir);
|
---|
623 | doNetRexxCompile();
|
---|
624 | }
|
---|
625 | }
|
---|
626 |
|
---|
627 |
|
---|
628 | /**
|
---|
629 | * Scans the directory looking for source files to be compiled and support
|
---|
630 | * files to be copied.
|
---|
631 | */
|
---|
632 | private void scanDir(File srcDir, File destDir, String[] files) {
|
---|
633 | for (int i = 0; i < files.length; i++) {
|
---|
634 | File srcFile = new File(srcDir, files[i]);
|
---|
635 | File destFile = new File(destDir, files[i]);
|
---|
636 | String filename = files[i];
|
---|
637 | // if it's a non source file, copy it if a later date than the
|
---|
638 | // dest
|
---|
639 | // if it's a source file, see if the destination class file
|
---|
640 | // needs to be recreated via compilation
|
---|
641 | if (filename.toLowerCase().endsWith(".nrx")) {
|
---|
642 | File classFile =
|
---|
643 | new File(destDir,
|
---|
644 | filename.substring(0, filename.lastIndexOf('.')) + ".class");
|
---|
645 |
|
---|
646 | if (!compile || srcFile.lastModified() > classFile.lastModified()) {
|
---|
647 | filecopyList.put(srcFile.getAbsolutePath(), destFile.getAbsolutePath());
|
---|
648 | compileList.addElement(destFile.getAbsolutePath());
|
---|
649 | }
|
---|
650 | } else {
|
---|
651 | if (srcFile.lastModified() > destFile.lastModified()) {
|
---|
652 | filecopyList.put(srcFile.getAbsolutePath(), destFile.getAbsolutePath());
|
---|
653 | }
|
---|
654 | }
|
---|
655 | }
|
---|
656 | }
|
---|
657 |
|
---|
658 |
|
---|
659 | /** Copy eligible files from the srcDir to destDir */
|
---|
660 | private void copyFilesToDestination() {
|
---|
661 | if (filecopyList.size() > 0) {
|
---|
662 | log("Copying " + filecopyList.size() + " file"
|
---|
663 | + (filecopyList.size() == 1 ? "" : "s")
|
---|
664 | + " to " + destDir.getAbsolutePath());
|
---|
665 |
|
---|
666 | Enumeration e = filecopyList.keys();
|
---|
667 |
|
---|
668 | while (e.hasMoreElements()) {
|
---|
669 | String fromFile = (String) e.nextElement();
|
---|
670 | String toFile = (String) filecopyList.get(fromFile);
|
---|
671 |
|
---|
672 | try {
|
---|
673 | getProject().copyFile(fromFile, toFile);
|
---|
674 | } catch (IOException ioe) {
|
---|
675 | String msg = "Failed to copy " + fromFile + " to " + toFile
|
---|
676 | + " due to " + ioe.getMessage();
|
---|
677 |
|
---|
678 | throw new BuildException(msg, ioe);
|
---|
679 | }
|
---|
680 | }
|
---|
681 | }
|
---|
682 | }
|
---|
683 |
|
---|
684 |
|
---|
685 | /** Performs a compile using the NetRexx 1.1.x compiler */
|
---|
686 | private void doNetRexxCompile() throws BuildException {
|
---|
687 | log("Using NetRexx compiler", Project.MSG_VERBOSE);
|
---|
688 |
|
---|
689 | String classpath = getCompileClasspath();
|
---|
690 | StringBuffer compileOptions = new StringBuffer();
|
---|
691 |
|
---|
692 | // create an array of strings for input to the compiler: one array
|
---|
693 | // comes from the compile options, the other from the compileList
|
---|
694 | String[] compileOptionsArray = getCompileOptionsAsArray();
|
---|
695 | String[] fileListArray = new String[compileList.size()];
|
---|
696 | Enumeration e = compileList.elements();
|
---|
697 | int j = 0;
|
---|
698 |
|
---|
699 | while (e.hasMoreElements()) {
|
---|
700 | fileListArray[j] = (String) e.nextElement();
|
---|
701 | j++;
|
---|
702 | }
|
---|
703 | // create a single array of arguments for the compiler
|
---|
704 | String[] compileArgs = new String[compileOptionsArray.length + fileListArray.length];
|
---|
705 |
|
---|
706 | for (int i = 0; i < compileOptionsArray.length; i++) {
|
---|
707 | compileArgs[i] = compileOptionsArray[i];
|
---|
708 | }
|
---|
709 | for (int i = 0; i < fileListArray.length; i++) {
|
---|
710 | compileArgs[i + compileOptionsArray.length] = fileListArray[i];
|
---|
711 | }
|
---|
712 |
|
---|
713 | // print nice output about what we are doing for the log
|
---|
714 | compileOptions.append("Compilation args: ");
|
---|
715 | for (int i = 0; i < compileOptionsArray.length; i++) {
|
---|
716 | compileOptions.append(compileOptionsArray[i]);
|
---|
717 | compileOptions.append(" ");
|
---|
718 | }
|
---|
719 | log(compileOptions.toString(), Project.MSG_VERBOSE);
|
---|
720 |
|
---|
721 | String eol = System.getProperty("line.separator");
|
---|
722 | StringBuffer niceSourceList = new StringBuffer("Files to be compiled:" + eol);
|
---|
723 |
|
---|
724 | for (int i = 0; i < compileList.size(); i++) {
|
---|
725 | niceSourceList.append(" ");
|
---|
726 | niceSourceList.append(compileList.elementAt(i).toString());
|
---|
727 | niceSourceList.append(eol);
|
---|
728 | }
|
---|
729 |
|
---|
730 | log(niceSourceList.toString(), Project.MSG_VERBOSE);
|
---|
731 |
|
---|
732 | // need to set java.class.path property and restore it later
|
---|
733 | // since the NetRexx compiler has no option for the classpath
|
---|
734 | String currentClassPath = System.getProperty("java.class.path");
|
---|
735 | Properties currentProperties = System.getProperties();
|
---|
736 |
|
---|
737 | currentProperties.put("java.class.path", classpath);
|
---|
738 |
|
---|
739 | try {
|
---|
740 | StringWriter out = new StringWriter();
|
---|
741 | int rc =
|
---|
742 | COM.ibm.netrexx.process.NetRexxC.main(new Rexx(compileArgs), new PrintWriter(out));
|
---|
743 | String sdir = srcDir.getAbsolutePath();
|
---|
744 | String ddir = destDir.getAbsolutePath();
|
---|
745 | boolean doReplace = !(sdir.equals(ddir));
|
---|
746 | int dlen = ddir.length();
|
---|
747 | String l;
|
---|
748 | BufferedReader in = new BufferedReader(new StringReader(out.toString()));
|
---|
749 |
|
---|
750 | log("replacing destdir '" + ddir + "' through sourcedir '"
|
---|
751 | + sdir + "'", Project.MSG_VERBOSE);
|
---|
752 | while ((l = in.readLine()) != null) {
|
---|
753 | int idx;
|
---|
754 |
|
---|
755 | while (doReplace && ((idx = l.indexOf(ddir)) != -1)) {
|
---|
756 | // path is mentioned in the message
|
---|
757 | l = (new StringBuffer(l)).replace(idx, idx + dlen, sdir).toString();
|
---|
758 | }
|
---|
759 | // verbose level logging for suppressed messages
|
---|
760 | if (suppressMethodArgumentNotUsed
|
---|
761 | && l.indexOf(MSG_METHOD_ARGUMENT_NOT_USED) != -1) {
|
---|
762 | log(l, Project.MSG_VERBOSE);
|
---|
763 | } else if (suppressPrivatePropertyNotUsed
|
---|
764 | && l.indexOf(MSG_PRIVATE_PROPERTY_NOT_USED) != -1) {
|
---|
765 | log(l, Project.MSG_VERBOSE);
|
---|
766 | } else if (suppressVariableNotUsed
|
---|
767 | && l.indexOf(MSG_VARIABLE_NOT_USED) != -1) {
|
---|
768 | log(l, Project.MSG_VERBOSE);
|
---|
769 | } else if (suppressExceptionNotSignalled
|
---|
770 | && l.indexOf(MSG_EXCEPTION_NOT_SIGNALLED) != -1) {
|
---|
771 | log(l, Project.MSG_VERBOSE);
|
---|
772 | } else if (suppressDeprecation
|
---|
773 | && l.indexOf(MSG_DEPRECATION) != -1) {
|
---|
774 | log(l, Project.MSG_VERBOSE);
|
---|
775 | } else if (l.indexOf("Error:") != -1) {
|
---|
776 | // error level logging for compiler errors
|
---|
777 | log(l, Project.MSG_ERR);
|
---|
778 | } else if (l.indexOf("Warning:") != -1) {
|
---|
779 | // warning for all warning messages
|
---|
780 | log(l, Project.MSG_WARN);
|
---|
781 | } else {
|
---|
782 | log(l, Project.MSG_INFO); // info level for the rest.
|
---|
783 | }
|
---|
784 | }
|
---|
785 | if (rc > 1) {
|
---|
786 | throw new BuildException("Compile failed, messages should "
|
---|
787 | + "have been provided.");
|
---|
788 | }
|
---|
789 | } catch (IOException ioe) {
|
---|
790 | throw new BuildException("Unexpected IOException while "
|
---|
791 | + "playing with Strings", ioe);
|
---|
792 | } finally {
|
---|
793 | // need to reset java.class.path property
|
---|
794 | // since the NetRexx compiler has no option for the classpath
|
---|
795 | currentProperties = System.getProperties();
|
---|
796 | currentProperties.put("java.class.path", currentClassPath);
|
---|
797 | }
|
---|
798 |
|
---|
799 | }
|
---|
800 |
|
---|
801 |
|
---|
802 | /** Builds the compilation classpath. */
|
---|
803 | private String getCompileClasspath() {
|
---|
804 | StringBuffer classpath = new StringBuffer();
|
---|
805 |
|
---|
806 | // add dest dir to classpath so that previously compiled and
|
---|
807 | // untouched classes are on classpath
|
---|
808 | classpath.append(destDir.getAbsolutePath());
|
---|
809 |
|
---|
810 | // add our classpath to the mix
|
---|
811 | if (this.classpath != null) {
|
---|
812 | addExistingToClasspath(classpath, this.classpath);
|
---|
813 | }
|
---|
814 |
|
---|
815 | // add the system classpath
|
---|
816 | // addExistingToClasspath(classpath,System.getProperty("java.class.path"));
|
---|
817 | return classpath.toString();
|
---|
818 | }
|
---|
819 |
|
---|
820 |
|
---|
821 | /** This */
|
---|
822 | private String[] getCompileOptionsAsArray() {
|
---|
823 | Vector options = new Vector();
|
---|
824 |
|
---|
825 | options.addElement(binary ? "-binary" : "-nobinary");
|
---|
826 | options.addElement(comments ? "-comments" : "-nocomments");
|
---|
827 | options.addElement(compile ? "-compile" : "-nocompile");
|
---|
828 | options.addElement(compact ? "-compact" : "-nocompact");
|
---|
829 | options.addElement(console ? "-console" : "-noconsole");
|
---|
830 | options.addElement(crossref ? "-crossref" : "-nocrossref");
|
---|
831 | options.addElement(decimal ? "-decimal" : "-nodecimal");
|
---|
832 | options.addElement(diag ? "-diag" : "-nodiag");
|
---|
833 | options.addElement(explicit ? "-explicit" : "-noexplicit");
|
---|
834 | options.addElement(format ? "-format" : "-noformat");
|
---|
835 | options.addElement(keep ? "-keep" : "-nokeep");
|
---|
836 | options.addElement(logo ? "-logo" : "-nologo");
|
---|
837 | options.addElement(replace ? "-replace" : "-noreplace");
|
---|
838 | options.addElement(savelog ? "-savelog" : "-nosavelog");
|
---|
839 | options.addElement(sourcedir ? "-sourcedir" : "-nosourcedir");
|
---|
840 | options.addElement(strictargs ? "-strictargs" : "-nostrictargs");
|
---|
841 | options.addElement(strictassign ? "-strictassign" : "-nostrictassign");
|
---|
842 | options.addElement(strictcase ? "-strictcase" : "-nostrictcase");
|
---|
843 | options.addElement(strictimport ? "-strictimport" : "-nostrictimport");
|
---|
844 | options.addElement(strictprops ? "-strictprops" : "-nostrictprops");
|
---|
845 | options.addElement(strictsignal ? "-strictsignal" : "-nostrictsignal");
|
---|
846 | options.addElement(symbols ? "-symbols" : "-nosymbols");
|
---|
847 | options.addElement(time ? "-time" : "-notime");
|
---|
848 | options.addElement("-" + trace);
|
---|
849 | options.addElement(utf8 ? "-utf8" : "-noutf8");
|
---|
850 | options.addElement("-" + verbose);
|
---|
851 |
|
---|
852 | String[] results = new String[options.size()];
|
---|
853 |
|
---|
854 | options.copyInto(results);
|
---|
855 | return results;
|
---|
856 | }
|
---|
857 |
|
---|
858 |
|
---|
859 | /**
|
---|
860 | * Takes a classpath-like string, and adds each element of this string to
|
---|
861 | * a new classpath, if the components exist. Components that don't exist,
|
---|
862 | * aren't added. We do this, because jikes issues warnings for
|
---|
863 | * non-existant files/dirs in his classpath, and these warnings are pretty
|
---|
864 | * annoying.
|
---|
865 | *
|
---|
866 | * @param target - target classpath
|
---|
867 | * @param source - source classpath to get file objects.
|
---|
868 | */
|
---|
869 | private void addExistingToClasspath(StringBuffer target, String source) {
|
---|
870 | StringTokenizer tok = new StringTokenizer(source,
|
---|
871 | System.getProperty("path.separator"), false);
|
---|
872 |
|
---|
873 | while (tok.hasMoreTokens()) {
|
---|
874 | File f = getProject().resolveFile(tok.nextToken());
|
---|
875 |
|
---|
876 | if (f.exists()) {
|
---|
877 | target.append(File.pathSeparator);
|
---|
878 | target.append(f.getAbsolutePath());
|
---|
879 | } else {
|
---|
880 | log("Dropping from classpath: "
|
---|
881 | + f.getAbsolutePath(), Project.MSG_VERBOSE);
|
---|
882 | }
|
---|
883 | }
|
---|
884 |
|
---|
885 | }
|
---|
886 |
|
---|
887 |
|
---|
888 | public static class TraceAttr extends EnumeratedAttribute {
|
---|
889 | public String[] getValues() {
|
---|
890 | return new String[]{"trace", "trace1", "trace2", "notrace"};
|
---|
891 | }
|
---|
892 | }
|
---|
893 |
|
---|
894 |
|
---|
895 | public static class VerboseAttr extends EnumeratedAttribute {
|
---|
896 | public String[] getValues() {
|
---|
897 | return new String[]{"verbose", "verbose0", "verbose1",
|
---|
898 | "verbose2", "verbose3", "verbose4",
|
---|
899 | "verbose5", "noverbose"};
|
---|
900 | }
|
---|
901 | }
|
---|
902 | }
|
---|
903 |
|
---|