Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. /* *******************************************************************
  2. * Copyright (c) 2000-2001 Xerox Corporation.
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v 2.0
  6. * which accompanies this distribution and is available at
  7. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  8. *
  9. * Contributors:
  10. * Xerox/PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.tools.ant.taskdefs;
  13. import java.io.File;
  14. import java.util.Arrays;
  15. import java.util.Collections;
  16. import java.util.HashSet;
  17. import java.util.List;
  18. import java.util.Set;
  19. import java.util.StringTokenizer;
  20. import java.util.Vector;
  21. import org.apache.tools.ant.BuildException;
  22. import org.apache.tools.ant.Location;
  23. import org.apache.tools.ant.Project;
  24. import org.apache.tools.ant.taskdefs.MatchingTask;
  25. import org.apache.tools.ant.types.Commandline;
  26. import org.apache.tools.ant.types.Path;
  27. import org.apache.tools.ant.types.Reference;
  28. import org.aspectj.bridge.AbortException;
  29. import org.aspectj.bridge.IMessage;
  30. import org.aspectj.bridge.IMessageHandler;
  31. import org.aspectj.bridge.IMessageHolder;
  32. import org.aspectj.bridge.MessageHandler;
  33. import org.aspectj.tools.ajc.Main;
  34. import org.aspectj.tools.ajc.Main.MessagePrinter;
  35. import org.aspectj.util.FileUtil;
  36. /**
  37. * Main taskdef class for the AspectJ 1.0 compiler, <code>ajc</code>.
  38. * See the README and examples/build.xml for more information.
  39. */
  40. public class Ajc10 extends MatchingTask {
  41. private static final List<String> VALID_XOPTIONS;
  42. static {
  43. String[] xs = new String[]
  44. { "lint", "serializableAspects", "targetNearSource", "OcodeSize",
  45. "incrementalFile" };
  46. VALID_XOPTIONS = Collections.unmodifiableList(Arrays.asList(xs));
  47. }
  48. //protected boolean version;
  49. protected boolean source14;
  50. protected Set ignoredOptions;
  51. protected Commandline cmd;
  52. protected Commandline vmcmd;
  53. private int threads = -1;
  54. private File destdir;
  55. private File workingdir;
  56. private Path internalclasspath;
  57. private Path classpath;
  58. private Path bootclasspath;
  59. private Path extdirs;
  60. private Path srcdir;
  61. private List<File> argfiles;
  62. private boolean fork;
  63. private boolean failonerror;
  64. private boolean verbose;
  65. private String encoding;
  66. private String source;
  67. public Ajc10() {
  68. reset();
  69. }
  70. // ------------------------- options
  71. // find option types and whether ignored:
  72. // sed -n '/void set/p' Ajc.java | sed 's/.*\/\/ //' | sort -u
  73. // sed -n '/ignoredOptions/d;/ignored/p' Ajc.java
  74. // each option may be "ignored" and is one+ of:
  75. // ajc-old used to be an ajc option
  76. // ajc-only only an option for ajc, not javac
  77. // ajc-taskdef only only an option for ajc taskdef, not ajc
  78. // javac-also also an option in javac
  79. // eajc-also
  80. // ------------------------- options in order per ajc output
  81. public void setVerbose(boolean verbose) { // javac-also eajc-also docDone
  82. setif(verbose, "-verbose");
  83. this.verbose = verbose;
  84. }
  85. public void setVersion(boolean version) { // javac-also eajc-also docDone
  86. // let the compiler handle it
  87. if (version) {
  88. setif(true, "-version");
  89. }
  90. //this.version = version;
  91. }
  92. public void setNocomments(boolean nocomments) { // ajc-only not-eajc docDone
  93. if (nocomments) {
  94. ignore("-nocomments");
  95. }
  96. //setif(nocomments, "-nocomments");
  97. }
  98. public void setEmacssym(boolean input) { // ajc-only eajc-also docDone
  99. setif(input, "-emacssym");
  100. }
  101. public void setUsejavac(boolean input) { // ajc-only not-eajc docDone
  102. if (input) {
  103. ignore("-usejavac");
  104. }
  105. //setif(input, "-usejavac");
  106. }
  107. public void setPreprocess(boolean preprocess) { // ajc-only not-eajc docDone
  108. if (preprocess) {
  109. ignore("-preprocess");
  110. //setif(preprocess, "-preprocess");
  111. }
  112. }
  113. public void setWorkingdir(String workingdir) { // ajc-only not-eajc ocDone
  114. ignore("-workingdir");
  115. //this.workingdir = project.resolveFile(workingdir);
  116. }
  117. public void setDestdir(String destdir) { // javac-also eajc-also docDone
  118. this.destdir = project.resolveFile(destdir);
  119. }
  120. public void setOptimize(boolean optimize) { // javac-also ignored docDone
  121. setif(optimize, "-O");
  122. }
  123. public void setClasspath(Path classpath) { // javac-also eajc-also docDone
  124. if (this.classpath == null) {
  125. this.classpath = classpath;
  126. } else {
  127. this.classpath.append(classpath);
  128. }
  129. }
  130. public Path createClasspath() { // javac-also docDone
  131. if (classpath == null) {
  132. classpath = new Path(project);
  133. }
  134. return classpath.createPath();
  135. }
  136. public void setClasspathref(Reference classpathref) { // javac-also docDone
  137. createClasspath().setRefid(classpathref);
  138. }
  139. public void setBootclasspath(Path bootclasspath) { // javac-also not-eajc docDone
  140. ignore("bootclasspath"); // XXX may jury-rig
  141. // if (this.bootclasspath == null) {
  142. // this.bootclasspath = bootclasspath;
  143. // } else {
  144. // this.bootclasspath.append(bootclasspath);
  145. // }
  146. }
  147. public Path createBootclasspath() { // javac-also not-eajc docDone
  148. ignore("bootclasspath"); // XXX may jury-rig
  149. if (bootclasspath == null) {
  150. bootclasspath = new Path(project);
  151. }
  152. return bootclasspath.createPath();
  153. }
  154. public void setBootclasspathref(Reference bootclasspathref) { // javac-also not-eajc docDone
  155. ignore("bootclasspath"); // XXX may jury-rig
  156. // createBootclasspath().setRefid(bootclasspathref);
  157. }
  158. public void setExtdirs(Path extdirs) { // javac-also not-eajc docDone
  159. ignore("-extdirs");
  160. // if (this.extdirs == null) {
  161. // this.extdirs = extdirs;
  162. // } else {
  163. // this.extdirs.append(extdirs);
  164. // }
  165. }
  166. public Path createExtdirs() { // javac-also not-eajc docDone
  167. ignore("-extdirs");
  168. if (extdirs == null) {
  169. extdirs = new Path(project);
  170. }
  171. return extdirs.createPath();
  172. }
  173. public void setArgfile(File argfile) { // ajc-only eajc-also docDone
  174. if (argfiles == null) {
  175. argfiles = new Vector<>();
  176. }
  177. argfiles.add(argfile);
  178. }
  179. public void setArgfiles(String argfiles) { // ajc-only eajc-also docDone
  180. StringTokenizer tok = new StringTokenizer(argfiles, ", ", false);
  181. if (tok.hasMoreTokens() && this.argfiles == null) {
  182. this.argfiles = new Vector<>();
  183. }
  184. while (tok.hasMoreTokens()) {
  185. this.argfiles.add(project.resolveFile(tok.nextToken().trim()));
  186. }
  187. }
  188. public void setEncoding(String encoding) { // ignored eajc-also docDone
  189. // XXX add support
  190. //ignore("encoding");
  191. this.encoding = encoding;
  192. }
  193. public void setSource(String input) { // javac-also (Ant 1.4) eajc-also docDone
  194. source = input;
  195. //source14 = "1.4".equals(input); // XXX todo
  196. }
  197. public void setLenient(boolean input) { // ajc-only not-eajc docDone
  198. ignore("-lenient");
  199. //setif(input, "-lenient");
  200. }
  201. public void setStrict(boolean input) { // ajc-only not-eajc docDone
  202. ignore("-strict");
  203. //setif(input, "-strict");
  204. }
  205. public void setPorting(boolean input) { // ajc-only not-eajc docDone
  206. ignore("-porting");
  207. //setif(input, "-porting");
  208. }
  209. public void setX(String input) { // ajc-only eajc-also docDone
  210. StringTokenizer tokens = new StringTokenizer(input, ",", false);
  211. while (tokens.hasMoreTokens()) {
  212. String token = tokens.nextToken().trim();
  213. if (1 < token.length()) {
  214. if (VALID_XOPTIONS.contains(token)) {
  215. setif(true, "-X" + token);
  216. } else {
  217. ignore("-X" + token);
  218. }
  219. }
  220. }
  221. }
  222. // ------------------------- vestigial
  223. public void setThreads(int threads) { // ajc-old docDone ignored
  224. ignore("-threads");
  225. //this.threads = threads;
  226. }
  227. public void setDumpstack(boolean dumpstack) { // ajc-old
  228. ignore("-dumpstack");
  229. //setif(dumpstack, "-dumpstack");
  230. }
  231. // ------------------------- specific to taskdef
  232. public void setInternalclasspath(Path internalclasspath) { // ajc-taskdef only
  233. if (this.internalclasspath == null) {
  234. this.internalclasspath = internalclasspath;
  235. } else {
  236. this.internalclasspath.append(internalclasspath);
  237. }
  238. }
  239. public Path createInternalclasspath() { // ajc-taskdef only
  240. if (internalclasspath == null) {
  241. internalclasspath = new Path(project);
  242. }
  243. return internalclasspath.createPath();
  244. }
  245. public void setInternalclasspathref(Reference internalclasspathref) { // ajc-taskdef only
  246. createInternalclasspath().setRefid(internalclasspathref);
  247. }
  248. public void setSrcdir(Path srcdir) { // javac-also eajc-also docDone
  249. if (this.srcdir == null) {
  250. this.srcdir = srcdir;
  251. } else {
  252. this.srcdir.append(srcdir);
  253. }
  254. }
  255. public Path createSrc() { // javac-also eajc-also docDone
  256. return createSrcdir();
  257. }
  258. public Path createSrcdir() { // javac-also eajc-also docDone
  259. if (srcdir == null) {
  260. srcdir = new Path(project);
  261. }
  262. return srcdir.createPath();
  263. }
  264. public void setFork(boolean fork) { // ajc-only not-eajc docDone
  265. ignore("fork");
  266. //this.fork = fork;
  267. }
  268. public void setFailonerror(boolean failonerror) { // javac-also docDone
  269. this.failonerror = failonerror;
  270. }
  271. public void setMaxmemory(String max) { // ajc-taskdef only docDone
  272. ignore("-maxmemory");
  273. // we do not run under 1.1 anyway...
  274. // createJvmarg().setValue((Project.getJavaVersion().
  275. // startsWith("1.1") ?
  276. // "-mx" : "-Xmx") +max);
  277. }
  278. public void setJvmarg(String input) { // ajc-taskdef only docDone
  279. ignore("jvmarg"); // XXX fork
  280. //vmcmd.createArgument().setValue(input);
  281. }
  282. public Commandline.Argument createJvmarg() { // ajc-taskdef only docDone
  283. ignore("jvmarg"); // XXX fork
  284. return vmcmd.createArgument();
  285. }
  286. // ------------------------- javac task compatibility
  287. public void setNosymbols(boolean nosymbols) { // todo remove?
  288. ignore("-nosymbols");
  289. //setif(nosymbols, "-nosymbols");
  290. }
  291. public void setDebug(boolean debug) { // javac-also eajc-also docDone
  292. setif(debug, "-g"); // todo: changed from -debug
  293. }
  294. public void setDeprecation(boolean deprecation) { // javac-also eajc-also docDone
  295. setif(deprecation, "-deprecation"); // XXX eajc: also "warn:deprecation"
  296. }
  297. // ------------------------- javac task compatibility - ignored
  298. public void setTarget(String target) { // javac-also ignored docDone
  299. ignore("target"); // todo: ajc accepts but doesn't use - pass in?
  300. }
  301. public void setDepend(String depend) { // javac-also ignored docDone
  302. ignore("depend");
  303. }
  304. public void setIncludeantruntime(boolean includeAntruntime) { // javac-also ignored docDone
  305. ignore("includeantruntime");
  306. }
  307. public void setIncludejavaruntime(boolean includeJavaruntime ) { // javac-also ignored docDone
  308. ignore("includeJavaruntime");
  309. }
  310. // ------------------------- other state methods
  311. protected final void ignore(String attribute) {
  312. ignoredOptions.add(attribute);
  313. }
  314. public void backdoorSetFile(File file) {
  315. if (null != file) {
  316. cmd.createArgument().setFile(file);
  317. }
  318. }
  319. /** reset variables to permit gc */
  320. public void reset() {
  321. //version = false;
  322. source14 = false;
  323. ignoredOptions = new HashSet();
  324. cmd = new Commandline();
  325. vmcmd = new Commandline();
  326. threads = -1;
  327. destdir = null;
  328. workingdir = null;
  329. internalclasspath = null;
  330. classpath = null;
  331. bootclasspath = null;
  332. extdirs = null;
  333. srcdir = null;
  334. argfiles = null;
  335. fork = false;
  336. failonerror = true;
  337. encoding = null;
  338. source = null;
  339. }
  340. protected final void setif(boolean b, String flag) {
  341. if (b) cmd.createArgument().setValue(flag);
  342. }
  343. // ------------------------- operational methods
  344. @Override
  345. public void execute() throws BuildException {
  346. if (srcdir == null && argfiles == null) {
  347. throw new BuildException("one of srcdir or argfiles must be set!",
  348. location);
  349. }
  350. // if (threads != -1) {
  351. // cmd.createArgument().setValue("-threads");
  352. // cmd.createArgument().setValue(threads+"");
  353. // }
  354. // if (workingdir != null) {
  355. // cmd.createArgument().setValue("-workingdir");
  356. // cmd.createArgument().setFile(workingdir);
  357. // }
  358. if (destdir != null) {
  359. cmd.createArgument().setValue("-d");
  360. cmd.createArgument().setFile(destdir);
  361. }
  362. if (classpath != null) {
  363. cmd.createArgument().setValue("-classpath");
  364. cmd.createArgument().setPath(classpath);
  365. }
  366. if (bootclasspath != null) {
  367. cmd.createArgument().setValue("-bootclasspath");
  368. cmd.createArgument().setPath(bootclasspath);
  369. }
  370. if (extdirs != null) {
  371. cmd.createArgument().setValue("-extdirs");
  372. cmd.createArgument().setPath(extdirs);
  373. }
  374. if (null != encoding) {
  375. cmd.createArgument().setValue("-encoding");
  376. cmd.createArgument().setValue(encoding);
  377. }
  378. if (null != source) {
  379. cmd.createArgument().setValue("-source");
  380. cmd.createArgument().setValue(source);
  381. }
  382. int numargfiles = 0;
  383. if (argfiles != null) {
  384. for (Object o : argfiles) {
  385. String name = o + "";
  386. File argfile = project.resolveFile(name);
  387. if (check(argfile, name, false, location)) {
  388. cmd.createArgument().setValue("-argfile");
  389. cmd.createArgument().setFile(argfile);
  390. numargfiles++;
  391. }
  392. }
  393. }
  394. int numfiles = 0;
  395. if (srcdir != null) {
  396. // todo: ignore any srcdir if any argfiles and no explicit includes
  397. String[] dirs = srcdir.list();
  398. for (String value : dirs) {
  399. File dir = project.resolveFile(value);
  400. check(dir, value, true, location);
  401. String[] files = getDirectoryScanner(dir).getIncludedFiles();
  402. for (String s : files) {
  403. File file = new File(dir, s);
  404. if (FileUtil.hasSourceSuffix(file)) {
  405. cmd.createArgument().setFile(file);
  406. numfiles++;
  407. }
  408. }
  409. }
  410. }
  411. if ((null != ignoredOptions) && (ignoredOptions.size() > 0)) {
  412. log("The following attributes were ignored " + ignoredOptions,
  413. Project.MSG_WARN);
  414. if (ignoredOptions.contains("-preprocess")) {
  415. throw new BuildException("preprocess no longer supported");
  416. }
  417. }
  418. log("Compiling " + numfiles + " source and " +
  419. + numargfiles + " arg files"
  420. + (null == destdir ? "" : " to " + destdir.getPath()), Project.MSG_INFO);
  421. // here is the actual invocation
  422. //int result = (fork || (internalclasspath != null)) ? fork() : spoon();
  423. if (fork || (internalclasspath != null)) {
  424. log("WARNING: fork not supported", Project.MSG_WARN);
  425. }
  426. int result = spoon();
  427. if (result != 0) {
  428. String msg = "Compilation error: " + result;
  429. if (failonerror) {
  430. reset();
  431. throw new BuildException(msg);
  432. } else {
  433. log(msg, Project.MSG_WARN);
  434. }
  435. }
  436. reset(); // see throw above
  437. }
  438. // now leaving version to compiler - remove
  439. // protected void version(Path classpath) {
  440. // try {
  441. // Class main = findClass("org.aspectj.tools.ajc.Main",
  442. // classpath);
  443. // Method printVersion = main.getDeclaredMethod("printVersion",
  444. // new Class[]{});
  445. // printVersion.setAccessible(true);
  446. // printVersion.invoke(main.newInstance(), new Object[]{});
  447. // } catch (Exception e) {}
  448. // }
  449. //
  450. // protected Class findClass(String classname, Path classpathPath) {
  451. // String classpath = (classpathPath != null ?
  452. // classpathPath+"" : "").trim();
  453. // if (classpath.length() == 0) {
  454. // try {
  455. // return Class.forName(classname);
  456. // } catch (ClassNotFoundException e){}
  457. // }
  458. // List urls = new ArrayList();
  459. // for (StringTokenizer t = new StringTokenizer(classpath,
  460. // File.pathSeparator);
  461. // t.hasMoreTokens();) {
  462. // File f = new File(t.nextToken().trim());
  463. // try {
  464. // if (f.exists()) {
  465. // URL url = f.toURL();
  466. // if (url != null) urls.add(url);
  467. // }
  468. // } catch (MalformedURLException e) {}
  469. // }
  470. // if (urls.size() == 0) return null;
  471. // try {
  472. // return new URLClassLoader((URL[])urls.toArray
  473. // (new URL[urls.size()]),
  474. // null).loadClass(classname);
  475. // } catch (ClassNotFoundException e) {}
  476. // return null;
  477. // }
  478. // unused now, but leave in
  479. // protected int fork() throws BuildException {
  480. // Java java = (Java)project.createTask("java");
  481. // java.setTaskName(getTaskName());
  482. // Path compileClasspath;
  483. // if (internalclasspath != null) {
  484. // compileClasspath = internalclasspath;
  485. // compileClasspath.append(Path.systemClasspath);
  486. // } else {
  487. // compileClasspath = Path.systemClasspath;
  488. // }
  489. // //if (version) version(compileClasspath);
  490. // java.setClasspath(compileClasspath);
  491. // java.setClassname(FALSE_MAIN);
  492. // String[] args;
  493. // args = cmd.getArguments();
  494. // for (int i = 0; i < args.length; i++) {
  495. // java.createArg().setValue(args[i]);
  496. // }
  497. // args = vmcmd.getArguments();
  498. // for (int i = 0; i < args.length; i++) {
  499. // java.createJvmarg().setValue(args[i]);
  500. // }
  501. // java.setFork(fork);
  502. // // java handles its own verbose logging when forking
  503. // return java.executeJava();
  504. // }
  505. /** utility to render String[] for logging */
  506. public static String render(String[] args) {
  507. if (null == args) return "";
  508. StringBuilder sb = new StringBuilder();
  509. for (String arg : args) {
  510. sb.append(arg);
  511. sb.append(" ");
  512. }
  513. return sb.toString();
  514. }
  515. protected int spoon() throws BuildException {
  516. //if (version) version(null);
  517. int result = -1;
  518. final IMessageHolder holder;
  519. {
  520. MessageHandler handler = new MessageHandler();
  521. if (!verbose) {
  522. handler.ignore(IMessage.INFO);
  523. }
  524. final IMessageHandler delegate
  525. = verbose ? MessagePrinter.VERBOSE: MessagePrinter.TERSE;
  526. handler.setInterceptor(delegate);
  527. holder = handler;
  528. }
  529. try {
  530. String[] args = cmd.getCommandline();
  531. // XXX avoid rendering if not verbosely logging?
  532. log("Running in-process using "
  533. + Ajc10.render(cmd.getCommandline()), Project.MSG_VERBOSE);
  534. Main main = new Main();
  535. main.run(args, holder);
  536. int errs = holder.numMessages(IMessage.ERROR, true);
  537. if (0 < errs) {
  538. result = 1;
  539. } else {
  540. result = 0;
  541. }
  542. } catch (Throwable t) {
  543. while (t instanceof AbortException) {
  544. // check for "just quit -- message printed already"
  545. if (((AbortException)t).isSilent()) {
  546. t = null;
  547. break;
  548. }
  549. IMessage m = ((AbortException) t).getIMessage();
  550. if (null == m) {
  551. break;
  552. } else {
  553. Throwable tt = m.getThrown();
  554. if (null != tt) {
  555. t = tt;
  556. } else {
  557. break;
  558. }
  559. }
  560. }
  561. if (null != t) {
  562. // t.printStackTrace(); // let recipient print
  563. throw new BuildException("Compiler failure", t, location);
  564. }
  565. } finally {
  566. // now printing messages as we go, above
  567. // IMessage.Kind level = (verbose ? IMessage.INFO : IMessage.WARNING);
  568. // if (0 < holder.numMessages(level, true)) {
  569. // final String prefix = "";
  570. // final boolean printSummary = false;
  571. // MessageUtil.print(System.err,
  572. // holder,
  573. // prefix,
  574. // MessageUtil.MESSAGE_ALL,
  575. // (verbose ? MessageUtil.PICK_INFO_PLUS : MessageUtil.PICK_WARNING_PLUS),
  576. // printSummary);
  577. // }
  578. }
  579. return result;
  580. }
  581. protected final boolean check(File file, String name,
  582. boolean isDir, Location loc) {
  583. loc = loc != null ? loc : location;
  584. if (file == null) {
  585. throw new BuildException(name + " is null!", loc);
  586. }
  587. if (!file.exists()) {
  588. throw new BuildException(file + "doesn't exist!", loc);
  589. }
  590. if (isDir ^ file.isDirectory()) {
  591. String e = file + " should" + (isDir ? "" : "n't") +
  592. " be a directory!";
  593. throw new BuildException(e, loc);
  594. }
  595. return true;
  596. }
  597. }