summaryrefslogtreecommitdiffstats
path: root/org.aspectj.ajdt.core
diff options
context:
space:
mode:
authorAndy Clement <andrew.clement@gmail.com>2013-01-21 17:56:20 -0800
committerAndy Clement <andrew.clement@gmail.com>2013-01-21 17:56:20 -0800
commitf54f44a104806b06ab72b223c55d71476c95415d (patch)
tree990b928064e6cc988086f8402c9da22681c5534c /org.aspectj.ajdt.core
parent96ebaaed65fe5d507cae3d56126d76f217a9f13a (diff)
downloadaspectj-f54f44a104806b06ab72b223c55d71476c95415d.tar.gz
aspectj-f54f44a104806b06ab72b223c55d71476c95415d.zip
Allow code generation hints for generated compiler names
Diffstat (limited to 'org.aspectj.ajdt.core')
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfPseudoToken.java103
1 files changed, 83 insertions, 20 deletions
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfPseudoToken.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfPseudoToken.java
index 9bf2f3171..821b8b3be 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfPseudoToken.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfPseudoToken.java
@@ -14,15 +14,23 @@ package org.aspectj.ajdt.internal.compiler.ast;
import java.lang.reflect.Modifier;
+import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.FalseLiteral;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.StringLiteral;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TrueLiteral;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser;
@@ -35,15 +43,18 @@ import org.aspectj.weaver.patterns.Pointcut;
/**
* (formals*): ... if(expr) ...
*
- * generates the following: public static final boolean ajc$if_N(formals*, [thisJoinPoints as needed]) { return expr; }
+ * generates the following: public static final boolean ajc$if_N(formals*,
+ * [thisJoinPoints as needed]) { return expr; }
*
- * 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 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 parameters. If a is used, we signal an error because a was not one of the cflow
- * variables. XXX we'll do this part after we do cflow
+ * 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
+ * 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
+ * parameters. If a is used, we signal an error because a was not one of the
+ * cflow variables. XXX we'll do this part after we do cflow
*
- * The IfPointcut pcd then generates itself always as a dynamic test, it has to get the right parameters through any named pointcut
- * references...
+ * The IfPointcut pcd then generates itself always as a dynamic test, it has to
+ * get the right parameters through any named pointcut references...
*/
public class IfPseudoToken extends PseudoToken {
public Expression expr;
@@ -61,7 +72,8 @@ public class IfPseudoToken extends PseudoToken {
} else if (expr instanceof TrueLiteral) {
return IfPointcut.makeIfTruePointcut(Pointcut.SYMBOLIC);
} else {
- pointcut = new IfPointcut(new ResolvedMemberImpl(Member.METHOD, UnresolvedType.OBJECT, 0, "if_", "()V"), 0);
+ pointcut = new IfPointcut(new ResolvedMemberImpl(Member.METHOD,
+ UnresolvedType.OBJECT, 0, "if_", "()V"), 0);
}
return pointcut;
@@ -70,33 +82,80 @@ public class IfPseudoToken extends PseudoToken {
/**
* enclosingDec is either AdviceDeclaration or PointcutDeclaration
*/
- public void postParse(TypeDeclaration typeDec, MethodDeclaration enclosingDec) {
+ public void postParse(TypeDeclaration typeDec,
+ MethodDeclaration enclosingDec) {
// typeDec.scope.problemReporter().signalError(sourceStart, sourceEnd,
// "if pcd is not implemented in 1.1alpha1");
// XXX need to implement correctly
if (pointcut == null)
return;
- testMethod = makeIfMethod(enclosingDec.compilationResult, enclosingDec, typeDec);
+ testMethod = makeIfMethod(enclosingDec.compilationResult, enclosingDec,
+ typeDec);
AstUtil.addMethodDeclaration(typeDec, testMethod);
}
+ private final static char[] CodeGenerationHint = "CodeGenerationHint".toCharArray();
+ private final static char[] FullyQualifiedCodeGenerationHint = "org.aspectj.lang.annotation.control.CodeGenerationHint".toCharArray();
+ private final static char[] IfNameSuffix = "ifNameSuffix".toCharArray();
+
// XXX todo: make sure that errors in Arguments only get displayed once
- private MethodDeclaration makeIfMethod(CompilationResult result, MethodDeclaration enclosingDec,
- TypeDeclaration containingTypeDec) {
+ private MethodDeclaration makeIfMethod(CompilationResult result,
+ MethodDeclaration enclosingDec, TypeDeclaration containingTypeDec) {
MethodDeclaration ret = new IfMethodDeclaration(result, pointcut);
- ret.modifiers = ClassFileConstants.AccStatic | ClassFileConstants.AccFinal | ClassFileConstants.AccPublic;
+ ret.modifiers = ClassFileConstants.AccStatic
+ | ClassFileConstants.AccFinal | ClassFileConstants.AccPublic;
ret.returnType = AstUtil.makeTypeReference(TypeBinding.BOOLEAN);
+
+ String nameSuffix = null;
+
+ if (enclosingDec!=null && enclosingDec.annotations!=null) {
+ NormalAnnotation interestingAnnotation = null;
+ Annotation[] as = enclosingDec.annotations;
+ if (as!=null) {
+ for (int a = 0; a < as.length && interestingAnnotation == null; a++) {
+ if (as[a] instanceof NormalAnnotation) {
+ TypeReference tr = as[a].type;
+ if (tr instanceof SingleTypeReference) {
+ if (CharOperation.equals(CodeGenerationHint,((SingleTypeReference)tr).token)) {
+ interestingAnnotation = (NormalAnnotation)as[a];
+ }
+ } else if (tr instanceof QualifiedTypeReference) {
+ char[] qualifiedName = CharOperation.concatWith(((QualifiedTypeReference)tr).tokens,'.');
+ if (CharOperation.equals(FullyQualifiedCodeGenerationHint,qualifiedName)) {
+ interestingAnnotation = (NormalAnnotation)as[a];
+ }
+ }
+ }
+ }
+ }
+ if (interestingAnnotation!=null) {
+ MemberValuePair[] memberValuePairs = interestingAnnotation.memberValuePairs;
+ for (MemberValuePair memberValuePair: memberValuePairs) {
+ if (CharOperation.equals(IfNameSuffix,memberValuePair.name) && (memberValuePair.value instanceof StringLiteral)) {
+ nameSuffix = new String(((StringLiteral)memberValuePair.value).source());
+ }
+ }
+ }
+ }
+
+
// create a more stable name 277508
StringBuffer ifSelector = new StringBuffer();
ifSelector.append("ajc$if$");
- ifSelector.append(Integer.toHexString(expr.sourceStart));
+ if (nameSuffix == null || nameSuffix.length()==0) {
+ ifSelector.append(Integer.toHexString(expr.sourceStart));
+ } else {
+ ifSelector.append(nameSuffix);
+ }
// possibly even better logic for more reliable name:
// if (enclosingDec instanceof AdviceDeclaration) {
- // // name is ajc$if$<adviceSequenceNumber>$<hashcodeOfIfExpressionInHex>
+ // // name is
+ // ajc$if$<adviceSequenceNumber>$<hashcodeOfIfExpressionInHex>
// ifSelector.append("ajc$if$");
- // ifSelector.append(((AdviceDeclaration) enclosingDec).adviceSequenceNumberInType);
+ // ifSelector.append(((AdviceDeclaration)
+ // enclosingDec).adviceSequenceNumberInType);
// ifSelector.append("$").append(Integer.toHexString(expr.toString().hashCode()));
// } else if (enclosingDec instanceof PointcutDeclaration) {
// // name is pointcut selector then $if$<hashcodeOfIfExpressionInHex>
@@ -104,16 +163,19 @@ public class IfPseudoToken extends PseudoToken {
// ifSelector.append("$if$");
// ifSelector.append(Integer.toHexString(expr.toString().hashCode()));
// } else {
- // throw new BCException("Unexpected enclosing declaration of " + enclosingDec + " for if pointcut designator");
+ // throw new BCException("Unexpected enclosing declaration of " +
+ // enclosingDec + " for if pointcut designator");
// }
// hashcode of expression
ret.selector = ifSelector.toString().toCharArray();
ret.arguments = makeArguments(enclosingDec, containingTypeDec);
- ret.statements = new Statement[] { new ReturnStatement(expr, expr.sourceStart, expr.sourceEnd) };
+ ret.statements = new Statement[] { new ReturnStatement(expr,
+ expr.sourceStart, expr.sourceEnd) };
return ret;
}
- private Argument[] makeArguments(MethodDeclaration enclosingDec, TypeDeclaration containingTypeDec) {
+ private Argument[] makeArguments(MethodDeclaration enclosingDec,
+ TypeDeclaration containingTypeDec) {
Argument[] baseArguments = enclosingDec.arguments;
int len = baseArguments.length;
if (enclosingDec instanceof AdviceDeclaration) {
@@ -123,7 +185,8 @@ public class IfPseudoToken extends PseudoToken {
Argument[] ret = new Argument[len];
for (int i = 0; i < len; i++) {
Argument a = baseArguments[i];
- ret[i] = new Argument(a.name, AstUtil.makeLongPos(a.sourceStart, a.sourceEnd), a.type, Modifier.FINAL);
+ ret[i] = new Argument(a.name, AstUtil.makeLongPos(a.sourceStart,
+ a.sourceEnd), a.type, Modifier.FINAL);
}
ret = AdviceDeclaration.addTjpArguments(ret, containingTypeDec);