/** | /** | ||||
* Responsible for controlling the editor. | * Responsible for controlling the editor. | ||||
* | * | ||||
* @todo remove coupling to <CODE>BasicEditor</CODE> | |||||
* <p><b>TODO:</b> remove coupling to <CODE>BasicEditor</CODE></p> | |||||
* @author Mik Kersten | * @author Mik Kersten | ||||
*/ | */ | ||||
public class EditorManager { | public class EditorManager { | ||||
} | } | ||||
/** | /** | ||||
* @todo remove "instanceof AjdeManager" hack | |||||
* <b>TODO</b>: remove "instanceof AjdeManager" hack | |||||
*/ | */ | ||||
public void showSourceLine(String filePath, int lineNumber, boolean highlight) { | public void showSourceLine(String filePath, int lineNumber, boolean highlight) { | ||||
if (editors.size() > 1) { | if (editors.size() > 1) { |
List<File> getAllOutputLocations(); | List<File> getAllOutputLocations(); | ||||
/** | /** | ||||
* Return the default output location (for example, <my_project>/bin). This is where classes which are on the inpath will be | |||||
* Return the default output location (for example, <my_project>/bin). This is where classes which are on the inpath will be | |||||
* placed. | * placed. | ||||
*/ | */ | ||||
File getDefaultOutputLocation(); | File getDefaultOutputLocation(); | ||||
void reportFileWrite(String outputfile, int fileType); | void reportFileWrite(String outputfile, int fileType); | ||||
/** | /** | ||||
* @return a Map<File,String> from inpath absolute paths to handle components | |||||
* @return a Map<File,String> from inpath absolute paths to handle components | |||||
*/ | */ | ||||
Map<File, String> getInpathMap(); | Map<File, String> getInpathMap(); | ||||
* Utility to run the project main class from the project properties in the same VM using a class loader populated with the | * Utility to run the project main class from the project properties in the same VM using a class loader populated with the | ||||
* classpath and output path or jar. Errors are logged to the ErrorHandler. | * classpath and output path or jar. Errors are logged to the ErrorHandler. | ||||
* | * | ||||
* @param project the ProjectPropertiesAdapter specifying the main class, classpath, and executable arguments. | |||||
* @return Thread running with process, or null if unable to start | * @return Thread running with process, or null if unable to start | ||||
*/ | */ | ||||
public Thread runInSameVM() { | public Thread runInSameVM() { |
/** | /** | ||||
* Sets the currently active build configuration file. | * Sets the currently active build configuration file. | ||||
* | * | ||||
* @param full path to the file | |||||
* @param currConfigFilePath full path to the file | |||||
*/ | */ | ||||
void setActiveConfigFile(String currConfigFilePath); | void setActiveConfigFile(String currConfigFilePath); | ||||
/** | /** | ||||
* Build a model for the corresponding configuration file. | * Build a model for the corresponding configuration file. | ||||
* | * | ||||
* @param full path to the file | |||||
* @param configFilePath full path to the file | |||||
*/ | */ | ||||
BuildConfigModel buildModel(String configFilePath); | BuildConfigModel buildModel(String configFilePath); | ||||
/** | /** | ||||
* Utility class for building a structure model for a given compile. Typical command-line usage: <BR> | * Utility class for building a structure model for a given compile. Typical command-line usage: <BR> | ||||
* > <TT>java org.aspectj.tools.ajde.StructureManager @<config-file>.lst</TT> | |||||
* > {@code java org.aspectj.tools.ajde.StructureManager @<config-file>.lst} | |||||
*/ | */ | ||||
public class StructureUtilities { | public class StructureUtilities { | ||||
public interface BuildConfigEditor { | public interface BuildConfigEditor { | ||||
/** | /** | ||||
* @param the full path to the file resource to be opened | |||||
* @param filePath the full path to the file resource to be opened | |||||
*/ | */ | ||||
void openFile(String filePath) throws IOException, InvalidResourceException; | void openFile(String filePath) throws IOException, InvalidResourceException; | ||||
} | } |
* @author Mik Kersten | * @author Mik Kersten | ||||
* | * | ||||
* To change this generated comment edit the template variable "typecomment": | * To change this generated comment edit the template variable "typecomment": | ||||
* Window>Preferences>Java>Templates. | |||||
* Window>Preferences>Java>Templates. | |||||
*/ | */ | ||||
public class InvalidResourceException extends Exception { | public class InvalidResourceException extends Exception { | ||||
} | } | ||||
} | } | ||||
/** | |||||
* History is recorded for {@link LinkNode} navigations. | |||||
*/ | |||||
public void fireNavigationAction(IProgramElement pe, boolean isLink) { | public void fireNavigationAction(IProgramElement pe, boolean isLink) { | ||||
navigationAction(pe, isLink); | navigationAction(pe, isLink); | ||||
} | } |
} | } | ||||
/** | /** | ||||
* @todo get rid of instanceof tests | |||||
* <b>TODO</b>: get rid of instanceof tests | |||||
*/ | */ | ||||
public void buildView(StructureView view, IHierarchy model) { | public void buildView(StructureView view, IHierarchy model) { | ||||
// StructureViewProperties properties = view.getViewProperties(); | // StructureViewProperties properties = view.getViewProperties(); |
private boolean buildIsCancelled = false; | private boolean buildIsCancelled = false; | ||||
/** | |||||
* @param maxVal the value to which value to which the progress bar will | |||||
* count up to (in seconds) | |||||
*/ | |||||
public BuildProgressPanel() { | public BuildProgressPanel() { | ||||
try { | try { | ||||
jbInit(); | jbInit(); | ||||
compile_progressBar.setValue(newVal); | compile_progressBar.setValue(newVal); | ||||
} | } | ||||
/** | |||||
* @param maxVal the value to which value to which the progress bar will | |||||
* count up to (in seconds) | |||||
*/ | |||||
public void setProgressBarMax(int maxVal) { | public void setProgressBarMax(int maxVal) { | ||||
compile_progressBar.setMaximum(maxVal); | compile_progressBar.setMaximum(maxVal); | ||||
} | } |
* thread. You can instantiate multiple games at once. For the time being | * thread. You can instantiate multiple games at once. For the time being | ||||
* the only way to end the game is to exit from the Java VM. | * the only way to end the game is to exit from the Java VM. | ||||
* | * | ||||
* @param isDemo Controls whether the game runs in demo mode or not. True | |||||
* @param mode Controls whether the game runs in demo mode or not. True | |||||
* means it is a demo, false means it runs in normal 2 player mode. | * means it is a demo, false means it runs in normal 2 player mode. | ||||
*/ | */ | ||||
public Game(String mode) { | public Game(String mode) { |
} | } | ||||
/** | /** | ||||
* Sets the output working dir to be <fullyQualifiedOutputDir>\ajdocworkingdir Useful in testing to redirect the ajdocworkingdir | |||||
* Sets the output working dir to be <fullyQualifiedOutputDir>\ajdocworkingdir. Useful in testing to redirect the ajdocworkingdir | |||||
* to the sandbox | * to the sandbox | ||||
*/ | */ | ||||
public static void setOutputWorkingDir(String fullyQulifiedOutputDir) { | public static void setOutputWorkingDir(String fullyQulifiedOutputDir) { | ||||
} | } | ||||
/** | /** | ||||
* Resets the output working dir to be the default which is <the current directory>\ajdocworkingdir | |||||
* Resets the output working dir to be the default which is <the current directory>\ajdocworkingdir | |||||
*/ | */ | ||||
public static void resetOutputWorkingDir() { | public static void resetOutputWorkingDir() { | ||||
outputWorkingDir = Config.WORKING_DIR; | outputWorkingDir = Config.WORKING_DIR; |
* thread. You can instantiate multiple games at once. For the time being | * thread. You can instantiate multiple games at once. For the time being | ||||
* the only way to end the game is to exit from the Java VM. | * the only way to end the game is to exit from the Java VM. | ||||
* | * | ||||
* @param isDemo Controls whether the game runs in demo mode or not. True | |||||
* @param mode Controls whether the game runs in demo mode or not. True | |||||
* means it is a demo, false means it runs in normal 2 player mode. | * means it is a demo, false means it runs in normal 2 player mode. | ||||
*/ | */ | ||||
public Game(String mode) { | public Game(String mode) { |
/** | /** | ||||
* @param packageName if null default package is searched | * @param packageName if null default package is searched | ||||
* @param className can't be null | |||||
* @param typeName can't be null | |||||
*/ | */ | ||||
IProgramElement findElementForType(String packageName, String typeName); | IProgramElement findElementForType(String packageName, String typeName); | ||||
/** | /** | ||||
* @param sourceFilePath modified to '/' delimited path for consistency | |||||
* @param sourceFile modified to '/' delimited path for consistency | |||||
* @return a new structure node for the file if it was not found in the model | * @return a new structure node for the file if it was not found in the model | ||||
*/ | */ | ||||
IProgramElement findElementForSourceFile(String sourceFile); | IProgramElement findElementForSourceFile(String sourceFile); |
/** | /** | ||||
* Called when about to dump out an absolute file location, enabling it to be altered (eg. | * Called when about to dump out an absolute file location, enabling it to be altered (eg. | ||||
* c:/temp/ajcsSandbox/foo/ajctemp.12323/<BLAH> could become TEST_SANDBOX/<BLAH> | |||||
* c:/temp/ajcsSandbox/foo/ajctemp.12323/<BLAH> could become TEST_SANDBOX/<BLAH> | |||||
*/ | */ | ||||
String processFilelocation(String loc); | String processFilelocation(String loc); | ||||
String getPackageName(); | String getPackageName(); | ||||
/** | /** | ||||
* @param method | |||||
* @param returnType | |||||
* return types or field types | * return types or field types | ||||
*/ | */ | ||||
void setCorrespondingType(String returnType); | void setCorrespondingType(String returnType); |
* the list or relationships is uniquely identified by a kind and a relationship name. For example, the advice affecting a | * the list or relationships is uniquely identified by a kind and a relationship name. For example, the advice affecting a | ||||
* particular shadow (e.g. method call) can be retrieved by calling <CODE>get</CODE> on the handle for that method. Symmetrically | * particular shadow (e.g. method call) can be retrieved by calling <CODE>get</CODE> on the handle for that method. Symmetrically | ||||
* the method call shadows that an advice affects can be retrieved. | * the method call shadows that an advice affects can be retrieved. | ||||
* <p> | |||||
* | * | ||||
* <p> | * <p> | ||||
* The elements can be stored and looked up as IProgramElement(s), in which cases the element corresponding to the handle is looked | * The elements can be stored and looked up as IProgramElement(s), in which cases the element corresponding to the handle is looked | ||||
* up in the containment hierarchy. | * up in the containment hierarchy. | ||||
* </p> | |||||
* | * | ||||
* <p> | * <p> | ||||
* put/get methods taking IProgramElement as a parameter are for convenience only. They work identically to calling their | * put/get methods taking IProgramElement as a parameter are for convenience only. They work identically to calling their | ||||
* counterparts with IProgramElement.getIdentifierHandle() | * counterparts with IProgramElement.getIdentifierHandle() | ||||
* </p> | |||||
* | * | ||||
* @author Mik Kersten | * @author Mik Kersten | ||||
* @author Andy Clement | * @author Andy Clement |
} | } | ||||
/** | /** | ||||
* @param sourceFilePath modified to '/' delimited path for consistency | |||||
* @param sourceFile modified to '/' delimited path for consistency | |||||
* @return a new structure node for the file if it was not found in the model | * @return a new structure node for the file if it was not found in the model | ||||
*/ | */ | ||||
public IProgramElement findElementForSourceFile(String sourceFile) { | public IProgramElement findElementForSourceFile(String sourceFile) { |
/** | /** | ||||
* Creates JDT-like handles, for example | * Creates JDT-like handles, for example | ||||
* | * | ||||
* method with string argument: <tjp{Demo.java[Demo~main~\[QString; method with generic argument: | |||||
* <pkg{MyClass.java[MyClass~myMethod~QList\<QString;>; an aspect: <pkg*A1.aj}A1 advice with Integer arg: | |||||
* <pkg*A8.aj}A8&afterReturning&QInteger; method call: <pkg*A10.aj[C~m1?method-call(void pkg.C.m2()) | |||||
* method with string argument: <tjp{Demo.java[Demo~main~\[QString; method with generic argument: | |||||
* <pkg{MyClass.java[MyClass~myMethod~QList\<QString;>; an aspect: <pkg*A1.aj}A1 advice with Integer arg: | |||||
* <pkg*A8.aj}A8&afterReturning&QInteger; method call: <pkg*A10.aj[C~m1?method-call(void pkg.C.m2()) | |||||
* | * | ||||
*/ | */ | ||||
public class JDTLikeHandleProvider implements IElementHandleProvider { | public class JDTLikeHandleProvider implements IElementHandleProvider { |
/** | /** | ||||
* Creates a readable name from the given char array, for example, given 'I' returns 'int'. Moreover, given | * Creates a readable name from the given char array, for example, given 'I' returns 'int'. Moreover, given | ||||
* 'Ljava/lang/String;<Ljava/lang/String;>' returns 'java.lang.String<java.lang.String>' | |||||
* 'Ljava/lang/String;<Ljava/lang/String;>' returns 'java.lang.String<java.lang.String>' | |||||
*/ | */ | ||||
public static char[] convertFromSignature(char[] c) { | public static char[] convertFromSignature(char[] c) { | ||||
int lt = CharOperation.indexOf('<', c); | int lt = CharOperation.indexOf('<', c); | ||||
// } | // } | ||||
/** | /** | ||||
* Given 'Ppkg/MyGenericClass<Ljava/lang/String;Ljava/lang/Integer;>;' will return 'QMyGenericClass<QString;QInteger;>;' | |||||
* Given 'Ppkg/MyGenericClass<Ljava/lang/String;Ljava/lang/Integer;>;' will return 'QMyGenericClass<QString;QInteger;>;' | |||||
*/ | */ | ||||
public static char[] createShortName(char[] c, boolean haveFullyQualifiedAtLeastOneThing, boolean needsFullyQualifiedFirstEntry) { | public static char[] createShortName(char[] c, boolean haveFullyQualifiedAtLeastOneThing, boolean needsFullyQualifiedFirstEntry) { | ||||
if (c[0] == '[') { | if (c[0] == '[') { |
} | } | ||||
/** | /** | ||||
* Trim down fully qualified types to their short form (e.g. a.b.c.D<e.f.G> becomes D<G>) | |||||
* Trim down fully qualified types to their short form (e.g., a.b.c.D<e.f.G> becomes D<G>) | |||||
*/ | */ | ||||
public static String trim(String fqname) { | public static String trim(String fqname) { | ||||
int i = fqname.indexOf("<"); | int i = fqname.indexOf("<"); | ||||
} | } | ||||
/** | /** | ||||
* TODO: move the "parent != null"==>injar heuristic to more explicit | |||||
* TODO: move the "parent != null"→injar heuristic to more explicit | |||||
*/ | */ | ||||
public String toLinkLabelString() { | public String toLinkLabelString() { | ||||
return toLinkLabelString(true); | return toLinkLabelString(true); |
* Return count of messages seen through this interface. | * Return count of messages seen through this interface. | ||||
* | * | ||||
* @param kind the IMessage.Kind of the messages to count (if null, count all) | * @param kind the IMessage.Kind of the messages to count (if null, count all) | ||||
* @param orGreater if true, then count this kind and any considered greater by the ordering of IMessage.Kind.COMPARATOR | |||||
* @param orGreater if true, then count this kind and any considered greater by the ordering of IMessage.Kind#COMPARATOR | |||||
* @return number of messages of this kind (optionally or greater) | * @return number of messages of this kind (optionally or greater) | ||||
* @see IMessage.Kind.COMPARATOR | |||||
* @see IMessage.Kind#COMPARATOR | |||||
*/ | */ | ||||
public int numMessages(IMessage.Kind kind, boolean orGreater) { | public int numMessages(IMessage.Kind kind, boolean orGreater) { | ||||
if (null != proxy) { | if (null != proxy) { |
// public static final Kind ANY = new Kind("any-selector", 0); | // public static final Kind ANY = new Kind("any-selector", 0); | ||||
/** | /** | ||||
* list of Kind in precedence order. 0 is less than IMessage.Kind.COMPARATOR.compareTo(KINDS.get(i), KINDS.get(i + 1)) | |||||
* list of Kind in precedence order. 0 is less than IMessage.Kind#COMPARATOR.compareTo(KINDS.get(i), KINDS.get(i + 1)) | |||||
*/ | */ | ||||
List<Kind> KINDS = Collections.unmodifiableList(Arrays.asList(new Kind[] { WEAVEINFO, INFO, DEBUG, TASKTAG, | List<Kind> KINDS = Collections.unmodifiableList(Arrays.asList(new Kind[] { WEAVEINFO, INFO, DEBUG, TASKTAG, | ||||
WARNING, ERROR, FAIL, ABORT })); | WARNING, ERROR, FAIL, ABORT })); | ||||
* being based on a subtype of a defining type. | * being based on a subtype of a defining type. | ||||
* @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=41952">AspectJ bug 41952</a> | * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=41952">AspectJ bug 41952</a> | ||||
*/ | */ | ||||
/** | |||||
* Return a List of <code>ISourceLocation</code> instances that indicate additional source locations relevent to this message as | |||||
* specified by the message creator. The list should not include the primary source location associated with the message | |||||
* which can be obtained from <code>getSourceLocation()<code>. | |||||
* <p> | |||||
* An example of using extra locations would be in a warning message that | |||||
* flags all shadow locations that will go unmatched due to a pointcut definition | |||||
* being based on a subtype of a defining type. | |||||
* </p> | |||||
* | |||||
* @return a list of additional source locations | |||||
* @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=41952">AspectJ bug 41952</a> | |||||
*/ | |||||
List<ISourceLocation> getExtraSourceLocations(); | List<ISourceLocation> getExtraSourceLocations(); | ||||
} | } |
* why? | * why? | ||||
* | * | ||||
* @see org.aspectj.lang.reflect.SourceLocation | * @see org.aspectj.lang.reflect.SourceLocation | ||||
* @see org.aspectj.compiler.base.parser.SourceInfo | |||||
* @see org.aspectj.tools.ide.SourceLine | |||||
* @see org.aspectj.testing.harness.ErrorLine | |||||
*/ | */ | ||||
public interface ISourceLocation extends java.io.Serializable { | public interface ISourceLocation extends java.io.Serializable { | ||||
int MAX_LINE = Integer.MAX_VALUE / 2; | int MAX_LINE = Integer.MAX_VALUE / 2; |
* | * | ||||
* @param messageHolder | * @param messageHolder | ||||
* @param out | * @param out | ||||
* @see #print(PrintStream, String, IMessageHolder, IMessageRenderer, IMessageHandler) | |||||
* @see #print(PrintStream, IMessageHolder, String, IMessageRenderer, IMessageHandler) | |||||
*/ | */ | ||||
public static void print(PrintStream out, IMessageHolder messageHolder) { | public static void print(PrintStream out, IMessageHolder messageHolder) { | ||||
print(out, messageHolder, (String) null, (IMessageRenderer) null, (IMessageHandler) null); | print(out, messageHolder, (String) null, (IMessageRenderer) null, (IMessageHandler) null); | ||||
/** | /** | ||||
* Print all message to the print stream, starting each on a new line, with a prefix. | * Print all message to the print stream, starting each on a new line, with a prefix. | ||||
* | * | ||||
* @param messageHolder | |||||
* @param holder | |||||
* @param out | * @param out | ||||
* @see #print(PrintStream, String, IMessageHolder, IMessageRenderer, IMessageHandler) | |||||
* @see #print(PrintStream, IMessageHolder, String, IMessageRenderer, IMessageHandler) | |||||
*/ | */ | ||||
public static void print(PrintStream out, IMessageHolder holder, String prefix) { | public static void print(PrintStream out, IMessageHolder holder, String prefix) { | ||||
print(out, holder, prefix, (IMessageRenderer) null, (IMessageHandler) null); | print(out, holder, prefix, (IMessageRenderer) null, (IMessageHandler) null); | ||||
/** | /** | ||||
* Print all message to the print stream, starting each on a new line, with a prefix and using a renderer. | * Print all message to the print stream, starting each on a new line, with a prefix and using a renderer. | ||||
* | * | ||||
* @param messageHolder | |||||
* @param holder | |||||
* @param out | * @param out | ||||
* @param renderer IMessageRender to render result - use MESSAGE_LINE if null | * @param renderer IMessageRender to render result - use MESSAGE_LINE if null | ||||
* @see #print(PrintStream, String, IMessageHolder, IMessageRenderer, IMessageHandler) | |||||
* @see #print(PrintStream, IMessageHolder, String, IMessageRenderer, IMessageHandler) | |||||
*/ | */ | ||||
public static void print(PrintStream out, IMessageHolder holder, String prefix, IMessageRenderer renderer) { | public static void print(PrintStream out, IMessageHolder holder, String prefix, IMessageRenderer renderer) { | ||||
print(out, holder, prefix, renderer, (IMessageHandler) null); | print(out, holder, prefix, renderer, (IMessageHandler) null); | ||||
* are free to render multi-line output. | * are free to render multi-line output. | ||||
* | * | ||||
* @param out the PrintStream sink - return silently if null | * @param out the PrintStream sink - return silently if null | ||||
* @param messageHolder the IMessageHolder with the messages to print | |||||
* @param holder the IMessageHolder with the messages to print | |||||
* @param prefix the prefix for each line | |||||
* @param renderer IMessageRender to render result - use MESSAGE_ALL if null | * @param renderer IMessageRender to render result - use MESSAGE_ALL if null | ||||
* @param selector IMessageHandler to select messages to render - if null, do all non-null | * @param selector IMessageHandler to select messages to render - if null, do all non-null | ||||
*/ | */ | ||||
* | * | ||||
* @param messages if null, return EMPTY_LIST | * @param messages if null, return EMPTY_LIST | ||||
* @param kind if null, return messages | * @param kind if null, return messages | ||||
* @see MessageHandler#getMessages(Kind) | |||||
* @see MessageHandler#getMessages(Kind, boolean) | |||||
*/ | */ | ||||
public static List<IMessage> getMessages(List<IMessage> messages, IMessage.Kind kind) { | public static List<IMessage> getMessages(List<IMessage> messages, IMessage.Kind kind) { | ||||
if (null == messages) { | if (null == messages) { | ||||
/** | /** | ||||
* Handle all messages in the second handler using the first | * Handle all messages in the second handler using the first | ||||
* | * | ||||
* @param handler the IMessageHandler sink for all messages in source | |||||
* @param holder the IMessageHolder source for all messages to handle | |||||
* @param sink the IMessageHandler sink for all messages in source | |||||
* @param source the IMessageHolder source for all messages to handle | |||||
* @param fastFail if true, stop on first failure | * @param fastFail if true, stop on first failure | ||||
* @return false if any sink.handleMessage(..) failed | * @return false if any sink.handleMessage(..) failed | ||||
*/ | */ | ||||
/** | /** | ||||
* Handle messages in the second handler using the first | * Handle messages in the second handler using the first | ||||
* | * | ||||
* @param handler the IMessageHandler sink for all messages in source | |||||
* @param holder the IMessageHolder source for all messages to handle | |||||
* @param sink the IMessageHandler sink for all messages in source | |||||
* @param source the IMessageHolder source for all messages to handle | |||||
* @param kind the IMessage.Kind to select, if not null | * @param kind the IMessage.Kind to select, if not null | ||||
* @param orGreater if true, also accept greater kinds | * @param orGreater if true, also accept greater kinds | ||||
* @param fastFail if true, stop on first failure | * @param fastFail if true, stop on first failure | ||||
* Handle messages in the second handler using the first if they are NOT of this kind (optionally, or greater). If you pass null | * Handle messages in the second handler using the first if they are NOT of this kind (optionally, or greater). If you pass null | ||||
* as the kind, then all messages are ignored and this returns true. | * as the kind, then all messages are ignored and this returns true. | ||||
* | * | ||||
* @param handler the IMessageHandler sink for all messages in source | |||||
* @param holder the IMessageHolder source for all messages to handle | |||||
* @param sink the IMessageHandler sink for all messages in source | |||||
* @param source the IMessageHolder source for all messages to handle | |||||
* @param kind the IMessage.Kind to reject, if not null | * @param kind the IMessage.Kind to reject, if not null | ||||
* @param orGreater if true, also reject greater kinds | * @param orGreater if true, also reject greater kinds | ||||
* @param fastFail if true, stop on first failure | * @param fastFail if true, stop on first failure | ||||
/** | /** | ||||
* Handle messages in the sink. | * Handle messages in the sink. | ||||
* | * | ||||
* @param handler the IMessageHandler sink for all messages in source | |||||
* @param sink the IMessageHandler sink for all messages in source | |||||
* @param sources the IMessage[] messages to handle | * @param sources the IMessage[] messages to handle | ||||
* @param fastFail if true, stop on first failure | * @param fastFail if true, stop on first failure | ||||
* @return false if any sink.handleMessage(..) failed | * @return false if any sink.handleMessage(..) failed |
import org.aspectj.util.LangUtil; | import org.aspectj.util.LangUtil; | ||||
/** | /** | ||||
* Immutable source location. This guarantees that the source file is not null and that the numeric values are positive and line <= | |||||
* Immutable source location. This guarantees that the source file is not null and that the numeric values are positive and line ≤ | |||||
* endLine. | * endLine. | ||||
* | * | ||||
* @see org.aspectj.lang.reflect.SourceLocation | * @see org.aspectj.lang.reflect.SourceLocation | ||||
* @see org.aspectj.compiler.base.parser.SourceInfo | |||||
* @see org.aspectj.tools.ide.SourceLine | |||||
* @see org.aspectj.testing.harness.ErrorLine | |||||
*/ | */ | ||||
public class SourceLocation implements ISourceLocation { | public class SourceLocation implements ISourceLocation { | ||||
/** | /** | ||||
* @param file File of the source; if null, use ISourceLocation.NO_FILE, not null | * @param file File of the source; if null, use ISourceLocation.NO_FILE, not null | ||||
* @param line int starting line of the location - positive number | * @param line int starting line of the location - positive number | ||||
* @param endLine int ending line of the location - <= starting line | |||||
* @param endLine int ending line of the location - ≤ starting line | |||||
* @param column int character position of starting location - positive number | * @param column int character position of starting location - positive number | ||||
*/ | */ | ||||
public SourceLocation(File file, int line, int endLine, int column) { | public SourceLocation(File file, int line, int endLine, int column) { |
* thread. You can instantiate multiple games at once. For the time being | * thread. You can instantiate multiple games at once. For the time being | ||||
* the only way to end the game is to exit from the Java VM. | * the only way to end the game is to exit from the Java VM. | ||||
* | * | ||||
* @param isDemo Controls whether the game runs in demo mode or not. True | |||||
* @param mode Controls whether the game runs in demo mode or not. True | |||||
* means it is a demo, false means it runs in normal 2 player mode. | * means it is a demo, false means it runs in normal 2 player mode. | ||||
*/ | */ | ||||
public Game(String mode) { | public Game(String mode) { |
* thread. You can instantiate multiple games at once. For the time being | * thread. You can instantiate multiple games at once. For the time being | ||||
* the only way to end the game is to exit from the Java VM. | * the only way to end the game is to exit from the Java VM. | ||||
* | * | ||||
* @param isDemo Controls whether the game runs in demo mode or not. True | |||||
* @param mode Controls whether the game runs in demo mode or not. True | |||||
* means it is a demo, false means it runs in normal 2 player mode. | * means it is a demo, false means it runs in normal 2 player mode. | ||||
*/ | */ | ||||
public Game(String mode) { | public Game(String mode) { |
* Adapter between the generic class pre processor interface and the AspectJ weaver Load time weaving consistency relies on | * Adapter between the generic class pre processor interface and the AspectJ weaver Load time weaving consistency relies on | ||||
* Bcel.setRepository | * Bcel.setRepository | ||||
* | * | ||||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||||
* @author Alexandre Vasseur (alex AT gnilux DOT com) | |||||
*/ | */ | ||||
public class Aj implements ClassPreProcessor { | public class Aj implements ClassPreProcessor { | ||||
/** | /** | ||||
* References are added to this queue when their associated classloader is removed, and once on here that indicates that we | * References are added to this queue when their associated classloader is removed, and once on here that indicates that we | ||||
* should tidy up the adaptor map and remove the adaptor (weaver) from the map we are maintaining from adaptorkey > adaptor | |||||
* should tidy up the adaptor map and remove the adaptor (weaver) from the map we are maintaining from adaptorkey > adaptor | |||||
* (weaver) | * (weaver) | ||||
*/ | */ | ||||
private static ReferenceQueue adaptorQueue = new ReferenceQueue(); | private static ReferenceQueue adaptorQueue = new ReferenceQueue(); | ||||
((ClassLoaderWeavingAdaptor) WeaverContainer.getWeaver(loader, weavingContext)).flushGeneratedClassesFor(className); | ((ClassLoaderWeavingAdaptor) WeaverContainer.getWeaver(loader, weavingContext)).flushGeneratedClassesFor(className); | ||||
} | } | ||||
} | |||||
} |
import org.aspectj.bridge.IMessageHandler; | import org.aspectj.bridge.IMessageHandler; | ||||
/** | /** | ||||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||||
* @author Alexandre Vasseur (alex AT gnilux DOT com) | |||||
*/ | */ | ||||
public class DefaultMessageHandler implements IMessageHandler { | public class DefaultMessageHandler implements IMessageHandler { | ||||
/** | /** | ||||
* Simply call weaving adaptor back to parse aop.xml | * Simply call weaving adaptor back to parse aop.xml | ||||
* | * | ||||
* @param weaver | |||||
* @param adaptor | |||||
* @param loader | * @param loader | ||||
*/ | */ | ||||
public List<Definition> getDefinitions(final ClassLoader loader, final WeavingAdaptor adaptor) { | public List<Definition> getDefinitions(final ClassLoader loader, final WeavingAdaptor adaptor) { |
* A class that hanldes LTW options. Note: AV - I choosed to not reuse AjCompilerOptions and alike since those implies too many | * A class that hanldes LTW options. Note: AV - I choosed to not reuse AjCompilerOptions and alike since those implies too many | ||||
* dependancies on jdt and ajdt modules. | * dependancies on jdt and ajdt modules. | ||||
* | * | ||||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||||
* @author Alexandre Vasseur (alex AT gnilux DOT com) | |||||
*/ | */ | ||||
public class Options { | public class Options { | ||||
* | * | ||||
* @param flush if true, empty errors | * @param flush if true, empty errors | ||||
* @return null if none, String otherwise | * @return null if none, String otherwise | ||||
* @see BuildArgParser() | |||||
* @see #BuildArgParser(IMessageHandler) | |||||
*/ | */ | ||||
public String getOtherMessages(boolean flush) { | public String getOtherMessages(boolean flush) { | ||||
if (null == errorSink) { | if (null == errorSink) { |
* @param weaver the weaver | * @param weaver the weaver | ||||
* @param intRequestor recipient of interim compilation results from compiler (pre-weave) | * @param intRequestor recipient of interim compilation results from compiler (pre-weave) | ||||
* @param outputFileNameProvider implementor of a strategy providing output file names for results | * @param outputFileNameProvider implementor of a strategy providing output file names for results | ||||
* @param binarySourceEntries binary source that we didn't compile, but that we need to weave | |||||
* @param resultSetForFullWeave if we are doing an incremental build, and the weaver determines that we need to weave the world, | |||||
* @param binarySourceProvider binary source that we didn't compile, but that we need to weave | |||||
* @param incrementalCompilationState if we are doing an incremental build, and the weaver determines that we need to weave the world, | |||||
* this is the set of intermediate results that will be passed to the weaver. | * this is the set of intermediate results that will be passed to the weaver. | ||||
*/ | */ | ||||
public AjCompilerAdapter(Compiler compiler, boolean isBatchCompile, BcelWorld world, BcelWeaver weaver, | public AjCompilerAdapter(Compiler compiler, boolean isBatchCompile, BcelWorld world, BcelWeaver weaver, |
* Here is the compiler loop difference when pipelining. | * Here is the compiler loop difference when pipelining. | ||||
* | * | ||||
* the old way: Finished diet parsing [C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java] Finished diet parsing | * the old way: Finished diet parsing [C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java] Finished diet parsing | ||||
* [C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java] > AjLookupEnvironment.completeTypeBindings() < | |||||
* [C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java] > AjLookupEnvironment.completeTypeBindings() < | |||||
* AjLookupEnvironment.completeTypeBindings() compiling C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java | * AjLookupEnvironment.completeTypeBindings() compiling C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java | ||||
* >Compiler.process(C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java) | |||||
* <Compiler.process(C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java) compiling | |||||
* >Compiler.process(C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java) | |||||
* <Compiler.process(C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java) compiling | |||||
* C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java | * C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java | ||||
* >Compiler.process(C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java) | |||||
* <Compiler.process(C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java) >AjCompilerAdapter.weave() | |||||
* >BcelWeaver.prepareForWeave <BcelWeaver.prepareForWeave woven class ClassOne (from | |||||
* >Compiler.process(C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java) | |||||
* <Compiler.process(C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java) >AjCompilerAdapter.weave() | |||||
* >BcelWeaver.prepareForWeave <BcelWeaver.prepareForWeave woven class ClassOne (from | |||||
* C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java) woven class ClassTwo (from | * C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java) woven class ClassTwo (from | ||||
* C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java) <AjCompilerAdapter.weave() | |||||
* C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java) <AjCompilerAdapter.weave() | |||||
* | * | ||||
* the new way (see the compiling/weaving mixed up): Finished diet parsing | * the new way (see the compiling/weaving mixed up): Finished diet parsing | ||||
* [C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java] Finished diet parsing | * [C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java] Finished diet parsing | ||||
* [C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java] >AjLookupEnvironment.completeTypeBindings() | |||||
* <AjLookupEnvironment.completeTypeBindings() compiling C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java | |||||
* >Compiler.process(C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java) | |||||
* <Compiler.process(C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java) >AjCompilerAdapter.weave() | |||||
* >BcelWeaver.prepareForWeave <BcelWeaver.prepareForWeave woven class ClassOne (from | |||||
* C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java) <AjCompilerAdapter.weave() compiling | |||||
* [C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java] >AjLookupEnvironment.completeTypeBindings() | |||||
* <AjLookupEnvironment.completeTypeBindings() compiling C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java | |||||
* >Compiler.process(C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java) | |||||
* <Compiler.process(C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java) >AjCompilerAdapter.weave() | |||||
* >BcelWeaver.prepareForWeave <BcelWeaver.prepareForWeave woven class ClassOne (from | |||||
* C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassOne.java) <AjCompilerAdapter.weave() compiling | |||||
* C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java | * C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java | ||||
* >Compiler.process(C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java) | |||||
* <Compiler.process(C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java) >AjCompilerAdapter.weave() woven class ClassTwo | |||||
* >Compiler.process(C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java) | |||||
* <Compiler.process(C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java) >AjCompilerAdapter.weave() woven class ClassTwo | |||||
* (from C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java) <AjCompilerAdapter.weave() | * (from C:\temp\ajcSandbox\aspectjhead\ajcTest23160.tmp\ClassTwo.java) <AjCompilerAdapter.weave() | ||||
* | * | ||||
* | * | ||||
* @param weaver the weaver | * @param weaver the weaver | ||||
* @param intRequestor recipient of interim compilation results from compiler (pre-weave) | * @param intRequestor recipient of interim compilation results from compiler (pre-weave) | ||||
* @param outputFileNameProvider implementor of a strategy providing output file names for results | * @param outputFileNameProvider implementor of a strategy providing output file names for results | ||||
* @param binarySourceEntries binary source that we didn't compile, but that we need to weave | |||||
* @param resultSetForFullWeave if we are doing an incremental build, and the weaver determines that we need to weave the world, | |||||
* @param binarySourceProvider binary source that we didn't compile, but that we need to weave | |||||
* @param incrementalCompilationState if we are doing an incremental build, and the weaver determines that we need to weave the world, | |||||
* this is the set of intermediate results that will be passed to the weaver. | * this is the set of intermediate results that will be passed to the weaver. | ||||
*/ | */ | ||||
public AjPipeliningCompilerAdapter(Compiler compiler, boolean isBatchCompile, BcelWorld world, BcelWeaver weaver, | public AjPipeliningCompilerAdapter(Compiler compiler, boolean isBatchCompile, BcelWorld world, BcelWeaver weaver, | ||||
return resultsPendingWeave; | return resultsPendingWeave; | ||||
} | } | ||||
} | |||||
} |
List /* File */getAllOutputLocations(); | List /* File */getAllOutputLocations(); | ||||
/** | /** | ||||
* Return the default output location (for example, <my_project>/bin). This is where classes which are on the inpath will be | |||||
* Return the default output location (for example, <my_project>/bin). This is where classes which are on the inpath will be | |||||
* placed. | * placed. | ||||
*/ | */ | ||||
File getDefaultOutputLocation(); | File getDefaultOutputLocation(); |
* generates the following: public static final boolean ajc$if_N(formals*, | * generates the following: public static final boolean ajc$if_N(formals*, | ||||
* [thisJoinPoints as needed]) { return expr; } | * [thisJoinPoints as needed]) { return expr; } | ||||
* | * | ||||
* Here's the complicated bit, it deals with cflow: (a): ... this(a) && cflow(if | |||||
* Here's the complicated bit, it deals with cflow: (a): ... this(a) && cflow(if | |||||
* (a == foo)) is an error. The way we capture this is: We generate the ajc$if | * (a == foo)) is an error. The way we capture this is: We generate the ajc$if | ||||
* method with an (a) parameter, we let eclipse do the proper name binding. We | * method with an (a) parameter, we let eclipse do the proper name binding. We | ||||
* then, as a post pass (that we need to do anyway) look for the used | * then, as a post pass (that we need to do anyway) look for the used |
/** | /** | ||||
* Create the list of aliases based on what was supplied as parameters for the ontype. | * Create the list of aliases based on what was supplied as parameters for the ontype. | ||||
* For example, if the declaration is 'List<N> SomeType<N>.foo' then the alias list | |||||
* For example, if the declaration is 'List<N> SomeType<N>.foo' then the alias list | |||||
* will simply contain 'N' and 'N' will mean 'the first type variable declared for | * will simply contain 'N' and 'N' will mean 'the first type variable declared for | ||||
* type SomeType' | * type SomeType' | ||||
*/ | */ |
/** | /** | ||||
* In the pipeline world, we can be weaving before all types have come through from compilation. In some cases this means the weaver | * In the pipeline world, we can be weaving before all types have come through from compilation. In some cases this means the weaver | ||||
* will want to ask questions of eclipse types and this subtype of ResolvedMemberImpl is here to answer some of those questions - it | * will want to ask questions of eclipse types and this subtype of ResolvedMemberImpl is here to answer some of those questions - it | ||||
* is backed by the real eclipse MethodBinding object and can translate from Eclipse -> Weaver information. | |||||
* is backed by the real eclipse MethodBinding object and can translate from Eclipse → Weaver information. | |||||
*/ | */ | ||||
public class EclipseResolvedMember extends ResolvedMemberImpl { | public class EclipseResolvedMember extends ResolvedMemberImpl { | ||||
*/ | */ | ||||
public class PointcutBinding extends Binding { | public class PointcutBinding extends Binding { | ||||
/** | |||||
/* (non-Javadoc) | |||||
* @see org.eclipse.jdt.internal.compiler.lookup.BindingPattern#bindingType() | * @see org.eclipse.jdt.internal.compiler.lookup.BindingPattern#bindingType() | ||||
*/ | */ | ||||
public int bindingType() { | public int bindingType() { | ||||
return 0; | return 0; | ||||
} | } | ||||
/** | |||||
/* (non-Javadoc) | |||||
* @see org.eclipse.jdt.internal.compiler.lookup.BindingPattern#readableName() | * @see org.eclipse.jdt.internal.compiler.lookup.BindingPattern#readableName() | ||||
*/ | */ | ||||
public char[] readableName() { | public char[] readableName() { |
* <li>Collections are unioned</li> | * <li>Collections are unioned</li> | ||||
* <li>values takes local value unless default and global set</li> | * <li>values takes local value unless default and global set</li> | ||||
* <li>this only sets one of outputDir and outputJar as needed</li> | * <li>this only sets one of outputDir and outputJar as needed</li> | ||||
* <ul> | |||||
* This also configures super if javaOptions change. | |||||
* </ul> | |||||
* <p>This also configures super if javaOptions change.</p> | |||||
* | * | ||||
* @param global the AjBuildConfig to read globals from | * @param global the AjBuildConfig to read globals from | ||||
*/ | */ |
* Central point for all things incremental... - keeps track of the state recorded for each different config file - allows limited | * Central point for all things incremental... - keeps track of the state recorded for each different config file - allows limited | ||||
* interaction with these states | * interaction with these states | ||||
* | * | ||||
* - records dependency/change info for particular classpaths > this will become what JDT keeps in its 'State' object when its | |||||
* - records dependency/change info for particular classpaths > this will become what JDT keeps in its 'State' object when it's | |||||
* finished | * finished | ||||
*/ | */ | ||||
public class IncrementalStateManager { | public class IncrementalStateManager { | ||||
// FIXME asc needs a persistence mechanism for storing/loading all state info | // FIXME asc needs a persistence mechanism for storing/loading all state info | ||||
// FIXME asc needs to understand two config files might point at the same output dir... what to do about this? | // FIXME asc needs to understand two config files might point at the same output dir... what to do about this? | ||||
} | |||||
} |
/** | /** | ||||
* This method is used to retrieve the ending position for a type declaration when the dimension is right after the type name. | * This method is used to retrieve the ending position for a type declaration when the dimension is right after the type name. | ||||
* For example: int[] i; => return 5, but int i[] => return -1; | |||||
* For example: int[] i; → return 5, but int i[] → return -1; | |||||
* | * | ||||
* @return int the dimension found | * @return int the dimension found | ||||
*/ | */ |
/** | /** | ||||
* Creates a new AST matcher instance. | * Creates a new AST matcher instance. | ||||
* <p> | * <p> | ||||
* For backwards compatibility, the matcher ignores tag elements below doc comments by default. Use {@link #ASTMatcher(boolean) | |||||
* ASTMatcher(true)} for a matcher that compares doc tags by default. | |||||
* For backwards compatibility, the matcher ignores tag elements below doc comments by default. Use {@link #AjASTMatcher(boolean) | |||||
* AjASTMatcher(true)} for a matcher that compares doc tags by default. | |||||
* </p> | * </p> | ||||
*/ | */ | ||||
public AjASTMatcher() { | public AjASTMatcher() { |
* fine for generating debug print strings. | * fine for generating debug print strings. | ||||
* <p> | * <p> | ||||
* Example usage: | * Example usage: | ||||
* <code> | |||||
* </p> | |||||
* <pre> | * <pre> | ||||
* <code> | |||||
* NaiveASTFlattener p = new NaiveASTFlattener(); | * NaiveASTFlattener p = new NaiveASTFlattener(); | ||||
* node.accept(p); | * node.accept(p); | ||||
* String result = p.getResult(); | * String result = p.getResult(); | ||||
* </pre> | |||||
* </code> | * </code> | ||||
* </pre> | |||||
* <p> | |||||
* Call the <code>reset</code> method to clear the previous result before reusing an | * Call the <code>reset</code> method to clear the previous result before reusing an | ||||
* existing instance. | * existing instance. | ||||
* </p> | * </p> |
/** | /** | ||||
* Convenience method to run ajc and collect String lists of messages. This can be reflectively invoked with the List collecting | * Convenience method to run ajc and collect String lists of messages. This can be reflectively invoked with the List collecting | ||||
* parameters supplied by a parent class loader. The String messages take the same form as command-line messages. | * parameters supplied by a parent class loader. The String messages take the same form as command-line messages. | ||||
* This method does not catch unchecked exceptions thrown by the compiler. | |||||
* | * | ||||
* @param args the String[] args to pass to the compiler | * @param args the String[] args to pass to the compiler | ||||
* @param useSystemExit if true and errors, return System.exit(errs) | * @param useSystemExit if true and errors, return System.exit(errs) | ||||
* @param fails the List sink, if any, for String failure (or worse) messages | * @param fails the List sink, if any, for String failure (or worse) messages | ||||
* @param errors the List sink, if any, for String error messages | * @param errors the List sink, if any, for String error messages | ||||
* @param warnings the List sink, if any, for String warning messages | * @param warnings the List sink, if any, for String warning messages | ||||
* @param info the List sink, if any, for String info messages | |||||
* @param infos the List sink, if any, for String info messages | |||||
* @return number of messages reported with level ERROR or above | * @return number of messages reported with level ERROR or above | ||||
* @throws any unchecked exceptions the compiler does | |||||
*/ | */ | ||||
public static int bareMain(String[] args, boolean useSystemExit, List fails, List errors, List warnings, List infos) { | public static int bareMain(String[] args, boolean useSystemExit, List fails, List errors, List warnings, List infos) { | ||||
Main main = new Main(); | Main main = new Main(); | ||||
* | * | ||||
* @param args the String[] command line for the compiler | * @param args the String[] command line for the compiler | ||||
* @param useSystemExit if true, use System.exit(int) to complete unless one of the args is -noExit. and signal result (0 no | * @param useSystemExit if true, use System.exit(int) to complete unless one of the args is -noExit. and signal result (0 no | ||||
* exceptions/error, <0 exceptions, >0 compiler errors). | |||||
* exceptions/error, <0 exceptions, >0 compiler errors). | |||||
*/ | */ | ||||
public void runMain(String[] args, boolean useSystemExit) { | public void runMain(String[] args, boolean useSystemExit) { | ||||
// Urk - default no check for AJDT, enabled here for Ant, command-line | // Urk - default no check for AJDT, enabled here for Ant, command-line | ||||
* Call System.exit(int) with values derived from the number of failures/aborts or errors in messages. | * Call System.exit(int) with values derived from the number of failures/aborts or errors in messages. | ||||
* | * | ||||
* @param messages the IMessageHolder to interrogate. | * @param messages the IMessageHolder to interrogate. | ||||
* @param messages | |||||
*/ | */ | ||||
protected void systemExit(IMessageHolder messages) { | protected void systemExit(IMessageHolder messages) { | ||||
int num = lastFails; // messages.numMessages(IMessage.FAIL, true); | int num = lastFails; // messages.numMessages(IMessage.FAIL, true); | ||||
* | * | ||||
* @param pass true result of the command | * @param pass true result of the command | ||||
* @param holder IMessageHolder with messages from the command | * @param holder IMessageHolder with messages from the command | ||||
* @see reportCommandResults(IMessageHolder) | |||||
* @return false if the process should abort | * @return false if the process should abort | ||||
*/ | */ | ||||
protected boolean report(boolean pass, IMessageHolder holder) { | protected boolean report(boolean pass, IMessageHolder holder) { | ||||
} | } | ||||
/** | /** | ||||
* @param argList read and strip incremental args from this | |||||
* @param args read and strip incremental args from this | |||||
* @param sink IMessageHandler for error messages | * @param sink IMessageHandler for error messages | ||||
* @return String[] remainder of args | * @return String[] remainder of args | ||||
*/ | */ |
/** | /** | ||||
* Writes the full attribute, i.e. name_index, length, and contents | * Writes the full attribute, i.e. name_index, length, and contents | ||||
* | * | ||||
* @param constantPool | |||||
* @param dataCompressor | |||||
*/ | */ | ||||
public byte[] getAllBytes(short nameIndex, ConstantPoolWriter dataCompressor) { | public byte[] getAllBytes(short nameIndex, ConstantPoolWriter dataCompressor) { | ||||
try { | try { | ||||
private UnresolvedType[] declaredExceptions; | private UnresolvedType[] declaredExceptions; | ||||
/** | /** | ||||
* @param lexicalPosition must be greater than the lexicalPosition of any advice declared before this one in an aspect, | |||||
* @param start must be greater than the start of any advice declared before this one in an aspect, | |||||
* otherwise, it can be any value. | * otherwise, it can be any value. | ||||
*/ | */ | ||||
public AdviceAttribute(AdviceKind kind, Pointcut pointcut, int extraArgumentFlags, int start, int end, | public AdviceAttribute(AdviceKind kind, Pointcut pointcut, int extraArgumentFlags, int start, int end, |
} | } | ||||
/** | /** | ||||
* Return a resolvedmember representing the synthetic getter for the field. The old style (<1.6.9) is a heavyweight static | |||||
* Return a resolvedmember representing the synthetic getter for the field. The old style (<1.6.9) is a heavyweight static | |||||
* method with a long name. The new style (1.6.9 and later) is short, and reusable across aspects. | * method with a long name. The new style (1.6.9 and later) is short, and reusable across aspects. | ||||
* | * | ||||
* @param aspectType the aspect attempting the access | * @param aspectType the aspect attempting the access | ||||
} | } | ||||
/** | /** | ||||
* Return a resolvedmember representing the synthetic setter for the field. The old style (<1.6.9) is a heavyweight static | |||||
* Return a resolvedmember representing the synthetic setter for the field. The old style (<1.6.9) is a heavyweight static | |||||
* method with a long name. The new style (1.6.9 and later) is short, not always static, and reusable across aspects. | * method with a long name. The new style (1.6.9 and later) is short, not always static, and reusable across aspects. | ||||
* | * | ||||
* @param aspectType the aspect attempting the access | * @param aspectType the aspect attempting the access | ||||
} | } | ||||
/** | /** | ||||
* Sometimes the intertyped method requires a bridge method alongside it. For example if the method 'N SomeI<N>.m()' is put onto | |||||
* an interface 'interface I<N extends Number>' and then a concrete implementation is 'class C implements I<Float>' then the ITD | |||||
* Sometimes the intertyped method requires a bridge method alongside it. For example if the method 'N SomeI<N>.m()' is put onto | |||||
* an interface 'interface I<N extends Number>' and then a concrete implementation is 'class C implements I<Float>' then the ITD | |||||
* on the interface will be 'Number m()', whereas the ITD on the 'topmostimplementor' will be 'Float m()'. A bridge method needs | * on the interface will be 'Number m()', whereas the ITD on the 'topmostimplementor' will be 'Float m()'. A bridge method needs | ||||
* to be created in the topmostimplementor 'Number m()' that delegates to 'Float m()' | * to be created in the topmostimplementor 'Number m()' that delegates to 'Float m()' | ||||
*/ | */ |
} | } | ||||
/** | /** | ||||
* returns true if the ITD target type used type variables, for example I<T>. When they are specified like this, the ITDs | |||||
* returns true if the ITD target type used type variables, for example I<T>. When they are specified like this, the ITDs | |||||
* 'share' type variables with the generic type. Usually this method is called because we need to know whether to tailor the | * 'share' type variables with the generic type. Usually this method is called because we need to know whether to tailor the | ||||
* munger for addition to a particular type. For example: <code> | |||||
* interface I<T> {} | |||||
* munger for addition to a particular type. For example: <pre><code> | |||||
* interface I<T> {} | |||||
* | * | ||||
* aspect X implements I<String> { | |||||
* List<T> I<T>.foo { return null; } | |||||
* aspect X implements I<String> { | |||||
* List<T> I<T>.foo { return null; } | |||||
* } | * } | ||||
* </code> In this case the munger matches X but it matches with the form <code> | |||||
* List<String> foo() { return null; } | |||||
* </code></pre> In this case the munger matches X but it matches with the form <code> | |||||
* List<String> foo() { return null; } | |||||
* </code> | * </code> | ||||
*/ | */ | ||||
public boolean isTargetTypeParameterized() { | public boolean isTargetTypeParameterized() { |
/** | /** | ||||
* Encapsulates operations that a world will need to support if it is actually going to modify bytecode rather than just match | * Encapsulates operations that a world will need to support if it is actually going to modify bytecode rather than just match | ||||
* against it. {@see BcelWeavingSupport} | |||||
* against it. @see BcelWeavingSupport | |||||
* | * | ||||
* @author Andy Clement | * @author Andy Clement | ||||
*/ | */ | ||||
ConcreteTypeMunger makeCflowCounterFieldAdder(ResolvedMember cflowField); | ConcreteTypeMunger makeCflowCounterFieldAdder(ResolvedMember cflowField); | ||||
/** | /** | ||||
* Register a munger for perclause @AJ aspect so that we add aspectOf(..) to them as needed | |||||
* Register a munger for perclause {@literal @}AJ aspect so that we add aspectOf(..) to them as needed | |||||
* | * | ||||
* @see org.aspectj.weaver.bcel.BcelWorld#makePerClauseAspect(ResolvedType, org.aspectj.weaver.patterns.PerClause.Kind) | |||||
* @see org.aspectj.weaver.bcel.BcelWeavingSupport#makePerClauseAspect(ResolvedType, org.aspectj.weaver.patterns.PerClause.Kind) | |||||
*/ | */ | ||||
ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, PerClause.Kind kind); | ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, PerClause.Kind kind); | ||||
// ---- utility methods | // ---- utility methods | ||||
/** | /** | ||||
* Build a signature based on the return type and parameter types. For example: "(Ljava/util/Set<Ljava/lang/String;>;)V" or | |||||
* Build a signature based on the return type and parameter types. For example: "(Ljava/util/Set<Ljava/lang/String;>;)V" or | |||||
* "(Ljava/util/Set;)V". The latter form shows what happens when the generics are erased | * "(Ljava/util/Set;)V". The latter form shows what happens when the generics are erased | ||||
*/ | */ | ||||
public static String typesToSignature(UnresolvedType returnType, UnresolvedType[] paramTypes, boolean eraseGenerics) { | public static String typesToSignature(UnresolvedType returnType, UnresolvedType[] paramTypes, boolean eraseGenerics) { | ||||
} | } | ||||
/** | /** | ||||
* Returns "(<signaturesOfParamTypes>,...)" - unlike the other typesToSignature that also includes the return type, this one | |||||
* Returns "(<signaturesOfParamTypes>,...)" - unlike the other typesToSignature that also includes the return type, this one | |||||
* just deals with the parameter types. | * just deals with the parameter types. | ||||
*/ | */ | ||||
public static String typesToSignature(UnresolvedType[] paramTypes) { | public static String typesToSignature(UnresolvedType[] paramTypes) { |
} | } | ||||
/** | /** | ||||
* Create the old style (<1.6.9) format getter name which includes the aspect requesting access and the type containing the | |||||
* field in the name of the type. At 1.6.9 and above the name is simply ajc$get$<fieldname> | |||||
* Create the old style (<1.6.9) format getter name which includes the aspect requesting access and the type containing the | |||||
* field in the name of the type. At 1.6.9 and above the name is simply ajc$get$<fieldname> | |||||
*/ | */ | ||||
public static String privilegedAccessMethodForFieldGet(String name, UnresolvedType objectType, UnresolvedType aspectType) { | public static String privilegedAccessMethodForFieldGet(String name, UnresolvedType objectType, UnresolvedType aspectType) { | ||||
StringBuilder nameBuilder = new StringBuilder(); | StringBuilder nameBuilder = new StringBuilder(); | ||||
} | } | ||||
/** | /** | ||||
* Create the old style (<1.6.9) format setter name which includes the aspect requesting access and the type containing the | |||||
* field in the name of the type. At 1.6.9 and above the name is simply ajc$set$<fieldname> | |||||
* Create the old style (<1.6.9) format setter name which includes the aspect requesting access and the type containing the | |||||
* field in the name of the type. At 1.6.9 and above the name is simply ajc$set$<fieldname> | |||||
*/ | */ | ||||
public static String privilegedAccessMethodForFieldSet(String name, UnresolvedType objectType, UnresolvedType aspectType) { | public static String privilegedAccessMethodForFieldSet(String name, UnresolvedType objectType, UnresolvedType aspectType) { | ||||
return makeName("privFieldSet", aspectType.getNameAsIdentifier(), objectType.getNameAsIdentifier(), name); | return makeName("privFieldSet", aspectType.getNameAsIdentifier(), objectType.getNameAsIdentifier(), name); |
* | * | ||||
* There are two syntax styles for field access, the older style was in use up to AspectJ 1.6.9 and involves long named getters and | * There are two syntax styles for field access, the older style was in use up to AspectJ 1.6.9 and involves long named getters and | ||||
* setters which include the requesting aspect and the target type. The short style syntax is use from AspectJ 1.6.9 onwards is | * setters which include the requesting aspect and the target type. The short style syntax is use from AspectJ 1.6.9 onwards is | ||||
* simply 'ajc$get$<fieldname>' and 'ajc$set$<fieldname>' - as the requesting aspect isn't included in the name they can be shared | |||||
* simply 'ajc$get$<fieldname>' and 'ajc$set$<fieldname>' - as the requesting aspect isn't included in the name they can be shared | |||||
* across aspects. | * across aspects. | ||||
*/ | */ | ||||
public class PrivilegedAccessMunger extends ResolvedTypeMunger { | public class PrivilegedAccessMunger extends ResolvedTypeMunger { |
} | } | ||||
/** | /** | ||||
* Return the member generic signature that would be suitable for inclusion in a class file Signature attribute. For: <T> | |||||
* List<String> getThem(T t) {} we would create: <T:Ljava/lang/Object;>(TT;)Ljava/util/List<Ljava/lang/String;>;; | |||||
* Return the member generic signature that would be suitable for inclusion in a class file Signature attribute. For: <T> | |||||
* List<String> getThem(T t) {} we would create: <T:Ljava/lang/Object;>(TT;)Ljava/util/List<Ljava/lang/String;>;; | |||||
* | * | ||||
* @return the generic signature for the member that could be inserted into a class file | * @return the generic signature for the member that could be inserted into a class file | ||||
*/ | */ | ||||
/** | /** | ||||
* Return a resolvedmember in which all the type variables in the signature have been replaced with the given bindings. The | * Return a resolvedmember in which all the type variables in the signature have been replaced with the given bindings. The | ||||
* 'isParameterized' flag tells us whether we are creating a raw type version or not. if (isParameterized) then List<T> will | |||||
* turn into List<String> (for example) - if (!isParameterized) then List<T> will turn into List. | |||||
* 'isParameterized' flag tells us whether we are creating a raw type version or not. if (isParameterized) then List<T> will | |||||
* turn into List<String> (for example) - if (!isParameterized) then List<T> will turn into List. | |||||
*/ | */ | ||||
public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType, | public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType, | ||||
boolean isParameterized, List<String> aliases) { | boolean isParameterized, List<String> aliases) { | ||||
/** | /** | ||||
* Replace occurrences of type variables in the signature with values contained in the map. The map is of the form | * Replace occurrences of type variables in the signature with values contained in the map. The map is of the form | ||||
* A=String,B=Integer and so a signature List<A> Foo.m(B i) {} would become List<String> Foo.m(Integer i) {} | |||||
* A=String,B=Integer and so a signature List<A> Foo.m(B i) {} would become List<String> Foo.m(Integer i) {} | |||||
*/ | */ | ||||
public ResolvedMember parameterizedWith(Map<String, UnresolvedType> m, World w) { | public ResolvedMember parameterizedWith(Map<String, UnresolvedType> m, World w) { | ||||
// if (//isParameterized && <-- might need this bit... | // if (//isParameterized && <-- might need this bit... | ||||
} | } | ||||
/** | /** | ||||
* If this member is defined by a parameterized super-type, return the erasure of that member. For example: interface I<T> { T | |||||
* foo(T aTea); } class C implements I<String> { String foo(String aString) { return "something"; } } The resolved member for | |||||
* If this member is defined by a parameterized super-type, return the erasure of that member. For example: interface I<T> { T | |||||
* foo(T aTea); } class C implements I<String> { String foo(String aString) { return "something"; } } The resolved member for | |||||
* C.foo has signature String foo(String). The erasure of that member is Object foo(Object) -- use upper bound of type variable. | * C.foo has signature String foo(String). The erasure of that member is Object foo(Object) -- use upper bound of type variable. | ||||
* A type is a supertype of itself. | * A type is a supertype of itself. | ||||
*/ | */ |
/** | /** | ||||
* returns an iterator through all of the fields of this type, in order for checking from JVM spec 2ed 5.4.3.2. This means that | * returns an iterator through all of the fields of this type, in order for checking from JVM spec 2ed 5.4.3.2. This means that | ||||
* the order is | * the order is | ||||
* <p/> | |||||
* <ul> | * <ul> | ||||
* <li>fields from current class</li> | * <li>fields from current class</li> | ||||
* <li>recur into direct superinterfaces</li> | * <li>recur into direct superinterfaces</li> | ||||
* <li>recur into superclass</li> | * <li>recur into superclass</li> | ||||
* </ul> | * </ul> | ||||
* <p/> | |||||
* <p> | |||||
* We keep a hashSet of interfaces that we've visited so we don't spiral out into 2^n land. | * We keep a hashSet of interfaces that we've visited so we don't spiral out into 2^n land. | ||||
* </p> | |||||
*/ | */ | ||||
public Iterator<ResolvedMember> getFields() { | public Iterator<ResolvedMember> getFields() { | ||||
final Iterators.Filter<ResolvedType> dupFilter = Iterators.dupFilter(); | final Iterators.Filter<ResolvedType> dupFilter = Iterators.dupFilter(); | ||||
/** | /** | ||||
* returns an iterator through all of the methods of this type, in order for checking from JVM spec 2ed 5.4.3.3. This means that | * returns an iterator through all of the methods of this type, in order for checking from JVM spec 2ed 5.4.3.3. This means that | ||||
* the order is | * the order is | ||||
* <p/> | |||||
* <ul> | * <ul> | ||||
* <li>methods from current class</li> | * <li>methods from current class</li> | ||||
* <li>recur into superclass, all the way up, not touching interfaces</li> | * <li>recur into superclass, all the way up, not touching interfaces</li> | ||||
* <li>recur into all superinterfaces, in some unspecified order (but those 'closest' to this type are first)</li> | * <li>recur into all superinterfaces, in some unspecified order (but those 'closest' to this type are first)</li> | ||||
* </ul> | * </ul> | ||||
* <p/> | |||||
* | * | ||||
* @param wantGenerics is true if the caller would like all generics information, otherwise those methods are collapsed to their | * @param wantGenerics is true if the caller would like all generics information, otherwise those methods are collapsed to their | ||||
* erasure | * erasure | ||||
/** | /** | ||||
* Return an iterator over the types in this types hierarchy - starting with this type first, then all superclasses up to Object | * Return an iterator over the types in this types hierarchy - starting with this type first, then all superclasses up to Object | ||||
* and then all interfaces (starting with those 'nearest' this type). | * and then all interfaces (starting with those 'nearest' this type). | ||||
* | |||||
* @param wantGenerics true if the caller wants full generic information | |||||
* @param wantDeclaredParents true if the caller even wants those parents introduced via declare parents | |||||
* @return an iterator over all types in the hierarchy of this type | * @return an iterator over all types in the hierarchy of this type | ||||
*/ | */ | ||||
public Iterator<ResolvedType> getHierarchy() { | public Iterator<ResolvedType> getHierarchy() { | ||||
return getHierarchy(false, false); | return getHierarchy(false, false); | ||||
} | } | ||||
/** | |||||
* Return an iterator over the types in this types hierarchy - starting with this type first, then all superclasses up to Object | |||||
* and then all interfaces (starting with those 'nearest' this type). | |||||
* | |||||
* @param wantGenerics true if the caller wants full generic information | |||||
* @param wantDeclaredParents true if the caller even wants those parents introduced via declare parents | |||||
* @return an iterator over all types in the hierarchy of this type | |||||
*/ | |||||
public Iterator<ResolvedType> getHierarchy(final boolean wantGenerics, final boolean wantDeclaredParents) { | public Iterator<ResolvedType> getHierarchy(final boolean wantGenerics, final boolean wantDeclaredParents) { | ||||
final Iterators.Getter<ResolvedType, ResolvedType> interfaceGetter = new Iterators.Getter<ResolvedType, ResolvedType>() { | final Iterators.Getter<ResolvedType, ResolvedType> interfaceGetter = new Iterators.Getter<ResolvedType, ResolvedType>() { | ||||
/** | /** | ||||
* Do the two members conflict? Due to the change in 1.7.1, field itds on interfaces now act like 'default' fields - so types implementing | * Do the two members conflict? Due to the change in 1.7.1, field itds on interfaces now act like 'default' fields - so types implementing | ||||
* those fields get the field if they don't have it already, otherwise they keep what they have. The conflict detection below had to be | * those fields get the field if they don't have it already, otherwise they keep what they have. The conflict detection below had to be | ||||
* altered. Previously (<1.7.1) it is not a conflict if the declaring types are different. With v2itds it may still be a conflict if the | |||||
* altered. Previously (<1.7.1) it is not a conflict if the declaring types are different. With v2itds it may still be a conflict if the | |||||
* declaring types are different. | * declaring types are different. | ||||
*/ | */ | ||||
public static boolean conflictingSignature(Member m1, Member m2, boolean v2itds) { | public static boolean conflictingSignature(Member m1, Member m2, boolean v2itds) { | ||||
/** | /** | ||||
* returns an iterator through all of the pointcuts of this type, in order for checking from JVM spec 2ed 5.4.3.2 (as for | * returns an iterator through all of the pointcuts of this type, in order for checking from JVM spec 2ed 5.4.3.2 (as for | ||||
* fields). This means that the order is | * fields). This means that the order is | ||||
* <p/> | |||||
* <ul> | * <ul> | ||||
* <li>pointcuts from current class</li> | * <li>pointcuts from current class</li> | ||||
* <li>recur into direct superinterfaces</li> | * <li>recur into direct superinterfaces</li> | ||||
* <li>recur into superclass</li> | * <li>recur into superclass</li> | ||||
* </ul> | * </ul> | ||||
* <p/> | |||||
* <p> | |||||
* We keep a hashSet of interfaces that we've visited so we don't spiral out into 2^n land. | * We keep a hashSet of interfaces that we've visited so we don't spiral out into 2^n land. | ||||
* </p> | |||||
*/ | */ | ||||
public Iterator<ResolvedMember> getPointcuts() { | public Iterator<ResolvedMember> getPointcuts() { | ||||
final Iterators.Filter<ResolvedType> dupFilter = Iterators.dupFilter(); | final Iterators.Filter<ResolvedType> dupFilter = Iterators.dupFilter(); | ||||
/** | /** | ||||
* Returns a ResolvedType object representing the declaring type of this type, or null if this type does not represent a | * Returns a ResolvedType object representing the declaring type of this type, or null if this type does not represent a | ||||
* non-package-level-type. | * non-package-level-type. | ||||
* <p/> | |||||
* <p> | |||||
* <strong>Warning</strong>: This is guaranteed to work for all member types. For anonymous/local types, the only guarantee is | * <strong>Warning</strong>: This is guaranteed to work for all member types. For anonymous/local types, the only guarantee is | ||||
* given in JLS 13.1, where it guarantees that if you call getDeclaringType() repeatedly, you will eventually get the top-level | * given in JLS 13.1, where it guarantees that if you call getDeclaringType() repeatedly, you will eventually get the top-level | ||||
* class, but it does not say anything about classes in between. | * class, but it does not say anything about classes in between. | ||||
* </p> | |||||
* | * | ||||
* @return the declaring type, or null if it is not an nested type. | * @return the declaring type, or null if it is not an nested type. | ||||
*/ | */ | ||||
/** | /** | ||||
* Called for all type mungers but only does something if they share type variables with a generic type which they target. When | * Called for all type mungers but only does something if they share type variables with a generic type which they target. When | ||||
* this happens this routine will check for the target type in the target hierarchy and 'bind' any type parameters as | * this happens this routine will check for the target type in the target hierarchy and 'bind' any type parameters as | ||||
* appropriate. For example, for the ITD "List<T> I<T>.x" against a type like this: "class A implements I<String>" this routine | |||||
* will return a parameterized form of the ITD "List<String> I.x" | |||||
* appropriate. For example, for the ITD "List<T> I<T>.x" against a type like this: "class A implements I<String>" this routine | |||||
* will return a parameterized form of the ITD "List<String> I.x" | |||||
*/ | */ | ||||
public ConcreteTypeMunger fillInAnyTypeParameters(ConcreteTypeMunger munger) { | public ConcreteTypeMunger fillInAnyTypeParameters(ConcreteTypeMunger munger) { | ||||
boolean debug = false; | boolean debug = false; | ||||
* assignable to a variable of type X without loss of precision. | * assignable to a variable of type X without loss of precision. | ||||
* | * | ||||
* @param other the other type | * @param other the other type | ||||
* @param world the {@link World} in which the possible assignment should be checked. | |||||
* @return true iff variables of this type could be assigned values of other with possible conversion | * @return true iff variables of this type could be assigned values of other with possible conversion | ||||
*/ | */ | ||||
public final boolean isConvertableFrom(ResolvedType other) { | public final boolean isConvertableFrom(ResolvedType other) { | ||||
* assignment conversion as per JLS 2ed 5.2. For object types, this means supertypeOrEqual(THIS, OTHER). | * assignment conversion as per JLS 2ed 5.2. For object types, this means supertypeOrEqual(THIS, OTHER). | ||||
* | * | ||||
* @param other the other type | * @param other the other type | ||||
* @param world the {@link World} in which the possible assignment should be checked. | |||||
* @return true iff variables of this type could be assigned values of other without casting | * @return true iff variables of this type could be assigned values of other without casting | ||||
* @throws NullPointerException if other is null | * @throws NullPointerException if other is null | ||||
*/ | */ | ||||
/** | /** | ||||
* Determines if values of another type could possibly be cast to this type. The rules followed are from JLS 2ed 5.5, | * Determines if values of another type could possibly be cast to this type. The rules followed are from JLS 2ed 5.5, | ||||
* "Casting Conversion". | * "Casting Conversion". | ||||
* <p/> | |||||
* <p> | * <p> | ||||
* This method should be commutative, i.e., for all UnresolvedType a, b and all World w: | * This method should be commutative, i.e., for all UnresolvedType a, b and all World w: | ||||
* <p/> | |||||
* </p> | |||||
* <blockquote> | * <blockquote> | ||||
* | * | ||||
* <pre> | * <pre> | ||||
* </blockquote> | * </blockquote> | ||||
* | * | ||||
* @param other the other type | * @param other the other type | ||||
* @param world the {@link World} in which the possible coersion should be checked. | |||||
* @return true iff values of other could possibly be cast to this type. | * @return true iff values of other could possibly be cast to this type. | ||||
* @throws NullPointerException if other is null. | * @throws NullPointerException if other is null. | ||||
*/ | */ |
/** | /** | ||||
* return true if type variables are specified with the target type for this ITD. e.g. this would return true: | * return true if type variables are specified with the target type for this ITD. e.g. this would return true: | ||||
* "int I<A,B>.m() { return 42; }" | |||||
* "int I<A,B>.m() { return 42; }" | |||||
*/ | */ | ||||
public boolean sharesTypeVariablesWithGenericType() { | public boolean sharesTypeVariablesWithGenericType() { | ||||
return (typeVariableAliases != null && typeVariableAliases.size() > 0); | return (typeVariableAliases != null && typeVariableAliases.size() > 0); |
/** | /** | ||||
* Create a parameterized version of a generic type. | * Create a parameterized version of a generic type. | ||||
* | * | ||||
* @param aGenericType | |||||
* @param aBaseType | |||||
* @param someTypeParameters note, in the case of an inner type of a parameterized type, this parameter may legitimately be null | * @param someTypeParameters note, in the case of an inner type of a parameterized type, this parameter may legitimately be null | ||||
* @param inAWorld | * @param inAWorld | ||||
* @return | * @return | ||||
/** | /** | ||||
* Create a signature then delegate to the other factory method. Same input/output: baseTypeSignature="LSomeType;" arguments[0]= | * Create a signature then delegate to the other factory method. Same input/output: baseTypeSignature="LSomeType;" arguments[0]= | ||||
* something with sig "Pcom/Foo<Ljava/lang/String;>;" signature created = "PSomeType<Pcom/Foo<Ljava/lang/String;>;>;" | |||||
* something with sig "Pcom/Foo<Ljava/lang/String;>;" signature created = "PSomeType<Pcom/Foo<Ljava/lang/String;>;>;" | |||||
*/ | */ | ||||
public static UnresolvedType createUnresolvedParameterizedType(String baseTypeSignature, UnresolvedType[] arguments) { | public static UnresolvedType createUnresolvedParameterizedType(String baseTypeSignature, UnresolvedType[] arguments) { | ||||
StringBuffer parameterizedSig = new StringBuffer(); | StringBuffer parameterizedSig = new StringBuffer(); |
/** | /** | ||||
* Constructs a UnresolvedType for each JVM bytecode type signature in an incoming array. | * Constructs a UnresolvedType for each JVM bytecode type signature in an incoming array. | ||||
* | * | ||||
* @param names an array of JVM bytecode type signatures | |||||
* @param sigs an array of JVM bytecode type signatures | |||||
* @return an array of UnresolvedType objects. | * @return an array of UnresolvedType objects. | ||||
* @see #forSignature(String) | * @see #forSignature(String) | ||||
*/ | */ |
* whether reweaving is allowed. The format in the data stream is: | * whether reweaving is allowed. The format in the data stream is: | ||||
* | * | ||||
* Byte: Kind. UNTOUCHED|WOVEN|EXTENDED - If extended it can have two extra bits set 'REWEAVABLE' and 'REWEAVABLE_COMPRESSION_BIT' | * Byte: Kind. UNTOUCHED|WOVEN|EXTENDED - If extended it can have two extra bits set 'REWEAVABLE' and 'REWEAVABLE_COMPRESSION_BIT' | ||||
* Short: typeMungerCount - how many type mungers have affected this type <UnresolvedType & ResolvedTypeMunger>: The type mungers | |||||
* Short: typeMungerCount - how many type mungers have affected this type <UnresolvedType & ResolvedTypeMunger>: The type mungers | |||||
* themselves If we are reweavable then we also have: Short: Number of aspects that touched this type in some way when it was | * themselves If we are reweavable then we also have: Short: Number of aspects that touched this type in some way when it was | ||||
* previously woven <String> The fully qualified name of each type Int: Length of class file data (i.e. the unwovenclassfile) | |||||
* previously woven <String> The fully qualified name of each type Int: Length of class file data (i.e. the unwovenclassfile) | |||||
* Byte[]: The class file data, compressed if REWEAVABLE_COMPRESSION_BIT set. | * Byte[]: The class file data, compressed if REWEAVABLE_COMPRESSION_BIT set. | ||||
* | * | ||||
* @author Andy Clement | * @author Andy Clement |
import org.aspectj.weaver.World; | import org.aspectj.weaver.World; | ||||
/** | /** | ||||
* left && right | |||||
* left && right | |||||
* | * | ||||
* <p> | * <p> | ||||
* any binding to formals is explicitly forbidden for any composite by the language | * any binding to formals is explicitly forbidden for any composite by the language |
private boolean isForParameterAnnotationMatch; | private boolean isForParameterAnnotationMatch; | ||||
/** | /** | ||||
* TODO: write, read, equals & hashCode both in annotation hierarchy and in altered TypePattern hierarchy | |||||
* TODO: write, read, equals & hashCode both in annotation hierarchy and in altered TypePattern hierarchy | |||||
*/ | */ | ||||
protected AnnotationTypePattern() { | protected AnnotationTypePattern() { | ||||
super(); | super(); | ||||
public void setForParameterAnnotationMatch() { | public void setForParameterAnnotationMatch() { | ||||
} | } | ||||
} | |||||
} |
public class AnyTypePattern extends TypePattern { | public class AnyTypePattern extends TypePattern { | ||||
/** | /** | ||||
* Constructor for EllipsisTypePattern. | |||||
* | |||||
* @param includeSubtypes | |||||
* Constructor for AnyTypePattern. | |||||
*/ | */ | ||||
public AnyTypePattern() { | public AnyTypePattern() { | ||||
super(false, false, new TypePatternList()); | super(false, false, new TypePatternList()); | ||||
} | } | ||||
/** | /** | ||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType) | |||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(ResolvedType) | |||||
*/ | */ | ||||
@Override | @Override | ||||
protected boolean matchesExactly(ResolvedType type) { | protected boolean matchesExactly(ResolvedType type) { | ||||
} | } | ||||
/** | /** | ||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType) | |||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(ResolvedType) | |||||
*/ | */ | ||||
@Override | @Override | ||||
public FuzzyBoolean matchesInstanceof(ResolvedType type) { | public FuzzyBoolean matchesInstanceof(ResolvedType type) { | ||||
// return FuzzyBoolean.YES; | // return FuzzyBoolean.YES; | ||||
// } | // } | ||||
/** | /** | ||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesSubtypes(IType) | |||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesSubtypes(ResolvedType) | |||||
*/ | */ | ||||
@Override | @Override | ||||
protected boolean matchesSubtypes(ResolvedType type) { | protected boolean matchesSubtypes(ResolvedType type) { |
import org.aspectj.weaver.World; | import org.aspectj.weaver.World; | ||||
/** | /** | ||||
* Represents an attempt to bind the field of an annotation within a pointcut. For example:<br> | |||||
* <code><pre> | |||||
* Represents an attempt to bind the field of an annotation within a pointcut. For example: | |||||
* <pre><code> | |||||
* before(Level lev): execution(* *(..)) && @annotation(TraceAnnotation(lev)) | * before(Level lev): execution(* *(..)) && @annotation(TraceAnnotation(lev)) | ||||
* </pre></code><br> | |||||
* This binding annotation type pattern will be for 'lev'. | |||||
* </code></pre> | |||||
* <p>This binding annotation type pattern will be for 'lev'.</p> | |||||
*/ | */ | ||||
public class BindingAnnotationFieldTypePattern extends ExactAnnotationTypePattern implements BindingPattern { | public class BindingAnnotationFieldTypePattern extends ExactAnnotationTypePattern implements BindingPattern { | ||||
} | } | ||||
/** | /** | ||||
* returns "declare warning: <message>" or "declare error: <message>" | |||||
* returns "declare warning: <message>" or "declare error: <message>" | |||||
*/ | */ | ||||
public String toString() { | public String toString() { | ||||
StringBuffer buf = new StringBuffer(); | StringBuffer buf = new StringBuffer(); |
} | } | ||||
/** | /** | ||||
* returns "declare warning: <typepattern>: <message>" or "declare error: <typepattern>: <message>" | |||||
* returns "declare warning: <typepattern>: <message>" or "declare error: <typepattern>: <message>" | |||||
*/ | */ | ||||
public String toString() { | public String toString() { | ||||
StringBuffer buf = new StringBuffer(); | StringBuffer buf = new StringBuffer(); |
/** | /** | ||||
* Constructor for EllipsisTypePattern. | * Constructor for EllipsisTypePattern. | ||||
* | |||||
* @param includeSubtypes | |||||
*/ | */ | ||||
public EllipsisTypePattern() { | public EllipsisTypePattern() { | ||||
super(false, false, new TypePatternList()); | super(false, false, new TypePatternList()); | ||||
} | } | ||||
/** | /** | ||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType) | |||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(ResolvedType) | |||||
*/ | */ | ||||
@Override | @Override | ||||
protected boolean matchesExactly(ResolvedType type) { | protected boolean matchesExactly(ResolvedType type) { | ||||
} | } | ||||
/** | /** | ||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType) | |||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(ResolvedType) | |||||
*/ | */ | ||||
@Override | @Override | ||||
public FuzzyBoolean matchesInstanceof(ResolvedType type) { | public FuzzyBoolean matchesInstanceof(ResolvedType type) { |
import org.aspectj.weaver.World; | import org.aspectj.weaver.World; | ||||
/** | /** | ||||
* Represents an attempt to bind the field of an annotation within a pointcut. For example:<br> | |||||
* <code><pre> | |||||
* Represents an attempt to bind the field of an annotation within a pointcut. For example: | |||||
* <pre><code> | |||||
* before(Level lev): execution(* *(..)) && @annotation(TraceAnnotation(lev)) | * before(Level lev): execution(* *(..)) && @annotation(TraceAnnotation(lev)) | ||||
* </pre></code><br> | |||||
* This binding annotation type pattern will be for 'lev'. | |||||
* </code></pre> | |||||
* <p>This binding annotation type pattern will be for 'lev'.</p> | |||||
*/ | */ | ||||
public class ExactAnnotationFieldTypePattern extends ExactAnnotationTypePattern { | public class ExactAnnotationFieldTypePattern extends ExactAnnotationTypePattern { | ||||
* A marker class for bindings for which we want to ignore unbound issue and consider them as implicit binding - f.e. to handle | * A marker class for bindings for which we want to ignore unbound issue and consider them as implicit binding - f.e. to handle | ||||
* JoinPoint in @AJ advices | * JoinPoint in @AJ advices | ||||
* | * | ||||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||||
* @author Alexandre Vasseur (alex AT gnilux DOT com) | |||||
*/ | */ | ||||
public static class ImplicitFormalBinding extends FormalBinding { | public static class ImplicitFormalBinding extends FormalBinding { | ||||
public ImplicitFormalBinding(UnresolvedType type, String name, int index) { | public ImplicitFormalBinding(UnresolvedType type, String name, int index) { |
import org.aspectj.weaver.ResolvedType; | import org.aspectj.weaver.ResolvedType; | ||||
/** | /** | ||||
* pr354470. This is a special subtype of HasMemberTypePattern. In order to optimize this situation: <br> | |||||
* <code><pre> | |||||
* pr354470. This is a special subtype of HasMemberTypePattern. In order to optimize this situation: | |||||
* <pre><code> | |||||
* aspect X perthis(transactional()) {<br> | * aspect X perthis(transactional()) {<br> | ||||
* pointcut transactional: execution(@Foo * *(..));<br> | * pointcut transactional: execution(@Foo * *(..));<br> | ||||
* </pre></code> | |||||
* </code></pre> | |||||
* <p> | * <p> | ||||
* When this occurs we obviously only want an aspect instance when there is a method annotated with @Foo. For a regular execution | * When this occurs we obviously only want an aspect instance when there is a method annotated with @Foo. For a regular execution | ||||
* pointcut we couldn't really do this due to the multiple joinpoint signatures for each joinpoint (and so lots of types get the | * pointcut we couldn't really do this due to the multiple joinpoint signatures for each joinpoint (and so lots of types get the | ||||
* subclass is created to say 'if the supertype thinks it is a match, great, but if it doesnt then if there are ITDs on the target, | * subclass is created to say 'if the supertype thinks it is a match, great, but if it doesnt then if there are ITDs on the target, | ||||
* they might match so just say 'true''. Note that returning true is just confirming whether the 'mightHaveAspect' interface (and | * they might match so just say 'true''. Note that returning true is just confirming whether the 'mightHaveAspect' interface (and | ||||
* friends) are getting added. | * friends) are getting added. | ||||
* </p> | |||||
* | * | ||||
* @author Andy Clement | * @author Andy Clement | ||||
*/ | */ |
} | } | ||||
/** | /** | ||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType) | |||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(ResolvedType) | |||||
*/ | */ | ||||
@Override | @Override | ||||
protected boolean matchesExactly(ResolvedType type) { | protected boolean matchesExactly(ResolvedType type) { | ||||
} | } | ||||
/** | /** | ||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType) | |||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(ResolvedType) | |||||
*/ | */ | ||||
@Override | @Override | ||||
public FuzzyBoolean matchesInstanceof(ResolvedType type) { | public FuzzyBoolean matchesInstanceof(ResolvedType type) { | ||||
// return FuzzyBoolean.YES; | // return FuzzyBoolean.YES; | ||||
// } | // } | ||||
/** | /** | ||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesSubtypes(IType) | |||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesSubtypes(ResolvedType) | |||||
*/ | */ | ||||
@Override | @Override | ||||
protected boolean matchesSubtypes(ResolvedType type) { | protected boolean matchesSubtypes(ResolvedType type) { |
/** | /** | ||||
* A Pointcut or TypePattern visitor | * A Pointcut or TypePattern visitor | ||||
* | * | ||||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||||
* @author Alexandre Vasseur (alex AT gnilux DOT com) | |||||
*/ | */ | ||||
public interface PatternNodeVisitor { | public interface PatternNodeVisitor { | ||||
} | } | ||||
/** | /** | ||||
* Attempt to parse a typeIs(<category>) construct. If it cannot be parsed we just return null and that should cause the caller | |||||
* Attempt to parse a typeIs(<category>) construct. If it cannot be parsed we just return null and that should cause the caller | |||||
* to reset their position and attempt to consume it in another way. This means we won't have problems here: execution(* | * to reset their position and attempt to consume it in another way. This means we won't have problems here: execution(* | ||||
* typeIs(..)) because someone has decided to call a method the same as our construct. | * typeIs(..)) because someone has decided to call a method the same as our construct. | ||||
* | * | ||||
* Parse type variable declarations for a generic method or at the start of a signature pointcut to identify type variable names | * Parse type variable declarations for a generic method or at the start of a signature pointcut to identify type variable names | ||||
* in a generic type. | * in a generic type. | ||||
* | * | ||||
* @param includeParameterizedTypes | |||||
* @return | * @return | ||||
*/ | */ | ||||
public TypeVariablePatternList maybeParseTypeVariableList() { | public TypeVariablePatternList maybeParseTypeVariableList() { |
import org.aspectj.weaver.Shadow; | import org.aspectj.weaver.Shadow; | ||||
/** | /** | ||||
* A visitor that turns a pointcut into a type pattern equivalent for a perthis or pertarget matching: - pertarget(target(Foo)) => | |||||
* Foo+ (this one is a special case..) - pertarget(execution(* Foo.do()) => Foo - perthis(call(* Foo.do()) => * - perthis(!call(* | |||||
* Foo.do()) => * (see how the ! has been absorbed here..) | |||||
* A visitor that turns a pointcut into a type pattern equivalent for a perthis or pertarget matching: - pertarget(target(Foo)) → | |||||
* Foo+ (this one is a special case..) - pertarget(execution(* Foo.do()) → Foo - perthis(call(* Foo.do()) → * - perthis(!call(* | |||||
* Foo.do()) → * (see how the ! has been absorbed here..) | |||||
* | * | ||||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||||
* @author Alexandre Vasseur (alex AT gnilux DOT com) | |||||
*/ | */ | ||||
public class PerThisOrTargetPointcutVisitor extends AbstractPatternNodeVisitor { | public class PerThisOrTargetPointcutVisitor extends AbstractPatternNodeVisitor { | ||||
* Resolves and removes ReferencePointcuts, replacing with basic ones | * Resolves and removes ReferencePointcuts, replacing with basic ones | ||||
* | * | ||||
* @param inAspect the aspect to resolve relative to | * @param inAspect the aspect to resolve relative to | ||||
* @param bindings a Map from formal index in the current lexical context -> formal index in the concrete advice that will run | |||||
* @param bindings a Map from formal index in the current lexical context → formal index in the concrete advice that will run | |||||
* | * | ||||
* This must always return a new Pointcut object (even if the concretized Pointcut is identical to the resolved one). | * This must always return a new Pointcut object (even if the concretized Pointcut is identical to the resolved one). | ||||
* That behavior is assumed in many places. XXX fix implementors to handle state | * That behavior is assumed in many places. XXX fix implementors to handle state |
* | * | ||||
* within | * within | ||||
* | * | ||||
* @within staticinitialization [make sure this has a fast match method] adviceexecution handler get, set withincode | |||||
* @withincode execution, initialization, preinitialization call | |||||
* @annotation this, target | |||||
* @this, @target args | |||||
* @args cflow, cflowbelow if | |||||
* {@literal @}within staticinitialization [make sure this has a fast match method] adviceexecution handler get, set withincode | |||||
* {@literal @}withincode execution, initialization, preinitialization call | |||||
* {@literal @}annotation this, target | |||||
* {@literal @}this, {@literal @}target args | |||||
* {@literal @}args cflow, cflowbelow if | |||||
*/ | */ | ||||
public int compare(Pointcut p1, Pointcut p2) { | public int compare(Pointcut p1, Pointcut p2) { | ||||
// important property for a well-defined comparator | // important property for a well-defined comparator |
* Foo where Foo exists and is generic Parser creates WildTypePattern namePatterns={Foo} resolveBindings resolves Foo to RT(Foo - | * Foo where Foo exists and is generic Parser creates WildTypePattern namePatterns={Foo} resolveBindings resolves Foo to RT(Foo - | ||||
* raw) return ExactTypePattern(LFoo;) | * raw) return ExactTypePattern(LFoo;) | ||||
* | * | ||||
* Foo<String> where Foo exists and String meets the bounds Parser creates WildTypePattern namePatterns = {Foo}, | |||||
* Foo<String> where Foo exists and String meets the bounds Parser creates WildTypePattern namePatterns = {Foo}, | |||||
* typeParameters=WTP{String} resolveBindings resolves typeParameters to ExactTypePattern(String) resolves Foo to RT(Foo) returns | * typeParameters=WTP{String} resolveBindings resolves typeParameters to ExactTypePattern(String) resolves Foo to RT(Foo) returns | ||||
* ExactTypePattern(PFoo<String>; - parameterized) | |||||
* ExactTypePattern(PFoo<String>; - parameterized) | |||||
* | * | ||||
* Foo<Str*> where Foo exists and takes one bound Parser creates WildTypePattern namePatterns = {Foo}, typeParameters=WTP{Str*} | |||||
* Foo<Str*> where Foo exists and takes one bound Parser creates WildTypePattern namePatterns = {Foo}, typeParameters=WTP{Str*} | |||||
* resolveBindings resolves typeParameters to WTP{Str*} resolves Foo to RT(Foo) returns WildTypePattern(name = Foo, typeParameters = | * resolveBindings resolves typeParameters to WTP{Str*} resolves Foo to RT(Foo) returns WildTypePattern(name = Foo, typeParameters = | ||||
* WTP{Str*} isGeneric=false) | * WTP{Str*} isGeneric=false) | ||||
* | * | ||||
* Fo*<String> Parser creates WildTypePattern namePatterns = {Fo*}, typeParameters=WTP{String} resolveBindings resolves | |||||
* Fo*<String> Parser creates WildTypePattern namePatterns = {Fo*}, typeParameters=WTP{String} resolveBindings resolves | |||||
* typeParameters to ETP{String} returns WildTypePattern(name = Fo*, typeParameters = ETP{String} isGeneric=false) | * typeParameters to ETP{String} returns WildTypePattern(name = Fo*, typeParameters = ETP{String} isGeneric=false) | ||||
* | * | ||||
* | * | ||||
* Foo<?> | |||||
* Foo<?> | |||||
* | * | ||||
* Foo<? extends Number> | |||||
* Foo<? extends Number> | |||||
* | * | ||||
* Foo<? extends Number+> | |||||
* Foo<? extends Number+> | |||||
* | * | ||||
* Foo<? super Number> | |||||
* Foo<? super Number> | |||||
* | * | ||||
*/ | */ | ||||
public class WildTypePattern extends TypePattern { | public class WildTypePattern extends TypePattern { | ||||
} | } | ||||
/** | /** | ||||
* @see org.aspectj.weaver.TypePattern#matchesExactly(IType) | |||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(ResolvedType) | |||||
*/ | */ | ||||
@Override | @Override | ||||
protected boolean matchesExactly(ResolvedType type) { | protected boolean matchesExactly(ResolvedType type) { | ||||
} | } | ||||
/** | /** | ||||
* @see org.aspectj.weaver.TypePattern#matchesInstanceof(IType) | |||||
* @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(ResolvedType) | |||||
*/ | */ | ||||
@Override | @Override | ||||
public FuzzyBoolean matchesInstanceof(ResolvedType type) { | public FuzzyBoolean matchesInstanceof(ResolvedType type) { |
/** | /** | ||||
* Format arguments into a comma separated list | * Format arguments into a comma separated list | ||||
* | * | ||||
* @param names array of argument names | |||||
* @param args array of arguments | * @param args array of arguments | ||||
* @return the formated list | * @return the formated list | ||||
*/ | */ |
* static initialization of the type). | * static initialization of the type). | ||||
* @param aMethod the method being called | * @param aMethod the method being called | ||||
* @param callerType the declared type of the caller | * @param callerType the declared type of the caller | ||||
* @param receiverType the declared type of the recipient of the call | |||||
* @return a ShadowMatch indicating whether the pointcut always, sometimes, or never | * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never | ||||
* matches join points representing a call to this method during the execution of the given member. | * matches join points representing a call to this method during the execution of the given member. | ||||
*/ | */ |
/** | /** | ||||
* Determine whether or not this pointcut matches the static initialization of the given class. | * Determine whether or not this pointcut matches the static initialization of the given class. | ||||
* | * | ||||
* @param aClass the class being statically initialized | |||||
* @param aType the class being statically initialized | |||||
* @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matchs join points representing the static | * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matchs join points representing the static | ||||
* initialization of the given type | * initialization of the given type | ||||
*/ | */ |
* requires all the files every time. To work around this, | * requires all the files every time. To work around this, | ||||
* set the global property CLEAN ("build.compiler.clean") to delete | * set the global property CLEAN ("build.compiler.clean") to delete | ||||
* all .class files in the destination directory before compiling. | * all .class files in the destination directory before compiling. | ||||
* </p> | |||||
* | * | ||||
* <p><u>Warnings</u>: | |||||
* <p><u>Warnings</u>:</p> | |||||
* <ol> | * <ol> | ||||
* <li>cleaning will not work if no destination directory | * <li>cleaning will not work if no destination directory | ||||
* is specified in the javac task. | * is specified in the javac task. | ||||
* <li>If no files are out of date, then the adapter is <b>never</b> called | * <li>If no files are out of date, then the adapter is <b>never</b> called | ||||
* and thus cannot gain control to clean out the destination dir. | * and thus cannot gain control to clean out the destination dir. | ||||
* </li> | * </li> | ||||
* <p> | |||||
* </ol> | |||||
* | * | ||||
* @author Wes Isberg | * @author Wes Isberg | ||||
* @since AspectJ 1.1, Ant 1.5.1 | * @since AspectJ 1.1, Ant 1.5.1 |
* This task was developed by the <a href="http://aspectj.org">AspectJ Project</a> | * This task was developed by the <a href="http://aspectj.org">AspectJ Project</a> | ||||
* | * | ||||
* @author <a href="mailto:palm@parc.xerox.com">Jeffrey Palm</a> | * @author <a href="mailto:palm@parc.xerox.com">Jeffrey Palm</a> | ||||
* @see org.aspectj.tools.ant.taskdefs.compilers.AjcCompiler | |||||
* @see org.aspectj.tools.ant.taskdefs.compilers.Ajc | |||||
*/ | */ | ||||
public class Ajc2 extends Javac { | public class Ajc2 extends Javac { | ||||
} | } | ||||
/** | /** | ||||
* Returns if the <code>-preprocess</code> flag is turned on. | |||||
* Set the <code>-preprocess</code> flag. | |||||
* | * | ||||
* @return <code>true</code> if the <code>-preprocess</code> flag is on. | |||||
* @param preprocess <code>true</code> turns on the <code>-preprocess</code> flag. | |||||
* @see Ajc2#preprocess | * @see Ajc2#preprocess | ||||
*/ | */ | ||||
public void setPreprocess(boolean preprocess) { | public void setPreprocess(boolean preprocess) { | ||||
* to <code>true</code>. | * to <code>true</code>. | ||||
* | * | ||||
* @return new PatternSet.NameEntry to be added to the include list. | * @return new PatternSet.NameEntry to be added to the include list. | ||||
* @see org.apache.tools.taskdefs.Javac#createInclude() | |||||
* @see org.apache.tools.ant.taskdefs.Javac#createInclude() | |||||
*/ | */ | ||||
public PatternSet.NameEntry createInclude() { | public PatternSet.NameEntry createInclude() { | ||||
haveIncludes = true; | haveIncludes = true; | ||||
* to <code>true</code>. | * to <code>true</code>. | ||||
* | * | ||||
* @return new PatternSet.NameEntry to be added to the exclude list. | * @return new PatternSet.NameEntry to be added to the exclude list. | ||||
* @see org.apache.tools.taskdefs.Javac#createExclude() | |||||
* @see org.apache.tools.ant.taskdefs.Javac#createExclude() | |||||
*/ | */ | ||||
public PatternSet.NameEntry createExclude() { | public PatternSet.NameEntry createExclude() { | ||||
haveExcludes = true; | haveExcludes = true; | ||||
* to <code>true</code>. | * to <code>true</code>. | ||||
* | * | ||||
* @param includes Comma-separated list of includes. | * @param includes Comma-separated list of includes. | ||||
* @see org.apache.tools.taskdefs.Javac#setIncludes(java.lang.String) | |||||
* @see org.apache.tools.ant.taskdefs.Javac#setIncludes(java.lang.String) | |||||
*/ | */ | ||||
public void setIncludes(String includes) { | public void setIncludes(String includes) { | ||||
haveIncludes = true; | haveIncludes = true; | ||||
* to <code>true</code>. | * to <code>true</code>. | ||||
* | * | ||||
* @param excludes Comma-separated list of excludes. | * @param excludes Comma-separated list of excludes. | ||||
* @see org.apache.tools.taskdefs.Javac#setExcludes(java.lang.String) | |||||
* @see org.apache.tools.ant.taskdefs.Javac#setExcludes(java.lang.String) | |||||
*/ | */ | ||||
public void setExcludes(String excludes) { | public void setExcludes(String excludes) { | ||||
haveExcludes = true; | haveExcludes = true; |
* </pre> | * </pre> | ||||
* | * | ||||
* @param javac the Javac command to implement (not null) | * @param javac the Javac command to implement (not null) | ||||
* @param ajc the AjcTask to adapt (not null) | |||||
* @param destDir the File class destination directory (may be null) | |||||
* @return null if no error, or String error otherwise | * @return null if no error, or String error otherwise | ||||
*/ | */ | ||||
public String setupAjc(Javac javac) { | public String setupAjc(Javac javac) { | ||||
} | } | ||||
/** | /** | ||||
* -Xlint - set default level of -Xlint messages to warning (same as </code>-Xlint:warning</code>) | |||||
* -Xlint - set default level of -Xlint messages to warning (same as <code>-Xlint:warning</code>) | |||||
*/ | */ | ||||
public void setXlintwarnings(boolean xlintwarnings) { | public void setXlintwarnings(boolean xlintwarnings) { | ||||
cmd.addFlag("-Xlint", xlintwarnings); | cmd.addFlag("-Xlint", xlintwarnings); | ||||
} | } | ||||
/** | /** | ||||
* @throw BuildException if options conflict | |||||
* @throws BuildException if options conflict | |||||
*/ | */ | ||||
protected void verifyOptions() { | protected void verifyOptions() { | ||||
StringBuffer sb = new StringBuffer(); | StringBuffer sb = new StringBuffer(); | ||||
* | * | ||||
* @param args String[] of the complete compiler command to execute | * @param args String[] of the complete compiler command to execute | ||||
* | * | ||||
* @see DefaultCompilerAdapter#executeExternalCompile(String[], int) | |||||
* @throws BuildException if ajc aborts (negative value) or if failonerror and there were compile errors. | * @throws BuildException if ajc aborts (negative value) or if failonerror and there were compile errors. | ||||
*/ | */ | ||||
protected void executeInOtherVM(String[] args) { | protected void executeInOtherVM(String[] args) { | ||||
} | } | ||||
// ------------------------------ setup and reporting | // ------------------------------ setup and reporting | ||||
/** @return null if path null or empty, String rendition otherwise */ | |||||
protected static void addFlaggedPath(String flag, Path path, List<String> list) { | protected static void addFlaggedPath(String flag, Path path, List<String> list) { | ||||
if (!LangUtil.isEmpty(flag) && ((null != path) && (0 < path.size()))) { | if (!LangUtil.isEmpty(flag) && ((null != path) && (0 < path.size()))) { | ||||
list.add(flag); | list.add(flag); |
* This task was developed by the <a href="http://aspectj.org">AspectJ Project</a> | * This task was developed by the <a href="http://aspectj.org">AspectJ Project</a> | ||||
* | * | ||||
* @author <a href="mailto:palm@parc.xerox.com">Jeffrey Palm</a> | * @author <a href="mailto:palm@parc.xerox.com">Jeffrey Palm</a> | ||||
* @see org.aspectj.tools.ant.taskdefs.Ajc | |||||
* @see org.aspectj.tools.ant.taskdefs.Ajc2 | |||||
*/ | */ | ||||
public class Ajc extends DefaultCompilerAdapter { | public class Ajc extends DefaultCompilerAdapter { | ||||
/** | /** | ||||
* Checks the command line for arguments allowed only in AJC and | * Checks the command line for arguments allowed only in AJC and | ||||
* disallowed by AJC and then calls the <code>compile()<code> method. | |||||
* disallowed by AJC and then calls the <code>compile()</code> method. | |||||
* | * | ||||
* @return true if a good compile, false otherwise. | * @return true if a good compile, false otherwise. | ||||
* @throws org.apache.tools.ant.BuildException | * @throws org.apache.tools.ant.BuildException | ||||
/** | /** | ||||
* Logs the compilation parameters, adds the files to compile and logs the | * Logs the compilation parameters, adds the files to compile and logs the | ||||
* &qout;niceSourceList" | |||||
* "niceSourceList" | |||||
*/ | */ | ||||
@Override | @Override | ||||
protected void logAndAddFilesToCompile(Commandline cmd) { | protected void logAndAddFilesToCompile(Commandline cmd) { |
* thread. You can instantiate multiple games at once. For the time being | * thread. You can instantiate multiple games at once. For the time being | ||||
* the only way to end the game is to exit from the Java VM. | * the only way to end the game is to exit from the Java VM. | ||||
* | * | ||||
* @param isDemo Controls whether the game runs in demo mode or not. True | |||||
* @param mode Controls whether the game runs in demo mode or not. True | |||||
* means it is a demo, false means it runs in normal 2 player mode. | * means it is a demo, false means it runs in normal 2 player mode. | ||||
*/ | */ | ||||
public Game(String mode) { | public Game(String mode) { |
* thread. You can instantiate multiple games at once. For the time being | * thread. You can instantiate multiple games at once. For the time being | ||||
* the only way to end the game is to exit from the Java VM. | * the only way to end the game is to exit from the Java VM. | ||||
* | * | ||||
* @param isDemo Controls whether the game runs in demo mode or not. True | |||||
* @param mode Controls whether the game runs in demo mode or not. True | |||||
* means it is a demo, false means it runs in normal 2 player mode. | * means it is a demo, false means it runs in normal 2 player mode. | ||||
*/ | */ | ||||
public Game(String mode) { | public Game(String mode) { |
/** | /** | ||||
* Flatten File[] to String. | * Flatten File[] to String. | ||||
* | * | ||||
* @param files the File[] of paths to flatten - null ignored | |||||
* @param paths the String[] of paths to flatten - null ignored | |||||
* @param infix the String infix to use - null treated as File.pathSeparator | * @param infix the String infix to use - null treated as File.pathSeparator | ||||
*/ | */ | ||||
public static String flatten(String[] paths, String infix) { | public static String flatten(String[] paths, String infix) { | ||||
* result. | * result. | ||||
* | * | ||||
* @param sought the String text to seek in the file | * @param sought the String text to seek in the file | ||||
* @param sources the List of String paths to the source files | |||||
* @param sourcePath the String of paths to the source files | |||||
* @param listAll if false, only list first match in file | * @param listAll if false, only list first match in file | ||||
* @param List sink the List for String entries of the form {sourcePath}:line:column | |||||
* @param sink the List of String entries of the form {sourcePath}:line:column | |||||
* @return String error if any, or add String entries to sink | * @return String error if any, or add String entries to sink | ||||
*/ | */ | ||||
public static String lineSeek(String sought, String sourcePath, boolean listAll, List<String> sink) { | public static String lineSeek(String sought, String sourcePath, boolean listAll, List<String> sink) { |
* Renders exception <code>t</code> after unwrapping and eliding any test packages. | * Renders exception <code>t</code> after unwrapping and eliding any test packages. | ||||
* | * | ||||
* @param t <code>Throwable</code> to print. | * @param t <code>Throwable</code> to print. | ||||
* @see #maxStackTrace | |||||
* @see StringChecker#TEST_PACKAGES | |||||
*/ | */ | ||||
public static String renderException(Throwable t) { | public static String renderException(Throwable t) { | ||||
return renderException(t, true); | return renderException(t, true); |
*/ | */ | ||||
public interface PartialComparable { | public interface PartialComparable { | ||||
/** | /** | ||||
* @returns <ul> | |||||
* <li>+1 if this is greater than other</li> | |||||
* <li>-1 if this is less than other</li> | |||||
* <li>0 if this is not comparable to other</li> | |||||
* </ul> | |||||
* @return <ul> | |||||
* <li>+1 if this is greater than other</li> | |||||
* <li>-1 if this is less than other</li> | |||||
* <li>0 if this is not comparable to other</li> | |||||
* </ul> | |||||
* | * | ||||
* <b> Note: returning 0 from this method doesn't mean the same thing as returning 0 from | |||||
* java.util.Comparable.compareTo()</b> | |||||
* <b> Note: returning 0 from this method doesn't mean the same thing as returning 0 from | |||||
* java.util.Comparable.compareTo()</b> | |||||
*/ | */ | ||||
int compareTo(Object other); | int compareTo(Object other); | ||||
/** | /** | ||||
* @param objects must all implement PartialComparable | * @param objects must all implement PartialComparable | ||||
* | * | ||||
* @returns the same members as objects, but sorted according to their partial order. returns null if the objects are cyclical | |||||
* @return the same members as objects, but sorted according to their partial order. returns null if the objects are cyclical | |||||
* | * | ||||
*/ | */ | ||||
public static <T extends PartialComparable> List<T> sort(List<T> objects) { | public static <T extends PartialComparable> List<T> sort(List<T> objects) { |
* Return an object that can access a particular value of this annotation. | * Return an object that can access a particular value of this annotation. | ||||
* | * | ||||
* @param valueType The type from the annotation that is of interest | * @param valueType The type from the annotation that is of interest | ||||
* @param the formal name expressed in the pointcut, can be used to disambiguate | |||||
* @param formalName the formal name expressed in the pointcut, can be used to disambiguate | |||||
* @return a variable that represents access to that annotation value | * @return a variable that represents access to that annotation value | ||||
*/ | */ | ||||
@Override | @Override |
/** | /** | ||||
* Annotation defined aspect reader. Reads the Java 5 annotations and turns them into AjAttributes | * Annotation defined aspect reader. Reads the Java 5 annotations and turns them into AjAttributes | ||||
* | * | ||||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||||
* @author Alexandre Vasseur (alex AT gnilux DOT com) | |||||
*/ | */ | ||||
public class AtAjAttributes { | public class AtAjAttributes { | ||||
} | } | ||||
/** | /** | ||||
* Return a nicely formatted method string, for example: int X.foo(java.lang.String) | |||||
* @return a nicely formatted method string, for example: int X.foo(java.lang.String) | |||||
*/ | */ | ||||
public static String getMethodForMessage(AjAttributeMethodStruct methodstructure) { | public static String getMethodForMessage(AjAttributeMethodStruct methodstructure) { | ||||
StringBuffer sb = new StringBuffer(); | StringBuffer sb = new StringBuffer(); | ||||
* LazyResolvedPointcutDefinition lazyly resolve the pointcut so that we have time to register all pointcut referenced before | * LazyResolvedPointcutDefinition lazyly resolve the pointcut so that we have time to register all pointcut referenced before | ||||
* pointcut resolution happens | * pointcut resolution happens | ||||
* | * | ||||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||||
* @author Alexandre Vasseur (alex AT gnilux DOT com) | |||||
*/ | */ | ||||
public static class LazyResolvedPointcutDefinition extends ResolvedPointcutDefinition { | public static class LazyResolvedPointcutDefinition extends ResolvedPointcutDefinition { | ||||
private final Pointcut m_pointcutUnresolved; // null for abstract | private final Pointcut m_pointcutUnresolved; // null for abstract |
/** | /** | ||||
* Looks for all access to method or field that are not public within the body of the around advices and replace the invocations to | * Looks for all access to method or field that are not public within the body of the around advices and replace the invocations to | ||||
* a wrapper call so that the around advice can further be inlined. | * a wrapper call so that the around advice can further be inlined. | ||||
* <p/> | |||||
* <p> | |||||
* This munger is used for @AJ aspects for which inlining wrapper is not done at compile time. | * This munger is used for @AJ aspects for which inlining wrapper is not done at compile time. | ||||
* <p/> | |||||
* </p> | |||||
* <p> | |||||
* Specific state and logic is kept in the munger ala ITD so that call/get/set pointcuts can still be matched on the wrapped member | * Specific state and logic is kept in the munger ala ITD so that call/get/set pointcuts can still be matched on the wrapped member | ||||
* thanks to the EffectiveSignature attribute. | * thanks to the EffectiveSignature attribute. | ||||
* </p> | |||||
* | * | ||||
* @author Alexandre Vasseur | * @author Alexandre Vasseur | ||||
* @author Andy Clement | * @author Andy Clement |
/** | /** | ||||
* Create an initialization join point associated with a constructor, but not with any body of code yet. If this is actually | * Create an initialization join point associated with a constructor, but not with any body of code yet. If this is actually | ||||
* matched, it's range will be set when we inline self constructors. | |||||
* matched, its range will be set when we inline self constructors. | |||||
* | * | ||||
* @param constructor The constructor starting this initialization. | * @param constructor The constructor starting this initialization. | ||||
*/ | */ | ||||
public String getActualTargetType() { | public String getActualTargetType() { | ||||
return actualInstructionTargetType; | return actualInstructionTargetType; | ||||
} | } | ||||
} | |||||
} |
} | } | ||||
/** | /** | ||||
* Returns a list of type variable aliases used in this munger. For example, if the ITD is 'int I<A,B>.m(List<A> las,List<B> | |||||
* Returns a list of type variable aliases used in this munger. For example, if the ITD is 'int I<A,B>.m(List<A> las,List<B> | |||||
* lbs) {}' then this returns a list containing the strings "A" and "B". | * lbs) {}' then this returns a list containing the strings "A" and "B". | ||||
*/ | */ | ||||
public List<String> getTypeVariableAliases() { | public List<String> getTypeVariableAliases() { |
* replace an instruction handle with another instruction, in this case, a branch instruction. | * replace an instruction handle with another instruction, in this case, a branch instruction. | ||||
* | * | ||||
* @param ih the instruction handle to replace. | * @param ih the instruction handle to replace. | ||||
* @param branchInstruction the branch instruction to replace ih with | |||||
* @param replacementInstructions the branch instruction to replace ih with | |||||
* @param enclosingMethod where to find ih's instruction list. | * @param enclosingMethod where to find ih's instruction list. | ||||
*/ | */ | ||||
public static void replaceInstruction(InstructionHandle ih, InstructionList replacementInstructions, | public static void replaceInstruction(InstructionHandle ih, InstructionList replacementInstructions, |
Enumeration<URL> getResources(String name) throws IOException; | Enumeration<URL> getResources(String name) throws IOException; | ||||
/** | /** | ||||
* In an OSGi environment, determin which bundle a URL originated from. | |||||
* In a non-OSGi environment, implementors should return <code>null<code>. | |||||
* In an OSGi environment, determine which bundle a URL originated from. | |||||
* In a non-OSGi environment, implementors should return <code>null</code>. | |||||
* @param url | * @param url | ||||
* @return | * @return | ||||
* @deprecated use getFile() or getClassLoaderName() | * @deprecated use getFile() or getClassLoaderName() |
/** | /** | ||||
* A POJO that contains raw strings from the XML (sort of XMLBean for our simple LTW DTD) | * A POJO that contains raw strings from the XML (sort of XMLBean for our simple LTW DTD) | ||||
* | * | ||||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||||
* @author Alexandre Vasseur (alex AT gnilux DOT com) | |||||
*/ | */ | ||||
public class Definition { | public class Definition { | ||||
// } | // } | ||||
/** | /** | ||||
* @Override | |||||
* Override | |||||
*/ | */ | ||||
@Override | @Override | ||||
protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) { | protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) { |
} | } | ||||
/** | /** | ||||
* Generates the pointcut details for the given pointcut, for example an anonymous pointcut will return '<anonymous pointcut>' | |||||
* Generates the pointcut details for the given pointcut, for example an anonymous pointcut will return '<anonymous pointcut>' | |||||
* and a named pointcut called p() will return 'p()..' | * and a named pointcut called p() will return 'p()..' | ||||
*/ | */ | ||||
public static String genPointcutDetails(Pointcut pcd) { | public static String genPointcutDetails(Pointcut pcd) { |
* @param name | * @param name | ||||
* @param b | * @param b | ||||
* @param before whether we are dumping before weaving | * @param before whether we are dumping before weaving | ||||
* @throws Throwable | |||||
*/ | */ | ||||
protected void dump(String name, byte[] b, boolean before) { | protected void dump(String name, byte[] b, boolean before) { | ||||
String dirName = getDumpDir(); | String dirName = getDumpDir(); |