@@ -0,0 +1,240 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2005 Contributors. | |||
* All rights reserved. | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Public License v1.0 | |||
* which accompanies this distribution and is available at | |||
* http://eclipse.org/legal/epl-v10.html | |||
* | |||
* Contributors: | |||
* Adrian Colyer Initial implementation | |||
* ******************************************************************/ | |||
package org.aspectj.bridge.context; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
import java.util.Map; | |||
import java.util.Stack; | |||
/** | |||
* @author colyer | |||
* This class is responsible for tracking progress through the various phases of | |||
* compilation and weaving. When an exception occurs (or a message is issued, if | |||
* desired), you can ask this class for a "stack trace" that gives information about | |||
* what the compiler was doing at the time. The trace will say something like: | |||
* | |||
* when matching pointcut xyz | |||
* when matching shadow sss | |||
* when weaving type ABC | |||
* when weaving shadow mungers | |||
* | |||
* Since we can't use ThreadLocal (have to work on 1.3), we use a | |||
* map from Thread -> ContextStack. | |||
*/ | |||
public class CompilationAndWeavingContext { | |||
private static int nextTokenId = 1; | |||
// unique constants for the different phases that can be registered | |||
// "FRONT END" | |||
public static final int BATCH_BUILD = 0; | |||
public static final int INCREMENTAL_BUILD = 1; | |||
public static final int PROCESSING_COMPILATION_UNIT = 2; | |||
public static final int RESOLVING_COMPILATION_UNIT = 3; | |||
public static final int ANALYSING_COMPILATION_UNIT = 4; | |||
public static final int GENERATING_UNWOVEN_CODE_FOR_COMPILATION_UNIT = 5; | |||
public static final int COMPLETING_TYPE_BINDINGS = 6; | |||
public static final int PROCESSING_DECLARE_PARENTS = 7; | |||
public static final int CHECK_AND_SET_IMPORTS = 8; | |||
public static final int CONNECTING_TYPE_HIERARCHY = 9; | |||
public static final int BUILDING_FIELDS_AND_METHODS = 10; | |||
public static final int COLLECTING_ITDS_AND_DECLARES = 11; | |||
public static final int PROCESSING_DECLARE_ANNOTATIONS = 12; | |||
public static final int WEAVING_INTERTYPE_DECLARATIONS = 13; | |||
public static final int RESOLVING_POINTCUT_DECLARATIONS = 14; | |||
public static final int ADDING_DECLARE_WARNINGS_AND_ERRORS = 15; | |||
public static final int VALIDATING_AT_ASPECTJ_ANNOTATIONS = 16; | |||
public static final int ACCESS_FOR_INLINE = 17; | |||
public static final int ADDING_AT_ASPECTJ_ANNOTATIONS = 18; | |||
public static final int FIXING_SUPER_CALLS_IN_ITDS = 19; | |||
public static final int FIXING_SUPER_CALLS = 20; | |||
public static final int OPTIMIZING_THIS_JOIN_POINT_CALLS = 21; | |||
// "BACK END" | |||
public static final int WEAVING = 22; | |||
public static final int PROCESSING_REWEAVABLE_STATE = 23; | |||
public static final int PROCESSING_TYPE_MUNGERS = 24; | |||
public static final int WEAVING_ASPECTS = 25; | |||
public static final int WEAVING_CLASSES = 26; | |||
public static final int WEAVING_TYPE = 27; | |||
public static final int MATCHING_SHADOW = 28; | |||
public static final int IMPLEMENTING_ON_SHADOW = 29; | |||
public static final int MATCHING_POINTCUT = 30; | |||
public static final int MUNGING_WITH = 31; | |||
// phase names | |||
public static final String[] PHASE_NAMES = new String[] { | |||
"batch building", | |||
"incrementally building", | |||
"processing compilation unit", | |||
"resolving types defined in compilation unit", | |||
"analysing types defined in compilation unit", | |||
"generating unwoven code for type defined in compilation unit", | |||
"completing type bindings", | |||
"processing declare parents", | |||
"checking and setting imports", | |||
"connecting type hierarchy", | |||
"building fields and methods", | |||
"collecting itds and declares", | |||
"processing declare annotations", | |||
"weaving intertype declarations", | |||
"resolving pointcut declarations", | |||
"adding declare warning and errors", | |||
"validating @AspectJ annotations", | |||
"creating accessors for inlining", | |||
"adding @AspectJ annotations", | |||
"fixing super calls in ITDs in interface context", | |||
"fixing super calls in ITDs", | |||
"optimizing thisJoinPoint calls", | |||
// BACK END | |||
"weaving", | |||
"processing reweavable state", | |||
"processing type mungers", | |||
"weaving aspects", | |||
"weaving classes", | |||
"weaving type", | |||
"matching shadow", | |||
"implementing on shadow", | |||
"matching pointcut", | |||
"type munging with" | |||
}; | |||
// context stacks, one per thread | |||
private static Map contextMap = new HashMap(); | |||
// formatters, by phase id | |||
private static Map formatterMap = new HashMap(); | |||
private static ContextFormatter defaultFormatter = new DefaultFormatter(); | |||
/** | |||
* this is a static service | |||
*/ | |||
private CompilationAndWeavingContext() { | |||
} | |||
// for testing... | |||
public static void reset() { | |||
contextMap = new HashMap(); | |||
formatterMap = new HashMap(); | |||
nextTokenId = 1; | |||
} | |||
public static void registerFormatter(int phaseId, ContextFormatter aFormatter) { | |||
formatterMap.put(new Integer(phaseId),aFormatter); | |||
} | |||
/** | |||
* Returns a string description of what the compiler/weaver is currently doing | |||
*/ | |||
public static String getCurrentContext() { | |||
Stack contextStack = getContextStack(); | |||
Stack explanationStack = new Stack(); | |||
for (Iterator iter = contextStack.iterator(); iter.hasNext();) { | |||
ContextStackEntry entry = (ContextStackEntry) iter.next(); | |||
explanationStack.push(getFormatter(entry).formatEntry(entry.phaseId,entry.data)); | |||
} | |||
StringBuffer sb = new StringBuffer(); | |||
for (Iterator iter = explanationStack.iterator(); iter.hasNext();) { | |||
sb.append("when "); | |||
sb.append(iter.next().toString()); | |||
sb.append("\n"); | |||
} | |||
return sb.toString(); | |||
} | |||
public static ContextToken enteringPhase(int phaseId, Object data) { | |||
Stack contextStack = getContextStack(); | |||
ContextTokenImpl nextToken = nextToken(); | |||
contextStack.push(new ContextStackEntry(nextToken,phaseId,data)); | |||
return nextToken; | |||
} | |||
/** | |||
* Exit a phase, all stack entries from the one with the given token | |||
* down will be removed. | |||
*/ | |||
public static void leavingPhase(ContextToken aToken) { | |||
Stack contextStack = getContextStack(); | |||
while (!contextStack.isEmpty()) { | |||
ContextStackEntry entry = (ContextStackEntry) contextStack.pop(); | |||
if (entry.contextToken == aToken) break; | |||
} | |||
} | |||
private static Stack getContextStack() { | |||
if (contextMap.containsKey(Thread.currentThread())) { | |||
return (Stack) contextMap.get(Thread.currentThread()); | |||
} else { | |||
Stack contextStack = new Stack(); | |||
contextMap.put(Thread.currentThread(),contextStack); | |||
return contextStack; | |||
} | |||
} | |||
private static ContextTokenImpl nextToken() { | |||
return new ContextTokenImpl(nextTokenId++); | |||
} | |||
private static ContextFormatter getFormatter(ContextStackEntry entry) { | |||
Integer key = new Integer(entry.phaseId); | |||
if (formatterMap.containsKey(key)) { | |||
return (ContextFormatter) formatterMap.get(key); | |||
} else { | |||
return defaultFormatter; | |||
} | |||
} | |||
private static class ContextTokenImpl implements ContextToken { | |||
public int tokenId; | |||
public ContextTokenImpl(int id) { this.tokenId = id; } | |||
} | |||
// dumb data structure | |||
private static class ContextStackEntry { | |||
public ContextTokenImpl contextToken; | |||
public int phaseId; | |||
public Object data; | |||
public ContextStackEntry(ContextTokenImpl ct, int phase, Object data) { | |||
this.contextToken = ct; | |||
this.phaseId = phase; | |||
this.data = data; | |||
} | |||
} | |||
private static class DefaultFormatter implements ContextFormatter { | |||
public String formatEntry(int phaseId, Object data) { | |||
StringBuffer sb = new StringBuffer(); | |||
sb.append(PHASE_NAMES[phaseId]); | |||
sb.append(" "); | |||
if (data instanceof char[]) { | |||
sb.append(new String((char[])data)); | |||
} else { | |||
try { | |||
sb.append(data.toString()); | |||
} catch (RuntimeException ex) { | |||
// don't lose vital info because of bad toString | |||
sb.append("** broken toString in data object **"); | |||
} | |||
} | |||
return sb.toString(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,21 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2005 Contributors. | |||
* All rights reserved. | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Public License v1.0 | |||
* which accompanies this distribution and is available at | |||
* http://eclipse.org/legal/epl-v10.html | |||
* | |||
* Contributors: | |||
* Adrian Colyer Initial implementation | |||
* ******************************************************************/ | |||
package org.aspectj.bridge.context; | |||
/** | |||
* @author colyer | |||
* Implementors of this interface know how to turn the "Object" data and phase id | |||
* associated with a context stack entry into a meaningful string. | |||
*/ | |||
public interface ContextFormatter { | |||
String formatEntry(int phaseId, Object data); | |||
} |
@@ -0,0 +1,20 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2005 Contributors. | |||
* All rights reserved. | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Public License v1.0 | |||
* which accompanies this distribution and is available at | |||
* http://eclipse.org/legal/epl-v10.html | |||
* | |||
* Contributors: | |||
* Adrian Colyer Initial implementation | |||
* ******************************************************************/ | |||
package org.aspectj.bridge.context; | |||
/** | |||
* When an entry is added to the CompilationAndWeavingContext stack, | |||
* a ContextToken is returned. | |||
* When leaving a compilation or weaving phase, this token must be supplied. | |||
* The token details are opaque to clients | |||
*/ | |||
public interface ContextToken {} |
@@ -0,0 +1,106 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2005 Contributors. | |||
* All rights reserved. | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Public License v1.0 | |||
* which accompanies this distribution and is available at | |||
* http://eclipse.org/legal/epl-v10.html | |||
* | |||
* Contributors: | |||
* Adrian Colyer Initial implementation | |||
* ******************************************************************/ | |||
package org.aspectj.bridge.context; | |||
import java.io.PrintWriter; | |||
import java.io.StringWriter; | |||
import java.util.List; | |||
import org.aspectj.bridge.AbortException; | |||
import org.aspectj.bridge.IMessage; | |||
import org.aspectj.bridge.IMessageHandler; | |||
import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.bridge.IMessage.Kind; | |||
/** | |||
* @author colyer | |||
* Facade for an IMessageHandler | |||
* Extends message with details of exactly what the compiler / weaver was doing at the | |||
* time. Use the -Xdev:Pinpoint option to turn this facility on. | |||
*/ | |||
public class PinpointingMessageHandler implements IMessageHandler { | |||
private IMessageHandler delegate; | |||
public PinpointingMessageHandler(IMessageHandler delegate) { | |||
this.delegate = delegate; | |||
} | |||
/* (non-Javadoc) | |||
* @see org.aspectj.bridge.IMessageHandler#handleMessage(org.aspectj.bridge.IMessage) | |||
*/ | |||
public boolean handleMessage(IMessage message) throws AbortException { | |||
if (!isIgnoring(message.getKind())) { | |||
MessageIssued ex = new MessageIssued(); | |||
ex.fillInStackTrace(); | |||
StringWriter sw = new StringWriter(); | |||
ex.printStackTrace(new PrintWriter(sw)); | |||
StringBuffer sb = new StringBuffer(); | |||
sb.append(CompilationAndWeavingContext.getCurrentContext()); | |||
sb.append(sw.toString()); | |||
IMessage pinpointedMessage = new PinpointedMessage(message,sb.toString()); | |||
return delegate.handleMessage(pinpointedMessage); | |||
} else { | |||
return delegate.handleMessage(message); | |||
} | |||
} | |||
/* (non-Javadoc) | |||
* @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind) | |||
*/ | |||
public boolean isIgnoring(Kind kind) { | |||
return delegate.isIgnoring(kind); | |||
} | |||
/* (non-Javadoc) | |||
* @see org.aspectj.bridge.IMessageHandler#dontIgnore(org.aspectj.bridge.IMessage.Kind) | |||
*/ | |||
public void dontIgnore(Kind kind) { | |||
delegate.dontIgnore(kind); | |||
} | |||
private static class PinpointedMessage implements IMessage { | |||
private IMessage delegate; | |||
private String message; | |||
public PinpointedMessage(IMessage delegate, String pinpoint) { | |||
this.delegate = delegate; | |||
this.message = delegate.getMessage() + "\n" + pinpoint; | |||
} | |||
public String getMessage() { return this.message; } | |||
public Kind getKind() { return delegate.getKind();} | |||
public boolean isError() { return delegate.isError(); } | |||
public boolean isWarning() { return delegate.isWarning();} | |||
public boolean isDebug() { return delegate.isDebug();} | |||
public boolean isInfo() { return delegate.isInfo();} | |||
public boolean isAbort() { return delegate.isAbort();} | |||
public boolean isTaskTag() { return delegate.isTaskTag();} | |||
public boolean isFailed() { return delegate.isFailed();} | |||
public boolean getDeclared() { return delegate.getDeclared(); } | |||
public int getID() { return delegate.getID();} | |||
public int getSourceStart() { return delegate.getSourceStart();} | |||
public int getSourceEnd() { return delegate.getSourceEnd();} | |||
public Throwable getThrown() { return delegate.getThrown();} | |||
public ISourceLocation getSourceLocation() { return delegate.getSourceLocation();} | |||
public String getDetails() { return delegate.getDetails();} | |||
public List getExtraSourceLocations() { return delegate.getExtraSourceLocations();} | |||
} | |||
private static class MessageIssued extends RuntimeException { | |||
public String getMessage() { | |||
return "message issued..."; | |||
} | |||
} | |||
} |
@@ -14,6 +14,8 @@ | |||
// default package | |||
import org.aspectj.bridge.context.CompilationAndWeavingContextTest; | |||
import junit.framework.Test; | |||
import junit.framework.TestCase; | |||
import junit.framework.TestSuite; | |||
@@ -23,6 +25,7 @@ public class BridgeModuleTests extends TestCase { | |||
public static Test suite() { | |||
TestSuite suite = new TestSuite(BridgeModuleTests.class.getName()); | |||
suite.addTest(org.aspectj.bridge.BridgeTests.suite()); | |||
suite.addTestSuite(CompilationAndWeavingContextTest.class); | |||
return suite; | |||
} | |||
@@ -0,0 +1,67 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2005 Contributors. | |||
* All rights reserved. | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Public License v1.0 | |||
* which accompanies this distribution and is available at | |||
* http://eclipse.org/legal/epl-v10.html | |||
* | |||
* Contributors: | |||
* Adrian Colyer Initial implementation | |||
* ******************************************************************/ | |||
package org.aspectj.bridge.context; | |||
import junit.framework.TestCase; | |||
/** | |||
* @author colyer | |||
* | |||
*/ | |||
public class CompilationAndWeavingContextTest extends TestCase { | |||
public void testEnteringPhase() { | |||
CompilationAndWeavingContext.enteringPhase(1,"XYZ"); | |||
assertEquals("when fiddling XYZ\n",CompilationAndWeavingContext.getCurrentContext()); | |||
} | |||
public void testDoubleEntry() { | |||
CompilationAndWeavingContext.enteringPhase(1,"XYZ"); | |||
CompilationAndWeavingContext.enteringPhase(2, "ABC"); | |||
assertEquals("when fiddling XYZ\nwhen mucking about with ABC\n",CompilationAndWeavingContext.getCurrentContext()); | |||
} | |||
public void testEntryEntryExit() { | |||
CompilationAndWeavingContext.enteringPhase(1,"XYZ"); | |||
ContextToken ct = CompilationAndWeavingContext.enteringPhase(2, "ABC"); | |||
CompilationAndWeavingContext.leavingPhase(ct); | |||
assertEquals("when fiddling XYZ\n",CompilationAndWeavingContext.getCurrentContext()); | |||
} | |||
public void testEntryExitTop() { | |||
ContextToken ct = CompilationAndWeavingContext.enteringPhase(1,"XYZ"); | |||
CompilationAndWeavingContext.enteringPhase(2, "ABC"); | |||
CompilationAndWeavingContext.leavingPhase(ct); | |||
assertEquals("",CompilationAndWeavingContext.getCurrentContext()); | |||
} | |||
protected void setUp() throws Exception { | |||
CompilationAndWeavingContext.reset(); | |||
CompilationAndWeavingContext.registerFormatter(1, new MyContextFormatter("fiddling ")); | |||
CompilationAndWeavingContext.registerFormatter(2, new MyContextFormatter("mucking about with ")); | |||
} | |||
private static class MyContextFormatter implements ContextFormatter { | |||
private String prefix; | |||
public MyContextFormatter(String prefix) { | |||
this.prefix = prefix; | |||
} | |||
public String formatEntry(int phaseId, Object data) { | |||
return prefix + data.toString(); | |||
} | |||
} | |||
} |
@@ -182,6 +182,7 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { | |||
world.setMessageHandler(weaverOption.messageHandler); | |||
world.setXlazyTjp(weaverOption.lazyTjp); | |||
world.setXHasMemberSupportEnabled(weaverOption.hasMember); | |||
world.setPinpointMode(weaverOption.pinpoint); | |||
weaver.setReweavableMode(weaverOption.reWeavable, false); | |||
world.setXnoInline(weaverOption.noInline); | |||
world.setBehaveInJava5Way(weaverOption.java5);//TODO should be autodetected ? |
@@ -38,6 +38,7 @@ public class Options { | |||
private final static String OPTION_reweavable = "-Xreweavable"; | |||
private final static String OPTION_noinline = "-Xnoinline"; | |||
private final static String OPTION_hasMember = "-XhasMember"; | |||
private final static String OPTION_pinpoint = "-Xdev:pinpoint"; | |||
private final static String OPTION_showWeaveInfo = "-showWeaveInfo"; | |||
private final static String OPTIONVALUED_messageHandler = "-XmessageHandlerClass:"; | |||
private static final String OPTIONVALUED_Xlintfile = "-Xlintfile:"; | |||
@@ -96,8 +97,10 @@ public class Options { | |||
weaverOption.showWeaveInfo = true; | |||
} else if (arg.equalsIgnoreCase(OPTION_hasMember)) { | |||
weaverOption.hasMember = true; | |||
} else if (arg.equalsIgnoreCase(OPTION_verbose)) { | |||
} else if (arg.equalsIgnoreCase(OPTION_verbose)) { | |||
weaverOption.verbose = true; | |||
} else if (arg.equalsIgnoreCase(OPTION_pinpoint)) { | |||
weaverOption.pinpoint = true; | |||
} else if (arg.startsWith(OPTIONVALUED_messageHandler)) { | |||
;// handled in first round | |||
} else if (arg.startsWith(OPTIONVALUED_Xlintfile)) { | |||
@@ -144,6 +147,7 @@ public class Options { | |||
boolean reWeavable; | |||
boolean noInline; | |||
boolean showWeaveInfo; | |||
boolean pinpoint; | |||
IMessageHandler messageHandler; | |||
String lint; | |||
String lintFile; |
@@ -516,7 +516,9 @@ public class BuildArgParser extends Main { | |||
buildConfig.setGenerateJavadocsInModelMode(true); | |||
} else if (arg.equals("-Xdev:NoAtAspectJProcessing")) { | |||
buildConfig.setNoAtAspectJAnnotationProcessing(true); | |||
}else if (arg.equals("-noweave") || arg.equals( "-XnoWeave")) { | |||
} else if (arg.equals("-Xdev:Pinpoint")) { | |||
buildConfig.setXdevPinpointMode(true); | |||
} else if (arg.equals("-noweave") || arg.equals( "-XnoWeave")) { | |||
buildConfig.setNoWeave(true); | |||
} else if (arg.equals("-XserializableAspects")) { | |||
buildConfig.setXserializableAspects(true); |
@@ -25,6 +25,8 @@ import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory; | |||
import org.aspectj.bridge.IMessage; | |||
import org.aspectj.bridge.IMessageHandler; | |||
import org.aspectj.bridge.IProgressListener; | |||
import org.aspectj.bridge.context.CompilationAndWeavingContext; | |||
import org.aspectj.bridge.context.ContextToken; | |||
import org.aspectj.org.eclipse.jdt.core.compiler.IProblem; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.Compiler; | |||
@@ -60,6 +62,11 @@ public class AjCompilerAdapter implements ICompilerAdapter { | |||
private Map /* fileName |-> List<UnwovenClassFile> */ binarySourceSetForFullWeave = new HashMap(); | |||
private Collection /*InterimCompilationResult*/ resultSetForFullWeave = Collections.EMPTY_LIST; | |||
private ContextToken processingToken = null; | |||
private ContextToken resolvingToken = null; | |||
private ContextToken analysingToken = null; | |||
private ContextToken generatingToken = null; | |||
List /*InterimResult*/ resultsPendingWeave = new ArrayList(); | |||
/** | |||
@@ -122,22 +129,26 @@ public class AjCompilerAdapter implements ICompilerAdapter { | |||
public void beforeProcessing(CompilationUnitDeclaration unit) { | |||
eWorld.showMessage(IMessage.INFO, "compiling " + new String(unit.getFileName()), null, null); | |||
processingToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_COMPILATION_UNIT,unit.getFileName()); | |||
if (inJava5Mode && !noAtAspectJAnnotationProcessing) { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.ADDING_AT_ASPECTJ_ANNOTATIONS, unit.getFileName()); | |||
AddAtAspectJAnnotationsVisitor atAspectJVisitor = new AddAtAspectJAnnotationsVisitor(unit); | |||
unit.traverse(atAspectJVisitor, unit.scope); | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
} | |||
} | |||
public void beforeResolving(CompilationUnitDeclaration unit) { | |||
// no-op | |||
resolvingToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.RESOLVING_COMPILATION_UNIT, unit.getFileName()); | |||
} | |||
public void afterResolving(CompilationUnitDeclaration unit) { | |||
// no-op | |||
if (resolvingToken != null) | |||
CompilationAndWeavingContext.leavingPhase(resolvingToken); | |||
} | |||
public void beforeAnalysing(CompilationUnitDeclaration unit) { | |||
analysingToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.ANALYSING_COMPILATION_UNIT, unit.getFileName()); | |||
if (inJava5Mode && !noAtAspectJAnnotationProcessing) { | |||
ValidateAtAspectJAnnotationsVisitor atAspectJVisitor = new ValidateAtAspectJAnnotationsVisitor(unit); | |||
unit.traverse(atAspectJVisitor, unit.scope); | |||
@@ -145,15 +156,17 @@ public class AjCompilerAdapter implements ICompilerAdapter { | |||
} | |||
public void afterAnalysing(CompilationUnitDeclaration unit) { | |||
// no-op | |||
if (analysingToken != null) | |||
CompilationAndWeavingContext.leavingPhase(analysingToken); | |||
} | |||
public void beforeGenerating(CompilationUnitDeclaration unit) { | |||
// no-op | |||
generatingToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.GENERATING_UNWOVEN_CODE_FOR_COMPILATION_UNIT, unit.getFileName()); | |||
} | |||
public void afterGenerating(CompilationUnitDeclaration unit) { | |||
// no-op | |||
if (generatingToken != null) | |||
CompilationAndWeavingContext.leavingPhase(generatingToken); | |||
} | |||
public void afterCompiling(CompilationUnitDeclaration[] units) { |
@@ -20,6 +20,8 @@ import java.util.List; | |||
import org.aspectj.ajdt.internal.compiler.lookup.AjTypeConstants; | |||
import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory; | |||
import org.aspectj.ajdt.internal.compiler.lookup.PrivilegedHandler; | |||
import org.aspectj.bridge.context.CompilationAndWeavingContext; | |||
import org.aspectj.bridge.context.ContextToken; | |||
import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult; | |||
@@ -166,7 +168,9 @@ public class AdviceDeclaration extends AjMethodDeclaration { | |||
this.traverse(new MakeDeclsPublicVisitor(), (ClassScope)null); | |||
AccessForInlineVisitor v = new AccessForInlineVisitor((AspectDeclaration)upperScope.referenceContext, handler); | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.ACCESS_FOR_INLINE, selector); | |||
this.traverse(v, (ClassScope) null); | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
// ??? if we found a construct that we can't inline, set | |||
// proceedInInners so that we won't try to inline this body |
@@ -21,6 +21,8 @@ import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory; | |||
import org.aspectj.ajdt.internal.compiler.lookup.EclipseTypeMunger; | |||
import org.aspectj.ajdt.internal.compiler.lookup.InterTypeScope; | |||
import org.aspectj.ajdt.internal.core.builder.EclipseSourceContext; | |||
import org.aspectj.bridge.context.CompilationAndWeavingContext; | |||
import org.aspectj.bridge.context.ContextToken; | |||
import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult; | |||
@@ -138,10 +140,12 @@ public abstract class InterTypeDeclaration extends AjMethodDeclaration { | |||
private void fixSuperCallsForInterfaceContext(ClassScope scope) { | |||
if (onTypeBinding.isInterface()) { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.FIXING_SUPER_CALLS, selector); | |||
InterSuperFixerVisitor v = | |||
new InterSuperFixerVisitor(this, | |||
EclipseFactory.fromScopeLookupEnvironment(scope), scope); | |||
this.traverse(v, scope); | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
} | |||
} | |||
@@ -151,9 +155,11 @@ public abstract class InterTypeDeclaration extends AjMethodDeclaration { | |||
public abstract EclipseTypeMunger build(ClassScope classScope); | |||
public void fixSuperCallsInBody() { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.FIXING_SUPER_CALLS_IN_ITDS, selector); | |||
SuperFixerVisitor v = new SuperFixerVisitor(this, onTypeBinding); | |||
this.traverse(v, (ClassScope)null); | |||
munger.setSuperMethodsCalled(v.superMethodsCalled); | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
} | |||
protected void resolveOnType(ClassScope classScope) { |
@@ -14,6 +14,8 @@ | |||
package org.aspectj.ajdt.internal.compiler.ast; | |||
import org.aspectj.weaver.Advice; | |||
import org.aspectj.bridge.context.CompilationAndWeavingContext; | |||
import org.aspectj.bridge.context.ContextToken; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ASTVisitor; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression; | |||
@@ -135,6 +137,7 @@ public class ThisJoinPointVisitor extends ASTVisitor { | |||
boolean inBlockThatCantRun = false; | |||
public boolean visit(MessageSend call, BlockScope scope) { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.OPTIMIZING_THIS_JOIN_POINT_CALLS, call.selector); | |||
Expression receiver = call.receiver; | |||
if (isRef(receiver, thisJoinPointDec)) { | |||
if (canTreatAsStatic(new String(call.selector))) { | |||
@@ -148,12 +151,15 @@ public class ThisJoinPointVisitor extends ASTVisitor { | |||
for (int i = 0; i < argumentsLength; i++) | |||
call.arguments[i].traverse(this, scope); | |||
} | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
return false; | |||
} | |||
} | |||
} | |||
return super.visit(call, scope); | |||
boolean ret = super.visit(call, scope); | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
return ret; | |||
} | |||
private void replaceEffectivelyStaticRef(MessageSend call) { |
@@ -17,6 +17,8 @@ import java.util.Stack; | |||
import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory; | |||
import org.aspectj.ajdt.internal.compiler.lookup.EclipseScope; | |||
import org.aspectj.ajdt.internal.core.builder.EclipseSourceContext; | |||
import org.aspectj.bridge.context.CompilationAndWeavingContext; | |||
import org.aspectj.bridge.context.ContextToken; | |||
import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ASTVisitor; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation; | |||
@@ -109,6 +111,7 @@ public class ValidateAtAspectJAnnotationsVisitor extends ASTVisitor { | |||
} | |||
private void checkTypeDeclaration(TypeDeclaration typeDecl) { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.VALIDATING_AT_ASPECTJ_ANNOTATIONS, typeDecl.name); | |||
if (!(typeDecl instanceof AspectDeclaration)) { | |||
if (ajAnnotations.hasAspectAnnotation) { | |||
validateAspectDeclaration(typeDecl); | |||
@@ -138,9 +141,11 @@ public class ValidateAtAspectJAnnotationsVisitor extends ASTVisitor { | |||
); | |||
} | |||
} | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
} | |||
public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.VALIDATING_AT_ASPECTJ_ANNOTATIONS, methodDeclaration.selector); | |||
ajAnnotations = new AspectJAnnotations(methodDeclaration.annotations); | |||
if (!methodDeclaration.getClass().equals(AjMethodDeclaration.class)) { | |||
// simply test for innapropriate use of annotations on code-style members | |||
@@ -171,6 +176,7 @@ public class ValidateAtAspectJAnnotationsVisitor extends ASTVisitor { | |||
"@AspectJ annotations cannot be declared on this aspect member"); | |||
} | |||
} | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
return false; | |||
} | |||
@@ -179,6 +185,7 @@ public class ValidateAtAspectJAnnotationsVisitor extends ASTVisitor { | |||
} else if (ajAnnotations.hasPointcutAnnotation) { | |||
convertToPointcutDeclaration(methodDeclaration,scope); | |||
} | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
return false; | |||
} | |||
@@ -27,6 +27,8 @@ import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration; | |||
import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration; | |||
import org.aspectj.bridge.IMessage; | |||
import org.aspectj.bridge.WeaveMessage; | |||
import org.aspectj.bridge.context.CompilationAndWeavingContext; | |||
import org.aspectj.bridge.context.ContextToken; | |||
import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation; | |||
@@ -91,22 +93,29 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC | |||
//??? duplicates some of super's code | |||
public void completeTypeBindings() { | |||
ContextToken completeTypeBindingsToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.COMPLETING_TYPE_BINDINGS, ""); | |||
// builtInterTypesAndPerClauses = false; | |||
//pendingTypesToWeave = new ArrayList(); | |||
stepCompleted = BUILD_TYPE_HIERARCHY; | |||
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.CHECK_AND_SET_IMPORTS, units[i].compilationResult.fileName); | |||
units[i].scope.checkAndSetImports(); | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
} | |||
stepCompleted = CHECK_AND_SET_IMPORTS; | |||
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.CONNECTING_TYPE_HIERARCHY, units[i].compilationResult.fileName); | |||
units[i].scope.connectTypeHierarchy(); | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
} | |||
stepCompleted = CONNECT_TYPE_HIERARCHY; | |||
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.BUILDING_FIELDS_AND_METHODS, units[i].compilationResult.fileName); | |||
units[i].scope.buildFieldsAndMethods(); | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
} | |||
// would like to gather up all TypeDeclarations at this point and put them in the factory | |||
@@ -190,14 +199,18 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC | |||
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { | |||
SourceTypeBinding[] b = units[i].scope.topLevelTypes; | |||
for (int j = 0; j < b.length; j++) { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.RESOLVING_POINTCUT_DECLARATIONS, b[j].sourceName); | |||
resolvePointcutDeclarations(b[j].scope); | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
} | |||
} | |||
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { | |||
SourceTypeBinding[] b = units[i].scope.topLevelTypes; | |||
for (int j = 0; j < b.length; j++) { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.ADDING_DECLARE_WARNINGS_AND_ERRORS, b[j].sourceName); | |||
addAdviceLikeDeclares(b[j].scope); | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
} | |||
} | |||
@@ -207,6 +220,8 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC | |||
stepCompleted = BUILD_FIELDS_AND_METHODS; | |||
lastCompletedUnitIndex = lastUnitIndex; | |||
CompilationAndWeavingContext.leavingPhase(completeTypeBindingsToken); | |||
} | |||
@@ -218,6 +233,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC | |||
*/ | |||
private void collectAllITDsAndDeclares(SourceTypeBinding sourceType, Collection yetToProcess) { | |||
// Look at the supertype first | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.COLLECTING_ITDS_AND_DECLARES, sourceType.sourceName); | |||
ReferenceBinding superType = sourceType.superclass(); | |||
if (yetToProcess.contains(superType) && superType instanceof SourceTypeBinding) { | |||
collectAllITDsAndDeclares((SourceTypeBinding)superType, yetToProcess); | |||
@@ -225,6 +241,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC | |||
buildInterTypeAndPerClause(sourceType.scope); | |||
addCrosscuttingStructures(sourceType.scope); | |||
yetToProcess.remove(sourceType); | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
} | |||
/** | |||
@@ -259,7 +276,9 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC | |||
private void doPendingWeaves() { | |||
for (Iterator i = pendingTypesToWeave.iterator(); i.hasNext(); ) { | |||
SourceTypeBinding t = (SourceTypeBinding)i.next(); | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_INTERTYPE_DECLARATIONS, t.sourceName); | |||
weaveInterTypeDeclarations(t); | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
} | |||
pendingTypesToWeave.clear(); | |||
} | |||
@@ -397,6 +416,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC | |||
private void weaveInterTypeDeclarations(SourceTypeBinding sourceType, Collection typeMungers, | |||
Collection declareParents, Collection declareAnnotationOnTypes, boolean skipInners) { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_INTERTYPE_DECLARATIONS, sourceType.sourceName); | |||
ResolvedType onType = factory.fromEclipse(sourceType); | |||
// AMC we shouldn't need this when generic sigs are fixed?? | |||
if (onType.isRawType()) onType = onType.getGenericType(); | |||
@@ -423,7 +443,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC | |||
} | |||
} | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
return; | |||
} | |||
@@ -556,9 +576,11 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC | |||
weaveInterTypeDeclarations((SourceTypeBinding) memberTypes[i], typeMungers, declareParents,declareAnnotationOnTypes, false); | |||
} | |||
} | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
} | |||
private boolean doDeclareParents(DeclareParents declareParents, SourceTypeBinding sourceType) { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_DECLARE_PARENTS, sourceType.sourceName); | |||
List newParents = declareParents.findMatchingNewParents(factory.fromEclipse(sourceType),false); | |||
if (!newParents.isEmpty()) { | |||
for (Iterator i = newParents.iterator(); i.hasNext(); ) { | |||
@@ -576,8 +598,10 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC | |||
addParent(sourceType, parent); | |||
} | |||
} | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
return true; | |||
} | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
return false; | |||
} | |||
@@ -608,7 +632,8 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC | |||
if (!decA.matches(rtx)) return false; | |||
if (!rtx.isExposedToWeaver()) return false; | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_DECLARE_ANNOTATIONS, sourceType.sourceName); | |||
// Get the annotation specified in the declare | |||
TypeBinding tb = factory.makeTypeBinding(decA.getAspect()); | |||
@@ -635,12 +660,16 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC | |||
// FIXME asc we have a lint for attempting to add an annotation twice to a method, | |||
// we could put it out here *if* we can resolve the problem of errors coming out | |||
// multiple times if we have cause to loop through here | |||
if (a.equals(b)) return false; | |||
if (a.equals(b)) { | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
return false; | |||
} | |||
} | |||
if (((abits & TagBits.AnnotationTargetMASK)!=0)) { | |||
if ( (abits & (TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType))==0) { | |||
// this means it specifies something other than annotation or normal type - error will have been already reported, just resolution process above | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
return false; | |||
} | |||
if ( (sourceType.isAnnotationType() && (abits & TagBits.AnnotationForAnnotationType)==0) || | |||
@@ -659,6 +688,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC | |||
// } | |||
// } | |||
} | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
return false; | |||
} | |||
} | |||
@@ -675,6 +705,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC | |||
System.arraycopy(abefore,0,newset,toAdd.length,abefore.length); | |||
} | |||
sourceType.scope.referenceContext.annotations = newset; | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
return true; | |||
} | |||
@@ -13,6 +13,8 @@ | |||
package org.aspectj.ajdt.internal.compiler.problem; | |||
import java.io.PrintWriter; | |||
import java.io.StringWriter; | |||
import java.lang.reflect.Modifier; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
@@ -22,6 +24,7 @@ import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration; | |||
import org.aspectj.ajdt.internal.compiler.ast.Proceed; | |||
import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory; | |||
import org.aspectj.ajdt.internal.compiler.lookup.InterTypeMethodBinding; | |||
import org.aspectj.bridge.context.CompilationAndWeavingContext; | |||
import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation; | |||
import org.aspectj.org.eclipse.jdt.core.compiler.IProblem; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult; | |||
@@ -430,4 +433,64 @@ public class AjProblemReporter extends ProblemReporter { | |||
if (currentMethod == inheritedMethod) return; | |||
super.finalMethodCannotBeOverridden(currentMethod, inheritedMethod); | |||
} | |||
/** | |||
* All problems end up routed through here at some point... | |||
*/ | |||
public IProblem createProblem(char[] fileName, int problemId, String[] problemArguments, String[] messageArguments, int severity, int problemStartPosition, int problemEndPosition, int lineNumber) { | |||
IProblem problem = super.createProblem(fileName, problemId, problemArguments, | |||
messageArguments, severity, problemStartPosition, problemEndPosition, | |||
lineNumber); | |||
if (factory.getWorld().isInPinpointMode()) { | |||
MessageIssued ex = new MessageIssued(); | |||
ex.fillInStackTrace(); | |||
StringWriter sw = new StringWriter(); | |||
ex.printStackTrace(new PrintWriter(sw)); | |||
StringBuffer sb = new StringBuffer(); | |||
sb.append(CompilationAndWeavingContext.getCurrentContext()); | |||
sb.append(sw.toString()); | |||
problem = new PinpointedProblem(problem,sb.toString()); | |||
} | |||
return problem; | |||
} | |||
private static class MessageIssued extends RuntimeException { | |||
public String getMessage() { | |||
return "message issued..."; | |||
} | |||
} | |||
private static class PinpointedProblem implements IProblem { | |||
private IProblem delegate; | |||
private String message; | |||
public PinpointedProblem(IProblem aProblem, String pinpoint) { | |||
this.delegate = aProblem; | |||
// if this was a problem that came via the weaver, it will already have | |||
// pinpoint info, don't do it twice... | |||
if (delegate.getMessage().indexOf("message issued...") == -1) { | |||
this.message = delegate.getMessage() + "\n" + pinpoint; | |||
} else { | |||
this.message = delegate.getMessage(); | |||
} | |||
} | |||
public String[] getArguments() {return delegate.getArguments();} | |||
public int getID() {return delegate.getID();} | |||
public String getMessage() { return message; } | |||
public char[] getOriginatingFileName() {return delegate.getOriginatingFileName();} | |||
public int getSourceEnd() { return delegate.getSourceEnd();} | |||
public int getSourceLineNumber() { return delegate.getSourceLineNumber();} | |||
public int getSourceStart() { return delegate.getSourceStart();} | |||
public boolean isError() { return delegate.isError();} | |||
public boolean isWarning() { return delegate.isWarning();} | |||
public void setSourceEnd(int sourceEnd) { delegate.setSourceEnd(sourceEnd); } | |||
public void setSourceLineNumber(int lineNumber) { delegate.setSourceLineNumber(lineNumber);} | |||
public void setSourceStart(int sourceStart) { delegate.setSourceStart(sourceStart);} | |||
public void setSeeAlsoProblems(IProblem[] problems) { delegate.setSeeAlsoProblems(problems);} | |||
public IProblem[] seeAlso() { return delegate.seeAlso();} | |||
public void setSupplementaryMessageInfo(String msg) { delegate.setSupplementaryMessageInfo(msg);} | |||
public String getSupplementaryMessageInfo() { return delegate.getSupplementaryMessageInfo();} | |||
} | |||
} |
@@ -485,6 +485,14 @@ public class AjBuildConfig { | |||
return options.xHasMember; | |||
} | |||
public void setXdevPinpointMode(boolean enabled) { | |||
options.xdevPinpoint = enabled; | |||
} | |||
public boolean isXdevPinpoint() { | |||
return options.xdevPinpoint; | |||
} | |||
public boolean isXreweavable() { | |||
return options.xReweavable; | |||
} |
@@ -56,6 +56,9 @@ import org.aspectj.bridge.Message; | |||
import org.aspectj.bridge.MessageUtil; | |||
import org.aspectj.bridge.SourceLocation; | |||
import org.aspectj.bridge.Version; | |||
import org.aspectj.bridge.context.CompilationAndWeavingContext; | |||
import org.aspectj.bridge.context.ContextFormatter; | |||
import org.aspectj.bridge.context.ContextToken; | |||
import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation; | |||
import org.aspectj.org.eclipse.jdt.core.compiler.IProblem; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile; | |||
@@ -74,7 +77,6 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.problem.AbortCompilation; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; | |||
import org.aspectj.util.FileUtil; | |||
import org.aspectj.weaver.Dump; | |||
import org.aspectj.weaver.MissingResolvedTypeWithKnownSignature; | |||
import org.aspectj.weaver.ResolvedType; | |||
import org.aspectj.weaver.World; | |||
import org.aspectj.weaver.bcel.BcelWeaver; | |||
@@ -101,7 +103,14 @@ public class AjBuildManager implements IOutputClassFileNameProvider,IBinarySourc | |||
* the latter will get used. | |||
*/ | |||
private static AsmHierarchyBuilder asmHierarchyBuilder = new AsmHierarchyBuilder(); | |||
static { | |||
CompilationAndWeavingContext.registerFormatter( | |||
CompilationAndWeavingContext.BATCH_BUILD, new AjBuildContexFormatter()); | |||
CompilationAndWeavingContext.registerFormatter( | |||
CompilationAndWeavingContext.INCREMENTAL_BUILD, new AjBuildContexFormatter()); | |||
} | |||
private IProgressListener progressListener = null; | |||
private int compiledCount; | |||
@@ -158,6 +167,8 @@ public class AjBuildManager implements IOutputClassFileNameProvider,IBinarySourc | |||
boolean ret = true; | |||
batchCompile = batch; | |||
int phase = batch ? CompilationAndWeavingContext.BATCH_BUILD : CompilationAndWeavingContext.INCREMENTAL_BUILD; | |||
ContextToken ct = CompilationAndWeavingContext.enteringPhase(phase ,buildConfig); | |||
try { | |||
if (batch) { | |||
this.state = new AjState(this); | |||
@@ -269,6 +280,7 @@ public class AjBuildManager implements IOutputClassFileNameProvider,IBinarySourc | |||
AsmManager.getDefault().fireModelUpdated(); | |||
} | |||
} finally { | |||
CompilationAndWeavingContext.leavingPhase(ct); | |||
if (zos != null) { | |||
closeOutputStream(buildConfig.getOutputJar()); | |||
} | |||
@@ -538,6 +550,7 @@ public class AjBuildManager implements IOutputClassFileNameProvider,IBinarySourc | |||
bcelWorld.setXnoInline(buildConfig.isXnoInline()); | |||
bcelWorld.setXlazyTjp(buildConfig.isXlazyTjp()); | |||
bcelWorld.setXHasMemberSupportEnabled(buildConfig.isXHasMemberEnabled()); | |||
bcelWorld.setPinpointMode(buildConfig.isXdevPinpoint()); | |||
BcelWeaver bcelWeaver = new BcelWeaver(bcelWorld); | |||
state.setWorld(bcelWorld); | |||
state.setWeaver(bcelWeaver); | |||
@@ -1056,5 +1069,26 @@ public class AjBuildManager implements IOutputClassFileNameProvider,IBinarySourc | |||
public void setState(AjState buildState) { | |||
state = buildState; | |||
} | |||
private static class AjBuildContexFormatter implements ContextFormatter { | |||
public String formatEntry(int phaseId, Object data) { | |||
StringBuffer sb = new StringBuffer(); | |||
if (phaseId == CompilationAndWeavingContext.BATCH_BUILD) { | |||
sb.append("batch building "); | |||
} else { | |||
sb.append("incrementally building "); | |||
} | |||
AjBuildConfig config = (AjBuildConfig) data; | |||
List classpath = config.getClasspath(); | |||
sb.append("with classpath: "); | |||
for (Iterator iter = classpath.iterator(); iter.hasNext();) { | |||
sb.append(iter.next().toString()); | |||
sb.append(File.pathSeparator); | |||
} | |||
return sb.toString(); | |||
} | |||
} | |||
} | |||
@@ -43,6 +43,7 @@ public class AjCompilerOptions extends CompilerOptions { | |||
public static final String OPTION_XReweavable = "org.aspectj.ajdt.core.compiler.weaver.XReweavable"; | |||
public static final String OPTION_XReweavableCompress = "org.aspectj.ajdt.core.compiler.weaver.XReweavableCompress"; | |||
public static final String OPTION_XHasMember = "org.aspectj.ajdt.core.compiler.weaver.XHasMember"; | |||
public static final String OPTION_XdevPinpoint = "org.aspectj.ajdt.core.compiler.weaver.XdevPinpoint"; | |||
// these next four not exposed by IDEs | |||
public static final String OPTION_XDevNoAtAspectJProcessing = "org.aspectj.ajdt.core.compiler.ast.NoAtAspectJProcessing"; | |||
@@ -68,6 +69,7 @@ public class AjCompilerOptions extends CompilerOptions { | |||
public boolean xReweavable = false; | |||
public boolean xReweavableCompress = false; | |||
public boolean xHasMember = false; | |||
public boolean xdevPinpoint = false; | |||
public boolean showWeavingInformation = false; | |||
// If true - autoboxing behaves differently ... | |||
@@ -122,6 +124,7 @@ public class AjCompilerOptions extends CompilerOptions { | |||
map.put(OPTION_XReweavable,this.xReweavable ? ENABLED : DISABLED); | |||
map.put(OPTION_XReweavableCompress,this.xReweavableCompress ? ENABLED : DISABLED); | |||
map.put(OPTION_XHasMember, this.xHasMember ? ENABLED : DISABLED); | |||
map.put(OPTION_XdevPinpoint, this.xdevPinpoint ? ENABLED : DISABLED); | |||
map.put(OPTION_GenerateModel,this.generateModel ? ENABLED : DISABLED); | |||
map.put(OPTION_GenerateJavaDocsInModel,this.generateJavaDocsInModel ? ENABLED : DISABLED); | |||
@@ -196,7 +199,15 @@ public class AjCompilerOptions extends CompilerOptions { | |||
this.xHasMember = false; | |||
} | |||
} | |||
if ((optionValue = optionsMap.get(OPTION_XdevPinpoint)) != null) { | |||
if (ENABLED.equals(optionValue)) { | |||
this.xdevPinpoint = true; | |||
} else if (DISABLED.equals(optionValue)) { | |||
this.xdevPinpoint = false; | |||
} | |||
} | |||
if ((optionValue = optionsMap.get(OPTION_GenerateModel)) != null) { | |||
if (ENABLED.equals(optionValue)) { | |||
this.generateModel = true; |
@@ -159,6 +159,7 @@ public class AspectJBuilder extends JavaBuilder implements ICompilerAdapterFacto | |||
myBcelWorld.setXnoInline(options.xNoInline); | |||
myBcelWorld.setXlazyTjp(options.xLazyThisJoinPoint); | |||
myBcelWorld.setXHasMemberSupportEnabled(options.xHasMember); | |||
myBcelWorld.setPinpointMode(options.xdevPinpoint); | |||
setLintProperties(myBcelWorld,options); | |||
myWeaver = new BcelWeaver(myBcelWorld); | |||
myWeaver.setReweavableMode(options.xReweavable,options.xReweavableCompress); |
@@ -33,6 +33,7 @@ import org.aspectj.bridge.MessageHandler; | |||
import org.aspectj.bridge.MessageUtil; | |||
import org.aspectj.bridge.ReflectionFactory; | |||
import org.aspectj.bridge.Version; | |||
import org.aspectj.bridge.context.CompilationAndWeavingContext; | |||
import org.aspectj.util.FileUtil; | |||
import org.aspectj.util.LangUtil; | |||
@@ -143,6 +144,7 @@ public class Main { | |||
String m = thrown.getMessage(); | |||
return THROWN_PREFIX | |||
+ (null != m ? m + "\n": "") | |||
+ CompilationAndWeavingContext.getCurrentContext() | |||
+ LangUtil.renderException(thrown, true); | |||
} | |||
@@ -16,6 +16,8 @@ package org.aspectj.weaver; | |||
import java.io.PrintStream; | |||
import java.io.PrintWriter; | |||
import org.aspectj.bridge.context.CompilationAndWeavingContext; | |||
/** | |||
* Exception to use inside the bcweaver. | |||
*/ | |||
@@ -26,10 +28,10 @@ public class BCException extends RuntimeException { | |||
} | |||
public BCException(String s) { | |||
super(s); | |||
super(s + "\n" + CompilationAndWeavingContext.getCurrentContext()); | |||
} | |||
public BCException(String s, Throwable thrown) { | |||
super(s); | |||
this(s); | |||
this.thrown = thrown; | |||
} | |||
public void printStackTrace() { |
@@ -29,6 +29,7 @@ import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.bridge.Message; | |||
import org.aspectj.bridge.MessageUtil; | |||
import org.aspectj.bridge.IMessage.Kind; | |||
import org.aspectj.bridge.context.PinpointingMessageHandler; | |||
import org.aspectj.weaver.UnresolvedType.TypeKind; | |||
import org.aspectj.weaver.patterns.DeclarePrecedence; | |||
import org.aspectj.weaver.patterns.PerClause; | |||
@@ -69,6 +70,9 @@ public abstract class World implements Dump.INode { | |||
/** XhasMember option setting passed down to weaver */ | |||
private boolean XhasMember = false; | |||
/** Xpinpoint controls whether we put out developer info showing the source of messages */ | |||
private boolean Xpinpoint = false; | |||
/** When behaving in a Java 5 way autoboxing is considered */ | |||
private boolean behaveInJava5Way = false; | |||
@@ -504,7 +508,11 @@ public abstract class World implements Dump.INode { | |||
} | |||
public void setMessageHandler(IMessageHandler messageHandler) { | |||
this.messageHandler = messageHandler; | |||
if (this.isInPinpointMode()) { | |||
this.messageHandler = new PinpointingMessageHandler(messageHandler); | |||
} else { | |||
this.messageHandler = messageHandler; | |||
} | |||
} | |||
/** | |||
@@ -602,6 +610,14 @@ public abstract class World implements Dump.INode { | |||
XhasMember = b; | |||
} | |||
public boolean isInPinpointMode() { | |||
return Xpinpoint; | |||
} | |||
public void setPinpointMode(boolean b) { | |||
this.Xpinpoint = b; | |||
} | |||
public void setBehaveInJava5Way(boolean b) { | |||
behaveInJava5Way = b; | |||
} |
@@ -57,6 +57,8 @@ import org.aspectj.apache.bcel.generic.annotation.AnnotationGen; | |||
import org.aspectj.bridge.IMessage; | |||
import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.bridge.WeaveMessage; | |||
import org.aspectj.bridge.context.CompilationAndWeavingContext; | |||
import org.aspectj.bridge.context.ContextToken; | |||
import org.aspectj.util.PartialOrder; | |||
import org.aspectj.weaver.AjAttribute; | |||
import org.aspectj.weaver.AjcMemberMaker; | |||
@@ -1726,9 +1728,11 @@ class BcelClassWeaver implements IClassWeaver { | |||
private boolean match(BcelShadow shadow, List shadowAccumulator) { | |||
//System.err.println("match: " + shadow); | |||
ContextToken shadowMatchToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.MATCHING_SHADOW, shadow); | |||
boolean isMatched = false; | |||
for (Iterator i = shadowMungers.iterator(); i.hasNext(); ) { | |||
ShadowMunger munger = (ShadowMunger)i.next(); | |||
ContextToken mungerMatchToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.MATCHING_POINTCUT, munger.getPointcut()); | |||
if (munger.match(shadow, world)) { | |||
WeaverMetrics.recordMatchResult(true);// Could pass: munger | |||
@@ -1741,9 +1745,11 @@ class BcelClassWeaver implements IClassWeaver { | |||
} else { | |||
WeaverMetrics.recordMatchResult(false); // Could pass: munger | |||
} | |||
CompilationAndWeavingContext.leavingPhase(mungerMatchToken); | |||
} | |||
if (isMatched) shadowAccumulator.add(shadow); | |||
CompilationAndWeavingContext.leavingPhase(shadowMatchToken); | |||
return isMatched; | |||
} | |||
@@ -1759,7 +1765,9 @@ class BcelClassWeaver implements IClassWeaver { | |||
for (Iterator i = shadows.iterator(); i.hasNext(); ) { | |||
BcelShadow shadow = (BcelShadow)i.next(); | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.IMPLEMENTING_ON_SHADOW,shadow); | |||
shadow.implement(); | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
} | |||
mg.matchedShadows = null; | |||
} |
@@ -2822,7 +2822,7 @@ public class BcelShadow extends Shadow { | |||
public LazyMethodGen extractMethod(String newMethodName, int visibilityModifier, ShadowMunger munger) { | |||
LazyMethodGen.assertGoodBody(range.getBody(), newMethodName); | |||
if (!getKind().allowsExtraction()) throw new BCException(); | |||
if (!getKind().allowsExtraction()) throw new BCException("Attempt to extract method from a shadow kind that does not support this operation (" + getKind() + ")"); | |||
LazyMethodGen freshMethod = createMethodGen(newMethodName,visibilityModifier); | |||
// System.err.println("******"); |
@@ -34,6 +34,8 @@ import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.bridge.Message; | |||
import org.aspectj.bridge.MessageUtil; | |||
import org.aspectj.bridge.WeaveMessage; | |||
import org.aspectj.bridge.context.CompilationAndWeavingContext; | |||
import org.aspectj.bridge.context.ContextToken; | |||
import org.aspectj.weaver.AjcMemberMaker; | |||
import org.aspectj.weaver.AnnotationOnTypeMunger; | |||
import org.aspectj.weaver.AnnotationX; | |||
@@ -71,6 +73,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
} | |||
public boolean munge(BcelClassWeaver weaver) { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.MUNGING_WITH, this); | |||
boolean changed = false; | |||
boolean worthReporting = true; | |||
@@ -150,6 +153,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
} | |||
} | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
return changed; | |||
} | |||
@@ -52,6 +52,8 @@ import org.aspectj.bridge.Message; | |||
import org.aspectj.bridge.MessageUtil; | |||
import org.aspectj.bridge.SourceLocation; | |||
import org.aspectj.bridge.WeaveMessage; | |||
import org.aspectj.bridge.context.CompilationAndWeavingContext; | |||
import org.aspectj.bridge.context.ContextToken; | |||
import org.aspectj.util.FileUtil; | |||
import org.aspectj.util.FuzzyBoolean; | |||
import org.aspectj.weaver.Advice; | |||
@@ -952,10 +954,12 @@ public class BcelWeaver implements IWeaver { | |||
// variation of "weave" that sources class files from an external source. | |||
public Collection weave(IClassFileProvider input) throws IOException { | |||
ContextToken weaveToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING, ""); | |||
Collection wovenClassNames = new ArrayList(); | |||
IWeaveRequestor requestor = input.getRequestor(); | |||
requestor.processingReweavableState(); | |||
ContextToken reweaveToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_REWEAVABLE_STATE,""); | |||
prepareToProcessReweavableState(); | |||
// clear all state from files we'll be reweaving | |||
for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) { | |||
@@ -965,10 +969,16 @@ public class BcelWeaver implements IWeaver { | |||
// null return from getClassType() means the delegate is an eclipse source type - so | |||
// there *cant* be any reweavable state... (he bravely claimed...) | |||
if (classType !=null) | |||
if (classType !=null) { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_REWEAVABLE_STATE, className); | |||
processReweavableStateIfPresent(className, classType); | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
} | |||
} | |||
CompilationAndWeavingContext.leavingPhase(reweaveToken); | |||
ContextToken typeMungingToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_TYPE_MUNGERS,""); | |||
requestor.addingTypeMungers(); | |||
// We process type mungers in two groups, first mungers that change the type | |||
@@ -993,7 +1003,10 @@ public class BcelWeaver implements IWeaver { | |||
addNormalTypeMungers(className); | |||
} | |||
CompilationAndWeavingContext.leavingPhase(typeMungingToken); | |||
requestor.weavingAspects(); | |||
ContextToken aspectToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_ASPECTS, ""); | |||
// first weave into aspects | |||
for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) { | |||
UnwovenClassFile classFile = (UnwovenClassFile)i.next(); | |||
@@ -1004,8 +1017,10 @@ public class BcelWeaver implements IWeaver { | |||
wovenClassNames.add(className); | |||
} | |||
} | |||
CompilationAndWeavingContext.leavingPhase(aspectToken); | |||
requestor.weavingClasses(); | |||
ContextToken classToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_CLASSES, ""); | |||
// then weave into non-aspects | |||
for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) { | |||
UnwovenClassFile classFile = (UnwovenClassFile)i.next(); | |||
@@ -1016,6 +1031,7 @@ public class BcelWeaver implements IWeaver { | |||
wovenClassNames.add(className); | |||
} | |||
} | |||
CompilationAndWeavingContext.leavingPhase(classToken); | |||
addedClasses = new ArrayList(); | |||
deletedTypenames = new ArrayList(); | |||
@@ -1024,6 +1040,7 @@ public class BcelWeaver implements IWeaver { | |||
warnOnUnmatchedAdvice(); | |||
requestor.weaveCompleted(); | |||
CompilationAndWeavingContext.leavingPhase(weaveToken); | |||
return wovenClassNames; | |||
} | |||
@@ -1119,7 +1136,9 @@ public class BcelWeaver implements IWeaver { | |||
weaveParentsFor(typesForWeaving,rtxI.getName()); | |||
} | |||
} | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_DECLARE_PARENTS,rtx.getName()); | |||
weaveParentTypeMungers(rtx); // Now do this type | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
typesForWeaving.remove(typeToWeave); // and remove it from the list of those to process | |||
} | |||
@@ -1168,6 +1187,7 @@ public class BcelWeaver implements IWeaver { | |||
private void weaveAndNotify(UnwovenClassFile classFile, BcelObjectType classType, | |||
IWeaveRequestor requestor) throws IOException { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_TYPE, classType.getResolvedTypeX().getName()); | |||
LazyClassGen clazz = weaveWithoutDump(classFile,classType); | |||
classType.finishedWith(); | |||
//clazz is null if the classfile was unchanged by weaving... | |||
@@ -1179,6 +1199,7 @@ public class BcelWeaver implements IWeaver { | |||
} else { | |||
requestor.acceptResult(classFile); | |||
} | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
} | |||
/** helper method - will return NULL if the underlying delegate is an EclipseSourceType and not a BcelObjectType */ | |||
@@ -1379,6 +1400,7 @@ public class BcelWeaver implements IWeaver { | |||
} | |||
public void weaveNormalTypeMungers(ResolvedType onType) { | |||
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_TYPE_MUNGERS, onType.getName()); | |||
if (onType.isRawType() || onType.isParameterizedType()) onType = onType.getGenericType(); | |||
for (Iterator i = typeMungerList.iterator(); i.hasNext(); ) { | |||
ConcreteTypeMunger m = (ConcreteTypeMunger)i.next(); | |||
@@ -1386,6 +1408,7 @@ public class BcelWeaver implements IWeaver { | |||
onType.addInterTypeMunger(m); | |||
} | |||
} | |||
CompilationAndWeavingContext.leavingPhase(tok); | |||
} | |||
@@ -148,7 +148,7 @@ public class ClassPathManager { | |||
try { | |||
if (fis!=null) fis.close(); | |||
} catch (IOException ioe) { | |||
throw new BCException("Can't close class file : "+file.getName()+": "+ioe.toString()); | |||
throw new BCException("Can't close class file : "+file.getName(),ioe); | |||
} finally { | |||
fis = null; | |||
} | |||
@@ -250,7 +250,7 @@ public class ClassPathManager { | |||
zipFile = new ZipFile(file); | |||
openArchives.add(zipFile); | |||
} catch (IOException ioe) { | |||
throw new BCException("Can't open archive: "+file.getName()+": "+ioe.toString()); | |||
throw new BCException("Can't open archive: "+file.getName(),ioe); | |||
} | |||
} | |||
@@ -272,7 +272,7 @@ public class ClassPathManager { | |||
openArchives.remove(zipFile); | |||
zipFile.close(); | |||
} catch (IOException ioe) { | |||
throw new BCException("Can't close archive: "+file.getName()+": "+ioe.toString()); | |||
throw new BCException("Can't close archive: "+file.getName(),ioe); | |||
} finally { | |||
zipFile = null; | |||
} |