123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- /* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * PARC initial implementation
- * ******************************************************************/
-
-
- package org.aspectj.ajdt.ajc;
-
- import org.aspectj.ajdt.internal.core.builder.*;
- import org.aspectj.bridge.*;
- import org.aspectj.weaver.Dump;
- import org.aspectj.org.eclipse.jdt.internal.core.builder.MissingSourceFileException;
-
- /**
- * ICommand adapter for the AspectJ compiler.
- * Not thread-safe.
- */
- public class AjdtCommand implements ICommand {
-
- /** Message String for any AbortException thrown from ICommand API's */
- public static final String ABORT_MESSAGE = "ABORT";
-
- // private boolean canRepeatCommand = true;
-
- AjBuildManager buildManager = null;
- String[] savedArgs = null;
-
- /**
- * Run AspectJ compiler, wrapping any exceptions thrown as
- * ABORT messages (containing ABORT_MESSAGE String).
- * @param args the String[] for the compiler
- * @param handler the IMessageHandler for any messages
- * @see org.aspectj.bridge.ICommand#runCommand(String[], IMessageHandler)
- * @return false if handler has errors or the command failed
- */
- public boolean runCommand(String[] args, IMessageHandler handler) {
- buildManager = new AjBuildManager(handler);
- savedArgs = new String[args.length];
- System.arraycopy(args, 0, savedArgs, 0, savedArgs.length);
- return doCommand(handler, false);
- }
-
- /**
- * Run AspectJ compiler, wrapping any exceptions thrown as
- * ABORT messages (containing ABORT_MESSAGE String).
- * @param handler the IMessageHandler for any messages
- * @see org.aspectj.bridge.ICommand#repeatCommand(IMessageHandler)
- * @return false if handler has errors or the command failed
- */
- public boolean repeatCommand(IMessageHandler handler) {
- if (null == buildManager) {
- MessageUtil.abort(handler, "repeatCommand called before runCommand");
- return false;
- }
- return doCommand(handler, true);
- }
-
- /**
- * Delegate of both runCommand and repeatCommand.
- * This invokes the argument parser each time
- * (even when repeating).
- * If the parser detects errors, this signals an
- * abort with the usage message and returns false.
- * @param handler the IMessageHandler sink for any messages
- * @param repeat if true, do incremental build, else do batch build
- * @return false if handler has any errors or command failed
- */
- protected boolean doCommand(IMessageHandler handler, boolean repeat) {
- try {
- if (handler instanceof IMessageHolder) {
- Dump.saveMessageHolder((IMessageHolder) handler);
- }
- // buildManager.setMessageHandler(handler);
- CountingMessageHandler counter = new CountingMessageHandler(handler);
- if (counter.hasErrors()) {
- return false;
- }
- // regenerate configuration b/c world might have changed (?)
- AjBuildConfig config = genBuildConfig(savedArgs, counter);
- if (!config.shouldProceed()) {
- return true;
- }
- if (!config.hasSources()) {
- MessageUtil.error(counter, "no sources specified");
- }
- if (counter.hasErrors()) {
- // Do *not* print usage for config errors (just like ECJ does it). Otherwise the user would have to
- // scroll up several screens in order to actually see the error messages.
- // String usage = BuildArgParser.getUsage();
- // MessageUtil.abort(handler, usage);
- return false;
- }
- //System.err.println("errs: " + counter.hasErrors());
- boolean result = ((repeat
- ? buildManager.incrementalBuild(config, handler)
- : buildManager.batchBuild(config, handler))
- && !counter.hasErrors());
- Dump.dumpOnExit();
- return result;
- } catch (AbortException ae) {
- if (ae.isSilent()) {
- throw ae;
- } else {
- MessageUtil.abort(handler, ABORT_MESSAGE, ae);
- }
- } catch (MissingSourceFileException t) {
- MessageUtil.error(handler, t.getMessage());
- } catch (Throwable t) {
- MessageUtil.abort(handler, ABORT_MESSAGE, t);
- Dump.dumpWithException(t);
- }
- return false;
- }
-
- /**
- * This creates a build configuration for the arguments.
- * Errors reported to the handler:
- * <ol>
- * <li>The parser detects some directly</li>
- * <li>The parser grabs some from the error stream
- * emitted by its superclass</li>
- * <li>The configuration has a self-test</li>
- * </ol>
- * In the latter two cases, the errors do not have
- * a source location context for locating the error.
- */
- public static AjBuildConfig genBuildConfig(String[] args, CountingMessageHandler handler) {
- BuildArgParser parser = new BuildArgParser(handler);
- AjBuildConfig config = parser.genBuildConfig(args);
-
- ISourceLocation location = null;
- if (config.getConfigFile() != null) {
- location = new SourceLocation(config.getConfigFile(), 0);
- }
-
- String message = parser.getOtherMessages(true);
- if (null != message) {
- IMessage.Kind kind = inferKind(message);
- IMessage m = new Message(message, kind, null, location);
- handler.handleMessage(m);
- }
- // message = config.configErrors();
- // if (null != message) {
- // IMessage.Kind kind = inferKind(message);
- // IMessage m = new Message(message, kind, null, location);
- // handler.handleMessage(m);
- // }
- return config;
- }
-
- /**
- * Heuristically infer the type of output message logged by the AspectJ compiler. This is a simple keyword matcher
- * looking for substrings like "[error]", "[warning]", "AspectJ-specific options:", "AspectJ-specific non-standard
- * options:"
- *
- * @param message AspectJ compiler message
- * @return inferred message kind, either of ERROR, WARNING, USAGE, INFO
- */
- protected static IMessage.Kind inferKind(String message) { // XXX dubious
- if (message.contains("[error]")) {
- return IMessage.ERROR;
- } else if (message.contains("[warning]")) {
- return IMessage.WARNING;
- } else if (message.contains("AspectJ-specific options:") || message.contains("AspectJ-specific non-standard options:")) {
- return IMessage.USAGE;
- } else {
- return IMessage.INFO;
- }
- }
- }
|