You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AjdtCommand.java 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.ajdt.ajc;
  13. import org.aspectj.ajdt.internal.core.builder.*;
  14. import org.aspectj.bridge.*;
  15. import org.aspectj.weaver.Dump;
  16. import org.aspectj.org.eclipse.jdt.internal.core.builder.MissingSourceFileException;
  17. /**
  18. * ICommand adapter for the AspectJ compiler.
  19. * Not thread-safe.
  20. */
  21. public class AjdtCommand implements ICommand {
  22. /** Message String for any AbortException thrown from ICommand API's */
  23. public static final String ABORT_MESSAGE = "ABORT";
  24. // private boolean canRepeatCommand = true;
  25. AjBuildManager buildManager = null;
  26. String[] savedArgs = null;
  27. /**
  28. * Run AspectJ compiler, wrapping any exceptions thrown as
  29. * ABORT messages (containing ABORT_MESSAGE String).
  30. * @param args the String[] for the compiler
  31. * @param handler the IMessageHandler for any messages
  32. * @see org.aspectj.bridge.ICommand#runCommand(String[], IMessageHandler)
  33. * @return false if handler has errors or the command failed
  34. */
  35. public boolean runCommand(String[] args, IMessageHandler handler) {
  36. buildManager = new AjBuildManager(handler);
  37. savedArgs = new String[args.length];
  38. System.arraycopy(args, 0, savedArgs, 0, savedArgs.length);
  39. for (String arg : args) {
  40. // AMC - PR58681. No need to abort on -help as the Eclipse compiler does the right thing.
  41. // if ("-help".equals(args[i])) {
  42. // // should be info, but handler usually suppresses
  43. // MessageUtil.abort(handler, BuildArgParser.getUsage());
  44. // return true;
  45. // } else
  46. if ("-X".equals(arg)) {
  47. // should be info, but handler usually suppresses
  48. MessageUtil.abort(handler, BuildArgParser.getXOptionUsage());
  49. return true;
  50. }
  51. }
  52. return doCommand(handler, false);
  53. }
  54. /**
  55. * Run AspectJ compiler, wrapping any exceptions thrown as
  56. * ABORT messages (containing ABORT_MESSAGE String).
  57. * @param handler the IMessageHandler for any messages
  58. * @see org.aspectj.bridge.ICommand#repeatCommand(IMessageHandler)
  59. * @return false if handler has errors or the command failed
  60. */
  61. public boolean repeatCommand(IMessageHandler handler) {
  62. if (null == buildManager) {
  63. MessageUtil.abort(handler, "repeatCommand called before runCommand");
  64. return false;
  65. }
  66. return doCommand(handler, true);
  67. }
  68. /**
  69. * Delegate of both runCommand and repeatCommand.
  70. * This invokes the argument parser each time
  71. * (even when repeating).
  72. * If the parser detects errors, this signals an
  73. * abort with the usage message and returns false.
  74. * @param handler the IMessageHandler sink for any messages
  75. * @param repeat if true, do incremental build, else do batch build
  76. * @return false if handler has any errors or command failed
  77. */
  78. protected boolean doCommand(IMessageHandler handler, boolean repeat) {
  79. try {
  80. if (handler instanceof IMessageHolder) {
  81. Dump.saveMessageHolder((IMessageHolder) handler);
  82. }
  83. // buildManager.setMessageHandler(handler);
  84. CountingMessageHandler counter = new CountingMessageHandler(handler);
  85. if (counter.hasErrors()) {
  86. return false;
  87. }
  88. // regenerate configuration b/c world might have changed (?)
  89. AjBuildConfig config = genBuildConfig(savedArgs, counter);
  90. if (!config.shouldProceed()) {
  91. return true;
  92. }
  93. if (!config.hasSources()) {
  94. MessageUtil.error(counter, "no sources specified");
  95. }
  96. if (counter.hasErrors()) { // print usage for config errors
  97. String usage = BuildArgParser.getUsage();
  98. MessageUtil.abort(handler, usage);
  99. return false;
  100. }
  101. //System.err.println("errs: " + counter.hasErrors());
  102. boolean result = ((repeat
  103. ? buildManager.incrementalBuild(config, handler)
  104. : buildManager.batchBuild(config, handler))
  105. && !counter.hasErrors());
  106. Dump.dumpOnExit();
  107. return result;
  108. } catch (AbortException ae) {
  109. if (ae.isSilent()) {
  110. throw ae;
  111. } else {
  112. MessageUtil.abort(handler, ABORT_MESSAGE, ae);
  113. }
  114. } catch (MissingSourceFileException t) {
  115. MessageUtil.error(handler, t.getMessage());
  116. } catch (Throwable t) {
  117. MessageUtil.abort(handler, ABORT_MESSAGE, t);
  118. Dump.dumpWithException(t);
  119. }
  120. return false;
  121. }
  122. /**
  123. * This creates a build configuration for the arguments.
  124. * Errors reported to the handler:
  125. * <ol>
  126. * <li>The parser detects some directly</li>
  127. * <li>The parser grabs some from the error stream
  128. * emitted by its superclass</li>
  129. * <li>The configuration has a self-test</li>
  130. * </ol>
  131. * In the latter two cases, the errors do not have
  132. * a source location context for locating the error.
  133. */
  134. public static AjBuildConfig genBuildConfig(String[] args, CountingMessageHandler handler) {
  135. BuildArgParser parser = new BuildArgParser(handler);
  136. AjBuildConfig config = parser.genBuildConfig(args);
  137. ISourceLocation location = null;
  138. if (config.getConfigFile() != null) {
  139. location = new SourceLocation(config.getConfigFile(), 0);
  140. }
  141. String message = parser.getOtherMessages(true);
  142. if (null != message) {
  143. IMessage.Kind kind = inferKind(message);
  144. IMessage m = new Message(message, kind, null, location);
  145. handler.handleMessage(m);
  146. }
  147. // message = config.configErrors();
  148. // if (null != message) {
  149. // IMessage.Kind kind = inferKind(message);
  150. // IMessage m = new Message(message, kind, null, location);
  151. // handler.handleMessage(m);
  152. // }
  153. return config;
  154. }
  155. /** @return IMessage.WARNING unless message contains error or info */
  156. protected static IMessage.Kind inferKind(String message) { // XXX dubious
  157. if (message.contains("error")) {
  158. return IMessage.ERROR;
  159. } else if (message.contains("info")) {
  160. return IMessage.INFO;
  161. } else {
  162. return IMessage.WARNING;
  163. }
  164. }
  165. }